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

history-beginning-local function



This function allows you to have a local history file so that, for
example, you can pick "make" commands appropriate to a local directory
without rendering the history unusable for other operations.  It uses
the "fc -p" command that Wayne added.

The main problem is that you have to create and update the local history
file yourself since commands aren't saved to it.  This is tricky since
it happens in the main shell after zle returns.  We'd need a hook
function of some sort to be able to do the effect of fc -p around the
point the history is saved, unless there's a smarter way of doing it.

There are probably more subtle problems.


# history-beginning-local
#
#   Mostly a drop-in replacement for history-beginning-search-backward
#   or -forward, depending on the name.
#
#   Allows a local history file to be searched for certain commands to execute.
#   The main restriction is that at the moment commands are not saved
#   to the local history file, which needs to be primed by hand
#   (for example, by selecting lines from the global history file).
#
#   The style local-history-file should be set to a file that
#   will contain the local history, in the same format as $HISTFILE,
#   while local-history-commands should be set to a list of commands
#   (or patterns matching commands) that should use the local history
#   file.  Both must be set.
#
#   If the style local-history-only is not set the global history
#   will be searched if there is no match in the local history.
#   The global history is tried again from the most recent entry;
#   no ordering is implied between the two histories.
#
#   If the style local-history-verbose is set a notice is printed
#   below the command line if the local history was searched.
#
#   Styles use the context ":zle:" followed by the widget name followed
#   by a colon.  It is recommended that a wildcard be used at the end
#   to protect against future enhancements.
#
#   For example,
#    zstyle ':zle:*' local-history-file .zsh-local-history
#    zstyle ':zle:*' local-history-commands make gcc gdb

emulate -L zsh
setopt extendedglob

local w lhf
local -a lhc
integer lhv lho restore

zstyle -s ":zle:$WIDGET:" local-history-file lhf || return 1
zstyle -a ":zle:$WIDGET:" local-history-commands lhc || return 1
zstyle -t ":zle:$WIDGET:" local-history-verbose && lhv=1
zstyle -t ":zle:$WIDGET:" local-history-only && lho=1

# try / always block for restoring history
{
  if [[ -f $lhf ]]; then
    integer oldcursor=CURSOR iline
    local new
    local -a words found

    words=(${(z)BUFFER})
    if [[ ${(Q)words[1]} = (${(j.|.)~lhc}) ]]; then
      (( restore = 1 ))
      fc -p $lhf

      # Search history for pattern.
      # As $history is an associative array we can get all matches.
      found=(${(kon)history[(R)${LBUFFER}*]})

      if [[ $WIDGET = *forw* ]]; then
	# Searching forward.  Look back through matches until we
	# get back to the current history number.
	for iline in $found; do
	  (( $iline <= HISTNO )) && break
	  # Skip duplicates.
	  [[ $history[$iline] = $BUFFER ]] || new=$found[$i]
	done
      else
	# Searching backward.  Look forward through matches until we
	# reach the current history number.
	for iline in $found; do
	  (( $iline >= HISTNO )) && break
	  # Skip duplicates.
	  [[ $history[$iline] = $BUFFER ]] || new=$iline
	done
      fi
      if [[ -n $new ]]; then
	# Match found.  Move to line.
	HISTNO=$new
	(( CURSOR = oldcursor ))
	(( lhv )) && zle -M "Matched in local history"
	return 0
      elif (( lho )); then
	(( lhv )) && zle -M "No match in local history"
	return 1
      else
	(( lhv )) && zle -M "No match in local history; falling through"
      fi
    fi
  fi
} always {
  (( restore )) && fc -P
}

if [[ $WIDGET = *forw* ]]; then
  zle history-beginning-search-forward
else
  zle history-beginning-search-backward
fi

if [[ $WIDGET = *-end* ]]; then
  zle end-of-line
fi

# end


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070



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