.
[emacs.git] / .emacs.d / init.el
1 ;; Ganneff's emacs config
2
3 ;; Emacs can not read its config directly from org-mode files.
4 ;; But as my config nearly completly is inside an org-mode file,
5 ;; emacs need to be told to deal with it.
6 ;; Meet org-tangle/org-babel-load-file, which extracts the emacs-lisp
7 ;; source parts of my config files, writes them into .el files
8 ;; and then lets emacs load those.
9
10 ;; That way I have a nice environment to edit and comment - and easily export
11 ;; to web or elsewhere - while emacs has its elisp. The initial run after
12 ;; a config change takes longer, but as that only happens when I change
13 ;; something in the .org files - I don't care.
14
15 ;; Go go go
16 (message "Emacs is powering up... Be patient, Master %s!" (getenv "USER"))
17
18 ;; I like to see how long it takes to "boot" emacs (usually one or two
19 ;; seconds), so save the start time
20 (defvar emacs-load-start-time (current-time))
21
22 ;; We will need a set of directories for stuff
23 ;; Lets define some variables for them
24
25 ;; I might have special configuration based on various states
26 ;; First we set an own variable, as system-type from emacs directly is
27 ;; useless. gnu/linux and gnu/kfreebsd have extra /, which is plenty annoying
28 ;; when you want to use them in a path entry.
29 (defun jj-system-type ()
30 "Return a string depending on the OS we use"
31 (interactive)
32 (cond
33 ((eq system-type 'darwin) "macosx")
34 ((eq system-type 'gnu/linux) "linux")
35 ((eq system-type 'gnu/kfreebsd) "kfreebsd")
36 ((eq system-type 'cygwin) "cygwin")
37 ((eq system-type 'windows-nt) "windows")))
38
39
40 (defvar jj-dir (file-name-directory (or load-file-name (buffer-file-name)))
41 "The master directory for Ganneffs emacs configuration and storage.
42 Usually ~/.emacs.d/")
43 (defvar jj-config-dir
44 (expand-file-name "config" jj-dir)
45 "Ganneffs main emacs configuration can be found here.")
46 (defvar jj-emacs-config
47 (expand-file-name "emacs.org" jj-config-dir)
48 "Ganneffs main emacs configuration file.")
49 (defvar jj-elisp-dir
50 (expand-file-name "elisp" jj-dir)
51 "This directory stores subdirs for local packages in Ganneffs emacs config.")
52 (defvar jj-elisp-local-dir
53 (expand-file-name "local" jj-elisp-dir)
54 "This directory stores extra elisp files for Ganneffs emacs config.")
55 (defvar jj-custom-file
56 (expand-file-name "customized.el" jj-config-dir)
57 "Changes from the customization interface in Ganneffs emacs config.")
58 (defvar jj-cache-dir
59 (expand-file-name "cache" jj-dir)
60 "This directory stores cache files and other volatile data.")
61 (defvar jj-backup-directory
62 (expand-file-name (concat "emacs-autosave-" user-login-name) jj-cache-dir)
63 "This directory stores backup files.")
64 (defvar jj-theme-dir
65 (expand-file-name "themes" jj-dir)
66 "This directory stores theme files for Ganneffs emacs config")
67
68 (defvar jj-sys-config
69 (expand-file-name (concat system-name ".org") jj-config-dir)
70 "Ganneffs System/Host specific emacs configiraton file.")
71 (defvar jj-os-config
72 (expand-file-name (concat (jj-system-type) ".org") jj-config-dir)
73 "Ganneffs Operating system specific emacs configuration file.")
74 (defvar jj-user-config
75 (expand-file-name (concat user-login-name ".org") jj-config-dir)
76 "Ganneffs username specific emacs configuration file.")
77 (defvar jj-ev-config (expand-file-name
78 (concat "emacs"
79 (number-to-string emacs-major-version) ".org")
80 jj-config-dir)
81 "Ganneffs emacs version specific configuration file.")
82 (defvar jj-color-style 'dark "Which color scheme of solarized to select. Dark or Light")
83
84 ;; Ensure that the cache directory hierarchy exists
85 (if (not (file-exists-p jj-cache-dir))
86 (make-directory jj-cache-dir))
87 (if (not (file-exists-p jj-backup-directory))
88 (make-directory jj-backup-directory))
89
90 ;; Set path to (my, recent) Org-Mode version
91 (add-to-list 'load-path (concat jj-elisp-dir "/org/"))
92 ;; Have use-package/bindkey in here wich are needed for startup
93 (add-to-list 'load-path jj-elisp-local-dir)
94
95 ;; As we use org-mode/org-babel/org-tangle to extract the real emacs
96 ;; config out of the org-mode files, we have to load that first.
97 (setq org-modules (quote
98 (org-bbdb org-bibtex org-crypt org-docview org-gnus
99 org-id org-info org-jsinfo org-habit org-inlinetask
100 org-irc org-protocol org-w3m org-mouse org-checklist
101 org-notmuch icalendar)))
102 (require 'org-install)
103 (require 'ob-tangle)
104
105 (defvar jj-init-files '() "Temporary list of files that need a byte-compile")
106 (defun jj-byte-compile-init ()
107 "Byte compile a list of files"
108 (let (filename)
109 (dolist (filename jj-init-files)
110 (when (file-exists-p filename)
111 (message "Byte-compiling %s, standby" filename)
112 (byte-compile-file filename))))
113 (makunbound 'jj-init-files)
114 (makunbound 'jj-byte-compile-init)
115 )
116 (defun jj-compile-and-load (&optional arg)
117 "Use org-tangle to get the emacs-lisp parts from .org emacs
118 config files into .el ones, byte-compile those and then load
119 them."
120 (let ((el-file (concat (file-name-sans-extension arg) ".el")))
121 (cond
122 ((file-newer-than-file-p arg el-file)
123 (org-babel-tangle-file arg el-file "emacs-lisp")
124 (add-hook 'after-init-hook 'jj-byte-compile-init)
125 (add-to-list 'jj-init-files (symbol-value 'el-file))))
126 (load-file el-file)
127 ))
128
129 ;; Now read my config
130 ;; Note that those files *can* include further files.
131 ;; The basic config is always loaded, no matter where we start emacs.
132 (jj-compile-and-load jj-emacs-config)
133
134 ;; All the others are optional. We try the order of os, system, user
135 ;; specific files and load them, should they be there
136 (if (file-exists-p jj-os-config) (jj-compile-and-load jj-os-config))
137 (if (file-exists-p jj-sys-config) (jj-compile-and-load jj-sys-config))
138 (if (file-exists-p jj-user-config) (jj-compile-and-load jj-user-config))
139 (if (file-exists-p jj-ev-config) (jj-compile-and-load jj-ev-config))
140
141 (makunbound 'jj-compile-and-load)
142
143 ;; Lets get a message about startup time out
144 (when (require 'time-date nil t)
145 (message "Emacs startup time: %d seconds."
146 (time-to-seconds (time-since emacs-load-start-time)))
147 )