Bash – ignore case but disallow autocomplete if ambiguous

autocompletebashcase sensitivityinputrc

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 ?

Best Answer

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