Emacs Configuration
Table of Contents
Introduction
I like Emacs, but slowly I have accumulated around 15 000 lines of code written in Emacs lisp in my personal configuration. I have also added (some) unit tests and broke it into a file tree. This works rather well, but this is also sort of limited and troublesome as it
This will basically comprise the public section of my Emacs configuration. Currently there's not too much here.
Components
Here's a quick listing of the various components to my setup. This list is comprised of various sets of features that I want loaded, in essence a list of porcelains. These then go on to load the various libraries I have written to actually execute the code.
Component | Description |
---|---|
world-wide-web | A collection of web search and display tools. |
styling | The styling for my Emacs configuration. |
Plans
TODO Memex
Personal wiki (Memex) source code added to the public portion of my website.
TODO Core Feature Code
Core features of my configuration including package loading, EXWM
, and other similar things.
TODO Aesthetics Code
The rest of the code covering the aesthetics of my development environment.
TODO Unify Lookup Code
I would like to eventually unify all of my lookup code into one set of lookup code.
Fancy Loading
This is currently a work in progress, but basically it provides a fancy function that uses tables in org-mode buffers to define certain common tasks such as variable assignment or dependency specification for a file.
org-bable-execute:org
I like to occasionally include org-mode blocks as variables for my configuration (mostly for templates) so I have written a little function that basically just returns a string containing the body.
(defun org-babel-execute:org (body params) body)
ec-load-deps
Generally I like to declare my dependencies in a table at the start of my file (as you can see above) because it allows me to link to them, have commentary on what they do, and generally looks nicer than a list of strings. However, to make this possible I need to process the list a little bit.
Eventually I might add a system to lazy-load them (presumably with an extra column as a falg to indicate it), but for now this will do.
This also returns a list of the loaded dependencies to allow me to wrap the loaded code within the
(defun ec-load-deps (deps-list) "Load dependencies from DEPS-LIST." (let ((link-contents-rx (rx (or (seq "[" (or (seq "id:" (* (any "-" "0-9" "a-f"))) (seq "https://" (* (or "." (not "]"))))) "]") "[" "]")))) (->> deps-list (-map 'car) (-map (lambda (dep) (let ((stripped-dep (s-replace-regexp link-contents-rx "" dep))) (if (s-matches? (rx (or "https://" "http://")) dep) (progn (eval `(use-package ,(intern stripped-dep))) stripped-dep) (progn (org-babel-load-file (format "econf-%s.org" stripped-dep)) (delete-file (format "econf-%s.el" stripped-dep)) ;; immediately delete file once I am done with it stripped-dep))))))))
ec-set-variables
This parses the contents of a table to a series of setq statements which will be joined together into a function that is then evaluated.
(defun ec-set-variables (vars-list) (-map (lambda (v) (let ((val (cadr v))) (set (read (s-replace "~" "" (car v))) (if (eq (type-of val) 'string) (eval (read (s-replace "~" "" val))) val)))) vars-list))
ec-bind-keys
Another function for processing tables, in this case binding keys in the tables.
(defun ec-bind-keys (bindings-list keymap) (-map (lambda (p) (bind-key (kbd (car p)) (intern (cadr p)) keymap)) bindings-list))
ec-literate-load
Now for the literate loading function. 1 Note that this is heavily WIP and doesn't work right now This goes over the list of different functions and then evaluates them if they are src blocks and processes them if they are a table into.
(defun ec-parse-table (tbl) "Convert the org-element table TBL into a babel table." (with-temp-buffer (insert (org-element-interpret-data tbl)) (org-babel-read-table))) (defun ec-literate-load (file) "Load FILE with special literate functions." (let* ((org-obj (with-temp-buffer (insert-file-contents file) (org-element-parse-buffer))) (deps-list (org-element-map org-obj 'table (lambda (e) (let* ((tbl (ec-parse-table e)) (tbl-head (-take-while (lambda (row) (not (equal row 'hline))) tbl)) (tbl-body (-take-while (lambda (row) (not (equal row 'hline))) (reverse tbl)))) (when (equal tbl-head '("Dependency" "Description")) (ec-load-deps tbl-body))))))) (-> org-obj (org-element-map '(table src-block) (lambda (e) (if (eq (org-element-type e) 'src-block) (read (org-element-property :value e)) (let* ((tbl (ec-parse-table e)) (tbl-head (-take-while (lambda (row) (not (equal row 'hline))) tbl)) (tbl-body (-take-while (lambda (row) (not (equal row 'hline))) (reverse tbl)))) (cond ((equal (car tbl-head) '("Variable" "Value")) (ec-set-variables tbl-body)) ((equal (cadr tbl-head) '("Chord" "Function")) (ec-bind-keys tbl-body (intern (caar tbl-head))))))))) -concat)))
Initialization Code
This code is used to load the code in the components list automatically.
(ec-load-deps components)