From 262902a28d2d490b6e9feb78684c2d2747b88e0e Mon Sep 17 00:00:00 2001 From: Eduardo Dominguez Date: Mon, 19 Aug 2024 12:19:00 -0600 Subject: [PATCH] macos: jump to last_tab --- include/ghostty.h | 1 + .../Features/Terminal/TerminalController.swift | 2 ++ macos/Sources/Ghostty/Ghostty.App.swift | 8 ++++++++ src/Surface.zig | 13 +++++++++++++ src/apprt/embedded.zig | 10 ++++++++++ src/config/Config.zig | 10 ++++++++++ src/input/Binding.zig | 3 +++ 7 files changed, 47 insertions(+) diff --git a/include/ghostty.h b/include/ghostty.h index b56b8827e..b413dec41 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -143,6 +143,7 @@ typedef enum { typedef enum { GHOSTTY_TAB_PREVIOUS = -1, GHOSTTY_TAB_NEXT = -2, + GHOSTTY_TAB_LAST = -3, } ghostty_tab_e; typedef enum { diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 729757dd2..c154fa3e1 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -724,6 +724,8 @@ class TerminalController: NSWindowController, NSWindowDelegate, } else { finalIndex = selectedIndex + 1 } + } else if (tabIndex == GHOSTTY_TAB_LAST.rawValue) { + finalIndex = tabbedWindows.count - 1 } else { return } diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index b4fe17f86..c56a53b77 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -379,6 +379,14 @@ extension Ghostty { ) } + static func gotoLastTab(_ userdata: UnsafeMutableRawPointer?) { + let surface = self.surfaceUserdata(from: userdata) + NotificationCenter.default.post( + name: Notification.ghosttyGotoTab, + object: surface + ) + } + static func readClipboard(_ userdata: UnsafeMutableRawPointer?, location: ghostty_clipboard_e, state: UnsafeMutableRawPointer?) { // If we don't even have a surface, something went terrible wrong so we have // to leak "state". diff --git a/src/Surface.zig b/src/Surface.zig index 4b5b3f98c..08db61c10 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -3429,6 +3429,19 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool } else log.warn("runtime doesn't implement gotoNextTab", .{}); }, + .last_tab => { + if (@hasDecl(apprt.Surface, "hasTabs")) { + if (!self.rt_surface.hasTabs()) { + log.debug("surface has no tabs, ignoring last_tab binding", .{}); + return false; + } + } + + if (@hasDecl(apprt.Surface, "gotoLastTab")) { + self.rt_surface.gotoLastTab(); + } else log.warn("runtime doesn't implement gotoLastTab", .{}); + }, + .goto_tab => |n| { if (@hasDecl(apprt.Surface, "gotoTab")) { self.rt_surface.gotoTab(n); diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig index d3b2d6f29..fff14967d 100644 --- a/src/apprt/embedded.zig +++ b/src/apprt/embedded.zig @@ -139,6 +139,7 @@ pub const App = struct { const GotoTab = enum(i32) { previous = -1, next = -2, + last = -3, _, }; @@ -1008,6 +1009,15 @@ pub const Surface = struct { func(self.userdata, @enumFromInt(idx)); } + pub fn gotoLastTab(self: *Surface) void { + const func = self.app.opts.goto_tab orelse { + log.info("runtime embedder does not goto_tab", .{}); + return; + }; + + func(self.userdata, .last); + } + pub fn gotoPreviousTab(self: *Surface) void { const func = self.app.opts.goto_tab orelse { log.info("runtime embedder does not goto_tab", .{}); diff --git a/src/config/Config.zig b/src/config/Config.zig index 6d45ab4ec..a6327c063 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1582,6 +1582,11 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config { .{ .key = .{ .translated = .right }, .mods = .{ .ctrl = true, .shift = true } }, .{ .next_tab = {} }, ); + try result.keybind.set.put( + alloc, + .{ .key = .{ .physical = inputpkg.Key.zero }, .mods = .{ .super = true } }, + .{ .last_tab = {} }, + ); try result.keybind.set.put( alloc, .{ .key = .{ .translated = .page_up }, .mods = .{ .ctrl = true } }, @@ -1850,6 +1855,11 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config { .{ .key = .{ .translated = .right_bracket }, .mods = .{ .super = true, .shift = true } }, .{ .next_tab = {} }, ); + try result.keybind.set.put( + alloc, + .{ .key = .{ .physical = inputpkg.Key.zero }, .mods = .{ .super = true } }, + .{ .last_tab = {} }, + ); try result.keybind.set.put( alloc, .{ .key = .{ .translated = .d }, .mods = .{ .super = true } }, diff --git a/src/input/Binding.zig b/src/input/Binding.zig index ef0f8e4c1..a4002ddc9 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -257,6 +257,9 @@ pub const Action = union(enum) { /// Go to the next tab. next_tab: void, + /// Go to the last tab (the one with the highest index) + last_tab: void, + /// Go to the tab with the specific number, 1-indexed. goto_tab: usize,