1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-11-28 02:54:31 +03:00
This commit is contained in:
Tae Won Ha 2020-12-10 21:50:40 +01:00
parent 78d95ce6b5
commit da43da7ff0
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44

View File

@ -4,87 +4,90 @@
*/ */
import Cocoa import Cocoa
import RxSwift
import MessagePack import MessagePack
import RxPack import RxPack
import RxSwift
extension NvimView { public extension NvimView {
func isBlocked() -> Single<Bool> {
public func isBlocked() -> Single<Bool> { self.api.getMode().map { dict in dict["blocking"]?.boolValue ?? false }
return self.api.getMode().map { dict in dict["blocking"]?.boolValue ?? false }
} }
public func hasDirtyBuffers() -> Single<Bool> { func hasDirtyBuffers() -> Single<Bool> {
return self.api.getDirtyStatus() self.api.getDirtyStatus()
} }
public func waitTillNvimExits() { func waitTillNvimExits() {
self.nvimExitedCondition.wait(for: 5) self.nvimExitedCondition.wait(for: 5)
} }
public func enterResizeMode() { func enterResizeMode() {
self.currentlyResizing = true self.currentlyResizing = true
self.markForRenderWholeView() self.markForRenderWholeView()
} }
public func exitResizeMode() { func exitResizeMode() {
self.currentlyResizing = false self.currentlyResizing = false
self.markForRenderWholeView() self.markForRenderWholeView()
self.resizeNeoVimUi(to: self.bounds.size) self.resizeNeoVimUi(to: self.bounds.size)
} }
public func currentBuffer() -> Single<NvimView.Buffer> { func currentBuffer() -> Single<NvimView.Buffer> {
return self.api self.api
.getCurrentBuf() .getCurrentBuf()
.flatMap { self.neoVimBuffer(for: $0, currentBuffer: $0) } .flatMap { self.neoVimBuffer(for: $0, currentBuffer: $0) }
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func allBuffers() -> Single<[NvimView.Buffer]> { func allBuffers() -> Single<[NvimView.Buffer]> {
return Single Single
.zip(self.api.getCurrentBuf(), self.api.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) } } .map { tuple in tuple.bufs.map { buf in
self.neoVimBuffer(for: buf, currentBuffer: tuple.curBuf)
} }
.flatMap(Single.fromSinglesToSingleOfArray) .flatMap(Single.fromSinglesToSingleOfArray)
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func isCurrentBufferDirty() -> Single<Bool> { func isCurrentBufferDirty() -> Single<Bool> {
return self self
.currentBuffer() .currentBuffer()
.map { $0.isDirty } .map(\.isDirty)
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func allTabs() -> Single<[NvimView.Tabpage]> { func allTabs() -> Single<[NvimView.Tabpage]> {
return Single.zip(self.api.getCurrentBuf(), Single.zip(
self.api.getCurrentBuf(),
self.api.getCurrentTabpage(), self.api.getCurrentTabpage(),
self.api.listTabpages()) { (curBuf: $0, curTab: $1, tabs: $2) } self.api.listTabpages()
) { (curBuf: $0, curTab: $1, tabs: $2) }
.map { tuple in .map { tuple in
return tuple.tabs.map { tab in tuple.tabs.map { tab in
return self.neoVimTab(for: tab, currentTabpage: tuple.curTab, currentBuffer: tuple.curBuf) self.neoVimTab(for: tab, currentTabpage: tuple.curTab, currentBuffer: tuple.curBuf)
} }
} }
.flatMap(Single.fromSinglesToSingleOfArray) .flatMap(Single.fromSinglesToSingleOfArray)
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func newTab() -> Completable { func newTab() -> Completable {
return self.api self.api
.command(command: "tabe") .command(command: "tabe")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func `open`(urls: [URL]) -> Completable { func open(urls: [URL]) -> Completable {
return self self
.allTabs() .allTabs()
.flatMapCompletable { tabs -> Completable in .flatMapCompletable { tabs -> Completable in
let buffers = tabs.map { $0.windows }.flatMap { $0 }.map { $0.buffer } let buffers = tabs.map(\.windows).flatMap { $0 }.map(\.buffer)
let currentBufferIsTransient = buffers.first { $0.isCurrent }?.isTransient ?? false let currentBufferIsTransient = buffers.first { $0.isCurrent }?.isTransient ?? false
return Completable.concat( return Completable.concat(
urls.map { url -> Completable in urls.map { url -> Completable in
let bufExists = buffers.contains { $0.url == url } let bufExists = buffers.contains { $0.url == url }
let wins = tabs.map({ $0.windows }).flatMap({ $0 }) let wins = tabs.map(\.windows).flatMap { $0 }
if let win = bufExists ? wins.first(where: { win in win.buffer.url == url }) : nil { if let win = bufExists ? wins.first(where: { win in win.buffer.url == url }) : nil {
return self.api.setCurrentWin(window: RxNeovimApi.Window(win.handle)) return self.api.setCurrentWin(window: RxNeovimApi.Window(win.handle))
} }
@ -96,32 +99,32 @@ extension NvimView {
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func openInNewTab(urls: [URL]) -> Completable { func openInNewTab(urls: [URL]) -> Completable {
return Completable Completable
.concat(urls.map { url in self.open(url, cmd: "tabe") }) .concat(urls.map { url in self.open(url, cmd: "tabe") })
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func openInCurrentTab(url: URL) -> Completable { func openInCurrentTab(url: URL) -> Completable {
return self.open(url, cmd: "e") self.open(url, cmd: "e")
} }
public func openInHorizontalSplit(urls: [URL]) -> Completable { func openInHorizontalSplit(urls: [URL]) -> Completable {
return Completable Completable
.concat(urls.map { url in self.open(url, cmd: "sp") }) .concat(urls.map { url in self.open(url, cmd: "sp") })
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func openInVerticalSplit(urls: [URL]) -> Completable { func openInVerticalSplit(urls: [URL]) -> Completable {
return Completable Completable
.concat(urls.map { url in self.open(url, cmd: "vsp") }) .concat(urls.map { url in self.open(url, cmd: "vsp") })
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func select(buffer: NvimView.Buffer) -> Completable { func select(buffer: NvimView.Buffer) -> Completable {
return self self
.allTabs() .allTabs()
.map { tabs in tabs.map { $0.windows }.flatMap { $0 } } .map { tabs in tabs.map(\.windows).flatMap { $0 } }
.flatMapCompletable { wins -> Completable in .flatMapCompletable { wins -> Completable in
if let win = wins.first(where: { $0.buffer == buffer }) { if let win = wins.first(where: { $0.buffer == buffer }) {
return self.api.setCurrentWin(window: RxNeovimApi.Window(win.handle)) return self.api.setCurrentWin(window: RxNeovimApi.Window(win.handle))
@ -132,64 +135,65 @@ extension NvimView {
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func goTo(line: Int) -> Completable { func goTo(line: Int) -> Completable {
return self.api.command(command: "\(line)") self.api.command(command: "\(line)")
} }
/// Closes the current window. /// Closes the current window.
public func closeCurrentTab() -> Completable { func closeCurrentTab() -> Completable {
return self.api self.api
.command(command: "q") .command(command: "q")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func saveCurrentTab() -> Completable { func saveCurrentTab() -> Completable {
return self.api self.api
.command(command: "w") .command(command: "w")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func saveCurrentTab(url: URL) -> Completable { func saveCurrentTab(url: URL) -> Completable {
return self.api self.api
.command(command: "w \(url.path)") .command(command: "w \(url.path)")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func closeCurrentTabWithoutSaving() -> Completable { func closeCurrentTabWithoutSaving() -> Completable {
return self.api self.api
.command(command: "q!") .command(command: "q!")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func quitNeoVimWithoutSaving() -> Completable { func quitNeoVimWithoutSaving() -> Completable {
return self.api self.api
.command(command: "qa!") .command(command: "qa!")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func vimOutput(of command: String) -> Single<String> { func vimOutput(of command: String) -> Single<String> {
return self.api self.api
.exec(src: command, output: true) .exec(src: command, output: true)
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func cursorGo(to position: Position) -> Completable { func cursorGo(to position: Position) -> Completable {
return self.api self.api
.getCurrentWin() .getCurrentWin()
.flatMapCompletable { curWin in self.api.winSetCursor(window: curWin, pos: [position.row, position.column]) } .flatMapCompletable { curWin in
self.api.winSetCursor(window: curWin, pos: [position.row, position.column])
}
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
public func didBecomeMain() -> Completable { func didBecomeMain() -> Completable { self.bridge.focusGained(true) }
return self.bridge.focusGained(true)
}
public func didResignMain() -> Completable { func didResignMain() -> Completable { self.bridge.focusGained(false) }
return self.bridge.focusGained(false)
}
func neoVimBuffer(for buf: RxNeovimApi.Buffer, currentBuffer: RxNeovimApi.Buffer?) -> Single<NvimView.Buffer> { internal func neoVimBuffer(
return self.api for buf: RxNeovimApi.Buffer,
currentBuffer: RxNeovimApi.Buffer?
) -> Single<NvimView.Buffer> {
self.api
.bufGetInfo(buffer: buf) .bufGetInfo(buffer: buf)
.map { info -> NvimView.Buffer in .map { info -> NvimView.Buffer in
let current = buf == currentBuffer let current = buf == currentBuffer
@ -198,50 +202,62 @@ extension NvimView {
let buftype = info["buftype"]?.stringValue, let buftype = info["buftype"]?.stringValue,
let listed = info["buflisted"]?.boolValue let listed = info["buflisted"]?.boolValue
else { else {
throw RxNeovimApi.Error.exception(message: "Could not convert values from the dictionary.") throw RxNeovimApi.Error
.exception(message: "Could not convert values from the dictionary.")
} }
let url = path == "" || buftype != "" ? nil : URL(fileURLWithPath: path) let url = path == "" || buftype != "" ? nil : URL(fileURLWithPath: path)
return NvimView.Buffer(apiBuffer: buf, return NvimView.Buffer(
apiBuffer: buf,
url: url, url: url,
type: buftype, type: buftype,
isDirty: dirty, isDirty: dirty,
isCurrent: current, isCurrent: current,
isListed: listed) isListed: listed
)
} }
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
private func `open`(_ url: URL, cmd: String) -> Completable { private func open(_ url: URL, cmd: String) -> Completable {
return self.api self.api
.command(command: "\(cmd) \(url.path)") .command(command: "\(cmd) \(url.path)")
.subscribeOn(self.scheduler) .subscribeOn(self.scheduler)
} }
private func neoVimWindow(for window: RxNeovimApi.Window, private func neoVimWindow(
for window: RxNeovimApi.Window,
currentWindow: RxNeovimApi.Window?, currentWindow: RxNeovimApi.Window?,
currentBuffer: RxNeovimApi.Buffer?) -> Single<NvimView.Window> { currentBuffer: RxNeovimApi.Buffer?
) -> Single<NvimView.Window> {
return self.api self.api
.winGetBuf(window: window) .winGetBuf(window: window)
.flatMap { buf in self.neoVimBuffer(for: buf, currentBuffer: currentBuffer) } .flatMap { buf in self.neoVimBuffer(for: buf, currentBuffer: currentBuffer) }
.map { buffer in NvimView.Window(apiWindow: window, buffer: buffer, isCurrentInTab: window == currentWindow) } .map { buffer in NvimView.Window(
apiWindow: window,
buffer: buffer,
isCurrentInTab: window == currentWindow
) }
} }
private func neoVimTab(for tabpage: RxNeovimApi.Tabpage, private func neoVimTab(
for tabpage: RxNeovimApi.Tabpage,
currentTabpage: RxNeovimApi.Tabpage?, currentTabpage: RxNeovimApi.Tabpage?,
currentBuffer: RxNeovimApi.Buffer?) -> Single<NvimView.Tabpage> { currentBuffer: RxNeovimApi.Buffer?
) -> Single<NvimView.Tabpage> {
return Single.zip( Single.zip(
self.api.tabpageGetWin(tabpage: tabpage), self.api.tabpageGetWin(tabpage: tabpage),
self.api.tabpageListWins(tabpage: tabpage)) { (curWin: $0, wins: $1) } self.api.tabpageListWins(tabpage: tabpage)
) { (curWin: $0, wins: $1) }
.map { tuple in .map { tuple in
tuple.wins.map { win in tuple.wins.map { win in
return self.neoVimWindow(for: win, currentWindow: tuple.curWin, currentBuffer: currentBuffer) self.neoVimWindow(for: win, currentWindow: tuple.curWin, currentBuffer: currentBuffer)
} }
} }
.flatMap(Single.fromSinglesToSingleOfArray) .flatMap(Single.fromSinglesToSingleOfArray)
.map { wins in NvimView.Tabpage(apiTabpage: tabpage, windows: wins, isCurrent: tabpage == currentTabpage) } .map { wins in
NvimView.Tabpage(apiTabpage: tabpage, windows: wins, isCurrent: tabpage == currentTabpage)
}
} }
} }