mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 23:02:35 +03:00
GH-339 Restructure slightly
This commit is contained in:
parent
cd776791eb
commit
fa82e30cc4
@ -9,13 +9,13 @@
|
||||
#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.
|
||||
#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:
|
||||
@ -40,7 +40,7 @@ data_to_array(NSInteger)
|
||||
@interface NeoVimServer ()
|
||||
|
||||
- (NSCondition *)outputCondition;
|
||||
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
|
||||
- (void)handleQuitMsg;
|
||||
|
||||
@end
|
||||
|
||||
@ -76,8 +76,10 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
||||
switch (msgid) {
|
||||
|
||||
case NeoVimAgentMsgIdAgentReady:
|
||||
server_start_neovim();
|
||||
return nil;
|
||||
start_neovim();
|
||||
return NULL;
|
||||
|
||||
case NeoVimAgentMsgIdQuit: [neoVimServer handleQuitMsg];
|
||||
|
||||
case NeoVimAgentMsgIdCommandOutput: return data_sync(data, outputCondition, neovim_vim_command_output);
|
||||
|
||||
@ -105,17 +107,9 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
||||
|
||||
case NeoVimAgentMsgIdDelete: return null_data_async(data, neovim_delete);
|
||||
|
||||
default: break;
|
||||
default: return NULL;
|
||||
|
||||
}
|
||||
|
||||
NSData *responseData = [neoVimServer handleMessageWithId:msgid data:(__bridge NSData *) data];
|
||||
|
||||
if (responseData == nil) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return CFDataCreateCopy(kCFAllocatorDefault, (__bridge CFDataRef) responseData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,20 +234,12 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
||||
}
|
||||
|
||||
- (void)quit {
|
||||
server_quit();
|
||||
quit_neovim();
|
||||
}
|
||||
|
||||
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data {
|
||||
switch (msgid) {
|
||||
|
||||
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];
|
||||
return nil;
|
||||
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
- (void)handleQuitMsg {
|
||||
// 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];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
extern NeoVimServer *_neovim_server;
|
||||
|
||||
extern void server_start_neovim();
|
||||
extern void server_quit();
|
||||
extern void start_neovim();
|
||||
extern void quit_neovim();
|
||||
|
||||
extern void neovim_select_window(void **argv);
|
||||
extern void neovim_tabs(void **argv);
|
||||
|
@ -75,6 +75,7 @@ static NSString *_backspace = nil;
|
||||
|
||||
static dispatch_queue_t _queue;
|
||||
|
||||
#pragma mark Helper functions
|
||||
static inline int screen_cursor_row() {
|
||||
return curwin->w_winrow + curwin->w_wrow;
|
||||
}
|
||||
@ -95,6 +96,60 @@ static inline String vim_string_from(NSString *str) {
|
||||
return (String) { .data = (char *) str.cstr, .size = str.clength };
|
||||
}
|
||||
|
||||
static bool has_dirty_docs() {
|
||||
FOR_ALL_BUFFERS(buffer) {
|
||||
if (buffer->b_p_bl == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bufIsChanged(buffer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void send_dirty_status() {
|
||||
bool new_dirty_status = has_dirty_docs();
|
||||
DLOG("dirty status: %d vs. %d", _dirty, new_dirty_status);
|
||||
if (_dirty == new_dirty_status) {
|
||||
return;
|
||||
}
|
||||
|
||||
_dirty = new_dirty_status;
|
||||
DLOG("sending dirty status: %d", _dirty);
|
||||
NSData *data = [[NSData alloc] initWithBytes:&_dirty length:sizeof(bool)];
|
||||
[_neovim_server sendMessageWithId:NeoVimServerMsgIdDirtyStatusChanged data:data];
|
||||
[data release];
|
||||
}
|
||||
|
||||
static void insert_marked_text(NSString *markedText) {
|
||||
_marked_text = [markedText retain]; // release when the final text is input in -vimInput
|
||||
|
||||
nvim_input(vim_string_from(markedText));
|
||||
}
|
||||
|
||||
static void delete_marked_text() {
|
||||
NSUInteger length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
|
||||
|
||||
[_marked_text release];
|
||||
_marked_text = nil;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
nvim_input(vim_string_from(_backspace));
|
||||
}
|
||||
}
|
||||
|
||||
static void run_neovim(void *arg __unused) {
|
||||
char *argv[1];
|
||||
argv[0] = "nvim";
|
||||
|
||||
int returnCode = nvim_main(1, argv);
|
||||
|
||||
NSLog(@"neovim's main returned with code: %d\n", returnCode);
|
||||
}
|
||||
|
||||
static void set_ui_size(UIBridgeData *bridge, int width, int height) {
|
||||
bridge->ui->width = width;
|
||||
bridge->ui->height = height;
|
||||
@ -139,7 +194,6 @@ static void server_ui_main(UIBridgeData *bridge, UI *ui) {
|
||||
}
|
||||
|
||||
#pragma mark NeoVim's UI callbacks
|
||||
|
||||
static void server_ui_resize(UI *ui __unused, int width, int height) {
|
||||
queue(^{
|
||||
int values[] = { width, height };
|
||||
@ -405,62 +459,8 @@ static void server_ui_stop(UI *ui __unused) {
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark Helper functions
|
||||
static bool has_dirty_docs() {
|
||||
FOR_ALL_BUFFERS(buffer) {
|
||||
if (buffer->b_p_bl == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bufIsChanged(buffer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void send_dirty_status() {
|
||||
bool new_dirty_status = has_dirty_docs();
|
||||
DLOG("dirty status: %d vs. %d", _dirty, new_dirty_status);
|
||||
if (_dirty == new_dirty_status) {
|
||||
return;
|
||||
}
|
||||
|
||||
_dirty = new_dirty_status;
|
||||
DLOG("sending dirty status: %d", _dirty);
|
||||
NSData *data = [[NSData alloc] initWithBytes:&_dirty length:sizeof(bool)];
|
||||
[_neovim_server sendMessageWithId:NeoVimServerMsgIdDirtyStatusChanged data:data];
|
||||
[data release];
|
||||
}
|
||||
|
||||
static void insert_marked_text(NSString *markedText) {
|
||||
_marked_text = [markedText retain]; // release when the final text is input in -vimInput
|
||||
|
||||
nvim_input(vim_string_from(markedText));
|
||||
}
|
||||
|
||||
static void delete_marked_text() {
|
||||
NSUInteger length = [_marked_text lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;
|
||||
|
||||
[_marked_text release];
|
||||
_marked_text = nil;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
nvim_input(vim_string_from(_backspace));
|
||||
}
|
||||
}
|
||||
|
||||
static void run_neovim(void *arg __unused) {
|
||||
char *argv[1];
|
||||
argv[0] = "nvim";
|
||||
|
||||
int returnCode = nvim_main(1, argv);
|
||||
|
||||
NSLog(@"neovim's main returned with code: %d\n", returnCode);
|
||||
}
|
||||
|
||||
#pragma mark Public
|
||||
// called by neovim
|
||||
|
||||
void custom_ui_start(void) {
|
||||
UI *ui = xcalloc(1, sizeof(UI));
|
||||
@ -525,7 +525,8 @@ void custom_ui_autocmds_groups(
|
||||
}
|
||||
}
|
||||
|
||||
void server_start_neovim() {
|
||||
#pragma mark Other help functions
|
||||
void start_neovim() {
|
||||
_queue = dispatch_queue_create("com.qvacua.vimr.neovim-server.queue", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
// set $VIMRUNTIME to ${RESOURCE_PATH_OF_XPC_BUNDLE}/runtime
|
||||
@ -561,6 +562,46 @@ void server_start_neovim() {
|
||||
[data release];
|
||||
}
|
||||
|
||||
void quit_neovim() {
|
||||
DLOG("NeoVimServer exiting...");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#pragma mark Functions for neovim's main loop
|
||||
// already in an autorelease pool and in neovim's main loop
|
||||
|
||||
typedef NSData *(^work_block)(NSData *);
|
||||
|
||||
static void work_and_write_data_sync(void **argv, work_block block) {
|
||||
NSCondition *outputCondition = argv[1];
|
||||
[outputCondition lock];
|
||||
|
||||
NSData *data = argv[0];
|
||||
Wrapper *wrapper = argv[2];
|
||||
wrapper.data = block(data);
|
||||
wrapper.dataReady = YES;
|
||||
[data release]; // retained in local_server_callback
|
||||
|
||||
[outputCondition signal];
|
||||
[outputCondition unlock];
|
||||
}
|
||||
|
||||
static NSString *escaped_filename(NSString *filename) {
|
||||
const char *file_system_rep = filename.fileSystemRepresentation;
|
||||
|
||||
char_u *escaped_filename = vim_strsave_fnameescape((char_u *) file_system_rep, 0);
|
||||
NSString *result = [NSString stringWithCString:(const char *) escaped_filename encoding:NSUTF8StringEncoding];
|
||||
xfree(escaped_filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void work_async(void **argv, work_block block) {
|
||||
NSData *data = argv[0];
|
||||
block(data);
|
||||
[data release]; // retained in local_server_callback
|
||||
}
|
||||
|
||||
static NeoVimBuffer *buffer_for(buf_T *buf) {
|
||||
// To be sure...
|
||||
if (buf == NULL) {
|
||||
@ -587,85 +628,6 @@ static NeoVimBuffer *buffer_for(buf_T *buf) {
|
||||
return [buffer autorelease];
|
||||
}
|
||||
|
||||
NSArray *server_buffers() {
|
||||
NSMutableArray <NeoVimBuffer *> *result = [[NSMutableArray new] autorelease];
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
NeoVimBuffer *buffer = buffer_for(buf);
|
||||
if (buffer == nil) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[result addObject:buffer];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
NSArray *server_tabs() {
|
||||
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];
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
void server_quit() {
|
||||
DLOG("NeoVimServer exiting...");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
typedef NSData *(^work_block)(NSData *);
|
||||
|
||||
static void work_and_write_data_sync(void **argv, work_block block) {
|
||||
NSCondition *outputCondition = argv[1];
|
||||
[outputCondition lock];
|
||||
|
||||
NSData *data = argv[0];
|
||||
Wrapper *wrapper = argv[2];
|
||||
wrapper.data = block(data);
|
||||
wrapper.dataReady = YES;
|
||||
[data release]; // retained in local_server_callback
|
||||
|
||||
[outputCondition signal];
|
||||
[outputCondition unlock];
|
||||
}
|
||||
|
||||
#pragma mark Functions for neovim's main loop
|
||||
// already in an autorelease pool and in neovim's main loop
|
||||
|
||||
static NSString *escaped_filename(NSString *filename) {
|
||||
const char *file_system_rep = filename.fileSystemRepresentation;
|
||||
|
||||
char_u *escaped_filename = vim_strsave_fnameescape((char_u *) file_system_rep, 0);
|
||||
NSString *result = [NSString stringWithCString:(const char *) escaped_filename encoding:NSUTF8StringEncoding];
|
||||
xfree(escaped_filename);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void work_async(void **argv, work_block block) {
|
||||
NSData *data = argv[0];
|
||||
block(data);
|
||||
[data release]; // retained in local_server_callback
|
||||
}
|
||||
|
||||
void neovim_select_window(void **argv) {
|
||||
work_async(argv, ^NSData *(NSData *data) {
|
||||
int handle = ((int *) data.bytes)[0];
|
||||
@ -715,7 +677,7 @@ void neovim_tabs(void **argv) {
|
||||
[tab release];
|
||||
}
|
||||
|
||||
WLOG("tabs: %s", tabs.description.cstr);
|
||||
DLOG("tabs: %s", tabs.description.cstr);
|
||||
return [NSKeyedArchiver archivedDataWithRootObject:tabs];
|
||||
});
|
||||
}
|
||||
@ -732,7 +694,7 @@ void neovim_buffers(void **argv) {
|
||||
[buffers addObject:buffer];
|
||||
}
|
||||
|
||||
WLOG("buffers: %s", buffers.description.cstr);
|
||||
DLOG("buffers: %s", buffers.description.cstr);
|
||||
return [NSKeyedArchiver archivedDataWithRootObject:buffers];
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user