Emacs and config eh? We spend our lives toying with it.
For about the last 3 years I’ve been working towards the following model.
3 init files:
.emacs.d/init.el
- the default emacs init file, mine is unusually small for an Emacs hacker.emacs.d/nic-custom.el.gpg
- used for Emacs customizations and protected by gpg, see Secure customize with epa for details.emacs.d/nic-after-init.el
- used to load stuff that depends on packagesMy init.el is very small:
;; Continue with init (load-file (setq custom-file (concat (file-name-directory (or (buffer-file-name) load-file-name)) "nic-custom.el.gpg"))) ;; After init stuff (add-hook 'after-init-hook ;; should abstract the location of this (lambda nil (load-file "~/.emacs.d/nic-after-init.el"))) ;; I really hate brief-mode's keybinding (fmakunbound 'brief-mode) ;; No need for any other xml mode (fset 'xml-mode 'nxml-mode) (defadvice server-start (around nic-custome-detect-existing first activate compile) "Detect if the Emacs server is already running. If it's running then don't start it." (unless (file-exists-p (concat "/tmp/emacs1000/" server-name)) ad-do-it)) (add-hook 'js-mode-hook (lambda () (linum-mode 1)(flyspell-prog-mode)(smartparens-mode))) (add-hook 'js2-mode-hook (lambda () (linum-mode 1)(flyspell-prog-mode)(smartparens-mode))) (add-hook 'css-mode-hook (lambda () (linum-mode 1)(flyspell-prog-mode)(rainbow-mode 1))) (add-hook 'nxml-mode-hook (lambda () (linum-mode 1)(flyspell-prog-mode))) (add-hook 'creole-mode-hook 'turn-on-auto-fill) ;; Make git not use a pager (setenv "GIT_PAGER" "head") (setenv "PAGER" "head") (global-set-key "\M-?" 'magit-status) (global-set-key (kbd "C-#") 'er/expand-region) (global-set-key (kbd "C-'") 'shell-switcher-switch-buffer) (global-set-key (kbd "C-x 4 '") 'shell-switcher-switch-buffer-other-window) (global-set-key (kbd "C-M-'") 'shell-switcher-new-shell) (global-set-key (kbd "C-x C-b") 'ibuffer) ;;(global-set-key (kbd "C-+") 'text-scale-increase) ; use neg arg to decrease (global-set-key (kbd "<f6>") 'rcirc-next-active-buffer) (windmove-default-keybindings) (ffap-bindings) ;; Stuff we need (require 'uniquify) (require 'dired-x) (require 'ert) (put 'downcase-region 'disabled nil) ;; End init file
the point of this is to install hooks and advice that can’t be done with customize or shouldn’t be done with the {{{after-init}}}
There is a lot of debate about how to handle config for packages. There is johnw’s use-package
and there are people who like to do (package-initialize)
in their init.el
.
Personally I use an after-init-hook
to load a file of config that does specific things after my packages have loaded.
Here’s my after init file:
;;; Nic's after init hook ;; AC (require 'auto-complete-config) (ac-config-default) ;; Keychords (key-chord-mode t) (key-chord-define-global "12" 'rcirc-next-active-buffer) (key-chord-define-global "23" 'jabber-activity-switch-to) (key-chord-define-global "45" 'maildir-refresh) (key-chord-define-global "90" 'gnomenm-flip) ;; Buffer handing stuff (key-chord-define-global "bn" 'bury-buffer) (key-chord-define-global "1q" 'delete-other-windows) (key-chord-define-global "2q" 'delete-window) (key-chord-define-global "[]" (lambda () (interactive) (find-file "~/work/org/todo.org"))) ;; Jabber stuff (defun jabber-switch-or-start () (interactive) (let ((buf (get-buffer "*-jabber-roster-*"))) (unless (bufferp buf) (let ((acc-list (get 'jabber-account-list 'saved-value))) (unless (get 'jabber-account-list 'customize-value) (setq jabber-account-list (cadr (car acc-list))))) (jabber-connect-all)) (switch-to-buffer "*-jabber-roster-*"))) (key-chord-define-global "jl" 'jabber-switch-or-start) ;; Better hide show - I think of this as @< and @> (require 'hideshow) (key-chord-define hs-minor-mode-map "'," 'hs-hide-block) (key-chord-define hs-minor-mode-map "'." 'hs-show-block) ;; Do key-chords for macrostep (key-chord-define emacs-lisp-mode-map "m." 'macrostep-expand) (key-chord-define lisp-interaction-mode-map "m." 'macrostep-expand) (require 'mark-tools) (key-chord-define-global "m/" 'list-marks) (frame-font-keychord-init) ;; Org agenga stuff (global-set-key "\C-ca" 'org-agenda) ;; smartparens stuff (add-hook 'minibuffer-setup-hook 'smartparens-mode) (defun nics-smartparens-hook-fn () (require 'smartparens-config)) (add-hook 'smartparens-enabled-hook 'nics-smartparens-hook-fn) ;; Twitter stuff... no customize for now (setq twittering-icon-mode t) (setq twittering-timer-interval 180) (setq twittering-url-show-status nil) (setq twittering-status-format "%i %s, %@: %FILL[ ]{%T} ") (add-hook 'twittering-edit-mode (lambda nil (visual-line-mode t))) ;; (key-chord-define-global ;; "op" ;; (lambda nil ;; (interactive) ;; (switch-to-buffer (car (twittering-get-buffer-list))))) ;; Do stuff with the secrets we've loaded through customize (require 'kv) ;; Scratchy working out rcirc extra stuff (defun rcirc-process-for-server (server) "Return any dicovered process for rcirc host SERVER." (loop for p in (process-list) if (and (eq 'rcirc-mode (let ((buf (process-buffer p))) (when (and (bufferp buf) (buffer-live-p buf)) (with-current-buffer buf major-mode)))) (equal server (process-contact (get-process p) :host))) return p)) (defun rcirc-choose-server () "Interactively choose an rcirc server from the process list." (assoc (completing-read "Select a server: " (loop for rp in (rcirc-process-list) collect (process-contact (get-process rp) :host))) rcirc-server-alist)) (defun rcirc-reboot (server-entry &optional args) "Kill any existing connection and restart. SERVER-ENTRY is the server entry as it would appear in the `rcirc-server-alist'. With ARGS just kill the connection." (interactive (list (rcirc-choose-server) current-prefix-arg)) (destructuring-bind (server &key nick port user-name password full-name channels encryption) server-entry (let ((proc (rcirc-process-for-server server))) (when (processp proc) (delete-process proc))) (unless args (rcirc-connect server port nick user-name full-name channels password encryption))))