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

PATCH: narrow-to-region (was Re: This widget implementation feels a bit clunky)



On Jun 20, 10:21am, Bart Schaefer wrote:
} 
} [...]  If you used "narrow-to-region -S state ..." then I think the
} resulting text would be $BUFFER between the exit from recursive-edit
} and the call to "narrow-to-region -R state" ?
} 
} Except that I'm having a little trouble with -S / -R.  The value of
} $MARK never seems to be correctly restored.  Is it supposed to be?

What was happening:

In order to narrow the editable buffer to just the current region, the
lesser of MARK and CURSOR is calculated and assigned to _ntr_start.
Then the leading $_ntr_start characters are removed from BUFFER and
MARK and CURSOR are shifted to correspond, so one or the other of them
always ends up being set to 0.

Upon exit from recursive-edit (or calling "narrow-to-region -R state")
the values of LBUFFER and RBUFFER are reset, which automatically moves
CURSOR to the beginning of the new RBUFFER, but does not change MARK.
This guarantees that MARK will be wrong, because it will either be left
as zero, or at a now-irrelevant position in the middle of the buffer,
possibly even past the end of it.

So this patch:

- cleans up white space in the documentary comment

- checks that the -l and -r buffer variables also don't use _ntr_

- consistently uses "zle -M ... >&2" even though I don't know why

- does away with a bunch of unnecessary "eval"s

- declares the -l -r and -S variables with "typeset -g"

- forces MARK and CURSOR to point to opposite ends of the region after
  the function returns, which is really the point of all this


diff --git a/Functions/Zle/narrow-to-region b/Functions/Zle/narrow-to-region
index 8b88da4..293f89b 100644
--- a/Functions/Zle/narrow-to-region
+++ b/Functions/Zle/narrow-to-region
@@ -5,21 +5,26 @@
 # Optionally accepts exactly two arguments, which are used instead of
 # $CURSOR and $MARK as limits to the range.
 #
+# Upon exit, $MARK is always the start of the edited range and $CURSOR
+# the end of the range, even if they began in the opposite order.
+#
 # Other options:
-#   -p pretext   show `pretext' instead of the buffer text before the region.
-#   -P posttext  show  `posttext' instead of the buffer text after the region.
-# Either or both may be empty.
+#   -p pretext   show "pretext" instead of the buffer text before the region.
+#   -P posttext  show "posttext" instead of the buffer text after the region.
+#                Either or both may be empty.
 #   -n           Only replace the text before or after the region with
 #                the -p or -P options if the text was not empty.
-#   -l lbufvar   ) $lbufvar and $rbufvar will contain the value of $LBUFFER and
-#   -r rbufvar   ) $RBUFFER resulting from any recursive edit (i.e. not with -S or -R)
+#   -l lbufvar   $lbufvar is assigned the value of $LBUFFER and
+#   -r rbufvar   $rbufvar is assigned the value of $RBUFFER
+#                from any recursive edit (i.e. not with -S or -R).  Neither
+#                lbufvar nor rbufvar may begin with the prefix "_ntr_".
 #   -S statevar
 #   -R statevar
-# Save or restore the state in/from the parameter named statevar.  In
-# either case no recursive editing takes place; this will typically be
-# done within the calling function between calls with -S and -R.  The
-# statevar may not begin with the prefix _ntr_ which is reserved for
-# parameters within narrow-to-region.
+#      Save or restore the state in/from the parameter named statevar.  In
+#      either case no recursive editing takes place; this will typically be
+#      done within the calling function between calls with -S and -R.  The
+#      statevar may not begin with the prefix "_ntr_" which is reserved for
+#      parameters within narrow-to-region.
 
 emulate -L zsh
 setopt extendedglob
@@ -55,7 +60,8 @@ while getopts "l:np:P:r:R:S:" _ntr_opt; do
 done
 (( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
 
-if [[ $_ntr_restore = _ntr_* || $_ntr_save = _ntr_* ]]; then
+if [[ $_ntr_restore = _ntr_* || $_ntr_save = _ntr_* ||
+      $_ntr_lbuf_return = _ntr_* || $ntr_rbuf_return = _ntr_* ]]; then
   zle -M "$0: _ntr_ prefix is reserved" >&2
   return 1
 fi
@@ -64,7 +70,7 @@ if [[ -n $_ntr_save || -z $_ntr_restore ]]; then
 
   if (( $# )); then
     if (( $# != 2 )); then
-      zle -M "$0: supply zero or two arguments"
+      zle -M "$0: supply zero or two arguments" >&2
       return 1
     fi
     _ntr_start=$1
@@ -94,39 +100,44 @@ if [[ -n $_ntr_save || -z $_ntr_restore ]]; then
   fi
   PREDISPLAY="$_ntr_predisplay$_ntr_pretext"
   POSTDISPLAY="$_ntr_posttext$_ntr_postdisplay"
-  BUFFER=${BUFFER[_ntr_start+1,_ntr_end-1]}
-  CURSOR=$_ntr_cursor
-  MARK=$_ntr_mark
 
   if [[ -n $_ntr_save ]]; then
-    eval "$_ntr_save=(${(qq)_ntr_predisplay} ${(qq)_ntr_postdisplay}
-${(qq)_ntr_lbuffer} ${(qq)_ntr_rbuffer})" || return 1
+    builtin typeset -ga $_ntr_save
+    set -A $_ntr_save "${_ntr_predisplay}" "${_ntr_postdisplay}" \
+	"${_ntr_lbuffer}" "${_ntr_rbuffer}" || return 1
   fi
+
+  BUFFER=${BUFFER[_ntr_start+1,_ntr_end-1]}
+  CURSOR=$_ntr_cursor
+  MARK=$_ntr_mark
 fi
 
 if [[ -z $_ntr_save && -z $_ntr_restore ]]; then
   zle recursive-edit
   _ntr_stat=$?
 
-  [[ -n $_ntr_lbuf_return ]] && eval "${_ntr_lbuf_return}=\${LBUFFER}"
-  [[ -n $_ntr_rbuf_return ]] && eval "${_ntr_rbuf_return}=\${RBUFFER}"
+  [[ -n $_ntr_lbuf_return ]] &&
+    builtin typeset -g ${_ntr_lbuf_return}="${LBUFFER}"
+  [[ -n $_ntr_rbuf_return ]] &&
+    builtin typeset -g ${_ntr_rbuf_return}="${RBUFFER}"
 fi
 
 if [[ -n $_ntr_restore || -z $_ntr_save ]]; then
   if [[ -n $_ntr_restore ]]; then
-    if ! eval "_ntr_predisplay=\${${_ntr_restore}[1]}
-_ntr_postdisplay=\${${_ntr_restore}[2]}
-_ntr_lbuffer=\${${_ntr_restore}[3]}
-_ntr_rbuffer=\${${_ntr_restore}[4]}"; then
-      zle -M Failed.
+    if ! { _ntr_predisplay="${${(@P)_ntr_restore}[1]}"
+           _ntr_postdisplay="${${(@P)_ntr_restore}[2]}"
+           _ntr_lbuffer="${${(@P)_ntr_restore}[3]}"
+           _ntr_rbuffer="${${(@P)_ntr_restore}[4]}" }; then
+      zle -M Failed. >&2
       return 1
     fi
   fi
 
   PREDISPLAY=$_ntr_predisplay
   POSTDISPLAY=$_ntr_postdisplay
-  LBUFFER="$_ntr_lbuffer$LBUFFER"
-  RBUFFER="$RBUFFER$_ntr_rbuffer"
+  LBUFFER="$_ntr_lbuffer$BUFFER"
+  RBUFFER="$_ntr_rbuffer"
+  MARK=${#_ntr_lbuffer}
 fi
 
 return $_ntr_stat



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