zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh workers <zsh-workers@zsh.org>
Subject: PATCH: narrow-to-region (was Re: This widget implementation feels a bit clunky)
Date: Sat, 18 Jul 2015 16:42:24 -0700	[thread overview]
Message-ID: <150718164224.ZM4759@torch.brasslantern.com> (raw)
In-Reply-To: <150620102144.ZM5618@torch.brasslantern.com>

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


  reply	other threads:[~2015-07-18 23:42 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-20  9:16 This widget implementation feels a bit clunky (edit-quoted-word) Mikael Magnusson
2015-06-20 17:06 ` Peter Stephenson
2015-06-21  7:09   ` Mikael Magnusson
2015-06-21 17:17     ` Peter Stephenson
2015-06-22  2:26       ` Mikael Magnusson
2015-06-22  0:18     ` PATCH: Document narrow-to-region -l and -r Mikael Magnusson
2015-06-20 17:21 ` This widget implementation feels a bit clunky (edit-quoted-word) Bart Schaefer
2015-07-18 23:42   ` Bart Schaefer [this message]
2015-07-19  3:55     ` PATCH: narrow-to-region (was Re: This widget implementation feels a bit clunky) Oliver Kiddle
2015-07-19  8:23       ` Bart Schaefer
2015-07-20  9:19         ` Oliver Kiddle
2015-07-20 16:29           ` Bart Schaefer
2015-07-23  5:41           ` Undo and narrow-to-region (was Re: PATCH: narrow-to-region (was ...)) Bart Schaefer
2015-07-27 15:44             ` Oliver Kiddle
2015-08-12 17:00               ` PATCH: Re: Undo and narrow-to-region (was ...) Oliver Kiddle
2015-08-17 21:15                 ` Daniel Hahler
2015-08-17 21:58                   ` Bart Schaefer
2015-08-18  3:43                     ` Bart Schaefer
2015-08-18  7:05                   ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=150718164224.ZM4759@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).