Skip to content

Instantly share code, notes, and snippets.

@godDLL
Last active October 1, 2022 07:46
Show Gist options
  • Save godDLL/d6529ad64fe7359686b7bb8d0eb545e3 to your computer and use it in GitHub Desktop.
Save godDLL/d6529ad64fe7359686b7bb8d0eb545e3 to your computer and use it in GitHub Desktop.
Quick jump to file or folder, sorted by recency.

Z Fish

Choose a file to edit or a directory to visit, quickly.
Screen Shot 2021-12-04 at 22 40 14

Automatically sorted by recent use. Can have multiple lists.

Add items easily from the command line. Interactively remove from items in a list.

Can integrate with the excellent fzf for fuzzy search and better keyboard navigation.

100 lines of code or so. Not big.

Install

You need three functions autoloaded into your Fish. This is for use in Fish shell, not as a standalone script.

  • pick (can be calling out to fzf) for selecting an item with [ or ] and Enter.
  • fish_z is the actual quick-jump function, defaults to the "goto" list.
  • q or c or similar shortcut function for your "places" or "config" list.

Usage

To add the current directory to a list use fish_z . or q .

To go to a directory on the list use fish_z or q

To add a file to the list, do fish_z ~/.vimrc or full path to file.

To choose an item to remove use fish_z -e or q --remove

Screen Shot 2021-12-04 at 23 02 48
There is --help to every function supplied.

# Quick picker for configuration and directories.
# fish_z v0.1 gist.github.com/godDLL/d6529ad64fe7359686b7bb8d0eb545e3
function pick --description 'Show a screenful of options, pick one'
if test -n "$argv[1]"
and contains -- "$argv[1]" -h --help
echo 'Usage: pick [OPTIONS] ITEM1 ITEM2 ...
Returns selected item number.
-i NUM pre-select item
-d STR menu item delimiter, default to \n
-x return code is item index, no echo
' >&2
return
else
set -l clm \e\[m
set -l sel \e\[7m
argparse 'i/item=' 'd/delim=' 'x/echo' -- $argv
test -n "$_flag_d"
and set -l NL $_flag_d
or set -l NL \n
test -n "$_flag_i"
and set -l ID $_flag_i
or set -l ID 1
set -l -- ITEM ' '{$argv}' '
set -l -- LEN (count -- $ITEM)
set -- ITEM[$ID] "$sel$ITEM[$ID]$clm"
echo -en \e\[A >&2
string join -- $NL ' '{$ITEM}' ' >&2
echo -en \e\[H >&2
while read -s -n1 -P '' -l K
switch "$K"
case ' ' '' # select
test -z "$_flag_x"
and echo -en -- $argv[$ID]
or return $ID
return
case ',' k h \[ \' # back
set ITEM[$ID] ' '$argv[$ID]' '
test 1 -lt $ID
and set ID (math -s0 $ID'- 1')
case '.' j l \] \\ # forth
set ITEM[$ID] ' '$argv[$ID]' '
test 1 -lt (math -s0 "$LEN - $ID")
and set ID (math -s0 $ID'+ 1')
end #switch
set ITEM[$ID] "$sel$ITEM[$ID]$clm"
echo -en \e\[A >&2
string join -- $NL ' '{$ITEM}' ' >&2
echo -en \e\[H >&2
end
end
end #fun
function fish_z --description 'Quick jump to fav/goto files and folders'
set -l I
set -l K 'goto'
set -l C
if test -n "$argv"
if contains -- $argv[1] '-h' '--help'
echo -e -- "Usage: fish_z [- KEY]
# Choose directory to cd or file to edit
fish_z [- KEY] DIR|FILE
# Add an item
fish_z [- KEY] -e|--remove
# Choose an item to remove
fish_z -2 config ~/.vimrc
# Add file to list config, use color 2 (green)
# Ctrl-C to exit
" >&2
return
end
if test '-' = (string sub -l1 -- $argv[1])
set -- K $argv[2]
set -- C (string sub -l1 -s2 -- $argv[1])
set -e argv[1..2]
end
end
test -z "$C"
and set C 5
set -l H (math -s0 '4+ '(string length -- $K))
echo -e -- '\e[A\e['$COLUMNS'G\e['$H'D\e[3'$C'm\e[30;4'$C"m $K: \e[0m" >&2
set -- K fish_z_$K
set I $$K
if test -n "$argv"
set -l A "$argv"
if not contains -- "$A" '-e' '--remove'
test '.' = "$A"
and set A (pwd)
set -p -- I (string replace -- "$HOME" '~' $A)
end
end
set -l bI \e\[2m'..'
set -l aI \e\[2m'-'
pick -x -i 3 $bI $I $aI
set -l ID $status
if test 0 -eq "$ID"
return
else
set ID (math -s0 "$ID -1")
end
set -l tI
if test 0 -ne "$ID" -a (count $I) -ge "$ID"
if contains -- "$argv" '-e' '--remove'
set -e I[$ID]
set -U $K $I
return
else
set -- tI $I[$ID]
set -e I[$ID]
set -p -- I $tI
end
else if test 0 -eq "$ID"
set -- tI $bI
else
set -- tI $aI
end
set -U $K $I
set -l G
if test "$aI" = "$tI"
cd -
set G $PWD
else
set G (echo -- $tI |sed 's/'\e'\[[0-9;]*[m]//g' |string replace -- '~' "$HOME")
if test -d "$G"
cd "$G"
else
$EDITOR -o "$G"
end
end
test '..' = "$G"
and set -- G $PWD
set -- G (string replace -- "$HOME" '~' $G)
set -l -- L (math -s0 "$COLUMNS -4 -$H -"(string length -- $G))
test 0 -ge "$L"
and printf '\e[A\e[2;3%sm%s\e[0m\n' $C $G >&2
or printf '\e[A\e[%sC \e[2;3%sm%s\e[0m\n' $L $C $G >&2
end #fun
function q
if contains -- "$argv" '-h' '--help'
echo -- 'fish_z - places'
fish_z --help
else
fish_z - places $argv
end
end #fun
@godDLL
Copy link
Author

godDLL commented Dec 4, 2021

License MIT, free to do whatever. Yours to fuck up.
asciinema.org/a/453650
Screen Shot 2021-12-04 at 21 09 38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment