Commit c9da38b6c04b

Vincent Demeester <vincent@sbr.pm>
2026-07-06 23:11:21
feat(zsh): add directory bookmarks with syncthing sync
Plain text file-based bookmarks using zsh named directories. Shared bookmarks sync via ~/sync/bookmarks, local ones stored in ~/.local/share/bookmarks. Inspired by Vincent Bernat's zshrc.
1 parent f6de297
Changed files (1)
dots
config
dots/config/zsh/core/55-bookmarks.zsh
@@ -0,0 +1,61 @@
+# Directory bookmarks using zsh static named directories (hash -d)
+# Inspired by https://vincent.bernat.ch/en/blog/2015-zsh-directory-bookmarks
+#
+# Plain text files (containing target path) instead of symlinks,
+# so bookmarks sync cleanly via Syncthing.
+#
+# Usage:
+#   bookmark name    — bookmark PWD as "name"
+#   bookmark .       — bookmark PWD using its basename
+#   bookmark -d name — delete bookmark
+#   bookmark -l name — create local-only bookmark (not synced)
+#   bookmark         — list all bookmarks
+#   ~-name           — use bookmark in any path context
+#   @@               — ZLE shortcut, inserts ~-
+
+typeset -g MARKPATH_SHARED=$HOME/sync/bookmarks
+typeset -g MARKPATH_LOCAL=${XDG_DATA_HOME:-$HOME/.local/share}/bookmarks
+
+_bookmark-populate() {
+    local f
+    for f ($MARKPATH_SHARED/*(N.) $MARKPATH_LOCAL/*(N.)) {
+        hash -d -- -${f:t}="$(<$f)"
+    }
+}
+_bookmark-populate
+
+_vde-insert-bookmark() {
+    emulate -L zsh
+    LBUFFER=${LBUFFER}"~-"
+}
+zle -N _vde-insert-bookmark
+bindkey '@@' _vde-insert-bookmark
+
+bookmark() {
+    local markpath=$MARKPATH_SHARED
+    local -a delete local_flag
+    zparseopts -D d=delete l=local_flag
+
+    (( $+local_flag[1] )) && markpath=$MARKPATH_LOCAL
+
+    if (( $# == 0 )) && (( ! $+delete[1] )); then
+        local f
+        for f ($MARKPATH_SHARED/*(N.) $MARKPATH_LOCAL/*(N.)) {
+            local origin="shared"
+            [[ $f = $MARKPATH_LOCAL/* ]] && origin="local"
+            local markname=${(%):-%F{green}${f:t}%f}
+            local marktarget=${(%):-%F{blue}$(<$f)%f}
+            local markorigin=${(%):-%F{yellow}${origin}%f}
+            printf "%-30s → %-50s [%s]\n" $markname $marktarget $markorigin
+        }
+    elif (( $+delete[1] )); then
+        command rm -f $MARKPATH_SHARED/$1 $MARKPATH_LOCAL/$1
+        unhash -d -- -$1 2>/dev/null
+    else
+        local name=$1
+        [[ $name == "." ]] && name=${PWD:t}
+        [[ -d $markpath ]] || mkdir -p $markpath
+        print -r -- $PWD > $markpath/$name
+        hash -d -- -${name}=${PWD}
+    fi
+}