X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/fdeb777a1d88efa9112d2b75aa4415c7659ba522..cb83c00bd13b63c0d0752698e4ad441968bc04ac:/lisp/info.el diff --git a/lisp/info.el b/lisp/info.el index ae62e9dd3f..78e3f2ef70 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -34,7 +34,7 @@ ;;; Code: -(eval-when-compile (require 'jka-compr)) +(eval-when-compile (require 'jka-compr) (require 'cl)) (defgroup info nil "Info subsystem." @@ -221,7 +221,8 @@ when you hit the end of the current node." "*If non-nil, hide the tag and section reference in *note and * menu items. If value is non-nil but not `hide', also replaces the \"*note\" with \"see\". If value is non-nil but not t or `hide', the reference section is still shown. -`nil' completely disables this feature." +`nil' completely disables this feature. If this is non-nil, you might +want to set `Info-refill-paragraphs'." :version "22.1" :type '(choice (const :tag "No hiding" nil) (const :tag "Replace tag and hide reference" t) @@ -232,11 +233,17 @@ If value is non-nil but not t or `hide', the reference section is still shown. (defcustom Info-refill-paragraphs nil "*If non-nil, attempt to refill paragraphs with hidden references. This refilling may accidentally remove explicit line breaks in the Info -file, so be prepared for a few surprises if you enable this feature." +file, so be prepared for a few surprises if you enable this feature. +This only has an effect if `Info-hide-note-references' is non-nil." :version "22.1" :type 'boolean :group 'info) +(defcustom Info-breadcrumbs-depth 4 + "Depth of breadcrumbs to display. +0 means do not display breadcrumbs." + :type 'integer) + (defcustom Info-search-whitespace-regexp "\\s-+" "*If non-nil, regular expression to match a sequence of whitespace chars. This applies to Info search for regular expressions. @@ -305,6 +312,11 @@ Marker points nowhere if file has no tag table.") (defvar Info-file-supports-index-cookies nil "Non-nil if current Info file supports index cookies.") +(defvar Info-file-supports-index-cookies-list nil + "List of Info files with information about index cookies support. +Each element of the list is a list (FILENAME SUPPORTS-INDEX-COOKIES) +where SUPPORTS-INDEX-COOKIES can be either t or nil.") + (defvar Info-index-alternatives nil "List of possible matches for last `Info-index' command.") @@ -456,6 +468,34 @@ Do the right thing if the file has been compressed or zipped." (apply 'call-process-region (point-min) (point-max) (car decoder) t t nil (cdr decoder)))) (insert-file-contents fullname visit)))) + +(defun Info-file-supports-index-cookies (&optional file) + "Return non-nil value if FILE supports Info index cookies. +Info index cookies were first introduced in 4.7, and all later +makeinfo versions output them in index nodes, so we can rely +solely on the makeinfo version. This function caches the information +in `Info-file-supports-index-cookies-list'." + (or file (setq file Info-current-file)) + (or (assoc file Info-file-supports-index-cookies-list) + ;; Skip virtual Info files + (and (or (not (stringp file)) + (member file '("dir" apropos history toc))) + (setq Info-file-supports-index-cookies-list + (cons (cons file nil) Info-file-supports-index-cookies-list))) + (save-excursion + (let ((found nil)) + (goto-char (point-min)) + (condition-case () + (if (and (re-search-forward + "makeinfo[ \n]version[ \n]\\([0-9]+.[0-9]+\\)" + (line-beginning-position 3) t) + (not (version< (match-string 1) "4.7"))) + (setq found t)) + (error nil)) + (setq Info-file-supports-index-cookies-list + (cons (cons file found) Info-file-supports-index-cookies-list))))) + (cdr (assoc file Info-file-supports-index-cookies-list))) + (defun Info-default-dirs () (let ((source (expand-file-name "info/" source-directory)) @@ -543,7 +583,9 @@ appended to the Info buffer name. The search path for Info files is in the variable `Info-directory-list'. The top-level Info directory is made by combining all the files named `dir' -in all the directories in that path." +in all the directories in that path. + +See a list of available Info commands in `Info-mode'." (interactive (list (if (and current-prefix-arg (not (numberp current-prefix-arg))) (read-file-name "Info file name: " nil nil t)) @@ -681,9 +723,8 @@ it says do not attempt further (recursive) error recovery." ;; Record the node we are leaving, if we were in one. (and (not no-going-back) Info-current-file - (setq Info-history - (cons (list Info-current-file Info-current-node (point)) - Info-history))) + (push (list Info-current-file Info-current-node (point)) + Info-history)) (Info-find-node-2 filename nodename no-going-back)) ;;;###autoload @@ -842,18 +883,8 @@ a case-insensitive match is tried." (info-insert-file-contents filename nil) (setq default-directory (file-name-directory filename)))) (set-buffer-modified-p nil) - - ;; Check makeinfo version for index cookie support - (let ((found nil)) - (goto-char (point-min)) - (condition-case () - (if (and (re-search-forward - "makeinfo[ \n]version[ \n]\\([0-9]+.[0-9]+\\)" - (line-beginning-position 3) t) - (not (version< (match-string 1) "4.7"))) - (setq found t)) - (error nil)) - (set (make-local-variable 'Info-file-supports-index-cookies) found)) + (set (make-local-variable 'Info-file-supports-index-cookies) + (Info-file-supports-index-cookies filename)) ;; See whether file has a tag table. Record the location if yes. (goto-char (point-max)) @@ -963,6 +994,10 @@ a case-insensitive match is tried." (Info-select-node) (goto-char (point-min)) + (forward-line 1) ; skip header line + (when (> Info-breadcrumbs-depth 0) ; skip breadcrumbs line + (forward-line 1)) + (cond (anchorpos (let ((new-history (list Info-current-file (substring-no-properties nodename)))) @@ -1210,19 +1245,20 @@ a case-insensitive match is tried." (delete-region (1- (point)) (point)))) ;; Now remove duplicate entries under the same heading. - (let ((seen nil) - (limit (point-marker))) - (goto-char start) - (while (and (> limit (point)) - (re-search-forward "^* \\([^:\n]+:\\(:\\|[^.\n]+\\).\\)" - limit 'move)) - ;; Fold case straight away; `member-ignore-case' here wasteful. - (let ((x (downcase (match-string 1)))) - (if (member x seen) - (delete-region (match-beginning 0) - (progn (re-search-forward "^[^ \t]" nil t) - (match-beginning 0))) - (push x seen)))))))))) + (let (seen) + (save-restriction + (narrow-to-region start (point)) + (goto-char (point-min)) + (while (re-search-forward "^* \\([^:\n]+:\\(:\\|[^.\n]+\\).\\)" nil 'move) + ;; Fold case straight away; `member-ignore-case' here wasteful. + (let ((x (downcase (match-string 1)))) + (if (member x seen) + (delete-region + (match-beginning 0) + (if (re-search-forward "^[^ \t]" nil 'move) + (goto-char (match-beginning 0)) + (point-max))) + (push x seen))))))))))) ;; Note that on entry to this function the current-buffer must be the ;; *info* buffer; not the info tags buffer. @@ -1992,14 +2028,14 @@ Table of contents is created from the tree structure of menus." p) (with-current-buffer (get-buffer-create " *info-toc*") (let ((inhibit-read-only t) - (node-list (Info-build-toc curr-file))) + (node-list (Info-toc-nodes curr-file))) (erase-buffer) (goto-char (point-min)) (insert "\n\^_\nFile: toc, Node: Top, Up: (dir)\n\n") (insert "Table of Contents\n*****************\n\n") (insert "*Note Top: (" curr-file ")Top.\n") (Info-insert-toc - (nth 2 (assoc "Top" node-list)) ; get Top nodes + (nth 3 (assoc "Top" node-list)) ; get Top nodes node-list 0 curr-file)) (if (not (bobp)) (let ((Info-hide-note-references 'hide) @@ -2023,11 +2059,11 @@ Table of contents is created from the tree structure of menus." (let ((section "Top")) (while nodes (let ((node (assoc (car nodes) node-list))) - (unless (member (nth 1 node) (list nil section)) - (insert (setq section (nth 1 node)) "\n")) + (unless (member (nth 2 node) (list nil section)) + (insert (setq section (nth 2 node)) "\n")) (insert (make-string level ?\t)) (insert "*Note " (car nodes) ": (" curr-file ")" (car nodes) ".\n") - (Info-insert-toc (nth 2 node) node-list (1+ level) curr-file) + (Info-insert-toc (nth 3 node) node-list (1+ level) curr-file) (setq nodes (cdr nodes)))))) (defun Info-build-toc (file) @@ -2041,17 +2077,22 @@ Table of contents is created from the tree structure of menus." (sections '(("Top" "Top"))) nodes subfiles) (while (or main-file subfiles) - (or main-file (message "Searching subfile %s..." (car subfiles))) + ;; (or main-file (message "Searching subfile %s..." (car subfiles))) (erase-buffer) (info-insert-file-contents (or main-file (car subfiles))) (goto-char (point-min)) (while (and (search-forward "\n\^_\nFile:" nil 'move) (search-forward "Node: " nil 'move)) - (let ((nodename (substring-no-properties (Info-following-node-name))) - (bound (- (or (save-excursion (search-forward "\n\^_" nil t)) - (point-max)) 2)) - (section "Top") - menu-items) + (let* ((nodename (substring-no-properties (Info-following-node-name))) + (bound (- (or (save-excursion (search-forward "\n\^_" nil t)) + (point-max)) 2)) + (upnode (and (re-search-forward + (concat "Up:" (Info-following-node-name-re)) + bound t) + (match-string-no-properties 1))) + (section "Top") + menu-items) + (when (string-match "(" upnode) (setq upnode nil)) (when (and (not (Info-index-node nodename file)) (re-search-forward "^\\* Menu:" bound t)) (forward-line 1) @@ -2079,7 +2120,7 @@ Table of contents is created from the tree structure of menus." (setq section (match-string-no-properties 1)))) (forward-line 1) (beginning-of-line))) - (setq nodes (cons (list nodename + (setq nodes (cons (list nodename upnode (cadr (assoc nodename sections)) (nreverse menu-items)) nodes)) @@ -2097,6 +2138,32 @@ Table of contents is created from the tree structure of menus." (setq subfiles (cdr subfiles)))) (message "") (nreverse nodes)))) + +(defvar Info-toc-nodes nil + "Alist of cached parent-children node information in visited Info files. +Each element is (FILE (NODE-NAME PARENT SECTION CHILDREN) ...) +where PARENT is the parent node extracted from the Up pointer, +SECTION is the section name in the Top node where this node is placed, +CHILDREN is a list of child nodes extracted from the node menu.") + +(defun Info-toc-nodes (file) + "Return a node list of Info FILE with parent-children information. +This information is cached in the variable `Info-toc-nodes' with the help +of the function `Info-build-toc'." + (or file (setq file Info-current-file)) + (or (assoc file Info-toc-nodes) + ;; Skip virtual Info files + (and (or (not (stringp file)) + (member file '("dir" apropos history toc))) + (push (cons file nil) Info-toc-nodes)) + ;; Scan the entire manual and cache the result in Info-toc-nodes + (let ((nodes (Info-build-toc file))) + (push (cons file nodes) Info-toc-nodes) + nodes) + ;; If there is an error, still add nil to the cache + (push (cons file nil) Info-toc-nodes)) + (cdr (assoc file Info-toc-nodes))) + (defun Info-follow-reference (footnotename &optional fork) "Follow cross reference named FOOTNOTENAME to the node it refers to. @@ -2377,17 +2444,21 @@ new buffer." (Info-extract-menu-node-name nil (Info-index-node)))))) ;; If COUNT is nil, use the last item in the menu. -(defun Info-extract-menu-counting (count) +(defun Info-extract-menu-counting (count &optional no-detail) (let ((case-fold-search t)) (save-excursion - (let ((case-fold-search t)) + (let ((case-fold-search t) + (bound (when (and no-detail + (re-search-forward + "^[ \t-]*The Detailed Node Listing" nil t)) + (match-beginning 0)))) (goto-char (point-min)) - (or (search-forward "\n* menu:" nil t) + (or (search-forward "\n* menu:" bound t) (error "No menu in this node")) (if count - (or (search-forward "\n* " nil t count) + (or (search-forward "\n* " bound t count) (error "Too few items in menu")) - (while (search-forward "\n* " nil t) + (while (search-forward "\n* " bound t) nil)) (Info-extract-menu-node-name nil (Info-index-node)))))) @@ -2410,17 +2481,19 @@ N is the digit argument used to invoke this command." (Info-goto-node "Top") (let ((Info-history nil) (case-fold-search t)) - ;; Go to the last node in the menu of Top. - (Info-goto-node (Info-extract-menu-counting nil)) + ;; Go to the last node in the menu of Top. But don't delve into + ;; detailed node listings. + (Info-goto-node (Info-extract-menu-counting nil t)) ;; If the last node in the menu is not last in pointer structure, - ;; move forward until we can't go any farther. - (while (Info-forward-node t t) nil) + ;; move forward (but not down- or upward - see bug#1116) until we + ;; can't go any farther. + (while (Info-forward-node t t t) nil) ;; Then keep moving down to last subnode, unless we reach an index. (while (and (not (Info-index-node)) (save-excursion (search-forward "\n* Menu:" nil t))) (Info-goto-node (Info-extract-menu-counting nil))))) -(defun Info-forward-node (&optional not-down no-error) +(defun Info-forward-node (&optional not-down not-up no-error) "Go forward one node, considering all nodes as forming one sequence." (interactive) (goto-char (point-min)) @@ -2438,7 +2511,8 @@ N is the digit argument used to invoke this command." ((save-excursion (search-backward "next:" nil t)) (Info-next) t) - ((and (save-excursion (search-backward "up:" nil t)) + ((and (not not-up) + (save-excursion (search-backward "up:" nil t)) ;; Use string-equal, not equal, to ignore text props. (not (string-equal (downcase (Info-extract-pointer "up")) "top"))) @@ -2446,7 +2520,7 @@ N is the digit argument used to invoke this command." (Info-up) (let (Info-history success) (unwind-protect - (setq success (Info-forward-node t no-error)) + (setq success (Info-forward-node t nil no-error)) (or success (Info-goto-node old-node)))))) (no-error nil) (t (error "No pointer forward from this node"))))) @@ -2701,10 +2775,10 @@ following nodes whose names also contain the word \"Index\"." (or file (setq file Info-current-file)) (or (assoc file Info-index-nodes) ;; Skip virtual Info files - (and (member file '("dir" apropos history toc)) + (and (or (not (stringp file)) + (member file '("dir" apropos history toc))) (setq Info-index-nodes (cons (cons file nil) Info-index-nodes))) - (not (stringp file)) - (if Info-file-supports-index-cookies + (if (Info-file-supports-index-cookies file) ;; Find nodes with index cookie (let* ((default-directory (or (and (stringp file) (file-name-directory @@ -2741,7 +2815,7 @@ following nodes whose names also contain the word \"Index\"." nodes) ;; Else find nodes with the word "Index" in the node name (let ((case-fold-search t) - Info-history Info-history-list Info-fontify-maximum-menu-size + Info-history Info-history-list Info-fontify-maximum-menu-size Info-point-loc nodes node) (condition-case nil (with-temp-buffer @@ -2769,12 +2843,13 @@ following nodes whose names also contain the word \"Index\"." "Return non-nil value if NODE is an index node. If NODE is nil, check the current Info node. If FILE is nil, check the current Info file." + (or file (setq file Info-current-file)) (if (or (and node (not (equal node Info-current-node))) - (assoc (or file Info-current-file) Info-index-nodes)) + (assoc file Info-index-nodes)) (member (or node Info-current-node) (Info-index-nodes file)) ;; Don't search all index nodes if request is only for the current node ;; and file is not in the cache of index nodes - (if Info-file-supports-index-cookies + (if (Info-file-supports-index-cookies file) (save-excursion (goto-char (+ (or (save-excursion (search-backward "\n\^_" nil t)) @@ -3064,7 +3139,7 @@ Like \\[Info-menu], \\[Info-follow-reference], \\[Info-next], \\[Info-prev] or \ At end of the node's text, moves to the next node, or up if none." (interactive "e") (mouse-set-point click) - (and (not (Info-try-follow-nearest-node)) + (and (not (Info-follow-nearest-node)) (save-excursion (forward-line 1) (eobp)) (Info-next-preorder))) @@ -3088,12 +3163,16 @@ If FORK is a string, it is the name to use for the new buffer." (Info-goto-node (Info-extract-menu-item (match-string-no-properties 1)) fork) t))) + (and (eq this-command 'Info-mouse-follow-nearest-node) + ;; Don't raise an error when mouse-1 is bound to this - it's + ;; often used to simply select the window or frame. + (eq 'mouse-1 (event-basic-type last-input-event))) (error "Point neither on reference nor in menu item description"))) ;; Common subroutine. (defun Info-try-follow-nearest-node (&optional fork) "Follow a node reference near point. Return non-nil if successful. -If FORK is non-nil, it i spassed to `Info-goto-node'." +If FORK is non-nil, it is passed to `Info-goto-node'." (let (node) (cond ((Info-get-token (point) "[hf]t?tps?://" "[hf]t?tps?://\\([^ \t\n\"`({<>})']+\\)") @@ -3238,23 +3317,22 @@ If FORK is non-nil, it i spassed to `Info-goto-node'." (defvar info-tool-bar-map - (if (display-graphic-p) - (let ((map (make-sparse-keymap))) - (tool-bar-local-item-from-menu 'Info-history-back "left-arrow" map Info-mode-map - :rtl "right-arrow") - (tool-bar-local-item-from-menu 'Info-history-forward "right-arrow" map Info-mode-map - :rtl "left-arrow") - (tool-bar-local-item-from-menu 'Info-prev "prev-node" map Info-mode-map - :rtl "next-node") - (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map - :rtl "prev-node") - (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map) - (tool-bar-local-item-from-menu 'Info-exit "exit" map Info-mode-map) - map))) + (let ((map (make-sparse-keymap))) + (tool-bar-local-item-from-menu 'Info-history-back "left-arrow" map Info-mode-map + :rtl "right-arrow") + (tool-bar-local-item-from-menu 'Info-history-forward "right-arrow" map Info-mode-map + :rtl "left-arrow") + (tool-bar-local-item-from-menu 'Info-prev "prev-node" map Info-mode-map + :rtl "next-node") + (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map + :rtl "prev-node") + (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map) + (tool-bar-local-item-from-menu 'Info-exit "exit" map Info-mode-map) + map)) (defvar Info-menu-last-node nil) ;; Last node the menu was created for. @@ -3402,6 +3480,7 @@ Advanced commands: \\[Info-search-case-sensitively] Search through this Info file for specified regexp case-sensitively. \\[Info-search-next] Search for another occurrence of regexp from a previous \\\\[Info-search] command. +\\[isearch-forward], \\[isearch-forward-regexp] Use Isearch to search through multiple Info nodes. \\[Info-index] Search for a topic in this manual's Index and go to index entry. \\[Info-index-next] (comma) Move to the next match from a previous \\\\[Info-index] command. \\[info-apropos] Look for a string in the indices of all manuals. @@ -3433,10 +3512,9 @@ Advanced commands: (make-local-variable 'Info-history) (make-local-variable 'Info-history-forward) (make-local-variable 'Info-index-alternatives) - (setq header-line-format - (if Info-use-header-line - '(:eval (get-text-property (point-min) 'header-line)) - nil)) ; so the header line isn't displayed + (if Info-use-header-line ; do not override global header lines + (setq header-line-format + '(:eval (get-text-property (point-min) 'header-line)))) (set (make-local-variable 'tool-bar-map) info-tool-bar-map) ;; This is for the sake of the invisible text we use handling titles. (make-local-variable 'line-move-ignore-invisible) @@ -3711,48 +3789,46 @@ the variable `Info-file-list-for-emacs'." keymap) "Keymap to put on the Up link in the text or the header line.") -(defcustom Info-breadcrumbs-depth 3 - "Depth of breadcrumbs to display. -0 means do not display breadcrumbs." - :type 'integer) - (defun Info-insert-breadcrumbs () - (let ((onode Info-current-node) + (let ((nodes (Info-toc-nodes Info-current-file)) + (node Info-current-node) (crumbs ()) - (depth Info-breadcrumbs-depth) - (Info-fontify-maximum-menu-size nil)) ; Prevent infinite recursion. - (unwind-protect - (while (and (not (equal "Top" Info-current-node)) (> depth 0)) - (let ((up (Info-extract-pointer "up"))) - (push up crumbs) - (setq depth (1- depth)) - (Info-goto-node up))) - (Info-goto-node onode) - ;; Add bottom node. - (when Info-use-header-line - ;; Let it disappear if crumbs is nil. - (nconc crumbs (list Info-current-node))) - (when (or Info-use-header-line crumbs) - ;; Add top node (and continuation if needed). - (setq crumbs - (cons "Top" (if (member (pop crumbs) '(nil "Top")) - crumbs (cons nil crumbs)))) - ;; Eliminate duplicate. - (forward-line 1) - (dolist (node crumbs) - (let ((text - (if (not (equal node "Top")) node - (format "(%s)Top" - (file-name-nondirectory Info-current-file))))) - (insert (if (bolp) "> " " > ") - (cond - ((null node) "...") - ((equal node Info-current-node) - ;; No point linking to ourselves. - (propertize text 'font-lock-face 'info-header-node)) - (t - (concat "*Note " text "::")))))) - (insert "\n"))))) + (depth Info-breadcrumbs-depth)) + + ;; Get ancestors from the cached parent-children node info + (while (and (not (equal "Top" node)) (> depth 0)) + (setq node (nth 1 (assoc node nodes))) + (if node (push node crumbs)) + (setq depth (1- depth))) + + ;; Add bottom node. + (when Info-use-header-line + ;; Let it disappear if crumbs is nil. + (nconc crumbs (list Info-current-node))) + (when (or Info-use-header-line crumbs) + ;; Add top node (and continuation if needed). + (setq crumbs + (cons "Top" (if (member (pop crumbs) '(nil "Top")) + crumbs (cons nil crumbs)))) + ;; Eliminate duplicate. + (forward-line 1) + (dolist (node crumbs) + (let ((text + (if (not (equal node "Top")) node + (format "(%s)Top" + (if (stringp Info-current-file) + (file-name-nondirectory Info-current-file) + ;; Can be `toc', `apropos', or even `history'. + Info-current-file))))) + (insert (if (bolp) "" " > ") + (cond + ((null node) "...") + ((equal node Info-current-node) + ;; No point linking to ourselves. + (propertize text 'font-lock-face 'info-header-node)) + (t + (concat "*Note " text "::")))))) + (insert "\n")))) (defun Info-fontify-node () "Fontify the node." @@ -3798,10 +3874,10 @@ the variable `Info-file-list-for-emacs'." ((string-equal (downcase tag) "prev") Info-prev-link-keymap) ((string-equal (downcase tag) "next") Info-next-link-keymap) ((string-equal (downcase tag) "up" ) Info-up-link-keymap)))))) - + (when (> Info-breadcrumbs-depth 0) (Info-insert-breadcrumbs)) - + ;; Treat header line. (when Info-use-header-line (goto-char (point-min)) @@ -3860,7 +3936,7 @@ the variable `Info-file-list-for-emacs'." ;; This is a serious problem for trying to handle multiple ;; frame types at once. We want this text to be invisible ;; on frames that can display the font above. - (when (memq (framep (selected-frame)) '(x pc w32 mac)) + (when (memq (framep (selected-frame)) '(x pc w32 ns)) (add-text-properties (1- (match-beginning 2)) (match-end 2) '(invisible t front-sticky nil rear-nonsticky t))))) @@ -4346,62 +4422,30 @@ BUFFER is the buffer speedbar is requesting buttons for." '(Info-mode . Info-restore-desktop-buffer)) ;;;; Bookmark support - -(defvar bookmark-search-size) - -;; This is only called from bookmark.el. -(declare-function bookmark-buffer-file-name "bookmark" ()) +(declare-function bookmark-make-record-default "bookmark" (&optional pos-only)) +(declare-function bookmark-prop-get "bookmark" (bookmark prop)) +(declare-function bookmark-default-handler "bookmark" (bmk)) +(declare-function bookmark-get-bookmark-record "bookmark" (bmk)) (defun Info-bookmark-make-record () `(,Info-current-node - (filename . ,(bookmark-buffer-file-name)) - (front-context-string - . ,(if (>= (- (point-max) (point)) bookmark-search-size) - (buffer-substring-no-properties - (point) - (+ (point) bookmark-search-size)) - nil)) - (rear-context-string - . ,(if (>= (- (point) (point-min)) bookmark-search-size) - (buffer-substring-no-properties - (point) - (- (point) bookmark-search-size)) - nil)) + ,@(bookmark-make-record-default 'point-only) + (filename . ,Info-current-file) (info-node . ,Info-current-node) (handler . Info-bookmark-jump))) - -(defvar bookmark-current-bookmark) -(declare-function bookmark-prop-get "bookmark" (bookmark prop)) -(declare-function bookmark-file-or-variation-thereof "bookmark" (file)) -(declare-function bookmark-jump-noselect "bookmark" (str)) -(declare-function bookmark-get-bookmark-record "bookmark" (bookmark)) - ;;;###autoload (defun Info-bookmark-jump (bmk) ;; This implements the `handler' function interface for record type returned ;; by `Info-bookmark-make-record', which see. - (let* ((file (expand-file-name (bookmark-prop-get bmk 'filename))) - (forward-str (bookmark-prop-get bmk 'front-context-string)) - (behind-str (bookmark-prop-get bmk 'rear-context-string)) - (info-node (bookmark-prop-get bmk 'info-node))) - (if (setq file (bookmark-file-or-variation-thereof file)) - (save-excursion - (save-window-excursion - (with-no-warnings - (Info-find-node file info-node)) - ;; Go searching forward first. Then, if forward-str exists and was - ;; found in the file, we can search backward for behind-str. - ;; Rationale is that if text was inserted between the two in the - ;; file, it's better to be put before it so you can read it, rather - ;; than after and remain perhaps unaware of the changes. - (if forward-str - (if (search-forward forward-str (point-max) t) - (goto-char (match-beginning 0)))) - (if behind-str - (if (search-backward behind-str (point-min) t) - (goto-char (match-end 0)))) - `((buffer ,(current-buffer)) (position ,(point)))))))) + (let* ((file (bookmark-prop-get bmk 'filename)) + (info-node (bookmark-prop-get bmk 'info-node)) + (buf (save-window-excursion ;FIXME: doesn't work with frames! + (Info-find-node file info-node) (current-buffer)))) + ;; Use bookmark-default-handler to move to the appropriate location + ;; within the node. + (bookmark-default-handler + (list* "" `(buffer . ,buf) (bookmark-get-bookmark-record bmk))))) (provide 'info)