fish 4.0.1 distinguishes interactive reads from ordinary execution
fish 4.0.1 adds a predicate for interactive read contexts and repairs terminal-control output, prompt display and keyboard compatibility.
A shell can be interactive while running a function that should produce plain data. It can also run an interactive input reader inside a script. Treating those situations as identical leads to terminal behavior appearing in the wrong context. fish 4.0.1, released on March 12, adds status is-interactive-read and corrects several related boundaries between terminal interaction and ordinary command execution.
I like fish because interactive features are available without an extensive configuration project. That makes their context important. A cursor adjustment belongs on the terminal being edited, while a command's redirected output should remain suitable for the program receiving it. Convenience depends on the shell respecting that distinction.
A read invocation is its own interaction
The status reference in 4.0.1 defines the new predicate as succeeding when fish is running an interactive read builtin connected to a keyboard. This is narrower than status is-interactive, which describes whether fish itself is interactive. A function can now ask which of these contexts it is serving.
if status is-interactive-read
printf '%s\n' 'An interactive read is active.'
end
The fragment illustrates the predicate rather than a recommended message for every input reader. It gives custom behavior a specific condition to inspect. A function shared by ordinary command-line editing and a nested reader no longer has to infer that distinction indirectly from the surrounding shell session.
The read documentation explains that read obtains a line from standard input and stores the result in variables. When used interactively, its editing and prompt behavior can differ from a simple redirected input operation. The new status query exposes that interactive-reader context explicitly to scripts that need it.
This is useful because connection to a keyboard is a property of the current interaction, not proof that all output produced during the session should carry terminal controls. A shell function can be called in several contexts. The more precisely it can identify the one it is in, the less it needs to rely on global assumptions about the shell.
Cursor commands must not enter redirected output
The cursor-shape report concerns control sequences emitted outside the intended interactive context. The patch release stops sending cursor-shape commands in non-interactive shells and redirections. That restores the distinction between a terminal instruction and bytes returned as command output.
A cursor-shape sequence is meaningful to a terminal emulator. The same bytes in a file or pipe are just unexpected content. A downstream consumer cannot be expected to remove them, because it may legitimately process arbitrary bytes or require a strict input format. Preventing the terminal instruction at its source preserves the command's output contract.
This kind of defect is easy to overlook in a terminal-only demonstration. The terminal interprets the bytes and may leave no visible textual residue. A redirected invocation exercises a different interface, where the bytes become observable data. The correction belongs to that output boundary even when the original feature was entirely visual.
Prompt controls also affect width calculations
The prompt-display report identifies incorrect command-line display when prompts contain control characters. The release corrects that case. Prompt rendering requires the shell to distinguish bytes sent to the terminal from the screen columns those bytes occupy.
That distinction determines where fish believes editing can continue. A control sequence may affect terminal state without occupying visible columns. Counting it as ordinary displayed text can leave the shell and terminal with different models of the cursor position. The resulting error can appear in the command line even though the problematic bytes originated in the prompt.
For a configurable shell, prompts are executable functions and their output participates in this rendering process. A prompt's appearance therefore depends on both its own output and the shell's interpretation of that output. The correction makes an existing class of prompt output work properly without requiring users to abandon prompt customization.
Keyboard compatibility depends on the terminal implementation
The version-pinned changelog also records targeted keyboard-protocol changes. fish stops using modifyOtherKeys under WezTerm because of layout problems, and disables the kitty protocol in affected older iTerm versions and under Midnight Commander. These are scoped compatibility decisions, not a withdrawal of the readable key-binding notation introduced in 4.0.
The same notes record fixes for background-task startup in macOS Terminal.app and completion behavior for several commands. Those corrections show why an interactive shell's patch release spans several interfaces. A key can be encoded incorrectly before a binding runs, while a completion can be wrong after input has already been interpreted correctly.
My preference for fish rests on those interactions behaving predictably. Version 4.0.1 makes the active input context more visible to scripts and confines terminal behavior more carefully to that context. The new predicate and the output corrections give custom functions a better-defined environment in which to operate.