July 6, 2021·3 min read·engineeringfishpromptsediting

Fish 3.3.1 repaints prompts after state changes

Fish 3.3.1 repairs redraws after universal-variable changes and cancellation in Vi mode. The failures show why updating editor state and displaying that state are separate operations.

A prompt can show stale information even when the underlying variable has changed correctly. Fish's event handlers and prompt rendering are separate parts of the interactive shell, and a repaint request must connect them. Fish 3.3.1, released on July 6, repairs prompt and command-line redraws after universal-variable changes.

The same patch release fixes the Vi mode indicator after Control+C cancels the current command. Both problems concern the relationship between internal state and the terminal display. Correctly changing a variable or editing mode does not establish that the user can see the new state at the next prompt.

I like fish's interactive feedback because it reduces the amount of shell state that has to be remembered. A stale prompt weakens that benefit. When the shell presents a value or a mode indicator, its usefulness depends on repainting after the state it represents changes.

The variable handler ran but the prompt stayed stale

The reproduction in issue 8088 defines a prompt that prints the current directory and a variable named foo. A handler for changes to foo requests a repaint. The report identifies the behavior as a regression from 3.2.2 and records testing on Arch Linux and macOS.

The prompt does not update automatically in the failing case, but pressing a key makes it update. That symptom points to when rendering occurs. The variable's new value is available, yet the requested visual update does not happen at the expected time.

The reporter checks a second handler that prints the variable instead of requesting repaint. That handler works. This is a useful distinction because it separates event delivery from display invalidation. Describing the bug as universal variables not updating would put the failure in the wrong part of the system.

The minimal handler pattern is:

function on_foo --on-variable foo
    commandline -f repaint
end

This excerpt illustrates the request used by the report. The function reacts to the variable event and asks the command-line editor to repaint. The fix ensures that the interactive prompt and command line can reflect the state change without relying on a later keystroke to produce a visible update.

Universal variables make changes cross session boundaries

The language reference shipped with 3.3.1 describes universal variables as shared among a user's fish sessions on the computer. They also persist across logout and reboot. Fish uses them for many configuration options, so a setting changed in one shell can affect another shell already displaying a prompt.

That makes repainting different from the ordinary sequence of entering a command and waiting for the next prompt. The display may need to change while the shell is waiting for input. A variable event can request that update even though the user has not executed another command in the receiving session.

The reference uses prompt color as an example of a shared configuration change. The underlying persistence file is fish_variables in fish's configuration directory, and the documentation says to change variables through fish rather than editing the file directly. Changing a variable through fish updates configuration through the supported shell interface.

Persistence also explains why repeatedly appending to universal variables in startup configuration is problematic. The reference warns that the variable grows with every new shell. A redraw fix does not change those storage semantics. It restores the display response to state that the variable system already manages.

Cancellation must repaint the Vi mode indicator

Issue 8103 describes cancelling input with Control+C while in Vi normal mode. Fish prints a new prompt, but the mode indicator does not update. The report includes a reproduction on 3.2.2, and a maintainer confirms the problem in 3.3.0. This particular issue therefore predates the new minor release.

The proposed correction adds repaint-mode after cancelling the command line. The binding shipped in 3.3.1 includes that operation alongside cancel-commandline and the transition to insert mode. This binding makes both the state transition and the display update explicit.

A mode indicator is part of the editing interface because the next key can have a different meaning in each mode. Updating the command line without updating that indicator leaves a misleading view of what the editor will do. The fix concerns that consistency, rather than adding a new Vi editing command.

I consider these small display corrections worthwhile because fish relies on visible feedback during command construction. The prompt is executable configuration, universal variables can change it across sessions, and modal editing adds another source of display state. Version 3.3.1 repairs the repaint paths that connect those changes to what the terminal shows.