1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-25 14:52:19 +03:00

Migrate to swift bridge

This commit is contained in:
Tae Won Ha 2018-01-21 14:16:07 +01:00
parent c72d04ebc8
commit afeb94a2ea
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
19 changed files with 862 additions and 189 deletions

View File

@ -5,7 +5,7 @@
@import Foundation; @import Foundation;
#import "NeoVimMsgIds.h" #import "SharedTypes.h"
@interface NvimServer : NSObject @interface NvimServer : NSObject

View File

@ -79,10 +79,6 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
case NeoVimAgentMsgIdFocusGained: return data_sync(data, outputCondition, neovim_focus_gained); case NeoVimAgentMsgIdFocusGained: return data_sync(data, outputCondition, neovim_focus_gained);
#ifdef DEBUG
case NeoVimAgentDebug1: return data_sync(data, outputCondition, neovim_debug1);
#endif
default: return NULL; default: return NULL;
} }

View File

@ -630,7 +630,7 @@ void custom_ui_autocmds_groups(
send_dirty_status(); send_dirty_status();
} }
NSUInteger eventCode = event; NSInteger eventCode = (NSInteger) event;
NSMutableData *data; NSMutableData *data;
if (buf == NULL) { if (buf == NULL) {
@ -777,11 +777,11 @@ void neovim_escaped_filenames(void **argv) {
void neovim_resize(void **argv) { void neovim_resize(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_and_write_data_sync(argv, ^NSData *(NSData *data) {
const int *values = data.bytes; const NSInteger *values = data.bytes;
int width = values[0]; NSInteger width = values[0];
int height = values[1]; NSInteger height = values[1];
set_ui_size(_server_ui_data->bridge, width, height); set_ui_size(_server_ui_data->bridge, (int) width, (int) height);
ui_refresh(); ui_refresh();
return nil; return nil;

View File

@ -8,19 +8,18 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */; }; 1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */; };
1929B6C618D440AC4D3FFE3A /* ThreadWithBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 1929BC4314B428D5011D100A /* ThreadWithBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */; }; 1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */; };
1929BA62EF7586682CF68E8C /* ThreadWithBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 1929B4A84091D5BAA0493B44 /* ThreadWithBlock.m */; };
1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B52174EC68D2974B5BAE /* UiBridge.swift */; };
4B177886201220F300E32FF0 /* SharedTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 1929B4F32708E99C40A57020 /* SharedTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B177886201220F300E32FF0 /* SharedTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 1929B4F32708E99C40A57020 /* SharedTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B2016EE1FD45EED0038528A /* NvimAutoCommandEvent.generated.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2016EC1FD45EED0038528A /* NvimAutoCommandEvent.generated.m */; };
4B2016EF1FD45EED0038528A /* NvimAutoCommandEvent.generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2016ED1FD45EED0038528A /* NvimAutoCommandEvent.generated.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B8662E81FDC3F9F007F490D /* vimr.vim in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B8662E41FDC3D4F007F490D /* vimr.vim */; }; 4B8662E81FDC3F9F007F490D /* vimr.vim in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B8662E41FDC3D4F007F490D /* vimr.vim */; };
4B90F02D1FD2AFAE008A39E0 /* NvimUiBridgeProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90F00F1FD2AFAC008A39E0 /* NvimUiBridgeProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B90F02E1FD2AFAE008A39E0 /* NvimView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0101FD2AFAC008A39E0 /* NvimView.swift */; }; 4B90F02E1FD2AFAE008A39E0 /* NvimView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0101FD2AFAC008A39E0 /* NvimView.swift */; };
4B90F02F1FD2AFAE008A39E0 /* NvimView+Resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0111FD2AFAC008A39E0 /* NvimView+Resize.swift */; }; 4B90F02F1FD2AFAE008A39E0 /* NvimView+Resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0111FD2AFAC008A39E0 /* NvimView+Resize.swift */; };
4B90F0301FD2AFAE008A39E0 /* KeyUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0121FD2AFAC008A39E0 /* KeyUtils.swift */; }; 4B90F0301FD2AFAE008A39E0 /* KeyUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0121FD2AFAC008A39E0 /* KeyUtils.swift */; };
4B90F0321FD2AFAE008A39E0 /* NvimView+Dragging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0141FD2AFAC008A39E0 /* NvimView+Dragging.swift */; }; 4B90F0321FD2AFAE008A39E0 /* NvimView+Dragging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0141FD2AFAC008A39E0 /* NvimView+Dragging.swift */; };
4B90F0341FD2AFAE008A39E0 /* CocoaExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0161FD2AFAC008A39E0 /* CocoaExtensions.swift */; }; 4B90F0341FD2AFAE008A39E0 /* CocoaExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0161FD2AFAC008A39E0 /* CocoaExtensions.swift */; };
4B90F0351FD2AFAE008A39E0 /* NvimView+Mouse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0171FD2AFAC008A39E0 /* NvimView+Mouse.swift */; }; 4B90F0351FD2AFAE008A39E0 /* NvimView+Mouse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0171FD2AFAC008A39E0 /* NvimView+Mouse.swift */; };
4B90F0371FD2AFAE008A39E0 /* UiClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90F0191FD2AFAC008A39E0 /* UiClient.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B90F0381FD2AFAE008A39E0 /* ColorUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F01A1FD2AFAC008A39E0 /* ColorUtils.swift */; }; 4B90F0381FD2AFAE008A39E0 /* ColorUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F01A1FD2AFAC008A39E0 /* ColorUtils.swift */; };
4B90F0391FD2AFAE008A39E0 /* NvimView+Api.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F01B1FD2AFAC008A39E0 /* NvimView+Api.swift */; }; 4B90F0391FD2AFAE008A39E0 /* NvimView+Api.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F01B1FD2AFAC008A39E0 /* NvimView+Api.swift */; };
4B90F03A1FD2AFAE008A39E0 /* NvimView+Key.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F01C1FD2AFAC008A39E0 /* NvimView+Key.swift */; }; 4B90F03A1FD2AFAE008A39E0 /* NvimView+Key.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F01C1FD2AFAC008A39E0 /* NvimView+Key.swift */; };
@ -36,7 +35,6 @@
4B90F0451FD2AFAE008A39E0 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0271FD2AFAD008A39E0 /* Logger.swift */; }; 4B90F0451FD2AFAE008A39E0 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0271FD2AFAD008A39E0 /* Logger.swift */; };
4B90F0461FD2AFAE008A39E0 /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0281FD2AFAD008A39E0 /* Grid.swift */; }; 4B90F0461FD2AFAE008A39E0 /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0281FD2AFAD008A39E0 /* Grid.swift */; };
4B90F0491FD2AFAE008A39E0 /* CellAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F02B1FD2AFAD008A39E0 /* CellAttributes.swift */; }; 4B90F0491FD2AFAE008A39E0 /* CellAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F02B1FD2AFAD008A39E0 /* CellAttributes.swift */; };
4B90F04A1FD2AFAE008A39E0 /* UiClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F02C1FD2AFAE008A39E0 /* UiClient.m */; };
4B90F0521FD2AFD3008A39E0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0511FD2AFD3008A39E0 /* main.m */; }; 4B90F0521FD2AFD3008A39E0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0511FD2AFD3008A39E0 /* main.m */; };
4B90F0661FD2AFF7008A39E0 /* server_ui.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0561FD2AFF7008A39E0 /* server_ui.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 4B90F0661FD2AFF7008A39E0 /* server_ui.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0561FD2AFF7008A39E0 /* server_ui.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
4B90F0681FD2AFF7008A39E0 /* CocoaCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */; }; 4B90F0681FD2AFF7008A39E0 /* CocoaCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */; };
@ -44,9 +42,8 @@
4B90F06B1FD2AFF7008A39E0 /* NvimServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */; }; 4B90F06B1FD2AFF7008A39E0 /* NvimServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */; };
4B90F0701FD2B9F1008A39E0 /* MsgPackRpc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B90F0721FD2B9F1008A39E0 /* MsgPackRpc.framework */; }; 4B90F0701FD2B9F1008A39E0 /* MsgPackRpc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B90F0721FD2B9F1008A39E0 /* MsgPackRpc.framework */; };
4B90F0711FD2B9F1008A39E0 /* NvimMsgPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B90F0731FD2B9F1008A39E0 /* NvimMsgPack.framework */; }; 4B90F0711FD2B9F1008A39E0 /* NvimMsgPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B90F0731FD2B9F1008A39E0 /* NvimMsgPack.framework */; };
4B90F0781FD2BA7B008A39E0 /* Logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90F0771FD2BA7B008A39E0 /* Logger.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B90F07B1FD30650008A39E0 /* NeoVimMsgIds.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90F0591FD2AFF7008A39E0 /* NeoVimMsgIds.h */; settings = {ATTRIBUTES = (Private, ); }; };
4BC5B0431FE551DF0071D64F /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC5B0421FE551DF0071D64F /* RxSwift.framework */; }; 4BC5B0431FE551DF0071D64F /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC5B0421FE551DF0071D64F /* RxSwift.framework */; };
4BD874302014C2600039888E /* NvimAutoCommandEvent.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BD8742F2014C25F0039888E /* NvimAutoCommandEvent.generated.swift */; };
4BE45C081FD2D4E3005C0A95 /* NvimServer in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B90F04F1FD2AFD3008A39E0 /* NvimServer */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 4BE45C081FD2D4E3005C0A95 /* NvimServer in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B90F04F1FD2AFD3008A39E0 /* NvimServer */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
4BE45C0C1FD2DA49005C0A95 /* runtime in Resources */ = {isa = PBXBuildFile; fileRef = 4BE45C0B1FD2DA49005C0A95 /* runtime */; }; 4BE45C0C1FD2DA49005C0A95 /* runtime in Resources */ = {isa = PBXBuildFile; fileRef = 4BE45C0B1FD2DA49005C0A95 /* runtime */; };
4BF18C5D1FD2EEE400DF95D1 /* NvimView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF18C5C1FD2EEE400DF95D1 /* NvimView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BF18C5D1FD2EEE400DF95D1 /* NvimView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF18C5C1FD2EEE400DF95D1 /* NvimView.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -96,21 +93,20 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimViewObjects.swift; sourceTree = "<group>"; }; 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimViewObjects.swift; sourceTree = "<group>"; };
1929B4A84091D5BAA0493B44 /* ThreadWithBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadWithBlock.m; sourceTree = "<group>"; };
1929B4F32708E99C40A57020 /* SharedTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTypes.h; sourceTree = "<group>"; }; 1929B4F32708E99C40A57020 /* SharedTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTypes.h; sourceTree = "<group>"; };
1929B52174EC68D2974B5BAE /* UiBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UiBridge.swift; sourceTree = "<group>"; };
1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimApiExtension.swift; sourceTree = "<group>"; }; 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimApiExtension.swift; sourceTree = "<group>"; };
4B2016EC1FD45EED0038528A /* NvimAutoCommandEvent.generated.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NvimAutoCommandEvent.generated.m; sourceTree = "<group>"; }; 1929BC4314B428D5011D100A /* ThreadWithBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadWithBlock.h; sourceTree = "<group>"; };
4B2016ED1FD45EED0038528A /* NvimAutoCommandEvent.generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NvimAutoCommandEvent.generated.h; sourceTree = "<group>"; };
4B8662E41FDC3D4F007F490D /* vimr.vim */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vimr.vim; sourceTree = "<group>"; }; 4B8662E41FDC3D4F007F490D /* vimr.vim */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vimr.vim; sourceTree = "<group>"; };
4B90F0041FD2AF59008A39E0 /* NvimView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NvimView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B90F0041FD2AF59008A39E0 /* NvimView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NvimView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4B90F0081FD2AF59008A39E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4B90F0081FD2AF59008A39E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4B90F00F1FD2AFAC008A39E0 /* NvimUiBridgeProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NvimUiBridgeProtocol.h; sourceTree = "<group>"; };
4B90F0101FD2AFAC008A39E0 /* NvimView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimView.swift; sourceTree = "<group>"; }; 4B90F0101FD2AFAC008A39E0 /* NvimView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimView.swift; sourceTree = "<group>"; };
4B90F0111FD2AFAC008A39E0 /* NvimView+Resize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Resize.swift"; sourceTree = "<group>"; }; 4B90F0111FD2AFAC008A39E0 /* NvimView+Resize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Resize.swift"; sourceTree = "<group>"; };
4B90F0121FD2AFAC008A39E0 /* KeyUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyUtils.swift; sourceTree = "<group>"; }; 4B90F0121FD2AFAC008A39E0 /* KeyUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyUtils.swift; sourceTree = "<group>"; };
4B90F0141FD2AFAC008A39E0 /* NvimView+Dragging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Dragging.swift"; sourceTree = "<group>"; }; 4B90F0141FD2AFAC008A39E0 /* NvimView+Dragging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Dragging.swift"; sourceTree = "<group>"; };
4B90F0161FD2AFAC008A39E0 /* CocoaExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CocoaExtensions.swift; sourceTree = "<group>"; }; 4B90F0161FD2AFAC008A39E0 /* CocoaExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CocoaExtensions.swift; sourceTree = "<group>"; };
4B90F0171FD2AFAC008A39E0 /* NvimView+Mouse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Mouse.swift"; sourceTree = "<group>"; }; 4B90F0171FD2AFAC008A39E0 /* NvimView+Mouse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Mouse.swift"; sourceTree = "<group>"; };
4B90F0191FD2AFAC008A39E0 /* UiClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UiClient.h; sourceTree = "<group>"; };
4B90F01A1FD2AFAC008A39E0 /* ColorUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorUtils.swift; sourceTree = "<group>"; }; 4B90F01A1FD2AFAC008A39E0 /* ColorUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorUtils.swift; sourceTree = "<group>"; };
4B90F01B1FD2AFAC008A39E0 /* NvimView+Api.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Api.swift"; sourceTree = "<group>"; }; 4B90F01B1FD2AFAC008A39E0 /* NvimView+Api.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Api.swift"; sourceTree = "<group>"; };
4B90F01C1FD2AFAC008A39E0 /* NvimView+Key.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Key.swift"; sourceTree = "<group>"; }; 4B90F01C1FD2AFAC008A39E0 /* NvimView+Key.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NvimView+Key.swift"; sourceTree = "<group>"; };
@ -127,12 +123,10 @@
4B90F0271FD2AFAD008A39E0 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; }; 4B90F0271FD2AFAD008A39E0 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
4B90F0281FD2AFAD008A39E0 /* Grid.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Grid.swift; sourceTree = "<group>"; }; 4B90F0281FD2AFAD008A39E0 /* Grid.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Grid.swift; sourceTree = "<group>"; };
4B90F02B1FD2AFAD008A39E0 /* CellAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellAttributes.swift; sourceTree = "<group>"; }; 4B90F02B1FD2AFAD008A39E0 /* CellAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellAttributes.swift; sourceTree = "<group>"; };
4B90F02C1FD2AFAE008A39E0 /* UiClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UiClient.m; sourceTree = "<group>"; };
4B90F04F1FD2AFD3008A39E0 /* NvimServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = NvimServer; sourceTree = BUILT_PRODUCTS_DIR; }; 4B90F04F1FD2AFD3008A39E0 /* NvimServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = NvimServer; sourceTree = BUILT_PRODUCTS_DIR; };
4B90F0511FD2AFD3008A39E0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 4B90F0511FD2AFD3008A39E0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
4B90F0561FD2AFF7008A39E0 /* server_ui.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = server_ui.m; sourceTree = "<group>"; }; 4B90F0561FD2AFF7008A39E0 /* server_ui.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = server_ui.m; sourceTree = "<group>"; };
4B90F0571FD2AFF7008A39E0 /* CocoaCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CocoaCategories.h; sourceTree = "<group>"; }; 4B90F0571FD2AFF7008A39E0 /* CocoaCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CocoaCategories.h; sourceTree = "<group>"; };
4B90F0591FD2AFF7008A39E0 /* NeoVimMsgIds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeoVimMsgIds.h; sourceTree = "<group>"; };
4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaCategories.m; sourceTree = "<group>"; }; 4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CocoaCategories.m; sourceTree = "<group>"; };
4B90F05B1FD2AFF7008A39E0 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; }; 4B90F05B1FD2AFF7008A39E0 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
4B90F05C1FD2AFF7008A39E0 /* DataWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataWrapper.h; sourceTree = "<group>"; }; 4B90F05C1FD2AFF7008A39E0 /* DataWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataWrapper.h; sourceTree = "<group>"; };
@ -142,8 +136,8 @@
4B90F0641FD2AFF7008A39E0 /* NvimServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NvimServer.m; sourceTree = "<group>"; }; 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NvimServer.m; sourceTree = "<group>"; };
4B90F0721FD2B9F1008A39E0 /* MsgPackRpc.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MsgPackRpc.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B90F0721FD2B9F1008A39E0 /* MsgPackRpc.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MsgPackRpc.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4B90F0731FD2B9F1008A39E0 /* NvimMsgPack.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = NvimMsgPack.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B90F0731FD2B9F1008A39E0 /* NvimMsgPack.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = NvimMsgPack.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4B90F0771FD2BA7B008A39E0 /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logger.h; path = NvimView/Logger.h; sourceTree = SOURCE_ROOT; };
4BC5B0421FE551DF0071D64F /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = ../Carthage/Build/Mac/RxSwift.framework; sourceTree = "<group>"; }; 4BC5B0421FE551DF0071D64F /* RxSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxSwift.framework; path = ../Carthage/Build/Mac/RxSwift.framework; sourceTree = "<group>"; };
4BD8742F2014C25F0039888E /* NvimAutoCommandEvent.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimAutoCommandEvent.generated.swift; sourceTree = "<group>"; };
4BE45C0B1FD2DA49005C0A95 /* runtime */ = {isa = PBXFileReference; lastKnownFileType = folder; name = runtime; path = neovim/runtime; sourceTree = "<group>"; }; 4BE45C0B1FD2DA49005C0A95 /* runtime */ = {isa = PBXFileReference; lastKnownFileType = folder; name = runtime; path = neovim/runtime; sourceTree = "<group>"; };
4BF18C5A1FD2E72D00DF95D1 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = neovim/src/nvim; sourceTree = "<group>"; }; 4BF18C5A1FD2E72D00DF95D1 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = neovim/src/nvim; sourceTree = "<group>"; };
4BF18C5B1FD2E74800DF95D1 /* auto */ = {isa = PBXFileReference; lastKnownFileType = folder; name = auto; path = neovim/build/src/nvim/auto; sourceTree = "<group>"; }; 4BF18C5B1FD2E74800DF95D1 /* auto */ = {isa = PBXFileReference; lastKnownFileType = folder; name = auto; path = neovim/build/src/nvim/auto; sourceTree = "<group>"; };
@ -177,7 +171,6 @@
4BF18C5B1FD2E74800DF95D1 /* auto */, 4BF18C5B1FD2E74800DF95D1 /* auto */,
4BF18C5A1FD2E72D00DF95D1 /* nvim */, 4BF18C5A1FD2E72D00DF95D1 /* nvim */,
4BE45C0B1FD2DA49005C0A95 /* runtime */, 4BE45C0B1FD2DA49005C0A95 /* runtime */,
4B90F0591FD2AFF7008A39E0 /* NeoVimMsgIds.h */,
4B90F0061FD2AF59008A39E0 /* NvimView */, 4B90F0061FD2AF59008A39E0 /* NvimView */,
4B90F0501FD2AFD3008A39E0 /* NvimServer */, 4B90F0501FD2AFD3008A39E0 /* NvimServer */,
4B90F0051FD2AF59008A39E0 /* Products */, 4B90F0051FD2AF59008A39E0 /* Products */,
@ -210,12 +203,8 @@
4B90F0271FD2AFAD008A39E0 /* Logger.swift */, 4B90F0271FD2AFAD008A39E0 /* Logger.swift */,
4B90F0261FD2AFAD008A39E0 /* MMCoreTextView.h */, 4B90F0261FD2AFAD008A39E0 /* MMCoreTextView.h */,
4B90F0201FD2AFAD008A39E0 /* MMCoreTextView.m */, 4B90F0201FD2AFAD008A39E0 /* MMCoreTextView.m */,
4B90F0191FD2AFAC008A39E0 /* UiClient.h */, 4BD8742F2014C25F0039888E /* NvimAutoCommandEvent.generated.swift */,
4B90F02C1FD2AFAE008A39E0 /* UiClient.m */,
4B2016ED1FD45EED0038528A /* NvimAutoCommandEvent.generated.h */,
4B2016EC1FD45EED0038528A /* NvimAutoCommandEvent.generated.m */,
4B90F01D1FD2AFAC008A39E0 /* NvimObjectsExtensions.swift */, 4B90F01D1FD2AFAC008A39E0 /* NvimObjectsExtensions.swift */,
4B90F00F1FD2AFAC008A39E0 /* NvimUiBridgeProtocol.h */,
4B90F0101FD2AFAC008A39E0 /* NvimView.swift */, 4B90F0101FD2AFAC008A39E0 /* NvimView.swift */,
4B90F01B1FD2AFAC008A39E0 /* NvimView+Api.swift */, 4B90F01B1FD2AFAC008A39E0 /* NvimView+Api.swift */,
4B90F0141FD2AFAC008A39E0 /* NvimView+Dragging.swift */, 4B90F0141FD2AFAC008A39E0 /* NvimView+Dragging.swift */,
@ -228,9 +217,11 @@
4B90F0241FD2AFAD008A39E0 /* NvimView+UiBridge.swift */, 4B90F0241FD2AFAD008A39E0 /* NvimView+UiBridge.swift */,
4B90F0231FD2AFAD008A39E0 /* TextDrawer.h */, 4B90F0231FD2AFAD008A39E0 /* TextDrawer.h */,
4B90F0221FD2AFAD008A39E0 /* TextDrawer.m */, 4B90F0221FD2AFAD008A39E0 /* TextDrawer.m */,
4B90F0771FD2BA7B008A39E0 /* Logger.h */,
1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */, 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */,
1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */, 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */,
1929B52174EC68D2974B5BAE /* UiBridge.swift */,
1929B4A84091D5BAA0493B44 /* ThreadWithBlock.m */,
1929BC4314B428D5011D100A /* ThreadWithBlock.h */,
); );
path = NvimView; path = NvimView;
sourceTree = "<group>"; sourceTree = "<group>";
@ -271,13 +262,9 @@
files = ( files = (
4BF18C5D1FD2EEE400DF95D1 /* NvimView.h in Headers */, 4BF18C5D1FD2EEE400DF95D1 /* NvimView.h in Headers */,
4B90F0411FD2AFAE008A39E0 /* TextDrawer.h in Headers */, 4B90F0411FD2AFAE008A39E0 /* TextDrawer.h in Headers */,
4B90F0371FD2AFAE008A39E0 /* UiClient.h in Headers */, 1929B6C618D440AC4D3FFE3A /* ThreadWithBlock.h in Headers */,
4B90F02D1FD2AFAE008A39E0 /* NvimUiBridgeProtocol.h in Headers */,
4B177886201220F300E32FF0 /* SharedTypes.h in Headers */, 4B177886201220F300E32FF0 /* SharedTypes.h in Headers */,
4B2016EF1FD45EED0038528A /* NvimAutoCommandEvent.generated.h in Headers */,
4B90F0441FD2AFAE008A39E0 /* MMCoreTextView.h in Headers */, 4B90F0441FD2AFAE008A39E0 /* MMCoreTextView.h in Headers */,
4B90F0781FD2BA7B008A39E0 /* Logger.h in Headers */,
4B90F07B1FD30650008A39E0 /* NeoVimMsgIds.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -413,11 +400,10 @@
4B90F0461FD2AFAE008A39E0 /* Grid.swift in Sources */, 4B90F0461FD2AFAE008A39E0 /* Grid.swift in Sources */,
4B90F0421FD2AFAE008A39E0 /* NvimView+UiBridge.swift in Sources */, 4B90F0421FD2AFAE008A39E0 /* NvimView+UiBridge.swift in Sources */,
4B90F0401FD2AFAE008A39E0 /* TextDrawer.m in Sources */, 4B90F0401FD2AFAE008A39E0 /* TextDrawer.m in Sources */,
4BD874302014C2600039888E /* NvimAutoCommandEvent.generated.swift in Sources */,
4B90F02E1FD2AFAE008A39E0 /* NvimView.swift in Sources */, 4B90F02E1FD2AFAE008A39E0 /* NvimView.swift in Sources */,
4B90F03C1FD2AFAE008A39E0 /* NvimView+TouchBar.swift in Sources */, 4B90F03C1FD2AFAE008A39E0 /* NvimView+TouchBar.swift in Sources */,
4B2016EE1FD45EED0038528A /* NvimAutoCommandEvent.generated.m in Sources */,
4B90F03B1FD2AFAE008A39E0 /* NvimObjectsExtensions.swift in Sources */, 4B90F03B1FD2AFAE008A39E0 /* NvimObjectsExtensions.swift in Sources */,
4B90F04A1FD2AFAE008A39E0 /* UiClient.m in Sources */,
4B90F0351FD2AFAE008A39E0 /* NvimView+Mouse.swift in Sources */, 4B90F0351FD2AFAE008A39E0 /* NvimView+Mouse.swift in Sources */,
4B90F0431FD2AFAE008A39E0 /* NvimView+MenuItems.swift in Sources */, 4B90F0431FD2AFAE008A39E0 /* NvimView+MenuItems.swift in Sources */,
4B90F0391FD2AFAE008A39E0 /* NvimView+Api.swift in Sources */, 4B90F0391FD2AFAE008A39E0 /* NvimView+Api.swift in Sources */,
@ -428,6 +414,8 @@
4B90F03A1FD2AFAE008A39E0 /* NvimView+Key.swift in Sources */, 4B90F03A1FD2AFAE008A39E0 /* NvimView+Key.swift in Sources */,
1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */, 1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */,
1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */, 1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */,
1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */,
1929BA62EF7586682CF68E8C /* ThreadWithBlock.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -0,0 +1,96 @@
enum NvimAutoCommandEvent: Int {
case bufadd = 0
case bufdelete = 1
case bufenter = 2
case buffilepost = 3
case buffilepre = 4
case bufhidden = 5
case bufleave = 6
case bufnew = 7
case bufnewfile = 8
case bufreadcmd = 9
case bufreadpost = 10
case bufreadpre = 11
case bufunload = 12
case bufwinenter = 13
case bufwinleave = 14
case bufwipeout = 15
case bufwritecmd = 16
case bufwritepost = 17
case bufwritepre = 18
case cmdundefined = 19
case cmdwinenter = 20
case cmdwinleave = 21
case colorscheme = 22
case completedone = 23
case cursorhold = 24
case cursorholdi = 25
case cursormoved = 26
case cursormovedi = 27
case dirchanged = 28
case encodingchanged = 29
case fileappendcmd = 30
case fileappendpost = 31
case fileappendpre = 32
case filechangedro = 33
case filechangedshell = 34
case filechangedshellpost = 35
case filereadcmd = 36
case filereadpost = 37
case filereadpre = 38
case filetype = 39
case filewritecmd = 40
case filewritepost = 41
case filewritepre = 42
case filterreadpost = 43
case filterreadpre = 44
case filterwritepost = 45
case filterwritepre = 46
case focusgained = 47
case focuslost = 48
case funcundefined = 49
case guienter = 50
case guifailed = 51
case insertchange = 52
case insertcharpre = 53
case insertenter = 54
case insertleave = 55
case jobactivity = 56
case menupopup = 57
case optionset = 58
case quickfixcmdpost = 59
case quickfixcmdpre = 60
case quitpre = 61
case remotereply = 62
case sessionloadpost = 63
case shellcmdpost = 64
case shellfilterpost = 65
case sourcecmd = 66
case sourcepre = 67
case spellfilemissing = 68
case stdinreadpost = 69
case stdinreadpre = 70
case swapexists = 71
case syntax = 72
case tabclosed = 73
case tabenter = 74
case tableave = 75
case tabnew = 76
case tabnewentered = 77
case termchanged = 78
case termclose = 79
case termopen = 80
case termresponse = 81
case textchanged = 82
case textchangedi = 83
case textyankpost = 84
case user = 85
case vimenter = 86
case vimleave = 87
case vimleavepre = 88
case vimresized = 89
case winnew = 90
case winenter = 91
case winleave = 92
}

View File

@ -215,18 +215,18 @@ extension NvimView {
} }
public func didBecomeMain() { public func didBecomeMain() {
self.uiClient.focusGained(true) self.uiBridge.focusGained(true)
} }
public func didResignMain() { public func didResignMain() {
self.uiClient.focusGained(false) self.uiBridge.focusGained(false)
} }
func waitForNeoVimToQuit() { func waitForNeoVimToQuit() {
self.uiClient.neoVimQuitCondition.lock() self.uiBridge.nvimQuitCondition.lock()
defer { self.uiClient.neoVimQuitCondition.unlock() } defer { self.uiBridge.nvimQuitCondition.unlock() }
while self.uiClient.neoVimHasQuit == false while self.uiBridge.isNvimQuit == false
&& self.uiClient.neoVimQuitCondition.wait(until: Date(timeIntervalSinceNow: neoVimQuitTimeout)) {} && self.uiBridge.nvimQuitCondition.wait(until: Date(timeIntervalSinceNow: neoVimQuitTimeout)) {}
} }
private func `open`(_ url: URL, cmd: String) { private func `open`(_ url: URL, cmd: String) {

View File

@ -38,7 +38,7 @@ extension NvimView {
? self.wrapNamedKeys(flags + namedChars) ? self.wrapNamedKeys(flags + namedChars)
: self.vimPlainString(chars) : self.vimPlainString(chars)
self.uiClient.vimInput(finalInput) self.uiBridge.vimInput(finalInput)
self.keyDownDone = true self.keyDownDone = true
} }
@ -47,9 +47,9 @@ extension NvimView {
switch aString { switch aString {
case let string as String: case let string as String:
self.uiClient.vimInput(self.vimPlainString(string)) self.uiBridge.vimInput(self.vimPlainString(string))
case let attributedString as NSAttributedString: case let attributedString as NSAttributedString:
self.uiClient.vimInput(self.vimPlainString(attributedString.string)) self.uiBridge.vimInput(self.vimPlainString(attributedString.string))
default: default:
break; break;
} }
@ -98,7 +98,7 @@ extension NvimView {
// Control code \0 causes rpc parsing problems. // Control code \0 causes rpc parsing problems.
// So we escape as early as possible // So we escape as early as possible
if chars == "\0" { if chars == "\0" {
self.uiClient.vimInput(self.wrapNamedKeys("Nul")) self.uiBridge.vimInput(self.wrapNamedKeys("Nul"))
return true return true
} }
@ -106,12 +106,12 @@ extension NvimView {
// See special cases in vim/os_win32.c from vim sources // See special cases in vim/os_win32.c from vim sources
// Also mentioned in MacVim's KeyBindings.plist // Also mentioned in MacVim's KeyBindings.plist
if .control == flags && chars == "6" { if .control == flags && chars == "6" {
self.uiClient.vimInput("\u{1e}") // AKA ^^ self.uiBridge.vimInput("\u{1e}") // AKA ^^
return true return true
} }
if .control == flags && chars == "2" { if .control == flags && chars == "2" {
// <C-2> should generate \0, escaping as above // <C-2> should generate \0, escaping as above
self.uiClient.vimInput(self.wrapNamedKeys("Nul")) self.uiBridge.vimInput(self.wrapNamedKeys("Nul"))
return true return true
} }
// NsEvent already sets \u{1f} for <C--> && <C-_> // NsEvent already sets \u{1f} for <C--> && <C-_>
@ -126,7 +126,7 @@ extension NvimView {
// eg -> hanja popup, cf comment for self.lastMarkedText // eg -> hanja popup, cf comment for self.lastMarkedText
if replacementRange.length > 0 { if replacementRange.length > 0 {
self.uiClient.deleteCharacters(replacementRange.length) self.uiBridge.deleteCharacters(replacementRange.length)
} }
switch aString { switch aString {
@ -140,7 +140,7 @@ extension NvimView {
// self.logger.debug("\(#function): \(self.markedText), \(selectedRange), \(replacementRange)") // self.logger.debug("\(#function): \(self.markedText), \(selectedRange), \(replacementRange)")
self.uiClient.vimInputMarkedText(self.markedText!) self.uiBridge.vimInputMarkedText(self.markedText!)
self.keyDownDone = true self.keyDownDone = true
} }

View File

@ -48,9 +48,9 @@ extension NvimView {
@IBAction func undo(_ sender: AnyObject?) { @IBAction func undo(_ sender: AnyObject?) {
switch self.mode { switch self.mode {
case .insert, .replace: case .insert, .replace:
self.uiClient.vimInput("<Esc>ui") self.uiBridge.vimInput("<Esc>ui")
case .normal, .visual: case .normal, .visual:
self.uiClient.vimInput("u") self.uiBridge.vimInput("u")
default: default:
return return
} }
@ -59,9 +59,9 @@ extension NvimView {
@IBAction func redo(_ sender: AnyObject?) { @IBAction func redo(_ sender: AnyObject?) {
switch self.mode { switch self.mode {
case .insert, .replace: case .insert, .replace:
self.uiClient.vimInput("<Esc><C-r>i") self.uiBridge.vimInput("<Esc><C-r>i")
case .normal, .visual: case .normal, .visual:
self.uiClient.vimInput("<C-r>") self.uiBridge.vimInput("<C-r>")
default: default:
return return
} }
@ -70,7 +70,7 @@ extension NvimView {
@IBAction func cut(_ sender: AnyObject?) { @IBAction func cut(_ sender: AnyObject?) {
switch self.mode { switch self.mode {
case .visual, .normal: case .visual, .normal:
self.uiClient.vimInput("\"+d") self.uiBridge.vimInput("\"+d")
default: default:
return return
} }
@ -79,7 +79,7 @@ extension NvimView {
@IBAction func copy(_ sender: AnyObject?) { @IBAction func copy(_ sender: AnyObject?) {
switch self.mode { switch self.mode {
case .visual, .normal: case .visual, .normal:
self.uiClient.vimInput("\"+y") self.uiBridge.vimInput("\"+y")
default: default:
return return
} }
@ -93,7 +93,7 @@ extension NvimView {
if self.mode == .cmdline || self.mode == .cmdlineInsert || self.mode == .cmdlineReplace if self.mode == .cmdline || self.mode == .cmdlineInsert || self.mode == .cmdlineReplace
|| self.mode == .replace || self.mode == .replace
|| self.mode == .termFocus { || self.mode == .termFocus {
self.uiClient.vimInput(self.vimPlainString(content)) self.uiBridge.vimInput(self.vimPlainString(content))
return return
} }
@ -113,9 +113,9 @@ extension NvimView {
switch self.mode { switch self.mode {
case .insert: case .insert:
self.uiClient.vimInput("<ESC>\"+pa") self.uiBridge.vimInput("<ESC>\"+pa")
case .normal, .visual: case .normal, .visual:
self.uiClient.vimInput("\"+p") self.uiBridge.vimInput("\"+p")
default: default:
return return
} }
@ -128,7 +128,7 @@ extension NvimView {
@IBAction func delete(_ sender: AnyObject?) { @IBAction func delete(_ sender: AnyObject?) {
switch self.mode { switch self.mode {
case .normal, .visual: case .normal, .visual:
self.uiClient.vimInput("x") self.uiBridge.vimInput("x")
default: default:
return return
} }
@ -137,9 +137,9 @@ extension NvimView {
@IBAction public override func selectAll(_ sender: Any?) { @IBAction public override func selectAll(_ sender: Any?) {
switch self.mode { switch self.mode {
case .insert, .visual: case .insert, .visual:
self.uiClient.vimInput("<Esc>ggVG") self.uiBridge.vimInput("<Esc>ggVG")
default: default:
self.uiClient.vimInput("ggVG") self.uiBridge.vimInput("ggVG")
} }
} }
} }

View File

@ -32,15 +32,15 @@ extension NvimView {
let (vimInputX, vimInputY) = self.vimScrollInputFor(deltaX: deltaX, deltaY: deltaY, let (vimInputX, vimInputY) = self.vimScrollInputFor(deltaX: deltaX, deltaY: deltaY,
modifierFlags: event.modifierFlags, modifierFlags: event.modifierFlags,
cellPosition: cellPosition) cellPosition: cellPosition)
self.uiClient.vimInput(vimInputX) self.uiBridge.vimInput(vimInputX)
self.uiClient.vimInput(vimInputY) self.uiBridge.vimInput(vimInputY)
return return
} }
let (absDeltaX, absDeltaY) = (min(Int(ceil(abs(deltaX) / 5.0)), maxScrollDeltaX), let (absDeltaX, absDeltaY) = (min(Int(ceil(abs(deltaX) / 5.0)), maxScrollDeltaX),
min(Int(ceil(abs(deltaY) / 5.0)), maxScrollDeltaY)) min(Int(ceil(abs(deltaY) / 5.0)), maxScrollDeltaY))
let (horizSign, vertSign) = (deltaX > 0 ? 1 : -1, deltaY > 0 ? 1 : -1) let (horizSign, vertSign) = (deltaX > 0 ? 1 : -1, deltaY > 0 ? 1 : -1)
self.uiClient.scrollHorizontal(horizSign * absDeltaX, vertical: vertSign * absDeltaY, at: cellPosition) self.uiBridge.scroll(horizontal: horizSign * absDeltaX, vertical: vertSign * absDeltaY, at: cellPosition)
} }
override public func magnify(with event: NSEvent) { override public func magnify(with event: NSEvent) {
@ -97,7 +97,7 @@ extension NvimView {
} }
// self.logger.debug("\(#function): \(result)") // self.logger.debug("\(#function): \(result)")
self.uiClient.vimInput(result) self.uiBridge.vimInput(result)
} }
private func shouldFireVimInputFor(event: NSEvent, newCellPosition: Position) -> Bool { private func shouldFireVimInputFor(event: NSEvent, newCellPosition: Position) -> Bool {

View File

@ -51,12 +51,12 @@ extension NvimView {
self.xOffset = floor((size.width - self.cellSize.width * CGFloat(discreteSize.width)) / 2) 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.yOffset = floor((size.height - self.cellSize.height * CGFloat(discreteSize.height)) / 2)
self.uiClient.resize(toWidth: Int32(discreteSize.width), height: Int32(discreteSize.height)) self.uiBridge.resize(width: discreteSize.width, height: discreteSize.height)
} }
private func launchNeoVim(_ size: Size) { private func launchNeoVim(_ size: Size) {
self.logger.info("=== Starting neovim...") self.logger.info("=== Starting neovim...")
let noErrorDuringInitialization = self.uiClient.runLocalServerAndNeoVim(withWidth: size.width, height: size.height) let noErrorDuringInitialization = self.uiBridge.runLocalServerAndNvim(width: size.width, height: size.height)
do { do {
try self.nvim.connect() try self.nvim.connect()

View File

@ -9,7 +9,7 @@ import RxSwift
extension NvimView { extension NvimView {
public func resize(toWidth width: Int, height: Int) { func resize(toWidth width: Int, height: Int) {
gui.async { gui.async {
self.bridgeLogger.debug("\(width) x \(height)") self.bridgeLogger.debug("\(width) x \(height)")
@ -18,7 +18,7 @@ extension NvimView {
} }
} }
public func clear() { func clear() {
gui.async { gui.async {
self.bridgeLogger.mark() self.bridgeLogger.mark()
@ -27,7 +27,7 @@ extension NvimView {
} }
} }
public func eolClear() { func eolClear() {
gui.async { gui.async {
self.bridgeLogger.mark() self.bridgeLogger.mark()
@ -42,14 +42,14 @@ extension NvimView {
} }
} }
public func modeChange(_ mode: CursorModeShape) { func modeChange(_ mode: CursorModeShape) {
gui.async { gui.async {
self.bridgeLogger.debug(self.cursorModeShapeName(mode)) self.bridgeLogger.debug(name(of: mode))
self.mode = mode self.mode = mode
} }
} }
public func setScrollRegionToTop(_ top: Int, bottom: Int, left: Int, right: Int) { func setScrollRegionToTop(_ top: Int, bottom: Int, left: Int, right: Int) {
gui.async { gui.async {
self.bridgeLogger.debug("\(top):\(bottom):\(left):\(right)") self.bridgeLogger.debug("\(top):\(bottom):\(left):\(right)")
@ -58,7 +58,7 @@ extension NvimView {
} }
} }
public func scroll(_ count: Int) { func scroll(_ count: Int) {
gui.async { gui.async {
self.bridgeLogger.debug(count) self.bridgeLogger.debug(count)
@ -70,7 +70,7 @@ extension NvimView {
} }
} }
public func unmarkRow(_ row: Int, column: Int) { func unmarkRow(_ row: Int, column: Int) {
gui.async { gui.async {
self.bridgeLogger.debug("\(row):\(column)") self.bridgeLogger.debug("\(row):\(column)")
@ -81,7 +81,7 @@ extension NvimView {
} }
} }
public func flush(_ renderData: [Data]) { func flush(_ renderData: [Data]) {
gui.async { gui.async {
self.bridgeLogger.hr() self.bridgeLogger.hr()
@ -134,14 +134,14 @@ extension NvimView {
} }
} }
public func updateForeground(_ fg: Int) { func updateForeground(_ fg: Int) {
gui.async { gui.async {
self.bridgeLogger.debug(ColorUtils.colorIgnoringAlpha(fg)) self.bridgeLogger.debug(ColorUtils.colorIgnoringAlpha(fg))
self.grid.foreground = fg self.grid.foreground = fg
} }
} }
public func updateBackground(_ bg: Int) { func updateBackground(_ bg: Int) {
gui.async { gui.async {
self.bridgeLogger.debug(ColorUtils.colorIgnoringAlpha(bg)) self.bridgeLogger.debug(ColorUtils.colorIgnoringAlpha(bg))
@ -150,23 +150,23 @@ extension NvimView {
} }
} }
public func updateSpecial(_ sp: Int) { func updateSpecial(_ sp: Int) {
gui.async { gui.async {
self.bridgeLogger.debug(ColorUtils.colorIgnoringAlpha(sp)) self.bridgeLogger.debug(ColorUtils.colorIgnoringAlpha(sp))
self.grid.special = sp self.grid.special = sp
} }
} }
public func setTitle(_ title: String) { func setTitle(_ title: String) {
self.bridgeLogger.debug(title) self.bridgeLogger.debug(title)
self.eventsSubject.onNext(.setTitle(title)) self.eventsSubject.onNext(.setTitle(title))
} }
public func stop() { func stop() {
self.bridgeLogger.hr() self.bridgeLogger.hr()
self.nvim.disconnect() self.nvim.disconnect()
self.uiClient.quit() self.uiBridge.quit()
gui.async { gui.async {
self.waitForNeoVimToQuit() self.waitForNeoVimToQuit()
@ -175,31 +175,31 @@ extension NvimView {
} }
} }
public func autoCommandEvent(_ event: NvimAutoCommandEvent, bufferHandle: Int) { func autoCommandEvent(_ event: NvimAutoCommandEvent, bufferHandle: Int) {
self.bridgeLogger.debug("\(nvimAutoCommandEventName(event)) -> \(bufferHandle)") self.bridgeLogger.debug("\(event) -> \(bufferHandle)")
if event == .BUFWINENTER || event == .BUFWINLEAVE { if event == .bufwinenter || event == .bufwinleave {
self.bufferListChanged() self.bufferListChanged()
} }
if event == .TABENTER { if event == .tabenter {
self.eventsSubject.onNext(.tabChanged) self.eventsSubject.onNext(.tabChanged)
} }
if event == .BUFWRITEPOST { if event == .bufwritepost {
self.bufferWritten(bufferHandle) self.bufferWritten(bufferHandle)
} }
if event == .BUFENTER { if event == .bufenter {
self.newCurrentBuffer(bufferHandle) self.newCurrentBuffer(bufferHandle)
} }
} }
public func ipcBecameInvalid(_ reason: String) { func ipcBecameInvalid(_ reason: String) {
gui.async { gui.async {
self.bridgeLogger.debug(reason) self.bridgeLogger.debug(reason)
if self.uiClient.neoVimIsQuitting || self.uiClient.neoVimHasQuit { if self.uiBridge.isNvimQuitting == 1 || self.uiBridge.isNvimQuit {
return return
} }
@ -208,7 +208,7 @@ extension NvimView {
self.bridgeLogger.error("Force-closing due to IPC error.") self.bridgeLogger.error("Force-closing due to IPC error.")
self.nvim.disconnect() self.nvim.disconnect()
self.uiClient.forceQuit() self.uiBridge.forceQuit()
} }
} }
@ -244,12 +244,12 @@ extension NvimView {
} }
private func doHighlightSet(_ attrs: CellAttributes) { private func doHighlightSet(_ attrs: CellAttributes) {
self.bridgeLogger.debug(attrs) // self.bridgeLogger.debug(attrs)
self.grid.attrs = attrs self.grid.attrs = attrs
} }
private func doGotoPosition(_ position: Position, textPosition: Position) { private func doGotoPosition(_ position: Position, textPosition: Position) {
self.bridgeLogger.debug(position) // self.bridgeLogger.debug(position)
self.markForRender(cellPosition: self.grid.position) self.markForRender(cellPosition: self.grid.position)
self.grid.goto(position) self.grid.goto(position)
@ -261,21 +261,21 @@ extension NvimView {
// MARK: - Simple // MARK: - Simple
extension NvimView { extension NvimView {
public func bell() { func bell() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
NSSound.beep() NSSound.beep()
} }
public func cwdChanged(_ cwd: String) { func cwdChanged(_ cwd: String) {
self.bridgeLogger.debug(cwd) self.bridgeLogger.debug(cwd)
self._cwd = URL(fileURLWithPath: cwd) self._cwd = URL(fileURLWithPath: cwd)
self.eventsSubject.onNext(.cwdChanged) self.eventsSubject.onNext(.cwdChanged)
} }
public func colorSchemeChanged(_ values: [NSNumber]) { func colorSchemeChanged(_ values: [Int]) {
gui.async { gui.async {
let theme = Theme(values.map { $0.intValue }) let theme = Theme(values)
self.bridgeLogger.debug(theme) self.bridgeLogger.debug(theme)
self.theme = theme self.theme = theme
@ -283,41 +283,41 @@ extension NvimView {
} }
} }
public func setDirtyStatus(_ dirty: Bool) { func setDirtyStatus(_ dirty: Bool) {
self.bridgeLogger.debug(dirty) self.bridgeLogger.debug(dirty)
self.eventsSubject.onNext(.setDirtyStatus(dirty)) self.eventsSubject.onNext(.setDirtyStatus(dirty))
} }
public func updateMenu() { func updateMenu() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func busyStart() { func busyStart() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func busyStop() { func busyStop() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func mouseOn() { func mouseOn() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func mouseOff() { func mouseOff() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func visualBell() { func visualBell() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func suspend() { func suspend() {
self.bridgeLogger.mark() self.bridgeLogger.mark()
} }
public func setIcon(_ icon: String) { func setIcon(_ icon: String) {
self.bridgeLogger.debug(icon) self.bridgeLogger.debug(icon)
} }
} }
@ -398,30 +398,32 @@ extension NvimView {
self.updateTouchBarCurrentBuffer() self.updateTouchBarCurrentBuffer()
} }
} }
private func cursorModeShapeName(_ mode: CursorModeShape) -> String {
switch mode {
case .normal: return "Normal"
case .visual: return "Visual"
case .insert: return "Insert"
case .replace: return "Replace"
case .cmdline: return "Cmdline"
case .cmdlineInsert: return "CmdlineInsert"
case .cmdlineReplace: return "CmdlineReplace"
case .operatorPending: return "OperatorPending"
case .visualExclusive: return "VisualExclusive"
case .onCmdline: return "OnCmdline"
case .onStatusLine: return "OnStatusLine"
case .draggingStatusLine: return "DraggingStatusLine"
case .onVerticalSepLine: return "OnVerticalSepLine"
case .draggingVerticalSepLine: return "DraggingVerticalSepLine"
case .more: return "More"
case .moreLastLine: return "MoreLastLine"
case .showingMatchingParen: return "ShowingMatchingParen"
case .termFocus: return "TermFocus"
case .count: return "Count"
}
}
} }
private let gui = DispatchQueue.main private let gui = DispatchQueue.main
private func name(of mode: CursorModeShape) -> String {
switch mode {
// @formatter:off
case .normal: return "Normal"
case .visual: return "Visual"
case .insert: return "Insert"
case .replace: return "Replace"
case .cmdline: return "Cmdline"
case .cmdlineInsert: return "CmdlineInsert"
case .cmdlineReplace: return "CmdlineReplace"
case .operatorPending: return "OperatorPending"
case .visualExclusive: return "VisualExclusive"
case .onCmdline: return "OnCmdline"
case .onStatusLine: return "OnStatusLine"
case .draggingStatusLine: return "DraggingStatusLine"
case .onVerticalSepLine: return "OnVerticalSepLine"
case .draggingVerticalSepLine: return "DraggingVerticalSepLine"
case .more: return "More"
case .moreLastLine: return "MoreLastLine"
case .showingMatchingParen: return "ShowingMatchingParen"
case .termFocus: return "TermFocus"
case .count: return "Count"
// @formatter:on
}
}

View File

@ -1,10 +1,7 @@
// /**
// NvimView.h * Tae Won Ha - http://taewon.de - @hataewon
// NvimView * See LICENSE
// */
// Created by hat on 02.12.17.
// Copyright © 2017 Tae Won Ha. All rights reserved.
//
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -16,9 +13,7 @@ FOUNDATION_EXPORT const unsigned char NvimViewVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <NvimView/PublicHeader.h> // In this header, you should import all the public headers of your framework using statements like #import <NvimView/PublicHeader.h>
#import <NvimView/NvimUiBridgeProtocol.h>
// TODO: this header should not be public, but we cannot use a bridging header in a framework. // TODO: this header should not be public, but we cannot use a bridging header in a framework.
#import <NvimView/TextDrawer.h> #import <NvimView/TextDrawer.h>
#import <NvimView/UiClient.h>
#import <NvimView/NvimAutoCommandEvent.generated.h>
#import <NvimView/SharedTypes.h> #import <NvimView/SharedTypes.h>
#import <NvimView/ThreadWithBlock.h>

View File

@ -8,7 +8,6 @@ import NvimMsgPack
import RxSwift import RxSwift
public class NvimView: NSView, public class NvimView: NSView,
NvimUiBridgeProtocol,
NSUserInterfaceValidations, NSUserInterfaceValidations,
NSTextInputClient { NSTextInputClient {
@ -175,7 +174,7 @@ public class NvimView: NSView,
public init(frame rect: NSRect, config: Config) { public init(frame rect: NSRect, config: Config) {
self.drawer = TextDrawer(font: self._font) self.drawer = TextDrawer(font: self._font)
self.uiClient = UiClient(uuid: self.uuid) self.uiBridge = UiBridge(uuid: self.uuid)
let sockPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("vimr_\(self.uuid).sock").path let sockPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("vimr_\(self.uuid).sock").path
guard let nvim = NvimApi(at: sockPath) else { guard let nvim = NvimApi(at: sockPath) else {
@ -193,10 +192,10 @@ public class NvimView: NSView,
self.leading = self.drawer.leading self.leading = self.drawer.leading
// We cannot set bridge in init since self is not available before super.init()... // We cannot set bridge in init since self is not available before super.init()...
self.uiClient.bridge = self self.uiBridge.nvimView = self
self.uiClient.useInteractiveZsh = config.useInteractiveZsh self.uiBridge.useInteractiveZsh = config.useInteractiveZsh
self.uiClient.cwd = config.cwd self.uiBridge.cwd = config.cwd
self.uiClient.nvimArgs = config.nvimArgs self.uiBridge.nvimArgs = config.nvimArgs ?? []
} }
convenience override public init(frame rect: NSRect) { convenience override public init(frame rect: NSRect) {
@ -209,7 +208,7 @@ public class NvimView: NSView,
@IBAction public func debug1(_ sender: Any?) { @IBAction public func debug1(_ sender: Any?) {
self.logger.debug("DEBUG 1 - Start") self.logger.debug("DEBUG 1 - Start")
self.uiClient.debug() self.uiBridge.debug()
self.logger.debug("DEBUG 1 - End") self.logger.debug("DEBUG 1 - End")
} }
@ -230,7 +229,7 @@ public class NvimView: NSView,
let bridgeLogger = LogContext.fileLogger(as: NvimView.self, let bridgeLogger = LogContext.fileLogger(as: NvimView.self,
with: URL(fileURLWithPath: "/tmp/nvv-bridge.log"), with: URL(fileURLWithPath: "/tmp/nvv-bridge.log"),
shouldLogDebug: nil) shouldLogDebug: nil)
let uiClient: UiClient let uiBridge: UiBridge
let nvim: NvimApi let nvim: NvimApi
let grid = Grid() let grid = Grid()

View File

@ -6,7 +6,9 @@
@import Cocoa; @import Cocoa;
@import CoreText; @import CoreText;
#import "NvimUiBridgeProtocol.h"
#import "SharedTypes.h"
@interface TextDrawer : NSObject @interface TextDrawer : NSObject

View File

@ -0,0 +1,14 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import <Foundation/Foundation.h>
typedef void (^ThreadInitBlock)(id);
@interface ThreadWithBlock : NSThread
- (instancetype)initWithThreadInitBlock:(ThreadInitBlock)block;
@end

View File

@ -0,0 +1,48 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import "ThreadWithBlock.h"
@interface BlockHolder: NSObject
- (instancetype)initWithBlock:(ThreadInitBlock)block;
- (void)blockInit:(id)sender;
@end
@implementation BlockHolder {
ThreadInitBlock _block;
}
- (instancetype)initWithBlock:(ThreadInitBlock)block {
self = [super init];
if (self == nil) {
return nil;
}
_block = block;
return self;
}
- (void)blockInit:(id)sender {
_block(sender);
}
@end
@implementation ThreadWithBlock
- (instancetype)initWithThreadInitBlock:(ThreadInitBlock)block {
BlockHolder *blockHolder = [[BlockHolder alloc] initWithBlock:block];
self = [super initWithTarget:blockHolder selector:@selector(blockInit:) object:nil];
if (self == nil) {
return nil;
}
return self;
}
@end

View File

@ -0,0 +1,510 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Foundation
class UiBridge {
weak var nvimView: NvimView?
var isNvimQuitting = UInt32(0)
var isNvimQuit = false
let nvimQuitCondition = NSCondition()
var useInteractiveZsh = false
var cwd = URL(fileURLWithPath: NSHomeDirectory())
var nvimArgs = [String]()
init(uuid: String) {
self.uuid = uuid
self.messageHandler = MessageHandler()
self.messageHandler.bridge = self
}
func runLocalServerAndNvim(width: Int, height: Int) -> Bool {
self.initialWidth = width
self.initialHeight = height
self.localServerThread = ThreadWithBlock(threadInitBlock: { _ in self.runLocalServer() })
self.localServerThread?.start()
self.launchNvimUsingLoginShell()
let deadline = Date().addingTimeInterval(timeout)
self.nvimReadyCondition.lock()
defer { self.nvimReadyCondition.unlock() }
while (!self.isNvimReady && self.nvimReadyCondition.wait(until: deadline)) {}
return !self.isInitErrorPresent
}
func vimInput(_ str: String) {
self.sendMessage(msgId: .input, data: str.data(using: .utf8))
}
func vimInputMarkedText(_ markedText: String) {
self.sendMessage(msgId: .inputMarked, data: markedText.data(using: .utf8))
}
func deleteCharacters(_ count: Int) {
self.sendMessage(msgId: .delete, data: [count].data())
}
func resize(width: Int, height: Int) {
self.sendMessage(msgId: .resize, data: [width, height].data())
}
func focusGained(_ gained: Bool) {
self.sendMessage(msgId: .focusGained, data: [gained].data())
}
func scroll(horizontal: Int, vertical: Int, at position: Position) {
self.sendMessage(msgId: .scroll, data: [horizontal, vertical, position.row, position.column].data())
}
func quit() {
OSAtomicOr32Barrier(1, &self.isNvimQuitting)
self.closePorts()
self.nvimServerProc?.waitUntilExit()
self.nvimQuitCondition.lock()
defer {
self.nvimQuitCondition.signal()
self.nvimQuitCondition.unlock()
}
self.isNvimQuit = true
self.logger.info("NvimServer \(self.uuid) exited successfully.")
}
func forceQuit() {
self.logger.info("Force-exiting NvimServer \(self.uuid).")
OSAtomicOr32Barrier(1, &self.isNvimQuitting)
self.closePorts()
self.forceExitNvimServer()
self.nvimQuitCondition.lock()
defer {
self.nvimQuitCondition.signal()
self.nvimQuitCondition.unlock()
}
self.isNvimQuit = true
self.logger.info("NvimServer \(self.uuid) was forcefully exited.")
}
func debug() {
self.sendMessage(msgId: .debug1, data: nil)
}
fileprivate func handleMessage(msgId: Int32, data: Data?) {
guard let msg = NeoVimServerMsgId(rawValue: Int(msgId)) else {
return
}
switch msg {
case .serverReady:
self.establishNvimConnection()
case .neoVimReady:
self.isInitErrorPresent = data?.asArray(ofType: Bool.self, count: 1)?[0] ?? false
self.nvimReadyCondition.lock()
self.isNvimReady = true
defer {
self.nvimReadyCondition.signal()
self.nvimReadyCondition.unlock()
}
case .resize:
guard let values = data?.asArray(ofType: Int.self, count: 2) else {
return
}
self.nvimView?.resize(toWidth: values[0], height: values[1])
case .clear:
self.nvimView?.clear()
case .eolClear:
self.nvimView?.eolClear()
case .setMenu:
self.nvimView?.updateMenu()
case .busyStart:
self.nvimView?.busyStart()
case .busyStop:
self.nvimView?.busyStop()
case .mouseOn:
self.nvimView?.mouseOn()
case .mouseOff:
self.nvimView?.mouseOff()
case .modeChange:
guard let values = data?.asArray(ofType: CursorModeShape.self, count: 1) else {
return
}
self.nvimView?.modeChange(values[0])
case .setScrollRegion:
guard let values = data?.asArray(ofType: Int.self, count: 4) else {
return
}
self.nvimView?.setScrollRegionToTop(values[0], bottom: values[1], left: values[2], right: values[3])
case .scroll:
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
return
}
self.nvimView?.scroll(values[0])
case .unmark:
guard let values = data?.asArray(ofType: Int.self, count: 2) else {
return
}
self.nvimView?.unmarkRow(values[0], column: values[1])
case .bell:
self.nvimView?.bell()
case .visualBell:
self.nvimView?.visualBell()
case .flush:
guard let d = data, let renderData = NSKeyedUnarchiver.unarchiveObject(with: d) as? [Data] else {
return
}
self.nvimView?.flush(renderData)
case .setForeground:
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
return
}
self.nvimView?.updateForeground(values[0])
case .setBackground:
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
return
}
self.nvimView?.updateBackground(values[0])
case .setSpecial:
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
return
}
self.nvimView?.updateSpecial(values[0])
case .setTitle:
guard let d = data, let title = String(data: d, encoding: .utf8) else {
return
}
self.nvimView?.setTitle(title)
case .setIcon:
guard let d = data, let icon = String(data: d, encoding: .utf8) else {
return
}
self.nvimView?.setTitle(icon)
case .stop:
self.nvimView?.stop()
case .dirtyStatusChanged:
guard let values = data?.asArray(ofType: Bool.self, count: 1) else {
return
}
self.nvimView?.setDirtyStatus(values[0])
case .cwdChanged:
guard let d = data, let cwd = String(data: d, encoding: .utf8) else {
return
}
self.nvimView?.cwdChanged(cwd)
case .colorSchemeChanged:
guard let values = data?.asArray(ofType: Int.self, count: 5) else {
return
}
self.nvimView?.colorSchemeChanged(values)
case .autoCommandEvent:
if data?.count == 2 * MemoryLayout<Int>.stride {
guard let values = data?.asArray(ofType: Int.self, count: 2),
let cmd = NvimAutoCommandEvent(rawValue: values[0])
else {
return
}
self.nvimView?.autoCommandEvent(cmd, bufferHandle: values[1])
} else {
guard let values = data?.asArray(ofType: NvimAutoCommandEvent.self, count: 1) else {
return
}
self.nvimView?.autoCommandEvent(values[0], bufferHandle: -1)
}
case .debug1:
break
}
return
}
private func closePorts() {
CFRunLoopStop(self.localServerRunLoop)
self.localServerThread?.cancel()
if CFMessagePortIsValid(self.remoteServerPort) {
CFMessagePortInvalidate(self.remoteServerPort)
}
self.remoteServerPort = nil
if CFMessagePortIsValid(self.localServerPort) {
CFMessagePortInvalidate(self.localServerPort)
}
self.localServerPort = nil
}
private func establishNvimConnection() {
self.remoteServerPort = CFMessagePortCreateRemote(kCFAllocatorDefault, self.remoteServerName.CFStr)
self.sendMessage(msgId: .agentReady, data: [self.initialWidth, self.initialHeight].data())
}
/// Does not wait for reply.
private func sendMessage(msgId: NeoVimAgentMsgId, data: Data?) {
if self.isNvimQuitting == 1 {
self.logger.info("NvimServer is quitting, but trying to send msg: \(msgId).")
return
}
if self.remoteServerPort == nil {
self.logger.info("Remote server port is nil, but trying to send msg: \(msgId).")
return
}
let responseCode = CFMessagePortSendRequest(self.remoteServerPort,
Int32(msgId.rawValue),
data as NSData?,
timeout,
timeout,
nil,
nil)
if self.isNvimQuitting == 1 {
return
}
if responseCode != kCFMessagePortSuccess {
let msg = "Remote server responded with \(name(of: responseCode)) for msg \(msgId)."
self.logger.error(msg)
if self.isNvimQuitting == 0 {
self.nvimView?.ipcBecameInvalid(msg)
}
}
}
private func forceExitNvimServer() {
self.nvimServerProc?.interrupt()
self.nvimServerProc?.terminate()
}
private func launchNvimUsingLoginShell() {
let selfEnv = ProcessInfo.processInfo.environment
let shellPath = URL(fileURLWithPath: selfEnv["SHELL"] ?? "/bin/bash")
let shellName = shellPath.lastPathComponent
var shellArgs = [String]()
if shellName != "tcsh" {
// tcsh does not like the -l option
shellArgs.append("-l")
}
if self.useInteractiveZsh && shellName == "zsh" {
shellArgs.append("-i")
}
let inputPipe = Pipe()
self.nvimServerProc = Process()
let listenAddress = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("vimr_\(self.uuid).sock")
var env = selfEnv
env["NVIM_LISTEN_ADDRESS"] = listenAddress.path
self.nvimServerProc?.environment = env
self.nvimServerProc?.standardInput = inputPipe
self.nvimServerProc?.currentDirectoryPath = self.cwd.path
self.nvimServerProc?.launchPath = shellPath.path
self.nvimServerProc?.arguments = shellArgs
self.nvimServerProc?.launch()
nvimArgs.append("--headless")
let cmd = "exec '\(self.nvimServerExecutablePath())' '\(self.localServerName)' '\(self.remoteServerName)' "
.appending(self.nvimArgs.map { "\($0)" }.joined(separator: " "))
let writeHandle = inputPipe.fileHandleForWriting
guard let cmdData = cmd.data(using: .utf8) else {
preconditionFailure("Could not get Data from the string '\(cmd)'")
}
writeHandle.write(cmdData)
writeHandle.closeFile()
}
private func nvimServerExecutablePath() -> String {
guard let plugInsPath = Bundle(for: UiBridge.self).builtInPlugInsPath else {
preconditionFailure("NvimServer not available!")
}
return URL(fileURLWithPath: plugInsPath).appendingPathComponent("NvimServer").path
}
private func runLocalServer() {
var localCtx = CFMessagePortContext(version: 0,
info: &self.messageHandler,
retain: nil,
release: nil,
copyDescription: nil)
self.localServerPort = CFMessagePortCreateLocal(
kCFAllocatorDefault,
self.localServerName.CFStr,
{ _, msgid, data, info in
return info?
.load(as: MessageHandler.self)
.handleMessage(msgId: msgid, data: data)
},
&localCtx,
nil // FIXME
)
self.localServerRunLoop = CFRunLoopGetCurrent()
let runLoopSrc = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, self.localServerPort, 0)
CFRunLoopAddSource(self.localServerRunLoop, runLoopSrc, .defaultMode)
CFRunLoopRun()
}
private let logger = LogContext.fileLogger(as: UiBridge.self, with: URL(fileURLWithPath: "/tmp/nvv-bridge.log"))
private let uuid: String
private var remoteServerPort: CFMessagePort?
private var localServerPort: CFMessagePort?
private var localServerThread: Thread?
private var localServerRunLoop: CFRunLoop?
private var nvimServerProc: Process?
private var isNvimReady = false
private let nvimReadyCondition = NSCondition()
private var isInitErrorPresent = false
private var initialWidth = 40
private var initialHeight = 20
private var messageHandler: MessageHandler
private var localServerName: String {
return "com.qvacua.vimr.\(self.uuid)"
}
private var remoteServerName: String {
return "com.qvacua.vimr.neovim-server.\(self.uuid)"
}
}
private class MessageHandler {
fileprivate weak var bridge: UiBridge?
fileprivate func handleMessage(msgId: Int32, data: CFData?) -> Unmanaged<CFData>? {
self.bridge?.handleMessage(msgId: msgId, data: data?.data)
return nil
}
}
private let timeout = CFTimeInterval(5)
private extension CFData {
var data: Data {
return self as NSData as Data
}
}
private extension String {
var CFStr: CFString {
return self as NSString
}
}
private extension Data {
func asArray<T>(ofType: T.Type, count: Int) -> [T]? {
guard (self.count / MemoryLayout<T>.stride) <= count else {
return nil
}
return self.withUnsafeBytes { (p: UnsafePointer<T>) in Array(UnsafeBufferPointer(start: p, count: count)) }
}
}
private extension Array {
func data() -> Data {
return self.withUnsafeBytes { pointer in
if let baseAddr = pointer.baseAddress {
return Data(bytes: baseAddr, count: pointer.count)
}
let newPointer = UnsafeMutablePointer<Element>.allocate(capacity: self.count)
for (index, element) in self.enumerated() {
newPointer[index] = element
}
return Data(bytesNoCopy: newPointer, count: self.count, deallocator: .free)
}
}
}
private func name(of errorCode: Int32) -> String {
switch errorCode {
// @formatter:off
case kCFMessagePortSendTimeout: return "kCFMessagePortSendTimeout"
case kCFMessagePortReceiveTimeout: return "kCFMessagePortReceiveTimeout"
case kCFMessagePortIsInvalid: return "kCFMessagePortIsInvalid"
case kCFMessagePortTransportError: return "kCFMessagePortTransportError"
case kCFMessagePortBecameInvalidError: return "kCFMessagePortBecameInvalidError"
default: return "unknown error"
// @formatter:on
}
}

View File

@ -55,3 +55,51 @@ typedef NS_ENUM(NSInteger, RenderDataType) {
RenderDataTypeGoto, RenderDataTypeGoto,
RenderDataTypeHighlight RenderDataTypeHighlight
}; };
typedef NS_ENUM(NSInteger, NeoVimServerMsgId) {
NeoVimServerMsgIdServerReady = 0,
NeoVimServerMsgIdNeoVimReady,
NeoVimServerMsgIdResize,
NeoVimServerMsgIdClear,
NeoVimServerMsgIdEolClear,
NeoVimServerMsgIdSetMenu,
NeoVimServerMsgIdBusyStart,
NeoVimServerMsgIdBusyStop,
NeoVimServerMsgIdMouseOn,
NeoVimServerMsgIdMouseOff,
NeoVimServerMsgIdModeChange,
NeoVimServerMsgIdSetScrollRegion,
NeoVimServerMsgIdScroll,
NeoVimServerMsgIdUnmark,
NeoVimServerMsgIdBell,
NeoVimServerMsgIdVisualBell,
NeoVimServerMsgIdFlush,
NeoVimServerMsgIdSetForeground,
NeoVimServerMsgIdSetBackground,
NeoVimServerMsgIdSetSpecial,
NeoVimServerMsgIdSetTitle,
NeoVimServerMsgIdSetIcon,
NeoVimServerMsgIdStop,
NeoVimServerMsgIdDirtyStatusChanged,
NeoVimServerMsgIdCwdChanged,
NeoVimServerMsgIdColorSchemeChanged,
NeoVimServerMsgIdAutoCommandEvent,
NeoVimServerMsgIdDebug1,
};
typedef NS_ENUM(NSInteger, NeoVimAgentMsgId) {
NeoVimAgentMsgIdAgentReady = 0,
NeoVimAgentMsgIdInput,
NeoVimAgentMsgIdInputMarked,
NeoVimAgentMsgIdDelete,
NeoVimAgentMsgIdResize,
NeoVimAgentMsgIdScroll,
NeoVimAgentMsgIdGetEscapeFileNames,
NeoVimAgentMsgIdFocusGained,
NeoVimAgentMsgIdDebug1,
};

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
import os import os
import io import io
@ -7,7 +7,7 @@ from string import Template
print(os.getcwd()) print(os.getcwd())
if 'CONFIGURATION' in os.environ and os.environ['CONFIGURATION'] == 'Debug': if 'CONFIGURATION' in os.environ and os.environ['CONFIGURATION'] == 'Debug':
if os.path.isfile('./NvimView/NvimAutoCommandEvent.generated.h') and os.path.isfile('./NvimView/NvimAutoCommandEvent.generated.m'): if os.path.isfile('./NvimView/NvimAutoCommandEvent.generated.swift'):
print("Files already there, exiting...") print("Files already there, exiting...")
exit(0) exit(0)
@ -21,43 +21,18 @@ def convert(line):
auto_cmds = [convert(line) for line in raw_auto_cmds] auto_cmds = [convert(line) for line in raw_auto_cmds]
auto_cmds_impl_template = Template( auto_cmds_template = Template(
''' '''
@import Foundation; enum NvimAutoCommandEvent: Int {
#import "NvimAutoCommandEvent.generated.h"
NSString *nvimAutoCommandEventName(NvimAutoCommandEvent event) {
switch (event) {
${event_cases} ${event_cases}
default: return @"NON_EXISTING_EVENT";
}
} }
''')
impl = auto_cmds_impl_template.substitute(
event_cases='\n'.join(
[' case NvimAutoCommandEvent{}: return @"{}";'.format(event[0], event[0]) for event in auto_cmds])
)
with io.open('./NvimView/NvimAutoCommandEvent.generated.m', 'w') as auto_cmds_impl_file:
auto_cmds_impl_file.write(unicode(impl))
auto_cmds_header_template = Template(
''' '''
@import Foundation;
typedef NS_ENUM(NSUInteger, NvimAutoCommandEvent) {
${event_cases}
};
#define NumberOfAutoCommandEvents ${count}
extern NSString * __nonnull nvimAutoCommandEventName(NvimAutoCommandEvent event);
''')
header = auto_cmds_header_template.substitute(
event_cases='\n'.join(
[' NvimAutoCommandEvent{} = {},'.format(event[0], event[1]) for event in auto_cmds]
),
count=str(len(auto_cmds))
) )
with io.open('./NvimView/NvimAutoCommandEvent.generated.h', 'w') as auto_cmds_header_file:
auto_cmds_header_file.write(unicode(header)) header = auto_cmds_template.substitute(
event_cases='\n'.join(
[' case {} = {}'.format(event[0].lower(), event[1]) for event in auto_cmds]
),
)
with io.open('./NvimView/NvimAutoCommandEvent.generated.swift', 'w') as auto_cmds_header_file:
auto_cmds_header_file.write(header)