1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-11-24 11:37:32 +03:00

Fire GUIEnter when all rpc events subscription is done

This commit is contained in:
Tae Won Ha 2019-03-02 18:58:01 +01:00
parent 9caa84f8c5
commit 0ba13f0a2b
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
14 changed files with 254 additions and 100 deletions

View File

@ -16,6 +16,7 @@
#define FileInfo CarbonFileInfo
#define Boolean CarbonBoolean
#import <nvim/main.h>
#import <nvim/vim.h>
#import <nvim/api/vim.h>
#import <nvim/ui.h>
@ -73,6 +74,8 @@ static NSInteger _initialHeight = 15;
static msgpack_sbuffer flush_sbuffer;
static msgpack_packer *flush_packer;
static dispatch_queue_t rpc_queue;
#pragma mark Helper functions
static inline String vim_string_from(NSString *str) {
@ -245,6 +248,8 @@ static void server_ui_main(UIBridgeData *bridge, UI *ui) {
msgpack_sbuffer_init(&flush_sbuffer);
flush_packer = msgpack_packer_new(&flush_sbuffer, msgpack_sbuffer_write);
rpc_queue = dispatch_queue_create("rpc_queu", NULL);
Loop loop;
loop_init(&loop, NULL);
@ -553,6 +558,21 @@ void custom_ui_start(void) {
ui_bridge_attach(ui, server_ui_main, server_ui_scheduler);
}
static int rpc_event_counter = 0;
void custom_ui_rpcevent_subscribed() {
dispatch_async(rpc_queue, ^{
rpc_event_counter++;
ELOG("counter: %d", rpc_event_counter);
send_msg_packing(
NvimServerMsgIdRpcEventSubscribed,
^(msgpack_packer *packer) {
msgpack_pack_int(packer, rpc_event_counter);
});
});
}
void custom_ui_autocmds_groups(
event_T event,
char_u *fname __unused,
@ -573,6 +593,8 @@ void custom_ui_autocmds_groups(
case EVENT_TABENTER:
case EVENT_TEXTCHANGED:
case EVENT_TEXTCHANGEDI:
case EVENT_VIMENTER:
case EVENT_GUIENTER:
break;
default:
@ -739,6 +761,25 @@ void neovim_delete_and_input(void **argv) {
});
}
static void do_autocmd_guienter() {
static bool recursive = false;
if (recursive) {
return; // disallow recursion
}
recursive = true;
apply_autocmds(EVENT_GUIENTER, NULL, NULL, false, curbuf);
recursive = false;
}
static void guienter_event(void **argv __unused) {
do_autocmd_guienter();
}
static void aucmd_schedule_guienter() {
loop_schedule_deferred(&main_loop, event_create(guienter_event, 0));
}
void neovim_focus_gained(void **argv) {
work_async(argv, ^(NSData *data) {
const bool *values = data.bytes;
@ -749,7 +790,7 @@ void neovim_focus_gained(void **argv) {
void neovim_ready_for_rpcevents(void **argv) {
work_async(argv, ^(NSData *data) {
apply_autocmds(EVENT_GUIENTER, NULL, NULL, false, NULL);
aucmd_schedule_guienter();
});
}

View File

@ -86,7 +86,7 @@ class Logger {
default: self.name = String(describing: name)
}
self.logDateFormatter.dateFormat = "dd HH:mm:SSS"
self.logDateFormatter.dateFormat = "dd HH:mm:ss.SSS"
self.appender = appender
}

View File

@ -1,4 +1,4 @@
// Auto generated for nvim v0.3.2-dev.
// Auto generated for nvim v0.3.4.
// See bin/generate_autocmds.py
enum NvimAutoCommandEvent: Int {
@ -21,86 +21,89 @@ enum NvimAutoCommandEvent: Int {
case bufwritecmd = 16
case bufwritepost = 17
case bufwritepre = 18
case chanopen = 19
case chaninfo = 20
case cmdlineenter = 21
case cmdlineleave = 22
case cmdundefined = 23
case cmdwinenter = 24
case cmdwinleave = 25
case colorscheme = 26
case completedone = 27
case cursorhold = 28
case cursorholdi = 29
case cursormoved = 30
case cursormovedi = 31
case dirchanged = 32
case encodingchanged = 33
case exitpre = 34
case fileappendcmd = 35
case fileappendpost = 36
case fileappendpre = 37
case filechangedro = 38
case filechangedshell = 39
case filechangedshellpost = 40
case filereadcmd = 41
case filereadpost = 42
case filereadpre = 43
case filetype = 44
case filewritecmd = 45
case filewritepost = 46
case filewritepre = 47
case filterreadpost = 48
case filterreadpre = 49
case filterwritepost = 50
case filterwritepre = 51
case focusgained = 52
case focuslost = 53
case funcundefined = 54
case guienter = 55
case guifailed = 56
case insertchange = 57
case insertcharpre = 58
case insertenter = 59
case insertleave = 60
case jobactivity = 61
case menupopup = 62
case optionset = 63
case quickfixcmdpost = 64
case quickfixcmdpre = 65
case quitpre = 66
case remotereply = 67
case sessionloadpost = 68
case shellcmdpost = 69
case shellfilterpost = 70
case sourcecmd = 71
case sourcepre = 72
case spellfilemissing = 73
case stdinreadpost = 74
case stdinreadpre = 75
case swapexists = 76
case syntax = 77
case tabclosed = 78
case tabenter = 79
case tableave = 80
case tabnew = 81
case tabnewentered = 82
case termchanged = 83
case termclose = 84
case termopen = 85
case termresponse = 86
case textchanged = 87
case textchangedi = 88
case textchangedp = 89
case textyankpost = 90
case user = 91
case vimenter = 92
case vimleave = 93
case vimleavepre = 94
case vimresized = 95
case vimresume = 96
case vimsuspend = 97
case winnew = 98
case winenter = 99
case winleave = 100
case chaninfo = 19
case chanopen = 20
case cmdlinechanged = 21
case cmdlineenter = 22
case cmdlineleave = 23
case cmdundefined = 24
case cmdwinenter = 25
case cmdwinleave = 26
case colorscheme = 27
case colorschemepre = 28
case completedone = 29
case cursorhold = 30
case cursorholdi = 31
case cursormoved = 32
case cursormovedi = 33
case diffupdated = 34
case dirchanged = 35
case encodingchanged = 36
case exitpre = 37
case fileappendcmd = 38
case fileappendpost = 39
case fileappendpre = 40
case filechangedro = 41
case filechangedshell = 42
case filechangedshellpost = 43
case filereadcmd = 44
case filereadpost = 45
case filereadpre = 46
case filetype = 47
case filewritecmd = 48
case filewritepost = 49
case filewritepre = 50
case filterreadpost = 51
case filterreadpre = 52
case filterwritepost = 53
case filterwritepre = 54
case focusgained = 55
case focuslost = 56
case funcundefined = 57
case guienter = 58
case guifailed = 59
case insertchange = 60
case insertcharpre = 61
case insertenter = 62
case insertleave = 63
case jobactivity = 64
case menupopup = 65
case optionset = 66
case quickfixcmdpost = 67
case quickfixcmdpre = 68
case quitpre = 69
case remotereply = 70
case sessionloadpost = 71
case shellcmdpost = 72
case shellfilterpost = 73
case sourcecmd = 74
case sourcepre = 75
case spellfilemissing = 76
case stdinreadpost = 77
case stdinreadpre = 78
case swapexists = 79
case syntax = 80
case tabclosed = 81
case tabenter = 82
case tableave = 83
case tabnew = 84
case tabnewentered = 85
case termchanged = 86
case termclose = 87
case termopen = 88
case termresponse = 89
case textchanged = 90
case textchangedi = 91
case textchangedp = 92
case textyankpost = 93
case user = 94
case vimenter = 95
case vimleave = 96
case vimleavepre = 97
case vimresized = 98
case vimresume = 99
case vimsuspend = 100
case winenter = 101
case winleave = 102
case winnew = 103
}

View File

@ -88,6 +88,13 @@ extension NvimView {
}
let cursorRegion = self.cursorRegion(for: self.ugrid.cursorPosition)
if cursorRegion.top < 0
|| cursorRegion.bottom > self.ugrid.size.height - 1
|| cursorRegion.left < 0
|| cursorRegion.right > self.ugrid.size.width - 1 {
logger.error("\(cursorRegion) vs. \(self.ugrid.size)")
return
}
guard let cursorAttrs = self.cellAttributesCollection.attributes(
of: self.ugrid.cells[cursorPosition.row][cursorPosition.column].attrId
)?.reversed else {

View File

@ -92,17 +92,18 @@ extension NvimView {
try? self.bridge
.runLocalServerAndNvim(width: size.width, height: size.height)
.andThen(self.api.run(at: sockPath))
.andThen(
self.sourceFileUrls.reduce(Completable.empty()) { prev, url in
prev.andThen(self.api
.commandOutput(str: "source \(url.path)")
.asCompletable())
}
)
.andThen(
self.subscribedEvents.reduce(Completable.empty()) { prev, event in
prev.andThen(self.api.subscribe(event: event))
}
)
.andThen(
self.sourceFileUrls.reduce(Completable.empty()) { prev, url in
prev.andThen(self.api.command(command: "source \(url.path)"))
}
)
.andThen(self.bridge.notifyReadinessForRpcEvents())
.wait()
}

View File

@ -132,7 +132,6 @@ extension NvimView {
}
final func autoCommandEvent(_ value: MessagePackValue) {
logger.debug(value)
guard let array = MessagePackUtils.array(
from: value, ofSize: 2, conversion: { $0.intValue }
),
@ -142,6 +141,32 @@ extension NvimView {
}
let bufferHandle = array[1]
logger.debug("aucmd: \(event)")
if event == .vimenter {
Completable
.empty()
.observeOn(SerialDispatchQueueScheduler(qos: .userInitiated))
.andThen(
Completable.create { completable in
self.rpcSubscribedCondition.lock()
defer { self.rpcSubscribedCondition.unlock() }
while !self.rpcEventsSubscribed
&& self.rpcSubscribedCondition
.wait(until: Date(timeIntervalSinceNow: 5)) {}
completable(.completed)
return Disposables.create()
}
)
.andThen(self.bridge.notifyReadinessForRpcEvents())
.subscribe(onCompleted: {})
.disposed(by: self.disposeBag)
return
}
#if TRACE
self.bridgeLogger.trace("\(event) -> \(bufferHandle)")
#endif
@ -365,6 +390,18 @@ extension NvimView {
self.eventsSubject.onNext(.setDirtyStatus(dirty))
}
final func rpcEventSubscribed() {
self.subscribedEventCount += 1
if self.subscribedEvents.count == self.subscribedEventCount {
self.rpcSubscribedCondition.lock()
defer { self.rpcSubscribedCondition.unlock() }
self.rpcEventsSubscribed = true
self.rpcSubscribedCondition.broadcast()
self.eventsSubject.onNext(.rpcEventSubscribed)
}
}
final func setAttr(with value: MessagePackValue) {
guard let array = value.arrayValue else { return }
guard array.count == 6 else { return }

View File

@ -59,6 +59,7 @@ public class NvimView: NSView,
case cursor(Position)
case rpcEvent(String, [MessagePack.MessagePackValue])
case rpcEventSubscribed
case initVimError
@ -298,6 +299,10 @@ public class NvimView: NSView,
case let .highlightAttrs(value):
self.setAttr(with: value)
case .rpcEventSubscribed:
self.rpcEventSubscribed()
case .debug1:
self.debug1(self)
@ -396,9 +401,13 @@ public class NvimView: NSView,
shouldLogDebug: nil
)
var subscribedEvents = Set<String>()
let sourceFileUrls: [URL]
var subscribedEvents = Set<String>()
var subscribedEventCount = 0
let rpcSubscribedCondition = NSCondition()
var rpcEventsSubscribed = false
// MARK: - Private
private var _linespacing = NvimView.defaultLinespacing
}

View File

@ -35,6 +35,7 @@ class UiBridge {
case defaultColorsChanged(MessagePackValue)
case autoCommandEvent(MessagePackValue)
case highlightAttrs(MessagePackValue)
case rpcEventSubscribed
case debug1
case unknown
}
@ -253,6 +254,9 @@ class UiBridge {
guard let v = MessagePackUtils.value(from: data) else { return }
self.streamSubject.onNext(.highlightAttrs(v))
case .rpcEventSubscribed:
self.streamSubject.onNext(.rpcEventSubscribed)
}
}

View File

@ -1,3 +1,45 @@
set termguicolors
set mouse=a
set title
"function! s:VimRMakeSessionTemporary() abort
" call rpcnotify(0, 'com.qvacua.vimr.rpc-events.make-session-temporary')
"endfunction
"command! -nargs=0 VimRMakeSessionTemporary call s:VimRMakeSessionTemporary(<args>)
"
"function! s:VimRMaximizeWindow() abort
" call rpcnotify(0, 'com.qvacua.vimr.rpc-events.maximize-window')
"endfunction
"command! -nargs=0 VimRMaximizeWindow call s:VimRMaximizeWindow(<args>)
"
"" -1: hide, 0: toggle, 1: show
"function! s:VimRToggleTools(value) abort
" call rpcnotify(0, 'com.qvacua.vimr.rpc-events.toggle-tools', a:value)
"endfunction
"command! -nargs=0 VimRHideTools call s:VimRToggleTools(-1)
"command! -nargs=0 VimRToggleTools call s:VimRToggleTools(0)
"command! -nargs=0 VimRShowTools call s:VimRToggleTools(1)
"
"" -1: hide, 0: toggle, 1: show
"function! s:VimRToggleToolButtons(value) abort
" call rpcnotify(0, 'com.qvacua.vimr.rpc-events.toggle-tool-buttons', a:value)
"endfunction
"command! -nargs=0 VimRHideToolButtons call s:VimRToggleToolButtons(-1)
"command! -nargs=0 VimRToggleToolButtons call s:VimRToggleToolButtons(0)
"command! -nargs=0 VimRShowToolButtons call s:VimRToggleToolButtons(1)
"
"function! s:VimRToggleFullscreen() abort
" call rpcnotify(0, 'com.qvacua.vimr.rpc-events.toggle-fullscreen')
"endfunction
"command! -nargs=0 VimRToggleFullscreen call s:VimRToggleFullscreen(<args>)
"
"function! s:VimRTest() abort
" VimRMakeSessionTemporary
" VimRHideTools
" VimRMaximizeWindow
" normal o
"endfunction
"command! -nargs=0 VimRTest call s:VimRTest()
"
""au VimEnter * echo "hello"
""au GuiEnter * echo "world"

View File

@ -41,6 +41,7 @@ typedef NS_ENUM(NSInteger, NvimServerMsgId) {
NvimServerMsgIdColorSchemeChanged,
NvimServerMsgIdDefaultColorsChanged,
NvimServerMsgIdAutoCommandEvent,
NvimServerMsgIdRpcEventSubscribed,
NvimServerMsgIdDebug1,
};

@ -1 +1 @@
Subproject commit 722d04f7e67679f136ee9e5808aa4b96014ca286
Subproject commit 57d2679d048678210fd19db6b197afc4385c4ded

View File

@ -80,7 +80,7 @@ class Logger {
default: self.name = String(describing: name)
}
self.logDateFormatter.dateFormat = "dd HH:mm:SSS"
self.logDateFormatter.dateFormat = "dd HH:mm:ss.SSS"
self.appender = appender
}

View File

@ -11,6 +11,7 @@ import MessagePack
extension MainWindow {
func rpcEventAction(for event: RpcEvent, params: [MessagePackValue]) {
stdoutLog.debug("\(event)")
switch event {
case .makeSessionTemporary:
self.emit(self.uuidAction(for: .makeSessionTemporary))

View File

@ -127,12 +127,17 @@ class MainWindow: NSObject,
windowNibName: NSNib.Name("MainWindow")
)
let sourceFileUrls: [URL]
var sourceFileUrls = [URL]()
if let sourceFileUrl = Bundle(for: MainWindow.self)
.url(forResource: "com.qvacua.VimR", withExtension: "vim") {
sourceFileUrls = [sourceFileUrl]
} else {
sourceFileUrls = []
sourceFileUrls.append(sourceFileUrl)
}
let ginitUrl = URL(fileURLWithPath: NSHomeDirectory())
.appendingPathComponent(".config/nvim/ginit.vim")
let loadGinit = FileManager.default.fileExists(atPath: ginitUrl.path)
if loadGinit {
sourceFileUrls.append(ginitUrl)
}
let neoVimViewConfig = NvimView.Config(
@ -292,6 +297,9 @@ class MainWindow: NSObject,
guard let event = RpcEvent(rawValue: method) else { break }
self.rpcEventAction(for: event, params: params)
case .rpcEventSubscribed:
break
}
}, onError: { error in
// FIXME call onError