:group 'info)
(defface info-xref
- '((((class color) (background light)) :foreground "blue")
- (((class color) (background dark)) :foreground "cyan")
+ '((((class color) (background light)) :foreground "blue" :underline t)
+ (((class color) (background dark)) :foreground "cyan" :underline t)
(t :underline t))
"Face for Info cross-references."
:group 'info)
(defface info-xref-visited
- '((t :inherit info-xref)
+ '((default :inherit info-xref)
(((class color) (background light)) :foreground "magenta4")
(((class color) (background dark)) :foreground "magenta3")) ;"violet"?
"Face for visited Info cross-references."
:type 'boolean
:group 'info)
-(defcustom Info-search-whitespace-regexp "\\(?:\\s-+\\)"
+(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.
You might want to use something like \"[ \\t\\r\\n]+\" instead.
;;;###autoload (add-hook 'same-window-regexps "\\*info\\*\\(\\|<[0-9]+>\\)")
+;;;###autoload (put 'info 'info-file "emacs")
;;;###autoload
(defun info (&optional file buffer)
"Enter Info, the documentation browser.
(equal old-nodename Info-current-node))
(progn
;; note goto-line is no good, we want to measure from point-min
- (beginning-of-buffer)
+ (goto-char (point-min))
(forward-line wline)
(set-window-start (selected-window) (point))
- (beginning-of-buffer)
+ (goto-char (point-min))
(forward-line pline)
(move-to-column pcolumn))
;; only add to the history when coming from a different file+node
;; into the menu in the like-named node in the main buffer.
(apply 'insert-buffer-substring (cdr node))))
(Info-dir-remove-duplicates)
- ;; Kill all the buffers we just made.
- (mapc 'kill-buffer buffers)
+ ;; Kill all the buffers we just made, including the special one excised.
+ (mapc 'kill-buffer (cons buffer buffers))
(goto-char (point-min))
(if problems
(message "Composing main Info directory...problems encountered, see `*Messages*'")
(opoint-max (point-max))
(ostart (window-start))
(osubfile Info-current-subfile))
- (when Info-search-whitespace-regexp
- (setq regexp
- (mapconcat 'identity (split-string regexp "[ \t\n]+")
- Info-search-whitespace-regexp)))
(setq Info-search-case-fold case-fold-search)
(save-excursion
(save-restriction
(widen)
+ (when backward
+ ;; Hide Info file header for backward search
+ (narrow-to-region (save-excursion
+ (goto-char (point-min))
+ (search-forward "\n\^_")
+ (1- (point)))
+ (point-max)))
(while (and (not give-up)
- (or (null found)
- (if backward
- (isearch-range-invisible found beg-found)
- (isearch-range-invisible beg-found found))))
- (if (if backward
- (re-search-backward regexp bound t)
- (re-search-forward regexp bound t))
- (setq found (point) beg-found (if backward (match-end 0)
- (match-beginning 0)))
- (setq give-up t)))))
+ (save-match-data
+ (or (null found)
+ (if backward
+ (isearch-range-invisible found beg-found)
+ (isearch-range-invisible beg-found found))
+ ;; Skip node header line
+ (and (save-excursion (forward-line -1)
+ (looking-at "\^_"))
+ (forward-line 1))
+ ;; Skip Tag Table node
+ (save-excursion
+ (and (search-backward "\^_" nil t)
+ (looking-at "\^_\nTag Table"))))))
+ (let ((search-spaces-regexp Info-search-whitespace-regexp))
+ (if (if backward
+ (re-search-backward regexp bound t)
+ (re-search-forward regexp bound t))
+ (setq found (point) beg-found (if backward (match-end 0)
+ (match-beginning 0)))
+ (setq give-up t))))))
;; If no subfiles, give error now.
(if give-up
(if (null Info-current-subfile)
- (if backward
- (re-search-backward regexp)
- (re-search-forward regexp))
+ (let ((search-spaces-regexp Info-search-whitespace-regexp))
+ (if backward
+ (re-search-backward regexp)
+ (re-search-forward regexp)))
(setq found nil)))
(unless (or found bound)
(while list
(message "Searching subfile %s..." (cdr (car list)))
(Info-read-subfile (car (car list)))
- (if backward (goto-char (point-max)))
+ (when backward
+ ;; Hide Info file header for backward search
+ (narrow-to-region (save-excursion
+ (goto-char (point-min))
+ (search-forward "\n\^_")
+ (1- (point)))
+ (point-max))
+ (goto-char (point-max)))
(setq list (cdr list))
(setq give-up nil found nil)
(while (and (not give-up)
- (or (null found)
- (if backward
- (isearch-range-invisible found beg-found)
- (isearch-range-invisible beg-found found))))
- (if (if backward
- (re-search-backward regexp nil t)
- (re-search-forward regexp nil t))
- (setq found (point) beg-found (if backward (match-end 0)
- (match-beginning 0)))
- (setq give-up t)))
+ (save-match-data
+ (or (null found)
+ (if backward
+ (isearch-range-invisible found beg-found)
+ (isearch-range-invisible beg-found found))
+ ;; Skip node header line
+ (and (save-excursion (forward-line -1)
+ (looking-at "\^_"))
+ (forward-line 1))
+ ;; Skip Tag Table node
+ (save-excursion
+ (and (search-backward "\^_" nil t)
+ (looking-at "\^_\nTag Table"))))))
+ (let ((search-spaces-regexp Info-search-whitespace-regexp))
+ (if (if backward
+ (re-search-backward regexp nil t)
+ (re-search-forward regexp nil t))
+ (setq found (point) beg-found (if backward (match-end 0)
+ (match-beginning 0)))
+ (setq give-up t))))
(if give-up
(setq found nil))
(if found
(let ((inhibit-read-only t))
(erase-buffer)
(goto-char (point-min))
- (insert "\n\^_\nFile: history Node: Top, Up: (dir)\n\n")
+ (insert "\n\^_\nFile: history, Node: Top, Up: (dir)\n\n")
(insert "Recently Visited Nodes\n**********************\n\n")
(insert "* Menu:\n\n")
(let ((hl (delete '("history" "Top") Info-history-list)))
"Go to a node with table of contents of the current Info file.
Table of contents is created from the tree structure of menus."
(interactive)
- (let ((curr-file Info-current-file)
- (curr-node Info-current-node)
+ (let ((curr-file (substring-no-properties Info-current-file))
+ (curr-node (substring-no-properties Info-current-node))
p)
(with-current-buffer (get-buffer-create " *info-toc*")
(let ((inhibit-read-only t)
(node-list (Info-build-toc curr-file)))
(erase-buffer)
(goto-char (point-min))
- (insert "\n\^_\nFile: toc Node: Top, Up: (dir)\n\n")
+ (insert "\n\^_\nFile: toc, Node: Top, Up: (dir)\n\n")
(insert "Table of Contents\n*****************\n\n")
- (insert "*Note Top::\n")
+ (insert "*Note Top: (" curr-file ")Top.\n")
(Info-insert-toc
(nth 2 (assoc "Top" node-list)) ; get Top nodes
- node-list 0 (substring-no-properties curr-file)))
+ node-list 0 curr-file))
(if (not (bobp))
(let ((Info-hide-note-references 'hide)
(Info-fontify-visited-nodes nil))
(Info-mode)
(setq Info-current-file "toc" Info-current-node "Top")
- (Info-fontify-node)))
+ (goto-char (point-min))
+ (narrow-to-region (or (re-search-forward "\n[\^_\f]\n" nil t)
+ (point-min))
+ (point-max))
+ (Info-fontify-node)
+ (widen)))
(goto-char (point-min))
(if (setq p (search-forward (concat "*Note " curr-node ":") nil t))
(setq p (- p (length curr-node) 2))))
(defun Info-build-toc (file)
"Build table of contents from menus of Info FILE and its subfiles."
- (if (equal file "dir")
- (error "Table of contents for Info directory is not supported yet"))
(with-temp-buffer
- (let* ((default-directory (or (and (stringp file)
- (file-name-directory
- (setq file (Info-find-file file))))
+ (let* ((file (and (stringp file) (Info-find-file file)))
+ (default-directory (or (and (stringp file)
+ (file-name-directory file))
default-directory))
- (main-file file)
+ (main-file (and (stringp file) file))
(sections '(("Top" "Top")))
nodes subfiles)
(while (or main-file subfiles)
(if (match-beginning 5)
(string-to-number (match-string 5))
(buffer-substring (match-beginning 0) (1- (match-beginning 1)))))
-;;; Comment out the next line to use names of cross-references:
+;;; Uncomment next line to use names of cross-references in non-index nodes:
;;; (setq Info-point-loc
;;; (buffer-substring (match-beginning 0) (1- (match-beginning 1))))
)
"Follow a node reference near point. Return non-nil if successful."
(let (node)
(cond
- ((and (Info-get-token (point) "[hf]t?tp://" "[hf]t?tp://\\([^ \t\n\"`({<>})']+\\)")
- (or (featurep 'browse-url) (require 'browse-url nil t)))
+ ((Info-get-token (point) "[hf]t?tp://" "[hf]t?tp://\\([^ \t\n\"`({<>})']+\\)")
(setq node t)
(browse-url (browse-url-url-at-point)))
((setq node (Info-get-token (point) "\\*note[ \n\t]+"
(message "Tags may have changed. Use Info-tagify if necessary")))
\f
(defvar Info-file-list-for-emacs
- '("ediff" "eudc" "forms" "gnus" "info" ("mh" . "mh-e")
+ '("ediff" "eudc" "forms" "gnus" "info" ("Info" . "info") ("mh" . "mh-e")
"sc" "message" ("dired" . "dired-x") "viper" "vip" "idlwave"
("c" . "ccmode") ("c++" . "ccmode") ("objc" . "ccmode")
("java" . "ccmode") ("idl" . "ccmode") ("pike" . "ccmode")
If COMMAND has no property, the variable `Info-file-list-for-emacs'
defines heuristics for which Info manual to try.
The locations are of the format used in `Info-history', i.e.
-\(FILENAME NODENAME BUFFERPOS\)."
- (let ((where '())
+\(FILENAME NODENAME BUFFERPOS\), where BUFFERPOS is the line number
+in the first element of the returned list (which is treated specially in
+`Info-goto-emacs-command-node'), and 0 for the rest elements of a list."
+ (let ((where '()) line-number
(cmd-desc (concat "^\\* +" (regexp-quote (symbol-name command))
- "\\( <[0-9]+>\\)?:\\s *\\(.*\\)\\.$"))
+ "\\( <[0-9]+>\\)?:\\s *\\(.*\\)\\."
+ "\\(?:[ \t\n]+(line +\\([0-9]+\\))\\)?"))
(info-file "emacs")) ;default
;; Determine which info file this command is documented in.
(if (get command 'info-file)
(car elt)
elt))
(file (if (consp elt) (cdr elt) elt))
+ (case-fold-search nil)
(regexp (concat "\\`" (regexp-quote name)
"\\(\\'\\|-\\)")))
(if (string-match regexp (symbol-name command))
(cons (list Info-current-file
(match-string-no-properties 2)
0)
- where)))
+ where))
+ (setq line-number (and (match-beginning 3)
+ (string-to-number (match-string 3)))))
(and (setq nodes (cdr nodes) node (car nodes))))
(Info-goto-node node)))
- where))
+ (if (and line-number where)
+ (cons (list (nth 0 (car where)) (nth 1 (car where)) line-number)
+ (cdr where))
+ where)))
+;;;###autoload (put 'Info-goto-emacs-command-node 'info-file "emacs")
;;;###autoload
(defun Info-goto-emacs-command-node (command)
"Go to the Info node in the Emacs manual for command COMMAND.
;; Bind Info-history to nil, to prevent the last Index node
;; visited by Info-find-emacs-command-nodes from being
;; pushed onto the history.
- (let ((Info-history nil) (Info-history-list nil))
- (Info-find-node (car (car where))
- (car (cdr (car where)))))
+ (let ((Info-history nil) (Info-history-list nil)
+ (line-number (nth 2 (car where))))
+ (Info-find-node (nth 0 (car where)) (nth 1 (car where)))
+ (if (and (integerp line-number) (> line-number 0))
+ (forward-line (1- line-number))))
(if (> num-matches 1)
(progn
;; (car where) will be pushed onto Info-history
(if (> num-matches 2) "them" "it")))))
(error "Couldn't find documentation for %s" command))))
+;;;###autoload (put 'Info-goto-emacs-key-command-node 'info-file "emacs")
;;;###autoload
(defun Info-goto-emacs-key-command-node (key)
"Go to the node in the Emacs manual which describes the command bound to KEY.
(fontify-visited-p ; visited nodes need to be re-fontified
(and Info-fontify-visited-nodes
;; Don't take time to refontify visited nodes in huge nodes
- (< (- (point-max) (point-min)) Info-fontify-maximum-menu-size))))
+ (< (- (point-max) (point-min)) Info-fontify-maximum-menu-size)))
+ rbeg rend)
;; Fontify header line
(goto-char (point-min))
other-tag)
(when not-fontified-p
(when Info-hide-note-references
- ;; *Note is often used where *note should have been
- (goto-char start)
- (skip-syntax-backward " ")
- (setq other-tag
- (cond ((memq (char-before) '(nil ?\. ?! ??))
- "See ")
- ((memq (char-before) '(?\, ?\; ?\: ?-))
- "see ")
- ((memq (char-before) '(?\( ?\[ ?\{))
- ;; Check whether the paren is preceded by
- ;; an end of sentence
- (skip-syntax-backward " (")
- (if (memq (char-before) '(nil ?\. ?! ??))
- "See "
- "see "))
- ((save-match-data (looking-at "\n\n"))
- "See ")))
+ (when (not (eq Info-hide-note-references 'hide))
+ ;; *Note is often used where *note should have been
+ (goto-char start)
+ (skip-syntax-backward " ")
+ (setq other-tag
+ (cond ((memq (char-before) '(nil ?\. ?! ??))
+ "See ")
+ ((memq (char-before) '(?\, ?\; ?\: ?-))
+ "see ")
+ ((memq (char-before) '(?\( ?\[ ?\{))
+ ;; Check whether the paren is preceded by
+ ;; an end of sentence
+ (skip-syntax-backward " (")
+ (if (memq (char-before) '(nil ?\. ?! ??))
+ "See "
+ "see "))
+ ((save-match-data (looking-at "\n\n"))
+ "See "))))
(goto-char next)
(add-text-properties
(match-beginning 1)
(if (string-match "\n" (match-string 1))
(+ start1 (match-beginning 0)))))
(match-end 1))
- (if (and other-tag (not (eq Info-hide-note-references 'hide)))
+ (if other-tag
`(display ,other-tag front-sticky nil rear-nonsticky t)
'(invisible t front-sticky nil rear-nonsticky t))))
(add-text-properties
"mouse-2: go to this node")
'mouse-face 'highlight)))
(when (or not-fontified-p fontify-visited-p)
- (add-text-properties
- (match-beginning 2) (match-end 2)
- (list
- 'font-lock-face
- ;; Display visited nodes in a different face
- (if (and Info-fontify-visited-nodes
- (save-match-data
- (let* ((node (replace-regexp-in-string
- "^[ \t]+" ""
- (replace-regexp-in-string
- "[ \t\n]+" " "
- (or (match-string 5)
- (and (not (equal (match-string 4) ""))
- (match-string 4))
- (match-string 2)))))
- (file (file-name-nondirectory
- Info-current-file))
- (hl Info-history-list)
- res)
- (if (string-match "(\\([^)]+\\))\\([^)]*\\)" node)
- (setq file (file-name-nondirectory
- (match-string 1 node))
- node (if (equal (match-string 2 node) "")
- "Top"
- (match-string 2 node))))
- (while hl
- (if (and (string-equal node (nth 1 (car hl)))
- (string-equal file
- (file-name-nondirectory
- (nth 0 (car hl)))))
- (setq res (car hl) hl nil)
- (setq hl (cdr hl))))
- res))) 'info-xref-visited 'info-xref))))
+ (setq rbeg (match-beginning 2)
+ rend (match-end 2))
+ (put-text-property
+ rbeg rend
+ 'font-lock-face
+ ;; Display visited nodes in a different face
+ (if (and Info-fontify-visited-nodes
+ (save-match-data
+ (let* ((node (replace-regexp-in-string
+ "^[ \t]+" ""
+ (replace-regexp-in-string
+ "[ \t\n]+" " "
+ (or (match-string 5)
+ (and (not (equal (match-string 4) ""))
+ (match-string 4))
+ (match-string 2)))))
+ (file (file-name-nondirectory
+ Info-current-file))
+ (hl Info-history-list)
+ res)
+ (if (string-match "(\\([^)]+\\))\\([^)]*\\)" node)
+ (setq file (file-name-nondirectory
+ (match-string 1 node))
+ node (if (equal (match-string 2 node) "")
+ "Top"
+ (match-string 2 node))))
+ (while hl
+ (if (and (string-equal node (nth 1 (car hl)))
+ (string-equal file
+ (file-name-nondirectory
+ (nth 0 (car hl)))))
+ (setq res (car hl) hl nil)
+ (setq hl (cdr hl))))
+ res))) 'info-xref-visited 'info-xref))
+ ;; For multiline ref, unfontify newline and surrounding whitespace
+ (save-excursion
+ (goto-char rbeg)
+ (save-match-data
+ (while (re-search-forward "\\s-*\n\\s-*" rend t nil)
+ (remove-text-properties (match-beginning 0)
+ (match-end 0)
+ '(font-lock-face t))))))
(when not-fontified-p
(when (memq Info-hide-note-references '(t hide))
(add-text-properties (match-beginning 3) (match-end 3)