;;; info+.el --- Extensions to `info.el'. -*- coding:utf-8 -*- ;; ;; Filename: info+.el ;; Description: Extensions to `info.el'. ;; Author: Drew Adams ;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") ;; Copyright (C) 1996-2017, Drew Adams, all rights reserved. ;; Created: Tue Sep 12 16:30:11 1995 ;; Version: 0 ;; Package-Requires: () ;; Last-Updated: Fri Nov 17 10:02:09 2017 (-0800) ;; By: dradams ;; Update #: 6275 ;; URL: https://www.emacswiki.org/emacs/download/info%2b.el ;; Doc URL: https://www.emacswiki.org/emacs/InfoPlus ;; Keywords: help, docs, internal ;; Compatibility: GNU Emacs: 23.x, 24.x, 25.x ;; ;; Features that might be required by this library: ;; ;; `apropos', `apropos+', `avoid', `backquote', `bookmark', ;; `bookmark+', `bookmark+-1', `bookmark+-bmu', `bookmark+-key', ;; `bookmark+-lit', `button', `cl', `cmds-menu', `col-highlight', ;; `crosshairs', `fit-frame', `font-lock', `font-lock+', ;; `frame-fns', `help+', `help-fns', `help-fns+', `help-macro', ;; `help-macro+', `help-mode', `hl-line', `hl-line+', `info', ;; `info+', `kmacro', `menu-bar', `menu-bar+', `misc-cmds', ;; `misc-fns', `naked', `pp', `pp+', `second-sel', `strings', ;; `syntax', `thingatpt', `thingatpt+', `view', `vline', ;; `w32browser-dlgopen', `wid-edit', `wid-edit+'. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Commentary: ;; ;; Extensions to `info.el'. ;; ;; More description below. ;; ;; If you use Emacs 20, 21, or 22 then use library `info+20.el' ;; instead of `info+.el'. ;;(@> "Index") ;; ;; Index ;; ----- ;; ;; If you have library `linkd.el', load `linkd.el' and turn on ;; `linkd-mode' now. It lets you easily navigate around the sections ;; of this doc. Linkd mode will highlight this Index, as well as the ;; cross-references and section headings throughout this file. You ;; can get `linkd.el' here: ;; https://www.emacswiki.org/emacs/download/linkd.el. ;; ;; (@> "Things Defined Here") ;; (@> "Documentation") ;; (@> "Macros") ;; (@> "Faces (Customizable)") ;; (@> "User Options (Customizable)") ;; (@> "Internal Variables") ;; (@> "New Commands") ;; (@> "Replacements for Existing Functions") ;; (@> "Non-Interactive Functions") ;;(@* "Things Defined Here") ;; ;; Things Defined Here ;; ------------------- ;; ;; Commands defined here: ;; ;; `Info-breadcrumbs-in-mode-line-mode', ;; `Info-change-visited-status' (Emacs 24+), ;; `Info-describe-bookmark' (Emacs 24.2+), ;; `Info-follow-nearest-node-new-window', `Info-goto-node-web', ;; `Info-history-clear', `Info-make-node-unvisited', `info-manual', ;; `Info-merge-subnodes', ;; `Info-mouse-follow-nearest-node-new-window', ;; `Info-outline-demote', `Info-outline-promote', ;; `Info-persist-history-mode' (Emacs 24.4+), ;; `Info-save-current-node', `Info-set-breadcrumbs-depth', ;; `Info-set-face-for-bookmarked-xref' (Emacs 24.2+), ;; `Info-toggle-breadcrumbs-in-header', ;; `Info-toggle-fontify-angle-bracketed', ;; `Info-toggle-fontify-bookmarked-xrefs' (Emacs 24.2+), ;; `Info-toggle-fontify-emphasis', ;; `Info-toggle-fontify-quotations', ;; `Info-toggle-fontify-single-quote', ;; `Info-toggle-node-access-invokes-bookmark' (Emacs 24.4+), ;; `Info-toc-outline', `Info-toc-outline-refontify-region', ;; `Info-url-for-node', `Info-virtual-book'. ;; ;; Faces defined here: ;; ;; `info-command-ref-item', `info-constant-ref-item', ;; `info-double-quoted-name', `info-emphasis', `info-file', ;; `info-function-ref-item',`info-macro-ref-item', `info-menu', ;; `info-node', `info-quoted-name', `info-reference-item', ;; `info-single-quote', `info-special-form-ref-item', ;; `info-string', `info-syntax-class-item', ;; `info-user-option-ref-item', `info-variable-ref-item', ;; `info-xref-bookmarked' (Emacs 24.2+). ;; ;; Options (user variables) defined here: ;; ;; `Info-bookmarked-node-xref-faces' (Emacs 24.2+), ;; `Info-breadcrumbs-in-header-flag', ;; `Info-display-node-header-fn', `Info-emphasis-regexp', ;; `Info-fit-frame-flag', `Info-fontify-angle-bracketed-flag', ;; `Info-fontify-bookmarked-xrefs-flag' (Emacs 24.2+), ;; `Info-fontify-emphasis-flag', `Info-fontify-quotations-flag', ;; `Info-fontify-reference-items-flag', ;; `Info-fontify-single-quote-flag', ;; `Info-node-access-invokes-bookmark-flag' (Emacs 24.4+), ;; `Info-saved-history-file' (Emacs 24.4+), `Info-saved-nodes', ;; `Info-subtree-separator', `Info-toc-outline-no-redundancy-flag'. ;; ;; Macros defined here: ;; ;; `info-user-error'. ;; ;; Non-interactive functions defined here: ;; ;; `Info-bookmark-for-node', `Info-bookmark-name-at-point', ;; `Info-bookmark-named-at-point', `Info-bookmark-name-for-node', ;; `Info-display-node-default-header', `info-fontify-quotations', ;; `info-fontify-reference-items', ;; `Info-insert-breadcrumbs-in-mode-line', `Info-isearch-search-p', ;; `Info-node-name-at-point', `Info-read-bookmarked-node-name', ;; `Info-restore-history-list' (Emacs 24.4+), ;; `Info-save-history-list' (Emacs 24.4+), `Info-search-beg', ;; `Info-search-end', `Info-toc-outline-find-node', ;; `Info-toc-outline-refontify-links'. ;; ;; Internal variables defined here: ;; ;; `Info-breadcrumbs-depth-internal', `info-fontify-emphasis', ;; `Info-merged-map', `Info-mode-syntax-table', ;; `info-quotation-regexp', `info-quoted+<>-regexp', ;; `Info-toc-outline-map'. ;; ;; ;; ***** NOTE: The following standard faces defined in `info.el' ;; have been REDEFINED HERE: ;; ;; `info-title-1', `info-title-2', `info-title-3', `info-title-4'. ;; ;; ;; ***** NOTE: The following standard functions defined in `info.el' ;; have been REDEFINED or ADVISED HERE: ;; ;; `info-display-manual' - Use completion to input manual name. ;; `Info-find-emacs-command-nodes' - Added arg MSGP and message. ;; `Info-find-file' - Handle virtual books. ;; `Info-find-node', `Info-find-node-2' - ;; Call `fit-frame' if `Info-fit-frame-flag'. ;; Added optional arg NOMSG. ;; `Info-fontify-node' - ;; 1. Show breadcrumbs in header line and/or mode line. ;; 2. File name in face `info-file'. ;; 3. Node names in face `info-node'. ;; 4. Menu items in face `info-menu'. ;; 5. Only 5th and 9th menu items have their `*' colored. ;; 6. Notes in face `info-xref'. ;; 7. If `Info-fontify-emphasis-flag', then fontify _..._. ;; 8. If `Info-fontify-quotations-flag', then fontify ‘...’ or ;; `...' in face `info-quoted-name', “...” in face ;; `info-double-quoted-name', and "..." in face `info-string'. ;; 9. If `Info-fontify-angle-bracketed-flag' and ;; `Info-fontify-quotations-flag' then fontify <...> in face ;; `info-quoted-name'. ;; 10. If `Info-fontify-single-quote-flag' and ;; `Info-fontify-quotations-flag', then fontify ' in face ;; `info-single-quote'. ;; `Info-goto-emacs-command-node' - ;; 1. Uses `completing-read' in interactive spec, with, ;; as default, `symbol-nearest-point'. ;; 2. Added optional arg MSGP. ;; 3. Message if single node found. ;; 4. Returns `num-matches' if found; nil if not. ;; `Info-goto-emacs-key-command-node' - ;; 1. Added optional arg MSGP. ;; 2. If key's command not found, then `Info-search's for key ;; sequence in text and displays message about repeating. ;; `Info-goto-node' - Respect option ;; `Info-node-access-invokes-bookmark-flag' (Emacs 24.4+). ;; `Info-history' - A prefix arg clears the history. ;; `Info-insert-dir' - ;; Added optional arg NOMSG to inhibit showing progress msgs. ;; `Info-mode' - Doc string shows all bindings. ;; `Info-read-node-name' - Added optional arg DEFAULT. ;; `Info-search' - 1. Fits frame. ;; 2. Highlights found regexp if `search-highlight'. ;; `Info-set-mode-line' - Handles breadcrumbs in the mode line. ;; `Info-mouse-follow-nearest-node' - With prefix arg, show node in ;; a new Info buffer. ;; `Info-isearch-search' - Respect restriction to active region. ;; `Info-isearch-wrap' - Respect restriction to active region. ;; ;; ;; ***** NOTE: The following standard function ;; has been REDEFINED HERE: ;; ;; `outline-invisible-p' - Fixes Emacs bug #28080. ;;(@* "Documentation") ;; ;; Documentation ;; ------------- ;; ;; Library `info+.el' extends the standard Emacs library `info.el' in ;; several ways. It provides: ;; ;; * Association of additional information (metadata) with Info ;; nodes. You do this by bookmarking the nodes. Library Bookmark+ ;; gives you the following features in combination with `info+.el'. ;; In many ways an Info node and its default bookmark can be ;; thought of as the same animal. ;; ;; - Rich node metadata. In particular, you can tag nodes with any ;; number of arbitrary tags, to classify them in different and ;; overlapping ways. You can also annotate them (in Org mode, by ;; default). ;; ;; - You can use `C-h C-b' to show the metadata for a (bookmarked) ;; node. This is all of the associated bookmark information, ;; including the annotation and tags for that node and the number ;; of times you have visited it. If invoked with point on a ;; link, the targeted node is described; otherwise, you are ;; prompted for the node name. ;; ;; - Links for bookmarked nodes can have a different face, to let ;; you know that those nodes have associated metadata. Option ;; `Info-fontify-bookmarked-xrefs-flag' controls whether this is ;; done. ;; ;; - The face for this is `info-xref-bookmarked' by default, but ;; you can set the face to use for a given Info bookmark using ;; `C-x f' (command `Info-set-face-for-bookmarked-xref'). This ;; gives you an easy way to classify nodes and show the class of ;; a node by its links. Uses faces to make clear which nodes are ;; most important to you, or which are related to this or that ;; general topic. ;; ;; - If option `Info-node-access-invokes-bookmark-flag' is non-nil ;; then going to a bookmarked Info node invokes its bookmark, so ;; that the node metadata (such as number of visits) gets ;; updated. Command `Info-toggle-node-access-invokes-bookmark' ;; toggles the option value. ;; ;; - You can automatically bookmark nodes you visit, by enabling ;; mode `bmkp-info-auto-bookmark-mode'. Toggle the mode off ;; anytime you do not want to record Info visits. ;; ;; - In the bookmark-list display (from `C-x r l') you can sort ;; bookmarks by the time of last visit (`s d') or by the number ;; of visits (`s v'). This gives you an easy way to see which ;; parts of which Info manuals you have visited most recently and ;; how much you have visited them. ;; ;; * Editable, outline-enabled tables of contents (TOCs). Command ;; `Info-toc-outline' (bound to `O') opens a separate Info buffer ;; showing the table of contents (TOC). This is similar to the ;; standard command `Info-toc' (bound to `T'), but the buffer is ;; cloned from the manual and is in `outline-minor-mode'. Also, ;; there is no redundancy, by default: each TOC entry is listed ;; only once, not multiple times. (This is controlled by option ;; `Info-toc-outline-no-redundancy-flag'.) ;; ;; You can have any number of such TOCs, for the same manual or for ;; different manuals. ;; ;; Outline minor mode lets you hide and show, and promote and ;; demote, various parts of the TOC tree for a manual. And since ;; the TOC is editable you can make other changes to it: sort parts ;; of it, delete parts of it, duplicate parts of it, move parts ;; aroundin an ad hoc way, and so on. Info+ makes the outlining ;; commands behave, so that hidden Info text (e.g. markup text such ;; as `*note'...`::' surrounding links) is kept hidden. ;; ;; Especially when combined with `Info-persist-history-mode', ;; command `Info-change-visited-status' (`C-x DEL', see below), and ;; the Info+ bookmarking enhancements (e.g., special link ;; highlighting and persistently tracking the number of visits per ;; node), `Info-toc-outline' gives you a way to organize access and ;; visibility of a manual's nodes, to reflect how you use it. ;; ;; * Additional, finer-grained Info highlighting. This can make a ;; big difference in readability. ;; ;; - Quoted names, like this: `name-stands-out' or ;; `name-stands-out', and strings, like this: "string-stands-out" ;; are highlighted if `Info-fontify-quotations-flag' is ;; non-`nil'. ;; ;; - Angle-bracketed names, like this: , are highlighted if ;; `Info-fontify-angle-bracketed-flag' and ;; `Info-fontify-quotations-flag' are non-`nil'. ;; ;; - Isolated single quotes, like this: 'foobar, are highlighted if ;; `Info-fontify-single-quote-flag' and ;; `Info-fontify-quotations-flag' are non-`nil'. ;; ;; - Emphasized text, that is, text enclosed in underscore ;; characters, like this: _this is emphasized text_, is ;; highlighted if `Info-fontify-emphasis-flag' is non-`nil'. ;; (But if internal variable `info-fontify-emphasis' is `nil' ;; then there is no such highlighting, and that option has no ;; effect.) ;; ;; - In the Emacs Lisp manual, reference items are highlighted, so ;; they stand out. This means: constants, commands, functions, ;; macros, special forms, syntax classes, user options, and other ;; variables. ;; ;; Be aware that such highlighting is not 100% foolproof. ;; Especially for a manual such as Emacs or Elisp, where arbitrary ;; keys and characters can be present anywhere, the highlighting ;; can be thrown off. ;; ;; You can toggle each of the `Info-fontify-*-flag' options from ;; the `Info' menu or using an `Info-toggle-fontify-*' command. ;; For example, command `Info-toggle-fontify-emphasis' toggles ;; option `Info-fontify-emphasis-flag'. ;; ;; * You can show breadcrumbs in the mode line or the header line, or ;; both. See where you are in the Info hierarchy, and access higher ;; nodes directly. ;; ;; - In the mode line. Turned on by default. ;; ;; See ‘Toggle Breadcrumbs’ in the `mouse-3' mode-line menu and ;; `Toggle Breadcrumbs in Mode Line' in the `Info' menu (in the ;; menu-bar or in the minor-mode indicator). You can customize ;; option `Info-breadcrumbs-in-mode-line-mode' if you want to ;; turn this off by default. (Available for Emacs 23+ only.) ;; ;; - In the header (just below the header line). ;; ;; (I also added this to vanilla Emacs 23.) This is OFF by ;; default in `Info+'. See `Toggle Breadcrumbs in Header Line' ;; in `Info' menu. Be aware that unlike breadcrumbs in the mode ;; line, this can occasionally throw off the destination accuracy ;; of cross references and searches slightly. ;; ;; * Some of the commands defined here: ;; ;; - `Info-virtual-book' (bound to `v') – Open a virtual Info ;; manual of saved nodes from any number of manuals. The nodes ;; are those saved in option `Info-virtual-book'. With `C-u', ;; bookmarked Info nodes are also included. (If you use Icicles, ;; see also `icicle-Info-virtual-book'.) ;; ;; - `Info-persist-history-mode' - Enabling this minor mode saves ;; the list of your visited Info nodes between Emacs sessions. ;; Together with command `Info-history' (bound to `L' by ;; default), this gives you a persistent virtual manual of the ;; nodes you have visited in the past. If the mode is enabled ;; then the list of visited nodes is saved to the file named by ;; option `Info-saved-history-file' when you quit Emacs (not ;; Info) or when you kill an Info buffer. ;; ;; (If you also use library Bookmark+ then you can bookmark Info ;; nodes, including automatically. This records how many times ;; you have visited each node and when you last did so.) ;; ;; - `Info-change-visited-status' (bound to `C-x DEL') - Toggle or ;; set the visited status of the node at point or the nodes in ;; the active region. Useful if you use ;; `Info-fontify-visited-nodes' to show you which nodes you have ;; visited. No prefix arg: toggle. Non-negative prefix arg: set ;; to visited. Negative prefix arg: set to unvisited. ;; ;; - `Info-save-current-node' (bound to `.') – Save the name of the ;; current node to list `Info-saved-nodes', for use by `v' ;; (`Info-virtual-book'). ;; ;; - `Info-merge-subnodes' – Integrate the current Info node with ;; its subnodes (the nodes in its Menu), perhaps recursively. ;; ;; Use `Info-merge-subnodes' to extract a self-contained report ;; (possibly the whole manual) from an Info manual. The report ;; is itself an Info buffer, with hyperlinks and normal Info ;; behavior. ;; ;; There are various prefix-argument possibilities that govern ;; just how subnodes are treated (recursively or not, for ;; instance). There are a few user options that let you ;; customize the report appearance. ;; ;; ;; The following bindings are made here for Info-mode: ;; ;; `?' `describe-mode' (replaces `Info-summary') ;; `+' `Info-merge-subnodes' ;; `.' `Info-save-current-node' ;; `a' `info-apropos' ;; `G' `Info-goto-node-web' ;; `O' `Info-toc-outline' ;; `v' `Info-virtual-book' ;; `mouse-4' `Info-history-back' ;; `mouse-5' `Info-history-forward' ;; `S-down-mouse-2' `Info-mouse-follow-nearest-node-new-window' ;; `S-RET' `Info-follow-nearest-node-new-window' ;; ;; The following bindings are made here for merged Info buffers: ;; ;; `.' `beginning-of-buffer' ;; `b' `beginning-of-buffer' ;; `q' `quit-window' ;; `s' `nonincremental-re-search-forward' ;; `M-s' `nonincremental-re-search-forward' ;; `TAB' `Info-next-reference' ;; `ESC TAB' `Info-prev-reference' ;; ;; The global binding `C-h r' is changed from `info-emacs-manual' to ;; `info-manual', which behaves the same except if you use a prefix ;; arg. With a prefix arg you can open any manual, choosing either ;; from all installed manuals or from those that are already shown in ;; Info buffers. ;; ;; The following behavior defined in `info.el' has been changed: ;; "*info" has been removed from `same-window-buffer-names', so that ;; a separate window can be used if you so choose. ;; ;; Suggestion: Use a medium-dark background for Info. Try, for ;; example, setting the background to "LightSteelBlue" in your ;; `~/.emacs' file. You can do this as follows: ;; ;; (setq special-display-buffer-names ;; (cons '("*info*" (background-color . "LightSteelBlue")) ;; special-display-buffer-names)) ;; ;; Alternatively, you can change the background value of ;; `special-display-frame-alist' and set `special-display-regexps' to ;; something matching "*info*": ;; ;; (setq special-display-frame-alist ;; (cons '(background-color . "LightSteelBlue") ;; special-display-frame-alist)) ;; (setq special-display-regexps '("[ ]?[*][^*]+[*]")) ;; ;; If you do use a medium-dark background for Info, consider ;; customizing face to a lighter foreground color - I use "Yellow". ;; ;; Also, consider customizing face `link' to remove its underline ;; attribute. ;; ;; This file should be loaded after loading the standard GNU file ;; `info.el'. So, in your `~/.emacs' file, do this: ;; (eval-after-load "info" '(require 'info+)) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Change Log: ;; ;; 2017/11/17 dadams ;; Info-TOC-outline stuff needs Info-virtual-nodes. Thx to Mike Fitzgerald. ;; http -> https everywhere. ;; 2017/11/09 dadams ;; info-quotation-regexp, info-quoted+<>-regexp: Added \\ to first alternative of each ... type, to exclude \ from it. ;; 2017/09/23 dadams ;; Info-url-for-node: Fix per TeXInfo manual - encode embedded hyphens etc. ;; 2017/08/30 dadams ;; Renamed: Info-refontify-toc-outline-region to Info-toc-outline-refontify-region. ;; 2017/08/28 dadams ;; Added: Info-refontify-toc-outline-region. ;; Info-refontify-toc-outline-region: Add Info-refontify-toc-outline-region to post-command-hook and bind to C-x M-l. ;; Info-toc-outline: Turn off Info-breadcrumbs-in-mode-line-mode in TOC buffer. ;; Info-change-visited-status: Typo: go-to-char. ;; 2017/08/25 dadams ;; Added: Info-change-visited-status. Bound to `C-x DEL (instead of Info-make-node-unvisited). ;; Info-node-name-at-point: Replace newline chars by spaces. ;; Info-toc-outline: Pass NEWNAME arg to clone-buffer, instead of explicitly renaming buffer. ;; 2017/08/22 dadams ;; Added: Info-toc-outline, Info-outline-demote, Info-outline-promote, Info-toc-outline-no-redundancy-flag, ;; Info-toc-outline-find-node, Info-toc-outline-map, Info-toc-outline-refontify-links, redefinition of ;; outline-invisible-p. ;; Bind Info-toc-outline to O. ;; Info-mode-menu: Added Editable Outline TOC item for Info-toc-outline. ;; Info-node-access-invokes-bookmark-flag, Info-toggle-node-access-invokes-bookmark, Info-goto-node advice: ;; Reserve for Emacs 24.4+. ;; 2017/08/10 dadams ;; Info-goto-node: Define it for Emacs 23 also. ;; Info-mode-menu: Add menu items for Info-toggle-node-access-invokes-bookmark, Info-toggle-fontify-bookmarked-xrefs. ;; 2017/08/07 dadams ;; Added: Info-make-node-unvisited. Bound to C-x DEL. ;; 2017/08/06 dadams ;; Added: Info-bookmarked-node-xref-faces, Info-read-bookmarked-node-name, ;; Info-set-face-for-bookmarked-xref. ;; Bind Info-set-face-for-bookmarked-xref to C-x f. ;; Info-describe-bookmark: If no bookmarked node name at point, use Info-read-bookmarked-node-name. ;; Info-bookmark-for-node: Made NODE arg optional - if nil then read the node name. Added LOCALP arg. ;; Info-fontify-node (Emacs 24.2+): Get face for bookmarked xref from bmkp-info-face tag value, if any. ;; Call Info-bookmark-for-node with arg LOCALP. ;; 2017/08/04 dadams ;; Info-describe-bookmark: Use Info-bookmark-name-at-point, not Info-node-name-at-point. ;; Info-goto-node: Do it only for Emacs 24.2+. ;; 2017/08/02 dadams ;; Info-goto-node: Define only if can soft-require bookmark+.el. ;; No-op if NODE is in Info-index-nodes. ;; Bind Info-node-access-invokes-bookmark-flag to nil while invoking bookmark. ;; Use bookmark--jump-via with ignore as display function, instead of bookmark-jump. ;; 2017/07/30 dadams ;; Added advice of Info-goto-node, to respect Info-node-access-invokes-bookmark-flag. ;; Removed redefinitions of Info-follow-nearest-node, Info-try-follow-nearest-node. ;; Replaced Info-follow-xref-bookmarks-flag by Info-node-access-invokes-bookmark-flag. ;; Replaced Info-toggle-follow-bookmarked-xrefs by Info-toggle-node-access-invokes-bookmark. ;; Info-bookmark-for-node, Info-bookmark-named-at-point: Include manual name in bookmark name. ;; 2017/07/29 dadams ;; Added: Info-fontify-bookmarked-xrefs-flag, face info-xref-bookmarked, Info-describe-bookmark, ;; Info-bookmark-for-node, Info-bookmark-name-at-point, Info-bookmark-named-at-point, ;; Info-bookmark-name-for-node, Info-toggle-fontify-bookmarked-xrefs, ;; Info-follow-xref-bookmarks-flag, Info-toggle-follow-bookmarked-xrefs. ;; Added (redefinition of): Info-follow-nearest-node, Info-try-follow-nearest-node. ;; Info-fontify-node (24.2+): Respect Info-fontify-bookmarked-xrefs-flag. ;; Bind Info-describe-bookmark to C-h C-b. ;; 2017/02/20 dadams ;; Added: Info-saved-history-file, Info-persist-history-mode, Info-save-history-list, ;; Info-restore-history-list. ;; Added autoload cookies: Info-breadcrumbs-in-mode-line-mode, Info-set-breadcrumbs-depth, ;; Info-search, Info-mouse-follow-nearest-node, info-display-manual. ;; 2017/01/09 dadams ;; Info-find-emacs-command-nodes: Updated for handle LINE-NUMBER (Emacs 24.5+). ;; 2016/12/13 dadams ;; Removed obsolete face aliases: info-menu-5, Info-title-*-face. ;; 2016/12/11 dadams ;; Added defvars for isearch(-regexp)-lax-whitespace for Emacs 24.1 and 24.2. ;; 2016/12/10 dadams ;; Use string as 3rd arg to make-obsolete. ;; 2016/10/31 dadams ;; info-quotation-regexp: Typo: misplaced curly double-quote. Thx to Don March. ;; 2016/07/02 dadams ;; Added: Info-toggle-fontify-emphasis, Info-breadcrumbs-in-header-flag, Info-emphasis-regexp, ;; Info-fontify-emphasis-flag, info-fontify-emphasis, and face info-emphasis. ;; Added some doc from Emacs Wiki to commentary. ;; Info-mode-menu: ;; Add toggle indicators. Moved toggle commands to Toggle submenu. Added Info-toggle-fontify-emphasis. ;; Info-fontify-node: Fontify emphasis. ;; 2015/09/14 dadams ;; info-double-quoted-name: Changed default colors. ;; 2015/09/13 dadams ;; Added face info-double-quoted-name. ;; info-quotation-regexp, info-quoted+<>-regexp: Added pattern for curly double-quotes (“...”). ;; Use shy groups for all parts. ;; info-fontify-quotations: Fontify text between curly double-quotes (“...”). ;; 2015/03/19 dadams ;; info-quoted+<>-regexp: Highlight <...> only if the first char is alphabetic. ;; 2015/03/06 dadams ;; Added: info-manual. Bound it globally to C-h r. ;; Info-fontify-node (Emacs 24.1.N+): Updated per Emacs 24.4: allow Info-fontify-maximum-menu-size to be t. ;; info-display-manual: Updated for Emacs 25: use info--manual-names with prefix arg. ;; 2015/02/28 dadams ;; Added: redefinition of Info-read-node-name. ;; Info-goto-node-web, Info-url-for-node: Use Info-current-node as default. ;; 2014/12/21 dadams ;; Added: Info-goto-node-web, Info-url-for-node. ;; Reorganized. Code cleanup. Improved commentary. Added index links. ;; Info-toggle-breadcrumbs-in-header-line: Added 3rd arg to make-obsolete. ;; Info-breadcrumbs-in-mode-line-mode: (default-value 'mode-line-format), not default-mode-line-format, ;; Info-display-node-default-header: (goto-char (point-min)), not (beginning-of-buffer). ;; Info-merge-subnodes: with-current-buffer, not save-excursion + set-buffer. ;; 2014/05/04 dadams ;; REMOVED SUPPORT for Emacs 20-22. That support is offered by a new library now: info+20.el. ;; Added coding:utf-8 declaration. Replace \x2018, \x2019 with literal ‘ and ’, since now Emacs 23+. ;; 2014/05/03 dadams ;; info-quotation-regexp, info-quoted+<>-regexp: Handle also curly single quotes (Emacs 24.4+). ;; Removed double * and moved openers outside \(...\) group. ;; info-fontify-quotations: Handle also curly single quotes (Emacs 24.4+). ;; 2014/03/04 dadams ;; Renamed Info-toggle-breadcrumbs-in-header-line to Info-toggle-breadcrumbs-in-header. ;; Declared old name obsolete. ;; 2014/03/02 dadams ;; Info-find-file: Go to directory if no previous file (per Emacs 24.4+). ;; Info-find-node-2 (Emacs > 22): Go to Top node at end, if no history. ;; 2013/10/17 dadams ;; Added: Info-search-beg, Info-search-end, Info-isearch-search-p. ;; Added redefinition: Info-isearch-wrap, Info-isearch-search. ;; Info-display-node-default-header, Info-merge-subnodes: Renamed node-name to infop-node-name. ;; 2013/03/17 dadams ;; Added: Info-history-clear, macro info-user-error (and font-lock it). Advised: Info-history. ;; Use info-user-error instead of error, where appropriate. ;; 2013/02/26 dadams ;; Info-mode-menu and Info-mode doc string: Removed Info-edit, Info-enable-edit (now obsolete). ;; 2013/02/09 dadams ;; Info-read-node-name-1: Removed Emacs 23+ redefinition. ;; 2013/02/03 dadams ;; Added: Info-fontify-angle-bracketed-flag, Info-toggle-fontify-angle-bracketed, ;; Info-toggle-fontify-quotations, Info-toggle-fontify-single-quote, info-quoted+<>-regexp. ;; info-fontify-quotations: Fixed case for Info-toggle-fontify-single-quote = nil. ;; Handle also Info-fontify-angle-bracketed-flag. ;; Added Info-fontify-*-flag to Info menu (so menu bar and C-mouse-3). ;; 2012/09/24 dadams ;; Info-search. Info-mode: Applied latest Emacs 24 updates by Juri (from 2012-09-12). ;; 2012/08/25 dadams ;; Info-fontify-node: Hide any empty lines at end of node (fixes bug #12272). ;; 2012/08/24 dadams ;; info-fontify-reference-items: Fontify parameters on continuation lines also. ;; Info-fontify-node: Juri's fix for Emacs bug #12187. ;; Reverted Juri's change from 08/20, since Juri fixed it elsewhere afterward. ;; 2012/08/21 dadams ;; Call tap-put-thing-at-point-props after load thingatpt+.el. ;; 2012/08/20 dadams ;; Applied Juri's fix for Emacs bug #12230: ;; Added: Info-file-attributes. ;; Info-find-file: Clear caches of modified Info files. ;; 2012/08/18 dadams ;; Invoke tap-define-aliases-wo-prefix if thingatpt+.el is loaded. ;; 2012/08/12 dadams ;; Added: info-constant-ref-item (face). ;; info-fontify-reference-items: Handle constants, using face info-constant-ref-item. ;; Info-toggle-breadcrumbs-in-header-line, Info-save-current-node: Added MSGP arg. ;; 2012/08/10 dadams ;; Info-search: Use latest Emacs 24 msg: _end of node_, not _initial node_. ;; 2012/08/09 dadams ;; Info-fontify-node: Updated guards for Emacs 24 versions. ;; 2012/07/28 dadams ;; Info-fontify-node: Typo on guard: (/= 1 emacs-minor-version) should have been =, not /=. ;; 2012/07/17 dadams ;; Added redefinition of Info-fontify-node for post-Emacs 24.1. ;; Added redefinitions of Info-insert-dir, Info(-directory)-find-node, with args controlling msgs. ;; info-find-node-2: Added optional arg NOMSG. ;; Info-find-emacs-command-nodes, Info-goto-emacs(-key)-command-node: Added optional arg MSGP. ;; Info-search, Info-save-current-node: Show messages only if interactive-p. ;; 2012/01/15 dadams ;; Added: info-display-manual (redefinition). ;; Info-find-file: Do not define for < Emacs 23.2 - no virtual books. ;; 2011/11/15 dadams ;; Added: redefinition of Info-find-file for Emacs 23+, to handle virtual books. ;; 2011/08/23 dadams ;; Removed hard-code removal of info from same-window-(regexps|buffer-names). Thx to PasJa. ;; 2011/02/06 dadams ;; info-user-option-ref-item: Corrected background for light-bg case. ;; 2011/02/03 dadams ;; All deffaces: Provided default values for dark-background screens too. ;; 2011/01/04 dadams ;; Removed autoload cookies from non def* sexps. Added for defgroup and defface. ;; 2010/05/27 dadams ;; Added: Info-set-mode-line. ;; Info-find-node-2: ;; Added redefinition of it for Emacs 23.2 (they keep twiddling it). ;; Do not call Info-insert-breadcrumbs-in-mode-line. Do that in Info-set-mode-line now. ;; 2010/04/06 dadams ;; Added: Info-breadcrumbs-in-header-flag, Info-toggle-breadcrumbs-in-header-line, ;; Info-breadcrumbs-in-mode-line-mode, Info-set-breadcrumbs-depth, ;; Info-insert-breadcrumbs-in-mode-line, Info-breadcrumbs-depth-internal. ;; Added to Info-mode-menu (Emacs 23+): Info-breadcrumbs-in-mode-line-mode. ;; Info-find-node-2 (Emacs 23+): Add breadcrumbs to header line & mode line only according to vars. ;; Info-fontify-node (Emacs 23+): Handle breadcrumbs in header only if flag says to. ;; 2010/01/12 dadams ;; Info-find-node for Emacs 20, Info-find-node-2 for Emacs 21, 22, Info-search: ;; save-excursion + set-buffer -> with-current-buffer. ;; 2010/01/10 dadams ;; Info-find-node-2 for Emacs 23+: Updated for Emacs 23.2 (pretest) - virtual function stuff. ;; 2009/12/13 dadams ;; Typo: Incorrectly used Emacs 22 version for Emacs 21 also. ;; 2009/12/11 dadams ;; info-fontify-(node|quotations|reference-items), Info-merge-subnodes: ;; Use font-lock-face property, not face, if > Emacs 21. ;; 2009/08/03 dadams ;; Updated for Emacs 23.1 release: Info-find-node-2, Info-fontify-node, Info-search: new version. ;; 2009/06/10 dadams ;; Added: Info-fontify-reference-items-flag, Info-mode-syntax-table. ;; Info-mode: Use Info-mode-syntax-table, not text-mode-syntax-table. ;; Info-fontify-node: Fontify ref items if *-reference-items-flag, not just for Elisp manual. ;; Renamed: info-elisp-* to info-*. ;; 2009/06/09 dadams ;; info-fontify-quotations: Allow \ before ', just not before`. ;; 2009/06/08 dadams ;; info-fontify-quotations: Rewrote, using better regexp. Don't fontify escaped ` or '. ;; Fontify `\', `\\', etc. Respect Info-fontify-single-quote-flag. ;; Added: info-single-quote, Info-fontify-single-quote-flag, info-quotation-regexp. ;; info-quoted-name: Changed face spec to (:inherit font-lock-string-face :foreground "DarkViolet") ;; 2009/05/25 dadams ;; Info-virtual-book: Treat info-node bookmarks too. ;; 2009/05/23 dadams ;; Added: Info-mode for Emacs 23. ;; They added Info-isearch-filter, Info-revert-buffer-function, Info-bookmark-make-record. ;; 2009/05/22 dadams ;; Added: Info-saved-nodes, Info-save-current-node, Info-virtual-book. Added to Info-mode-menu. ;; Bind info-apropos, Info-save-current-node, Info-virtual-book to a, ., and v. ;; Info-mode: Updated doc string. ;; 2009/04/26 dadams ;; Info-merge-subnodes: Bind inhibit-field-text-motion to t, for end-of-line. ;; 2008/10/07 dadams ;; Require cl.el at compile time for all Emacs versions, because of case. ;; 2008/10/05 dadams ;; Added: Info-read-node-name-1, Info-read-node-name-2. ;; 2008-07-11 dadams ;; Info-fontify-node (Emacs 22+): Protect histories when getting ancestor nodes for breadcrumbs. ;; (Emacs 22+) Don't change faces info-menu-header, *-title-*, *(-header)-node, header-line. ;; (Emacs 20, 21): Removed bold and italic attributes from info-node and info-xref. ;; Removed commented out defface for info-xref and info-node. ;; Face info-file: Blue, not DarkBlue, foreground, by default. ;; 2008/06/12 dadams ;; Info-fontify-node (Emacs 22+): ;; Prevent infinite recursion from Info-goto-node calling Info-fontify-node. ;; Fixed for nil Info-hide-note-references. ;; 2008/06/10 dadams ;; Info-fontify-node (Emacs 22+): Added breadcrumbs. ;; 2008/03/06 dadams ;; info-mode: Use fboundp for Info-clone-buffer, not version test, for Emacs 22+. Thx to Sebastien Vauban. ;; 2008/02/01 dadams ;; Info-mode: Renamed Info-clone-buffer-hook to Info-clone-buffer for Emacs 22.1.90. ;; 2008/01/08 dadams ;; Info-search (Emacs 22): Removed phony pred arg. ;; 2008/01/06 dadams ;; Removed soft require of Icicles due to cirular dependency. Thx to Tennis Smith. ;; 2007/11/27 dadams ;; Info-search: Use icicle-read-string-completing, if available. ;; Added soft require Icicles. ;; 2007/11/20 dadams ;; Info-subtree-separator: Escaped slashes in doc string: \f -> \\f. ;; 2007/09/26 dadams ;; Better default color for info-quoted-name. Added group face to all deffaces. ;; 2007/09/25 dadams ;; Bound Info-mouse-*-new-* to S-down-mouse-2, not S-mouse-2, because of mouse-scan-lines-or-M-:. ;; Info-goto-emacs-command-node: Convert completion default value to string. ;; 2007/08/27 dadams ;; Info-fontify-node: Ensure Info-fontify-node is a string when fontifiy quotations. Updated for Emacs 22. ;; 2007/07/13 dadams ;; Info-find-node: Redefine only for Emacs < 21. ;; 2006/09/15 dadams ;; Info-mouse-follow-nearest-node redefinition is only for Emacs >= 22. ;; Changed Emacs 22 tests to just (>= emacs-major-version 22). ;; Bind tool-bar-map for Emacs 21. Otherwise, binding of [tool-bar] gives an error (why?). ;; 2006/08/18 dadams ;; Everywhere: Corrected previous change: minibuffer-selected-window to window-minibuffer-p. ;; 2006/08/14 dadams ;; Everywhere: fit-frame only if not a minibuffer window. ;; 2006/08/12 dadams ;; Info-merge-subnodes: Bug fixes: ;; Added concat for insertion of main node when recursive-display-p is negative. ;; Don't recurse down Index menus. ;; When checking for subnodes menu, check for nonfile menu item also. ;; After come back from recursion, go back to Info buffer before trying to go back in history. ;; Call fit-frame at end. ;; 2006/06/10 dadams ;; Added: Info(-mouse)-follow-nearest-node-new-window. Bound to S-RET, S-mouse-2. ;; 2006/03/31 dadams ;; info-menu-header: Removed :underline, because links are underlined in Emacs 22. ;; No longer use display-in-minibuffer. ;; 2006/01/08 dadams ;; Added: redefinition of Info-mouse-follow-nearest-node. ;; 2006/01/07 dadams ;; Added :link for sending bug report. ;; 2006/01/06 dadams ;; Added defgroup Info-Plus and used it. Added :link. ;; 2005/12/30 dadams ;; Moved everything from setup-info.el to here, after getting rid of some of it. ;; Use defface for all faces. Renamed faces, without "-face". ;; Use minibuffer-prompt face, not info-msg-face. ;; No longer require setup-info.el. No longer require cl.el when compile. ;; 2005/11/21 dadams ;; Info-search for Emacs 22: Don't display repeat `s' message if isearch-mode. ;; 2005/11/09 dadams ;; Info-fontify-node: Updated to reflect latest CVS (replaced Info-escape-percent header). ;; 2005/10/31 dadams ;; Use nil as init-value arg in calls to completing-read, everywhere. ;; 2005/07/04 dadams ;; info-fontify-quotations: Use font-lock-face property, instead of face, for Emacs 22. ;; Wrap re-search-forward in condition-case for stack overflow. ;; 2005/07/02 dadams ;; Info-search: fit-frame. Added Emacs 22 version too. ;; Info-goto-emacs-command-node, Info-goto-emacs-key-command-node, Info-merge-subnodes: ;; Use Info-history-back for Emacs 22. ;; Info-mode: Added Emacs 22 version. ;; 2005/06/23 dadams ;; Info-fontify-node: Fontify reference items if in Emacs-Lisp manual. ;; Added: info-fontify-reference-items ;; 2005/05/17 dadams ;; Updated to work with Emacs 22.x. ;; 2004/11/20 dadams ;; Info-find-emacs-command-nodes: bug fix: regexp (cmd-desc) was only for Emacs 21. ;; Refined to deal with Emacs 21 < 21.3.50 (soon to be 22.x) ;; 2004/10/09 dadams ;; info-fontify-quotations: ;; 1) Allow all characters inside `...'. ;; 2) Treat case of "..." preceded by backslashes ;; Info-fontify-node (for Emacs 21): Moved info-fontify-quotations before fontification of titles. ;; 2004/10/07 dadams ;; Renamed Info-resize-frame-p to Info-fit-frame-flag. ;; 2004/10/05 dadams ;; Improved regexp treatment further for fontifying quotations. ;; 2004/10/04 dadams ;; Improved regexp treatment for fontifying quotations. ;; Added info-fontify-quotations. Removed info-fontify-strings-p. ;; Renamed Info-fontify-quotations-p to Info-fontify-quotations-flag. ;; 2004/10/03/dadams ;; Major update: updated to work with Emacs 21 also. ;; Made require of setup-info.el mandatory. ;; Removed all variables and keys to setup-info.el. ;; Renamed to Emacs 21 names and only define for Emacs < 21: emacs-info -> info-emacs-manual. ;; 2004/09/28 dadams ;; Removed dir-info (same as Info-directory). ;; Renamed to Emacs 21 names and only define for Emacs < 21: emacs-lisp-info -> menu-bar-read-lispref ;; 2004/06/01 dadams ;; Renamed: Info-fit-frame-p to Info-resize-frame-p, shrink-frame-to-fit to resize-frame. ;; 2000/09/27 dadams ;; 1. Added: Info-fit-frame-p. ;; 2. Info-find-node: added shrink-frame-to-fit. ;; 1999/04/14 dadams ;; Info-fontify-node: Fontify indexes too. ;; 1999/04/14 dadams ;; 1. Added vars: info-file-face, info-menu-face, info-node-face, info-quoted-name-face, info-string-face, ;; info-xref-face. ;; 2. No longer use (or define) faces: info-node, info-file, info-xref, info-menu-5, info-quoted-name, ;; info-string. ;; 3. Info-fontify-node: Use new face variables instead of faces in #2, above. ;; Corrected: node names in info-node-face (was xref). Use info-menu-face for * and menu item. ;; 4. Info-mode: Redefined like original, but: no make-face's; use face vars. ;; Added user options description to doc string. ;; 1999/04/08 dadams ;; Info-goto-emacs-key-command-node: regexp-quote pp-key for Info-search. ;; 1999/04/07 dadams ;; Info-goto-emacs-key-command-node: a) msgs only if interactive, b) return nil if not found, else non-nil, ;; c) "is undefined" -> "doc not found", d) use display-in-minibuffer more, e) corrected error handler. ;; 1999/04/01 dadams ;; 1. Added: (remove-hook 'same-window-buffer-names "*info*"). ;; 2. Info-find-node: switch-to-buffer-other-window -> pop-to-buffer. ;; 1999/03/31 dadams ;; 1. Added (put 'Info-goto-emacs-(key-)command-node 'info-file "emacs"). ;; 2. Info-find-node: Mention searched file in error messages. ;; 3. Added (replacement): Info-find-emacs-command-nodes, with progress msg. ;; 4. a. Info-goto-emacs-key-command-node: Use global-map, unless menu item. ;; b. Added message "Not found using Index ...". ;; 1999/03/31 dadams ;; 1. Info-goto-emacs(-key)-command-node: Only display-in-minibuffer if ;; interactive-p. ;; 2. Info-goto-emacs-key-command-node: Messages: "key"; other entries. ;; 1999/03/31 dadams ;; 1. Added (put 'info 'info-file "emacs") so find doc on `info' cmd. ;; 2. Info-goto-emacs-command-node: ;; a. Added message when =< 1 match. ;; b. Return num-matches if found. ;; c. Uses `display-in-minibuffer' instead of `message'. ;; 3. a. Wrapped call to Info-search in condition-case, not if. ;; b. Info-goto-emacs-key-command-node: Return num-matches if found. ;; 1999/03/30 dadams ;; 1. Added Info menu bar menu. ;; 2. Info-goto-emacs-command-node: Only error if interactive-p. ;; 3. Info-goto-emacs-key-command-node: ;; a. Print key in msgs ;; b. If Info-goto-emacs-command-node doesn't find it, then try Info-search. ;; If found & interactive-p, then msg ("repeat"). Else error. ;; 4. Info-search: Msg ("repeat") if found & interactive-p. ;; 1999/03/17 dadams ;; 1. Updated to correspond with Emacs 34.1 version. ;; 2. Protect with fboundp. ;; 1996/07/11 dadams ;; Added redefinitions of Info-goto-emacs-(key-)command-node. ;; 1996/04/26 dadams ;; Put escaped newlines on long-line strings. ;; 1996/04/16 dadams ;; Added: info-file, info-quoted-name, info-string, Info-fontify-quotations-flag, info-fontify-strings-p. ;; Take into account in Info-fontify-node. ;; 1996/02/23 dadams ;; 1. Changed binding of Info-merge-subnodes back to `r', but now requires user confirmation when invoked. ;; 2. Info-subtree-separator: Incorporates "\n* ". variable-interactive prop. ;; 1996/02/22 dadams ;; display-Info-node-subtree: ;; 1. display-Info-node-subtree -> Info-merge-subnodes (renamed). ;; 2. Changed binding of Info-merge-subnodes from `r' to `C-d'. ;; 3. Don't pick up text between menu-item-line and "\n* ". Hardwire "\n* ". ;; 4. Untabify menu-item-line, so can count chars to underline. ;; 5. indent-rigidly, not indent-region. ;; 1996/02/22 dadams ;; 1. Bind describe-mode and display-Info-node-subtree. ;; 2. Added redefinition of Info-mode: Only the doc string was changed. ;; 3. Added Info-subtree-separator. ;; 3. display-Info-node-subtree: Info-subtree-separator. Doc. Garbage-collect. ;; 1996/02/22 dadams ;; Info-merge-subnodes: Rewrote, adding optional args. Renamed (defaliased) to display-Info-node-subtree. ;; 1996/02/22 dadams ;; Added redefinition of Info-merge-subnodes (cleanup, corrections). ;; 1996/02/20 dadams ;; 1. Make info-node, info-xref, info-menu-5 here. (Diff faces than before.) ;; 2. Added redefinition of Info-find-node. (Uses other window.) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth ;; Floor, Boston, MA 02110-1301, USA. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: (require 'info) (eval-when-compile (require 'cl)) ;; case ;; These are optional, for cosmetic purposes. (require 'thingatpt nil t) ;; (no error if not found): symbol-at-point (when (and (require 'thingatpt+ nil t) ;; (no error if not found): symbol-nearest-point (fboundp 'tap-put-thing-at-point-props)) ; >= 2012-08-21 (tap-define-aliases-wo-prefix) (tap-put-thing-at-point-props)) (require 'strings nil t) ;; (no error if not found): concat-w-faces (require 'fit-frame nil t) ;; (no error if not found): fit-frame ;; Took this out because it leads to a circular `require' dependency. ;; (require 'icicles nil t) ;; (no error if not found): icicle-read-string-completing ;; Quiet the byte compiler a bit. ;; (defvar browse-url-new-window-flag) ; In `browse-url.el' (defvar desktop-save-buffer) (defvar header-line-format) (defvar Info-breadcrumbs-depth) (defvar Info-breadcrumbs-depth-internal) (defvar Info-breadcrumbs-in-header-flag) (defvar Info-breadcrumbs-in-mode-line-mode) (defvar Info-current-node-virtual) (defvar isearch-filter-predicate) (defvar Info-bookmarked-node-xref-faces) ; Here, Emacs 24.2+, with Bookmark+. (defvar Info-fontify-bookmarked-xrefs-flag) ; Here, Emacs 24.2+, with Bookmark+. (defvar Info-fontify-visited-nodes) (defvar Info-hide-note-references) (defvar Info-history-list) (defvar Info-isearch-initial-node) (defvar Info-isearch-search) (defvar Info-last-search) (defvar Info-link-keymap) (defvar Info-menu-entry-name-re) (defvar Info-next-link-keymap) (defvar Info-mode-line-node-keymap) (defvar Info-node-spec-re) (defvar Info-persist-history-mode) (defvar Info-point-loc) (defvar Info-prev-link-keymap) (defvar Info-read-node-completion-table) (defvar Info-refill-paragraphs) (defvar Info-saved-history-file) (defvar Info-saved-nodes) (defvar Info-search-case-fold) (defvar Info-search-history) (defvar Info-search-whitespace-regexp) (defvar info-tool-bar-map) (defvar Info-up-link-keymap) (defvar Info-use-header-line) (defvar isearch-lax-whitespace) ; In `isearch.el'. (defvar isearch-regexp-lax-whitespace) ; In `isearch.el'. (defvar infop-node-name) ; Here, in `Info-merge-subnodes'. (defvar outline-heading-alist) ; In `outline.el'. (defvar widen-automatically) ;;;;;;;;;;;;;;;;;;;; (provide 'info+) (require 'info+) ;; Ensure loaded before compiling. ;;;;;;;;;;;;;;;;;;;; ;;(@* "Macros") ;;; Macros ----------------------------------------------------------- (defmacro info-user-error (&rest args) "`user-error' if defined, otherwise `error'." `(if (fboundp 'user-error) (user-error ,@args) (error ,@args))) (font-lock-add-keywords 'emacs-lisp-mode '(("(\\(info-user-error\\)\\>" 1 font-lock-warning-face))) ;;; KEYS & MENUS ;;;;;;;;;;;;;;;;;;;;;;;; (define-key Info-mode-map "?" 'describe-mode) ; Don't use `Info-summary'. (define-key Info-mode-map "+" 'Info-merge-subnodes) (define-key Info-mode-map "." 'Info-save-current-node) (define-key Info-mode-map "a" 'info-apropos) (define-key Info-mode-map "G" 'Info-goto-node-web) (define-key Info-mode-map "O" 'Info-toc-outline) (define-key Info-mode-map "v" 'Info-virtual-book) (define-key Info-mode-map (kbd "C-x DEL") 'Info-change-visited-status) ;; Mouse back and forward buttons (define-key Info-mode-map [S-down-mouse-2] 'Info-mouse-follow-nearest-node-new-window) (define-key Info-mode-map [S-return] 'Info-follow-nearest-node-new-window) (define-key Info-mode-map [mouse-4] 'Info-history-back) (define-key Info-mode-map [mouse-5] 'Info-history-forward) ;;(@* "Faces (Customizable)") ;;; Faces (Customizable) --------------------------------------------- ;;;###autoload (defgroup Info-Plus nil "Various enhancements to Info." :group 'info :link `(url-link :tag "Send Bug Report" ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ info+.el bug: \ &body=Describe bug here, starting with `emacs -q'. \ Don't forget to mention your Emacs and library versions.")) :link '(url-link :tag "Other Libraries by Drew" "https://www.emacswiki.org/DrewsElispLibraries") :link '(url-link :tag "Download" "https://www.emacswiki.org/info+.el") :link '(url-link :tag "Description" "https://www.emacswiki.org/InfoPlus") :link '(emacs-commentary-link :tag "Commentary" "info+") ) ;; FWIW, I use a `LightSteelBlue' background for `*info*', and I use `red3' for this face. ;;;###autoload (defface info-double-quoted-name ; For “...” '((((background dark)) (:inherit font-lock-string-face :foreground "Cyan")) (t (:inherit font-lock-string-face :foreground "DarkOrange"))) "*Face for names enclosed in curly double-quotes (“...”) in `info'." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-emphasis ; For _..._ '((t (:inherit italic))) "*Face for emphasizing text enclosed with underscores (_..._) in `info'." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-file '((((background dark)) (:foreground "Yellow" :background "DimGray")) (t (:foreground "Blue" :background "LightGray"))) "*Face for file heading labels in `info'." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-menu '((((background dark)) (:foreground "Yellow")) (t (:foreground "Blue"))) "*Face used for menu items in `info'." :group 'Info-Plus :group 'faces) ;; FWIW, I use a `LightSteelBlue' background for `*info*', and I use `yellow' for this face. ;;;###autoload (defface info-quoted-name ; For ‘...’ and `...' '((((background dark)) (:inherit font-lock-string-face :foreground "#6B6BFFFF2C2C")) ; ~ bright green (((background light)) (:inherit font-lock-string-face :foreground "DarkViolet")) (t (:foreground "yellow"))) "*Face for quoted names (‘...’ or `...') in `info'." :group 'Info-Plus :group 'faces) ;; FWIW, I use a `LightSteelBlue' background for `*info*', and I use `red3' for this face. ;;;###autoload (defface info-string ; For "..." '((((background dark)) (:inherit font-lock-string-face :foreground "Orange")) (t (:inherit font-lock-string-face :foreground "red3"))) "*Face for strings (\"...\") in `info'." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-single-quote ; For ' '((((background dark)) (:inherit font-lock-keyword-face :foreground "Green")) (t (:inherit font-lock-keyword-face :foreground "Magenta"))) "*Face for isolated single-quote marks (') in `info'." :group 'Info-Plus :group 'faces) ;; Standard faces from vanilla Emacs `info.el', but without `:weight', `:height' and `:inherit'. ;;;###autoload (defface info-title-1 '((((type tty pc) (class color) (background dark)) :foreground "yellow" :weight bold) (((type tty pc) (class color) (background light)) :foreground "brown" :weight bold)) "*Face for info titles at level 1." :group 'info) ;;;###autoload (defface info-title-2 '((((type tty pc) (class color)) :foreground "lightblue" :weight bold)) "*Face for info titles at level 2." :group 'info) ;;;###autoload (defface info-title-3 '((((type tty pc) (class color)) :weight bold)) "*Face for info titles at level 3." :group 'info) ;;;###autoload (defface info-title-4 '((((type tty pc) (class color)) :weight bold)) "*Face for info titles at level 4." :group 'info) ;;; Faces for highlighting reference items ;;;###autoload (defface info-command-ref-item '((((background dark)) (:foreground "#7474FFFF7474" :background "DimGray")) ; ~ light green (t (:foreground "Blue" :background "LightGray"))) "*Face used for \"Command:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-constant-ref-item '((((background dark)) (:foreground "DeepPink" :background "DimGray")) (t (:foreground "DeepPink" :background "LightGray"))) "*Face used for \"Constant:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-function-ref-item '((((background dark)) (:foreground "#4D4DDDDDDDDD" :background "DimGray")) ; ~ cyan (t (:foreground "DarkBlue" :background "LightGray"))) "*Face used for \"Function:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-macro-ref-item '((((background dark)) (:foreground "Yellow" :background "DimGray")) (t (:foreground "DarkMagenta" :background "LightGray"))) "*Face used for \"Macro:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-reference-item '((((background dark)) (:background "DimGray")) (t (:background "LightGray"))) "*Face used for reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-special-form-ref-item '((((background dark)) (:foreground "Yellow" :background "DimGray")) (t (:foreground "DarkMagenta" :background "LightGray"))) "*Face used for \"Special Form:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-syntax-class-item '((((background dark)) (:foreground "#FFFF9B9BFFFF" :background "DimGray")) ; ~ pink (t (:foreground "DarkGreen" :background "LightGray"))) "*Face used for \"Syntax Class:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-user-option-ref-item '((((background dark)) (:foreground "Red" :background "DimGray")) (t (:foreground "Red" :background "LightGray"))) "*Face used for \"User Option:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) ;;;###autoload (defface info-variable-ref-item '((((background dark)) (:foreground "Orange" :background "DimGray")) (t (:foreground "FireBrick" :background "LightGray"))) "*Face used for \"Variable:\" reference items in `info' manual." :group 'Info-Plus :group 'faces) (when (and (require 'bookmark+ nil t) ; Emacs 24.2+ (do not bother for Emacs 23-24.1) (or (> emacs-major-version 24) (and (= emacs-major-version 24) (> emacs-minor-version 1)))) (defface info-xref-bookmarked '((((background dark)) (:foreground "violet")) (t (:foreground "DarkGreen"))) "Face for bookmarked Info nodes." :group 'Info-Plus :group 'faces) ) ;;(@* "User Options (Customizable)") ;;; User Options (Customizable) -------------------------------------- ;;;###autoload (defcustom Info-breadcrumbs-in-header-flag nil "*Non-nil means breadcrumbs are shown in the header line." :type 'boolean :group 'Info-Plus) ;;;###autoload (defcustom Info-display-node-header-fn 'Info-display-node-default-header "*Function to insert header by `Info-merge-subnodes'." :type 'function :group 'Info-Plus) ;;;###autoload (defcustom Info-emphasis-regexp "_\\(\\(\\sw\\(\\s-\\|\\sw\\|\\s.\\)*\\)\\|\\(\\(\\s-\\|\\sw\\|\\s.\\)\\sw*\\)\\)_" "Regexp to match text enclosed in underscore (`_') characters. The default value matches the following (enclosed in underscores): word, punctuation, and whitespace characters, plus hyphens, with at least one word character. Hyphen is included explicitly because it generally has symbol syntax in Info. Some possible values include: _\\(\\(\\sw\\(\\s-\\|\\sw\\|\\s.\\)*\\)\\|\\(\\(\\s-\\|\\sw\\|\\s.\\)\\sw*\\)\\)_ (default) _\\(\\(\\s-\\|\\sw\\|\\s.\\)+\\)_ (word, punctuation, whitespace) _\\(\\sw+\\)_\t\t (single words) _\\(\\s-*\\sw+\\s-*\\)_\t (single words, maybe whitespace-separated) _\\([^_\\n]+\\)_\t\t (anything except newlines) _\\([^_]+\\)_\t\t (anything) Note that any value can be problematic for some Info text - see `Info-fontify-emphasis-flag'." :type 'regexp :group 'Info-Plus) ;;;###autoload (defcustom Info-fit-frame-flag t "*Non-nil means call `fit-frame' on Info buffer." :type 'boolean :group 'Info-Plus :group 'Fit-Frame) (when (and (require 'bookmark+ nil t) ; Emacs 24.4+ (or (> emacs-major-version 24) (and (= emacs-major-version 24) (> emacs-minor-version 3)))) (defcustom Info-node-access-invokes-bookmark-flag t "*Non-nil means invoke the bookmark when you access an Info node. This applies to Info bookmarks whose names correspond to the default name. This is normally the full node name, `(MANUAL) NODE', where MANUAL is the lowercase name of the Info manual. For example, node `Modes' in the Emacs manual has full name `(emacs) Modes', and the bookmark must have that same name. This automatic bookmark invocation can be useful to update the bookmark data, such as the number of visits to the node." :type 'boolean :group 'Info-Plus) ) ;;;###autoload (defcustom Info-fontify-angle-bracketed-flag t "*Non-nil means `info' fontifies text within <...>. A non-nil value has no effect unless `Info-fontify-quotations-flag' is also non-nil. Note: This fontification can never be 100% reliable. It aims to be useful in most Info texts, but it can occasionally result in fontification that you might not expect. This is not a bug; it is part of the design to be able to appropriately fontify a great variety of texts. Set this flag to nil if you do not find this fontification useful. You can use command `Info-toggle-fontify-angle-bracketed' to toggle the option value." :type 'boolean :group 'Info-Plus) (when (and (require 'bookmark+ nil t) ; Emacs 24.2+ (do not bother for prior) (or (> emacs-major-version 24) (and (= emacs-major-version 24) (> emacs-minor-version 1)))) (defcustom Info-bookmarked-node-xref-faces '() "List of faces to use to classify bookmarked nodes. The faces are used for links to bookmarked nodes. They classify nodes by serving as the values of bookmark tag \"bmkp-info-face\". You can use any face for such a link. The faces in this option list are just provided as defaults when you are asked to enter a face for a node link. " :type '(repeat face) :group 'Info-Plus) (defcustom Info-fontify-bookmarked-xrefs-flag t "Non-nil means fontify references to bookmarked nodes. The face used is `info-xref-bookmarked'." :type 'boolean :group 'Info-Plus) ) ;;;###autoload (defcustom Info-fontify-emphasis-flag t "*Non-nil means `info' fontifies text between underscores (`_'). The text that is highlighted matches the value of option `Info-emphasis-regexp'. Note 1: This fontification hides the underscores that surround text that is emphasized. Because this fontification is not 100% reliable (see Note 2), in cases where it is inappropriate or unhelpful you might want to see the hidden underscore characters. You can toggle showing all hidden text (not just hidden underscores) using `M-x visible-mode'. See (info) `Help-Inv' for more information about this. Note 2: This fontification can never be 100% reliable. It aims to be useful in most Info texts, but it can occasionally result in fontification that you might not expect. This is not a bug; it is part of the design to be able to appropriately fontify a great variety of texts. Set this flag to nil if you do not find this fontification useful. You can use command `Info-toggle-fontify-emphasis' to toggle the option value. Note 3: If internal variable `info-fontify-emphasis' is `nil' then emphasis is never highlighted, and this option has no effect. This gives you a way to turn off all matching of `Info-emphasis-regexp'." :type 'boolean :group 'Info-Plus) ;;;###autoload (defcustom Info-fontify-quotations-flag t "*Non-nil means `info' fontifies text between quotes. This applies to double-quoted text (“...” or \"...\") and text between single-quotes (‘...’ or `...'). Note: This fontification can never be 100% reliable. It aims to be useful in most Info texts, but it can occasionally result in fontification that you might not expect. This is not a bug; it is part of the design to be able to appropriately fontify a great variety of texts. Set this flag to nil if you do not find this fontification useful. You can use command `Info-toggle-fontify-quotations' to toggle the option value." :type 'boolean :group 'Info-Plus) ;;;###autoload (defcustom Info-fontify-reference-items-flag t "*Non-nil means `info' fontifies reference items such as \"Function:\"." :type 'boolean :group 'Info-Plus) (when (fboundp 'advice-add) ; Emacs 24.4+ (defcustom Info-saved-history-file (locate-user-emacs-file "info-history" ".emacs.info-history") "File where `Info-persist-history-mode' saves `Info-history-list'." :type '(file :must-match t) :group 'Info-Plus) ) ;;;###autoload (defcustom Info-saved-nodes () "*List of Info node names you can visit using `\\\\[Info-virtual-book]'. Each node name is a string. The node name can be absolute, including a filename, such as \"(emacs)Basic\", or it can be relative, such as \"Basic\". You can customize this option, but you can also add node names to it easily using `\\\\[Info-save-current-node]'." :type '(repeat (string :tag "Node name")) :group 'info) ;;;###autoload (defcustom Info-fontify-single-quote-flag t "*Non-nil means `info' fontifies ' when not preceded by `.... A non-nil value has no effect unless `Info-fontify-quotations-flag' is also non-nil. Note: This fontification can never be 100% reliable. It aims to be useful in most Info texts, but it can occasionally result in fontification that you might not expect. This is not a bug; it is part of the design to be able to appropriately fontify a great variety of texts. Set this flag to nil if you do not find this fontification useful. You can use command `Info-toggle-fontify-single-quote' to toggle the option value." :type 'boolean :group 'Info-Plus) ;;;###autoload (defcustom Info-subtree-separator "\n* " "*A string used to separate Info node descriptions. Inserted by `Info-merge-subnodes' just before each node title. Setting this to a string that includes a form-feed (^L), such as \"\\f\\n* \", will cause a page break before each node description. Use command `set-variable' to set this, quoting any control characters you want to include, such as form-feed (^L) and newline (^J), with ^Q. For example, type `^Q^L^Q^J* ' to set this to \"\\f\\n* \"." :type 'string :group 'Info-Plus) ;;;###autoload (defcustom Info-toc-outline-no-redundancy-flag t "Non-nil means `Info-toc-outline' TOC has no redundancy. If nil then section headings from the TOC manual are included, and nodes can be repeated because they are in more than one section." :type 'boolean :group 'Info-Plus) ;;(@* "Internal Variables") ;;; Internal Variables ----------------------------------------------- (defvar info-fontify-emphasis t "Non-nil means allow `Info-fontify-emphasis-flag' to work. If nil then emphasis is never fontified, regardless of that flag.") ;; I reported this as Emacs bug #3312. If it gets fixed, this can be removed. (defvar Info-mode-syntax-table (let ((table (copy-syntax-table text-mode-syntax-table))) (modify-syntax-entry ?' "." table) ; Punctuation syntax for apostrophe ('). (modify-syntax-entry ?\240 "." table) ; Punctuation syntax for non-breaking space. table) "Syntax table for `info'.") (defvar Info-merged-map nil "Keymap for merged Info buffer.") (if Info-merged-map nil (setq Info-merged-map (make-keymap)) (suppress-keymap Info-merged-map) (define-key Info-merged-map "." 'beginning-of-buffer) (define-key Info-merged-map "\t" 'Info-next-reference) (define-key Info-merged-map "\e\t" 'Info-prev-reference) (define-key Info-merged-map "b" 'beginning-of-buffer) (define-key Info-merged-map "q" 'quit-window) (define-key Info-merged-map "s" 'nonincremental-re-search-forward) (define-key Info-merged-map "\M-s" 'nonincremental-re-search-forward)) (defvar Info-breadcrumbs-depth-internal Info-breadcrumbs-depth "Current breadcrumbs depth for Info.") ;; Match has, inside “...”, "...", ‘...’, or `...', zero or more of these characters: ;; - any character except ”, ", ’, or ', respectively ;; - \ followed by any character ;; ;; The `... in `...' is optional, so the regexp can also match just '. ;; ;; The regexp matches also ‘...’, `...', “...”, and "..." where at least one of the ;; ‘, ’, `, ', “, ”, or " is escaped by a backslash. ;; So we check those cases explicitly and do not highlight them. ;; (defvar info-quotation-regexp (concat "\"\\(?:[^\\\"]\\|\\\\\\(?:.\\|[\n]\\)\\)*\"\\|" ; "..." "`\\(?:[^\\']\\|\\\\\\(.\\|[\n]\\)\\)*'\\|" ; `...' "‘\\(?:[^\\’]\\|\\\\\\(.\\|[\n]\\)\\)*’\\|" ; ‘...’ "\“\\(?:[^\\”]\\|\\\\\\(.\\|[\n]\\)\\)*”" ; “...” ) "Regexp to match `...', ‘...’, “...”, \"...\", or just '. If ... contains an end char then that char must be backslashed.") (defvar info-quoted+<>-regexp (concat "\"\\(?:[^\\\"]\\|\\\\\\(?:.\\|[\n]\\)\\)*\"\\|" ; "..." "`\\(?:[^\\']\\|\\\\\\(.\\|[\n]\\)\\)*'\\|" ; `...' "‘\\(?:[^\\’]\\|\\\\\\(.\\|[\n]\\)\\)*’\\|" ; ‘...’ "\“\\(?:[^\\”]\\|\\\\\\(.\\|[\n]\\)\\)*”\\|" ; “...” "<\\(?:[[:alpha:]][^\\>]*\\|\\(\\\\\\(.\\|[\n]\\)\\)*\\)>" ; <...> ) "Same as `info-quotation-regexp', but matches also <...>. If ... contains an end char then that char must be backslashed.") (defvar Info-toc-outline-map (let ((map (make-sparse-keymap))) (set-keymap-parent map Info-mode-map)) "Keymap for Info TOC with outlining.") ;;(@* "New Commands") ;;; New Commands ----------------------------------------------------- ;; Make `Info-find-emacs-command-nodes' look for these commands in the Emacs manual. ;; In particular, don't look for command `info' in Info manual, because that has no index. (put 'info 'info-file "emacs") (put 'Info-goto-emacs-command-node 'info-file "emacs") (put 'Info-goto-emacs-key-command-node 'info-file "emacs") ;;;###autoload (autoload 'Info-mouse-follow-nearest-node-new-window "info+") (defun Info-mouse-follow-nearest-node-new-window (click) "Open the link at the mouse pointer in a new window." (interactive "e") (Info-mouse-follow-nearest-node click t)) ;;;###autoload (autoload 'Info-follow-nearest-node-new-window "info+") (defun Info-follow-nearest-node-new-window () "Open the link near the text cursor in a new window." (interactive) (Info-follow-nearest-node t)) ;;;###autoload (autoload 'Info-clear "info+") (defun Info-history-clear (&optional msgp) "Clear Info history and reload current manual." (interactive (progn (unless (y-or-n-p "Clear the Info history? ") (info-user-error "OK, canceled")) (list t))) (setq Info-history () Info-history-list ()) (when (derived-mode-p 'Info-mode) (revert-buffer nil t)) (when msgp (message "Info history cleared"))) (when (fboundp 'advice-add) ; Emacs 24.4+ (define-minor-mode Info-persist-history-mode "Automatically persist the Info history in `Info-saved-history-file'." :init-value nil :global t :group 'Info-Plus (cond (Info-persist-history-mode (add-hook 'kill-emacs-hook 'Info-save-history-list) (advice-add 'Info-kill-buffer :before 'Info-save-history-list) (advice-add 'Info-directory :after 'Info-restore-history-list)) (t (remove-hook 'kill-emacs-hook 'Info-save-history-list) (advice-remove 'Info-kill-buffer 'Info-save-history-list) (advice-remove 'Info-directory 'Info-restore-history-list)))) ) (when (> emacs-major-version 23) ; Emacs 23 `revert-buffer' invokes a brain-dead `kill-buffer' etc. (defun Info-change-visited-status (start end &optional arg) "Change whether the nodes in the region have been visited. If the region is not active then act on only the node at point. No prefix arg means toggle the visited status of each node. A non-negative prefix arg means consider the nodes visited. A negative prefix arg means consider the nodes not visited." (interactive "r\nP") (let ((toggle (not arg)) (visit (and arg (natnump (prefix-numeric-value arg)))) (unvisit (and arg (not (natnump (prefix-numeric-value arg))))) (opoint (point)) (omark (mark)) (active mark-active) (file (Info-find-file Info-current-file)) node visitedp trim) (unless mark-active (setq start (setq end (point)))) (save-excursion (goto-char start) (while (<= (point) end) (unless (setq node (Info-node-name-at-point)) (Info-next-reference)) (when (setq node (Info-node-name-at-point)) (save-match-data (string-match "\\s *\\((\\s *\\([^\t)]*\\)\\s *)\\s *\\|\\)\\(.*\\)" node) (setq node (match-string 3 node)) (setq trim (string-match "\\s +\\'" node))) (when trim (setq node (substring node 0 trim))) (when (or (not node) (string= node "")) (setq node "Top")) (setq visitedp (member (list file node) Info-history-list)) (if (and visitedp (or toggle unvisit)) (setq Info-history-list (delete (list file node) Info-history-list)) (if (and (not visitedp) (or toggle visit)) (setq Info-history-list (cons (list file node) Info-history-list))))) (when (> (forward-line 1) 0) (goto-char (point-max))))) (when (derived-mode-p 'Info-mode) (revert-buffer nil t)) (when omark (set-mark omark)) (goto-char opoint) (message (if toggle "Node visited status toggled" (format "Node visited status is now %s" (if visit 'VISITED 'UNvisited)))) (if (not active) (deactivate-mark) (activate-mark) (setq deactivate-mark nil)))) ) ;; Not bound. Use `Info-change-visited-status' instead. ;; ;;;###autoload (autoload 'Info-make-node-unvisited "info+") (defun Info-make-node-unvisited (node &optional msgp) "Reset the visited status of NODE to unvisited." (interactive (list (or (Info-node-name-at-point) (Info-read-node-name "Node: " Info-current-node)) t)) (let (file trim) (save-match-data (string-match "\\s *\\((\\s *\\([^\t)]*\\)\\s *)\\s *\\|\\)\\(.*\\)" node) (setq file (if (= (match-beginning 1) (match-end 1)) "" (match-string 2 node)) node (match-string 3 node) trim (string-match "\\s +\\'" file)) (when trim (setq file (substring file 0 trim))) (setq trim (string-match "\\s +\\'" node))) (when trim (setq node (substring node 0 trim))) (when (or (not node) (string= node "")) (setq node "Top")) (when (or (not file) (string= file "")) (setq file Info-current-file)) (setq file (Info-find-file file) Info-history-list (remove (list file (substring-no-properties node)) Info-history-list)) ;; Emacs 23 has brain-dead `kill-buffer', which is invoked by `revert-buffer' and deletes the window/frame if dedicated. (when (and (> emacs-major-version 23) (derived-mode-p 'Info-mode)) (revert-buffer nil t)) (when msgp (message "Node %sis now unvisited" (if (string= "dir" Info-current-file) "" (format "`%s%s' " (if (equal file Info-current-file) "" (format "(%s) " (file-name-nondirectory file))) node)))))) ;; I made this a global minor mode and turned it on by default, contrary to "the rules". ;; I did this so (a) users could easily customize it but (b) it would be on by default, otherwise. ;; ;;;###autoload (autoload 'Info-breadcrumbs-in-mode-line-mode "info+") (define-minor-mode Info-breadcrumbs-in-mode-line-mode "Toggle the use of breadcrumbs in Info mode line. With arg, show breadcrumbs iff arg is positive. Change the default behavior by customizing option `Info-breadcrumbs-in-mode-line-mode'." :init-value t :global t :group 'mode-line :group 'Info-Plus (if (not Info-breadcrumbs-in-mode-line-mode) (setq Info-breadcrumbs-depth-internal 0 mode-line-format (default-value 'mode-line-format)) (setq Info-breadcrumbs-depth-internal Info-breadcrumbs-depth) (Info-insert-breadcrumbs-in-mode-line))) ;;;###autoload (autoload 'Info-toggle-breadcrumbs-in-header "info+") (defun Info-toggle-breadcrumbs-in-header (&optional msgp) "Toggle option `Info-breadcrumbs-in-header-flag'. Toggles showing breadcrumbs in the Info header (top of the node). This means the area at the top of the node, not the separate header line from non-nil `Info-use-header-line'." (interactive "p") (setq Info-breadcrumbs-in-header-flag (not Info-breadcrumbs-in-header-flag)) (when msgp (message "Showing breadcrumbs in Info header is now %s" (if Info-breadcrumbs-in-header-flag "ON" "OFF")))) (defalias 'Info-toggle-breadcrumbs-in-header-line 'Info-toggle-breadcrumbs-in-header) (make-obsolete 'Info-toggle-breadcrumbs-in-header-line 'Info-toggle-breadcrumbs-in-header "2014/03/04") (when (boundp 'Info-node-access-invokes-bookmark-flag) ; Emacs 24.4+ (defun Info-toggle-node-access-invokes-bookmark (&optional msgp) "Toggle option `Info-node-access-invokes-bookmark-flag'." (interactive "p") (setq Info-node-access-invokes-bookmark-flag (not Info-node-access-invokes-bookmark-flag)) (when (eq major-mode 'Info-mode) (font-lock-defontify) (let ((modp (buffer-modified-p)) (inhibit-read-only t)) (Info-fontify-node)) (when msgp (message "`Info-node-access-invokes-bookmark-flag' is now %s" (if Info-node-access-invokes-bookmark-flag 'ON 'OFF))))) ) (when (and (require 'bookmark+ nil t) ; Emacs 24.2+ (do not bother for prior) (or (> emacs-major-version 24) (and (= emacs-major-version 24) (> emacs-minor-version 1)))) (defun Info-set-face-for-bookmarked-xref (node) "Specify the face to use for Info links to bookmarked NODE. Sets the value of bookmark tag \"bmkp-info-face\" to a face symbol you name. If option `Info-bookmarked-node-xref-faces' is non-nil then only the faces in that list are available for completion, but you can enter any face name. If that option is nil then all faces are available for completion. NODE defaults to the bookmarked node named at point. If none then you are prompted for NODE." (interactive (list (or (Info-bookmark-name-at-point) (Info-read-bookmarked-node-name)))) (let* ((alist (bmkp-info-alist-only)) (bmk (bmkp-get-bookmark-in-alist node t alist))) (unless bmk (error "No Info bookmark for node `%s'" node)) (bmkp-set-tag-value bmk "bmkp-info-face" (if Info-bookmarked-node-xref-faces (intern (completing-read "Face: " Info-bookmarked-node-xref-faces (lambda (ff) (memq ff (face-list))))) (read-face-name "Face" 'info-xref-bookmarked))))) (define-key Info-mode-map (kbd "C-x f") 'Info-set-face-for-bookmarked-xref) (defun Info-toggle-fontify-bookmarked-xrefs (&optional msgp) "Toggle option `Info-fontify-bookmarked-xrefs-flag'." (interactive "p") (setq Info-fontify-bookmarked-xrefs-flag (not Info-fontify-bookmarked-xrefs-flag)) (when (eq major-mode 'Info-mode) (font-lock-defontify) (let ((modp (buffer-modified-p)) (inhibit-read-only t)) (Info-fontify-node)) (when msgp (message "`Info-fontify-bookmarked-xrefs-flag' is now %s" (if Info-fontify-bookmarked-xrefs-flag 'ON 'OFF))))) ) ;;;###autoload (autoload 'Info-toggle-fontify-emphasis "info+") (defun Info-toggle-fontify-emphasis (&optional msgp) "Toggle option `Info-fontify-emphasis-flag'." (interactive "p") (unless info-fontify-emphasis (error "`info-fontify-emphasis' must be non-nil to use this command")) (setq Info-fontify-emphasis-flag (not Info-fontify-emphasis-flag)) (when (eq major-mode 'Info-mode) (font-lock-defontify) (let ((modp (buffer-modified-p)) (inhibit-read-only t)) (Info-fontify-node)) (when msgp (message "`Info-fontify-emphasis-flag' is now %s" (if Info-fontify-emphasis-flag 'ON 'OFF))))) ;;;###autoload (autoload 'Info-toggle-fontify-quotations "info+") (defun Info-toggle-fontify-quotations (&optional msgp) "Toggle option `Info-fontify-quotations-flag'." (interactive "p") (setq Info-fontify-quotations-flag (not Info-fontify-quotations-flag)) (when (eq major-mode 'Info-mode) (font-lock-defontify) (let ((modp (buffer-modified-p)) (inhibit-read-only t)) (Info-fontify-node)) (when msgp (message "`Info-fontify-quotations-flag' is now %s" (if Info-fontify-quotations-flag 'ON 'OFF))))) ;;;###autoload (autoload 'Info-toggle-fontify-single-quote "info+") (defun Info-toggle-fontify-single-quote (&optional msgp) "Toggle option `Info-fontify-single-quote-flag'." (interactive "p") (setq Info-fontify-single-quote-flag (not Info-fontify-single-quote-flag)) (when (eq major-mode 'Info-mode) (font-lock-defontify) (let ((modp (buffer-modified-p)) (inhibit-read-only t)) (Info-fontify-node)) (when msgp (message "`Info-fontify-single-quote-flag' is now %s" (if Info-fontify-single-quote-flag 'ON 'OFF))))) ;;;###autoload (autoload 'Info-toggle-fontify-angle-bracketed "info+") (defun Info-toggle-fontify-angle-bracketed (&optional msgp) "Toggle option `Info-fontify-angle-bracketed-flag'." (interactive "p") (setq Info-fontify-angle-bracketed-flag (not Info-fontify-angle-bracketed-flag)) (when (eq major-mode 'Info-mode) (font-lock-defontify) (let ((modp (buffer-modified-p)) (inhibit-read-only t)) (Info-fontify-node)) (when msgp (message "`Info-fontify-angle-bracketed-flag' is now %s" (if Info-fontify-angle-bracketed-flag 'ON 'OFF))))) ;;;###autoload (autoload 'Info-save-current-node "info+") (defun Info-save-current-node (&optional msgp) "Save name of current Info node to list `Info-saved-nodes'." (interactive "p") (unless (eq major-mode 'Info-mode) (info-user-error "You must be in Info to use this command")) (unless Info-current-node (info-user-error "No current Info node")) (unless Info-current-file (info-user-error "No Info file")) (add-to-list 'Info-saved-nodes (concat "(" (file-name-nondirectory Info-current-file) ")" Info-current-node)) (when msgp (message (format "Node `%s' saved" Info-current-node)))) (when (require 'bookmark+ nil t) (defun Info-describe-bookmark (&optional node show-definition-p) "Describe bookmark for NODE (default: bookmarked node named at point). With a prefix argument, show the internal definition of the bookmark. If there is no bookmarked node named at point then you are prompted for the name of one. When called from Lisp, NODE is a full node name: `(MANUAL) NODE'. That is, it corresponds to a default Info bookmark name." (interactive (list (or (Info-bookmark-name-at-point) (Info-read-bookmarked-node-name)) current-prefix-arg)) (let* ((alist (bmkp-info-alist-only)) (bmk (or (bmkp-get-bookmark-in-alist node t alist) (bmkp-read-bookmark-for-type "Info" alist nil nil 'bmkp-info-history "Describe ")))) (bmkp-describe-bookmark bmk show-definition-p))) (defun Info-read-bookmarked-node-name (&optional localp) "Read and return the name of a bookmarked Info node. A bookmarked node name has the form \"(MANUAL) NODE\", referring to NODE in MANUAL. Optional arg LOCALP means read a node name from the current manual." (let* ((completion-ignore-case t) (bmks (remove-if-not (lambda (bmk) (bmkp-string-match-p (if (and localp Info-current-file) (format "\\`(%s) " (file-name-sans-extension (file-name-nondirectory Info-current-file))) "(\\([^)]+\\)) \\([^)]*\\)") (bmkp-bookmark-name-from-record bmk))) (bmkp-info-alist-only))) (bmk (completing-read "Bookmarked node: " bmks nil t nil 'bmkp-info-history))) (while (equal bmk "") (setq bmk (completing-read "Bookmarked node: " bmks nil t nil 'bmkp-info-history))) bmk)) ) ;;; Support for TOC with Outline support --------------------- ;; REPLACE ORIGINAL in `outline.el': ;; ;; See Emacs bug #28080. ;; (defun outline-invisible-p (&optional pos) "Non-nil if the character after point has been made invisible by Outline." (eq (get-char-property (or pos (point)) 'invisible) 'outline)) (when (boundp 'Info-virtual-nodes) ; Emacs 23.4+ (add-to-list 'Info-virtual-nodes '("\\`\\*TOC Outline\\* (.*)\\'" (find-node . Info-toc-outline-find-node))) (defun Info-toc-outline (&optional arg) "Go to a node with a table of contents (TOC) in `outline-minor-mode'. The TOC is created from the tree structure of Info menus. In this node you can use the commands and menu items of `outline-minor-mode' to navigate, hide/show, delete, or rearrange parts of the TOC. Start with menu-bar menu `Outline' to see what is possible. * With no prefix arg: - If buffer `*TOC Outline* (MANUAL)' exists, where MANUAL is the manual/file name for the current manual, then pop to it. - Else create that buffer for the current manual, and pop to it. * With a plain prefix arg (`C-u'): Pop to a new TOC buffer, `*TOC Outline* (MANUAL)' (or `*TOC Outline* (MANUAL)', N=1,2,3...), for the current MANUAL. * With any other prefix arg (e.g. `M--'): Reuse the current Info buffer, going to a node `*TOC Outline*' for the current manual." (interactive (list (if (consp current-prefix-arg) 'clone current-prefix-arg))) (unless (derived-mode-p 'Info-mode) (info-user-error "You must be in Info to use this command")) (unless Info-current-node (info-user-error "No current Info node")) (unless Info-current-file (info-user-error "No Info file")) (when (equal Info-current-file "dir") (info-user-error "No TOC for Info Directory - choose a manual")) (if (and (not arg) (get-buffer (format "*TOC Outline* (%s)" (file-name-nondirectory Info-current-file)))) (pop-to-buffer (format "*TOC Outline* (%s)" (file-name-nondirectory Info-current-file))) (when (or (not arg) (eq arg 'clone)) (clone-buffer (format "*TOC Outline* (%s)" (file-name-nondirectory Info-current-file)) t)) (Info-breadcrumbs-in-mode-line-mode -1) (setq mark-ring ()) ;`clone-buffer' causes this to be needed, if `*info*' buffer has no mark. (Info-find-node Info-current-file (format "*TOC Outline* (%s)" (file-name-nondirectory Info-current-file))) (let ((prev-node (nth 1 (car Info-history))) prev-posn) (goto-char (point-min)) (when (setq prev-posn (search-forward (concat "*Note " prev-node ":") nil t)) (setq prev-posn (- prev-posn (length prev-node) 2))) (goto-char (or prev-posn (point-min)))))) (defun Info-toc-outline-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))) (insert (format "\n\^_\nFile: %s, Node: %s, Up: Top\n\n" curr-file curr-node)) (let ((title (format "Contents (%s)" (file-name-nondirectory curr-file)))) (insert title "\n" (make-string (length title) ?*) "\n\n")) (insert "*Note Top::\n") (Info-toc-insert (nth 3 (assoc "Top" node-list)) node-list 0 curr-file) ; `Top' nodes (unless (bobp) (let ((Info-hide-note-references 'hide) (Info-fontify-visited-nodes nil)) (setq Info-current-file filename Info-current-node (format "*TOC Outline* (%s)" (file-name-nondirectory curr-file))) (goto-char (point-min)) (narrow-to-region (or (re-search-forward "\n[\^_\f]\n" nil t) (point-min)) (point-max)) (Info-fontify-node) (widen)))) (set (make-local-variable 'inhibit-read-only) t) (goto-char (point-min)) (search-forward "Contents" nil t) (forward-line 3) ;; If `Info-toc-outline-no-redundancy-flag' is non-nil then remove redundancies. Else give non-links face `info-title-4'. (save-excursion (let ((note-re "^[\t]*[*]Note ")) (while (not (eobp)) (if (re-search-forward note-re (line-end-position) t) (if (and Info-toc-outline-no-redundancy-flag ; Remove node line if already listed. (let ((node (buffer-substring-no-properties (point) (line-end-position)))) (save-excursion (beginning-of-line) (re-search-backward (concat note-re node) nil t)))) (delete-region (line-beginning-position) (line-beginning-position 2)) (save-excursion ; Indent previous line to same column, if it was a heading. (let ((col (current-column))) (forward-line -1) (unless (re-search-forward note-re (line-end-position) t) (insert (propertize " " 'display `(space :align-to ,col)))))) (forward-line 1)) (if Info-toc-outline-no-redundancy-flag (delete-region (line-beginning-position) (line-beginning-position 2)) ;; The line is a section heading. Put face `info-title-4' on it. (put-text-property (line-beginning-position 1) (line-end-position 1) 'face 'info-title-4) (unless (looking-at "\\s-") (insert "\n")) (forward-line 1)))))) (outline-minor-mode 1) (define-key Info-toc-outline-map [remap outline-promote] 'Info-outline-promote) (define-key Info-toc-outline-map [remap outline-demote] 'Info-outline-demote) (define-key Info-toc-outline-map "\C-x\M-l" 'Info-toc-outline-refontify-region) (use-local-map Info-toc-outline-map) (setq outline-regexp "[\t]*[*]Note ") ; Include no "^" here. (set (make-local-variable 'Info-hide-note-references) 'hide) (add-hook 'post-command-hook 'Info-toc-outline-refontify-region nil 'LOCAL) (buffer-enable-undo)) (defun Info-toc-outline-refontify-region (&optional start end forcep) "In Info `*TOC Outline*' buffer, refontify region. Interactively, if region is not active or is empty, refontify buffer. From Lisp: * Do nothing if not in a `*TOC Outline* buffer or if buffer has not been modified. * START defaults to `point-min', END defaults to `point-max'." (interactive (let* ((regionp (use-region-p)) (st (if regionp (region-beginning) (point-min))) (en (if regionp (region-end) (point-max)))) (list st en t))) (setq start (or start (point-min)) end (or end (point-max))) (let ((buff (buffer-name))) (when (or forcep (and buff (buffer-modified-p) (string-match-p "\\`\\*TOC Outline\\* ([^)]+)" buff) (derived-mode-p 'Info-mode))) (Info-toc-outline-refontify-links start end)))) (defun Info-outline-promote (&optional which) "Promote headings higher up the tree. If `transient-mark-mode' is on and the mark is active, promote headings in the region (from a Lisp program, pass the symbol `region' for WHICH). Otherwise: * With no prefix arg, promote the current heading and all headings in the subtree (from a Lisp program, pass symbol `subtree' for WHICH); * with a prefix arg, promote just the current heading (from a Lisp program, pass nil for WHICH, or do not pass any argument). This is a version of `outline-promote' for use with Info. It refontifies the buffer to hide the link prefix `*Note'." (interactive (list (if (and transient-mark-mode mark-active) 'region (outline-back-to-heading) (and (not current-prefix-arg) 'subtree)))) (let (start end) (cond ((eq which 'region) (outline-map-region 'Info-outline-promote (setq start (copy-marker (region-beginning))) (prog1 (region-end) (setq end (save-excursion (goto-char (region-end)) (copy-marker (line-end-position))))))) (which (outline-map-region 'Info-outline-promote (setq start (copy-marker (point))) (save-excursion (outline-get-next-sibling) (setq end (copy-marker (point)))))) (t (outline-back-to-heading t) (setq start (copy-marker (point)) end (copy-marker (line-end-position))) (let* ((head (match-string-no-properties 0)) (level (save-match-data (funcall outline-level))) (up-head (or (outline-head-from-level (1- level) head) (save-excursion ; Use the parent heading, if it is really one level less. (save-match-data (outline-up-heading 1 t) (and (= (1- level) (funcall outline-level)) (match-string-no-properties 0)))) (error "Cannot promote - already at highest level")))) (unless (rassoc level outline-heading-alist) (push (cons head level) outline-heading-alist)) (replace-match up-head nil t)))) (Info-toc-outline-refontify-links start end))) (defun Info-outline-demote (&optional which) "Demote headings lower down the tree. If `transient-mark-mode' is on and the mark isactive, demote headings in the region (from a Lisp program, pass symbol `region' for WHICH). Otherwise: * Without a prefix arg, demote current heading and all headings in the subtree (from a Lisp program, pass symbol `subtree' for WHICH). * With a prefix arg, demote just the current heading (from a Lisp program, pass nil for WHICH, or do not pass any argument). This is a version of `outline-demote' for use with Info. It refontifies the buffer to hide link prefix `*Note'." (interactive (list (if (and transient-mark-mode mark-active) 'region (outline-back-to-heading) (and (not current-prefix-arg) 'subtree)))) (let (start end) (cond ((eq which 'region) (outline-map-region 'Info-outline-demote (setq start (copy-marker (region-beginning))) (prog1 (region-end) (setq end (save-excursion (goto-char (region-end)) (copy-marker (line-end-position))))))) (which (outline-map-region 'Info-outline-demote (setq start (copy-marker (point))) (save-excursion (outline-get-next-sibling) (setq end (copy-marker (point)))))) (t (setq start (copy-marker (point)) end (copy-marker (line-end-position))) (let* ((head (match-string-no-properties 0)) (level (save-match-data (funcall outline-level))) (down-head (or (outline-head-from-level (1+ level) head) (save-excursion (save-match-data (while (and (progn (outline-next-heading) (not (eobp))) (<= (funcall outline-level) level))) (when (eobp) ; Try again from beginning of buffer. (goto-char (point-min)) (while (and (progn (outline-next-heading) (not (eobp))) (<= (funcall outline-level) level)))) (unless (eobp) (looking-at outline-regexp) (match-string-no-properties 0)))) (error "Cannot demote - already at lowest level")))) (unless (rassoc level outline-heading-alist) (push (cons head level) outline-heading-alist)) (replace-match down-head nil t)))) (Info-toc-outline-refontify-links start end))) (defun Info-toc-outline-refontify-links (begin end) "Refontify TOC cross references between buffer positions BEGIN and END." ;; (interactive "r") ; Not really intended as a command, but might be handy sometimes (?). (save-excursion (let* ((inhibit-read-only t) (case-fold-search t) (fontify-bookmarked-p (and (boundp 'Info-fontify-bookmarked-xrefs-flag) Info-fontify-bookmarked-xrefs-flag)) (node-not-too-large (and (or fontify-bookmarked-p Info-fontify-visited-nodes) Info-fontify-maximum-menu-size (or (eq t Info-fontify-maximum-menu-size) (< (- (point-max) (point-min)) Info-fontify-maximum-menu-size)))) (fontify-bookmarked-p (and node-not-too-large fontify-bookmarked-p)) (fontify-visited-p (and node-not-too-large Info-fontify-visited-nodes)) paragraph-markers rbeg rend) (goto-char begin) (while (re-search-forward "\\(\\*Note[ \n\t]+\\)\\([^:]*\\)\\(:[ \t]*\\([^.,:(]*\\)\\(\\(([^)]\ *)\\)[^.,:]*\\)?[,:]?\n?\\)" end t) (let ((start (match-beginning 0)) (next (point)) other-tag) (when Info-hide-note-references (when (not (eq Info-hide-note-references 'hide)) ; *Note is often used where *note should have been. (goto-char start) (skip-syntax-backward " ") (when (memq (char-before) '(?\( ?\[ ?\{)) (skip-syntax-backward " (")) ; Check whether the paren is preceded by an end of sentence. (setq other-tag (cond ((save-match-data (looking-back "\\