Index Emagician Base Install Meta Interface Programming Text Org Lamp Journal Snippets jonnay.netFork on Github


Table of Contents

1 Base Initialization and Circle Casting

(defconst emagician/version "0.23.2")

This is my emacs. There are many like it, but this one is mine.

1.1 Breakage Helpers

Debug Errors. Super fundamental.

(setq debug-on-error t)

1.1.1 Scratch messaging

Snarfed this idea from

​‌డ(°益°)హ ,( Bro, Even if you're swol, it doesn't mean you're a bro, bro. )

It's a super great idea to use the scratch buffer as a way to communicate state to the user. For now we need simple functions that are not prone to breaking.

First step is to inhibit the splash. We're making our own splash!

(setq inhibit-splash-screen t)

Now a basic scratch message. If things go pants-up here, we want a basic message saying so.

(setq initial-stratch-message
      (concat ";;; -X-x-X- Invokaction SuperFailure! -X-x-X-" "\n"
              ";;; Problem in when setting up Breakage Helpers"))

Now that we have the basics done, lets define 2 helper functions to set or add the scratch message.

(defun emagician/set-scratch (&rest lines)
  (setq initial-scratch-message (apply 'concat lines)))

(defun emagician/append-scratch (&rest lines)
  (setq initial-scratch-message (apply 'concat initial-scratch-message lines)))

1.1.2 Pre-Scratch-Links

The scratch buffer will turn into something of a desktop. It's handy to be able to stuff "scratch links" in there. Anything in there gets output to the scratch during Thee Scratch Initiation. This is a Homestuck reference. It will be expounded upon later.

Then when Emacs loads, you can put the cursor over the sexp and C-x C-e. I use this to launch magit for work/personal projects, start vms, etc.

(defvar emagician/pre-scratch-links '()
  "A list of links to append to emagician/scratch-links.

This is necessary because we may need to communicate to the user
before the rest of the scratch interface is built.")

1.1.3 Now set it to our Baseline beautified "you're-busted" text

Okay, so this is the secret sauce. I set the scratch to this baseline helper (plus cuteness) so that I can debug startups much easier. It includes a chunk to launch emacs forcing debug-init.

  ";; -|-+-|- Invocation Failure.  Sorry. -|-+-|-" "\n"
  ";; You know what to do." "\n"
  ";; \n"
  ";; Emagician Starter kit Version: " emagician/version "\n"
  ";; Emacs: " (number-to-string emacs-major-version) "." 
      (number-to-string emacs-minor-version) 
      " [" (when emacs-repository-version (number-to-string emacs-repository-version)) "]" 
  ";; \n"
  ";;;;;;;;;;;;;;;;;;;;;;;;;;" "\n"
  ";;                      ;;" "\n"      
  ";; It's dangerous to go ;;" "\n"
  ";; alone! take this:    ;;" "\n"
  ";;                      ;;" "\n"
  ";;   🔥     👷     🔥  ;;" "\n"
  ";;          🔮          ;;" "\n"
  ";;                      ;;" "\n"
  ";;;;;;;;;;;;  ;;;;;;;;;;;;" "\n"
  "(shell-command \"" invocation-directory invocation-name " --debug-init\")\n")

1.2 Verify emagician/dir

IF this isn't around, then everything goes pear shaped. Explicitly look for it and fail with helpful messages.

(when (null emagician/dir)
  (let ((err (concat "Variable emagician/dir is not set!  This is important and should be set in " user-init-file)))
    (emagician/append-scratch ";;; " err "\n" ";;; Check the file for more details.")
    (error err)))

Now that we have the emagician/dir we can keep going and add new helpers to the scratch.

  "(find-file-other-window \"" emagician/dir "\")" "\n"
  "(find-file-other-window \"" emagician/dir "/*.org\"  t)" "\n")

1.3 Use the new improved emagician scratch.

1.3.1 Add a show-scratch function

This is generally useful anyway. We could also use initial buffer, but that has a tendency to get overridden by hooks.

(defun emagician/show-scratch ()
  "Show the scratch buffer"
  (set-window-buffer nil "*scratch*"))

(add-hook 'emacs-startup-hook 'emagician/show-scratch t)

1.4 Package Archives setup

1.4.1 TODO Figure out

We set our download dir to local-packages. We also do the trick of doing package-refresh-contents if package-archive-contents is empty.

We set the archives to the big 3 plus orgmode. MELPA, ELPA and Org! Oh My!


(defvar emagician/are-elpas-reachable? t "Whether or not ELPAs are reachable")

(setq package-user-dir (concat emagician/dir "elpa"))

(setq package-archives
      '(("gnu"         . "")
        ("MELPA"       . "")
        ("org"         . "")))


(condition-case err
    (unless package-archive-contents (package-refresh-contents))
   (let ((scratch-msg (concat ";;; !!! Couldn't refresh package contents\n"
     (message "Could not refresh package contents: %s %S" (car err) (cdr err))
     (emagician/append-scratch scratch-msg)
     (add-to-list 'emagician/pre-scratch-links scratch-msg)
     (setq emagician/are-elpas-reachable? nil))))

1.5 Load Paths, Custom Files, etc.

1.5.1 Standard Emagician distribution load paths

(add-to-list 'load-path emagician/dir)
(add-to-list 'load-path (concat emagician/dir "src"))
(add-to-list 'load-path (concat emagician/dir "dist"))
(add-to-list 'custom-theme-load-path (concat emagician/dir "themes"))

1.5.2 Custom file shouldn't matter so much anymore, but lets stick it here anyway.

(setq custom-file (concat emagician/dir "custom.el"))

2 Emagician/load

Originally from Eschulte. This function takes a <foo>.org file, and load it.

This doesn't try to load from a tag or a header arg. That got crufty for my needs.

(defvar emagician/load-depth 0)
(defvar emagician/slow-loaders '() "A list of files that took long to load with `emagician/load'")
(defun emagician/load (file)
  "Load configuration from other .org files."
  (let ((start-time (current-time))
        (file (expand-file-name (if (string-match ".+\.org" file)
                                  (format "" file))
        (load-result nil)
        (emagician/load-depth (1+ emagician/load-depth))
        (org-babel-default-header-args (cons '(:comments . "link") 
                                             (assq-delete-all :comment
    (if (file-exists-p file)
          (emagician/append-scratch "\n;; "
                                    (make-string emagician/load-depth ?-)
                                    " Loading " file)
          (setq load-result (org-babel-load-file file)))
        (emagician/append-scratch "\n;; "
                                  (make-string emagician/load-depth ?-)
                                  "Skipped Loading "
                                  " It doesn't exist!\n")
        (setq load-result nil)))
    (let ((elapsed (float-time (time-subtract (current-time)
      (when (> elapsed 3.2)
        (add-to-list 'emagician/slow-loaders (cons file elapsed)))
      (message (format "Emagician/Loaded %s %.3fs elapsed" 
    (emagician/append-scratch "...done!" "\n")

3 Package Management

3.1 Emagician Expect, for bootstrapping

This is almost vestigial.

(defun emagician/expect-package (package)
  "If the named PACKAGE isn't currently installed, install it"
  (unless (package-installed-p package)
    (package-install package)))  

Mainly due to…

3.2 😻 Use-Package 😻

Is the cat's ass. Why would you not use it?

(setq use-package-always-ensure emagician/are-elpas-reachable?)
(emagician/expect-package 'use-package)

4 Emagician Starter Kit has it's own Helper Functions

(emagician/load "")

5 Assets

Assets are either

  1. org files that tangle assets into a directory or
  2. files that are distributed with the starter kit.

In the case of #1, we want the assets directory to be destroyed and rebuilt everytime. In the case of #2, it should be in source control

6 Key Concepts

  • The Bunny of ÆSÞETIC
  • The Bunny of Discoverability
  • The Bunny of Mise en Place

7 File Layout

Most of the files will have a layout similar to this:

7.1 Interface

There is both an Interface file to handle the general emacs UI and sections inside of individual files.

Key related commands.
anything visible, modeline, titlebar, theme, etc
about inserting and using text, including snippets and autocomplete
Moving the mark. This includes searching.
All about backups.
State Management
Persist state across emacs sessions.
Help and Discoverability
Getting more help with emacs, and learning commands better.

7.2 Tools

External or Internal. Think of tools as being less about Editing of text and more about getting a particular job done.

There is no global tools file. But maybe There should be, and E-Shell would be in it.

8 Files

There is a fine line between too many files, and too few.

8.1 Interface

(emagician/load "")

8.2 Text

Emacs is a text editor afteral.

(emagician/load "")

8.3 Programming

This sets up some baseline programming helpers and then loads individual org files for each programming mode.

(emagician/load "")

8.4 Org Mode

Deserves it's own file… ORG GRIMOIRE!

(emagician/load "")

8.5 E-Shell

Why would you not use E-Shell?

(emagician/load "")

8.6 Lamp

The Lamp is a 5th magickal weapon along with the wand, sword, cup and chalace. It represents illumination and self knowledge.

(emagician/load "")

8.7 Emagician Starter Kit has it's own Lamp

Tools to make developing the Emagician Starter kit easier.

(emagician/load "")

9 Entity Customization

9.1 First the customization

(load custom-file)

9.2 Next is the true-name-file

(emagician/load emagician/true-name)

9.3 System Type Initialization

(emagician/load (emagician/sanitize-file-name (symbol-name system-type)))

9.4 Machine Name Initialization

(emagician/load (emagician/sanitize-file-name system-name))

9.5 Login name Initialization

(emagician/load user-login-name)

10 Some Inspirational words from the book of emacs

Liber Lisper Legis
as (R)eceived (M)ade (S)ound [RMS]
on this 15th day of December,
the Year of our Editor 2007.

Chapter 1

  1. Buf! Manifestation of Chat.
  2. All Gods Seek Her Company.
  3. Intelligent, she watches.
  4. Every act a function, there is no difference.
  5. Help me o RMS, in unveiling thee before the Needy on Earth
  6. Be thou not just my editor, but mine eyes, heart and yes, Soul.
  7. Behold from darkness and byte code interpreter thou groweth strong.
  8. The car is in the cdr, not the cdr in the car.
  9. Worship then the car and behold the Maserati of all programs ever.
  10. Thou powers known to but a few, thou public API widely advertised.
  11. Whilst others seek bells and whistles, thou sweet hum caresseth me.
  12. Open me up, list my buffers, be they ibuffer or buff-menu+
  13. No limit to the ecstasy. I EVAL ALL. `(,ALL ,@I ,EVAL!)

M-x all-hail-emacs!topic/alt.religion.emacs/Yej_PTIqekg

11 References, Bibliography, Shout Outs, and Props.

In most cases I explicitly call out where I found the config I snarfed. Sometimes I didn't. If you know the source, let me know!

Magician Source Last Visited Status
ESchultes Emacs Starter Kit    
Sacha Chu 2016-09-05 Revist
Emacs Starter Kit    
Cabbage 2016-09-05 Meh
Emacs Live    
Ryan Rix    
Lee Hinman    
Wasamasa 2016-08-26  

12 Thee End

12.0.1 Initiate thee scratch



12.0.2 Turn off debugging

We're Almost Done.

(setq debug-on-error nil)

12.0.3 So Mote it Be.

(provide 'emagician)



This is a Homestuck reference. It will be expounded upon later.

Author: Jonathan Arkell

Created: 2018-05-18 Fri 10:30