<<babel-init>>
This is my fourth version of an emacs configuration. While I had previously been basically living inside of emacs, I’ve used it less in the last 3 years. The emphasis in this configuration is portability – I’d like to just be able to download this file and the init and have emacs.
Previously, I was expecting a whole bunch of binaries to have already been installed and then call them from emacs. It turns out this isn’t a great plan for moving the configuation to a new machine so now we expect less.
(require 'package)
(add-to-list 'package-archives
'("melpa-stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(unless (file-exists-p (concat
user-emacs-directory "/org-files"))
(make-directory (concat user-emacs-directory "/org-files") t))
(setq custom-file (concat user-emacs-directory "/custom.el"))
A lot of these are just the way I expect an editor to act. The main
difference here from my previous configuration is that I’ve switched
from helm
to ido
.
(load-theme 'tango-dark)
(setq org-todo-keywords '((sequence "TODO" "|" "DONE" "WAIT")))
(global-display-line-numbers-mode)
(setq column-number-mode t)
(defalias 'yes-or-no-p 'y-or-n-p)
(setq ring-bell-function 'ignore)
(defun dont-kill-emacs()
"Disable C-x C-c binding execute kill-emacs."
(interactive)
(if (not window-system) (kill-emacs))
(error (substitute-command-keys "To exit emacs: \\[kill-emacs]")))
(global-set-key (kbd "C-x C-c") 'dont-kill-emacs)
(setq-default indent-tabs-mode nil)
(setq ido-enable-flex-matching t)
(setq ido-everywhere t)
(ido-mode 1)
To use M-x compile
, it’s easiest for emacs to see the same path as the terminal. This code snippet is from the StackOverflow.
(defun set-exec-path-from-shell-PATH () (let ((path-from-shell (replace-regexp-in-string "[ \t\n]*$" "" (shell-command-to-string "$SHELL --login -i -c 'echo $PATH'")))) (setenv "PATH" path-from-shell) (setq eshell-path-env path-from-shell) ; for eshell users (setq exec-path (split-string path-from-shell path-separator)))) (when window-system (set-exec-path-from-shell-PATH))
In the past I’ve had emacs load a lot of packages. I’ve
narrowed it down here to the ones which I actually use
frequently. The big difference here is the use of
use-package
both for cleanliness, and for auto-install of
missing packages.
(use-package recentf
:ensure t
:init
(setq recentf-max-saved-items 150)
(recentf-mode)
(global-set-key (kbd "C-x C-r") 'recentf-open-files))
(use-package multiple-cursors
:ensure t)
(use-package pyvenv
:ensure t)
(use-package super-save
:ensure t
:init
(super-save-mode +1)
(setq super-save-auto-save-when-idle t)
(setq auto-save-default nil)
(add-to-list 'super-save-triggers 'ace-window)
(add-to-list 'super-save-hook-triggers 'find-file-hook))
(use-package ace-window
:ensure t
:init (setq aw-dispatch-always t)
(defvar aw-dispatch-alist
'((?d aw-delete-window "Delete Window")
(?D delete-other-windows "Delete Other Windows")
(?m aw-swap-window "Swap Windows")
(?M aw-move-window "Move Window")
(?c aw-copy-window "Copy Window")
(?j aw-switch-buffer-in-window "Select Buffer")
(?n aw-flip-window "Flip Window")
(?u aw-switch-buffer-other-window "Switch Buffer Other Window")
(?f aw-split-window-fair "Split Fair Window")
(?h aw-split-window-vert "Split Vertical")
(?v aw-split-window-horz "Split Horizontal")
(?? aw-show-dispatch-help))
"List of actions for `aw-dispatch-default'.")
:bind
("C-x o" . ace-window)
("M-o" . ace-window))
(use-package which-key
:ensure t
:init
(setq which-key-idle-delay .2)
(which-key-mode))
(use-package magit
:ensure t)
(use-package markdown-mode
:ensure t
:mode ("README\\.md\\'" . gfm-mode)
:init (setq markdown-command "multimarkdown"))
(use-package projectile
:ensure t
:init
(projectile-mode +1)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))
(use-package evil
:ensure t
:init
(setq evil-want-C-i-jump nil)
(evil-mode)
(define-key evil-normal-state-map (kbd "C-e") 'evil-end-of-line)
(evil-define-key 'normal 'global (kbd "zd") 'mc/mark-next-like-this))
(with-eval-after-load 'evil-maps
(define-key evil-motion-state-map (kbd "SPC") nil)
(define-key evil-motion-state-map (kbd "RET") nil)
(define-key evil-motion-state-map (kbd "TAB") nil))
(use-package company
:ensure t
:init
(global-company-mode)
(setq company-global-modes '(not org-mode text-mode shell-mode))
(setq company-idle-delay .1))
The only lisp I can’t easily abandon is my TODO list method. I like ephemeral TODO lists where I can create a daily list and then forget about anything that wasn’t done that day. This function does that.
(defun get-TODO-file-today ()
"Return filename for today's journal entry."
(let ((daily-name (format-time-string "%Y-%m-%d")))
(expand-file-name (concat "~/.emacs.d/org-files/" daily-name ".org"))))
(defun TODO-file-today ()
"Create and load a journal file based on today's date."
(interactive)
(if (equal (file-exists-p (get-TODO-file-today)) t)
(find-file (get-TODO-file-today))
(progn
(find-file (get-TODO-file-today))
(insert (concat "#+TITLE: TODO List for " (format-time-string "%A, %B %d")))
(newline)
(insert "#+DATE: ")
(calendar)
(find-file (get-TODO-file-today))
(org-date-from-calendar)
(save-buffer t)
(delete-other-windows))))
(defun ido-mx ()
(interactive)
(call-interactively
(intern
(ido-completing-read
"M-x "
(append extended-command-history (all-completions "" obarray 'commandp))
nil nil nil 'extended-command-history
(car extended-command-history)))))
(global-set-key (kbd "M-x") 'ido-mx)
(defun change-text-size (size)
(interactive "nSize: ")
(set-face-attribute 'default nil :height size))