rupa / z Goto Github PK
View Code? Open in Web Editor NEWz - jump around
License: Do What The F*ck You Want To Public License
z - jump around
License: Do What The F*ck You Want To Public License
Z(1) User Commands Z(1) NAME z - jump around SYNOPSIS z [-chlrtx] [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, 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 -e echo the best match, don't cd -h show a brief help message -l list only -r match by rank only -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, then 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_MAX_SCORE lower to age entries out faster (default 9000). 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 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 in your MANPATH, 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 over 9000, all ranks are multiplied by 0.99. Entries with a rank lower than 1 are forgotten. Frecency: 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 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 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 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 environment 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 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)
It would be even nicer if I could also use "z" instead of normal "cd" to change directory. Maybe z could fall back to cd if directory is not found in z's database or something. I find it hard to use cd for some directory changes and z for others.
I have the following in my .bashrc
:
_Z_DATA="$HOME/.local/share/z"
. ~/Code/cloned/z/z.sh
but instead of creating a file at ~/.local/share/z
a directory is created with what seems like random files:
$ ls -l ~/.local/share/z
total 304
-rw------- 1 michael michael 0 2011-12-24 17:30 z.0xXKJf
-rw------- 1 michael michael 0 2011-12-24 17:32 z.2uF7Ug
-rw------- 1 michael michael 0 2011-12-24 17:32 z.6Rucr5
-rw------- 1 michael michael 0 2011-12-24 17:39 z.7b0XFP
-rw------- 1 michael michael 0 2011-12-24 17:28 z.7nvgo8
-rw------- 1 michael michael 0 2011-12-24 17:21 z.9VLve2
...
Keeping $_Z_DATA
at the default works as expected.
On my system (OS X 10.5.7) calling z without arguments results in the errors below. Everything else seems to work as expected.
→ z
awk: syntax error at source line 36
context is
print $0 >> FILENAME >>> ".tmp" <<<
awk: illegal statement at source line 37
awk: illegal statement at source line 37
mv: rename /Users/adam/.z.tmp to /Users/adam/.z: No such file or directory
./z.sh: 206: ./z.sh: Syntax error: "(" unexpected (expecting "}")
received via email:
Current version of z sets $PROMPT_COMMAND variable in any shells (zsh/ksh/..),
and that causes annoyance in some situations.Example;
When ". /path/to/z.sh" in zsh, $PROMPT_COMMAND is set but not used.
Then start bash from zsh, bash takes over $PROMPT_COMMAND from zsh
whether ". /path/to/z.sh" is written in ~/.bashrc or not.
If not, bash complains that "bash: z: command not found" or so.
'v' allows us to select from a list. Why can't 'z' to that.
I often type 'z' and see my directory in the list. But typing the substring takes me to the wrong dir since I have several that are similar. I ultimately have to copy paste or use 'wd' (a perl utility) to get to my directory.
Would appreciate, if you could give a list and allow us to select by number. Thx for the great utilities.
I have installed Z a while ago and have been using the terminal cd'ing around to build up the database.
The Z command doesn't fail at all and I can see lots of small files been created at ~/.z,
but Z never gets to works.
z -l
z -r test
...
nothing!
Any thoughts ?
Hi,
I am quickly becoming a fan of z, so thanks. However, I wanted to share a difficulty that I had getting it working.
For some reason in the past I had unset my PROMPT_COMMAND from my .bash_profile, just a few lines below where my .bashrc file was sourced. This effectively disabled z, and kept me puzzled for a while. Finally, after digging though the code, I figured out what was wrong.
It might help others if you were to describe how z relies on the PROMPT_COMMAND in the README.
Best,
As mentioned in the title, running z with no arguments or in list mode (-l) increases the frecency of the current directory. I suppose this is a bug since such behaviour is quite unintuitive.
$ z
awk: cmd. line:41: case[$1] = nocase[$1] = f
awk: cmd. line:41: ^ syntax error
awk: cmd. line:43: if( $1 !~ a[i] ) delete case[$1]
awk: cmd. line:43: ^ syntax error
awk: cmd. line:46: if( case[$1] > oldf ) {
awk: cmd. line:46: ^ syntax error
awk: cmd. line:48: oldf = case[$1]
awk: cmd. line:48: ^ syntax error
awk: cmd. line:49: } else if( nocase[$1] > noldf ) {
awk: cmd. line:49: ^ syntax error
awk: cmd. line:56: output(case, cx, common(case, a, 0))
awk: cmd. line:56: ^ syntax error
awk: cmd. line:56: output(case, cx, common(case, a, 0))
awk: cmd. line:56: ^ syntax error
mv: cannot stat `/cygdrive/c/Users/darnold/.z.tmp': No such file or directory
Got this when I tried running z in Cygwin. My ~ is /cygdrive/c/Users/darnold/, z.sh is located in ~/bin, and is in PATH
I can type z m
and think I'll get taken to the right place, but I might be surprised.
When using cd
with a CDPATH
set, cd
prints the directory it takes you to. Can z
do this?
I just cloned the repos and setup z.sh like on my main box. However some update seems to have broken the whole thing, as nothing happens at all. After cd'ing around for some time, all I can find are some empty .z.$random tmpfiles in my home folder. This happens on Ubuntu Natty, so it might be some kind of dash interference.
https://github.com/robbyrussell/oh-my-zsh
That would be splendid. Then I'll use it!
I had to change a line to get it to work.
$ diff z.sh z_old.sh
28c28
< [ "$(ls -l "$datafile" | cut -d' ' -f 4)" = "$USER" ] || return
---
> [ "$(ls -l "$datafile" | cut -d' ' -f 3)" = "$USER" ] || return
Just wanted to say thanks for this! I've been thinking about how to make this happen for a while. I ran across a comment here that linked to this.
It was so sweet to type "z foo" and skip all that tabbing it made me giggle joy. You made my week!
Thanks.
It'd be neat if you could devise a scheme allowing Z to help with tab completion of directories as arguments to any command.
I’m experiencing an error when I try to jump to a folder that contains a left parenthesis.
$ z -l test
awk: syntax error in regular expression /Volumes/Studio/Client name &test)/test at /test
input record number 19, file
source line number 32
The folder in question is /Volumes/Studio/Client name (test)/test
– I don't know if the (
being changed to an &
is part of the problem?
When I type a matching string and hit tab to autocomplete the full path, it works okay. However if I type z test
and hit enter, the above error occurs. I am using zsh on OS X.
Hi there,
I have done a lot of work (probably over 2000 operations, thanks to xargs and friends) inside a special folder deep inside my folder structure (let's say "/home/xyz/script/project/something/weird/data"). If I now do 'z script', I will be sent to the deep location, where I would want to land if I typed 'data', or maybe 'weird'. Is there some way to tweak the algorithm to favor a result if the pattern is near the end of the path?
malexmave
Z will encounter a performance bottleneck when there are too many entries in the datafile. My debugging showed that it's because of the use of system(test -d $1)
when searching in awk. So I worked out a hack. The hack is an awk function. It uses that fact that "traversing" valid directory is valid while "traversing" invalid directory is invalid. Here's the commit.
By the way, these discoveries and improvements were made while I was working on my fork of z
, called f
(https://github.com/clvv/f) It's not a forked project on github because it has different design goals. And I want to say a huge thanks for z
, it was using z
for months that gave me the idea to write f
.
Anyway, I just thought I should contribute the improvements back to z
. I've tested this hack on gawk
, nawk
, busybox awk
and mawk
. It worked in all of them. But whether to accept this hack into z
is up to you.
Hi there,
Absolutely love z. Have been looking for something like this for ages.
Our team uses symlinks everywhere on our system to point to the latest version of our released software.
e.g.
/app/x -> /release/x-3.0.45
So when I:
cd /app/x/bin
In my case I'd prefer to store /app/x/bin, rather than /release/x-3.0.45/bin so that when versions change, my z store remains relevant.
I've looked over the code, but I'm afraid my shell skills are not up to speed.
I was wondering if you might be kind enough to point me to what I might change in the z.sh script to get it working in this manner.
Kind regards,
Ben Warner
This is the first custom shell script I've "installed" and I wanted to make sure I'm doing it right.
Location:
~/shell_stuff/z.sh
In ~/.bashrc
. ~/shell_stuff/z.sh
I start a new terminal window and cd around, but when I try to use z: z autocom
it tells me the z command is not found.
I'm sure I'm leaving something out, but what am I missing? Do I also need the z.1 file?
I have alised my mv command to mv -v, so every time the temp file is moved it is echoed on my shell... You should use /bin/mv, or do a MV=which mv
and then use $MV
How is z different from autojump?
Cheers!
I've been using z
on both Linux and Mac. Indispensable. Would be nice to have support for Windows. Perhaps as .bat, or at least .ps1 (powershell).
hi!
it would be very nice if z allowed for fuzzy matching of paths, at least on the basename.
so instead of z source
i could type z src
.
that would make z even cooler! ;)
If z foo bar baz
yields no matches and if z foo bar
does, I'd like to be taken to that match when I isssue the first command.
So, I think it would be a good idea to pop the tokens list until either it's empty or a match was found.
When I type z cod
and then hit tab, I get this: [jga] ~: z "/Users/jga/code
(notice the open quote, but not closing)
z currently has no license information. Is it intended to be MIT? BSD?
z
doesn't work with zsh.
/Users/nikitavasilev/.shell/z.sh:145: command not found: complete
➤ zsh --version
zsh 4.3.10 (i386-apple-darwin9.8.0)
something like curl foo; bar
I'm attempting to submit a Homebrew formula for installing Z but they would prefer it if there was a tagged release of Z (instead of just using HEAD): Homebrew/legacy-homebrew#4449 (comment)
Would it be possible to tag a release as stable (even if it's 0.0.1)?
If I have two terminal windows open and they both run z at the same time, I get this error message:
mv: rename /Users/makane/.z.tmp to /Users/makane/.z: No such file or directory
Occasionally this blows away ~/.z entirely. Is there a way to use flock to get around this?
To reproduce this, open some long running process in two different terminal windows, then kill both processes from a third window at the same time. Two instances of ssh and a killall ssh
in the third window seems to do the trick for me, although, as with all race conditions, it doesn't happen every time.
I'm using Mac OS X, I couldn't find .zshrc or .bashrc files so I created them in the directory:
/Users/simonowen/
with the following code:
.zshrc:
. /Users/simonowen/z.sh
function precmd () {
_z --add "$(pwd -P)"
}
.bashrc:
. /Users/simonowen/z.sh
Added the z.sh file from:
https://github.com/rupa/z/blob/master/z.sh
to:
/Users/simonowen/z.sh
I then opened terminal, did some cd, then tried using z, but got the following error:
-bash: z: command not found
Tried closing and opening Terminal again, but still get the same error.
As in issue #49, I'd love to if z would not resolve symlinks.
I've tried a proposed solution, changing pwd -P
to pwd
.
This does add a symlink to .z
file.
However, z never uses that symlink. Output of z
does not list
the symlink.
I love this script, it is awesome, but symlinking is a very important
feature to me, so it makes me sad that it does not work.
Could you please take a look at this?
I also think it should be the default behaviour, but that's just me.
It seems like brackets in file names with lead to tricky situations:
awk: cmd. line:32: (FILENAME=- FNR=67) fatal: Invalid range end: //home/foo/bar/Foo.-.[12-3-4567]/
I have a prompt that displays red if the last exit status was a failure,
this no longer works if z.sh bash completion is loaded (the lower part of z.sh)
function prompt_func() {
previous_return_value=$?;
PS1="${previous_return_value}"
}
PROMPT_COMMAND=prompt_func
I had to create the datafile manually (touch ~/.z) to get z working. (Then it's probably the most useful script I know, thank you!)
If creating the .z file manually is the intended way to install z, you might want to update the readme.
The following will fix it
' "$datafile" 2>/dev/null >| "$tempfile"
Instead of the existing
' "$datafile" 2>/dev/null > "$tempfile"
frecent & freceny should be frequent & frequency
For its own convenience, z
uses stdout internally, and prints to console using stderr. This is counterintuitive and breaks piping.
so using z with sudo -s doesnt seem to work very well. Now that I am a root, the .z directory's permissions are changed in my home directory (which is still the same as if i wasnt root), and when i log back in, somehow everything gets reset.
I get an initial permission error, run the command again, and my history is gone.
I'll try setgid on my home directory to see if that improves things.
Also it seems as my history disappears after awhile? I'm not sure if this is related to the above issue, but I get the feeling it isn't, since when it happens I don't remember sudoing to root
Just a interesting suggestion: i think it would be powerful if z also did filename completion based on frecency, i find myself typing z alot and forgetting the directory (partly because im using z all the time) but remembering the name of the file only. locate works, but its slower..
btw way, this is one of the most convenient and awesome tools i have come across.. id love to read more about power tools like this.
Hi,
Is there anyway to get this awesome command into Vim? something like :z www
to navigate to my webdev directory?
Thanks in advance!
Using the latest revision of this script as of the time of writing on bash 4.2, I receive a syntax error after every inputted command:
-bash: PROMPT_COMMAND: line 1: syntax error near unexpected token `;;'
-bash: PROMPT_COMMAND: line 1: `z --add "$(pwd -P 2>/dev/null)";; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
By the way, the reported line number is completely arbitrary. It seems to increment after every command.
Nice job! z is a great enhancement to bash and zsh. Would you be willing to extend it to tcsh?
Hi. Nice script :). There's a problem in bash (haven't tried zsh) where you get 'z: command not found' errors if you use a subshell.
For example:
22:23:28 ~$ su
Password:
bash: z: command not found
[root@stefan normal]#
Well, a long time ago I put in some code that, when multiple directories match the query, and they all have the same prefix, z will go to shortest directory no matter what the ranking turns out.
So if I have
10 ~/Documents/dev/
100 ~/Documents/dev/z/
i will always go to the shorter one for z ocu
. But if I have:
10 ~/Documents/dev/
20 ~/oculus/
100 ~/Documents/dev/z/
the behavior will be as expected.
I put this code in place and forgot about it for the most part, returned to it lately when I realized how poorly written it was, and realized that the whole thing is arguably The Wrong Thing To Do, or at least Something Undocumented The People Might Resent. I'd like to talk about why I did it, and request comments.
Shorter directories get lost in z. Without this behavior, in the above example, it's annoyingly tough to get to ~/Documents/dev/
as ~/Documents/dev/z/
swallows up most of its regex. So I wanted to weight common prefixes highly.
On one hand, this approach has a tendency to throw away all the ranking info at the last second, and could give unfair weight to a rarely used directory containing several frequently used directories. However, it seems to me you'd tend to acces those frequently used directories with an mnemonic unique to them, that the parent directory would not match. In my usage, I find myself typing z ocu
to get to ~/Documents
more than I find myself irritated it didn't go to highest ranked subdir of it.
It may be telling that this code has been in place for a long time, and that I am rarely surprised at where z
goes. It's felt pretty intuitive. I could make this configurable maybe, but then should it be the default?
I often want to z
to a path i was last in like 3 weeks ago. But they seem to be unavailable.. i imagine they are being evicted from the cache..
I know this is one of the 2 hardest problems, but i'd like to see if we can cache evict smarter so my projects that i work on occasionally are still z
-able
In my particular care, most of my projects are in ~/Sites/
and i'm z
ing around them, so the heuristic could give items within my Sites folder a longer expire time..
(But maybe I totally misundertand how it works, so apologies if so)
I use zsh (zsh 4.3.12 ) on Debian, but the z doesn't work with it.
I have updated the z to the latest source code and installed it as illustrated in "README". After cd for a long time, there was not a file named ".z" under $HOME.
( Some weeks ago when I used z on bash, it worked fine.)
Please help to have a look, much thanks!
z.sh appears to have a number of problems when $HOME contains spaces. For example, on a cygwin installation where $HOME=/cygdrive/c/Documents and Settings/Paul, I encounter the following error:
$ cd /cygdrive/c
mv: target `Settings/Paul/.z' is not a directory
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.