: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)
: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
+ '(;; Because header-lines on tty's are usually reverse-video, the
+ ;; normal info-node colors probably won't look good, so just stick
+ ;; with bold-italic
+ (((type tty) (class color)) (:bold t :italic t))
+ (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', 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. (If
+you want to override that, 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.
;; 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.
(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 ()
") "
(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))
+ (forward-line 1)
+ (set (make-local-variable 'Info-header-line)
+ (buffer-substring (point-min) (1- (point))))
+ (setq header-line-format 'Info-header-line)
+ (narrow-to-region (point) (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.
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
+ (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 ":") nil bound)
(goto-char (match-end 0))
(Info-following-node-name))
- (if (eq errorname t)
- nil
- (error "Node has no %s" (capitalize (or errorname 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.
\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.
(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" "cl" "idlwave" "reftex" "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)
;; 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)
The command is found by looking up in Emacs manual's Command Index
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)))
+ '((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)))
+ '((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)))
+ '((t (:height 1.2 :weight bold :inherit variable-pitch)))
"Face for Info titles at level 3."
:group 'info)
(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 "Goto 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\\(\\*+\\|=+\\|-+\\)$"
nil t)