28065 plus unposted zsh.mdd:

add cdr and related functions and docs
This commit is contained in:
Peter Stephenson 2010-07-09 14:47:48 +00:00
parent 924f40b772
commit 5da6530d83
9 changed files with 768 additions and 4 deletions

View file

@ -1,3 +1,12 @@
2010-07-09 Peter Stephenson <pws@csr.com>
* 28065: Doc/Zsh/contrib.yo, Functions/Chpwd/.distfiles,
Functions/Chpwd/cdr, Functions/Chpwd/_cdr,
Functions/Chpwd/chpwd_recent_add,
Functions/Chpwd/chpwd_recent_dirs,
Functions/Chpwd/chpwd_recent_filehandler, plus Src/zsh.mdd
(not posted): add cdr function, tools, and documentation.
2010-06-30 Clint Adams <clint@zsh.org>
* 27998, 28061, 28062: Functions/Newuser/zsh-newuser-install:
@ -13343,5 +13352,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.5019 $
* $Revision: 1.5020 $
*****************************************************

View file

@ -11,6 +11,7 @@ such as shell functions, look for comments in the function source files.
startmenu()
menu(Utilities)
menu(Recent Directories)
menu(Version Control Information)
menu(Prompt Themes)
menu(ZLE Functions)
@ -21,7 +22,7 @@ menu(User Configuration Functions)
menu(Other Functions)
endmenu()
texinode(Utilities)(Version Control Information)()(User Contributions)
texinode(Utilities)(Recent Directories)()(User Contributions)
sect(Utilities)
subsect(Accessing On-Line Help)
@ -317,7 +318,270 @@ functions to be executed.
)
enditem()
texinode(Version Control Information)(Prompt Themes)(Utilities)(User Contributions)
texinode(Recent Directories)(Version Control Information)(Utilities)(User
Contributions)
cindex(recent directories, maintaining list of)
cindex(directories, maintaining list of recent)
findex(cdr)
findex(_cdr)
findex(chpwd_recent_add)
findex(chpwd_recent_dirs)
findex(chpwd_recent_filehandler)
sect(Remembering Recent Directories)
The function tt(cdr) allows you to change the working directory to a
previous working directory from a list maintained automatically. It is
similar in concept to the directory stack controlled by the tt(pushd),
tt(popd) and tt(dirs) builtins, but is more configurable, and as it stores
all entries in files it is maintained across sessions and (by default)
between terminal emulators in the current session. (The tt(pushd)
directory stack is not actually modified or used by tt(cdr) unless you
configure it to do so as described in the configuration section below.)
subsect(Installation)
The system works by means of a hook function that is called every time the
directory changes. To install the system, autoload the required functions
and use the tt(add-zsh-hook) function described above:
example(autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs)
Now every time you change directly interactively, no matter which
command you use, the directory to which you change will be remembered
in most-recent-first order.
subsect(Use)
All direct user interaction is via the tt(cdr) function.
The argument to cdr is a number var(N) corresponding to the var(N)th most
recently changed-to directory. 1 is the immediately preceeding directory;
the current directory is remembered but is not offered as a destination.
Note that if you have multiple windows open 1 may refer to a directory
changed to in another window; you can avoid this by having per-terminal
files for storing directory as described for the
tt(recent-dirs-file) style below.
If you set the tt(recent-dirs-default) style described below tt(cdr)
will behave the same as tt(cd) if given a non-numeric argument, or more
than one argument. The recent directory list is updated just the same
however you change directory.
If the argument is omitted, 1 is assumed. This is similar to tt(pushd)'s
behaviour of swapping the two most recent directories on the stack.
Completion for the argument to tt(cdr) is available if compinit has been
run; menu selection is recommended, using:
example(zstyle ':completion:*:*:cdr:*:*' menu selection)
to allow you to cycle through recent directories; the order is preserved,
so the first choice is the most recent directory before the current one.
The verbose style is also recommended to ensure the directory is shown; this
style is on by default so no action is required unless you have changed it.
subsect(Options)
The behaviour of tt(cdr) may be modified by the following options.
startitem()
item(tt(-l))(
lists the numbers and the corresponding directories in
abbreviated form (i.e. with tt(~) substitution reapplied), one per line.
The directories here are not quoted (this would only be an issue if a
directory name contained a newline). This is used by the completion
system.
)
item(tt(-r))(
sets the variable tt(reply) to the current set of directories. Nothing
is printed and the directory is not changed.
)
item(tt(-e))(
allows you to edit the list of directories, one per line. The
list can be edited to any extent you like; no sanity checking is
performed. Completion is available. No quoting is necessary (except for
newlines, where I have in any case no sympathy); directories are in
unabbreviated from and contain an absolute path, i.e. they start with tt(/).
Usually the first entry should be left as the current directory.
)
enditem()
subsect(Configuration)
Configuration is by mean of the styles mechanism that should be familiar
from completion; if not, see the description of the tt(zstyle) command in
ifzman(see zmanref(zshmodules))\
ifnzman(noderef(The zsh/zutil Module)). The context for setting styles
should be tt(':chpwd:*') in case the meaning of the context is extended in
future, for example:
example(zstyle ':chpwd:*' recent-dirs-max 0)
sets the value of the tt(recent-dirs-max) style to 0. In practice the
style name is specific enough that a context of '*' should be fine.
An exception is tt(recent-dirs-insert), which is used exclusively by the
completion system and so has the usual completion system context
(tt(':completion:*') if nothing more specific is needed), though again
tt('*') should be fine in practice.
startitem()
item(tt(recent-dirs-default))(
If true, and the command is expecting a recent directory index, and
either there is more than one argument or the argument is not an
integer, then fall through to "cd". This allows the lazy to use only
one command for directory changing. Completion recognises this, too;
see recent-dirs-insert for how to control completion when this option
is in use.
)
item(tt(recent-dirs-file))(
The file where the list of directories is saved. The default
is tt(${ZDOTDIR:-$HOME}/.chpwd-recent-dirs), i.e. this is in your
home directory unless you have set the variable tt(ZDOTDIR) to point
somewhere else. Directory names are saved in tt($')var(...)tt(') quoted
form, so each line in the file can be supplied directly to the shell as an
argument.
The value of this style may be an array. In this case, the first
file in the list will always be used for saving directories while any
other files are left untouched. When reading the recent directory
list, if there are fewer than the maximum number of entries in the
first file, the contents of later files in the array will be appended
with duplicates removed from the list shown. The contents of the two
files are not sorted together, i.e. all the entries in the first file
are shown first. The special value tt(+) can appear in the list to
indicate the default file should be read at that point. This allows
effects like the following:
example(zstyle recent-dirs-file ':chpwd:*' \
~/.chpwd-recent-dirs-${TTY##*/} +)
Recent directories are read from a file numbered according to
the terminal. If there are insufficient entries the list
is supplemented from the default file.
)
item(tt(recent-dirs-insert))(
Used by completion. If tt(recent-dirs-default) is true, then setting
this to tt(true) causes the actual directory, rather than its index, to
be inserted on the command line; this has the same effect as using
the corresponding index, but makes the history clearer and the line
easier to edit. With this setting, if part of an argument was
already typed, normal directory completion rather than recent
directory completion is done; this is because recent directory
completion is expected to be done by cycling through entries menu
fashion.
If the value of the style is tt(always), then only recent directories will
be completed; in that case, use the tt(cd) command when you want to
complete other directories.
If the value is tt(fallback), recent directories will be tried first, then
normal directory completion is performed if recent directory completion
failed to find a match.
Finally, if the value is tt(both) then both sets of completions are
presented; the usual tag mechanism can be used to distinguish results, with
recent directories tagged as tt(recent-dirs). Note that the recent
directories inserted are abbreviated with directory names where appropriate.
)
item(tt(recent-dirs-max))(
The maximum number of directories to save to the file. If
this is zero or negative there is no maximum. The default is 20.
Note this includes the current directory, which isn't offered,
so the highest number of directories you will be offered
is one less than the maximum.
)
item(tt(recent-dirs-prune))(
This style is an array determining what directories should (or should
not) be added to the recent list. Elements of the array can include:
startitem()
item(tt(parent))(
Prune parents (more accurately, ancestors) from the recent list.
If present, changing directly down by any number of directories
causes the current directory to be overwritten. For example,
changing from ~pws to ~pws/some/other/dir causes ~pws not to be
left on the recent directory stack. This only applies to direct
changes to descendant diretories; earlier directories on the
list are not pruned. For example, changing from ~pws/yet/another
to ~pws/some/other/dir does not cause ~pws to be pruned.
)
item(tt(pattern:var(pattern)))(
Gives a zsh pattern for directories that should not be
added to the recent list (if not already there). This element
can be repeated to add different patterns. For example,
tt('pattern:/tmp(|/*)') stops tt(/tmp) or its descendants from being
added. The tt(EXTENDED_GLOB) option is always turned on for
these patterns.
)
enditem()
)
item(tt(recent-dirs-pushd))(
If set to true, tt(cdr) will use tt(pushd) instead of tt(cd) to change the
directory, so the directory is saved on the directory stack. As the
directory stack is completely separate from the list of files saved
by the mechanism used in this file there is no obvious reason to do
this.
)
enditem()
subsect(Use with dynamic directory naming)
It is possible to refer to recent directories using the dynamic directory
name syntax that appeared in zsh version 4.3.7. If you create and
autoload a function tt(zsh_directory_name) containing the following code,
tt(~[1]) will refer to the most recent directory other than $PWD, and so on.
This also includes completion.
example(if [[ $1 = n ]]; then
if [[ $2 = <-> ]]; then
# Recent directory
typeset -ga reply
autoload -Uz cdr
cdr -r
if [[ -n ${reply[$2]} ]]; then
reply=LPAR()${reply[$2]}RPAR()
return 0
else
reply=LPAR()RPAR()
return 1
fi
fi
elif [[ $1 = c ]]; then
if [[ $PREFIX = <-> || -z $PREFIX ]]; then
typeset -a keys values
values=LPAR()${${(f)"$+LPAR()cdr -l+RPAR()"}/ ##/:}RPAR()
keys=LPAR()${values%%:*}RPAR()
_describe -t dir-index 'recent directory index' \
values keys -V unsorted -S']'
return
fi
fi
return 1)
subsect(Details of directory handling)
This section is for the curious or confused; most users will not
need to know this information.
Recent directories are saved to a file immediately and hence are
preserved across sessions. Note currently no file locking is applied:
the list is updated immediately on interactive commands and nowhere else
(unlike history), and it is assumed you are only going to change
directory in one window at once. This is not safe on shared accounts,
but in any case the system has limited utility when someone else is
changing to a different set of directories behind your back.
To make this a little safer, only directory changes instituted from the
command line, either directly or indirectly through shell function calls
(but not through subshells, evals, traps, completion functions and the
like) are saved. Shell functions should use tt(cd -q) or tt(pushd -q) to
avoid side effects if the change to the directory is to be invisible at the
command line. See the contents of the function tt(chpwd_recent_dirs) for
more details.
texinode(Version Control Information)(Prompt Themes)(Recent Directories)(User Contributions)
sect(Gathering information from version control systems)
cindex(version control utility)

View file

@ -0,0 +1,8 @@
DISTFILES_SRC='
.distfiles
cdr
_cdr
chpwd_recent_add
chpwd_recent_dirs
chpwd_recent_filehandler
'

57
Functions/Chpwd/_cdr Normal file
View file

@ -0,0 +1,57 @@
#compdef cdr
local expl insert_string
integer default insert
zstyle -t ':chpwd:' recent-dirs-default && default=1
if (( default )); then
zstyle -s ':completion:${curcontext}' recent-dirs-insert insert_string
case $insert_string in
(both)
insert=4
;;
(fallback)
insert=3
;;
(always)
insert=2
;;
([tT]*|1|[yY]*)
insert=1
;;
(*)
insert=0
esac
fi
# See if we should fall back to cd completion.
if [[ default -ne 0 && insert -lt 2 && \
( CURRENT -ne 2 || (-n $words[2] && $words[2] != <->) ) ]]; then
$_comps[cd] "$@"
return
fi
local -a values keys
if (( insert )); then
# insert the actual directory, not the number
values=(${${(f)"$(cdr -l)"}##<-> ##})
# Suppress the usual space suffix, since there's no further argument
# and it's useful to be able to edit the directory e.g. add /more/stuff.
if _wanted -V recent-dirs expl 'recent directory' compadd -S '' -Q -a values
then
(( insert == 4 )) || return 0
fi
(( insert >= 3 )) || return
$_comps[cd] "$@"
else
values=(${${(f)"$(cdr -l)"}/ ##/:})
keys=(${values%%:*})
_describe -t dir-index 'recent directory index' values keys -V unsorted
fi

311
Functions/Chpwd/cdr Normal file
View file

@ -0,0 +1,311 @@
# Description
# ===========
#
# Change to a recently used directory recorded in a file so that the
# recent file list persists across sessions.
#
# To use this system,
#
# autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
# add-zsh-hook chpwd chpwd_recent_dirs
#
# (add-zsh-hook appeared in zsh version 4.3.4.) This ensures that all
# directories you change to interactively are registered. The
# chpwd_recent_dirs function does some guesswork to see if you are "really"
# changing directory permanently, see below.
#
# The argument to cdr is a number corresponding to the Nth most recently
# changed-to directory starting at 1 for the immediately preceeding
# directory (the current directory is remembered but is not offered as a
# destination). You can use directory arguments if you set the
# recent-dirs-default style, see below; however, it should be noted
# that if you do you gain nothing over using cd directly (the recent
# directory list is updated in either case).
#
# If the argument is omitted, 1 is assumed.
#
# Completion is available if compinit has been run; menu selection is
# recommended, using
#
# zstyle ':completion:*:*:cdr:*:*' menu selection
#
# and also the verbose style to ensure the directory is shown (this
# is on by default).
#
# Options
# =======
#
# "cdr -l" lists the numbers and the corresponding directories in
# abbreviated form (i.e. with "~" substitution reapplied), one per line.
# The directories here are not quoted (this would only be an issue if a
# directory name contained a newline). This is used by the completion
# system.
#
# "cdr -r" sets the parameter "reply" to the current set of directories.
#
# "cdr -e" allows you to edit the list of directories, one per line. The
# list can be edited to any extent you like; no sanity checking is
# performed. Completion is available. No quoting is necessary (except for
# newlines, where I have in any case no sympathy); directories are in
# unabbreviated from and contain an absolute path, i.e. they start with /
# (and only /). Usually the first entry should be left as the current
# directory.
#
# Details of directory handling
# =============================
#
# Recent directories are saved to a file immediately and hence are
# preserved across sessions. Note currently no file locking is applied:
# the list is updated immediately on interactive commands and nowhere else
# (unlike history), and it is assumed you are only going to change
# directory in one window at once. This is not safe on shared accounts,
# but in any case the system has limited utility when someone else is
# changing to a different set of directories behind your back.
#
# To make this a little safer, only directory changes instituted from the
# command line, either directly or indirectly through shell function calls
# (but not through subshells, evals, traps, completion functions and the
# like) are saved. This works best in versions of the shell from 4.3.11
# which has facilities to check the evaluation context. Shell functions
# should use cd -q or pushd -q to avoid side effects if the change to the
# directory is to be invisible at the command line. See the function
# chpwd_recent_dirs for more details.
#
# Styles
# ======
#
# Various styles are available. The context for setting styles should be
# ':chpwd:*' in case the meaning of the context is extended in future, for
# example:
#
# zstyle ':chpwd:*' recent-dirs-max 0
#
# although the style name is specific enough that a context of '*' should
# be fine in practice. The only exception is recent-dirs-insert, which is
# used exclusively by the completion system and so has the usual completion
# system context (':completion:*' if nothing more specific is needed,
# though again '*' should be fine in practice).
#
# recent-dirs-default
# If true, and the command is expecting a recent directory index, and
# either there is more than one argument or the argument is not an
# integer, then fall through to "cd". This allows the lazy to use only
# one command for directory changing. Completion recognises this, too;
# see recent-dirs-insert for how to control completion when this option
# is in use.
#
# recent-dirs-file
# The file where the list of directories is saved. The default
# is ${ZDOTDIR:-$HOME}/.chpwd-recent-dirs, i.e. this is in your
# home directory unless you have set ZDOTDIR to point somewhere else.
# Directory names are saved in $'...' quoted form, so each line
# in the file can be supplied directly to the shell as an argument.
#
# The value of this style may be an array. In this case, the first
# file in the list will always be used for saving directories while any
# other files are left untouched. When reading the recent directory
# list, if there are fewer than the maximum number of entries in the
# first file, the contents of later files in the array will be appended
# with duplicates removed from the list shown. The contents of the two
# files are not sorted together, i.e. all the entries in the first file
# are shown first. The special value "+" can appear in the list to
# indicate the default file should be read at that point. This allows
# effects like the following:
#
# zstyle recent-dirs-file ':chpwd:*' ~/.chpwd-recent-dirs-${TTY##*/} +
#
# Recent directories are read from a file numbered according to
# the terminal. If there are insufficient entries the list
# is supplemented from the default file.
#
# recent-dirs-insert
# Used by completion. If recent-dirs-default is true, then setting
# this to true causes the actual directory, rather than its index, to
# be inserted on the command line; this has the same effect as using
# the corresponding index, but makes the history clearer and the line
# easier to edit. With this setting, if part of an argument was
# already typed, normal directory completion rather than recent
# directory completion is done; this is because recent directory
# completion is expected to be done by cycling through entries menu
# fashion. However, if the value of the style is "always", then only
# recent directories will be completed; in that case, use the cd
# command when you want to complete other directories. If the value is
# "fallback", recent directories will be tried first, then normal
# directory completion is performed if recent directory completion
# failed to find a match. Finally, if the value is "both" then both
# sets of completions are presented; the usual tag mechanism can be
# used to distinguish results, with recent directories tagged as
# "recent-dirs". Note that the recent directories inserted are
# abbreviated with directory names where appropriate.
#
# recent-dirs-max
# The maximum number of directories to save to the file. If
# this is zero or negative there is no maximum. The default is 20.
# Note this includes the current directory, which isn't offered,
# so the highest number of directories you will be offered
# is one less than the maximum.
#
# recent-dirs-prune
# This style is an array determining what directories should (or should
# not) be added to the recent list. Elements of the array can include:
# parent
# Prune parents (more accurately, ancestors) from the recent list.
# If present, changing directly down by any number of directories
# causes the current directory to be overwritten. For example,
# changing from ~pws to ~pws/some/other/dir causes ~pws not to be
# left on the recent directory stack. This only applies to direct
# changes to descendant diretories; earlier directories on the
# list are not pruned. For example, changing from ~pws/yet/another
# to ~pws/some/other/dir does not cause ~pws to be pruned.
# pattern:<pattern>
# Gives a zsh pattern for directories that should not be
# added to the recent list (if not already there). This element
# can be repeated to add different patterns. For example,
# 'pattern:/tmp(|/*)' stops /tmp or its descendants from being
# added. The EXTENDED_GLOB option is always turned on for
# these patterns.
#
# recent-dirs-pushd
# If set to true, cdr will use pushd instead of cd to change the
# directory, so the directory is saved on the directory stack. As the
# directory stack is completely separate from the list of files saved
# by the mechanism used in this file there is no obvious reason to do
# this.
#
# Use with dynamic directory naming
# =================================
#
# It is possible to refer to recent directories using the dynamic directory
# name syntax that appeared in zsh version 4.3.7. If you create and
# autoload a function zsh_directory_name containing the following code,
# ~[1] will refer to the most recent directory other than $PWD, and so on.
# This also includes completion (version 4.3.11 is required for this to
# work; previous versions needed the file _dynamic_directory_name to
# be overloaded).
#
# if [[ $1 = n ]]; then
# if [[ $2 = <-> ]]; then
# # Recent directory
# typeset -ga reply
# autoload -Uz cdr
# cdr -r
# if [[ -n ${reply[$2]} ]]; then
# reply=(${reply[$2]})
# return 0
# else
# reply=()
# return 1
# fi
# fi
# elif [[ $1 = c ]]; then
# if [[ $PREFIX = <-> || -z $PREFIX ]]; then
# typeset -a keys values
#
# values=(${${(f)"$(cdr -l)"}/ ##/:})
# keys=(${values%%:*})
#
# _describe -t dir-index 'recent directory index' \
# values keys -V unsorted -S']'
# return
# fi
# fi
# return 1
emulate -L zsh
setopt extendedglob
autoload -Uz chpwd_recent_filehandler chpwd_recent_add
integer list set_reply i bad edit
local opt dir
local -aU dirs
while getopts "elr" opt; do
case $opt in
(e)
edit=1
;;
(l)
list=1
;;
(r)
set_reply=1
;;
(*)
return 1
;;
esac
done
shift $(( OPTIND - 1 ))
if (( set_reply )); then
typeset -ga reply
else
local -a reply
fi
if (( list || set_reply || edit )); then
(( $# )) && bad=1
else
if [[ $#1 -eq 0 ]]; then
1=1
elif [[ $# -ne 1 || $1 != <-> ]]; then
if zstyle -t ':chpwd:' recent-dirs-default; then
cd "$@"
return
else
bad=1
fi
fi
fi
if (( bad )); then
print "Usage: $0 [-l | -r | <dir-num> ]
Use $0 -l or completion to see possible directories."
return 1
fi
chpwd_recent_filehandler
if [[ $PWD != $reply[1] ]]; then
# When we first start we don't have the current directory.
# Add it now for consistency.
chpwd_recent_add $PWD && chpwd_recent_filehandler $reply
fi
if (( edit )); then
local compcontext='directories:directory:_path_files -/'
IFS='
' vared reply || return 1
chpwd_recent_filehandler $reply
fi
# Skip current directory if present (may have been pruned).
[[ $reply[1] = $PWD ]] && reply=($reply[2,-1])
if (( list )); then
dirs=($reply)
for (( i = 1; i <= ${#dirs}; i++ )); do
print -n ${(r.5.)i}
print -D ${dirs[i]}
done
return
fi
(( set_reply || edit )) && return
if (( $1 > ${#reply} )); then
print "Not enough directories ($(( ${#dirs} - 1)) possibilities)" >&2
return 1
fi
dir=${reply[$1]}
if zstyle -t ':chpwd:' recent-dirs-pushd; then
pushd -- $dir
else
cd -- $dir
fi

View file

@ -0,0 +1,24 @@
# Helper for chpwd_recent_dirs.
# Add a directory to the reply array unless we're skipping it.
# If skipping, return non-zero status.
local pat
local add=$1
local -a prune patterns
zstyle -a ':chpwd:' recent-dirs-prune prune
if (( ${#prune} )); then
patterns=(${${prune:#^pattern:*}##pattern:})
fi
for pat in $patterns; do
if [[ $add =~ ${~pat} ]]; then
return 1
fi
done
if [[ ${prune[(I)parent]} -ne 0 && $add = $reply[1]/* ]]; then
# replace
reply=($reply[2,-1])
fi
reply=($add $reply)

View file

@ -0,0 +1,49 @@
# Save the current directory in the stack of most recently used directories.
emulate -L zsh
setopt extendedglob
local -aU reply
integer changed
autoload -Uz chpwd_recent_filehandler chpwd_recent_add
# Don't save if this is not interactive, or is in a subshell.
# Don't save if this is not being called directly from the top level
# of the shell via a straightforward sequence of shell functions.
# So this is called
# - on any straightforward cd or pushd (including AUTO_CD)
# - any time cd or pushd is called from a function invoked directly
# or indirectly from the command line, e.g. if pushd is a function
# fixing the order of directories that got broken years ago
# but it is not called any time
# - the shell is not interactive
# - we forked
# - we are being eval'd, including for some special purpose such
# as a style
# - we are not called from the top-level command loop, for example
# we are in a completion function (which is called from zle
# when the main top-level command interpreter isn't running)
# - obviously, when cd -q is in use (that's what the option is for).
#
# For compatibility with older shells, skip this test if $ZSH_EVAL_CONTEXT
# isn't set. This will never be the case inside a shell function when
# the variable is implemented.
if [[ ! -o interactive || $ZSH_SUBSHELL -ne 0 || \
( -n $ZSH_EVAL_CONTEXT && \
$ZSH_EVAL_CONTEXT != toplevel(:[a-z]#func|)# ) ]]; then
return
fi
chpwd_recent_filehandler
if [[ $reply[1] != $PWD ]]; then
if [[ -n $OLDPWD && $reply[1] != $OLDPWD ]]; then
# The first time we change directory we probably don't have
# the initial directory.
chpwd_recent_add $OLDPWD && changed=1
fi
chpwd_recent_add $PWD && changed=1
(( changed )) && chpwd_recent_filehandler $reply
fi

View file

@ -0,0 +1,42 @@
# With arguments, output those files to the recent directory file.
# With no arguments, read in the directories from the file into $reply.
#
# Handles recent-dirs-file and recent-dirs-max styles.
emulate -L zsh
setopt extendedglob
integer max
local file
local -a files
local default=${ZDOTDIR:-$HOME}/.chpwd-recent-dirs
if zstyle -a ':chpwd:' recent-dirs-file files; then
files=(${files//(#s)+(#e)/$default})
fi
if (( ${#files} == 0 )); then
files=($default)
fi
zstyle -s ':chpwd:' recent-dirs-max max || max=20
if (( $# )); then
if (( max > 0 && ${#argv} > max )); then
argv=(${argv[1,max]})
fi
# Quote on write.
# Use $'...' quoting... this fixes newlines and other nastiness.
print -rl ${(qqqq)argv} >${files[1]}
else
typeset -g reply
# Unquote on read.
reply=()
for file in $files; do
[[ -r $file ]] || continue
reply+=(${(Q)${(f)"$(<$file)"}})
if (( max > 0 && ${#reply} >= max )); then
reply=(${reply[1,max]})
break
fi
done
fi

View file

@ -2,7 +2,7 @@ name=zsh/main
link=static
load=yes
# load=static should replace use of alwayslink
functions='Functions/Exceptions/* Functions/Misc/* Functions/MIME/* Functions/Prompts/* Functions/VCS_Info/* Functions/VCS_Info/Backends/*'
functions='Functions/Chpwd/* Functions/Exceptions/* Functions/Misc/* Functions/MIME/* Functions/Prompts/* Functions/VCS_Info/* Functions/VCS_Info/Backends/*'
nozshdep=1
alwayslink=1