Commit c9da38b6c04b
Changed files (1)
dots
config
zsh
core
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
+}