Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH bracketed-paste-magic for vi-modes and emulations



In thinking about the "callbacks" that bracketed-paste-magic performs via
the paste-init and paste-finish lists plus invoking "zle $REPLY" for any
active widgets, I concluded that it wasn't appropriate for it to impose
zsh emulation context on those functions.

I also realized that I hadn't handled the special vi-mode behavior, e.g.,
pasting directly to a cutbuffer, nor that a paste started in vicmd mode
needs to temporarily switch to insert mode.  (Does anyone expect to be
able to paste vi editing commands, even when using older zsh?)

I did some rudimentary testing and this works in the basic cases e.g.
pasting in vicmd mode under sh emulation; I didn't try to guess at other
option settings but it should at least be no more broken than it was
before in these cases.

This is written so as to work around the "emulate -L" problem reported
in 36256 and the "function" syntax oddity of 36257.


diff --git a/Functions/Zle/bracketed-paste-magic b/Functions/Zle/bracketed-paste-magic
index da106d1..daf5aec 100644
--- a/Functions/Zle/bracketed-paste-magic
+++ b/Functions/Zle/bracketed-paste-magic
@@ -40,7 +40,6 @@
 #  Also looked up in the context :bracketed-paste-magic, these styles
 #  each are a list of function names.  They are executed in widget
 #  context but are called as functions (NOT as widgets with "zle name").
-#  They also run in zsh emulation context set by bracketed-paste-magic.
 #  As with hooks, the functions are called in order until one of them
 #  returns a nonzero exit status.  The parameter PASTED contains the
 #  current state of the pasted text, other ZLE parameters are as usual.
@@ -68,7 +67,7 @@ zstyle -m :bracketed-paste-magic active-widgets '*' ||
 # TODO: rewrite this using match-words-by-style
 #
 backward-extend-paste() {
-    : emulate -LR zsh	# Already set by bracketed-paste-magic
+    emulate -L zsh
     integer bep_mark=$MARK bep_region=$REGION_ACTIVE
     if (( REGION_ACTIVE && MARK < CURSOR )); then
 	zle .exchange-point-and-mark
@@ -99,7 +98,7 @@ backward-extend-paste() {
 #       zstyle :bracketed-paste-magic:finish quote-style none
 #
 quote-paste() {
-    : emulate -LR zsh	# Already set by bracketed-paste-magic
+    emulate -L zsh
     local qstyle
     # If there's a quoting style, be sure .bracketed-paste leaves it alone
     zstyle -s :bracketed-paste-magic:finish quote-style qstyle && NUMERIC=1
@@ -117,16 +116,28 @@ quote-paste() {
 # Now the actual function
 
 bracketed-paste-magic() {
-    emulate -LR zsh
+    # Fast exit in the vi-mode cut-buffer context
+    if [[ "$LASTWIDGET" = *vi-set-buffer ]]; then
+	zle .bracketed-paste
+	return
+    fi
+
+    # Really necessary to go to this much effort?
+    local bpm_emulate="$(emulate)" bpm_opts="$-"
+
+    emulate -L zsh
     local -a bpm_hooks bpm_inactive
-    local PASTED bpm_func bpm_active
+    local PASTED bpm_func bpm_active bpm_keymap=$KEYMAP
 
     # Set PASTED and run the paste-init functions
     zle .bracketed-paste PASTED
     if zstyle -a :bracketed-paste-magic paste-init bpm_hooks; then
 	for bpm_func in $bpm_hooks; do
 	    if (( $+functions[$bpm_func] )); then
-		$bpm_func || break
+		function () {
+		    emulate -L $bpm_emulate; set -$bpm_opts
+		    $bpm_func || break
+		}
 	    fi
 	done
     fi
@@ -143,18 +154,37 @@ bracketed-paste-magic() {
         # There are active widgets.  Reprocess $PASTED as keystrokes.
 	NUMERIC=1
 	zle -U - $PASTED
+
+	if [[ $bmp_keymap = vicmd ]]; then
+	    zle -K viins
+	fi
+
+	# Just in case there are active undo widgets
+	zle .split-undo
+	integer bpm_limit=$UNDO_LIMIT_NO bpm_undo=$UNDO_CHANGE_NO
+	UNDO_LIMIT_NO=$UNDO_CHANGE_NO
+
 	while [[ -n $PASTED ]] && zle .read-command; do
 	    PASTED=${PASTED#$KEYS}
 	    if [[ $KEYS = ${(~j:|:)${(b)bpm_inactive}} ]]; then
 		zle .self-insert-unmeta
 	    else
 		case $REPLY in
-		    (${~bpm_active}) zle $REPLY;;
+		    (${~bpm_active}) function () {
+			emulate -L $bpm_emulate; set -$bpm_opts
+			zle $REPLY
+		    };;
 		    (*) zle .self-insert-unmeta;;
 		esac
 	    fi
 	done
 	PASTED=$BUFFER
+
+	# Reset the undo state
+	zle undo $bpm_undo
+	UNDO_LIMIT_NO=$bpm_limit
+
+	zle -K $bpm_keymap
     fi
 
     # Restore state
@@ -169,7 +199,10 @@ bracketed-paste-magic() {
     if zstyle -a :bracketed-paste-magic paste-finish bpm_hooks; then
 	for bpm_func in $bpm_hooks; do
 	    if (( $+functions[$bpm_func] )); then
-		$bpm_func || break
+		function () {
+		    emulate -L $bpm_emulate; set -$bpm_opts
+		    $bpm_func || break
+		}
 	    fi
 	done
     fi
@@ -187,6 +220,6 @@ bracketed-paste-magic() {
 }
 
 # Handle zsh autoloading conventions
-if [[ $zsh_eval_context = *loadautofunc && ! -o kshautoload ]]; then
+if [[ "$zsh_eval_context" = *loadautofunc && ! -o kshautoload ]]; then
     bracketed-paste-magic "$@"
 fi

-- 
Barton E. Schaefer



Messages sorted by: Reverse Date, Date, Thread, Author