# -*- ispell-local-dictionary: "en"; -*- #+TITLE: Emacs init #+HTML_HEAD: #+OPTIONS: num:nil toc:nil #+PROPERTY: tangle init2.el #+STARTUP: showall * First things first: Lexical binding To make sure that the code in this file follows the correct rules, make sure it uses lexical binding. #+BEGIN_SRC emacs-lisp :padline no ;;; -*- lexical-binding: t -*- #+END_SRC * Improved eval-after-load A lot of the options and functionality isn't necessary until a certain package has been loaded. So in order to keep start-up as fast as possible, while still taking advantage of byte-compiling everything, I wrap most settings in the following macro, which is explained [[http://lunaryorn.com/blog/2013/05/31_byte-compiling-eval-after-load.html][here]]. #+BEGIN_SRC emacs-lisp (defmacro stante-after (feature &rest forms) "After FEATURE is loaded, evaluate FORMS. FEATURE may be an unquoted feature symbol or a file name, see `eval-after-load'." (declare (indent 1) (debug t)) ;; Byte compile the body. If the feature is not available, ignore ;; warnings. Taken from ;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2012-11/msg01262.html (let ((loaded (if (symbolp feature) (require feature nil :no-error) (load feature :no-error :no-message)))) `(,(if loaded 'progn (message "stante-after: cannot find %s" feature) 'with-no-warnings) (eval-after-load ',feature `(funcall (function ,(lambda () ,@forms))))))) #+END_SRC * Executing things after initialization has finished Some functionality, for example everything loaded with ~package.el~, is only available after the initialization process has finished. So code that requires ~package.el~ packages to be available or other things that the initialization process does to be done should only be executed after initialization has finished. The =emacs-startup-hook= is good for this. This also seems more efficient than using =(package-initialize)=. #+BEGIN_SRC emacs-lisp (defmacro eval-after-init (&rest body) "Defer execution of BODY until after Emacs init." (declare (indent 0)) `(add-hook 'emacs-startup-hook #'(lambda () ,@body))) #+END_SRC * Preparing the load-path For anything that isn't loaded with ~package.el~ (like a manually installed ~org-mode~) its directory should be in =load-path=. If there happens to be a ~loaddefs.el~ in that same directory, load it so that it can add some autoloads. These directories contain manually installed packages, my local ~site-lisp~ directory and any project directories for projects which I (occasionally) work on. All of it is put in an =eval-and-compile= block so it is run both at compile-time and run-time, since it is necessary to properly compile my init file as well. #+BEGIN_SRC emacs-lisp (eval-and-compile (defun loadpath-add-and-autoload (path) "Add PATH to `load-path' and load a `loaddefs.el' if it exists." (add-to-list 'load-path path) (let ((loaddefs (concat path "/loaddefs.el"))) (when (file-exists-p loaddefs) (load loaddefs)))) (mapc #'loadpath-add-and-autoload '("~/.emacs.d/site-lisp" "~/projects/emacs/pony-mode/src" "~/.emacs.d/vendor-lisp/org/lisp" "~/.emacs.d/vendor-lisp/org/contrib/lisp" "~/.emacs.d/vendor-lisp/eap" "/usr/share/emacs/site-lisp"))) #+END_SRC * Speeding up yes/no questions Typing ~yes~ or ~no~ when just ~y~ or ~n~ would suffice seems unnecessary. I've been using it almost as long as Emacs and I haven't had any accidents yet. #+BEGIN_SRC emacs-lisp (defalias 'yes-or-no-p 'y-or-n-p) #+END_SRC * Getting a more feature-full buffer list ~ibuffer~ has a lot more features than regular =list-buffers=, plus does everything =list-buffers= does. #+BEGIN_SRC emacs-lisp (defalias 'list-buffers 'ibuffer) #+END_SRC * Getting more feature-full text-completion One of the completion mechanisms of =hippie-expand= is a ~dabbrev~ based expansion, so it should do everything =dabbrev-expand= does, plus more. It also doesn't use =dabbrev-expand= directly, so it shouldn't be a problem to switch them. #+BEGIN_SRC emacs-lisp (defalias 'dabbrev-expand 'hippie-expand) #+END_SRC * Making buffer names unique and understandable The problem with the default way of making buffer names unique is that it doesn't tell me anything about what makes them unique. I don't know what makes ~init.el<1>~ different from ~init.el<2>~. However, seeing it as, for example, ~init.el|.emacs.d~ and ~init.el|dotemacs~ tells me a lot more. #+BEGIN_SRC emacs-lisp (require 'uniquify) (stante-after uniquify (setq uniquify-buffer-name-style 'post-forward)) #+END_SRC * Telling gnus where to look for its initialization file I prefer to keep everything in my =~/.emacs.d/= directory, so =~/.gnus= wouldn't work with that. To silence a compiler warning I define a "vacuous" variable first, so Emacs knows the name is defined. I don't specify an ~init-value~ with the =defvar= so that if it happens to already be defined, =setq= will still change it (=defvar= won't). #+BEGIN_SRC emacs-lisp (defvar gnus-init-file) (setq gnus-init-file "~/.emacs.d/site-lisp/gnus-init") #+END_SRC * Clean up the UI There are things, like a blinking cursor, a menu bar, etc. that I just don't need, so I want to turn them off. Since they all have the same API, just loop through the symbols and turn each off. #+BEGIN_SRC emacs-lisp (defmacro turn-off (&rest modes) "Turn off each mode in MODES." `(progn ,@(mapcar (lambda (m) `(,m -1)) modes))) (turn-off menu-bar-mode scroll-bar-mode tool-bar-mode blink-cursor-mode column-number-mode line-number-mode tooltip-mode) #+END_SRC * Loading a theme at the correct time A problem with loading some themes immediately at start-up, while using the ~--daemon~ switch is that there is no guarantee that it will ever use a window system, so it's like starting from the terminal. This may affect the colors of some themes. To get around this I use =lexical-binding= (because I'm not sure dynamic binding will work here) and create a closure that tracks if I've set the theme, so it doesn't reset it every time a new frame is created. Then I have this executed one tenth of a second after a frame is created, at which point there should be a window system and colors should be correct. One more problem is that when starting Emacs without the ~--daemon~ switch the =after-make-frame-functions= aren't run, so if we're not running a daemon, just set the theme. #+BEGIN_SRC emacs-lisp (let ((setp (not (daemonp)))) (defun init-set-theme (frame) "Try to set the theme for the current (first) frame." (ignore frame) (unless setp (run-at-time .1 nil (lambda () (setq setp (load-theme 'yoshi t))))))) (if (daemonp) (add-hook 'after-make-frame-functions #'init-set-theme) (eval-after-init (load-theme 'yoshi t))) #+END_SRC * Browsing with eww =eww= is a very cool project, but I don't like where it downloads things. #+BEGIN_SRC emacs-lisp (setq eww-download-path "~/downloads/") #+END_SRC * Double space to end a sentence in Emacs Lisp The Emacs Lisp syntax checker is hell-bent on forcing me to use a double space at the end of sentences in comments and docstrings. Fine, then I will use double spaces in Emacs Lisp. #+BEGIN_SRC emacs-lisp (defun init-locally-enable-double-spaces () (setq-local sentence-end-double-space t)) (add-hook 'emacs-lisp-mode-hook #'init-locally-enable-double-spaces) #+END_SRC * Show pretty symbols Emacs lisp has the default of showing ~lambda~ as ~λ~. I also want to show ~<=~ as ~≤~, ~>=~ as ~≥~ and ~sqrt~ as ~√~. #+BEGIN_SRC emacs-lisp (defun init-set-emacs-lisp-symbols () (setq prettify-symbols-alist (append prettify-symbols-alist '(("<=" . ?≤) (">=" . ?≥) ("sqrt" . ?√))))) (add-hook 'emacs-lisp-mode-hook #'init-set-emacs-lisp-symbols) #+END_SRC Aside from Emacs lisp, I would also like to show most of these in Python. Though the ~sqrt~ doesn't seem applicable, I do want to show ~!=~ as ~≠~ here. #+BEGIN_SRC emacs-lisp (defun init-set-python-symbols () (setq prettify-symbols-alist '(("lambda" . ?λ) ("<=" . ?≤) (">=" . ?≥) ("!=" . ?≠)))) (add-hook 'python-mode-hook #'init-set-python-symbols) #+END_SRC Now just turn it on for =prog-mode=. #+BEGIN_SRC emacs-lisp (add-hook 'prog-mode-hook 'prettify-symbols-mode) #+END_SRC * Slime implementations I usually use [[http://sbcl.org][SBCL]], but sometimes also [[http://www.clisp.org/][GNU CLISP]]. #+BEGIN_SRC emacs-lisp (stante-after slime (setq slime-lisp-implementations '((sbcl ("sbcl" "--noinform") :coding-system utf-8-unix) (clisp ("clisp") :coding-system utf-8-unix)) slime-default-lisp 'sbcl)) #+END_SRC * Use Liberation Mono font for unicode [[http://paratype.com/public/][PT Mono]] is a very nice font, but is misses some unicode characters I would like to use. [[https://www.redhat.com/promo/fonts/][Liberation Mono]] on the other hand does seem to contain these characters, so I use that for any unicode fonts. #+BEGIN_SRC emacs-lisp (set-fontset-font "fontset-default" 'unicode (font-spec :family "Liberation Mono" :width 'normal :size 12.4 :weight 'normal)) #+END_SRC * A function to sort python includes At work I use Python. Our project is getting bigger and bigger, import statements are growing. We use the following style: #+BEGIN_SRC python :tangle no from somemodule import ( Class1, Class2, Class3, ) #+END_SRC Which we found to be one of the better-looking ways to handle multi-line import statements. To sort these lines I wrote a very simplistic (and error-prone, but I'll handle it when I get to it) command. All it does is save the current point, searches backwards for a ~(~, then forwards for a ~)~ and sorts the region in between (not including) the ~()~. #+BEGIN_SRC emacs-lisp (defun sort-imports () (interactive) (save-excursion (sort-lines nil (1+ (search-backward "(")) (1- (search-forward ")"))))) #+END_SRC