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

Re: Editing the history in the shell



Thanks for the review, Daniel.

On Fri, May 22, 2020 at 7:28 PM Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx> wrote:
>
> Bart Schaefer wrote on Fri, 22 May 2020 15:24 -0700:
> > 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)
>
> Hmm.  I guess they might be useful as separators?

I did not do this yet.

> Evaluating «$#var» takes O(N) time, which makes this an O(N²) loop.
> Save $#var into an auxiliary variable?

Did that.

> Also, s/print -s/print -s --/.

I went all the way to "print -rs --" although -r may not have been necessary.

I believe the following fixes the last-line-lost problem with "fc -p"
and also a problem that you couldn't save more lines to a history file
than were read from it in the first place.  And I updated the _zed
completer, though not yet the doc.  I'm not entirely sure about some
of the _zed optspecs, but all the desired combinations seem to work
and all the undesired ones seem not to.

Inlined and attached, again.

diff --git a/Completion/Zsh/Command/_zed b/Completion/Zsh/Command/_zed
index 6b68fad..cb90dde 100644
--- a/Completion/Zsh/Command/_zed
+++ b/Completion/Zsh/Command/_zed
@@ -1,10 +1,14 @@
-#compdef zed fned
+#compdef zed fned histed

 case $service in
 (fned) _arguments -S : ':shell function:_functions';;
+(histed) _arguments -S : \
+    '1:history file:_files' \
+    '2:history size: ';;
 (zed) _arguments -S : \
     '(- 2):file:_files' \
-    '(1):shell function:_functions' \
-    '(1)-x+[specify spaces to use for indentation in function
expansion]:spaces' \
-    '(1)-f[edit function]';;
+    '(-h 1 2)-f[edit function]:shell function:_functions' \
+    '(-h 1 2)-x+[specify spaces to use for indentation in function
expansion]:spaces' \
+    '(-f -x 1)-h[edit history]:history file:_files' \
+    '2:history size: ';;
 esac
diff --git a/Functions/Misc/zed b/Functions/Misc/zed
index 9eb4b2d..21aa94f 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,23 +26,28 @@ elif (( $+opts[-x] )); then
 fi

 [[ $0 = fned ]] && fun=1
+[[ $0 = histed ]] && hist=1
+(( hist && $# <= 2 )) && okargs=$#
 (( bind )) && okargs=0

-if (( $# != okargs )); then
+if (( $# != okargs || bind + fun + hist > 1 )); then
     echo 'Usage:
 zed filename
 zed -f [ -x N ] function
+zed -h [ filename [ size ] ]
 zed -b' >&2
     return 1
 fi

 local curcontext=zed:::

-# Matching used in zstyle -m: hide result from caller.
-# Variables not used directly here.
-local -a match mbegin mend
-zstyle -m ":completion:zed:*" insert-tab '*' ||
-    zstyle ":completion:zed:*" insert-tab yes
+() {
+    # Matching used in zstyle -m: hide result from caller.
+    # Variables not used directly here.
+    local -a match mbegin mend
+    zstyle -m ":completion:zed:*" insert-tab '*' ||
+    zstyle ":completion:zed:*" insert-tab yes
+}

 zmodload zsh/terminfo 2>/dev/null

@@ -133,6 +140,28 @@ if ((fun)) then
 }"
   fi
   vared -M zed -m zed-vicmd -i __zed_init var && eval function "$var"
+elif ((hist)) then
+  if [[ -n $1 ]]; then
+    { fc -p -a $1 ${2:-$({ wc -l <$1 } 2>/dev/null)} || return }
+    let HISTSIZE++
+    print -s ""        # Work around fc -p limitation
+  fi
+  var=( "${(@Oav)history:gs/\\/\\\\}" )
+  IFS=$'\n' vared -M zed -m zed-vicmd -i __zed_init var
+  if (( ? )); then
+    [[ -n $1 ]] && unset HISTFILE
+  else
+    local savehist=$#var
+    hist=$HISTSIZE; HISTSIZE=0; fc -R /dev/null
+    if [[ -n $1 ]]; then
+      # Resets on function exit
+      HISTSIZE=$savehist
+      SAVEHIST=$savehist
+    else
+      HISTSIZE=$hist
+    fi
+    for (( hist=1; hist <= savehist; hist++ )) print -rs -- "$var[hist]"
+  fi
 else
   zed_file_name=$1
   [[ -f $1 ]] && var="$(<$1)"
diff --git a/Completion/Zsh/Command/_zed b/Completion/Zsh/Command/_zed
index 6b68fad..cb90dde 100644
--- a/Completion/Zsh/Command/_zed
+++ b/Completion/Zsh/Command/_zed
@@ -1,10 +1,14 @@
-#compdef zed fned
+#compdef zed fned histed
 
 case $service in
 (fned) _arguments -S : ':shell function:_functions';;
+(histed) _arguments -S : \
+	'1:history file:_files' \
+	'2:history size: ';;
 (zed) _arguments -S : \
 	'(- 2):file:_files' \
-	'(1):shell function:_functions' \
-	'(1)-x+[specify spaces to use for indentation in function expansion]:spaces' \
-	'(1)-f[edit function]';;
+	'(-h 1 2)-f[edit function]:shell function:_functions' \
+	'(-h 1 2)-x+[specify spaces to use for indentation in function expansion]:spaces' \
+	'(-f -x 1)-h[edit history]:history file:_files' \
+	'2:history size: ';;
 esac
diff --git a/Functions/Misc/zed b/Functions/Misc/zed
index 9eb4b2d..21aa94f 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,23 +26,28 @@ elif (( $+opts[-x] )); then
 fi
 
 [[ $0 = fned ]] && fun=1
+[[ $0 = histed ]] && hist=1
+(( hist && $# <= 2 )) && okargs=$#
 (( bind )) && okargs=0
 
-if (( $# != okargs )); then
+if (( $# != okargs || bind + fun + hist > 1 )); then
     echo 'Usage:
 zed filename
 zed -f [ -x N ] function
+zed -h [ filename [ size ] ]
 zed -b' >&2
     return 1
 fi
 
 local curcontext=zed:::
 
-# Matching used in zstyle -m: hide result from caller.
-# Variables not used directly here.
-local -a match mbegin mend
-zstyle -m ":completion:zed:*" insert-tab '*' ||
-    zstyle ":completion:zed:*" insert-tab yes
+() {
+    # Matching used in zstyle -m: hide result from caller.
+    # Variables not used directly here.
+    local -a match mbegin mend
+    zstyle -m ":completion:zed:*" insert-tab '*' ||
+	zstyle ":completion:zed:*" insert-tab yes
+}
 
 zmodload zsh/terminfo 2>/dev/null
 
@@ -133,6 +140,28 @@ if ((fun)) then
 }"
   fi
   vared -M zed -m zed-vicmd -i __zed_init var && eval function "$var"
+elif ((hist)) then
+  if [[ -n $1 ]]; then
+    { fc -p -a $1 ${2:-$({ wc -l <$1 } 2>/dev/null)} || return }
+    let HISTSIZE++  
+    print -s ""		# Work around fc -p limitation
+  fi
+  var=( "${(@Oav)history:gs/\\/\\\\}" )
+  IFS=$'\n' vared -M zed -m zed-vicmd -i __zed_init var
+  if (( ? )); then
+    [[ -n $1 ]] && unset HISTFILE
+  else
+    local savehist=$#var
+    hist=$HISTSIZE; HISTSIZE=0; fc -R /dev/null
+    if [[ -n $1 ]]; then
+      # Resets on function exit
+      HISTSIZE=$savehist
+      SAVEHIST=$savehist
+    else
+      HISTSIZE=$hist
+    fi
+    for (( hist=1; hist <= savehist; hist++ )) print -rs -- "$var[hist]"
+  fi
 else
   zed_file_name=$1
   [[ -f $1 ]] && var="$(<$1)"


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