X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/00d32b3f9876edb92144543928bce6f3ba1d7d00..9c0c2af5a157eca18c86f644121f7eac5488dbda:/lisp/info.el diff --git a/lisp/info.el b/lisp/info.el index 64fe0687f9..47af5bb815 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -149,6 +149,7 @@ that you visit a subnode before getting to the end of the menu. Setting this option to nil results in behavior similar to the stand-alone Info reader program, which visits the first subnode from the menu only when you hit the end of the current node." + :version "21.4" :type 'boolean :group 'info) @@ -1327,7 +1328,7 @@ If FORK is a string, it is the name to use for the new buffer." (when (equal regexp "") (setq regexp (car Info-search-history))) (when regexp - (let ((found ()) + (let (found beg-found give-up (onode Info-current-node) (ofile Info-current-file) (opoint (point)) @@ -1336,53 +1337,70 @@ If FORK is a string, it is the name to use for the new buffer." (save-excursion (save-restriction (widen) + (while (and (not give-up) + (or (null found) + (isearch-range-invisible beg-found found))) + (if (re-search-forward regexp nil t) + (setq found (point) beg-found (match-beginning 0)) + (setq give-up t))))) + ;; If no subfiles, give error now. + (if give-up (if (null Info-current-subfile) - (progn (re-search-forward regexp) (setq found (point))) - (condition-case err - (progn (re-search-forward regexp) (setq found (point))) - (search-failed nil))))) - (if (not found) ;can only happen in subfile case -- else would have erred - (unwind-protect - (let ((list ())) - (save-excursion - (set-buffer (marker-buffer Info-tag-table-marker)) + (re-search-forward regexp) + (setq found nil))) + + (unless found + (unwind-protect + ;; Try other subfiles. + (let ((list ())) + (save-excursion + (set-buffer (marker-buffer Info-tag-table-marker)) + (goto-char (point-min)) + (search-forward "\n\^_\nIndirect:") + (save-restriction + (narrow-to-region (point) + (progn (search-forward "\n\^_") + (1- (point)))) (goto-char (point-min)) - (search-forward "\n\^_\nIndirect:") - (save-restriction - (narrow-to-region (point) - (progn (search-forward "\n\^_") - (1- (point)))) - (goto-char (point-min)) - ;; Find the subfile we just searched. - (search-forward (concat "\n" osubfile ": ")) - ;; Skip that one. - (forward-line 1) - ;; Make a list of all following subfiles. - ;; Each elt has the form (VIRT-POSITION . SUBFILENAME). - (while (not (eobp)) - (re-search-forward "\\(^.*\\): [0-9]+$") - (goto-char (+ (match-end 1) 2)) - (setq list (cons (cons (+ (point-min) - (read (current-buffer))) - (match-string-no-properties 1)) - list)) - (goto-char (1+ (match-end 0)))) - ;; Put in forward order - (setq list (nreverse list)))) - (while list - (message "Searching subfile %s..." (cdr (car list))) - (Info-read-subfile (car (car list))) - (setq list (cdr list)) + ;; Find the subfile we just searched. + (search-forward (concat "\n" osubfile ": ")) + ;; Skip that one. + (forward-line 1) + ;; Make a list of all following subfiles. + ;; Each elt has the form (VIRT-POSITION . SUBFILENAME). + (while (not (eobp)) + (re-search-forward "\\(^.*\\): [0-9]+$") + (goto-char (+ (match-end 1) 2)) + (setq list (cons (cons (+ (point-min) + (read (current-buffer))) + (match-string-no-properties 1)) + list)) + (goto-char (1+ (match-end 0)))) + ;; Put in forward order + (setq list (nreverse list)))) + (while list + (message "Searching subfile %s..." (cdr (car list))) + (Info-read-subfile (car (car list))) + (setq list (cdr list)) + (setq give-up nil found nil) + (while (and (not give-up) + (or (null found) + (isearch-range-invisible beg-found found))) (if (re-search-forward regexp nil t) - (setq found (point) list ()))) + (setq found (point) beg-found (match-beginning 0)) + (setq give-up t))) + (if give-up + (setq found nil)) (if found - (message "") - (signal 'search-failed (list regexp)))) - (if (not found) - (progn (Info-read-subfile osubfile) - (goto-char opoint) - (Info-select-node) - (set-window-start (selected-window) ostart))))) + (setq list nil))) + (if found + (message "") + (signal 'search-failed (list regexp)))) + (if (not found) + (progn (Info-read-subfile osubfile) + (goto-char opoint) + (Info-select-node) + (set-window-start (selected-window) ostart))))) (widen) (goto-char found) (Info-select-node) @@ -1423,6 +1441,11 @@ End of submatch 0, 1, and 3 are the same, so you can safely concat." "[" (or allowedchars "^,\t\n") " ]" ;The last char can't be a space. "\\|\\)\\)")) ;Allow empty node names. +;;; For compatibility; other files have used this name. +(defun Info-following-node-name () + (and (looking-at (Info-following-node-name-re)) + (match-string 1))) + (defun Info-next () "Go to the next node of this node." (interactive) @@ -1540,7 +1563,9 @@ FOOTNOTENAME may be an abbreviation of the reference name." (setq i (+ i 1))) (Info-goto-node target))) -(defconst Info-menu-entry-name-re "\\(?:[^:\n]\\|:[^:,.;() \t\n]\\)*" +(defconst Info-menu-entry-name-re "\\(?:[^:]\\|:[^:,.;() \t\n]\\)*" + ;; We allow newline because this is also used in Info-follow-reference, + ;; where the xref name might be wrapped over two lines. "Regexp that matches a menu entry name upto but not including the colon. Because of ambiguities, this should be concatenated with something like `:' and `Info-following-node-name-re'.") @@ -2092,8 +2117,11 @@ Give a blank topic name to go to the Index node itself." (search-forward (format "`%s'" (substring name 0 (match-beginning 1))) nil t)) - (search-forward name nil t)) - (beginning-of-line) + (search-forward name nil t) + ;; Try again without the " <1>" makeinfo can append + (and (string-match "\\`\\(.*\\) <[0-9]+>\\'" name) + (Info-find-index-name (match-string 1 name)))) + (progn (beginning-of-line) t) ;; non-nil for recursive call (goto-char (point-min))))) (defun Info-undefined () @@ -2236,7 +2264,8 @@ if point is in a menu item description, follow that menu item." (define-key Info-mode-map " " 'Info-scroll-up) (define-key Info-mode-map "\C-m" 'Info-follow-nearest-node) (define-key Info-mode-map "\t" 'Info-next-reference) - (define-key Info-mode-map "\e\t" 'Info-prev-reference) + (define-key Info-mode-map [(shift tab)] 'Info-prev-reference) + (define-key Info-mode-map [backtab] 'Info-prev-reference) (define-key Info-mode-map "1" 'Info-nth-menu-item) (define-key Info-mode-map "2" 'Info-nth-menu-item) (define-key Info-mode-map "3" 'Info-nth-menu-item) @@ -2743,6 +2772,27 @@ the variable `Info-file-list-for-emacs'." "Face for headers in Info menus." :group 'info) +(defun Info-escape-percent (string) + "Double all occurrences of `%' in STRING. + +Return a new string with all `%' characters replaced by `%%'. +Preserve text properties." + (let ((start 0) + (end (length string)) + mb me m matches) + (save-match-data + (while (and (< start end) (string-match "%" string start)) + (setq mb (match-beginning 0) + me (1+ mb) + m (substring string mb me) + matches (cons m + (cons m + (cons (substring string start mb) + matches))) + start me)) + (push (substring string start end) matches) + (apply #'concat (nreverse matches))))) + (defun Info-fontify-menu-headers () "Add the face `info-menu-header' to any header before a menu entry." (save-excursion @@ -2836,7 +2886,7 @@ the variable `Info-file-list-for-emacs'." (setq header (buffer-substring (point) header-end)))) (put-text-property (point-min) (1+ (point-min)) - 'header-line header) + 'header-line (Info-escape-percent header)) ;; Hide the part of the first line ;; that is in the header, if it is just part. (unless (bobp) @@ -3181,4 +3231,5 @@ BUFFER is the buffer speedbar is requesting buttons for." (provide 'info) +;;; arch-tag: f2480fe2-2139-40c1-a49b-6314991164ac ;;; info.el ends here