Skip to content

Commit

Permalink
Rename goto_split top/bottom directions to up/down. (#3427)
Browse files Browse the repository at this point in the history
Renames the top/bottom directions of `goto_split` to up/down. I have
tested this on linux (nixos) but given that `goto_split` is broken on
linux anyway (#2866) there's not a whole lot to test.

I have no way to build on macOS so I can't verify that I've changed
everything correctly for that.

Closes #3237
  • Loading branch information
mitchellh authored Jan 2, 2025
2 parents 2030599 + 3e11476 commit 9503c9f
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 36 deletions.
4 changes: 2 additions & 2 deletions include/ghostty.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ typedef enum {
typedef enum {
GHOSTTY_GOTO_SPLIT_PREVIOUS,
GHOSTTY_GOTO_SPLIT_NEXT,
GHOSTTY_GOTO_SPLIT_TOP,
GHOSTTY_GOTO_SPLIT_UP,
GHOSTTY_GOTO_SPLIT_LEFT,
GHOSTTY_GOTO_SPLIT_BOTTOM,
GHOSTTY_GOTO_SPLIT_DOWN,
GHOSTTY_GOTO_SPLIT_RIGHT,
} ghostty_action_goto_split_e;

Expand Down
4 changes: 2 additions & 2 deletions macos/Sources/App/macOS/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ class AppDelegate: NSObject,
syncMenuShortcut(config, action: "toggle_split_zoom", menuItem: self.menuZoomSplit)
syncMenuShortcut(config, action: "goto_split:previous", menuItem: self.menuPreviousSplit)
syncMenuShortcut(config, action: "goto_split:next", menuItem: self.menuNextSplit)
syncMenuShortcut(config, action: "goto_split:top", menuItem: self.menuSelectSplitAbove)
syncMenuShortcut(config, action: "goto_split:bottom", menuItem: self.menuSelectSplitBelow)
syncMenuShortcut(config, action: "goto_split:up", menuItem: self.menuSelectSplitAbove)
syncMenuShortcut(config, action: "goto_split:down", menuItem: self.menuSelectSplitBelow)
syncMenuShortcut(config, action: "goto_split:left", menuItem: self.menuSelectSplitLeft)
syncMenuShortcut(config, action: "goto_split:right", menuItem: self.menuSelectSplitRight)
syncMenuShortcut(config, action: "resize_split:up,10", menuItem: self.menuMoveSplitDividerUp)
Expand Down
4 changes: 2 additions & 2 deletions macos/Sources/Features/Terminal/BaseTerminalController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -540,11 +540,11 @@ class BaseTerminalController: NSWindowController,
}

@IBAction func splitMoveFocusAbove(_ sender: Any) {
splitMoveFocus(direction: .top)
splitMoveFocus(direction: .up)
}

@IBAction func splitMoveFocusBelow(_ sender: Any) {
splitMoveFocus(direction: .bottom)
splitMoveFocus(direction: .down)
}

@IBAction func splitMoveFocusLeft(_ sender: Any) {
Expand Down
16 changes: 8 additions & 8 deletions macos/Sources/Ghostty/Ghostty.SplitNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ extension Ghostty {
/// Returns the view that would prefer receiving focus in this tree. This is always the
/// top-left-most view. This is used when creating a split or closing a split to find the
/// next view to send focus to.
func preferredFocus(_ direction: SplitFocusDirection = .top) -> SurfaceView {
func preferredFocus(_ direction: SplitFocusDirection = .up) -> SurfaceView {
let container: Container
switch (self) {
case .leaf(let leaf):
Expand All @@ -64,10 +64,10 @@ extension Ghostty {

let node: SplitNode
switch (direction) {
case .previous, .top, .left:
case .previous, .up, .left:
node = container.bottomRight

case .next, .bottom, .right:
case .next, .down, .right:
node = container.topLeft
}

Expand Down Expand Up @@ -431,12 +431,12 @@ extension Ghostty {
struct Neighbors {
var left: SplitNode?
var right: SplitNode?
var top: SplitNode?
var bottom: SplitNode?
var up: SplitNode?
var down: SplitNode?

/// These are the previous/next nodes. It will certainly be one of the above as well
/// but we keep track of these separately because depending on the split direction
/// of the containing node, previous may be left OR top (same for next).
/// of the containing node, previous may be left OR up (same for next).
var previous: SplitNode?
var next: SplitNode?

Expand All @@ -448,8 +448,8 @@ extension Ghostty {
let map: [SplitFocusDirection : KeyPath<Self, SplitNode?>] = [
.previous: \.previous,
.next: \.next,
.top: \.top,
.bottom: \.bottom,
.up: \.up,
.down: \.down,
.left: \.left,
.right: \.right,
]
Expand Down
4 changes: 2 additions & 2 deletions macos/Sources/Ghostty/Ghostty.TerminalSplit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ extension Ghostty {
resizeIncrements: .init(width: 1, height: 1),
resizePublisher: container.resizeEvent,
left: {
let neighborKey: WritableKeyPath<SplitNode.Neighbors, SplitNode?> = container.direction == .horizontal ? \.right : \.bottom
let neighborKey: WritableKeyPath<SplitNode.Neighbors, SplitNode?> = container.direction == .horizontal ? \.right : \.down

TerminalSplitNested(
node: closeableTopLeft(),
Expand All @@ -318,7 +318,7 @@ extension Ghostty {
])
)
}, right: {
let neighborKey: WritableKeyPath<SplitNode.Neighbors, SplitNode?> = container.direction == .horizontal ? \.left : \.top
let neighborKey: WritableKeyPath<SplitNode.Neighbors, SplitNode?> = container.direction == .horizontal ? \.left : \.up

TerminalSplitNested(
node: closeableBottomRight(),
Expand Down
18 changes: 9 additions & 9 deletions macos/Sources/Ghostty/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ extension Ghostty {

/// An enum that is used for the directions that a split focus event can change.
enum SplitFocusDirection {
case previous, next, top, bottom, left, right
case previous, next, up, down, left, right

/// Initialize from a Ghostty API enum.
static func from(direction: ghostty_action_goto_split_e) -> Self? {
Expand All @@ -77,11 +77,11 @@ extension Ghostty {
case GHOSTTY_GOTO_SPLIT_NEXT:
return .next

case GHOSTTY_GOTO_SPLIT_TOP:
return .top
case GHOSTTY_GOTO_SPLIT_UP:
return .up

case GHOSTTY_GOTO_SPLIT_BOTTOM:
return .bottom
case GHOSTTY_GOTO_SPLIT_DOWN:
return .down

case GHOSTTY_GOTO_SPLIT_LEFT:
return .left
Expand All @@ -102,11 +102,11 @@ extension Ghostty {
case .next:
return GHOSTTY_GOTO_SPLIT_NEXT

case .top:
return GHOSTTY_GOTO_SPLIT_TOP
case .up:
return GHOSTTY_GOTO_SPLIT_UP

case .bottom:
return GHOSTTY_GOTO_SPLIT_BOTTOM
case .down:
return GHOSTTY_GOTO_SPLIT_DOWN

case .left:
return GHOSTTY_GOTO_SPLIT_LEFT
Expand Down
4 changes: 2 additions & 2 deletions src/apprt/action.zig
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,9 @@ pub const GotoSplit = enum(c_int) {
previous,
next,

top,
up,
left,
bottom,
down,
right,
};

Expand Down
4 changes: 2 additions & 2 deletions src/apprt/gtk/Split.zig
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,15 @@ pub fn directionMap(self: *const Split, from: Side) DirectionMap {
// This behavior matches the behavior of macOS at the time of writing
// this. There is an open issue (#524) to make this depend on the
// actual physical location of the current split.
result.put(.top, prev.surface);
result.put(.up, prev.surface);
result.put(.left, prev.surface);
}
}

if (self.directionNext(from)) |next| {
result.put(.next, next.surface);
if (!next.wrapped) {
result.put(.bottom, next.surface);
result.put(.down, next.surface);
result.put(.right, next.surface);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/config/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2247,12 +2247,12 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config {
try result.keybind.set.put(
alloc,
.{ .key = .{ .translated = .up }, .mods = .{ .ctrl = true, .alt = true } },
.{ .goto_split = .top },
.{ .goto_split = .up },
);
try result.keybind.set.put(
alloc,
.{ .key = .{ .translated = .down }, .mods = .{ .ctrl = true, .alt = true } },
.{ .goto_split = .bottom },
.{ .goto_split = .down },
);
try result.keybind.set.put(
alloc,
Expand Down Expand Up @@ -2516,12 +2516,12 @@ pub fn default(alloc_gpa: Allocator) Allocator.Error!Config {
try result.keybind.set.put(
alloc,
.{ .key = .{ .translated = .up }, .mods = .{ .super = true, .alt = true } },
.{ .goto_split = .top },
.{ .goto_split = .up },
);
try result.keybind.set.put(
alloc,
.{ .key = .{ .translated = .down }, .mods = .{ .super = true, .alt = true } },
.{ .goto_split = .bottom },
.{ .goto_split = .down },
);
try result.keybind.set.put(
alloc,
Expand Down
47 changes: 44 additions & 3 deletions src/input/Binding.zig
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,42 @@ pub const Action = union(enum) {
previous,
next,

top,
up,
left,
bottom,
down,
right,

pub fn parse(input: []const u8) !SplitFocusDirection {
return std.meta.stringToEnum(SplitFocusDirection, input) orelse {
// For backwards compatibility we map "top" and "bottom" onto the enum
// values "up" and "down"
if (std.mem.eql(u8, input, "top")) {
return .up;
} else if (std.mem.eql(u8, input, "bottom")) {
return .down;
} else {
return Error.InvalidFormat;
}
};
}

test "parse" {
const testing = std.testing;

try testing.expectEqual(.previous, try SplitFocusDirection.parse("previous"));
try testing.expectEqual(.next, try SplitFocusDirection.parse("next"));

try testing.expectEqual(.up, try SplitFocusDirection.parse("up"));
try testing.expectEqual(.left, try SplitFocusDirection.parse("left"));
try testing.expectEqual(.down, try SplitFocusDirection.parse("down"));
try testing.expectEqual(.right, try SplitFocusDirection.parse("right"));

try testing.expectEqual(.up, try SplitFocusDirection.parse("top"));
try testing.expectEqual(.down, try SplitFocusDirection.parse("bottom"));

try testing.expectError(error.InvalidFormat, SplitFocusDirection.parse(""));
try testing.expectError(error.InvalidFormat, SplitFocusDirection.parse("green"));
}
};

pub const SplitResizeDirection = enum {
Expand Down Expand Up @@ -524,7 +556,16 @@ pub const Action = union(enum) {
comptime field: std.builtin.Type.UnionField,
param: []const u8,
) !field.type {
return switch (@typeInfo(field.type)) {
const field_info = @typeInfo(field.type);

// Fields can provide a custom "parse" function
if (field_info == .Struct or field_info == .Union or field_info == .Enum) {
if (@hasDecl(field.type, "parse") and @typeInfo(@TypeOf(field.type.parse)) == .Fn) {
return field.type.parse(param);
}
}

return switch (field_info) {
.Enum => try parseEnum(field.type, param),
.Int => try parseInt(field.type, param),
.Float => try parseFloat(field.type, param),
Expand Down

0 comments on commit 9503c9f

Please sign in to comment.