main
1# Directory bookmarks using zsh static named directories (hash -d)
2# Inspired by https://vincent.bernat.ch/en/blog/2015-zsh-directory-bookmarks
3#
4# Plain text files (containing target path) instead of symlinks,
5# so bookmarks sync cleanly via Syncthing.
6#
7# Usage:
8# bookmark name — bookmark PWD as "name"
9# bookmark . — bookmark PWD using its basename
10# bookmark -d name — delete bookmark
11# bookmark -l name — create local-only bookmark (not synced)
12# bookmark — list all bookmarks
13# ~-name — use bookmark in any path context
14# @@ — ZLE shortcut, inserts ~-
15
16typeset -g MARKPATH_SHARED=$HOME/sync/bookmarks
17typeset -g MARKPATH_LOCAL=${XDG_DATA_HOME:-$HOME/.local/share}/bookmarks
18
19_bookmark-populate() {
20 local f
21 for f ($MARKPATH_SHARED/*(N.) $MARKPATH_LOCAL/*(N.)) {
22 hash -d -- -${f:t}="$(<$f)"
23 }
24}
25_bookmark-populate
26
27_vde-insert-bookmark() {
28 emulate -L zsh
29 LBUFFER=${LBUFFER}"~-"
30}
31zle -N _vde-insert-bookmark
32bindkey '@@' _vde-insert-bookmark
33
34bookmark() {
35 local markpath=$MARKPATH_SHARED
36 local -a delete local_flag
37 zparseopts -D d=delete l=local_flag
38
39 (( $+local_flag[1] )) && markpath=$MARKPATH_LOCAL
40
41 if (( $# == 0 )) && (( ! $+delete[1] )); then
42 local f
43 for f ($MARKPATH_SHARED/*(N.) $MARKPATH_LOCAL/*(N.)) {
44 local origin="shared"
45 [[ $f = $MARKPATH_LOCAL/* ]] && origin="local"
46 local markname=${(%):-%F{green}${f:t}%f}
47 local marktarget=${(%):-%F{blue}$(<$f)%f}
48 local markorigin=${(%):-%F{yellow}${origin}%f}
49 printf "%-30s → %-50s [%s]\n" $markname $marktarget $markorigin
50 }
51 elif (( $+delete[1] )); then
52 command rm -f $MARKPATH_SHARED/$1 $MARKPATH_LOCAL/$1
53 unhash -d -- -$1 2>/dev/null
54 else
55 local name=$1
56 [[ $name == "." ]] && name=${PWD:t}
57 [[ -d $markpath ]] || mkdir -p $markpath
58 print -r -- $PWD > $markpath/$name
59 hash -d -- -${name}=${PWD}
60 fi
61}