From 3b6c163391c9326a6df1b3acdea01a50a3e703d7 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 3 May 2009 11:13:11 -0500 Subject: update the autojump script --- bash/j.sh | 144 ++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 41 deletions(-) (limited to 'bash') diff --git a/bash/j.sh b/bash/j.sh index 83ba0f0..db1f541 100644 --- a/bash/j.sh +++ b/bash/j.sh @@ -1,6 +1,6 @@ -# maintains a jump-list of directories you actually use +# maintains a jump-list of the directories you actually use # old directories eventually fall off the list -# inspired by http://wiki.github.com/joelthelion/autojump +# inspired by Joel Schaerer's http://wiki.github.com/joelthelion/autojump # and something similar i had - but i could never get the dir list right. # # INSTALL: @@ -8,63 +8,125 @@ # cd around for a while # # USE: -# j [--l] [regex1 ... regexn] -# regex1 ... regexn jump to the most used directory matching all masks +# j [--h[elp]] [--l] [--r] [--s] [regex1 ... regexn] +# with no args, returns full list (same as j --l) +# regex1 ... regexn jump to the the weighted directory matching all masks # --l show the list instead of jumping -# with no args, returns full list +# --r order by recently used instead of most used. +# --s shortest matching path +# +# TIPS: +# Some handy aliases: +# alias jl='j --l' +# alias jr='j --r' +# alias js='j --s' +# +# CREDITS: +# Joel Schaerer aka joelthelion for autojump +# Daniel Drucker aka dmd for finding bugs and making me late for lunch j() { # change jfile if you already have a .j file for something else - jfile=$HOME/.j - if [ "$1" = "--add" ]; then + local jfile=$HOME/.j + [ "$1" = "--add" ] && { shift # we're in $HOME all the time, let something else get all the good letters [ "$*" = "$HOME" ] && return - awk -v q="$*" -v mx=1000 -F"|" ' + awk -v q="$*" -v t="$(date +%s)" -F"|" ' $2 >= 1 { - if( $1 == q ) { l[$1] = $2 + 1; x = 1 } else l[$1] = $2 - y += $2 + if( $1 == q ) { + l[$1] = $2 + 1 + d[$1] = t + found = 1 + } else { + l[$1] = $2 + d[$1] = $3 + count += $2 + } } END { - x || l[q] = 1 - if( y > mx ) { - for( i in l ) print i "|" l[i]*(0.9*mx/y) # aging - } else for( i in l ) print i "|" l[i] + if( !found ) l[q] = 1 && d[q] = t + if( count > 1000 ) { + for( i in l ) print i "|" 0.9*l[i] "|" d[i] # aging + } else for( i in l ) print i "|" l[i] "|" d[i] } ' $jfile 2>/dev/null > $jfile.tmp mv -f $jfile.tmp $jfile - elif [ "$1" = "" -o "$1" = "--l" ];then - shift - awk -v q="$*" -F"|" ' - BEGIN { split(q,a," ") } - { for( o in a ) $1 !~ a[o] && $1 = ""; if( $1 ) print $2 "\t" $1 } - ' $jfile 2>/dev/null | sort -n - # for completion - elif [ "$1" = "--complete" ];then - awk -v q="$3" -F"|" ' - BEGIN { split(q,a," ") } - { for( o in a ) $1 !~ a[o] && $1 = ""; if( $1 ) print $1 } + return + } + # tab completion + [ "$1" = "--complete" ] && { + awk -v q="$2" -F"|" ' + BEGIN { split(substr(q,3),a," ") } + { + if( system("test -d \"" $1 "\"") ) next + for( i in a ) $1 !~ a[i] && $1 = ""; if( $1 ) print $1 + } ' $jfile 2>/dev/null + return + } + if [ $1 ]; then + local x; local out + for x do case $x in + --h*) echo "j [--h[elp]] [--r] [--l] [regex1 ... regexn]"; return;; + --l)local list=1;; + --r)local recent=r;; + --s)local short=1;; + *)local out="$out $x";; + esac; shift; done + set -- $out + else + local list=1 + fi + if [ $list ]; then + [ "$short" ] && return + awk -v q="$*" -v t="$(date +%s)" -v r="$recent" -F"|" ' + BEGIN { f = 2; split(q,a," "); if( r ) f = 3 } + { + if( system("test -d \"" $1 "\"") ) next + for( i in a ) $1 !~ a[i] && $1 = "" + if( $1 ) if( f == 3 ) { print t - $f "\t" $1 } else print $f "\t" $1 + } + ' $jfile 2>/dev/null | sort -n$recent # if we hit enter on a completion just go there - elif [ "${1:0:1}" = "/" -a -d "$*" ]; then - cd "$*" + elif [ -d "/${out#*/}" ]; then + cd "/${out#*/}" + # prefer case sensitive else - # prefer case sensitive - cd=$(awk -v q="$*" -F"|" ' - BEGIN { split(q,a," ") } - { for( o in a ) $1 !~ a[o] && $1 = ""; if( $1 ) { print $2 "\t" $1; x = 1 } } + out=$(awk -v q="$*" -v s="$short" -v r="$recent" -F"|" ' + BEGIN { split(q,a," "); if( r ) { f = 3 } else f = 2 } + { + if( system("test -d \"" $1 "\"") ) next + for( i in a ) $1 !~ a[i] && $1 = "" + if( $1 ) { + if( s ) { + if( length($1) <= length(x) ) { + x = $1 + } else if( ! x ) x = $1 + } else if( $f >= dx ) { x = $1; dx = $f } + } + } END { - if( x ) exit - close(FILENAME) - while( getline < FILENAME ) { - for( o in a ) tolower($1) !~ tolower(a[o]) && $1 = "" - if( $1 ) print $2 "\t" $1 + if( ! x ) { + close(FILENAME) + while( getline < FILENAME ) { + if( system("test -d \"" $1 "\"") ) continue + for( i in a ) tolower($1) !~ tolower(a[i]) && $1 = "" + if( $1 ) { + if( s ) { + if( length($1) <= length(x) ) { + x = $1 + } else if( ! x ) x = $1 + } else if( $f >= dx ) { x = $1; dx = $f } + } + } } + if( x ) print x } - ' $jfile 2>/dev/null | sort -nr | head -n 1 | cut -f 2) - [ "$cd" ] && cd "$cd" + ' $jfile) + [ "$out" ] && cd "$out" fi } -# prepend to PROMPT_COMMAND +# tab completion for j +complete -C 'j --complete "$COMP_LINE"' j +# populate directory list. avoid clobbering other PROMPT_COMMANDs. PROMPT_COMMAND='j --add "$(pwd -P)";'"$PROMPT_COMMAND" -# bash completions for j -complete -o dirnames -o filenames -C "j --complete" j -- cgit v1.2.3-54-g00ecf