mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 06:43:24 +03:00
Merge remote-tracking branch 'origin/develop' into update-neovim
This commit is contained in:
commit
52e3401760
2
Cartfile
2
Cartfile
@ -8,7 +8,7 @@ github "qvacua/RxMsgpackRpc" == 0.0.1
|
||||
github "qvacua/RxMessagePort" == 0.0.1
|
||||
github "qvacua/RxNeovimApi" "nightly"
|
||||
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 "Quick/Nimble" == 7.0.3
|
||||
|
@ -3,11 +3,11 @@ github "Quick/Nimble" "v7.0.3"
|
||||
github "ReactiveX/RxSwift" "4.1.2"
|
||||
github "a2/MessagePack.swift" "3.0.0"
|
||||
github "eonil/FileSystemEvents" "85a089104af37f04a6bf7f2d07d7a93cac0b4fe1"
|
||||
github "httpswift/swifter" "1.4.1"
|
||||
github "qvacua/CocoaFontAwesome" "76cf6c4ef3088d84f78988183c56fc6abdc19f83"
|
||||
github "qvacua/CocoaMarkdown" "7756ad96d5fb390c66531004868e828bb54d3609"
|
||||
github "qvacua/RxMessagePort" "v0.0.1"
|
||||
github "qvacua/RxMsgpackRpc" "v0.0.1"
|
||||
github "qvacua/RxNeovimApi" "nightly"
|
||||
github "qvacua/swifter" "6fc24bdb5bbafd01efa8e448070c6e8ba89fcf0f"
|
||||
github "sindresorhus/github-markdown-css" "v2.10.0"
|
||||
github "sparkle-project/Sparkle" "1.18.1"
|
||||
|
@ -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
|
@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Tae Won Ha - http://taewon.de - @hataewon
|
||||
* See LICENSE
|
||||
*/
|
||||
|
||||
#import "DataWrapper.h"
|
||||
|
||||
|
||||
@implementation DataWrapper { } @end
|
@ -15,7 +15,8 @@
|
||||
nvimArgs:(NSArray<NSString *> *)nvimArgs;
|
||||
|
||||
- (void)sendMessageWithId:(NvimServerMsgId)msgid;
|
||||
- (void)sendMessageWithId:(NvimServerMsgId)msgid data:(NSData *)data;
|
||||
|
||||
- (void)sendMessageWithId:(NvimServerMsgId)msgid data:(CFDataRef)data;
|
||||
- (void)notifyReadiness;
|
||||
|
||||
@end
|
||||
|
@ -7,7 +7,6 @@
|
||||
#import "server_ui.h"
|
||||
#import "Logging.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
|
||||
// them.
|
||||
@ -23,63 +22,59 @@
|
||||
//#define DEBUG_NEOVIM_SERVER_STANDALONE
|
||||
|
||||
|
||||
static const double qTimeout = 10;
|
||||
static const double qTimeout = 5;
|
||||
|
||||
|
||||
@interface NvimServer ()
|
||||
|
||||
- (NSArray<NSString *> *)nvimArgs;
|
||||
- (NSCondition *)outputCondition;
|
||||
|
||||
@end
|
||||
|
||||
static CFDataRef data_sync(CFDataRef data, NSCondition *condition, argv_callback cb) {
|
||||
DataWrapper *wrapper = [[DataWrapper alloc] init];
|
||||
NSDate *deadline = [[NSDate date] dateByAddingTimeInterval:qTimeout];
|
||||
|
||||
[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 data_async(CFDataRef data, argv_callback cb) {
|
||||
loop_schedule(&main_loop, event_create(cb, 3, data));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
|
||||
@autoreleasepool {
|
||||
NvimServer *neoVimServer = (__bridge NvimServer *) info;
|
||||
NSCondition *outputCondition = neoVimServer.outputCondition;
|
||||
CFRetain(data); // release in the loop callbacks!
|
||||
CFRetain(data); // release in the loop callbacks! (or in the case clause when not passed to the callback)
|
||||
|
||||
switch (msgid) {
|
||||
switch (msgid) {
|
||||
|
||||
case NvimBridgeMsgIdAgentReady: {
|
||||
case NvimBridgeMsgIdAgentReady: {
|
||||
@autoreleasepool {
|
||||
NSInteger *values = (NSInteger *) CFDataGetBytePtr(data);
|
||||
start_neovim(values[0], values[1], neoVimServer.nvimArgs);
|
||||
return NULL;
|
||||
NvimServer *nvimServer = (__bridge NvimServer *) info;
|
||||
|
||||
start_neovim(values[0], values[1], nvimServer.nvimArgs);
|
||||
|
||||
CFRelease(data);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
remoteServerName:(NSString *)remoteServerName
|
||||
nvimArgs:(NSArray<NSString*> *)nvimArgs {
|
||||
nvimArgs:(NSArray<NSString *> *)nvimArgs {
|
||||
|
||||
self = [super init];
|
||||
if (self == nil) {
|
||||
@ -182,33 +177,31 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
||||
}
|
||||
|
||||
- (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
|
||||
return;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
SInt32 responseCode = CFMessagePortSendRequest(
|
||||
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, NULL, NULL
|
||||
);
|
||||
SInt32 responseCode = CFMessagePortSendRequest(_remoteServerPort, msgid, data, qTimeout, qTimeout, NULL, NULL);
|
||||
|
||||
if (responseCode == kCFMessagePortSuccess) {
|
||||
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 {
|
||||
#ifndef DEBUG_NEOVIM_SERVER_STANDALONE
|
||||
[self sendMessageWithId:NvimServerMsgIdServerReady data:nil];
|
||||
[self sendMessageWithId:NvimServerMsgIdServerReady data:NULL];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -48,8 +48,8 @@ int main(int argc, const char *argv[]) {
|
||||
: nil;
|
||||
|
||||
_neovim_server = [[NvimServer alloc] initWithLocalServerName:localServerName
|
||||
remoteServerName:remoteServerName
|
||||
nvimArgs:nvimArgs];
|
||||
remoteServerName:remoteServerName
|
||||
nvimArgs:nvimArgs];
|
||||
DLOG("Started neovim server '%s' with args '%@' and connected it with the remote agent '%s'.",
|
||||
localServerName.cstr, nvimArgs, remoteServerName.cstr);
|
||||
|
||||
|
@ -9,8 +9,6 @@
|
||||
#import "server_ui.h"
|
||||
#import "NvimServer.h"
|
||||
#import "CocoaCategories.h"
|
||||
#import "DataWrapper.h"
|
||||
#import "SharedTypes.h"
|
||||
|
||||
// FileInfo and Boolean are #defined by Carbon and NeoVim:
|
||||
// Since we don't need the Carbon versions of them, we rename
|
||||
@ -22,7 +20,6 @@
|
||||
#import <nvim/api/vim.h>
|
||||
#import <nvim/ui.h>
|
||||
#import <nvim/ui_bridge.h>
|
||||
#import <nvim/ex_getln.h>
|
||||
#import <nvim/fileio.h>
|
||||
#import <nvim/undo.h>
|
||||
#import <nvim/mouse.h>
|
||||
@ -32,8 +29,11 @@
|
||||
#import <nvim/aucmd.h>
|
||||
#import <nvim/msgpack_rpc/helpers.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))))
|
||||
|
||||
|
||||
@ -42,10 +42,10 @@ static NSInteger _default_background = 0xFFFFFFFF;
|
||||
static NSInteger _default_special = 0xFFFF0000;
|
||||
|
||||
typedef struct {
|
||||
UIBridgeData *bridge;
|
||||
Loop *loop;
|
||||
UIBridgeData *bridge;
|
||||
Loop *loop;
|
||||
|
||||
bool stop;
|
||||
bool stop;
|
||||
} ServerUiData;
|
||||
|
||||
// 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 _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
|
||||
|
||||
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) {
|
||||
@ -105,8 +108,39 @@ static bool has_dirty_docs() {
|
||||
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() {
|
||||
bool new_dirty_status = has_dirty_docs();
|
||||
var new_dirty_status = has_dirty_docs();
|
||||
DLOG("dirty status: %d vs. %d", _dirty, new_dirty_status);
|
||||
if (_dirty == new_dirty_status) {
|
||||
return;
|
||||
@ -114,23 +148,25 @@ static void send_dirty_status() {
|
||||
|
||||
_dirty = new_dirty_status;
|
||||
DLOG("sending dirty status: %d", _dirty);
|
||||
NSData *data = [[NSData alloc] initWithBytes:&_dirty length:sizeof(bool)];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdDirtyStatusChanged data:data];
|
||||
[data release];
|
||||
|
||||
send_msg_packing(NvimServerMsgIdDirtyStatusChanged, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_bool(packer, _dirty);
|
||||
});
|
||||
}
|
||||
|
||||
static void send_cwd() {
|
||||
char_u *temp = xmalloc(MAXPATHL);
|
||||
var temp = xmalloc(MAXPATHL);
|
||||
if (os_dirname(temp, MAXPATHL) == FAIL) {
|
||||
xfree(temp);
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdCwdChanged];
|
||||
}
|
||||
|
||||
NSString *pwd = [NSString stringWithCString:(const char *) temp encoding:NSUTF8StringEncoding];
|
||||
xfree(temp);
|
||||
|
||||
NSData *resultData = [pwd dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdCwdChanged data:resultData];
|
||||
send_msg_packing(NvimServerMsgIdCwdChanged, ^(msgpack_packer *packer) {
|
||||
let value = cstr_to_string((const char *) temp);
|
||||
msgpack_rpc_from_string(value, packer);
|
||||
api_free_string(value);
|
||||
xfree(temp);
|
||||
});
|
||||
}
|
||||
|
||||
static HlAttrs HlAttrsFromAttrCode(int attr_code) {
|
||||
@ -139,18 +175,6 @@ static HlAttrs HlAttrsFromAttrCode(int attr_code) {
|
||||
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) {
|
||||
int mask = attrs.rgb_ae_attr;
|
||||
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 dirAttrs = HlAttrsFromAttrCode(highlight_attr[HLF_D]);
|
||||
|
||||
NSInteger values[] = {
|
||||
normal_fg, normal_bg,
|
||||
foreground_for(visualAttrs), background_for(visualAttrs),
|
||||
foreground_for(dirAttrs),
|
||||
};
|
||||
NSData *resultData = [NSData dataWithBytes:values length:5 * sizeof(NSInteger)];
|
||||
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdColorSchemeChanged data:resultData];
|
||||
send_msg_packing(NvimServerMsgIdColorSchemeChanged, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_array(packer, 5);
|
||||
msgpack_pack_int64(packer, normal_fg);
|
||||
msgpack_pack_int64(packer, normal_bg);
|
||||
msgpack_pack_int64(packer, foreground_for(visualAttrs));
|
||||
msgpack_pack_int64(packer, background_for(visualAttrs));
|
||||
msgpack_pack_int64(packer, foreground_for(dirAttrs));
|
||||
});
|
||||
}
|
||||
|
||||
static void insert_marked_text(NSString *markedText) {
|
||||
@ -188,7 +212,7 @@ static void insert_marked_text(NSString *markedText) {
|
||||
}
|
||||
|
||||
static void delete_marked_text() {
|
||||
NSUInteger length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
|
||||
let length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
|
||||
|
||||
[_marked_text release];
|
||||
_marked_text = nil;
|
||||
@ -203,13 +227,13 @@ static void run_neovim(void *arg) {
|
||||
char **argv;
|
||||
|
||||
@autoreleasepool {
|
||||
NSArray<NSString *> *nvimArgs = (NSArray *) arg;
|
||||
let nvimArgs = (NSArray<NSString *> *) arg;
|
||||
|
||||
argc = (int) nvimArgs.count + 1;
|
||||
argv = (char **) malloc((argc + 1) * sizeof(char *));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -235,7 +259,9 @@ static void server_ui_scheduler(Event event, void *d) {
|
||||
}
|
||||
|
||||
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_init(&loop, NULL);
|
||||
@ -265,64 +291,63 @@ static void server_ui_main(UIBridgeData *bridge, UI *ui) {
|
||||
xfree(_server_ui_data);
|
||||
xfree(ui);
|
||||
|
||||
[_render_data release];
|
||||
msgpack_sbuffer_clear(&flush_sbuffer);
|
||||
msgpack_packer_free(flush_packer);
|
||||
}
|
||||
|
||||
#pragma mark NeoVim's UI callbacks
|
||||
|
||||
static void server_ui_flush(UI *ui __unused) {
|
||||
@autoreleasepool {
|
||||
if (_render_data.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdFlush
|
||||
data:[NSKeyedArchiver archivedDataWithRootObject:_render_data]];
|
||||
[_render_data removeAllObjects];
|
||||
if (flush_sbuffer.size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
@autoreleasepool {
|
||||
server_ui_flush(NULL);
|
||||
server_ui_flush(NULL);
|
||||
|
||||
NSInteger values[] = {width, height};
|
||||
NSData *data = [[NSData alloc] initWithBytes:values length:(2 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdResize data:data];
|
||||
[data release];
|
||||
}
|
||||
send_msg_packing(NvimServerMsgIdResize, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_array(packer, 2);
|
||||
msgpack_pack_int64(packer, width);
|
||||
msgpack_pack_int64(packer, height);
|
||||
});
|
||||
}
|
||||
|
||||
static void server_ui_clear(UI *ui __unused) {
|
||||
@autoreleasepool {
|
||||
server_ui_flush(NULL);
|
||||
}
|
||||
server_ui_flush(NULL);
|
||||
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdClear];
|
||||
}
|
||||
|
||||
static void server_ui_eol_clear(UI *ui __unused) {
|
||||
@autoreleasepool {
|
||||
add_to_render_data(RenderDataTypeEolClear, nil);
|
||||
}
|
||||
pack_flush_data(RenderDataTypeEolClear, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_nil(packer);
|
||||
});
|
||||
}
|
||||
|
||||
static void server_ui_cursor_goto(UI *ui __unused, Integer row, Integer col) {
|
||||
@autoreleasepool {
|
||||
_put_row = row;
|
||||
_put_column = col;
|
||||
_put_row = row;
|
||||
_put_column = col;
|
||||
|
||||
NSInteger values[] = {
|
||||
row, col,
|
||||
(NSInteger) curwin->w_cursor.lnum, curwin->w_cursor.col + 1
|
||||
};
|
||||
DLOG("%d:%d - %d:%d - %d:%d", row, col, curwin->w_cursor.lnum, curwin->w_cursor.col + 1);
|
||||
|
||||
DLOG("%d:%d - %d:%d - %d:%d", values[0], values[1], values[2], values[3]);
|
||||
|
||||
NSData *data = [[NSData alloc] initWithBytes:values length:(4 * sizeof(NSInteger))];
|
||||
add_to_render_data(RenderDataTypeGoto, data);
|
||||
[data release];
|
||||
}
|
||||
pack_flush_data(RenderDataTypeGoto, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_array(packer, 4);
|
||||
msgpack_pack_int64(packer, row);
|
||||
msgpack_pack_int64(packer, col);
|
||||
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) {
|
||||
@ -345,46 +370,40 @@ static void server_ui_mouse_off(UI *ui __unused) {
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdMouseOff];
|
||||
}
|
||||
|
||||
static void server_ui_mode_info_set(UI *ui __unused, Boolean enabled __unused,
|
||||
Array cursor_styles __unused) {
|
||||
static void server_ui_mode_info_set(UI *ui __unused, Boolean enabled __unused, Array cursor_styles __unused) {
|
||||
// yet noop
|
||||
}
|
||||
|
||||
static void server_ui_mode_change(UI *ui __unused, String mode_str __unused, Integer mode) {
|
||||
@autoreleasepool {
|
||||
NSInteger value = mode;
|
||||
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdModeChange data:data];
|
||||
[data release];
|
||||
send_msg_packing(NvimServerMsgIdModeChange, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_int64(packer, mode);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void server_ui_set_scroll_region(UI *ui __unused, Integer top, Integer bot,
|
||||
Integer left, Integer right) {
|
||||
static void server_ui_set_scroll_region(UI *ui __unused, Integer top, Integer bot, Integer left, Integer right) {
|
||||
server_ui_flush(NULL);
|
||||
|
||||
@autoreleasepool {
|
||||
server_ui_flush(NULL);
|
||||
|
||||
NSInteger values[] = {top, bot, left, right};
|
||||
NSData *data = [[NSData alloc] initWithBytes:values length:(4 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdSetScrollRegion data:data];
|
||||
[data release];
|
||||
}
|
||||
send_msg_packing(NvimServerMsgIdSetScrollRegion, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_array(packer, 4);
|
||||
msgpack_pack_int64(packer, top);
|
||||
msgpack_pack_int64(packer, bot);
|
||||
msgpack_pack_int64(packer, left);
|
||||
msgpack_pack_int64(packer, right);
|
||||
});
|
||||
}
|
||||
|
||||
static void server_ui_scroll(UI *ui __unused, Integer count) {
|
||||
@autoreleasepool {
|
||||
server_ui_flush(NULL);
|
||||
server_ui_flush(NULL);
|
||||
|
||||
NSInteger value = count;
|
||||
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdScroll data:data];
|
||||
[data release];
|
||||
}
|
||||
send_msg_packing(NvimServerMsgIdScroll, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_int64(packer, count);
|
||||
});
|
||||
}
|
||||
|
||||
static void server_ui_highlight_set(UI *ui __unused, HlAttrs attrs) {
|
||||
FontTrait trait = FontTraitNone;
|
||||
var trait = FontTraitNone;
|
||||
if (attrs.rgb_ae_attr & HL_ITALIC) {
|
||||
trait |= FontTraitItalic;
|
||||
}
|
||||
@ -400,52 +419,49 @@ static void server_ui_highlight_set(UI *ui __unused, HlAttrs attrs) {
|
||||
CellAttributes cellAttrs;
|
||||
cellAttrs.fontTrait = trait;
|
||||
|
||||
NSInteger 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 fg = attrs.rgb_fg_color == -1 ? _default_foreground : attrs.rgb_fg_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.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);
|
||||
|
||||
@autoreleasepool {
|
||||
NSData *data = [[NSData alloc] initWithBytes:&cellAttrs length:sizeof(CellAttributes)];
|
||||
add_to_render_data(RenderDataTypeHighlight, data);
|
||||
[data release];
|
||||
}
|
||||
pack_flush_data(RenderDataTypeHighlight, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_bin(packer, sizeof(cellAttrs));
|
||||
msgpack_pack_bin_body(packer, &cellAttrs, sizeof(cellAttrs));
|
||||
});
|
||||
}
|
||||
|
||||
static void server_ui_put(UI *ui __unused, String str) {
|
||||
NSString *string = [[NSString alloc] initWithBytes:str.data
|
||||
length:str.size
|
||||
encoding:NSUTF8StringEncoding];
|
||||
if (_marked_text != nil
|
||||
&& _marked_row == _put_row
|
||||
&& _marked_column == _put_column) {
|
||||
|
||||
@autoreleasepool {
|
||||
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
DLOG("putting marked text: '%s'", str.data);
|
||||
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);
|
||||
add_to_render_data(RenderDataTypePutMarked, data);
|
||||
DLOG("putting marked text cuz zero");
|
||||
pack_flush_data(RenderDataTypePutMarked, ^(msgpack_packer *packer) {
|
||||
msgpack_rpc_from_string(str, packer);
|
||||
});
|
||||
|
||||
} else if (_marked_text != nil
|
||||
&& str.size == 0
|
||||
&& _marked_row == _put_row
|
||||
&& _marked_column == _put_column - 1) {
|
||||
} else {
|
||||
|
||||
DLOG("putting marked text cuz zero");
|
||||
add_to_render_data(RenderDataTypePutMarked, data);
|
||||
DLOG("putting non-marked text: '%s'", str.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) {
|
||||
@ -458,65 +474,38 @@ static void server_ui_visual_bell(UI *ui __unused) {
|
||||
|
||||
static void server_ui_update_fg(UI *ui __unused, Integer fg) {
|
||||
@autoreleasepool {
|
||||
NSInteger value[1];
|
||||
|
||||
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;
|
||||
if (fg != -1) {
|
||||
_default_foreground = fg;
|
||||
}
|
||||
|
||||
_default_foreground = fg;
|
||||
|
||||
value[0] = fg;
|
||||
NSData *data = [[NSData alloc] initWithBytes:value length:(1 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdSetForeground data:data];
|
||||
[data release];
|
||||
send_msg_packing(NvimServerMsgIdSetForeground, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_int64(packer, _default_foreground);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void server_ui_update_bg(UI *ui __unused, Integer bg) {
|
||||
@autoreleasepool {
|
||||
NSInteger value[1];
|
||||
|
||||
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;
|
||||
if (bg != -1) {
|
||||
_default_background = bg;
|
||||
}
|
||||
|
||||
_default_background = bg;
|
||||
value[0] = bg;
|
||||
NSData *data = [[NSData alloc] initWithBytes:value length:(1 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdSetBackground data:data];
|
||||
[data release];
|
||||
send_msg_packing(NvimServerMsgIdSetBackground, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_int64(packer, _default_background);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void server_ui_update_sp(UI *ui __unused, Integer sp) {
|
||||
@autoreleasepool {
|
||||
NSInteger value[2];
|
||||
|
||||
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;
|
||||
if (sp != -1) {
|
||||
_default_special = sp;
|
||||
}
|
||||
|
||||
_default_special = sp;
|
||||
value[0] = sp;
|
||||
NSData *data = [[NSData alloc] initWithBytes:&value length:(1 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdSetSpecial data:data];
|
||||
[data release];
|
||||
|
||||
send_msg_packing(NvimServerMsgIdSetSpecial, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_int64(packer, _default_special);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,10 +525,11 @@ static void server_ui_default_colors_set(
|
||||
_default_special = rgb_sp;
|
||||
}
|
||||
|
||||
NSInteger values[] = { rgb_fg, rgb_bg, rgb_sp };
|
||||
NSData *resultData = [NSData dataWithBytes:values length:3 * sizeof(NSInteger)];
|
||||
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdDefaultColorsChanged data:resultData];
|
||||
send_msg_packing(NvimServerMsgIdDefaultColorsChanged, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_int64(packer, _default_foreground);
|
||||
msgpack_pack_int64(packer, _default_background);
|
||||
msgpack_pack_int64(packer, _default_special);
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NSString *string = [[NSString alloc] initWithCString:title.data encoding:NSUTF8StringEncoding];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdSetTitle
|
||||
data:[string dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[string release];
|
||||
send_msg_packing(NvimServerMsgIdSetTitle, ^(msgpack_packer *packer) {
|
||||
msgpack_rpc_from_string(title, packer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,10 +550,9 @@ static void server_ui_set_icon(UI *ui __unused, String icon) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *string = [[NSString alloc] initWithCString:icon.data encoding:NSUTF8StringEncoding];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdSetIcon
|
||||
data:[string dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[string release];
|
||||
send_msg_packing(NvimServerMsgIdSetTitle, ^(msgpack_packer *packer) {
|
||||
msgpack_rpc_from_string(icon, packer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdStop];
|
||||
|
||||
ServerUiData *data = (ServerUiData *) ui->data;
|
||||
let data = (ServerUiData *) ui->data;
|
||||
data->stop = true;
|
||||
}
|
||||
|
||||
@ -663,42 +651,35 @@ void custom_ui_autocmds_groups(
|
||||
}
|
||||
|
||||
if (event == EVENT_TEXTCHANGED
|
||||
|| event == EVENT_TEXTCHANGEDI
|
||||
|| event == EVENT_BUFWRITEPOST
|
||||
|| event == EVENT_BUFLEAVE)
|
||||
{
|
||||
|| event == EVENT_TEXTCHANGEDI
|
||||
|| event == EVENT_BUFWRITEPOST
|
||||
|| event == EVENT_BUFLEAVE) {
|
||||
send_dirty_status();
|
||||
}
|
||||
|
||||
NSInteger eventCode = (NSInteger) event;
|
||||
|
||||
NSMutableData *data;
|
||||
if (buf == NULL) {
|
||||
data = [[NSMutableData alloc] initWithBytes:&eventCode length:sizeof(NSInteger)];
|
||||
} else {
|
||||
NSInteger bufHandle = 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];
|
||||
send_msg_packing(NvimServerMsgIdAutoCommandEvent, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_array(packer, 2);
|
||||
msgpack_pack_int64(packer, (NSInteger) event);
|
||||
if (buf == NULL) {
|
||||
msgpack_pack_int64(packer, -1);
|
||||
} else {
|
||||
msgpack_pack_int64(packer, (NSInteger) buf->handle);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Other help functions
|
||||
|
||||
void start_neovim(NSInteger width, NSInteger height, NSArray<NSString *> *args) {
|
||||
// The caller has an @autoreleasepool.
|
||||
_initialWidth = width;
|
||||
_initialHeight = height;
|
||||
|
||||
// set $VIMRUNTIME to ${RESOURCE_PATH_OF_XPC_BUNDLE}/runtime
|
||||
NSString *bundlePath = [NSBundle bundleForClass:[NvimServer class]].bundlePath;
|
||||
NSString *resourcesPath = [bundlePath.stringByDeletingLastPathComponent
|
||||
stringByAppendingPathComponent:@"Resources"];
|
||||
NSString *runtimePath = [resourcesPath stringByAppendingPathComponent:@"runtime"];
|
||||
let bundlePath = [NSBundle bundleForClass:[NvimServer class]].bundlePath;
|
||||
let resourcesPath = [bundlePath.stringByDeletingLastPathComponent stringByAppendingPathComponent:@"Resources"];
|
||||
let runtimePath = [resourcesPath stringByAppendingPathComponent:@"runtime"];
|
||||
setenv("VIMRUNTIME", runtimePath.fileSystemRepresentation, true);
|
||||
|
||||
// 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>"];
|
||||
|
||||
bool value = msg_didany > 0;
|
||||
NSData *data = [[NSData alloc] initWithBytes:&value length:sizeof(bool)];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdNvimReady data:data];
|
||||
[data release];
|
||||
send_msg_packing(NvimServerMsgIdNvimReady, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_bool(packer, msg_didany > 0);
|
||||
});
|
||||
|
||||
// We have to manually trigger this to initially get the 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
|
||||
|
||||
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 {
|
||||
NSCondition *outputCondition = argv[1];
|
||||
[outputCondition lock];
|
||||
|
||||
NSData *data = argv[0];
|
||||
DataWrapper *wrapper = argv[2];
|
||||
wrapper.data = block(data);
|
||||
wrapper.dataReady = YES;
|
||||
block(data);
|
||||
[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) {
|
||||
work_and_write_data_sync(argv, ^NSData *(NSData *data) {
|
||||
NSInteger *values = (NSInteger *) data.bytes;
|
||||
work_async(argv, ^(NSData *data) {
|
||||
let values = (NSInteger *) data.bytes;
|
||||
int horiz = (int) values[0];
|
||||
int vert = (int) values[1];
|
||||
int row = (int) values[2];
|
||||
int column = (int) values[3];
|
||||
|
||||
if (horiz == 0 && vert == 0) {
|
||||
return nil;
|
||||
return;
|
||||
}
|
||||
|
||||
if (row < 0 || column < 0) {
|
||||
@ -780,41 +744,37 @@ void neovim_scroll(void **argv) {
|
||||
int horizDir;
|
||||
int vertDir;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
refresh_ui_screen(VALID);
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
||||
void neovim_resize(void **argv) {
|
||||
work_and_write_data_sync(argv, ^NSData *(NSData *data) {
|
||||
work_async(argv, ^(NSData *data) {
|
||||
const NSInteger *values = data.bytes;
|
||||
NSInteger width = values[0];
|
||||
NSInteger height = values[1];
|
||||
let width = values[0];
|
||||
let height = values[1];
|
||||
|
||||
set_ui_size(_server_ui_data->bridge, (int) width, (int) height);
|
||||
ui_refresh();
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
||||
void neovim_vim_input(void **argv) {
|
||||
work_and_write_data_sync(argv, ^NSData *(NSData *data) {
|
||||
NSString *input = [[[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
work_async(argv, ^(NSData *data) {
|
||||
let input = [[[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
|
||||
if (_marked_text == nil) {
|
||||
nvim_input(vim_string_from(input));
|
||||
return nil;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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++) {
|
||||
DLOG("unmarking at %d:%d", _put_row, _put_column - i);
|
||||
NSInteger values[] = {_put_row, MAX(_put_column - i, 0)};
|
||||
|
||||
NSData *unmarkData = [[NSData alloc] initWithBytes:values length:(2 * sizeof(NSInteger))];
|
||||
[_neovim_server sendMessageWithId:NvimServerMsgIdUnmark data:unmarkData];
|
||||
[unmarkData release];
|
||||
send_msg_packing(NvimServerMsgIdUnmark, ^(msgpack_packer *packer) {
|
||||
msgpack_pack_array(packer, 2);
|
||||
msgpack_pack_int64(packer, _put_row);
|
||||
msgpack_pack_int64(packer, MAX(_put_column - i, 0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
delete_marked_text();
|
||||
nvim_input(vim_string_from(input));
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
||||
void neovim_vim_input_marked_text(void **argv) {
|
||||
work_and_write_data_sync(argv, ^NSData *(NSData *data) {
|
||||
NSString *markedText = [[[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
work_async(argv, ^(NSData *data) {
|
||||
let markedText = [[[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
|
||||
if (_marked_text == nil) {
|
||||
_marked_row = _put_row;
|
||||
_marked_column = _put_column + _marked_delta;
|
||||
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;
|
||||
} 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);
|
||||
insert_marked_text(markedText);
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
||||
void neovim_delete(void **argv) {
|
||||
work_and_write_data_sync(argv, ^NSData *(NSData *data) {
|
||||
work_async(argv, ^(NSData *data) {
|
||||
const NSInteger *values = data.bytes;
|
||||
NSInteger count = values[0];
|
||||
|
||||
@ -895,23 +851,19 @@ void neovim_delete(void **argv) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
nvim_input(vim_string_from(_backspace));
|
||||
}
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
aucmd_schedule_focusgained(values[0]);
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
||||
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 bg: %#08X", normal_bg);
|
||||
NSLog(@"normal sp: %#08X", normal_sp);
|
||||
@ -919,7 +871,5 @@ void neovim_debug1(void **argv) {
|
||||
for (int i = 0; i < HLF_COUNT; i++) {
|
||||
NSLog(@"%s: %#08X", hlf_names[i], HlAttrsFromAttrCode(highlight_attr[i]).rgb_fg_color);
|
||||
}
|
||||
|
||||
return nil;
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* 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 */; };
|
||||
1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBD7F88AE4F01E626691 /* NvimApiExtension.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 */; };
|
||||
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 */; };
|
||||
4B90F06A1FD2AFF7008A39E0 /* DataWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0611FD2AFF7008A39E0 /* DataWrapper.m */; };
|
||||
4B90F06B1FD2AFF7008A39E0 /* NvimServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B90F0641FD2AFF7008A39E0 /* NvimServer.m */; };
|
||||
4B9E5E1C20990DF2006455C3 /* RxMessagePort.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9E5E1B20990DF1006455C3 /* RxMessagePort.framework */; };
|
||||
4BB1F5C9209740E400EC394A /* RxMsgpackRpc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BB1F5C8209740E400EC394A /* RxMsgpackRpc.framework */; };
|
||||
@ -94,6 +94,7 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -130,8 +131,6 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -225,6 +224,7 @@
|
||||
1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */,
|
||||
1929B52174EC68D2974B5BAE /* UiBridge.swift */,
|
||||
1929B6F4B70B90F7CFB7B523 /* RxSwiftCommons.swift */,
|
||||
1929B44323D6611E2927EC3B /* MessagePackCommons.swift */,
|
||||
);
|
||||
path = NvimView;
|
||||
sourceTree = "<group>";
|
||||
@ -235,8 +235,6 @@
|
||||
4B90F0511FD2AFD3008A39E0 /* main.m */,
|
||||
4B90F0571FD2AFF7008A39E0 /* CocoaCategories.h */,
|
||||
4B90F05A1FD2AFF7008A39E0 /* CocoaCategories.m */,
|
||||
4B90F05C1FD2AFF7008A39E0 /* DataWrapper.h */,
|
||||
4B90F0611FD2AFF7008A39E0 /* DataWrapper.m */,
|
||||
4B90F05B1FD2AFF7008A39E0 /* Logging.h */,
|
||||
4B90F0621FD2AFF7008A39E0 /* NvimServer.h */,
|
||||
4B90F0641FD2AFF7008A39E0 /* NvimServer.m */,
|
||||
@ -406,6 +404,7 @@
|
||||
1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */,
|
||||
1929BA70C221E3C199833B8C /* UiBridge.swift in Sources */,
|
||||
1929BA93BDEA029011F034FF /* RxSwiftCommons.swift in Sources */,
|
||||
1929B30D6C4175835D1F5B21 /* MessagePackCommons.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -417,7 +416,6 @@
|
||||
4B90F0661FD2AFF7008A39E0 /* server_ui.m in Sources */,
|
||||
4B90F0521FD2AFD3008A39E0 /* main.m in Sources */,
|
||||
4B90F0681FD2AFF7008A39E0 /* CocoaCategories.m in Sources */,
|
||||
4B90F06A1FD2AFF7008A39E0 /* DataWrapper.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -464,7 +462,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 275;
|
||||
CURRENT_PROJECT_VERSION = 277;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@ -524,7 +522,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 275;
|
||||
CURRENT_PROJECT_VERSION = 277;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@ -551,7 +549,7 @@
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 275;
|
||||
DYLIB_CURRENT_VERSION = 277;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
|
||||
FRAMEWORK_VERSION = A;
|
||||
@ -573,7 +571,7 @@
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 275;
|
||||
DYLIB_CURRENT_VERSION = 277;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
|
||||
FRAMEWORK_VERSION = A;
|
||||
|
@ -15,9 +15,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.23.0</string>
|
||||
<string>SNAPSHOT-277</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>275</string>
|
||||
<string>277</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2017 Tae Won Ha. All rights reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
18
NvimView/NvimView/MessagePackCommons.swift
Normal file
18
NvimView/NvimView/MessagePackCommons.swift
Normal 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)
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
import Cocoa
|
||||
import RxNeovimApi
|
||||
import RxSwift
|
||||
import MessagePack
|
||||
|
||||
extension NvimView {
|
||||
|
||||
@ -67,59 +68,51 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func flush(_ renderData: [Data]) {
|
||||
func flush(_ renderData: [MessagePackValue]) {
|
||||
self.bridgeLogger.hr()
|
||||
|
||||
|
||||
gui.async {
|
||||
var goto: Position? = nil
|
||||
renderData.forEach { data in
|
||||
data.withUnsafeBytes { (pointer: UnsafePointer<RenderDataType>) in
|
||||
let sizeOfType = MemoryLayout<RenderDataType>.size
|
||||
let rawPointer = UnsafeRawPointer(pointer).advanced(by: sizeOfType);
|
||||
let renderType = pointer[0]
|
||||
|
||||
switch renderType {
|
||||
|
||||
case .put:
|
||||
guard let str = String(data: Data(bytes: rawPointer, count: data.count - sizeOfType),
|
||||
encoding: .utf8)
|
||||
else {
|
||||
break
|
||||
}
|
||||
|
||||
self.doPut(string: str)
|
||||
|
||||
case .putMarked:
|
||||
guard let str = String(data: Data(bytes: rawPointer, count: data.count - sizeOfType),
|
||||
encoding: .utf8)
|
||||
else {
|
||||
break
|
||||
}
|
||||
|
||||
self.doPut(markedText: str)
|
||||
|
||||
case .highlight:
|
||||
let attr = rawPointer.load(as: CellAttributes.self)
|
||||
self.doHighlightSet(attr)
|
||||
|
||||
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()
|
||||
|
||||
}
|
||||
renderData.forEach { value in
|
||||
guard let renderEntry = value.arrayValue,
|
||||
renderEntry.count == 2,
|
||||
let rawType = renderEntry[0].intValue,
|
||||
let type = RenderDataType(rawValue: rawType) else { return }
|
||||
|
||||
switch type {
|
||||
|
||||
case .put:
|
||||
guard let str = renderEntry[1].stringValue else { return }
|
||||
self.doPut(string: str)
|
||||
|
||||
case .putMarked:
|
||||
guard let str = renderEntry[1].stringValue else { return }
|
||||
self.doPut(markedText: str)
|
||||
|
||||
case .highlight:
|
||||
guard let data = renderEntry[1].dataValue else { return }
|
||||
let attr = data.withUnsafeBytes { (pointer: UnsafePointer<CellAttributes>) in pointer.pointee }
|
||||
self.doHighlightSet(attr)
|
||||
|
||||
case .goto:
|
||||
guard let rawValues = renderEntry[1].arrayValue else { return }
|
||||
let values = rawValues.compactMap { $0.intValue }
|
||||
guard values.count == 4 else { return }
|
||||
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 {
|
||||
self.eventsSubject.onNext(.cursor(pos))
|
||||
}
|
||||
|
||||
|
||||
self.shouldDrawCursor = true
|
||||
|
||||
|
||||
if self.usesLigatures {
|
||||
self.markForRender(region: self.grid.regionOfWord(at: self.grid.position))
|
||||
} else {
|
||||
@ -250,8 +243,6 @@ extension NvimView {
|
||||
|
||||
self.markForRender(cellPosition: self.grid.position)
|
||||
self.grid.goto(position)
|
||||
|
||||
self.eventsSubject.onNext(.cursor(textPosition))
|
||||
}
|
||||
|
||||
func doEolClear() {
|
||||
|
@ -28,7 +28,7 @@ class UiBridge {
|
||||
case unmark(row: Int, column: Int)
|
||||
case bell
|
||||
case visualBell
|
||||
case flush([Data])
|
||||
case flush([MessagePackValue])
|
||||
case setForeground(Int)
|
||||
case setBackground(Int)
|
||||
case setSpecial(Int)
|
||||
@ -162,16 +162,18 @@ class UiBridge {
|
||||
|
||||
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 {
|
||||
self.streamSubject.onNext(.initVimError)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.resize(width: values[0], height: values[1]))
|
||||
|
||||
case .clear:
|
||||
@ -193,28 +195,31 @@ class UiBridge {
|
||||
self.streamSubject.onNext(.mouseOff)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.modeChange(values[0]))
|
||||
self.streamSubject.onNext(.modeChange(value))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.setScrollRegion(top: values[0], bottom: values[1], left: values[2], right: values[3]))
|
||||
|
||||
case .scroll:
|
||||
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
|
||||
guard let value = value(from: data, conversion: { $0.intValue }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.scroll(values[0]))
|
||||
self.streamSubject.onNext(.scroll(value))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -227,42 +232,42 @@ class UiBridge {
|
||||
self.streamSubject.onNext(.visualBell)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.flush(renderData))
|
||||
|
||||
case .setForeground:
|
||||
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
|
||||
guard let value = value(from: data, conversion: { $0.intValue }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.setForeground(values[0]))
|
||||
self.streamSubject.onNext(.setForeground(value))
|
||||
|
||||
case .setBackground:
|
||||
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
|
||||
guard let value = value(from: data, conversion: { $0.intValue }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.setBackground(values[0]))
|
||||
self.streamSubject.onNext(.setBackground(value))
|
||||
|
||||
case .setSpecial:
|
||||
guard let values = data?.asArray(ofType: Int.self, count: 1) else {
|
||||
guard let value = value(from: data, conversion: { $0.intValue }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.setSpecial(values[0]))
|
||||
self.streamSubject.onNext(.setSpecial(value))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.setTitle(title))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -272,31 +277,32 @@ class UiBridge {
|
||||
self.streamSubject.onNext(.stop)
|
||||
|
||||
case .dirtyStatusChanged:
|
||||
guard let values = data?.asArray(ofType: Bool.self, count: 1) else {
|
||||
guard let value = value(from: data, conversion: { $0.boolValue }) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.dirtyStatusChanged(values[0]))
|
||||
self.streamSubject.onNext(.dirtyStatusChanged(value))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.cwdChanged(cwd))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
self.streamSubject.onNext(.defaultColorsChanged(values))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
let values = rawValues.compactMap { $0.integerValue }.map { Int($0) }
|
||||
self.streamSubject.onNext(.colorSchemeChanged(values))
|
||||
|
||||
case .optionSet:
|
||||
@ -314,22 +320,10 @@ class UiBridge {
|
||||
self.streamSubject.onNext(.optionSet(key: key, value: value))
|
||||
|
||||
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
|
||||
}
|
||||
guard let values = array(from: data, ofSize: 2, conversion: { $0.intValue }),
|
||||
let cmd = NvimAutoCommandEvent(rawValue: values[0]) else { return }
|
||||
|
||||
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))
|
||||
}
|
||||
self.streamSubject.onNext(.autoCommandEvent(autocmd: cmd, bufferHandle: values[1]))
|
||||
|
||||
case .debug1:
|
||||
self.streamSubject.onNext(.debug1)
|
||||
@ -457,17 +451,6 @@ class UiBridge {
|
||||
|
||||
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 {
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -980,7 +980,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 275;
|
||||
CURRENT_PROJECT_VERSION = 277;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@ -1037,7 +1037,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 275;
|
||||
CURRENT_PROJECT_VERSION = 277;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -75,30 +75,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDele
|
||||
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()
|
||||
notification.title = "FontAwesome could not be loaded."
|
||||
notification.subtitle = "Unfortunately we don't know yet what is causing this."
|
||||
|
@ -1,4 +1,4 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1504\cocoasubrtf830
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1561\cocoasubrtf400
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;;}
|
||||
@ -38,7 +38,7 @@ By:
|
||||
\
|
||||
|
||||
\b Using stuff from:\
|
||||
NeoVim\
|
||||
Neovim\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/neovim/neovim"}}{\fldrslt
|
||||
\b0 https://github.com/neovim/neovim}}
|
||||
\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}}\
|
||||
\
|
||||
|
||||
\b Result\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/antitypical/Result"}}{\fldrslt
|
||||
\b0 https://github.com/antitypical/Result}}
|
||||
\b0 \
|
||||
\
|
||||
|
||||
\b MessagePack.swift\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/a2/MessagePack.swift"}}{\fldrslt
|
||||
\b0 https://github.com/a2/MessagePack.swift}}
|
||||
|
@ -32,7 +32,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.23.0</string>
|
||||
<string>SNAPSHOT-277</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@ -49,7 +49,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>275</string>
|
||||
<string>277</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.productivity</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
@ -206,11 +206,6 @@ class MainWindow: NSObject,
|
||||
self.neoVimView.usesLiveResize = state.useLiveResize
|
||||
self.updateNeoVimAppearance()
|
||||
|
||||
self.window.setFrame(state.frame, display: true)
|
||||
self.window.makeFirstResponder(self.neoVimView)
|
||||
|
||||
self.open(urls: state.urlsToOpen)
|
||||
|
||||
Observable
|
||||
.of(self.scrollDebouncer.observable, self.cursorDebouncer.observable)
|
||||
.merge()
|
||||
@ -221,7 +216,7 @@ class MainWindow: NSObject,
|
||||
|
||||
self.neoVimView.events
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onNext: { event in
|
||||
.subscribe(onNext: { [unowned self] event in
|
||||
switch event {
|
||||
|
||||
case .neoVimStopped: self.neoVimStopped()
|
||||
@ -336,6 +331,11 @@ class MainWindow: NSObject,
|
||||
}
|
||||
})
|
||||
.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> {
|
||||
@ -432,8 +432,10 @@ class MainWindow: NSObject,
|
||||
private func showInitError() {
|
||||
let notification = NSUserNotification()
|
||||
notification.title = "Error during initialization"
|
||||
notification.informativeText = "There was an error during the initialization of NeoVim. " +
|
||||
"Use :messages to view the error messages."
|
||||
notification.informativeText = """
|
||||
There was an error during the initialization of NeoVim.
|
||||
Use :messages to view the error messages.
|
||||
"""
|
||||
|
||||
NSUserNotificationCenter.default.deliver(notification)
|
||||
}
|
||||
|
@ -15,10 +15,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.23.0</string>
|
||||
<string>SNAPSHOT-277</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>275</string>
|
||||
<string>277</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -7,20 +7,23 @@
|
||||
<description>Most recent changes with links to updates for VimR.</description>
|
||||
<language>en</language>
|
||||
<item>
|
||||
<title>v0.23.0-275</title>
|
||||
<title>SNAPSHOT-277</title>
|
||||
<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>
|
||||
<releaseNotesLink>
|
||||
https://github.com/qvacua/vimr/releases/tag/v0.23.0-275
|
||||
https://github.com/qvacua/vimr/releases/tag/snapshot/277
|
||||
</releaseNotesLink>
|
||||
<pubDate>2018-05-05T10:32:16.520757</pubDate>
|
||||
<pubDate>2018-05-13T17:19:23.286126</pubDate>
|
||||
<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"
|
||||
sparkle:version="275"
|
||||
sparkle:shortVersionString="0.23.0"
|
||||
sparkle:dsaSignature="MC0CFQCi65UeKDlPEFa1PBiBAFae2TssJAIUaM4zcNPIxFzlE2cCQPCNwUQX3PM="
|
||||
length="12162223"
|
||||
<enclosure url="https://github.com/qvacua/vimr/releases/download/snapshot/277/VimR-SNAPSHOT-277.tar.bz2"
|
||||
sparkle:version="277"
|
||||
sparkle:shortVersionString="SNAPSHOT-277"
|
||||
sparkle:dsaSignature="MC0CFGdf4V1p+6xmrgx9QcRF9zeppeF0AhUAw+Uh6O+1/jyMin2h/ytnfWDFqm4="
|
||||
length="12541702"
|
||||
type="application/octet-stream"/>
|
||||
</item>
|
||||
</channel>
|
||||
|
@ -22,7 +22,7 @@ agvtool new-marketing-version ${MARKETING_VERSION}
|
||||
|
||||
popd
|
||||
|
||||
for proj in 'MsgPackRpc' 'NvimMsgPack' 'NvimView'; do
|
||||
for proj in 'NvimView'; do
|
||||
pushd ${proj}
|
||||
agvtool new-version -all ${BUNDLE_VERSION}
|
||||
agvtool new-marketing-version ${MARKETING_VERSION}
|
||||
|
Loading…
Reference in New Issue
Block a user