fzf-tab-completion icon indicating copy to clipboard operation
fzf-tab-completion copied to clipboard

FZF_COMPLETION_AUTO_COMMON_PREFIX_PART fails on filenames with spaces in Bash

Open erhhung opened this issue 1 year ago • 9 comments

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)

erhhung avatar Feb 07 '24 02:02 erhhung

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?

d-enk avatar Feb 07 '24 08:02 d-enk

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.

erhhung avatar Feb 08 '24 00:02 erhhung

The problem comes here

https://github.com/lincheney/fzf-tab-completion/blob/9bcc7098f79510765b9f539118dd92a2366ec992/bash/fzf-bash-completion.sh#L475

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

d-enk avatar Feb 09 '24 18:02 d-enk

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 avatar Mar 13 '24 15:03 overtomanu

Reported another issue for this repo as well

https://github.com/lincheney/fzf-tab-completion/issues/96

overtomanu avatar Mar 14 '24 09:03 overtomanu

I've made a number of changes https://github.com/lincheney/fzf-tab-completion/compare/b8e71337d3a78a67f858f0fcbc4193aff5cb0720...32fd6371a6e266c2c10239690e5d93a583c3c5e4 which I think fixes this issue, but it will need a bit of testing.

lincheney avatar Apr 24 '24 04:04 lincheney

@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 avatar May 02 '24 20:05 erhhung

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

overtomanu avatar May 03 '24 11:05 overtomanu