Some years ago I discovered ietf-cli in OpenBSD ports. It creates a local mirror of IETF drafts, RFCs and other files and makes them accessible from the command line. I have it configured to use Emacs for the pager1.
I was never too happy about the cli interface though. While it is open
source I never got around to hack on it or to send feature
requests. These are the things I do not like. Most of them are a
question of work flow more than limitations of the
- I never figured out how to configure tab-completion in my shell for it.
- I am not yet running a shell inside of Emacs, so it breaks my work flow when reading a draft and I want to quickly open an RFC for reference.
- The tool is pretty opinionated. You need to call just so for it do
what you ask. To open an RFC you need to type
ietf rfc 1925. It will not accept
ietf rfc1925. That means that copy & paste does not work most of the time.
More recently I discovered the vertico completion extension combined with orderless completion. Those two extensions provide the kind of completion I want for RFCs and even more so for drafts:
[Orderless] divides the pattern into space-separated components, and matches candidates that match all of the components in any order.
ietf tool provides the
mirror command that rsyncs the IETF
documents to a configurable folder. Reading an RFC or draft then
comes down to opening the correct file. So we can copy the code of
default-directory and we are good to go:
;; were ietf mirror stores the local mirror (setq ietf-mirror "~/ietf-mirror/") ;; look for drafts in the 'short-id/' sub-directory and make sure the ;; buffer is a read-only text buffer. (defun ietf-draft (filename &optional wildcards) (interactive (let ((default-directory (concat ietf-mirror "short-id/"))) (find-file-read-args "Find file: " (confirm-nonexistent-file-or-buffer)))) (let ((value (find-file-noselect filename nil nil wildcards))) (if (listp value) (mapcar 'pop-to-buffer-same-window (nreverse value)) (pop-to-buffer-same-window value)) (read-only-mode) (text-mode))) ;; RFCs are stored in 'in-notes/' (defun ietf-rfc (filename &optional wildcards) (interactive (let ((default-directory (concat ietf-mirror "in-notes/")) (completion-ignored-extensions '("/" ".html" ".json" ".pdf" ".ps" ".tar" ".xml" ".xsd"))) (find-file-read-args "Find file: " (confirm-nonexistent-file-or-buffer)))) (let ((value (find-file-noselect filename nil nil wildcards))) (if (listp value) (mapcar 'pop-to-buffer-same-window (nreverse value)) (pop-to-buffer-same-window value)) (read-only-mode) (text-mode)))
Setting a global key binding lets us open RFCs and drafts from anywhere within Emacs:
(global-set-key (kbd "C-c i d") 'ietf-draft) (global-set-key (kbd "C-c i r") 'ietf-rfc)
ietf tool has many more options that I have not explored or used
draft are the two main commands I am using and on
occasion I am using the diff tool.
I will keep the tool around to keep the mirror up2date and for the
occasional use of
diff. Having moved the functionality I use most
often into Emacs and making it behave like I want it is a huge
Like normal people… I uses emacsclient for performance reasons.