fish 4.0.2 makes partial completions easier to extend
fish 4.0.2 distinguishes complete and partial completion results, restores grouped test expressions and prevents abbreviation callbacks from invalidating editor offsets.
Completing a filename is not always the final editing operation on that filename. A user may append a wildcard or continue changing the token, and the representation inserted by the shell affects what those later keystrokes mean. fish 4.0.2, released on April 20, changes completion quoting so that only an unambiguous completion uses quotes. Partial completion continues to use backslash escaping, making the token easier to extend.
I like fish's completion system because it participates in editing rather than merely printing possible strings. That makes the inserted representation part of its behavior. Two forms can initially identify the same file while behaving differently when the next character is typed.
A quoted token can change the next edit
The completion report describes a workflow in which the user completes a path containing special characters and then adds a wildcard. Quoting introduced in 4.0 made that continuation awkward. A wildcard inside quotes is literal text, so the user's next edit could stop expressing the intended pattern.
Backslash escaping protects the special characters already present while allowing a subsequent unescaped wildcard to remain active. The difference is not whether the completed filename was valid when inserted. It is whether the representation remains appropriate while the user continues composing a larger expression.
The release's heuristic uses ambiguity to distinguish these cases. A unique completion can be treated as a completed token, while a partial result is more likely to need continued editing. That is an interactive design decision about the next operation, rather than a change in which files exist or which paths the shell can represent.
Completion is a transformation of the command buffer
The version-pinned changelog states the new rule and identifies it as a change from 4.0's quoting behavior. It also corrects super- key binding support, which had been listed in 4.0.1's notes without working correctly. These corrections show why release behavior needs to be checked against the version actually delivered.
Completion and binding changes meet in the command editor. A completion operation must insert valid text at the right location, while a binding determines which operation the input event requests. A visible editing problem can originate in either layer. The April release addresses both without requiring a different shell language or replacing the command editor's overall model.
The same changelog reports faster Cargo completions by avoiding network requests. That is a different improvement from quoting. One concerns how completion obtains its candidates, while the other concerns how the chosen candidate becomes editable command text. Both affect the time and effort required to finish an interactive command.
Abbreviation callbacks must not invalidate their own replacement
The abbreviation crash report gives a precise failure mechanism. A function used for abbreviation expansion called commandline -r and replaced the current line. The abbreviation machinery then attempted to replace the abbreviation at its old offset, which could be outside the newly shortened line.
The release prevents abbreviation callbacks from altering command-line contents in that context. An expansion function can supply replacement text through its intended interface without independently rewriting the buffer that the pending replacement refers to. This preserves the editor's assumptions about the range being replaced.
The abbreviation documentation distinguishes fixed expansions from function-produced expansions. A dynamic expansion is useful when a function computes the replacement. It does not require that function to perform the replacement itself. Keeping computation separate from mutation avoids competing edits to the same buffer.
Grouping belongs to test's expression parser
The test regression report concerns parentheses passed to the test builtin. A previously accepted grouped expression began producing an error after the 4.0 transition. Version 4.0.2 restores recognition of those grouping arguments.
The test reference describes predicates that return success or failure through their exit status. In fish syntax, parentheses intended for test need to reach it as literal arguments rather than being interpreted as shell command substitution. Escaping them makes that intent explicit.
if test \( -f /usr/bin/fdfind \) -a \( ! -f /usr/bin/fd \)
printf '%s\n' 'Only fdfind is present at these paths.'
end
The example follows the reported shape of the failure. The shell passes grouping tokens to the builtin, and the builtin evaluates the combined file predicates. Restoring that parsing behavior preserves existing configuration that correctly separated shell syntax from the expression syntax understood by test.
These are the kinds of details that matter to my preference for fish as a personal shell. A completion should remain editable, and an expansion callback should have a defined way to return its result. Version 4.0.2 repairs those assumptions alongside an existing scripting construct, so configuration and interactive editing can continue relying on their documented interfaces.