diff --git a/README.org b/README.org index d98ec7a..75272e4 100644 --- a/README.org +++ b/README.org @@ -684,11 +684,32 @@ have ~tab-bar-tab-post-open-functions~, the bookmark context will not be available when those functions are called. #+begin_src emacs-lisp + (add-hook 'bufferlo-bookmark-map-functions #'buffer-bookmark-store-fun) + (add-hook 'bufferlo-bookmark-buffer-handler-functions #'buffer-bookmark-restore-fun) (add-hook 'bufferlo-bookmark-tab-handler-functions #'tab-bookmark-fun) (add-hook 'bufferlo-bookmark-frame-handler-functions #'frame-bookmark-fun) (add-hook 'bufferlo-bookmark-set-handler-functions #'set-bookmark-fun) #+end_src +There are buffer-bookmark convenience functions you can use to persist +text-scale-mode-amount, and persist buffer-local variables (though you should +prefer [[https://www.gnu.org/software/emacs/manual/html_node/emacs/File-Variables.html][file-local variables]], and directory variables [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html][directory variables]] and +take care to store buffer local variables that you consider safe to restore, +see [[https://www.gnu.org/software/emacs/manual/html_node/elisp/File-Local-Variables.html#index-safe_002dlocal_002dvariable_002dp][risky-local-variable-p]]). + +Note: These need to be bound before ~bufferlo-mode~ is enabled. + +#+begin_src emacs-lisp + ;; To persist text-scale-mode-amount + (setq bufferlo-bookmark-buffer-locals t) +#+end_src + +#+begin_src emacs-lisp + ;; To persist buffer-local variables + (setq bufferlo-bookmark-text-scale-mode-amount t) + (setq bufferlo-bookmark-buffer-local-variables '(my:special-local-1 my:special-local-2)) +#+end_src + *** Frame geometry options Bufferlo provides wrappers around Emacs frame functions to provide @@ -1133,6 +1154,8 @@ remain in force until they are saved if this policy is set to t. (setq bufferlo-prefer-local-buffers 'tabs) (setq bufferlo-ibuffer-bind-local-buffer-filter t) (setq bufferlo-ibuffer-bind-keys t) + (setq bufferlo-bookmark-buffer-locals t) + (setq bufferlo-bookmark-text-scale-mode-amount t) :config (setq bufferlo-mode-line-prefix "🐃") ; "🐮" (setq bufferlo-mode-line-set-active-prefix "Ⓢ") @@ -1173,6 +1196,7 @@ remain in force until they are saved if this policy is set to t. (setq bufferlo-bookmark-frame-save-on-delete 'when-bookmarked) (setq bufferlo-bookmark-tab-save-on-close 'when-bookmarked) (setq bufferlo-close-tab-kill-buffers-prompt t) + (setq bufferlo-bookmark-buffer-local-variables '(tab-width)) (setq bufferlo-bookmark-frame-load-make-frame 'restore-geometry) (setq bufferlo-bookmark-frame-load-policy 'prompt) (setq bufferlo-bookmark-frame-duplicate-policy 'prompt) diff --git a/bufferlo.el b/bufferlo.el index 4a32210..0e46879 100644 --- a/bufferlo.el +++ b/bufferlo.el @@ -191,6 +191,36 @@ This overrides buffers excluded by `bufferlo-bookmark-buffers-exclude-filters'." :package-version '(bufferlo . "1.1") :type '(repeat regexp)) +(defcustom bufferlo-bookmark-buffer-local-variables '() + "List of buffer-local variables to store/restore in/from buffer bookmarks. +This is a list of symbols; e.g., \\='(my:special-local my:special-local-2). + +To use this, add the function +`bufferlo-bookmark-map-function-buffer-locals` to +`bufferlo-bookmark-map-functions` to store buffer locals, and its +corollary function `bufferlo-bookmark-buffer-handler-buffer-locals` +`bufferlo-bookmark-buffer-handler-functions` to restore them when a +bufferlo buffer bookmark is restored. + +Note: Local file variables and directory variables are the preferred +methods for managing buffer-local variables. Use this facility only +when necessary. + +See Info nodes `(elisp) File Local Variables' and `(elisp) Directory +Local Variables'." + :package-version '(bufferlo . "1.3") + :type '(repeat symbol)) + +(defcustom bufferlo-bookmark-buffer-locals t + "If non-nil, enable bookmark buffer-local variable persistence." + :package-version '(bufferlo . "1.3") + :type 'boolean) + +(defcustom bufferlo-bookmark-text-scale-mode-amount t + "If non-nil, enable bookmark `text-scale-mode-amount` persistence." + :package-version '(bufferlo . "1.3") + :type 'boolean) + (defcustom bufferlo-bookmark-frame-load-make-frame nil "If non-nil, create a new frame to hold a loaded frame bookmark. Set to \\='restore-geometry to restore the frame geometry to that @@ -628,6 +658,17 @@ frame bookmark is a collection of tab bookmarks." :package-version '(bufferlo . "0.8") :type 'hook) +(defcustom bufferlo-bookmark-buffer-handler-functions nil + "Abnormal hooks to call after a bookmark buffer is handled. +This is the corollary to `bufferlo-bookmark-map-functions` to process +extra properties added to a buffer bookmark. + +Each function is called with the restored buffer current, and with the +following arguments: + bookmark-record: See `bookmark-make-record-default`." + :package-version '(bufferlo . "1.3") + :type 'hook) + (defcustom bufferlo-bookmark-tab-handler-functions nil "Abnormal hooks to call after a bookmark tab is handled. Each function takes the following arguments: @@ -1004,7 +1045,7 @@ string, FACE is the face for STR." #'string-equal))) (setq bufferlo--command-line-noload pos) (setq command-line-args (seq-remove-at-position command-line-args pos))) - (when (file-exists-p (expand-file-name "bufferlo-noload" user-emacs-directory)) + (when (locate-user-emacs-file "bufferlo-noload") (message "bufferlo-noload file found; inhibiting bufferlo bookmark loading") (setq bufferlo--command-line-noload t))) @@ -1100,7 +1141,13 @@ string, FACE is the face for STR." #'bufferlo-bookmark--tab-save-on-close) (add-hook 'delete-frame-functions #'bufferlo-bookmark--frame-save-on-delete) - ;; bookmark advice + (when bufferlo-bookmark-buffer-locals + (add-hook 'bufferlo-bookmark-map-functions #'bufferlo-bookmark-map-function-buffer-locals) + (add-hook 'bufferlo-bookmark-buffer-handler-functions #'bufferlo-bookmark-buffer-handler-buffer-locals)) + (when bufferlo-bookmark-text-scale-mode-amount + (add-hook 'bufferlo-bookmark-map-functions #'bufferlo-bookmark-map-function-text-scale-mode-amount) + (add-hook 'bufferlo-bookmark-buffer-handler-functions #'bufferlo-bookmark-buffer-handler-text-scale-mode-amount)) + ;; bookmark commands advice (advice-add #'bookmark--jump-via :around #'bufferlo--bookmark--jump-via-advice) (advice-add #'bookmark-rename :around #'bufferlo--bookmark-rename-advice) (advice-add #'bookmark-delete :around #'bufferlo--bookmark-delete-advice) @@ -1148,7 +1195,19 @@ string, FACE is the face for STR." #'bufferlo-bookmark--tab-save-on-close) (remove-hook 'delete-frame-functions #'bufferlo-bookmark--frame-save-on-delete) - ;; bookmark advice + ;; bufferlo-bookmark-buffer-locals + (progn + (remove-hook 'bufferlo-bookmark-map-functions + #'bufferlo-bookmark-map-function-buffer-locals) + (remove-hook 'bufferlo-bookmark-buffer-handler-functions + #'bufferlo-bookmark-buffer-handler-buffer-locals)) + ;; bufferlo-bookmark-text-scale-mode-amount + (progn + (remove-hook 'bufferlo-bookmark-map-functions + #'bufferlo-bookmark-map-function-text-scale-mode-amount) + (remove-hook 'bufferlo-bookmark-buffer-handler-functions + #'bufferlo-bookmark-buffer-handler-text-scale-mode-amount)) + ;; bookmark commands advice (advice-remove #'bookmark--jump-via #'bufferlo--bookmark--jump-via-advice) (advice-remove #'bookmark-rename #'bufferlo--bookmark-rename-advice) (advice-remove #'bookmark-delete #'bufferlo--bookmark-delete-advice))) @@ -2380,6 +2439,62 @@ empty (no-op) display-func." err bookmark))) nil))) +(defun bufferlo-bookmark-map-function-buffer-locals (bookmark-record) + "Store buffer local variables in BOOKMARK-RECORD. +Add this function to `bufferlo-bookmark-map-functions`, and add a list +of symbols representing the variables you want to store in +`bufferlo-buffer-locals`. + +These are restored upon buffer bookmark loading if +`bufferlo-bookmark-buffer-handler-buffer-locals` is a member of +`bufferlo-bookmark-buffer-handler-functions`. + +Note: Take care to store buffer local variables that you consider safe +to restore, which see `risky-local-variable-p`." + (when-let* ((buffer-locals + (seq-filter + (lambda (x) (not (null x))) + (mapcar (lambda (sym) + (when (local-variable-p sym) + (cons sym (symbol-value sym)))) + bufferlo-bookmark-buffer-local-variables)))) + (bookmark-prop-set bookmark-record + 'bufferlo-buffer-locals + buffer-locals)) + bookmark-record) + +(defun bufferlo-bookmark-buffer-handler-buffer-locals (bookmark-record) + "Restore buffer local variables from BOOKMARK-RECORD. +See `bufferlo-bookmark-map-function-buffer-locals`." + (when-let* + ((buffer-locals + (bookmark-prop-get bookmark-record + 'bufferlo-buffer-locals))) + (mapc (lambda (pair) + (make-local-variable (car pair)) + (set (car pair) (cdr pair))) + buffer-locals))) + +(defun bufferlo-bookmark-map-function-text-scale-mode-amount (bookmark-record) + "Store the buffer local `text-scale-mode-amount` in BOOKMARK-RECORD. +Add this function to `bufferlo-bookmark-map-functions`, and its +corollary `bufferlo-bookmark-buffer-handler-text-scale-mode-amount` +to`bufferlo-bookmark-buffer-handler-functions`." + (when text-scale-mode-amount + (bookmark-prop-set bookmark-record + 'bufferlo-text-scale-mode-amount + text-scale-mode-amount)) + bookmark-record) + +(defun bufferlo-bookmark-buffer-handler-text-scale-mode-amount (bookmark-record) + "Restore `text-scale-mode-amount` from BOOKMARK-RECORD. +See `bufferlo-bookmark-map-function-text-scale-mode-amount`." + (when-let* + ((val + (bookmark-prop-get bookmark-record + 'bufferlo-text-scale-mode-amount))) + (text-scale-set val))) + (defun bufferlo--bookmark-get-for-buffer (buffer) "Get `buffer-name' and bookmark for BUFFER." (with-current-buffer buffer @@ -2781,6 +2896,9 @@ Returns nil on success, non-nil on abort." (funcall (or (bookmark-get-handler record) 'bookmark-default-handler) record) + (run-hook-with-args + 'bufferlo-bookmark-buffer-handler-functions + record) (run-hooks 'bookmark-after-jump-hook) nil) (error