1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-25 23:02:35 +03:00

GH-339 Try to call methods directly in the main loop

This commit is contained in:
Tae Won Ha 2017-01-05 19:35:44 +01:00
parent 7932c8afe9
commit df7f321082
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
6 changed files with 149 additions and 31 deletions

View File

@ -7,6 +7,15 @@
#import "server_globals.h"
#import "Logging.h"
#import "CocoaCategories.h"
#import "Wrapper.h"
#define FileInfo CarbonFileInfo
#define Boolean CarbonBoolean
#import <nvim/vim.h>
#import <nvim/api/vim.h>
#import <nvim/main.h>
#import <nvim/ui.h>
// When #define'd you can execute the NeoVimServer binary and neovim will be started:
@ -42,13 +51,46 @@ static inline NSData *data_without_response_id(NSData *data) {
@interface NeoVimServer ()
- (NSCondition *)outputCondition;
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
@end
static CFDataRef dataByWaiting(NSCondition *condition, CFDataRef data, argv_callback cb) {
Wrapper *wrapper = [[Wrapper alloc] init];
NSDate *deadline = [[NSDate date] dateByAddingTimeInterval:qTimeout];
[condition lock];
loop_schedule(&main_loop, event_create(1, cb, 3, data, condition, wrapper));
while (wrapper.data == nil && [condition waitUntilDate:deadline]);
[condition unlock];
return (__bridge CFDataRef) wrapper.data;
}
static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
@autoreleasepool {
NeoVimServer *neoVimServer = (__bridge NeoVimServer *) info;
CFRetain(data); // release in the loop callbacks!
switch (msgid) {
case NeoVimAgentMsgIdSelectWindow: {
loop_schedule(&main_loop, event_create(1, neovim_select_window, 1, data));
return NULL;
}
case NeoVimAgentMsgIdGetTabs: {
return dataByWaiting(neoVimServer.outputCondition, data, neovim_tabs);
}
default:
break;
}
NSData *responseData = [neoVimServer handleMessageWithId:msgid data:(__bridge NSData *) data];
if (responseData == nil) {
@ -69,6 +111,12 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
NSThread *_localServerThread;
CFMessagePortRef _localServerPort;
CFRunLoopRef _localServerRunLoop;
NSCondition *_outputCondition;
}
- (NSCondition *)outputCondition {
return _outputCondition;
}
- (instancetype)initWithLocalServerName:(NSString *)localServerName remoteServerName:(NSString *)remoteServerName {
@ -77,6 +125,8 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
return nil;
}
_outputCondition = [[NSCondition alloc] init];
_localServerName = localServerName;
_remoteServerName = remoteServerName;
@ -223,12 +273,6 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
return nil;
}
case NeoVimAgentMsgIdSelectWindow: {
int *values = data_to_int_array(data, 1);
server_select_win(values[0]);
return nil;
}
case NeoVimAgentMsgIdQuit:
// exit() after returning the response such that the agent can get the response and so does not log a warning.
[self performSelector:@selector(quit) onThread:_localServerThread withObject:nil waitUntilDone:NO];
@ -254,10 +298,6 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
return [NSKeyedArchiver archivedDataWithRootObject:server_buffers()];
}
case NeoVimAgentMsgIdGetTabs: {
return [NSKeyedArchiver archivedDataWithRootObject:server_tabs()];
}
case NeoVimAgentMsgIdGetBoolOption: {
NSUInteger responseId = response_id_from_data(data);
NSString *optionName = [[NSString alloc] initWithData:data_without_response_id(data)

13
NeoVimServer/Wrapper.h Normal file
View File

@ -0,0 +1,13 @@
//
// Created by Tae Won Ha on 1/5/17.
// Copyright (c) 2017 Tae Won Ha. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Wrapper : NSObject
@property (nonatomic, nonnull) NSData *data;
@end

12
NeoVimServer/Wrapper.m Normal file
View File

@ -0,0 +1,12 @@
//
// Created by Tae Won Ha on 1/5/17.
// Copyright (c) 2017 Tae Won Ha. All rights reserved.
//
#import "Wrapper.h"
@implementation Wrapper {
}
@end

View File

@ -23,5 +23,7 @@ extern NSArray *server_buffers();
extern NSArray *server_tabs();
extern void server_get_bool_option(NSUInteger responseId, NSString *option);
extern void server_set_bool_option(NSUInteger responseId, NSString *option, bool value);
extern void server_select_win(int window_handle);
extern void server_quit();
extern void neovim_select_window(void **argv);
extern void neovim_tabs(void **argv);

View File

@ -13,6 +13,7 @@
#import "NeoVimWindow.h"
#import "NeoVimTab.h"
#import "CocoaCategories.h"
#import "Wrapper.h"
// FileInfo and Boolean are #defined by Carbon and NeoVim: Since we don't need the Carbon versions of them, we rename
// them.
@ -479,18 +480,6 @@ static void neovim_input(void **argv) {
}
}
static void neovim_select_window(void **argv) {
win_T *window = (win_T *) argv[0];
Error err;
nvim_set_current_win(window->handle, &err);
// TODO: handle error
WLOG("Error selecting window with handle %d: %s", window->handle, err.msg);
// nvim_set_current_win() does not seem to trigger a redraw.
ui_schedule_refresh();
}
static void send_dirty_status() {
bool new_dirty_status = server_has_dirty_docs();
DLOG("dirty status: %d vs. %d", _dirty, new_dirty_status);
@ -818,14 +807,6 @@ NSArray *server_tabs() {
return tabs;
}
void server_select_win(int window_handle) {
FOR_ALL_TAB_WINDOWS(tab, win) {
if (win->handle == window_handle) {
loop_schedule(&main_loop, event_create(1, neovim_select_window, 1, win));
}
}
}
static void neovim_get_bool_option(void ** argv) {
@autoreleasepool {
NSUInteger *values = (NSUInteger *) argv[0];
@ -912,3 +893,67 @@ void server_quit() {
DLOG("NeoVimServer exiting...");
exit(0);
}
static inline NSUInteger response_id_from_data(NSData *data) {
NSUInteger *values = (NSUInteger *) data.bytes;
return values[0];
}
void neovim_select_window(void **argv) {
NSData *data = argv[0];
int handle = ((int *) data.bytes)[0];
[data release]; // retained in local_server_callback
FOR_ALL_TAB_WINDOWS(tab, win) {
if (win->handle == handle) {
Error err;
nvim_set_current_win(win->handle, &err);
if (err.set) {
WLOG("Error selecting window with handle %d: %s", win->handle, err.msg);
return;
}
// nvim_set_current_win() does not seem to trigger a redraw.
ui_schedule_refresh();
return;
}
}
}
void neovim_tabs(void **argv) {
NSData *data = argv[0];
[data release]; // retained in local_server_callback
NSCondition *outputCondition = argv[1];
[outputCondition lock];
Wrapper *wrapper = argv[2];
NSMutableArray *tabs = [[NSMutableArray new] autorelease];
FOR_ALL_TABS(t) {
NSMutableArray *windows = [NSMutableArray new];
FOR_ALL_WINDOWS_IN_TAB(win, t) {
NeoVimBuffer *buffer = buffer_for(win->w_buffer);
if (buffer == nil) {
continue;
}
NeoVimWindow *window = [[NeoVimWindow alloc] initWithHandle:win->handle buffer:buffer];
[windows addObject:window];
[window release];
}
NeoVimTab *tab = [[NeoVimTab alloc] initWithHandle:t->handle windows:windows];
[windows release];
[tabs addObject:tab];
[tab release];
}
wrapper.data = [NSKeyedArchiver archivedDataWithRootObject:tabs];
[outputCondition signal];
[outputCondition unlock];
}

View File

@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */; };
1929B165820D7177743B537A /* Component.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B39DA7AC4A9B62D7CD39 /* Component.swift */; };
1929B18A0D7C7407C51DB642 /* Wrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1929BB6CFF4CC0B5E8B00C62 /* Wrapper.m */; };
1929B1E05C116514C1D3A384 /* CocoaCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5C3F2F1CA4113DABFFD /* CocoaCategories.m */; };
1929B3CEE0C1A1850E9CCE2F /* BasicTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B2FBE11048569391E092 /* BasicTypes.swift */; };
1929B3F5743967125F357C9F /* Matcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BEEB33113B0E33C3830F /* Matcher.swift */; };
@ -265,6 +266,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1929B0EEBE4A765934AF8335 /* Wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Wrapper.h; sourceTree = "<group>"; };
1929B15B7EDC9B0F40E5E95C /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
1929B1A51F076E088EF4CCA4 /* server_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server_globals.h; sourceTree = "<group>"; };
1929B2FBE11048569391E092 /* BasicTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicTypes.swift; sourceTree = "<group>"; };
@ -282,6 +284,7 @@
1929BA6128BFDD54CA92F46E /* ColorUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorUtils.swift; sourceTree = "<group>"; };
1929BA8AC40B901B20F20B71 /* FileUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileUtils.swift; sourceTree = "<group>"; };
1929BB251F74BEFC82CEEF84 /* PrefPane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefPane.swift; sourceTree = "<group>"; };
1929BB6CFF4CC0B5E8B00C62 /* Wrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Wrapper.m; sourceTree = "<group>"; };
1929BBC84557C8351EC6183E /* FileItemIgnorePatternTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileItemIgnorePatternTest.swift; sourceTree = "<group>"; };
1929BC19C1BC19246AFF1621 /* MatcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherTests.swift; sourceTree = "<group>"; };
1929BDF9EBAF1D9D44399045 /* ScoredFileItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScoredFileItem.swift; sourceTree = "<group>"; };
@ -643,6 +646,8 @@
1929B5C3F2F1CA4113DABFFD /* CocoaCategories.m */,
1929BE69CF9AB1A10D0DD4F2 /* CocoaCategories.h */,
1929BFC86BF38D341F2DDCBD /* NeoVim Objects */,
1929BB6CFF4CC0B5E8B00C62 /* Wrapper.m */,
1929B0EEBE4A765934AF8335 /* Wrapper.h */,
);
path = NeoVimServer;
sourceTree = "<group>";
@ -1163,6 +1168,7 @@
4BDD058D1DBBC50000D1B405 /* NeoVimWindow.m in Sources */,
4BDD05871DBBC50000D1B405 /* NeoVimBuffer.m in Sources */,
1929B1E05C116514C1D3A384 /* CocoaCategories.m in Sources */,
1929B18A0D7C7407C51DB642 /* Wrapper.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};