88 lines
3.7 KiB
Org Mode
88 lines
3.7 KiB
Org Mode
#+TITLE: Emacs IETF
|
|
#+DATE: 2023-04-05
|
|
* Prologue
|
|
Some years ago I discovered [[https://github.com/paulehoffman/ietf-cli][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 pager[fn::Like normal people... I uses emacsclient for
|
|
performance reasons.].
|
|
|
|
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 =ietf= tool:
|
|
1. I never figured out how to configure tab-completion in my shell for it.
|
|
2. 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.
|
|
3. 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= or =ietf rfc1925=. That means that
|
|
copy & paste does not work most of the time.
|
|
|
|
More recently I discovered the [[https://github.com/minad/vertico][vertico]] completion extension combined
|
|
with [[https://github.com/oantolin/orderless][orderless]] completion. Those two extensions provide the kind of
|
|
completion I want for RFCs and even more so for drafts:
|
|
#+begin_quote
|
|
[Orderless] divides the pattern into space-separated components, and
|
|
matches candidates that match all of the components in any order.
|
|
#+end_quote
|
|
* Emacs-lisp
|
|
The =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
|
|
=find-file=, change =default-directory= and we are good to go:
|
|
|
|
#+begin_src emacs-lisp
|
|
;; 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)))
|
|
#+end_src
|
|
|
|
Setting a global key binding lets us open RFCs and drafts from
|
|
anywhere within Emacs:
|
|
#+begin_src emacs-lisp
|
|
(global-set-key (kbd "C-c i d") 'ietf-draft)
|
|
(global-set-key (kbd "C-c i r") 'ietf-rfc)
|
|
#+end_src
|
|
* Epilogue
|
|
The =ietf= tool has many more options that I have not explored or used
|
|
yet. =rfc= and =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
|
|
improvement.
|