mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 06:43:24 +03:00
GH-264 Add (sync) NeoVimAgent.vimCommandOutput
This commit is contained in:
parent
f1b09641fa
commit
0bd9511550
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -60,6 +60,21 @@ public class NeoVimView: NSView, NSUserInterfaceValidations {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
private let agent: NeoVimAgent
|
||||
@ -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!
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -9,6 +9,8 @@ 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()
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ class OpenQuicklyWindowService: StandardFlow {
|
||||
}
|
||||
|
||||
func open(forMainWindow mainWindow: MainWindowComponent) {
|
||||
Swift.print("\(#function): \(mainWindow.uuid)")
|
||||
self.openQuicklyWindow.show()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user