From c971f1b6e809f9fb6373329d14db7e27ea7d4749 Mon Sep 17 00:00:00 2001 From: Alexander Rosenberg Date: Sun, 10 Mar 2024 05:54:07 -0700 Subject: [PATCH] Change to emacs-bookmark.zsh --- emacs-bookmark.zsh | 166 +++++++++++++++++++++++++++++++++++++++++++++ init.zsh | 9 ++- 2 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 emacs-bookmark.zsh diff --git a/emacs-bookmark.zsh b/emacs-bookmark.zsh new file mode 100644 index 0000000..5e9acd4 --- /dev/null +++ b/emacs-bookmark.zsh @@ -0,0 +1,166 @@ +# Emacs-based bookmark system + +# Enable color utilities +autoload colors && colors + +__bm_bookmark_cache=() + +function __bm_find_user_emacs_dir { + [[ -f "${HOME}/.emacs.d/var/bookmark-default.el" ]] && + { printf '%s' "${HOME}/.emacs.d/var/bookmark-default.el"; return 0 } + [[ -f "${HOME}/.emacs.d/bookmark-default.el" ]] && + { printf '%s' "${HOME}/.emacs.d/bookmark-default.el"; return 0 } + [[ -f "${HOME}/.config/emacs/var/bookmark-default.el" ]] && + { printf '%s' "${HOME}/.config/emacs/var/bookmark-default.el"; return 0 } + [[ -f "${HOME}/.config/emacs/bookmark-default.el" ]] && + { printf '%s' "${HOME}/.config/emacs/bookmark-default.el"; return 0 } + [[ -f "${XDG_CONFIG_HOME}/emacs/var/bookmark-default.el" ]] && + { printf '%s' "${XDG_CONFIG_HOME}/emacs/var/bookmark-default.el"; return 0 } + [[ -f "${XDG_CONFIG_HOME}/emacs/bookmark-default.el" ]] && + { printf '%s' "${XDG_CONFIG_HOME}/emacs/bookmark-default.el"; return 0 } + printf 'Could not discover Emacs bookmark file! Please set $BM_MODE to +"daemon" or define $BM_BOOKMARK_PATH!\n' + return 1 +} +function __bm_update_bookmark_list { + local quoted_output + case "${BM_MODE}" in + 'daemon') + quoted_output=(${(z)${"$(command emacsclient --eval \ +"(let ((out)) + (dolist (entry bookmark-alist out) + (let ((path (alist-get 'filename (cdr entry) "")) + (pos (alist-get 'position (cdr entry) 1))) + (setq out (append (list (car entry) path + (expand-file-name path) pos) + out)))))")":1:-1}}) + ;; + ''|'emacs') + if ! [[ -v BM_BOOKMARK_PATH ]]; then + local BM_BOOKMARK_PATH="$(__bm_find_user_emacs_dir)" + fi + quoted_output=(${(z)${"$(command emacs -Q --batch --eval \ +"(prin1 + (with-temp-buffer + (insert-file-contents \"${BM_BOOKMARK_PATH:gs#\\#\\\\#:gs#\"#\\\"#}\") + (require 'cl-lib) + (let ((out)) + (dolist (entry (read (current-buffer)) out) + (let ((path (alist-get 'filename (cdr entry) "")) + (pos (alist-get 'position (cdr entry) 1))) + (setq out (append (list (car entry) path + (expand-file-name path) pos) + out)))))))))")":1:-1}}) + ;; + *) + printf 'Unknown value for $BM_MODE: "%s"\n' "${BM_MODE}" + return 1 + ;; + esac + __bm_bookmark_cache=() + for entry in ${quoted_output}; do + __bm_bookmark_cache+="${(Q)entry}" + done +} +function __bm_bookmark_location { + for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do + if [[ "${1}" = "${__bm_bookmark_cache[${i}]}" ]]; then + printf '%s\n%d\n' "${__bm_bookmark_cache[${i} + 2]}" \ + "${__bm_bookmark_cache[${i} + 3]}" + return 0 + fi + done + return 1 +} +function __bm_list_bookmarks { + for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do + local name="${__bm_bookmark_cache[${i}]}" + local pretty_path="${__bm_bookmark_cache[${i} + 1]}" + local abs_path="${__bm_bookmark_cache[${i} + 2]}" + local print_color="" + if [[ -d "${abs_path}" ]]; then + print_color="${bold_color}${fg[blue]}" + fi + printf "${print_color}%s${reset_color} => %s\n" \ + "${name}" "${pretty_path}" + done +} + +alias lsbm="__bm_update_bookmark_list && __bm_list_bookmarks" +function bm { + __bm_update_bookmark_list || \ + { printf 'Updating bookmark list failed!\n'; return 1 } + (( ${#} == 0 )) && { __bm_list_bookmarks; return } + local loc=(${(f)"$(__bm_bookmark_location "${1}")"}) + if [[ -d "${loc[1]}" ]]; then + cd "${loc[1]}" + [[ "${BM_CWD_LS}" = '1' ]] && ls || true + elif [[ -e "${loc[1]}" ]]; then + ${=EDITOR} "${loc[1]}" + else + printf 'No such bookmark: "%s"\n' "${1}" + return 1 + fi +} + +function bmadd { + if [[ "${1}" = '-h' ]]; then + printf 'usage: bmadd [PATH] [NAME]\n' + return 0 + fi + [[ "${1}" = '--' ]] && shift 1 + local name + local loc + case "${#}" in + 0) + loc="${PWD}" + name="${PWD:t}" + ;; + 1) + loc="${1}" + name="${1:t}" + ;; + *) + loc="${1}" + name="${2}" + ;; + esac + local res="$(emacsclient --eval \ +"(let* ((loc \"${loc:gs#\\#\\\\#:gs#\"#\\\"#}\") + (name \"${name:gs#\\#\\\\#:gs#\"#\\\"#}\") + (res (with-temp-buffer + (set-visited-file-name loc t nil) + (bookmark-set name) + (set-buffer-modified-p nil))) + (inhibit-message t)) + (bookmark-save) + res)")" + [[ "${res}" = 'nil' ]] && printf 'Added bookmark "%s"\n' "${name}" \ + || { printf '%s\n' "${res}"; return 1 } +} + +function bmrm { + if [[ "${1}" = '-h' ]]; then + printf 'usage: bmrm [NAME]\n' + return 0 + fi + [[ "${1}" = '--' ]] && shift 1 + if (( ${#} < 1 )); then + printf 'usage: bmrm [NAME]\n' + return 1 + fi + printf 'Really delete "%s" [y/N]: ' "${1}" + if read -q; then + printf '\n' + local res="$(emacsclient --eval \ +"(let* ((res (bookmark-delete \"${1:gs#\\#\\\\#:gs#\"#\\\"#}\")) + (inhibit-message t)) + (bookmark-save) + res)")" + [[ "${res}" = 'nil' ]] && printf 'Deleted bookmark "%s"\n' "${1}" \ + || { printf '%s\n' "${res}"; return 1 } + else + printf '\n' + return 1 + fi +} diff --git a/init.zsh b/init.zsh index fe9a86a..396243f 100644 --- a/init.zsh +++ b/init.zsh @@ -252,9 +252,12 @@ if cmd_exists direnv; then fi # Bookmarks -[ -v ZSH_BOOKMARK_DIR ] || ZSH_BOOKMARK_DIR="${HOME}/.cache/zsh/bookmarks" -[ -v ZSH_BOOKMARK_LS ] || ZSH_BOOKMARK_LS=true -source "${ZSH_CONFIG_DIR}/bookmark.zsh" +# [ -v ZSH_BOOKMARK_DIR ] || ZSH_BOOKMARK_DIR="${HOME}/.cache/zsh/bookmarks" +# [ -v ZSH_BOOKMARK_LS ] || ZSH_BOOKMARK_LS=true +# source "${ZSH_CONFIG_DIR}/bookmark.zsh" +[[ -v BM_MODE ]] || BM_CWD_LS=1 +[[ -v BM_MODE ]] || BM_MODE=daemon +source "${ZSH_CONFIG_DIR}/emacs-bookmark.zsh" # Platform specific stuff [ -f /usr/bin/pacman ] && source "${ZSH_CONFIG_DIR}/arch.zsh"