Skip to content

fish: Completion script rewrite (SHIFT-TAB)#4731

Merged
junegunn merged 5 commits into
junegunn:develfrom
bitraid:fish-complete
Apr 2, 2026
Merged

fish: Completion script rewrite (SHIFT-TAB)#4731
junegunn merged 5 commits into
junegunn:develfrom
bitraid:fish-complete

Conversation

@bitraid

@bitraid bitraid commented Mar 21, 2026

Copy link
Copy Markdown
Collaborator

Contribution Policy

We do not accept pull requests generated primarily by AI without genuine understanding or real-world usage context.

All contributions are expected to demonstrate:

  • A clear understanding of the codebase
  • Alignment with product direction
  • Thoughtful reasoning behind changes
  • Evidence of real-world usage or hands-on experience with the problem

If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.


Acknowledgement

  • I confirm that this PR meets the above expectations and reflects my own understanding and real-world context.

The current completion script suffers from various issues:

  • It crashes on open quotes, single or trailing unescaped \ or $, and commands like env -i cmd. Also, due to an oversight in complete, a single escaped backslash (\\) in command line crashes the shell.
  • Completion of tokens with escaped/unescaped $ work in the opposite way: Unescaped $ does file completion while escaped $ does variable name completion (instead of the other way around).
  • It does not handle names containing newlines.
  • Descriptions text is not searchable and not wrapped by default. If wrapping is enabled, the wrapped text is not aligned.
  • I think it is not correct for the current token to automatically become the fzf query on startup. The generated list is already based upon the token, and having the token also as the query modifies the natural order (as listed by tab) of the results and gives the wrong impression that by deleting the query the whole list is going to be displayed.

This implementation is designed from the beginning as a replacement for the native <shift-tab> functionality and is cleaner and more robust, while providing the additional ability of recognizing tokens that are wildcard expansion patterns, and perform search on the expanded lists. It consists of a single function (fzf_complete) of about 100 LOC, which can also be used by custom completion functions. The function is defined as a wrapper of fzf, so its command line options (same as fzf) can be auto completed. Since the script makes use of fish completion functions, it should be advised for users to create/update regular completion functions (which will work for both tab and shift-tab), and create custom fzf completion functions only when needing to modify fzf options or want different results for shift-tab (for example, have no limit on the number of results for a command like git checkout).

Minimal custom function example:

function _fzf_complete_foo
  ls -la | fzf_complete --header-lines 3
end

function _fzf_post_complete_foo
  # Or use an external command instead of the while loop: awk '{print $NF}'
  while read -l result
    string split -r -m 1 -f 2 -- ' ' $result
  end
end

Null terminated items from custom functions (that don't have custom post-functions) are supported, even though it doesn't make much sense for completion items to insert newlines (or other unescaped whitespace characters). For that reason, custom post completion functions are always expected to return line terminated items:

function _fzf_complete_foo
  ls --zero | fzf_complete --read0 --print0
end

function _fzf_post_complete_foo
  while read -lz result
    string escape -- $result
  end
end

A more useful example that demonstrates the different ways the function can be used:

# Customize git completion
function _fzf_complete_git
    # Show header text with active branch for all git completions
    set -lx -- FZF_COMPLETION_OPTS --header=\'(git branch --color=always 2>/dev/null)\'

    # No other changes when less than 3 arguments, or when completing options
    if not set -q argv[3]; or string match -q -- '-*' $argv[-1]
        fzf_complete
        return
    end

    # Check subcommand
    switch $argv[2]
        case checkout diff log show
            # Set preview and display all branches and commits for subcommands: checkout, diff, log, show
            begin
                git branch --all --format='%(refname:short)'
                git log --all --oneline --color=always
            end | fzf_complete --no-multi --ansi --accept-nth=1 --query=$argv[-1] --preview='git show --color=always {1}'

        case add rm mv
            # Only set preview for subcommands: add, rm, mv
            fzf_complete --preview="git diff --color=always {r1}"

        case '*'
            # No changes for other subcommands
            fzf_complete
    end
end

The README isn't updated yet. There are some things than must be decided:

  • The script uses the --visible (-V) option of string length, and --escape option of complete -C, both of which were introduced in fish v3.4.0. This makes the version requirement different than that of key-bindings.fish, which is v3.1b1. There are three different ways we can handle this:

    • Make the script compatible with v3.1b1 by adding version checks and alternative commands for versions older than 3.4.0. But maybe supporting such old versions doesn't worth the added complexity, because probably there are hardly any users that would benefit from it. The current completion script also uses string length -V, and there were no complaints yet.
    • Make v3.4.0 the minimum required version for both scripts and simplify the code of key-bindings.fish. A key-bindings-legacy.fish could be left in the repository, so that users with old fish versions can still have a way to use the key bindings.
    • Have different version requirements for the two scripts.
  • The file names in completion lists (but not in glob lists) are escaped. This can be changed, but:

    • This is the most direct and reliable way of escaping only when needed. If the escaping was to be done by the script, it would first need to check if it is a variable name completion (by checking if the list contains the string \tVariable: , which is not very elegant or 100% reliable) and not apply escaping in this case. It should also check after escaping if the token starts with unescaped ~, and unescape the leading ~ from the result.
    • Because completion items can have descriptions separated by the tab character, this would be the only way of correctly handling filenames with tabs. Unfortunately, complete seems to split the item before escaping, so names that contain tabs are still not handled correctly. This is something that the native fish completion also suffers from and will probably be fixed in the future.
  • The environment variable $FZF_EXPANSION_OPTS is used for customizing the options of glob expansion search, in addition to the usual $FZF_COMPLETION_OPTS for setting completion options. The list in glob expansions is certain to be files or directories, so it makes sense to have separate options, but it is also necessary for accessing the selections because different templates must be used ({+} for expansions, {+r1} for completions). It would be possible to use a single variable though, if the names in both completion and expansion were escaped or unescaped, and also have \x00 as delimiter for expansion (so the same template can be used).

  • The custom post completion functions are named _fzf_post_complete_COMMAND instead of _fzf_compete_COMMAND_post that is used for other shells. This is done for being able to handle binaries named foo and foo_post. If having the same function name as other shells is preferred, we can change it.

  • The script tries to detect the command to be completed, by stripping any leading variable definitions and launcher commands (builtin, command, doas, env, sudo) from the command line. If a custom function is defined for that command, the function is called and the (stripped) command line tokens are passed as arguments ($argv[1] is the command name, $argv[-1] is the current token). Any options of the launcher commands are removed, but in order to also support options that accept parameters and remove the parameters too, it would require much code (for something rarely used), whereas now a single regex is used. Let me know if this is OK.

@github-actions github-actions Bot added shell Shell scripts fish Fish shell test Tests install Install/uninstall scripts labels Mar 21, 2026
@junegunn

junegunn commented Mar 22, 2026

Copy link
Copy Markdown
Owner

I've rebased devel onto the latest master, so the CI error should resolve.

EDIT: Hmm, it doesnt. Let me rebase your branch.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reworks the Fish integration to provide a new <shift-tab> completion implementation centered around a single fzf_complete function, while simplifying the shell script update workflow and adjusting related install/test configuration.

Changes:

  • Replaces the Fish completion implementation with a new fzf_complete function and binds it to Shift-Tab (or btab on older Fish).
  • Removes shell/common.fish and inlines/adjusts shared Fish logic in shell/key-bindings.fish.
  • Simplifies shell/update.sh to only update Bash/Zsh scripts from common.sh, and updates install/test/editorconfig accordingly.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
shell/completion.fish Rewritten Fish completion entrypoint (fzf_complete) + Shift-Tab binding, plus wildcard-expansion search path.
shell/key-bindings.fish Removes generated include block and keeps required Fish helper functions inline.
shell/common.fish Deleted (previous Fish shared include file).
shell/update.sh Hardcodes common.sh inclusion and updates only Bash/Zsh targets.
test/lib/common.fish Updates test environment variables for the new Fish completion behavior/options.
install Updates the post-install Fish instruction to call fish_user_key_bindings.
.editorconfig Applies shell-style indentation rules to *.fish files as well.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread shell/completion.fish
Comment thread shell/completion.fish Outdated
Comment thread shell/completion.fish Outdated
Comment thread shell/completion.fish Outdated
Comment thread shell/completion.fish Outdated
Comment thread shell/completion.fish
Comment thread shell/completion.fish
@junegunn

junegunn commented Mar 22, 2026

Copy link
Copy Markdown
Owner

Thanks. Some questions:

It looks like this change breaks backward compatibility for the custom completion API, right? Could you explain the rationale behind it? Also, what happens to users who rely on the previous API for custom completions? e.g.

function _fzf_complete_foo
  function _fzf_complete_foo_post
    awk '{print $NF}'
  end
  _fzf_complete --multi --reverse --header-lines=3 -- $argv < (ls -al | psub)

  functions -e _fzf_complete_foo_post
end

Could the new code detect old-style functions and still call them, at least with a warning? Maybe keep _fzf_complete (with _ prefix) as a compatibility shim?

  • The custom post completion functions are named _fzf_post_complete_COMMAND instead of _fzf_compete_COMMAND_post that is used for other shells. This is done for being able to handle binaries named foo and foo_post. If having the same function name as other shells is preferred, we can change it.

I see the point, but I'd lean toward consistency and handle the _post edge case only if it becomes a real issue. The earlier work aimed to keep the API consistent with other shell implementations, which I thought was a strong design choice.

@junegunn

Copy link
Copy Markdown
Owner

Please take a look at the Copilot comments, but feel free to disregard irrelevant ones. Copilot often speaks nonsense.

@bitraid

bitraid commented Mar 22, 2026

Copy link
Copy Markdown
Collaborator Author

The earlier work aimed to keep the API consistent with other shell implementations, which I thought was a strong design choice.

It looks like this change breaks backward compatibility for the custom completion API, right? Could you explain the rationale behind it? Also, what happens to users who rely on the previous API for custom completions?

I just went with the most optimal implementation this time, since completion already works different than the other shells and it's a recent addition to fish. It is easy to maintain compatibility though: Rename the main function and custom post functions, and remove -- and any following arguments that may be present in the command line (these are no longer used by the script and all arguments are passed to fzf, which will cause issues if they contain $argv). It doesn't matter if the input comes from a pipe or a process substitution redirection, but there is no __fzf_complete_native function (instead, the single function is called with no redirected input). We can also support this though, by creating a copy of the function (functions -c _fzf_complete __fzf_complete_native) when the script is sourced. Let me know if I should make those changes (or some of them).

@junegunn

Copy link
Copy Markdown
Owner

Option 1

  • fzf_complete - The new, simpler API designed for ease of use
  • _fzf_complete - A compatibility shim aligned with the bash/zsh style for backward compatibility (i.e. fzf args + -- + mandatory $argv)

Option 2

Make _fzf_complete print deprecation warning (and do nothing).


What do you think? Although the fish completion is new, we neglected to mark it as experimental, so we should at least let the users know.

@junegunn

junegunn commented Mar 23, 2026

Copy link
Copy Markdown
Owner

Make v3.4.0 the minimum required version for both scripts and simplify the code of key-bindings.fish.

Let's go with this. I can't imagine someone installing the latest version of fzf while still being stuck on a 4-year-old version of fish. We should mention it on the CHANGELOG though.

@bitraid

bitraid commented Mar 23, 2026

Copy link
Copy Markdown
Collaborator Author

Option 1

  • fzf_complete - The new, simpler API designed for ease of use
  • _fzf_complete - A compatibility shim aligned with the bash/zsh style for backward compatibility (i.e. fzf args + -- + mandatory $argv)

Good idea, lets do that.

Make v3.4.0 the minimum required version for both scripts and simplify the code of key-bindings.fish.

Let's go with this. I can't imagine someone installing the latest version of fzf while still being stuck on a 4-year-old version of fish. We should mention it on the CHANGELOG though.

Great, now there are more commands and more command options available, as well as the command substitution syntax $() which can be used inside double quotes.

I might delay the changes a little because one of my dogs thew my laptop off the desk and now is dead (the laptop not the dog!).

@junegunn

Copy link
Copy Markdown
Owner

No rush, just wondering if this is close to landing so I can decide whether to put out a quick patch for #4737 in the meantime and make a new fzf release without this.

@bitraid

bitraid commented Mar 29, 2026

Copy link
Copy Markdown
Collaborator Author

I found some issues with commandline and complete when the current token is split by a line break or has newlines inside quotes. I've been trying some workarounds and I think I have a solution that works good enough. I will probably push it later today (I need to test it a little more).

In case that this doesn't make it to the new release, the patch below fixes #4737 for the current script:

diff --git a/shell/completion.fish b/shell/completion.fish
index a1281c31..d9c74b79 100644
--- a/shell/completion.fish
+++ b/shell/completion.fish
@@ -214,6 +214,12 @@ function fzf_completion_setup
 
   # Main completion function
   function fzf-completion
+    # Restore the default shift-tab behavior on tab completions
+    if commandline --paging-mode
+      commandline -f complete-and-search
+      return
+    end
+
     set -l -- tokens (__fzf_cmd_tokens)
     set -l -- current_token (commandline -t)
     set -l -- cmd_name $tokens[1]

@junegunn

Copy link
Copy Markdown
Owner

I see, thanks! If this can be completed within a week, I'd like to wait and include it in the next release.

@bitraid

bitraid commented Mar 29, 2026

Copy link
Copy Markdown
Collaborator Author

OK, good. I'll push the changes tomorrow (Monday) then - I'll try to fix an edge case where there is still an issue.

@bitraid bitraid force-pushed the fish-complete branch 2 times, most recently from 6d86afc to 0805e51 Compare March 30, 2026 15:32
@bitraid

bitraid commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator Author

I pushed the changes - please test.

@bitraid bitraid force-pushed the fish-complete branch 2 times, most recently from f7c0f4e to 9437db0 Compare March 31, 2026 09:33
@junegunn

junegunn commented Mar 31, 2026

Copy link
Copy Markdown
Owner

Thanks! I ran some basic tests and everything worked as expected.

  • The shift-tab bug has been fixed.
  • The examples in the current README all work as before. Great!
  • The description part is no longer dimmed. Is this intended? To be clear, I don't have a strong opinion on the style.

And could you elaborate a bit more on$FZF_EXPANSION_OPTS? I read your explanation in the PR description, but I'm having trouble understanding it. How do you expect users to make use of it in practice? Could you share a few concrete examples?

@bitraid

bitraid commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator Author

The description part is no longer dimmed. Is this intended?

The intention is for the descriptions to be searchable (and unless there is an option that I'm not aware of, it is not possible to dim the field), which I think is more useful, don't you agree?

And could you elaborate a bit more on $FZF_EXPANSION_OPTS?

The $FZF_EXPANSION_OPTS sets the options for when searching expansion lists (the command line token is a wildcard pattern). The main reason is that the filenames in completion lists are escaped (I explain the reason in the PR description) and they belong to the first field (filenames can also have descriptions - for example in git add it displays if a file is modified or untracked). So, to set a preview for example, the option should be --preview="test -f {r1}; and bat -- {r1}", while for expansion lists would be --preview="test -f {}; and bat -- {}. We could have only $FZF_COMPLETION_OPTS, if the files in expansion lists were also escaped (or the files in completion lists were unescaped, but that would have the drawbacks I mention in the PR description), and also have --delimiter=\x00 to the default expansion list options, so that in both cases {r1} would work. Let me know if you prefer that, or if you have a better idea.

@junegunn

Copy link
Copy Markdown
Owner

I see. I wasn't familiar with the term "expansion list", but I suppose fish users would know it. Sounds fine to me. By the way, this doesn't seem to work. Could you take a look?

touch 'foo " bar'

git add <shift-tab>
  # git add \"foo\ \\\"\ bar\"
  # fatal: pathspec '"foo \" bar"' did not match any files

@bitraid

bitraid commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator Author

I see. I wasn't familiar with the term "expansion list", but I suppose fish users would know it. Sounds fine to me. By the way, this doesn't seem to work. Could you take a look?

touch 'foo " bar'

git add <shift-tab>
  # git add \"foo\ \\\"\ bar\"
  # fatal: pathspec '"foo \" bar"' did not match any files

This is an issue with the fish completion function of git. You will notice you get the same result with <tab>.

@junegunn

Copy link
Copy Markdown
Owner

You will notice you get the same result with <tab>.

Ha, you're right!

Anything else to decide? If not, we should update the README and CHANGELOG.

@bitraid

bitraid commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator Author

Anything else to decide?

I can't think of anything else. I just forgot to mention a couple of changes with the last commit (maybe worth mentioning in README):

  • The tabstop value can be set by $FZF_COMPLETION_OPTS or passed by custom functions to set the minimum starting position of descriptions.
  • The custom post completion function names can be either _fzf_complete_COMMAND_post or _fzf_post_complete_COMMAND, with the latter having precedence (so that the post completion function of foo won't collide with the completion function of foo_post).

If not, we should update the README and CHANGELOG.

Should I update the README in this PR, or do you prefer to make the changes yourself in master?

@junegunn

Copy link
Copy Markdown
Owner
  • The custom post completion function names can be either _fzf_complete_COMMAND_post or _fzf_post_complete_COMMAND

Yeah, that's a good strategy. We could adopt it in bash and zsh as well in the future, though I wouldn't worry too much about it in practice.

Should I update the README in this PR, or do you prefer to make the changes yourself in master?

Could you update here? I'll make the final edit when I merge your changes from devel to master. Thanks.

@github-actions github-actions Bot added the docs Documentation label Apr 1, 2026
@bitraid

bitraid commented Apr 1, 2026

Copy link
Copy Markdown
Collaborator Author

Sorry for taking so long - there was an issue with the arguments passed to custom functions (it is now fixed).
Please let me know if the information in the README is missing something or needs any changes.

Comment thread README.md Outdated
@junegunn

junegunn commented Apr 2, 2026

Copy link
Copy Markdown
Owner

Thanks! Would you like to add an entry to the CHANGELOG.md as well? I think we should at least mention that the new version requirement of 3.4.0.

@bitraid

bitraid commented Apr 2, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks! Would you like to add an entry to the CHANGELOG.md as well? I think we should at least mention that the new version requirement of 3.4.0.

Done.

Comment thread README.md
@junegunn junegunn merged commit 96835ca into junegunn:devel Apr 2, 2026
4 checks passed
@junegunn

junegunn commented Apr 2, 2026

Copy link
Copy Markdown
Owner

Thanks a lot! Merged to devel branch. I'll release a new version with your work this weekend.

@bitraid bitraid deleted the fish-complete branch April 2, 2026 16:10
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Apr 8, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [junegunn/fzf](https://github.com/junegunn/fzf) | minor | `v0.70.0` → `v0.71.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>junegunn/fzf (junegunn/fzf)</summary>

### [`v0.71.0`](https://github.com/junegunn/fzf/releases/tag/v0.71.0): 0.71.0

[Compare Source](junegunn/fzf@v0.70.0...v0.71.0)

*Release highlights: <https://junegunn.github.io/fzf/releases/0.71.0/>*

- Added `--popup` as a new name for `--tmux` with Zellij support
  - `--popup` starts fzf in a tmux popup or a Zellij floating pane
  - `--tmux` is now an alias for `--popup`
  - Requires tmux 3.3+ or Zellij 0.44+
- Cross-reload item identity with `--id-nth`
  - Added `--id-nth=NTH` to define item identity fields for cross-reload operations
  - When a `reload` is triggered with tracking enabled, fzf searches for the tracked item by its identity fields in the new list.
    - `--track --id-nth ..` tracks by the entire line
    - `--track --id-nth 1` tracks by the first field
    - `--track` without `--id-nth` retains the existing index-based tracking behavior
    - The UI is temporarily blocked (prompt dimmed, input disabled) until the item is found or loading completes.
      - Press `Escape` or `Ctrl-C` to cancel the blocked state without quitting
      - Info line shows `+T*` / `+t*` while searching
  - With `--multi`, selected items are preserved across `reload-sync` by matching their identity fields
- Performance improvements
  - The search performance now scales linearly with the number of CPU cores, as we dropped static partitioning to allow better load balancing across threads.
    ```
    === query: 'linux' ===
      [all]   baseline:    21.95ms  current:    17.47ms  (1.26x)  matches: 179966 (12.79%)
      [1T]    baseline:   179.63ms  current:   180.53ms  (1.00x)  matches: 179966 (12.79%)
      [2T]    baseline:    97.38ms  current:    90.05ms  (1.08x)  matches: 179966 (12.79%)
      [4T]    baseline:    53.83ms  current:    44.77ms  (1.20x)  matches: 179966 (12.79%)
      [8T]    baseline:    41.66ms  current:    22.58ms  (1.84x)  matches: 179966 (12.79%)
    ```
  - Improved the cache structure, reducing memory footprint per entry by 86x.
    - With the reduced per-entry cost, the cache now has broader coverage.
- Shell integration improvements
  - bash: CTRL-R now supports multi-select and `shift-delete` to delete history entries ([#&#8203;4715](junegunn/fzf#4715))
  - fish:
    - Improved command history (CTRL-R) ([#&#8203;4703](junegunn/fzf#4703)) ([@&#8203;bitraid](https://github.com/bitraid))
    - Rewrite completion script (SHIFT-TAB) ([#&#8203;4731](junegunn/fzf#4731)) ([@&#8203;bitraid](https://github.com/bitraid))
    - Increase minimum fish version requirement to 3.4.0 ([#&#8203;4731](junegunn/fzf#4731)) ([@&#8203;bitraid](https://github.com/bitraid))
- `GET /` HTTP endpoint now includes `positions` field in each match entry, providing the indices of matched characters for external highlighting ([#&#8203;4726](junegunn/fzf#4726))
- Allow adaptive height with negative value (`--height=~-HEIGHT`) ([#&#8203;4682](junegunn/fzf#4682))
- Bug fixes
  - `--walker=follow` no longer follows symlinks whose target is an ancestor of the walker root, avoiding severe resource exhaustion when a symlink points outside the tree (e.g. Wine's `z:` → `/`) ([#&#8203;4710](junegunn/fzf#4710))
  - Fixed AWK tokenizer not treating a new line character as whitespace
  - Fixed `--{accept,with}-nth` removing trailing whitespaces with a non-default `--delimiter`
  - Fixed OSC8 hyperlinks being mangled when the URL contains unicode characters ([#&#8203;4707](junegunn/fzf#4707))
  - Fixed `--with-shell` not handling quoted arguments correctly ([#&#8203;4709](junegunn/fzf#4709))
  - Fixed child processes not being terminated on Windows ([#&#8203;4723](junegunn/fzf#4723)) ([@&#8203;pjeby](https://github.com/pjeby))
  - Fixed preview scrollbar not rendered after `toggle-preview`
  - Fixed preview follow/scroll with long wrapped lines
  - Fixed tab width when `--frozen-left` is used
  - Fixed preview mouse events being processed when no preview window exists
  - zsh: Fixed history widget when `sh_glob` option is on ([#&#8203;4714](junegunn/fzf#4714)) ([@&#8203;EvanHahn](https://github.com/EvanHahn))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDQuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwNC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
@llakala

llakala commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

I think it is not correct for the current token to automatically become the fzf query on startup. The generated list is already based upon the token, and having the token also as the query modifies the natural order (as listed by tab) of the results and gives the wrong impression that by deleting the query the whole list is going to be displayed.

I've been getting much worse completions as a result of this change. When I type git l and complete:
image
Then only things starting with l show up, but because l isn't autofilled into my search results, when I type o, log doesn't appear first anymroe.
image
While I understand the intentions of this change, I think it's going to result in a degraded experience for most users.

@bitraid

bitraid commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator Author

This is not the reason that log is no longer the first item after you enter o, but because now it is possible to also search the descriptions. To restore the previous behavior of applying the search on options only, set:

set -gx FZF_COMPLETION_OPTS '--nth=1'

@bitraid

bitraid commented Apr 8, 2026

Copy link
Copy Markdown
Collaborator Author

Alternatively, if you want to keep the descriptions search and mimic the native shift-tab behavior, set the --no-sort option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation fish Fish shell install Install/uninstall scripts shell Shell scripts test Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants