[![Made with Doom Emacs](https://img.shields.io/badge/Made_with-Doom_Emacs-blueviolet.svg?style=flat-square&logo=GNU%20Emacs&logoColor=white)](https://github.com/hlissner/doom-emacs) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](./LICENSE) ![ZSH 5.0.2+](https://img.shields.io/badge/zsh-v5.0.2-orange.svg?style=flat-square) [![Build Status](https://img.shields.io/travis/hlissner/zsh-autopair/master.svg?label=master&style=flat-square)](https://travis-ci.org/hlissner/zsh-autopair) # zsh-autopair A simple plugin that auto-closes, deletes and skips over matching delimiters in zsh intelligently. Hopefully. > NOTE: zsh-autopair is untested for versions of Zsh below 5.0.2. Please report > any issues you have in earlier versions! Specifically, zsh-autopair does 5 things for you: 1. It inserts matching pairs (by default, that means brackets, quotes and spaces): e.g. `echo |` => " => `echo "|"` 2. It skips over matched pairs: e.g. `cat ./*.{py,rb|}` => } => `cat ./*.{py,rb}|` 3. It auto-deletes pairs on backspace: e.g. `git commit -m "|"` => backspace => `git commit -m |` 4. And does all of the above only when it makes sense to do so. e.g. when the pair is balanced and when the cursor isn't next to a boundary character: e.g. `echo "|""` => backspace => `echo |""` (doesn't aggressively eat up too many quotes) 5. Spaces between brackets are expanded and contracted. e.g. `echo [|]` => space => `echo [ | ]` => backspace => `echo [|]` **Table of Contents** - [Install](#install) - [Antigen](#antigen) - [zgen](#zgen) - [zplug](#zplug) - [Hombrew](#homebrew) - [Oh My Zsh](#oh-my-zsh) - [Configuration](#configuration) - [Adding/Removing pairs](#addingremoving-pairs) - [Troubleshooting & compatibility issues](#troubleshooting--compatibility-issues) - [zgen & prezto compatibility](#zgen--prezto-compatibility) - [text on right-side of cursor interfere with completion](#text-on-right-side-of-cursor-interfere-with-completion) - [zsh-autopair & isearch?](#zsh-autopair--isearch) - [Midnight Commander](#midnight-commander) - [Other resources](#other-resources) ## Install Download and source `autopair.zsh` ```bash if [[ ! -d ~/.zsh-autopair ]]; then git clone https://github.com/hlissner/zsh-autopair ~/.zsh-autopair fi source ~/.zsh-autopair/autopair.zsh autopair-init ``` ### Hoembrew `brew install zsh-autopair` ``` bash # Add to .zshrc source $HOMEBREW_PREFIX/share/zsh-autopair/autopair.zsh ``` ### Antigen `antigen bundle hlissner/zsh-autopair` ### zgen ```bash if ! zgen saved; then echo "Creating a zgen save" # ... other plugins zgen load hlissner/zsh-autopair zgen save fi ``` ### zplug Load autopair _after compinit_, otherwise, the plugin won't work. ```bash zplug "hlissner/zsh-autopair", defer:2 ``` ### Homebrew For Homebrew users, you can install it through the following command ```shell brew install zsh-autopair ``` Then source it in your `.zshrc` ```shell source $(brew --prefix)/share/zsh-autopair/autopair.zsh ``` ### Oh My Zsh 1. Clone this repository into `$ZSH_CUSTOM/plugins` (by default `~/.oh-my-zsh/custom/plugins`) ```sh git clone https://github.com/hlissner/zsh-autopair ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autopair ``` 2. Add the plugin to the list of plugins for Oh My Zsh to load (inside `~/.zshrc`): ```sh plugins=( # other plugins... zsh-autopair ) ``` 3. Start a new terminal session. ## Configuration zsh-autopair sets itself up. You can prevent this by setting `AUTOPAIR_INHIBIT_INIT`. **Options:** * `AUTOPAIR_BETWEEN_WHITESPACE` (default: blank): if set, regardless of whether delimiters are unbalanced or do not meet a boundary check, pairs will be auto-closed if surrounded by whitespace, BOL or EOL. * `AUTOPAIR_INHIBIT_INIT` (default: blank): if set, autopair will not automatically set up keybinds. [Check out the initialization code](autopair.zsh#L118) if you want to know what it does. * `AUTOPAIR_PAIRS` (default: ``('`' '`' "'" "'" '"' '"' '{' '}' '[' ']' '(' ')' ' ' ' ')``): An associative array that map pairs. Only one-character pairs are supported. To modify this, see the "Adding/Removing pairs" section. * `AUTOPAIR_LBOUNDS`/`AUTOPAIR_RBOUNDS` (default: see below): Associative lists of regex character groups dictating the 'boundaries' for autopairing depending on the delimiter. These are their default values: ```bash AUTOPAIR_LBOUNDS=(all '[.:/\!]') AUTOPAIR_LBOUNDS+=(quotes '[]})a-zA-Z0-9]') AUTOPAIR_LBOUNDS+=(spaces '[^{([]') AUTOPAIR_LBOUNDS+=(braces '') AUTOPAIR_LBOUNDS+=('`' '`') AUTOPAIR_LBOUNDS+=('"' '"') AUTOPAIR_LBOUNDS+=("'" "'") AUTOPAIR_RBOUNDS=(all '[[{(<,.:?/%$!a-zA-Z0-9]') AUTOPAIR_RBOUNDS+=(quotes '[a-zA-Z0-9]') AUTOPAIR_RBOUNDS+=(spaces '[^]})]') AUTOPAIR_RBOUNDS+=(braces '') ``` For example, if `$AUTOPAIR_LBOUNDS[braces]="[a-zA-Z]"`, then braces (`{([`) won't be autopaired if the cursor follows an alphabetical character. Individual delimiters can be used too. Setting `$AUTOPAIR_RBOUNDS['{']="[0-9]"` will cause { specifically to not be autopaired when the cursor precedes a number. ### Adding/Removing pairs You can change the designated pairs in zsh-autopair by modifying the `AUTOPAIR_PAIRS` envvar. This can be done _before_ initialization like so: ``` sh typeset -gA AUTOPAIR_PAIRS AUTOPAIR_PAIRS+=("<" ">") ``` Or after initialization; however, you'll have to bind keys to `autopair-insert` manually: ```sh AUTOPAIR_PAIRS+=("<" ">") bindkey "<" autopair-insert # prevents breakage in isearch bindkey -M isearch "<" self-insert ``` To _remove_ pairs, use `unset 'AUTOPAIR_PAIRS[<]'`. Unbinding is optional. ## Troubleshooting & compatibility issues ### zgen & prezto compatibility Prezto's Editor module is known to reset autopair's bindings. A workaround is to _defer autopair from initializing_ (by setting `AUTOPAIR_INHIBIT_INIT=1`) and initialize it manually (by calling `autopair-init`): ``` sh source "$HOME/.zgen/zgen.zsh" # Add this AUTOPAIR_INHIBIT_INIT=1 if ! zgen saved; then zgen prezto # ... zgen load hlissner/zsh-autopair 'autopair.zsh' #... zgen save fi # And this autopair-init ``` ### text on right-side of cursor interfere with completion Bind Tab to `expand-or-complete-prefix` and completion will ignore what's to the right of cursor: `bindkey '^I' expand-or-complete-prefix` This has the unfortunate side-effect of overwriting whatever's right of the cursor, however. ### zsh-autopair & isearch? zsh-autopair silently disables itself in isearch, as the two are incompatible. ### Midnight Commander MC hangs when zsh-autopair tries to bind the space key. This also breaks the MC subshell. Disable space expansion to work around this: `unset 'AUTOPAIR_PAIRS[ ]'` ## Other resources * Works wonderfully with [zsh-syntax-highlight] and `ZSH_HIGHLIGHT_HIGHLIGHTERS+=brackets`, but zsh-syntax-highlight must be loaded *after* zsh-autopair. * Mixes well with these vi-mode zsh modules: [surround], [select-quoted], and [select-bracketed] (they're built into zsh as of zsh-5.0.8) * Other relevant repositories of mine: + [dotfiles] + [emacs.d] + [vimrc] + [zshrc] [dotfiles]: https://github.com/hlissner/dotfiles [vimrc]: https://github.com/hlissner/.vim [emacs.d]: https://github.com/hlissner/doom-emacs [zshrc]: https://github.com/hlissner/dotfiles/blob/master/config/zsh/.zshrc [zsh-syntax-highlighting]: https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/docs/highlighters/pattern.md [surround]: https://github.com/zsh-users/zsh/blob/master/Functions/Zle/surround [select-quoted]: https://github.com/zsh-users/zsh/blob/master/Functions/Zle/select-quoted [select-bracketed]: https://github.com/zsh-users/zsh/blob/master/Functions/Zle/select-bracketed