(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
: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 ()
(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*'")
;; 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))))
(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)
;; 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))
("time-stamp" . "autotype") ("quickurl" . "autotype")
("tempo" . "autotype") ("hippie-expand" . "autotype")
("cvs" . "pcl-cvs")
- "ebrowse" "cl" "idlwave" "reftex" "speedbar" "widget" "woman")
+ "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.
"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)
;; 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))
+ (if (memq (framep (selected-frame)) '(x pc w32 mac))
(add-text-properties (match-end 1) (match-end 2)
'(invisible t intangible t))))
(goto-char (point-min))
(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