Skip to content

fix(ui): enable j/k step scroll in normal mode#131

Merged
benvinegar merged 1 commit intomodem-dev:mainfrom
aliou:fix/normal-mode-jk-scroll
Mar 30, 2026
Merged

fix(ui): enable j/k step scroll in normal mode#131
benvinegar merged 1 commit intomodem-dev:mainfrom
aliou:fix/normal-mode-jk-scroll

Conversation

@aliou
Copy link
Copy Markdown
Contributor

@aliou aliou commented Mar 29, 2026

Hello!

Noticed this mismatch when I couldn't undersatnd why j/k would work in some case and not others.

Let me know if you need/want other changes!

summary by gpt 5.3

Summary

Enable j/k line-step scrolling in normal diff mode by reusing the existing shared step-key detection already used in pager mode.

Changes

  • Updated src/ui/App.tsx keyboard handler in normal mode:
    • up step scroll condition now uses stepUpKey
    • down step scroll condition now uses stepDownKey
  • This reuses existing key abstraction where:
    • stepUpKey includes up + k
    • stepDownKey includes down + j

Why

j/k were already supported in pager mode but not in normal mode due to direct arrow-key checks in the normal-mode branch. This caused inconsistent navigation behavior across modes.

Validation

  • bun run typecheck
  • Manual repro in tmux with a large diff (hunk show HEAD~6):
    • before: j/k no-op in normal mode
    • after: j/k scroll line-by-line in normal mode

Notes

  • No new shortcuts introduced.
  • No behavior change in pager mode.
  • Scope is limited to normal-mode keyboard parity.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 29, 2026

Greptile Summary

This is a small, focused fix that closes the j/k navigation gap between pager mode and normal mode. The stepUpKey / stepDownKey variables (which already include both arrow keys and vim keys) were already defined at the top of the keyboard handler and correctly used in the pager branch — the normal-mode branch simply hadn't been updated to use them.

  • Change: Two key.name === \"up\" / key.name === \"down\" checks in the normal-mode scroll path are replaced with the shared stepUpKey / stepDownKey boolean variables.
  • Impact: j and k now scroll one line at a time in normal mode, matching the existing behaviour in pager mode.
  • Side-effect to verify: Because the activeMenuId block does not have a catch-all return for unhandled keys, j/k will now also scroll the diff when a menu is open (they previously fell through without doing anything). This is consistent with how other non-menu keys (e.g. s, 1, 2) already behave, but is worth a quick confirmation that it is the intended UX.

Confidence Score: 5/5

Safe to merge — the change is minimal, well-scoped, and correctly reuses an existing abstraction.

Only one file changes, the fix is two lines, the stepUpKey/stepDownKey variables are already tested in pager mode, and the PR description includes manual validation. The one observation about j/k falling through menu context is consistent with existing behaviour for other keys and is P2 at most.

No files require special attention.

Important Files Changed

Filename Overview
src/ui/App.tsx Two-line change replacing direct key.name === "up"/"down" checks in normal mode with the already-defined stepUpKey/stepDownKey variables, enabling j/k vim navigation consistently with pager mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    K[Key event received] --> DEF[Define stepUpKey / stepDownKey\nup · k  /  down · j]
    DEF --> PM{pagerMode?}
    PM -- yes --> PS[stepUpKey → scrollDiff -1 step\nstepDownKey → scrollDiff +1 step]
    PM -- no --> AM{activeMenuId?}
    AM -- yes, captures up/down/etc. --> MENU[Menu navigation / action]
    AM -- j or k falls through --> STEP
    AM -- no --> FF[focusArea, q, ?, escape…]
    FF --> STEP["stepUpKey → scrollDiff -1 step ✅ NEW\nstepDownKey → scrollDiff +1 step ✅ NEW"]
Loading

Reviews (1): Last reviewed commit: "fix(ui): enable j/k step scroll in norma..." | Re-trigger Greptile

Comment on lines +809 to 816
if (stepUpKey) {
scrollDiff(-1, "step");
return;
}

if (key.name === "down") {
if (stepDownKey) {
scrollDiff(1, "step");
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 j/k scroll through when a menu is open

With this change, pressing j or k while activeMenuId is set will fall through the menu block (which only captures up/down/left/right/tab/enter/escape) and reach the new stepDownKey/stepUpKey checks, silently scrolling the diff in the background while the menu is open.

Before this PR, j and k were no-ops in the menu context. This is now a behaviour change. The menu item navigation on lines 717–724 uses key.name === "up" / key.name === "down" directly, so j/k will never navigate menu items — they'll just scroll.

Whether this is intentional is worth a quick sanity-check. If the menu should fully consume all input while open, adding an early return at the end of the activeMenuId block would prevent unintended fall-through for all non-captured keys (not just the scrolling ones).

@benvinegar benvinegar merged commit 1d6e029 into modem-dev:main Mar 30, 2026
3 checks passed
@benvinegar
Copy link
Copy Markdown
Member

@aliou Nice find, I never actually use these so never noticed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants