123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- # -*- mode: sh -*-
- #
- # git-escape-magic - zle tweak for git command line arguments
- #
- # Copyright (c) 2011, 2012, 2014 Akinori MUSHA
- # Licensed under the 2-clause BSD license.
- #
- # This tweak eliminates the need for manually escaping shell
- # meta-characters such as [~^{}] that are used for specifying a git
- # object (commit or tree). Every time you type one of these
- # characters on a git command line, it is automatically escaped with a
- # backslash as necessary and as appropriate.
- #
- # If you want to use this with url-quote-magic, make sure to enable it
- # first.
- #
- # Usage:
- # autoload -Uz git-escape-magic
- # git-escape-magic
- #
- git-escape-magic.self-insert() {
- emulate -L zsh
- setopt extendedglob
- local self_insert_function
- zstyle -s ':git-escape-magic' self-insert-function self_insert_function
- if [[ "$KEYS" == [{}~^]* ]] && {
- local qkey="${(q)KEYS}"
- [[ "$KEYS" != "$qkey" ]]
- } && {
- local lbuf="$LBUFFER$qkey"
- [[ "${(Q)LBUFFER}$KEYS" == "${(Q)lbuf}" ]]
- } && {
- local -a words
- words=("${(@Q)${(z)lbuf}}")
- [[ "$words[(i)(*/|)git(|-[^/]##)]" -le $#words ]]
- }
- then
- local i
- i="$words[(I)([;(){\&]|\&[\&\!]|\|\||[=<>]\(*)]"
- if [[ $i -gt 0 ]]; then
- shift $((i-1)) words
- if [[ "$words[1]" == [\=\<\>]\(* ]]; then
- words[1]="${words[1]#[=<>]\(}"
- else
- [[ "$words[1]" == \; && $words[2] == (then|else|elif|do) ]] && shift words
- shift words
- fi
- fi
- while [[ "$words[1]" == (if|while|until|\!) ]]; do
- shift words
- done
- while [[ "$words[1]" == [A-Za-z_][A-Za-z0-9_]#=* ]]; do
- shift words
- done
- [[ "$words[1]" == (*/|)git(|-[^/]##) ]] && {
- local subcommand
- subcommand="${words[1]##*/git-}"
- if [[ -z "$subcommand" ]]; then
- shift words
- subcommand="$words[1]"
- fi
- [[ $#words -ge 2 ]]
- } &&
- case "$subcommand" in
- # commands that may take pathspec but never take refspec with [{}~^]
- (add|rm|am|apply|check-attr|checkout-index|clean|clone|config|diff-files|hash-object|help|index-pack|mailinfo|mailsplit|merge-file|merge-index|mergetool|mktag|mv|pack-objects|pack-redundant|relink|send-email|show-index|show-ref|stage|status|verify-pack)
- false ;;
- # commands that may take pathspec but rarely take refspec with [{}~^]
- (for-each-ref|grep|ls-files|update-index)
- false ;;
- (archive|ls-tree)
- ! [[ $#words -ge 3 &&
- "$words[-2]" == [^-]* ]] ;;
- (diff-tree)
- ! [[ $#words -ge 4 &&
- "$words[-2]" == [^-]* &&
- "$words[-3]" == [^-]* ]] ;;
- (*)
- [[ $words[(i)--] -gt $#words ]] ;;
- esac &&
- case "${words[-1]%%"$KEYS"}" in
- (*[@^])
- [[ "$KEYS" == [{~^]* ]] ;;
- (*[@^]\{[^}]##)
- [[ "$KEYS" == \}* ]] ;;
- (?*)
- [[ "$KEYS" == [~^]* ]] ;;
- (*)
- false ;;
- esac &&
- LBUFFER="$LBUFFER\\"
- fi
- zle "$self_insert_function"
- }
- git-escape-magic.on() {
- emulate -L zsh
- local self_insert_function="${$(zle -lL | awk \
- '$1=="zle"&&$2=="-N"&&$3=="self-insert"{print $4;exit}'):-.self-insert}"
- [[ "$self_insert_function" == git-escape-magic.self-insert ]] &&
- return 0
- # For url-quote-magic which does not zle -N itself
- zle -la "$self_insert_function" || zle -N "$self_insert_function"
- zstyle ':git-escape-magic' self-insert-function "$self_insert_function"
- zle -A git-escape-magic.self-insert self-insert
- return 0
- }
- git-escape-magic.off() {
- emulate -L zsh
- local self_insert_function
- zstyle -s ':git-escape-magic' self-insert-function self_insert_function
- [[ -n "$self_insert_function" ]] &&
- zle -A "$self_insert_function" self-insert
- return 0
- }
- zle -N git-escape-magic.self-insert
- zle -N git-escape-magic.on
- zle -N git-escape-magic.off
- git-escape-magic() {
- git-escape-magic.on
- }
- [[ -o kshautoload ]] || git-escape-magic "$@"
|