# Autocomplete for Zsh This plugin for Zsh adds real-time type-ahead autocompletion to your command line, similar to what you find in desktop apps. While you type on the command line, available completions are listed automatically; no need to press any keyboard shortcuts. Press Tab to insert the top completion or to select a different one. Additional features: * Out-of-the-box configuration of Zsh's completion system * Multi-line history search * Completion of recent directories * Useful [keyboard shortcuts](#keyboard-shortcuts) * Easy to [configure](#configuration) > Enjoy using this software? [Become a sponsor!](https://github.com/sponsors/marlonrichert) 💝 ## Requirements Recommended: * Tested to work with [Zsh](http://zsh.sourceforge.net) 5.8 and newer. Minimum: * Should theoretically work with Zsh 5.4, but I'm unable to test that. ## Installation & setup > Note: In this manual, `%` represents the command line prompt. If you see it in front of a command, > it means you should run it on the command line, not put it in a script. First, install Autocomplete itself. Here are some way to do so: * To use only releases (instead of the `main` branch), install `zsh-autocomplete` with a package manager. As of this writing, this package is available through Homebrew, Nix, `pacman`, Plumage, and (as `app-shells/zsh-autocomplete`) Portage. * To always use the latest commit on the `main` branch, do one of the following: * Install the AUR package [zsh-autocomplete-git](https://aur.archlinux.org/packages/zsh-autocomplete-git)AUR from the Arch User Repository (for example, using [yay](https://github.com/Jguer/yay), an AUR helper): ```sh yay -S zsh-autocomplete-git ``` * Use a Zsh plugin manager to install `marlonrichert/zsh-autocomplete`. (If you don't have a plugin manager yet, I recommend using [Znap](https://github.com/marlonrichert/zsh-snap).) * Clone the repo directly: ```sh % git clone --depth 1 -- https://github.com/marlonrichert/zsh-autocomplete.git ``` After installing, make the following modifications to your shell config: * In your `.zshrc` file: * Remove any calls to `compinit`. * Add near the top, _before_ any calls to `compdef`: ```sh source /path/to/zsh-autocomplete/zsh-autocomplete.plugin.zsh ``` * When using **Ubuntu,** add to your `.zshenv` file: ```sh skip_global_compinit=1 ``` * When using **Nix,** add to your `home.nix` file: ``` programs.zsh.enableCompletion = false; ``` Finally, restart your shell. Here's two ways to do so: * Open a new tab or window in your terminal. * Replace the current shell with a new one: ```sh % exec zsh ``` ### Updating If you installed manually, run: ```sh % git -C ~autocomplete pull ``` Otherwise, simply use your package manager or plugin manager's update mechanisms. ### Uninstalling 1. Revert the actions you took to [install](#installation). 1. Restart your shell. ## Keyboard shortcuts | `main` | `emacs` | `vicmd` | On the command line | In the menus | ---: | ---: | ---: | :--- | :--- | Enter
Return | | | | Exit menu text search or exit menu | Tab | | | Insert first listed menu item | Next completion | ShiftTab | | | Expand the current word | Previous completion | | CtrlN | J | Cursor down or enter completion menu | Change selection | | CtrlP | K | Cursor up or enter [history menu](#history-menu) | Change selection | Alt | AltN | CtrlN | Enter completion menu | Next section | Alt | AltP | CtrlP | Enter history menu | Previous section | PgDn | | | | Page down | PgUp | | | | Page up | | CtrlX / | | Toggle recent path search | | | CtrlR | / | Toggle history search | Start menu text search or go to previous match | | CtrlS | ? | Start menu text search | Start menu text search or go to next match | | CtrlSpace | V | Toggle selection mode | Add another item | | Ctrl-
Ctrl/ | U | | Undo last item | | CtrlG | | | Undo all added items ### Caveats * `main` is whichever keymap was aliased to `main` when Autocomplete was sourced. * By default, this is `emacs`. * If you run `bindkey -v` _before_ sourcing Autocomplete, then `main` will be `viins` when Autocomplete installs keybindings. * Plugins or other scripts that you load _after_ loading Autocomplete may override these bindings. If you find that some shortcuts don't work as expected, then you can fix them by * changing the order in which you source your plugins or by * running [`bindkey` commands](#reassign-keys) in your dotfiles _after_ you source your plugins. * Depending on your terminal, not all keybindings might be available to you. * Instead of Alt, your terminal might require you to press Escape, Option or Meta. * In the menus, the bindings listed under `vicmd` require you to press Alt for each, instead of just once. * The bindings listed under `emacs` and `vicmd` are always both active in the menus, no matter which keymap you actually use. This is a limitation of Zsh. * What any other keys do while you're in a menu depends on the keymap from which you opened the menu. See the Zsh manual section on [menu selection](https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#Menu-selection) for more info. ## Configuration The following are the most commonly requested ways to configure Autocomplete's behavior. To use any of these, add the code shown to your `.zshrc` file and modify it there, then restart you shell. ### Reassign keys You can use [Zsh's `bindkey` command](https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Zle-Builtins), _after_ loading Autocomplete, to customize your keybindings. Below are some examples of what you can do with this. #### Make Tab and ShiftTab cycle completions on the command line This makes Tab and ShiftTab, when pressed on the command line, cycle through listed completions, without changing what's listed in the menu: ```sh bindkey '^I' menu-complete bindkey "$terminfo[kcbt]" reverse-menu-complete ``` #### Make Tab and ShiftTab go to the menu This makes Tab and ShiftTab, when pressed on the command line, enter the menu instead of inserting a completion: ```sh bindkey '^I' menu-select bindkey "$terminfo[kcbt]" menu-select ``` #### Make Tab and ShiftTab change the selection in the menu This makes Tab and ShiftTab move the selection in the menu right and left, respectively, instead of exiting the menu: ```sh bindkey -M menuselect '^I' menu-complete bindkey -M menuselect "$terminfo[kcbt]" reverse-menu-complete ``` #### Make and always move the cursor on the command line This makes and always move the cursor on the command line, even when you are in the menu: ```sh bindkey -M menuselect '^[[D' .backward-char '^[OD' .backward-char bindkey -M menuselect '^[[C' .forward-char '^[OC' .forward-char ``` #### Make Enter always submit the command line This makes Enter always submit the command line, even when you are in the menu: ```sh bindkey -M menuselect '^M' .accept-line ``` #### Restore Zsh-default history shortcuts This restores the default Zsh keybindings for history control: ```sh bindkey -M emacs \ "^[p" .history-search-backward \ "^[n" .history-search-forward \ "^P" .up-line-or-history \ "^[OA" .up-line-or-history \ "^[[A" .up-line-or-history \ "^N" .down-line-or-history \ "^[OB" .down-line-or-history \ "^[[B" .down-line-or-history \ "^R" .history-incremental-search-backward \ "^S" .history-incremental-search-forward \ # bindkey -a \ "^P" .up-history \ "^N" .down-history \ "k" .up-line-or-history \ "^[OA" .up-line-or-history \ "^[[A" .up-line-or-history \ "j" .down-line-or-history \ "^[OB" .down-line-or-history \ "^[[B" .down-line-or-history \ "/" .vi-history-search-backward \ "?" .vi-history-search-forward \ # ``` ### Pass arguments to `compinit` If necessary, you can let Autocomplete pass arguments to `compinit` as follows: ```sh zstyle '*:compinit' arguments -D -i -u -C -w ``` ### First insert the common substring You can make any completion widget first insert the longest sequence of characters that will complete to all completions shown, if any, before inserting actual completions: ```zsh # all Tab widgets zstyle ':autocomplete:*complete*:*' insert-unambiguous yes # all history widgets zstyle ':autocomplete:*history*:*' insert-unambiguous yes # ^S zstyle ':autocomplete:menu-search:*' insert-unambiguous yes ``` #### Insert prefix instead of substring When using the above, if you want each widget to first try to insert only the longest _prefix_ that will complete to all completions shown, if any, then add the following: ```zsh zstyle ':completion:*:*' matcher-list 'm:{[:lower:]-}={[:upper:]_}' '+r:|[.]=**' ``` Note, though, that this will also slightly change what completions are listed initially. This is a limitation of the underlying implementation in Zsh. ### Customize common substring message You can customize the way the common substring is presented. The following sets the presentation to the default: ```zsh builtin zstyle ':autocomplete:*:unambiguous' format \ $'%{\e[0;2m%}%Bcommon substring:%b %0F%11K%d%f%k' ``` `%d` will be replaced with the common substring. Additionally, the following [Zsh prompt escape sequences](https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Visual-effects) are supported for adding visual effects: * `%B`: bold * `%F`: foreground color * `%K`: background color * `%S`: `terminfo` "standout" * `%U`: underline * `%{...%}`: arbitrary [ANSI escape sequence](https://en.wikipedia.org/wiki/ANSI_escape_code#Select_Graphic_Rendition_parameters) ### Make Enter submit the command line straight from the menu By default, pressing Enter in the menu search exits the search and pressing it otherwise in the menu exits the menu. If you instead want to make Enter _always_ submit the command line, use the following: ```zsh bindkey -M menuselect '\r' .accept-line ``` ### Add or don't add a space after certain completions When inserting a completion, a space is added after certain types of completions. The default list is as follows: ```zsh zstyle ':autocomplete:*' add-space \ executables aliases functions builtins reserved-words commands ``` Modifying this list will change when a space is inserted. If you change the list to `'*'`, a space is always inserted. If you put no elements in the list, then a space is never inserted. ### Don't add a semicolon after history completions By default, Autocomplete adds a semicolon to each history line to allow adding another line with CtrlSpace. You can deactivate this feature as follows: ```zsh zstyle ':autocomplete:*' add-semicolon no ``` ### Start each command line in history search mode This will make Autocomplete behave as if you pressed CtrlR at the start of each new command line: ```zsh zstyle ':autocomplete:*' default-context history-incremental-search-backward ``` ### Wait with autocompletion until typing stops for a certain amount of seconds Normally, Autocomplete fetches completions after you stop typing for about 0.05 seconds. You can change this as follows: ```zsh zstyle ':autocomplete:*' delay 0.1 # seconds (float) ``` ### Wait longer before timing out autocompletion Slow autocompletion can make the command line hang. Therefore, by default, Autocomplete waits at most 1 second for completion to finish. You can change this value as follows: ```zsh zstyle ':autocomplete:*' timeout 2.0 # seconds (float) ``` Note, though, that increasing this value can make your command line feel less responsive. ### Wait for a minimum amount of input To suppress autocompletion until a minimum number of characters have been typed: ```zsh zstyle ':autocomplete:*' min-input 3 ``` ### Don't show completions if the current word matches a pattern For example, this will stop completions from showing whenever the current word consists of two or more dots: ```zsh zstyle ':autocomplete:*' ignored-input '..##' ``` ## Change the max number of lines shown By default, Autocomplete lets the history menu fill half of the screen, and limits all real-time listings to a maximum of 16 lines. You can change these limits as follows: ```zsh # Note: -e lets you specify a dynamically generated value. # Override default for all listings # $LINES is the number of lines that fit on screen. zstyle -e ':autocomplete:*:*' list-lines 'reply=( $(( LINES / 3 )) )' # Override for recent path search only zstyle ':autocomplete:recent-paths:*' list-lines 10 # Override for history search only zstyle ':autocomplete:history-incremental-search-backward:*' list-lines 8 # Override for history menu only zstyle ':autocomplete:history-search-backward:*' list-lines 2000 ``` Note that for all real-time listings, the maximum number of lines is additionally capped to the number of lines that fit on screen. However, there is no such limit for the history menu. If that generates more lines than fit on screen, you can simply use PgUp and PgDn to scroll through the excess lines. (Note: On some terminals, you have to additionally hold Shift or, otherwise, it will scroll the terminal buffer instead.) ### Use a custom backend for recent directories/files Autocomplete by default uses [`cdr`]( https://zsh.sourceforge.io/Doc/Release/User-Contributions.html#Recent-Directories) to keeping track of and list recent directories (but not files). Override the following two functions to supply Autocomplete with recent directories/files from any source that you like: ```zsh # This function should populate an array $reply with a list of absolute paths. Path completions are # listed in the same order as in this array. chpwd_recent_filehandler() { reply=( '/first/recent/dir' '/recent/file' '/second/recent/dir' ) } # Called whenever you change dirs, to give you a chance to write the new dir to file. # NOTE: If you override the function above, then you are *required* to override this one, too. Can # be left empty, though. chpwd_recent_dirs() {} ``` ### Auto-include recent directories Instead of having to press a keyboard shortcut, you can automatically include recent directories whenever directories are listed: ```zsh # Show recent dirs unless the current word is empty or equal to an existing directory. zstyle -e ':completion:*:directories' fake ' [[ -z $PREFIX$SUFFIX || -d $PREFIX$SUFFIX ]] || +autocomplete:recent-directories ' zstyle ':completion:*:directories' sort no ``` ## Troubleshooting Try the steps in the [bug report template](.github/ISSUE_TEMPLATE/bug-report.md). ## Author & License See the [LICENSE](LICENSE) file for details.