QJump (short for QuickJump) allows you to bookmark directories on your local machine and switch between them easily. It's like a URL shortener but it's designed for your local machine.
Build a simple "key": "value" database in a text file and start using it:
$ cat qjump.txt
"nimony": "~/Dropbox/nim/Nimony"
"xcb": "~/Dropbox/c64/XC=BASIC"
$ pwd
/tmp
$ qj nimony
$ pwd
/home/user/Dropbox/nim/Nimony
$ qj xcb
$ pwd
/home/user/Dropbox/c64/XC=BASIC
During my daily work, there are some folders that I visit regularly. QJump lets me change directories with the speed of light :)
See the GitHub page (https://github.com/jabbalaci/qjump) for more details.
Why not simply:
alias gonimony='cd "$HOME/Dropbox/nim/Nimony"' (put it in .bashrc or .profile or .zhsrc (or similar) then:
$ gonimony
$ pwd
/home/user/Dropbox/nim/Nimony
or:
go() {
case "$1" in
proj) cd "$HOME/projects" ;;
docs) cd "$HOME/Documents" ;;
tmp) cd /tmp ;;
*) printf 'Usage: go {proj|docs|tmp}\n' ;;
esac
} then:
$ go proj
$ pwd
/home/user/projects
Or even better, a portable bookmark system:
BOOKS="$HOME/.bookmarks"
mark() {
[ -z "$1" ] && { echo "mark <name>"; return; }
mkdir -p "$(dirname "$BOOKS")"
# remove old entry
grep -v "^$1=" "$BOOKS" 2>/dev/null > "$BOOKS.tmp" || true
printf '%s=%s\n' "$1" "$PWD" >> "$BOOKS.tmp"
mv "$BOOKS.tmp" "$BOOKS"
}
_go_fuzzy() {
# find closest match by substring
grep "$1" "$BOOKS" | head -n1
}
go() {
[ -z "$1" ] && { echo "go <name>"; return; }
# exact match
line=$(grep "^$1=" "$BOOKS" 2>/dev/null)
# fuzzy fallback
[ -z "$line" ] && line=$(_go_fuzzy "$1")
[ -z "$line" ] && { echo "No match for '$1'"; return; }
dir=${line#*=}
cd "$dir" || echo "Cannot cd to $dir"
} (put this in ~/.shrc and source it from .bashrc, .zshrc, etc.)
Usage:
$ cd ~/projects/myapp
$ mark app
$ cd /
$ go app
$ pwd
/home/user/projects/myapp
$ go pro # matches "project" via 'fuzzy search' mechanism - no need to be precise
$ pwd
/home/user/projects/myapp
Don't you think Nim is an overkill for such usecase? I think Nim is worthy of more ambitious problems to solve with it ;)
Here's something more convenient (to my liking). Like fzf, but less fuzzy.
vip + lfreq + a harness for you shell, Fish in my case.
A shell function:
# fish shell function, saved to ~/.config/fish/functions/dvip.fish
function dvip
# 1. Get only the current token (the word the cursor is on) to use as the initial query
set -l query (commandline -t)
# 2. Run the selection logic
set -l selection (lfreq -o.975 -f@k -n-99999 < "/home/$USER/.local/share/vip/pwdlog" | vip -r "$query")
# 3. If a selection was made...
if test -n "$selection"
# Use -tr to REPLACE the current TOKEN with the selection
commandline -tr -- "$selection"
end
# 4. Optional: Force a repaint to ensure the UI updates immediately
commandline -f repaint
end
In you config.fish:
# Step 1: Log directory changes on every prompt.
# Use the fish_prompt event to save the current directory to a history file.
# Ensure the directory for the log file exists.
set pwd_log_dir "/home/$USER/.local/share/vip"
function log_directory_history --on-variable PWD
# Append the current directory to the log file.
pwd >> "$pwd_log_dir/pwdlog"
end
lfreq by cblake:
"n" : "emit `n`-most common lines(0:all; <0 sorted)",
"count": "only emit counts: unique & grand total",
"size" : "pre-size hash table for size unique entries",
"dSize": "pre-size str data area to this many bytes",
"recTerm": "input record terminator",
"RecTerm": "output record terminator",
"format" : "output format: @k=key @c=count @f=fraction",
"old" : "exponen.weight for 'old' ages (if not intCnt)",
"tm" : "emit wall time of counting to stderr & quit"}
vip by cblake:
"qs" : "initial query strings to interactively edit",
"n" : "max number of terminal rows to use",
"alt" : "use the alternate screen buffer",
"inSen" : "match query case-insensitively; Ctrl-I",
"sort" : "sort by match score,not input order; Ctrl-O",
"term" : "input record terminator (vs. newline)",
"delim" : "Pre-1st-*THIS* = Context Label; Post=AnItem",
"label" : "emit parsed label to this file descriptor",
"digits": "num.digits for nMatch/nItem on query Line",
"rev" : "reverse default \"log file\" input order",
"quit" : "value written upon quit (e.g. Ctrl-C)",
"keep" : "Eg `-klibvip.so:cdable` ptr,len->cint==1",
"print" : "Eg `-plibvip.so:zxhPrint` (ou,mxOu,i,nI)->nO",
"colors": "colorAliases;Syntax: NAME = ATTR1 ATTR2..",
"color":""";-separated on/off attrs for UI elements:
qtext choice match label"""}, short={"color": 'c', "digits": 'D'
This setup brings up a list of the visited paths sorted by "frecency" and makes navigation effortless. Configurable and as simple as it can be. No effort from the user required - your behaviour defines the results.
Marking directories or adding them to bookmarks manually will get annoying fast. They'll also get stale or break if you change parent directories.
Something like z is a better model, because it remembers all paths that you cd into and then fuzzy matches directory names.