;;; Org Mode
(add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))
;; Standard key bindings
(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cb" 'org-iswitchb)
https://emacs.cafe/emacs/orgmode/gtd/2017/06/30/orgmode-gtd.html
(if (boundp 'org-user-agenda-files)
(setq org-agenda-files org-user-agenda-files)
(setq org-agenda-files '("~/gtd/refile.org"
"~/gtd/gtd.org"
"~/gtd/tickler.org")))
;; Custom Key Bindings
(global-set-key (kbd "<f12>") 'org-agenda)
(global-set-key (kbd "<f8>") 'org-cycle-agenda-files)
;(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> g") 'gnus)
(global-set-key (kbd "<f9> r") 'boxquote-region)
(global-set-key (kbd "<f9> v") 'visible-mode)
(global-set-key (kbd "<f9> l") 'org-toggle-link-display)
(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 "<f11>") 'org-clock-goto)
(global-set-key (kbd "C-<f11>") 'org-clock-in)
(global-set-key (kbd "C-c c") 'org-capture)
(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-use-fast-todo-selection t)
(setq org-treat-S-cursor-todo-selection-as-state-change nil)
(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")))))
(setq org-directory "~/gtd")
(setq org-default-notes-file (concat org-directory "/refile.org"))
;; Capture templates for: TODO tasks, Notes, appointments, phone calls, meetings, and org-protocol
(setq org-capture-templates
(quote (("t" "todo" entry (file "refile.org")
"* TODO %?\n%U\n%a\n")
("r" "respond" entry (file "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 "refile.org")
"* %? :NOTE:\n%U\n%a\n")
("j" "Journal" entry (file+datetree "diary.org")
"* %?\n%U\n")
("w" "org-protocol" entry (file "refile.org")
"* TODO Review %c\n%U\n" :immediate-finish t)
("m" "Meeting" entry (file "refile.org")
"* MEETING with %? :MEETING:\n%U")
("p" "Phone call" entry (file "refile.org")
"* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t)
("T" "Tickler" entry (file+headline "tickler.org" "Tickler")
"* 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 (point))))
(add-hook 'org-clock-out-hook 'bh/remove-empty-drawer-on-clock-out 'append)
; 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)
;; 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 (concat "Waiting and Postponed Tasks"
(if bh/hide-scheduled-and-waiting-next-tasks
""
" (including WAITING and SCHEDULED tasks)")))
(org-agenda-skip-function 'bh/skip-non-tasks)
(org-tags-match-list-sublevels nil)
(org-agenda-todo-ignore-scheduled bh/hide-scheduled-and-waiting-next-tasks)
(org-agenda-todo-ignore-deadlines bh/hide-scheduled-and-waiting-next-tasks)))
(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))))
(defun bh/org-auto-exclude-function (tag)
"Automatic task exclusion in the agenda with / RET"
(and (cond
((string= tag "hold")
t)
((string= tag "farm")
t))
(concat "-" tag)))
(setq org-agenda-auto-exclude-function 'bh/org-auto-exclude-function)
; Tags with fast selection keys
(setq org-tag-alist (quote ((:startgroup)
("MUCFC" . ?m)
("@office" . ?o)
("@home" . ?H)
(:endgroup)
("WAITING" . ?w)
("HOLD" . ?h)
("PERSONAL" . ?P)
("WORK" . ?W)
("ORG" . ?O)
("crypt" . ?E)
("NOTE" . ?n)
("CANCELLED" . ?c)
("FLAGGED" . ??))))
; Allow setting single tags without the menu
(setq org-fast-tag-selection-single-key (quote expert))
; For tag searches ignore tasks with scheduled and deadline dates
(setq org-agenda-tags-todo-honor-ignore-options t)
(setq org-archive-mark-done nil)
(setq org-archive-location "%s_archive::* Archived Tasks")
(defun bh/skip-non-archivable-tasks ()
"Skip trees that are not available for archiving"
(save-restriction
(widen)
;; Consider only tasks with done todo headings as archivable candidates
(let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
(subtree-end (save-excursion (org-end-of-subtree t))))
(if (member (org-get-todo-state) org-todo-keywords-1)
(if (member (org-get-todo-state) org-done-keywords)
(let* ((daynr (string-to-int (format-time-string "%d" (current-time))))
(a-month-ago (* 60 60 24 (+ daynr 1)))
(last-month (format-time-string "%Y-%m-" (time-subtract (current-time) (seconds-to-time a-month-ago))))
(this-month (format-time-string "%Y-%m-" (current-time)))
(subtree-is-current (save-excursion
(forward-line 1)
(and (< (point) subtree-end)
(re-search-forward (concat last-month "\\|" this-month) subtree-end t)))))
(if subtree-is-current
subtree-end ; Has a date in this month or last month, skip it
nil)) ; available to archive
(or subtree-end (point-max)))
next-headline))))
;; Include agenda archive files when searching for things
(setq org-agenda-text-search-extra-files (quote (agenda-archives "~/personal/org/mucfc.org")))
;; Use sticky agenda's so they persist
(setq org-agenda-sticky t)
(setq org-hide-leading-stars nil)
I now use org-indent mode which hides leading stars.
(setq org-startup-indented t)
(setq org-cycle-separator-lines 0)
(setq org-blank-before-new-entry (quote ((heading)
(plain-list-item . auto))))
(setq org-insert-heading-respect-content nil)
(setq org-reverse-note-order nil)
(setq org-show-following-heading t)
(setq org-show-hierarchy-above t)
(setq org-show-siblings (quote ((default))))
(setq org-special-ctrl-a/e t)
(setq org-special-ctrl-k t)
(setq org-yank-adjusted-subtrees t)
(setq org-id-method (quote uuidgen))
(setq org-deadline-warning-days 30)
(setq org-table-export-default-format "orgtbl-to-csv")
(setq org-link-frame-setup (quote ((vm . vm-visit-folder)
(gnus . org-gnus-no-new-news)
(file . find-file))))
; Use the current window for C-c ' source editing
(setq org-src-window-setup 'current-window)
(setq org-log-done (quote time))
(setq org-log-into-drawer t)
(setq org-log-state-notes-insert-after-drawers nil)
(global-auto-revert-mode t)
(require 'org-crypt)
; Encrypt all entries before saving
(org-crypt-use-before-save-magic)
(setq org-tags-exclude-from-inheritance (quote ("crypt")))
; GPG key to use for encryption
(setq org-crypt-key "F0B66B40")
(setq org-crypt-disable-auto-save nil)
(setq org-return-follows-link t)
(setq org-read-date-prefer-future 'time)
(setq org-list-demote-modify-bullet (quote (("+" . "-")
("*" . "-")
("1." . "-")
("1)" . "-")
("A)" . "-")
("B)" . "-")
("a)" . "-")
("b)" . "-")
("A." . "-")
("B." . "-")
("a." . "-")
("b." . "-"))))
(setq org-tags-match-list-sublevels t)
(setq org-agenda-persistent-filter t)
(setq org-link-mailto-program (quote (compose-mail "%a" "%s")))
(require 'org-mime)
(setq org-agenda-skip-additional-timestamps-same-entry t)
(setq org-table-use-standard-references (quote from))
(setq org-file-apps (quote ((auto-mode . emacs)
("\\.mm\\'" . system)
("\\.x?html?\\'" . system)
("\\.pdf\\'" . system))))
; Overwrite the current window with the agenda
(setq org-agenda-window-setup 'current-window)
(setq org-clone-delete-id t)
(setq org-cycle-include-plain-lists t)
(setq org-src-fontify-natively t)
(setq org-structure-template-alist
(quote (("s" "#+begin_src ?\n\n#+end_src" "<src lang=\"?\">\n\n</src>")
("e" "#+begin_example\n?\n#+end_example" "<example>\n?\n</example>")
("q" "#+begin_quote\n?\n#+end_quote" "<quote>\n?\n</quote>")
("v" "#+begin_verse\n?\n#+end_verse" "<verse>\n?\n</verse>")
("c" "#+begin_center\n?\n#+end_center" "<center>\n?\n</center>")
("l" "#+begin_latex\n?\n#+end_latex" "<literal style=\"latex\">\n?\n</literal>")
("L" "#+latex: " "<literal style=\"latex\">?</literal>")
("h" "#+begin_html\n?\n#+end_html" "<literal style=\"html\">\n?\n</literal>")
("H" "#+html: " "<literal style=\"html\">?</literal>")
("a" "#+begin_ascii\n?\n#+end_ascii")
("A" "#+ascii: ")
("i" "#+index: ?" "#+index: ?")
("I" "#+include %file ?" "<include file=%file markup=\"?\">"))))
(defun bh/mark-next-parent-tasks-todo ()
"Visit each parent task and change NEXT states to TODO"
(let ((mystate (or (and (fboundp 'org-state)
state)
(nth 2 (org-heading-components)))))
(when mystate
(save-excursion
(while (org-up-heading-safe)
(when (member (nth 2 (org-heading-components)) (list "NEXT"))
(org-todo "TODO")))))))
(add-hook 'org-after-todo-state-change-hook 'bh/mark-next-parent-tasks-todo 'append)
(add-hook 'org-clock-in-hook 'bh/mark-next-parent-tasks-todo 'append)
(setq org-startup-folded t)
(setq org-alphabetical-lists t)
(add-hook 'message-mode-hook 'orgstruct++-mode 'append)
(add-hook 'message-mode-hook 'turn-on-auto-fill 'append)
;(add-hook 'message-mode-hook 'bbdb-define-all-aliases 'append)
(add-hook 'message-mode-hook 'orgtbl-mode 'append)
;(add-hook 'message-mode-hook 'turn-on-flyspell 'append)
(add-hook 'message-mode-hook
'(lambda () (setq fill-column 72))
'append)
(setq org-src-preserve-indentation nil)
(setq org-edit-src-content-indentation 0)
(setq org-catch-invisible-edits 'error)
(setq org-export-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(set-charset-priority 'unicode)
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))
(setq org-time-clocksum-format
'(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t))
(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)
(run-at-time "00:59" 3600 'org-save-all-org-buffers)
#!/bin/sh
# Add org file changes to the repository
REPOS="org doc.norang.ca www.norang.ca"
for REPO in $REPOS
do
echo "Repository: $REPO"
cd ~/git/$REPO
# Remove deleted files
git ls-files --deleted -z | xargs -0 git rm >/dev/null 2>&1
# Add new files
git add . >/dev/null 2>&1
git commit -m "$(date)"
done