4

Recently i face inconvenient when using bash auto complete with ignore case.

Let's say i have this directories:

[xiaobai@xiaobai test]$ l
total 20K
3407873 drwx------. 60 xiaobai xiaobai 4.0K May 25 17:17 ../
3409017 drwxrwxr-x.  2 xiaobai xiaobai 4.0K May 25 17:35 hello/
3681826 drwxrwxr-x.  2 xiaobai xiaobai 4.0K May 25 17:55 Hello_STACKOVERFLOW/
3681837 drwxrwxr-x.  2 xiaobai xiaobai 4.0K May 25 17:55 Hello_StackOverflow/
3412549 drwxrwxr-x.  5 xiaobai xiaobai 4.0K May 25 17:56 ./
[xiaobai@xiaobai test]$

then cd h[Tab]:

[xiaobai@xiaobai test]$ cd h #and press [Tab]
hello/               Hello_StackOverflow/ Hello_STACKOVERFLOW/ 
[xiaobai@xiaobai test]$ cd hello #auto generate

You will notice the new command prompt come with auto complete 'hello' while there's alternative 'Hello' exist. But here i have no problem because i can either insert / OR press [Enter] to go inside hello/. Or i can insert underscore _ and press [Tab] to go further Hello_*:

[xiaobai@xiaobai test]$ cd hello_ #and press [Tab]
Hello_StackOverflow/ Hello_STACKOVERFLOW/ 
[xiaobai@xiaobai test]$ cd Hello_StackOverflow #auto generate

Now the problem become obvious, what if my target was 'Hello_STACKOVERFLOW/' ? I have to press Back Space to delete 'tackOverflow' and then insert T+[Tab] to reach my target.

What i want is:

[xiaobai@xiaobai test]$ cd hello_ #and press [Tab]
Hello_StackOverflow/ Hello_STACKOVERFLOW/ 
[xiaobai@xiaobai test]$ cd Hello_S #without 'tackOverflow', so i just have to type T+[Tab] without redundant erase step.

Of course it wouldn't have such problem if completion-ignore-case off on my inputrc file. But i like to ignore case but avoid auto complete when ambiguous. Is it possible to do that ?

  • 2
    This might be too advanced for bash. I know zsh can do it (via matcher-list). – Gilles May 25 '15 at 18:50
2

There is a workaround for your problem.

Try:

bind 'set completion-ignore-case on'
bind 'TAB:menu-complete'
bind 'set menu-complete-display-prefix on'
bind 'set show-all-if-ambiguous on'

Type cd h,Tab. Line expands to cd hello.

Then type _, Tab. Line expands to cd Hello_StackOverflow

Press Tab,Tab. Line expands to cd Hello_STACKOVERFLOW/

Explanation:

menu-complete Similar to complete, but replaces the word to be completed with a single match from the list of possible completions. Repeated execution of menu-complete steps through the list of possible completions, inserting each match in turn. At the end of the list of completions, the bell is rung (subject to the setting of bell-style) and the original text is restored. Thiscommand is intended to be bound to TAB, but is unbound by default.

Available since bash-2.02-alpha1

menu-complete-display-prefix If set to On, menu completion displays the common prefix of the list of possible completions (which may be empty) before cycling through the list.

Available since bash-4.2-alpha

show-all-if-ambiguous This alters the default behavior of the completion functions. If set to On, words which have more than one possible completion cause the matches to be listed immediately instead of ringing the bell.

Work together with menu-complete-display-prefix since bash-4.3-alpha

  • Amazing workaround. Nota that the last step [Tab] will keep exchange between the candidates. I have to press dummy key like arrow key to choose(take effect) in order to make [Tab] continue to expand its content. When no trailing slash appear, just type '/' instead of arrow key to continue expand its content. – 林果皞 Jul 22 '15 at 7:36
0

I found the best option for me was simply adding

bind 'set menu-complete-display-prefix on'

to .inputrc.

First tab will complete the unambiguous prefix. The second tab will list all the remaining ambiguous options. Type your characters and a third tab will complete your command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.