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}