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:

  1. Cursor movement + recentering: Navigate with j/k, then press zz to reposition the view
  2. Configuration change: Edit scroll_offset in config.toml and restart tuicr

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_offset in ~/.config/tuicr/config.toml to skip initial lines
  • Center dynamically: Press zz to center the cursor line (implemented in App::center_cursor())
  • Align to edges: Use zt for top alignment or zb for bottom alignment
  • Toggle highlight: Set cursor_line = false to disable the cursor line indicator
  • Workaround runtime changes: Combine cursor movement with zz since 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →