diff options
| author | Mekeor Melire | 2023-12-04 16:37:37 +0100 |
|---|---|---|
| committer | Eli Zaretskii | 2024-01-27 12:18:17 +0200 |
| commit | 756daa93b3ef7ce33e741ab30000fa397fcd9783 (patch) | |
| tree | a786173c459d98118abe77156296205b2ab62491 | |
| parent | 09cdf8a406c5b73e8924a7396c2aaabe74a1a638 (diff) | |
| download | emacs-756daa93b3ef7ce33e741ab30000fa397fcd9783.tar.gz emacs-756daa93b3ef7ce33e741ab30000fa397fcd9783.zip | |
Add option Info-url-alist
* lisp/info.el (Info-url-alist): New option mapping manuals
to URLs.
(Info-url-for-node): Use it.
* test/lisp/info-tests.el (test-info-urls): Add more tests.
In particular, 'Info-url-for-node' should error when
manual-name is not handled in 'Info-url-alist'.
* etc/NEWS: Announce the change. (Bug#67615)
| -rw-r--r-- | etc/NEWS | 9 | ||||
| -rw-r--r-- | lisp/info.el | 108 | ||||
| -rw-r--r-- | test/lisp/info-tests.el | 14 |
3 files changed, 105 insertions, 26 deletions
| @@ -436,6 +436,15 @@ only to specify the 'mouse-4/5/6/7' events generated by older | |||
| 436 | configurations such as X11 when the X server does not support at least | 436 | configurations such as X11 when the X server does not support at least |
| 437 | version 2.1 of the X Input Extension, and 'xterm-mouse-mode'. | 437 | version 2.1 of the X Input Extension, and 'xterm-mouse-mode'. |
| 438 | 438 | ||
| 439 | ** Info | ||
| 440 | |||
| 441 | --- | ||
| 442 | *** New user option 'Info-url-alist'. | ||
| 443 | This user option associates manual-names with URLs. It affects the | ||
| 444 | 'Info-goto-node-web' command. By default, associations for all | ||
| 445 | Emacs-included manuals are set. Further associations can be added for | ||
| 446 | arbitrary Info manuals. | ||
| 447 | |||
| 439 | +++ | 448 | +++ |
| 440 | ** New command 'lldb'. | 449 | ** New command 'lldb'. |
| 441 | Run the LLDB debugger, analogous to the 'gud-gdb' command. | 450 | Run the LLDB debugger, analogous to the 'gud-gdb' command. |
diff --git a/lisp/info.el b/lisp/info.el index e56344825b9..e91cc7b8e54 100644 --- a/lisp/info.el +++ b/lisp/info.el | |||
| @@ -213,6 +213,53 @@ a version of Emacs without installing it.") | |||
| 213 | These directories are searched after those in `Info-directory-list'." | 213 | These directories are searched after those in `Info-directory-list'." |
| 214 | :type '(repeat directory)) | 214 | :type '(repeat directory)) |
| 215 | 215 | ||
| 216 | (defcustom Info-url-alist | ||
| 217 | '((("auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x" | ||
| 218 | "ebrowse" "ede" "ediff" "edt" "efaq" "efaq-w32" "eglot" "eieio" | ||
| 219 | "eintr" "elisp" "emacs" "emacs-gnutls" "emacs-mime" "epa" "erc" | ||
| 220 | "ert" "eshell" "eudc" "eww" "flymake" "forms" "gnus" | ||
| 221 | "htmlfontify" "idlwave" "ido" "info" "mairix-el" "message" | ||
| 222 | "mh-e" "modus-themes" "newsticker" "nxml-mode" "octave-mode" | ||
| 223 | "org" "pcl-cvs" "pgg" "rcirc" "reftex" "remember" "sasl" "sc" | ||
| 224 | "semantic" "ses" "sieve" "smtpmail" "speedbar" "srecode" | ||
| 225 | "todo-mode" "tramp" "transient" "url" "use-package" "vhdl-mode" | ||
| 226 | "vip" "viper" "vtable" "widget" "wisent" "woman") . | ||
| 227 | "https://www.gnu.org/software/emacs/manual/html_node/%m/%e")) | ||
| 228 | "Alist telling `Info-mode' where manuals are accessible online. | ||
| 229 | |||
| 230 | Each element of this list has the form (MANUALs . URL-SPEC). | ||
| 231 | MANUALs represents the name of one or more manuals. It can | ||
| 232 | either be a string or a list of strings. URL-SPEC can be a | ||
| 233 | string in which the substring \"%m\" will be expanded to the | ||
| 234 | manual-name, \"%n\" to the node-name, and \"%e\" to the | ||
| 235 | URL-encoded node-name (without a `.html' suffix). (The | ||
| 236 | URL-encoding of the node-name mimics GNU Texinfo, as documented | ||
| 237 | at Info node `(texinfo)HTML Xref Node Name Expansion'.) | ||
| 238 | Alternatively, URL-SPEC can be a function which is given | ||
| 239 | manual-name, node-name and URL-encoded node-name as arguments, | ||
| 240 | and is expected to return the corresponding URL as a string. | ||
| 241 | |||
| 242 | This variable particularly affects the command | ||
| 243 | `Info-goto-node-web', which see. | ||
| 244 | |||
| 245 | The default value of this variable refers to the official, | ||
| 246 | HTTPS-accessible HTML-representations of all manuals that Emacs | ||
| 247 | includes. These URLs refer to the most recently released version | ||
| 248 | of Emacs, disregarding the version of the running Emacs. In | ||
| 249 | other words, the content of your local Info node and the | ||
| 250 | associated online node may differ. The resource represented by | ||
| 251 | the generated URL may even be not found by the gnu.org server." | ||
| 252 | :version "30.1" | ||
| 253 | :type '(alist | ||
| 254 | :tag "Mapping from manual-name(s) to URL-specification" | ||
| 255 | :key-type (choice | ||
| 256 | (string :tag "A single manual-name") | ||
| 257 | (repeat :tag "List of manual-names" string)) | ||
| 258 | :value-type (choice | ||
| 259 | (string :tag "URL-specification string") | ||
| 260 | (function | ||
| 261 | :tag "URL-specification function")))) | ||
| 262 | |||
| 216 | (defcustom Info-scroll-prefer-subnodes nil | 263 | (defcustom Info-scroll-prefer-subnodes nil |
| 217 | "If non-nil, \\<Info-mode-map>\\[Info-scroll-up] in a menu visits subnodes. | 264 | "If non-nil, \\<Info-mode-map>\\[Info-scroll-up] in a menu visits subnodes. |
| 218 | 265 | ||
| @@ -1854,33 +1901,50 @@ By default, go to the current Info node." | |||
| 1854 | (Info-url-for-node (format "(%s)%s" filename node))))) | 1901 | (Info-url-for-node (format "(%s)%s" filename node))))) |
| 1855 | 1902 | ||
| 1856 | (defun Info-url-for-node (node) | 1903 | (defun Info-url-for-node (node) |
| 1857 | "Return a URL for NODE, a node in the GNU Emacs or Elisp manual. | 1904 | "Return the URL corresponding to NODE. |
| 1858 | NODE should be a string on the form \"(manual)Node\". Only emacs | 1905 | |
| 1859 | and elisp manuals are supported." | 1906 | NODE should be a string of the form \"(manual)Node\"." |
| 1860 | (unless (string-match "\\`(\\(.+\\))\\(.+\\)\\'" node) | 1907 | ;; GNU Texinfo skips whitespaces and newlines between the closing |
| 1861 | (error "Invalid node name %s" node)) | 1908 | ;; parenthesis and the node-name, i.e. space, tab, line feed and |
| 1862 | (let ((manual (match-string 1 node)) | 1909 | ;; carriage return. |
| 1863 | (node (match-string 2 node))) | 1910 | (unless (string-match "\\`(\\(.+\\))[ \t\n\r]*\\(.+\\)\\'" node) |
| 1864 | (unless (member manual '("emacs" "elisp")) | 1911 | (error "Invalid node-name %s" node)) |
| 1865 | (error "Only emacs/elisp manuals are supported")) | 1912 | ;; Use `if-let*' instead of `let*' so we check if an association was |
| 1866 | ;; Encode a bunch of characters the way that makeinfo does. | 1913 | ;; found. |
| 1867 | (setq node | 1914 | (if-let* ((manual (match-string 1 node)) |
| 1868 | (mapconcat (lambda (ch) | 1915 | (node (match-string 2 node)) |
| 1869 | (if (or (< ch 32) ; ^@^A-^Z^[^\^]^^^- | 1916 | (association (seq-find |
| 1917 | (lambda (pair) | ||
| 1918 | (seq-contains-p (ensure-list (car pair)) | ||
| 1919 | manual #'string-equal-ignore-case)) | ||
| 1920 | Info-url-alist)) | ||
| 1921 | (url-spec (cdr association)) | ||
| 1922 | (encoded-node | ||
| 1923 | ;; Reproduce GNU Texinfo's way of URL-encoding. | ||
| 1924 | ;; (info "(texinfo) HTML Xref Node Name Expansion") | ||
| 1925 | (if (equal node "Top") | ||
| 1926 | "" | ||
| 1927 | (url-hexify-string | ||
| 1928 | (string-replace " " "-" | ||
| 1929 | (mapconcat | ||
| 1930 | (lambda (ch) | ||
| 1931 | (if (or (< ch 32) ; ^@^A-^Z^[^\^]^^^- | ||
| 1870 | (<= 33 ch 47) ; !"#$%&'()*+,-./ | 1932 | (<= 33 ch 47) ; !"#$%&'()*+,-./ |
| 1871 | (<= 58 ch 64) ; :;<=>?@ | 1933 | (<= 58 ch 64) ; :;<=>?@ |
| 1872 | (<= 91 ch 96) ; [\]_` | 1934 | (<= 91 ch 96) ; [\]_` |
| 1873 | (<= 123 ch 127)) ; {|}~ DEL | 1935 | (<= 123 ch 127)) ; {|}~ DEL |
| 1874 | (format "_00%x" ch) | 1936 | (format "_00%x" ch) |
| 1875 | (char-to-string ch))) | 1937 | (char-to-string ch))) |
| 1876 | node | 1938 | node "")))))) |
| 1877 | "")) | 1939 | (cond |
| 1878 | (concat "https://www.gnu.org/software/emacs/manual/html_node/" | 1940 | ((stringp url-spec) |
| 1879 | manual "/" | 1941 | (format-spec url-spec |
| 1880 | (and (not (equal node "Top")) | 1942 | `((?m . ,manual) (?n . ,node) (?e . ,encoded-node)))) |
| 1881 | (concat | 1943 | ((functionp url-spec) |
| 1882 | (url-hexify-string (string-replace " " "-" node)) | 1944 | (funcall url-spec manual node encoded-node)) |
| 1883 | ".html"))))) | 1945 | (t (error "URL-specification neither string nor function"))) |
| 1946 | (error "No URL-specification associated with manual-name `%s'" | ||
| 1947 | manual))) | ||
| 1884 | 1948 | ||
| 1885 | (defvar Info-read-node-completion-table) | 1949 | (defvar Info-read-node-completion-table) |
| 1886 | 1950 | ||
diff --git a/test/lisp/info-tests.el b/test/lisp/info-tests.el index ebe718167bf..0dfdbf417e8 100644 --- a/test/lisp/info-tests.el +++ b/test/lisp/info-tests.el | |||
| @@ -29,11 +29,17 @@ | |||
| 29 | 29 | ||
| 30 | (ert-deftest test-info-urls () | 30 | (ert-deftest test-info-urls () |
| 31 | (should (equal (Info-url-for-node "(emacs)Minibuffer") | 31 | (should (equal (Info-url-for-node "(emacs)Minibuffer") |
| 32 | "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer.html")) | 32 | "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer")) |
| 33 | (should (equal (Info-url-for-node "(emacs)Minibuffer File") | 33 | (should (equal (Info-url-for-node "(emacs)Minibuffer File") |
| 34 | "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-File.html")) | 34 | "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-File")) |
| 35 | (should (equal (Info-url-for-node "(elisp)Backups and Auto-Saving") | 35 | (should (equal (Info-url-for-node "(elisp)Backups and Auto-Saving") |
| 36 | "https://www.gnu.org/software/emacs/manual/html_node/elisp/Backups-and-Auto_002dSaving.html")) | 36 | "https://www.gnu.org/software/emacs/manual/html_node/elisp/Backups-and-Auto_002dSaving")) |
| 37 | (should-error (Info-url-for-node "(gnus)Minibuffer File"))) | 37 | (should (equal (Info-url-for-node "(eintr)car & cdr") |
| 38 | "https://www.gnu.org/software/emacs/manual/html_node/eintr/car-_0026-cdr")) | ||
| 39 | (should (equal (Info-url-for-node "(emacs-mime)\tIndex") | ||
| 40 | "https://www.gnu.org/software/emacs/manual/html_node/emacs-mime/Index")) | ||
| 41 | (should (equal (Info-url-for-node "(gnus) Don't Panic") | ||
| 42 | "https://www.gnu.org/software/emacs/manual/html_node/gnus/Don_0027t-Panic")) | ||
| 43 | (should-error (Info-url-for-node "(nonexistent)Example"))) | ||
| 38 | 44 | ||
| 39 | ;;; info-tests.el ends here | 45 | ;;; info-tests.el ends here |