-
Notifications
You must be signed in to change notification settings - Fork 11
/
init.el
117 lines (97 loc) · 5.46 KB
/
init.el
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
;; Emacs 24 init.el
;; Based on http://github.com/eschulte/emacs24-starter-kit
;; NOTE: The name of the Org files is important! When a file gets tangled,
;; it gets the same base name as the Org file. Thus, tangling Emacs Lisp from
;; a file `init.org` would generate `init.el`, obliterating this file in the
;; process. So your config org file should not be named "init.org".
;; log starting time to come up with a duration afterwards
;; Added by Package.el. This must come before configurations of
;; installed packages. Don't delete this line. If you don't want it,
;; just comment it out by adding a semicolon to the start of the line.
;; You may delete these explanatory comments.
(package-initialize)
(defvar my-init-el-start-time (current-time) "Time when init.el was started")
;; set paths to manually installed Org-mode (from git; instead of built-in Org-mode)
;;(add-to-list 'load-path "~/.emacs.d/contrib/org-mode/lisp")
;;(add-to-list 'load-path "~/.emacs.d/contrib/org-mode/contrib/lisp" t)
(require 'org)
;; user-emacs-directory on Windows is "c:/Users/karl.voit/AppData/Roaming/.emacs.d/" which I don't want to use
(setq my-user-emacs-directory "~/.emacs.d/")
;; =======================================================================================
;; The init.el file looks for "config.org" and tangles its elisp blocks (matching
;; the criteria described below) to "config.el" which is loaded as Emacs configuration.
;; Inspired and copied from: http://www.holgerschurig.de/en/emacs-init-tangle/
;; =======================================================================================
;; from: http://stackoverflow.com/questions/251908/how-can-i-insert-current-date-and-time-into-a-file-using-emacs
(defvar current-date-time-format "%a %b %d %Y-%m-%dT%H:%M:%S "
"Format of date to insert with `insert-current-date-time' func
See help of `format-time-string' for possible replacements")
;; from: http://stackoverflow.com/questions/251908/how-can-i-insert-current-date-and-time-into-a-file-using-emacs
(defvar current-time-format "%a %H:%M:%S"
"Format of date to insert with `insert-current-time' func.
Note the weekly scope of the command's precision.")
(defun my-tangle-config-org ()
"This function will write all source blocks from =config.org= into =config.el= that are ...
- not marked as =tangle: no=
- doesn't have the TODO state =DISABLED=
- have a source-code of =emacs-lisp="
(require 'org)
(let* ((body-list ())
(output-file (concat my-user-emacs-directory "config.el"))
(org-babel-default-header-args (org-babel-merge-params org-babel-default-header-args
(list (cons :tangle output-file)))))
(message "—————• Re-generating %s …" output-file)
(save-restriction
(save-excursion
(org-babel-map-src-blocks (concat my-user-emacs-directory "config.org")
(let* (
(org_block_info (org-babel-get-src-block-info 'light))
;;(block_name (nth 4 org_block_info))
(tfile (cdr (assq :tangle (nth 2 org_block_info))))
(match_for_TODO_keyword)
)
(save-excursion
(catch 'exit
;;(when (string= "" block_name)
;; (message "Going to write block name: " block_name)
;; (add-to-list 'body-list (concat "message(\"" block_name "\")"));; adding a debug statement for named blocks
;; )
(org-back-to-heading t)
(when (looking-at org-outline-regexp)
(goto-char (1- (match-end 0))))
(when (looking-at (concat " +" org-todo-regexp "\\( +\\|[ \t]*$\\)"))
(setq match_for_TODO_keyword (match-string 1)))))
(unless (or (string= "no" tfile)
(string= "DISABLED" match_for_TODO_keyword)
(not (string= "emacs-lisp" lang)))
(add-to-list 'body-list (concat "\n\n;; #####################################################################################\n"
"(message \"config • " (org-get-heading) " …\")\n\n")
)
(add-to-list 'body-list body)
))))
(with-temp-file output-file
(insert ";; ============================================================\n")
(insert ";; Don't edit this file, edit config.org' instead ...\n")
(insert ";; Auto-generated at " (format-time-string current-date-time-format (current-time)) " on host " system-name "\n")
(insert ";; ============================================================\n\n")
(insert (apply 'concat (reverse body-list))))
(message "—————• Wrote %s" output-file))))
;; following lines are executed only when my-tangle-config-org-hook-func()
;; was not invoked when saving config.org which is the normal case:
(let ((orgfile (concat my-user-emacs-directory "config.org"))
(elfile (concat my-user-emacs-directory "config.el"))
(gc-cons-threshold most-positive-fixnum))
(when (or (not (file-exists-p elfile))
(file-newer-than-file-p orgfile elfile))
(my-tangle-config-org)
;;(save-buffers-kill-emacs);; TEST: kill Emacs when config has been re-generated due to many issues when loading newly generated config.el
)
(load-file elfile))
;; when config.org is saved, re-generate config.el:
(defun my-tangle-config-org-hook-func ()
(when (string= "config.org" (buffer-name))
(let ((orgfile (concat my-user-emacs-directory "config.org"))
(elfile (concat my-user-emacs-directory "config.el")))
(my-tangle-config-org))))
(add-hook 'after-save-hook 'my-tangle-config-org-hook-func)
(message "→★ loading init.el in %.2fs" (float-time (time-subtract (current-time) my-init-el-start-time)))