mirror of
https://github.com/qvacua/vimr.git
synced 2024-11-28 11:35:35 +03:00
Merge pull request #528 from greg/develop
Rudimentary Touch Bar support (#358)
This commit is contained in:
commit
c136e55b1b
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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")
|
||||
|
91
SwiftNeoVim/NeoVimView+TouchBar.swift
Normal file
91
SwiftNeoVim/NeoVimView+TouchBar.swift
Normal 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])
|
||||
}
|
||||
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,6 +236,9 @@ public class NeoVimView: NSView,
|
||||
var shouldDrawCursor = false
|
||||
var isInitialResize = true
|
||||
|
||||
// cache the tabs for Touch Bar use
|
||||
var tabsCache = [NeoVimTab]()
|
||||
|
||||
// MARK: - Private
|
||||
fileprivate var _linespacing = NeoVimView.defaultLinespacing
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 */,
|
||||
|
Loading…
Reference in New Issue
Block a user