;; info.el --- info package for Emacs
-;; Copyright (C) 1985-1986, 1992-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1992-2013 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: help
:group 'info
:version "24.1")
-(defcustom Info-enable-edit nil
- "Non-nil means the \\<Info-mode-map>\\[Info-edit] command in Info can edit the current node.
-This is convenient if you want to write Info files by hand.
-However, we recommend that you not do this.
-It is better to write a Texinfo file and generate the Info file from that,
-because that gives you a printed manual as well."
- :type 'boolean
- :group 'info)
-
(defvar Info-enable-active-nodes nil
"Non-nil allows Info to execute Lisp code associated with nodes.
The Lisp code is executed when the node is selected.")
(defvar Info-edit-mode-hook nil
"Hooks run when `Info-edit-mode' is called.")
+(make-obsolete-variable 'Info-edit-mode-hook
+ "editing Info nodes by hand is not recommended." "24.4")
+
(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 NODENAME is of the form (FILENAME)NODENAME, the node is in the Info file
FILENAME; otherwise, NODENAME should be in the current Info file (or one of
its sub-files).
-Completion is available, but only for node names in the current Info file.
+Completion is available for node names in the current Info file as well as
+in the Info file FILENAME after the closing parenthesis in (FILENAME).
+Empty NODENAME in (FILENAME) defaults to the Top node.
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."
(when (file-name-absolute-p string)
(setq dirs (list (file-name-directory string))))
(let ((names nil)
+ (names-sans-suffix nil)
(suffix (concat (regexp-opt suffixes t) "\\'"))
(string-dir (file-name-directory string)))
(dolist (dir dirs)
;; add the unsuffixed name as a completion option.
(when (string-match suffix file)
(setq file (substring file 0 (match-beginning 0)))
- (push (if string-dir (concat string-dir file) file) names)))))
+ (push (if string-dir (concat string-dir file) file)
+ names-sans-suffix)))))
+ ;; If there is just one file, don't duplicate it with suffixes,
+ ;; so `Info-read-node-name-1' will be able to complete a single
+ ;; candidate and to add the terminating ")".
+ (if (and (= (length names) 1) (= (length names-sans-suffix) 1))
+ (setq names names-sans-suffix)
+ (setq names (append names-sans-suffix names)))
(complete-with-action action names string pred)))
(defun Info-read-node-name-1 (string predicate code)
((string-match "\\`(\\([^)]+\\))" string)
(let ((file0 (match-string 0 string))
(file1 (match-string 1 string))
- (node (substring string (match-end 0))))
- (completion-table-with-context
- file0
- (apply-partially
- (lambda (string pred action)
- (complete-with-action
- action
- (Info-build-node-completions (Info-find-file file1))
- string pred)))
- node predicate code)))
+ (nodename (substring string (match-end 0))))
+ (if (and (equal nodename "") (eq code 'lambda))
+ ;; Empty node name is permitted that means "Top".
+ t
+ (completion-table-with-context
+ file0
+ (apply-partially
+ (lambda (string pred action)
+ (complete-with-action
+ action
+ (Info-build-node-completions (Info-find-file file1))
+ string pred)))
+ nodename predicate code))))
;; Otherwise use Info-read-node-completion-table.
(t (complete-with-action
code Info-read-node-completion-table string predicate))))
(defun Info-read-node-name (prompt)
"Read an Info node name with completion, prompting with PROMPT.
A node name can have the form \"NODENAME\", referring to a node
-in the current Info file, or \"(FILENAME)NODENAME\"."
+in the current Info file, or \"(FILENAME)NODENAME\", referring to
+a node in FILENAME. \"(FILENAME)\" is a short format to go to
+the Top node in FILENAME."
(let* ((completion-ignore-case t)
(Info-read-node-completion-table (Info-build-node-completions))
(nodename (completing-read prompt 'Info-read-node-name-1 nil t)))
(Info-read-node-name prompt)
nodename)))
-(defun Info-build-node-completions (&optional file)
- (if file
- (or (cdr (assoc file Info-file-completions))
+(defun Info-build-node-completions (&optional filename)
+ (if filename
+ (or (cdr (assoc filename Info-file-completions))
(with-temp-buffer
(Info-mode)
- (Info-goto-node (format "(%s)Top" file))
+ (Info-goto-node (format "(%s)Top" filename))
(Info-build-node-completions-1)
- (push (cons file Info-current-file-completions) Info-file-completions)
+ (push (cons filename Info-current-file-completions) Info-file-completions)
Info-current-file-completions))
(or Info-current-file-completions
(Info-build-node-completions-1))))
(let ((backward (< found beg-found)))
(not
(or
- (and (not (eq search-invisible t))
+ (and (not search-invisible)
(if backward
(or (text-property-not-all found beg-found 'invisible nil)
(text-property-not-all found beg-found 'display nil))
(select-window (posn-window (event-start e))))
(Info-scroll-down)))
-(defun Info-next-reference (&optional recur)
- "Move cursor to the next cross-reference or menu item in the node."
- (interactive)
- (let ((pat "\\*note[ \n\t]+\\([^:]+\\):\\|^\\* .*:\\|[hf]t?tps?://")
- (old-pt (point))
- (case-fold-search t))
- (or (eobp) (forward-char 1))
- (or (re-search-forward pat nil t)
- (progn
- (goto-char (point-min))
- (or (re-search-forward pat nil t)
- (progn
- (goto-char old-pt)
- (user-error "No cross references in this node")))))
- (goto-char (or (match-beginning 1) (match-beginning 0)))
- (if (looking-at "\\* Menu:")
- (if recur
- (user-error "No cross references in this node")
- (Info-next-reference t))
- (if (looking-at "^\\* ")
- (forward-char 2)))))
-
-(defun Info-prev-reference (&optional recur)
- "Move cursor to the previous cross-reference or menu item in the node."
- (interactive)
- (let ((pat "\\*note[ \n\t]+\\([^:]+\\):\\|^\\* .*:\\|[hf]t?tps?://")
- (old-pt (point))
- (case-fold-search t))
- (or (re-search-backward pat nil t)
- (progn
- (goto-char (point-max))
- (or (re-search-backward pat nil t)
- (progn
- (goto-char old-pt)
- (user-error "No cross references in this node")))))
- (goto-char (or (match-beginning 1) (match-beginning 0)))
- (if (looking-at "\\* Menu:")
- (if recur
- (user-error "No cross references in this node")
- (Info-prev-reference t))
- (if (looking-at "^\\* ")
- (forward-char 2)))))
+(defun Info-next-reference (&optional recur count)
+ "Move cursor to the next cross-reference or menu item in the node.
+If COUNT is non-nil (interactively with a prefix arg), jump over
+COUNT cross-references."
+ (interactive "i\np")
+ (unless count
+ (setq count 1))
+ (if (< count 0)
+ (Info-prev-reference recur (- count))
+ (while (unless (zerop count) (setq count (1- count)))
+ (let ((pat "\\*note[ \n\t]+\\([^:]+\\):\\|^\\* .*:\\|[hf]t?tps?://")
+ (old-pt (point))
+ (case-fold-search t))
+ (or (eobp) (forward-char 1))
+ (or (re-search-forward pat nil t)
+ (progn
+ (goto-char (point-min))
+ (or (re-search-forward pat nil t)
+ (progn
+ (goto-char old-pt)
+ (user-error "No cross references in this node")))))
+ (goto-char (or (match-beginning 1) (match-beginning 0)))
+ (if (looking-at "\\* Menu:")
+ (if recur
+ (user-error "No cross references in this node")
+ (Info-next-reference t))
+ (if (looking-at "^\\* ")
+ (forward-char 2)))))))
+
+(defun Info-prev-reference (&optional recur count)
+ "Move cursor to the previous cross-reference or menu item in the node.
+If COUNT is non-nil (interactively with a prefix arg), jump over
+COUNT cross-references."
+ (interactive "i\np")
+ (unless count
+ (setq count 1))
+ (if (< count 0)
+ (Info-next-reference recur (- count))
+ (while (unless (zerop count) (setq count (1- count)))
+ (let ((pat "\\*note[ \n\t]+\\([^:]+\\):\\|^\\* .*:\\|[hf]t?tps?://")
+ (old-pt (point))
+ (case-fold-search t))
+ (or (re-search-backward pat nil t)
+ (progn
+ (goto-char (point-max))
+ (or (re-search-backward pat nil t)
+ (progn
+ (goto-char old-pt)
+ (user-error "No cross references in this node")))))
+ (goto-char (or (match-beginning 1) (match-beginning 0)))
+ (if (looking-at "\\* Menu:")
+ (if recur
+ (user-error "No cross references in this node")
+ (Info-prev-reference t))
+ (if (looking-at "^\\* ")
+ (forward-char 2)))))))
\f
(defun Info-index-nodes (&optional file)
"Return a list of names of all index nodes in Info FILE.
(suppress-keymap map)
(define-key map "." 'beginning-of-buffer)
(define-key map " " 'Info-scroll-up)
+ (define-key map [?\S-\ ] 'Info-scroll-down)
(define-key map "\C-m" 'Info-follow-nearest-node)
(define-key map "\t" 'Info-next-reference)
(define-key map "\e\t" 'Info-prev-reference)
map)
"Local keymap used within `e' command of Info.")
+(make-obsolete-variable 'Info-edit-map
+ "editing Info nodes by hand is not recommended."
+ "24.4")
+
;; Info-edit mode is suitable only for specially formatted data.
(put 'Info-edit-mode 'mode-class 'special)
(buffer-enable-undo (current-buffer))
(run-mode-hooks 'Info-edit-mode-hook))
+(make-obsolete 'Info-edit-mode
+ "editing Info nodes by hand is not recommended." "24.4")
+
(defun Info-edit ()
- "Edit the contents of this Info node.
-Allowed only if variable `Info-enable-edit' is non-nil."
+ "Edit the contents of this Info node."
(interactive)
- (or Info-enable-edit
- (error "Editing Info nodes is not enabled"))
(Info-edit-mode)
(message "%s" (substitute-command-keys
"Editing: Type \\<Info-edit-map>\\[Info-cease-edit] to return to info")))
+(put 'Info-edit 'disabled "Editing Info nodes by hand is not recommended.
+This feature will be removed in future.")
+
+(make-obsolete 'Info-edit
+ "editing Info nodes by hand is not recommended." "24.4")
+
(defun Info-cease-edit ()
"Finish editing Info node; switch back to Info proper."
(interactive)
(and (marker-position Info-tag-table-marker)
(buffer-modified-p)
(message "Tags may have changed. Use Info-tagify if necessary")))
+
+(make-obsolete 'Info-cease-edit
+ "editing Info nodes by hand is not recommended." "24.4")
\f
(defvar Info-file-list-for-emacs
'("ediff" "eudc" "forms" "gnus" "info" ("Info" . "info") ("mh" . "mh-e")
The `info-file' property of COMMAND says which Info manual to search.
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.
+The locations are of the format used in the variable `Info-history', i.e.
\(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."
(with-current-buffer buffer
(and (eq major-mode 'Info-mode)
(stringp Info-current-file)
+ (not (string= (substring (buffer-name) 0 1) " "))
(push (file-name-sans-extension
(file-name-nondirectory Info-current-file))
names))))
(delete-dups (append (nreverse names)
- (apply-partially 'Info-read-node-name-2
- Info-directory-list
- (mapcar 'car Info-suffix-list))))))
+ (all-completions
+ ""
+ (apply-partially 'Info-read-node-name-2
+ Info-directory-list
+ (mapcar 'car Info-suffix-list)))))))
(provide 'info)