2017-05-27 16:13:22 +03:00
|
|
|
/**
|
|
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
|
|
* See LICENSE
|
|
|
|
*/
|
|
|
|
|
|
|
|
import Cocoa
|
|
|
|
|
|
|
|
extension NeoVimView {
|
|
|
|
|
|
|
|
public func syncNeoVimWithBounds() {
|
|
|
|
self.resizeNeoVimUi(to: self.bounds.size)
|
|
|
|
}
|
|
|
|
|
|
|
|
public func enterResizeMode() {
|
|
|
|
self.currentlyResizing = true
|
|
|
|
self.needsDisplay = true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func exitResizeMode() {
|
|
|
|
self.currentlyResizing = false
|
|
|
|
self.needsDisplay = true
|
|
|
|
self.resizeNeoVimUi(to: self.bounds.size)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
- returns: nil when for exampls a quickfix panel is open.
|
|
|
|
*/
|
|
|
|
public func currentBuffer() -> NeoVimBuffer? {
|
|
|
|
return self.agent.buffers().first { $0.isCurrent }
|
|
|
|
}
|
|
|
|
|
|
|
|
public func allBuffers() -> [NeoVimBuffer] {
|
|
|
|
return self.agent.tabs().map { $0.allBuffers() }.flatMap { $0 }
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hasDirtyDocs() -> Bool {
|
|
|
|
return self.agent.hasDirtyDocs()
|
|
|
|
}
|
|
|
|
|
|
|
|
public func isCurrentBufferDirty() -> Bool {
|
|
|
|
let curBuf = self.currentBuffer()
|
|
|
|
return curBuf?.isDirty ?? true
|
|
|
|
}
|
|
|
|
|
|
|
|
public func newTab() {
|
|
|
|
self.exec(command: "tabe")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func `open`(urls: [URL]) {
|
|
|
|
let tabs = self.agent.tabs()
|
|
|
|
let buffers = self.allBuffers()
|
|
|
|
let currentBufferIsTransient = buffers.first { $0.isCurrent }?.isTransient ?? false
|
|
|
|
|
|
|
|
urls.enumerated().forEach { (idx, url) in
|
|
|
|
if buffers.filter({ $0.url == url }).first != nil {
|
|
|
|
for window in tabs.map({ $0.windows }).flatMap({ $0 }) {
|
|
|
|
if window.buffer.url == url {
|
|
|
|
self.agent.select(window)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if currentBufferIsTransient {
|
|
|
|
self.open(url, cmd: "e")
|
|
|
|
} else {
|
|
|
|
self.open(url, cmd: "tabe")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public func openInNewTab(urls: [URL]) {
|
|
|
|
urls.forEach { self.open($0, cmd: "tabe") }
|
|
|
|
}
|
|
|
|
|
|
|
|
public func openInCurrentTab(url: URL) {
|
|
|
|
self.open(url, cmd: "e")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func openInHorizontalSplit(urls: [URL]) {
|
|
|
|
urls.forEach { self.open($0, cmd: "sp") }
|
|
|
|
}
|
|
|
|
|
|
|
|
public func openInVerticalSplit(urls: [URL]) {
|
|
|
|
urls.forEach { self.open($0, cmd: "vsp") }
|
|
|
|
}
|
|
|
|
|
|
|
|
public func select(buffer: NeoVimBuffer) {
|
|
|
|
for window in self.agent.tabs().map({ $0.windows }).flatMap({ $0 }) {
|
|
|
|
if window.buffer.handle == buffer.handle {
|
|
|
|
self.agent.select(window)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public func closeCurrentTab() {
|
|
|
|
self.exec(command: "q")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func saveCurrentTab() {
|
|
|
|
self.exec(command: "w")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func saveCurrentTab(url: URL) {
|
|
|
|
let path = url.path
|
|
|
|
guard let escapedFileName = self.agent.escapedFileName(path) else {
|
2017-05-27 16:22:37 +03:00
|
|
|
self.logger.fault("Escaped file name returned nil.")
|
2017-05-27 16:13:22 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
self.exec(command: "w \(escapedFileName)")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func closeCurrentTabWithoutSaving() {
|
|
|
|
self.exec(command: "q!")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func closeAllWindows() {
|
|
|
|
self.exec(command: "qa")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func closeAllWindowsWithoutSaving() {
|
|
|
|
self.exec(command: "qa!")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func vimOutput(of command: String) -> String {
|
|
|
|
return self.agent.vimCommandOutput(command) ?? ""
|
|
|
|
}
|
|
|
|
|
|
|
|
public func cursorGo(to position: Position) {
|
|
|
|
self.agent.cursorGo(toRow: Int32(position.row), column: Int32(position.column))
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Does the following
|
|
|
|
- normal mode: `:command<CR>`
|
|
|
|
- else: `:<Esc>:command<CR>`
|
|
|
|
|
2017-05-27 17:41:28 +03:00
|
|
|
We don't use NeoVimAgent.vimCommand because if we do for example "e /some/file"
|
|
|
|
and its swap file already exists, then NeoVimServer spins and become unresponsive.
|
2017-05-27 16:13:22 +03:00
|
|
|
*/
|
|
|
|
fileprivate func exec(command cmd: String) {
|
|
|
|
switch self.mode {
|
|
|
|
case .normal:
|
|
|
|
self.agent.vimInput(":\(cmd)<CR>")
|
|
|
|
default:
|
|
|
|
self.agent.vimInput("<Esc>:\(cmd)<CR>")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fileprivate func `open`(_ url: URL, cmd: String) {
|
|
|
|
let path = url.path
|
|
|
|
guard let escapedFileName = self.agent.escapedFileName(path) else {
|
2017-05-27 16:22:37 +03:00
|
|
|
self.logger.fault("Escaped file name returned nil.")
|
2017-05-27 16:13:22 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
self.exec(command: "\(cmd) \(escapedFileName)")
|
|
|
|
}
|
|
|
|
}
|