diff --git a/agnoster.zsh-theme b/agnoster.zsh-theme new file mode 100644 index 0000000..93ddf8c --- /dev/null +++ b/agnoster.zsh-theme @@ -0,0 +1,228 @@ +# vim:ft=zsh ts=2 sw=2 sts=2 +# +# agnoster's Theme - https://gist.github.com/3712874 +# A Powerline-inspired theme for ZSH +# +# # README +# +# In order for this theme to render correctly, you will need a +# [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts). +# Make sure you have a recent version: the code points that Powerline +# uses changed in 2012, and older versions will display incorrectly, +# in confusing ways. +# +# In addition, I recommend the +# [Solarized theme](https://github.com/altercation/solarized/) and, if you're +# using it on Mac OS X, [iTerm 2](http://www.iterm2.com/) over Terminal.app - +# it has significantly better color fidelity. +# +# # Goals +# +# The aim of this theme is to only show you *relevant* information. Like most +# prompts, it will only show git information when in a git working directory. +# However, it goes a step further: everything from the current user and +# hostname to whether the last call exited with an error to whether background +# jobs are running in this shell will all be displayed automatically when +# appropriate. + +### Segment drawing +# A few utility functions to make it easy and re-usable to draw segmented prompts + +CURRENT_BG='NONE' + +# Special Powerline characters + +() { + local LC_ALL="" LC_CTYPE="en_US.UTF-8" + # NOTE: This segment separator character is correct. In 2012, Powerline changed + # the code points they use for their special characters. This is the new code point. + # If this is not working for you, you probably have an old version of the + # Powerline-patched fonts installed. Download and install the new version. + # Do not submit PRs to change this unless you have reviewed the Powerline code point + # history and have new information. + # This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of + # what font the user is viewing this source code in. Do not replace the + # escape sequence with a single literal character. + # Do not change this! Do not make it '\u2b80'; that is the old, wrong code point. + SEGMENT_SEPARATOR=$'\ue0b0' +} + +# Begin a segment +# Takes two arguments, background and foreground. Both can be omitted, +# rendering default background/foreground. +prompt_segment() { + local bg fg + [[ -n $1 ]] && bg="%K{$1}" || bg="%k" + [[ -n $2 ]] && fg="%F{$2}" || fg="%f" + if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then + echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} " + else + echo -n "%{$bg%}%{$fg%} " + fi + CURRENT_BG=$1 + [[ -n $3 ]] && echo -n $3 +} + +# End the prompt, closing any open segments +prompt_end() { + if [[ -n $CURRENT_BG ]]; then + echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR" + else + echo -n "%{%k%}" + fi + echo -n "%{%f%}" + CURRENT_BG='' +} + +### Prompt components +# Each component will draw itself, and hide itself if no information needs to be shown + +# Context: user@hostname (who am I and where am I) +prompt_context() { + if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then + prompt_segment black default "%T %(!.%{%F{red}%}.)$USER" + fi +} + +# Git: branch/detached head, dirty status +prompt_git() { + (( $+commands[git] )) || return + local PL_BRANCH_CHAR + () { + local LC_ALL="" LC_CTYPE="en_US.UTF-8" + PL_BRANCH_CHAR=$'\ue0a0' #  + } + local ref dirty mode repo_path + repo_path=$(git rev-parse --git-dir 2>/dev/null) + + if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then + dirty=$(parse_git_dirty) + ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git rev-parse --short HEAD 2> /dev/null)" + if [[ -n $dirty ]]; then + prompt_segment yellow black + else + prompt_segment green black + fi + + if [[ -e "${repo_path}/BISECT_LOG" ]]; then + mode=" " + elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then + mode=" >M<" + elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then + mode=" >R>" + fi + + setopt promptsubst + autoload -Uz vcs_info + + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:*' get-revision true + zstyle ':vcs_info:*' check-for-changes true + zstyle ':vcs_info:*' stagedstr '✚' + zstyle ':vcs_info:*' unstagedstr '●' + zstyle ':vcs_info:*' formats ' %u%c' + zstyle ':vcs_info:*' actionformats ' %u%c' + vcs_info + echo -n "${ref/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}" + fi +} + +prompt_bzr() { + (( $+commands[bzr] )) || return + if (bzr status >/dev/null 2>&1); then + status_mod=`bzr status | head -n1 | grep "modified" | wc -m` + status_all=`bzr status | head -n1 | wc -m` + revision=`bzr log | head -n2 | tail -n1 | sed 's/^revno: //'` + if [[ $status_mod -gt 0 ]] ; then + prompt_segment yellow black + echo -n "bzr@"$revision "✚ " + else + if [[ $status_all -gt 0 ]] ; then + prompt_segment yellow black + echo -n "bzr@"$revision + + else + prompt_segment green black + echo -n "bzr@"$revision + fi + fi + fi +} + +prompt_hg() { + (( $+commands[hg] )) || return + local rev status + if $(hg id >/dev/null 2>&1); then + if $(hg prompt >/dev/null 2>&1); then + if [[ $(hg prompt "{status|unknown}") = "?" ]]; then + # if files are not added + prompt_segment red white + st='±' + elif [[ -n $(hg prompt "{status|modified}") ]]; then + # if any modification + prompt_segment yellow black + st='±' + else + # if working copy is clean + prompt_segment green black + fi + echo -n $(hg prompt "☿ {rev}@{branch}") $st + else + st="" + rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g') + branch=$(hg id -b 2>/dev/null) + if `hg st | grep -q "^\?"`; then + prompt_segment red black + st='±' + elif `hg st | grep -q "^[MA]"`; then + prompt_segment yellow black + st='±' + else + prompt_segment green black + fi + echo -n "☿ $rev@$branch" $st + fi + fi +} + +# Dir: current working directory +prompt_dir() { + prompt_segment blue black '%~' +} + +# Virtualenv: current working virtualenv +prompt_virtualenv() { + local virtualenv_path="$VIRTUAL_ENV" + if [[ -n $virtualenv_path && -n $VIRTUAL_ENV_DISABLE_PROMPT ]]; then + prompt_segment blue black "(`basename $virtualenv_path`)" + fi +} + +# Status: +# - was there an error +# - am I root +# - are there background jobs? +prompt_status() { + local symbols + symbols=() + [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘" + [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡" + [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙" + + [[ -n "$symbols" ]] && prompt_segment black default "$symbols" +} + +## Main prompt +build_prompt() { + RETVAL=$? + prompt_status + prompt_virtualenv + prompt_context + prompt_dir + prompt_git + prompt_bzr + prompt_hg + prompt_end +} + +PROMPT='%{%f%b%k%}$(build_prompt) ' diff --git a/solarized.dircolors b/solarized.dircolors new file mode 100644 index 0000000..65b8720 --- /dev/null +++ b/solarized.dircolors @@ -0,0 +1,480 @@ +# Exact Solarized Dark color theme for the color GNU ls utility. +# Designed for dircolors (GNU coreutils) 5.97 +# +# This simple theme was simultaneously designed for these terminal color schemes: +# - Solarized dark (best) +# - Solarized light +# - default dark +# - default light +# with a slight optimization for Solarized Dark. +# +# How the colors were selected: +# - Terminal emulators often have an option typically enabled by default that makes +# bold a different color. It is important to leave this option enabled so that +# you can access the entire 16-color Solarized palette, and not just 8 colors. +# - We favor universality over a greater number of colors. So we limit the number +# of colors so that this theme will work out of the box in all terminals, +# Solarized or not, dark or light. +# - We choose to have the following category of files: +# NORMAL & FILE, DIR, LINK, EXEC and +# editable text including source, unimportant text, binary docs & multimedia source +# files, viewable multimedia, archived/compressed, and unimportant non-text +# - For uniqueness, we stay away from the Solarized foreground colors are -- either +# base00 (brightyellow) or base0 (brightblue). However, they can be used if +# you know what the bg/fg colors of your terminal are, in order to optimize the display. +# - 3 different options are provided: universal, solarized dark, and solarized light. +# The only difference between the universal scheme and one that's optimized for +# dark/light is the color of "unimportant" files, which should blend more with the +# background +# - We note that blue is the hardest color to see on dark bg and yellow is the hardest +# color to see on light bg (with blue being particularly bad). So we choose yellow +# for multimedia files which are usually accessed in a GUI folder browser anyway. +# And blue is kept for custom use of this scheme's user. +# - See table below to see the assignments. + + +# Installation instructions: +# This file goes in the /etc directory, and must be world readable. +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. + +# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not +# pipes. 'all' adds color characters to all output. 'none' shuts colorization +# off. +COLOR tty + +# Below, there should be one TERM entry for each termtype that is colorizable +TERM ansi +TERM color_xterm +TERM color-xterm +TERM con132x25 +TERM con132x30 +TERM con132x43 +TERM con132x60 +TERM con80x25 +TERM con80x28 +TERM con80x30 +TERM con80x43 +TERM con80x50 +TERM con80x60 +TERM cons25 +TERM console +TERM cygwin +TERM dtterm +TERM dvtm +TERM dvtm-256color +TERM Eterm +TERM eterm-color +TERM fbterm +TERM gnome +TERM gnome-256color +TERM jfbterm +TERM konsole +TERM konsole-256color +TERM kterm +TERM linux +TERM linux-c +TERM mach-color +TERM mlterm +TERM nxterm +TERM putty +TERM putty-256color +TERM rxvt +TERM rxvt-256color +TERM rxvt-cygwin +TERM rxvt-cygwin-native +TERM rxvt-unicode +TERM rxvt-unicode256 +TERM rxvt-unicode-256color +TERM screen +TERM screen-16color +TERM screen-16color-bce +TERM screen-16color-s +TERM screen-16color-bce-s +TERM screen-256color +TERM screen-256color-bce +TERM screen-256color-s +TERM screen-256color-bce-s +TERM screen-256color-italic +TERM screen-bce +TERM screen-w +TERM screen.linux +TERM screen.xterm-256color +TERM screen.xterm-new +TERM st +TERM st-meta +TERM st-256color +TERM st-meta-256color +TERM tmux +TERM tmux-256color +TERM vt100 +TERM xterm +TERM xterm-new +TERM xterm-16color +TERM xterm-256color +TERM xterm-256color-italic +TERM xterm-88color +TERM xterm-color +TERM xterm-debian +TERM xterm-termite + +# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) +EIGHTBIT 1 + +############################################################################# +# Below are the color init strings for the basic file types. A color init +# string consists of one or more of the following numeric codes: +# +# Attribute codes: +# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed +# Text color codes: +# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white +# Background color codes: +# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white +# +# NOTES: +# - See http://www.oreilly.com/catalog/wdnut/excerpt/color_names.html +# - Color combinations +# ANSI Color code Solarized Notes Universal SolDark SolLight +# ~~~~~~~~~~~~~~~ ~~~~~~~~~ ~~~~~ ~~~~~~~~~ ~~~~~~~ ~~~~~~~~ +# 00 none NORMAL, FILE +# 30 black base02 +# 01;30 bright black base03 bg of SolDark +# 31 red red docs & mm src +# 01;31 bright red orange EXEC +# 32 green green editable text +# 01;32 bright green base01 unimportant text +# 33 yellow yellow unclear in light bg multimedia +# 01;33 bright yellow base00 fg of SolLight unimportant non-text +# 34 blue blue unclear in dark bg user customized +# 01;34 bright blue base0 fg in SolDark unimportant text +# 35 magenta magenta LINK +# 01;35 bright magenta violet archive/compressed +# 36 cyan cyan DIR +# 01;36 bright cyan base1 unimportant non-text +# 37 white base2 +# 01;37 bright white base3 bg in SolLight +# 05;37;41 unclear in Putty dark + + +### By file type + +# global default +NORMAL 00 +# normal file +FILE 00 +# directory +DIR 34 +# 777 directory +OTHER_WRITABLE 34;40 +# symbolic link +LINK 35 + +# pipe, socket, block device, character device (blue bg) +FIFO 30;44 +SOCK 35;44 +DOOR 35;44 # Solaris 2.5 and later +BLK 33;44 +CHR 37;44 + + +############################################################################# +### By file attributes + +# Orphaned symlinks (blinking white on red) +# Blink may or may not work (works on iTerm dark or light, and Putty dark) +ORPHAN 05;37;41 +# ... and the files that orphaned symlinks point to (blinking white on red) +MISSING 05;37;41 + +# files with execute permission +EXEC 01;31 # Unix +.cmd 01;31 # Win +.exe 01;31 # Win +.com 01;31 # Win +.bat 01;31 # Win +.reg 01;31 # Win +.app 01;31 # OSX + +############################################################################# +### By extension + +# List any file extensions like '.gz' or '.tar' that you would like ls +# to colorize below. Put the extension, a space, and the color init string. +# (and any comments you want to add after a '#') + +### Text formats + +# Text that we can edit with a regular editor +.txt 32 +.org 32 +.md 32 +.mkd 32 + +# Source text +.h 32 +.hpp 32 +.c 32 +.C 32 +.cc 32 +.cpp 32 +.cxx 32 +.objc 32 +.cl 32 +.sh 32 +.bash 32 +.csh 32 +.zsh 32 +.el 32 +.vim 32 +.java 32 +.pl 32 +.pm 32 +.py 32 +.rb 32 +.hs 32 +.php 32 +.htm 32 +.html 32 +.shtml 32 +.erb 32 +.haml 32 +.xml 32 +.rdf 32 +.css 32 +.sass 32 +.scss 32 +.less 32 +.js 32 +.coffee 32 +.man 32 +.0 32 +.1 32 +.2 32 +.3 32 +.4 32 +.5 32 +.6 32 +.7 32 +.8 32 +.9 32 +.l 32 +.n 32 +.p 32 +.pod 32 +.tex 32 +.go 32 +.sql 32 +.csv 32 +.sv 32 +.svh 32 +.v 32 +.vh 32 +.vhd 32 + +### Multimedia formats + +# Image +.bmp 33 +.cgm 33 +.dl 33 +.dvi 33 +.emf 33 +.eps 33 +.gif 33 +.jpeg 33 +.jpg 33 +.JPG 33 +.mng 33 +.pbm 33 +.pcx 33 +.pdf 33 +.pgm 33 +.png 33 +.PNG 33 +.ppm 33 +.pps 33 +.ppsx 33 +.ps 33 +.svg 33 +.svgz 33 +.tga 33 +.tif 33 +.tiff 33 +.xbm 33 +.xcf 33 +.xpm 33 +.xwd 33 +.xwd 33 +.yuv 33 + +# Audio +.aac 33 +.au 33 +.flac 33 +.m4a 33 +.mid 33 +.midi 33 +.mka 33 +.mp3 33 +.mpa 33 +.mpeg 33 +.mpg 33 +.ogg 33 +.opus 33 +.ra 33 +.wav 33 + +# Video +.anx 33 +.asf 33 +.avi 33 +.axv 33 +.flc 33 +.fli 33 +.flv 33 +.gl 33 +.m2v 33 +.m4v 33 +.mkv 33 +.mov 33 +.MOV 33 +.mp4 33 +.mp4v 33 +.mpeg 33 +.mpg 33 +.nuv 33 +.ogm 33 +.ogv 33 +.ogx 33 +.qt 33 +.rm 33 +.rmvb 33 +.swf 33 +.vob 33 +.webm 33 +.wmv 33 + +### Misc + +# Binary document formats and multimedia source +.doc 31 +.docx 31 +.rtf 31 +.odt 31 +.dot 31 +.dotx 31 +.ott 31 +.xls 31 +.xlsx 31 +.ods 31 +.ots 31 +.ppt 31 +.pptx 31 +.odp 31 +.otp 31 +.fla 31 +.psd 31 + +# Archives, compressed +.7z 1;35 +.apk 1;35 +.arj 1;35 +.bin 1;35 +.bz 1;35 +.bz2 1;35 +.cab 1;35 # Win +.deb 1;35 +.dmg 1;35 # OSX +.gem 1;35 +.gz 1;35 +.iso 1;35 +.jar 1;35 +.msi 1;35 # Win +.rar 1;35 +.rpm 1;35 +.tar 1;35 +.tbz 1;35 +.tbz2 1;35 +.tgz 1;35 +.tx 1;35 +.war 1;35 +.xpi 1;35 +.xz 1;35 +.z 1;35 +.Z 1;35 +.zip 1;35 + +# For testing +.ANSI-30-black 30 +.ANSI-01;30-brblack 01;30 +.ANSI-31-red 31 +.ANSI-01;31-brred 01;31 +.ANSI-32-green 32 +.ANSI-01;32-brgreen 01;32 +.ANSI-33-yellow 33 +.ANSI-01;33-bryellow 01;33 +.ANSI-34-blue 34 +.ANSI-01;34-brblue 01;34 +.ANSI-35-magenta 35 +.ANSI-01;35-brmagenta 01;35 +.ANSI-36-cyan 36 +.ANSI-01;36-brcyan 01;36 +.ANSI-37-white 37 +.ANSI-01;37-brwhite 01;37 + +############################################################################# +# Your customizations + +# Unimportant text files +# For universal scheme, use brightgreen 01;32 +# For optimal on light bg (but too prominent on dark bg), use white 01;34 +.log 01;32 +*~ 01;32 +*# 01;32 +#.log 01;34 +#*~ 01;34 +#*# 01;34 + +# Unimportant non-text files +# For universal scheme, use brightcyan 01;36 +# For optimal on dark bg (but too prominent on light bg), change to 01;33 +#.bak 01;36 +#.BAK 01;36 +#.old 01;36 +#.OLD 01;36 +#.org_archive 01;36 +#.off 01;36 +#.OFF 01;36 +#.dist 01;36 +#.DIST 01;36 +#.orig 01;36 +#.ORIG 01;36 +#.swp 01;36 +#.swo 01;36 +#*,v 01;36 +.bak 01;33 +.BAK 01;33 +.old 01;33 +.OLD 01;33 +.org_archive 01;33 +.off 01;33 +.OFF 01;33 +.dist 01;33 +.DIST 01;33 +.orig 01;33 +.ORIG 01;33 +.swp 01;33 +.swo 01;33 +*,v 01;33 + +# The brightmagenta (Solarized: purple) color is free for you to use for your +# custom file type +.gpg 34 +.gpg 34 +.pgp 34 +.asc 34 +.3des 34 +.aes 34 +.enc 34 +.sqlite 34 diff --git a/z.sh b/z.sh new file mode 100644 index 0000000..86cdb7c --- /dev/null +++ b/z.sh @@ -0,0 +1,251 @@ +# Copyright (c) 2009 rupa deadwyler. Licensed under the WTFPL license, Version 2 + +# 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. +# 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 + +[ -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}" + + # if symlink, dereference + [ -h "$datafile" ] && datafile=$(readlink "$datafile") + + # bail if we don't own ~/.z and $_Z_OWNER not set + [ -z "$_Z_OWNER" -a -f "$datafile" -a ! -O "$datafile" ] && return + + _z_dirs () { + local line + while read line; do + # only count directories + [ -d "${line%%\|*}" ] && echo "$line" + done < "$datafile" + return 0 + } + + # add entries + if [ "$1" = "--add" ]; then + shift + + # $HOME isn't worth matching + [ "$*" = "$HOME" ] && return + + # don't track excluded directory trees + local exclude + for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do + case "$*" in "$exclude*") return;; esac + done + + # maintain the data file + local tempfile="$datafile.$RANDOM" + _z_dirs | 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" -a -s "$datafile" ]; then + _z_dirs | awk -v q="$2" -F"|" ' + BEGIN { + q = substr(q, 3) + if( q == tolower(q) ) imatch = 1 + gsub(/ /, ".*", q) + } + { + if( imatch ) { + if( tolower($1) ~ 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${fnd:+ }$1";done;; + -*) local opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in + c) local fnd="^$PWD $fnd";; + e) local echo=echo;; + h) echo "${_Z_CMD:-z} [-cehlrtx] args" >&2; return;; + l) local list=1;; + r) local typ="rank";; + t) local typ="recent";; + x) sed -i -e "\:^${PWD}|.*:d" "$datafile";; + 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" ] && builtin cd "$last" && return;; + esac + + # no file yet + [ -f "$datafile" ] || return + + local cd + cd="$( < <( _z_dirs ) 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(matches, best_match, common) { + # list or return the desired directory + if( list ) { + cmd = "sort -n >&2" + for( x in matches ) { + if( matches[x] ) { + printf "%-10s %s\n", matches[x], x | cmd + } + } + if( common ) { + printf "%-10s %s\n", "common:", common > "/dev/stderr" + } + } else { + if( common ) best_match = common + print best_match + } + } + 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 + for( x in matches ) if( matches[x] && index(x, short) != 1 ) { + 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)) + } + } + ')" + + [ $? -eq 0 ] && [ "$cd" ] && { + if [ "$echo" ]; then echo "$cd"; else builtin cd "$cd"; fi + } + fi +} + +alias ${_Z_CMD:-z}='_z 2>&1' + +[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P" + +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 + } + } + _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