diff --git a/NvimMsgPack/NvimMsgPack/NvimApi.swift b/NvimMsgPack/NvimMsgPack/NvimApi.swift index 84b951ea..c3d8ebc6 100644 --- a/NvimMsgPack/NvimMsgPack/NvimApi.swift +++ b/NvimMsgPack/NvimMsgPack/NvimApi.swift @@ -77,7 +77,11 @@ public class NvimApi { return self.msgpackRpc.stream } - public var queue = DispatchQueue(label: "com.qvacua.NvimMsgpack.NvimApi", qos: .userInitiated) + public var queue = DispatchQueue(label: "com.qvacua.NvimMsgpack.NvimApi", qos: .userInitiated) { + didSet { + self.msgpackRpc.queue = self.queue + } + } public init() { self.msgpackRpc.queue = self.queue diff --git a/NvimView/NvimView/NvimView+Api.swift b/NvimView/NvimView/NvimView+Api.swift index e2539b88..4c969f02 100644 --- a/NvimView/NvimView/NvimView+Api.swift +++ b/NvimView/NvimView/NvimView+Api.swift @@ -22,44 +22,44 @@ extension NvimView { } public func currentBuffer() -> Single { - return self.nvim + return self.api .getCurrentBuf() .flatMap { self.neoVimBuffer(for: $0, currentBuffer: $0) } - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func allBuffers() -> Single<[NvimView.Buffer]> { return Single - .zip(self.nvim.getCurrentBuf(), self.nvim.listBufs()) { (curBuf: $0, bufs: $1) } + .zip(self.api.getCurrentBuf(), self.api.listBufs()) { (curBuf: $0, bufs: $1) } .map { tuple in tuple.bufs.map { buf in self.neoVimBuffer(for: buf, currentBuffer: tuple.curBuf) } } .flatMap(Single.fromSinglesToSingleOfArray) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func isCurrentBufferDirty() -> Single { return self .currentBuffer() .map { $0.isDirty } - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func allTabs() -> Single<[NvimView.Tabpage]> { - return Single.zip(self.nvim.getCurrentBuf(), - self.nvim.getCurrentTabpage(), - self.nvim.listTabpages()) { (curBuf: $0, curTab: $1, tabs: $2) } + return Single.zip(self.api.getCurrentBuf(), + self.api.getCurrentTabpage(), + self.api.listTabpages()) { (curBuf: $0, curTab: $1, tabs: $2) } .map { tuple in return tuple.tabs.map { tab in return self.neoVimTab(for: tab, currentTabpage: tuple.curTab, currentBuffer: tuple.curBuf) } } .flatMap(Single.fromSinglesToSingleOfArray) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func newTab() -> Completable { - return self.nvim + return self.api .command(command: "tabe", expectsReturnValue: false) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func `open`(urls: [URL]) -> Completable { @@ -74,20 +74,20 @@ extension NvimView { let bufExists = buffers.contains { $0.url == url } let wins = tabs.map({ $0.windows }).flatMap({ $0 }) if let win = bufExists ? wins.first(where: { win in win.buffer.url == url }) : nil { - return self.nvim.setCurrentWin(window: NvimApi.Window(win.handle), expectsReturnValue: false) + return self.api.setCurrentWin(window: NvimApi.Window(win.handle), expectsReturnValue: false) } return currentBufferIsTransient ? self.open(url, cmd: "e") : self.open(url, cmd: "tabe") } ) } - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func openInNewTab(urls: [URL]) -> Completable { return Completable .concat(urls.map { url in self.open(url, cmd: "tabe") }) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func openInCurrentTab(url: URL) -> Completable { @@ -97,13 +97,13 @@ extension NvimView { public func openInHorizontalSplit(urls: [URL]) -> Completable { return Completable .concat(urls.map { url in self.open(url, cmd: "sp") }) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func openInVerticalSplit(urls: [URL]) -> Completable { return Completable .concat(urls.map { url in self.open(url, cmd: "vsp") }) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func select(buffer: NvimView.Buffer) -> Completable { @@ -112,69 +112,69 @@ extension NvimView { .map { tabs in tabs.map { $0.windows }.flatMap { $0 } } .flatMapCompletable { wins -> Completable in if let win = wins.first(where: { $0.buffer == buffer }) { - return self.nvim.setCurrentWin(window: NvimApi.Window(win.handle), expectsReturnValue: false) + return self.api.setCurrentWin(window: NvimApi.Window(win.handle), expectsReturnValue: false) } - return self.nvim.command(command: "tab sb \(buffer.handle)", expectsReturnValue: false) + return self.api.command(command: "tab sb \(buffer.handle)", expectsReturnValue: false) } - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } /// Closes the current window. public func closeCurrentTab() -> Completable { - return self.nvim + return self.api .command(command: "q", expectsReturnValue: true) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func saveCurrentTab() -> Completable { - return self.nvim + return self.api .command(command: "w", expectsReturnValue: true) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func saveCurrentTab(url: URL) -> Completable { - return self.nvim + return self.api .command(command: "w \(url.path)", expectsReturnValue: true) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func closeCurrentTabWithoutSaving() -> Completable { - return self.nvim + return self.api .command(command: "q!", expectsReturnValue: true) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func quitNeoVimWithoutSaving() -> Completable { self.bridgeLogger.mark() - return self.nvim + return self.api .command(command: "qa!", expectsReturnValue: true) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func vimOutput(of command: String) -> Single { - return self.nvim + return self.api .commandOutput(str: command) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } public func cursorGo(to position: Position) -> Completable { - return self.nvim + return self.api .getCurrentWin() - .flatMapCompletable { curWin in self.nvim.winSetCursor(window: curWin, pos: [position.row, position.column]) } - .subscribeOn(self.nvimApiScheduler) + .flatMapCompletable { curWin in self.api.winSetCursor(window: curWin, pos: [position.row, position.column]) } + .subscribeOn(self.scheduler) } public func didBecomeMain() -> Completable { - return self.uiBridge.focusGained(true) + return self.bridge.focusGained(true) } public func didResignMain() -> Completable { - return self.uiBridge.focusGained(false) + return self.bridge.focusGained(false) } func neoVimBuffer(for buf: NvimApi.Buffer, currentBuffer: NvimApi.Buffer?) -> Single { - return self.nvim + return self.api .getBufGetInfo(buffer: buf) .map { info -> NvimView.Buffer in let current = buf == currentBuffer @@ -195,27 +195,27 @@ extension NvimView { isCurrent: current, isListed: listed) } - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } func waitForNeoVimToQuit() { - self.uiBridge.nvimQuitCondition.lock() - defer { self.uiBridge.nvimQuitCondition.unlock() } - while self.uiBridge.isNvimQuit == false - && self.uiBridge.nvimQuitCondition.wait(until: Date(timeIntervalSinceNow: neoVimQuitTimeout)) {} + self.bridge.nvimQuitCondition.lock() + defer { self.bridge.nvimQuitCondition.unlock() } + while self.bridge.isNvimQuit == false + && self.bridge.nvimQuitCondition.wait(until: Date(timeIntervalSinceNow: neoVimQuitTimeout)) {} } private func `open`(_ url: URL, cmd: String) -> Completable { - return self.nvim + return self.api .command(command: "\(cmd) \(url.path)", expectsReturnValue: false) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) } private func neoVimWindow(for window: NvimApi.Window, currentWindow: NvimApi.Window?, currentBuffer: NvimApi.Buffer?) -> Single { - return self.nvim + return self.api .winGetBuf(window: window) .flatMap { buf in self.neoVimBuffer(for: buf, currentBuffer: currentBuffer) } .map { buffer in NvimView.Window(apiWindow: window, buffer: buffer, isCurrentInTab: window == currentWindow) } @@ -226,8 +226,8 @@ extension NvimView { currentBuffer: NvimApi.Buffer?) -> Single { return Single.zip( - self.nvim.tabpageGetWin(tabpage: tabpage), - self.nvim.tabpageListWins(tabpage: tabpage)) { (curWin: $0, wins: $1) } + self.api.tabpageGetWin(tabpage: tabpage), + self.api.tabpageListWins(tabpage: tabpage)) { (curWin: $0, wins: $1) } .map { tuple in tuple.wins.map { win in return self.neoVimWindow(for: win, currentWindow: tuple.curWin, currentBuffer: currentBuffer) diff --git a/NvimView/NvimView/NvimView+Dragging.swift b/NvimView/NvimView/NvimView+Dragging.swift index 058a08ee..56fb8fe2 100644 --- a/NvimView/NvimView/NvimView+Dragging.swift +++ b/NvimView/NvimView/NvimView+Dragging.swift @@ -27,7 +27,7 @@ extension NvimView { } self.open(urls: paths.map { URL(fileURLWithPath: $0) }) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "\(paths) could not be opened.", cause: error)) }) diff --git a/NvimView/NvimView/NvimView+Key.swift b/NvimView/NvimView/NvimView+Key.swift index 04a5a858..0d3ed9ec 100644 --- a/NvimView/NvimView/NvimView+Key.swift +++ b/NvimView/NvimView/NvimView+Key.swift @@ -40,7 +40,7 @@ extension NvimView { let namedChars = KeyUtils.namedKey(from: charsIgnoringModifiers) let finalInput = isWrapNeeded ? self.wrapNamedKeys(flags + namedChars) : self.vimPlainString(chars) - self.uiBridge + self.bridge .vimInput(finalInput) .subscribe() @@ -53,12 +53,12 @@ extension NvimView { switch aString { case let string as String: - self.uiBridge + self.bridge .vimInput(self.vimPlainString(string)) .subscribe() case let attributedString as NSAttributedString: - self.uiBridge + self.bridge .vimInput(self.vimPlainString(attributedString.string)) .subscribe() @@ -112,7 +112,7 @@ extension NvimView { // Control code \0 causes rpc parsing problems. // So we escape as early as possible if chars == "\0" { - self.uiBridge + self.bridge .vimInput(self.wrapNamedKeys("Nul")) .subscribe() return true @@ -122,14 +122,14 @@ extension NvimView { // See special cases in vim/os_win32.c from vim sources // Also mentioned in MacVim's KeyBindings.plist if .control == flags && chars == "6" { - self.uiBridge + self.bridge .vimInput("\u{1e}") // AKA ^^ .subscribe() return true } if .control == flags && chars == "2" { // should generate \0, escaping as above - self.uiBridge + self.bridge .vimInput(self.wrapNamedKeys("Nul")) .subscribe() return true @@ -157,7 +157,7 @@ extension NvimView { .flatMap { length -> Observable in // eg 하 -> hanja popup, cf comment for self.lastMarkedText if length > 0 { - return self.uiBridge.deleteCharacters(length).asObservable() + return self.bridge.deleteCharacters(length).asObservable() } return Completable.empty().asObservable() @@ -180,7 +180,7 @@ extension NvimView { return Disposables.create() } ) - .andThen(self.uiBridge.vimInputMarkedText(self.markedText!)) + .andThen(self.bridge.vimInputMarkedText(self.markedText!)) .subscribe() self.keyDownDone = true diff --git a/NvimView/NvimView/NvimView+MenuItems.swift b/NvimView/NvimView/NvimView+MenuItems.swift index 3b400ba0..1453a7c6 100644 --- a/NvimView/NvimView/NvimView+MenuItems.swift +++ b/NvimView/NvimView/NvimView+MenuItems.swift @@ -49,13 +49,13 @@ extension NvimView { @IBAction func undo(_ sender: AnyObject?) { switch self.mode { case .insert, .replace: - self.uiBridge + self.bridge .vimInput("ui") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not undo", cause: error)) }) case .normal, .visual: - self.uiBridge + self.bridge .vimInput("u") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not undo", cause: error)) @@ -68,13 +68,13 @@ extension NvimView { @IBAction func redo(_ sender: AnyObject?) { switch self.mode { case .insert, .replace: - self.uiBridge + self.bridge .vimInput("i") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not redo", cause: error)) }) case .normal, .visual: - self.uiBridge + self.bridge .vimInput("") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not redo", cause: error)) @@ -87,7 +87,7 @@ extension NvimView { @IBAction func cut(_ sender: AnyObject?) { switch self.mode { case .visual, .normal: - self.uiBridge + self.bridge .vimInput("\"+d") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not cut", cause: error)) @@ -100,7 +100,7 @@ extension NvimView { @IBAction func copy(_ sender: AnyObject?) { switch self.mode { case .visual, .normal: - self.uiBridge + self.bridge .vimInput("\"+y") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not copy", cause: error)) @@ -118,7 +118,7 @@ extension NvimView { if self.mode == .cmdline || self.mode == .cmdlineInsert || self.mode == .cmdlineReplace || self.mode == .replace || self.mode == .termFocus { - self.uiBridge + self.bridge .vimInput(self.vimPlainString(content)) .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not paste \(content)", cause: error)) @@ -126,11 +126,11 @@ extension NvimView { return } - self.nvim + self.api .getOption(name: "paste") .flatMap { curPasteMode -> Single in if curPasteMode == false { - return self.nvim + return self.api .setOption(name: "paste", value: .bool(true)) .andThen(Single.just(true)) } else { @@ -141,12 +141,12 @@ extension NvimView { switch self.mode { case .insert: - return self.uiBridge + return self.bridge .vimInput("\"+pa") .andThen(Single.just(pasteModeSet)) case .normal, .visual: - return self.uiBridge + return self.bridge .vimInput("\"+p") .andThen(Single.just(pasteModeSet)) @@ -157,7 +157,7 @@ extension NvimView { } .flatMapCompletable { pasteModeSet -> Completable in if pasteModeSet { - return self.nvim.setOption(name: "paste", value: .bool(false)) + return self.api.setOption(name: "paste", value: .bool(false)) } return Completable.empty() @@ -170,7 +170,7 @@ extension NvimView { @IBAction func delete(_ sender: AnyObject?) { switch self.mode { case .normal, .visual: - self.uiBridge + self.bridge .vimInput("x") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not delete", cause: error)) @@ -183,13 +183,13 @@ extension NvimView { @IBAction public override func selectAll(_ sender: Any?) { switch self.mode { case .insert, .visual: - self.uiBridge + self.bridge .vimInput("ggVG") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not select all", cause: error)) }) default: - self.uiBridge + self.bridge .vimInput("ggVG") .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not select all", cause: error)) diff --git a/NvimView/NvimView/NvimView+Mouse.swift b/NvimView/NvimView/NvimView+Mouse.swift index 21385a2f..97db32de 100644 --- a/NvimView/NvimView/NvimView+Mouse.swift +++ b/NvimView/NvimView/NvimView+Mouse.swift @@ -33,9 +33,9 @@ extension NvimView { let (vimInputX, vimInputY) = self.vimScrollInputFor(deltaX: deltaX, deltaY: deltaY, modifierFlags: event.modifierFlags, cellPosition: cellPosition) - self.uiBridge + self.bridge .vimInput(vimInputX) - .andThen(self.uiBridge.vimInput(vimInputY)) + .andThen(self.bridge.vimInput(vimInputY)) .subscribe() return @@ -46,7 +46,7 @@ extension NvimView { min(Int(ceil(abs(deltaY) / self.trackpadScrollResistance)), maxScrollDeltaY) ) let (horizSign, vertSign) = (deltaX > 0 ? 1 : -1, deltaY > 0 ? 1 : -1) - self.uiBridge + self.bridge .scroll(horizontal: horizSign * absDeltaX, vertical: vertSign * absDeltaY, at: cellPosition) .subscribe() } @@ -105,7 +105,7 @@ extension NvimView { } // self.logger.debug("\(#function): \(result)") - self.uiBridge + self.bridge .vimInput(result) .subscribe() } diff --git a/NvimView/NvimView/NvimView+Resize.swift b/NvimView/NvimView/NvimView+Resize.swift index c90a2b13..41d42174 100644 --- a/NvimView/NvimView/NvimView+Resize.swift +++ b/NvimView/NvimView/NvimView+Resize.swift @@ -55,7 +55,7 @@ extension NvimView { self.xOffset = floor((size.width - self.cellSize.width * CGFloat(discreteSize.width)) / 2) self.yOffset = floor((size.height - self.cellSize.height * CGFloat(discreteSize.height)) / 2) - try? self.uiBridge + try? self.bridge .resize(width: discreteSize.width, height: discreteSize.height) .wait() } @@ -64,9 +64,9 @@ extension NvimView { self.logger.info("=== Starting neovim...") let sockPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("vimr_\(self.uuid).sock").path - self.uiBridge + self.bridge .runLocalServerAndNvim(width: size.width, height: size.height) - .andThen(self.nvim.run(at: sockPath)) + .andThen(self.api.run(at: sockPath)) .subscribe(onError: { error in self.eventsSubject.onError(Error.nvimLaunch(msg: "Could not launch nvim", cause: error)) }) diff --git a/NvimView/NvimView/NvimView+TouchBar.swift b/NvimView/NvimView/NvimView+TouchBar.swift index f001bc12..58eb2147 100644 --- a/NvimView/NvimView/NvimView+TouchBar.swift +++ b/NvimView/NvimView/NvimView+TouchBar.swift @@ -126,9 +126,9 @@ extension NvimView: NSTouchBarDelegate, NSScrubberDataSource, NSScrubberDelegate } let window = tab.currentWindow ?? tab.windows[0] - self.nvim + self.api .setCurrentWin(window: NvimApi.Window(window.handle), expectsReturnValue: false) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) .subscribe(onError: { error in self.eventsSubject.onNext(.apiError(msg: "Could not set current window to \(window.handle).", cause: error)) }) diff --git a/NvimView/NvimView/NvimView+UiBridge.swift b/NvimView/NvimView/NvimView+UiBridge.swift index b3e66d11..a6986bde 100644 --- a/NvimView/NvimView/NvimView+UiBridge.swift +++ b/NvimView/NvimView/NvimView+UiBridge.swift @@ -156,9 +156,9 @@ extension NvimView { func stop() { self.bridgeLogger.hr() - try? self.nvim + try? self.api .stop() - .andThen(self.uiBridge.quit()) + .andThen(self.bridge.quit()) .wait() gui.async { @@ -192,7 +192,7 @@ extension NvimView { self.bridgeLogger.debug(reason) gui.async { - if self.uiBridge.isNvimQuitting || self.uiBridge.isNvimQuit { + if self.bridge.isNvimQuitting || self.bridge.isNvimQuit { return } @@ -200,9 +200,9 @@ extension NvimView { self.eventsSubject.onCompleted() self.bridgeLogger.error("Force-closing due to IPC error.") - try? self.nvim + try? self.api .stop() - .andThen(self.uiBridge.forceQuit()) + .andThen(self.bridge.forceQuit()) .wait() } } diff --git a/NvimView/NvimView/NvimView.swift b/NvimView/NvimView/NvimView.swift index 2a5772b4..e9c0b4ce 100644 --- a/NvimView/NvimView/NvimView.swift +++ b/NvimView/NvimView/NvimView.swift @@ -170,9 +170,9 @@ public class NvimView: NSView, } set { - self.nvim + self.api .setCurrentDir(dir: newValue.path, expectsReturnValue: false) - .subscribeOn(self.nvimApiScheduler) + .subscribeOn(self.scheduler) .subscribe(onError: { error in self.eventsSubject.onError(Error.ipc(msg: "Could not set cwd to \(newValue)", cause: error)) }) @@ -183,7 +183,8 @@ public class NvimView: NSView, return true } - public let nvimApiScheduler = SerialDispatchQueueScheduler(qos: .userInitiated) + public let queue = DispatchQueue(label: "com.qvacua.NvimView.NvimView", qos: .userInitiated) + public let scheduler: SerialDispatchQueueScheduler public internal(set) var currentPosition = Position.beginning @@ -193,7 +194,9 @@ public class NvimView: NSView, public init(frame rect: NSRect, config: Config) { self.drawer = TextDrawer(font: self._font) - self.uiBridge = UiBridge(uuid: self.uuid, config: config) + self.bridge = UiBridge(uuid: self.uuid, queue: self.queue, config: config) + self.scheduler = SerialDispatchQueueScheduler(queue: self.queue, + internalSerialQueueName: "com.qvacua.NvimView.NvimView") super.init(frame: .zero) self.registerForDraggedTypes([NSPasteboard.PasteboardType(String(kUTTypeFileURL))]) @@ -203,7 +206,8 @@ public class NvimView: NSView, self.descent = self.drawer.descent self.leading = self.drawer.leading - self.uiBridge.stream + self.api.queue = self.queue + self.bridge.stream .subscribe(onNext: { [unowned self] msg in switch msg { @@ -309,7 +313,7 @@ public class NvimView: NSView, @IBAction public func debug1(_ sender: Any?) { self.logger.debug("DEBUG 1 - Start") - self.uiBridge + self.bridge .debug() .subscribe() self.logger.debug("DEBUG 1 - End") @@ -332,8 +336,8 @@ public class NvimView: NSView, let bridgeLogger = LogContext.fileLogger(as: NvimView.self, with: URL(fileURLWithPath: "/tmp/nvv-bridge.log"), shouldLogDebug: nil) - let uiBridge: UiBridge - let nvim = NvimApi() + let bridge: UiBridge + let api = NvimApi() let grid = Grid() let drawer: TextDrawer diff --git a/NvimView/NvimView/UiBridge.swift b/NvimView/NvimView/UiBridge.swift index 1f14cd72..1c6960b9 100644 --- a/NvimView/NvimView/UiBridge.swift +++ b/NvimView/NvimView/UiBridge.swift @@ -54,29 +54,20 @@ class UiBridge { return self.streamSubject.asObservable() } - var scheduler: SerialDispatchQueueScheduler - var queue = DispatchQueue(label: "com.qvacua.NvimView.UiBridge", qos: .userInitiated) { - didSet { - self.scheduler = SerialDispatchQueueScheduler(queue: self.queue, - internalSerialQueueName: "com.qvacua.NvimView.UiBridge") - } - } - let nvimQuitCondition = NSCondition() private(set) var isNvimQuitting = false private(set) var isNvimQuit = false - init(uuid: String, config: NvimView.Config) { + init(uuid: String, queue: DispatchQueue, config: NvimView.Config) { self.uuid = uuid self.useInteractiveZsh = config.useInteractiveZsh self.nvimArgs = config.nvimArgs ?? [] self.cwd = config.cwd - self.scheduler = SerialDispatchQueueScheduler(queue: self.queue, - internalSerialQueueName: "com.qvacua.NvimView.UiBridge") - + self.queue = queue + self.scheduler = SerialDispatchQueueScheduler(queue: queue, internalSerialQueueName: "com.qvacua.NvimView.UiBridge") self.client.queue = self.queue self.server.queue = self.queue @@ -454,6 +445,9 @@ class UiBridge { private var runLocalServerAndNvimCompletable: Completable.CompletableObserver? + private let scheduler: SerialDispatchQueueScheduler + private let queue: DispatchQueue + private let streamSubject = PublishSubject() private let disposeBag = DisposeBag()