Select multiple zsh completions item

# ^Xa to insert all matches
zle -C all-matches complete-word _generic
bindkey '^Xa' all-matches
zstyle ':completion:all-matches:*' old-matches only
zstyle ':completion:all-matches::::' completer _all_matches

UPDATE: The snippet above brings insert-completions to zsh. Thanks, Trevor Joynson, who has provided the solution in comment.

Command insert-completions (see man bash) is the feature I most miss in bash.

[insert-completions] Insert all completions of the text before point that would have been generated by possible-completions.

Its default binding is M-*, a.k.a, Alt-Shift-8 or Meta-Shift-8.

It is useful for simple batch operations, such as removing all git branches starting with feature/.

After I switched to zsh, I have been looking for a similar command, but for no results. However, I just discovered the zsh way to select multiple completions recently, using accept-and-hold (see man zshzle).

[accept-and-hold] Push the contents of the buffer on the buffer stack and execute it.

The default binding is M-a (a.k.a, Alt-a or Meta-a). If the command line has input content ls, M-a executes the line ls without clearing the input.

It seems unrelated. But if completion menu is activated and a menu item is selected (the simplest way is Tab twice), accept-and-hold accepts the current menu item without closing completing menu. So it is possible to select multiple items by navigating to wanted items, and type M-a to select them.

Bash Sample to delete git branches

  1. First enter following text.

    $ git branch -D feature/
    
  2. Type Tab to activate completion.

    $ git branch -D feature/
    feature/a feature/b
    
  3. Type M-* to insert all completions.

    $ git branch -D feature/a feature/b
    
  4. Review, delete branches should be keep.

  5. Type Enter to execute the line.

Zsh way

  1. First enter following text.

    $ git branch -D feature/
    
  2. Type Tab to activate completion.

    $ git branch -D feature/
    feature/a feature/b
    
  3. Type Tab again, to select first item. Brackets demonstrate which item is currently selected.

    $ git branch -D feature/a
    [feature/a] feature/b
    
  4. Type M-a to keep selected item and continue completing

    $ git branch -D feature/a feature/b 
    feature/a [feature/b]
    
  5. Use Tab to skip branches that should be keep. The item selection mode also supports C-n, C-p, C-f, C-b to move around, and C-s, C-r to search.

  6. When cursor is on the last branch to be deleted, type Enter to accept it and stop completion. If M-a is typed by accident, you have to delete the last inserted completion item, because zsh auto inserts current selected item.

Discover zsh commands

The builtin bindkey lists all commands with key-bindings. They are most frequently used commands, that’s why they deserve a key-binding.

The commands reference can be looked up in man zshzle. I also discovered several other interesting key-bindings:

  • M-h Run man on current entered command. Say you are editing tcpdump options, and want to check manual without losing the input.
  • M-? Run which-command on current entered command.
comments powered by Disqus