summaryrefslogtreecommitdiffstats
path: root/.emacs.d
diff options
context:
space:
mode:
authorGravatar Tom Willemse2013-11-03 17:05:27 +0100
committerGravatar Tom Willemse2013-11-03 17:05:27 +0100
commite604e35ae28fd6496cae0d9768b821012bc1b293 (patch)
treecea93e2986ac955c232d5b1fb83392f9726384e8 /.emacs.d
parent95fc334b2fcdb816cf5eb468d7fe54907a298f89 (diff)
downloademacs-e604e35ae28fd6496cae0d9768b821012bc1b293.tar.gz
emacs-e604e35ae28fd6496cae0d9768b821012bc1b293.zip
The literate emacs init is back
Diffstat (limited to '.emacs.d')
-rw-r--r--.emacs.d/init.org287
1 files changed, 287 insertions, 0 deletions
diff --git a/.emacs.d/init.org b/.emacs.d/init.org
new file mode 100644
index 0000000..0fd1f11
--- /dev/null
+++ b/.emacs.d/init.org
@@ -0,0 +1,287 @@
+# -*- ispell-local-dictionary: "en"; -*-
+#+TITLE: Emacs init
+#+HTML_HEAD: <link href="http://ryuslash.org/org.css" type="text/css" rel="stylesheet" />
+#+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
+
+* Writing Dockerfiles
+
+ I've been playing around with docker a little bit and I wasn't able
+ to find any modes that provided syntax highlighting for them. So I
+ wrote a very simple one.
+
+ #+BEGIN_SRC emacs-lisp
+ (define-generic-mode docker-mode
+ '(?#)
+ '("FROM" "MAINTAINER" "RUN" "CMD" "EXPOSE" "ENV" "ADD" "ENTRYPOINT" "VOLUME"
+ "USER" "WORKDIR")
+ nil '("Dockerfile") nil
+ "A simple Dockerfile mode.")
+ #+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
+
+* 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