From 69f1bd38f0628503dac935b2b38dca430d80266b Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Tue, 6 Jul 2021 18:56:51 +0200 Subject: [PATCH] Warn when wrapping index matches with `,' after `i' in Info * lisp/info.el (Info--current-index-alternative): New internal variable. (Info-warn-on-index-alternatives-wrap): New user option (bug#24282). (Info-index-next): Use the new user option. --- etc/NEWS | 10 +++++++ lisp/info.el | 83 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b1ab6941d03..7bf8c1d8f56 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1185,6 +1185,16 @@ can provide a better overview in a long list of available bindings. In previous Emacs versions, the "*Help*" buffer was killed instead when clicking the "X" icon in the tool bar. +** Info + +--- +*** New user option 'Info-warn-on-index-alternatives-wrap'. +This option affects what happens when using the ',' command after +looking up an entry with 'i' in info buffers. If non-nil (the +default), the ',' command will now warn you when proceeding beyond the +final entry, and tapping ',' once more will then take you to the +first entry. + +++ ** New command 'lossage-size'. It allows users to set the maximum number of keystrokes and commands diff --git a/lisp/info.el b/lisp/info.el index cdf339ff6fb..b65728ba41b 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -391,6 +391,14 @@ where SUPPORTS-INDEX-COOKIES can be either t or nil.") (defvar-local Info-index-alternatives nil "List of possible matches for last `Info-index' command.") +(defvar-local Info--current-index-alternative 0 + "Current displayed index alternative.") + +(defcustom Info-warn-on-index-alternatives-wrap t + "Warn when wrapping to the beginning/end when displaying index alternatives." + :type 'boolean + :version "28.1") + (defvar Info-point-loc nil "Point location within a selected node. If string, the point is moved to the proper occurrence of the @@ -3375,39 +3383,56 @@ Give an empty topic name to go to the Index node itself." (setq exact (cons found exact) matches (delq found matches))) (setq Info-history-list ohist-list) - (setq Info-index-alternatives (nconc exact (nreverse matches))) + (setq Info-index-alternatives (nconc exact (nreverse matches)) + Info--current-index-alternative 0) (Info-index-next 0))))) (defun Info-index-next (num) - "Go to the next matching index item from the last \\\\[Info-index] command." + "Go to the next matching index item from the last \\\\[Info-index] command. +If given a numeric prefix, skip that many index items forward (or +backward). + +Also see the `Info-warn-on-index-alternatives-wrap' user option." (interactive "p" Info-mode) - (or Info-index-alternatives - (user-error "No previous `i' command")) - (while (< num 0) - (setq num (+ num (length Info-index-alternatives)))) - (while (> num 0) - (setq Info-index-alternatives - (nconc (cdr Info-index-alternatives) - (list (car Info-index-alternatives))) - num (1- num))) - (Info-goto-node (nth 1 (car Info-index-alternatives))) - (if (> (nth 3 (car Info-index-alternatives)) 0) - ;; Forward 2 lines less because `Info-find-node-2' initially - ;; puts point to the 2nd line. - (forward-line (- (nth 3 (car Info-index-alternatives)) 2)) - (forward-line 3) ; don't search in headers - (let ((name (car (car Info-index-alternatives)))) - (Info-find-index-name name))) - (message "Found `%s' in %s. %s" - (car (car Info-index-alternatives)) - (nth 2 (car Info-index-alternatives)) - (if (cdr Info-index-alternatives) - (format-message - "(%s total; use `%s' for next)" - (length Info-index-alternatives) - (key-description (where-is-internal - 'Info-index-next overriding-local-map t))) - "(Only match)"))) + (unless Info-index-alternatives + (user-error "No previous `i' command")) + (let ((index (+ Info--current-index-alternative num)) + (total (length Info-index-alternatives)) + (next-key (key-description (where-is-internal + 'Info-index-next overriding-local-map t)))) + (if (and Info-warn-on-index-alternatives-wrap + (> total 1) + (cond + ((< index 0) + (setq Info--current-index-alternative (- total 2)) + (message + "No previous matches, use `%s' to continue from end of list" + next-key) + t) + ((>= index total) + (setq Info--current-index-alternative -1) + (message + "No previous matches, use `%s' to continue from start of list" + next-key) + t))) + () ; Do nothing + (setq index (mod index total) + Info--current-index-alternative index) + (let ((entry (nth index Info-index-alternatives))) + (Info-goto-node (nth 1 entry)) + (if (> (nth 3 entry) 0) + ;; Forward 2 lines less because `Info-find-node-2' initially + ;; puts point to the 2nd line. + (forward-line (- (nth 3 entry) 2)) + (forward-line 3) ; don't search in headers + (Info-find-index-name (car entry))) + (message "Found `%s' in %s. %s" + (car entry) + (nth 2 entry) + (if (> total 1) + (format-message + "(%s total; use `%s' for next)" total next-key) + "(Only match)")))))) (defun Info-find-index-name (name) "Move point to the place within the current node where NAME is defined." -- 2.39.2