Today's Stream - Literate Configuration: A Direct Approach

In today’s stream, I’ll be making another big change to my configuration: I’m going back to a literate configuration once again!

This time I’ll take a different approach from what I did last time and attempt to generate configuration files directly into the $HOME folder without the use of a tool like GNU Stow.

Join us on YouTube or one of the following locations:

:clock1: in your time zone: Time in Athens and Fremont - Time.is

1 Like

(PS: I am not through the video yet)

For tangling I have been using this for ages and can recommend it.
It just works and is very efficient, never had to adjust anything.

https://holgerschurig.github.io/en/emacs-efficiently-untangling-elisp/

Copy of the code in case the site goes down:

;; from http://www.holgerschurig.de/en/emacs-efficiently-untangling-elisp/
;; 2023-11-02 site is not there anymore. Probably this now
;; https://holgerschurig.github.io/en/emacs-efficiently-untangling-elisp/
;; This is GPLv2. If you still don't know the details, read
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html

(defun my-tangle-section-CANCELLED ()
  "Return t if the current section header was CANCELLED, else nil."
  (save-excursion
    (if (re-search-backward "^\\*+\\s-+\\(.*?\\)?\\s-*$" nil t)
        (string-prefix-p "CANCELLED" (match-string 1))
      nil)))

;; This uses partially derived code from ob-core.el. So this snippet
;; is GPLv3 or later. If you still don't know the details, read
;; http://www.gnu.org/licenses/

(defun my-tangle-config-org (orgfile elfile)
  "This function will write all source blocks from =config.org= into
=config.el= that are ...

- not marked as :tangle no
- have a source-code of =emacs-lisp=
- doesn't have the todo-marker CANCELLED"
  (let* ((body-list ())
         (gc-cons-threshold most-positive-fixnum)
         (org-babel-src-block-regexp   (concat
                                        ;; (1) indentation                 (2) lang
                                        "^\\([ \t]*\\)#\\+begin_src[ \t]+\\([^ \f\t\n\r\v]+\\)[ \t]*"
                                        ;; (3) switches
                                        "\\([^\":\n]*\"[^\"\n*]*\"[^\":\n]*\\|[^\":\n]*\\)"
                                        ;; (4) header arguments
                                        "\\([^\n]*\\)\n"
                                        ;; (5) body
                                        "\\([^\000]*?\n\\)??[ \t]*#\\+end_src")))
    (with-temp-buffer
      (insert-file-contents orgfile)
      (goto-char (point-min))
      (while (re-search-forward org-babel-src-block-regexp nil t)
        (let ((lang (match-string 2))
              (args (match-string 4))
              (body (match-string 5))
              (canc (my-tangle-section-CANCELLED)))
          (when (and (string= lang "emacs-lisp")
                     (not (string-match-p ":tangle\\s-+no" args))
                     (not canc))
            (add-to-list 'body-list body)))))
    (with-temp-file elfile
      (insert (format ";; Don't edit this file, edit %s instead ...\n\n" orgfile))
      (apply 'insert (reverse body-list)))
    (message "Wrote %s ..." elfile)))

;; This is GPLv2. If you still don't know the details, read
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html

(let ((orgfile (concat user-emacs-directory "config.org"))
      (elfile (concat user-emacs-directory "config.el")))
  (when (or (not (file-exists-p elfile))
            (file-newer-than-file-p orgfile elfile))
    (my-tangle-config-org orgfile elfile))
  (load-file elfile))

;; This is GPLv2. If you still don't know the details, read
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html

(defun my-tangle-config-org-hook-func ()
  (when (string= "config.org" (buffer-name))
    (let ((orgfile (concat user-emacs-directory "config.org"))
          (elfile (concat user-emacs-directory "config.el")))
      (my-tangle-config-org orgfile elfile))))
(add-hook 'after-save-hook #'my-tangle-config-org-hook-func)

1 Like