(defconst emagician/version "0.23.2")
This is my emacs. There are many like it, but this one is mine.
Debug Errors. Super fundamental.
(setq debug-on-error t)
Snarfed this idea from https://github.com/overtone/emacs-live.
డ(°益°)హ ,( 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 Emagician.org 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)))
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.[fn:1]
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.")
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.
(emagician/set-scratch
";; -|-+-|- 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"
";; ;;" "\n"
";; It's dangerous to go ;;" "\n"
";; alone! take this: ;;" "\n"
";; ;;" "\n"
";; 🔥 👷 🔥 ;;" "\n"
";; 🔮 ;;" "\n"
";; ;;" "\n"
";;;;;;;;;;;; ;;;;;;;;;;;;" "\n"
"\n"
"(shell-command \"" invocation-directory invocation-name " --debug-init\")\n")
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 Emagician-Install.org for more details.")
(error err)))
Now that we have the emagician/dir we can keep going and add new helpers to the scratch.
(emagician/append-scratch
"\n"
"(find-file-other-window \"" emagician/dir "\")" "\n"
"(find-file-other-window \"" emagician/dir "/*.org\" t)" "\n")
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"
(interactive)
(set-window-buffer nil "*scratch*"))
(add-hook 'emacs-startup-hook 'emagician/show-scratch t)
Figure out https://github.com/raxod502/straight.el
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!
file:./assets/images/sulu-swordfight-oh-my.jpg
(defvar emagician/are-elpas-reachable? t "Whether or not ELPAs are reachable")
(setq package-user-dir (concat emagician/dir "elpa"))
(setq package-archives
'(("gnu" . "http://elpa.gnu.org/packages/")
("MELPA" . "http://melpa.org/packages/")
("org" . "http://orgmode.org/elpa/")))
(package-initialize)
(condition-case err
(unless package-archive-contents (package-refresh-contents))
((error)
(let ((scratch-msg (concat ";;; !!! Couldn't refresh package contents\n"
"((package-refresh-contents)(beginning-of-line)(kill-line))")))
(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))))
(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"))
(setq custom-file (concat emagician/dir "custom.el"))
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)
file
(format "%s.org" file))
emagician/dir))
(load-result nil)
(emagician/load-depth (1+ emagician/load-depth))
(org-babel-default-header-args (cons '(:comments . "link")
(assq-delete-all :comment
org-babel-default-header-args))))
(if (file-exists-p file)
(progn
(emagician/append-scratch "\n;; "
(make-string emagician/load-depth ?-)
" Loading " file)
(setq load-result (org-babel-load-file file)))
(progn
(emagician/append-scratch "\n;; "
(make-string emagician/load-depth ?-)
"Skipped Loading "
file
" It doesn't exist!\n")
(setq load-result nil)))
(let ((elapsed (float-time (time-subtract (current-time)
start-time))))
(when (> elapsed 3.2)
(add-to-list 'emagician/slow-loaders (cons file elapsed)))
(message (format "Emagician/Loaded %s %.3fs elapsed"
file
elapsed)))
(emagician/append-scratch "...done!" "\n")
load-result))
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…
https://github.com/jwiegley/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)
(emagician/load "Emagician-Base.org")
Assets are either
- org files that tangle assets into a directory or
- 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
- The Bunny of ÆSÞETIC
- The Bunny of Discoverability
- The Bunny of Mise en Place
Most of the files will have a layout similar to this:
There is both an Interface file to handle the general emacs UI and sections inside of individual files.
- Keystrokes
- Key related commands.
- Display
- anything visible, modeline, titlebar, theme, etc
- Editing
- about inserting and using text, including snippets and autocomplete
- Navigating
- Moving the mark. This includes searching.
- Saving
- All about backups.
- State Management
- Persist state across emacs sessions.
- Help and Discoverability
- Getting more help with emacs, and learning commands better.
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.
There is a fine line between too many files, and too few.
(emagician/load "Interface.org")
Emacs is a text editor afteral.
(emagician/load "Text.org")
This sets up some baseline programming helpers and then loads individual org files for each programming mode.
(emagician/load "Programming.org")
Deserves it’s own file… ORG GRIMOIRE!
(emagician/load "Org-Grimoire.org")
Why would you not use E-Shell?
(emagician/load "Eshell-Magick.org")
The Lamp is a 5th magickal weapon along with the wand, sword, cup and chalace. It represents illumination and self knowledge.
(emagician/load "Lamp.org")
Tools to make developing the Emagician Starter kit easier.
(emagician/load "Emagician-Meta.org")
(load custom-file)
(emagician/load emagician/true-name)
(emagician/load (emagician/sanitize-file-name (symbol-name system-type)))
(emagician/load (emagician/sanitize-file-name system-name))
(emagician/load user-login-name)
https://groups.google.com/forum/#!topic/alt.religion.emacs/Yej_PTIqekg
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 |
---|---|---|---|
MagnarS | https://github.com/magnars/.emacs.d | ||
ESchultes Emacs Starter Kit | http://eschulte.github.io/emacs-starter-kit/ | ||
Sacha Chu | http://dl.dropbox.com/u/3968124/sacha-emacs.html | 2016-09-05 | Revist |
Emacs Starter Kit | https://github.com/technomancy/emacs-starter-kit | ||
Cabbage | https://github.com/senny/cabbage | 2016-09-05 | Meh |
Emacs Live | https://github.com/overtone/emacs-live | ||
novoid | https://github.com/novoid/dot-emacs | ||
ocodo | https://github.com/ocodo/emacs.d | ||
Ryan Rix | http://doc.rix.si/cce/cce.html | ||
Lee Hinman | https://www.writequit.org/org/settings.html#sec-1-20 | ||
Wasamasa | https://github.com/wasamasa/dotemacs | 2016-08-26 |
(emagician/initiate-thee-scratch)
We’re Almost Done.
(setq debug-on-error nil)
(provide 'emagician)
[fn:1] This is a Homestuck reference. It will be expounded upon later.