Cursor Wake

Cursor Wake draws an elastic streak that follows the cursor when it jumps a long way, for example when an editor moves you to another part of the screen or when you switch to another pane. It helps your eyes find the cursor again.

The real cursor and its character always move at once. Typing, selection, and the cursor position that programs report are never delayed or animated. The streak is only a visual effect around the cursor.

Cursor Wake needs Nash 0.9.1 or newer.

Turn it on or off

The nash.toml file that Nash ships has Cursor Wake on. To turn it off, for example if you prefer less motion, set this in ~/.config/nash/nash.toml:

[cursor_wake] enabled = false

Nash watches the file. The change applies when Nash reloads the configuration, and a reload happens by itself when you save the file.

When you update to 0.9.1, the first launch adds the [cursor_wake] table to your nash.toml if it is not there. Configuration sync only adds settings. It never changes a value that you set, and a setting that you commented out stays off.

To turn the effect off, set enabled = false. Do not delete the table, because the next sync adds it again. See Configuration Sync.

Settings

All keys are optional. Times are in milliseconds, and distances are in character cells.

KeyShipped valueBuilt-in value if the key is missingWhat it does
enabledtruefalseTurns the effect on or off.
settle_ms11How long a new cursor position must stay the same before the streak reacts. 0 reacts at once.
fast_ms100100How fast the front of the streak catches up. A smaller number is faster. It must be above 0.
slow_ms240400How fast the tail catches up. A larger number gives a longer streak. It must be at least fast_ms.
min_distance_cells_x22Horizontal jump size, in cells, that the effect ignores.
min_distance_cells_y22Vertical jump size, in rows, that the effect ignores.
color""noneStreak color. An empty value uses the color of the cursor. Use a color such as "#86b5ff" to choose one.
opacity1.01.0From 0 to 1. It multiplies the alpha of the color. 0 draws nothing.
animate_focus_changestruetrueAlso shows the streak when you switch to another pane or tab in the same window.

Two of the keys need more explanation:

  • Small jumps are ignored only when both limits hold. With the defaults, a move of 2 cells or fewer, both across and down, does not start a streak. A move of 3 cells in either direction does. Set both limits to 0 to animate every jump.
  • settle_ms is not a switch. 0 means "react now". It does not turn the effect off. A larger value can hide short cursor moves that a full-screen program makes while it redraws, but it also delays the streak after a move that you meant.

Nash rejects a bad value instead of correcting it silently. A fast_ms of 0, a slow_ms below fast_ms, and an opacity outside 0 to 1 are configuration errors.

What you see

  • The front of the streak moves quickly to the new cursor position. The tail follows more slowly, so the shape stretches and then shrinks.
  • The streak never covers the live cursor or its character.
  • Block, bar, and underline cursors all work. The streak follows the size of the cursor, including your display density and wide characters.
  • Cursor blinking is independent of the streak.
  • If a program hides the cursor, an existing streak fades out. When the cursor shows again, the effect starts at the new position and does not replay the hidden movement.
  • The streak is drawn only inside panes. It does not cover the dividers between panes or the strips of folded panes.

Switching panes and tabs

With animate_focus_changes = true, the streak also runs when you move to another pane or tab in the same window. The distance limit and the settle delay do not apply to this move. The effect needs the cursor to be visible in both places. If either cursor is hidden, Nash resets the effect and does not carry the old streak into the new pane.

With animate_focus_changes = false, the effect snaps to the new position. There is never a streak between two windows or between Nash and another application.

When Nash resets or pauses the effect

Nash resets the effect, and starts again at the cursor position, when:

  • the window is resized, or the font or the display density changes,
  • the pane layout changes, for example by a split or a fold,
  • you scroll the scrollback,
  • the program switches between the normal screen and the alternate screen,
  • Nash reloads the configuration, or the window gains or loses focus.

Nash does not draw the effect while the window does not have focus. It also pauses the effect while the command palette or another modal is open, while an overlay such as copy mode is open on the pane, during dead-key composition, and while a leader key is active.

Rendering and cost

Cursor Wake works with the WebGPU front end, which the bundled configuration uses, and with the OpenGL front end. To try OpenGL, put front_end = 'OpenGL' in a return { ... } table in ~/.config/nash/custom.lua.

While the streak moves, Nash redraws the window at the rate of animation_fps and reuses the text it already drew. When the streak is at rest, or the effect is off, Nash schedules no frames for it.

Check that it works

Run this in a Nash pane. The cursor jumps to row 5, then back to the top-left corner, then the shell prompt returns it:

printf '\033[5;40H'; sleep 1; printf '\033[H'; sleep 1

You should see a streak on each jump. If you do not, check that the window has focus, that enabled = true, and that opacity is above 0.

Differences from Kitty

Cursor Wake is Nash's own effect. It does not use Kitty's settings or setting names, and it has its own switch. Nash sees the cursor positions that the window samples, so it cannot show a move that finished before the window took a sample. A settle_ms of 1 does not promise to hide every redraw that a full-screen program makes. There are no custom shaders, particles, or ghost cursors.