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)"