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
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.
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.
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=.
21 If you have Javascript disabled you only miss the nice navigation, you
22 will see the whole file at once.
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
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.
37 Copyright © 200x-2012 Joerg Jaspert <joerg@ganneff.de>
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.
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]]
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:
55 Copyright © 2001-2012 Sacha Chua (sacha@sachachua.com).
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.
63 Functions copied from her start with /sacha//.
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:
71 Copyright (C) 2012 Bernt Hansen.
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.
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.
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.
90 Functions copied from him start with /bh//.
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:
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.
105 In case you are as good in french as I am, that should be equal to:
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.
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.
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...
129 Anything copied from prelude should start with prelude-, and their
130 license statement is:
134 Copyright © 2011-2013 Bozhidar Batsov
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.
145 You should be able to find a full list of contributors at
146 [[https://github.com/bbatsov/prelude/graphs/contributors][their github]] pages.
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.
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.
160 As I commented inside that file, I won't repeat stuff here, just read it
163 #+INCLUDE: "~/.emacs.d/init.el" src emacs-lisp
165 * Basic initialization
166 First of I want a set of variables defined, makes it easier to refer
167 to common things later.
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"
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")))
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/")
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.")
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.")
213 Where do I store packages for emacs.
214 #+BEGIN_SRC emacs-lisp :tangle yes
216 (expand-file-name "elisp" jj-dir)
217 "This directory stores subdirs for local packages in Ganneffs emacs config.")
220 *** jj-elisp-local-dir
221 Some packages just come with a single file. I put them into this
222 local directory instead of giving them an own one.
223 #+BEGIN_SRC emacs-lisp :tangle yes
224 (defvar jj-elisp-local-dir
225 (expand-file-name "local" jj-elisp-dir)
226 "This directory stores extra elisp files for Ganneffs emacs config.")
230 The customization interface of emacs stores its values in this file.
231 #+BEGIN_SRC emacs-lisp :tangle yes
232 (defvar jj-custom-file
233 (expand-file-name "customized.el" jj-config-dir)
234 "Changes from the customization interface in Ganneffs emacs config.")
238 Similar to /var on a unix system, volatile data, cache files, ...
239 #+BEGIN_SRC emacs-lisp :tangle yes
241 (expand-file-name "cache" jj-dir)
242 "This directory stores cache files and other volatile data.")
245 *** jj-backup-directory
246 Backup copies of files I edit are stored here.
247 #+BEGIN_SRC emacs-lisp :tangle yes
248 (defvar jj-backup-directory
249 (expand-file-name (concat "emacs-autosave-" user-login-name) jj-cache-dir)
250 "This directory stores backup files.")
254 Where my theme files are stored.
255 #+BEGIN_SRC emacs-lisp :tangle yes
257 (expand-file-name "themes" jj-dir)
258 "This directory stores theme files for Ganneffs emacs config")
262 System dependent configuration information stored in here.
263 #+BEGIN_SRC emacs-lisp :tangle yes
264 (defvar jj-sys-config
265 (expand-file-name (concat system-name ".org") jj-config-dir)
266 "Ganneffs System/Host specific emacs configuration file.")
270 Operating System dependent configuration information stored in here.
271 #+BEGIN_SRC emacs-lisp :tangle yes
273 (expand-file-name (concat (jj-system-type) ".org") jj-config-dir)
274 "Ganneffs Operating system specific emacs configuration file.")
278 User dependent configuration stored in here.
279 #+BEGIN_SRC emacs-lisp :tangle yes
280 (defvar jj-user-config
281 (expand-file-name (concat user-login-name ".org") jj-config-dir)
282 "Ganneffs username specific emacs configuration file.")
286 Emacs version dependent configuration stored in here.
287 #+BEGIN_SRC emacs-lisp :tangle yes
288 (defvar jj-ev-config (expand-file-name
290 (number-to-string emacs-major-version) ".org")
292 "Ganneffs emacs version specific configuration file.")
296 Which color scheme should be loaded? I prefer dark very much.
297 #+BEGIN_SRC emacs-lisp :tangle yes
298 (defvar jj-color-style 'dark "Which color scheme of solarized to select. Dark or Light")
302 A small wrapper around =eval-after-load=, taken from [[http://milkbox.net/note/single-file-master-emacs-configuration/][Single File Master Emacs Configuration : milkbox]]
303 #+BEGIN_SRC emacs-lisp :tangle yes
304 (defmacro after (mode &rest body)
305 "`eval-after-load' MODE evaluate BODY."
306 (declare (indent defun))
307 `(eval-after-load ,mode
311 First we want to ensure that our cache and backup directories really exist.
312 #+BEGIN_SRC emacs-lisp :tangle yes
313 (if (not (file-exists-p jj-cache-dir))
314 (make-directory jj-cache-dir))
315 (if (not (file-exists-p jj-backup-directory))
316 (make-directory jj-backup-directory))
319 Add our local elisp directory to the load path early, as it contains
320 files we want to load during configuration processing, before the
321 load-path gets set up for real.
322 #+BEGIN_SRC emacs-lisp :tangle yes
323 ;; Have use-package/bindkey in here wich are needed for startup
324 (add-to-list 'load-path jj-elisp-local-dir)
327 I have a function that uses org-tangle to extract all emacs-lisp
328 codeblocks out of my org-mode configuration files. After which it
329 ensures that the generated elisp files get byte-compiled.
331 As my configuration requires certain parts of the configuration to
332 already be loaded when the byte-compilation happens, this is done
333 using an /after-init-hook/.
334 #+BEGIN_SRC emacs-lisp :tangle yes
335 (defvar jj-init-files '() "Temporary list of files that need a byte-compile")
336 (defun jj-byte-compile-init ()
337 "Byte compile a list of files"
339 (dolist (filename jj-init-files)
340 (when (file-exists-p filename)
341 (message "Byte-compiling %s, standby" filename)
342 (byte-compile-file filename))))
343 (makunbound 'jj-init-files)
344 (makunbound 'jj-byte-compile-init)
346 (defun jj-compile-and-load (&optional arg)
347 "Use org-tangle to get the emacs-lisp parts from .org emacs
348 config files into .el ones, byte-compile those and then load
350 (let ((el-file (concat (file-name-sans-extension arg) ".el")))
352 ((file-newer-than-file-p arg el-file)
353 (org-babel-tangle-file arg el-file "emacs-lisp")
354 (add-hook 'after-init-hook 'jj-byte-compile-init)
355 (add-to-list 'jj-init-files (symbol-value 'el-file))))
360 ** Extra files to load
362 And finally we are going to load the various files.
364 *** Global emacs config, always loaded
366 This file is loaded no matter what and exists on all machines my
367 dotfiles are on. [[file:config/emacs.org][Main Emacs config]]
368 #+BEGIN_SRC emacs-lisp :tangle yes
369 (jj-compile-and-load jj-emacs-config)
372 *** Specific configurations
374 The following may exist - or may not. Depending on the operating
375 system, system type, username or emacs version I can load special
377 #+BEGIN_SRC emacs-lisp :tangle yes
378 (if (file-exists-p jj-os-config) (jj-compile-and-load jj-os-config))
379 (if (file-exists-p jj-sys-config) (jj-compile-and-load jj-sys-config))
380 (if (file-exists-p jj-user-config) (jj-compile-and-load jj-user-config))
381 (if (file-exists-p jj-ev-config) (jj-compile-and-load jj-ev-config))
386 And finally, we ensure that our function goes away, no reason to keep
387 it. And then print out the time it took to start emacs.
388 #+BEGIN_SRC emacs-lisp :tangle yes
389 (makunbound 'jj-compile-and-load)
391 ;; Lets get a message about startup time out
392 (when (require 'time-date nil t)
393 (message "Emacs startup time: %d seconds."
394 (time-to-seconds (time-since emacs-load-start-time)))