diff --git a/Makefile b/Makefile index dcf433d..397da40 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,12 @@ +prefix=/usr/local + +all: + cc -Wall -Wextra -pedantic -o _z_prompt_command z_prompt_command.c + +install: _z_prompt_command + install -m 0755 _z_prompt_command $(prefix)/bin + readme: @groff -man -Tascii z.1 | col -bx -.PHONY: readme +.PHONY: install readme diff --git a/README b/README index 2f39e2d..fd44d44 100644 --- a/README +++ b/README @@ -57,28 +57,27 @@ NOTES Optionally: Set $_Z_CMD to change the command name (default z). Set $_Z_DATA to change the datafile (default $HOME/.z). - Set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution. - Set $_Z_NO_PROMPT_COMMAND to handle PROMPT_COMMAND/precmd your- + Set $_Z_NO_PROMPT_COMMAND to handle PROMPT_COMMAND/precmd your- self. Set $_Z_EXCLUDE_DIRS to an array of directories to exclude. - (These settings should go in .bashrc/.zshrc before the line + (These settings should go in .bashrc/.zshrc before the line added above.) - Install the provided man page z.1 somewhere like + Install the provided man page z.1 somewhere like /usr/local/man/man1. Aging: The rank of directories maintained by z undergoes aging based on a sim- - ple formula. The rank of each entry is incremented every time it is - accessed. When the sum of ranks is greater than 6000, all ranks are + ple formula. The rank of each entry is incremented every time it is + accessed. When the sum of ranks is greater than 6000, all ranks are multiplied by 0.99. Entries with a rank lower than 1 are forgotten. Frecency: Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted - rank that depends on how often and how recently something occurred. As + rank that depends on how often and how recently something occurred. As far as I know, Mozilla came up with the term. - To z, a directory that has low ranking but has been accessed recently - will quickly have higher rank than a directory accessed frequently a + To z, a directory that has low ranking but has been accessed recently + will quickly have higher rank than a directory accessed frequently a long time ago. Frecency is determined at runtime. @@ -86,17 +85,17 @@ NOTES Common: When multiple directories match all queries, and they all have a common prefix, z will cd to the shortest matching directory, without regard to - priority. This has been in effect, if undocumented, for quite some + priority. This has been in effect, if undocumented, for quite some time, but should probably be configurable or reconsidered. Tab Completion: - z supports tab completion. After any number of arguments, press TAB to + z supports tab completion. After any number of arguments, press TAB to complete on directories that match each argument. Due to limitations of - the completion implementations, only the last argument will be com- + the completion implementations, only the last argument will be com- pleted in the shell. - Internally, z decides you've requested a completion if the last argu- - ment passed is an absolute path to an existing directory. This may + Internally, z decides you've requested a completion if the last argu- + ment passed is an absolute path to an existing directory. This may cause unexpected behavior if the last argument to z begins with /. ENVIRONMENT @@ -105,27 +104,23 @@ ENVIRONMENT The contents of the variable $_Z_CMD is aliased to _z 2>&1. If not set, $_Z_CMD defaults to z. - The environment variable $_Z_DATA can be used to control the datafile + The environment variable $_Z_DATA can be used to control the datafile location. If it is not defined, the location defaults to $HOME/.z. - The environment variable $_Z_NO_RESOLVE_SYMLINKS can be set to prevent - resolving of symlinks. If it is not set, symbolic links will be - resolved when added to the datafile. - In bash, z appends a command to the PROMPT_COMMAND environment variable to maintain its database. In zsh, z appends a function _z_precmd to the precmd_functions array. - The environment variable $_Z_NO_PROMPT_COMMAND can be set if you want + The environment variable $_Z_NO_PROMPT_COMMAND can be set if you want to handle PROMPT_COMMAND or precmd yourself. - The environment variable $_Z_EXCLUDE_DIRS can be set to an array of + The environment variable $_Z_EXCLUDE_DIRS can be set to an array of directories to exclude from tracking. $HOME is always excluded. Direc- tories must be full paths without trailing slashes. FILES - Data is stored in $HOME/.z. This can be overridden by setting the - $_Z_DATA environment variable. When initialized, z will raise an error + Data is stored in $HOME/.z. This can be overridden by setting the + $_Z_DATA environment variable. When initialized, z will raise an error if this path is a directory, and not function correctly. A man page (z.1) is provided. diff --git a/c/Makefile b/c/Makefile deleted file mode 100644 index 23728ab..0000000 --- a/c/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - cc -Wall -Wextra -pedantic -o _z_prompt_command z_prompt_command.c diff --git a/z.1 b/z.1 index a3ce2b7..d687391 100644 --- a/z.1 +++ b/z.1 @@ -75,9 +75,6 @@ Set \fB$_Z_CMD\fR to change the command name (default \fBz\fR). Set \fB$_Z_DATA\fR to change the datafile (default \fB$HOME/.z\fR). .RE .RS -Set \fB$_Z_NO_RESOLVE_SYMLINKS\fR to prevent symlink resolution. -.RE -.RS Set \fB$_Z_NO_PROMPT_COMMAND\fR to handle \fBPROMPT_COMMAND/precmd\fR yourself. .RE .RS @@ -132,10 +129,6 @@ set, \fB$_Z_CMD\fR defaults to \fBz\fR. The environment variable \fB$_Z_DATA\fR can be used to control the datafile location. If it is not defined, the location defaults to \fB$HOME/.z\fR. .P -The environment variable \fB$_Z_NO_RESOLVE_SYMLINKS\fR can be set to prevent -resolving of symlinks. If it is not set, symbolic links will be resolved when -added to the datafile. -.P In bash, \fBz\fR appends a command to the \fBPROMPT_COMMAND\fR environment variable to maintain its database. In zsh, \fBz\fR appends a function \fB_z_precmd\fR to the \fBprecmd_functions\fR array. diff --git a/z.sh b/z.sh index bcc9112..2230904 100644 --- a/z.sh +++ b/z.sh @@ -33,56 +33,8 @@ _z() { # bail if we don't own ~/.z (we're another user but our ENV is still set) [ -f "$datafile" -a ! -O "$datafile" ] && return - # add entries - if [ "$1" = "--add" ]; then - shift - - # $HOME isn't worth matching - [ "$*" = "$HOME" ] && return - - # don't track excluded dirs - local exclude - for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do - [ "$*" = "$exclude" ] && return - done - - # maintain the data file - local tempfile="$datafile.$RANDOM" - while read line; do - # only count directories - [ -d "${line%%\|*}" ] && echo $line - done < "$datafile" | awk -v path="$*" -v now="$(date +%s)" -F"|" ' - BEGIN { - rank[path] = 1 - time[path] = now - } - $2 >= 1 { - # drop ranks below 1 - if( $1 == path ) { - rank[$1] = $2 + 1 - time[$1] = now - } else { - rank[$1] = $2 - time[$1] = $3 - } - count += $2 - } - END { - if( count > 6000 ) { - # aging - for( x in rank ) print x "|" 0.99*rank[x] "|" time[x] - } else for( x in rank ) print x "|" rank[x] "|" time[x] - } - ' 2>/dev/null >| "$tempfile" - # do our best to avoid clobbering the datafile in a race condition - if [ $? -ne 0 -a -f "$datafile" ]; then - env rm -f "$tempfile" - else - env mv -f "$tempfile" "$datafile" || env rm -f "$tempfile" - fi - # tab completion - elif [ "$1" = "--complete" ]; then + if [ "$1" = "--complete" ]; then while read line; do [ -d "${line%%\|*}" ] && echo $line done < "$datafile" | awk -v q="$2" -F"|" ' @@ -202,21 +154,13 @@ _z() { alias ${_Z_CMD:-z}='_z 2>&1' -[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P" - if compctl >/dev/null 2>&1; then # zsh [ "$_Z_NO_PROMPT_COMMAND" ] || { # populate directory list, avoid clobbering any other precmds. - if [ "$_Z_NO_RESOLVE_SYMLINKS" ]; then - _z_precmd() { - _z --add "${PWD:a}" - } - else - _z_precmd() { - _z --add "${PWD:A}" - } - fi + _z_precmd() { + /usr/local/bin/_z_prompt_command + } [[ -n "${precmd_functions[(r)_z_precmd]}" ]] || { precmd_functions[$(($#precmd_functions+1))]=_z_precmd } @@ -234,8 +178,8 @@ elif complete >/dev/null 2>&1; then complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z} [ "$_Z_NO_PROMPT_COMMAND" ] || { # populate directory list. avoid clobbering other PROMPT_COMMANDs. - grep "_z --add" <<< "$PROMPT_COMMAND" >/dev/null || { - PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''_z --add "$(pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null;' + grep "_z_prompt_command" <<< "$PROMPT_COMMAND" >/dev/null || { + PROMPT_COMMAND="$PROMPT_COMMAND"$'\n'"/usr/local/bin/_z_prompt_command;" } } fi diff --git a/c/z_prompt_command.c b/z_prompt_command.c similarity index 100% rename from c/z_prompt_command.c rename to z_prompt_command.c