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

Merge remote-tracking branch 'origin/develop' into update-neovim

This commit is contained in:
Tae Won Ha 2018-05-13 18:24:26 +02:00
commit 52e3401760
21 changed files with 422 additions and 516 deletions

View File

@ -8,7 +8,7 @@ github "qvacua/RxMsgpackRpc" == 0.0.1
github "qvacua/RxMessagePort" == 0.0.1 github "qvacua/RxMessagePort" == 0.0.1
github "qvacua/RxNeovimApi" "nightly" github "qvacua/RxNeovimApi" "nightly"
github "sindresorhus/github-markdown-css" == 2.10.0 github "sindresorhus/github-markdown-css" == 2.10.0
github "qvacua/swifter" "stable" github "httpswift/swifter" == 1.4.1
github "a2/MessagePack.swift" == 3.0.0 github "a2/MessagePack.swift" == 3.0.0
github "Quick/Nimble" == 7.0.3 github "Quick/Nimble" == 7.0.3

View File

@ -3,11 +3,11 @@ github "Quick/Nimble" "v7.0.3"
github "ReactiveX/RxSwift" "4.1.2" github "ReactiveX/RxSwift" "4.1.2"
github "a2/MessagePack.swift" "3.0.0" github "a2/MessagePack.swift" "3.0.0"
github "eonil/FileSystemEvents" "85a089104af37f04a6bf7f2d07d7a93cac0b4fe1" github "eonil/FileSystemEvents" "85a089104af37f04a6bf7f2d07d7a93cac0b4fe1"
github "httpswift/swifter" "1.4.1"
github "qvacua/CocoaFontAwesome" "76cf6c4ef3088d84f78988183c56fc6abdc19f83" github "qvacua/CocoaFontAwesome" "76cf6c4ef3088d84f78988183c56fc6abdc19f83"
github "qvacua/CocoaMarkdown" "7756ad96d5fb390c66531004868e828bb54d3609" github "qvacua/CocoaMarkdown" "7756ad96d5fb390c66531004868e828bb54d3609"
github "qvacua/RxMessagePort" "v0.0.1" github "qvacua/RxMessagePort" "v0.0.1"
github "qvacua/RxMsgpackRpc" "v0.0.1" github "qvacua/RxMsgpackRpc" "v0.0.1"
github "qvacua/RxNeovimApi" "nightly" github "qvacua/RxNeovimApi" "nightly"
github "qvacua/swifter" "6fc24bdb5bbafd01efa8e448070c6e8ba89fcf0f"
github "sindresorhus/github-markdown-css" "v2.10.0" github "sindresorhus/github-markdown-css" "v2.10.0"
github "sparkle-project/Sparkle" "1.18.1" github "sparkle-project/Sparkle" "1.18.1"

View File

@ -1,14 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import <Foundation/Foundation.h>
@interface DataWrapper : NSObject
@property (strong) NSData *data;
@property (getter=isDataReady) bool dataReady;
@end

View File

@ -1,9 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
#import "DataWrapper.h"
@implementation DataWrapper { } @end

View File

@ -15,7 +15,8 @@
nvimArgs:(NSArray<NSString *> *)nvimArgs; nvimArgs:(NSArray<NSString *> *)nvimArgs;
- (void)sendMessageWithId:(NvimServerMsgId)msgid; - (void)sendMessageWithId:(NvimServerMsgId)msgid;
- (void)sendMessageWithId:(NvimServerMsgId)msgid data:(NSData *)data;
- (void)sendMessageWithId:(NvimServerMsgId)msgid data:(CFDataRef)data;
- (void)notifyReadiness; - (void)notifyReadiness;
@end @end

View File

@ -7,7 +7,6 @@
#import "server_ui.h" #import "server_ui.h"
#import "Logging.h" #import "Logging.h"
#import "CocoaCategories.h" #import "CocoaCategories.h"
#import "DataWrapper.h"
// FileInfo and Boolean are #defined by Carbon and NeoVim: Since we don't need the Carbon versions of them, we rename // FileInfo and Boolean are #defined by Carbon and NeoVim: Since we don't need the Carbon versions of them, we rename
// them. // them.
@ -23,63 +22,59 @@
//#define DEBUG_NEOVIM_SERVER_STANDALONE //#define DEBUG_NEOVIM_SERVER_STANDALONE
static const double qTimeout = 10; static const double qTimeout = 5;
@interface NvimServer () @interface NvimServer ()
- (NSArray<NSString *> *)nvimArgs; - (NSArray<NSString *> *)nvimArgs;
- (NSCondition *)outputCondition;
@end @end
static CFDataRef data_sync(CFDataRef data, NSCondition *condition, argv_callback cb) { static CFDataRef data_async(CFDataRef data, argv_callback cb) {
DataWrapper *wrapper = [[DataWrapper alloc] init]; loop_schedule(&main_loop, event_create(cb, 3, data));
NSDate *deadline = [[NSDate date] dateByAddingTimeInterval:qTimeout]; return NULL;
[condition lock];
loop_schedule(&main_loop, event_create(cb, 3, data, condition, wrapper));
while (wrapper.isDataReady == false && [condition waitUntilDate:deadline]);
[condition unlock];
if (wrapper.data == nil) {
return NULL;
}
return CFDataCreateCopy(kCFAllocatorDefault, (__bridge CFDataRef) wrapper.data);
} }
static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) { static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
@autoreleasepool { CFRetain(data); // release in the loop callbacks! (or in the case clause when not passed to the callback)
NvimServer *neoVimServer = (__bridge NvimServer *) info;
NSCondition *outputCondition = neoVimServer.outputCondition;
CFRetain(data); // release in the loop callbacks!
switch (msgid) { switch (msgid) {
case NvimBridgeMsgIdAgentReady: { case NvimBridgeMsgIdAgentReady: {
@autoreleasepool {
NSInteger *values = (NSInteger *) CFDataGetBytePtr(data); NSInteger *values = (NSInteger *) CFDataGetBytePtr(data);
start_neovim(values[0], values[1], neoVimServer.nvimArgs); NvimServer *nvimServer = (__bridge NvimServer *) info;
return NULL;
start_neovim(values[0], values[1], nvimServer.nvimArgs);
CFRelease(data);
} }
return NULL;
case NvimBridgeMsgIdScroll: return data_sync(data, outputCondition, neovim_scroll);
case NvimBridgeMsgIdResize: return data_sync(data, outputCondition, neovim_resize);
case NvimBridgeMsgIdInput: return data_sync(data, outputCondition, neovim_vim_input);
case NvimBridgeMsgIdInputMarked: return data_sync(data, outputCondition, neovim_vim_input_marked_text);
case NvimBridgeMsgIdDelete: return data_sync(data, outputCondition, neovim_delete);
case NvimBridgeMsgIdFocusGained: return data_sync(data, outputCondition, neovim_focus_gained);
default: return NULL;
} }
case NvimBridgeMsgIdScroll:
return data_async(data, neovim_scroll);
case NvimBridgeMsgIdResize:
return data_async(data, neovim_resize);
case NvimBridgeMsgIdInput:
return data_async(data, neovim_vim_input);
case NvimBridgeMsgIdInputMarked:
return data_async(data, neovim_vim_input_marked_text);
case NvimBridgeMsgIdDelete:
return data_async(data, neovim_delete);
case NvimBridgeMsgIdFocusGained:
return data_async(data, neovim_focus_gained);
default:
CFRelease(data);
return NULL;
} }
} }
@ -108,7 +103,7 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
- (instancetype)initWithLocalServerName:(NSString *)localServerName - (instancetype)initWithLocalServerName:(NSString *)localServerName
remoteServerName:(NSString *)remoteServerName remoteServerName:(NSString *)remoteServerName
nvimArgs:(NSArray<NSString*> *)nvimArgs { nvimArgs:(NSArray<NSString *> *)nvimArgs {
self = [super init]; self = [super init];
if (self == nil) { if (self == nil) {
@ -182,33 +177,31 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
} }
- (void)sendMessageWithId:(NvimServerMsgId)msgid { - (void)sendMessageWithId:(NvimServerMsgId)msgid {
[self sendMessageWithId:msgid data:nil]; [self sendMessageWithId:msgid data:NULL];
} }
- (void)sendMessageWithId:(NvimServerMsgId)msgid data:(NSData *)data { - (void)sendMessageWithId:(NvimServerMsgId)msgid data:(CFDataRef)data {
#ifdef DEBUG_NEOVIM_SERVER_STANDALONE #ifdef DEBUG_NEOVIM_SERVER_STANDALONE
return; return;
#endif #endif
if (_remoteServerPort == NULL) { if (_remoteServerPort == NULL) {
WLOG("Remote server is null: The msg (%lu:%s) could not be sent.", (unsigned long) msgid, data.cdesc); WLOG("Remote server is null: The msg (%lu) could not be sent.", (unsigned long) msgid);
return; return;
} }
SInt32 responseCode = CFMessagePortSendRequest( SInt32 responseCode = CFMessagePortSendRequest(_remoteServerPort, msgid, data, qTimeout, qTimeout, NULL, NULL);
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, NULL, NULL
);
if (responseCode == kCFMessagePortSuccess) { if (responseCode == kCFMessagePortSuccess) {
return; return;
} }
WLOG("The msg (%lu:%s) could not be sent: %d", (unsigned long) msgid, data.cdesc, responseCode); WLOG("The msg (%lu) could not be sent: %d", (unsigned long) msgid, responseCode);
} }
- (void)notifyReadiness { - (void)notifyReadiness {
#ifndef DEBUG_NEOVIM_SERVER_STANDALONE #ifndef DEBUG_NEOVIM_SERVER_STANDALONE
[self sendMessageWithId:NvimServerMsgIdServerReady data:nil]; [self sendMessageWithId:NvimServerMsgIdServerReady data:NULL];
#endif #endif
} }

View File

@ -48,8 +48,8 @@ int main(int argc, const char *argv[]) {
: nil; : nil;
_neovim_server = [[NvimServer alloc] initWithLocalServerName:localServerName _neovim_server = [[NvimServer alloc] initWithLocalServerName:localServerName
remoteServerName:remoteServerName remoteServerName:remoteServerName
nvimArgs:nvimArgs]; nvimArgs:nvimArgs];
DLOG("Started neovim server '%s' with args '%@' and connected it with the remote agent '%s'.", DLOG("Started neovim server '%s' with args '%@' and connected it with the remote agent '%s'.",
localServerName.cstr, nvimArgs, remoteServerName.cstr); localServerName.cstr, nvimArgs, remoteServerName.cstr);

View File

@ -9,8 +9,6 @@
#import "server_ui.h" #import "server_ui.h"
#import "NvimServer.h" #import "NvimServer.h"
#import "CocoaCategories.h" #import "CocoaCategories.h"
#import "DataWrapper.h"
#import "SharedTypes.h"
// FileInfo and Boolean are #defined by Carbon and NeoVim: // FileInfo and Boolean are #defined by Carbon and NeoVim:
// Since we don't need the Carbon versions of them, we rename // Since we don't need the Carbon versions of them, we rename
@ -22,7 +20,6 @@
#import <nvim/api/vim.h> #import <nvim/api/vim.h>
#import <nvim/ui.h> #import <nvim/ui.h>
#import <nvim/ui_bridge.h> #import <nvim/ui_bridge.h>
#import <nvim/ex_getln.h>
#import <nvim/fileio.h> #import <nvim/fileio.h>
#import <nvim/undo.h> #import <nvim/undo.h>
#import <nvim/mouse.h> #import <nvim/mouse.h>
@ -32,8 +29,11 @@
#import <nvim/aucmd.h> #import <nvim/aucmd.h>
#import <nvim/msgpack_rpc/helpers.h> #import <nvim/msgpack_rpc/helpers.h>
#import <msgpack.h> #import <msgpack.h>
#import <nvim/api/private/helpers.h>
#define let __auto_type const
#define var __auto_type
#define pun_type(t, x) (*((t *) (&(x)))) #define pun_type(t, x) (*((t *) (&(x))))
@ -42,10 +42,10 @@ static NSInteger _default_background = 0xFFFFFFFF;
static NSInteger _default_special = 0xFFFF0000; static NSInteger _default_special = 0xFFFF0000;
typedef struct { typedef struct {
UIBridgeData *bridge; UIBridgeData *bridge;
Loop *loop; Loop *loop;
bool stop; bool stop;
} ServerUiData; } ServerUiData;
// We declare nvim_main because it's not declared in any header files of neovim // We declare nvim_main because it's not declared in any header files of neovim
@ -82,11 +82,14 @@ static bool _dirty = false;
static NSInteger _initialWidth = 30; static NSInteger _initialWidth = 30;
static NSInteger _initialHeight = 15; static NSInteger _initialHeight = 15;
static NSMutableArray <NSData *> *_render_data; static msgpack_sbuffer msg_sbuffer;
static msgpack_sbuffer flush_sbuffer;
static msgpack_packer *flush_packer;
#pragma mark Helper functions #pragma mark Helper functions
static inline String vim_string_from(NSString *str) { static inline String vim_string_from(NSString *str) {
return (String) { .data = (char *) str.cstr, .size = str.clength }; return (String) {.data = (char *) str.cstr, .size = str.clength};
} }
static void refresh_ui_screen(int type) { static void refresh_ui_screen(int type) {
@ -105,8 +108,39 @@ static bool has_dirty_docs() {
return false; return false;
} }
static void msgpack_pack_bool(msgpack_packer *packer, bool value) {
if (value) {
msgpack_pack_true(packer);
} else {
msgpack_pack_false(packer);
}
}
typedef void (^pack_block)(msgpack_packer *packer);
static void send_msg_packing(NvimServerMsgId msgid, pack_block body) {
msgpack_packer packer;
msgpack_packer_init(&packer, &msg_sbuffer, msgpack_sbuffer_write);
body(&packer);
let data = CFDataCreateWithBytesNoCopy(
kCFAllocatorDefault, (const UInt8 *) msg_sbuffer.data, msg_sbuffer.size, kCFAllocatorNull
);
[_neovim_server sendMessageWithId:msgid data:data];
CFRelease(data);
msgpack_sbuffer_clear(&msg_sbuffer);
}
static void pack_flush_data(RenderDataType type, pack_block body) {
msgpack_pack_array(flush_packer, 2);
msgpack_pack_int64(flush_packer, type);
body(flush_packer);
}
static void send_dirty_status() { static void send_dirty_status() {
bool new_dirty_status = has_dirty_docs(); var new_dirty_status = has_dirty_docs();
DLOG("dirty status: %d vs. %d", _dirty, new_dirty_status); DLOG("dirty status: %d vs. %d", _dirty, new_dirty_status);
if (_dirty == new_dirty_status) { if (_dirty == new_dirty_status) {
return; return;
@ -114,23 +148,25 @@ static void send_dirty_status() {
_dirty = new_dirty_status; _dirty = new_dirty_status;
DLOG("sending dirty status: %d", _dirty); DLOG("sending dirty status: %d", _dirty);
NSData *data = [[NSData alloc] initWithBytes:&_dirty length:sizeof(bool)];
[_neovim_server sendMessageWithId:NvimServerMsgIdDirtyStatusChanged data:data]; send_msg_packing(NvimServerMsgIdDirtyStatusChanged, ^(msgpack_packer *packer) {
[data release]; msgpack_pack_bool(packer, _dirty);
});
} }
static void send_cwd() { static void send_cwd() {
char_u *temp = xmalloc(MAXPATHL); var temp = xmalloc(MAXPATHL);
if (os_dirname(temp, MAXPATHL) == FAIL) { if (os_dirname(temp, MAXPATHL) == FAIL) {
xfree(temp); xfree(temp);
[_neovim_server sendMessageWithId:NvimServerMsgIdCwdChanged]; [_neovim_server sendMessageWithId:NvimServerMsgIdCwdChanged];
} }
NSString *pwd = [NSString stringWithCString:(const char *) temp encoding:NSUTF8StringEncoding]; send_msg_packing(NvimServerMsgIdCwdChanged, ^(msgpack_packer *packer) {
xfree(temp); let value = cstr_to_string((const char *) temp);
msgpack_rpc_from_string(value, packer);
NSData *resultData = [pwd dataUsingEncoding:NSUTF8StringEncoding]; api_free_string(value);
[_neovim_server sendMessageWithId:NvimServerMsgIdCwdChanged data:resultData]; xfree(temp);
});
} }
static HlAttrs HlAttrsFromAttrCode(int attr_code) { static HlAttrs HlAttrsFromAttrCode(int attr_code) {
@ -139,18 +175,6 @@ static HlAttrs HlAttrsFromAttrCode(int attr_code) {
return rgb_attrs; return rgb_attrs;
} }
static void add_to_render_data(RenderDataType type, NSData *data) {
NSMutableData *rData = [NSMutableData new];
[rData appendBytes:&type length:sizeof(RenderDataType)];
if (data != nil) {
[rData appendData:data];
}
[_render_data addObject:rData];
[rData release];
}
static int foreground_for(HlAttrs attrs) { static int foreground_for(HlAttrs attrs) {
int mask = attrs.rgb_ae_attr; int mask = attrs.rgb_ae_attr;
return mask & HL_INVERSE ? attrs.rgb_bg_color: attrs.rgb_fg_color; return mask & HL_INVERSE ? attrs.rgb_bg_color: attrs.rgb_fg_color;
@ -171,14 +195,14 @@ static void send_colorscheme() {
HlAttrs visualAttrs = HlAttrsFromAttrCode(highlight_attr[HLF_V]); HlAttrs visualAttrs = HlAttrsFromAttrCode(highlight_attr[HLF_V]);
HlAttrs dirAttrs = HlAttrsFromAttrCode(highlight_attr[HLF_D]); HlAttrs dirAttrs = HlAttrsFromAttrCode(highlight_attr[HLF_D]);
NSInteger values[] = { send_msg_packing(NvimServerMsgIdColorSchemeChanged, ^(msgpack_packer *packer) {
normal_fg, normal_bg, msgpack_pack_array(packer, 5);
foreground_for(visualAttrs), background_for(visualAttrs), msgpack_pack_int64(packer, normal_fg);
foreground_for(dirAttrs), msgpack_pack_int64(packer, normal_bg);
}; msgpack_pack_int64(packer, foreground_for(visualAttrs));
NSData *resultData = [NSData dataWithBytes:values length:5 * sizeof(NSInteger)]; msgpack_pack_int64(packer, background_for(visualAttrs));
msgpack_pack_int64(packer, foreground_for(dirAttrs));
[_neovim_server sendMessageWithId:NvimServerMsgIdColorSchemeChanged data:resultData]; });
} }
static void insert_marked_text(NSString *markedText) { static void insert_marked_text(NSString *markedText) {
@ -188,7 +212,7 @@ static void insert_marked_text(NSString *markedText) {
} }
static void delete_marked_text() { static void delete_marked_text() {
NSUInteger length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4; let length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
[_marked_text release]; [_marked_text release];
_marked_text = nil; _marked_text = nil;
@ -203,13 +227,13 @@ static void run_neovim(void *arg) {
char **argv; char **argv;
@autoreleasepool { @autoreleasepool {
NSArray<NSString *> *nvimArgs = (NSArray *) arg; let nvimArgs = (NSArray<NSString *> *) arg;
argc = (int) nvimArgs.count + 1; argc = (int) nvimArgs.count + 1;
argv = (char **) malloc((argc + 1) * sizeof(char *)); argv = (char **) malloc((argc + 1) * sizeof(char *));
argv[0] = "nvim"; argv[0] = "nvim";
for (int i = 0; i < nvimArgs.count; i++) { for (var i = 0; i < nvimArgs.count; i++) {
argv[i + 1] = (char *) nvimArgs[(NSUInteger) i].cstr; argv[i + 1] = (char *) nvimArgs[(NSUInteger) i].cstr;
} }
@ -235,7 +259,9 @@ static void server_ui_scheduler(Event event, void *d) {
} }
static void server_ui_main(UIBridgeData *bridge, UI *ui) { static void server_ui_main(UIBridgeData *bridge, UI *ui) {
_render_data = [NSMutableArray new]; msgpack_sbuffer_init(&msg_sbuffer);
msgpack_sbuffer_init(&flush_sbuffer);
flush_packer = msgpack_packer_new(&flush_sbuffer, msgpack_sbuffer_write);
Loop loop; Loop loop;
loop_init(&loop, NULL); loop_init(&loop, NULL);
@ -265,64 +291,63 @@ static void server_ui_main(UIBridgeData *bridge, UI *ui) {
xfree(_server_ui_data); xfree(_server_ui_data);
xfree(ui); xfree(ui);
[_render_data release]; msgpack_sbuffer_clear(&flush_sbuffer);
msgpack_packer_free(flush_packer);
} }
#pragma mark NeoVim's UI callbacks #pragma mark NeoVim's UI callbacks
static void server_ui_flush(UI *ui __unused) { static void server_ui_flush(UI *ui __unused) {
@autoreleasepool { if (flush_sbuffer.size == 0) {
if (_render_data.count == 0) { return;
return;
}
[_neovim_server sendMessageWithId:NvimServerMsgIdFlush
data:[NSKeyedArchiver archivedDataWithRootObject:_render_data]];
[_render_data removeAllObjects];
} }
let data = CFDataCreateWithBytesNoCopy(
kCFAllocatorDefault, (const UInt8 *) flush_sbuffer.data, flush_sbuffer.size, kCFAllocatorNull
);
[_neovim_server sendMessageWithId:NvimServerMsgIdFlush data:data];
CFRelease(data);
msgpack_sbuffer_clear(&flush_sbuffer);
msgpack_packer_free(flush_packer);
flush_packer = msgpack_packer_new(&flush_sbuffer, msgpack_sbuffer_write);
} }
static void server_ui_resize(UI *ui __unused, Integer width, Integer height) { static void server_ui_resize(UI *ui __unused, Integer width, Integer height) {
@autoreleasepool { server_ui_flush(NULL);
server_ui_flush(NULL);
NSInteger values[] = {width, height}; send_msg_packing(NvimServerMsgIdResize, ^(msgpack_packer *packer) {
NSData *data = [[NSData alloc] initWithBytes:values length:(2 * sizeof(NSInteger))]; msgpack_pack_array(packer, 2);
[_neovim_server sendMessageWithId:NvimServerMsgIdResize data:data]; msgpack_pack_int64(packer, width);
[data release]; msgpack_pack_int64(packer, height);
} });
} }
static void server_ui_clear(UI *ui __unused) { static void server_ui_clear(UI *ui __unused) {
@autoreleasepool { server_ui_flush(NULL);
server_ui_flush(NULL);
}
[_neovim_server sendMessageWithId:NvimServerMsgIdClear]; [_neovim_server sendMessageWithId:NvimServerMsgIdClear];
} }
static void server_ui_eol_clear(UI *ui __unused) { static void server_ui_eol_clear(UI *ui __unused) {
@autoreleasepool { pack_flush_data(RenderDataTypeEolClear, ^(msgpack_packer *packer) {
add_to_render_data(RenderDataTypeEolClear, nil); msgpack_pack_nil(packer);
} });
} }
static void server_ui_cursor_goto(UI *ui __unused, Integer row, Integer col) { static void server_ui_cursor_goto(UI *ui __unused, Integer row, Integer col) {
@autoreleasepool { _put_row = row;
_put_row = row; _put_column = col;
_put_column = col;
NSInteger values[] = { DLOG("%d:%d - %d:%d - %d:%d", row, col, curwin->w_cursor.lnum, curwin->w_cursor.col + 1);
row, col,
(NSInteger) curwin->w_cursor.lnum, curwin->w_cursor.col + 1
};
DLOG("%d:%d - %d:%d - %d:%d", values[0], values[1], values[2], values[3]); pack_flush_data(RenderDataTypeGoto, ^(msgpack_packer *packer) {
msgpack_pack_array(packer, 4);
NSData *data = [[NSData alloc] initWithBytes:values length:(4 * sizeof(NSInteger))]; msgpack_pack_int64(packer, row);
add_to_render_data(RenderDataTypeGoto, data); msgpack_pack_int64(packer, col);
[data release]; msgpack_pack_int64(packer, curwin->w_cursor.lnum);
} msgpack_pack_int64(packer, curwin->w_cursor.col + 1);
});
} }
static void server_ui_update_menu(UI *ui __unused) { static void server_ui_update_menu(UI *ui __unused) {
@ -345,46 +370,40 @@ static void server_ui_mouse_off(UI *ui __unused) {
[_neovim_server sendMessageWithId:NvimServerMsgIdMouseOff]; [_neovim_server sendMessageWithId:NvimServerMsgIdMouseOff];
} }
static void server_ui_mode_info_set(UI *ui __unused, Boolean enabled __unused, static void server_ui_mode_info_set(UI *ui __unused, Boolean enabled __unused, Array cursor_styles __unused) {
Array cursor_styles __unused) {
// yet noop // yet noop
} }
static void server_ui_mode_change(UI *ui __unused, String mode_str __unused, Integer mode) { static void server_ui_mode_change(UI *ui __unused, String mode_str __unused, Integer mode) {
@autoreleasepool { @autoreleasepool {
NSInteger value = mode; send_msg_packing(NvimServerMsgIdModeChange, ^(msgpack_packer *packer) {
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))]; msgpack_pack_int64(packer, mode);
[_neovim_server sendMessageWithId:NvimServerMsgIdModeChange data:data]; });
[data release];
} }
} }
static void server_ui_set_scroll_region(UI *ui __unused, Integer top, Integer bot, static void server_ui_set_scroll_region(UI *ui __unused, Integer top, Integer bot, Integer left, Integer right) {
Integer left, Integer right) { server_ui_flush(NULL);
@autoreleasepool { send_msg_packing(NvimServerMsgIdSetScrollRegion, ^(msgpack_packer *packer) {
server_ui_flush(NULL); msgpack_pack_array(packer, 4);
msgpack_pack_int64(packer, top);
NSInteger values[] = {top, bot, left, right}; msgpack_pack_int64(packer, bot);
NSData *data = [[NSData alloc] initWithBytes:values length:(4 * sizeof(NSInteger))]; msgpack_pack_int64(packer, left);
[_neovim_server sendMessageWithId:NvimServerMsgIdSetScrollRegion data:data]; msgpack_pack_int64(packer, right);
[data release]; });
}
} }
static void server_ui_scroll(UI *ui __unused, Integer count) { static void server_ui_scroll(UI *ui __unused, Integer count) {
@autoreleasepool { server_ui_flush(NULL);
server_ui_flush(NULL);
NSInteger value = count; send_msg_packing(NvimServerMsgIdScroll, ^(msgpack_packer *packer) {
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))]; msgpack_pack_int64(packer, count);
[_neovim_server sendMessageWithId:NvimServerMsgIdScroll data:data]; });
[data release];
}
} }
static void server_ui_highlight_set(UI *ui __unused, HlAttrs attrs) { static void server_ui_highlight_set(UI *ui __unused, HlAttrs attrs) {
FontTrait trait = FontTraitNone; var trait = FontTraitNone;
if (attrs.rgb_ae_attr & HL_ITALIC) { if (attrs.rgb_ae_attr & HL_ITALIC) {
trait |= FontTraitItalic; trait |= FontTraitItalic;
} }
@ -400,52 +419,49 @@ static void server_ui_highlight_set(UI *ui __unused, HlAttrs attrs) {
CellAttributes cellAttrs; CellAttributes cellAttrs;
cellAttrs.fontTrait = trait; cellAttrs.fontTrait = trait;
NSInteger fg = attrs.rgb_fg_color == -1 ? _default_foreground : attrs.rgb_fg_color; let fg = attrs.rgb_fg_color == -1 ? _default_foreground : attrs.rgb_fg_color;
NSInteger bg = attrs.rgb_bg_color == -1 ? _default_background : attrs.rgb_bg_color; let bg = attrs.rgb_bg_color == -1 ? _default_background : attrs.rgb_bg_color;
cellAttrs.foreground = attrs.rgb_ae_attr & HL_INVERSE ? bg : fg; cellAttrs.foreground = attrs.rgb_ae_attr & HL_INVERSE ? bg : fg;
cellAttrs.background = attrs.rgb_ae_attr & HL_INVERSE ? fg : bg; cellAttrs.background = attrs.rgb_ae_attr & HL_INVERSE ? fg : bg;
cellAttrs.special = attrs.rgb_sp_color == -1 ? _default_special : pun_type(unsigned int, attrs.rgb_sp_color); cellAttrs.special = attrs.rgb_sp_color == -1 ? _default_special : pun_type(unsigned int, attrs.rgb_sp_color);
@autoreleasepool { pack_flush_data(RenderDataTypeHighlight, ^(msgpack_packer *packer) {
NSData *data = [[NSData alloc] initWithBytes:&cellAttrs length:sizeof(CellAttributes)]; msgpack_pack_bin(packer, sizeof(cellAttrs));
add_to_render_data(RenderDataTypeHighlight, data); msgpack_pack_bin_body(packer, &cellAttrs, sizeof(cellAttrs));
[data release]; });
}
} }
static void server_ui_put(UI *ui __unused, String str) { static void server_ui_put(UI *ui __unused, String str) {
NSString *string = [[NSString alloc] initWithBytes:str.data if (_marked_text != nil
length:str.size && _marked_row == _put_row
encoding:NSUTF8StringEncoding]; && _marked_column == _put_column) {
@autoreleasepool { DLOG("putting marked text: '%s'", str.data);
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; pack_flush_data(RenderDataTypePutMarked, ^(msgpack_packer *packer) {
msgpack_rpc_from_string(str, packer);
});
if (_marked_text != nil && _marked_row == _put_row && _marked_column == _put_column) { } else if (_marked_text != nil
&& str.size == 0
&& _marked_row == _put_row
&& _marked_column == _put_column - 1) {
DLOG("putting marked text: '%s'", string.cstr); DLOG("putting marked text cuz zero");
add_to_render_data(RenderDataTypePutMarked, data); pack_flush_data(RenderDataTypePutMarked, ^(msgpack_packer *packer) {
msgpack_rpc_from_string(str, packer);
});
} else if (_marked_text != nil } else {
&& str.size == 0
&& _marked_row == _put_row
&& _marked_column == _put_column - 1) {
DLOG("putting marked text cuz zero"); DLOG("putting non-marked text: '%s'", str.data);
add_to_render_data(RenderDataTypePutMarked, data); pack_flush_data(RenderDataTypePut, ^(msgpack_packer *packer) {
msgpack_rpc_from_string(str, packer);
});
} else {
DLOG("putting non-marked text: '%s'", string.cstr);
add_to_render_data(RenderDataTypePut, data);
}
_put_column += 1;
[string release];
} }
_put_column += 1;
} }
static void server_ui_bell(UI *ui __unused) { static void server_ui_bell(UI *ui __unused) {
@ -458,65 +474,38 @@ static void server_ui_visual_bell(UI *ui __unused) {
static void server_ui_update_fg(UI *ui __unused, Integer fg) { static void server_ui_update_fg(UI *ui __unused, Integer fg) {
@autoreleasepool { @autoreleasepool {
NSInteger value[1]; if (fg != -1) {
_default_foreground = fg;
if (fg == -1) {
value[0] = _default_foreground;
NSData *data = [[NSData alloc] initWithBytes:value length:(1 * sizeof(NSInteger))];
[_neovim_server sendMessageWithId:NvimServerMsgIdSetForeground data:data];
[data release];
return;
} }
_default_foreground = fg; send_msg_packing(NvimServerMsgIdSetForeground, ^(msgpack_packer *packer) {
msgpack_pack_int64(packer, _default_foreground);
value[0] = fg; });
NSData *data = [[NSData alloc] initWithBytes:value length:(1 * sizeof(NSInteger))];
[_neovim_server sendMessageWithId:NvimServerMsgIdSetForeground data:data];
[data release];
} }
} }
static void server_ui_update_bg(UI *ui __unused, Integer bg) { static void server_ui_update_bg(UI *ui __unused, Integer bg) {
@autoreleasepool { @autoreleasepool {
NSInteger value[1]; if (bg != -1) {
_default_background = bg;
if (bg == -1) {
value[0] = _default_background;
NSData *data = [[NSData alloc] initWithBytes:value length:(1 * sizeof(NSInteger))];
[_neovim_server sendMessageWithId:NvimServerMsgIdSetBackground data:data];
[data release];
return;
} }
_default_background = bg; send_msg_packing(NvimServerMsgIdSetBackground, ^(msgpack_packer *packer) {
value[0] = bg; msgpack_pack_int64(packer, _default_background);
NSData *data = [[NSData alloc] initWithBytes:value length:(1 * sizeof(NSInteger))]; });
[_neovim_server sendMessageWithId:NvimServerMsgIdSetBackground data:data];
[data release];
} }
} }
static void server_ui_update_sp(UI *ui __unused, Integer sp) { static void server_ui_update_sp(UI *ui __unused, Integer sp) {
@autoreleasepool { @autoreleasepool {
NSInteger value[2]; if (sp != -1) {
_default_special = sp;
if (sp == -1) {
value[0] = _default_special;
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))];
[_neovim_server sendMessageWithId:NvimServerMsgIdSetSpecial data:data];
[data release];
return;
} }
_default_special = sp;
value[0] = sp; send_msg_packing(NvimServerMsgIdSetSpecial, ^(msgpack_packer *packer) {
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))]; msgpack_pack_int64(packer, _default_special);
[_neovim_server sendMessageWithId:NvimServerMsgIdSetSpecial data:data]; });
[data release];
} }
} }
@ -536,10 +525,11 @@ static void server_ui_default_colors_set(
_default_special = rgb_sp; _default_special = rgb_sp;
} }
NSInteger values[] = { rgb_fg, rgb_bg, rgb_sp }; send_msg_packing(NvimServerMsgIdDefaultColorsChanged, ^(msgpack_packer *packer) {
NSData *resultData = [NSData dataWithBytes:values length:3 * sizeof(NSInteger)]; msgpack_pack_int64(packer, _default_foreground);
msgpack_pack_int64(packer, _default_background);
[_neovim_server sendMessageWithId:NvimServerMsgIdDefaultColorsChanged data:resultData]; msgpack_pack_int64(packer, _default_special);
});
} }
static void server_ui_set_title(UI *ui __unused, String title) { static void server_ui_set_title(UI *ui __unused, String title) {
@ -548,10 +538,9 @@ static void server_ui_set_title(UI *ui __unused, String title) {
return; return;
} }
NSString *string = [[NSString alloc] initWithCString:title.data encoding:NSUTF8StringEncoding]; send_msg_packing(NvimServerMsgIdSetTitle, ^(msgpack_packer *packer) {
[_neovim_server sendMessageWithId:NvimServerMsgIdSetTitle msgpack_rpc_from_string(title, packer);
data:[string dataUsingEncoding:NSUTF8StringEncoding]]; });
[string release];
} }
} }
@ -561,10 +550,9 @@ static void server_ui_set_icon(UI *ui __unused, String icon) {
return; return;
} }
NSString *string = [[NSString alloc] initWithCString:icon.data encoding:NSUTF8StringEncoding]; send_msg_packing(NvimServerMsgIdSetTitle, ^(msgpack_packer *packer) {
[_neovim_server sendMessageWithId:NvimServerMsgIdSetIcon msgpack_rpc_from_string(icon, packer);
data:[string dataUsingEncoding:NSUTF8StringEncoding]]; });
[string release];
} }
} }
@ -592,7 +580,7 @@ static void server_ui_option_set(UI *ui __unused, String name, Object value) {
static void server_ui_stop(UI *ui __unused) { static void server_ui_stop(UI *ui __unused) {
[_neovim_server sendMessageWithId:NvimServerMsgIdStop]; [_neovim_server sendMessageWithId:NvimServerMsgIdStop];
ServerUiData *data = (ServerUiData *) ui->data; let data = (ServerUiData *) ui->data;
data->stop = true; data->stop = true;
} }
@ -663,42 +651,35 @@ void custom_ui_autocmds_groups(
} }
if (event == EVENT_TEXTCHANGED if (event == EVENT_TEXTCHANGED
|| event == EVENT_TEXTCHANGEDI || event == EVENT_TEXTCHANGEDI
|| event == EVENT_BUFWRITEPOST || event == EVENT_BUFWRITEPOST
|| event == EVENT_BUFLEAVE) || event == EVENT_BUFLEAVE) {
{
send_dirty_status(); send_dirty_status();
} }
NSInteger eventCode = (NSInteger) event; send_msg_packing(NvimServerMsgIdAutoCommandEvent, ^(msgpack_packer *packer) {
msgpack_pack_array(packer, 2);
NSMutableData *data; msgpack_pack_int64(packer, (NSInteger) event);
if (buf == NULL) { if (buf == NULL) {
data = [[NSMutableData alloc] initWithBytes:&eventCode length:sizeof(NSInteger)]; msgpack_pack_int64(packer, -1);
} else { } else {
NSInteger bufHandle = buf->handle; msgpack_pack_int64(packer, (NSInteger) buf->handle);
}
data = [[NSMutableData alloc] initWithCapacity:(sizeof(NSInteger) + sizeof(NSInteger))]; });
[data appendBytes:&eventCode length:sizeof(NSInteger)];
[data appendBytes:&bufHandle length:sizeof(NSInteger)];
}
[_neovim_server sendMessageWithId:NvimServerMsgIdAutoCommandEvent data:data];
[data release];
} }
} }
#pragma mark Other help functions #pragma mark Other help functions
void start_neovim(NSInteger width, NSInteger height, NSArray<NSString *> *args) { void start_neovim(NSInteger width, NSInteger height, NSArray<NSString *> *args) {
// The caller has an @autoreleasepool.
_initialWidth = width; _initialWidth = width;
_initialHeight = height; _initialHeight = height;
// set $VIMRUNTIME to ${RESOURCE_PATH_OF_XPC_BUNDLE}/runtime // set $VIMRUNTIME to ${RESOURCE_PATH_OF_XPC_BUNDLE}/runtime
NSString *bundlePath = [NSBundle bundleForClass:[NvimServer class]].bundlePath; let bundlePath = [NSBundle bundleForClass:[NvimServer class]].bundlePath;
NSString *resourcesPath = [bundlePath.stringByDeletingLastPathComponent let resourcesPath = [bundlePath.stringByDeletingLastPathComponent stringByAppendingPathComponent:@"Resources"];
stringByAppendingPathComponent:@"Resources"]; let runtimePath = [resourcesPath stringByAppendingPathComponent:@"runtime"];
NSString *runtimePath = [resourcesPath stringByAppendingPathComponent:@"runtime"];
setenv("VIMRUNTIME", runtimePath.fileSystemRepresentation, true); setenv("VIMRUNTIME", runtimePath.fileSystemRepresentation, true);
// Set $LANG to en_US.UTF-8 such that the copied text to the system clipboard is not garbled. // Set $LANG to en_US.UTF-8 such that the copied text to the system clipboard is not garbled.
@ -722,10 +703,9 @@ void start_neovim(NSInteger width, NSInteger height, NSArray<NSString *> *args)
_backspace = [[NSString alloc] initWithString:@"<BS>"]; _backspace = [[NSString alloc] initWithString:@"<BS>"];
bool value = msg_didany > 0; send_msg_packing(NvimServerMsgIdNvimReady, ^(msgpack_packer *packer) {
NSData *data = [[NSData alloc] initWithBytes:&value length:sizeof(bool)]; msgpack_pack_bool(packer, msg_didany > 0);
[_neovim_server sendMessageWithId:NvimServerMsgIdNvimReady data:data]; });
[data release];
// We have to manually trigger this to initially get the colorscheme. // We have to manually trigger this to initially get the colorscheme.
send_colorscheme(); send_colorscheme();
@ -733,42 +713,26 @@ void start_neovim(NSInteger width, NSInteger height, NSArray<NSString *> *args)
#pragma mark Functions for neovim's main loop #pragma mark Functions for neovim's main loop
typedef NSData *(^work_block)(NSData *); typedef void (^async_work_block)(NSData *);
static void work_and_write_data_sync(void **argv, work_block block) { static void work_async(void **argv, async_work_block block) {
@autoreleasepool { @autoreleasepool {
NSCondition *outputCondition = argv[1];
[outputCondition lock];
NSData *data = argv[0]; NSData *data = argv[0];
DataWrapper *wrapper = argv[2]; block(data);
wrapper.data = block(data);
wrapper.dataReady = YES;
[data release]; // retained in local_server_callback [data release]; // retained in local_server_callback
[outputCondition signal];
[outputCondition unlock];
} }
} }
//static void work_async(void **argv, work_block block) {
// @autoreleasepool {
// NSData *data = argv[0];
// block(data);
// [data release]; // retained in local_server_callback
// }
//}
void neovim_scroll(void **argv) { void neovim_scroll(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
NSInteger *values = (NSInteger *) data.bytes; let values = (NSInteger *) data.bytes;
int horiz = (int) values[0]; int horiz = (int) values[0];
int vert = (int) values[1]; int vert = (int) values[1];
int row = (int) values[2]; int row = (int) values[2];
int column = (int) values[3]; int column = (int) values[3];
if (horiz == 0 && vert == 0) { if (horiz == 0 && vert == 0) {
return nil; return;
} }
if (row < 0 || column < 0) { if (row < 0 || column < 0) {
@ -780,41 +744,37 @@ void neovim_scroll(void **argv) {
int horizDir; int horizDir;
int vertDir; int vertDir;
if (horiz != 0) { if (horiz != 0) {
horizDir = horiz > 0 ? MSCR_RIGHT: MSCR_LEFT; horizDir = horiz > 0 ? MSCR_RIGHT : MSCR_LEFT;
custom_ui_scroll(horizDir, ABS(horiz), row, column); custom_ui_scroll(horizDir, ABS(horiz), row, column);
} }
if (vert != 0) { if (vert != 0) {
vertDir = vert > 0 ? MSCR_DOWN: MSCR_UP; vertDir = vert > 0 ? MSCR_DOWN : MSCR_UP;
custom_ui_scroll(vertDir, ABS(vert), row, column); custom_ui_scroll(vertDir, ABS(vert), row, column);
} }
refresh_ui_screen(VALID); refresh_ui_screen(VALID);
return nil;
}); });
} }
void neovim_resize(void **argv) { void neovim_resize(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
const NSInteger *values = data.bytes; const NSInteger *values = data.bytes;
NSInteger width = values[0]; let width = values[0];
NSInteger height = values[1]; let height = values[1];
set_ui_size(_server_ui_data->bridge, (int) width, (int) height); set_ui_size(_server_ui_data->bridge, (int) width, (int) height);
ui_refresh(); ui_refresh();
return nil;
}); });
} }
void neovim_vim_input(void **argv) { void neovim_vim_input(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
NSString *input = [[[NSString alloc] initWithData:data let input = [[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding] autorelease]; encoding:NSUTF8StringEncoding] autorelease];
if (_marked_text == nil) { if (_marked_text == nil) {
nvim_input(vim_string_from(input)); nvim_input(vim_string_from(input));
return nil; return;
} }
// Handle cases like -> arrow key: The previously marked text is the same as the finalized // Handle cases like -> arrow key: The previously marked text is the same as the finalized
@ -827,31 +787,29 @@ void neovim_vim_input(void **argv) {
for (int i = 1; i <= cellCount; i++) { for (int i = 1; i <= cellCount; i++) {
DLOG("unmarking at %d:%d", _put_row, _put_column - i); DLOG("unmarking at %d:%d", _put_row, _put_column - i);
NSInteger values[] = {_put_row, MAX(_put_column - i, 0)}; send_msg_packing(NvimServerMsgIdUnmark, ^(msgpack_packer *packer) {
msgpack_pack_array(packer, 2);
NSData *unmarkData = [[NSData alloc] initWithBytes:values length:(2 * sizeof(NSInteger))]; msgpack_pack_int64(packer, _put_row);
[_neovim_server sendMessageWithId:NvimServerMsgIdUnmark data:unmarkData]; msgpack_pack_int64(packer, MAX(_put_column - i, 0));
[unmarkData release]; });
} }
} }
delete_marked_text(); delete_marked_text();
nvim_input(vim_string_from(input)); nvim_input(vim_string_from(input));
return nil;
}); });
} }
void neovim_vim_input_marked_text(void **argv) { void neovim_vim_input_marked_text(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
NSString *markedText = [[[NSString alloc] initWithData:data let markedText = [[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding] autorelease]; encoding:NSUTF8StringEncoding] autorelease];
if (_marked_text == nil) { if (_marked_text == nil) {
_marked_row = _put_row; _marked_row = _put_row;
_marked_column = _put_column + _marked_delta; _marked_column = _put_column + _marked_delta;
DLOG( DLOG(
"marking position: %d:%d(%d + %d)", _put_row, _marked_column, _put_column, _marked_delta "marking position: %d:%d(%d + %d)", _put_row, _marked_column, _put_column, _marked_delta
); );
_marked_delta = 0; _marked_delta = 0;
} else { } else {
@ -860,13 +818,11 @@ void neovim_vim_input_marked_text(void **argv) {
DLOG("inserting marked text '%s' at %d:%d", markedText.cstr, _put_row, _put_column); DLOG("inserting marked text '%s' at %d:%d", markedText.cstr, _put_row, _put_column);
insert_marked_text(markedText); insert_marked_text(markedText);
return nil;
}); });
} }
void neovim_delete(void **argv) { void neovim_delete(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
const NSInteger *values = data.bytes; const NSInteger *values = data.bytes;
NSInteger count = values[0]; NSInteger count = values[0];
@ -895,23 +851,19 @@ void neovim_delete(void **argv) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
nvim_input(vim_string_from(_backspace)); nvim_input(vim_string_from(_backspace));
} }
return nil;
}); });
} }
void neovim_focus_gained(void **argv) { void neovim_focus_gained(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
const bool *values = data.bytes; const bool *values = data.bytes;
aucmd_schedule_focusgained(values[0]); aucmd_schedule_focusgained(values[0]);
return nil;
}); });
} }
void neovim_debug1(void **argv) { void neovim_debug1(void **argv) {
work_and_write_data_sync(argv, ^NSData *(NSData *data) { work_async(argv, ^(NSData *data) {
NSLog(@"normal fg: %#08X", normal_fg); NSLog(@"normal fg: %#08X", normal_fg);
NSLog(@"normal bg: %#08X", normal_bg); NSLog(@"normal bg: %#08X", normal_bg);
NSLog(@"normal sp: %#08X", normal_sp); NSLog(@"normal sp: %#08X", normal_sp);
@ -919,7 +871,5 @@ void neovim_debug1(void **argv) {
for (int i = 0; i < HLF_COUNT; i++) { for (int i = 0; i < HLF_COUNT; i++) {
NSLog(@"%s: %#08X", hlf_names[i], HlAttrsFromAttrCode(highlight_attr[i]).rgb_fg_color); NSLog(@"%s: %#08X", hlf_names[i], HlAttrsFromAttrCode(highlight_attr[i]).rgb_fg_color);
} }
return nil;
}); });
} }

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1929B30D6C4175835D1F5B21 /* MessagePackCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B44323D6611E2927EC3B /* MessagePackCommons.swift */; };
1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */; }; 1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */; };
1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */; }; 1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */; };
1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B52174EC68D2974B5BAE /* UiBridge.swift */; }; 1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B52174EC68D2974B5BAE /* UiBridge.swift */; };
@ -38,7 +39,6 @@
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 */; };
4B90F06A1FD2AFF7008A39E0 /* DataWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0611FD2AFF7008A39E0 /* DataWrapper.m */; };
4B90F06B1FD2AFF7008A39E0 /* NvimServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */; }; 4B90F06B1FD2AFF7008A39E0 /* NvimServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */; };
4B9E5E1C20990DF2006455C3 /* RxMessagePort.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9E5E1B20990DF1006455C3 /* RxMessagePort.framework */; }; 4B9E5E1C20990DF2006455C3 /* RxMessagePort.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9E5E1B20990DF1006455C3 /* RxMessagePort.framework */; };
4BB1F5C9209740E400EC394A /* RxMsgpackRpc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BB1F5C8209740E400EC394A /* RxMsgpackRpc.framework */; }; 4BB1F5C9209740E400EC394A /* RxMsgpackRpc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BB1F5C8209740E400EC394A /* RxMsgpackRpc.framework */; };
@ -94,6 +94,7 @@
/* 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>"; };
1929B44323D6611E2927EC3B /* MessagePackCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagePackCommons.swift; 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>"; }; 1929B52174EC68D2974B5BAE /* UiBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UiBridge.swift; sourceTree = "<group>"; };
1929B6F4B70B90F7CFB7B523 /* RxSwiftCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxSwiftCommons.swift; sourceTree = "<group>"; }; 1929B6F4B70B90F7CFB7B523 /* RxSwiftCommons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxSwiftCommons.swift; sourceTree = "<group>"; };
@ -130,8 +131,6 @@
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>"; };
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>"; };
4B90F0611FD2AFF7008A39E0 /* DataWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataWrapper.m; sourceTree = "<group>"; };
4B90F0621FD2AFF7008A39E0 /* NvimServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NvimServer.h; sourceTree = "<group>"; }; 4B90F0621FD2AFF7008A39E0 /* NvimServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NvimServer.h; sourceTree = "<group>"; };
4B90F0631FD2AFF7008A39E0 /* server_ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server_ui.h; sourceTree = "<group>"; }; 4B90F0631FD2AFF7008A39E0 /* server_ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server_ui.h; sourceTree = "<group>"; };
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>"; };
@ -225,6 +224,7 @@
1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */, 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */,
1929B52174EC68D2974B5BAE /* UiBridge.swift */, 1929B52174EC68D2974B5BAE /* UiBridge.swift */,
1929B6F4B70B90F7CFB7B523 /* RxSwiftCommons.swift */, 1929B6F4B70B90F7CFB7B523 /* RxSwiftCommons.swift */,
1929B44323D6611E2927EC3B /* MessagePackCommons.swift */,
); );
path = NvimView; path = NvimView;
sourceTree = "<group>"; sourceTree = "<group>";
@ -235,8 +235,6 @@
4B90F0511FD2AFD3008A39E0 /* main.m */, 4B90F0511FD2AFD3008A39E0 /* main.m */,
4B90F0571FD2AFF7008A39E0 /* CocoaCategories.h */, 4B90F0571FD2AFF7008A39E0 /* CocoaCategories.h */,
4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */, 4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */,
4B90F05C1FD2AFF7008A39E0 /* DataWrapper.h */,
4B90F0611FD2AFF7008A39E0 /* DataWrapper.m */,
4B90F05B1FD2AFF7008A39E0 /* Logging.h */, 4B90F05B1FD2AFF7008A39E0 /* Logging.h */,
4B90F0621FD2AFF7008A39E0 /* NvimServer.h */, 4B90F0621FD2AFF7008A39E0 /* NvimServer.h */,
4B90F0641FD2AFF7008A39E0 /* NvimServer.m */, 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */,
@ -406,6 +404,7 @@
1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */, 1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */,
1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */, 1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */,
1929BA93BDEA029011F034FF /* RxSwiftCommons.swift in Sources */, 1929BA93BDEA029011F034FF /* RxSwiftCommons.swift in Sources */,
1929B30D6C4175835D1F5B21 /* MessagePackCommons.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -417,7 +416,6 @@
4B90F0661FD2AFF7008A39E0 /* server_ui.m in Sources */, 4B90F0661FD2AFF7008A39E0 /* server_ui.m in Sources */,
4B90F0521FD2AFD3008A39E0 /* main.m in Sources */, 4B90F0521FD2AFD3008A39E0 /* main.m in Sources */,
4B90F0681FD2AFF7008A39E0 /* CocoaCategories.m in Sources */, 4B90F0681FD2AFF7008A39E0 /* CocoaCategories.m in Sources */,
4B90F06A1FD2AFF7008A39E0 /* DataWrapper.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -464,7 +462,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 275; CURRENT_PROJECT_VERSION = 277;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
@ -524,7 +522,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 275; CURRENT_PROJECT_VERSION = 277;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -551,7 +549,7 @@
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 275; DYLIB_CURRENT_VERSION = 277;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac"; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
FRAMEWORK_VERSION = A; FRAMEWORK_VERSION = A;
@ -573,7 +571,7 @@
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 275; DYLIB_CURRENT_VERSION = 277;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac"; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
FRAMEWORK_VERSION = A; FRAMEWORK_VERSION = A;

View File

@ -15,9 +15,9 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.23.0</string> <string>SNAPSHOT-277</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>275</string> <string>277</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 Tae Won Ha. All rights reserved.</string> <string>Copyright © 2017 Tae Won Ha. All rights reserved.</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@ -0,0 +1,18 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Foundation
import MessagePack
extension MessagePackValue {
var intValue: Int? {
guard let i64 = self.integerValue else {
return nil
}
return Int(i64)
}
}

View File

@ -6,6 +6,7 @@
import Cocoa import Cocoa
import RxNeovimApi import RxNeovimApi
import RxSwift import RxSwift
import MessagePack
extension NvimView { extension NvimView {
@ -67,59 +68,51 @@ extension NvimView {
} }
} }
func flush(_ renderData: [Data]) { func flush(_ renderData: [MessagePackValue]) {
self.bridgeLogger.hr() self.bridgeLogger.hr()
gui.async { gui.async {
var goto: Position? = nil var goto: Position? = nil
renderData.forEach { data in renderData.forEach { value in
data.withUnsafeBytes { (pointer: UnsafePointer<RenderDataType>) in guard let renderEntry = value.arrayValue,
let sizeOfType = MemoryLayout<RenderDataType>.size renderEntry.count == 2,
let rawPointer = UnsafeRawPointer(pointer).advanced(by: sizeOfType); let rawType = renderEntry[0].intValue,
let renderType = pointer[0] let type = RenderDataType(rawValue: rawType) else { return }
switch renderType { switch type {
case .put: case .put:
guard let str = String(data: Data(bytes: rawPointer, count: data.count - sizeOfType), guard let str = renderEntry[1].stringValue else { return }
encoding: .utf8) self.doPut(string: str)
else {
break case .putMarked:
} guard let str = renderEntry[1].stringValue else { return }
self.doPut(markedText: str)
self.doPut(string: str)
case .highlight:
case .putMarked: guard let data = renderEntry[1].dataValue else { return }
guard let str = String(data: Data(bytes: rawPointer, count: data.count - sizeOfType), let attr = data.withUnsafeBytes { (pointer: UnsafePointer<CellAttributes>) in pointer.pointee }
encoding: .utf8) self.doHighlightSet(attr)
else {
break case .goto:
} guard let rawValues = renderEntry[1].arrayValue else { return }
let values = rawValues.compactMap { $0.intValue }
self.doPut(markedText: str) guard values.count == 4 else { return }
goto = Position(row: values[2], column: values[3])
case .highlight: self.doGoto(position: Position(row: values[0], column: values[1]), textPosition: goto!)
let attr = rawPointer.load(as: CellAttributes.self)
self.doHighlightSet(attr) case .eolClear:
self.doEolClear()
case .goto:
let values = rawPointer.bindMemory(to: Int.self, capacity: 4)
goto = Position(row: values[2], column: values[3])
self.doGoto(position: Position(row: values[0], column: values[1]), textPosition: goto!)
case .eolClear:
self.doEolClear()
}
} }
} }
if let pos = goto { if let pos = goto {
self.eventsSubject.onNext(.cursor(pos)) self.eventsSubject.onNext(.cursor(pos))
} }
self.shouldDrawCursor = true self.shouldDrawCursor = true
if self.usesLigatures { if self.usesLigatures {
self.markForRender(region: self.grid.regionOfWord(at: self.grid.position)) self.markForRender(region: self.grid.regionOfWord(at: self.grid.position))
} else { } else {
@ -250,8 +243,6 @@ extension NvimView {
self.markForRender(cellPosition: self.grid.position) self.markForRender(cellPosition: self.grid.position)
self.grid.goto(position) self.grid.goto(position)
self.eventsSubject.onNext(.cursor(textPosition))
} }
func doEolClear() { func doEolClear() {

View File

@ -28,7 +28,7 @@ class UiBridge {
case unmark(row: Int, column: Int) case unmark(row: Int, column: Int)
case bell case bell
case visualBell case visualBell
case flush([Data]) case flush([MessagePackValue])
case setForeground(Int) case setForeground(Int)
case setBackground(Int) case setBackground(Int)
case setSpecial(Int) case setSpecial(Int)
@ -162,16 +162,18 @@ class UiBridge {
self.streamSubject.onNext(.ready) self.streamSubject.onNext(.ready)
let isInitErrorPresent = data?.asArray(ofType: Bool.self, count: 1)?[0] ?? false let isInitErrorPresent = value(from: data, conversion: { $0.boolValue }) ?? false
if isInitErrorPresent { if isInitErrorPresent {
self.streamSubject.onNext(.initVimError) self.streamSubject.onNext(.initVimError)
} }
case .resize: case .resize:
guard let values = data?.asArray(ofType: Int.self, count: 2) else { guard let values = array(from: data, ofSize: 2, conversion: { v -> Int? in
guard let i64 = v.integerValue else { return nil }
return Int(i64)
}) else {
return return
} }
self.streamSubject.onNext(.resize(width: values[0], height: values[1])) self.streamSubject.onNext(.resize(width: values[0], height: values[1]))
case .clear: case .clear:
@ -193,28 +195,31 @@ class UiBridge {
self.streamSubject.onNext(.mouseOff) self.streamSubject.onNext(.mouseOff)
case .modeChange: case .modeChange:
guard let values = data?.asArray(ofType: CursorModeShape.self, count: 1) else { guard let value = value(from: data, conversion: { v -> CursorModeShape? in
guard let i64 = v.integerValue else { return nil }
return CursorModeShape(rawValue: UInt(i64))
}) else {
return return
} }
self.streamSubject.onNext(.modeChange(values[0])) self.streamSubject.onNext(.modeChange(value))
case .setScrollRegion: case .setScrollRegion:
guard let values = data?.asArray(ofType: Int.self, count: 4) else { guard let values = array(from: data, ofSize: 4, conversion: { $0.intValue }) else {
return return
} }
self.streamSubject.onNext(.setScrollRegion(top: values[0], bottom: values[1], left: values[2], right: values[3])) self.streamSubject.onNext(.setScrollRegion(top: values[0], bottom: values[1], left: values[2], right: values[3]))
case .scroll: case .scroll:
guard let values = data?.asArray(ofType: Int.self, count: 1) else { guard let value = value(from: data, conversion: { $0.intValue }) else {
return return
} }
self.streamSubject.onNext(.scroll(values[0])) self.streamSubject.onNext(.scroll(value))
case .unmark: case .unmark:
guard let values = data?.asArray(ofType: Int.self, count: 2) else { guard let values = array(from: data, ofSize: 2, conversion: { $0.intValue }) else {
return return
} }
@ -227,42 +232,42 @@ class UiBridge {
self.streamSubject.onNext(.visualBell) self.streamSubject.onNext(.visualBell)
case .flush: case .flush:
guard let d = data, let renderData = NSKeyedUnarchiver.unarchiveObject(with: d) as? [Data] else { guard let d = data, let renderData = try? unpackAll(d) else {
return return
} }
self.streamSubject.onNext(.flush(renderData)) self.streamSubject.onNext(.flush(renderData))
case .setForeground: case .setForeground:
guard let values = data?.asArray(ofType: Int.self, count: 1) else { guard let value = value(from: data, conversion: { $0.intValue }) else {
return return
} }
self.streamSubject.onNext(.setForeground(values[0])) self.streamSubject.onNext(.setForeground(value))
case .setBackground: case .setBackground:
guard let values = data?.asArray(ofType: Int.self, count: 1) else { guard let value = value(from: data, conversion: { $0.intValue }) else {
return return
} }
self.streamSubject.onNext(.setBackground(values[0])) self.streamSubject.onNext(.setBackground(value))
case .setSpecial: case .setSpecial:
guard let values = data?.asArray(ofType: Int.self, count: 1) else { guard let value = value(from: data, conversion: { $0.intValue }) else {
return return
} }
self.streamSubject.onNext(.setSpecial(values[0])) self.streamSubject.onNext(.setSpecial(value))
case .setTitle: case .setTitle:
guard let d = data, let title = String(data: d, encoding: .utf8) else { guard let title = value(from: data, conversion: { $0.stringValue }) else {
return return
} }
self.streamSubject.onNext(.setTitle(title)) self.streamSubject.onNext(.setTitle(title))
case .setIcon: case .setIcon:
guard let d = data, let icon = String(data: d, encoding: .utf8) else { guard let icon = value(from: data, conversion: { $0.stringValue }) else {
return return
} }
@ -272,31 +277,32 @@ class UiBridge {
self.streamSubject.onNext(.stop) self.streamSubject.onNext(.stop)
case .dirtyStatusChanged: case .dirtyStatusChanged:
guard let values = data?.asArray(ofType: Bool.self, count: 1) else { guard let value = value(from: data, conversion: { $0.boolValue }) else {
return return
} }
self.streamSubject.onNext(.dirtyStatusChanged(values[0])) self.streamSubject.onNext(.dirtyStatusChanged(value))
case .cwdChanged: case .cwdChanged:
guard let d = data, let cwd = String(data: d, encoding: .utf8) else { guard let cwd = value(from: data, conversion: { $0.stringValue }) else {
return return
} }
self.streamSubject.onNext(.cwdChanged(cwd)) self.streamSubject.onNext(.cwdChanged(cwd))
case .defaultColorsChanged: case .defaultColorsChanged:
guard let values = data?.asArray(ofType: Int.self, count: 3) else { guard let values = array(from: data, ofSize: 3, conversion: { $0.intValue }) else {
return return
} }
self.streamSubject.onNext(.defaultColorsChanged(values)) self.streamSubject.onNext(.defaultColorsChanged(values))
case .colorSchemeChanged: case .colorSchemeChanged:
guard let values = data?.asArray(ofType: Int.self, count: 5) else { guard let d = data, let rawValues = (try? unpack(d))?.value.arrayValue else {
return return
} }
let values = rawValues.compactMap { $0.integerValue }.map { Int($0) }
self.streamSubject.onNext(.colorSchemeChanged(values)) self.streamSubject.onNext(.colorSchemeChanged(values))
case .optionSet: case .optionSet:
@ -314,22 +320,10 @@ class UiBridge {
self.streamSubject.onNext(.optionSet(key: key, value: value)) self.streamSubject.onNext(.optionSet(key: key, value: value))
case .autoCommandEvent: case .autoCommandEvent:
if data?.count == 2 * MemoryLayout<Int>.stride { guard let values = array(from: data, ofSize: 2, conversion: { $0.intValue }),
guard let values = data?.asArray(ofType: Int.self, count: 2), let cmd = NvimAutoCommandEvent(rawValue: values[0]) else { return }
let cmd = NvimAutoCommandEvent(rawValue: values[0])
else {
return
}
self.streamSubject.onNext(.autoCommandEvent(autocmd: cmd, bufferHandle: values[1])) self.streamSubject.onNext(.autoCommandEvent(autocmd: cmd, bufferHandle: values[1]))
} else {
guard let values = data?.asArray(ofType: NvimAutoCommandEvent.self, count: 1) else {
return
}
self.streamSubject.onNext(.autoCommandEvent(autocmd: values[0], bufferHandle: -1))
}
case .debug1: case .debug1:
self.streamSubject.onNext(.debug1) self.streamSubject.onNext(.debug1)
@ -457,17 +451,6 @@ class UiBridge {
private let timeout = CFTimeInterval(5) private let timeout = CFTimeInterval(5)
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 { private extension Array {
func data() -> Data { func data() -> Data {
@ -484,3 +467,23 @@ private extension Array {
} }
} }
} }
private func value<T>(from data: Data?, conversion: (MessagePackValue) -> T?) -> T? {
guard let d = data, let value = (try? unpack(d))?.value else {
return nil
}
return conversion(value)
}
private func array<T>(from data: Data?, ofSize size: Int, conversion: (MessagePackValue) -> T?) -> [T]? {
guard let d = data, let array = (try? unpack(d))?.value.arrayValue else {
return nil
}
guard array.count == size else {
return nil
}
return array.compactMap(conversion)
}

View File

@ -980,7 +980,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 275; CURRENT_PROJECT_VERSION = 277;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
@ -1037,7 +1037,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 275; CURRENT_PROJECT_VERSION = 277;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;

View File

@ -75,30 +75,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
return return
} }
let alert = NSAlert()
alert.alertStyle = .warning
alert.messageText = "FontAwesome could not be loaded."
let accessoryView = NSTextField(frame: CGRect(x: 0, y: 0, width: 300, height: 40))
accessoryView.isEditable = false
accessoryView.drawsBackground = false
accessoryView.isBordered = false
accessoryView.usesSingleLineMode = false
// both are needed, otherwise hyperlink won't accept mousedown
accessoryView.isSelectable = true
accessoryView.allowsEditingTextAttributes = true
accessoryView.attributedStringValue = NSAttributedString.infoLabel(markdown: """
Unfortunately we don't know yet what is causing this. This seems to happen only to some users.
We use the FontAwesome font for icons in the tools, e.g. the file browser. Those icons are now
shown as `?`.
You can track the progress on this issue at [GitHub](https://github.com/qvacua/vimr/issues/611).
""")
alert.accessoryView = accessoryView
// alert.runModal()
let notification = NSUserNotification() let notification = NSUserNotification()
notification.title = "FontAwesome could not be loaded." notification.title = "FontAwesome could not be loaded."
notification.subtitle = "Unfortunately we don't know yet what is causing this." notification.subtitle = "Unfortunately we don't know yet what is causing this."

View File

@ -1,4 +1,4 @@
{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf830 {\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf400
{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;} {\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;} {\*\expandedcolortbl;;}
@ -38,7 +38,7 @@ By:
\ \
\b Using stuff from:\ \b Using stuff from:\
NeoVim\ Neovim\
{\field{\*\fldinst{HYPERLINK "https://github.com/neovim/neovim"}}{\fldrslt {\field{\*\fldinst{HYPERLINK "https://github.com/neovim/neovim"}}{\fldrslt
\b0 https://github.com/neovim/neovim}} \b0 https://github.com/neovim/neovim}}
\b0 \ \b0 \
@ -93,12 +93,6 @@ By:
\b0 {\field{\*\fldinst{HYPERLINK "https://github.com/sindresorhus/github-markdown-css"}}{\fldrslt https://github.com/sindresorhus/github-markdown-css}}\ \b0 {\field{\*\fldinst{HYPERLINK "https://github.com/sindresorhus/github-markdown-css"}}{\fldrslt https://github.com/sindresorhus/github-markdown-css}}\
\ \
\b Result\
{\field{\*\fldinst{HYPERLINK "https://github.com/antitypical/Result"}}{\fldrslt
\b0 https://github.com/antitypical/Result}}
\b0 \
\
\b MessagePack.swift\ \b MessagePack.swift\
{\field{\*\fldinst{HYPERLINK "https://github.com/a2/MessagePack.swift"}}{\fldrslt {\field{\*\fldinst{HYPERLINK "https://github.com/a2/MessagePack.swift"}}{\fldrslt
\b0 https://github.com/a2/MessagePack.swift}} \b0 https://github.com/a2/MessagePack.swift}}

View File

@ -32,7 +32,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.23.0</string> <string>SNAPSHOT-277</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@ -49,7 +49,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>275</string> <string>277</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string> <string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@ -206,11 +206,6 @@ class MainWindow: NSObject,
self.neoVimView.usesLiveResize = state.useLiveResize self.neoVimView.usesLiveResize = state.useLiveResize
self.updateNeoVimAppearance() self.updateNeoVimAppearance()
self.window.setFrame(state.frame, display: true)
self.window.makeFirstResponder(self.neoVimView)
self.open(urls: state.urlsToOpen)
Observable Observable
.of(self.scrollDebouncer.observable, self.cursorDebouncer.observable) .of(self.scrollDebouncer.observable, self.cursorDebouncer.observable)
.merge() .merge()
@ -221,7 +216,7 @@ class MainWindow: NSObject,
self.neoVimView.events self.neoVimView.events
.observeOn(MainScheduler.instance) .observeOn(MainScheduler.instance)
.subscribe(onNext: { event in .subscribe(onNext: { [unowned self] event in
switch event { switch event {
case .neoVimStopped: self.neoVimStopped() case .neoVimStopped: self.neoVimStopped()
@ -336,6 +331,11 @@ class MainWindow: NSObject,
} }
}) })
.disposed(by: self.disposeBag) .disposed(by: self.disposeBag)
self.window.setFrame(state.frame, display: true)
self.window.makeFirstResponder(self.neoVimView)
self.open(urls: state.urlsToOpen)
} }
func uuidAction(for action: Action) -> UuidAction<Action> { func uuidAction(for action: Action) -> UuidAction<Action> {
@ -432,8 +432,10 @@ class MainWindow: NSObject,
private func showInitError() { private func showInitError() {
let notification = NSUserNotification() let notification = NSUserNotification()
notification.title = "Error during initialization" notification.title = "Error during initialization"
notification.informativeText = "There was an error during the initialization of NeoVim. " + notification.informativeText = """
"Use :messages to view the error messages." There was an error during the initialization of NeoVim.
Use :messages to view the error messages.
"""
NSUserNotificationCenter.default.deliver(notification) NSUserNotificationCenter.default.deliver(notification)
} }

View File

@ -15,10 +15,10 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>BNDL</string> <string>BNDL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.23.0</string> <string>SNAPSHOT-277</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>275</string> <string>277</string>
</dict> </dict>
</plist> </plist>

View File

@ -7,20 +7,23 @@
<description>Most recent changes with links to updates for VimR.</description> <description>Most recent changes with links to updates for VimR.</description>
<language>en</language> <language>en</language>
<item> <item>
<title>v0.23.0-275</title> <title>SNAPSHOT-277</title>
<description><![CDATA[ <description><![CDATA[
<p>GH-419: File browser sorts folders on the top. (Thanks @laibulle for the PR)</p> <p><em>WARNING</em>: This snapshot may very well be instable!</p>
<ul>
<li>Some <em>more</em> refactorings in the communication layer between the UI and the backend Neovim process. (Scrolling got a bit faster, I think 🙂)</li>
</ul>
]]></description> ]]></description>
<releaseNotesLink> <releaseNotesLink>
https://github.com/qvacua/vimr/releases/tag/v0.23.0-275 https://github.com/qvacua/vimr/releases/tag/snapshot/277
</releaseNotesLink> </releaseNotesLink>
<pubDate>2018-05-05T10:32:16.520757</pubDate> <pubDate>2018-05-13T17:19:23.286126</pubDate>
<minimumSystemVersion>10.10.0</minimumSystemVersion> <minimumSystemVersion>10.10.0</minimumSystemVersion>
<enclosure url="https://github.com/qvacua/vimr/releases/download/v0.23.0-275/VimR-v0.23.0-275.tar.bz2" <enclosure url="https://github.com/qvacua/vimr/releases/download/snapshot/277/VimR-SNAPSHOT-277.tar.bz2"
sparkle:version="275" sparkle:version="277"
sparkle:shortVersionString="0.23.0" sparkle:shortVersionString="SNAPSHOT-277"
sparkle:dsaSignature="MC0CFQCi65UeKDlPEFa1PBiBAFae2TssJAIUaM4zcNPIxFzlE2cCQPCNwUQX3PM=" sparkle:dsaSignature="MC0CFGdf4V1p+6xmrgx9QcRF9zeppeF0AhUAw+Uh6O+1/jyMin2h/ytnfWDFqm4="
length="12162223" length="12541702"
type="application/octet-stream"/> type="application/octet-stream"/>
</item> </item>
</channel> </channel>

View File

@ -22,7 +22,7 @@ agvtool new-marketing-version ${MARKETING_VERSION}
popd popd
for proj in 'MsgPackRpc' 'NvimMsgPack' 'NvimView'; do for proj in 'NvimView'; do
pushd ${proj} pushd ${proj}
agvtool new-version -all ${BUNDLE_VERSION} agvtool new-version -all ${BUNDLE_VERSION}
agvtool new-marketing-version ${MARKETING_VERSION} agvtool new-marketing-version ${MARKETING_VERSION}