Convert Emacs config to literate org document
This commit is contained in:
parent
c14dce53a8
commit
745c56f7fc
3 changed files with 576 additions and 344 deletions
1
emacs/.emacs.d/.gitignore
vendored
Normal file
1
emacs/.emacs.d/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
init.el
|
|
@ -1,344 +0,0 @@
|
||||||
;;; init.el --- Tom-Emacs Interface -*- lexical-binding: t; -*-
|
|
||||||
|
|
||||||
;; Copyright (C) 2016 Tom Willemse
|
|
||||||
|
|
||||||
;; Author: Tom Willemse <tom@ryuslash.org>
|
|
||||||
;; Keywords: local
|
|
||||||
|
|
||||||
;; This program is free software; you can redistribute it and/or modify
|
|
||||||
;; it under the terms of the GNU General Public License as published by
|
|
||||||
;; the Free Software Foundation, either version 3 of the License, or
|
|
||||||
;; (at your option) any later version.
|
|
||||||
|
|
||||||
;; This program is distributed in the hope that it will be useful,
|
|
||||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
;; GNU General Public License for more details.
|
|
||||||
|
|
||||||
;; You should have received a copy of the GNU General Public License
|
|
||||||
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
;;; Commentary:
|
|
||||||
|
|
||||||
;; This is my personal Emacs configuration. The name was inspired by
|
|
||||||
;; "Ghost in the Shell 2: Man-Machine Interface" and Ryan Rix's
|
|
||||||
;; "Complete Computing Environment".
|
|
||||||
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
;;;; Package configuration:
|
|
||||||
;;; Require package.el since we immediately start using its variables
|
|
||||||
;;; and functions anyway, no need to delay loading.
|
|
||||||
(require 'package)
|
|
||||||
|
|
||||||
;; Add the MELPA and org package archives because I like living on the
|
|
||||||
;; bleeding edge. This should be done both at run-time and
|
|
||||||
;; compile-time so I can install packages at compile time.
|
|
||||||
(eval-and-compile
|
|
||||||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
|
||||||
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")))
|
|
||||||
|
|
||||||
;; Initialize package.el so that packages can be loaded and used. This
|
|
||||||
;; also needs to be done at both run-time and compile-time so packages
|
|
||||||
;; can be installed at compile-time.
|
|
||||||
(eval-and-compile (package-initialize))
|
|
||||||
|
|
||||||
;; Refresh the package contents so packages can be installed from all
|
|
||||||
;; configured archives. Don't do this at run-time because it slows
|
|
||||||
;; down the process too much.
|
|
||||||
(eval-when-compile (package-refresh-contents))
|
|
||||||
|
|
||||||
;; This macro is inspired by use-package, but I want to maintain some
|
|
||||||
;; control of the syntax I use to configure my settings.
|
|
||||||
(defmacro ensure-library (library &rest args)
|
|
||||||
"Make sure LIBRARY is installed.
|
|
||||||
|
|
||||||
ARGS should be a plist which may contain one of the following options:
|
|
||||||
|
|
||||||
- :package
|
|
||||||
|
|
||||||
Specify which package should actually be installed to ensure
|
|
||||||
the library named in LIBRARY exists.
|
|
||||||
|
|
||||||
- :path
|
|
||||||
|
|
||||||
Specify a path to add to the load path to be able to load this
|
|
||||||
package."
|
|
||||||
(declare (indent 1))
|
|
||||||
(let ((library-symbol (cl-gensym))
|
|
||||||
(package-symbol (cl-gensym))
|
|
||||||
(path-symbol (cl-gensym))
|
|
||||||
(package (or (plist-get args :package) library))
|
|
||||||
(path (plist-get args :path)))
|
|
||||||
`(progn
|
|
||||||
(eval-and-compile
|
|
||||||
(let ((,path-symbol ,path))
|
|
||||||
(if ,path-symbol
|
|
||||||
(add-to-list 'load-path
|
|
||||||
(if (file-name-absolute-p ,path-symbol)
|
|
||||||
,path-symbol
|
|
||||||
(concat user-emacs-directory ,path-symbol))))))
|
|
||||||
(eval-when-compile
|
|
||||||
(let ((,library-symbol ',library)
|
|
||||||
(,package-symbol ',package))
|
|
||||||
(unless (require ,library-symbol nil :noerror)
|
|
||||||
(package-install ,package-symbol)
|
|
||||||
(require ,library-symbol)))))))
|
|
||||||
|
|
||||||
;;;; Helper functions:
|
|
||||||
|
|
||||||
;; I have noticed that I refer to the combination of
|
|
||||||
;; `user-emacs-directory' and "data/" a lot, so I wrote this function
|
|
||||||
;; to make referencing it cleaner. Also useful if I ever want to move
|
|
||||||
;; my data directory.
|
|
||||||
(defun oni:data-location (file-name)
|
|
||||||
"Return the location of FILE-NAME within my data directory.
|
|
||||||
This is currently the data directory under the
|
|
||||||
`user-emacs-directory'."
|
|
||||||
(concat user-emacs-directory "data/" file-name))
|
|
||||||
|
|
||||||
(with-eval-after-load 'ert
|
|
||||||
(ert-deftest oni:data-location ()
|
|
||||||
"Test that `oni:data-location' returns the correct locations."
|
|
||||||
(should (string= "~/.emacs.d/data/backup-files/"
|
|
||||||
(oni:data-location "backup-files/")))
|
|
||||||
(should (string= "~/.emacs.d/data/auto-save-files/"
|
|
||||||
(oni:data-location "auto-save-files/")))
|
|
||||||
(should (string= "~/.emacs.d/data/auto-save-list/.saves-"
|
|
||||||
(oni:data-location "auto-save-list/.saves-")))))
|
|
||||||
|
|
||||||
;;;; Backups:
|
|
||||||
|
|
||||||
;; I don't like having every directory filled with "filename~"
|
|
||||||
;; files. So instead of saving backup files to the same directory,
|
|
||||||
;; save them to a special one instead.
|
|
||||||
(setq backup-directory-alist `((".*" . ,(oni:data-location "backup-files/"))))
|
|
||||||
|
|
||||||
;;;; Auto saves:
|
|
||||||
|
|
||||||
;; I prefer to keep all autosave files in a single directory so they
|
|
||||||
;; don't clog up my filesystem so much. Usually these files get
|
|
||||||
;; deleted, but sometimes they don't, and I don't think they look
|
|
||||||
;; pretty. Add it to the end of the list because the default value
|
|
||||||
;; stores auto-saves for remote files in /tmp, which is fine by me.
|
|
||||||
(add-to-list 'auto-save-file-name-transforms
|
|
||||||
`(".*" ,(oni:data-location "auto-save-files/") t) :append)
|
|
||||||
|
|
||||||
;; Place the files which contain the auto save files in a similar
|
|
||||||
;; directory.
|
|
||||||
(setq auto-save-list-file-prefix (oni:data-location "auto-save-list/.saves-"))
|
|
||||||
|
|
||||||
;;;; Tabs:
|
|
||||||
;; Generally I prefer using spaces over tabs. Especially for lisp-like
|
|
||||||
;; languages.
|
|
||||||
(setq-default indent-tabs-mode nil)
|
|
||||||
|
|
||||||
;; A tab-width of 8 is too wide for me, and 2 is too narrow. 4 is just
|
|
||||||
;; right.
|
|
||||||
(setq-default tab-width 4)
|
|
||||||
|
|
||||||
;;;; Font:
|
|
||||||
|
|
||||||
(defvar oni:preferred-font "Fantasque Sans Mono-13"
|
|
||||||
"My personally preferred font.")
|
|
||||||
|
|
||||||
;; This sets the font for normal Emacs sessions. This will change the
|
|
||||||
;; font for all _existing_ frames, any future frames will not be
|
|
||||||
;; affected by this.
|
|
||||||
(set-frame-font oni:preferred-font nil t)
|
|
||||||
|
|
||||||
;; This sets the font for Emacs daemon-mode sessions. This changes the
|
|
||||||
;; font for all _future_ frames, but doesn't change anything for the
|
|
||||||
;; currently existing frames.
|
|
||||||
(add-to-list 'default-frame-alist `(font . ,oni:preferred-font))
|
|
||||||
|
|
||||||
;;;; Menu bar:
|
|
||||||
|
|
||||||
;; I don't use the menu bar, so it just takes up space.
|
|
||||||
(menu-bar-mode -1)
|
|
||||||
|
|
||||||
;;;; Tool bar:
|
|
||||||
|
|
||||||
;; I don't use the tool bar, so it just takes up space.
|
|
||||||
(tool-bar-mode -1)
|
|
||||||
|
|
||||||
;;;; Scroll bar:
|
|
||||||
;; I don't use the scroll bar to either navigate my buffers or see
|
|
||||||
;; whereabouts I am, so they just take up space.
|
|
||||||
(scroll-bar-mode -1)
|
|
||||||
|
|
||||||
;;;; Whitespace:
|
|
||||||
;; I hate it when trailing whitespace is left around a file. I've been
|
|
||||||
;; using this for years, and apart from having some trouble working
|
|
||||||
;; with people who don't pay attention to it, it has worked
|
|
||||||
;; flawlessly.
|
|
||||||
(ensure-library destroy-trailing-whitespace
|
|
||||||
:path "vendor-lisp/destroy-trailing-whitespace")
|
|
||||||
(require 'destroy-trailing-whitespace)
|
|
||||||
(global-destroy-trailing-whitespace-mode)
|
|
||||||
|
|
||||||
;; Having a final newline at the end of the file is always a good
|
|
||||||
;; idea. Some programs just don't work without it and others produce
|
|
||||||
;; some strange results. Github diffs are an example.
|
|
||||||
(setq require-final-newline t)
|
|
||||||
|
|
||||||
;;;; Load theme:
|
|
||||||
(ensure-library zerodark-theme)
|
|
||||||
(load-theme 'zerodark :no-confirm)
|
|
||||||
|
|
||||||
;;;; Flx:
|
|
||||||
|
|
||||||
;;; Install flx so ivy can use it for fuzzy matching.
|
|
||||||
|
|
||||||
(ensure-library flx)
|
|
||||||
|
|
||||||
;;;; Ivy:
|
|
||||||
|
|
||||||
;;; Ivy is a completing read implementation that offers choises
|
|
||||||
;;; vertically.
|
|
||||||
|
|
||||||
(ensure-library ivy)
|
|
||||||
(require 'ivy)
|
|
||||||
|
|
||||||
;; Use fuzzy matching in Ivy.
|
|
||||||
(with-eval-after-load 'ivy
|
|
||||||
(setq ivy-re-builders-alist '((t . ivy--regex-fuzzy))
|
|
||||||
ivy-initial-inputs-alist nil))
|
|
||||||
|
|
||||||
(ivy-mode)
|
|
||||||
|
|
||||||
;;;; Counsel:
|
|
||||||
|
|
||||||
;;; Counsel is a group of functions that use Ivy to specialize on
|
|
||||||
;;; certain built-in commands, such as M-x.
|
|
||||||
|
|
||||||
(ensure-library counsel)
|
|
||||||
(require 'counsel)
|
|
||||||
(counsel-mode)
|
|
||||||
|
|
||||||
;;;; Bookmarks:
|
|
||||||
(eval-when-compile (require 'bookmark))
|
|
||||||
|
|
||||||
;;; Save bookmarks in my data directory.
|
|
||||||
(setq bookmark-default-file (oni:data-location "bookmarks"))
|
|
||||||
|
|
||||||
;;;; Minor modes:
|
|
||||||
|
|
||||||
;;;;; Paredit:
|
|
||||||
|
|
||||||
(ensure-library paredit)
|
|
||||||
|
|
||||||
;;;;; Electric indent mode:
|
|
||||||
|
|
||||||
;;; By default `electric-indent-mode' is enabled globally, but I
|
|
||||||
;;; prefer to enable it locally where I need it.
|
|
||||||
(electric-indent-mode -1)
|
|
||||||
|
|
||||||
;;; Since Emacs 24 `electric-indent-mode' switches the behavior of the
|
|
||||||
;;; C-j and RET keys. I prefer the original situation:
|
|
||||||
(defun oni:switch-newline-keys ()
|
|
||||||
"Switch the C-j and RET keys in the local buffer."
|
|
||||||
(if electric-indent-mode
|
|
||||||
(progn
|
|
||||||
(local-set-key (kbd "C-j") 'newline)
|
|
||||||
(local-set-key (kbd "RET") 'electric-newline-and-maybe-indent))
|
|
||||||
(local-unset-key (kbd "C-j"))
|
|
||||||
(local-unset-key (kbd "RET"))))
|
|
||||||
|
|
||||||
(add-hook 'electric-indent-local-mode-hook #'oni:switch-newline-keys)
|
|
||||||
|
|
||||||
;;;; Major modes:
|
|
||||||
|
|
||||||
;;;;; Emacs lisp mode:
|
|
||||||
|
|
||||||
(add-hook 'emacs-lisp-mode-hook 'paredit-mode)
|
|
||||||
|
|
||||||
;;;;; Scheme mode:
|
|
||||||
|
|
||||||
;; Enable paredit-mode.
|
|
||||||
|
|
||||||
(add-hook 'scheme-mode-hook 'paredit-mode)
|
|
||||||
|
|
||||||
;; Add scsh to the list of known interpreters for scheme mode.
|
|
||||||
|
|
||||||
(add-to-list 'interpreter-mode-alist '("scsh" . scheme-mode))
|
|
||||||
|
|
||||||
;;;;; Inferior Emacs Lisp mode:
|
|
||||||
|
|
||||||
(add-hook 'inferior-emacs-lisp-mode-hook 'paredit-mode)
|
|
||||||
|
|
||||||
;;;;; Mbsync configuration mode:
|
|
||||||
|
|
||||||
(ensure-library mbsync-conf-mode
|
|
||||||
:path "vendor-lisp/mbsync-conf-mode")
|
|
||||||
(autoload 'mbsync-conf-mode "mbsync-conf-mode"
|
|
||||||
"Major mode for editing mbsync configuration files."
|
|
||||||
:interactive)
|
|
||||||
(add-to-list 'auto-mode-alist '("\\.mbsyncrc\\'" . mbsync-conf-mode))
|
|
||||||
|
|
||||||
;;;;; Msmtprc mode:
|
|
||||||
|
|
||||||
(ensure-library msmtprc-mode
|
|
||||||
:path "vendor-lisp/msmtprc-mode")
|
|
||||||
(autoload 'msmtprc-mode "msmtprc-mode"
|
|
||||||
"Major mode for editing msmtp configuration files."
|
|
||||||
:interactive)
|
|
||||||
(add-to-list 'auto-mode-alist '("\\.msmtprc\\'" . msmtprc-mode))
|
|
||||||
|
|
||||||
;;;;; Git commit mode:
|
|
||||||
|
|
||||||
;; Enable `electric-quote-local-mode' to easily type nice-looking
|
|
||||||
;; quotes while writing commits.
|
|
||||||
(add-hook 'git-commit-mode-hook 'electric-quote-local-mode)
|
|
||||||
|
|
||||||
;;;; Applications:
|
|
||||||
|
|
||||||
;;;;; Magit:
|
|
||||||
|
|
||||||
(ensure-library magit)
|
|
||||||
|
|
||||||
;;;;; Gnus:
|
|
||||||
|
|
||||||
(eval-when-compile
|
|
||||||
(require 'gnus)
|
|
||||||
(require 'mail-source)
|
|
||||||
(require 'nnfolder))
|
|
||||||
|
|
||||||
(defvar oni:mail-addresses
|
|
||||||
(rx (or "tom@ryuslash.org" "ryuslash@ninthfloor.org" "ryuslash@gmail.com"))
|
|
||||||
"Regular expression of all my email addresses.")
|
|
||||||
|
|
||||||
;;; Store gnus cache in my data dir.
|
|
||||||
(with-eval-after-load 'gnus
|
|
||||||
(setq gnus-directory (oni:data-location "News")
|
|
||||||
gnus-article-save-directory gnus-directory
|
|
||||||
gnus-cache-directory gnus-directory
|
|
||||||
gnus-kill-files-directory gnus-directory
|
|
||||||
mail-source-directory (oni:data-location "Mail")
|
|
||||||
message-directory mail-source-directory
|
|
||||||
nnfolder-directory mail-source-directory)
|
|
||||||
|
|
||||||
(setq gnus-select-method
|
|
||||||
'(nnmaildir "ryuslash" (directory "~/documents/mail/ryuslash/")))
|
|
||||||
(setq gnus-secondary-select-methods
|
|
||||||
'((nnmaildir "gmail" (directory "~/documents/mail/gmail/"))
|
|
||||||
(nnmaildir "ninthfloor" (directory "~/documents/mail/ninthfloor/"))
|
|
||||||
(nnmaildir "picturefix" (directory "~/documents/mail/picturefix/")))))
|
|
||||||
|
|
||||||
;;; Send mail with msmtp
|
|
||||||
(eval-when-compile (require 'sendmail))
|
|
||||||
|
|
||||||
(with-eval-after-load 'sendmail
|
|
||||||
(setq send-mail-function 'sendmail-send-it)
|
|
||||||
(setq sendmail-program "/usr/bin/msmtp"))
|
|
||||||
|
|
||||||
;;;; Custom:
|
|
||||||
|
|
||||||
;; Put the customize settings in a different file so that Emacs
|
|
||||||
;; doesn't have to modify this file whenever something changes through
|
|
||||||
;; customize.
|
|
||||||
(setq custom-file (concat user-emacs-directory "custom.el"))
|
|
||||||
(load custom-file)
|
|
||||||
|
|
||||||
(provide 'init)
|
|
||||||
;;; init.el ends here
|
|
575
emacs/.emacs.d/init.org
Normal file
575
emacs/.emacs.d/init.org
Normal file
|
@ -0,0 +1,575 @@
|
||||||
|
#+TITLE: Tom-Emacs Interface
|
||||||
|
#+STARTUP: showall
|
||||||
|
|
||||||
|
This is my personal Emacs configuration. The name was inspired by
|
||||||
|
"Ghost in the Shell 2: Man-Machine Interface and Ryan Rix's "Complete
|
||||||
|
Computing Environment".
|
||||||
|
|
||||||
|
To start off, first I need to enable lexical binding.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp :padline no
|
||||||
|
;; -*- lexical-binding: t; -*-
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Package configuration
|
||||||
|
|
||||||
|
Require package.el since I immediately start using its variables and
|
||||||
|
functions anyway, no need to delay loading.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(require 'package)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Add the MELPA and org package archives because I like living on the
|
||||||
|
bleeding edge. This should be done both at run-time and compile-time
|
||||||
|
so I can install packages at compile time.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-and-compile
|
||||||
|
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
|
||||||
|
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Initialize package.el so that packages can be loaded and used. This
|
||||||
|
also needs to be done at both run-time and compile-time so packages
|
||||||
|
can be installed at compile-time.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-and-compile (package-initialize))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Refresh the package contents so packages can be installed from all
|
||||||
|
configured archives. Don't do this at run-time because it slows down
|
||||||
|
the process too much.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (package-refresh-contents))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
This macro is inspired by use-package, but I want to maintain some
|
||||||
|
control of the syntax I use to configure my settings.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defmacro ensure-library (library &rest args)
|
||||||
|
"Make sure LIBRARY is installed.
|
||||||
|
|
||||||
|
ARGS should be a plist which may contain one of the following options:
|
||||||
|
|
||||||
|
- :package
|
||||||
|
|
||||||
|
Specify which package should actually be installed to ensure
|
||||||
|
the library named in LIBRARY exists.
|
||||||
|
|
||||||
|
- :path
|
||||||
|
|
||||||
|
Specify a path to add to the load path to be able to load this
|
||||||
|
package."
|
||||||
|
(declare (indent 1))
|
||||||
|
(let ((library-symbol (cl-gensym))
|
||||||
|
(package-symbol (cl-gensym))
|
||||||
|
(path-symbol (cl-gensym))
|
||||||
|
(package (or (plist-get args :package) library))
|
||||||
|
(path (plist-get args :path)))
|
||||||
|
`(progn
|
||||||
|
(eval-and-compile
|
||||||
|
(let ((,path-symbol ,path))
|
||||||
|
(if ,path-symbol
|
||||||
|
(add-to-list 'load-path
|
||||||
|
(if (file-name-absolute-p ,path-symbol)
|
||||||
|
,path-symbol
|
||||||
|
(concat user-emacs-directory ,path-symbol))))))
|
||||||
|
(eval-when-compile
|
||||||
|
(let ((,library-symbol ',library)
|
||||||
|
(,package-symbol ',package))
|
||||||
|
(unless (require ,library-symbol nil :noerror)
|
||||||
|
(package-install ,package-symbol)
|
||||||
|
(require ,library-symbol)))))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Helper functions
|
||||||
|
|
||||||
|
I have noticed that I refer to the combination of
|
||||||
|
=user-emacs-directory= and "data/" a lot, so I wrote this function
|
||||||
|
to make referencing it cleaner. Also useful if I ever want to move
|
||||||
|
my data directory.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun oni:data-location (file-name)
|
||||||
|
"Return the location of FILE-NAME within my data directory.
|
||||||
|
This is currently the data directory under the
|
||||||
|
`user-emacs-directory'."
|
||||||
|
(concat user-emacs-directory "data/" file-name))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
I also wrote a test for it.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(with-eval-after-load 'ert
|
||||||
|
(ert-deftest oni:data-location ()
|
||||||
|
"Test that `oni:data-location' returns the correct locations."
|
||||||
|
(should (string= "~/.emacs.d/data/backup-files/"
|
||||||
|
(oni:data-location "backup-files/")))
|
||||||
|
(should (string= "~/.emacs.d/data/auto-save-files/"
|
||||||
|
(oni:data-location "auto-save-files/")))
|
||||||
|
(should (string= "~/.emacs.d/data/auto-save-list/.saves-"
|
||||||
|
(oni:data-location "auto-save-list/.saves-")))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Backups
|
||||||
|
|
||||||
|
I don't like having every directory filled with "filename~"
|
||||||
|
files. So instead of saving backup files to the same directory, save
|
||||||
|
them to a special one instead.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq backup-directory-alist `((".*" . ,(oni:data-location "backup-files/"))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Auto saves
|
||||||
|
|
||||||
|
I prefer to keep all autosave files in a single directory so they
|
||||||
|
don't clog up my filesystem so much. Usually these files get
|
||||||
|
deleted, but sometimes they don't, and I don't think they look
|
||||||
|
pretty. Add it to the end of the list because the default value
|
||||||
|
stores auto-saves for remote files in /tmp, which is fine by me.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-to-list 'auto-save-file-name-transforms
|
||||||
|
`(".*" ,(oni:data-location "auto-save-files/") t) :append)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Place the files which contain the auto save files in a similar
|
||||||
|
directory.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq auto-save-list-file-prefix (oni:data-location "auto-save-list/.saves-"))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Tabs
|
||||||
|
|
||||||
|
Generally I prefer using spaces over tabs. Especially for lisp-like
|
||||||
|
languages.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq-default indent-tabs-mode nil)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
A tab-width of 8 is too wide for me, and 2 is too narrow. 4 is just
|
||||||
|
right.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq-default tab-width 4)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Font
|
||||||
|
|
||||||
|
Set the default font to a more pleasing one, in my opinion, with a
|
||||||
|
better size as well.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-to-list 'default-frame-alist '(font . "Fantasque Sans Mono-13"))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Menu bar
|
||||||
|
|
||||||
|
I don't use the menu bar, so it just takes up space.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(menu-bar-mode -1)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Tool bar
|
||||||
|
|
||||||
|
I don't use the tool bar, so it just takes up space.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(tool-bar-mode -1)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Scroll bar
|
||||||
|
|
||||||
|
I don't use the scroll bar to either navigate my buffers or see
|
||||||
|
whereabouts I am, so they just take up space.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(scroll-bar-mode -1)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Whitespace
|
||||||
|
|
||||||
|
I hate it when trailing whitespace is left around a file. I've been
|
||||||
|
using this for years, and apart from having some trouble working
|
||||||
|
with people who don't pay attention to it, it has worked flawlessly.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library destroy-trailing-whitespace
|
||||||
|
:path "vendor-lisp/destroy-trailing-whitespace")
|
||||||
|
(require 'destroy-trailing-whitespace)
|
||||||
|
(global-destroy-trailing-whitespace-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Having a final newline at the end of the file is always a good
|
||||||
|
idea. Some programs just don't work without it and others produce
|
||||||
|
some strange results. Github diffs are an example.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq require-final-newline t)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Theme
|
||||||
|
|
||||||
|
I am trying out Zerodark lately.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library zerodark-theme)
|
||||||
|
(load-theme 'zerodark :no-confirm)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Ivy
|
||||||
|
|
||||||
|
Ivy is a completing read implementation that offers choises
|
||||||
|
vertically. I'm surprised how much I like it. I've tried Swiper
|
||||||
|
before and I didn't like that so much.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library ivy)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Also install the =flx= package to allow ivy to use fuzzy matching.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library flx)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Since I immediately use and enable Ivy, there's no need to autoload
|
||||||
|
it, so require it to keep the byte-compiler quiet.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(require 'ivy)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Enable fuzzy matching in Ivy.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq ivy-re-builders-alist '((t . ivy--regex-fuzzy))
|
||||||
|
ivy-initial-inputs-alist nil)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Enable Ivy.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ivy-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Counsel
|
||||||
|
|
||||||
|
Counsel is a group of functions that use Ivy to specialize on
|
||||||
|
certain built-in commands, such as M-x.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library counsel)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Since I enable Counsel mode immediately, there's no point in leaving
|
||||||
|
it to be autoloaded. Requiring it keeps the byte-compiler happy.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(require 'counsel)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Enable Counsel.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(counsel-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Bookmarks
|
||||||
|
|
||||||
|
Save bookmarks in my data directory so my =user-emacs-directory= is less cluttered.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'bookmark))
|
||||||
|
(setq bookmark-default-file (oni:data-location "bookmarks"))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Personal info
|
||||||
|
|
||||||
|
Set some personal info for, for example, Gnus to use.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq user-full-name "Tom Willemse"
|
||||||
|
user-mail-address "tom@ryuslash.org")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Minor modes
|
||||||
|
|
||||||
|
** Paredit
|
||||||
|
|
||||||
|
Paredit is an awesome minor-mode to have when you write in any
|
||||||
|
lisp-like languages. It can feel rather strict and uncomfortable at
|
||||||
|
first, but once you get the hang of using it, you won't want to
|
||||||
|
live without it.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library paredit)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Electric indent mode
|
||||||
|
|
||||||
|
By default `electric-indent-mode' is enabled globally, but I prefer
|
||||||
|
to enable it locally where I need it.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(electric-indent-mode -1)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Since Emacs 24 `electric-indent-mode' switches the behavior of the
|
||||||
|
C-j and RET keys. I prefer the original situation because my
|
||||||
|
muscle-memory still remembers to use C-j for newline-and-indent
|
||||||
|
behaviour.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun oni:switch-newline-keys ()
|
||||||
|
"Switch the C-j and RET keys in the local buffer."
|
||||||
|
(if electric-indent-mode
|
||||||
|
(progn
|
||||||
|
(local-set-key (kbd "C-j") 'newline)
|
||||||
|
(local-set-key (kbd "RET") 'electric-newline-and-maybe-indent))
|
||||||
|
(local-unset-key (kbd "C-j"))
|
||||||
|
(local-unset-key (kbd "RET"))))
|
||||||
|
|
||||||
|
(add-hook 'electric-indent-local-mode-hook #'oni:switch-newline-keys)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Major modes
|
||||||
|
|
||||||
|
** Emacs lisp mode
|
||||||
|
|
||||||
|
Enable paredit mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-hook 'emacs-lisp-mode-hook 'paredit-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Scheme mode
|
||||||
|
|
||||||
|
Enable paredit mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-hook 'scheme-mode-hook 'paredit-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Add scsh to the list of known interpreters for scheme mode. This
|
||||||
|
way shell-scripts that don't have a file extension but specify scsh
|
||||||
|
as the interpreter are opened in scheme mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-to-list 'interpreter-mode-alist '("scsh" . scheme-mode))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Inferior Emacs lisp mode (ielm)
|
||||||
|
|
||||||
|
Enable paredit mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-hook 'inferior-emacs-lisp-mode-hook 'paredit-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Mbsync configuration mode
|
||||||
|
|
||||||
|
I wrote a simple major-mode for editing my =.mbsyncrc= file. I
|
||||||
|
might release it as a package, but for now I keep it with the rest
|
||||||
|
of my configuration.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library mbsync-conf-mode
|
||||||
|
:path "vendor-lisp/mbsync-conf-mode")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Since it isn't installed by package.el, I need to specify the
|
||||||
|
autoload myself.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(autoload 'mbsync-conf-mode "mbsync-conf-mode"
|
||||||
|
"Major mode for editing mbsync configuration files."
|
||||||
|
:interactive)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
I also need to add it to the =auto-mode-alist= so ~.mbsyncrc~ is
|
||||||
|
opened with mbsync conf mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.mbsyncrc\\'" . mbsync-conf-mode))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Msmtprc mode
|
||||||
|
|
||||||
|
I wrote a simple major-mode for editing my =.msmtprc= file. I might
|
||||||
|
release it as a package, but for now I keep it with the rest of my
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library msmtprc-mode
|
||||||
|
:path "vendor-lisp/msmtprc-mode")
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Since it isn't installed by package.el, I need to specify the
|
||||||
|
autoload myself.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(autoload 'msmtprc-mode "msmtprc-mode"
|
||||||
|
"Major mode for editing msmtp configuration files."
|
||||||
|
:interactive)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
I also need to add it to the =auto-mode-alist= so ~.msmtprc~ is
|
||||||
|
opened with msmtprc mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.msmtprc\\'" . msmtprc-mode))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Git commit mode
|
||||||
|
|
||||||
|
Enable =electric-quote-local-mode= to easily type nice-looking
|
||||||
|
quotes while writing commits.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-hook 'git-commit-mode-hook 'electric-quote-local-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Python mode
|
||||||
|
|
||||||
|
Enable electric pair mode.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-hook 'python-mode-hook 'electric-pair-local-mode)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Applications
|
||||||
|
|
||||||
|
** Magit
|
||||||
|
|
||||||
|
Magit is a very nice interface to Git for Emacs. It allows you to
|
||||||
|
do just about anything with Git without leaving the comfort of your
|
||||||
|
Emacs session.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(ensure-library magit)
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Gnus
|
||||||
|
|
||||||
|
Gnus is one of the most extensible Email programs on the
|
||||||
|
planet. And it's not even made for email but NNTP.
|
||||||
|
|
||||||
|
Store all Gnus-related data in my data directory.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'gnus))
|
||||||
|
|
||||||
|
(with-eval-after-load 'gnus
|
||||||
|
(setq gnus-directory (oni:data-location "News")
|
||||||
|
gnus-article-save-directory gnus-directory
|
||||||
|
gnus-cache-directory gnus-directory
|
||||||
|
gnus-kill-files-directory gnus-directory))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Store all Mail source-related data in my data directory.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'mail-source))
|
||||||
|
|
||||||
|
(with-eval-after-load 'mail-source
|
||||||
|
(setq mail-source-directory (oni:data-location "Mail")))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Store all message-related data in the same place as the Mail source
|
||||||
|
data.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'message))
|
||||||
|
|
||||||
|
(with-eval-after-load 'message
|
||||||
|
(setq message-directory mail-source-directory))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Store all nnfolder-related data in the same place as the Mail
|
||||||
|
source data.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'nnfolder))
|
||||||
|
|
||||||
|
(with-eval-after-load 'nnfolder
|
||||||
|
(setq nnfolder-directory mail-source-directory))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Use msmtp to send mail.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'sendmail))
|
||||||
|
|
||||||
|
(with-eval-after-load 'sendmail
|
||||||
|
(setq send-mail-function 'sendmail-send-it)
|
||||||
|
(setq sendmail-program "/usr/bin/msmtp"))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** ryuslash.org
|
||||||
|
|
||||||
|
Set my main email address as the primary select method for Gnus.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(with-eval-after-load 'gnus
|
||||||
|
(setq gnus-select-method
|
||||||
|
'(nnmaildir "ryuslash" (directory "~/documents/mail/ryuslash/"))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
When sending mail from the ryuslash inbox, use the ryuslash msmtp
|
||||||
|
account.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(eval-when-compile (require 'gnus-msg))
|
||||||
|
|
||||||
|
(with-eval-after-load 'gnus
|
||||||
|
(add-to-list 'gnus-posting-styles
|
||||||
|
'(".*"
|
||||||
|
(address "tom@ryuslash.org")
|
||||||
|
(eval (setq message-sendmail-extra-arguments
|
||||||
|
'("-a" "ryuslash"))))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** picturefix
|
||||||
|
|
||||||
|
Add my work email account as a secondary select method.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(add-to-list 'gnus-secondary-select-methods
|
||||||
|
'(nnmaildir "picturefix"
|
||||||
|
(directory "~/documents/mail/picturefix/")))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
When sending mail from the picturefix account, use the picturefix
|
||||||
|
msmtp account and set the proper name and email address.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(with-eval-after-load 'gnus
|
||||||
|
(add-to-list 'gnus-posting-styles
|
||||||
|
'("picturefix:"
|
||||||
|
(name "Tom Willemsen")
|
||||||
|
(address "tom@picturefix.nl")
|
||||||
|
(eval (setq message-sendmail-extra-arguments
|
||||||
|
'("-a" "picturefix"))))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
* Custom
|
||||||
|
|
||||||
|
Put the customize settings in a different file so that Emacs doesn't
|
||||||
|
have to modify this file whenever something changes through
|
||||||
|
customize. I put this into my init file last so any settings made in
|
||||||
|
there *can* overwrite the ones in the rest of the file, not that I
|
||||||
|
usually like to do that.
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(setq custom-file (concat user-emacs-directory "custom.el"))
|
||||||
|
(load custom-file)
|
||||||
|
#+END_SRC
|
Loading…
Reference in a new issue