commit 980888ab4e1bce741f3d9473ab6639933a2f2dae
parent 03756fa6ad4dcca5e0920622b1ee3f70abfc4e39
Author: andsy10 <andsy1016@gmail.com>
Date: Sat, 26 Sep 2026 14:37:47 +0800
Add back/forward navigation commands
Diffstat:
| M | helpful.el | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 68 insertions(+), 0 deletions(-)
diff --git a/helpful.el b/helpful.el
@@ -2678,9 +2678,72 @@ Returns the symbol."
predicate t nil nil
default-val)))
+(defvar helpful--back-stack nil
+ "Stack of previously visited helpful buffers.
+Each item takes the form (BUFFER SYMBOL CALLABLE-P POINT).
+
+Used by `helpful-go-back'.")
+
+(defvar helpful--forward-stack nil
+ "Stack of helpful buffers visited after going back.
+Each item takes the form (BUFFER SYMBOL CALLABLE-P POINT).
+
+Used by `helpful-go-forward'.")
+
+(defvar helpful--inhibit-history nil
+ "Non-nil to prevent `helpful--update-and-switch-buffer' recording history.
+This is bound dynamically when navigating the history, so going
+back or forward doesn't modify the stacks.")
+
+(defun helpful--record-history (buf)
+ "Record a visit to BUF from the current buffer, if appropriate."
+ (when (and (not helpful--inhibit-history)
+ (not (eq buf (current-buffer)))
+ (eq major-mode 'helpful-mode))
+ (push (list (current-buffer) helpful--sym helpful--callable-p (point))
+ helpful--back-stack)
+ (setq helpful--forward-stack nil)))
+
+(defun helpful--goto-history-item (item)
+ "Switch to the helpful buffer recorded in ITEM, restoring point.
+ITEM takes the form (BUFFER SYMBOL CALLABLE-P POINT). If BUFFER
+has been killed, recreate it from SYMBOL and CALLABLE-P."
+ (-let [(buf sym callable-p pos) item]
+ (let ((helpful--inhibit-history t))
+ (unless (buffer-live-p buf)
+ ;; BUFFER has been killed (e.g. by `helpful-max-buffers'),
+ ;; recreate it.
+ (setq buf (helpful--buffer sym callable-p))
+ (with-current-buffer buf
+ (helpful-update)))
+ (funcall helpful-switch-buffer-function buf)
+ (let ((pos (min pos (with-current-buffer buf (point-max)))))
+ (if-let* ((win (get-buffer-window buf)))
+ (set-window-point win pos)
+ (with-current-buffer buf (goto-char pos)))))))
+
+(defun helpful-go-back ()
+ "Go back to the previously visited helpful buffer."
+ (interactive nil helpful-mode)
+ (unless helpful--back-stack
+ (user-error "No previous helpful buffer"))
+ (push (list (current-buffer) helpful--sym helpful--callable-p (point))
+ helpful--forward-stack)
+ (helpful--goto-history-item (pop helpful--back-stack)))
+
+(defun helpful-go-forward ()
+ "Go forward to the helpful buffer visited before going back."
+ (interactive nil helpful-mode)
+ (unless helpful--forward-stack
+ (user-error "No next helpful buffer"))
+ (push (list (current-buffer) helpful--sym helpful--callable-p (point))
+ helpful--back-stack)
+ (helpful--goto-history-item (pop helpful--forward-stack)))
+
(defun helpful--update-and-switch-buffer (symbol callable-p)
"Update and switch to help buffer for SYMBOL."
(let ((buf (helpful--buffer symbol callable-p)))
+ (helpful--record-history buf)
(with-current-buffer buf
(helpful-update))
(funcall helpful-switch-buffer-function buf)))
@@ -3014,6 +3077,11 @@ See also `helpful-max-buffers'."
(define-key map (kbd "n") #'forward-button)
(define-key map (kbd "p") #'backward-button)
+
+ (define-key map (kbd "l") #'helpful-go-back)
+ (define-key map (kbd "r") #'helpful-go-forward)
+ (define-key map (kbd "C-c C-b") #'helpful-go-back)
+ (define-key map (kbd "C-c C-f") #'helpful-go-forward)
map)
"Keymap for `helpful-mode'.")