# 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 style local-history-file should be set to a list of files that # can contain the local history, in the same format as $HISTFILE. # The files are searched in order until the first is find. They # can contain a relative or absolute path; clearly an absolute # path to an existing file will always match. # # local-history-commands should be set to a list of commands # (or patterns matching commands) that should use the local history # file; this can be "*" to handle all commands. Both styles be set. # # Alternatively (or in addition), local-history-pattern is a scalar # that gives a pattern that must match the command line exactly to # initiate use of the mechanism. Typically this will end in a "*". # # 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. (Note # this style is also checked by zshaddhistory-local to decide # whether to save a history entry to the global history.) # # 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 standard form of components separated by colons. # The components are # - The string "zhist": used rather than "zle" to make this consistent # across different functions handling history in different parts of # the shell. # - The widget name # - The current directory as given by $PWD. # There is a terminating colon. It is recommended that a wildcard be # used at the end to protect against future enhancements. # # For example, # zstyle ':zhist:*' local-history-file .zsh-local-history # zstyle ':zhist:*' local-history-commands make gcc gdb emulate -L zsh setopt extendedglob local w f new lhp curline local -a lhf lhc integer lhv lho restore typeset -gA __history_beginning_matches if [[ $WIDGET != $LASTWIDGET ]]; then __history_beginning_matches=() fi integer oldcursor=CURSOR zstyle -a ":zhist:${WIDGET}:${PWD}:" local-history-file lhf || return 1 zstyle -a ":zhist:${WIDGET}:${PWD}:" local-history-commands lhc || return 1 zstyle -s ":zhist:${WIDGET}:${PWD}:" local-history-pattern lhp zstyle -t ":zhist:${WIDGET}:${PWD}:" local-history-verbose && lhv=1 zstyle -t ":zhist:${WIDGET}:${PWD}:" local-history-only && lho=1 # try / always block for restoring history { for f in $lhf; do if [[ -f $f ]]; then integer iline local -a words found words=(${(z)BUFFER}) if [[ ${(Q)words[1]} = (${(j.|.)~lhc}) || \ ( -n $lhp && ${BUFFER} = ${~lhp} ) ]]; then (( restore = 1 )) fc -p $f # Search history for pattern. # As $history is an associative array we can get all matches. if [[ $WIDGET = *forw* ]]; then # Searching forward. Look back through matches until we # get back to the current history number. found=(${(kOn)history[(R)${LBUFFER}*]}) for iline in $found; do (( $iline <= HISTNO )) && break # Skip duplicates. curline=$history[$iline] [[ $curline = $BUFFER ]] && continue [[ -n ${__history_beginning_matches[$curline]} ]] && continue new=$iline done else # Searching backward. Look forward through matches until we # reach the current history number. found=(${(kon)history[(R)${LBUFFER}*]}) for iline in $found; do (( $iline >= HISTNO )) && break # Skip duplicates. curline=$history[$iline] [[ $curline = $BUFFER ]] && continue [[ -n ${__history_beginning_matches[$curline]} ]] && continue new=$iline done fi [[ -n $new ]] && break fc -P (( restore = 0 )) fi fi done if [[ -n $new ]]; then # Match found. Move to line. HISTNO=$new __history_beginning_matches[$history[$HISTNO]]=1 if [[ $WIDGET = *-end* ]]; then zle end-of-line else (( CURSOR = oldcursor )) fi (( 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 } always { (( restore )) && fc -P } if [[ $WIDGET = *forw* ]]; then zle history-beginning-search-forward else zle history-beginning-search-backward fi local stat=$? if (( $stat == 0 )); then __history_beginning_matches[$history[$HISTNO]]=1 fi if [[ $WIDGET = *-end* ]]; then zle end-of-line else (( CURSOR = oldcursor )) fi return $stat # end