Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: Re: Undo and narrow-to-region (was ...)
Here is the narrow-to-region with support for undo limits along with
a related change to the undo mechanism.
It'd be good if this gets some wider testing because I only use
narrow-to-region in limited ways. This is showing up issues with
$UNDO_CHANGE_NO and zle undo to undo multiple changes.
The change to zle_utils.c here is for $UNDO_CHANGE_NO.
If you consider this function:
undostuff() {
LBUFFER+='a'
LBUFFER+='b'
zle split-undo
LBUFFER+='c'
_undo_here=$UNDO_CHANGE_NO
LBUFFER+='d'
}
A subsequent zle undo $_undo_here should take you back to 'abc' while a
default undo should skip straight to 'ab' without stopping at 'abc'.
The following adds a call to mkundoent() when $UNDO_CHANGE_NO is
referenced so you get a clear change number marking the current
state. I think the result is simpler than the current tricks with
undo_set_by_variable.
This is still not perfect with history changes. I'm not really happy
with the way history line changes are managed in the undo system in
general. The old fix in 10328 seems rather ugly. It might be better to
create full undo entries for history changes though that would need
hacks to ensure that multiple history changes are undone in a single
step.
This patch also replaces 35935.
Oliver
diff --git a/Functions/Zle/narrow-to-region b/Functions/Zle/narrow-to-region
index 293f89b..0ef28a8 100644
--- a/Functions/Zle/narrow-to-region
+++ b/Functions/Zle/narrow-to-region
@@ -26,11 +26,13 @@
# statevar may not begin with the prefix "_ntr_" which is reserved for
# parameters within narrow-to-region.
-emulate -L zsh
-setopt extendedglob
+# set the minimum of options to avoid changing behaviour away from
+# user preferences from within recursive-edit
+setopt localoptions noshwordsplit noksharrays
-local _ntr_lbuf_return _ntr_rbuf_return
+local _ntr_newbuf _ntr_lbuf_return _ntr_rbuf_return
local _ntr_predisplay=$PREDISPLAY _ntr_postdisplay=$POSTDISPLAY
+integer _ntr_savelim=UNDO_LIMIT_NO _ntr_changeno
integer _ntr_start _ntr_end _ntr_swap _ntr_cursor=$CURSOR _ntr_mark=$MARK
integer _ntr_stat
@@ -61,7 +63,7 @@ done
(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
if [[ $_ntr_restore = _ntr_* || $_ntr_save = _ntr_* ||
- $_ntr_lbuf_return = _ntr_* || $ntr_rbuf_return = _ntr_* ]]; then
+ $_ntr_lbuf_return = _ntr_* || $_ntr_rbuf_return = _ntr_* ]]; then
zle -M "$0: _ntr_ prefix is reserved" >&2
return 1
fi
@@ -86,30 +88,34 @@ if [[ -n $_ntr_save || -z $_ntr_restore ]]; then
_ntr_end=_ntr_swap
fi
- (( _ntr_end++, _ntr_cursor -= _ntr_start, _ntr_mark -= _ntr_start ))
+ (( _ntr_cursor -= _ntr_start, _ntr_mark -= _ntr_start ))
_ntr_lbuffer=${BUFFER[1,_ntr_start]}
if [[ -z $_ntr_usepretext || ( -n $_ntr_nonempty && -z $_ntr_lbuffer ) ]]
then
_ntr_pretext=$_ntr_lbuffer
fi
- _ntr_rbuffer=${BUFFER[_ntr_end,-1]}
+ _ntr_rbuffer=${BUFFER[_ntr_end+1,-1]}
if [[ -z $_ntr_useposttext || ( -n $_ntr_nonempty && -z $_ntr_rbuffer ) ]]
then
_ntr_posttext=$_ntr_rbuffer
fi
+ _ntr_changeno=$UNDO_CHANGE_NO
PREDISPLAY="$_ntr_predisplay$_ntr_pretext"
POSTDISPLAY="$_ntr_posttext$_ntr_postdisplay"
if [[ -n $_ntr_save ]]; then
builtin typeset -ga $_ntr_save
set -A $_ntr_save "${_ntr_predisplay}" "${_ntr_postdisplay}" \
- "${_ntr_lbuffer}" "${_ntr_rbuffer}" || return 1
+ "${_ntr_savelim}" "${_ntr_changeno}" \
+ "${_ntr_start}" "${_ntr_end}" || return 1
fi
- BUFFER=${BUFFER[_ntr_start+1,_ntr_end-1]}
+ BUFFER=${BUFFER[_ntr_start+1,_ntr_end]}
CURSOR=$_ntr_cursor
MARK=$_ntr_mark
+ zle split-undo
+ UNDO_LIMIT_NO=$UNDO_CHANGE_NO
fi
if [[ -z $_ntr_save && -z $_ntr_restore ]]; then
@@ -126,18 +132,22 @@ if [[ -n $_ntr_restore || -z $_ntr_save ]]; then
if [[ -n $_ntr_restore ]]; then
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
+ _ntr_savelim="${${(@P)_ntr_restore}[3]}"
+ _ntr_changeno="${${(@P)_ntr_restore}[4]}"
+ _ntr_start="${${(@P)_ntr_restore}[5]}"
+ _ntr_end="${${(@P)_ntr_restore}[6]}" }; then
zle -M Failed. >&2
return 1
fi
fi
+ _ntr_newbuf="$BUFFER"
+ zle undo $_ntr_changeno
PREDISPLAY=$_ntr_predisplay
POSTDISPLAY=$_ntr_postdisplay
- LBUFFER="$_ntr_lbuffer$BUFFER"
- RBUFFER="$_ntr_rbuffer"
- MARK=${#_ntr_lbuffer}
+ BUFFER[_ntr_start+1,_ntr_end]="$_ntr_newbuf"
+ (( MARK = _ntr_start, CURSOR = _ntr_start + ${#_ntr_newbuf} ))
+ UNDO_LIMIT_NO=_ntr_savelim
fi
return $_ntr_stat
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 8b55403..d1d3206 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1409,10 +1409,6 @@ zlong undo_changeno;
zlong undo_limitno;
-/* If non-zero, the last increment to undo_changeno was for the variable */
-
-static int undo_set_by_variable;
-
/**/
void
initundo(void)
@@ -1423,7 +1419,6 @@ initundo(void)
curchange->del = curchange->ins = NULL;
curchange->dell = curchange->insl = 0;
curchange->changeno = undo_changeno = undo_limitno = 0;
- undo_set_by_variable = 0;
lastline = zalloc((lastlinesz = linesz) * ZLE_CHAR_SIZE);
ZS_memcpy(lastline, zleline, (lastll = zlell));
lastcs = zlecs;
@@ -1549,7 +1544,6 @@ mkundoent(void)
ch->prev = NULL;
}
ch->changeno = ++undo_changeno;
- undo_set_by_variable = 0;
endnextchanges = ch;
}
@@ -1584,14 +1578,13 @@ undo(char **args)
struct change *prev = curchange->prev;
if(!prev)
return 1;
- if (prev->changeno < last_change)
+ if (prev->changeno <= last_change)
break;
- if (prev->changeno < undo_limitno && !*args)
+ if (prev->changeno <= undo_limitno && !*args)
return 1;
- if (unapplychange(prev))
- curchange = prev;
- else
- break;
+ if (!unapplychange(prev) && last_change >= 0)
+ unapplychange(prev);
+ curchange = prev;
} while (last_change >= (zlong)0 || (curchange->flags & CH_PREV));
setlastline();
return 0;
@@ -1741,18 +1734,10 @@ zlecallhook(char *name, char *arg)
zlong
get_undo_current_change(UNUSED(Param pm))
{
- if (undo_set_by_variable) {
- /* We were the last to increment this, doesn't need another one. */
- return undo_changeno;
- }
- undo_set_by_variable = 1;
- /*
- * Increment the number in case a change is in progress;
- * we don't want to back off what's already been done when
- * we return to this change number. This eliminates any
- * problem about the point where a change is numbered
- */
- return ++undo_changeno;
+ /* add entry for any pending changes */
+ mkundoent();
+ setlastline();
+ return undo_changeno;
}
/**/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author