1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-11-24 11:37:32 +03:00

Merge pull request #528 from greg/develop

Rudimentary Touch Bar support (#358)
This commit is contained in:
Tae Won Ha 2017-11-15 19:26:16 +01:00 committed by GitHub
commit c136e55b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 139 additions and 7 deletions

View File

@ -15,8 +15,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) NSInteger handle;
@property (nonatomic, readonly) NSArray <NeoVimWindow *> *windows;
@property (nonatomic, readonly) bool isCurrent;
- (instancetype)initWithHandle:(NSInteger)handle windows:(NSArray <NeoVimWindow *> *)windows;
- (instancetype)initWithHandle:(NSInteger)handle windows:(NSArray <NeoVimWindow *> *)windows current:(bool)current;
/// @returns The most recently selected window in *this* tab.
- (NeoVimWindow * _Nullable )currentWindow;
- (NSString *)description;

View File

@ -9,7 +9,7 @@
@implementation NeoVimTab
- (instancetype)initWithHandle:(NSInteger)handle windows:(NSArray <NeoVimWindow *> *)windows {
- (instancetype)initWithHandle:(NSInteger)handle windows:(NSArray <NeoVimWindow *> *)windows current:(bool)current {
self = [super init];
if (self == nil) {
return nil;
@ -17,14 +17,21 @@
_handle = handle;
_windows = windows;
_isCurrent = current;
return self;
}
- (NeoVimWindow *)currentWindow {
for (NeoVimWindow *window in self.windows) if (window.isCurrentInTab) return window;
return nil;
}
- (NSString *)description {
NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: ", NSStringFromClass([self class])];
[description appendFormat:@"self.handle=%li", self.handle];
[description appendFormat:@", self.windows=%@", self.windows];
[description appendFormat:@", self.current=%d", self.isCurrent];
[description appendString:@">"];
return description;
}
@ -32,6 +39,7 @@
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:@(self.handle) forKey:@"handle"];
[coder encodeObject:self.windows forKey:@"windows"];
[coder encodeBool:self.isCurrent forKey:@"current"];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
@ -40,6 +48,7 @@
NSNumber *objHandle = [coder decodeObjectForKey:@"handle"];
_handle = objHandle.integerValue;
_windows = [coder decodeObjectForKey:@"windows"];
_isCurrent = [coder decodeBoolForKey:@"current"];
}
return self;

View File

@ -15,8 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) NSInteger handle;
@property (nonatomic, readonly) NeoVimBuffer *buffer;
@property (nonatomic, readonly) bool isCurrentInTab;
- (instancetype)initWithHandle:(NSInteger)handle buffer:(NeoVimBuffer *)buffer;
- (instancetype)initWithHandle:(NSInteger)handle buffer:(NeoVimBuffer *)buffer currentInTab:(bool)current;
- (instancetype)initWithCoder:(NSCoder *)coder;
- (void)encodeWithCoder:(NSCoder *)coder;

View File

@ -9,7 +9,7 @@
@implementation NeoVimWindow
- (instancetype)initWithHandle:(NSInteger)handle buffer:(NeoVimBuffer *)buffer {
- (instancetype)initWithHandle:(NSInteger)handle buffer:(NeoVimBuffer *)buffer currentInTab:(bool)current {
self = [super init];
if (self == nil) {
return nil;
@ -17,6 +17,7 @@
_handle = handle;
_buffer = buffer;
_isCurrentInTab = current;
return self;
}
@ -25,6 +26,7 @@
NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: ", NSStringFromClass([self class])];
[description appendFormat:@"self.handle=%li", self.handle];
[description appendFormat:@", self.buffer=%@", self.buffer];
[description appendFormat:@", self.currentInTab=%d", self.isCurrentInTab];
[description appendString:@">"];
return description;
}
@ -32,6 +34,7 @@
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:@(self.handle) forKey:@"handle"];
[coder encodeObject:self.buffer forKey:@"buffer"];
[coder encodeBool:self.isCurrentInTab forKey:@"currentInTab"];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
@ -40,6 +43,7 @@
NSNumber *objHandle = [coder decodeObjectForKey:@"handle"];
_handle = objHandle.integerValue;
_buffer = [coder decodeObjectForKey:@"buffer"];
_isCurrentInTab = [coder decodeBoolForKey:@"currentInTab"];
}
return self;

View File

@ -780,18 +780,24 @@ void neovim_tabs(void **argv) {
FOR_ALL_TABS(t) {
NSMutableArray *windows = [NSMutableArray new];
bool currentTab = curtab ? t->handle == curtab->handle : false;
FOR_ALL_WINDOWS_IN_TAB(win, t) {
NeoVimBuffer *buffer = buffer_for(win->w_buffer);
if (buffer == nil) {
continue;
}
NeoVimWindow *window = [[NeoVimWindow alloc] initWithHandle:win->handle buffer:buffer];
bool current = false;
// tp_curwin is only valid for tabs that aren't the current one
if (currentTab) current = curwin ? win->handle == curwin->handle : false;
else if (t->tp_curwin) current = win->handle == t->tp_curwin->handle;
NeoVimWindow *window = [[NeoVimWindow alloc] initWithHandle:win->handle buffer:buffer currentInTab:current];
[windows addObject:window];
[window release];
}
NeoVimTab *tab = [[NeoVimTab alloc] initWithHandle:t->handle windows:windows];
NeoVimTab *tab = [[NeoVimTab alloc] initWithHandle:t->handle windows:windows current:currentTab];
[windows release];
[tabs addObject:tab];

View File

@ -90,6 +90,7 @@ extension NeoVimView {
}
}
/// Closes the current window.
public func closeCurrentTab() {
// We don't have to wait here even when neovim quits since we wait in gui.async() block in neoVimStopped().
self.exec(command: "q")

View File

@ -0,0 +1,91 @@
/**
* Greg Omelaenko - http://omelaen.co
* See LICENSE
*/
import Cocoa
@available(OSX 10.12.2, *)
extension NeoVimView : NSTouchBarDelegate, NSScrubberDataSource, NSScrubberDelegate {
private static let touchBarIdentifier = NSTouchBarCustomizationIdentifier("com.qvacua.VimR.SwiftNeoVim.touchBar")
private static let touchBarTabSwitcherIdentifier = NSTouchBarItemIdentifier("com.qvacua.VimR.SwiftNeoVim.touchBar.tabSwitcher")
private static let touchBarTabSwitcherItem = "com.qvacua.VimR.SwiftNeoVim.touchBar.tabSwitcher.item"
override public func makeTouchBar() -> NSTouchBar? {
let bar = NSTouchBar()
bar.delegate = self
bar.customizationIdentifier = NeoVimView.touchBarIdentifier
bar.defaultItemIdentifiers = [NeoVimView.touchBarTabSwitcherIdentifier]
bar.customizationRequiredItemIdentifiers = [NeoVimView.touchBarTabSwitcherIdentifier]
return bar
}
public func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItemIdentifier) -> NSTouchBarItem? {
switch identifier {
case NeoVimView.touchBarTabSwitcherIdentifier:
let item = NSCustomTouchBarItem(identifier: identifier)
item.customizationLabel = "Tab Switcher"
let tabsControl = NSScrubber()
tabsControl.register(NSScrubberTextItemView.self, forItemIdentifier: NeoVimView.touchBarTabSwitcherItem)
tabsControl.mode = .fixed
tabsControl.dataSource = self
tabsControl.delegate = self
tabsControl.selectionOverlayStyle = .outlineOverlay
tabsControl.selectedIndex = selectedTabIndex()
let layout = NSScrubberProportionalLayout()
layout.numberOfVisibleItems = 1
tabsControl.scrubberLayout = layout
item.view = tabsControl
return item
default:
return nil
}
}
private func selectedTabIndex() -> Int {
return tabsCache.index(where: { $0.isCurrent }) ?? -1
}
private func getTabsControl() -> NSScrubber? {
return (self.touchBar?.item(forIdentifier: NeoVimView.touchBarTabSwitcherIdentifier) as? NSCustomTouchBarItem)?.view as? NSScrubber
}
func updateTouchBarCurrentBuffer() {
guard let tabsControl = getTabsControl() else { return }
tabsCache = self.agent.tabs()
tabsControl.reloadData()
(tabsControl.scrubberLayout as! NSScrubberProportionalLayout).numberOfVisibleItems = tabsControl.numberOfItems > 0 ? tabsControl.numberOfItems : 1
tabsControl.selectedIndex = selectedTabIndex()
}
func updateTouchBarTab() {
guard let tabsControl = getTabsControl() else { return }
tabsCache = self.agent.tabs()
if tabsControl.numberOfItems != tabsCache.count {
tabsControl.reloadData()
}
tabsControl.selectedIndex = selectedTabIndex()
tabsControl.reloadItems(at: [tabsControl.selectedIndex])
}
public func numberOfItems(for scrubber: NSScrubber) -> Int {
return tabsCache.count
}
public func scrubber(_ scrubber: NSScrubber, viewForItemAt index: Int) -> NSScrubberItemView {
let itemView = scrubber.makeItem(withIdentifier: type(of: self).touchBarTabSwitcherItem, owner: nil) as! NSScrubberTextItemView
guard tabsCache.count > index else { return itemView }
let tab = tabsCache[index]
itemView.title = tab.currentWindow()?.buffer.name ?? "[No Name]"
return itemView
}
public func scrubber(_ scrubber: NSScrubber, didSelectItemAt selectedIndex: Int) {
let tab = tabsCache[selectedIndex]
guard tab.windows.count > 0 else { return }
self.agent.select(tab.currentWindow() ?? tab.windows[0])
}
}

View File

@ -200,7 +200,7 @@ extension NeoVimView {
self.tabChanged()
}
if event == .BUFREADPOST || event == .BUFWRITEPOST {
if event == .BUFREADPOST || event == .BUFWRITEPOST || event == .BUFENTER {
self.currentBufferChanged(bufferHandle)
}
}
@ -358,6 +358,9 @@ extension NeoVimView {
}
self.delegate?.currentBufferChanged(currentBuffer)
if #available(OSX 10.12.2, *) {
self.updateTouchBarTab()
}
}
fileprivate func tabChanged() {
@ -370,6 +373,9 @@ extension NeoVimView {
fileprivate func bufferListChanged() {
self.delegate?.bufferListChanged()
if #available(OSX 10.12.2, *) {
self.updateTouchBarCurrentBuffer()
}
}
}

View File

@ -235,6 +235,9 @@ public class NeoVimView: NSView,
var _cwd = URL(fileURLWithPath: NSHomeDirectory())
var shouldDrawCursor = false
var isInitialResize = true
// cache the tabs for Touch Bar use
var tabsCache = [NeoVimTab]()
// MARK: - Private
fileprivate var _linespacing = NeoVimView.defaultLinespacing

View File

@ -14,6 +14,7 @@ public protocol NeoVimViewDelegate: class {
func cwdChanged()
func bufferListChanged()
func tabChanged()
/// Called when the current buffer changes, including when a new one is selected.
func currentBufferChanged(_ currentBuffer: NeoVimBuffer)
func colorschemeChanged(to: NeoVimView.Theme)

View File

@ -94,6 +94,7 @@
1929BFC70581084B5CE04A5B /* MatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BFE179BCA3C75A13D71B /* MatcherTests.swift */; };
1929BFDE22D155F7C4B19E96 /* HtmlPreviewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B85023B042C485409CE1 /* HtmlPreviewTool.swift */; };
1F1000F81F0ABC0000CA3195 /* NeoVimView+Dragging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1000F71F0ABC0000CA3195 /* NeoVimView+Dragging.swift */; };
373416BD1F71879300A87A92 /* NeoVimView+TouchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373416BC1F71879300A87A92 /* NeoVimView+TouchBar.swift */; };
4B029F1A1D45E349004EE0D3 /* PrefWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B029F1C1D45E349004EE0D3 /* PrefWindow.xib */; };
4B0BCC941D70320C00D3CE65 /* Logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B0BCC931D70320C00D3CE65 /* Logger.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B12CD891F5A985600167D59 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B12CD881F5A985600167D59 /* AppDelegate.swift */; };
@ -454,6 +455,7 @@
1929BFC0A5A9C6DB09BE1368 /* Types.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
1929BFE179BCA3C75A13D71B /* MatcherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherTests.swift; sourceTree = "<group>"; };
1F1000F71F0ABC0000CA3195 /* NeoVimView+Dragging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NeoVimView+Dragging.swift"; sourceTree = "<group>"; };
373416BC1F71879300A87A92 /* NeoVimView+TouchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NeoVimView+TouchBar.swift"; sourceTree = "<group>"; };
4B029F1B1D45E349004EE0D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PrefWindow.xib; sourceTree = "<group>"; };
4B0BCC931D70320C00D3CE65 /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logger.h; path = VimR/Logger.h; sourceTree = SOURCE_ROOT; };
4B12CD861F5A985600167D59 /* ThemedWindow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThemedWindow.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -976,7 +978,9 @@
4B5012001EBA791000F76C46 /* Frameworks */,
4BEBA5061CFF374B00673FDF /* Products */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
};
4BEBA5061CFF374B00673FDF /* Products */ = {
isa = PBXGroup;
@ -1041,6 +1045,7 @@
1929BDF3167E15E7F3349798 /* NeoVimView+Key.swift */,
1929B4F65149D3C3E326DA65 /* NeoVimView+MenuItems.swift */,
1F1000F71F0ABC0000CA3195 /* NeoVimView+Dragging.swift */,
373416BC1F71879300A87A92 /* NeoVimView+TouchBar.swift */,
);
name = NeoVimView;
sourceTree = "<group>";
@ -1442,6 +1447,7 @@
4BDD05891DBBC50000D1B405 /* NeoVimTab.m in Sources */,
4BEE79171D16D3800012EDAA /* CellAttributes.swift in Sources */,
4BDD05861DBBC50000D1B405 /* NeoVimBuffer.m in Sources */,
373416BD1F71879300A87A92 /* NeoVimView+TouchBar.swift in Sources */,
4BF6E29C1D34153C0053FA76 /* KeyUtils.swift in Sources */,
4BCADE081D11ED12004DAD0F /* CocoaExtensions.swift in Sources */,
4B401B1A1D046E0600D99EDC /* NeoVimViewDelegate.swift in Sources */,