2023-03-01 Emacs widget for my literature list
This is an update to my phlog post "AWK replaces LibreCalc"[1] where
I describe how I use Awk to view, sort and filter my literature list
(a basic csv-file). This works great but manually adding new books
to the list is a bit cumbersome. I always wanted to make use of the
Emacs widget library[2] and this was the perfect opportunity. So I
created a simple widget containing editable-input fields
corresponding to the column header of the csv-file. Then I added one
button to append the data row to the file and one to reset the form.
This was fun because
- I learned how to use the widget library
- I learned about buffer-local variables[3]
- I came up with an elegant way to check if a list of variables is
defined (look for boundp in the source)
- I could use a macro to refactor the code
Code
~~~~
(require 'widget)
(defmacro sulaco/generate-field-widget (VAR LENGTH)
`(progn (widget-insert (format "%s:\n" ,(capitalize VAR)))
(widget-create 'editable-field
:size ,LENGTH
:notify (lambda (this &rest ignore)
(setq-local ,(intern VAR)
(widget-value this))))
(widget-insert "\n")))
(defun sulaco/add-book ()
"Create a widget to append a new entry to literaturliste.csv."
(interactive)
(if (not (get-buffer "*Add Book Form*"))
(progn
(switch-to-buffer "*Add Book Form*")
(kill-all-local-variables)
(let ((inhibit-read-only t))
(erase-buffer))
(sulaco/generate-field-widget "author" 60)
(sulaco/generate-field-widget "title" 60)
(sulaco/generate-field-widget "year" 5)
(sulaco/generate-field-widget "language" 20)
(sulaco/generate-field-widget "epoch" 20)
(sulaco/generate-field-widget "type" 20)
(sulaco/generate-field-widget "date-read" 20)
(sulaco/generate-field-widget "annotation" 60)
(widget-insert "\n")
(widget-create
'push-button
:notify (lambda (&rest ignore)
(let ((output-line (mapconcat
(lambda (x)
(if (boundp x) (symbol-value x) ""))
'(author title year language epoch type
date-read annotation)
"\t")))
(append-to-file
(concat output-line "\n")
nil "~/Dokumente/literaturliste.csv")))
"Add book")
(widget-create 'push-button
:notify (lambda (&rest ignore)
(progn
(kill-buffer (current-buffer))
(sulaco/add-book)))
"Reset Form")
(use-local-map widget-keymap)
(widget-setup)
(goto-char 9))
;; else
(switch-to-buffer "*Add Book Form*")))
Screenshot
~~~~~~~~~~
Author:
____________________________________
Title:
____________________________________
Year:
_____
Language:
______________________
Epoch:
______________________
Type:
______________________
Date-Read:
______________________
Annotation:
____________________________________
[Add book][Reset Form]
U:@**- *Add Book Form* All (2,0) (Fundamental)
Footnotes
~~~~~~~~~
[1]
gopher://tilde.club/0/~sulaco/phlog/9993-2023-02-12-AWK_replaces_LibreCalc
[2]
https://www.gnu.org/software/emacs/manual/html_mono/widget.html
or C-h i s widget RET RET
[3]
https://www.gnu.org/software/emacs/manual/html_node/elisp/Buffer_002dLocal-Variables.html
or C-h i s elisp RET RET s buffer-local RET RET