|
@@ -0,0 +1,135 @@
|
|
|
+# -*- 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 "$@"
|
|
|
+
|