From 52c0b7ec51d931f5963cab2ce9d6065cb806db64 Mon Sep 17 00:00:00 2001 From: Tae Won Ha Date: Fri, 8 Dec 2017 18:37:17 +0100 Subject: [PATCH] Use the custom API for getting buffer info --- NvimMsgPack/NvimMsgPack/NvimApi.swift | 2 +- NvimMsgPack/NvimMsgPack/NvimApiMethods.swift | 18 ++--- NvimView/NvimView.xcodeproj/project.pbxproj | 4 ++ NvimView/NvimView/NvimApiExtension.swift | 71 ++++++++++++++++++++ NvimView/NvimView/NvimView+Api.swift | 21 ++++-- NvimView/NvimView/NvimViewObjects.swift | 12 +++- NvimView/neovim | 2 +- VimR/VimR/OpenedFileList.swift | 5 +- bin/generate_api_methods.py | 18 ++--- 9 files changed, 123 insertions(+), 30 deletions(-) create mode 100644 NvimView/NvimView/NvimApiExtension.swift diff --git a/NvimMsgPack/NvimMsgPack/NvimApi.swift b/NvimMsgPack/NvimMsgPack/NvimApi.swift index d34b4cfb..4e21f678 100644 --- a/NvimMsgPack/NvimMsgPack/NvimApi.swift +++ b/NvimMsgPack/NvimMsgPack/NvimApi.swift @@ -56,7 +56,7 @@ public class NvimApi { return "\(Swift.type(of: self))(type: \(self.type), message: \"\(self.message)\")" } - init(_ message: String) { + public init(_ message: String) { self.type = .unknown self.message = message } diff --git a/NvimMsgPack/NvimMsgPack/NvimApiMethods.swift b/NvimMsgPack/NvimMsgPack/NvimApiMethods.swift index 3ef90883..b95304c9 100644 --- a/NvimMsgPack/NvimMsgPack/NvimApiMethods.swift +++ b/NvimMsgPack/NvimMsgPack/NvimApiMethods.swift @@ -2222,7 +2222,7 @@ extension NvimApi.Tabpage { } } -private func msgPackDictToSwift(_ dict: Dictionary?) -> Dictionary? { +fileprivate func msgPackDictToSwift(_ dict: Dictionary?) -> Dictionary? { return dict?.flatMapToDict { k, v in guard let strKey = k.stringValue else { return nil @@ -2232,29 +2232,29 @@ private func msgPackDictToSwift(_ dict: Dictionary } } -private func msgPackArrayDictToSwift(_ array: [NvimApi.Value]?) -> [Dictionary]? { +fileprivate func msgPackArrayDictToSwift(_ array: [NvimApi.Value]?) -> [Dictionary]? { return array? .flatMap { v in v.dictionaryValue } .flatMap { d in msgPackDictToSwift(d) } } - + extension Dictionary { - func mapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)) rethrows -> Dictionary { + fileprivate func mapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)) rethrows -> Dictionary { let array = try self.map(transform) return tuplesToDict(array) } - - func flatMapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> Dictionary { + + fileprivate func flatMapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> Dictionary { let array = try self.flatMap(transform) return tuplesToDict(array) } - private func tuplesToDict(_ sequence: S) + fileprivate func tuplesToDict(_ sequence: S) -> Dictionary where S.Iterator.Element == (K, V) { - + var result = Dictionary(minimumCapacity: sequence.underestimatedCount) - + for (key, value) in sequence { result[key] = value } diff --git a/NvimView/NvimView.xcodeproj/project.pbxproj b/NvimView/NvimView.xcodeproj/project.pbxproj index a0cde26e..3b375b61 100644 --- a/NvimView/NvimView.xcodeproj/project.pbxproj +++ b/NvimView/NvimView.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */; }; + 1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */; }; 4B2016EE1FD45EED0038528A /* NvimAutoCommandEvent.generated.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2016EC1FD45EED0038528A /* NvimAutoCommandEvent.generated.m */; }; 4B2016EF1FD45EED0038528A /* NvimAutoCommandEvent.generated.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2016ED1FD45EED0038528A /* NvimAutoCommandEvent.generated.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B90F02D1FD2AFAE008A39E0 /* NvimUiBridgeProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90F00F1FD2AFAC008A39E0 /* NvimUiBridgeProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -84,6 +85,7 @@ /* Begin PBXFileReference section */ 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimViewObjects.swift; sourceTree = ""; }; + 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NvimApiExtension.swift; sourceTree = ""; }; 4B2016EC1FD45EED0038528A /* NvimAutoCommandEvent.generated.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NvimAutoCommandEvent.generated.m; sourceTree = ""; }; 4B2016ED1FD45EED0038528A /* NvimAutoCommandEvent.generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NvimAutoCommandEvent.generated.h; sourceTree = ""; }; 4B90F0041FD2AF59008A39E0 /* NvimView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NvimView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -215,6 +217,7 @@ 4B90F0221FD2AFAD008A39E0 /* TextDrawer.m */, 4B90F0771FD2BA7B008A39E0 /* Logger.h */, 1929B22A0CAD417EC3790F02 /* NvimViewObjects.swift */, + 1929BBD7F88AE4F01E626691 /* NvimApiExtension.swift */, ); path = NvimView; sourceTree = ""; @@ -410,6 +413,7 @@ 4B90F03A1FD2AFAE008A39E0 /* NvimView+Key.swift in Sources */, 4B90F0361FD2AFAE008A39E0 /* NvimViewDelegate.swift in Sources */, 1929B40A751BDA2882D4FC94 /* NvimViewObjects.swift in Sources */, + 1929B86897DAEFDBABAB1C14 /* NvimApiExtension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/NvimView/NvimView/NvimApiExtension.swift b/NvimView/NvimView/NvimApiExtension.swift new file mode 100644 index 00000000..c39de825 --- /dev/null +++ b/NvimView/NvimView/NvimApiExtension.swift @@ -0,0 +1,71 @@ +// +// Created by Tae Won Ha on 08.12.17. +// Copyright (c) 2017 Tae Won Ha. All rights reserved. +// + +import Foundation +import NvimMsgPack + +extension NvimApi { + + public func getBufGetInfo( + buffer: NvimApi.Buffer, + checkBlocked: Bool = true + ) -> NvimApi.Response> { + + if checkBlocked && self.getMode().value?["blocking"]?.boolValue == true { + return .failure(NvimApi.Error(type: .blocked, message: "Nvim is currently blocked")) + } + + let params: [NvimApi.Value] = [ + .int(Int64(buffer.handle)), + ] + let response = self.rpc(method: "nvim_buf_get_info", params: params, expectsReturnValue: true) + + guard let value = response.value else { + return .failure(response.error!) + } + + guard let result = (msgPackDictToSwift(value.dictionaryValue)) else { + return .failure(NvimApi.Error("Error converting result to \(Dictionary.self)")) + } + + return .success(result) + } +} + +func msgPackDictToSwift(_ dict: Dictionary?) -> Dictionary? { + return dict?.flatMapToDict { k, v in + guard let strKey = k.stringValue else { + return nil + } + + return (strKey, v) + } +} + +fileprivate func msgPackArrayDictToSwift(_ array: [NvimApi.Value]?) -> [Dictionary]? { + return array? + .flatMap { v in v.dictionaryValue } + .flatMap { d in msgPackDictToSwift(d) } +} + +extension Dictionary { + + fileprivate func flatMapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> Dictionary { + let array = try self.flatMap(transform) + return tuplesToDict(array) + } + + fileprivate func tuplesToDict(_ sequence: S) + -> Dictionary where S.Iterator.Element == (K, V) { + + var result = Dictionary(minimumCapacity: sequence.underestimatedCount) + + for (key, value) in sequence { + result[key] = value + } + + return result + } +} diff --git a/NvimView/NvimView/NvimView+Api.swift b/NvimView/NvimView/NvimView+Api.swift index 7b8e95e0..e9cac506 100644 --- a/NvimView/NvimView/NvimView+Api.swift +++ b/NvimView/NvimView/NvimView+Api.swift @@ -189,18 +189,27 @@ extension NvimView { } private func neoVimBuffer(for buf: NvimApi.Buffer, currentBuffer: NvimApi.Buffer?) -> NvimView.Buffer? { - guard let path = self.nvim.bufGetName(buffer: buf).value else { - return nil - } - - guard let dirty = self.nvim.bufGetOption(buffer: buf, name: "mod").value?.boolValue else { + guard let info = self.nvim.getBufGetInfo(buffer: buf).value else { return nil } let current = buf == currentBuffer + guard let path = info["filename"]?.stringValue, + let dirty = info["modified"]?.boolValue, + let buftype = info["buftype"]?.stringValue, + let listed = info["buflisted"]?.boolValue + else { + return nil + } + + guard listed else { + return nil + } + let url = path == "" || buftype != "" ? nil : URL(fileURLWithPath: path) return NvimView.Buffer(apiBuffer: buf, - url: URL(fileURLWithPath: path), + url: url, + type: buftype, isDirty: dirty, isCurrent: current) } diff --git a/NvimView/NvimView/NvimViewObjects.swift b/NvimView/NvimView/NvimViewObjects.swift index ed6e218b..35850863 100644 --- a/NvimView/NvimView/NvimViewObjects.swift +++ b/NvimView/NvimView/NvimViewObjects.swift @@ -11,11 +11,17 @@ extension NvimView { public struct Buffer: Equatable { public static func ==(lhs: Buffer, rhs: Buffer) -> Bool { - return lhs.handle == rhs.handle + guard lhs.handle == rhs.handle else { + return false + } + + // Transient buffer active -> open a file -> the resulting buffer has the same handle, but different URL + return lhs.url == rhs.url } public let apiBuffer: NvimApi.Buffer public let url: URL? + public let type: String public let isDirty: Bool public let isCurrent: Bool @@ -33,6 +39,10 @@ extension NvimView { } public var name: String? { + if self.type == "quickfix" { + return "Quickfix" + } + return self.url?.lastPathComponent } diff --git a/NvimView/neovim b/NvimView/neovim index 95899422..741a6f02 160000 --- a/NvimView/neovim +++ b/NvimView/neovim @@ -1 +1 @@ -Subproject commit 9589942270b0e58bca6288c87b304ac7105f10bf +Subproject commit 741a6f026fbc3a3d1235e358331bfaf0d1cc6799 diff --git a/VimR/VimR/OpenedFileList.swift b/VimR/VimR/OpenedFileList.swift index a0ae754f..8014153f 100644 --- a/VimR/VimR/OpenedFileList.swift +++ b/VimR/VimR/OpenedFileList.swift @@ -54,13 +54,12 @@ class BuffersList: NSView, self.usesTheme = state.appearance.usesTheme - let buffers = state.buffers.removingDuplicatesPreservingFromBeginning() - if self.buffers == buffers && !themeChanged && self.showsFileIcon == state.appearance.showsFileIcon { + if self.buffers == state.buffers && !themeChanged && self.showsFileIcon == state.appearance.showsFileIcon { return } self.showsFileIcon = state.appearance.showsFileIcon - self.buffers = buffers + self.buffers = state.buffers self.bufferList.reloadData() self.adjustFileViewWidth() }) diff --git a/bin/generate_api_methods.py b/bin/generate_api_methods.py index 6cbfba3c..a81eeb1f 100755 --- a/bin/generate_api_methods.py +++ b/bin/generate_api_methods.py @@ -157,7 +157,7 @@ extension NvimApi.Tabpage { } } -private func msgPackDictToSwift(_ dict: Dictionary?) -> Dictionary? { +fileprivate func msgPackDictToSwift(_ dict: Dictionary?) -> Dictionary? { return dict?.flatMapToDict { k, v in guard let strKey = k.stringValue else { return nil @@ -167,29 +167,29 @@ private func msgPackDictToSwift(_ dict: Dictionary } } -private func msgPackArrayDictToSwift(_ array: [NvimApi.Value]?) -> [Dictionary]? { +fileprivate func msgPackArrayDictToSwift(_ array: [NvimApi.Value]?) -> [Dictionary]? { return array? .flatMap { v in v.dictionaryValue } .flatMap { d in msgPackDictToSwift(d) } } - + extension Dictionary { - func mapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)) rethrows -> Dictionary { + fileprivate func mapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)) rethrows -> Dictionary { let array = try self.map(transform) return tuplesToDict(array) } - - func flatMapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> Dictionary { + + fileprivate func flatMapToDict(_ transform: ((key: Key, value: Value)) throws -> (K, V)?) rethrows -> Dictionary { let array = try self.flatMap(transform) return tuplesToDict(array) } - private func tuplesToDict(_ sequence: S) + fileprivate func tuplesToDict(_ sequence: S) -> Dictionary where S.Iterator.Element == (K, V) { - + var result = Dictionary(minimumCapacity: sequence.underestimatedCount) - + for (key, value) in sequence { result[key] = value }