Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart case sensitivity matching by default #221

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ NAME
z - jump around

SYNOPSIS
z [-chlrtx] [regex1 regex2 ... regexn]
z [-cehilrstx] [regex1 regex2 ... regexn]

AVAILABILITY
bash, zsh
Expand All @@ -16,7 +16,8 @@ DESCRIPTION

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, in
order.
order. By default, smart case sensitivity is used, namely case insensi-
tive match when regexes are lower case, case sensitive match otherwise.

For example, z foo bar would match /foo/bar but not /bar/foo.

Expand All @@ -27,10 +28,14 @@ OPTIONS

-h show a brief help message

-i case insensitive match

-l list only

-r match by rank only

-s case sensitive match

-t match by recent access only

-x remove the current directory from the datafile
Expand Down
10 changes: 9 additions & 1 deletion z.1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ NAME
z \- jump around
.SH
SYNOPSIS
z [\-chlrtx] [regex1 regex2 ... regexn]
z [\-cehilrstx] [regex1 regex2 ... regexn]
.SH
AVAILABILITY
bash, zsh
Expand All @@ -14,6 +14,8 @@ 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, in order.
By default, smart case sensitivity is used, namely case insensitive match when
regexes are lower case, case sensitive match otherwise.

For example, \fBz foo bar\fR would match \fB/foo/bar\fR but not \fB/bar/foo\fR.
.SH
Expand All @@ -28,12 +30,18 @@ echo the best match, don't cd
\fB\-h\fR
show a brief help message
.TP
\fB\-i\fR
case insensitive match
.TP
\fB\-l\fR
list only
.TP
\fB\-r\fR
match by rank only
.TP
\fB\-s\fR
case sensitive match
.TP
\fB\-t\fR
match by recent access only
.TP
Expand Down
57 changes: 29 additions & 28 deletions z.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,18 +111,20 @@ _z() {
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
--) 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;;
h) echo "${_Z_CMD:-z} [-cehilrstx] [regex1 regex2 ... regexn]" >&2; return;;
i) local cas='i';;
l) local list=1;;
r) local typ="rank";;
t) local typ="recent";;
r) local typ='r';;
s) local cas='s';;
t) local typ='t';;
x) sed -i -e "\:^${PWD}|.*:d" "$datafile";;
esac; opt=${opt:1}; done;;
esac; opt="${opt:1}"; done;;
*) local fnd="$fnd${fnd:+ }$1";;
esac; local last=$1; [ "$#" -gt 0 ] && shift; done
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
Expand All @@ -135,10 +137,10 @@ _z() {
[ -f "$datafile" ] || return

local cd
cd="$( < <( _z_dirs ) awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" '
cd="$( < <( _z_dirs ) awk -v now="$(date +%s)" -v cas="$cas" -v list="$list" -v typ="$typ" -v q="$fnd" -F'|' '
function frecent(rank, time) {
# relate frequency and time
dx = t - time
dx = now - time
if( dx < 3600 ) return rank * 4
if( dx < 86400 ) return rank * 2
if( dx < 604800 ) return rank / 2
Expand Down Expand Up @@ -175,33 +177,32 @@ _z() {
return short
}
BEGIN {
gsub(" ", ".*", q)
hi_rank = ihi_rank = -9999999999
if( cas == "i" ) {
q = tolower(q)
imatch = 1
} else if( cas != "s" && q == tolower(q) ) imatch = 1
gsub(/ /, ".*", q)
hi_rank = -9999999999
}
{
if( typ == "rank" ) {
if( typ == "r" ) {
rank = $2
} else if( typ == "recent" ) {
rank = $3 - t
} else if( typ == "t" ) {
rank = $3 - now
} else rank = frecent($2, $3)
if( $1 ~ q ) {
if( imatch ) {
x = tolower($1)
} else x = $1
if( x ~ 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]
if( rank > hi_rank ) {
best_match = $1
hi_rank = rank
}
}
}
END {
# prefer case sensitive
if( best_match ) {
output(matches, best_match, common(matches))
} else if( ibest_match ) {
output(imatches, ibest_match, common(imatches))
}
output(matches, best_match, common(matches))
}
')"

Expand Down