Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Editing the history in the shell
This is not quite a finished product yet (for one thing, no doc) but
it demonstrates most of the interesting ideas.
The patch implements "zed -h" which loads the history into vared and
arranges to replace the existing history with that before it exits.
This does NOT solve Markus' complaint about the history numbers, they
increase by the number of entries output by the editor. It makes no
attempt to account for various history options, so those may change
the final result if they affect "print -s".
It also handles "zed -h filename" which loads that file and saves it
back again rather than alter the current shell history. There is a
glitch currently that may lose the most recent line from the file when
it is loaded (not when it is saved), which seems to be the fault of
"fc -p". There are probably other bugs, I've tested only minimally.
Some unanswered questions:
1) Should it be possible to edit empty events into the history?
Currently empty lines are removed, but changing to IFS=$'\n\n' would
preserve them (thanks Oliver for the idea)
2) Should "vared -h" be used? I'm inclined to say "no" because the
behavior becomes a bit strange; the entire content of the variable is
treated as one "history event" when navigating, i.e., if you move up
from the top (oldest) history event, the whole history disappears and
is replaced by the single newest event.
3) If the file for "zed -h filename" does not exist, should the editor
be populated from the current shell history? Currently the editor
starts empty.
Patch both inlined and attached in case gmail garbles the lines. I
followed the existing coding style of "zed", which is a little quirky.
diff --git a/Functions/Misc/zed b/Functions/Misc/zed
index 9eb4b2d..952e1a9 100644
--- a/Functions/Misc/zed
+++ b/Functions/Misc/zed
@@ -5,16 +5,18 @@
# Edit small files with the command line editor.
# Use ^X^W to save (or ZZ in vicmd mode), ^C to abort.
# Option -f: edit shell functions. (Also if called as fned.)
+# Option -h: edit shell history. (Also if called as histed.)
setopt localoptions noksharrays
local var opts zed_file_name
# We do not want timeout while we are editing a file
-integer TMOUT=0 okargs=1 fun bind
+integer TMOUT=0 okargs=1 fun hist bind
local -a expand
-zparseopts -D -A opts f b x:
+zparseopts -D -A opts f h b x:
fun=$+opts[-f]
+hist=$+opts[-h]
bind=$+opts[-b]
if [[ $opts[-x] == <-> ]]; then
expand=(-x $opts[-x])
@@ -24,12 +26,15 @@ elif (( $+opts[-x] )); then
fi
[[ $0 = fned ]] && fun=1
+[[ $0 = histed ]] && hist=1
(( bind )) && okargs=0
+(( hist && $# <= 2 )) && okargs=$#
-if (( $# != okargs )); then
+if (( $# != okargs || fun + hist > 1 )); then
echo 'Usage:
zed filename
zed -f [ -x N ] function
+zed -h [ filename [ size ] ]
zed -b' >&2
return 1
fi
@@ -133,6 +138,17 @@ if ((fun)) then
}"
fi
vared -M zed -m zed-vicmd -i __zed_init var && eval function "$var"
+elif ((hist)) then
+ [[ -n $1 ]] && { fc -p -a $1 ${2:-$({ wc -l <$1 } 2>/dev/null)} || return }
+ var=( "${(@Oav)history:gs/\\/\\\\}" )
+ IFS=$'\n' vared -M zed -m zed-vicmd -i __zed_init var
+ if (( ? )); then
+ [[ -n $1 ]] && unset HISTFILE
+ else
+ hist=$HISTSIZE; HISTSIZE=0; fc -R /dev/null; HISTSIZE=$hist
+ for (( hist=1; hist <= $#var; hist++ )) print -s "$var[hist]"
+ [[ -n $1 ]] && SAVEHIST=$#var # Resets on function exit
+ fi
else
zed_file_name=$1
[[ -f $1 ]] && var="$(<$1)"
diff --git a/Functions/Misc/zed b/Functions/Misc/zed
index 9eb4b2d..952e1a9 100644
--- a/Functions/Misc/zed
+++ b/Functions/Misc/zed
@@ -5,16 +5,18 @@
# Edit small files with the command line editor.
# Use ^X^W to save (or ZZ in vicmd mode), ^C to abort.
# Option -f: edit shell functions. (Also if called as fned.)
+# Option -h: edit shell history. (Also if called as histed.)
setopt localoptions noksharrays
local var opts zed_file_name
# We do not want timeout while we are editing a file
-integer TMOUT=0 okargs=1 fun bind
+integer TMOUT=0 okargs=1 fun hist bind
local -a expand
-zparseopts -D -A opts f b x:
+zparseopts -D -A opts f h b x:
fun=$+opts[-f]
+hist=$+opts[-h]
bind=$+opts[-b]
if [[ $opts[-x] == <-> ]]; then
expand=(-x $opts[-x])
@@ -24,12 +26,15 @@ elif (( $+opts[-x] )); then
fi
[[ $0 = fned ]] && fun=1
+[[ $0 = histed ]] && hist=1
(( bind )) && okargs=0
+(( hist && $# <= 2 )) && okargs=$#
-if (( $# != okargs )); then
+if (( $# != okargs || fun + hist > 1 )); then
echo 'Usage:
zed filename
zed -f [ -x N ] function
+zed -h [ filename [ size ] ]
zed -b' >&2
return 1
fi
@@ -133,6 +138,17 @@ if ((fun)) then
}"
fi
vared -M zed -m zed-vicmd -i __zed_init var && eval function "$var"
+elif ((hist)) then
+ [[ -n $1 ]] && { fc -p -a $1 ${2:-$({ wc -l <$1 } 2>/dev/null)} || return }
+ var=( "${(@Oav)history:gs/\\/\\\\}" )
+ IFS=$'\n' vared -M zed -m zed-vicmd -i __zed_init var
+ if (( ? )); then
+ [[ -n $1 ]] && unset HISTFILE
+ else
+ hist=$HISTSIZE; HISTSIZE=0; fc -R /dev/null; HISTSIZE=$hist
+ for (( hist=1; hist <= $#var; hist++ )) print -s "$var[hist]"
+ [[ -n $1 ]] && SAVEHIST=$#var # Resets on function exit
+ fi
else
zed_file_name=$1
[[ -f $1 ]] && var="$(<$1)"
Messages sorted by:
Reverse Date,
Date,
Thread,
Author