From 3cef8abddf84deb5e0f7eb476cf64de40fd0b761 Mon Sep 17 00:00:00 2001 From: Ben Vinegar Date: Tue, 24 Mar 2026 08:04:43 -0400 Subject: [PATCH] Add navigation shortcuts from issue #101 - d / u: scroll half page down / up (less/git diff convention) - f: alternative page down (less convention, like Space) - Shift+Space: page up (standard pager behavior) These shortcuts work in both normal and pager modes, matching muscle memory from less, git diff, man pages, and other pagers. Updated help dialog to document the new shortcuts. Fixes #101 --- src/ui/App.tsx | 55 +++++++++++++++++++++++-- src/ui/components/chrome/HelpDialog.tsx | 5 ++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/ui/App.tsx b/src/ui/App.tsx index 77ddfe83..efeecdc6 100644 --- a/src/ui/App.tsx +++ b/src/ui/App.tsx @@ -285,7 +285,23 @@ function AppShell({ }; /** Scroll the main review pane by line steps, viewport fractions, or whole-content jumps. */ - const scrollDiff = (delta: number, unit: "step" | "viewport" | "content" = "viewport") => { + const scrollDiff = ( + delta: number, + unit: "step" | "viewport" | "content" | "half" = "viewport", + ) => { + if (unit === "half") { + const scrollBox = diffScrollRef.current; + if (!scrollBox) return; + + // Calculate half the viewport height + const viewportHeight = scrollBox.viewport?.height ?? 20; + const scrollAmount = Math.floor(viewportHeight / 2); + + // Use scrollTo with current position + delta * amount + const currentScroll = scrollBox.scrollTop; + scrollBox.scrollTo(currentScroll + delta * scrollAmount); + return; + } diffScrollRef.current?.scrollBy(delta, unit); }; @@ -571,11 +587,22 @@ function AppShell({ useKeyboard((key: KeyEvent) => { const pageDownKey = - key.name === "pagedown" || key.name === "space" || key.name === " " || key.sequence === " "; + key.name === "pagedown" || + key.name === "space" || + key.name === " " || + key.sequence === " " || + key.name === "f" || + key.sequence === "f"; const pageUpKey = key.name === "pageup" || key.name === "b" || key.sequence === "b"; const stepDownKey = key.name === "down" || key.name === "j" || key.sequence === "j"; const stepUpKey = key.name === "up" || key.name === "k" || key.sequence === "k"; + // New shortcuts from issue #101 - using less/git diff conventions + const halfPageDownKey = key.name === "d" || key.sequence === "d"; + const halfPageUpKey = key.name === "u" || key.sequence === "u"; + const shiftSpacePageUpKey = + key.shift && (key.name === "space" || key.name === " " || key.sequence === " "); + if (key.name === "f10") { if (pagerMode) { return; @@ -600,11 +627,21 @@ function AppShell({ return; } - if (pageUpKey) { + if (pageUpKey || shiftSpacePageUpKey) { scrollDiff(-1, "viewport"); return; } + if (halfPageDownKey) { + scrollDiff(1, "half"); + return; + } + + if (halfPageUpKey) { + scrollDiff(-1, "half"); + return; + } + if (stepDownKey) { scrollDiff(1, "step"); return; @@ -716,11 +753,21 @@ function AppShell({ return; } - if (pageUpKey) { + if (pageUpKey || shiftSpacePageUpKey) { scrollDiff(-1, "viewport"); return; } + if (halfPageDownKey) { + scrollDiff(1, "half"); + return; + } + + if (halfPageUpKey) { + scrollDiff(-1, "half"); + return; + } + if (key.name === "home") { scrollDiff(-1, "content"); return; diff --git a/src/ui/components/chrome/HelpDialog.tsx b/src/ui/components/chrome/HelpDialog.tsx index 22ef090d..6b9ebd7e 100644 --- a/src/ui/components/chrome/HelpDialog.tsx +++ b/src/ui/components/chrome/HelpDialog.tsx @@ -21,7 +21,10 @@ export function HelpDialog({ title: "Navigation", items: [ ["↑ / ↓", "move line-by-line"], - ["Space / b", "page down / page up"], + ["Space / f", "page down (alt: f)"], + ["b", "page up"], + ["Shift+Space", "page up (alt)"], + ["d / u", "half page down / up"], ["[ / ]", "previous / next hunk"], ["Home / End", "jump to top / bottom"], ],