aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2021-11-11 08:09:59 +0100
committerLars Ingebrigtsen2021-11-11 13:20:38 +0100
commitbf9364a56e618277fe72c90b3a741ade8bc0d205 (patch)
treec0c982952fef9a8ae01c24c47ba33da4a6cddbee
parent997ca88ef44f5833f1a9a55fc3be863e7cc07a4b (diff)
downloademacs-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/NEWS7
-rw-r--r--lisp/info.el47
-rw-r--r--test/lisp/info-tests.el39
3 files changed, 90 insertions, 3 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 20e6b7da7b5..1dfdf640629 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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'.
217This will take you to the gnu.org web server's version of the current
218info 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.
1799By 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.
1811NODE should be a string on the form \"(manual)Node\". Only emacs
1812and 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.
1882A node name can have the form \"NODENAME\", referring to a node 1921A node name can have the form \"NODENAME\", referring to a node
1883in the current Info file, or \"(FILENAME)NODENAME\", referring to 1922in 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
1885the Top node in FILENAME." 1924the 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