mirror of
				https://github.com/ohmyzsh/ohmyzsh.git
				synced 2025-11-04 13:21:19 +08:00 
			
		
		
		
	ohmyzsh plugin of the z project: https://github.com/rupa/z
This commit is contained in:
		
							parent
							
								
									b8b241f630
								
							
						
					
					
						commit
						e4fb94306a
					
				
							
								
								
									
										4
									
								
								plugins/z/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								plugins/z/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
readme:
 | 
			
		||||
	@groff -man -Tascii z.1 | col -bx
 | 
			
		||||
 | 
			
		||||
.PHONY: readme
 | 
			
		||||
							
								
								
									
										135
									
								
								plugins/z/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								plugins/z/README
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,135 @@
 | 
			
		||||
Z(1)                             User Commands                            Z(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NAME
 | 
			
		||||
       z - jump around
 | 
			
		||||
 | 
			
		||||
SYNOPSIS
 | 
			
		||||
       z [-chlrt] [regex1 regex2 ... regexn]
 | 
			
		||||
 | 
			
		||||
AVAILABILITY
 | 
			
		||||
       bash, zsh
 | 
			
		||||
 | 
			
		||||
DESCRIPTION
 | 
			
		||||
       Tracks your most used directories, based on 'frecency'.
 | 
			
		||||
 | 
			
		||||
       After  a  short  learning  phase, z will take you to the most 'frecent'
 | 
			
		||||
       directory that matches ALL of the regexes given on the command line.
 | 
			
		||||
 | 
			
		||||
OPTIONS
 | 
			
		||||
       -c     restrict matches to subdirectories of the current directory.
 | 
			
		||||
 | 
			
		||||
       -h     show a brief help message
 | 
			
		||||
 | 
			
		||||
       -l     list only
 | 
			
		||||
 | 
			
		||||
       -r     match by rank only
 | 
			
		||||
 | 
			
		||||
       -t     match by recent access only
 | 
			
		||||
 | 
			
		||||
EXAMPLES
 | 
			
		||||
       z foo         cd to most frecent dir matching foo
 | 
			
		||||
 | 
			
		||||
       z foo bar     cd to most frecent dir matching foo and bar
 | 
			
		||||
 | 
			
		||||
       z -r foo      cd to highest ranked dir matching foo
 | 
			
		||||
 | 
			
		||||
       z -t foo      cd to most recently accessed dir matching foo
 | 
			
		||||
 | 
			
		||||
       z -l foo      list all dirs matching foo (by frecency)
 | 
			
		||||
 | 
			
		||||
NOTES
 | 
			
		||||
   Installation:
 | 
			
		||||
       Put something like this in your $HOME/.bashrc or $HOME/.zshrc:
 | 
			
		||||
 | 
			
		||||
              . /path/to/z.sh
 | 
			
		||||
 | 
			
		||||
       cd around for a while to build up the db.
 | 
			
		||||
 | 
			
		||||
       PROFIT!!
 | 
			
		||||
 | 
			
		||||
       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-
 | 
			
		||||
              self.
 | 
			
		||||
              Set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
 | 
			
		||||
              (These  settings  should  go  in .bashrc/.zshrc before the lines
 | 
			
		||||
              added above.)
 | 
			
		||||
              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
 | 
			
		||||
       multiplied by 0.99. Entries with a rank lower than 1 are forgotten.
 | 
			
		||||
 | 
			
		||||
   Frecency:
 | 
			
		||||
       Frecency is a portmantaeu of 'recent' and 'frequency'. It is a weighted
 | 
			
		||||
       rank  that  depends on how often and how recently something occured. 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
 | 
			
		||||
       long time ago.
 | 
			
		||||
 | 
			
		||||
       Frecency is determined at runtime.
 | 
			
		||||
 | 
			
		||||
   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
 | 
			
		||||
       time, but should probably be configurable or reconsidered.
 | 
			
		||||
 | 
			
		||||
   Tab Completion:
 | 
			
		||||
       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-
 | 
			
		||||
       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
 | 
			
		||||
       cause unexpected behavior if the last argument to z begins with /.
 | 
			
		||||
 | 
			
		||||
ENVIRONMENT
 | 
			
		||||
       A function _z() is defined.
 | 
			
		||||
 | 
			
		||||
       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
 | 
			
		||||
       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 prepends a command to the PROMPT_COMMAND  environment  vari-
 | 
			
		||||
       able  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
 | 
			
		||||
       to handle PROMPT_COMMAND or precmd yourself.
 | 
			
		||||
 | 
			
		||||
       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
 | 
			
		||||
       if this path is a directory, and not function correctly.
 | 
			
		||||
 | 
			
		||||
       A man page (z.1) is provided.
 | 
			
		||||
 | 
			
		||||
SEE ALSO
 | 
			
		||||
       regex(7), pushd, popd, autojump, cdargs
 | 
			
		||||
 | 
			
		||||
       Please file bugs at https://github.com/rupa/z/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
z                                January 2013                             Z(1)
 | 
			
		||||
							
								
								
									
										155
									
								
								plugins/z/z.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								plugins/z/z.1
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,155 @@
 | 
			
		||||
.TH "Z" "1" "January 2013" "z" "User Commands"
 | 
			
		||||
.SH
 | 
			
		||||
NAME
 | 
			
		||||
z \- jump around
 | 
			
		||||
.SH
 | 
			
		||||
SYNOPSIS
 | 
			
		||||
z [\-chlrt] [regex1 regex2 ... regexn]
 | 
			
		||||
.SH
 | 
			
		||||
AVAILABILITY
 | 
			
		||||
bash, zsh
 | 
			
		||||
.SH
 | 
			
		||||
DESCRIPTION
 | 
			
		||||
Tracks your most used directories, based on 'frecency'.
 | 
			
		||||
.P
 | 
			
		||||
After a short learning phase, \fBz\fR will take you to the most 'frecent'
 | 
			
		||||
directory that matches ALL of the regexes given on the command line.
 | 
			
		||||
.SH
 | 
			
		||||
OPTIONS
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-c\fR
 | 
			
		||||
restrict matches to subdirectories of the current directory.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-h\fR
 | 
			
		||||
show a brief help message
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-l\fR
 | 
			
		||||
list only
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-r\fR
 | 
			
		||||
match by rank only
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-t\fR
 | 
			
		||||
match by recent access only
 | 
			
		||||
.SH EXAMPLES
 | 
			
		||||
.TP 14
 | 
			
		||||
\fBz foo\fR
 | 
			
		||||
cd to most frecent dir matching foo
 | 
			
		||||
.TP 14
 | 
			
		||||
\fBz foo bar\fR
 | 
			
		||||
cd to most frecent dir matching foo and bar
 | 
			
		||||
.TP 14
 | 
			
		||||
\fBz -r foo\fR
 | 
			
		||||
cd to highest ranked dir matching foo
 | 
			
		||||
.TP 14
 | 
			
		||||
\fBz -t foo\fR
 | 
			
		||||
cd to most recently accessed dir matching foo
 | 
			
		||||
.TP 14
 | 
			
		||||
\fBz -l foo\fR
 | 
			
		||||
list all dirs matching foo (by frecency)
 | 
			
		||||
.SH
 | 
			
		||||
NOTES
 | 
			
		||||
.SS
 | 
			
		||||
Installation:
 | 
			
		||||
.P
 | 
			
		||||
Put something like this in your \fB$HOME/.bashrc\fR or \fB$HOME/.zshrc\fR:
 | 
			
		||||
.RS
 | 
			
		||||
.P
 | 
			
		||||
\fB. /path/to/z.sh\fR
 | 
			
		||||
.RE
 | 
			
		||||
.P
 | 
			
		||||
\fBcd\fR around for a while to build up the db.
 | 
			
		||||
.P
 | 
			
		||||
PROFIT!!
 | 
			
		||||
.P
 | 
			
		||||
Optionally:
 | 
			
		||||
.RS
 | 
			
		||||
Set \fB$_Z_CMD\fR to change the command name (default \fBz\fR).
 | 
			
		||||
.RE
 | 
			
		||||
.RS
 | 
			
		||||
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
 | 
			
		||||
Set \fB$_Z_EXCLUDE_DIRS\fR to an array of directories to exclude.
 | 
			
		||||
.RE
 | 
			
		||||
.RS
 | 
			
		||||
(These settings should go in .bashrc/.zshrc before the lines added above.)
 | 
			
		||||
.RE
 | 
			
		||||
.RS
 | 
			
		||||
Install the provided man page \fBz.1\fR somewhere like \fB/usr/local/man/man1\fR.
 | 
			
		||||
.RE
 | 
			
		||||
.SS
 | 
			
		||||
Aging:
 | 
			
		||||
The rank of directories maintained by \fBz\fR undergoes aging based on a simple
 | 
			
		||||
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.
 | 
			
		||||
.SS
 | 
			
		||||
Frecency:
 | 
			
		||||
Frecency is a portmantaeu of 'recent' and 'frequency'. It is a weighted rank
 | 
			
		||||
that depends on how often and how recently something occured. As far as I
 | 
			
		||||
know, Mozilla came up with the term.
 | 
			
		||||
.P
 | 
			
		||||
To \fBz\fR, 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.
 | 
			
		||||
.P
 | 
			
		||||
Frecency is determined at runtime.
 | 
			
		||||
.SS
 | 
			
		||||
Common:
 | 
			
		||||
When multiple directories match all queries, and they all have a common prefix,
 | 
			
		||||
\fBz\fR will cd to the shortest matching directory, without regard to priority.
 | 
			
		||||
This has been in effect, if undocumented, for quite some time, but should
 | 
			
		||||
probably be configurable or reconsidered.
 | 
			
		||||
.SS
 | 
			
		||||
Tab Completion:
 | 
			
		||||
\fBz\fR 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 completed in the
 | 
			
		||||
shell.
 | 
			
		||||
.P
 | 
			
		||||
Internally, \fBz\fR decides you've requested a completion if the last argument
 | 
			
		||||
passed is an absolute path to an existing directory. This may cause unexpected
 | 
			
		||||
behavior if the last argument to \fBz\fR begins with \fB/\fR.
 | 
			
		||||
.SH
 | 
			
		||||
ENVIRONMENT
 | 
			
		||||
A function \fB_z()\fR is defined.
 | 
			
		||||
.P
 | 
			
		||||
The contents of the variable \fB$_Z_CMD\fR is aliased to \fB_z 2>&1\fR. If not
 | 
			
		||||
set, \fB$_Z_CMD\fR defaults to \fBz\fR.
 | 
			
		||||
.P
 | 
			
		||||
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 prepends 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.
 | 
			
		||||
.P
 | 
			
		||||
The environment variable \fB$_Z_NO_PROMPT_COMMAND\fR can be set if you want to
 | 
			
		||||
handle \fBPROMPT_COMMAND\fR or \fBprecmd\fR yourself.
 | 
			
		||||
.P
 | 
			
		||||
The environment variable \fB$_Z_EXCLUDE_DIRS\fR can be set to an array of
 | 
			
		||||
directories to exclude from tracking. \fB$HOME\fR is always excluded.
 | 
			
		||||
Directories must be full paths without trailing slashes.
 | 
			
		||||
.SH
 | 
			
		||||
FILES
 | 
			
		||||
Data is stored in \fB$HOME/.z\fR. This can be overridden by setting the
 | 
			
		||||
\fB$_Z_DATA\fR environment variable. When initialized, \fBz\fR will raise an
 | 
			
		||||
error if this path is a directory, and not function correctly.
 | 
			
		||||
.P
 | 
			
		||||
A man page (\fBz.1\fR) is provided.
 | 
			
		||||
.SH
 | 
			
		||||
SEE ALSO
 | 
			
		||||
regex(7), pushd, popd, autojump, cdargs
 | 
			
		||||
.P
 | 
			
		||||
Please file bugs at https://github.com/rupa/z/
 | 
			
		||||
							
								
								
									
										6
									
								
								plugins/z/z.plugin.zsh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugins/z/z.plugin.zsh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
_load_z() {
 | 
			
		||||
  source $1/z.sh
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[[ -f $ZSH_CUSTOM/plugins/z/z.plugin.zsh ]] && _load_z $ZSH_CUSTOM/plugins/z
 | 
			
		||||
[[ -f $ZSH/plugins/z/z.plugin.zsh ]] && _load_z $ZSH/plugins/z
 | 
			
		||||
							
								
								
									
										228
									
								
								plugins/z/z.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								plugins/z/z.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,228 @@
 | 
			
		||||
# Copyright (c) 2009 rupa deadwyler under the WTFPL license
 | 
			
		||||
 | 
			
		||||
# maintains a jump-list of the directories you actually use
 | 
			
		||||
#
 | 
			
		||||
# INSTALL:
 | 
			
		||||
#   * put something like this in your .bashrc/.zshrc:
 | 
			
		||||
#     . /path/to/z.sh
 | 
			
		||||
#   * cd around for a while to build up the db
 | 
			
		||||
#   * PROFIT!!
 | 
			
		||||
#   * optionally:
 | 
			
		||||
#     set $_Z_CMD in .bashrc/.zshrc to change the command (default z).
 | 
			
		||||
#     set $_Z_DATA in .bashrc/.zshrc to change the datafile (default ~/.z).
 | 
			
		||||
#     set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution.
 | 
			
		||||
#     set $_Z_NO_PROMPT_COMMAND if you're handling PROMPT_COMMAND yourself.
 | 
			
		||||
#     set $_Z_EXCLUDE_DIRS to an array of directories to exclude.
 | 
			
		||||
#
 | 
			
		||||
# USE:
 | 
			
		||||
#   * z foo     # cd to most frecent dir matching foo
 | 
			
		||||
#   * z foo bar # cd to most frecent dir matching foo and bar
 | 
			
		||||
#   * z -r foo  # cd to highest ranked dir matching foo
 | 
			
		||||
#   * z -t foo  # cd to most recently accessed dir matching foo
 | 
			
		||||
#   * z -l foo  # list matches instead of cd
 | 
			
		||||
#   * z -c foo  # restrict matches to subdirs of $PWD
 | 
			
		||||
 | 
			
		||||
case $- in
 | 
			
		||||
 *i*) ;;
 | 
			
		||||
   *) echo 'ERROR: z.sh is meant to be sourced, not directly executed.'
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
[ -d "${_Z_DATA:-$HOME/.z}" ] && {
 | 
			
		||||
    echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory."
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_z() {
 | 
			
		||||
 | 
			
		||||
 local datafile="${_Z_DATA:-$HOME/.z}"
 | 
			
		||||
 | 
			
		||||
 # bail out 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 file
 | 
			
		||||
  local tempfile
 | 
			
		||||
  tempfile="$(mktemp "$datafile.XXXXXX")" || return
 | 
			
		||||
  while read line; do
 | 
			
		||||
   [ -d "${line%%\|*}" ] && echo $line
 | 
			
		||||
  done < "$datafile" | awk -v path="$*" -v now="$(date +%s)" -F"|" '
 | 
			
		||||
   BEGIN {
 | 
			
		||||
    rank[path] = 1
 | 
			
		||||
    time[path] = now
 | 
			
		||||
   }
 | 
			
		||||
   $2 >= 1 {
 | 
			
		||||
    if( $1 == path ) {
 | 
			
		||||
     rank[$1] = $2 + 1
 | 
			
		||||
     time[$1] = now
 | 
			
		||||
    } else {
 | 
			
		||||
     rank[$1] = $2
 | 
			
		||||
     time[$1] = $3
 | 
			
		||||
    }
 | 
			
		||||
    count += $2
 | 
			
		||||
   }
 | 
			
		||||
   END {
 | 
			
		||||
    if( count > 6000 ) {
 | 
			
		||||
     for( i in rank ) print i "|" 0.99*rank[i] "|" time[i] # aging
 | 
			
		||||
    } else for( i in rank ) print i "|" rank[i] "|" time[i]
 | 
			
		||||
   }
 | 
			
		||||
  ' 2>/dev/null >| "$tempfile"
 | 
			
		||||
  if [ $? -ne 0 -a -f "$datafile" ]; then
 | 
			
		||||
   env rm -f "$tempfile"
 | 
			
		||||
  else
 | 
			
		||||
   env mv -f "$tempfile" "$datafile"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
 # tab completion
 | 
			
		||||
 elif [ "$1" = "--complete" ]; then
 | 
			
		||||
  while read line; do
 | 
			
		||||
   [ -d "${line%%\|*}" ] && echo $line
 | 
			
		||||
  done < "$datafile" | awk -v q="$2" -F"|" '
 | 
			
		||||
   BEGIN {
 | 
			
		||||
    if( q == tolower(q) ) nocase = 1
 | 
			
		||||
    split(substr(q,3),fnd," ")
 | 
			
		||||
   }
 | 
			
		||||
   {
 | 
			
		||||
    if( nocase ) {
 | 
			
		||||
     for( i in fnd ) tolower($1) !~ tolower(fnd[i]) && $1 = ""
 | 
			
		||||
    } else {
 | 
			
		||||
     for( i in fnd ) $1 !~ fnd[i] && $1 = ""
 | 
			
		||||
    }
 | 
			
		||||
    if( $1 ) print $1
 | 
			
		||||
   }
 | 
			
		||||
  ' 2>/dev/null
 | 
			
		||||
 | 
			
		||||
 else
 | 
			
		||||
  # list/go
 | 
			
		||||
  while [ "$1" ]; do case "$1" in
 | 
			
		||||
   --) while [ "$1" ]; do shift; local fnd="$fnd $1";done;;
 | 
			
		||||
   -*) local opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in
 | 
			
		||||
        c) local fnd="^$PWD $fnd";;
 | 
			
		||||
        h) echo "${_Z_CMD:-z} [-chlrt] args" >&2; return;;
 | 
			
		||||
        l) local list=1;;
 | 
			
		||||
        r) local typ="rank";;
 | 
			
		||||
        t) local typ="recent";;
 | 
			
		||||
       esac; opt=${opt:1}; done;;
 | 
			
		||||
    *) local fnd="$fnd $1";;
 | 
			
		||||
  esac; local last=$1; shift; done
 | 
			
		||||
  [ "$fnd" -a "$fnd" != "^$PWD " ] || local list=1
 | 
			
		||||
 | 
			
		||||
  # if we hit enter on a completion just go there
 | 
			
		||||
  case "$last" in
 | 
			
		||||
   # completions will always start with /
 | 
			
		||||
   /*) [ -z "$list" -a -d "$last" ] && cd "$last" && return;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  # no file yet
 | 
			
		||||
  [ -f "$datafile" ] || return
 | 
			
		||||
 | 
			
		||||
  local cd
 | 
			
		||||
  cd="$(while read line; do
 | 
			
		||||
   [ -d "${line%%\|*}" ] && echo $line
 | 
			
		||||
  done < "$datafile" | awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" '
 | 
			
		||||
   function frecent(rank, time) {
 | 
			
		||||
    dx = t-time
 | 
			
		||||
    if( dx < 3600 ) return rank*4
 | 
			
		||||
    if( dx < 86400 ) return rank*2
 | 
			
		||||
    if( dx < 604800 ) return rank/2
 | 
			
		||||
    return rank/4
 | 
			
		||||
   }
 | 
			
		||||
   function output(files, toopen, override) {
 | 
			
		||||
    if( list ) {
 | 
			
		||||
     cmd = "sort -n >&2"
 | 
			
		||||
     for( i in files ) if( files[i] ) printf "%-10s %s\n", files[i], i | cmd
 | 
			
		||||
     if( override ) printf "%-10s %s\n", "common:", override > "/dev/stderr"
 | 
			
		||||
    } else {
 | 
			
		||||
     if( override ) toopen = override
 | 
			
		||||
     print toopen
 | 
			
		||||
    }
 | 
			
		||||
   }
 | 
			
		||||
   function common(matches) {
 | 
			
		||||
    # shortest match
 | 
			
		||||
    for( i in matches ) {
 | 
			
		||||
     if( matches[i] && (!short || length(i) < length(short)) ) short = i
 | 
			
		||||
    }
 | 
			
		||||
    if( short == "/" ) return
 | 
			
		||||
    # shortest match must be common to each match. escape special characters in
 | 
			
		||||
    # a copy when testing, so we can return the original.
 | 
			
		||||
    clean_short = short
 | 
			
		||||
    gsub(/[\(\)\[\]\|]/, "\\\\&", clean_short)
 | 
			
		||||
    for( i in matches ) if( matches[i] && i !~ clean_short ) return
 | 
			
		||||
    return short
 | 
			
		||||
   }
 | 
			
		||||
   BEGIN { split(q, a, " "); oldf = noldf = -9999999999 }
 | 
			
		||||
   {
 | 
			
		||||
    if( typ == "rank" ) {
 | 
			
		||||
     f = $2
 | 
			
		||||
    } else if( typ == "recent" ) {
 | 
			
		||||
     f = $3-t
 | 
			
		||||
    } else f = frecent($2, $3)
 | 
			
		||||
    wcase[$1] = nocase[$1] = f
 | 
			
		||||
    for( i in a ) {
 | 
			
		||||
     if( $1 !~ a[i] ) delete wcase[$1]
 | 
			
		||||
     if( tolower($1) !~ tolower(a[i]) ) delete nocase[$1]
 | 
			
		||||
    }
 | 
			
		||||
    if( wcase[$1] && wcase[$1] > oldf ) {
 | 
			
		||||
     cx = $1
 | 
			
		||||
     oldf = wcase[$1]
 | 
			
		||||
    } else if( nocase[$1] && nocase[$1] > noldf ) {
 | 
			
		||||
     ncx = $1
 | 
			
		||||
     noldf = nocase[$1]
 | 
			
		||||
    }
 | 
			
		||||
   }
 | 
			
		||||
   END {
 | 
			
		||||
    if( cx ) {
 | 
			
		||||
     output(wcase, cx, common(wcase))
 | 
			
		||||
    } else if( ncx ) output(nocase, ncx, common(nocase))
 | 
			
		||||
   }
 | 
			
		||||
  ')"
 | 
			
		||||
  [ $? -gt 0 ] && return
 | 
			
		||||
  [ "$cd" ] && cd "$cd"
 | 
			
		||||
 fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
alias ${_Z_CMD:-z}='_z 2>&1'
 | 
			
		||||
 | 
			
		||||
[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P"
 | 
			
		||||
 | 
			
		||||
if compctl &> /dev/null; then
 | 
			
		||||
 [ "$_Z_NO_PROMPT_COMMAND" ] || {
 | 
			
		||||
  # zsh 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
 | 
			
		||||
  precmd_functions+=(_z_precmd)
 | 
			
		||||
 }
 | 
			
		||||
 # zsh tab completion
 | 
			
		||||
 _z_zsh_tab_completion() {
 | 
			
		||||
  local compl
 | 
			
		||||
  read -l compl
 | 
			
		||||
  reply=(${(f)"$(_z --complete "$compl")"})
 | 
			
		||||
 }
 | 
			
		||||
 compctl -U -K _z_zsh_tab_completion _z
 | 
			
		||||
elif complete &> /dev/null; then
 | 
			
		||||
 # bash tab completion
 | 
			
		||||
 complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z}
 | 
			
		||||
 [ "$_Z_NO_PROMPT_COMMAND" ] || {
 | 
			
		||||
  # bash populate directory list. avoid clobbering other PROMPT_COMMANDs.
 | 
			
		||||
  echo $PROMPT_COMMAND | grep -q "_z --add" || {
 | 
			
		||||
   PROMPT_COMMAND='_z --add "$(pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null;'"$PROMPT_COMMAND"
 | 
			
		||||
  }
 | 
			
		||||
 }
 | 
			
		||||
fi
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user