mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +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,
|
.page_down => .page_down,
|
||||||
.home => .home,
|
.home => .home,
|
||||||
.end => .end,
|
.end => .end,
|
||||||
|
.beginning_of_line => .beginning_of_line,
|
||||||
|
.end_of_line => .end_of_line,
|
||||||
});
|
});
|
||||||
|
|
||||||
// If the selection endpoint is outside of the current viewpoint,
|
// If the selection endpoint is outside of the current viewpoint,
|
||||||
|
@ -304,6 +304,8 @@ pub const Action = union(enum) {
|
|||||||
page_down,
|
page_down,
|
||||||
home,
|
home,
|
||||||
end,
|
end,
|
||||||
|
beginning_of_line,
|
||||||
|
end_of_line,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SplitDirection = enum {
|
pub const SplitDirection = enum {
|
||||||
|
@ -344,6 +344,8 @@ pub const Adjustment = enum {
|
|||||||
end,
|
end,
|
||||||
page_up,
|
page_up,
|
||||||
page_down,
|
page_down,
|
||||||
|
beginning_of_line,
|
||||||
|
end_of_line,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Adjust the selection by some given adjustment. An adjustment allows
|
/// Adjust the selection by some given adjustment. An adjustment allows
|
||||||
@ -353,16 +355,16 @@ pub fn adjust(
|
|||||||
s: *const Screen,
|
s: *const Screen,
|
||||||
adjustment: Adjustment,
|
adjustment: Adjustment,
|
||||||
) void {
|
) 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
|
// 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.
|
// whether the user drags up or down.
|
||||||
const end_pin = self.endPtr();
|
const end_pin = self.endPtr();
|
||||||
switch (adjustment) {
|
switch (adjustment) {
|
||||||
.up => if (end_pin.up(1)) |new_end| {
|
.up => if (end_pin.up(1)) |new_end| {
|
||||||
end_pin.* = new_end;
|
end_pin.* = new_end;
|
||||||
} else {
|
} else {
|
||||||
end_pin.x = 0;
|
self.adjust(s, .beginning_of_line);
|
||||||
},
|
},
|
||||||
|
|
||||||
.down => {
|
.down => {
|
||||||
@ -377,7 +379,7 @@ pub fn adjust(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we're at the bottom, just go to the end of the line
|
// 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" {
|
test "Selection: order, standard" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
Reference in New Issue
Block a user