Skip to content

Commit

Permalink
Merge pull request #528 from greg/develop
Browse files Browse the repository at this point in the history
Rudimentary Touch Bar support (#358)
  • Loading branch information
qvacua committed Nov 15, 2017
2 parents 49e42a9 + b086260 commit c136e55
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 7 deletions.
6 changes: 5 additions & 1 deletion NeoVimServer/NeoVimTab.h
Expand Up @@ -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;

Expand Down
11 changes: 10 additions & 1 deletion NeoVimServer/NeoVimTab.m
Expand Up @@ -9,29 +9,37 @@

@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;
}

_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;
}

- (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 {
Expand All @@ -40,6 +48,7 @@ - (instancetype)initWithCoder:(NSCoder *)coder {
NSNumber *objHandle = [coder decodeObjectForKey:@"handle"];
_handle = objHandle.integerValue;
_windows = [coder decodeObjectForKey:@"windows"];
_isCurrent = [coder decodeBoolForKey:@"current"];
}

return self;
Expand Down
3 changes: 2 additions & 1 deletion NeoVimServer/NeoVimWindow.h
Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion NeoVimServer/NeoVimWindow.m
Expand Up @@ -9,14 +9,15 @@

@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;
}

_handle = handle;
_buffer = buffer;
_isCurrentInTab = current;

return self;
}
Expand All @@ -25,13 +26,15 @@ - (NSString *)description {
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;
}

- (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 {
Expand All @@ -40,6 +43,7 @@ - (instancetype)initWithCoder:(NSCoder *)coder {
NSNumber *objHandle = [coder decodeObjectForKey:@"handle"];
_handle = objHandle.integerValue;
_buffer = [coder decodeObjectForKey:@"buffer"];
_isCurrentInTab = [coder decodeBoolForKey:@"currentInTab"];
}

return self;
Expand Down
10 changes: 8 additions & 2 deletions NeoVimServer/server_ui.m
Expand Up @@ -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];
Expand Down
1 change: 1 addition & 0 deletions SwiftNeoVim/NeoVimView+Api.swift
Expand Up @@ -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")
Expand Down
91 changes: 91 additions & 0 deletions SwiftNeoVim/NeoVimView+TouchBar.swift
@@ -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])
}

}
8 changes: 7 additions & 1 deletion SwiftNeoVim/NeoVimView+UiBridge.swift
Expand Up @@ -200,7 +200,7 @@ extension NeoVimView {
self.tabChanged()
}

if event == .BUFREADPOST || event == .BUFWRITEPOST {
if event == .BUFREADPOST || event == .BUFWRITEPOST || event == .BUFENTER {
self.currentBufferChanged(bufferHandle)
}
}
Expand Down Expand Up @@ -358,6 +358,9 @@ extension NeoVimView {
}

self.delegate?.currentBufferChanged(currentBuffer)
if #available(OSX 10.12.2, *) {
self.updateTouchBarTab()
}
}

fileprivate func tabChanged() {
Expand All @@ -370,6 +373,9 @@ extension NeoVimView {

fileprivate func bufferListChanged() {
self.delegate?.bufferListChanged()
if #available(OSX 10.12.2, *) {
self.updateTouchBarCurrentBuffer()
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions SwiftNeoVim/NeoVimView.swift
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions SwiftNeoVim/NeoVimViewDelegate.swift
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions VimR.xcodeproj/project.pbxproj
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -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; };
Expand Down Expand Up @@ -976,7 +978,9 @@
4B5012001EBA791000F76C46 /* Frameworks */,
4BEBA5061CFF374B00673FDF /* Products */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
};
4BEBA5061CFF374B00673FDF /* Products */ = {
isa = PBXGroup;
Expand Down Expand Up @@ -1041,6 +1045,7 @@
1929BDF3167E15E7F3349798 /* NeoVimView+Key.swift */,
1929B4F65149D3C3E326DA65 /* NeoVimView+MenuItems.swift */,
1F1000F71F0ABC0000CA3195 /* NeoVimView+Dragging.swift */,
373416BC1F71879300A87A92 /* NeoVimView+TouchBar.swift */,
);
name = NeoVimView;
sourceTree = "<group>";
Expand Down Expand Up @@ -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 */,
Expand Down

0 comments on commit c136e55

Please sign in to comment.