-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget-rfc.el
252 lines (208 loc) · 7.91 KB
/
get-rfc.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
;;; get-rfc.el --- Getting and viewing RFCs
;; This file is NOT part of Emacs.
;; Copyright (C) 2002, 2003, 2011 Lawrence Mitchell <[email protected]>
;; Filename: get-rfc.el
;; Version: 1.14
;; Author: Lawrence Mitchell <[email protected]>
;; Created: 2002-04-16
;; Keywords: convenience RFCs
;; COPYRIGHT NOTICE
;; 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 of the License, 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. http://www.gnu.org/copyleft/gpl.html
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If you did not, write to the Free Software
;; Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
;;; Commentary:
;; This is a tiny little package to alleviate the pain of having to
;; switch out of Emacs if you want to view an RFC.
;; It prompts you for a RFC number and pops up a new buffer with said RFC.
;; You can specify whether you want to find RFCs locally or on the
;; internet, in either case the RFC is still opened in Emacs.
;;
;; Note, you need a working wget type program to get a remote RFC and
;; view it in Emacs. If you don't have one, set the variable
;; `get-rfc-no-wget' to t (in this case, a browser will be opened up
;; to view the RFC.)
;;
;; If you do view RFCs in Emacs, rfcview.el is a useful package that
;; formats them nicely, available at
;; <URL:http://www.neilvandyke.org/rfcview/rfcview.el>
;;
;; Two commands are provided:
;; `get-rfc-view-rfc' -- Prompts for an RFC number and then displays
;; it in a new frame.
;; `get-rfc-view-rfc-at-point' -- Displays the RFC number at point in
;; a new frame.
;; `get-rfc-grep-rfc-index' -- Greps for the occurrence of a string in
;; the file rfc-index.txt.
;;
;; To use this file, place it somewhere in your load path, and then
;; add the following to your .emacs
;; (autoload 'get-rfc-view-rfc "get-rfc" "Get and view an RFC" t nil)
;; (autoload 'get-rfc-view-rfc-at-point "get-rfc" "View the RFC at point" t nil)
;; (autoload 'get-rfc-grep-rfc-index "get-rfc" "Grep rfc-index.txt" t nil)
;; You can then bind these functions to a key.
;;; History:
;;
;;; Code:
;;;
;;; User variables
;;;
(defgroup get-rfc nil
"Getting RFCs from within Emacs."
:group 'convenience)
(defcustom get-rfc-rfcs-local-flag t
"*Non-nil means RFCs are available locally.
If this variable is t you will need to set
`get-rfc-local-rfc-directory' appropriately."
:group 'get-rfc
:type 'boolean)
(defcustom get-rfc-remote-rfc-directory "http://www.ietf.org/rfc/"
"*Where to find RFCs on the WWW.
This *must* end in a trailing slash."
:group 'get-rfc
:type 'string)
(defcustom get-rfc-remote-rfc-index
"http://www.isi.edu/in-notes/rfc-index.txt"
"*Where to find the file \"rfc-index.txt\" which lists all currently
available RFCS.
You probably want to change this to point to a site nearer you."
:group 'get-rfc
:type 'string)
(defcustom get-rfc-wget-program "wget"
"*The wget program `get-rfc' should use to fetch an RFC from the WWW."
:group 'get-rfc
:type 'string)
(defcustom get-rfc-no-wget nil
"Set this to non-nil if you don't have a working wget.
If this variable is non-nil, getting a remote RFC will call your
favourite browser (via `browse-url')."
:group 'get-rfc
:type 'boolean)
(defcustom get-rfc-wget-output-flag "-O"
"*Flag to pass to `get-rfc-wget-program' to output a downloaded file
to a specified filename."
:group 'get-rfc
:type 'string)
(defcustom get-rfc-local-rfc-directory "/usr/local/rfcs/"
"*Directory in which RFCs are available locally.
This *must* end in a trailing slash."
:group 'get-rfc
:type 'string)
(defcustom get-rfc-view-rfc-mode nil
"*Mode for viewing RFCs.
Set this to the name of your favourite mode for viewing RFCs."
:group 'get-rfc
:type 'symbol)
(defcustom get-rfc-open-in-new-frame t
"*Whether or not get-rfc should open a new frame to view an RFC."
:group 'get-rfc
:type 'boolean)
(defcustom get-rfc-save-new-rfcs-locally t
"*Whether or not get-rfc should save newly downloaded RFCs.
Files are saved in `get-rfc-local-rfc-directory' (q.v.)."
:group 'get-rfc
:type 'boolean)
;;;
;;; Internal variables
;;;
(defvar get-rfc-rfc-index "rfc-index.txt"
"*The file name of the index of RFCs.")
(defvar get-rfc-grep-command "grep"
"*The grep command to use.")
(defvar get-rfc-grep-flags "-n -e"
"*Flags to pass to grep.")
(defconst get-rfc-version
"1.14"
"get-rfc.el's version number.")
;;;
;;; Internal functions
;;;
(defun get-rfc (rfc &optional fullpath)
"Get RFC from `get-rfc-remote-rfc-directory'.
If FULLPATH is non-nil, then assume that RFC is an absolute location.
Return the file it was saved in, so we can do
\(find-file (get-rfc \"foo\"))."
(let ((rfc-full (concat (if (not fullpath)
get-rfc-remote-rfc-directory)
rfc))
(tmp-file (make-temp-file "get-rfc")))
(if get-rfc-no-wget
(browse-url rfc-full)
(call-process get-rfc-wget-program nil nil nil
rfc-full (concat get-rfc-wget-output-flag tmp-file))
(when get-rfc-save-new-rfcs-locally
(let ((file (concat get-rfc-local-rfc-directory rfc)))
(copy-file tmp-file file)
(setq tmp-file file)))
tmp-file)))
;;;
;;; User functions
;;;
(defun get-rfc-version (&optional arg)
"Print Get RFCs version number in the minibuffer.
If optional ARG is non-nil, insert in current buffer."
(interactive "*P")
(if arg
(insert "\n" get-rfc-version "\n")
(message get-rfc-version)))
;;;###autoload
(defun get-rfc-view-rfc (number)
"View RFC NUMBER.
You can specify whether RFCs are available locally by setting
`get-rfc-rfcs-local-flag' to t. If you do so you should also set
`get-rfc-local-rfc-directory' to point to the relevant directory.
You may also specify where on the web to find RFCs by setting
`get-rfc-remote-rfc-directory' appropriately."
(interactive "sWhich RFC number: ")
(let* ((rfc (concat "rfc"number".txt"))
(rfc-abs (concat (if get-rfc-rfcs-local-flag
get-rfc-local-rfc-directory
get-rfc-remote-rfc-directory)
rfc))
(find-file-command (if get-rfc-open-in-new-frame
'find-file-other-frame
'find-file)))
(if get-rfc-rfcs-local-flag
(if (file-exists-p rfc-abs)
(funcall find-file-command rfc-abs)
(funcall find-file-command (get-rfc rfc)))
(funcall find-file-command (get-rfc rfc))))
(if get-rfc-view-rfc-mode
(funcall get-rfc-view-rfc-mode)))
;;;###autoload
(defun get-rfc-view-rfc-at-point ()
"View the RFC whose number is at point."
(interactive)
(condition-case err ; in case there is no word at point
(let ((rfc (thing-at-point 'word)))
(and (string-match "[^0-9]+" rfc)
(setq rfc (replace-match "" nil t rfc)))
(if (string= "" rfc)
(message "There's no RFC here!")
(get-rfc-view-rfc rfc)))
(wrong-type-argument
(message "There's no RFC here!"))))
;;;###autoload
(defun get-rfc-grep-rfc-index (string)
"Grep for STRING in rfc-index.txt."
(interactive "sSearch for: ")
(let ((grep-args (concat get-rfc-grep-command
" -i " get-rfc-grep-flags " \""
string "\" "
(if get-rfc-rfcs-local-flag
(concat get-rfc-local-rfc-directory
get-rfc-rfc-index)
(get-rfc
get-rfc-remote-rfc-directory t)))))
(grep grep-args)))
(provide 'get-rfc)
;;; get-rfc.el ends here