diff options
| author | Lars Ingebrigtsen | 2021-11-11 08:09:59 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-11-11 13:20:38 +0100 |
| commit | bf9364a56e618277fe72c90b3a741ade8bc0d205 (patch) | |
| tree | c0c982952fef9a8ae01c24c47ba33da4a6cddbee | |
| parent | 997ca88ef44f5833f1a9a55fc3be863e7cc07a4b (diff) | |
| download | emacs-bf9364a56e618277fe72c90b3a741ade8bc0d205.tar.gz emacs-bf9364a56e618277fe72c90b3a741ade8bc0d205.zip | |
Add a command to go the gnu.org version of the info page
* lisp/info.el (Info-url-for-node):
(Info-goto-node-web): New function (bug#44895).
Based on code from Drew Adams <drew.adams@oracle.com>.
| -rw-r--r-- | etc/NEWS | 7 | ||||
| -rw-r--r-- | lisp/info.el | 47 | ||||
| -rw-r--r-- | test/lisp/info-tests.el | 39 |
3 files changed, 90 insertions, 3 deletions
| @@ -210,6 +210,13 @@ change the terminal used on a remote host. | |||
| 210 | 210 | ||
| 211 | * Changes in Specialized Modes and Packages in Emacs 29.1 | 211 | * Changes in Specialized Modes and Packages in Emacs 29.1 |
| 212 | 212 | ||
| 213 | ** Info | ||
| 214 | |||
| 215 | --- | ||
| 216 | *** New command 'Info-goto-node-web' and key binding 'W'. | ||
| 217 | This will take you to the gnu.org web server's version of the current | ||
| 218 | info node. This command only works for the Emacs and Emacs Lisp manuals. | ||
| 219 | |||
| 213 | ** vc | 220 | ** vc |
| 214 | 221 | ||
| 215 | --- | 222 | --- |
diff --git a/lisp/info.el b/lisp/info.el index 41889d6de17..28f25d0e0d4 100644 --- a/lisp/info.el +++ b/lisp/info.el | |||
| @@ -1792,7 +1792,46 @@ of NODENAME; if none is found it then tries a case-insensitive match | |||
| 1792 | (if trim (setq nodename (substring nodename 0 trim)))) | 1792 | (if trim (setq nodename (substring nodename 0 trim)))) |
| 1793 | (if transient-mark-mode (deactivate-mark)) | 1793 | (if transient-mark-mode (deactivate-mark)) |
| 1794 | (Info-find-node (if (equal filename "") nil filename) | 1794 | (Info-find-node (if (equal filename "") nil filename) |
| 1795 | (if (equal nodename "") "Top" nodename) nil strict-case))) | 1795 | (if (equal nodename "") "Top" nodename) nil strict-case))) |
| 1796 | |||
| 1797 | (defun Info-goto-node-web (node) | ||
| 1798 | "Use `browse-url' to go to the gnu.org web server's version of NODE. | ||
| 1799 | By default, go to the current Info node." | ||
| 1800 | (interactive (list (Info-read-node-name | ||
| 1801 | "Go to node (default current page): " Info-current-node)) | ||
| 1802 | Info-mode) | ||
| 1803 | (browse-url-button-open-url | ||
| 1804 | (Info-url-for-node (format "(%s)%s" (file-name-sans-extension | ||
| 1805 | (file-name-nondirectory | ||
| 1806 | Info-current-file)) | ||
| 1807 | node)))) | ||
| 1808 | |||
| 1809 | (defun Info-url-for-node (node) | ||
| 1810 | "Return a URL for NODE, a node in the GNU Emacs or Elisp manual. | ||
| 1811 | NODE should be a string on the form \"(manual)Node\". Only emacs | ||
| 1812 | and elisp manuals are supported." | ||
| 1813 | (unless (string-match "\\`(\\(.+\\))\\(.+\\)\\'" node) | ||
| 1814 | (error "Invalid node name %s" node)) | ||
| 1815 | (let ((manual (match-string 1 node)) | ||
| 1816 | (node (match-string 2 node))) | ||
| 1817 | (unless (member manual '("emacs" "elisp")) | ||
| 1818 | (error "Only emacs/elisp manuals are supported")) | ||
| 1819 | ;; Encode a bunch of characters the way that makeinfo does. | ||
| 1820 | (setq node | ||
| 1821 | (mapconcat (lambda (ch) | ||
| 1822 | (if (or (< ch 32) ; ^@^A-^Z^[^\^]^^^- | ||
| 1823 | (<= 33 ch 47) ; !"#$%&'()*+,-./ | ||
| 1824 | (<= 58 ch 64) ; :;<=>?@ | ||
| 1825 | (<= 91 ch 96) ; [\]_` | ||
| 1826 | (<= 123 ch 127)) ; {|}~ DEL | ||
| 1827 | (format "_00%x" ch) | ||
| 1828 | (char-to-string ch))) | ||
| 1829 | node | ||
| 1830 | "")) | ||
| 1831 | (concat "https://www.gnu.org/software/emacs/manual/html_node/" | ||
| 1832 | manual "/" | ||
| 1833 | (url-hexify-string (string-replace " " "-" node)) | ||
| 1834 | ".html"))) | ||
| 1796 | 1835 | ||
| 1797 | (defvar Info-read-node-completion-table) | 1836 | (defvar Info-read-node-completion-table) |
| 1798 | 1837 | ||
| @@ -1877,7 +1916,7 @@ See `completing-read' for a description of arguments and usage." | |||
| 1877 | code Info-read-node-completion-table string predicate)))) | 1916 | code Info-read-node-completion-table string predicate)))) |
| 1878 | 1917 | ||
| 1879 | ;; Arrange to highlight the proper letters in the completion list buffer. | 1918 | ;; Arrange to highlight the proper letters in the completion list buffer. |
| 1880 | (defun Info-read-node-name (prompt) | 1919 | (defun Info-read-node-name (prompt &optional default) |
| 1881 | "Read an Info node name with completion, prompting with PROMPT. | 1920 | "Read an Info node name with completion, prompting with PROMPT. |
| 1882 | A node name can have the form \"NODENAME\", referring to a node | 1921 | A node name can have the form \"NODENAME\", referring to a node |
| 1883 | in the current Info file, or \"(FILENAME)NODENAME\", referring to | 1922 | in the current Info file, or \"(FILENAME)NODENAME\", referring to |
| @@ -1885,7 +1924,8 @@ a node in FILENAME. \"(FILENAME)\" is a short format to go to | |||
| 1885 | the Top node in FILENAME." | 1924 | the Top node in FILENAME." |
| 1886 | (let* ((completion-ignore-case t) | 1925 | (let* ((completion-ignore-case t) |
| 1887 | (Info-read-node-completion-table (Info-build-node-completions)) | 1926 | (Info-read-node-completion-table (Info-build-node-completions)) |
| 1888 | (nodename (completing-read prompt #'Info-read-node-name-1 nil t))) | 1927 | (nodename (completing-read prompt #'Info-read-node-name-1 nil t nil |
| 1928 | 'Info-minibuf-history default))) | ||
| 1889 | (if (equal nodename "") | 1929 | (if (equal nodename "") |
| 1890 | (Info-read-node-name prompt) | 1930 | (Info-read-node-name prompt) |
| 1891 | nodename))) | 1931 | nodename))) |
| @@ -4067,6 +4107,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'." | |||
| 4067 | (define-key map "T" 'Info-toc) | 4107 | (define-key map "T" 'Info-toc) |
| 4068 | (define-key map "u" 'Info-up) | 4108 | (define-key map "u" 'Info-up) |
| 4069 | ;; `w' for consistency with `dired-copy-filename-as-kill'. | 4109 | ;; `w' for consistency with `dired-copy-filename-as-kill'. |
| 4110 | (define-key map "W" 'Info-goto-node-web) | ||
| 4070 | (define-key map "w" 'Info-copy-current-node-name) | 4111 | (define-key map "w" 'Info-copy-current-node-name) |
| 4071 | (define-key map "c" 'Info-copy-current-node-name) | 4112 | (define-key map "c" 'Info-copy-current-node-name) |
| 4072 | ;; `^' for consistency with `dired-up-directory'. | 4113 | ;; `^' for consistency with `dired-up-directory'. |
diff --git a/test/lisp/info-tests.el b/test/lisp/info-tests.el new file mode 100644 index 00000000000..3e2aa3e089d --- /dev/null +++ b/test/lisp/info-tests.el | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | ;;; info-tests.el --- Tests for info.el -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2021 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | ;; it under the terms of the GNU General Public License as published by | ||
| 9 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 10 | ;; (at your option) any later version. | ||
| 11 | |||
| 12 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;; GNU General Public License for more details. | ||
| 16 | |||
| 17 | ;; You should have received a copy of the GNU General Public License | ||
| 18 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 19 | |||
| 20 | ;;; Commentary: | ||
| 21 | |||
| 22 | ;; | ||
| 23 | |||
| 24 | ;;; Code: | ||
| 25 | |||
| 26 | (require 'info) | ||
| 27 | (require 'ert) | ||
| 28 | (require 'ert-x) | ||
| 29 | |||
| 30 | (ert-deftest test-info-urls () | ||
| 31 | (should (equal (Info-url-for-node "(emacs)Minibuffer") | ||
| 32 | "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer.html")) | ||
| 33 | (should (equal (Info-url-for-node "(emacs)Minibuffer File") | ||
| 34 | "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-File.html")) | ||
| 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")) | ||
| 37 | (should-error (Info-url-for-node "(gnus)Minibuffer File"))) | ||
| 38 | |||
| 39 | ;;; info-tests.el ends here | ||