about summary refs log tree commit diff
path: root/Functions/Zle/surround
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Zle/surround')
-rw-r--r--Functions/Zle/surround75
1 files changed, 75 insertions, 0 deletions
diff --git a/Functions/Zle/surround b/Functions/Zle/surround
new file mode 100644
index 000000000..b7be30b75
--- /dev/null
+++ b/Functions/Zle/surround
@@ -0,0 +1,75 @@
+# Implementation of some functionality of the popular vim surround plugin.
+# Allows "surroundings" to be changes: parentheses, brackets and quotes.
+
+# To use
+#   autoload -Uz surround
+#   zle -N delete-surround surround
+#   zle -N add-surround surround
+#   zle -N change-surround surround
+#   bindkey -a cs change-surround
+#   bindkey -a ds delete-surround
+#   bindkey -a ys add-surround
+#   bindkey -M visual S add-surround
+#
+#  This doesn't allow yss to operate on a line but VS will work
+
+setopt localoptions noksharrays
+autoload -Uz select-quoted select-bracketed
+local before after
+local -A matching
+matching=( \( \) \{ \} \< \> \[ \] )
+
+case $WIDGET in
+  change-*)
+    local MARK="$MARK" CURSOR="$CURSOR" call
+    read -k 1 before
+    if [[ ${(kvj::)matching} = *$before* ]]; then
+      call=select-bracketed
+    else
+      call=select-quoted
+    fi
+    read -k 1 after
+    $call "a$before" || return 1
+    before="$after"
+    if [[ -n $matching[$before] ]]; then
+      after=" $matching[$before]"
+      before+=' '
+    elif [[ -n $matching[(r)[$before:q]] ]]; then
+      before="${(k)matching[(r)[$before:q]]}"
+    fi
+    BUFFER[CURSOR]="$after"
+    BUFFER[MARK+1]="$before"
+    CURSOR=MARK
+  ;;
+  delete-*)
+    local MARK="$MARK" CURSOR="$CURSOR" call
+    read -k 1 before
+    if [[ ${(kvj::)matching} = *$before* ]]; then
+      call=select-bracketed
+    else
+      call=select-quoted
+    fi
+    if $call "a$before"; then
+      BUFFER[CURSOR]=''
+      BUFFER[MARK+1]=''
+      CURSOR=MARK
+    fi
+  ;;
+  add-*)
+    local save_cut="$CUTBUFFER"
+    zle .vi-change || return
+    local save_cur="$CURSOR"
+    zle .vi-cmd-mode
+    read -k 1 before
+    after="$before"
+    if [[ -n $matching[$before] ]]; then
+      after=" $matching[$before]"
+      before+=' '
+    elif [[ -n $matching[(r)[$before:q]] ]]; then
+      before="${(k)matching[(r)[$before:q]]}"
+    fi
+    CUTBUFFER="$before$CUTBUFFER$after"
+    zle .vi-put-after -n 1
+    CUTBUFFER="$save_cut" CURSOR="$save_cur"
+  ;;
+esac