-(require 'org-id)
-(require 'reftex)
-(require 'gnus)
-
-;; The following lines are always needed. Choose your own keys.
-(add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))
-(require 'org)
-(global-set-key "\C-cl" 'org-store-link)
-(global-set-key "\C-ca" 'org-agenda)
-(global-set-key "\C-cb" 'org-iswitchb)
-(setq-default org-log-done 'time)
-(setq-default org-agenda-ndays 5)
-
-;; agenda configuration
-;; Do not dim blocked tasks
-(setq org-agenda-dim-blocked-tasks nil)
-
-;; Compact the block agenda view
-(setq org-agenda-compact-blocks t)
-
-;; Custom agenda command definitions
-(setq org-agenda-custom-commands
- (quote (("N" "Notes" tags "NOTE"
- ((org-agenda-overriding-header "Notes")
- (org-tags-match-list-sublevels t)))
- ("h" "Habits" tags-todo "STYLE=\"habit\""
- ((org-agenda-overriding-header "Habits")
- (org-agenda-sorting-strategy
- '(todo-state-down effort-up category-keep))))
- (" " "Agenda"
- ((agenda "" nil)
- (tags "REFILE"
- ((org-agenda-overriding-header "Tasks to Refile")
- (org-tags-match-list-sublevels nil)))
- (tags-todo "-CANCELLED/!"
- ((org-agenda-overriding-header "Stuck Projects")
- (org-agenda-skip-function 'bh/skip-non-stuck-projects)
- (org-agenda-sorting-strategy
- '(category-keep))))
- (tags-todo "-HOLD-CANCELLED/!"
- ((org-agenda-overriding-header "Projects")
- (org-agenda-skip-function 'bh/skip-non-projects)
- (org-tags-match-list-sublevels 'indented)
- (org-agenda-sorting-strategy
- '(category-keep))))
- (tags-todo "-CANCELLED/!NEXT"
- ((org-agenda-overriding-header (concat "Project Next Tasks"
- (if bh/hide-scheduled-and-waiting-next-tasks
- ""
- " (including WAITING and SCHEDULED tasks)")))
- (org-agenda-skip-function 'bh/skip-projects-and-habits-and-single-tasks)
- (org-tags-match-list-sublevels t)
- (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-sorting-strategy
- '(todo-state-down effort-up category-keep))))
- (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
- ((org-agenda-overriding-header (concat "Project Subtasks"
- (if bh/hide-scheduled-and-waiting-next-tasks
- ""
- " (including WAITING and SCHEDULED tasks)")))
- (org-agenda-skip-function 'bh/skip-non-project-tasks)
- (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-sorting-strategy
- '(category-keep))))
- (tags-todo "-REFILE-CANCELLED-WAITING-HOLD/!"
- ((org-agenda-overriding-header (concat "Standalone Tasks"
- (if bh/hide-scheduled-and-waiting-next-tasks
- ""
- " (including WAITING and SCHEDULED tasks)")))
- (org-agenda-skip-function 'bh/skip-project-tasks)
- (org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-todo-ignore-with-date bh/hide-scheduled-and-waiting-next-tasks)
- (org-agenda-sorting-strategy
- '(category-keep))))
- (tags-todo "-CANCELLED+WAITING|HOLD/!"
- ((org-agenda-overriding-header "Waiting and Postponed Tasks")
- (org-agenda-skip-function 'bh/skip-stuck-projects)
- (org-tags-match-list-sublevels nil)
- (org-agenda-todo-ignore-scheduled t)
- (org-agenda-todo-ignore-deadlines t)))
- (tags "-REFILE/"
- ((org-agenda-overriding-header "Tasks to Archive")
- (org-agenda-skip-function 'bh/skip-non-archivable-tasks)
- (org-tags-match-list-sublevels nil))))
- nil))))
-
-; org mode agenda files
-(setq org-agenda-files
- (quote ("~/projects/debbugs/debbugs.org"
- "~/projects/notes/notes.org"
- "~/projects/notes/refile.org"
- "~/projects/notes/diary.org"
- "~/projects/origins_of_life/ool.org"
- "~/projects/sysadmin/sndservers/sndservers.org"
- "~/projects/chaim/chaim.org"
- "~/projects/chaim/papers/gwas_paper_2012/gwas_paper.org"
- "~/projects/reviews/reviews.org"
- "~/projects/fh/fh.org")))
-
-(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")))
-(setq org-columns-default-format "%40ITEM(Task) %TAGS %PRIORITY %TODO %13SCHEDULED %13DEADLINE %6Effort{:} %CLOCKSUM")
-
-(setq org-default-notes-file "~/projects/notes/notes.org")
-(setq org-capture-templates ;; mail-specific note template, identified by "m"
- '(("m" "Mail" entry (file+headline "~/projects/notes/refile.org" "Mail")
- "* %?\n\n Source: %u, %c\n %i")
- ("t" "todo" entry (file "~/projects/notes/refile.org")
- "* TODO %?\n%U\n%a\n" :clock-in t :clock-resume t)
- ("r" "respond" entry (file "~/projects/notes/refile.org")
- "* NEXT Respond to %:from on %:subject\nSCHEDULED: %t\n%U\n%a\n" :clock-in t :clock-resume t :immediate-finish t)
- ("n" "note" entry (file "~/projects/notes/refile.org")
- "* %? :NOTE:\n%U\n%a\n" :clock-in t :clock-resume t)
- ("s" "schedule" entry (file "~/projects/notes/refile.org")
- "* %? \n%^{scheduled:}t\n%U\n%a\n" :clock-in t :clock-resume t)
- ("j" "Journal" entry (file+datetree "~/projects/notes/diary.org")
- "* %?\n%U\n" :clock-in t :clock-resume t)
- ("w" "org-protocol" entry (file "~/projects/notes/refile.org")
- "* TODO Review %c\n%U\n" :immediate-finish t)
- ("m" "Meeting" entry (file "~/projects/notes/refile.org")
- "* MEETING with %? :MEETING:\n%U" :clock-in t :clock-resume t)
- ("p" "Phone call" entry (file "~/projects/notes/refile.org")
- "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t)
- ("J" "job" entry (file "~/projects/notes/refile.org")
- "* TODO Apply for %a%? :job:\n%U\n" :clock-in t :clock-resume t)
- ("h" "Habit" entry (file "~/projects/notes/refile.org")
- "* NEXT %?\n%U\n%a\nSCHEDULED: %(format-time-string \"<%Y-%m-%d %a .+1d/3d>\")\n:PROPERTIES:\n:STYLE: habit\n:REPEAT_TO_STATE: NEXT\n:END:\n")
- )
- )
-
-;; Remove empty LOGBOOK drawers on clock out
-(defun bh/remove-empty-drawer-on-clock-out ()
- (interactive)
- (save-excursion
- (beginning-of-line 0)
- (org-remove-empty-drawer-at "LOGBOOK" (point))))
-
-(defun my/org-add-id ()
- (interactive)
- (save-excursion
- (if (org-current-level)
- ()
- (forward-char 1)
- )
- (org-id-get-create)
- )
-)
-
-; org mode configuration from http://doc.norang.ca/org-mode.html
-;; Custom Key Bindings
-(global-set-key (kbd "<f12>") 'org-agenda)
-(global-set-key (kbd "<f5>") 'bh/org-todo)
-(global-set-key (kbd "<S-f5>") 'bh/widen)
-(global-set-key (kbd "<f7>") 'bh/set-truncate-lines)
-(global-set-key (kbd "<f8>") 'org-cycle-agenda-files)
-(global-set-key (kbd "<f9> <f9>") 'bh/show-org-agenda)
-(global-set-key (kbd "<f9> b") 'bbdb)
-(global-set-key (kbd "<f9> c") 'calendar)
-(global-set-key (kbd "<f9> f") 'boxquote-insert-file)
-(global-set-key (kbd "<f9> h") 'bh/hide-other)
-(global-set-key (kbd "<f9> n") 'bh/toggle-next-task-display)
-(global-set-key (kbd "<f9> w") 'widen)
-
-(global-set-key (kbd "<f9> I") 'bh/punch-in)
-(global-set-key (kbd "<f9> O") 'bh/punch-out)
-
-(global-set-key (kbd "<f9> o") 'bh/make-org-scratch)
-
-(global-set-key (kbd "<f9> r") 'boxquote-region)
-(global-set-key (kbd "<f9> s") 'bh/switch-to-scratch)
-
-(global-set-key (kbd "<f9> t") 'bh/insert-inactive-timestamp)
-(global-set-key (kbd "<f9> T") 'bh/toggle-insert-inactive-timestamp)
-
-(global-set-key (kbd "<f9> v") 'visible-mode)
-(global-set-key (kbd "<f9> l") 'org-toggle-link-display)
-(global-set-key (kbd "<f9> SPC") 'bh/clock-in-last-task)
-(global-set-key (kbd "C-<f9>") 'previous-buffer)
-(global-set-key (kbd "M-<f9>") 'org-toggle-inline-images)
-(global-set-key (kbd "C-x n r") 'narrow-to-region)
-(global-set-key (kbd "C-<f10>") 'next-buffer)
-(global-set-key (kbd "<f11>") 'org-clock-goto)
-(global-set-key (kbd "C-<f11>") 'org-clock-in)
-(global-set-key (kbd "C-s-<f12>") 'bh/save-then-publish)
-(global-set-key (kbd "C-c c") 'org-capture)
-
-(defun bh/hide-other ()
- (interactive)
- (save-excursion
- (org-back-to-heading 'invisible-ok)
- (hide-other)
- (org-cycle)
- (org-cycle)
- (org-cycle)))
-
-(defun bh/set-truncate-lines ()
- "Toggle value of truncate-lines and refresh window display."
- (interactive)
- (setq truncate-lines (not truncate-lines))
- ;; now refresh window display (an idiom from simple.el):
- (save-excursion
- (set-window-start (selected-window)
- (window-start (selected-window)))))
-
-(defun bh/make-org-scratch ()
- (interactive)
- (find-file "/tmp/publish/scratch.org")
- (gnus-make-directory "/tmp/publish"))
-
-(defun bh/switch-to-scratch ()
- (interactive)
- (switch-to-buffer "*scratch*"))
-
-(setq org-use-fast-todo-selection t)
-(setq org-treat-S-cursor-todo-selection-as-state-change nil)
-
-(setq org-todo-keywords
- (quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
- (sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))
-
-(setq org-todo-keyword-faces
- (quote (("TODO" :foreground "red" :weight bold)
- ("NEXT" :foreground "blue" :weight bold)
- ("DONE" :foreground "forest green" :weight bold)
- ("WAITING" :foreground "orange" :weight bold)
- ("HOLD" :foreground "magenta" :weight bold)
- ("CANCELLED" :foreground "forest green" :weight bold)
- ("MEETING" :foreground "forest green" :weight bold)
- ("PHONE" :foreground "forest green" :weight bold))))
-
-(setq org-todo-state-tags-triggers
- (quote (("CANCELLED" ("CANCELLED" . t))
- ("WAITING" ("WAITING" . t))
- ("HOLD" ("WAITING") ("HOLD" . t))
- (done ("WAITING") ("HOLD"))
- ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
- ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
- ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))
-
-
-
-(add-hook 'org-clock-out-hook 'bh/remove-empty-drawer-on-clock-out 'append)
-; add ids on creation of nodes
-(add-hook 'org-capture-prepare-finalize-hook 'my/org-add-id)
-; create function to create headlines in file. This comes from
-; http://stackoverflow.com/questions/13340616/assign-ids-to-every-entry-in-org-mode
-(defun my/org-add-ids-to-headlines-in-file ()
- "Add ID properties to all headlines in the current file which
-do not already have one."
- (interactive)
- (org-map-entries 'org-id-get-create))
-; if we wanted to do this to every buffer, do the following:
-; (add-hook 'org-mode-hook
-; (lambda ()
-; (add-hook 'before-save-hook 'my/org-add-ids-to-headlines-in-file nil 'local)))
-
-
-; resolve clocks after 10 minutes of idle; use xprintidle
-; (setq org-clock-idle-time 10)
-; (setq org-clock-x11idle-program-name "xprintidle")
-
-; this is from http://doc.norang.ca/org-mode.html#Capture
-; use C-M-r for org mode capture
-(global-set-key (kbd "C-M-r") 'org-capture)
-
-; Targets include this file and any file contributing to the agenda - up to 9 levels deep
-(setq org-refile-targets (quote ((nil :maxlevel . 9)
- (org-agenda-files :maxlevel . 9))))
-
-; Use full outline paths for refile targets - we file directly with IDO
-(setq org-refile-use-outline-path t)
-
-; Targets complete directly with IDO
-(setq org-outline-path-complete-in-steps nil)
-
-; Allow refile to create parent tasks with confirmation
-(setq org-refile-allow-creating-parent-nodes (quote confirm))
-
-; Use IDO for both buffer and file completion and ido-everywhere to t
-(setq org-completion-use-ido t)
-(setq ido-everywhere t)
-(setq ido-max-directory-size 100000)
-(ido-mode (quote both))
-; Use the current window when visiting files and buffers with ido
-(setq ido-default-file-method 'selected-window)
-(setq ido-default-buffer-method 'selected-window)
-; Use the current window for indirect buffer display
-(setq org-indirect-buffer-display 'current-window)
-
-
-;;;; Refile settings
-; Exclude DONE state tasks from refile targets
-(defun bh/verify-refile-target ()
- "Exclude todo keywords with a done state from refile targets"
- (not (member (nth 2 (org-heading-components)) org-done-keywords)))
-
-(setq org-refile-target-verify-function 'bh/verify-refile-target)
-
-;; ensure that emacsclient will show just the note to be edited when invoked
-;; from Mutt, and that it will shut down emacsclient once finished;
-;; fallback to legacy behavior when not invoked via org-protocol.
-(require 'org-protocol)
-(add-hook 'org-capture-mode-hook 'delete-other-windows)
-(setq my-org-protocol-flag nil)
-(defadvice org-capture-finalize (after delete-frame-at-end activate)
- "Delete frame at remember finalization"
- (progn (if my-org-protocol-flag (delete-frame))
- (setq my-org-protocol-flag nil)))
-(defadvice org-capture-refile (around delete-frame-after-refile activate)
- "Delete frame at remember refile"
- (if my-org-protocol-flag
- (progn
- (setq my-org-protocol-flag nil)
- ad-do-it
- (delete-frame))
- ad-do-it)
- )
-(defadvice org-capture-kill (after delete-frame-at-end activate)
- "Delete frame at remember abort"
- (progn (if my-org-protocol-flag (delete-frame))
- (setq my-org-protocol-flag nil)))
-(defadvice org-protocol-capture (before set-org-protocol-flag activate)
- (setq my-org-protocol-flag t))
-
-(defadvice org-insert-todo-heading (after dla/create-id activate)
- (org-id-get-create)
- )
-
-;; org modules
-(add-to-list 'org-modules 'org-habit)
-
-; this comes from http://upsilon.cc/~zack/blog/posts/2010/02/integrating_Mutt_with_Org-mode/
-(defun open-mail-in-mutt (message)
- "Open a mail message in Mutt, using an external terminal.
-
-Message can be specified either by a path pointing inside a
-Maildir, or by Message-ID."
- (interactive "MPath or Message-ID: ")
- (shell-command
- (format "faf xterm -e \"%s %s\""
- (substitute-in-file-name "$HOME/bin/mutt_open") message)))
-
-;; add support for "mutt:ID" links
-(org-add-link-type "mutt" 'open-mail-in-mutt)
-
-(defun my-org-mode-setup ()
- (load-library "reftex")
- (and (buffer-file-name)
- (file-exists-p (buffer-file-name))
- (progn
- (reftex-parse-all)
- (reftex-set-cite-format
- '((?b . "[[bib:%l][%l-bib]]")
- (?n . "[[notes:%l][%l-notes]]")
- (?c . "\\cite{%l}")
- (?h . "*** %t\n:PROPERTIES:\n:Custom_ID: %l\n:END:\n[[papers:%l][%l paper]]")))
- ))
- (define-key org-mode-map (kbd "C-c )") 'reftex-citation)
- (define-key org-mode-map (kbd "C-c [") 'reftex-citation)
- (define-key org-mode-map (kbd "C-c (") 'org-mode-reftex-search)
- (define-key org-mode-map (kbd "C-c 0") 'reftex-view-crossref)
- )
-(add-hook 'org-mode-hook 'my-org-mode-setup)
-
-(defun org-mode-reftex-search ()
- (interactive)
- (org-open-link-from-string (format "[[notes:%s]]" (first (reftex-citation t)))))
-
-(defun open-research-paper (bibtexkey)
- "Open a paper by bibtex key"
- (interactive "bibtex key: ")
- (shell-command
- (format "%s %s"
- (substitute-in-file-name "$HOME/bin/bibtex_to_paper") bibtexkey)))
-(org-add-link-type "papers" 'open-research-paper)
-
-(add-to-list 'org-link-abbrev-alist
- '("notes" .
- "~/projects/research/paper_notes.org::#%s"))
-
-; I pretty much always want hiearchical checkboxes
-(setq org-hierachical-checkbox-statistics nil)
-
-;; stolen from
-;; http://www-public.it-sudparis.eu/~berger_o/weblog/2012/03/23/how-to-manage-and-export-bibliographic-notesrefs-in-org-mode/
-(defun my-rtcite-export-handler (path desc format)
- (message "my-rtcite-export-handler is called : path = %s, desc = %s, format = %s" path desc format)
- (let* ((search (when (string-match "::#?\\(.+\\)\\'" path)
- (match-string 1 path)))
- (path (substring path 0 (match-beginning 0))))
- (cond ((eq format 'latex)
- (if (or (not desc)
- (equal 0 (search "rtcite:" desc)))
- (format "\\cite{%s}" search)
- (format "\\cite[%s]{%s}" desc search))))))
-
-(org-add-link-type "rtcite"
- 'org-bibtex-open
- 'my-rtcite-export-handler)
-
-
-(setq-default org-mobile-directory "/rzlab.ucr.edu:/sites/dav.donarmstrong.com/root/org/")
-(setq-default org-directory "/home/don/org-mode/")
-(setq-default org-mobile-inbox-for-pull "/home/don/org-mode/from-mobile.org")
-
-;; org mode ical export
-(setq org-icalendar-timezone "America/Los_Angeles")
-(setq org-icalendar-use-scheduled '(todo-start event-if-todo))
-(setq org-icalendar-store-UID t)
-
-;; org babel support
-(org-babel-do-load-languages
- 'org-babel-load-languages
- '((emacs-lisp . t )
- (R . t)
- (latex . t)))
-;; org-babel-by-backend
-(defmacro org-babel-by-backend (&rest body)
- `(case (if (boundp 'backend)
- (org-export-backend-name backend)
- nil) ,@body))
-
-
-
-;; org latex
-;; stolen from http://kieranhealy.org/esk/kjhealy.html
-(require 'org-latex)
-;; Choose either listings or minted for exporting source code blocks.
-;; Using minted (as here) requires pygments be installed. To use the
-;; default listings package instead, use
-;; (setq org-latex-listings t)
-;; and change references to "minted" below to "listings"
-; (setq org-latex-listings 'minted)
-
-;; default settings for minted code blocks
-(setq org-latex-minted-options
- '(;("frame" "single")
- ("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.
- ("fontsize" "\\small")
- ))
-;; turn off the default toc behavior; deal with it properly in headers to files.
-(defun org-latex-no-toc (depth)
- (when depth
- (format "%% Org-mode is exporting headings to %s levels.\n"
- depth)))
-(setq org-latex-format-toc-function 'org-latex-no-toc)
-
-(require 'ox-latex)
-(add-to-list 'org-latex-classes
- '("memarticle"
- "\\documentclass[11pt,oneside,article]{memoir}\n"
- ("\\section{%s}" . "\\section*{%s}")
- ("\\subsection{%s}" . "\\subsection*{%s}")
- ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
- ("\\paragraph{%s}" . "\\paragraph*{%s}")
- ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
-
-(add-to-list 'org-latex-classes
- '("membook"
- "\\documentclass[11pt,oneside]{memoir}\n"
- ("\\chapter{%s}" . "\\chapter*{%s}")
- ("\\section{%s}" . "\\section*{%s}")
- ("\\subsection{%s}" . "\\subsection*{%s}")
- ("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
-
-(add-to-list 'org-latex-classes
- '("letter"
- "\\documentclass[11pt]{letter}
-[NO-DEFAULT-PACKAGES]
-[PACKAGES]
-[EXTRA]"
- ("\\section{%s}" . "\\section*{%s}")
- ("\\subsection{%s}" . "\\subsection*{%s}")
- ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
- ("\\paragraph{%s}" . "\\paragraph*{%s}")
- ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))
-
-;; Originally taken from Bruno Tavernier: http://thread.gmane.org/gmane.emacs.orgmode/31150/focus=31432
-;; but adapted to use latexmk 4.22 or higher.
-(setq org-latex-pdf-process '("latexmk -pdflatex=xelatex -bibtex -use-make -pdf %f"))
-
-;; Default packages included in /every/ tex file, latex, pdflatex or xelatex
-(setq org-latex-default-packages-alist
- '())
-(setq org-latex-packages-alist
- '(("" "graphicx" t)
- ("" "fontspec" t)
- ("" "xunicode" t)
- ("" "hyperref" t)
- ("" "url" t)
- ("" "rotating" t)
- ("" "longtable" nil)
- ("" "float" )))
-
-(defun org-create-formula--latex-header ()
- "Return LaTeX header appropriate for previewing a LaTeX snippet."
- (let ((info (org-combine-plists (org-export--get-global-options
- (org-export-get-backend 'latex))
- (org-export--get-inbuffer-options
- (org-export-get-backend 'latex)))))
- (org-latex-guess-babel-language
- (org-latex-guess-inputenc
- (org-splice-latex-header
- org-format-latex-header
- org-latex-default-packages-alist
- nil t
- (plist-get info :latex-header)))
- info)))
-
-
-; support ignoring headers in org mode export to latex
-; from http://article.gmane.org/gmane.emacs.orgmode/67692
-(defadvice org-latex-headline (around my-latex-skip-headlines
- (headline contents info) activate)
- (if (member "ignoreheading" (org-element-property :tags headline))
- (setq ad-return-value contents)
- ad-do-it))
-
-
-;; helper functions
-(defun bh/is-project-p ()
- "Any task with a todo keyword subtask"
- (save-restriction
- (widen)
- (let ((has-subtask)
- (subtree-end (save-excursion (org-end-of-subtree t)))
- (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
- (save-excursion
- (forward-line 1)
- (while (and (not has-subtask)
- (< (point) subtree-end)
- (re-search-forward "^\*+ " subtree-end t))
- (when (member (org-get-todo-state) org-todo-keywords-1)
- (setq has-subtask t))))
- (and is-a-task has-subtask))))
-
-(defun bh/is-project-subtree-p ()
- "Any task with a todo keyword that is in a project subtree.
-Callers of this function already widen the buffer view."
- (let ((task (save-excursion (org-back-to-heading 'invisible-ok)
- (point))))
- (save-excursion
- (bh/find-project-task)
- (if (equal (point) task)
- nil
- t))))
-
-(defun bh/is-task-p ()
- "Any task with a todo keyword and no subtask"
- (save-restriction
- (widen)
- (let ((has-subtask)
- (subtree-end (save-excursion (org-end-of-subtree t)))
- (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
- (save-excursion
- (forward-line 1)
- (while (and (not has-subtask)
- (< (point) subtree-end)
- (re-search-forward "^\*+ " subtree-end t))
- (when (member (org-get-todo-state) org-todo-keywords-1)
- (setq has-subtask t))))
- (and is-a-task (not has-subtask)))))
-
-(defun bh/is-subproject-p ()
- "Any task which is a subtask of another project"
- (let ((is-subproject)
- (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
- (save-excursion
- (while (and (not is-subproject) (org-up-heading-safe))
- (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
- (setq is-subproject t))))
- (and is-a-task is-subproject)))
-
-(defun bh/list-sublevels-for-projects-indented ()
- "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
- This is normally used by skipping functions where this variable is already local to the agenda."
- (if (marker-buffer org-agenda-restrict-begin)
- (setq org-tags-match-list-sublevels 'indented)
- (setq org-tags-match-list-sublevels nil))
- nil)
-
-(defun bh/list-sublevels-for-projects ()
- "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
- This is normally used by skipping functions where this variable is already local to the agenda."
- (if (marker-buffer org-agenda-restrict-begin)
- (setq org-tags-match-list-sublevels t)
- (setq org-tags-match-list-sublevels nil))
- nil)
-
-(defvar bh/hide-scheduled-and-waiting-next-tasks t)
-
-(defun bh/toggle-next-task-display ()
- (interactive)
- (setq bh/hide-scheduled-and-waiting-next-tasks (not bh/hide-scheduled-and-waiting-next-tasks))
- (when (equal major-mode 'org-agenda-mode)
- (org-agenda-redo))
- (message "%s WAITING and SCHEDULED NEXT Tasks" (if bh/hide-scheduled-and-waiting-next-tasks "Hide" "Show")))
-
-(defun bh/skip-stuck-projects ()
- "Skip trees that are not stuck projects"
- (save-restriction
- (widen)
- (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
- (if (bh/is-project-p)
- (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
- (has-next ))
- (save-excursion
- (forward-line 1)
- (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
- (unless (member "WAITING" (org-get-tags-at))
- (setq has-next t))))
- (if has-next
- nil
- next-headline)) ; a stuck project, has subtasks but no next task
- nil))))
-
-(defun bh/skip-non-stuck-projects ()
- "Skip trees that are not stuck projects"
- ;; (bh/list-sublevels-for-projects-indented)
- (save-restriction
- (widen)
- (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
- (if (bh/is-project-p)
- (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
- (has-next ))
- (save-excursion
- (forward-line 1)
- (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
- (unless (member "WAITING" (org-get-tags-at))
- (setq has-next t))))
- (if has-next
- next-headline
- nil)) ; a stuck project, has subtasks but no next task
- next-headline))))
-
-(defun bh/skip-non-projects ()
- "Skip trees that are not projects"
- ;; (bh/list-sublevels-for-projects-indented)
- (if (save-excursion (bh/skip-non-stuck-projects))
- (save-restriction
- (widen)
- (let ((subtree-end (save-excursion (org-end-of-subtree t))))
- (cond
- ((bh/is-project-p)
- nil)
- ((and (bh/is-project-subtree-p) (not (bh/is-task-p)))
- nil)
- (t
- subtree-end))))
- (save-excursion (org-end-of-subtree t))))
-
-(defun bh/skip-project-trees-and-habits ()
- "Skip trees that are projects"
- (save-restriction
- (widen)
- (let ((subtree-end (save-excursion (org-end-of-subtree t))))
- (cond
- ((bh/is-project-p)
- subtree-end)
- ((org-is-habit-p)
- subtree-end)
- (t
- nil)))))
-
-(defun bh/skip-projects-and-habits-and-single-tasks ()
- "Skip trees that are projects, tasks that are habits, single non-project tasks"
- (save-restriction
- (widen)
- (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
- (cond
- ((org-is-habit-p)
- next-headline)
- ((and bh/hide-scheduled-and-waiting-next-tasks
- (member "WAITING" (org-get-tags-at)))
- next-headline)
- ((bh/is-project-p)
- next-headline)
- ((and (bh/is-task-p) (not (bh/is-project-subtree-p)))
- next-headline)
- (t
- nil)))))
-
-(defun bh/skip-project-tasks-maybe ()
- "Show tasks related to the current restriction.
-When restricted to a project, skip project and sub project tasks, habits, NEXT tasks, and loose tasks.
-When not restricted, skip project and sub-project tasks, habits, and project related tasks."
- (save-restriction
- (widen)
- (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
- (next-headline (save-excursion (or (outline-next-heading) (point-max))))
- (limit-to-project (marker-buffer org-agenda-restrict-begin)))
- (cond
- ((bh/is-project-p)
- next-headline)
- ((org-is-habit-p)
- subtree-end)
- ((and (not limit-to-project)
- (bh/is-project-subtree-p))
- subtree-end)
- ((and limit-to-project
- (bh/is-project-subtree-p)
- (member (org-get-todo-state) (list "NEXT")))
- subtree-end)
- (t
- nil)))))
-
-(defun bh/skip-project-tasks ()
- "Show non-project tasks.
-Skip project and sub-project tasks, habits, and project related tasks."
- (save-restriction
- (widen)
- (let* ((subtree-end (save-excursion (org-end-of-subtree t))))
- (cond
- ((bh/is-project-p)
- subtree-end)
- ((org-is-habit-p)
- subtree-end)
- ((bh/is-project-subtree-p)
- subtree-end)
- (t
- nil)))))
-
-(defun bh/skip-non-project-tasks ()
- "Show project tasks.
-Skip project and sub-project tasks, habits, and loose non-project tasks."
- (save-restriction
- (widen)
- (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
- (next-headline (save-excursion (or (outline-next-heading) (point-max)))))
- (cond
- ((bh/is-project-p)
- next-headline)
- ((org-is-habit-p)
- subtree-end)
- ((and (bh/is-project-subtree-p)
- (member (org-get-todo-state) (list "NEXT")))
- subtree-end)
- ((not (bh/is-project-subtree-p))
- subtree-end)
- (t
- nil)))))
-
-(defun bh/skip-projects-and-habits ()
- "Skip trees that are projects and tasks that are habits"
- (save-restriction
- (widen)
- (let ((subtree-end (save-excursion (org-end-of-subtree t))))
- (cond
- ((bh/is-project-p)
- subtree-end)
- ((org-is-habit-p)
- subtree-end)
- (t
- nil)))))
-
-(defun bh/skip-non-subprojects ()
- "Skip trees that are not projects"
- (let ((next-headline (save-excursion (outline-next-heading))))
- (if (bh/is-subproject-p)
- nil
- next-headline)))
-;
-;; Resume clocking task when emacs is restarted
-(org-clock-persistence-insinuate)
-;;
-;; Show lot of clocking history so it's easy to pick items off the C-F11 list
-(setq org-clock-history-length 23)
-;; Resume clocking task on clock-in if the clock is open
-(setq org-clock-in-resume t)
-;; Change tasks to NEXT when clocking in
-(setq org-clock-in-switch-to-state 'bh/clock-in-to-next)
-;; Separate drawers for clocking and logs
-(setq org-drawers (quote ("PROPERTIES" "LOGBOOK")))
-;; Save clock data and state changes and notes in the LOGBOOK drawer
-(setq org-clock-into-drawer t)
-(setq org-log-into-drawer t)
-;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
-(setq org-clock-out-remove-zero-time-clocks t)
-;; Clock out when moving task to a done state
-(setq org-clock-out-when-done t)
-;; Save the running clock and all clock history when exiting Emacs, load it on startup
-(setq org-clock-persist t)
-;; Do not prompt to resume an active clock
-(setq org-clock-persist-query-resume nil)
-;; Enable auto clock resolution for finding open clocks
-(setq org-clock-auto-clock-resolution (quote when-no-clock-is-running))
-;; Include current clocking task in clock reports
-(setq org-clock-report-include-clocking-task t)
-
-
-(defvar bh/keep-clock-running nil)
-
-(defun bh/clock-in-to-next (kw)
- "Switch a task from TODO to NEXT when clocking in.
-Skips capture tasks, projects, and subprojects.
-Switch projects and subprojects from NEXT back to TODO"
- (when (not (and (boundp 'org-capture-mode) org-capture-mode))
- (cond
- ((and (member (org-get-todo-state) (list "TODO"))
- (bh/is-task-p))
- "NEXT")
- ((and (member (org-get-todo-state) (list "NEXT"))
- (bh/is-project-p))
- "TODO"))))
-
-(defun bh/find-project-task ()
- "Move point to the parent (project) task if any"
- (save-restriction
- (widen)
- (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point))))
- (while (org-up-heading-safe)
- (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
- (setq parent-task (point))))
- (goto-char parent-task)
- parent-task)))
-
-(defun bh/punch-in (arg)
- "Start continuous clocking and set the default task to the
-selected task. If no task is selected set the Organization task
-as the default task."
- (interactive "p")
- (setq bh/keep-clock-running t)
- (if (equal major-mode 'org-agenda-mode)
- ;;
- ;; We're in the agenda
- ;;
- (let* ((marker (org-get-at-bol 'org-hd-marker))
- (tags (org-with-point-at marker (org-get-tags-at))))
- (if (and (eq arg 4) tags)
- (org-agenda-clock-in '(16))
- (bh/clock-in-organization-task-as-default)))
- ;;
- ;; We are not in the agenda
- ;;
- (save-restriction
- (widen)
- ; Find the tags on the current task
- (if (and (equal major-mode 'org-mode) (not (org-before-first-heading-p)) (eq arg 4))
- (org-clock-in '(16))
- (bh/clock-in-organization-task-as-default)))))
-
-(defun bh/punch-out ()
- (interactive)
- (setq bh/keep-clock-running nil)
- (when (org-clock-is-active)
- (org-clock-out))
- (org-agenda-remove-restriction-lock))
-
-(defun bh/clock-in-default-task ()
- (save-excursion
- (org-with-point-at org-clock-default-task
- (org-clock-in))))
-
-(defun bh/clock-in-parent-task ()
- "Move point to the parent (project) task if any and clock in"
- (let ((parent-task))
- (save-excursion
- (save-restriction
- (widen)
- (while (and (not parent-task) (org-up-heading-safe))
- (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
- (setq parent-task (point))))
- (if parent-task
- (org-with-point-at parent-task
- (org-clock-in))
- (when bh/keep-clock-running
- (bh/clock-in-default-task)))))))
-
-(defvar bh/organization-task-id "e22cb8bf-07c7-408b-8f60-ff3aadac95e4")
-
-(defun bh/clock-in-organization-task-as-default ()
- (interactive)
- (org-with-point-at (org-id-find bh/organization-task-id 'marker)
- (org-clock-in '(16))))
-
-(defun bh/clock-out-maybe ()
- (when (and bh/keep-clock-running
- (not org-clock-clocking-in)
- (marker-buffer org-clock-default-task)
- (not org-clock-resolving-clocks-due-to-idleness))
- (bh/clock-in-parent-task)))
-
-(add-hook 'org-clock-out-hook 'bh/clock-out-maybe 'append)
-
-(require 'org-id)
-(defun bh/clock-in-task-by-id (id)
- "Clock in a task by id"
- (org-with-point-at (org-id-find id 'marker)
- (org-clock-in nil)))
-
-(defun bh/clock-in-last-task (arg)
- "Clock in the interrupted task if there is one
-Skip the default task and get the next one.
-A prefix arg forces clock in of the default task."
- (interactive "p")
- (let ((clock-in-to-task
- (cond
- ((eq arg 4) org-clock-default-task)
- ((and (org-clock-is-active)
- (equal org-clock-default-task (cadr org-clock-history)))
- (caddr org-clock-history))
- ((org-clock-is-active) (cadr org-clock-history))
- ((equal org-clock-default-task (car org-clock-history)) (cadr org-clock-history))
- (t (car org-clock-history)))))
- (widen)
- (org-with-point-at clock-in-to-task
- (org-clock-in nil))))
-