:group 'info)
(defface info-node
- '((((class color)) (:foreground "brown" :bold t :italic t))
+ '((((class color) (background light)) (:foreground "brown" :bold t :italic t))
+ (((class color) (background dark)) (:foreground "white" :bold t :italic t))
(t (:bold t :italic t)))
"Face for Info node names."
:group 'info)
(defface info-menu-5
'((((class color)) (:foreground "red1"))
(t (:underline t)))
- "Face for the fifth and tenth `*' in an Info menu."
+ "Face for the fifth and nineth `*' in an Info menu."
:group 'info)
(defface info-xref
- '((((class color)) (:foreground "magenta4" :bold t))
+ '((((class color) (background light)) (:foreground "magenta4" :bold t))
+ (((class color) (background dark)) (:foreground "cyan" :bold t))
(t (:bold t)))
"Face for Info cross-references."
:group 'info)
:type 'integer
:group 'info)
+(defcustom Info-use-header-line t
+ "*Non-nil means to put the beginning-of-node links in an emacs header-line.
+A header-line does not scroll with the rest of the buffer."
+ :type 'boolean
+ :group 'info)
+
+(defface info-header-xref
+ '((t (:inherit info-xref)))
+ "Face for Info cross-references in a node header."
+ :group 'info)
+
+(defface info-header-node
+ '((t (:inherit info-node)))
+ "Face for Info nodes in a node header."
+ :group 'info)
+
(defvar Info-directory-list nil
"List of directories to search for Info documentation files.
nil means not yet initialized. In this case, Info uses the environment
variable INFOPATH to initialize it, or `Info-default-directory-list'
if there is no INFOPATH variable in the environment.
-The last element of `Info-default-directory-list' is the directory
-where Emacs installs the Info files that come with it.
+
+When `Info-directory-list' is initialized from the value of
+`Info-default-directory-list', and Emacs is installed in one of the
+standard directories, the directory of Info files that come with Emacs
+is put last (so that local Info files override standard ones).
+
+When `Info-directory-list' is initialized from the value of
+`Info-default-directory-list', and Emacs is not installed in one
+of the standard directories, the first element of the resulting
+list is the directory where Emacs installs the Info files that
+come with it. This is so that Emacs's own manual, which suits the
+version of Emacs you are using, will always be found first. This
+is useful when you install an experimental version of Emacs without
+removing the standard installation.
+
+If you want to override the order of directories in
+`Info-default-directory-list', set INFOPATH in the environment.
If you run the Emacs executable from the `src' directory in the Emacs
-source tree, the `info' directory in the source tree is used as the last
-element, in place of the installation Info directory. This is useful
-when you run a version of Emacs without installing it.")
+source tree, and INFOPATH is not defined, the `info' directory in the
+source tree is used as the first element of `Info-directory-list', in
+place of the installation Info directory. This is useful when you run
+a version of Emacs without installing it.")
(defcustom Info-additional-directory-list nil
"List of additional directories to search for Info documentation files.
:type '(repeat directory)
:group 'info)
+(defcustom Info-scroll-prefer-subnodes t
+ "*If non-nil, \\<Info-mode-map>\\[Info-scroll-up] in a menu visits subnodes.
+If this is non-nil, and you scroll far enough in a node that its menu
+appears on the screen, the next \\<Info-mode-map>\\[Info-scroll-up]
+moves to a subnode indicated by the following menu item. This means
+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."
+ :type 'boolean
+ :group 'info)
+
(defvar Info-current-file nil
"Info file that Info is now looking at, or nil.
This is the name that was specified in Info, not the actual file name.
(if (eq system-type 'ms-dos)
'( (".gz" . "gunzip")
(".z" . "gunzip")
- (".bz2" . "bzip2 -dc")
+ (".bz2" . ("bzip2" "-dc"))
(".inz" . "gunzip")
(".igz" . "gunzip")
(".info.Z" . "gunzip")
(".info.Y". "unyabba")
(".info.gz". "gunzip")
(".info.z". "gunzip")
- (".info.bz2" . "bzip2 -dc")
+ (".info.bz2" . ("bzip2" "-dc"))
(".info". nil)
("-info.Z". "uncompress")
("-info.Y". "unyabba")
("-info.gz". "gunzip")
- ("-info.bz2" . "bzip2 -dc")
+ ("-info.bz2" . ("bzip2" "-dc"))
("-info.z". "gunzip")
("-info". nil)
("/index.Z". "uncompress")
("/index.Y". "unyabba")
("/index.gz". "gunzip")
("/index.z". "gunzip")
- ("/index.bz2". "bzip2 -dc")
+ ("/index.bz2". ("bzip2" "-dc"))
("/index". nil)
(".Z". "uncompress")
(".Y". "unyabba")
(".gz". "gunzip")
(".z". "gunzip")
- (".bz2" . "bzip2 -dc")
+ (".bz2" . ("bzip2" "-dc"))
("". nil)))
"List of file name suffixes and associated decoding commands.
Each entry should be (SUFFIX . STRING); the file is given to
-the command as standard input. If STRING is nil, no decoding is done.
+the command as standard input.
+
+STRING may be a list of strings. In that case, the first element is
+the command name, and the rest are arguments to that command.
+
+If STRING is nil, no decoding is done.
Because the SUFFIXes are tried in order, the empty string should
be last in the list.")
(coding-system-for-write 'no-conversion)
(default-directory (or (file-name-directory fullname)
default-directory)))
- (call-process-region (point-min) (point-max) decoder t t)))
+ (or (consp decoder)
+ (setq decoder (list decoder)))
+ (apply 'call-process-region (point-min) (point-max)
+ (car decoder) t t nil (cdr decoder))))
(insert-file-contents fullname visit))))
\f
(defun info-initialize ()
(save-buffers-kill-emacs)))
(info)))
\f
-;; See if the the accessible portion of the buffer begins with a node
+;; See if the accessible portion of the buffer begins with a node
;; delimiter, and the node header line which follows matches REGEXP.
;; Typically, this test will be followed by a loop that examines the
;; rest of the buffer with (search-forward "\n\^_"), and it's a pity
;; want to use the results of re-search-backward.
;; The return value is the value of point at the beginning of matching
-;; REGERXP, if the function succeeds, nil otherwise.
+;; REGEXP, if the function succeeds, nil otherwise.
(defun Info-node-at-bob-matching (regexp)
(and (bobp) ; are we at beginning of buffer?
(looking-at "\^_") ; does it begin with node delimiter?
;; Search file for a suitable node.
(let ((guesspos (point-min))
(regexp (concat "\\(Node:\\|Ref:\\) *\\("
- (regexp-quote nodename)
+ (if (stringp nodename)
+ (regexp-quote nodename)
+ "")
"\\) *[,\t\n\177]"))
(nodepos nil))
(progn
(insert Info-dir-contents)
(goto-char (point-min)))
- (let ((dirs Info-directory-list)
+ (let ((dirs (if Info-additional-directory-list
+ (append Info-directory-list
+ Info-additional-directory-list)
+ Info-directory-list))
;; Bind this in case the user sets it to nil.
(case-fold-search t)
;; This is set non-nil if we find a problem in some input files.
(while (re-search-forward "^\\* Menu:" nil t)
(let (beg nodename end)
(forward-line 1)
+ (while (and (eolp) (not (eobp)))
+ (forward-line 1))
(setq beg (point))
(or (search-backward "\n\^_" nil 'move)
(looking-at "\^_")
(while buffers
(kill-buffer (car buffers))
(setq buffers (cdr buffers)))
+ (if Info-fontify (Info-fontify-menu-headers))
(goto-char (point-min))
(if problems
(message "Composing main Info directory...problems encountered, see `*Messages*'")
(if (numberp nodepos)
(+ (- nodepos lastfilepos) (point)))))
+(defvar Info-header-line nil
+ "If the info node header is hidden, the text of the header.")
+
(defun Info-select-node ()
"Select the info node that point is in.
Bind this in case the user sets it to nil."
;; Find the end of it, and narrow.
(beginning-of-line)
(let (active-expression)
+ ;; Narrow to the node contents
(narrow-to-region (point)
(if (re-search-forward "\n[\^_\f]" nil t)
(prog1
(point-max)))
(if Info-enable-active-nodes (eval active-expression))
(if Info-fontify (Info-fontify-node))
+ (if Info-use-header-line
+ (Info-setup-header-line)
+ (setq Info-header-line nil))
(run-hooks 'Info-selection-hook)))))
(defun Info-set-mode-line ()
(setq mode-line-buffer-identification
- (concat
- " *Info* ("
- (file-name-nondirectory (if (stringp Info-current-file)
- Info-current-file
- (or buffer-file-name "")))
- ") "
- (or Info-current-node ""))))
+ (nconc (propertized-buffer-identification "%b")
+ (list
+ (concat " ("
+ (file-name-nondirectory
+ (if (stringp Info-current-file)
+ Info-current-file
+ (or buffer-file-name "")))
+ ") "
+ (or Info-current-node ""))))))
+\f
+;; Skip the node header and make it into a header-line. This function
+;; should be called when the node is already narrowed.
+(defun Info-setup-header-line ()
+ (goto-char (point-min))
+ (let* ((case-fold-search t)
+ (header-end (save-excursion (forward-line 1) (1- (point))))
+ ;; If we find neither Next: nor Prev: link, show the entire
+ ;; node header. Otherwise, don't show the File: and Node:
+ ;; parts, to avoid wasting precious space on information that
+ ;; is available in the mode line.
+ (header-beg (if (re-search-forward
+ "\\(next\\|prev[ious]*\\): "
+ header-end t)
+ (match-beginning 1)
+ (point))))
+ (set (make-local-variable 'Info-header-line)
+ (buffer-substring header-beg header-end))
+ (setq header-line-format 'Info-header-line)
+ (narrow-to-region (1+ header-end) (point-max))))
\f
;; Go to an info node specified with a filename-and-nodename string
;; of the sort that is found in pointers in nodes.
(defun Info-goto-node (nodename &optional fork)
"Go to info node named NAME. Give just NODENAME or (FILENAME)NODENAME.
-If FORK is non-nil, show the node in a new info buffer.
+If FORK is non-nil (interactively with a prefix arg), show the node in
+a new info buffer.
If FORK is a string, it is the name to use for the new buffer."
- (interactive (list (Info-read-node-name "Goto node: ") current-prefix-arg))
+ (interactive (list (Info-read-node-name "Go to node: ") current-prefix-arg))
(info-initialize)
(if fork
(set-buffer
(defun Info-search (regexp)
"Search for REGEXP, starting from point, and select node it's found in."
- (interactive (list (read-string "Regexp search: "
- nil 'Info-search-history)))
+ (interactive (list (read-string
+ (if Info-search-history
+ (format "Regexp search (default `%s'): "
+ (car Info-search-history))
+ "Regexp search: ")
+ nil 'Info-search-history)))
(when transient-mark-mode
(deactivate-mark))
(when (equal regexp "")
Bind this in case the user sets it to nil."
(let ((case-fold-search t))
(save-excursion
- (goto-char (point-min))
- (forward-line 1)
- (if (re-search-backward (concat name ":") nil t)
- (progn
- (goto-char (match-end 0))
- (Info-following-node-name))
- (if (eq errorname t)
- nil
- (error "Node has no %s" (capitalize (or errorname name))))))))
+ (save-restriction
+ (goto-char (point-min))
+ (when Info-header-line
+ ;; expose the header line in the buffer
+ (widen)
+ (forward-line -1))
+ (let ((bound (point)))
+ (forward-line 1)
+ (cond ((re-search-backward (concat name ":") bound t)
+ (goto-char (match-end 0))
+ (Info-following-node-name))
+ ((not (eq errorname t))
+ (error "Node has no %s"
+ (capitalize (or errorname name))))))))))
(defun Info-following-node-name (&optional allowedchars)
"Return the node name in the buffer following point.
(defun Info-menu (menu-item &optional fork)
"Go to node for menu item named (or abbreviated) NAME.
-Completion is allowed, and the menu item point is on is the default."
+Completion is allowed, and the menu item point is on is the default.
+If FORK is non-nil (interactively with a prefix arg), show the node in
+a new info buffer. If FORK is a string, it is the name to use for the
+new buffer."
(interactive
(let ((completions '())
;; If point is within a menu item, use that item as the default
(not (string-match "\\<index\\>" Info-current-node)))
(Info-goto-node (Info-extract-menu-counting 1))
t)
- ((save-excursion (search-backward "next:" nil t))
+ ((save-excursion
+ (save-restriction
+ (let (limit)
+ (when Info-header-line
+ (goto-char (point-min))
+ (widen)
+ (forward-line -1)
+ (setq limit (point))
+ (forward-line 1))
+ (search-backward "next:" limit t))))
(Info-next)
t)
- ((and (save-excursion (search-backward "up:" nil t))
+ ((and (save-excursion
+ (save-restriction
+ (let (limit)
+ (when Info-header-line
+ (goto-char (point-min))
+ (widen)
+ (forward-line -1)
+ (setq limit (point))
+ (forward-line 1))
+ (search-backward "up:" limit t))))
;; Use string-equal, not equal, to ignore text props.
(not (string-equal (downcase (Info-extract-pointer "up"))
"top")))
;; so we can scroll back through it.
(goto-char (point-max))))
(recenter -1))
- ((and (not (equal (Info-extract-pointer "up")
+ ((and (Info-no-error (Info-extract-pointer "prev"))
+ (not (equal (Info-extract-pointer "up")
(Info-extract-pointer "prev"))))
(Info-no-error (Info-prev))
(goto-char (point-max))
(defun Info-scroll-up ()
"Scroll one screenful forward in Info, considering all nodes as one sequence.
Once you scroll far enough in a node that its menu appears on the screen
-but after point, the next scroll moves into its first subnode.
+but after point, the next scroll moves into its first subnode, unless
+`Info-scroll-prefer-subnodes' is nil.
-When you scroll past the end of a node, that goes to the next node; if
-this node has no successor, it moves to the parent node's successor,
-and so on. If point is inside the menu of a node, it moves to
-subnode indicated by the following menu item. (That case won't
-normally result from this command, but can happen in other ways.)"
+When you scroll past the end of a node, that goes to the next node if
+`Info-scroll-prefer-subnodes' is non-nil and to the first subnode otherwise;
+if this node has no successor, it moves to the parent node's successor,
+and so on. If `Info-scroll-prefer-subnodes' is non-nil and point is inside
+the menu of a node, it moves to subnode indicated by the following menu
+item. (That case won't normally result from this command, but can happen
+in other ways.)"
(interactive)
(if (or (< (window-start) (point-min))
(let* ((case-fold-search t)
(virtual-end (save-excursion
(goto-char (point-min))
- (if (search-forward "\n* Menu:" nil t)
+ (if (and Info-scroll-prefer-subnodes
+ (search-forward "\n* Menu:" nil t))
(point)
(point-max)))))
(if (or (< virtual-end (window-start))
(pos-visible-in-window-p virtual-end))
- (Info-next-preorder)
+ (cond
+ (Info-scroll-prefer-subnodes (Info-next-preorder))
+ ((Info-no-error (Info-goto-node (Info-extract-menu-counting 1))))
+ (t (Info-next-preorder)))
(scroll-up))))
(defun Info-scroll-down ()
"Scroll one screenful back in Info, considering all nodes as one sequence.
-Within the menu of a node, this goes to its last subnode.
-When you scroll past the beginning of a node, that goes to the
-previous node or back up to the parent node."
+If point is within the menu of a node, and `Info-scroll-prefer-subnodes'
+is non-nil, this goes to its last subnode. When you scroll past the
+beginning of a node, that goes to the previous node or back up to the
+parent node."
(interactive)
(if (or (< (window-start) (point-min))
(> (window-start) (point-max)))
(set-window-start (selected-window) (point)))
(let* ((case-fold-search t)
(current-point (point))
- (virtual-end (save-excursion
- (beginning-of-line)
- (setq current-point (point))
- (goto-char (point-min))
- (search-forward "\n* Menu:"
- current-point
- t))))
+ (virtual-end
+ (and Info-scroll-prefer-subnodes
+ (save-excursion
+ (beginning-of-line)
+ (setq current-point (point))
+ (goto-char (point-min))
+ (search-forward "\n* Menu:"
+ current-point
+ t)))))
(if (or virtual-end (pos-visible-in-window-p (point-min)))
(Info-last-preorder)
(scroll-down))))
(progn
(goto-char (point-min))
(while (re-search-forward pattern nil t)
- (setq matches
- (cons (list (match-string-no-properties 1)
- (match-string-no-properties 2)
- Info-current-node
- (string-to-int (concat "0"
- (match-string 3))))
- matches)))
+ (push (list (match-string-no-properties 1)
+ (match-string-no-properties 2)
+ Info-current-node
+ (string-to-int (concat "0"
+ (match-string 3))))
+ matches))
(and (setq node (Info-extract-pointer "next" t))
(string-match "\\<Index\\>" node)))
(Info-goto-node node))
Like \\[Info-menu], \\[Info-follow-reference], \\[Info-next], \\[Info-prev] or \\[Info-up] command, depending on where you click.
At end of the node's text, moves to the next node, or up if none."
(interactive "e")
- (let* ((start (event-start click))
- (window (car start))
- (pos (car (cdr start))))
- (select-window window)
- (goto-char pos))
+ (mouse-set-point click)
(and (not (Info-try-follow-nearest-node))
(save-excursion (forward-line 1) (eobp))
(Info-next-preorder)))
:help "Go backward one node, considering all as a sequence"]
["Forward" Info-forward-node
:help "Go forward one node, considering all as a sequence"]
+ ["Beginning" beginning-of-buffer
+ :help "Go to beginning of this node"]
["Top" Info-top-node
:help "Go to top node of file"]
["Final Node" Info-final-node
("Reference" ["You should never see this" report-emacs-bug t])
["Search..." Info-search
:help "Search for regular expression in this Info file"]
- ["Goto Node..." Info-goto-node
+ ["Go to Node..." Info-goto-node
:help "Go to a named node"]
- ["Last" Info-last Info-history
+ ["Last" Info-last :active Info-history
:help "Go to the last node you were at"]
("Index..."
["Lookup a String" Info-index
:help "Look for a string in the index items"]
["Next Matching Item" Info-index-next
:help "Look for another occurrence of previous item"])
- ["Exit" Info-exit t]))
+ ["Edit" Info-edit :help "Edit contents of this node"
+ :active Info-enable-edit]
+ ["Exit" Info-exit :help "Stop reading Info"]))
+
+
+(defvar info-tool-bar-map
+ (if (display-graphic-p)
+ (let ((tool-bar-map (make-sparse-keymap)))
+ (tool-bar-add-item-from-menu 'Info-exit "close" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-prev "left_arrow" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-next "right_arrow" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-up "up_arrow" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-last "undo" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-top-node "home" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-index "index" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-goto-node "jump_to" Info-mode-map)
+ (tool-bar-add-item-from-menu 'Info-search "search" Info-mode-map)
+ tool-bar-map)))
(defvar Info-menu-last-node nil)
;; Last node the menu was created for.
\f
;; Info mode is suitable only for specially formatted data.
-(put 'info-mode 'mode-class 'special)
+(put 'Info-mode 'mode-class 'special)
(defun Info-mode ()
"Info mode provides commands for browsing through the Info documentation tree.
(setq mode-name "Info")
(setq tab-width 8)
(use-local-map Info-mode-map)
- (make-local-hook 'activate-menubar-hook)
(add-hook 'activate-menubar-hook 'Info-menu-update nil t)
(set-syntax-table text-mode-syntax-table)
(setq local-abbrev-table text-mode-abbrev-table)
(setq Info-tag-table-buffer nil)
(make-local-variable 'Info-history)
(make-local-variable 'Info-index-alternatives)
+ (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)
(setq line-move-ignore-invisible t)
- (add-hook (make-local-hook 'clone-buffer-hook) 'Info-clone-buffer-hook nil t)
+ (add-hook 'clone-buffer-hook 'Info-clone-buffer-hook nil t)
(Info-set-mode-line)
(run-hooks 'Info-mode-hook))
(with-current-buffer Info-tag-table-buffer
(copy-marker (marker-position m))))))))
-(defvar Info-edit-map nil
+(defvar Info-edit-map (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map text-mode-map)
+ (define-key map "\C-c\C-c" 'Info-cease-edit)
+ map)
"Local keymap used within `e' command of Info.")
-(if Info-edit-map
- nil
- (setq Info-edit-map (nconc (make-sparse-keymap) text-mode-map))
- (define-key Info-edit-map "\C-c\C-c" 'Info-cease-edit))
;; Info-edit mode is suitable only for specially formatted data.
-(put 'info-edit-mode 'mode-class 'special)
+(put 'Info-edit-mode 'mode-class 'special)
(defun Info-edit-mode ()
"Major mode for editing the contents of an Info node.
(message "Tags may have changed. Use Info-tagify if necessary")))
\f
(defvar Info-file-list-for-emacs
- '("ediff" "forms" "gnus" "info" ("mh" . "mh-e") "sc" "message"
- ("dired" . "dired-x") ("c" . "ccmode") "viper")
+ '("ediff" "forms" "gnus" ("mh" . "mh-e") "sc" "message"
+ ("dired" . "dired-x") ("c" . "ccmode") "viper" "vip"
+ ("skeleton" . "autotype") ("auto-insert" . "autotype")
+ ("copyright" . "autotype") ("executable" . "autotype")
+ ("time-stamp" . "autotype") ("quickurl" . "autotype")
+ ("tempo" . "autotype") ("hippie-expand" . "autotype")
+ ("cvs" . "pcl-cvs")
+ "ebrowse" "eshell" "cl" "idlwave" "reftex" "speedbar" "widget" "woman")
"List of Info files that describe Emacs commands.
An element can be a file name, or a list of the form (PREFIX . FILE)
where PREFIX is a name prefix and FILE is the file to look in.
\(FILENAME NODENAME BUFFERPOS\)."
(let ((where '())
(cmd-desc (concat "^\\* +" (regexp-quote (symbol-name command))
- ":\\s *\\(.*\\)\\.$"))
+ "\\( <[0-9]+>\\)?:\\s *\\(.*\\)\\.$"))
(info-file "emacs")) ;default
;; Determine which info file this command is documented in.
(if (get command 'info-file)
(if (string-match regexp (symbol-name command))
(setq info-file file file-list nil))
(setq file-list (cdr file-list))))))
- (save-excursion
- (condition-case nil
- (Info-find-node info-file "Command Index")
- ;; Some manuals may not have a separate Command Index node,
- ;; so try just Index instead.
- (error
- (Info-find-node info-file "Index")))
- ;; Take the index node off the Info history.
- (setq Info-history (cdr Info-history))
- (goto-char (point-max))
- (while (re-search-backward cmd-desc nil t)
- (setq where (cons (list Info-current-file
- (match-string-no-properties 1)
+ (Info-find-node info-file "Top")
+ (or (and (search-forward "\n* menu:" nil t)
+ (re-search-forward "\n\\* \\(.*\\<Index\\>\\)" nil t))
+ (error "Info file `%s' appears to lack an index" info-file))
+ (goto-char (match-beginning 1))
+ ;; Bind Info-history to nil, to prevent the index nodes from
+ ;; getting into the node history.
+ (let ((Info-history nil)
+ (exact nil)
+ node found)
+ (Info-goto-node (Info-extract-menu-node-name))
+ (while
+ (progn
+ (goto-char (point-min))
+ (while (re-search-forward cmd-desc nil t)
+ (setq where
+ (cons (list Info-current-file
+ (match-string-no-properties 2)
0)
where)))
- where)))
+ (and (setq node (Info-extract-pointer "next" t))
+ (string-match "\\<Index\\>" node)))
+ (Info-goto-node node)))
+ where))
;;;###autoload
(defun Info-goto-emacs-command-node (command)
"Go to the Info node in the Emacs manual for command COMMAND.
-The command is found by looking up in Emacs manual's Command Index
+The command is found by looking up in Emacs manual's indices
or in another manual found via COMMAND's `info-file' property or
the variable `Info-file-list-for-emacs'."
(interactive "CFind documentation for command: ")
;; FIXME It would be cool if this could use a buffer other
;; than *info*.
(pop-to-buffer "*info*")
- (Info-find-node (car (car where))
- (car (cdr (car where))))
+ ;; 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-find-node (car (car where))
+ (car (cdr (car where)))))
(if (> num-matches 1)
(progn
- ;; Info-find-node already pushed (car where) onto
- ;; Info-history. Put the other nodes that were found on
- ;; the history.
+ ;; (car where) will be pushed onto Info-history
+ ;; when/if they go to another node. Put the other
+ ;; nodes that were found on the history.
(setq Info-history (nconc (cdr where) Info-history))
(message "Found %d other entr%s. Use %s to see %s."
(1- num-matches)
;;;###autoload
(defun Info-goto-emacs-key-command-node (key)
- "Go to the Info node in the Emacs manual the command bound to KEY, a string.
+ "Go to the node in the Emacs manual which describes the command bound to KEY.
+KEY is a string.
Interactively, if the binding is `execute-extended-command', a command is read.
-The command is found by looking up in Emacs manual's Command Index
+The command is found by looking up in Emacs manual's indices
or in another manual found via COMMAND's `info-file' property or
the variable `Info-file-list-for-emacs'."
- (interactive "kFind documentation for key:")
+ (interactive "kFind documentation for key: ")
(let ((command (key-binding key)))
(cond ((null command)
(message "%s is undefined" (key-description key)))
(Info-goto-emacs-command-node command)))))
\f
(defface Info-title-1-face
- '((t (:family "helv" :height 240 :weight bold)))
+ '((((type tty pc) (class color)) (:foreground "yellow" :weight bold))
+ (t (:height 1.2 :inherit Info-title-2-face)))
"Face for Info titles at level 1."
:group 'info)
(defface Info-title-2-face
- '((t (:family "helv" :height 180 :weight bold)))
+ '((((type tty pc) (class color)) (:foreground "lightblue" :weight bold))
+ (t (:height 1.2 :inherit Info-title-3-face)))
"Face for Info titles at level 2."
:group 'info)
(defface Info-title-3-face
- '((t (:family "helv" :height 160 :weight bold)))
+ '((((type tty pc) (class color)) (:weight bold))
+ (t (:height 1.2 :inherit Info-title-4-face)))
"Face for Info titles at level 3."
:group 'info)
+(defface Info-title-4-face
+ '((((type tty pc) (class color)) (:weight bold))
+ (t (:weight bold :inherit variable-pitch)))
+ "Face for Info titles at level 4."
+ :group 'info)
+
+(defface info-menu-header
+ '((((type tty pc))
+ :underline t
+ :weight bold)
+ (t
+ :inherit variable-pitch
+ :weight bold))
+ "Face for headers in Info menus."
+ :group 'info)
+
+(defun Info-fontify-menu-headers ()
+ "Add the face `info-menu-header' to any header before a menu entry."
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward "\\* Menu:" nil t)
+ (put-text-property (match-beginning 0) (match-end 0)
+ 'face 'info-menu-header)
+ (while (re-search-forward "\n\n\\([^*\n ].*\\)\n\n?[*]" nil t)
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'face 'info-menu-header)))))
+
(defun Info-fontify-node ()
(save-excursion
(let ((buffer-read-only nil)
(goto-char (point-min))
(when (looking-at "^File: [^,: \t]+,?[ \t]+")
(goto-char (match-end 0))
- (while
- (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?")
+ (while (looking-at "[ \t]*\\([^:, \t\n]+\\):[ \t]+\\([^:,\t\n]+\\),?")
(goto-char (match-end 0))
- (if (save-excursion
- (goto-char (match-beginning 1))
- (save-match-data (looking-at "Node:")))
- (put-text-property (match-beginning 2) (match-end 2)
- 'face 'info-node)
- (put-text-property (match-beginning 2) (match-end 2)
- 'face 'info-xref)
- (put-text-property (match-beginning 2) (match-end 2)
- 'mouse-face 'highlight))))
+ (let* ((nbeg (match-beginning 2))
+ (nend (match-end 2))
+ (tbeg (match-beginning 1))
+ (tag (buffer-substring tbeg (match-end 1))))
+ (if (string-equal tag "Node")
+ (put-text-property nbeg nend 'face 'info-header-node)
+ (put-text-property nbeg nend 'face 'info-header-xref)
+ (put-text-property nbeg nend 'mouse-face 'highlight)
+ (put-text-property tbeg nend
+ 'help-echo
+ (concat "Go to node "
+ (buffer-substring nbeg nend)))
+ (let ((fun (cdr (assoc tag '(("Prev" . Info-prev)
+ ("Next" . Info-next)
+ ("Up" . Info-up))))))
+ (when fun
+ (let ((keymap (make-sparse-keymap)))
+ (define-key keymap [header-line mouse-1] fun)
+ (define-key keymap [header-line mouse-2] fun)
+ (put-text-property tbeg nend 'local-map keymap))))
+ ))))
(goto-char (point-min))
- (while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\)$"
+ (while (re-search-forward "\n\\([^ \t\n].+\\)\n\\(\\*+\\|=+\\|-+\\|\\.+\\)$"
nil t)
(let ((c (preceding-char))
face)
(cond ((= c ?*) (setq face 'Info-title-1-face))
((= c ?=) (setq face 'Info-title-2-face))
- (t (setq face 'Info-title-3-face)))
+ ((= c ?-) (setq face 'Info-title-3-face))
+ (t (setq face 'Info-title-4-face)))
(put-text-property (match-beginning 1) (match-end 1)
'face face))
;; 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.
- (if (memq (framep (selected-frame)) '(x pc w32))
- (add-text-properties (match-end 1) (match-end 2)
- '(invisible t intangible t))))
+ (when (memq (framep (selected-frame)) '(x pc w32 mac))
+ (add-text-properties (match-end 1) (match-end 2)
+ '(invisible t intangible t))
+ (add-text-properties (1- (match-end 1)) (match-end 2)
+ '(intangible t))))
(goto-char (point-min))
(while (re-search-forward "\\*Note[ \n\t]+\\([^:]*\\):" nil t)
(if (= (char-after (1- (match-beginning 0))) ?\") ; hack
nil
- (put-text-property (match-beginning 1) (match-end 1)
- 'face 'info-xref)
- (put-text-property (match-beginning 1) (match-end 1)
- 'mouse-face 'highlight)))
+ (add-text-properties (match-beginning 1) (match-end 1)
+ '(face info-xref
+ mouse-face highlight
+ help-echo "mouse-2: go to this node"))))
(goto-char (point-min))
(if (and (search-forward "\n* Menu:" nil t)
(not (string-match "\\<Index\\>" Info-current-node))
(put-text-property (match-beginning 0)
(1+ (match-beginning 0))
'face 'info-menu-5))
- (put-text-property (match-beginning 1) (match-end 1)
- 'face 'info-xref)
- (put-text-property (match-beginning 1) (match-end 1)
- 'mouse-face 'highlight))))
+ (add-text-properties (match-beginning 1) (match-end 1)
+ '(face info-xref
+ mouse-face highlight
+ help-echo "mouse-2: go to this node")))))
+ (Info-fontify-menu-headers)
(set-buffer-modified-p nil))))
\f
(speedbar-change-initial-expansion-list "Info")
)
+(eval-when-compile (defvar speedbar-attached-frame))
+
(defun Info-speedbar-hierarchy-buttons (directory depth &optional node)
"Display an Info directory hierarchy in speedbar.
DIRECTORY is the current directory in the attached frame.
nil))))
(defun Info-speedbar-goto-node (text node indent)
- "When user clicks on TEXT, goto an info NODE.
+ "When user clicks on TEXT, go to an info NODE.
The INDENT level is ignored."
(select-frame speedbar-attached-frame)
(let* ((buff (or (get-buffer "*info*")