Jumping around ranger with zoxide
I live in ranger. I also live in zoxide, which remembers every directory I visit and ranks them by “frecency”. The two had no idea about each other, so I wrote ranger-zoxide to introduce them.
Usage is what you’d hope:
:z proj astro
…and ranger is now sitting in ~/projects/jchook.com/astro, because that’s
the highest-ranked match. No path typing, no tab-dance through five levels of
directories.
The whole trick
ranger plugins are just Python classes. The core of it is embarrassingly
small — shell out to zoxide, cd to whatever it says:
class z(Command):
def execute(self):
results = subprocess.check_output(
["zoxide", "query", *self.args[1:]],
text=True,
).splitlines()
if results:
self.fm.cd(results[0])
The real plugin also feeds ranger’s own navigation back into zoxide, so
directories you browse to by hand still climb the ranking. That closes the
loop: browse normally for a week, and after that :z almost always guesses
right on the first try.
Install
git clone https://github.com/jchook/ranger-zoxide.git \
~/.config/ranger/plugins/zoxide
That’s it. ranger auto-loads anything in plugins/.
Somehow this little glue script became my most-starred repo. The lesson generalizes: the best tools to write are the ten-line ones sitting between two great tools that haven’t met yet.