12 KiB
Emacs Configuration
Shout out to Harry R. Schwartz; A whole bunch of this config (including the idea of embeddeding the lot in an Org document) is yanked from his dotfiles repo.
The rest of this config grabs packages via use-package
, so that
needs to be set up to install them if they aren't already.
(require 'use-package-ensure)
(setq use-package-always-ensure t)
UI
The start-up message gets pretty annoying, so disable that.
(setq inhibit-startup-screen t)
The default window size is just a little too small for my taste.
(when window-system (set-frame-size (selected-frame) 90 48))
And I like a little more line spacing than default.
(setq-default line-spacing 0.2)
Also, the menu-, tool- and scroll-bar are ugly, take up space and I don't use them.
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
Colour Scheme
Currently using spacemacs-theme
's light variant, but I prefer a pure
white background to the off-white it has by default.
(use-package spacemacs-theme
:defer t)
(setq spacemacs-theme-custom-colors
'((bg1 . "#ffffff")
(comment-bg . "#ffffff")))
(load-theme 'spacemacs-light t)
Org-mode
I use a couple non-standard bits and pieces, but not a whole bunch. I
really like the <s
to insert a source block thing (which was
deprecated); org-tempo
brings that back.
(use-package org
:ensure org-plus-contrib
:config
(require 'org-tempo))
Agenda
Set up a keybinding for org-agenda and tell it where to look. I have a bunch of org documents making up a sort of wiki which I keep under ~/exo.
(define-key global-map (kbd "C-c a") 'org-agenda)
(setq org-agenda-files
(directory-files-recursively "~/exo" "\.org$"))
Log when tasks were marked DONE
, just for graphs.
(setq org-log-done t)
I often want to see TODO items that aren't scheduled to decide on something to do (if I've already done all the scheduled things), so it's nice for org-agenda to have an option for that.
(setq org-agenda-custom-commands
'(("u" "Unscheduled tasks" tags "-SCHEDULED={.+}/!+TODO")))
By default, the agenda clobbers the rest of the windows in the current frame, which I find a bit annoying. That behaviour is controlled by org-agenda-window-setup.
(setq org-agenda-window-setup 'current-window)
Source Blocks
Pressing tab inside a source block should indent appropriately for its language.
(setq org-src-tab-acts-natively t)
babel
lets us evaluate Org documents containing source blocks!
I've left the enabling of this for most languages to the section
for that language, but I'll add Emacs Lisp and shell here.
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)))
By default trying to execute a source block prompts you, which is
super annoying since I'm realistically not going to try to run any
code from Org documents I haven't written, so that needs
disabling. You can do that by setting org-confirm-babel-evaluate to
nil
.
(setq org-confirm-babel-evaluate nil)
Another annoying thing that happens by default is the clobbering of the window layout when you open a source block. You can change that by setting org-src-window-setup.
(setq org-src-window-setup 'split-window-below)
Exporting
I very rarely want a table of contents, as most of my org documents are pretty short.
(setq org-export-with-toc nil)
HTML
htmlize
is needed for decent HTML exporting, and there is no need
for all that stuff at the bottom.
(use-package htmlize)
(setq org-html-postamble nil)
LaTeX
Use minted
(LaTeX package) to do syntax highlighting in code blocks:
(add-to-list 'org-latex-packages-alist '("" "minted"))
(setq org-latex-listings 'minted)
minted
actually calls pygments
through the shell, which pdflatex
doesn't like; you have to tell it not to worry, and that everything is
going to be OK.
(setq org-latex-pdf-process
'("xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"xelatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
Also, I don't like Emacs' built-in PDF viewer, so open PDFs in Evince instead:
(eval-after-load "org"
'(progn
(setcdr (assoc "\\.pdf\\'" org-file-apps) "evince %s")))
Archival
It's nice to be able to clear out old and irrelevant things from task lists, etc. To that end, org-archive-subtree is very nice. To configure where archived items go, we can set org-archive-location:
(setq org-archive-location "%s-archive::datetree/")
The datetree
bit there is a special option that means archived
items will be grouped by the date they were marked DONE
, or the
date they were archived, if that's missing.
Start up
Org is better suited as scratch space than Funamental, I'd say.
(setq initial-major-mode 'org-mode)
(setq initial-scratch-message "")
I always want ~/exo/index.org to open on start-up, as that's where I keep links to whatever I happen to be doing at any given time; one does that by setting initial-buffer-choice
(setq initial-buffer-choice "~/exo/index.org")
Magit
magit
is truly a wonderful creation! Only deviations from defaults
here are a keybinding for magit-status
and a maximum length for the
summary line of commit messages (after which the excess is
highlighted).
(use-package magit
:bind
("C-x g" . magit-status)
:config
(setq git-commit-summary-max-length 50))
Language Integrations
Generally, 8-character-wide tabs are not my thing.
(setq-default tab-width 4)
(setq-default basic-offset 4)
And generally indenting with spaces is more common, so make that the default:
(setq-default indent-tabs-mode nil)
C
For C, I like to indent with tabs and align with spaces: this
behaviour is provided by smart-tabs-mode
.
(use-package smart-tabs-mode)
(smart-tabs-insinuate 'c)
I'll generally format my code in BSD style but I also use
clang-format
a lot, so I have a keybinding to run that.
(setq c-default-style "bsd")
(use-package clang-format)
(add-hook 'c-mode-hook
(lambda ()
(define-key c-mode-map (kbd "C-M-f")
'clang-format-buffer)))
Meson is my build system of choice for C, but I also use CMake a lot.
(use-package meson-mode)
(use-package cmake-mode)
Haskell
My workflow with Haskell is very REPL-based, so I always want
interactive-haskell-mode
on.
(use-package haskell-mode)
(require 'haskell-interactive-mode)
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
And, of course, that REPL needs to be taking advantage of parallelism!
(require 'haskell-process)
(set-variable 'haskell-process-args-ghci
'("-threaded" "+RTS" "-N8" "-RTS"))
Idris
The only thing to change from the defaults here is to add a more convenient way to case-split.
(use-package idris-mode)
(add-hook 'idris-mode-hook
(lambda ()
(define-key idris-mode-map (kbd "C-c SPC")
'idris-case-split)))
Rust
I never really use Rust without Cargo, so always turn on the minor mode for Cargo in Rust buffers.
(use-package rust-mode)
(use-package cargo)
(add-hook 'rust-mode-hook 'cargo-minor-mode)
Lisps
Racket
Get racket-mode
for some Racket-specific things, like searching documentation
(use-package racket-mode)
Common Lisp
Use SLIME and Quicklisp for Common Lisp (SBCL), with a convenient
binding for slime-selector
(use-package slime)
(setq inferior-lisp-program "sbcl")
(global-set-key (kbd "C-c s") 'slime-selector)
(load (expand-file-name "~/quicklisp/slime-helper.el"))
And we also want to enable execution of CL source blocks in Org mode, which we do by adding an item to org-babel-load-languages.
(org-babel-do-load-languages
'org-babel-load-languages
'((lisp . t)))
Paredit
paredit
is generally very useful for balancing parenthesis so we
want that turned on for all the lisps. Additionally, it's nice to have
an entire expression highlighted when the cursor is on one of its
enclosing parens.
(use-package paredit)
(setq lispy-mode-hooks
'(emacs-lisp-mode-hook
lisp-mode-hook
racket-mode-hook
scheme-mode-hook))
(dolist (hook lispy-mode-hooks)
(add-hook hook (lambda ()
(setq show-paren-style 'expression)
(paredit-mode))))
Music Player
I use MPD because it is clearly the best way to play music; sometimes it's nice to control it from Emacs, so I use MPDel for that.
(use-package mpdel
:config
(mpdel-mode))
RSS Feeds
Using Newsticker, because it's included in Emacs. All I have to do
here is add in all the feeds and add a global keybinding for
newsticker-show-news
. For some reason, I had to set both
newsticker-url-list-defaults
and newsticker-url-list
to get rid
of the EmacsWiki feed it has by default.
(use-package newsticker
:bind
("C-x M-r" . newsticker-show-news))
(setq newsticker-url-list-defaults nil)
(setq newsticker-url-list
'(("Sean Carroll's Mindscape Podcast"
"https://www.patreon.com/rss/seanmcarroll?auth=xZISWBuCvZ1rKXy547HnRXQVyBIscY1P"
nil
3600)
("Corecursive"
"https://link.chtbl.com/corecursive?platform=rss"
nil
3600)
("The Titanium Physicists Podcast"
"http://titaniumphysics.libsyn.com/rss"
nil
3600)))
Also I want Newsticker to download enclosed files so I set
newsticker-new-item-functions
to contain the provided
newsticker-download-enclosures
function.
(setq newsticker-new-item-functions
'(newsticker-download-enclosures))