1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-25 23:02:35 +03:00

GH-218 Add hasDirtyDocs()

- Use it to determine whether to close the window or not.
This commit is contained in:
Tae Won Ha 2016-07-18 20:16:56 +02:00
parent 10046cdc6b
commit 4b4ccd13b3
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
8 changed files with 82 additions and 23 deletions

View File

@ -48,6 +48,7 @@ typedef NS_ENUM(NSUInteger, NeoVimAgentMsgId) {
NeoVimAgentMsgIdDelete,
NeoVimAgentMsgIdResize,
NeoVimAgentMsgIdRedraw,
NeoVimAgentMsgIdDirtyDocs,
#ifdef DEBUG
NeoVimAgentDebug1,

View File

@ -24,17 +24,22 @@ data_to_array(NSInteger)
@interface NeoVimServer ()
- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
@end
static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
@autoreleasepool {
NeoVimServer *neoVimServer = (__bridge NeoVimServer *) info;
[neoVimServer handleMessageWithId:msgid data:(__bridge NSData *) data];
}
NSData *responseData = [neoVimServer handleMessageWithId:msgid data:(__bridge NSData *) data];
return NULL;
if (responseData == nil) {
return NULL;
}
log4Debug("server returning data: %@", responseData);
return CFDataCreateCopy(kCFAllocatorDefault, (__bridge CFDataRef) responseData);
}
}
@ -129,45 +134,50 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
[self sendMessageWithId:NeoVimServerMsgIdServerReady data:nil];
}
- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data {
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data {
switch (msgid) {
case NeoVimAgentMsgIdAgentReady:
server_start_neovim();
return;
return nil;
case NeoVimAgentMsgIdInput: {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
server_vim_input(string);
return;
return nil;
}
case NeoVimAgentMsgIdInputMarked: {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
server_vim_input_marked_text(string);
return;
return nil;
}
case NeoVimAgentMsgIdDelete: {
NSInteger *values = data_to_NSInteger_array(data, 1);
server_delete(values[0]);
return;
return nil;
}
case NeoVimAgentMsgIdResize: {
int *values = data_to_int_array(data, 2);
server_resize(values[0], values[1]);
return;
return nil;
}
case NeoVimAgentMsgIdRedraw:
server_redraw();
return;
return nil;
case NeoVimAgentMsgIdDirtyDocs: {
bool dirty = server_has_dirty_docs();
return [NSData dataWithBytes:&dirty length:sizeof(bool)];
}
default:
return;
return nil;
}
}

View File

@ -17,3 +17,4 @@ extern void server_redraw();
extern void server_resize(int width, int height);
extern void server_vim_input_marked_text(NSString *markedText);
extern void server_insert_marked_text(NSString *markedText);
extern bool server_has_dirty_docs();

View File

@ -20,7 +20,6 @@
#import <nvim/ui_bridge.h>
#import <nvim/event/signal.h>
#import <nvim/main.h>
#import <nvim/cursor.h>
#import <nvim/screen.h>
@ -614,3 +613,13 @@ void server_insert_marked_text(NSString *markedText) {
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_marked_text retain])); // release in neovim_input
}
bool server_has_dirty_docs() {
FOR_ALL_BUFFERS(buffer) {
if (buffer->b_changed) {
return true;
}
}
return false;
}

View File

@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)forceRedraw;
- (void)resizeToWidth:(int)width height:(int)height;
- (bool)hasDirtyDocs;
@end
NS_ASSUME_NONNULL_END

View File

@ -21,6 +21,7 @@ static type *data_to_ ## type ## _array(NSData *data, NSUInteger count) { \
}
data_to_array(int)
data_to_array(bool)
data_to_array(CellAttributes)
@interface NeoVimAgent ()
@ -45,7 +46,7 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
CFMessagePortRef _localServerPort;
NSThread *_localServerThread;
CFRunLoopRef _runLoop;
NSTask *_neoVimServerTask;
@ -114,6 +115,17 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
[self sendMessageWithId:NeoVimAgentMsgIdResize data:data];
}
- (bool)hasDirtyDocs {
NSData *responseData = [self sendMessageWithId:NeoVimAgentMsgIdDirtyDocs data:nil];
if (responseData == NULL) {
NSLog(@"WARNING: agent got response data null");
return false;
}
bool *values = data_to_bool_array(responseData, 1);
return values[0];
}
- (void)runLocalServer {
@autoreleasepool {
CFMessagePortContext localContext = {
@ -152,21 +164,34 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
[self sendMessageWithId:NeoVimAgentMsgIdAgentReady data:nil];
}
- (void)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data {
- (NSData *)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data {
if (_remoteServerPort == NULL) {
log4Warn("Remote server is null: The msg (%lu:%@) could not be sent.", (unsigned long) msgid, data);
return;
return nil;
}
CFDataRef responseData = NULL;
CFStringRef replyMode = NULL;
// We only expect reply from NeoVimAgentMsgIdDirtyDocs
if (msgid == NeoVimAgentMsgIdDirtyDocs) {
replyMode = kCFRunLoopDefaultMode;
}
SInt32 responseCode = CFMessagePortSendRequest(
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, NULL, NULL
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, replyMode, &responseData
);
if (responseCode == kCFMessagePortSuccess) {
return;
if (responseCode != kCFMessagePortSuccess) {
log4Warn("The msg (%lu:%@) could not be sent: %d", (unsigned long) msgid, data, responseCode);
return nil;
}
log4Warn("The msg (%lu:%@) could not be sent: %d", (unsigned long) msgid, data, responseCode);
if (responseData == NULL) {
return nil;
}
return [NSData dataWithData:(__bridge NSData *) responseData];
}
- (NSString *)neoVimServerExecutablePath {

View File

@ -180,6 +180,10 @@ public class NeoVimView: NSView {
self.drawCursor(self.grid.background)
}
public func hasDirtyDocs() -> Bool {
return self.agent.hasDirtyDocs()
}
private func drawCursor(background: UInt32) {
// FIXME: for now do some rudimentary cursor drawing
let cursorPosition = self.grid.putPosition

View File

@ -24,18 +24,25 @@ class MainWindowController: NSWindowController, NSWindowDelegate, NeoVimViewDele
self.window?.makeFirstResponder(self.neoVimView)
}
// MARK: - NSWindowDelegate
func windowWillClose(notification: NSNotification) {
self.mainWindowManager?.closeMainWindow(self)
}
func windowShouldClose(sender: AnyObject) -> Bool {
return !self.neoVimView.hasDirtyDocs()
}
// MARK: - NeoVimViewDelegate
func setNeoVimTitle(title: String) {
NSLog("\(#function): \(title)")
}
func neoVimStopped() {
self.window?.performClose(self)
self.close()
}
// MARK: - Private
private func addViews() {
self.window?.contentView?.addSubview(self.neoVimView)
self.neoVimView.autoPinEdgesToSuperviewEdges()