]> git.donarmstrong.com Git - lib.git/blob - emacs_el/configuration/org-mode-configuration.el
add automatic reminders for appointments
[lib.git] / emacs_el / configuration / org-mode-configuration.el
1 (require 'org-id)
2 (require 'reftex)
3 (require 'gnus)
4
5 (require 'org)
6 (require 'org-agenda)
7 (require 'org-habit)
8 ;; The following lines are always needed. Choose your own keys.
9 (add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))
10 (eval-when-compile
11   (require 'cl))
12 (global-set-key "\C-cl" 'org-store-link)
13 (global-set-key "\C-ca" 'org-agenda)
14 (global-set-key "\C-cb" 'org-iswitchb)
15 (setq-default org-log-done 'time)
16 (setq-default org-agenda-ndays 5)
17
18 ;; agenda configuration
19 ;; Do not dim blocked tasks
20 (setq org-agenda-dim-blocked-tasks nil)
21
22 ;; Compact the block agenda view
23 (setq org-agenda-compact-blocks t)
24
25 ;; Custom agenda command definitions
26 (setq org-agenda-custom-commands
27       (quote (("N" "Notes" tags "NOTE"
28                ((org-agenda-overriding-header "Notes")
29                 (org-tags-match-list-sublevels t)))
30               ("h" "Habits" tags-todo "STYLE=\"habit\""
31                ((org-agenda-overriding-header "Habits")
32                 (org-agenda-sorting-strategy
33                  '(todo-state-down effort-up category-keep))))
34               (" " "Agenda"
35                ((agenda "" nil)
36                 (tags "REFILE"
37                       ((org-agenda-overriding-header "Tasks to Refile")
38                        (org-tags-match-list-sublevels nil)))
39                 (tags-todo "-CANCELLED/!"
40                            ((org-agenda-overriding-header "Stuck Projects")
41                             (org-agenda-skip-function 'bh/skip-non-stuck-projects)
42                             (org-agenda-sorting-strategy
43                              '(category-keep))))
44                 (tags-todo "-HOLD-CANCELLED/!"
45                            ((org-agenda-overriding-header "Projects")
46                             (org-agenda-skip-function 'bh/skip-non-projects)
47                             (org-tags-match-list-sublevels 'indented)
48                             (org-agenda-sorting-strategy
49                              '(category-keep))))
50                 (tags-todo "-CANCELLED/!NEXT"
51                            ((org-agenda-overriding-header (concat "Project Next Tasks"
52                                                                   (if bh/hide-scheduled-and-waiting-next-tasks
53                                                                       ""
54                                                                     " (including WAITING and SCHEDULED tasks)")))
55                             (org-agenda-skip-function 'bh/skip-projects-and-habits-and-single-tasks)
56                             (org-tags-match-list-sublevels t)
57                             (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
58                             (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
59                             (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
60                             (org-agenda-sorting-strategy
61                              '(todo-state-down effort-up category-keep))))
62                 (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
63                            ((org-agenda-overriding-header (concat "Project Subtasks"
64                                                                   (if bh/hide-scheduled-and-waiting-next-tasks
65                                                                       ""
66                                                                     " (including WAITING and SCHEDULED tasks)")))
67                             (org-agenda-skip-function 'bh/skip-non-project-tasks)
68                             (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
69                             (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
70                             (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
71                             (org-agenda-sorting-strategy
72                              '(category-keep))))
73                 (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
74                            ((org-agenda-overriding-header (concat "Standalone Tasks"
75                                                                   (if bh/hide-scheduled-and-waiting-next-tasks
76                                                                       ""
77                                                                     " (including WAITING and SCHEDULED tasks)")))
78                             (org-agenda-skip-function 'bh/skip-project-tasks)
79                             (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
80                             (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
81                             (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
82                             (org-agenda-sorting-strategy
83                              '(category-keep))))
84                 (tags-todo "-CANCELLED+WAITING|HOLD/!"
85                            ((org-agenda-overriding-header "Waiting and Postponed Tasks")
86                             (org-agenda-skip-function 'bh/skip-stuck-projects)
87                             (org-tags-match-list-sublevels nil)
88                             (org-agenda-todo-ignore-scheduled t)
89                             (org-agenda-todo-ignore-deadlines t)))
90                 (tags "-REFILE/"
91                       ((org-agenda-overriding-header "Tasks to Archive")
92                        (org-agenda-skip-function 'bh/skip-non-archivable-tasks)
93                        (org-tags-match-list-sublevels nil))))
94                nil))))
95
96 ; org mode agenda files
97 (setq org-agenda-files
98       (quote ("~/projects/org-notes/debbugs.org"
99               "~/projects/org-notes/notes.org"
100               "~/projects/org-notes/refile.org"
101               "~/projects/org-notes/diary.org"
102               "~/projects/org-notes/ool.org"
103               "~/projects/org-notes/sndservers.org"
104               "~/projects/org-notes/chaim.org"
105               "~/projects/org-notes/wildman.org"
106               "~/projects/org-notes/uddin.org"
107           "~/projects/org-notes/reviews.org"
108           "~/projects/org-notes/hpcbio.org"
109           "~/org-mode/from-mobile.org"
110               "~/projects/org-notes/fh.org")))
111
112 (set-register ?n (cons 'file "~/projects/org-notes/notes.org"))
113 (set-register ?r (cons 'file "~/projects/org-notes/refile.org"))
114 (set-register ?o (cons 'file "~/projects/org-notes/ool.org"))
115 (set-register ?s (cons 'file "~/projects/org-notes/sndservers.org"))
116 (set-register ?c (cons 'file "~/projects/org-notes/chaim.org"))
117 (set-register ?w (cons 'file "~/projects/org-notes/wildman.org"))
118 (set-register ?u (cons 'file "~/projects/org-notes/uddin.org"))
119 (set-register ?R (cons 'file "~/projects/reviews/reviews.org"))
120 (set-register ?d (cons 'file "~/projects/org-notes/diary.org"))
121
122 (setq org-global-properties '(("Effort_ALL 0 0:10 0:30 1:00 2:00 3:00 4:00 5:00 6:00 7:00")))
123 (setq org-columns-default-format "%40ITEM(Task) %6Effort{:} %CLOCKSUM %PRIORITY %TODO %13SCHEDULED %13DEADLINE %TAGS")
124
125 ;; add automatic reminders for appointments
126 (defadvice  org-agenda-redo (after org-agenda-redo-add-appts)
127   "Pressing `r' on the agenda will also add appointments."
128   (progn 
129     (setq appt-time-msg-list nil)
130     (org-agenda-to-appt)))
131
132 (setq org-default-notes-file "~/projects/org-notes/notes.org")
133 (setq org-id-link-to-org-use-id t)
134 (setq org-capture-templates  ;; mail-specific note template, identified by "m"
135       '(("m" "Mail" entry (file+headline "~/projects/org-notes/refile.org" "Mail")
136          "* %?\n\n  Source: %u, %c\n  %i")
137         ("t" "todo" entry (file "~/projects/org-notes/refile.org")
138          "* TODO %?\n  :PROPERTIES:\n  :END:\n  :LOGBOOK:\n  :END:\n%U\n%a\n" :clock-in t :clock-resume t)
139         ("r" "respond" entry (file "~/projects/org-notes/refile.org")
140          "* NEXT Respond to %:from on %:subject\nSCHEDULED: %t\n%U\n%a\n" :clock-in t :clock-resume t :immediate-finish t)
141         ("n" "note" entry (file "~/projects/org-notes/refile.org")
142          "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t)
143         ("s" "schedule" entry (file "~/projects/org-notes/refile.org")
144          "* %? :cal:\n%^{scheduled:}t\n%U\n%a\n" :clock-in t :clock-resume t)
145         ("j" "Journal" entry (file+datetree "~/projects/org-notes/diary.org")
146          "* %?\n%U\n" :clock-in t :clock-resume t)
147         ("w" "org-protocol" entry (file "~/projects/org-notes/refile.org")
148          "* TODO Review %c\n%U\n" :immediate-finish t)
149         ("M" "Meeting" entry (file "~/projects/org-notes/refile.org")
150          "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t)
151         ("S" "Seminar" entry (file "~/projects/org-notes/refile.org")
152          "* SEMINAR notes %? :SEMINAR:\n%U" :clock-in t :clock-resume t)
153         ("P" "Paper to read" entry (file+headline "~/projects/research/papers_to_read.org" "Refile")
154          "* TODO Get/Read %? \n%U" :clock-in t :clock-resume t)
155         ("p" "Phone call" entry (file "~/projects/org-notes/refile.org")
156          "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t)
157         ("J" "job" entry (file "~/projects/org-notes/refile.org")
158          "* TODO Apply for %a%? :job:\nSCHEDULED: %(format-time-string \"<%Y-%m-%d 17:00-17:30>\")\n%U\n%a\n" :clock-in t :clock-resume t)
159         ("h" "Habit" entry (file "~/projects/org-notes/refile.org")
160          "* NEXT %?\n%U\n%a\nSCHEDULED: %(format-time-string \"<%Y-%m-%d .+1d/3d>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n%a\n")
161         )
162       )
163
164 ;; Remove empty LOGBOOK drawers on clock out
165 (defun bh/remove-empty-drawer-on-clock-out ()
166   (interactive)
167   (save-excursion
168     (beginning-of-line 0)
169     (org-remove-empty-drawer-at (point))))
170
171 (defun my/org-add-id ()
172   (interactive)
173   (save-excursion
174     (if (org-current-level)
175         ()
176       (forward-char 1)
177       )
178     (org-id-get-create)
179     )
180 )
181
182 ; org mode configuration from http://doc.norang.ca/org-mode.html
183 ;; Custom Key Bindings
184 (global-set-key (kbd "<f12>") 'org-agenda)
185 (global-set-key (kbd "<f5>") 'bh/org-todo)
186 (global-set-key (kbd "<S-f5>") 'bh/widen)
187 (global-set-key (kbd "<f7>") 'bh/set-truncate-lines)
188 (global-set-key (kbd "<f8>") 'org-cycle-agenda-files)
189 (global-set-key (kbd "<f9> <f9>") 'bh/show-org-agenda)
190 (global-set-key (kbd "<f9> b") 'bbdb)
191 (global-set-key (kbd "<f9> c") 'calendar)
192 (global-set-key (kbd "<f9> f") 'boxquote-insert-file)
193 (global-set-key (kbd "<f9> h") 'bh/hide-other)
194 (global-set-key (kbd "<f9> n") 'bh/toggle-next-task-display)
195 (global-set-key (kbd "<f9> w") 'widen)
196
197 ; change the outline mode prefix from C-c @ to C-c C-2
198 (setq outline-minor-mode-prefix "C-c C-2")
199 ;(add-hook 'outline-minor-mode-hook
200 ;          (lambda () (local-set-key (kbd "C-c C-2")
201 ;                                    outline-mode-prefix-map)))
202
203 (global-set-key (kbd "<f9> I") 'bh/punch-in)
204 (global-set-key (kbd "<f9> O") 'bh/punch-out)
205
206 (global-set-key (kbd "<f9> o") 'bh/make-org-scratch)
207
208 (global-set-key (kbd "<f9> r") 'boxquote-region)
209 (global-set-key (kbd "<f9> s") 'bh/switch-to-scratch)
210
211 (global-set-key (kbd "<f9> t") 'bh/insert-inactive-timestamp)
212 (global-set-key (kbd "<f9> T") 'bh/toggle-insert-inactive-timestamp)
213
214 (global-set-key (kbd "<f9> v") 'visible-mode)
215 (global-set-key (kbd "<f9> l") 'org-toggle-link-display)
216 (global-set-key (kbd "<f9> SPC") 'bh/clock-in-last-task)
217 (global-set-key (kbd "C-<f9>") 'previous-buffer)
218 (global-set-key (kbd "M-<f9>") 'org-toggle-inline-images)
219 (global-set-key (kbd "C-x n r") 'narrow-to-region)
220 (global-set-key (kbd "C-<f10>") 'next-buffer)
221 (global-set-key (kbd "<f11>") 'org-clock-goto)
222 (global-set-key (kbd "C-<f11>") 'org-clock-in)
223 (global-set-key (kbd "C-s-<f12>") 'bh/save-then-publish)
224 (global-set-key (kbd "C-c c") 'org-capture)
225
226 (defun bh/hide-other ()
227   (interactive)
228   (save-excursion
229     (org-back-to-heading 'invisible-ok)
230     (hide-other)
231     (org-cycle)
232     (org-cycle)
233     (org-cycle)))
234
235 (defun bh/set-truncate-lines ()
236   "Toggle value of truncate-lines and refresh window display."
237   (interactive)
238   (setq truncate-lines (not truncate-lines))
239   ;; now refresh window display (an idiom from simple.el):
240   (save-excursion
241     (set-window-start (selected-window)
242                       (window-start (selected-window)))))
243
244 (defun bh/make-org-scratch ()
245   (interactive)
246   (find-file "/tmp/publish/scratch.org")
247   (gnus-make-directory "/tmp/publish"))
248
249 (defun bh/switch-to-scratch ()
250   (interactive)
251   (switch-to-buffer "*scratch*"))
252
253 (setq org-use-fast-todo-selection t)
254 (setq org-treat-S-cursor-todo-selection-as-state-change nil)
255
256 (setq org-todo-keywords
257       (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
258               (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))
259
260 (setq org-todo-keyword-faces
261       (quote (("TODO" :foreground "red" :weight bold)
262               ("NEXT" :foreground "blue" :weight bold)
263               ("DONE" :foreground "forest green" :weight bold)
264               ("WAITING" :foreground "orange" :weight bold)
265               ("HOLD" :foreground "magenta" :weight bold)
266               ("CANCELLED" :foreground "forest green" :weight bold)
267               ("MEETING" :foreground "forest green" :weight bold)
268               ("PHONE" :foreground "forest green" :weight bold))))
269
270 (setq org-todo-state-tags-triggers
271       (quote (("CANCELLED" ("CANCELLED" . t))
272               ("WAITING" ("WAITING" . t))
273               ("HOLD" ("WAITING") ("HOLD" . t))
274               (done ("WAITING") ("HOLD"))
275               ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
276               ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
277               ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))
278
279
280
281 ; (add-hook 'org-clock-out-hook 'bh/remove-empty-drawer-on-clock-out 'append)
282 ; add ids on creation of nodes
283 (add-hook 'org-capture-prepare-finalize-hook 'my/org-add-id)
284 ; create function to create headlines in file. This comes from
285 ; http://stackoverflow.com/questions/13340616/assign-ids-to-every-entry-in-org-mode
286 (defun my/org-add-ids-to-headlines-in-file ()
287   "Add ID properties to all headlines in the current file which
288 do not already have one."
289   (interactive)
290   (org-map-entries 'org-id-get-create))
291 ; if we wanted to do this to every buffer, do the following:
292 ; (add-hook 'org-mode-hook
293 ;           (lambda ()
294 ;             (add-hook 'before-save-hook 'my/org-add-ids-to-headlines-in-file nil 'local)))
295
296
297 ; resolve clocks after 10 minutes of idle; use xprintidle
298 ; (setq org-clock-idle-time 10)
299 ; (setq org-clock-x11idle-program-name "xprintidle")
300
301 ; this is from http://doc.norang.ca/org-mode.html#Capture
302 ; use C-M-r for org mode capture
303 (global-set-key (kbd "C-M-r") 'org-capture)
304
305 ; Targets include this file and any file contributing to the agenda - up to 9 levels deep
306 (setq org-refile-targets (quote ((nil :maxlevel . 9)
307                                  (org-agenda-files :maxlevel . 9))))
308
309 ; Use full outline paths for refile targets - we file directly with IDO
310 (setq org-refile-use-outline-path t)
311
312 ; Targets complete directly with IDO
313 (setq org-outline-path-complete-in-steps nil)
314
315 ; Allow refile to create parent tasks with confirmation
316 (setq org-refile-allow-creating-parent-nodes (quote confirm))
317
318 ; ; Use IDO for both buffer and file completion and ido-everywhere to t
319 ; (setq org-completion-use-ido t)
320 ; (setq ido-everywhere t)
321 ; (setq ido-max-directory-size 100000)
322 ; (ido-mode (quote both))
323 ; ; Use the current window when visiting files and buffers with ido
324 ; (setq ido-default-file-method 'selected-window)
325 ; (setq ido-default-buffer-method 'selected-window)
326 ; ; Use the current window for indirect buffer display
327 ; (setq org-indirect-buffer-display 'current-window)
328
329
330 ;;;; Refile settings
331 ; Exclude DONE state tasks from refile targets
332 (defun bh/verify-refile-target ()
333   "Exclude todo keywords with a done state from refile targets"
334   (not (member (nth 2 (org-heading-components)) org-done-keywords)))
335
336 (setq org-refile-target-verify-function 'bh/verify-refile-target)
337
338 ;; ensure that emacsclient will show just the note to be edited when invoked
339 ;; from Mutt, and that it will shut down emacsclient once finished;
340 ;; fallback to legacy behavior when not invoked via org-protocol.
341 (require 'org-protocol)
342 ; (add-hook 'org-capture-mode-hook 'delete-other-windows)
343 (setq my-org-protocol-flag nil)
344 (defadvice org-capture-finalize (after delete-frame-at-end activate)
345   "Delete frame at remember finalization"
346   (progn (if my-org-protocol-flag (delete-frame))
347          (setq my-org-protocol-flag nil)))
348 (defadvice org-capture-refile (around delete-frame-after-refile activate)
349   "Delete frame at remember refile"
350   (if my-org-protocol-flag
351       (progn
352         (setq my-org-protocol-flag nil)
353         ad-do-it
354         (delete-frame))
355     ad-do-it)
356   )
357 (defadvice org-capture-kill (after delete-frame-at-end activate)
358   "Delete frame at remember abort"
359   (progn (if my-org-protocol-flag (delete-frame))
360          (setq my-org-protocol-flag nil)))
361 (defadvice org-protocol-capture (before set-org-protocol-flag activate)
362   (setq my-org-protocol-flag t))
363
364 (defadvice org-insert-todo-heading (after dla/create-id activate)
365   (org-id-get-create)
366   )
367
368 ;; org modules
369 (add-to-list 'org-modules 'org-habit)
370
371 ; this comes from http://upsilon.cc/~zack/blog/posts/2010/02/integrating_Mutt_with_Org-mode/
372 (defun open-mail-in-mutt (message)
373   "Open a mail message in Mutt, using an external terminal.
374
375 Message can be specified either by a path pointing inside a
376 Maildir, or by Message-ID."
377   (interactive "MPath or Message-ID: ")
378   (shell-command
379    (format "faf xterm -e \"%s %s\""
380        (substitute-in-file-name "$HOME/bin/mutt_open") message)))
381
382 ;; add support for "mutt:ID" links
383 (org-add-link-type "mutt" 'open-mail-in-mutt)
384
385 (defun my-org-mode-setup ()
386   (load-library "reftex")
387   (and (buffer-file-name)
388        (file-exists-p (buffer-file-name))
389        (progn
390          (reftex-parse-all)
391          (reftex-set-cite-format
392           '((?b . "[[bib:%l][%l-bib]]")
393             (?n . "[[notes:%l][%l-notes]]")
394             (?c . "\\cite{%l}")
395             (?h . "*** %t\n:PROPERTIES:\n:Custom_ID: %l\n:END:\n[[papers:%l][%l xoj]] [[papers-pdf:%l][pdf]]")))
396          ))
397   (define-key org-mode-map (kbd "C-c )") 'reftex-citation)
398   (define-key org-mode-map (kbd "C-c [") 'reftex-citation)
399   (define-key org-mode-map (kbd "C-c (") 'org-mode-reftex-search)
400   (define-key org-mode-map (kbd "C-c 0") 'reftex-view-crossref)
401   )
402 (add-hook 'org-mode-hook 'my-org-mode-setup)
403
404 (defun org-mode-reftex-search ()
405   (interactive)
406   (org-open-link-from-string (format "[[notes:%s]]" (first (reftex-citation t)))))
407
408 (defun open-research-paper (bibtexkey)
409   "Open a paper by bibtex key"
410   (interactive "bibtex key: ")
411   (shell-command
412    (format "%s %s"
413        (substitute-in-file-name "$HOME/bin/bibtex_to_paper") bibtexkey)))
414 (org-add-link-type "papers" 'open-research-paper)
415 (defun open-research-paper-pdf (bibtexkey)
416   "Open a paper pdf by bibtex key"
417   (interactive "bibtex key: ")
418   (shell-command
419    (format "%s -p evince_annot %s"
420        (substitute-in-file-name "$HOME/bin/bibtex_to_paper") bibtexkey)))
421 (org-add-link-type "papers-pdf" 'open-research-paper-pdf)
422
423 (add-to-list 'org-link-abbrev-alist
424              '("notes" .
425                "~/projects/research/paper_notes.org::#%s"))
426
427 ; I pretty much always want hiearchical checkboxes
428 (setq org-hierachical-checkbox-statistics nil)
429
430 ;; Add \begin{equation}\end{equation} templates to the org mode easy templates
431 (add-to-list 'org-structure-template-alist
432              '("E" "\\begin{equation}\n?\n\\end{equation}"))
433
434  ;; stolen from
435 ;; http://www-public.it-sudparis.eu/~berger_o/weblog/2012/03/23/how-to-manage-and-export-bibliographic-notesrefs-in-org-mode/
436 (defun my-rtcite-export-handler (path desc format)
437   (message "my-rtcite-export-handler is called : path = %s, desc = %s, format = %s" path desc format)
438   (let* ((search (when (string-match "::#?\\(.+\\)\\'" path)
439                    (match-string 1 path)))
440          (path (substring path 0 (match-beginning 0))))
441     (cond ((eq format 'latex)
442            (if (or (not desc) 
443                    (equal 0 (search "rtcite:" desc)))
444                (format "\\cite{%s}" search)
445              (format "\\cite[%s]{%s}" desc search))))))
446
447 (org-add-link-type "rtcite" 
448                    'org-bibtex-open
449                    'my-rtcite-export-handler)
450
451
452 (setq-default org-mobile-directory "/linnode.donarmstrong.com:/sites/dav.donarmstrong.com/root/org/")
453 (when (string= system-name "linnode.donarmstrong.com")
454   (setq-default org-mobile-directory "/sites/dav.donarmstrong.com/root/org/"))
455 (setq-default org-directory "/home/don/org-mode/")
456 (setq-default org-mobile-inbox-for-pull "/home/don/org-mode/from-mobile.org")
457
458 ;; org mode ical export
459 (setq org-icalendar-timezone "America/Los_Angeles")
460 (setq org-icalendar-use-scheduled '(todo-start event-if-todo))
461 ;; we already add the id manually
462 ;; (setq org-icalendar-store-UID t)
463
464 ;; org babel support
465 (org-babel-do-load-languages
466  'org-babel-load-languages
467  '((emacs-lisp . t )
468    (R . t)
469    (latex . t)
470    (ditaa . t)
471    (dot . t)
472    ))
473 ;; use graphviz-dot for dot things
474 (add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))
475 ;; org-babel-by-backend
476 (defmacro org-babel-by-backend (&rest body)
477    `(case (if (boundp 'backend) 
478               (org-export-backend-name backend)
479             nil) ,@body))
480
481 (defun my/fix-inline-images ()
482   (when org-inline-image-overlays
483     (org-redisplay-inline-images)))
484
485 (add-hook 'org-babel-after-execute-hook
486            'my/fix-inline-images)
487
488 ;; ;; org latex
489 ;; ;; stolen from http://kieranhealy.org/esk/kjhealy.html
490 ;; (require 'org-latex)   
491 ;; ;; Choose either listings or minted for exporting source code blocks.
492 ;; ;; Using minted (as here) requires pygments be installed. To use the
493 ;; ;; default listings package instead, use
494 ;; ;; (setq org-latex-listings t)
495 ;; ;; and change references to "minted" below to "listings"
496 ;; ; (setq org-latex-listings 'minted)
497 ;; 
498 ;; ;; default settings for minted code blocks
499 ;; (setq org-latex-minted-options
500 ;;       '(;("frame" "single")
501 ;;         ("bgcolor" "bg") ; bg will need to be defined in the preamble of your document. It's defined in org-preamble-pdflatex.sty and org-preamble-xelatex.sty below.
502 ;;         ("fontsize" "\\small")
503 ;;         ))
504 ;; ;; turn off the default toc behavior; deal with it properly in headers to files.
505 ;; (defun org-latex-no-toc (depth)  
506 ;;   (when depth
507 ;;     (format "%% Org-mode is exporting headings to %s levels.\n"
508 ;;             depth)))
509 ;; (setq org-latex-format-toc-function 'org-latex-no-toc)
510
511 (require 'ox-latex)
512 (add-to-list 'org-latex-classes
513              '("memarticle"
514                "\\documentclass[11pt,oneside,article]{memoir}\n"
515                ("\\section{%s}" . "\\section*{%s}")
516                ("\\subsection{%s}" . "\\subsection*{%s}")
517                ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
518                ("\\paragraph{%s}" . "\\paragraph*{%s}")
519                ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
520
521 (setq org-beamer-outline-frame-options "")
522 (require 'ox-beamer)
523 (add-to-list 'org-latex-classes
524              '("beamer"
525                "\\documentclass[ignorenonframetext]{beamer}
526 [NO-DEFAULT-PACKAGES]
527 [PACKAGES]
528 [EXTRA]"
529                ("\\section{%s}" . "\\section*{%s}")
530                ("\\subsection{%s}" . "\\subsection*{%s}")
531                ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
532                ("\\paragraph{%s}" . "\\paragraph*{%s}")
533                ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
534
535 (add-to-list 'org-latex-classes
536              '("membook"
537                "\\documentclass[11pt,oneside]{memoir}\n"
538                ("\\chapter{%s}" . "\\chapter*{%s}")
539                ("\\section{%s}" . "\\section*{%s}")
540                ("\\subsection{%s}" . "\\subsection*{%s}")
541                ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
542
543 (add-to-list 'org-latex-classes
544              '("letter"
545                "\\documentclass[11pt]{letter}
546 [NO-DEFAULT-PACKAGES]
547 [PACKAGES]
548 [EXTRA]"
549        ("\\section{%s}" . "\\section*{%s}")
550                ("\\subsection{%s}" . "\\subsection*{%s}")
551                ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
552                ("\\paragraph{%s}" . "\\paragraph*{%s}")
553                ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
554
555 ;; Originally taken from Bruno Tavernier: http://thread.gmane.org/gmane.emacs.orgmode/31150/focus=31432
556 ;; but adapted to use latexmk 4.22 or higher.  
557 (setq org-latex-pdf-process '("latexmk -pdflatex=xelatex -bibtex -use-make -pdf %f"))
558
559 ;; Default packages included in /every/ tex file, latex, pdflatex or xelatex
560 (setq org-latex-default-packages-alist
561       '(("" "amsmath" t)))
562 (setq org-latex-packages-alist
563       '(("" "graphicx" t)
564         ("" "fontspec" t)
565         ("" "xunicode" t)
566         ("" "hyperref" t)
567         ("" "url" t)
568         ("" "rotating" t)
569         ("" "longtable" nil)
570         ("" "float" )))
571
572 ;; make equations larger
573 (setq org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
574
575 (defun org-create-formula--latex-header ()
576   "Return LaTeX header appropriate for previewing a LaTeX snippet."
577   (let ((info (org-combine-plists (org-export--get-global-options
578                                    (org-export-get-backend 'latex))
579                                   (org-export--get-inbuffer-options
580                                    (org-export-get-backend 'latex)))))
581     (org-latex-guess-babel-language
582      (org-latex-guess-inputenc
583       (org-splice-latex-header
584        org-format-latex-header
585        org-latex-default-packages-alist
586        nil t
587        (plist-get info :latex-header)))
588      info)))
589
590
591 ; support ignoring headers in org mode export to latex
592 ; from http://article.gmane.org/gmane.emacs.orgmode/67692
593 (defadvice org-latex-headline (around my-latex-skip-headlines
594                                       (headline contents info) activate)
595   (if (member "ignoreheading" (org-element-property :tags headline))
596       (setq ad-return-value contents)
597     ad-do-it))
598
599 ;; keep latex logfiles
600
601 (setq org-latex-remove-logfiles nil)
602
603 ;; helper functions
604 (defun bh/is-project-p ()
605   "Any task with a todo keyword subtask"
606   (save-restriction
607     (widen)
608     (let ((has-subtask)
609           (subtree-end (save-excursion (org-end-of-subtree t)))
610           (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
611       (save-excursion
612         (forward-line 1)
613         (while (and (not has-subtask)
614                     (< (point) subtree-end)
615                     (re-search-forward "^\*+ " subtree-end t))
616           (when (member (org-get-todo-state) org-todo-keywords-1)
617             (setq has-subtask t))))
618       (and is-a-task has-subtask))))
619
620 (defun bh/is-project-subtree-p ()
621   "Any task with a todo keyword that is in a project subtree.
622 Callers of this function already widen the buffer view."
623   (let ((task (save-excursion (org-back-to-heading 'invisible-ok)
624                               (point))))
625     (save-excursion
626       (bh/find-project-task)
627       (if (equal (point) task)
628           nil
629         t))))
630
631 (defun bh/is-task-p ()
632   "Any task with a todo keyword and no subtask"
633   (save-restriction
634     (widen)
635     (let ((has-subtask)
636           (subtree-end (save-excursion (org-end-of-subtree t)))
637           (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
638       (save-excursion
639         (forward-line 1)
640         (while (and (not has-subtask)
641                     (< (point) subtree-end)
642                     (re-search-forward "^\*+ " subtree-end t))
643           (when (member (org-get-todo-state) org-todo-keywords-1)
644             (setq has-subtask t))))
645       (and is-a-task (not has-subtask)))))
646
647 (defun bh/is-subproject-p ()
648   "Any task which is a subtask of another project"
649   (let ((is-subproject)
650         (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
651     (save-excursion
652       (while (and (not is-subproject) (org-up-heading-safe))
653         (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
654           (setq is-subproject t))))
655     (and is-a-task is-subproject)))
656
657 (defun bh/list-sublevels-for-projects-indented ()
658   "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
659   This is normally used by skipping functions where this variable is already local to the agenda."
660   (if (marker-buffer org-agenda-restrict-begin)
661       (setq org-tags-match-list-sublevels 'indented)
662     (setq org-tags-match-list-sublevels nil))
663   nil)
664
665 (defun bh/list-sublevels-for-projects ()
666   "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
667   This is normally used by skipping functions where this variable is already local to the agenda."
668   (if (marker-buffer org-agenda-restrict-begin)
669       (setq org-tags-match-list-sublevels t)
670     (setq org-tags-match-list-sublevels nil))
671   nil)
672
673 (defvar bh/hide-scheduled-and-waiting-next-tasks t)
674
675 (defun bh/toggle-next-task-display ()
676   (interactive)
677   (setq bh/hide-scheduled-and-waiting-next-tasks (not bh/hide-scheduled-and-waiting-next-tasks))
678   (when  (equal major-mode 'org-agenda-mode)
679     (org-agenda-redo))
680   (message "%s WAITING and SCHEDULED NEXT Tasks" (if bh/hide-scheduled-and-waiting-next-tasks "Hide" "Show")))
681
682 (defun bh/skip-stuck-projects ()
683   "Skip trees that are not stuck projects"
684   (save-restriction
685     (widen)
686     (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
687       (if (bh/is-project-p)
688           (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
689                  (has-next ))
690             (save-excursion
691               (forward-line 1)
692               (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
693                 (unless (member "WAITING" (org-get-tags-at))
694                   (setq has-next t))))
695             (if has-next
696                 nil
697               next-headline)) ; a stuck project, has subtasks but no next task
698         nil))))
699
700 (defun bh/skip-non-stuck-projects ()
701   "Skip trees that are not stuck projects"
702   ;; (bh/list-sublevels-for-projects-indented)
703   (save-restriction
704     (widen)
705     (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
706       (if (bh/is-project-p)
707           (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
708                  (has-next ))
709             (save-excursion
710               (forward-line 1)
711               (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
712                 (unless (member "WAITING" (org-get-tags-at))
713                   (setq has-next t))))
714             (if has-next
715                 next-headline
716               nil)) ; a stuck project, has subtasks but no next task
717         next-headline))))
718
719 (defun bh/skip-non-projects ()
720   "Skip trees that are not projects"
721   ;; (bh/list-sublevels-for-projects-indented)
722   (if (save-excursion (bh/skip-non-stuck-projects))
723       (save-restriction
724         (widen)
725         (let ((subtree-end (save-excursion (org-end-of-subtree t))))
726           (cond
727            ((bh/is-project-p)
728             nil)
729            ((and (bh/is-project-subtree-p) (not (bh/is-task-p)))
730             nil)
731            (t
732             subtree-end))))
733     (save-excursion (org-end-of-subtree t))))
734
735 (defun bh/skip-project-trees-and-habits ()
736   "Skip trees that are projects"
737   (save-restriction
738     (widen)
739     (let ((subtree-end (save-excursion (org-end-of-subtree t))))
740       (cond
741        ((bh/is-project-p)
742         subtree-end)
743        ((org-is-habit-p)
744         subtree-end)
745        (t
746         nil)))))
747
748 (defun bh/skip-projects-and-habits-and-single-tasks ()
749   "Skip trees that are projects, tasks that are habits, single non-project tasks"
750   (save-restriction
751     (widen)
752     (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
753       (cond
754        ((org-is-habit-p)
755         next-headline)
756        ((and bh/hide-scheduled-and-waiting-next-tasks
757              (member "WAITING" (org-get-tags-at)))
758         next-headline)
759        ((bh/is-project-p)
760         next-headline)
761        ((and (bh/is-task-p) (not (bh/is-project-subtree-p)))
762         next-headline)
763        (t
764         nil)))))
765
766 (defun bh/skip-project-tasks-maybe ()
767   "Show tasks related to the current restriction.
768 When restricted to a project, skip project and sub project tasks, habits, NEXT tasks, and loose tasks.
769 When not restricted, skip project and sub-project tasks, habits, and project related tasks."
770   (save-restriction
771     (widen)
772     (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
773            (next-headline (save-excursion (or (outline-next-heading) (point-max))))
774            (limit-to-project (marker-buffer org-agenda-restrict-begin)))
775       (cond
776        ((bh/is-project-p)
777         next-headline)
778        ((org-is-habit-p)
779         subtree-end)
780        ((and (not limit-to-project)
781              (bh/is-project-subtree-p))
782         subtree-end)
783        ((and limit-to-project
784              (bh/is-project-subtree-p)
785              (member (org-get-todo-state) (list "NEXT")))
786         subtree-end)
787        (t
788         nil)))))
789
790 (defun bh/skip-project-tasks ()
791   "Show non-project tasks.
792 Skip project and sub-project tasks, habits, and project related tasks."
793   (save-restriction
794     (widen)
795     (let* ((subtree-end (save-excursion (org-end-of-subtree t))))
796       (cond
797        ((bh/is-project-p)
798         subtree-end)
799        ((org-is-habit-p)
800         subtree-end)
801        ((bh/is-project-subtree-p)
802         subtree-end)
803        (t
804         nil)))))
805
806 (defun bh/skip-non-project-tasks ()
807   "Show project tasks.
808 Skip project and sub-project tasks, habits, and loose non-project tasks."
809   (save-restriction
810     (widen)
811     (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
812            (next-headline (save-excursion (or (outline-next-heading) (point-max)))))
813       (cond
814        ((bh/is-project-p)
815         next-headline)
816        ((org-is-habit-p)
817         subtree-end)
818        ((and (bh/is-project-subtree-p)
819              (member (org-get-todo-state) (list "NEXT")))
820         subtree-end)
821        ((not (bh/is-project-subtree-p))
822         subtree-end)
823        (t
824         nil)))))
825
826 (defun bh/skip-projects-and-habits ()
827   "Skip trees that are projects and tasks that are habits"
828   (save-restriction
829     (widen)
830     (let ((subtree-end (save-excursion (org-end-of-subtree t))))
831       (cond
832        ((bh/is-project-p)
833         subtree-end)
834        ((org-is-habit-p)
835         subtree-end)
836        (t
837         nil)))))
838
839 (defun bh/skip-non-subprojects ()
840   "Skip trees that are not projects"
841   (let ((next-headline (save-excursion (outline-next-heading))))
842     (if (bh/is-subproject-p)
843         nil
844       next-headline)))
845 ;
846 ;; Resume clocking task when emacs is restarted
847 (org-clock-persistence-insinuate)
848 ;;
849 ;; Show lot of clocking history so it's easy to pick items off the C-F11 list
850 (setq org-clock-history-length 23)
851 ;; Resume clocking task on clock-in if the clock is open
852 (setq org-clock-in-resume t)
853 ;; Change tasks to NEXT when clocking in
854 (setq org-clock-in-switch-to-state 'bh/clock-in-to-next)
855 ;; (setq org-clock-in-switch-to-state "NEXT")
856 ;; Separate drawers for clocking and logs
857 (setq org-drawers (quote ("PROPERTIES" "LOGBOOK")))
858 ;; Save clock data and state changes and notes in the LOGBOOK drawer
859 (setq org-clock-into-drawer t)
860 (setq org-log-into-drawer t)
861 ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
862 (setq org-clock-out-remove-zero-time-clocks t)
863 ;; Clock out when moving task to a done state
864 (setq org-clock-out-when-done t)
865 ;; Save the running clock and all clock history when exiting Emacs, load it on startup
866 (setq org-clock-persist t)
867 ;; Do not prompt to resume an active clock
868 (setq org-clock-persist-query-resume nil)
869 ;; Enable auto clock resolution for finding open clocks
870 (setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
871 ;; Include current clocking task in clock reports
872 (setq org-clock-report-include-clocking-task t)
873
874 ;; the cache seems to be broken
875 (setq org-element-use-cache nil)
876
877 (defvar bh/keep-clock-running nil)
878
879 (defun bh/clock-in-to-next (kw)
880   "Switch a task from TODO to NEXT when clocking in.
881 Skips capture tasks, projects, and subprojects.
882 Switch projects and subprojects from NEXT back to TODO"
883   (when (not (and (boundp 'org-capture-mode) org-capture-mode))
884     (cond
885      ((and (member (org-get-todo-state) (list "TODO"))
886            (bh/is-task-p))
887       "NEXT")
888      ((and (member (org-get-todo-state) (list "NEXT"))
889            (bh/is-project-p))
890       "TODO"))))
891
892 (defun bh/find-project-task ()
893   "Move point to the parent (project) task if any"
894   (save-restriction
895     (widen)
896     (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point))))
897       (while (org-up-heading-safe)
898         (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
899           (setq parent-task (point))))
900       (goto-char parent-task)
901       parent-task)))
902
903 (defun bh/punch-in (arg)
904   "Start continuous clocking and set the default task to the
905 selected task.  If no task is selected set the Organization task
906 as the default task."
907   (interactive "p")
908   (setq bh/keep-clock-running t)
909   (if (equal major-mode 'org-agenda-mode)
910       ;;
911       ;; We're in the agenda
912       ;;
913       (let* ((marker (org-get-at-bol 'org-hd-marker))
914              (tags (org-with-point-at marker (org-get-tags-at))))
915         (if (and (eq arg 4) tags)
916             (org-agenda-clock-in '(16))
917           (bh/clock-in-organization-task-as-default)))
918     ;;
919     ;; We are not in the agenda
920     ;;
921     (save-restriction
922       (widen)
923       ; Find the tags on the current task
924       (if (and (equal major-mode 'org-mode) (not (org-before-first-heading-p)) (eq arg 4))
925           (org-clock-in '(16))
926         (bh/clock-in-organization-task-as-default)))))
927
928 (defun bh/punch-out ()
929   (interactive)
930   (setq bh/keep-clock-running nil)
931   (when (org-clock-is-active)
932     (org-clock-out))
933   (org-agenda-remove-restriction-lock))
934
935 (defun bh/clock-in-default-task ()
936   (save-excursion
937     (org-with-point-at org-clock-default-task
938       (org-clock-in))))
939
940 (defun bh/clock-in-parent-task ()
941   "Move point to the parent (project) task if any and clock in"
942   (let ((parent-task))
943     (save-excursion
944       (save-restriction
945         (widen)
946         (while (and (not parent-task) (org-up-heading-safe))
947           (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
948             (setq parent-task (point))))
949         (if parent-task
950             (org-with-point-at parent-task
951               (org-clock-in))
952           (when bh/keep-clock-running
953             (bh/clock-in-default-task)))))))
954
955 (defvar bh/organization-task-id "e22cb8bf-07c7-408b-8f60-ff3aadac95e4")
956
957 (defun bh/clock-in-organization-task-as-default ()
958   (interactive)
959   (org-with-point-at (org-id-find bh/organization-task-id 'marker)
960     (org-clock-in '(16))))
961
962 (defun bh/clock-out-maybe ()
963   (when (and bh/keep-clock-running
964              (not org-clock-clocking-in)
965              (marker-buffer org-clock-default-task)
966              (not org-clock-resolving-clocks-due-to-idleness))
967     (bh/clock-in-parent-task)))
968
969 ; (add-hook 'org-clock-out-hook 'bh/clock-out-maybe 'append)
970
971 (require 'org-id)
972 (defun bh/clock-in-task-by-id (id)
973   "Clock in a task by id"
974   (org-with-point-at (org-id-find id 'marker)
975     (org-clock-in nil)))
976
977 (defun bh/clock-in-last-task (arg)
978   "Clock in the interrupted task if there is one
979 Skip the default task and get the next one.
980 A prefix arg forces clock in of the default task."
981   (interactive "p")
982   (let ((clock-in-to-task
983          (cond
984           ((eq arg 4) org-clock-default-task)
985           ((and (org-clock-is-active)
986                 (equal org-clock-default-task (cadr org-clock-history)))
987            (caddr org-clock-history))
988           ((org-clock-is-active) (cadr org-clock-history))
989           ((equal org-clock-default-task (car org-clock-history)) (cadr org-clock-history))
990           (t (car org-clock-history)))))
991     (widen)
992     (org-with-point-at clock-in-to-task
993       (org-clock-in nil))))
994
995
996 (defun org-export-to-ods ()
997   (interactive)
998   (let ((csv-file "data.csv"))
999     (org-table-export csv-file "orgtbl-to-csv")
1000     (org-odt-convert csv-file "ods" 'open)))
1001
1002 ; allow for zero-width-space to be a break in regexp too
1003 ; (setcar org-emphasis-regexp-components "​ [:space:] \t('\"{")
1004 ; (setcar (nthcdr 1 org-emphasis-regexp-components) "​ [:space:]- \t.,:!?;'\")}\\")
1005 ; (org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
1006
1007 ;; support inserting screen shots
1008 (defun my/org-insert-screenshot ()
1009   "Take a screenshot into a time stamped unique-named file in the
1010 same directory as the org-buffer and insert a link to this file."
1011   (interactive)
1012   (defvar my/org-insert-screenshot/filename)
1013   (setq my/org-insert-screenshot/filename
1014         (read-file-name
1015          "Screenshot to insert: "
1016          nil
1017          (concat (buffer-file-name) "_" (format-time-string "%Y%m%d_%H%M%S") ".png")
1018          )
1019         )
1020   (call-process "import" nil nil nil my/org-insert-screenshot/filename)
1021   (insert (concat "[[" my/org-insert-screenshot/filename "]]"))
1022   (org-display-inline-images))
1023
1024 (defun my/fix-inline-images ()
1025   (when org-inline-image-overlays
1026     (org-redisplay-inline-images)))
1027
1028 (add-hook 'org-babel-after-execute-hook 'my/fix-inline-images)
1029
1030 ; from http://orgmode.org/Changes.html
1031 (defun my/org-repair-property-drawers ()
1032   "Fix properties drawers in current buffer.
1033  Ignore non Org buffers."
1034   (interactive)
1035   (when (eq major-mode 'org-mode)
1036     (org-with-wide-buffer
1037      (goto-char (point-min))
1038      (let ((case-fold-search t)
1039            (inline-re (and (featurep 'org-inlinetask)
1040                            (concat (org-inlinetask-outline-regexp)
1041                                    "END[ \t]*$"))))
1042        (org-map-entries
1043         (lambda ()
1044           (unless (and inline-re (org-looking-at-p inline-re))
1045             (save-excursion
1046               (let ((end (save-excursion (outline-next-heading) (point))))
1047                 (forward-line)
1048                 (when (org-looking-at-p org-planning-line-re) (forward-line))
1049                 (when (and (< (point) end)
1050                            (not (org-looking-at-p org-property-drawer-re))
1051                            (save-excursion
1052                              (and (re-search-forward org-property-drawer-re end t)
1053                                   (eq (org-element-type
1054                                        (save-match-data (org-element-at-point)))
1055                                       'drawer))))
1056                   (insert (delete-and-extract-region
1057                            (match-beginning 0)
1058                            (min (1+ (match-end 0)) end)))
1059                   (unless (bolp) (insert "\n"))))))))))))
1060
1061 (provide 'org-mode-configuration)