Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FZF_COMPLETION_AUTO_COMMON_PREFIX_PART fails on filenames with spaces in Bash #91

Open
erhhung opened this issue Feb 7, 2024 · 9 comments

Comments

@erhhung
Copy link

erhhung commented Feb 7, 2024

First, I'm using the standard setup in my ~/.bashrc:

[ -f $HOME/.fzf.bash_completion ] && \
   . $HOME/.fzf.bash_completion
bind -x '"\t": fzf_bash_completion'

export FZF_COMPLETION_AUTO_COMMON_PREFIX=true
# enable common prefix completion
# following standard Bash behavior
export FZF_COMPLETION_AUTO_COMMON_PREFIX_PART=true

Let's assume we have these files in a directory:

drwxrwxr-x  2 erhhung 4096 2024-02-06 17:00  ./
drwxrwxrwt 14 root    4096 2024-02-06 17:00  ../
-rw-rw-r--  1 erhhung    5 2024-02-06 17:00 'bar baz fred.txt'
-rw-rw-r--  1 erhhung    5 2024-02-06 17:00 'baz qux fred.txt'
-rw-rw-r--  1 erhhung    5 2024-02-06 17:00 'foo bar baz.txt'
-rw-rw-r--  1 erhhung    5 2024-02-06 17:00 'foo baz qux.txt'
-rw-rw-r--  1 erhhung    5 2024-02-06 17:00  qux_bar_baz.txt
-rw-rw-r--  1 erhhung    5 2024-02-06 17:00  qux_baz_foo.txt

Here are some scenarios, with the second illustrating the problem:

  1. $ less bar<tab>
    This works fine as there's only one match.
    $ less bar\ baz\ fred.txt (cursor after trailing space)

  2. $ less foo<tab>
    Initial completion to common prefix works fine.
    $ less foo\ ba(cursor right after a)

    $ less foo\ ba<tab>
    I'd would expect to see a popup with two choices, but the current partial
    command just repeats on a new line after the loading message flashes.

    $ less foo\ ba(cursor still right after a)

    Now delete a character, then hit tab, and repeat...
    $ less foo\ b<tab>
    Same as above: existing partial command repeats.
    $ less foo\ b(cursor still right after b)

    $ less foo\ <tab> (cursor right after escaped space)
    Hey, a popup! But I see all filenames instead of foo*.

    ╭─────────────────────────────╮
    │ > less foo\ ▆           6/6 │
    │ ▶ bar\ baz\ fred.txt        │
    │   baz\ qux\ fred.txt        │
    │   foo\ bar\ baz.txt         │
    │   foo\ baz\ qux.txt         │
    │   qux_baz_foo.txt           │
    │   qux_bar_baz.txt           │

    If I choose foo\ bar\ baz.txt from the list and hit Enter, the
    entire filename gets appended instead of completed to prefix,
    and the completed prompt line is repeated on a separate line.

    $ less foo\
    $ less foo\ foo\ bar\ baz.txt (cursor after trailing space)

  3. $ less qux<tab>
    Initial completion to common prefix works fine.
    $ less qux_ba(cursor right after a)

    $ less qux_ba<tab>
    Popup appears with filtered choices, as expected!

    ╭─────────────────────────────╮
    │ > less qux_ba▆          2/2 │
    │ ▶ qux_baz_foo.txt           │
    │   qux_bar_baz.txt           │

    If I choose a file from the list and hit Enter, name completion works fine—on the same line.
    $ less qux_baz_foo.txt (cursor after trailing space)

  4. $ unset FZF_COMPLETION_AUTO_COMMON_PREFIX_PART

    $ less foo<tab>
    Without partial common prefix completion, popup appears.

    ╭─────────────────────────────╮
    │ > less foo▆             2/2 │
    │ ▶ foo\ bar\ baz.txt         │
    │   foo\ baz\ qux.txt         │

    Again, name completion works as expected—on the same line.
    $ less foo\ bar\ baz.txt (cursor after trailing space)

@d-enk
Copy link
Contributor

d-enk commented Feb 7, 2024

When I made this functionality, I added a partial completion solely for some kind of compatibility of native behavior. In practice, I never used it myself, so I never ran into a problem. Just wondering why you need it. Basically, it just forces you to press Tab 2 times. Just got used to it?

@erhhung
Copy link
Author

erhhung commented Feb 8, 2024

It's often that one has files named with a common base followed by a digit, like:

  • foo_bar_baz1.txt
  • foo_bar_baz2.txt
  • foo_bar_baz8.txt
  • foo_bar_baz9.txt
  • foo_bar_baz_qux.txt

So when I type less foo<tab>, I'd like to first see less foo_bar_baz partially completed, and then I can simply type 8 and hit tab again to do the full completion if I knew the exact number I need, instead of having to navigate down a possibly long list.

If I actually wanted to search for a foo* file containing qux from a popup, then I'd just hit tab twice.

@d-enk
Copy link
Contributor

d-enk commented Feb 9, 2024

The problem comes here

compgen "${compgen_opts[@]}" -- "$2" \

the next call fails
compgen -o bashdefault -o default -- "foo\ ba"

intuitive fix
compgen "${compgen_opts[@]}" -- "${2//\\/}"

partially correct the situation, but there are arises other problems with escaping
I think @lincheney will be able to get into it easier

@overtomanu
Copy link

overtomanu commented Mar 13, 2024

I had faced similar issue and I had reported it for fzf.
cd to sub directory of directory with spaces does not work as slash gets removed

@overtomanu
Copy link

Reported another issue for this repo as well

#96

@lincheney
Copy link
Owner

I've made a number of changes b8e7133...32fd637
which I think fixes this issue, but it will need a bit of testing.

@erhhung
Copy link
Author

erhhung commented May 2, 2024

@lincheney Thanks for the fix! I've used it for a little while now and saw no more issues.
I have so many files with spaces in their names that it has been driving me nuts...

@erhhung erhhung closed this as completed May 2, 2024
@overtomanu
Copy link

@lincheney Thanks. I just tested it and didn't see the issue.

@erhhung erhhung reopened this Sep 6, 2024
@erhhung
Copy link
Author

erhhung commented Sep 6, 2024

As a "prolific" user of the FZF_COMPLETION_AUTO_COMMON_PREFIX option, I've, unfortunately, found another common scenario—for me, at least—where tab completion of filenames containing spaces hasn't been fixed by @lincheney's previous fix.

The unfixed issue has the same behavior as described above, except that the path typed prior to hitting <tab> contains a relative or absolute path, e.g. less /tmp/fzf/foo\ ba<tab>.

Here's a quick one-liner to create the same test files as above under /tmp/fzf:

mkdir -p /tmp/fzf && (cd /tmp/fzf; echo > 'bar baz fred.txt'; echo > 'baz qux fred.txt'; echo > 'foo bar baz.txt'; echo > 'foo baz qux.txt'; echo > qux_bar_baz.txt; echo > qux_baz_foo.txt) && ls -al /tmp/fzf

Reiterating scenario 2 from the original issue description:

  1. $ cd /tmp/fzf
    $ less foo<tab>
    Initial completion to common prefix works fine.
    $ less foo\ ba(cursor right after a)

    $ less foo\ ba<tab>
    Popup with two choices appear, as expected (this issue as originally reported has been fixed)

    $ cd /tmp
    $ less fzf/foo<tab>
    Initial completion to common prefix works fine.
    $ less fzf/foo\ ba(cursor right after a)

    $ less fzf/foo\ ba<tab>
    I'd would expect to see a popup with two choices, but the current partial
    command just repeats on a new line after the loading message flashes.

    $ less fzf/foo\ ba(cursor still right after a)

@lincheney I would be grateful if you could revisit the previous fix you've made on this issue, and see if you can have the completion code handle path components in the completion text. In my actual usage, I do a lot of completions of the form: less ~/dir/foo\ bar<tab>, which should be the same as any relative/absolute path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants