bootstrap.org 3.49 KB

Bootstrap The Machines

If you haven’t yet, be sure to checkout the README as it explains why I’m using literate programming in the first place and how to best traverse my org files.

Bootstrapping first uses org-babel-tangle to generate dotfile files based on their :tangle: property. It generates:

  • .emacs.d/init.el. This is automatically read by Emacs on startup and will evaluate emacs.org on opening or re-evaluating .emacs.d/init.el (this can be done with C-x C-r as can be found in the keybindings).
  • All of my other normal dotfiles.

After that, based on the certain information about a machine, specific org files will be run. For example, if I’m on a darwin machine (OSX) at the time of bootstrapping, run osx-defaults.org to set all of my desired configuration for OSX machines.

init.el

This file is where all of the Emacs config magic happens. It’s a thin emacs-lisp file that evaluates the contents of my emacs.org file so I can edit the emacs.org file, refresh my .emacs.d/init.el with C-x C-r and minimize the amount of restarts or convoluted tangling of all of my config.

First, as with all of my tangled files ake sure it’s clear that this file is auto-generated.

;;; AUTO-GENERATED FROM dotfiles/bootstrap.org

package-initialize sets up the load-paths and autoloads for installed packages. It’s a good way to make sure you don’t get undefined variables or functions at load time.

(package-initialize)

Evaluate emacs/init.org

Now we’ll create a temporary buffer with the emacs/init.org contents…

(with-temp-buffer
  (insert-file "~/src/gitlab.com/chaseadamsio/dotfiles/emacs.org")

start at the point-min or first accessible point in the buffer and go forward one line until we’ve reached the end of the buffer (eobp)…

(goto-char (point-min))
(while (not (eobp))
  (forward-line 1)

If it finds #+BEGIN_SRC emacs-lisp, which is the source code block for emacs-lisp, find to the end of the block (#+END_SRC) and eval that region that we’ve just found…

(cond
 ((looking-at "^#\\+BEGIN_SRC +emacs-lisp *$")
  (let ((l (match-end 0)))
    (search-forward "\n#+END_SRC")
    (eval-region l (match-beginning 0)))))

and finally, close out the emacs-lisp expression from the previous src blocks form above.

))

And that’s all there is to it!

Tangle Configuration Files

Ideally, all of the files would be generated by a push of a button, but I’m not there yet and I’m still honing in the rest of my emacs config, which is more pressing.

To Tangle Files

Open the buffer and run C-c C-v t. This will generate output into the filename that’s in the :tangle: property for the heading.

To Evaluate Files

This one is a little tricky. For files that need to be evaluated as shell scripts (such as osx-defaults.org), every source block needs to be visited and have C-c C-c followed by yes. Ideally, the way init.el is loaded could also be a function that takes a files to read and retrofitted to do for shell what init.el does for emacs-lisp.

Programatically tangle *.org files

Programatically evaluate files that only need to be evaluated (such as osx-defaults.org)