From 20381dea16c1ef87fb71e0490e37ed39c79051fe Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 16 Apr 2025 23:40:17 -0400 Subject: [PATCH] feat(emacs-lisp): add back/forward commands for helpful Adapted from Janfel's snippet in Wilfred/helpful#250. And bound to C-{o,i} and {<,>} for evil users, and C-c C-{b,f} and {l,r} for vanilla users (mirroring the back/forward keybinds for help.el). Ref: Wilfred/helpful#250 --- .../{autoload.el => autoload/emacs-lisp.el} | 2 +- modules/lang/emacs-lisp/autoload/helpful.el | 62 +++++++++++++++++++ modules/lang/emacs-lisp/config.el | 13 +++- 3 files changed, 75 insertions(+), 2 deletions(-) rename modules/lang/emacs-lisp/{autoload.el => autoload/emacs-lisp.el} (99%) create mode 100644 modules/lang/emacs-lisp/autoload/helpful.el diff --git a/modules/lang/emacs-lisp/autoload.el b/modules/lang/emacs-lisp/autoload/emacs-lisp.el similarity index 99% rename from modules/lang/emacs-lisp/autoload.el rename to modules/lang/emacs-lisp/autoload/emacs-lisp.el index e40b20ee0..2bf434fa0 100644 --- a/modules/lang/emacs-lisp/autoload.el +++ b/modules/lang/emacs-lisp/autoload/emacs-lisp.el @@ -1,4 +1,4 @@ -;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*- +;;; lang/emacs-lisp/autoload/emacs-lisp.el -*- lexical-binding: t; -*- ;; ;;; Library diff --git a/modules/lang/emacs-lisp/autoload/helpful.el b/modules/lang/emacs-lisp/autoload/helpful.el new file mode 100644 index 000000000..9a1a6d07a --- /dev/null +++ b/modules/lang/emacs-lisp/autoload/helpful.el @@ -0,0 +1,62 @@ +;;; lang/emacs-lisp/autoload/helpful.el -*- lexical-binding: t; -*- + +(defvar +emacs-lisp--helpful-buffer-ring-size 5 + "How many buffers are stored for use with `*helpful-next'.") + +(defvar +emacs-lisp--helpful-buffer-ring (make-ring +emacs-lisp--helpful-buffer-ring-size) + "Ring that stores the current Helpful buffer history.") + +(defun +emacs-lisp--helpful-buffer-index (&optional buffer) + "If BUFFER is a Helpful buffer, return it’s index in the buffer ring." + (let ((buf (or buffer (current-buffer)))) + (and (eq (buffer-local-value 'major-mode buf) 'helpful-mode) + (seq-position (ring-elements +emacs-lisp--helpful-buffer-ring) buf #'eq)))) + +;;;###autoload +(defun +emacs-lisp-record-new-buffers-a (buf) + "Update the buffer ring according to the current buffer and HELP-BUF." + (let ((buf-ring +emacs-lisp--helpful-buffer-ring)) + (let ((newer-buffers (or (+emacs-lisp--helpful-buffer-index) 0))) + (dotimes (_ newer-buffers) (ring-remove buf-ring 0))) + (when (/= (ring-size buf-ring) +emacs-lisp--helpful-buffer-ring-size) + (ring-resize buf-ring +emacs-lisp--helpful-buffer-ring-size)) + (ring-insert buf-ring buf))) + +(defun +emacs-lisp--helpful-next (&optional buffer) + "Return the next live Helpful buffer relative to BUFFER." + (let ((buf-ring +emacs-lisp--helpful-buffer-ring) + (index (or (+emacs-lisp--helpful-buffer-index buffer) -1))) + (cl-block nil + (while (> index 0) + (cl-decf index) + (let ((buf (ring-ref buf-ring index))) + (if (buffer-live-p buf) (cl-return buf))) + (ring-remove buf-ring index))))) + +(defun +emacs-lisp--helpful-previous (&optional buffer) + "Return the previous live Helpful buffer relative to BUFFER." + (let ((buf-ring +emacs-lisp--helpful-buffer-ring) + (index (1+ (or (+emacs-lisp--helpful-buffer-index buffer) -1)))) + (cl-block nil + (while (< index (ring-length buf-ring)) + (let ((buf (ring-ref buf-ring index))) + (if (buffer-live-p buf) (cl-return buf))) + (ring-remove buf-ring index))))) + +;;;###autoload +(defun +emacs-lisp/helpful-next () + "Go to the next Helpful buffer." + (interactive) + (if-let* ((buf (+emacs-lisp--helpful-next))) + (funcall helpful-switch-buffer-function buf) + (user-error "No helpful buffer to switch to"))) + +;;;###autoload +(defun +emacs-lisp/helpful-previous () + "Go to the previous Helpful buffer." + (interactive) + (if-let* ((buf (+emacs-lisp--helpful-previous))) + (funcall helpful-switch-buffer-function buf) + (user-error "No helpful buffer to switch to"))) + +;;; helpful.el ends here diff --git a/modules/lang/emacs-lisp/config.el b/modules/lang/emacs-lisp/config.el index 934e201d6..0f90fc246 100644 --- a/modules/lang/emacs-lisp/config.el +++ b/modules/lang/emacs-lisp/config.el @@ -318,9 +318,20 @@ current buffer." ;; Open help:* links with helpful-* instead of describe-* (advice-add #'org-link--open-help :around #'doom-use-helpful-a) + ;; Keep a record of buffers so our next/previous commands work. + (advice-add #'helpful--buffer :filter-return #'+emacs-lisp-record-new-buffers-a) + (map! :map helpful-mode-map :ng "o" #'link-hint-open-link - :n "gr" #'helpful-update)) + :n "gr" #'helpful-update + :n "C-o" #'+emacs-lisp/helpful-previous + :n [C-i] #'+emacs-lisp/helpful-next + :n "<" #'+emacs-lisp/helpful-previous + :n ">" #'+emacs-lisp/helpful-next + "C-c C-b" #'+emacs-lisp/helpful-previous + "C-c C-f" #'+emacs-lisp/helpful-next + "l" #'+emacs-lisp/helpful-previous + "r" #'+emacs-lisp/helpful-next)) ;;