diff --git a/NeoVimServer/NeoVimServerMsgIds.h b/NeoVimServer/NeoVimMsgIds.h similarity index 97% rename from NeoVimServer/NeoVimServerMsgIds.h rename to NeoVimServer/NeoVimMsgIds.h index 14e3f050..bcf65035 100644 --- a/NeoVimServer/NeoVimServerMsgIds.h +++ b/NeoVimServer/NeoVimMsgIds.h @@ -42,7 +42,7 @@ typedef NS_ENUM(NSUInteger, NeoVimServerMsgId) { }; typedef NS_ENUM(NSUInteger, NeoVimAgentMsgId) { - NeoVimAgendMsgIdAgentReady = 0, + NeoVimAgentMsgIdAgentReady = 0, NeoVimAgentMsgIdInput, NeoVimAgentMsgIdInputMarked, NeoVimAgentMsgIdDelete, diff --git a/NeoVimServer/NeoVimServer.h b/NeoVimServer/NeoVimServer.h index f94b2346..d8ba2415 100644 --- a/NeoVimServer/NeoVimServer.h +++ b/NeoVimServer/NeoVimServer.h @@ -5,7 +5,7 @@ #import #import "NeoVimUiBridgeProtocol.h" -#import "NeoVimServerMsgIds.h" +#import "NeoVimMsgIds.h" @interface NeoVimServer : NSObject @@ -14,7 +14,6 @@ localServerName:(NSString *)localServerName remoteServerName:(NSString *)remoteServerName; -- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data; - (void)sendMessageWithId:(NeoVimServerMsgId)msgid; - (void)sendMessageWithId:(NeoVimServerMsgId)msgid data:(NSData *)data; - (void)notifyReadiness; diff --git a/NeoVimServer/NeoVimServer.m b/NeoVimServer/NeoVimServer.m index 2d085dfc..f86b9a6c 100644 --- a/NeoVimServer/NeoVimServer.m +++ b/NeoVimServer/NeoVimServer.m @@ -4,21 +4,35 @@ */ #import "NeoVimServer.h" -#import "NeoVimServerMsgIds.h" +#import "NeoVimMsgIds.h" #import "server_globals.h" static const double qTimeout = 10.0; +#define data_to_array(type) \ +static type *data_to_ ## type ## _array(NSData *data, NSUInteger count) { \ + NSUInteger length = count * sizeof( type ); \ + if (data.length != length) { \ + return NULL; \ + } \ + return ( type *) data.bytes; \ +} + +data_to_array(int) +data_to_array(NSInteger) + +@interface NeoVimServer () + +- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data; + +@end + static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { @autoreleasepool { NeoVimServer *neoVimServer = (NeoVimServer *) info; - NSData *responseData = [neoVimServer handleMessageWithId:msgid data:(NSData *) data]; - if (responseData == NULL) { - return NULL; - } - - return CFDataCreate(kCFAllocatorDefault, responseData.bytes, responseData.length); + [neoVimServer handleMessageWithId:msgid data:(NSData *) data]; + return NULL; } } @@ -72,35 +86,6 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD [super dealloc]; } -- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data { - NSLog(@"msg received: %d -> %@", msgid, data); - - switch (msgid) { - - case NeoVimAgendMsgIdAgentReady: - start_neovim(); - return nil; - - case NeoVimAgentMsgIdInput: - return nil; - - case NeoVimAgentMsgIdInputMarked: - return nil; - - case NeoVimAgentMsgIdDelete: - return nil; - - case NeoVimAgentMsgIdResize: - return nil; - - case NeoVimAgentMsgIdRedraw: - return nil; - - default: - return nil; - } -} - - (void)runLocalServer { @autoreleasepool { unsigned char shouldFree = false; @@ -135,6 +120,11 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD } - (void)sendMessageWithId:(NeoVimServerMsgId)msgid data:(NSData *)data { + if (_remoteServerPort == NULL) { + NSLog(@"WARNING: remote server is null"); + return; + } + SInt32 responseCode = CFMessagePortSendRequest( _remoteServerPort, msgid, (CFDataRef) data, qTimeout, qTimeout, NULL, NULL ); @@ -150,4 +140,51 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD [self sendMessageWithId:NeoVimServerMsgIdServerReady data:nil]; } +- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data { +// NSLog(@"msg received: %d -> %@", msgid, data); + + switch (msgid) { + + case NeoVimAgentMsgIdAgentReady: + start_neovim(); + return; + + case NeoVimAgentMsgIdInput: { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + do_vim_input(string); + [string release]; + + return; + } + + case NeoVimAgentMsgIdInputMarked: { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + do_vim_input_marked_text(string); + [string release]; + + return; + } + + case NeoVimAgentMsgIdDelete: { + NSInteger *values = data_to_NSInteger_array(data, 1); + do_delete(values[0]); + return; + } + + case NeoVimAgentMsgIdResize: { + int *values = data_to_int_array(data, 2); + NSLog(@"!!! server rcv resize: %d:%d", values[0], values[1]); + do_resize(values[0], values[1]); + return; + } + + case NeoVimAgentMsgIdRedraw: + do_force_redraw(); + return; + + default: + return; + } +} + @end diff --git a/NeoVimServer/main.m b/NeoVimServer/main.m index 85bb0e6e..967a7f93 100644 --- a/NeoVimServer/main.m +++ b/NeoVimServer/main.m @@ -10,7 +10,6 @@ NeoVimServer *_neovim_server; - int main(int argc, const char *argv[]) { @autoreleasepool { NSArray *arguments = [NSProcessInfo processInfo].arguments; @@ -23,9 +22,7 @@ int main(int argc, const char *argv[]) { remoteServerName:remoteServerName]; [_neovim_server notifyReadiness]; - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - [runLoop addPort:[NSPort new] forMode:NSRunLoopCommonModes]; - [runLoop run]; + CFRunLoopRun(); } return 0; diff --git a/NeoVimServer/server_globals.h b/NeoVimServer/server_globals.h index 3bdbf32a..cc630156 100644 --- a/NeoVimServer/server_globals.h +++ b/NeoVimServer/server_globals.h @@ -11,3 +11,9 @@ extern NeoVimServer *_neovim_server; extern void start_neovim(); +extern void do_vim_input(NSString *input); +extern void do_delete(NSInteger count); +extern void do_force_redraw(); +extern void do_resize(int width, int height); +extern void do_vim_input_marked_text(NSString *markedText); +extern void do_insert_marked_text(NSString *markedText); diff --git a/NeoVimServer/server_ui.m b/NeoVimServer/server_ui.m index 4ed2754a..500da28a 100644 --- a/NeoVimServer/server_ui.m +++ b/NeoVimServer/server_ui.m @@ -237,6 +237,7 @@ static void xpc_ui_set_scroll_region(UI *ui __unused, int top, int bot, int left static void xpc_ui_scroll(UI *ui __unused, int count) { queue(^{ int value = count; + NSLog(@"ui_scroll: %d", count); NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; [data release]; @@ -321,7 +322,7 @@ static void xpc_ui_update_fg(UI *ui __unused, int fg) { if (fg == -1) { value = _default_foreground; NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; - [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdSetForeground data:data]; [data release]; return; @@ -331,7 +332,7 @@ static void xpc_ui_update_fg(UI *ui __unused, int fg) { value = fg; NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; - [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdSetForeground data:data]; [data release]; }); } @@ -343,7 +344,7 @@ static void xpc_ui_update_bg(UI *ui __unused, int bg) { if (bg == -1) { value = _default_background; NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; - [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdSetBackground data:data]; [data release]; return; @@ -352,7 +353,7 @@ static void xpc_ui_update_bg(UI *ui __unused, int bg) { _default_background = pun_type(unsigned int, bg); value = bg; NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; - [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdSetBackground data:data]; [data release]; }); } @@ -364,7 +365,7 @@ static void xpc_ui_update_sp(UI *ui __unused, int sp) { if (sp == -1) { value = _default_special; NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; - [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdSetSpecial data:data]; [data release]; return; @@ -373,7 +374,7 @@ static void xpc_ui_update_sp(UI *ui __unused, int sp) { _default_special = pun_type(unsigned int, sp); value = sp; NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(int))]; - [_neovim_server sendMessageWithId:NeoVimServerMsgIdScroll data:data]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdSetSpecial data:data]; [data release]; }); } @@ -510,3 +511,103 @@ void start_neovim() { [_neovim_server sendMessageWithId:NeoVimServerMsgIdNeoVimReady]; } +void do_delete_marked_text() { + NSUInteger length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4; + + [_marked_text release]; + _marked_text = nil; + + for (int i = 0; i < length; i++) { + loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_backspace retain])); // release in neovim_input + } +} + +void do_delete(NSInteger count) { + queue(^{ + _marked_delta = 0; + + // Very ugly: When we want to have the Hanja for 하, Cocoa first finalizes 하, then sets the Hanja as marked text. + // The main app will call this method when this happens, thus compute how many cell we have to go backward to + // correctly mark the will-be-soon-inserted Hanja... See also docs/notes-on-cocoa-text-input.md + int emptyCounter = 0; + for (int i = 0; i < count; i++) { + _marked_delta -= 1; + + // TODO: -1 because we assume that the cursor is one cell ahead, probably not always correct... + schar_T character = ScreenLines[_put_row * screen_Rows + _put_column - i - emptyCounter - 1]; + if (character == 0x00 || character == ' ') { + // FIXME: dunno yet, why we have to also match ' '... + _marked_delta -= 1; + emptyCounter += 1; + } + } + +// log4Debug("put cursor: %d:%d, count: %li, delta: %d", _put_row, _put_column, count, _marked_delta); + + for (int i = 0; i < count; i++) { + loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_backspace retain])); // release in neovim_input + } + }); +} + +void do_force_redraw() { + loop_schedule(&main_loop, event_create(1, force_redraw, 0)); +} + +void do_resize(int width, int height) { + queue(^{ + NSLog(@"!!! do_resize: %d:%d", width, height); + set_ui_size(_xpc_ui_data->bridge, width, height); + loop_schedule(&main_loop, event_create(1, refresh_ui, 0)); + }); +} + +void do_vim_input(NSString *input) { + queue(^{ + if (_marked_text == nil) { + loop_schedule(&main_loop, event_create(1, neovim_input, 1, [input retain])); // release in neovim_input + return; + } + + // Handle cases like ㅎ -> arrow key: The previously marked text is the same as the finalized text which should + // inserted. Neovim's drawing code is optimized such that it does not call put in this case again, thus, we have + // to manually unmark the cells in the main app. + if ([_marked_text isEqualToString:input]) { +// log4Debug("unmarking text: '%@'\t now at %d:%d", input, _put_row, _put_column); + const char *str = [_marked_text cStringUsingEncoding:NSUTF8StringEncoding]; + size_t cellCount = mb_string2cells((const char_u *) str); + for (int i = 1; i <= cellCount; i++) { +// log4Debug("unmarking at %d:%d", _put_row, _put_column - i); + int values[] = { _put_row, MAX(_put_column - i, 0) }; + NSData *data = [[NSData alloc] initWithBytes:values length:(2 * sizeof(int))]; + [_neovim_server sendMessageWithId:NeoVimServerMsgIdUnmark data:data]; + [data release]; + } + } + + do_delete_marked_text(); + loop_schedule(&main_loop, event_create(1, neovim_input, 1, [input retain])); // release in neovim_input + }); +} + +void do_vim_input_marked_text(NSString *markedText) { + queue(^{ + if (_marked_text == nil) { + _marked_row = _put_row; + _marked_column = _put_column + _marked_delta; +// log4Debug("marking position: %d:%d(%d + %d)", _put_row, _marked_column, _put_column, _marked_delta); + _marked_delta = 0; + } else { + do_delete_marked_text(); + } + +// log4Debug("inserting marked text '%@' at %d:%d", markedText, _put_row, _put_column); + do_insert_marked_text(markedText); + }); +} + +void do_insert_marked_text(NSString *markedText) { + _marked_text = [markedText retain]; // release when the final text is input in -vimInput + + loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_marked_text retain])); // release in neovim_input +} diff --git a/NeoVimXpc/NeoVimUiBridgeProtocol.h b/NeoVimXpc/NeoVimUiBridgeProtocol.h deleted file mode 120000 index 976db3cb..00000000 --- a/NeoVimXpc/NeoVimUiBridgeProtocol.h +++ /dev/null @@ -1 +0,0 @@ -../SwiftNeoVim/NeoVimUiBridgeProtocol.h \ No newline at end of file diff --git a/NeoVimXpc/NeoVimXpc.h b/NeoVimXpc/NeoVimXpc.h deleted file mode 100644 index 7986e3a8..00000000 --- a/NeoVimXpc/NeoVimXpc.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Tae Won Ha - http://taewon.de - @hataewon - * See LICENSE - */ - -@import Foundation; - -@protocol NeoVimXpc - -/** - * It seems that the XPC service does not get instantiated as long as no actual calls are made. However, we want neovim - * run as soon as we establish the connection. To achieve this, the client can call -probe which does not call anything - * on neovim. - */ -- (void)probe; - -- (void)startServerWithUuid:(NSString * _Nonnull)uuid; - -- (void)vimInput:(NSString * _Nonnull)input; -- (void)vimInputMarkedText:(NSString *_Nonnull)markedText; -- (void)deleteCharacters:(NSInteger)count; - -- (void)resizeToWidth:(int)width height:(int)height; -- (void)forceRedraw; - -- (void)debug1; - -@end diff --git a/NeoVimXpc/NeoVimXpcImpl.h b/NeoVimXpc/NeoVimXpcImpl.h deleted file mode 100644 index 8e61ca12..00000000 --- a/NeoVimXpc/NeoVimXpcImpl.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Tae Won Ha - http://taewon.de - @hataewon - * See LICENSE - */ - -@import Foundation; - -#import "NeoVimXpc.h" - -@protocol NeoVimUiBridgeProtocol; - -@interface NeoVimXpcImpl : NSObject - -- (instancetype _Nonnull)initWithNeoVimUi:(id _Nonnull)ui; - -- (void)probe; - -- (void)vimInput:(NSString *_Nonnull)input; -- (void)vimInputMarkedText:(NSString *_Nonnull)markedText; -- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data; -- (void)deleteCharacters:(NSInteger)count; -- (void)forceRedraw; - -- (void)resizeToWidth:(int)width height:(int)height; - -@end diff --git a/SwiftNeoVim/NeoVim.swift b/SwiftNeoVim/NeoVim.swift index 1243abaa..0d7fbc2a 100644 --- a/SwiftNeoVim/NeoVim.swift +++ b/SwiftNeoVim/NeoVim.swift @@ -7,10 +7,10 @@ import Foundation public class NeoVim { - private let agent: NeoVimAgent +// private let agent: NeoVimAgent public init() { - let uuid = NSUUID().UUIDString - self.agent = NeoVimAgent(uuid: uuid) +// let uuid = NSUUID().UUIDString +// self.agent = NeoVimAgent(uuid: uuid, uiBridge: nil) } } diff --git a/SwiftNeoVim/NeoVimAgent.h b/SwiftNeoVim/NeoVimAgent.h index e07f6ab6..d5ccb1af 100644 --- a/SwiftNeoVim/NeoVimAgent.h +++ b/SwiftNeoVim/NeoVimAgent.h @@ -6,11 +6,24 @@ #import +@protocol NeoVimUiBridgeProtocol; + + NS_ASSUME_NONNULL_BEGIN @interface NeoVimAgent : NSObject +@property (nonatomic, weak) id bridge; + - (instancetype)initWithUuid:(NSString *)uuid; +- (void)cleanUp; +- (void)establishLocalServer; + +- (void)vimInput:(NSString *)string; +- (void)vimInputMarkedText:(NSString *_Nonnull)markedText; +- (void)deleteCharacters:(NSInteger)count; +- (void)forceRedraw; +- (void)resizeToWidth:(int)width height:(int)height; @end diff --git a/SwiftNeoVim/NeoVimAgent.m b/SwiftNeoVim/NeoVimAgent.m index 3a6c45fc..57ee3ed4 100644 --- a/SwiftNeoVim/NeoVimAgent.m +++ b/SwiftNeoVim/NeoVimAgent.m @@ -4,14 +4,27 @@ */ #import "NeoVimAgent.h" -#import "NeoVimServerMsgIds.h" +#import "NeoVimMsgIds.h" +#import "NeoVimUiBridgeProtocol.h" static const int qTimeout = 10; +#define data_to_array(type) \ +static type *data_to_ ## type ## _array(NSData *data, NSUInteger count) { \ + NSUInteger length = count * sizeof( type ); \ + if (data.length != length) { \ + return NULL; \ + } \ + return ( type *) data.bytes; \ +} + +data_to_array(int) +data_to_array(CellAttributes) + @interface NeoVimAgent () -- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data; +- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data; @end @@ -19,12 +32,8 @@ static const int qTimeout = 10; static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { @autoreleasepool { NeoVimAgent *agent = (__bridge NeoVimAgent *) info; - NSData *responseData = [agent handleMessageWithId:msgid data:(__bridge NSData *) (data)]; - if (responseData == NULL) { - return NULL; - } - - return CFDataCreate(kCFAllocatorDefault, responseData.bytes, responseData.length); + [agent handleMessageWithId:msgid data:(__bridge NSData *) (data)]; + return NULL; } } @@ -46,6 +55,25 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD } _uuid = uuid; + + return self; +} + +// -dealloc would have been ideal for this, but if you quit the app, -dealloc does not necessarily get called... +- (void)cleanUp { + CFMessagePortInvalidate(_remoteServerPort); + CFRelease(_remoteServerPort); + + CFMessagePortInvalidate(_localServerPort); + CFRelease(_localServerPort); + + [_localServerThread cancel]; + [_neoVimServerTask interrupt]; + [_neoVimServerTask terminate]; + NSLog(@"terminated..."); +} + +- (void)establishLocalServer { _localServerThread = [[NSThread alloc] initWithTarget:self selector:@selector(runLocalServer) object:nil]; [_localServerThread start]; @@ -55,23 +83,32 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD _neoVimServerTask.arguments = @[ _uuid, [self localServerName], [self remoteServerName] ]; [_neoVimServerTask launch]; - - - return self; } -- (NSString *)neoVimServerExecutablePath { - return [[[NSBundle bundleForClass:[self class]] builtInPlugInsPath] stringByAppendingPathComponent:@"NeoVimServer"]; +- (void)vimInput:(NSString *)string { + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + [self sendMessageWithId:NeoVimAgentMsgIdInput data:data]; } -- (void)dealloc { - CFMessagePortInvalidate(_localServerPort); - CFRelease(_localServerPort); +- (void)vimInputMarkedText:(NSString *_Nonnull)markedText { + NSData *data = [markedText dataUsingEncoding:NSUTF8StringEncoding]; + [self sendMessageWithId:NeoVimAgentMsgIdInputMarked data:data]; +} - [_localServerThread cancel]; +- (void)deleteCharacters:(NSInteger)count { + NSData *data = [[NSData alloc] initWithBytes:&count length:sizeof(NSInteger)]; + [self sendMessageWithId:NeoVimAgentMsgIdDelete data:data]; +} - [_neoVimServerTask terminate]; - NSLog(@"terminated..."); +- (void)forceRedraw { + [self sendMessageWithId:NeoVimAgentMsgIdRedraw data:nil]; +} + +- (void)resizeToWidth:(int)width height:(int)height { + NSLog(@"!!! agent resize: %d:%d", width, height); + int values[] = { width, height }; + NSData *data = [[NSData alloc] initWithBytes:values length:(2 * sizeof(int))]; + [self sendMessageWithId:NeoVimAgentMsgIdResize data:data]; } - (void)runLocalServer { @@ -103,108 +140,34 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD } } -- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data { - NSLog(@"msg received: %d -> %@", msgid, data); - - switch (msgid) { - - case NeoVimServerMsgIdServerReady: - return [self setupNeoVimServer]; - - case NeoVimServerMsgIdNeoVimReady: - return nil; - - case NeoVimServerMsgIdResize: - return nil; - - case NeoVimServerMsgIdClear: - return nil; - - case NeoVimServerMsgIdEolClear: - return nil; - - case NeoVimServerMsgIdSetPosition: - return nil; - - case NeoVimServerMsgIdSetMenu: - return nil; - - case NeoVimServerMsgIdBusyStart: - return nil; - - case NeoVimServerMsgIdBusyStop: - return nil; - - case NeoVimServerMsgIdMouseOn: - return nil; - - case NeoVimServerMsgIdMouseOff: - return nil; - - case NeoVimServerMsgIdModeChange: - return nil; - - case NeoVimServerMsgIdSetScrollRegion: - return nil; - - case NeoVimServerMsgIdScroll: - return nil; - - case NeoVimServerMsgIdSetHighlightAttributes: - return nil; - - case NeoVimServerMsgIdPut: - return nil; - - case NeoVimServerMsgIdPutMarked: - return nil; - - case NeoVimServerMsgIdUnmark: - return nil; - - case NeoVimServerMsgIdBell: - return nil; - - case NeoVimServerMsgIdFlush: - return nil; - - case NeoVimServerMsgIdSetForeground: - return nil; - - case NeoVimServerMsgIdSetBackground: - return nil; - - case NeoVimServerMsgIdSetSpecial: - return nil; - - case NeoVimServerMsgIdSetTitle: - return nil; - - case NeoVimServerMsgIdSetIcon: - return nil; - - case NeoVimServerMsgIdStop: - return nil; - - default: - return nil; - } -} - -- (NSData *)setupNeoVimServer { +- (void)establishNeoVimConnection { _remoteServerPort = CFMessagePortCreateRemote( kCFAllocatorDefault, (__bridge CFStringRef) [self remoteServerName] ); - SInt32 responseCode = CFMessagePortSendRequest( - _remoteServerPort, NeoVimAgendMsgIdAgentReady, nil, qTimeout, qTimeout, NULL, NULL - ); - if (responseCode == kCFMessagePortSuccess) { - NSLog(@"!!!!!!!! SUCCESS!!!!"); + [self sendMessageWithId:NeoVimAgentMsgIdAgentReady data:nil]; +} + +- (void)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data { + if (_remoteServerPort == NULL) { + NSLog(@"WARNING: remote server is null"); + return; } - return nil; + SInt32 responseCode = CFMessagePortSendRequest( + _remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, NULL, NULL + ); + + if (responseCode == kCFMessagePortSuccess) { + return; + } + + NSLog(@"WARNING: (%d:%@) could not be sent!", (int) msgid, data); +} + +- (NSString *)neoVimServerExecutablePath { + return [[[NSBundle bundleForClass:[self class]] builtInPlugInsPath] stringByAppendingPathComponent:@"NeoVimServer"]; } - (NSString *)localServerName { @@ -215,4 +178,155 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD return [NSString stringWithFormat:@"com.qvacua.nvox.neovim-server.%@", _uuid]; } +- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data { +// NSLog(@"msg received: %d -> %@", msgid, data); + + switch (msgid) { + + case NeoVimServerMsgIdServerReady: + [self establishNeoVimConnection]; + return; + + case NeoVimServerMsgIdNeoVimReady: + [_bridge neoVimUiIsReady]; + return; + + case NeoVimServerMsgIdResize: { + int *values = data_to_int_array(data, 2); + if (values == nil) { + return; + } + [_bridge resizeToWidth:values[0] height:values[1]]; + return; + } + + case NeoVimServerMsgIdClear: + [_bridge clear]; + return; + + case NeoVimServerMsgIdEolClear: + [_bridge eolClear]; + return; + + case NeoVimServerMsgIdSetPosition: { + int *values = data_to_int_array(data, 4); + [_bridge gotoPosition:(Position) { .row = values[0], .column = values[1] } + screenCursor:(Position) { .row = values[2], .column = values[3] }]; + return; + } + + case NeoVimServerMsgIdSetMenu: + [_bridge updateMenu]; + return; + + case NeoVimServerMsgIdBusyStart: + [_bridge busyStart]; + return; + + case NeoVimServerMsgIdBusyStop: + [_bridge busyStop]; + return; + + case NeoVimServerMsgIdMouseOn: + [_bridge mouseOn]; + return; + + case NeoVimServerMsgIdMouseOff: + [_bridge mouseOff]; + return; + + case NeoVimServerMsgIdModeChange: { + int *values = data_to_int_array(data, 1); + [_bridge modeChange:values[0]]; + return; + } + + case NeoVimServerMsgIdSetScrollRegion: { + int *values = data_to_int_array(data, 4); + [_bridge setScrollRegionToTop:values[0] bottom:values[1] left:values[2] right:values[3]]; + return; + } + + case NeoVimServerMsgIdScroll: { + int *values = data_to_int_array(data, 1); + NSLog(@"msg rcv scroll: %d", values[0]); + [_bridge scroll:values[0]]; + return; + } + + case NeoVimServerMsgIdSetHighlightAttributes: { + CellAttributes *values = data_to_CellAttributes_array(data, 1); + [_bridge highlightSet:values[0]]; + return; + } + + case NeoVimServerMsgIdPut: { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + [_bridge put:string]; + return; + } + + case NeoVimServerMsgIdPutMarked: { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + [_bridge putMarkedText:string]; + return; + } + + case NeoVimServerMsgIdUnmark: { + int *values = data_to_int_array(data, 2); + [_bridge unmarkRow:values[0] column:values[1]]; + return; + } + + case NeoVimServerMsgIdBell: + [_bridge bell]; + return; + + case NeoVimServerMsgIdVisualBell: + [_bridge visualBell]; + return; + + case NeoVimServerMsgIdFlush: + [_bridge flush]; + return; + + case NeoVimServerMsgIdSetForeground: { + int *values = data_to_int_array(data, 1); + [_bridge updateForeground:values[0]]; + return; + } + + case NeoVimServerMsgIdSetBackground: { + int *values = data_to_int_array(data, 1); + [_bridge updateBackground:values[0]]; + return; + } + + case NeoVimServerMsgIdSetSpecial: { + int *values = data_to_int_array(data, 1); + [_bridge updateSpecial:values[0]]; + return; + } + + case NeoVimServerMsgIdSetTitle: { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + [_bridge setTitle:string]; + return; + } + + case NeoVimServerMsgIdSetIcon: { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + [_bridge setIcon:string]; + return; + } + + case NeoVimServerMsgIdStop: + [_bridge stop]; + return; + + default: + return; + } +} + @end diff --git a/SwiftNeoVim/NeoVimUiBridgeProtocol.h b/SwiftNeoVim/NeoVimUiBridgeProtocol.h index d1dd4aa4..e89bfc9f 100644 --- a/SwiftNeoVim/NeoVimUiBridgeProtocol.h +++ b/SwiftNeoVim/NeoVimUiBridgeProtocol.h @@ -4,6 +4,8 @@ */ @import Foundation; +#import "NeoVimMsgIds.h" + typedef NS_ENUM(NSUInteger, FontTrait) { FontTraitNone = 0, @@ -30,6 +32,8 @@ typedef struct { #define qDefaultBackground 0xFFFFFFFF #define qDefaultSpecial 0xFFFF0000 +NS_ASSUME_NONNULL_BEGIN + @protocol NeoVimUiBridgeProtocol - (void)neoVimUiIsReady; @@ -56,7 +60,7 @@ typedef struct { * 2. NeoVim wants to put the cursor at (row, column). * In case of 1. NeoVim will put in subsequent call. In case of 2. NeoVim seems to flush twice in a row. */ -- (void)gotoPosition:(Position)position screenCursor:(Position)screenCursor bufferCursor:(Position)bufferCursor; +- (void)gotoPosition:(Position)position screenCursor:(Position)screenCursor; - (void)updateMenu; - (void)busyStart; @@ -76,9 +80,9 @@ typedef struct { /** * Draw string at the current cursor which was set by a previous cursorGotoRow:column callback. */ -- (void)put:(NSString *_Nonnull)string; +- (void)put:(NSString *)string; -- (void)putMarkedText:(NSString *_Nonnull)markedText; +- (void)putMarkedText:(NSString *)markedText; - (void)unmarkRow:(int)row column:(int)column; - (void)bell; @@ -100,8 +104,8 @@ typedef struct { */ - (void)updateSpecial:(int)sp; - (void)suspend; -- (void)setTitle:(NSString *_Nonnull)title; -- (void)setIcon:(NSString *_Nonnull)icon; +- (void)setTitle:(NSString *)title; +- (void)setIcon:(NSString *)icon; /** * NeoVim has been stopped. @@ -109,3 +113,5 @@ typedef struct { - (void)stop; @end + +NS_ASSUME_NONNULL_END diff --git a/SwiftNeoVim/NeoVimView.swift b/SwiftNeoVim/NeoVimView.swift index 7aee63a2..88904dd3 100644 --- a/SwiftNeoVim/NeoVimView.swift +++ b/SwiftNeoVim/NeoVimView.swift @@ -72,8 +72,8 @@ public class NeoVimView: NSView { var yOffset = CGFloat(0) private let drawer: TextDrawer - - let xpc: NeoVimXpc + + let agent = NeoVimAgent(uuid: NSUUID().UUIDString) var markedText: String? @@ -91,9 +91,7 @@ public class NeoVimView: NSView { let grid = Grid() - init(frame rect: NSRect = CGRect.zero, xpc: NeoVimXpc) { - self.xpc = xpc - + override init(frame rect: NSRect = CGRect.zero) { self.font = NSFont(name: "Menlo", size: 16)! self.drawer = TextDrawer(font: font) @@ -103,6 +101,15 @@ public class NeoVimView: NSView { self.cellSize = self.drawer.cellSize self.descent = self.drawer.descent self.leading = self.drawer.leading + + // We cannot set bridge in init since self is not available before super.init()... + self.agent.bridge = self + self.agent.establishLocalServer() + } + + // deinit would have been ideal for this, but if you quit the app, deinit does not necessarily get called... + public func cleanUp() { + self.agent.cleanUp() } public func debugInfo() { @@ -150,7 +157,7 @@ public class NeoVimView: NSView { self.xOffset = floor((size.width - self.cellSize.width * CGFloat(discreteSize.width)) / 2) self.yOffset = floor((size.height - self.cellSize.height * CGFloat(discreteSize.height)) / 2) - self.xpc.resizeToWidth(Int32(discreteSize.width), height: Int32(discreteSize.height)) + self.agent.resizeToWidth(Int32(discreteSize.width), height: Int32(discreteSize.height)) } override public func drawRect(dirtyUnionRect: NSRect) { diff --git a/SwiftNeoVim/NeoVimViewEvents.swift b/SwiftNeoVim/NeoVimViewEvents.swift index 6f4b806d..72b92faa 100644 --- a/SwiftNeoVim/NeoVimViewEvents.swift +++ b/SwiftNeoVim/NeoVimViewEvents.swift @@ -25,9 +25,9 @@ extension NeoVimView: NSTextInputClient { let vimModifiers = self.vimModifierFlags(modifierFlags) if vimModifiers.characters.count > 0 { - self.xpc.vimInput(self.vimNamedKeys(vimModifiers + charsIgnoringModifiers)) + self.agent.vimInput(self.vimNamedKeys(vimModifiers + charsIgnoringModifiers)) } else { - self.xpc.vimInput(self.vimPlainString(chars)) + self.agent.vimInput(self.vimPlainString(chars)) } self.keyDownDone = true @@ -38,9 +38,9 @@ extension NeoVimView: NSTextInputClient { switch aString { case let string as String: - self.xpc.vimInput(self.vimPlainString(string)) + self.agent.vimInput(self.vimPlainString(string)) case let attributedString as NSAttributedString: - self.xpc.vimInput(self.vimPlainString(attributedString.string)) + self.agent.vimInput(self.vimPlainString(attributedString.string)) default: break; } @@ -78,7 +78,7 @@ extension NeoVimView: NSTextInputClient { // eg 하 -> hanja popup, cf comment for self.lastMarkedText if replacementRange.length > 0 { - self.xpc.deleteCharacters(replacementRange.length) + self.agent.deleteCharacters(replacementRange.length) } switch aString { @@ -92,7 +92,7 @@ extension NeoVimView: NSTextInputClient { // NSLog("\(#function): \(self.markedText), \(selectedRange), \(replacementRange)") - self.xpc.vimInputMarkedText(self.markedText!) + self.agent.vimInputMarkedText(self.markedText!) self.keyDownDone = true } diff --git a/SwiftNeoVim/NeoVimViewResponder.swift b/SwiftNeoVim/NeoVimViewResponder.swift index 6a2e4e03..377d5f41 100644 --- a/SwiftNeoVim/NeoVimViewResponder.swift +++ b/SwiftNeoVim/NeoVimViewResponder.swift @@ -9,50 +9,50 @@ import Cocoa extension NeoVimView { public override func moveForward(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("C-f")) + self.agent.vimInput(self.vimNamedKeys("C-f")) } public override func moveBackward(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("C-b")) + self.agent.vimInput(self.vimNamedKeys("C-b")) } public override func moveRight(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("Right")) + self.agent.vimInput(self.vimNamedKeys("Right")) } public override func moveLeft(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("Left")) + self.agent.vimInput(self.vimNamedKeys("Left")) } public override func moveUp(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("Up")) + self.agent.vimInput(self.vimNamedKeys("Up")) } public override func moveDown(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("Down")) + self.agent.vimInput(self.vimNamedKeys("Down")) } public override func deleteForward(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("DEL")) + self.agent.vimInput(self.vimNamedKeys("DEL")) } public override func deleteBackward(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("BS")) + self.agent.vimInput(self.vimNamedKeys("BS")) } public override func scrollPageUp(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("PageUp")) + self.agent.vimInput(self.vimNamedKeys("PageUp")) } public override func scrollPageDown(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("PageDown")) + self.agent.vimInput(self.vimNamedKeys("PageDown")) } public override func scrollToBeginningOfDocument(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("Home")) + self.agent.vimInput(self.vimNamedKeys("Home")) } public override func scrollToEndOfDocument(sender: AnyObject?) { - self.xpc.vimInput(self.vimNamedKeys("End")) + self.agent.vimInput(self.vimNamedKeys("End")) } } \ No newline at end of file diff --git a/SwiftNeoVim/NeoVimViewUiBridge.swift b/SwiftNeoVim/NeoVimViewUiBridge.swift index 693b06ff..990b28ad 100644 --- a/SwiftNeoVim/NeoVimViewUiBridge.swift +++ b/SwiftNeoVim/NeoVimViewUiBridge.swift @@ -45,10 +45,10 @@ extension NeoVimView: NeoVimUiBridgeProtocol { } } - public func gotoPosition(position: Position, screenCursor: Position, bufferCursor: Position) { + public func gotoPosition(position: Position, screenCursor: Position) { //if self.inLiveResize { return } DispatchUtils.gui { -// NSLog("\(#function): \(position), \(screenCursor), \(bufferCursor)") +// NSLog("\(#function): \(position), \(screenCursor)") self.setNeedsDisplay(cellPosition: self.grid.screenCursor) // redraw where the cursor was till now self.setNeedsDisplay(screenCursor: screenCursor) // draw the new cursor @@ -88,6 +88,7 @@ extension NeoVimView: NeoVimUiBridgeProtocol { public func scroll(count: Int32) { //if self.inLiveResize { return } DispatchUtils.gui { + NSLog("bridge scroll: \(count)") self.grid.scroll(Int(count)) self.setNeedsDisplay(region: self.grid.region) } diff --git a/SwiftNeoVim/SwiftNeoVim.h b/SwiftNeoVim/SwiftNeoVim.h index 9ca142fd..26620418 100644 --- a/SwiftNeoVim/SwiftNeoVim.h +++ b/SwiftNeoVim/SwiftNeoVim.h @@ -13,6 +13,6 @@ FOUNDATION_EXPORT const unsigned char SwiftNeoVimVersionString[]; #import // TODO: this header should not be public, but we cannot use a bridging header in a framework. -#import #import #import +#import diff --git a/nvox.xcodeproj/project.pbxproj b/nvox.xcodeproj/project.pbxproj index 2e7cebaa..83f57c51 100644 --- a/nvox.xcodeproj/project.pbxproj +++ b/nvox.xcodeproj/project.pbxproj @@ -18,11 +18,8 @@ 4B2A2BFA1D0351810074CE9A /* SwiftNeoVim.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2A2BF91D0351810074CE9A /* SwiftNeoVim.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2A2BFE1D0351810074CE9A /* SwiftNeoVim.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B2A2BF71D0351810074CE9A /* SwiftNeoVim.framework */; }; 4B2A2BFF1D0351810074CE9A /* SwiftNeoVim.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B2A2BF71D0351810074CE9A /* SwiftNeoVim.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 4B2A2C041D03528D0074CE9A /* NeoVimXpc.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BEBA5271CFF3DFF00673FDF /* NeoVimXpc.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4B2A2C091D0352CB0074CE9A /* NeoVimUiBridgeProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2A2C061D0352CB0074CE9A /* NeoVimUiBridgeProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B2A2C0F1D0353E30074CE9A /* NeoVim.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A2C0E1D0353E30074CE9A /* NeoVim.swift */; }; - 4B2A2C251D0359650074CE9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A2C201D0359650074CE9A /* main.m */; }; - 4B2A2C261D0359650074CE9A /* NeoVimXpcImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A2C231D0359650074CE9A /* NeoVimXpcImpl.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4B401B141D0454DC00D99EDC /* PureLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B401B131D0454DC00D99EDC /* PureLayout.framework */; }; 4B401B161D0454E900D99EDC /* PureLayout.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B401B131D0454DC00D99EDC /* PureLayout.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4B401B1A1D046E0600D99EDC /* NeoVimViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B401B191D046E0600D99EDC /* NeoVimViewDelegate.swift */; }; @@ -37,7 +34,6 @@ 4B9A15241D2993DA009F9F67 /* Nimble.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B56F29B1D29926600C1F92E /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4B9A15251D2993DA009F9F67 /* Quick.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B56F29C1D29926600C1F92E /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4B9A15261D2993DF009F9F67 /* SwiftNeoVim.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B2A2BF71D0351810074CE9A /* SwiftNeoVim.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 4BB202DC1D0359B0001D130D /* NeoVimXpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2A2C211D0359650074CE9A /* NeoVimXpc.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BCADE081D11ED12004DAD0F /* CocoaExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCADE071D11ED12004DAD0F /* CocoaExtensions.swift */; }; 4BDCFACB1D31449700F62670 /* NeoVimServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDCFACA1D31449700F62670 /* NeoVimServer.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4BDCFACD1D3145AC00F62670 /* libnvim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFACC1D3145AC00F62670 /* libnvim.a */; }; @@ -48,16 +44,7 @@ 4BDCFAD91D3145E500F62670 /* libmsgpack.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD21D3145E500F62670 /* libmsgpack.a */; }; 4BDCFADA1D3145E500F62670 /* libuv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD31D3145E500F62670 /* libuv.a */; }; 4BDCFADB1D3145E500F62670 /* libvterm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD41D3145E500F62670 /* libvterm.a */; }; - 4BDCFAE11D31475000F62670 /* libjemalloc_pic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFACE1D3145E500F62670 /* libjemalloc_pic.a */; }; - 4BDCFAE21D31475100F62670 /* libjemalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFACF1D3145E500F62670 /* libjemalloc.a */; }; - 4BDCFAE31D31475300F62670 /* libluajit-5.1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD01D3145E500F62670 /* libluajit-5.1.a */; }; - 4BDCFAE41D31475500F62670 /* libluv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD11D3145E500F62670 /* libluv.a */; }; - 4BDCFAE51D31475700F62670 /* libmsgpack.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD21D3145E500F62670 /* libmsgpack.a */; }; - 4BDCFAE61D31475900F62670 /* libuv.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD31D3145E500F62670 /* libuv.a */; }; - 4BDCFAE71D31475B00F62670 /* libvterm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFAD41D3145E500F62670 /* libvterm.a */; }; - 4BDCFAE81D31475D00F62670 /* libnvim.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BDCFACC1D3145AC00F62670 /* libnvim.a */; }; - 4BDCFAEA1D31486E00F62670 /* NeoVimServerMsgIds.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDCFAE91D3147A300F62670 /* NeoVimServerMsgIds.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4BDCFAEB1D3148A100F62670 /* NeoVimServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDCFAC91D31449700F62670 /* NeoVimServer.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4BDCFAEA1D31486E00F62670 /* NeoVimMsgIds.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDCFAE91D3147A300F62670 /* NeoVimMsgIds.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BDCFAED1D315CB800F62670 /* runtime in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA6621D00157A00673FDF /* runtime */; }; 4BDCFAEF1D315CF200F62670 /* NeoVimServer in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B854A1A1D31447C00E08DE1 /* NeoVimServer */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 4BDF641C1D0887C100D47E1D /* TextDrawer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDF641A1D0887C100D47E1D /* TextDrawer.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -68,7 +55,6 @@ 4BEBA50B1CFF374B00673FDF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA50A1CFF374B00673FDF /* Assets.xcassets */; }; 4BEBA50E1CFF374B00673FDF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA50C1CFF374B00673FDF /* MainMenu.xib */; }; 4BEBA5191CFF374B00673FDF /* nvoxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBA5181CFF374B00673FDF /* nvoxTests.swift */; }; - 4BEBA6631D00157A00673FDF /* runtime in Resources */ = {isa = PBXBuildFile; fileRef = 4BEBA6621D00157A00673FDF /* runtime */; }; 4BEE79121D16D0AC0012EDAA /* NeoVimViewUiBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE79111D16D0AC0012EDAA /* NeoVimViewUiBridge.swift */; }; 4BEE79151D16D2100012EDAA /* DispatchUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE79141D16D2100012EDAA /* DispatchUtils.swift */; }; 4BEE79171D16D3800012EDAA /* CellAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE79161D16D3800012EDAA /* CellAttributes.swift */; }; @@ -91,13 +77,6 @@ remoteGlobalIDString = 4B2A2BF61D0351810074CE9A; remoteInfo = SwiftNeoVim; }; - 4B854A041D3137B000E08DE1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4BEBA4FD1CFF374B00673FDF /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4BEBA5261CFF3DFF00673FDF; - remoteInfo = NeoVimXpc; - }; 4BDCFADD1D31465100F62670 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4BEBA4FD1CFF374B00673FDF /* Project object */; @@ -135,7 +114,6 @@ dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; dstSubfolderSpec = 16; files = ( - 4B2A2C041D03528D0074CE9A /* NeoVimXpc.xpc in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -190,8 +168,6 @@ 4B2A2C0E1D0353E30074CE9A /* NeoVim.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeoVim.swift; sourceTree = ""; }; 4B2A2C1F1D0359650074CE9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4B2A2C201D0359650074CE9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 4B2A2C211D0359650074CE9A /* NeoVimXpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeoVimXpc.h; sourceTree = ""; }; - 4B2A2C221D0359650074CE9A /* NeoVimXpcImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeoVimXpcImpl.h; sourceTree = ""; }; 4B2A2C231D0359650074CE9A /* NeoVimXpcImpl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NeoVimXpcImpl.m; sourceTree = ""; }; 4B401B131D0454DC00D99EDC /* PureLayout.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PureLayout.framework; path = Carthage/Build/Mac/PureLayout.framework; sourceTree = SOURCE_ROOT; }; 4B401B191D046E0600D99EDC /* NeoVimViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeoVimViewDelegate.swift; sourceTree = ""; }; @@ -206,6 +182,7 @@ 4B854A1A1D31447C00E08DE1 /* NeoVimServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = NeoVimServer; sourceTree = BUILT_PRODUCTS_DIR; }; 4B854A1C1D31447C00E08DE1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 4BCADE071D11ED12004DAD0F /* CocoaExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CocoaExtensions.swift; sourceTree = ""; }; + 4BCF638F1D323CFD00F15CE4 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = neovim/src/nvim; sourceTree = SOURCE_ROOT; }; 4BDCFAC91D31449700F62670 /* NeoVimServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeoVimServer.h; sourceTree = ""; }; 4BDCFACA1D31449700F62670 /* NeoVimServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NeoVimServer.m; sourceTree = ""; }; 4BDCFACC1D3145AC00F62670 /* libnvim.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libnvim.a; path = neovim/build/lib/libnvim.a; sourceTree = SOURCE_ROOT; }; @@ -216,8 +193,7 @@ 4BDCFAD21D3145E500F62670 /* libmsgpack.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmsgpack.a; path = neovim/.deps/usr/lib/libmsgpack.a; sourceTree = SOURCE_ROOT; }; 4BDCFAD31D3145E500F62670 /* libuv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libuv.a; path = neovim/.deps/usr/lib/libuv.a; sourceTree = SOURCE_ROOT; }; 4BDCFAD41D3145E500F62670 /* libvterm.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvterm.a; path = neovim/.deps/usr/lib/libvterm.a; sourceTree = SOURCE_ROOT; }; - 4BDCFAE01D31471500F62670 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = neovim/src/nvim; sourceTree = SOURCE_ROOT; }; - 4BDCFAE91D3147A300F62670 /* NeoVimServerMsgIds.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NeoVimServerMsgIds.h; sourceTree = ""; }; + 4BDCFAE91D3147A300F62670 /* NeoVimMsgIds.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NeoVimMsgIds.h; sourceTree = ""; }; 4BDF641A1D0887C100D47E1D /* TextDrawer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextDrawer.h; sourceTree = ""; }; 4BDF641B1D0887C100D47E1D /* TextDrawer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextDrawer.m; sourceTree = ""; }; 4BDF64221D08CAB000D47E1D /* MMCoreTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMCoreTextView.h; sourceTree = ""; }; @@ -230,7 +206,6 @@ 4BEBA5141CFF374B00673FDF /* nvoxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = nvoxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4BEBA5181CFF374B00673FDF /* nvoxTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = nvoxTests.swift; sourceTree = ""; }; 4BEBA51A1CFF374B00673FDF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 4BEBA5271CFF3DFF00673FDF /* NeoVimXpc.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = NeoVimXpc.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; 4BEBA6621D00157A00673FDF /* runtime */ = {isa = PBXFileReference; lastKnownFileType = folder; name = runtime; path = neovim/runtime; sourceTree = SOURCE_ROOT; }; 4BEE79111D16D0AC0012EDAA /* NeoVimViewUiBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeoVimViewUiBridge.swift; sourceTree = ""; }; 4BEE79141D16D2100012EDAA /* DispatchUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatchUtils.swift; sourceTree = ""; }; @@ -290,21 +265,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4BEBA5241CFF3DFF00673FDF /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4BDCFAE31D31475300F62670 /* libluajit-5.1.a in Frameworks */, - 4BDCFAE51D31475700F62670 /* libmsgpack.a in Frameworks */, - 4BDCFAE71D31475B00F62670 /* libvterm.a in Frameworks */, - 4BDCFAE61D31475900F62670 /* libuv.a in Frameworks */, - 4BDCFAE11D31475000F62670 /* libjemalloc_pic.a in Frameworks */, - 4BDCFAE81D31475D00F62670 /* libnvim.a in Frameworks */, - 4BDCFAE41D31475500F62670 /* libluv.a in Frameworks */, - 4BDCFAE21D31475100F62670 /* libjemalloc.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -364,9 +324,9 @@ 4B854A1B1D31447C00E08DE1 /* NeoVimServer */ = { isa = PBXGroup; children = ( + 4BCF638F1D323CFD00F15CE4 /* nvim */, 4BDCFADC1D3145EA00F62670 /* lib */, - 4BDCFAE01D31471500F62670 /* nvim */, - 4BDCFAE91D3147A300F62670 /* NeoVimServerMsgIds.h */, + 4BDCFAE91D3147A300F62670 /* NeoVimMsgIds.h */, 4BDCFAC91D31449700F62670 /* NeoVimServer.h */, 4BDCFACA1D31449700F62670 /* NeoVimServer.m */, 4B854A1C1D31447C00E08DE1 /* main.m */, @@ -411,7 +371,6 @@ children = ( 4BEBA5051CFF374B00673FDF /* nvox.app */, 4BEBA5141CFF374B00673FDF /* nvoxTests.xctest */, - 4BEBA5271CFF3DFF00673FDF /* NeoVimXpc.xpc */, 4B2A2BF71D0351810074CE9A /* SwiftNeoVim.framework */, 4B56F2901D29903F00C1F92E /* SwiftNeoVimTests.xctest */, 4B854A1A1D31447C00E08DE1 /* NeoVimServer */, @@ -443,8 +402,6 @@ 4BEBA5281CFF3DFF00673FDF /* NeoVimXpc */ = { isa = PBXGroup; children = ( - 4B2A2C211D0359650074CE9A /* NeoVimXpc.h */, - 4B2A2C221D0359650074CE9A /* NeoVimXpcImpl.h */, 4B2A2C231D0359650074CE9A /* NeoVimXpcImpl.m */, 4B2A2C201D0359650074CE9A /* main.m */, 4B2A2C1F1D0359650074CE9A /* Info.plist */, @@ -477,11 +434,9 @@ 4B2A2C091D0352CB0074CE9A /* NeoVimUiBridgeProtocol.h in Headers */, 4B570DC21D303CAF006EDC21 /* NeoVimAgent.h in Headers */, 4BDF641C1D0887C100D47E1D /* TextDrawer.h in Headers */, + 4BDCFAEA1D31486E00F62670 /* NeoVimMsgIds.h in Headers */, 4B2A2BFA1D0351810074CE9A /* SwiftNeoVim.h in Headers */, - 4BB202DC1D0359B0001D130D /* NeoVimXpc.h in Headers */, - 4BDCFAEB1D3148A100F62670 /* NeoVimServer.h in Headers */, 4BDF64241D08CAB000D47E1D /* MMCoreTextView.h in Headers */, - 4BDCFAEA1D31486E00F62670 /* NeoVimServerMsgIds.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -503,7 +458,6 @@ ); dependencies = ( 4BDCFADE1D31465100F62670 /* PBXTargetDependency */, - 4B854A051D3137B000E08DE1 /* PBXTargetDependency */, ); name = SwiftNeoVim; productName = SwiftNeoVim; @@ -533,6 +487,7 @@ isa = PBXNativeTarget; buildConfigurationList = 4B854A1E1D31447C00E08DE1 /* Build configuration list for PBXNativeTarget "NeoVimServer" */; buildPhases = ( + 4BBA71F11D319E0900E16612 /* ShellScript */, 4B854A161D31447C00E08DE1 /* Sources */, 4B854A171D31447C00E08DE1 /* Frameworks */, 4B854A181D31447C00E08DE1 /* CopyFiles */, @@ -583,24 +538,6 @@ productReference = 4BEBA5141CFF374B00673FDF /* nvoxTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 4BEBA5261CFF3DFF00673FDF /* NeoVimXpc */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4BEBA5331CFF3DFF00673FDF /* Build configuration list for PBXNativeTarget "NeoVimXpc" */; - buildPhases = ( - 4B2A2BBA1D00C7200074CE9A /* ShellScript */, - 4BEBA5231CFF3DFF00673FDF /* Sources */, - 4BEBA5241CFF3DFF00673FDF /* Frameworks */, - 4BEBA5251CFF3DFF00673FDF /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = NeoVimXpc; - productName = NeoVimXpc; - productReference = 4BEBA5271CFF3DFF00673FDF /* NeoVimXpc.xpc */; - productType = "com.apple.product-type.xpc-service"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -627,9 +564,6 @@ CreatedOnToolsVersion = 7.3.1; TestTargetID = 4BEBA5041CFF374B00673FDF; }; - 4BEBA5261CFF3DFF00673FDF = { - CreatedOnToolsVersion = 7.3.1; - }; }; }; buildConfigurationList = 4BEBA5001CFF374B00673FDF /* Build configuration list for PBXProject "nvox" */; @@ -647,7 +581,6 @@ targets = ( 4BEBA5041CFF374B00673FDF /* nvox */, 4BEBA5131CFF374B00673FDF /* nvoxTests */, - 4BEBA5261CFF3DFF00673FDF /* NeoVimXpc */, 4B2A2BF61D0351810074CE9A /* SwiftNeoVim */, 4B56F28F1D29903F00C1F92E /* SwiftNeoVimTests */, 4B854A191D31447C00E08DE1 /* NeoVimServer */, @@ -687,18 +620,10 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4BEBA5251CFF3DFF00673FDF /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4BEBA6631D00157A00673FDF /* runtime in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 4B2A2BBA1D00C7200074CE9A /* ShellScript */ = { + 4BBA71F11D319E0900E16612 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -770,15 +695,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4BEBA5231CFF3DFF00673FDF /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4B2A2C251D0359650074CE9A /* main.m in Sources */, - 4B2A2C261D0359650074CE9A /* NeoVimXpcImpl.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -792,11 +708,6 @@ target = 4B2A2BF61D0351810074CE9A /* SwiftNeoVim */; targetProxy = 4B56F2961D29903F00C1F92E /* PBXContainerItemProxy */; }; - 4B854A051D3137B000E08DE1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4BEBA5261CFF3DFF00673FDF /* NeoVimXpc */; - targetProxy = 4B854A041D3137B000E08DE1 /* PBXContainerItemProxy */; - }; 4BDCFADE1D31465100F62670 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B854A191D31447C00E08DE1 /* NeoVimServer */; @@ -927,6 +838,10 @@ 4B854A201D31447C00E08DE1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "INCLUDE_GENERATED_DECLARATIONS=1", + "CUSTOM_UI=1", + ); HEADER_SEARCH_PATHS = ( "$(PROJECT_DIR)/neovim/build/include", "$(PROJECT_DIR)/neovim/src", @@ -1088,66 +1003,6 @@ }; name = Release; }; - 4BEBA5341CFF3DFF00673FDF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - "INCLUDE_GENERATED_DECLARATIONS=1", - "CUSTOM_UI=1", - ); - HEADER_SEARCH_PATHS = ( - neovim/build/include, - neovim/src, - neovim/.deps/usr/include, - ); - INFOPLIST_FILE = "$(SRCROOT)/NeoVimXpc/Info.plist"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/neovim/build/lib", - "$(PROJECT_DIR)/neovim/.deps/usr/lib", - ); - OTHER_LDFLAGS = ( - /usr/local/opt/gettext/lib/libintl.a, - "-liconv", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.nvox.xpc; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 4BEBA5351CFF3DFF00673FDF /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "INCLUDE_GENERATED_DECLARATIONS=1", - "CUSTOM_UI=1", - ); - HEADER_SEARCH_PATHS = ( - neovim/build/include, - neovim/src, - neovim/.deps/usr/include, - ); - INFOPLIST_FILE = "$(SRCROOT)/NeoVimXpc/Info.plist"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/neovim/build/lib", - "$(PROJECT_DIR)/neovim/.deps/usr/lib", - ); - OTHER_LDFLAGS = ( - /usr/local/opt/gettext/lib/libintl.a, - "-liconv", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.qvacua.nvox.xpc; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1205,15 +1060,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4BEBA5331CFF3DFF00673FDF /* Build configuration list for PBXNativeTarget "NeoVimXpc" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4BEBA5341CFF3DFF00673FDF /* Debug */, - 4BEBA5351CFF3DFF00673FDF /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 4BEBA4FD1CFF374B00673FDF /* Project object */; diff --git a/nvox/AppDelegate.swift b/nvox/AppDelegate.swift index 5b3c1fbc..6c99d3d7 100644 --- a/nvox/AppDelegate.swift +++ b/nvox/AppDelegate.swift @@ -12,6 +12,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NeoVimViewDelegate { @IBOutlet weak var window: NSWindow! var neoVim: NeoVim! + let view = NeoVimView(forAutoLayout: ()) @IBAction func debugSomething(sender: AnyObject!) { // let font = NSFont(name: "Courier", size: 14)! @@ -23,7 +24,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NeoVimViewDelegate { // self.window.contentView?.addSubview(testView) // self.window.makeFirstResponder(testView) - self.neoVim = NeoVim() + self.window.contentView?.addSubview(self.view) + self.view.autoPinEdgesToSuperviewEdges() + self.window.makeFirstResponder(self.view) + } + + func applicationWillTerminate(notification: NSNotification) { + self.view.cleanUp() } func setTitle(title: String) {