Merge branch 'master' of git.ganneff.de:emacs
[emacs.git] / .emacs.d / initjj.org
1 #+TITLE: initjj.org - Ganneffs emacs configuration
2 #+DESCRIPTION: My current Emacs configuration
3 #+KEYWORDS: org-mode Emacs configuration
4 #+STARTUP: align fold nodlcheck hidestars oddeven lognotestate
5 #+SETUPFILE: ~/.emacs.d/elisp/org-templates/level-0.org
6 #+LATEX_CMD: xelatex
7
8 * Notes for people looking at this using a webbrowser
9 My whole emacs config is done using [[http://orgmode.org/][org-mode]] files, with a little magic
10 in ~/.emacs.d/init.el to have it readable for emacs.
11
12 I publish them using the [[http://orgmode.org/manual/HTML-export.html#HTML-export][HTML export feature]] of org-mode, combined with
13 a javascript [[http://orgmode.org/worg/code/org-info-js/][called org-info.js]] which lets you navigate my config
14 similar to what org-mode allows you in Emacs.
15
16 Basic navigation is =n= for next, =p= for previous, =l= will give you
17 a direct link to the point you are at and the key =?= will show you a
18 help with all keyboard shortcuts. You might also want to try pressing
19 =m= followed by a series of =F=.
20
21 If you have Javascript disabled you only miss the nice navigation, you
22 will see the whole file at once.
23
24 * Copyright notice(s)
25 My config is made up of stuff I wrote myself - and lots of stuff I
26 copied from all around the net. I try to list all of the original
27 authors here, but this config is a living thing for more than a decade
28 now, so there are things where I just don't know anymore where it might
29 be from.
30
31 If you find something that you are the author off and I forgot to
32 mention you don't hesitate to tell me and I will fix that oversight.
33
34 ** My own stuff
35 ----------
36 #+BEGIN_QUOTE
37 Copyright © 200x-2012 Joerg Jaspert <joerg@ganneff.de>
38
39 My code in this document is free software: you can redistribute it
40 and/or modify it under the terms of the [[http://www.gnu.org/licenses/old-licenses/gpl-2.0.html][GNU General Public License]]
41 as published by the Free Software Foundation, version 2.0.
42
43 My writing here is subject to the [[http://creativecommons.org/licenses/by-nc-sa/3.0/][CC —
44 Attribution-NonCommercial-ShareAlike 3.0 Unported — CC BY-NC-SA 3.0]]
45 license.
46 #+END_QUOTE
47 ----------
48
49 ** Sacha Chua
50 I copied various functions and snippets from [[http://sachachua.com/blog/category/emacs/][Sacha Chuas blog]] (worth a
51 read). Her copyright/license notice:
52
53 ----------
54 #+BEGIN_QUOTE
55 Copyright © 2001-2012 Sacha Chua (sacha@sachachua.com).
56
57 Please feel free to reuse content under a [[http://creativecommons.org/licenses/by-nc-sa/3.0/][Creative Commons —
58 Attribution-NonCommercial-ShareAlike Unported — CC BY-NC-SA]] license
59 unless otherwise noted.
60 #+END_QUOTE
61 ----------
62
63 Functions copied from her start with /sacha//.
64
65 ** Bernt Hansen
66 Much of my org-mode setup is copied from [[http://doc.norang.ca/org-mode.html][Bernt Hansens org-mode
67 page]]. His license statement:
68
69 ----------
70 #+BEGIN_QUOTE
71 Copyright (C) 2012 Bernt Hansen.
72
73 Permission is granted to copy, distribute and/or modify this document
74 under the terms of the GNU Free Documentation License, Version 1.3
75 or any later version published by the Free Software Foundation;
76 with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
77
78 Code in this document is free software: you can redistribute it
79 and/or modify it under the terms of the GNU General Public
80 License as published by the Free Software Foundation, either
81 version 3 of the License, or (at your option) any later version.
82
83 This code is distributed in the hope that it will be useful,
84 but WITHOUT ANY WARRANTY; without even the implied warranty of
85 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
86 GNU General Public License for more details.
87 #+END_QUOTE
88 ----------
89
90 Functions copied from him start with /bh//.
91
92 ** Roland Mas
93 I copied a few functions for my [[file:gnus.org][gnus]] setup from [[http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html][his blog]] that enable me to
94 use notmuch and gnus together. His license statement:
95
96 ----------
97 #+BEGIN_QUOTE
98 [[http://creativecommons.org/licenses/by-nc-sa/2.0/fr/][Creative Commons — Attribution - Pas d'Utilisation
99 Commerciale - Partage dans les Mêmes Conditions 2.0 France — CC BY-NC-SA
100 2.0]] Sauf indication contraire, le contenu de ce site est mis à
101 disposition sous un contrat Creative Commons.
102 #+END_QUOTE
103 ----------
104
105 In case you are as good in french as I am, that should be equal to:
106 ----------
107 #+BEGIN_QUOTE
108 Please feel free to reuse content under a [[http://creativecommons.org/licenses/by-nc-sa/2.0/][Creative Commons —
109 Attribution-NonCommercial-ShareAlike Unported — CC BY-NC-SA]] license
110 unless otherwise noted.
111 #+END_QUOTE
112 ----------
113
114 ** Emacs Prelude
115 #+BEGIN_QUOTE
116 Prelude is an enhanced Emacs 24 configuration that should make your
117 experience with Emacs both more pleasant and more powerful. Prelude
118 alters a lot of the default settings, bundles a plethora of additional
119 packages and adds its own core library to the mix. The final product
120 offers an easy to use Emacs configuration for Emacs newcomers and lots
121 of additional power for Emacs power users.
122 #+END_QUOTE
123
124 So much for their own advertisement, and while I agree it is a pretty
125 nice configuration, I only like parts of it. Especially as I am forced
126 to use older emacs too (prelude requires emacs24), and I also like to
127 do stuff on my own...
128
129 Anything copied from prelude should start with prelude-, and their
130 license statement is:
131
132 ----------
133 #+BEGIN_QUOTE
134 Copyright © 2011-2013 Bozhidar Batsov
135
136 Author: Bozhidar Batsov <bozhidar@batsov.com>
137 URL: https://github.com/bbatsov/prelude
138 This program is free software; you can redistribute it and/or
139 modify it under the terms of the GNU General Public License
140 as published by the Free Software Foundation; either version 3
141 of the License, or (at your option) any later version.
142 #+END_QUOTE
143 ----------
144
145 You should be able to find a full list of contributors at
146 [[https://github.com/bbatsov/prelude/graphs/contributors][their github]] pages.
147
148
149
150 ** Steve Purcell
151 [2013-05-21 Tue 23:30]
152 * Initial preparation
153 To have my config here actually work, =emacs= needs a little help. For
154 some reason it can't just read an =org-mode= based config on its own, tsk.
155
156 Which means that the emacs initfile needs to have the magic. My init
157 file is =~/.emacs.d/init.el=. I try to keep it as small as possible, yet
158 it does have some entries.
159
160 As I commented inside that file, I won't repeat stuff here, just read it
161 below.
162
163 #+INCLUDE: "~/.emacs.d/init.el" src emacs-lisp
164
165 * Basic initialization
166 First of I want a set of variables defined, makes it easier to refer
167 to common things later.
168
169 ** Variables
170 *** System type
171 The variable /system-type/ from emacs isn't directly usable in my
172 case. It contains gnu/linux and gnu/kfreebsd - which has extra /,
173 which is just annoying when using them in a path entry.
174 Hence we do a little creative redefinition for ourself.
175 #+BEGIN_SRC emacs-lisp :tangle yes
176 (defun jj-system-type ()
177 "Return a string depending on the OS we use"
178 (interactive)
179 (cond
180 ((eq system-type 'darwin) "macosx")
181 ((eq system-type 'gnu/linux) "linux")
182 ((eq system-type 'gnu/kfreebsd) "kfreebsd")
183 ((eq system-type 'cygwin) "cygwin")
184 ((eq system-type 'windows-nt) "windows")))
185 #+END_SRC
186
187 *** jj-dir
188 The base directory for all our emacs files. It is based on the
189 directory where we load this file from.
190 #+BEGIN_SRC emacs-lisp :tangle yes
191 (defvar jj-dir (file-name-directory (or load-file-name (buffer-file-name)))
192 "The master directory for Ganneffs emacs configuration and storage.
193 Usually ~/.emacs.d/")
194 #+END_SRC
195
196 *** jj-config-dir
197 In which directory do we store the rest of our config?
198 #+BEGIN_SRC emacs-lisp :tangle yes
199 (defvar jj-config-dir
200 (expand-file-name "config" jj-dir)
201 "Ganneffs main emacs configuration can be found here.")
202 #+END_SRC
203
204 *** jj-emacs-config
205 Name of the main configuration file.
206 #+BEGIN_SRC emacs-lisp :tangle yes
207 (defvar jj-emacs-config
208 (expand-file-name "emacs.org" jj-config-dir)
209 "Ganneffs main emacs configuration file.")
210 #+END_SRC
211
212 *** jj-info-dir
213 Where do I store info files.
214 #+BEGIN_SRC emacs-lisp :tangle yes
215 (defvar jj-info-dir
216 (expand-file-name "info" jj-dir)
217 "This directory stores info files in Ganneffs emacs config.")
218 #+END_SRC
219
220 *** jj-elisp-dir
221 Where do I store packages for emacs.
222 #+BEGIN_SRC emacs-lisp :tangle yes
223 (defvar jj-elisp-dir
224 (expand-file-name "elisp" jj-dir)
225 "This directory stores subdirs for local packages in Ganneffs emacs config.")
226 #+END_SRC
227
228 *** jj-elisp-local-dir
229 Some packages just come with a single file. I put them into this
230 local directory instead of giving them an own one.
231 #+BEGIN_SRC emacs-lisp :tangle yes
232 (defvar jj-elisp-local-dir
233 (expand-file-name "local" jj-elisp-dir)
234 "This directory stores extra elisp files for Ganneffs emacs config.")
235 #+END_SRC
236
237 *** jj-custom-file
238 The customization interface of emacs stores its values in this file.
239 #+BEGIN_SRC emacs-lisp :tangle yes
240 (defvar jj-custom-file
241 (expand-file-name "customized.el" jj-config-dir)
242 "Changes from the customization interface in Ganneffs emacs config.")
243 #+END_SRC
244
245 *** jj-cache-dir
246 Similar to /var on a unix system, volatile data, cache files, ...
247 #+BEGIN_SRC emacs-lisp :tangle yes
248 (defvar jj-cache-dir
249 (expand-file-name "cache" jj-dir)
250 "This directory stores cache files and other volatile data.")
251 #+END_SRC
252
253 *** jj-backup-directory
254 Backup copies of files I edit are stored here.
255 #+BEGIN_SRC emacs-lisp :tangle yes
256 (defvar jj-backup-directory
257 (expand-file-name (concat "emacs-autosave-" user-login-name) jj-cache-dir)
258 "This directory stores backup files.")
259 #+END_SRC
260
261 *** jj-theme-dir
262 Where my theme files are stored.
263 #+BEGIN_SRC emacs-lisp :tangle yes
264 (defvar jj-theme-dir
265 (expand-file-name "themes" jj-dir)
266 "This directory stores theme files for Ganneffs emacs config")
267 #+END_SRC
268
269 *** jj-sys-config
270 System dependent configuration information stored in here.
271 #+BEGIN_SRC emacs-lisp :tangle yes
272 (defvar jj-sys-config
273 (expand-file-name (concat system-name ".org") jj-config-dir)
274 "Ganneffs System/Host specific emacs configuration file.")
275 #+END_SRC
276
277 *** jj-os-config
278 Operating System dependent configuration information stored in here.
279 #+BEGIN_SRC emacs-lisp :tangle yes
280 (defvar jj-os-config
281 (expand-file-name (concat (jj-system-type) ".org") jj-config-dir)
282 "Ganneffs Operating system specific emacs configuration file.")
283 #+END_SRC
284
285 *** jj-user-config
286 User dependent configuration stored in here.
287 #+BEGIN_SRC emacs-lisp :tangle yes
288 (defvar jj-user-config
289 (expand-file-name (concat user-login-name ".org") jj-config-dir)
290 "Ganneffs username specific emacs configuration file.")
291 #+END_SRC
292
293 *** jj-ev-config
294 Emacs version dependent configuration stored in here.
295 #+BEGIN_SRC emacs-lisp :tangle yes
296 (defvar jj-ev-config (expand-file-name
297 (concat "emacs"
298 (number-to-string emacs-major-version) ".org")
299 jj-config-dir)
300 "Ganneffs emacs version specific configuration file.")
301 #+END_SRC
302
303 *** jj-color-style
304 Which color scheme should be loaded? I prefer dark very much.
305 #+BEGIN_SRC emacs-lisp :tangle yes
306 (defvar jj-color-style 'dark "Which color scheme of solarized to select. Dark or Light")
307 #+END_SRC
308
309 ** Macro
310 A small wrapper around =eval-after-load=, taken from [[http://milkbox.net/note/single-file-master-emacs-configuration/][Single File Master Emacs Configuration : milkbox]]
311 #+BEGIN_SRC emacs-lisp :tangle yes
312 (defmacro after (mode &rest body)
313 "`eval-after-load' MODE evaluate BODY."
314 (declare (indent defun))
315 `(eval-after-load ,mode
316 '(progn ,@body)))
317 #+END_SRC
318 ** Processing
319 First we want to ensure that our cache and backup directories really exist.
320 #+BEGIN_SRC emacs-lisp :tangle yes
321 (if (not (file-exists-p jj-cache-dir))
322 (make-directory jj-cache-dir))
323 (if (not (file-exists-p jj-backup-directory))
324 (make-directory jj-backup-directory))
325 #+END_SRC
326
327 Add our local elisp directory to the load path early, as it contains
328 files we want to load during configuration processing, before the
329 load-path gets set up for real.
330 #+BEGIN_SRC emacs-lisp :tangle yes
331 ;; Have use-package/bindkey in here wich are needed for startup
332 (add-to-list 'load-path jj-elisp-local-dir)
333 #+END_SRC
334
335 I have a function that uses org-tangle to extract all emacs-lisp
336 codeblocks out of my org-mode configuration files. After which it
337 ensures that the generated elisp files get byte-compiled.
338
339 As my configuration requires certain parts of the configuration to
340 already be loaded when the byte-compilation happens, this is done
341 using an /after-init-hook/.
342 #+BEGIN_SRC emacs-lisp :tangle yes
343 (defvar jj-init-files '() "Temporary list of files that need a byte-compile")
344 (defun jj-byte-compile-init ()
345 "Byte compile a list of files"
346 (let (filename)
347 (dolist (filename jj-init-files)
348 (when (file-exists-p filename)
349 (message "Byte-compiling %s, standby" filename)
350 (byte-compile-file filename))))
351 (makunbound 'jj-init-files)
352 (makunbound 'jj-byte-compile-init)
353 )
354 (defun jj-compile-and-load (&optional arg)
355 "Use org-tangle to get the emacs-lisp parts from .org emacs
356 config files into .el ones, byte-compile those and then load
357 them."
358 (let ((el-file (concat (file-name-sans-extension arg) ".el")))
359 (cond
360 ((file-newer-than-file-p arg el-file)
361 (org-babel-tangle-file arg el-file "emacs-lisp")
362 (add-hook 'after-init-hook 'jj-byte-compile-init)
363 (add-to-list 'jj-init-files (symbol-value 'el-file))))
364 (load-file el-file)
365 ))
366 #+END_SRC
367
368 ** Extra files to load
369
370 And finally we are going to load the various files.
371
372 *** Global emacs config, always loaded
373
374 This file is loaded no matter what and exists on all machines my
375 dotfiles are on. [[file:config/emacs.org][Main Emacs config]]
376 #+BEGIN_SRC emacs-lisp :tangle yes
377 (jj-compile-and-load jj-emacs-config)
378 #+END_SRC
379
380 *** Specific configurations
381
382 The following may exist - or may not. Depending on the operating
383 system, system type, username or emacs version I can load special
384 configuration.
385 #+BEGIN_SRC emacs-lisp :tangle yes
386 (if (file-exists-p jj-os-config) (jj-compile-and-load jj-os-config))
387 (if (file-exists-p jj-sys-config) (jj-compile-and-load jj-sys-config))
388 (if (file-exists-p jj-user-config) (jj-compile-and-load jj-user-config))
389 (if (file-exists-p jj-ev-config) (jj-compile-and-load jj-ev-config))
390 #+END_SRC
391
392 *** Final steps
393
394 And finally, we ensure that our function goes away, no reason to keep
395 it. And then print out the time it took to start emacs.
396 #+BEGIN_SRC emacs-lisp :tangle yes
397 (makunbound 'jj-compile-and-load)
398
399 ;; Lets get a message about startup time out
400 (when (require 'time-date nil t)
401 (message "Emacs startup time: %d seconds."
402 (time-to-seconds (time-since emacs-load-start-time)))
403 )
404 #+END_SRC