macos: navigate splits directionally

This commit is contained in:
Mitchell Hashimoto
2023-03-11 17:55:31 -08:00
parent 04c38ef3b0
commit 3976da8149
4 changed files with 79 additions and 20 deletions

View File

@ -92,6 +92,21 @@ extension Ghostty {
/// No neighbors, used by the root node.
static let empty: Self = .init()
/// Get the node for a given direction.
func get(direction: SplitFocusDirection) -> SplitNode? {
let map: [SplitFocusDirection : KeyPath<Self, SplitNode?>] = [
.previous: \.previous,
.next: \.next,
.top: \.top,
.bottom: \.bottom,
.left: \.left,
.right: \.right,
]
guard let path = map[direction] else { return nil }
return self[keyPath: path]
}
/// Update multiple keys and return a new copy.
func update(_ attrs: [WritableKeyPath<Self, SplitNode?>: SplitNode?]) -> Self {
var clone = self
@ -216,15 +231,8 @@ extension Ghostty {
// Determine our desired direction
guard let directionAny = notification.userInfo?[Notification.SplitDirectionKey] else { return }
guard let direction = directionAny as? SplitFocusDirection else { return }
switch (direction) {
case .previous:
guard let next = neighbors.previous else { return }
Self.moveFocus(next, previous: node)
case .next:
guard let next = neighbors.next else { return }
Self.moveFocus(next, previous: node)
}
guard let next = neighbors.get(direction: direction) else { return }
Self.moveFocus(next, previous: node)
}
/// There is a bug I can't figure out where when changing the split state, the terminal view

View File

@ -11,7 +11,7 @@ struct Ghostty {
extension Ghostty {
/// An enum that is used for the directions that a split focus event can change.
enum SplitFocusDirection {
case previous, next
case previous, next, top, bottom, left, right
/// Initialize from a Ghostty API enum.
static func from(direction: ghostty_split_focus_direction_e) -> Self? {
@ -22,6 +22,18 @@ extension Ghostty {
case GHOSTTY_SPLIT_FOCUS_NEXT:
return .next
case GHOSTTY_SPLIT_FOCUS_TOP:
return .top
case GHOSTTY_SPLIT_FOCUS_BOTTOM:
return .bottom
case GHOSTTY_SPLIT_FOCUS_LEFT:
return .left
case GHOSTTY_SPLIT_FOCUS_RIGHT:
return .right
default:
return nil
}
@ -34,6 +46,18 @@ extension Ghostty {
case .next:
return GHOSTTY_SPLIT_FOCUS_NEXT
case .top:
return GHOSTTY_SPLIT_FOCUS_TOP
case .bottom:
return GHOSTTY_SPLIT_FOCUS_BOTTOM
case .left:
return GHOSTTY_SPLIT_FOCUS_LEFT
case .right:
return GHOSTTY_SPLIT_FOCUS_RIGHT
}
}
}

View File

@ -40,8 +40,21 @@ struct GhosttyApp: App {
CommandGroup(before: .windowArrangement) {
Divider()
Button("Select Previous Split", action: splitMoveFocusPrevious).keyboardShortcut("[", modifiers: .command)
Button("Select Next Split", action: splitMoveFocusNext).keyboardShortcut("]", modifiers: .command)
Button("Select Previous Split") { splitMoveFocus(direction: .previous) }
.keyboardShortcut("[", modifiers: .command)
Button("Select Next Split") { splitMoveFocus(direction: .next) }
.keyboardShortcut("]", modifiers: .command)
Menu("Select Split") {
Button("Select Split Above") { splitMoveFocus(direction: .top) }
.keyboardShortcut(.upArrow, modifiers: [.command, .option])
Button("Select Split Below") { splitMoveFocus(direction: .bottom) }
.keyboardShortcut(.downArrow, modifiers: [.command, .option])
Button("Select Split Left") { splitMoveFocus(direction: .left) }
.keyboardShortcut(.leftArrow, modifiers: [.command, .option])
Button("Select Split Right") { splitMoveFocus(direction: .right)}
.keyboardShortcut(.rightArrow, modifiers: [.command, .option])
}
Divider()
}
}
@ -84,16 +97,10 @@ struct GhosttyApp: App {
ghostty.split(surface: surface, direction: GHOSTTY_SPLIT_DOWN)
}
func splitMoveFocusPrevious() {
func splitMoveFocus(direction: Ghostty.SplitFocusDirection) {
guard let surfaceView = focusedSurface else { return }
guard let surface = surfaceView.surface else { return }
ghostty.splitMoveFocus(surface: surface, direction: .previous)
}
func splitMoveFocusNext() {
guard let surfaceView = focusedSurface else { return }
guard let surface = surfaceView.surface else { return }
ghostty.splitMoveFocus(surface: surface, direction: .next)
ghostty.splitMoveFocus(surface: surface, direction: direction)
}
}

View File

@ -321,6 +321,26 @@ pub const Config = struct {
.{ .key = .right_bracket, .mods = .{ .super = true } },
.{ .goto_split = .next },
);
try result.keybind.set.put(
alloc,
.{ .key = .up, .mods = .{ .super = true, .alt = true } },
.{ .goto_split = .top },
);
try result.keybind.set.put(
alloc,
.{ .key = .down, .mods = .{ .super = true, .alt = true } },
.{ .goto_split = .bottom },
);
try result.keybind.set.put(
alloc,
.{ .key = .left, .mods = .{ .super = true, .alt = true } },
.{ .goto_split = .left },
);
try result.keybind.set.put(
alloc,
.{ .key = .right, .mods = .{ .super = true, .alt = true } },
.{ .goto_split = .right },
);
{
// Cmd+N for goto tab N
const start = @enumToInt(inputpkg.Key.one);