mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 08:16:13 +03:00
Merge pull request #1981 from injust/adjust-line
Add `adjust_selection` actions for `beginning_of_line` and `end_of_line`
This commit is contained in:
@ -3471,6 +3471,8 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
.page_down => .page_down,
|
||||
.home => .home,
|
||||
.end => .end,
|
||||
.beginning_of_line => .beginning_of_line,
|
||||
.end_of_line => .end_of_line,
|
||||
});
|
||||
|
||||
// If the selection endpoint is outside of the current viewpoint,
|
||||
|
@ -304,6 +304,8 @@ pub const Action = union(enum) {
|
||||
page_down,
|
||||
home,
|
||||
end,
|
||||
beginning_of_line,
|
||||
end_of_line,
|
||||
};
|
||||
|
||||
pub const SplitDirection = enum {
|
||||
|
@ -344,6 +344,8 @@ pub const Adjustment = enum {
|
||||
end,
|
||||
page_up,
|
||||
page_down,
|
||||
beginning_of_line,
|
||||
end_of_line,
|
||||
};
|
||||
|
||||
/// Adjust the selection by some given adjustment. An adjustment allows
|
||||
@ -353,16 +355,16 @@ pub fn adjust(
|
||||
s: *const Screen,
|
||||
adjustment: Adjustment,
|
||||
) void {
|
||||
// Note that we always adjusts "end" because end always represents
|
||||
// Note that we always adjust "end" because end always represents
|
||||
// the last point of the selection by mouse, not necessarilly the
|
||||
// top/bottom visually. So this results in the right behavior
|
||||
// top/bottom visually. So this results in the correct behavior
|
||||
// whether the user drags up or down.
|
||||
const end_pin = self.endPtr();
|
||||
switch (adjustment) {
|
||||
.up => if (end_pin.up(1)) |new_end| {
|
||||
end_pin.* = new_end;
|
||||
} else {
|
||||
end_pin.x = 0;
|
||||
self.adjust(s, .beginning_of_line);
|
||||
},
|
||||
|
||||
.down => {
|
||||
@ -377,7 +379,7 @@ pub fn adjust(
|
||||
}
|
||||
} else {
|
||||
// If we're at the bottom, just go to the end of the line
|
||||
end_pin.x = end_pin.page.data.size.cols - 1;
|
||||
self.adjust(s, .end_of_line);
|
||||
}
|
||||
},
|
||||
|
||||
@ -440,6 +442,10 @@ pub fn adjust(
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
.beginning_of_line => end_pin.x = 0,
|
||||
|
||||
.end_of_line => end_pin.x = end_pin.page.data.size.cols - 1,
|
||||
}
|
||||
}
|
||||
|
||||
@ -786,6 +792,144 @@ test "Selection: adjust end with not full screen" {
|
||||
}
|
||||
}
|
||||
|
||||
test "Selection: adjust beginning of line" {
|
||||
const testing = std.testing;
|
||||
var s = try Screen.init(testing.allocator, 8, 10, 0);
|
||||
defer s.deinit();
|
||||
try s.testWriteString("A12 B34\nC12 D34");
|
||||
|
||||
// Not at beginning of the line
|
||||
{
|
||||
var sel = Selection.init(
|
||||
s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?,
|
||||
s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?,
|
||||
false,
|
||||
);
|
||||
defer sel.deinit(&s);
|
||||
sel.adjust(&s, .beginning_of_line);
|
||||
|
||||
// Start line
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 5,
|
||||
.y = 1,
|
||||
} }, s.pages.pointFromPin(.screen, sel.start()).?);
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 0,
|
||||
.y = 1,
|
||||
} }, s.pages.pointFromPin(.screen, sel.end()).?);
|
||||
}
|
||||
|
||||
// Already at beginning of the line
|
||||
{
|
||||
var sel = Selection.init(
|
||||
s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?,
|
||||
s.pages.pin(.{ .screen = .{ .x = 0, .y = 1 } }).?,
|
||||
false,
|
||||
);
|
||||
defer sel.deinit(&s);
|
||||
sel.adjust(&s, .beginning_of_line);
|
||||
|
||||
// Start line
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 5,
|
||||
.y = 1,
|
||||
} }, s.pages.pointFromPin(.screen, sel.start()).?);
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 0,
|
||||
.y = 1,
|
||||
} }, s.pages.pointFromPin(.screen, sel.end()).?);
|
||||
}
|
||||
|
||||
// End pin moves to start pin
|
||||
{
|
||||
var sel = Selection.init(
|
||||
s.pages.pin(.{ .screen = .{ .x = 0, .y = 1 } }).?,
|
||||
s.pages.pin(.{ .screen = .{ .x = 5, .y = 1 } }).?,
|
||||
false,
|
||||
);
|
||||
defer sel.deinit(&s);
|
||||
sel.adjust(&s, .beginning_of_line);
|
||||
|
||||
// Start line
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 0,
|
||||
.y = 1,
|
||||
} }, s.pages.pointFromPin(.screen, sel.start()).?);
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 0,
|
||||
.y = 1,
|
||||
} }, s.pages.pointFromPin(.screen, sel.end()).?);
|
||||
}
|
||||
}
|
||||
|
||||
test "Selection: adjust end of line" {
|
||||
const testing = std.testing;
|
||||
var s = try Screen.init(testing.allocator, 8, 10, 0);
|
||||
defer s.deinit();
|
||||
try s.testWriteString("A12 B34\nC12 D34");
|
||||
|
||||
// Not at end of the line
|
||||
{
|
||||
var sel = Selection.init(
|
||||
s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?,
|
||||
s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?,
|
||||
false,
|
||||
);
|
||||
defer sel.deinit(&s);
|
||||
sel.adjust(&s, .end_of_line);
|
||||
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 1,
|
||||
.y = 0,
|
||||
} }, s.pages.pointFromPin(.screen, sel.start()).?);
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 7,
|
||||
.y = 0,
|
||||
} }, s.pages.pointFromPin(.screen, sel.end()).?);
|
||||
}
|
||||
|
||||
// Already at end of the line
|
||||
{
|
||||
var sel = Selection.init(
|
||||
s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?,
|
||||
s.pages.pin(.{ .screen = .{ .x = 7, .y = 0 } }).?,
|
||||
false,
|
||||
);
|
||||
defer sel.deinit(&s);
|
||||
sel.adjust(&s, .end_of_line);
|
||||
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 1,
|
||||
.y = 0,
|
||||
} }, s.pages.pointFromPin(.screen, sel.start()).?);
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 7,
|
||||
.y = 0,
|
||||
} }, s.pages.pointFromPin(.screen, sel.end()).?);
|
||||
}
|
||||
|
||||
// End pin moves to start pin
|
||||
{
|
||||
var sel = Selection.init(
|
||||
s.pages.pin(.{ .screen = .{ .x = 7, .y = 0 } }).?,
|
||||
s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?,
|
||||
false,
|
||||
);
|
||||
defer sel.deinit(&s);
|
||||
sel.adjust(&s, .end_of_line);
|
||||
|
||||
// Start line
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 7,
|
||||
.y = 0,
|
||||
} }, s.pages.pointFromPin(.screen, sel.start()).?);
|
||||
try testing.expectEqual(point.Point{ .screen = .{
|
||||
.x = 7,
|
||||
.y = 0,
|
||||
} }, s.pages.pointFromPin(.screen, sel.end()).?);
|
||||
}
|
||||
}
|
||||
|
||||
test "Selection: order, standard" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
Reference in New Issue
Block a user