This is an Emacs literate configuration template. It contains the basic structure of a literate config along with some optimizations to ensure a fast load time.
There are a few tweaks included in this org file that make it a little easier to work with.
First there is a property defined on the file:
header-args :tangle yes
This tells emacs to automatically tangle (include) all code blocks in this file when
generating the code for the config, unless the code block explicitly includes
:tangle no
as the above code block does.
Next we have a property defined on the Configuration heading that defines the visibility that tells org to show it’s direct children on startup. This way a clean outline of all sub headings under Configuration is shown each time this file is opened in org-mode.
Finally, there is a Table of Contents heading that includes the tag: :TOC_3_gh:
. This
tells an org-mode package toc-org
to generate a table of contents under this heading
that has a max depth of 3 and is created using Github-style hrefs. This table of contents
is updated everytime the file is saved and makes for a functional table of contents that
works property directly on github.
Let’s set some variables with basic user information.
(setq user-full-name "Your Name Here"
user-mail-address "user@email.com")
We’re going to increase the gc-cons-threshold to a very high number to decrease the load and compile time. We’ll lower this value significantly after initialization has completed. We don’t want to keep this value too high or it will result in long GC pauses during normal usage.
(eval-and-compile
(setq gc-cons-threshold 402653184
gc-cons-percentage 0.6))
Disable certain byte compiler warnings to cut down on the noise. This is a personal choice and can be removed if you would like to see any and all byte compiler warnings.
(setq byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local))
We’re going to set the load-path
ourselves and avoid calling (package-initilize)
(for
performance reasons) so we need to set package--init-file-ensured
to true to tell package.el
to not automatically call it on our behalf. Additionally we’re setting
package-enable-at-startup
to nil so that packages will not automatically be loaded for us since
use-package
will be handling that.
(eval-and-compile
(setq load-prefer-newer t
package-user-dir "~/.emacs.d/elpa"
package--init-file-ensured t
package-enable-at-startup nil)
(unless (file-directory-p package-user-dir)
(make-directory package-user-dir t)))
Tell use-package
to always defer loading packages unless explicitly told otherwise. This speeds up
initialization significantly as many packages are only loaded later when they are explicitly used.
(setq use-package-always-defer t
use-package-verbose t)
We’re going to set the load path ourselves so that we don’t have to call package-initialize
at
runtime and incur a large performance hit. This load-path will actually be faster than the one
created by package-initialize
because it appends the elpa packages to the end of the load path.
Otherwise any time a builtin package was required it would have to search all of third party paths
first.
(eval-and-compile
(setq load-path (append load-path (directory-files package-user-dir t "^[^.]" t))))
Next we are going to require package.el
and add our additional package archives, ‘melpa’ and ‘org’.
Afterwards we need to initialize our packages and then ensure that use-package
is installed, which
we promptly install if it’s missing. Finally we load use-package
and tell it to always install any
missing packages.
Note that this entire block is wrapped in eval-when-compile
. The effect of this is to perform all
of the package initialization during compilation so that when byte compiled, all of this time consuming
code is skipped. This can be done because the result of byte compiling use-package
statements results
in the macro being fully expanded at which point use-package
isn’t actually required any longer.
Since the code is automatically compiled during runtime, if the configuration hasn’t already been previously compiled manually then all of the package initialization will still take place at startup.
(eval-when-compile
(require 'package)
(unless (assoc-default "melpa" package-archives)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t))
(unless (assoc-default "org" package-archives)
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t))
(package-initialize)
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t))
Install, automatically load, and enable evil. It’s like vim, but better!
(use-package evil
:demand t
:config
(evil-mode 1))
Generic completion frontend that’s just awesome! Let’s install and enable it.
(use-package ivy
:demand t)
Counsel allows us to utilize ivy by replacing many built-in and common functions with richer versions. Let’s install it!
(use-package counsel-projectile)
(use-package counsel
:demand t)
Swiper is an awesome searching utility with a quick preview. Let’s install it and
load it when swiper
or swiper-all
is called.
(use-package swiper
:commands (swiper swiper-all))
The magical git client. Let’s load magit only when one of the several entry pont functions we invoke regularly outside of magit is called.
(use-package magit
:commands (magit-status magit-blame magit-log-buffer-file magit-log-all))
Projectile is a quick and easy project management package that “just works”. We’re going to install it and make sure it’s loaded immediately.
(use-package projectile
:demand t)
Let’s include a newer version of org-mode than the one that is built in. We’re going to manually remove the org directories from the load path, to ensure the version we want is prioritized instead.
(use-package org
:ensure org-plus-contrib
:pin org
:defer t)
;; Ensure ELPA org is prioritized above built-in org.
(require 'cl)
(setq load-path (remove-if (lambda (x) (string-match-p "org$" x)) load-path))
Let’s install and load the toc-org
package after org mode is loaded. This is the
package that automatically generates an up to date table of contents for us.
(use-package toc-org
:after org
:init (add-hook 'org-mode-hook #'toc-org-enable))
Let’s lower our GC thresholds back down to a sane level.
(setq gc-cons-threshold 16777216
gc-cons-percentage 0.1)