diff --git a/NvimView/Sources/NvimView/NvimView+Types.swift b/NvimView/Sources/NvimView/NvimView+Types.swift index 5a12c5b9..816048d0 100644 --- a/NvimView/Sources/NvimView/NvimView+Types.swift +++ b/NvimView/Sources/NvimView/NvimView+Types.swift @@ -58,6 +58,8 @@ public extension NvimView { case setTitle(String) case setDirtyStatus(Bool) case cwdChanged + case tcwdChanged + case lcwdChanged case bufferListChanged case tabChanged diff --git a/NvimView/Sources/NvimView/NvimView+UiBridge.swift b/NvimView/Sources/NvimView/NvimView+UiBridge.swift index 172b1751..fd0260f0 100644 --- a/NvimView/Sources/NvimView/NvimView+UiBridge.swift +++ b/NvimView/Sources/NvimView/NvimView+UiBridge.swift @@ -333,13 +333,21 @@ extension NvimView { } if event == .dirchanged { - guard array.count > 1, - array[1].stringValue != nil + guard array.count > 2, + array[1].stringValue != nil, + let scope = array[2].stringValue else { self.bridgeLogger.error("Could not convert \(array)") return } - self.cwdChanged(array[1]) + + if scope == "tabpage" { + self.tcwdChanged(array[1]) + } else if scope == "window" { + self.lcwdChanged(array[1]) + } else { + self.cwdChanged(array[1]) + } return } @@ -572,6 +580,28 @@ extension NvimView { self.eventsSubject.onNext(.cwdChanged) } + final func tcwdChanged(_ value: MessagePackValue) { + guard let cwd = value.stringValue else { + self.bridgeLogger.error("Could not convert \(value)") + return + } + + self.bridgeLogger.debug(cwd) + self._cwd = URL(fileURLWithPath: cwd) + self.eventsSubject.onNext(.tcwdChanged) + } + + final func lcwdChanged(_ value: MessagePackValue) { + guard let cwd = value.stringValue else { + self.bridgeLogger.error("Could not convert \(value)") + return + } + + self.bridgeLogger.debug(cwd) + self._cwd = URL(fileURLWithPath: cwd) + self.eventsSubject.onNext(.lcwdChanged) + } + final func colorSchemeChanged(_ value: MessagePackValue) { guard let values = MessagePackUtils.array( from: value, ofSize: 5, conversion: { $0.intValue } diff --git a/NvimView/Sources/NvimView/NvimView.swift b/NvimView/Sources/NvimView/NvimView.swift index 25f856f9..06d416b7 100644 --- a/NvimView/Sources/NvimView/NvimView.swift +++ b/NvimView/Sources/NvimView/NvimView.swift @@ -40,7 +40,7 @@ public protocol NvimViewDelegate: AnyObject { public final class NvimView: NSView, NSUserInterfaceValidations, NSTextInputClient { // MARK: - Public - + public static let rpcEventName = "com.qvacua.NvimView" public static let minFontSize = 4.0 @@ -142,6 +142,36 @@ public final class NvimView: NSView, NSUserInterfaceValidations, NSTextInputClie } } + public var tcwd: URL { + get { self._cwd } + + set { + self.api + .exec2(src:"tcd \(newValue.path)", opts: [:]) + .subscribe(on: self.scheduler) + .subscribe(onFailure: { [weak self] error in + self?.eventsSubject + .onError(Error.ipc(msg: "Could not set cwd to \(newValue)", cause: error)) + }) + .disposed(by: self.disposeBag) + } + } + + public var lcwd: URL { + get { self._cwd } + + set { + self.api + .exec2(src:"lcd \(newValue.path)", opts: [:]) + .subscribe(on: self.scheduler) + .subscribe(onFailure: { [weak self] error in + self?.eventsSubject + .onError(Error.ipc(msg: "Could not set cwd to \(newValue)", cause: error)) + }) + .disposed(by: self.disposeBag) + } + } + public var defaultCellAttributes: CellAttributes { self.cellAttributesCollection.defaultAttributes } @@ -375,7 +405,7 @@ public final class NvimView: NSView, NSUserInterfaceValidations, NSTextInputClie autocmd TabEnter * call rpcnotify(\(channel), 'autocommand', 'tabenter', str2nr(expand(''))) autocmd BufWritePost * call rpcnotify(\(channel), 'autocommand', 'bufwritepost', str2nr(expand(''))) autocmd BufEnter * call rpcnotify(\(channel), 'autocommand', 'bufenter', str2nr(expand(''))) - autocmd DirChanged * call rpcnotify(\( channel), 'autocommand', 'dirchanged', expand('')) + autocmd DirChanged * call rpcnotify(\( channel), 'autocommand', 'dirchanged', expand(''), v:event['scope']) autocmd BufModifiedSet * call rpcnotify(\(channel), 'autocommand', 'bufmodifiedset', str2nr(expand('')), getbufinfo(str2nr(expand('')))[0].changed) """, opts: [:], errWhenBlocked: false) // swiftformat:enable all diff --git a/VimR/VimR/Context.swift b/VimR/VimR/Context.swift index 3a64b17d..cfd94e39 100644 --- a/VimR/VimR/Context.swift +++ b/VimR/VimR/Context.swift @@ -112,6 +112,8 @@ final class Context: ReduxContext { private func cleanUpAppState() { self.state.mainWindows.keys.forEach { uuid in self.state.mainWindows[uuid]?.cwdToSet = nil + self.state.mainWindows[uuid]?.tcwdToSet = nil + self.state.mainWindows[uuid]?.lcwdToSet = nil self.state.mainWindows[uuid]?.currentBufferToSet = nil self.state.mainWindows[uuid]?.viewToBeFocused = nil self.state.mainWindows[uuid]?.urlsToOpen.removeAll() diff --git a/VimR/VimR/MainWindow+Delegates.swift b/VimR/VimR/MainWindow+Delegates.swift index 2571bfa2..a3ffdc77 100644 --- a/VimR/VimR/MainWindow+Delegates.swift +++ b/VimR/VimR/MainWindow+Delegates.swift @@ -67,6 +67,14 @@ extension MainWindow { self.emit(self.uuidAction(for: .cd(to: self.neoVimView.cwd))) } + func tcwdChanged() { + self.emit(self.uuidAction(for: .tcd(to: self.neoVimView.cwd))) + } + + func lcwdChanged() { + self.emit(self.uuidAction(for: .lcd(to: self.neoVimView.cwd))) + } + func bufferListChanged() { self.neoVimView .allBuffers() diff --git a/VimR/VimR/MainWindow+Types.swift b/VimR/VimR/MainWindow+Types.swift index 665ec903..2b0c8a09 100644 --- a/VimR/VimR/MainWindow+Types.swift +++ b/VimR/VimR/MainWindow+Types.swift @@ -10,6 +10,8 @@ import Workspace extension MainWindow { enum Action { case cd(to: URL) + case tcd(to: URL) + case lcd(to: URL) case setBufferList([NvimView.Buffer]) case newCurrentBuffer(NvimView.Buffer) diff --git a/VimR/VimR/MainWindow.swift b/VimR/VimR/MainWindow.swift index 93d23a67..97b62d73 100644 --- a/VimR/VimR/MainWindow.swift +++ b/VimR/VimR/MainWindow.swift @@ -290,6 +290,10 @@ final class MainWindow: NSObject, case .cwdChanged: self?.cwdChanged() + case .tcwdChanged: self?.tcwdChanged() + + case .lcwdChanged: self?.lcwdChanged() + case .bufferListChanged: self?.bufferListChanged() case .tabChanged: self?.tabChanged() @@ -348,6 +352,16 @@ final class MainWindow: NSObject, self.neoVimView.tabBar?.cwd = cwd.path } + if let cwd = state.tcwdToSet { + self.neoVimView.tcwd = cwd + self.neoVimView.tabBar?.cwd = cwd.path + } + + if let cwd = state.lcwdToSet { + self.neoVimView.lcwd = cwd + self.neoVimView.tabBar?.cwd = cwd.path + } + Completable .empty() .andThen { diff --git a/VimR/VimR/MainWindowReducer.swift b/VimR/VimR/MainWindowReducer.swift index 8711031d..d7700cec 100644 --- a/VimR/VimR/MainWindowReducer.swift +++ b/VimR/VimR/MainWindowReducer.swift @@ -22,6 +22,18 @@ final class MainWindowReducer: ReducerType { state.cwdToSet = cwd // Ensure updates also pend to tab bar } + case let .tcd(to: cwd): + if state.cwd != cwd { + state.cwd = cwd + state.tcwdToSet = cwd // Ensure updates also pend to tab bar + } + + case let .lcd(to: cwd): + if state.cwd != cwd { + state.cwd = cwd + state.lcwdToSet = cwd // Ensure updates also pend to tab bar + } + case let .setBufferList(buffers): state.buffers = buffers diff --git a/VimR/VimR/States.swift b/VimR/VimR/States.swift index b329ebf9..640e5e79 100644 --- a/VimR/VimR/States.swift +++ b/VimR/VimR/States.swift @@ -335,6 +335,8 @@ extension MainWindow { var urlsToOpen = [URL: OpenMode]() var currentBufferToSet: NvimView.Buffer? var cwdToSet: URL? + var tcwdToSet: URL? + var lcwdToSet: URL? var viewToBeFocused: FocusableView? = FocusableView.neoVimView init(isAllToolsVisible: Bool, isToolButtonsVisible: Bool, nvimBinary: String) {