Skip to content

Latest commit

 

History

History
253 lines (202 loc) · 8.42 KB

emacs.org

File metadata and controls

253 lines (202 loc) · 8.42 KB

Emacs Literate Configuration

Configuration

Table of Contents

About this file

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.

Org File Tweaks

There are a few tweaks included in this org file that make it a little easier to work with.

Automatically Tangle

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.

Visibility Settings

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.

Table of Contents

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.

Personal Information

Let’s set some variables with basic user information.

(setq user-full-name "Your Name Here"
      user-mail-address "user@email.com")

Emacs Initialization

Settings

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))

Package Management

Package Settings

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)))

Use-Package Settings

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)

Manually Set Load Path

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))))

Initialize Package Management

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))

Packages

Evil

Install, automatically load, and enable evil. It’s like vim, but better!

(use-package evil
  :demand t
  :config
  (evil-mode 1))

Ivy

Generic completion frontend that’s just awesome! Let’s install and enable it.

(use-package ivy
  :demand t)

Counsel

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

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))

Magit

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

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)

Org

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))

Toc-org

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))

Post Initialization

Let’s lower our GC thresholds back down to a sane level.

(setq gc-cons-threshold 16777216
      gc-cons-percentage 0.1)