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, NeoVimAgentMsgIdDelete,
NeoVimAgentMsgIdResize, NeoVimAgentMsgIdResize,
NeoVimAgentMsgIdRedraw, NeoVimAgentMsgIdRedraw,
NeoVimAgentMsgIdDirtyDocs,
#ifdef DEBUG #ifdef DEBUG
NeoVimAgentDebug1, NeoVimAgentDebug1,

View File

@ -24,17 +24,22 @@ data_to_array(NSInteger)
@interface NeoVimServer () @interface NeoVimServer ()
- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data; - (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
@end @end
static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
@autoreleasepool { @autoreleasepool {
NeoVimServer *neoVimServer = (__bridge NeoVimServer *) info; 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]; [self sendMessageWithId:NeoVimServerMsgIdServerReady data:nil];
} }
- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data { - (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data {
switch (msgid) { switch (msgid) {
case NeoVimAgentMsgIdAgentReady: case NeoVimAgentMsgIdAgentReady:
server_start_neovim(); server_start_neovim();
return; return nil;
case NeoVimAgentMsgIdInput: { case NeoVimAgentMsgIdInput: {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
server_vim_input(string); server_vim_input(string);
return; return nil;
} }
case NeoVimAgentMsgIdInputMarked: { case NeoVimAgentMsgIdInputMarked: {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
server_vim_input_marked_text(string); server_vim_input_marked_text(string);
return; return nil;
} }
case NeoVimAgentMsgIdDelete: { case NeoVimAgentMsgIdDelete: {
NSInteger *values = data_to_NSInteger_array(data, 1); NSInteger *values = data_to_NSInteger_array(data, 1);
server_delete(values[0]); server_delete(values[0]);
return; return nil;
} }
case NeoVimAgentMsgIdResize: { case NeoVimAgentMsgIdResize: {
int *values = data_to_int_array(data, 2); int *values = data_to_int_array(data, 2);
server_resize(values[0], values[1]); server_resize(values[0], values[1]);
return; return nil;
} }
case NeoVimAgentMsgIdRedraw: case NeoVimAgentMsgIdRedraw:
server_redraw(); server_redraw();
return; return nil;
case NeoVimAgentMsgIdDirtyDocs: {
bool dirty = server_has_dirty_docs();
return [NSData dataWithBytes:&dirty length:sizeof(bool)];
}
default: 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_resize(int width, int height);
extern void server_vim_input_marked_text(NSString *markedText); extern void server_vim_input_marked_text(NSString *markedText);
extern void server_insert_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/ui_bridge.h>
#import <nvim/event/signal.h> #import <nvim/event/signal.h>
#import <nvim/main.h> #import <nvim/main.h>
#import <nvim/cursor.h>
#import <nvim/screen.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 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)forceRedraw;
- (void)resizeToWidth:(int)width height:(int)height; - (void)resizeToWidth:(int)width height:(int)height;
- (bool)hasDirtyDocs;
@end @end
NS_ASSUME_NONNULL_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(int)
data_to_array(bool)
data_to_array(CellAttributes) data_to_array(CellAttributes)
@interface NeoVimAgent () @interface NeoVimAgent ()
@ -45,7 +46,7 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
CFMessagePortRef _localServerPort; CFMessagePortRef _localServerPort;
NSThread *_localServerThread; NSThread *_localServerThread;
CFRunLoopRef _runLoop; CFRunLoopRef _runLoop;
NSTask *_neoVimServerTask; NSTask *_neoVimServerTask;
@ -114,6 +115,17 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
[self sendMessageWithId:NeoVimAgentMsgIdResize data:data]; [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 { - (void)runLocalServer {
@autoreleasepool { @autoreleasepool {
CFMessagePortContext localContext = { CFMessagePortContext localContext = {
@ -152,21 +164,34 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
[self sendMessageWithId:NeoVimAgentMsgIdAgentReady data:nil]; [self sendMessageWithId:NeoVimAgentMsgIdAgentReady data:nil];
} }
- (void)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data { - (NSData *)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data {
if (_remoteServerPort == NULL) { if (_remoteServerPort == NULL) {
log4Warn("Remote server is null: The msg (%lu:%@) could not be sent.", (unsigned long) msgid, data); 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( SInt32 responseCode = CFMessagePortSendRequest(
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, NULL, NULL _remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, replyMode, &responseData
); );
if (responseCode == kCFMessagePortSuccess) { if (responseCode != kCFMessagePortSuccess) {
return; 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 { - (NSString *)neoVimServerExecutablePath {

View File

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

View File

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