1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-24 22:33:52 +03:00

GH-264 Add (sync) NeoVimAgent.vimCommandOutput

This commit is contained in:
Tae Won Ha 2016-09-02 18:22:40 +02:00
parent f1b09641fa
commit 0bd9511550
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
10 changed files with 132 additions and 16 deletions

View File

@ -35,6 +35,7 @@ typedef NS_ENUM(NSUInteger, NeoVimServerMsgId) {
NeoVimServerMsgIdSetTitle,
NeoVimServerMsgIdSetIcon,
NeoVimServerMsgIdDirtyStatusChanged,
NeoVimServerMsgIdCommandOutputResult,
NeoVimServerMsgIdStop,
#ifdef DEBUG
@ -45,6 +46,7 @@ typedef NS_ENUM(NSUInteger, NeoVimServerMsgId) {
typedef NS_ENUM(NSUInteger, NeoVimAgentMsgId) {
NeoVimAgentMsgIdAgentReady = 0,
NeoVimAgentMsgIdCommand,
NeoVimAgentMsgIdCommandOutput,
NeoVimAgentMsgIdInput,
NeoVimAgentMsgIdInputMarked,
NeoVimAgentMsgIdDelete,

View File

@ -178,6 +178,18 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
return nil;
}
case NeoVimAgentMsgIdCommandOutput: {
NSUInteger *values = (NSUInteger *) data.bytes;
NSUInteger responseId = values[0];
NSString *command = [[NSString alloc] initWithBytes:++values
length:data.length - sizeof(NSUInteger)
encoding:NSUTF8StringEncoding];
server_vim_command_output(responseId, command);
return nil;
}
case NeoVimAgentMsgIdInput: {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
server_vim_input(string);

View File

@ -12,6 +12,7 @@ extern NeoVimServer *_neovim_server;
extern void server_start_neovim();
extern void server_vim_command(NSString *input);
extern void server_vim_command_output(NSUInteger responseId, NSString *input);
extern void server_vim_input(NSString *input);
extern void server_delete(NSInteger count);
extern void server_resize(int width, int height);

View File

@ -27,7 +27,7 @@
#import <nvim/undo.h>
#define pun_type(t, x) (*((t *)(&x)))
#define pun_type(t, x) (*((t *) (&(x))))
typedef struct {
UIBridgeData *bridge;
@ -462,6 +462,32 @@ static void neovim_command(void **argv) {
}
}
static void neovim_command_output(void **argv) {
@autoreleasepool {
NSUInteger *values = (NSUInteger *) argv[0];
NSUInteger responseId = values[0];
NSString *input = (NSString *) argv[1];
Error err;
String commandOutput = nvim_command_output((String) {
.data = (char *) input.cstr,
.size = [input lengthOfBytesUsingEncoding:NSUTF8StringEncoding]
}, &err);
// FIXME: handle err.set == true
NSData *outputData = [NSData dataWithBytes:commandOutput.data length:commandOutput.size];
xfree(commandOutput.data);
NSMutableData *data = [NSMutableData dataWithBytes:&responseId length:sizeof(NSUInteger)];
[data appendData:outputData];
[_neovim_server sendMessageWithId:NeoVimServerMsgIdCommandOutputResult data:data];
free(values); // malloc'ed in loop_schedule(&main_loop, ...) (in _queue) somewhere
[input release]; // retained in loop_schedule(&main_loop, ...) (in _queue) somewhere
}
}
static void neovim_input(void **argv) {
@autoreleasepool {
NSString *input = (NSString *) argv[0];
@ -644,6 +670,18 @@ void server_vim_command(NSString *input) {
});
}
void server_vim_command_output(NSUInteger responseId, NSString *input) {
queue(^{
// We could use (NSInteger *) responseId, but that would be almost unreadable and would rely on the fact that
// (coincidentally) the pointers and NSUInteger are both 64bit wide.
NSUInteger *values = malloc(sizeof(NSUInteger));
values[0] = responseId;
// free release in neovim_command
loop_schedule(&main_loop, event_create(1, neovim_command_output, 2, values, [input retain]));
});
}
void server_vim_input(NSString *input) {
queue(^{
if (_marked_text == nil) {

View File

@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
- (bool)runLocalServerAndNeoVim;
- (void)vimCommand:(NSString *)string;
- (NSString *)vimCommandOutput:(NSString *)string;
- (void)vimInput:(NSString *)string;
- (void)vimInputMarkedText:(NSString *_Nonnull)markedText;

View File

@ -55,6 +55,10 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
bool _neoVimIsReady;
bool _isInitErrorPresent;
NSUInteger _requestResponseId;
NSMutableDictionary *_requestResponseConditions;
NSMutableDictionary *_requestResponses;
}
- (instancetype)initWithUuid:(NSString *)uuid {
@ -67,6 +71,10 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
_neoVimIsReady = NO;
_isInitErrorPresent = NO;
_requestResponseId = 0;
_requestResponseConditions = [NSMutableDictionary new];
_requestResponses = [NSMutableDictionary new];
return self;
}
@ -138,6 +146,31 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
[self sendMessageWithId:NeoVimAgentMsgIdCommand data:data expectsReply:NO];
}
- (NSString *)vimCommandOutput:(NSString *)string {
NSUInteger reqId = _requestResponseId;
_requestResponseId++;
NSCondition *condition = [NSCondition new];
_requestResponseConditions[@(reqId)] = condition;
NSMutableData *data = [[NSMutableData alloc] initWithBytes:&reqId length:sizeof(NSUInteger)];
[data appendData:[string dataUsingEncoding:NSUTF8StringEncoding]];
[self sendMessageWithId:NeoVimAgentMsgIdCommandOutput data:data expectsReply:NO];
NSDate *deadline = [[NSDate date] dateByAddingTimeInterval:qTimeout];
[condition lock];
while (_requestResponses[@(reqId)] == nil) {
[condition waitUntilDate:deadline];
}
[condition unlock];
[_requestResponseConditions removeObjectForKey:@(reqId)];
NSString *result = _requestResponses[@(reqId)];
[_requestResponses removeObjectForKey:@(reqId)];
return [result stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)vimInput:(NSString *)string {
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
[self sendMessageWithId:NeoVimAgentMsgIdInput data:data expectsReply:NO];
@ -427,6 +460,22 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
return;
}
case NeoVimServerMsgIdCommandOutputResult: {
NSUInteger *values = (NSUInteger *) data.bytes;
NSUInteger requestId = values[0];
NSString *output = [[NSString alloc] initWithBytes:++values
length:data.length - sizeof(NSUInteger)
encoding:NSUTF8StringEncoding];
NSCondition *condition = _requestResponseConditions[@(requestId)];
[condition lock];
_requestResponses[@(requestId)] = output;
[condition broadcast];
[condition unlock];
return;
}
case NeoVimServerMsgIdStop:
[_bridge stop];
return;

View File

@ -59,6 +59,21 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
self.resizeNeoVimUiTo(size: self.bounds.size)
}
}
public var cwd: NSURL {
get {
return NSURL(fileURLWithPath: self.agent.vimCommandOutput("silent pwd"))
}
set {
guard let path = cwd.path else {
return
}
let escapedCwd = self.agent.escapedFileName(path)
self.agent.vimCommand("cd \(escapedCwd)")
}
}
private var _font = NeoVimView.defaultFont
@ -135,6 +150,8 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
@IBAction public func debug1(sender: AnyObject!) {
Swift.print("DEBUG 1")
Swift.print(self.agent.vimCommandOutput("silent echo $PATH"))
Swift.print(self.agent.vimCommandOutput("silent pwd"))
}
public func debugInfo() {
@ -145,15 +162,6 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
// MARK: - API
extension NeoVimView {
public func set(cwd cwd: NSURL) {
guard let path = cwd.path else {
return
}
let escapedCwd = self.agent.escapedFileName(path)
self.agent.vimCommand("cd \(escapedCwd)")
}
public func currentBuffer() -> NeoVimBuffer {
return self.agent.buffers().filter { $0.current }.first!
}

View File

@ -48,7 +48,7 @@ class MainWindowComponent: WindowComponent, NSWindowDelegate, NeoVimViewDelegate
}
func set(cwd cwd: NSURL) {
self.neoVimView.set(cwd: cwd)
self.neoVimView.cwd = cwd
}
func isDirty() -> Bool {

View File

@ -8,6 +8,8 @@ import PureLayout
import RxSwift
class OpenQuicklyWindowComponent: WindowComponent, NSWindowDelegate, NSTableViewDelegate, NSTableViewDataSource {
private let searchField = NSTextField(forAutoLayout: ())
init(source: Observable<Any>) {
super.init(source: source, nibName: "OpenQuicklyWindow")
@ -16,15 +18,19 @@ class OpenQuicklyWindowComponent: WindowComponent, NSWindowDelegate, NSTableView
}
override func addViews() {
let searchField = NSTextField(forAutoLayout: ())
self.window.contentView?.addSubview(searchField)
searchField.autoPinEdgesToSuperviewEdgesWithInsets(NSEdgeInsets(top: 18, left: 18, bottom: 18, right: 18))
self.searchField.autoPinEdgesToSuperviewEdgesWithInsets(NSEdgeInsets(top: 18, left: 18, bottom: 18, right: 18))
searchField.becomeFirstResponder()
self.searchField.becomeFirstResponder()
}
override func subscription(source source: Observable<Any>) -> Disposable {
return NopDisposable.instance
}
override func show() {
super.show()
self.searchField.becomeFirstResponder()
}
}

View File

@ -17,7 +17,6 @@ class OpenQuicklyWindowService: StandardFlow {
}
func open(forMainWindow mainWindow: MainWindowComponent) {
Swift.print("\(#function): \(mainWindow.uuid)")
self.openQuicklyWindow.show()
}