X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/233ba4d924933cb56129bd7511e6137b7c0b8e3e..98cd6c18c57c031d8c0a0d13284375b8ccf60439:/lisp/info.el diff --git a/lisp/info.el b/lisp/info.el index bc2062e72b..447c86b3e9 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -32,7 +32,7 @@ ;;; Code: -(eval-when-compile (require 'jka-compr) (require 'cl)) +(eval-when-compile (require 'cl)) (defgroup info nil "Info subsystem." @@ -165,7 +165,7 @@ A header-line does not scroll with the rest of the buffer." If nil, meaning not yet initialized, Info uses the environment variable INFOPATH to initialize it, or `Info-default-directory-list' if there is no INFOPATH variable in the environment, or the -concatenation of the two if INFOPATH ends with a colon. +concatenation of the two if INFOPATH ends with a `path-separator'. When `Info-directory-list' is initialized from the value of `Info-default-directory-list', and Emacs is installed in one of the @@ -343,9 +343,8 @@ Each element of the list has the format (NODENAME (OPERATION . HANDLER) ...) where NODENAME is a regexp that matches a class of virtual Info node names. It should be carefully chosen to not cause node name clashes with existing node names. OPERATION is one of the following operation -symbols `find-node' that define what HANDLER -function to call instead of calling the default corresponding function -to override it.") +symbols `find-node' that define what HANDLER function to call instead +of calling the default corresponding function to override it.") (defvar Info-current-node-virtual nil "Non-nil if the current Info node is virtual.") @@ -379,50 +378,50 @@ or `Info-virtual-nodes'." ;; The MS-DOS list should work both when long file names are ;; supported (Windows 9X), and when only 8+3 file names are available. (if (eq system-type 'ms-dos) - '( (".gz" . "gunzip") - (".z" . "gunzip") - (".bz2" . ("bzip2" "-dc")) - (".inz" . "gunzip") - (".igz" . "gunzip") - (".info.Z" . "gunzip") - (".info.gz" . "gunzip") - ("-info.Z" . "gunzip") - ("-info.gz" . "gunzip") - ("/index.gz". "gunzip") - ("/index.z" . "gunzip") - (".inf" . nil) - (".info" . nil) - ("-info" . nil) - ("/index" . nil) - ("" . nil)) - '( (".info.Z". "uncompress") - (".info.Y". "unyabba") - (".info.gz". "gunzip") - (".info.z". "gunzip") - (".info.bz2" . ("bzip2" "-dc")) - (".info.xz". "unxz") - (".info". nil) - ("-info.Z". "uncompress") - ("-info.Y". "unyabba") - ("-info.gz". "gunzip") - ("-info.bz2" . ("bzip2" "-dc")) - ("-info.z". "gunzip") - ("-info.xz". "unxz") - ("-info". nil) - ("/index.Z". "uncompress") - ("/index.Y". "unyabba") - ("/index.gz". "gunzip") - ("/index.z". "gunzip") - ("/index.bz2". ("bzip2" "-dc")) - ("/index.xz". "unxz") - ("/index". nil) - (".Z". "uncompress") - (".Y". "unyabba") - (".gz". "gunzip") - (".z". "gunzip") - (".bz2" . ("bzip2" "-dc")) - (".xz". "unxz") - ("". nil))) + '( (".gz" . "gunzip") + (".z" . "gunzip") + (".bz2" . ("bzip2" "-dc")) + (".inz" . "gunzip") + (".igz" . "gunzip") + (".info.Z" . "gunzip") + (".info.gz" . "gunzip") + ("-info.Z" . "gunzip") + ("-info.gz" . "gunzip") + ("/index.gz" . "gunzip") + ("/index.z" . "gunzip") + (".inf" . nil) + (".info" . nil) + ("-info" . nil) + ("/index" . nil) + ("" . nil)) + '( (".info.Z" . "uncompress") + (".info.Y" . "unyabba") + (".info.gz" . "gunzip") + (".info.z" . "gunzip") + (".info.bz2" . ("bzip2" "-dc")) + (".info.xz" . "unxz") + (".info" . nil) + ("-info.Z" . "uncompress") + ("-info.Y" . "unyabba") + ("-info.gz" . "gunzip") + ("-info.bz2" . ("bzip2" "-dc")) + ("-info.z" . "gunzip") + ("-info.xz" . "unxz") + ("-info" . nil) + ("/index.Z" . "uncompress") + ("/index.Y" . "unyabba") + ("/index.gz" . "gunzip") + ("/index.z" . "gunzip") + ("/index.bz2" . ("bzip2" "-dc")) + ("/index.xz" . "unxz") + ("/index" . nil) + (".Z" . "uncompress") + (".Y" . "unyabba") + (".gz" . "gunzip") + (".z" . "gunzip") + (".bz2" . ("bzip2" "-dc")) + (".xz" . "unxz") + ("" . 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. @@ -465,6 +464,7 @@ be last in the list.") "Insert the contents of an Info file in the current buffer. Do the right thing if the file has been compressed or zipped." (let* ((tail Info-suffix-list) + (jka-compr-verbose nil) (lfn (if (fboundp 'msdos-long-file-names) (msdos-long-file-names) t)) @@ -594,15 +594,15 @@ in `Info-file-supports-index-cookies-list'." (defun info-initialize () "Initialize `Info-directory-list', if that hasn't been done yet." (unless Info-directory-list - (let ((path (getenv "INFOPATH"))) + (let ((path (getenv "INFOPATH")) + (sep (regexp-quote path-separator))) (setq Info-directory-list (prune-directory-list (if path - (if (string-match ":\\'" path) - (append (split-string (substring path 0 -1) - (regexp-quote path-separator)) + (if (string-match-p (concat sep "\\'") path) + (append (split-string (substring path 0 -1) sep) (Info-default-dirs)) - (split-string path (regexp-quote path-separator))) + (split-string path sep)) (Info-default-dirs))))))) ;;;###autoload @@ -622,7 +622,7 @@ in `Info-file-supports-index-cookies-list'." Optional argument FILE-OR-NODE specifies the file to examine; the default is the top-level directory of Info. Called from a program, FILE-OR-NODE may specify an Info node of the form -`(FILENAME)NODENAME'. +\"(FILENAME)NODENAME\". Optional argument BUFFER specifies the Info buffer name; the default buffer name is *info*. If BUFFER exists, just switch to BUFFER. Otherwise, create a new buffer @@ -705,7 +705,7 @@ In standalone mode, \\\\[Info-exit] exits Emacs itself." (re-search-backward regexp beg t)))) (defun Info-find-file (filename &optional noerror) - "Return expanded FILENAME, or t, if FILENAME is \"dir\". + "Return expanded FILENAME, or t if FILENAME is \"dir\". Optional second argument NOERROR, if t, means if file is not found just return nil (no error)." ;; Convert filename to lower case if not found as specified. @@ -729,6 +729,11 @@ just return nil (no error)." (append Info-directory-list Info-additional-directory-list) Info-directory-list))))) + ;; Fall back on the installation directory if we can't find + ;; the info node anywhere else. + (when installation-directory + (setq dirs (append dirs (list (expand-file-name + "info" installation-directory))))) ;; Search the directory list for file FILENAME. (while (and dirs (not found)) (setq temp (expand-file-name filename (car dirs))) @@ -835,7 +840,7 @@ is preserved, if possible." (if new-history (setq Info-history (cons new-history Info-history)))))) -(defun Info-revert-buffer-function (ignore-auto noconfirm) +(defun Info-revert-buffer-function (_ignore-auto noconfirm) (when (or noconfirm (y-or-n-p "Revert info buffer? ")) (Info-revert-find-node Info-current-file Info-current-node) (message "Reverted %s" Info-current-file))) @@ -1394,10 +1399,11 @@ a case-insensitive match is tried." ;; \0\h[image param=value ...\h\0] ;; into the Info file for handling images. (defun Info-split-parameter-string (parameter-string) - "Return alist of (\"KEY\" . \"VALUE\") from PARAMETER-STRING; a -whitespace separated list of KEY=VALUE pairs. If VALUE contains -whitespace or double quotes, it must be quoted in double quotes and -any double quotes or backslashes must be escaped (\\\",\\\\)." + "Return alist of (\"KEY\" . \"VALUE\") from PARAMETER-STRING. +PARAMETER-STRING is a whitespace separated list of KEY=VALUE pairs. +If VALUE contains whitespace or double quotes, it must be quoted +in double quotes and any double quotes or backslashes must be +escaped (\\\",\\\\)." (let ((start 0) (parameter-alist)) (while (string-match @@ -1572,8 +1578,12 @@ If FORK is a string, it is the name to use for the new buffer." (defvar Info-read-node-completion-table) (defun Info-read-node-name-2 (dirs suffixes string pred action) - "Virtual completion table for file names input in Info node names. -PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)." + "Internal function used to complete Info node names. +Return a completion table for Info files---the FILENAME part of a +node named \"(FILENAME)NODENAME\". DIRS is a list of Info +directories to search if FILENAME is not absolute; SUFFIXES is a +list of valid filename suffixes for Info files. See +`try-completion' for a description of the remaining arguments." (setq suffixes (remove "" suffixes)) (when (file-name-absolute-p string) (setq dirs (list (file-name-directory string)))) @@ -1603,10 +1613,9 @@ PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)." (push (if string-dir (concat string-dir file) file) names))))) (complete-with-action action names string pred))) -;; This function is used as the "completion table" while reading a node name. -;; It does completion using the alist in Info-read-node-completion-table -;; unless STRING starts with an open-paren. (defun Info-read-node-name-1 (string predicate code) + "Internal function used by `Info-read-node-name'. +See `completing-read' for a description of arguments and usage." (cond ;; First complete embedded file names. ((string-match "\\`([^)]*\\'" string) @@ -1619,7 +1628,6 @@ PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)." (substring string 1) predicate code)) - ;; If a file name was given, then any node is fair game. ((string-match "\\`(" string) (cond @@ -1631,9 +1639,10 @@ PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)." code Info-read-node-completion-table string predicate)))) ;; Arrange to highlight the proper letters in the completion list buffer. - - (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\"." (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))) @@ -1694,7 +1703,7 @@ PATH-AND-SUFFIXES is a pair of lists, (DIRECTORIES . SUFFIXES)." (defvar Info-search-case-fold nil "The value of `case-fold-search' from previous `Info-search' command.") -(defun Info-search (regexp &optional bound noerror count direction) +(defun Info-search (regexp &optional bound _noerror _count direction) "Search for REGEXP, starting from point, and select node it's found in. If DIRECTION is `backward', search in the reverse direction." (interactive (list (read-string @@ -1915,7 +1924,7 @@ If DIRECTION is `backward', search in the reverse direction." `(lambda (cmd) (Info-isearch-pop-state cmd ',Info-current-file ',Info-current-node))) -(defun Info-isearch-pop-state (cmd file node) +(defun Info-isearch-pop-state (_cmd file node) (or (and (equal Info-current-file file) (equal Info-current-node node)) (progn (Info-find-node file node) (sit-for 0)))) @@ -2093,16 +2102,16 @@ If SAME-FILE is non-nil, do not move to a different Info file." )) (defun Info-directory-toc-nodes (filename) - "Directory-specific implementation of Info-directory-toc-nodes." + "Directory-specific implementation of `Info-toc-nodes'." `(,filename ("Top" nil nil nil))) -(defun Info-directory-find-file (filename &optional noerror) - "Directory-specific implementation of Info-find-file." +(defun Info-directory-find-file (filename &optional _noerror) + "Directory-specific implementation of `Info-find-file'." filename) -(defun Info-directory-find-node (filename nodename &optional no-going-back) - "Directory-specific implementation of Info-find-node-2." +(defun Info-directory-find-node (_filename _nodename &optional _no-going-back) + "Directory-specific implementation of `Info-find-node-2'." (Info-insert-dir)) ;;;###autoload @@ -2119,16 +2128,16 @@ If SAME-FILE is non-nil, do not move to a different Info file." )) (defun Info-history-toc-nodes (filename) - "History-specific implementation of Info-history-toc-nodes." + "History-specific implementation of `Info-history-toc-nodes'." `(,filename ("Top" nil nil nil))) -(defun Info-history-find-file (filename &optional noerror) - "History-specific implementation of Info-find-file." +(defun Info-history-find-file (filename &optional _noerror) + "History-specific implementation of `Info-find-file'." filename) -(defun Info-history-find-node (filename nodename &optional no-going-back) - "History-specific implementation of Info-find-node-2." +(defun Info-history-find-node (filename nodename &optional _no-going-back) + "History-specific implementation of `Info-find-node-2'." (insert (format "\n\^_\nFile: %s, Node: %s, Up: (dir)\n\n" (or filename Info-current-file) nodename)) (insert "Recently Visited Nodes\n") @@ -2157,8 +2166,8 @@ If SAME-FILE is non-nil, do not move to a different Info file." (find-node . Info-toc-find-node) )) -(defun Info-toc-find-node (filename nodename &optional no-going-back) - "Toc-specific implementation of Info-find-node-2." +(defun Info-toc-find-node (filename nodename &optional _no-going-back) + "Toc-specific implementation of `Info-find-node-2'." (let* ((curr-file (substring-no-properties (or filename Info-current-file))) (curr-node (substring-no-properties (or nodename Info-current-node))) (node-list (Info-toc-nodes curr-file))) @@ -3138,8 +3147,8 @@ FILENAME is the file name of the manual, TOPIC is the search string given as an argument to `Info-virtual-index', MATCHES is a list of index matches found by `Info-index'.") -(defun Info-virtual-index-find-node (filename nodename &optional no-going-back) - "Index-specific implementation of Info-find-node-2." +(defun Info-virtual-index-find-node (filename nodename &optional _no-going-back) + "Index-specific implementation of `Info-find-node-2'." ;; Generate Index-like menu of matches (if (string-match "^\\*Index for `\\(.+\\)'\\*$" nodename) ;; Generate Index-like menu of matches @@ -3201,8 +3210,7 @@ search results." (Info-find-node Info-current-file "*Index*") (unless (assoc (cons Info-current-file topic) Info-virtual-index-nodes) (let ((orignode Info-current-node) - (ohist-list Info-history-list) - nodename) + (ohist-list Info-history-list)) ;; Reuse `Info-index' to set `Info-index-alternatives'. (Info-index topic) (push (cons (cons Info-current-file topic) Info-index-alternatives) @@ -3232,18 +3240,18 @@ STRING is the search string given as an argument to `info-apropos', MATCHES is a list of index matches found by `Info-apropos-matches'.") (defun Info-apropos-toc-nodes (filename) - "Apropos-specific implementation of Info-apropos-toc-nodes." + "Apropos-specific implementation of `Info-toc-nodes'." (let ((nodes (mapcar 'car (reverse Info-apropos-nodes)))) `(,filename ("Top" nil nil ,nodes) ,@(mapcar (lambda (node) `(,node "Top" nil nil)) nodes)))) -(defun Info-apropos-find-file (filename &optional noerror) - "Apropos-specific implementation of Info-find-file." +(defun Info-apropos-find-file (filename &optional _noerror) + "Apropos-specific implementation of `Info-find-file'." filename) -(defun Info-apropos-find-node (filename nodename &optional no-going-back) - "Apropos-specific implementation of Info-find-node-2." +(defun Info-apropos-find-node (_filename nodename &optional _no-going-back) + "Apropos-specific implementation of `Info-find-node-2'." (if (equal nodename "Top") ;; Generate Top menu (let ((nodes (reverse Info-apropos-nodes))) @@ -3283,7 +3291,6 @@ MATCHES is a list of index matches found by `Info-apropos-matches'.") "Collect STRING matches from all known Info files on your system. Return a list of matches where each element is in the format \((FILENAME INDEXTEXT NODENAME LINENUMBER))." - (interactive "sIndex apropos: ") (unless (string= string "") (let ((pattern (format "\n\\* +\\([^\n]*%s[^\n]*\\):[ \t]+\\([^\n]+\\)\\.\\(?:[ \t\n]*(line +\\([0-9]+\\))\\)?" (regexp-quote string))) @@ -3362,8 +3369,8 @@ Build a menu of the possible matches." (defvar Info-finder-file "*Finder*" "Info file name of the virtual Info keyword finder manual.") -(defun Info-finder-find-file (filename &optional noerror) - "Finder-specific implementation of Info-find-file." +(defun Info-finder-find-file (filename &optional _noerror) + "Finder-specific implementation of `Info-find-file'." filename) (defvar finder-known-keywords) @@ -3373,8 +3380,8 @@ Build a menu of the possible matches." (defvar finder-keywords-hash) (defvar package-alist) ; finder requires package -(defun Info-finder-find-node (filename nodename &optional no-going-back) - "Finder-specific implementation of Info-find-node-2." +(defun Info-finder-find-node (_filename nodename &optional _no-going-back) + "Finder-specific implementation of `Info-find-node-2'." (require 'finder) (cond ((equal nodename "Top") @@ -3468,7 +3475,7 @@ Build a menu of the possible matches." "Display descriptions of the keywords in the Finder virtual manual. In interactive use, a prefix argument directs this command to read a list of keywords separated by comma. After that, it displays a node -with a list packages that contain all specified keywords." +with a list of packages that contain all specified keywords." (interactive (when current-prefix-arg (require 'finder) @@ -3520,14 +3527,14 @@ with a list packages that contain all specified keywords." (defun Info-get-token (pos start all &optional errorstring) "Return the token around POS. -POS must be somewhere inside the token +POS must be somewhere inside the token. START is a regular expression which will match the - beginning of the tokens delimited string + beginning of the tokens delimited string. ALL is a regular expression with a single parenthesized subpattern which is the token to be returned. E.g. '{\(.*\)}' would return any string enclosed in braces around POS. -ERRORSTRING optional fourth argument, controls action on no match +ERRORSTRING optional fourth argument, controls action on no match: nil: return nil t: beep a string: signal an error, using that string." @@ -3648,7 +3655,6 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (define-key map "\C-m" 'Info-follow-nearest-node) (define-key map "\t" 'Info-next-reference) (define-key map "\e\t" 'Info-prev-reference) - (define-key map [(shift tab)] 'Info-prev-reference) (define-key map [backtab] 'Info-prev-reference) (define-key map "1" 'Info-nth-menu-item) (define-key map "2" 'Info-nth-menu-item) @@ -3666,6 +3672,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'." (define-key map "<" 'Info-top-node) (define-key map ">" 'Info-final-node) (define-key map "b" 'beginning-of-buffer) + (put 'beginning-of-buffer :advertised-binding "b") (define-key map "d" 'Info-directory) (define-key map "e" 'Info-edit) (define-key map "f" 'Info-follow-reference) @@ -4089,7 +4096,7 @@ 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. -\(FILENAME NODENAME BUFFERPOS\), where BUFFERPOS is the line number +\(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 @@ -4674,7 +4681,7 @@ the variable `Info-file-list-for-emacs'." (eval-when-compile (require 'speedbar)) (defvar Info-speedbar-key-map nil - "Keymap used when in the info display mode.") + "Keymap used when in the Info display mode.") (defun Info-install-speedbar-variables () "Install those variables used by speedbar to enhance Info." @@ -4722,7 +4729,7 @@ This will add a speedbar major display mode." (speedbar-change-initial-expansion-list "Info") ) -(defun Info-speedbar-hierarchy-buttons (directory depth &optional node) +(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. DEPTH is the current indentation depth. @@ -4756,7 +4763,7 @@ specific node to expand." t) nil)))) -(defun Info-speedbar-goto-node (text node indent) +(defun Info-speedbar-goto-node (_text node _indent) "When user clicks on TEXT, go to an info NODE. The INDENT level is ignored." (speedbar-select-attached-frame) @@ -4835,7 +4842,7 @@ NODESPEC is a string of the form: (file)node." ;;; Info mode node listing ;; This is called by `speedbar-add-localized-speedbar-support' -(defun Info-speedbar-buttons (buffer) +(defun Info-speedbar-buttons (_buffer) "Create a speedbar display to help navigation in an Info file. BUFFER is the buffer speedbar is requesting buttons for." (if (save-excursion (goto-char (point-min)) @@ -4866,7 +4873,7 @@ BUFFER is the buffer speedbar is requesting buttons for." ;;;; Desktop support -(defun Info-desktop-buffer-misc-data (desktop-dirname) +(defun Info-desktop-buffer-misc-data (_desktop-dirname) "Auxiliary information to be saved in desktop file." (list Info-current-file Info-current-node @@ -4878,7 +4885,7 @@ BUFFER is the buffer speedbar is requesting buttons for." 'slow Info-current-file Info-current-node) (cons 'slow t)))))) -(defun Info-restore-desktop-buffer (desktop-buffer-file-name +(defun Info-restore-desktop-buffer (_desktop-buffer-file-name desktop-buffer-name desktop-buffer-misc) "Restore an Info buffer specified in a desktop file." @@ -4930,6 +4937,27 @@ type returned by `Info-bookmark-make-record', which see." (bookmark-default-handler `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bmk))))) + +;;;###autoload +(defun info-display-manual (manual) + "Go to Info buffer that displays MANUAL, creating it if none already exists." + (interactive "sManual name: ") + (let ((blist (buffer-list)) + (manual-re (concat "\\(/\\|\\`\\)" manual "\\(\\.\\|\\'\\)")) + (case-fold-search t) + found) + (dolist (buffer blist) + (with-current-buffer buffer + (when (and (eq major-mode 'Info-mode) + (stringp Info-current-file) + (string-match manual-re Info-current-file)) + (setq found buffer + blist nil)))) + (if found + (pop-to-buffer found) + (info-initialize) + (info (Info-find-file manual))))) + (provide 'info) ;;; info.el ends here