mirror of
				https://github.com/ohmyzsh/ohmyzsh.git
				synced 2024-05-11 05:55:17 +00:00 
			
		
		
		
	@@ -6,7 +6,7 @@ NAME
 | 
			
		||||
       z - jump around
 | 
			
		||||
 | 
			
		||||
SYNOPSIS
 | 
			
		||||
       z [-chlrt] [regex1 regex2 ... regexn]
 | 
			
		||||
       z [-chlrtx] [regex1 regex2 ... regexn]
 | 
			
		||||
 | 
			
		||||
AVAILABILITY
 | 
			
		||||
       bash, zsh
 | 
			
		||||
@@ -15,10 +15,13 @@ 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.
 | 
			
		||||
       directory that matches ALL of the regexes given on the command line, in
 | 
			
		||||
       order.
 | 
			
		||||
 | 
			
		||||
       For example, z foo bar would match /foo/bar but not /bar/foo.
 | 
			
		||||
 | 
			
		||||
OPTIONS
 | 
			
		||||
       -c     restrict matches to subdirectories of the current directory.
 | 
			
		||||
       -c     restrict matches to subdirectories of the current directory
 | 
			
		||||
 | 
			
		||||
       -h     show a brief help message
 | 
			
		||||
 | 
			
		||||
@@ -28,10 +31,12 @@ OPTIONS
 | 
			
		||||
 | 
			
		||||
       -t     match by recent access only
 | 
			
		||||
 | 
			
		||||
       -x     remove the current directory from the datafile
 | 
			
		||||
 | 
			
		||||
EXAMPLES
 | 
			
		||||
       z foo         cd to most frecent dir matching foo
 | 
			
		||||
 | 
			
		||||
       z foo bar     cd to most frecent dir matching foo and bar
 | 
			
		||||
       z foo bar     cd to most frecent dir matching foo, then bar
 | 
			
		||||
 | 
			
		||||
       z -r foo      cd to highest ranked dir matching foo
 | 
			
		||||
 | 
			
		||||
@@ -55,8 +60,9 @@ NOTES
 | 
			
		||||
              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
 | 
			
		||||
              Set $_Z_EXCLUDE_DIRS to an array of directory trees to  exclude.
 | 
			
		||||
              Set $_Z_OWNER to allow usage when in 'sudo -s' mode.
 | 
			
		||||
              (These  settings  should  go  in  .bashrc/.zshrc before the line
 | 
			
		||||
              added above.)
 | 
			
		||||
              Install   the   provided   man   page   z.1    somewhere    like
 | 
			
		||||
              /usr/local/man/man1.
 | 
			
		||||
@@ -64,12 +70,12 @@ NOTES
 | 
			
		||||
   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.
 | 
			
		||||
       accessed.  When the sum of ranks is over 9000, 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
 | 
			
		||||
       Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted
 | 
			
		||||
       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
 | 
			
		||||
@@ -107,20 +113,23 @@ ENVIRONMENT
 | 
			
		||||
       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.
 | 
			
		||||
       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
 | 
			
		||||
       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.
 | 
			
		||||
       directory trees to exclude from tracking.  $HOME  is  always  excluded.
 | 
			
		||||
       Directories must be full paths without trailing slashes.
 | 
			
		||||
 | 
			
		||||
       The  environment  variable  $_Z_OWNER  can  be set to your username, to
 | 
			
		||||
       allow usage of z when your sudo enviroment keeps $HOME set.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ NAME
 | 
			
		||||
z \- jump around
 | 
			
		||||
.SH
 | 
			
		||||
SYNOPSIS
 | 
			
		||||
z [\-chlrt] [regex1 regex2 ... regexn]
 | 
			
		||||
z [\-chlrtx] [regex1 regex2 ... regexn]
 | 
			
		||||
.SH
 | 
			
		||||
AVAILABILITY
 | 
			
		||||
bash, zsh
 | 
			
		||||
@@ -13,12 +13,14 @@ 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.
 | 
			
		||||
directory that matches ALL of the regexes given on the command line, in order.
 | 
			
		||||
 | 
			
		||||
For example, \fBz foo bar\fR would match \fB/foo/bar\fR but not \fB/bar/foo\fR.
 | 
			
		||||
.SH
 | 
			
		||||
OPTIONS
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-c\fR
 | 
			
		||||
restrict matches to subdirectories of the current directory.
 | 
			
		||||
restrict matches to subdirectories of the current directory
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-h\fR
 | 
			
		||||
show a brief help message
 | 
			
		||||
@@ -31,13 +33,16 @@ match by rank only
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-t\fR
 | 
			
		||||
match by recent access only
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-x\fR
 | 
			
		||||
remove the current directory from the datafile
 | 
			
		||||
.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
 | 
			
		||||
cd to most frecent dir matching foo, then bar
 | 
			
		||||
.TP 14
 | 
			
		||||
\fBz -r foo\fR
 | 
			
		||||
cd to highest ranked dir matching foo
 | 
			
		||||
@@ -76,10 +81,13 @@ Set \fB$_Z_NO_RESOLVE_SYMLINKS\fR to prevent symlink resolution.
 | 
			
		||||
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.
 | 
			
		||||
Set \fB$_Z_EXCLUDE_DIRS\fR to an array of directory trees to exclude.
 | 
			
		||||
.RE
 | 
			
		||||
.RS
 | 
			
		||||
(These settings should go in .bashrc/.zshrc before the lines added above.)
 | 
			
		||||
Set \fB$_Z_OWNER\fR to allow usage when in 'sudo -s' mode.
 | 
			
		||||
.RE
 | 
			
		||||
.RS
 | 
			
		||||
(These settings should go in .bashrc/.zshrc before the line added above.)
 | 
			
		||||
.RE
 | 
			
		||||
.RS
 | 
			
		||||
Install the provided man page \fBz.1\fR somewhere like \fB/usr/local/man/man1\fR.
 | 
			
		||||
@@ -88,12 +96,12 @@ Install the provided man page \fBz.1\fR somewhere like \fB/usr/local/man/man1\fR
 | 
			
		||||
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.
 | 
			
		||||
the sum of ranks is over 9000, 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
 | 
			
		||||
Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted rank
 | 
			
		||||
that depends on how often and how recently something occurred. 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
 | 
			
		||||
@@ -131,7 +139,7 @@ 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
 | 
			
		||||
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.
 | 
			
		||||
.P
 | 
			
		||||
@@ -139,8 +147,11 @@ 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.
 | 
			
		||||
directory trees to exclude from tracking. \fB$HOME\fR is always excluded.
 | 
			
		||||
Directories must be full paths without trailing slashes.
 | 
			
		||||
.P
 | 
			
		||||
The environment variable \fB$_Z_OWNER\fR can be set to your username, to
 | 
			
		||||
allow usage of \fBz\fR when your sudo enviroment keeps \fB$HOME\fR set.
 | 
			
		||||
.SH
 | 
			
		||||
FILES
 | 
			
		||||
Data is stored in \fB$HOME/.z\fR. This can be overridden by setting the
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										405
									
								
								plugins/z/z.sh
									
									
									
									
									
								
							
							
						
						
									
										405
									
								
								plugins/z/z.sh
									
									
									
									
									
								
							@@ -3,29 +3,25 @@
 | 
			
		||||
# 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.
 | 
			
		||||
#     * 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.
 | 
			
		||||
#         set $_Z_OWNER to your username if you want use z while sudo with $HOME kept
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
#     * 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
 | 
			
		||||
 | 
			
		||||
[ -d "${_Z_DATA:-$HOME/.z}" ] && {
 | 
			
		||||
    echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory."
 | 
			
		||||
@@ -33,196 +29,215 @@ esac
 | 
			
		||||
 | 
			
		||||
_z() {
 | 
			
		||||
 | 
			
		||||
 local datafile="${_Z_DATA:-$HOME/.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
 | 
			
		||||
    # bail if we don't own ~/.z and $_Z_OWNER not set
 | 
			
		||||
    [ -z "$_Z_OWNER" -a -f "$datafile" -a ! -O "$datafile" ] && return
 | 
			
		||||
 | 
			
		||||
 # add entries
 | 
			
		||||
 if [ "$1" = "--add" ]; then
 | 
			
		||||
  shift
 | 
			
		||||
    # add entries
 | 
			
		||||
    if [ "$1" = "--add" ]; then
 | 
			
		||||
        shift
 | 
			
		||||
 | 
			
		||||
  # $HOME isn't worth matching
 | 
			
		||||
  [ "$*" = "$HOME" ] && return
 | 
			
		||||
        # $HOME isn't worth matching
 | 
			
		||||
        [ "$*" = "$HOME" ] && return
 | 
			
		||||
 | 
			
		||||
  # don't track excluded dirs
 | 
			
		||||
  local exclude
 | 
			
		||||
  for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do
 | 
			
		||||
   [ "$*" = "$exclude" ] && return
 | 
			
		||||
  done
 | 
			
		||||
        # don't track excluded directory trees
 | 
			
		||||
        local exclude
 | 
			
		||||
        for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do
 | 
			
		||||
            case "$*" in "$exclude*") return;; esac
 | 
			
		||||
        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
 | 
			
		||||
        # 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 > 9000 ) {
 | 
			
		||||
                    # 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
 | 
			
		||||
            [ "$_Z_OWNER" ] && chown $_Z_OWNER:$(id -ng $_Z_OWNER) "$tempfile"
 | 
			
		||||
            env mv -f "$tempfile" "$datafile" || env rm -f "$tempfile"
 | 
			
		||||
        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
 | 
			
		||||
    # tab completion
 | 
			
		||||
    elif [ "$1" = "--complete" -a -s "$datafile" ]; then
 | 
			
		||||
        while read line; do
 | 
			
		||||
            [ -d "${line%%\|*}" ] && echo $line
 | 
			
		||||
        done < "$datafile" | awk -v q="$2" -F"|" '
 | 
			
		||||
            BEGIN {
 | 
			
		||||
                if( q == tolower(q) ) imatch = 1
 | 
			
		||||
                q = substr(q, 3)
 | 
			
		||||
                gsub(" ", ".*", q)
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
                if( imatch ) {
 | 
			
		||||
                    if( tolower($1) ~ tolower(q) ) print $1
 | 
			
		||||
                } else if( $1 ~ q ) 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
 | 
			
		||||
    else
 | 
			
		||||
        # list/go
 | 
			
		||||
        while [ "$1" ]; do case "$1" in
 | 
			
		||||
            --) while [ "$1" ]; do shift; local fnd="$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} [-chlrtx] args" >&2; return;;
 | 
			
		||||
                    x) sed -i -e "\:^${PWD}|.*:d" "$datafile";;
 | 
			
		||||
                    l) local list=1;;
 | 
			
		||||
                    r) local typ="rank";;
 | 
			
		||||
                    t) local typ="recent";;
 | 
			
		||||
                esac; opt=${opt:1}; done;;
 | 
			
		||||
             *) local fnd="$fnd${fnd:+ }$1";;
 | 
			
		||||
        esac; local last=$1; [ "$#" -gt 0 ] && 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
 | 
			
		||||
        # 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
 | 
			
		||||
        # 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
 | 
			
		||||
        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) {
 | 
			
		||||
                # relate frequency and 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, out, common) {
 | 
			
		||||
                # list or return the desired directory
 | 
			
		||||
                if( list ) {
 | 
			
		||||
                    cmd = "sort -n >&2"
 | 
			
		||||
                    for( x in files ) {
 | 
			
		||||
                        if( files[x] ) printf "%-10s %s\n", files[x], x | cmd
 | 
			
		||||
                    }
 | 
			
		||||
                    if( common ) {
 | 
			
		||||
                        printf "%-10s %s\n", "common:", common > "/dev/stderr"
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if( common ) out = common
 | 
			
		||||
                    print out
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            function common(matches) {
 | 
			
		||||
                # find the common root of a list of matches, if it exists
 | 
			
		||||
                for( x in matches ) {
 | 
			
		||||
                    if( matches[x] && (!short || length(x) < length(short)) ) {
 | 
			
		||||
                        short = x
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if( short == "/" ) return
 | 
			
		||||
                # use a copy to escape special characters, as we want to return
 | 
			
		||||
                # the original. yeah, this escaping is awful.
 | 
			
		||||
                clean_short = short
 | 
			
		||||
                gsub(/\[\(\)\[\]\|\]/, "\\\\&", clean_short)
 | 
			
		||||
                for( x in matches ) if( matches[x] && x !~ clean_short ) return
 | 
			
		||||
                return short
 | 
			
		||||
            }
 | 
			
		||||
            BEGIN {
 | 
			
		||||
                gsub(" ", ".*", q)
 | 
			
		||||
                hi_rank = ihi_rank = -9999999999
 | 
			
		||||
            }
 | 
			
		||||
            {
 | 
			
		||||
                if( typ == "rank" ) {
 | 
			
		||||
                    rank = $2
 | 
			
		||||
                } else if( typ == "recent" ) {
 | 
			
		||||
                    rank = $3 - t
 | 
			
		||||
                } else rank = frecent($2, $3)
 | 
			
		||||
                if( $1 ~ q ) {
 | 
			
		||||
                    matches[$1] = rank
 | 
			
		||||
                } else if( tolower($1) ~ tolower(q) ) imatches[$1] = rank
 | 
			
		||||
                if( matches[$1] && matches[$1] > hi_rank ) {
 | 
			
		||||
                    best_match = $1
 | 
			
		||||
                    hi_rank = matches[$1]
 | 
			
		||||
                } else if( imatches[$1] && imatches[$1] > ihi_rank ) {
 | 
			
		||||
                    ibest_match = $1
 | 
			
		||||
                    ihi_rank = imatches[$1]
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            END {
 | 
			
		||||
                # prefer case sensitive
 | 
			
		||||
                if( best_match ) {
 | 
			
		||||
                    output(matches, best_match, common(matches))
 | 
			
		||||
                } else if( ibest_match ) {
 | 
			
		||||
                    output(imatches, ibest_match, common(imatches))
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        ')"
 | 
			
		||||
        [ $? -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}"
 | 
			
		||||
if type 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
 | 
			
		||||
        [[ -n "${precmd_functions[(r)_z_precmd]}" ]] || {
 | 
			
		||||
            precmd_functions[$(($#precmd_functions+1))]=_z_precmd
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    _z_precmd() {
 | 
			
		||||
      _z --add "${PWD:A}"
 | 
			
		||||
    _z_zsh_tab_completion() {
 | 
			
		||||
        # tab completion
 | 
			
		||||
        local compl
 | 
			
		||||
        read -l compl
 | 
			
		||||
        reply=(${(f)"$(_z --complete "$compl")"})
 | 
			
		||||
    }
 | 
			
		||||
    compctl -U -K _z_zsh_tab_completion _z
 | 
			
		||||
elif type complete >/dev/null 2>&1; then
 | 
			
		||||
    # bash
 | 
			
		||||
    # tab completion
 | 
			
		||||
    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 "$(command pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null;'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user