1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
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
|