core: scroll to selection working

This commit is contained in:
Mitchell Hashimoto
2024-03-13 13:23:55 -07:00
parent 522c28207e
commit 935063d892
3 changed files with 35 additions and 16 deletions

View File

@ -1358,14 +1358,14 @@ pub fn keyCallback(
if (event.mods.shift) adjust_selection: { if (event.mods.shift) adjust_selection: {
self.renderer_state.mutex.lock(); self.renderer_state.mutex.lock();
defer self.renderer_state.mutex.unlock(); defer self.renderer_state.mutex.unlock();
var screen = self.io.terminal.screen; var screen = &self.io.terminal.screen;
const sel = if (screen.selection) |*sel| sel else break :adjust_selection; const sel = if (screen.selection) |*sel| sel else break :adjust_selection;
// Silently consume key releases. We only want to process selection // Silently consume key releases. We only want to process selection
// adjust on press. // adjust on press.
if (event.action != .press and event.action != .repeat) return .consumed; if (event.action != .press and event.action != .repeat) return .consumed;
sel.adjust(&screen, switch (event.key) { sel.adjust(screen, switch (event.key) {
.left => .left, .left => .left,
.right => .right, .right => .right,
.up => .up, .up => .up,
@ -1378,20 +1378,24 @@ pub fn keyCallback(
}); });
// If the selection endpoint is outside of the current viewpoint, // If the selection endpoint is outside of the current viewpoint,
// scroll it in to view. // scroll it in to view. Note we always specifically use sel.end
// TODO(paged-terminal) // because that is what adjust modifies.
// scroll: { scroll: {
// const viewport_max = terminal.Screen.RowIndexTag.viewport.maxLen(&screen) - 1; const viewport_tl = screen.pages.getTopLeft(.viewport);
// const viewport_end = screen.viewport + viewport_max; const viewport_br = screen.pages.getBottomRight(.viewport).?;
// const delta: isize = if (sel.end.y < screen.viewport) if (sel.end().isBetween(viewport_tl, viewport_br))
// @intCast(screen.viewport) break :scroll;
// else if (sel.end.y > viewport_end)
// @intCast(viewport_end) // Our end point is not within the viewport. If the end
// else // point is after the br then we need to adjust the end so
// break :scroll; // that it is at the bottom right of the viewport.
// const start_y: isize = @intCast(sel.end.y); const target = if (sel.end().before(viewport_tl))
// try self.io.terminal.scrollViewport(.{ .delta = start_y - delta }); sel.end()
// } else
sel.end().up(screen.pages.rows - 1) orelse sel.end();
screen.scroll(.{ .pin = target });
}
// Queue a render so its shown // Queue a render so its shown
try self.queueRender(); try self.queueRender();

View File

@ -1413,6 +1413,10 @@ pub const Scroll = union(enum) {
/// prompts. If the absolute value is greater than the number of prompts /// prompts. If the absolute value is greater than the number of prompts
/// in either direction, jump to the furthest prompt in that direction. /// in either direction, jump to the furthest prompt in that direction.
delta_prompt: isize, delta_prompt: isize,
/// Scroll directly to a specific pin in the page. This will be set
/// as the top left of the viewport (ignoring the pin x value).
pin: Pin,
}; };
/// Scroll the viewport. This will never create new scrollback, allocate /// Scroll the viewport. This will never create new scrollback, allocate
@ -1422,6 +1426,15 @@ pub fn scroll(self: *PageList, behavior: Scroll) void {
switch (behavior) { switch (behavior) {
.active => self.viewport = .{ .active = {} }, .active => self.viewport = .{ .active = {} },
.top => self.viewport = .{ .top = {} }, .top => self.viewport = .{ .top = {} },
.pin => |p| {
if (self.pinIsActive(p)) {
self.viewport = .{ .active = {} };
return;
}
self.viewport_pin.* = p;
self.viewport = .{ .pin = {} };
},
.delta_prompt => |n| self.scrollPrompt(n), .delta_prompt => |n| self.scrollPrompt(n),
.delta_row => |n| { .delta_row => |n| {
if (n == 0) return; if (n == 0) return;

View File

@ -552,6 +552,7 @@ pub const Scroll = union(enum) {
/// For all of these, see PageList.Scroll. /// For all of these, see PageList.Scroll.
active, active,
top, top,
pin: Pin,
delta_row: isize, delta_row: isize,
delta_prompt: isize, delta_prompt: isize,
}; };
@ -566,6 +567,7 @@ pub fn scroll(self: *Screen, behavior: Scroll) void {
switch (behavior) { switch (behavior) {
.active => self.pages.scroll(.{ .active = {} }), .active => self.pages.scroll(.{ .active = {} }),
.top => self.pages.scroll(.{ .top = {} }), .top => self.pages.scroll(.{ .top = {} }),
.pin => |p| self.pages.scroll(.{ .pin = p }),
.delta_row => |v| self.pages.scroll(.{ .delta_row = v }), .delta_row => |v| self.pages.scroll(.{ .delta_row = v }),
.delta_prompt => |v| self.pages.scroll(.{ .delta_prompt = v }), .delta_prompt => |v| self.pages.scroll(.{ .delta_prompt = v }),
} }