zimfw: Tab completion incorrectly completes the wrong file when starting with the end of the filename

Please check the existing issues to make sure you’re not duplicating a report.

For bug reports, please provide the following information:

In a terminal, run zmanage info and paste the output below:

$ zmanage info
zsh: command not found: zmanage

But I’m running the zim master via Arch Linux AUR’s zsh-zim-git: 9eaba9a

  • gist of .zimrc: zmodules=(completion)
  • gist of .zshrc: source /usr/lib/zim/init.zsh

Description

Tab completion incorrectly fully completes the wrong file when starting with the end of the filename.

Steps to reproduce

Tab completion works fine if starting from the start of the filename.

$ touch foo-bar foo-baz-bar
$ touch f<tab>
$ touch foo-ba<tab>
 -- file --
foo-bar      foo-baz-bar

However, if I start typing from the back (or middle) of the filename, it fails.

$ touch bar<tab>
$ touch foo-bar<tab>
           ^ cursor here
$ touch foo-bar
                ^ cursor here

I would expect the second tab to bring up the completion-selection menu. However, it immediately completes to the shorter version instead.

Another slightly different case is if I type the entirety of the shared string.

$ touch -bar<tab>
$ touch foo-bar
                ^ cursor here

In this case, I’m not even given the cursor in the middle, it jumps straight to the end.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 54 (31 by maintainers)

Commits related to this issue

Most upvoted comments

Wow, cheers @ericbn and @protist. What a trip.

@protist, the partial completion to -bar (instead of foo-bar with the cursor in the middle) is actually what I think solves the main issue – that is not having the completion menu (because there’s a file that is named foo-bar). I also think it’s a simpler behavior than having the completion from both sides at the same time, so I like it. :- )

I get all kinds of different completions depending of the OS or zsh version I’m in. I just classified as “Bad” when I don’t get the completion menu, and “Good” when I do get it (no matter how many <kbd>tab</kbd>s I have to press).

@protist, I get mixed results depending on if I try to complete from touch bar<tab> or vi bar<tab>, and if I’m on Mac or PC:

Given we’re on an empty directory and then touch foo-bar foo-something-bar.

zstyle touch bar<tab> vi bar<tab>
'r:|=*' 'l:|=* r:|=*' Good on Mac, Bad on PC Good on Mac and PC
'r:|=*' '+l:|=*' Good on Mac, Bad on PC Good on Mac and PC
'm:{a-zA-Z}={A-Za-z} r:|=*' '+l:|=*' Bad on Mac and PC Good on Mac and PC

By “Good” I mean offering both files in the completion menu. By “Bad” I mean completing to foo-bar without showing the completion menu.

Tried with zsh 5.3 and zsh 5.5.1 running on MacOS 10.13.4 (Mac), and zsh 5.4.2 running on Ubuntu 16.04.3 on Linux Subsystem for Windows (PC).

Can you maybe make this configurable?

@edwardsmit You can just put the relevant zstyle line in your zshrc, after the zim initiation, of course. Only the last definition is used. (You can check this with zstyle -L | grep matcher.)

@ericbn I’ve actually lost track a bit of which configs we’ve tried before. I tested the suggestions in a new directory after touch foo-bar foo-something-bar, and basically tried to break each one. 😬 My bullet points correspond with each bullet point of code from your last comment, in the same order.

  • touch bar<TAB> does nothing.
  • touch f-b<TAB> does nothing. (Also, oddly enough touch bar<TAB> completed to -bar for me with my two files, whereas with the two files you mention, I get the same behaviour as you.)
  • This one seemed the most robust, but it’s liberalness can obviously be a little off-putting at time. Also, I could finally make it break with foo-bar and foo-baz-bar as follows:
$ touch bar<tab>
$ touch or-bar<tab>
        ^ cursor moves here
$ touch or-bar
              ^ cursor moves here
-- no matches found --

(Actually, this fails similarly to some other code previously in this thread.)

@protist, yeah. It works when we remove one of these two:

but it gets weird when we have both. And both are important I think… :- /

@AtomicCoding I don’t think you are testing the same thing, but it’s hard to tell without knowing your directory’s contents. In your example, create another file called mafoobarin.py first, then try the tab completion of in.py again, pressing tab twice. It will only auto-complete main.py. That’s what this issue is referring to.

@protist, thanks for the feedback. Good point, I agree the partial completions are a nice to have. Both options I proposed were getting rid of them.

Not having partial completions fixes some of issues here, since the completion system won’t have to pick up from those partial completions. If only we could make them cleaner.

Thanks @ericbn. Nice find. I tested the patch, and it does indeed fix that latest issue.

Thanks @ericbn! Tested and works well. I went through the same testing above, and it all works as expected. Thank you for persisting and well done on fixing this!

@ericbn asciicast Works for me!

I think this still needs to be fixed, and that the current configuration we have is not good enough.

@ericbn Works for me. Tested on a fresh Zim install on Ubuntu and on my installation.

I haven’t really noticed anything annoying yet personally, but I think I probably agree with you conceptually. Presumably, if you have barty and foobar in a directory, then typing bar or even b should complete to the former. That does make sense to me.

Thank you @ericbn. That commit works perfectly! Now the behaviour is as follows.

$ touch bar<tab>
$ touch foo-bar<tab>
              ^ cursor here
$ touch foo-bar
              ^ cursor here
-- file --
foo-bar      foo-baz-bar

And a subsequent tab can select from the menu. This is great, and no longer automatically completes. Just for the record, the cursor position was slightly unintuitive at first. Previously, it was at the -, and now it’s at the r. The latter is the first ambiguous character, so it makes sense. I guess previously zsh considered - to act more as a word break, but now I think about it, the current behaviour makes more sense to me. I think it’s better like this, agnostic of what a “word” is.

Thanks again!