With the grep command, I tend to use various combinations of -irln and restrict it to include one or more of the same file types py, js, html, css.


grep -ril --include=*{html,css}

I'm defining a suite of aliases for various permutations of grep which I use in the following format:


I generate the alias file with a python script which iterates over combinations of options and generates around 100 aliases in this case. Here are some of them:

alias grep.il.html-css='grep -ril --include=*{html,css}'
alias grep.il.html-css='grep -ril --include=*{html,css}'
alias grep.il.html-js='grep -ril --include=*{html,js}'
alias grep.iln.html-js-css='grep -riln --include=*{html,js,css}'

(they also all exclude the node_modules dir. I hid that for brevity, but now you know why I want these aliases!)

The reason I use full stops is because thanks to completion, it feels almost like typing properties on objects in an IDE, but not quite, and that's what I need help with.

The tab key attempts to select the first complete command it finds. I want it to cycle through the options up until the full stop (in the current namespace if you like).

Currently (untouched Mint/Ubuntu/Debian bash defaults) if I type this:


And hit tab, it goes straight to:


Whereas I would like it not to do that, but to cycle through the options available up until the next full stop first:


And when I hit . it selects that option, after which tab would then cycle through the options available from off there, such as:


Is this possible? Advisable?

I'm using bash, would consider moving to zshell if that's the only way.


I can improve this situation with a little hack, which is to create a stub alias for every intermediate alias, so in the above example:

alias grep.='echo stub'
alias grep.il.='echo stub'

This stops on the full stop, but completion adds a space after so I end up with:

"grep. "

at the terminal. I can still tab to cycle through the options, but need to backspace before I start typing else I get:

"grep. i"

I've looked at the option of creating custom autocompletion behaviour making it not add a space after commands which have a . in them, but that catches files too (e.g. it would mess up main.py hello) I'll keep digging...

  • really you need to have a function instead of tens of aliases. to reply for last update to avoid adding space try change completion of the command to complete -o nospace -F _longopt grep Commented Feb 10, 2020 at 16:16
  • Having tens of aliases instead of a function is exactly what I'm trying to achieve. As for the nospace I am unable to get that working. I've tried permutations of complete -o nospace less and compopt +o nospace less on less and other commands and it still always adds a space.
    – andyhasit
    Commented Feb 10, 2020 at 17:32
  • @αғsнιη the question you linked to seems to be about adding spaced after arguments, and doesn't seem to work for the initial command/alias itself.
    – andyhasit
    Commented Feb 10, 2020 at 18:09
  • I tried this with a clean install of Zsh and it works for me. Do you perhaps have some options or styles set that mess this up? Commented May 21, 2020 at 0:08

1 Answer 1


This is how you can make it work in zsh:

autoload -Uz compinit && compinit
bindkey '^I' complete-word

zle -C complete-word complete-word complete-word
complete-word() {
  (( compstate[unambiguous_cursor] > ${#:-$PREFIX$SUFFIX}+1 )) \
  && compstate[insert]='automenu-unambiguous'
  compstate[list]='list force'

zstyle ':completion:*:complete:*' show-ambiguity '07'

Then, when you type grep and press tab, you get: grep+tab You can then keep pressing tab to cycle through the shown completions: tab again to cycle Or you can type one of the highlighted characters and press tab again to insert the next set of characters that is common to the listed completions: or press highlighted char + tab Then press tab again to show a new completion list: tab again, rinse and repeat Etc., etc., etc. Lather, rinse and repeat.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .