How to Configure Scroll Offset and Cursor Centering Behavior in tuicr
Set scroll_offset in ~/.config/tuicr/config.toml to control the initial vertical scroll position, and use Vim-style zz, zt, and zb commands to dynamically center or align the cursor line in the viewport.
The tuicr terminal diff viewer provides fine-grained control over scrolling behavior through both configuration file options and runtime keyboard commands. Whether you need to skip boilerplate headers on startup or dynamically reposition the cursor during code review, the scroll offset and cursor centering behavior in tuicr can be adjusted to match your workflow preferences.
Setting the Initial Scroll Offset in Config
The scroll_offset configuration value determines how many lines are skipped from the top when tuicr first renders the diff pane.
In src/config/mod.rs:133-134, the AppConfig struct defines this field:
#[serde(default = "default_scroll_offset")]
pub scroll_offset: usize,
At startup, src/main.rs:310-312 applies this value to the App instance:
app.diff_state.scroll_offset = config.scroll_offset;
To configure a starting offset of 4 lines, add this to your ~/.config/tuicr/config.toml:
scroll_offset = 4
This is particularly useful when reviewing diffs that contain consistent header blocks or when you want to jump directly to relevant hunks.
Centering the Cursor with zz
The zz command centers the cursor line vertically in the viewport, following standard Vim conventions.
How the Key Sequence Works
When you press z, tuicr enters a pending state. In src/main.rs:60-78, the event loop captures this:
KeyCode::Char('z') => {
pending_z = true;
}
On the second keypress, if it's another z, the application calls App::center_cursor().
The Centering Calculation
The actual scroll adjustment happens in src/ui/diff_view.rs:365-374. The helper method recalculates app.diff_state.scroll_offset based on:
- The cursor's current line position
- The viewport height
- The desired center alignment
The result places the active line in the middle of the visible area.
Alternative Alignments: zt and zb
After the initial z keypress, pressing t or b provides top and bottom alignment respectively.
| Command | Function Call | Result |
|---|---|---|
zz |
App::center_cursor() |
Cursor line centered in viewport |
zt |
App::cursor_to_top() |
Cursor line at top of viewport |
zb |
App::cursor_to_bottom() |
Cursor line at bottom of viewport |
The event handling logic in src/main.rs implements this as follows:
if pending_z {
pending_z = false;
match key.code {
KeyCode::Char('z') => app.center_cursor(),
KeyCode::Char('t') => app.cursor_to_top(),
KeyCode::Char('b') => app.cursor_to_bottom(),
_ => {}
}
}
Controlling Cursor Line Highlight
Related to cursor visibility, the cursor_line boolean setting toggles the visual highlight on the current line.
Defined in src/config/mod.rs:123:
#[serde(default = "default_cursor_line")]
pub cursor_line: bool,
Applied in src/main.rs:307-309:
app.cursor_line = config.cursor_line;
To disable the highlight:
cursor_line = false
Modifying Scroll Offset at Runtime
tuicr does not expose a direct command to modify scroll_offset while the application is running. However, you can achieve equivalent behavior through:
- Cursor movement + recentering: Navigate with
j/k, then presszzto reposition the view - Configuration change: Edit
scroll_offsetinconfig.tomland restarttuicr
Key Source Files Reference
| File | Purpose |
|---|---|
src/config/mod.rs |
Defines scroll_offset and cursor_line in AppConfig |
src/main.rs |
Applies configuration values and handles zz/zt/zb key sequences |
src/ui/diff_view.rs |
Implements scroll offset calculations for cursor positioning |
src/ui/diff_unified.rs / src/ui/diff_side_by_side.rs |
Render views using the calculated scroll_offset |
Summary
- Configure startup position: Set
scroll_offsetin~/.config/tuicr/config.tomlto skip initial lines - Center dynamically: Press
zzto center the cursor line (implemented inApp::center_cursor()) - Align to edges: Use
ztfor top alignment orzbfor bottom alignment - Toggle highlight: Set
cursor_line = falseto disable the cursor line indicator - Workaround runtime changes: Combine cursor movement with
zzsince direct scroll offset commands aren't available
Frequently Asked Questions
How do I make tuicr start scrolled down past a license header?
Add scroll_offset = N to your ~/.config/tuicr/config.toml, where N is the number of lines to skip. This value is read at startup from src/config/mod.rs:133-134 and applied in src/main.rs:310-312.
Why doesn't zz work immediately after I press z once?
tuicr uses a pending-z state machine as implemented in src/main.rs:60-78. The first z sets pending_z = true; you must press a second key (z, t, or b) within the timeout to trigger the corresponding action.
Can I change scroll offset without restarting tuicr?
No direct command exists. According to the agavra/tuicr source code, scroll_offset is only read from configuration at startup. Navigate with j/k and use zz, zt, or zb to reposition the viewport dynamically instead.
What's the difference between cursor_line and scroll_offset?
cursor_line is a boolean that controls visual highlighting of the active line (src/config/mod.rs:123), while scroll_offset is a numeric value controlling how many lines are hidden above the initial viewport (src/config/mod.rs:133-134). They operate independently.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →