HOME
Updated: 2023-08-07

My Emacs Init

Notice: This page is duel licensed CC-BY-SA 4.0 and the GPLv3.

GNU Emacs is a free (as in freedom) text editor for writing and code. You can read more about Emacs and it's history on Wikipedia.

If you are interested in learning Emacs check out the guided tour and the internal Emacs Tutorial (from within Emacs type Ctrl + h then type t). In addition, if you are interested in using Emacs for general writing (not programming) check out Org-mode, its great!

1. Why use GNU Emacs?

As a professional email writer (lol), amateur blogger, and programmer my primary input/output to the computer is through text. Emacs provides me with a rock solid text editor that is able to stand out from the competition on the following five key points

  1. Extensibility — a complete programming interface for enhancing my own user experience and automating repetitive tasks.
  2. Portable — a portable environment that works on all major operating systems. (Not all of us have the luxury of using GNU/Linux at work)
  3. Universal Interface — a universal text based interface for all tasks involving text. In addition, it's a consistent and distraction free interface all tasks.
  4. Community — Great community developing high quality packages. (magit, org-mode, eshell, etc.)
  5. Free Software — The ability to access and modify all the source code of Emacs allows for complete customization. The source code also provides an excellent resource for those wishing to learn Lisp, programming, and programming language development1. This factor combined with a rich history and an enthusiastic community ensure that Emacs will not disappear any time soon.

1.1. Emacs Lisp

One aside on Emacs Lisp, which is often disparaged as the worst surviving Lisp dialect. I will not argue that point directly, but I will posit that Emacs Lisp is a more than capable Lisp and very pleasant work in.

The surprising strength of Emacs Lisp is well captured in this excerpt from the Emacs calculator (calc) manual:

I chose Emacs Lisp, a) because I had always been curious about it and b) because, being only a text editor extension language after all, Emacs Lisp would surely reach its limits long before the project got too far out of hand.

To make a long story short, Emacs Lisp turned out to be a distressingly solid implementation of Lisp, and the humble task of calculating turned out to be more open-ended than one might have expected.

1.2. Shortcomings

A minor problem is the limited support for concurrency which causes some actions complete slowly or lock-up Emacs. However, I rarely find this causes significant annoyances. In most situations computationally intensive actions can be handed off to a separate Emacs process (see info:elisp#Processes) or a separate program entirely (e.g. using isync to retrieve mail).

Beyond technical limitations my main issue with Emacs is I cannot use it all the time. With the huge investment I've made on my computer it would be wonderful to have the power of Emacs in a smartphone type package. However, touchscreen displays do not translate well to the Emacs workflow. That's why I've recently pre-ordered the Pyra Handheld to hopefully use as a Emacs PDA.

1.3. Thoughts from other Emacs Users

I've found both these video essays by Protesilaos Stavrou to be a great summary of the thought process involved for why someone would want to use Emacs:

2. Literate Configuration wih Org Mode

My Emacs configuration file is written in a literate programming-like style which allows for prose to be mixed with source code blocks. From that the relevant source blocks are extracted and copied to my Emacs configuration file.

I've held out for many years creating a literate config, but seeing other users' success has convinced me. The ability to maintain complete notes, links, and the configuration code all in one file is extremely convenient. In addition, the hierarchical structure of Org allows for a clearer organization of the code.

2.1. Setup

I have one org file init.org where I combine all of my Emacs configuration code with prose notes about it. That org file can be placed anywhere on my system because it is not the actual initialization file used by Emacs. From the org file my actual init.el is exported (tangled) from the elisp source blocks. In literate programming terms, the org file is where coded and prose is woven together, then code is tangled out to just elisp that can be evaluated by Emacs. That means using a literate config imposes no startup or runtime performance penalty.

Adding the following to your org file will copy (tangle) the code blocks into your init.el file when you run org-babel-tangle (C-c C-v t).

#+PROPERTY: header-args :results silent :tangle "~/.config/emacs/init.el"

To exclude specific source blocks from being tangled add :tangle no to the header.

I use the package org-auto-tangle (available on NonGNU ELPA) to automatically tangle the file on save. This can be enabled by adding the following to the org file.

#+AUTO_TANGLE: t

3. Emacs Boilerplate Setup

3.1. Early Init

Using an early-init.el file can speed up Emacs startup, by avoiding loading unnecessary UI elements. Below is my complete early-init.el:

;;; early-init.el --- Early initialization -*- lexical-binding: t -*-

;;; Commentary:

;;; Code:

;; Disable GUI
(tool-bar-mode -1)
(setq use-dialog-box t)
(setq use-file-dialog nil)
(setq-default frame-title-format '("%b  -  GNU Emacs"))
;; Hide the startup screen
(setq inhibit-startup-screen t)
;; Increase font size
(set-face-attribute 'default nil :height 130)

;;; early-init.el ends here

In my regular config, load early-init.el if not loaded already:

(when (version< emacs-version "27")
  (load (concat user-emacs-directory "early-init.el")))

3.2. Prefer UTF-8

(prefer-coding-system 'utf-8)

3.3. Customize

Emacs has its own customization functionality which can be useful for experimenting and finding new Emacs options. Normally these settings are appended to the end of the user's init file, setting custom-variable will save it there.

(setq custom-file (concat user-emacs-directory "customizations.el"))

Some prefer not to use this functionality as they prefer to code elisp themselves, but even if you do not use the customization interface loading it is still useful for setting safe file variables and themes.

(load custom-file 't)

3.4. Disable bell sound

(setq ring-bell-function 'ignore)

4. Emacs Lisp

4.1. Optimizations and elisp loading

Prefer newest elisp files

(setq load-prefer-newer t)

Increase the max amount allowed to be read from a process into Emacs.

(setq read-process-output-max (* 1024 1024))

4.2. Useful functions

(defun my/file-to-string (filename)
  "Convert contents of file FILENAME to a string."
  (string-trim
   (with-temp-buffer
     (insert-file-contents filename)
     (buffer-string))))
;; TODO: Could make more flexible with a variable pair for light and
;; dark themes.  Override default pairs with a user defined global
;; light/dark themes.  I'd also like to automate with sunrise/sunset.
(defun my/toggle-light-dark-theme ()
  (interactive)
  (cond
   ((custom-theme-enabled-p 'modus-operandi)
    (progn
      (disable-theme 'modus-operandi)
      (load-theme 'modus-vivendi)))
   ((custom-theme-enabled-p 'modus-vivendi)
    (progn
      (disable-theme 'modus-vivendi)
      (load-theme 'modus-operandi)))
   ((message "Unknown theme")))
  (shell-command "change-theme"))

4.3. Package Repositories

Add the new NonGNU ELPA (Emacs Lisp Package Archive). This repository contains only Free Software, but unlike GNU ELPA these packages have not assigned copyright to FSF and cannot be included in mainline Emacs for legal reasons.

Also adding MELPA, a popular third-party repository that contains some packages that haven't been added to NonGNU ELPA yet.

(with-eval-after-load 'package
  (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/"))
  (add-to-list 'package-archives '("melpa"  . "https://melpa.org/packages/")))

4.4. use-package

There is a good chance that =use-package may be included in Emacs 28 and this wont be necessary…

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(require 'use-package)

4.4.1. Hide minor modes from appearing in the mode-line

Delight is very similar to diminish.el, both are supported by use-package, but delight is included in GNU ELPA.

(use-package delight
  :ensure t)

5. General usage

These are settings that improve overall Emacs usage.

5.1. Startup Screen

(add-to-list 'load-path (concat user-emacs-directory
              "manual-packages/emacs-welcome"))

(require 'recentf)
(recentf-mode 1)

(require 'org-welcome)
(setq org-welcome-title nil)
(org-welcome)

5.2. Modeline formatting

Improve buffer naming convention when a buffer with a duplicate named buffer is opened.

(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

5.3. Global Keybindings

(global-set-key (kbd "C-x m") 'man)

5.3.1. Unbind keys

Don't hide the frame

(global-set-key (kbd "C-z") nil)
(global-set-key (kbd "C-x C-z") nil)

5.4. Keybinding reminders

When using Emacs there is always the problem of keeping track of the many keybindings used across multiple modes. One solution I recommend is keeping consistent bindings across modes as possible (many mode already attempt this to varying levels).

When it comes to remembering fringe keybindings that are useful to have, but inconsistent

. I have never quite been happy with which-key as I find the pop-ups overwhelming. Despite that, I do forget keybinding all the time.

(use-package which-key
  :ensure t
  :init
  (setq which-key-idle-delay 3)
  :config
  (which-key-mode))

5.5. Managing buffers

ibuffer offers a number of

(use-package ibuffer
  :bind (("C-x C-b" . ibuffer))
  :init
  (add-hook 'ibuffer-mode-hook #'hl-line-mode))

5.6. Windows Placement   WIP

This is discussed in detail in the Emacs Manual Window Choice and in the Elisp Manual Displaying Buffers.

I don't feel like I fully comprehend how to use this. Basically I am frustrated with how randomly placed some new windows are (Help, Org Src, etc.) and I'd like those to appear more consistently.

;; (setq display-buffer-alist
;;       `(("\\`\\*Async Shell Command\\*\\'"
;;          (display-buffer-no-window))
;;         ("\\*Shortdoc .*\\*"
;;          (display-buffer-reuse-window display-buffer-in-side-window))

;;         ("\\*Help\\*"
;;          display-buffer-pop-up-window
;;          (inhibit-same-window . t))
;;         ("\\*Org Src .*\\*"
;;          display-buffer-below-selected)))

5.7. Remember history

Track recently opened files.

(recentf-mode 1)

Track minibuffer history.

(savehist-mode 1)

5.8. Completion

5.8.1. Marginalia

(use-package marginalia
  :init (marginalia-mode))

5.8.2. Vertico

Trying out vertico. I need to read through the documentation to better understand what it improves over the built in icomplete framework.

(use-package vertico
  :init (vertico-mode))

;; Emacs 28: Hide commands in M-x which do not work in the current mode.
;; Vertico commands are hidden in normal buffers.
(when (version<= "28" emacs-version)
  (setq read-extended-command-predicate
        #'command-completion-default-include-p))

5.8.3. iComplete   OLD

Built into Emacs 28.

;; (require 'icomplete)
;; (fido-vertical-mode 1)

5.8.4. Helm   OLD

No longer using helm. It's a very powerful package but I've always had mixed feelings about it.

;; (use-package helm
;;   :ensure t
;;   :delight
;;   :bind (("M-x" . helm-M-x)
;;          ("C-x C-f" . helm-find-files)
;;          ("C-x r b" . helm-filtered-bookmarks)
;;          :map helm-map
;;          ("<tab>" . helm-execute-persistent-action))
;;   :config
;;   (helm-mode 1))

5.9. Dired

(setq dired-listing-switches "-l --group-directories-first")

(add-hook 'dired-mode-hook #'dired-hide-details-mode)

Allow using 'a' key in dired

(put 'dired-find-alternate-file 'disabled nil)

5.9.1. Delete to Trash

(setq delete-by-moving-to-trash t)

5.10. Read only file View

Enables view mode in all read-only files

(setq view-read-only t)

5.11. Passwords

;; Doing this appears to break Gnus.  May need to report a bug...
;; (setq auth-sources '(password-store))

5.12. Email

(setq user-full-name "Thomas Ingram"
      user-mail-address "thomas@taingram.org")
(setq smtpmail-default-smtp-server "mail.gandi.net"
      smtpmail-smtp-server "mail.gandi.net"
      smtpmail-stream-type 'ssl
      smtpmail-smtp-service 465
      message-send-mail-function 'smtpmail-send-it)

5.12.1. mu4e

I've struggled to find an email client for Emacs that I really like, but I think I've finally settled on mu4e. It is relatively simple and works like a traditional email client (unlike gnus or notmuch).

(require 'mu4e)

(setq mu4e-get-mail-command "mbsync thomas@taingram.org")

(setq mu4e-drafts-folder "/thomas@taingram.org/Drafts")
(setq mu4e-sent-folder   "/thomas@taingram.org/Sent")
(setq mu4e-trash-folder  "/thomas@taingram.org/Trash")

(setq mu4e-maildir-shortcuts
      '((:maildir "/thomas@taingram.org/Inbox" :key ?i)
        (:maildir "/thomas@taingram.org/Sent"  :key ?s)
        (:maildir "/thomas@taingram.org/Trash" :key ?t)
        (:maildir "/thomas@taingram.org/Junk"  :key ?j)
        (:maildir "/thomas@taingram.org/Archive" :key ?a)
        (:maildir "/thomas@taingram.org/Important" :key ?I)
        (:maildir "/thomas@taingram.org/Receipts" :key ?r)))

;; See: https://sourceforge.net/p/isync/mailman/message/34955844/
(setq mu4e-change-filenames-when-moving t)

;; Copy sent messages to sent.  Useful to review messages on other devices.
(setq mu4e-sent-messages-behavior 'sent)

;;; Prefer plain text if possible
(with-eval-after-load "mm-decode"
  (add-to-list 'mm-discouraged-alternatives "text/html")
  (add-to-list 'mm-discouraged-alternatives "text/richtext"))

5.13. Remote file editing

Don't check for version control over tramp, this slows down tramp.

(setq vc-ignore-dir-regexp
      (format "\\(%s\\)\\|\\(%s\\)"
              vc-ignore-dir-regexp
              tramp-file-name-regexp))

5.14. Terminal

(global-set-key (kbd "C-x t") 'shell)

Compilation in shell

(add-hook 'shell-mode-hook 'compilation-shell-minor-mode)

5.15. Calendar and Diary

(use-package calendar
  :config
  (setq calendar-week-start-date 1)     ; Monday
  (setq calendar-date-style 'iso)

  (setq calendar-view-diary-initially-flag t)

  (setq calendar-mark-holidays-flag t)
  (setq calendar-mark-diary-entries-flag t)

  (setq calendar-holidays
        '((holiday-fixed 1 1 "New Year's Day")
          (holiday-float 1 1 3 "Martin Luther King Day")
          (holiday-fixed 2 14 "Valentine's Day")
          (holiday-fixed 3 17 "St. Patrick's Day")
          (holiday-float 5 0 2 "Mother's Day")
          (holiday-float 5 1 -1 "Memorial Day")
          (holiday-float 6 0 3 "Father's Day")
          (holiday-fixed 7 4 "Independence Day")
          (holiday-float 9 1 1 "Labor Day")
          (holiday-fixed 10 31 "Halloween")
          (holiday-float 11 4 4 "Thanksgiving")
          (holiday-easter-etc)
          (holiday-fixed 12 25 "Christmas")
          (holiday-fixed 1 6 "Epiphany")
          (holiday-fixed 8 15 "Assumption")
          (holiday-advent 0 "Advent")
          (solar-equinoxes-solstices)
          (holiday-sexp calendar-daylight-savings-starts
                        (format "Daylight Saving Time Begins %s"
                                (solar-time-string
                                 (/ calendar-daylight-savings-starts-time
                                    (float 60))
                                 calendar-standard-time-zone-name)))
          (holiday-sexp calendar-daylight-savings-ends
                        (format "Daylight Saving Time Ends %s"
                                (solar-time-string
                                 (/ calendar-daylight-savings-ends-time
                                    (float 60))
                                 calendar-daylight-time-zone-name)))))

  (setq diary-date-forms diary-iso-date-forms)
  (defalias 'diary-birthday #'diary-anniversary))

5.16. Git   MELPA

Magit provides an enhanced git interface over the built in vc-mode.

#+beginsrc emacs-lisp (use-package magit :ensure t :bind ("C-x g" . magit)) #+endsr

6. Editing Text

Configuration and packages that are useful wherever text is edited inside Emacs.

6.1. Delete trailing whitespace

(add-hook 'before-save-hook #'delete-trailing-whitespace)

6.2. Allow overwriting of selected text

(require 'delsel)
(delete-selection-mode 1)

6.3. Improve handling long lines

so-long-mode is a new mode in 27.1 that trys to improve Emacs's longstanding issues with handling long lines.

(when (version< "27" emacs-version)
  (global-so-long-mode t))

6.4. Spell Checking

Emacs does not provide internal spellchecking but relies on external programs. The two most popular options are:

  1. GNU Aspell
  2. Hunspell

Aspell is generally faster and returns more results for English. Hunspell provides better spellchecking for other languages and is more widely used in other software (e.g. LibreOffice, Firefox, Google Chrome, and MacOS). On GNU/Linux either of these should be available from your distros package manager (or likely installed already).

Within Emacs there are two main ways to invoke the spellchecker invoke ispell manually check a buffer or region for spelling errors, or enable flyspell-mode to do so automatically like a word processor.

Enable flyspell globally in all text and programming modes:

(add-hook 'text-mode-hook #'flyspell-mode)
(add-hook 'prog-mode-hook #'flyspell-prog-mode)

flyspell-prog-mode will only check spelling in comments and strings.

6.4.1. MS Windows

Aspell has not released a version for Windows since 2002, and in my experience I've found Hunspell to be easier.

  1. Download Hunspell from ezwinports maintained by Eli Zaretskii
  2. Extract the hunspell folder and put it wherever you'd like.
  3. Add the following to your init file:

    ;; Set to wherever you put the hunspell folder
    (add-to-list 'exec-path "C:/hunspell/bin/")
    
    (setq ispell-program-name
          (locate-file "hunspell" exec-path exec-suffixes 'file-executable-p))
    

After that you should be all set to use spellchecking in Emacs

For further instructions see this guide by djc on the help-gnu-emacs@gnu.org mailing list. The guide contains some additional steps on setting up multiple dictionaries which is of no use to me as a stereotypical monolingual American.

6.5. Word Wrap

Disable fill-paragraph when visual-line-mode enabled (I have a habit of using it without thinking).

(define-key visual-line-mode-map [remap fill-paragraph] 'ignore)

6.5.1. Wrap at fill column   MELPA

Nice on occasion, but not great for writing in Org mode as even src blocks will be wrapped to this as well. Decided I prefer manually wrapping lines.

(use-package visual-fill-column
  :ensure t
  ;; :hook (visual-line-mode . visual-fill-column-mode)
  )

6.6. TODO Electric Pair

7. Programming

(use-package prog-mode
  :hook ((prog-mode . show-paren-mode)))

New feature Emacs 28.

(setq next-error-message-highlight 't)

7.1. IDE-like features

7.1.1. Expand and collapse functions

Disabling this for now I do not currently use it and there are other options in Emacs to explore.

Hideshow is a minor mode for hiding and showing contents of functions and comment blocks.

;; (setq hs-hide-comments-when-hiding-all nil)
;; (setq hs-isearch-open t)

;; Backtab is equivalent to shift+tab
;; (define-key hs-minor-mode-map (kbd "<backtab>") 'hs-toggle-hiding)

;; (add-hook 'prog-mode-hook #'hs-minor-mode)
  1. TODO Replace with outline-mode

    Stefan Monnier's talk at Emacs Conf convinced me to try using outline-mode instead of hideshow.

7.1.2. Snippets

(use-package yasnippet
  :ensure t
  :hook ((prog-mode) . yas-minor-mode)
  :config
  (yas-reload-all)
  (setq yas-snippet-dirs (concat user-emacs-directory "snippets/")))

7.1.3. Drop down auto-completion support

(use-package company
  :ensure t
  :delight
  :config
  (global-company-mode 1)
  :custom
  (company-idle-delay 0)
  (company-minimum-prefex-length 1))

7.1.4. Language Server Protocol (LSP)

LSP is a recently developed standard communication protocol that allows development tools (code completion, documentation retrieval on hover, lookup definition, and linting/diagnostics). The protocol was originally developed by Microsoft for their Visual Studio Code editor.

There are two competing Emacs plugins

While lsp-mode has a larger development community and is more feature rich, eglot is simpler and included in GNU ELPA.

(use-package eglot
  :ensure t)

7.2. Emacs Lisp

(use-package paredit
  :ensure t
  :hook ((emacs-lisp-mode lisp-mode scheme-mode clojure-mode) . paredit-mode))
(use-package emacs-lisp-mode
  :bind (:map emacs-lisp-mode-map
              ("C-c C-r" . eval-region)
              ("C-c C-d" . eval-defun)
              ("C-c C-b" . eval-buffer))
  :hook ((emacs-lisp-mode . flymake-mode)))

7.3. Clojure

Recently started toying with Clojure in the hopes it will motivate me to program more.

(use-package clojure-mode
  :ensure t)

(use-package cider
  :ensure t
  :after clojure-mode)

7.4. Shell

(add-hook 'sh-mode-hook 'flymake-shellcheck-load)
(add-hook 'sh-mode-hook 'flymake-mode)

7.5. C

(use-package c-mode
  :bind (:map c-mode-map
              ("C-c c"   . compile)
              ("C-c C-c" . recompile)
              ("C-c g"   . gdb)
              ("C-c C-r" . gdb-run))
  :hook ((c-mode . electric-pair-mode)
         (c-mode . flymake-mode))
  :config
  (setq c-block-comment-prefix "* "))

7.6. Python

(use-package python-mode
  :hook ((python-mode . electric-pair-mode)))

7.7. Go   MELPA

Note that go-mode is an external package.

(use-package go-mode
  :ensure t
  :bind (:map go-mode-map
              ("C-c RET" . compile)
              ("C-c c"   . compile)
              ("C-c C-c" . recompile)
              ("C-c d"   . godoc)
              ("C-c f"   . gofmt)
              ("C-c g"   . gdb)
              ("C-c C-g" . gdb-run))
  :config
  (defun my/go-mode-set-local ()
    (set (make-local-variable 'compile-command) "go build -v "))

  ;; Disables links to the web documentation
  (setq-default eglot-workspace-configuration
              '((:gopls . ((linksInHover . :json-false)))))

  :hook ((go-mode . my/go-mode-set-local)
         (go-mode . subword-mode)
         (go-mode . electric-pair-mode)
         (before-save . gofmt-before-save)))

8. Writing

8.1. Abbreviations

abbrev-mode is a built in minor mode that provides a convent way to expand abbreviations as you are writing. Abbreviations are expanded when a space or punctuation is typed after completing a word. For example you could have gv expand into government.

gv → government

Abbreviations can also preserve capitalization in useful ways:

Gv → Government

GV → GOVERNMENT

Capitalization works differently if your abbreviation expands to multiple words:

Gdp → Gross domestic product

GDP → Gross Domestic Product

By default abbrev commands can be accessed through C-x a

  • C-x a g take a word and define a global abbreviation for it.
  • C-x a l take a word and define a local (mode specific) abbreviation.
  • C-x a i g define the word at point as a global abbreviation and then expand it.
  • C-x a i l sames as above for a mode specific abbreviation.

Additional useful functions:

define-global-abbrev
define both the abbreviation and expansion without pulling from the buffer.
define-mode-abbrev
same as above for mode specific abbrev.
list-abbrevs
List all defined abbrevs. Can edit these directly and reload with C-c C-c.
edit-abbrevs
Functionally same as list-abbrevs but jumps you to mode specific definitions.

Abbreviations are automatically expanded when adding a space or punctuation. They can be manually expanded with C-x a e (this works even in buffers without abbrev-mode enabled).

Expansions can be escaped by typing C-q before typing your space/punctuation. Typing "G D P C-q ," would result in: GDP,

Alternatively if you need to prefix or suffix an abbrev you can note the end of the prefix and the start off the suffix with M-'

anit (M-') gv (M-') ental → antigovernmentental

Abbrev can automatically remind you when you forget to use abbreviations by enabling abbrev-suggest. You can get a summary of how often abbrev-suggest is showing with the abbrev-suggest-show-report command.

(setq abbrev-suggest 't)
(setq abbrev-suggest-hint-threshold 1)

By default Emacs prompts you to save the abbrev file before closing, this can be done automatically in the background by setting save-abbrevs

(setq save-abbrevs 'silently)

Enable abbrev-mode in the modes you wish to use it:

(add-hook 'org-mode-hook #'abbrev-mode)

8.1.1. TODO Look into Dynamic Abbreviation

8.2. Japanese

I'm currently learning Japanese as I'm interested in Japanese wood block printing, Japanese stationary, and Japanese carpentry. Emacs provides a lot of great functionality for writing Japanese (日本語).

8.2.1. Kanji-mode

Kanji-mode is a really cool little package that gives you.

  • Stroke order (M-s M-o)
  • Kanji to hiragana (M-s M-h) or romanji (M-s M-h)

8.3. Org mode

(add-to-list 'load-path (concat user-emacs-directory "org-mode"))

(use-package org
  :bind (("C-x C-a" . org-agenda)
         ("C-x c" . org-capture))
  :hook ((org-mode . auto-fill-mode))   ; Life is too short to manually wrap lines
  :config

  ;; Org src evaluation langauges
  (org-babel-do-load-languages 'org-babel-load-languages
                               '((emacs-lisp . t)
                                 (shell . t)
                                 (latex . t)))

  ;; Templates (e.g. <s)
  (require 'org-tempo)
  (tempo-define-template "my-tempo-template-org-elisp-src"
                         '("#+begin_src emacs-lisp" n p n "#+end_src" n)
                         "<el"
                         "Insert an Emacs Lisp source code block template")

  (set-face-attribute 'org-ellipsis nil
                      :inherit '(font-lock-comment-face default)
                      :weight 'normal)

  (set-face-attribute 'org-block-begin-line nil
                      :extend t)

  (set-face-attribute 'org-block-end-line nil
                      :extend t)

  :custom
  (org-ellipsis "⤵")
  ;; (org-startup-indented t)
  (org-adapt-indentation 'headline-data)
  (org-hide-emphasis-markers nil)

  ;; Org agenda setup
  (org-agenda-files '("~/todo.org"))
  (org-agenda-include-diary t)
  (org-agenda-todo-list-sublevels nil)

  ;; If clock is running bug me if I stop working
  (org-clock-idle-time 10)

  (org-capture-templates
   `(("t" "Todo" entry (file+headline "~/todo.org")
      "* TODO %^{Todo}\n %i\n %a\n\n%?")
     ("j" "Journal" entry (file+headline
                           "~/Documents/me.org"
                           ,(substring (current-time-string) -4 nil))
      "* %u %^{Entry title}\n %?\n")
     ("l" "Interesting Links" entry
      (file "~/Documents/taingram.org/org/interesting-links.org")
      "* %l\n%u"
      :prepend t)
     ("w" "Watchlist (defaults to movie)" entry
      (file+headline "~/Documents/taingram.org/org/watchlist.org" "Movies")
      "* %^{Title}
:PROPERTIES:
:RATING:   %^{Rating}p
:YEAR:     %^{Year}p
:END:
%u

%i"
      :prepend t
      :refile-targets (("watchlist.org" :regexp . "Movies\\|TV Shows\\|Games")))))

  :config
  (add-hook 'org-mode-hook
            (lambda ()
              (setq-local electric-pair-inhibit-predicate
                          (lambda (c) (char-equal c ?\<))))))

8.3.1. Optional Auto Tangle

(use-package org-auto-tangle
  :delight
  :config
  (add-hook 'org-mode-hook 'org-auto-tangle-mode))

8.3.2. Blogging

Load my blog's configuration file.

;; (load "~/Documents/taingram.org/publish")

8.3.3. Org Open Movie Database

I maintain my movie watchlist in an org file and orgmdb.el makes it easier to pull in metadata about the movies.

(add-to-list 'load-path (concat user-emacs-directory "manual-packages/orgmdb"))

(use-package orgmdb
  :config
  (setq orgmdb-omdb-apikey (my/file-to-string "~/.omdb-apikey"))
  (setq orgmdb-fill-property-list '(year genre director country imdb-id)))

8.4. Markdown   MELPA

I personally am not a huge fan of markdown, org mode's syntax just makes much more sense to me, but it's become nearly unavoidable.

(use-package markdown-mode
  :ensure t)

8.5. LaTeX

Old setup, I haven't used LaTeX since I graduated college and its unlikely that I'll use it any time soon…

(use-package tex
  :ensure auctex
  :mode ("\\.tex\\'" . latex-mode)
  :config
  (defun my/latex-compile ()
    "My compile latex function"
    (interactive)
    (save-buffer)
    (TeX-command "LaTeX" 'TeX-master-file))

  (setq TeX-command-default 'LaTeX)

  :bind (:map TeX-mode-map
              ("C-c _" . "\\textunderscore "))

  :hook ((TeX-mode . auto-fill-mode)))

8.6. HTML

(use-package web-mode
  )

9. See Also

Other interesting literate configuration files that inspired me.

Footnotes:

1

How Emacs changed my life by Matz Yukihori the creator of Ruby. The talk explains how access to Emacs's source code directly inspired him in the development of Ruby.

Comments

Email questions, comments, and corrections to comment@taingram.org.

Submissions may appear publicly on this website, unless requested otherwise in your email.