mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 23:02:35 +03:00
GH-218 Add hasDirtyDocs()
- Use it to determine whether to close the window or not.
This commit is contained in:
parent
10046cdc6b
commit
4b4ccd13b3
@ -48,6 +48,7 @@ typedef NS_ENUM(NSUInteger, NeoVimAgentMsgId) {
|
|||||||
NeoVimAgentMsgIdDelete,
|
NeoVimAgentMsgIdDelete,
|
||||||
NeoVimAgentMsgIdResize,
|
NeoVimAgentMsgIdResize,
|
||||||
NeoVimAgentMsgIdRedraw,
|
NeoVimAgentMsgIdRedraw,
|
||||||
|
NeoVimAgentMsgIdDirtyDocs,
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NeoVimAgentDebug1,
|
NeoVimAgentDebug1,
|
||||||
|
@ -24,17 +24,22 @@ data_to_array(NSInteger)
|
|||||||
|
|
||||||
@interface NeoVimServer ()
|
@interface NeoVimServer ()
|
||||||
|
|
||||||
- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
|
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
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 {
|
@autoreleasepool {
|
||||||
NeoVimServer *neoVimServer = (__bridge NeoVimServer *) info;
|
NeoVimServer *neoVimServer = (__bridge NeoVimServer *) info;
|
||||||
[neoVimServer handleMessageWithId:msgid data:(__bridge NSData *) data];
|
NSData *responseData = [neoVimServer handleMessageWithId:msgid data:(__bridge NSData *) data];
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
if (responseData == nil) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
log4Debug("server returning data: %@", responseData);
|
||||||
|
return CFDataCreateCopy(kCFAllocatorDefault, (__bridge CFDataRef) responseData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -129,45 +134,50 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
|||||||
[self sendMessageWithId:NeoVimServerMsgIdServerReady data:nil];
|
[self sendMessageWithId:NeoVimServerMsgIdServerReady data:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleMessageWithId:(SInt32)msgid data:(NSData *)data {
|
- (NSData *)handleMessageWithId:(SInt32)msgid data:(NSData *)data {
|
||||||
switch (msgid) {
|
switch (msgid) {
|
||||||
|
|
||||||
case NeoVimAgentMsgIdAgentReady:
|
case NeoVimAgentMsgIdAgentReady:
|
||||||
server_start_neovim();
|
server_start_neovim();
|
||||||
return;
|
return nil;
|
||||||
|
|
||||||
case NeoVimAgentMsgIdInput: {
|
case NeoVimAgentMsgIdInput: {
|
||||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
server_vim_input(string);
|
server_vim_input(string);
|
||||||
|
|
||||||
return;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NeoVimAgentMsgIdInputMarked: {
|
case NeoVimAgentMsgIdInputMarked: {
|
||||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
server_vim_input_marked_text(string);
|
server_vim_input_marked_text(string);
|
||||||
|
|
||||||
return;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NeoVimAgentMsgIdDelete: {
|
case NeoVimAgentMsgIdDelete: {
|
||||||
NSInteger *values = data_to_NSInteger_array(data, 1);
|
NSInteger *values = data_to_NSInteger_array(data, 1);
|
||||||
server_delete(values[0]);
|
server_delete(values[0]);
|
||||||
return;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NeoVimAgentMsgIdResize: {
|
case NeoVimAgentMsgIdResize: {
|
||||||
int *values = data_to_int_array(data, 2);
|
int *values = data_to_int_array(data, 2);
|
||||||
server_resize(values[0], values[1]);
|
server_resize(values[0], values[1]);
|
||||||
return;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NeoVimAgentMsgIdRedraw:
|
case NeoVimAgentMsgIdRedraw:
|
||||||
server_redraw();
|
server_redraw();
|
||||||
return;
|
return nil;
|
||||||
|
|
||||||
|
case NeoVimAgentMsgIdDirtyDocs: {
|
||||||
|
bool dirty = server_has_dirty_docs();
|
||||||
|
return [NSData dataWithBytes:&dirty length:sizeof(bool)];
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return;
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,3 +17,4 @@ extern void server_redraw();
|
|||||||
extern void server_resize(int width, int height);
|
extern void server_resize(int width, int height);
|
||||||
extern void server_vim_input_marked_text(NSString *markedText);
|
extern void server_vim_input_marked_text(NSString *markedText);
|
||||||
extern void server_insert_marked_text(NSString *markedText);
|
extern void server_insert_marked_text(NSString *markedText);
|
||||||
|
extern bool server_has_dirty_docs();
|
@ -20,7 +20,6 @@
|
|||||||
#import <nvim/ui_bridge.h>
|
#import <nvim/ui_bridge.h>
|
||||||
#import <nvim/event/signal.h>
|
#import <nvim/event/signal.h>
|
||||||
#import <nvim/main.h>
|
#import <nvim/main.h>
|
||||||
#import <nvim/cursor.h>
|
|
||||||
#import <nvim/screen.h>
|
#import <nvim/screen.h>
|
||||||
|
|
||||||
|
|
||||||
@ -614,3 +613,13 @@ void server_insert_marked_text(NSString *markedText) {
|
|||||||
|
|
||||||
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_marked_text retain])); // release in neovim_input
|
loop_schedule(&main_loop, event_create(1, neovim_input, 1, [_marked_text retain])); // release in neovim_input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool server_has_dirty_docs() {
|
||||||
|
FOR_ALL_BUFFERS(buffer) {
|
||||||
|
if (buffer->b_changed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (void)forceRedraw;
|
- (void)forceRedraw;
|
||||||
- (void)resizeToWidth:(int)width height:(int)height;
|
- (void)resizeToWidth:(int)width height:(int)height;
|
||||||
|
|
||||||
|
- (bool)hasDirtyDocs;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -21,6 +21,7 @@ static type *data_to_ ## type ## _array(NSData *data, NSUInteger count) { \
|
|||||||
}
|
}
|
||||||
|
|
||||||
data_to_array(int)
|
data_to_array(int)
|
||||||
|
data_to_array(bool)
|
||||||
data_to_array(CellAttributes)
|
data_to_array(CellAttributes)
|
||||||
|
|
||||||
@interface NeoVimAgent ()
|
@interface NeoVimAgent ()
|
||||||
@ -45,7 +46,7 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
|||||||
|
|
||||||
CFMessagePortRef _localServerPort;
|
CFMessagePortRef _localServerPort;
|
||||||
NSThread *_localServerThread;
|
NSThread *_localServerThread;
|
||||||
|
|
||||||
CFRunLoopRef _runLoop;
|
CFRunLoopRef _runLoop;
|
||||||
|
|
||||||
NSTask *_neoVimServerTask;
|
NSTask *_neoVimServerTask;
|
||||||
@ -114,6 +115,17 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
|||||||
[self sendMessageWithId:NeoVimAgentMsgIdResize data:data];
|
[self sendMessageWithId:NeoVimAgentMsgIdResize data:data];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (bool)hasDirtyDocs {
|
||||||
|
NSData *responseData = [self sendMessageWithId:NeoVimAgentMsgIdDirtyDocs data:nil];
|
||||||
|
if (responseData == NULL) {
|
||||||
|
NSLog(@"WARNING: agent got response data null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool *values = data_to_bool_array(responseData, 1);
|
||||||
|
return values[0];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)runLocalServer {
|
- (void)runLocalServer {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
CFMessagePortContext localContext = {
|
CFMessagePortContext localContext = {
|
||||||
@ -152,21 +164,34 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
|||||||
[self sendMessageWithId:NeoVimAgentMsgIdAgentReady data:nil];
|
[self sendMessageWithId:NeoVimAgentMsgIdAgentReady data:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data {
|
- (NSData *)sendMessageWithId:(NeoVimAgentMsgId)msgid data:(NSData *)data {
|
||||||
if (_remoteServerPort == NULL) {
|
if (_remoteServerPort == NULL) {
|
||||||
log4Warn("Remote server is null: The msg (%lu:%@) could not be sent.", (unsigned long) msgid, data);
|
log4Warn("Remote server is null: The msg (%lu:%@) could not be sent.", (unsigned long) msgid, data);
|
||||||
return;
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFDataRef responseData = NULL;
|
||||||
|
CFStringRef replyMode = NULL;
|
||||||
|
|
||||||
|
// We only expect reply from NeoVimAgentMsgIdDirtyDocs
|
||||||
|
if (msgid == NeoVimAgentMsgIdDirtyDocs) {
|
||||||
|
replyMode = kCFRunLoopDefaultMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
SInt32 responseCode = CFMessagePortSendRequest(
|
SInt32 responseCode = CFMessagePortSendRequest(
|
||||||
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, NULL, NULL
|
_remoteServerPort, msgid, (__bridge CFDataRef) data, qTimeout, qTimeout, replyMode, &responseData
|
||||||
);
|
);
|
||||||
|
|
||||||
if (responseCode == kCFMessagePortSuccess) {
|
if (responseCode != kCFMessagePortSuccess) {
|
||||||
return;
|
log4Warn("The msg (%lu:%@) could not be sent: %d", (unsigned long) msgid, data, responseCode);
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
log4Warn("The msg (%lu:%@) could not be sent: %d", (unsigned long) msgid, data, responseCode);
|
if (responseData == NULL) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [NSData dataWithData:(__bridge NSData *) responseData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)neoVimServerExecutablePath {
|
- (NSString *)neoVimServerExecutablePath {
|
||||||
|
@ -180,6 +180,10 @@ public class NeoVimView: NSView {
|
|||||||
self.drawCursor(self.grid.background)
|
self.drawCursor(self.grid.background)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func hasDirtyDocs() -> Bool {
|
||||||
|
return self.agent.hasDirtyDocs()
|
||||||
|
}
|
||||||
|
|
||||||
private func drawCursor(background: UInt32) {
|
private func drawCursor(background: UInt32) {
|
||||||
// FIXME: for now do some rudimentary cursor drawing
|
// FIXME: for now do some rudimentary cursor drawing
|
||||||
let cursorPosition = self.grid.putPosition
|
let cursorPosition = self.grid.putPosition
|
||||||
|
@ -24,18 +24,25 @@ class MainWindowController: NSWindowController, NSWindowDelegate, NeoVimViewDele
|
|||||||
self.window?.makeFirstResponder(self.neoVimView)
|
self.window?.makeFirstResponder(self.neoVimView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - NSWindowDelegate
|
||||||
func windowWillClose(notification: NSNotification) {
|
func windowWillClose(notification: NSNotification) {
|
||||||
self.mainWindowManager?.closeMainWindow(self)
|
self.mainWindowManager?.closeMainWindow(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func windowShouldClose(sender: AnyObject) -> Bool {
|
||||||
|
return !self.neoVimView.hasDirtyDocs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - NeoVimViewDelegate
|
||||||
func setNeoVimTitle(title: String) {
|
func setNeoVimTitle(title: String) {
|
||||||
NSLog("\(#function): \(title)")
|
NSLog("\(#function): \(title)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func neoVimStopped() {
|
func neoVimStopped() {
|
||||||
self.window?.performClose(self)
|
self.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
private func addViews() {
|
private func addViews() {
|
||||||
self.window?.contentView?.addSubview(self.neoVimView)
|
self.window?.contentView?.addSubview(self.neoVimView)
|
||||||
self.neoVimView.autoPinEdgesToSuperviewEdges()
|
self.neoVimView.autoPinEdgesToSuperviewEdges()
|
||||||
|
Loading…
Reference in New Issue
Block a user