, a minimal agenda file, and a .emacs, which I have strip off everything except org-mode related code including Bernt's clock set up. It's not minimal by any means, but I don't have the skills to decide what else can be removed without introducing missing functions.
#+STARTUP: content
#+STARTUP: hidestars
#+STARTUP: indent
Organization
:PROPERTIES:
:ID: kth92m81qwe0
:END:
<.emacs>
;; set up ELPA
(require 'package)
(package-initialize)
;;
;; Org Mode
;;
;; save all org buffers at 1 minute before the hour
(run-at-time "00:59" 3600 'org-save-all-org-buffers)
(add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))
;; enable org-struct mode in gnus messages
(setq message-mode-hook
(quote (orgstruct++-mode
(lambda nil (setq fill-column 72) (flyspell-mode 1))
turn-on-auto-fill)))
;; 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)
;; Org-Agenda Files
(setq org-agenda-files (quote("h:/org/
test.org")))
;; 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 "<f8>") 'org-cycle-agenda-files)
(global-set-key (kbd "<f9> c") 'calendar)
(global-set-key (kbd "<f9> I") 'bh/punch-in)
(global-set-key (kbd "<f9> O") 'bh/punch-out)
(global-set-key (kbd "<f9> m") 'bh/clock-in-email-task)
(global-set-key (kbd "<f9> o") 'bh/clock-in-organization-task)
(global-set-key (kbd "<f9> r") 'bh/clock-in-journal-review-task)
(global-set-key (kbd "<f9> q") 'boxquote-region)
(global-set-key (kbd "<f9> s") 'bh/switch-to-scratch)
(global-set-key (kbd "<f9> SPC") 'bh/clock-in-last-task)
(global-set-key (kbd "C-<f9>") 'previous-buffer)
(global-set-key (kbd "<f10>") 'hist-org-clock-in-select)
(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)
;; Functions for Custom Key Bindings
(defun bh/switch-to-scratch ()
(interactive)
(switch-to-buffer "*scratch*"))
(defun bh/org-todo (arg)
(interactive "p")
(if (equal arg 4)
(save-restriction
(bh/narrow-to-org-subtree)
(org-show-todo-tree nil))
(bh/narrow-to-org-subtree)
(org-show-todo-tree nil)))
(global-set-key (kbd "<S-f5>") 'bh/widen)
(defun bh/widen ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-agenda-remove-restriction-lock)
(when org-agenda-sticky
(org-agenda-redo)))
(widen)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "W" (lambda () (interactive) (setq bh/hide-scheduled-and-waiting-next-tasks t) (bh/widen))))
'append)
(defun bh/restrict-to-file-or-follow (arg)
"Set agenda restriction to 'file or with argument invoke follow mode.
I don't use follow mode very often but I restrict to file all the time
so change the default 'F' binding in the agenda to allow both"
(interactive "p")
(if (equal arg 4)
(org-agenda-follow-mode)
(widen)
(bh/set-agenda-restriction-lock 4)
(org-agenda-redo)
(beginning-of-buffer)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "F" 'bh/restrict-to-file-or-follow))
'append)
(defun bh/narrow-to-org-subtree ()
(widen)
(org-narrow-to-subtree)
(save-restriction
(org-agenda-set-restriction-lock)))
(defun bh/narrow-to-subtree ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-with-point-at (org-get-at-bol 'org-hd-marker)
(bh/narrow-to-org-subtree))
(when org-agenda-sticky
(org-agenda-redo)))
(bh/narrow-to-org-subtree)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "N" 'bh/narrow-to-subtree))
'append)
(defun bh/narrow-up-one-org-level ()
(widen)
(save-excursion
(outline-up-heading 1 'invisible-ok)
(bh/narrow-to-org-subtree)))
(defun bh/get-pom-from-agenda-restriction-or-point ()
(or (and (marker-position org-agenda-restrict-begin) org-agenda-restrict-begin)
(org-get-at-bol 'org-hd-marker)
(and (equal major-mode 'org-mode) (point))
org-clock-marker))
(defun bh/narrow-up-one-level ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-with-point-at (bh/get-pom-from-agenda-restriction-or-point)
(bh/narrow-up-one-org-level))
(org-agenda-redo))
(bh/narrow-up-one-org-level)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "U" 'bh/narrow-up-one-level))
'append)
(defun bh/narrow-to-org-project ()
(widen)
(save-excursion
(bh/find-project-task)
(bh/narrow-to-org-subtree)))
(defun bh/narrow-to-project ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-with-point-at (bh/get-pom-from-agenda-restriction-or-point)
(bh/narrow-to-org-project)
(save-excursion
(bh/find-project-task)
(org-agenda-set-restriction-lock)))
(org-agenda-redo)
(beginning-of-buffer))
(bh/narrow-to-org-project)
(save-restriction
(org-agenda-set-restriction-lock))))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "P" 'bh/narrow-to-project))
'append)
(defvar bh/project-list nil)
(defun bh/view-next-project ()
(interactive)
(let (num-project-left current-project)
(unless (marker-position org-agenda-restrict-begin)
(goto-char (point-min))
; Clear all of the existing markers on the list
(while bh/project-list
(set-marker (pop bh/project-list) nil))
(re-search-forward "Tasks to Refile")
(forward-visible-line 1))
; Build a new project marker list
(unless bh/project-list
(while (< (point) (point-max))
(while (and (< (point) (point-max))
(or (not (org-get-at-bol 'org-hd-marker))
(org-with-point-at (org-get-at-bol 'org-hd-marker)
(or (not (bh/is-project-p))
(bh/is-project-subtree-p)))))
(forward-visible-line 1))
(when (< (point) (point-max))
(add-to-list 'bh/project-list (copy-marker (org-get-at-bol 'org-hd-marker)) 'append))
(forward-visible-line 1)))
; Pop off the first marker on the list and display
(setq current-project (pop bh/project-list))
(when current-project
(org-with-point-at current-project
(setq bh/hide-scheduled-and-waiting-next-tasks nil)
(bh/narrow-to-project))
; Remove the marker
(setq current-project nil)
(org-agenda-redo)
(beginning-of-buffer)
(setq num-projects-left (length bh/project-list))
(if (> num-projects-left 0)
(message "%s projects left to view" num-projects-left)
(beginning-of-buffer)
(setq bh/hide-scheduled-and-waiting-next-tasks t)
(error "All projects viewed.")))))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "V" 'bh/view-next-project))
'append)
(setq org-show-entry-below (quote ((default))))
;; TODO keyword sequences
(setq org-todo-keywords
(quote ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
(sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))
;; TODO state triggers and tags
(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")))))
;; Custom agenda command definitions
(defvar bh/hide-scheduled-and-waiting-next-tasks t)
(defun bh/org-auto-exclude-function (tag)
"Automatic task exclusion in the agenda with / RET"
(and (cond
((string= tag "hold")
t))
(concat "-" tag)))
(setq org-agenda-auto-exclude-function 'bh/org-auto-exclude-function)
;; clock setup
;; 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)
;; 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)
(setq 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 "eb155a82-92b2-4f25-a3c6-0304591af2f9")
(defvar bh/organization-task-id "kth92m81qwe0")
(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))))
;; 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)
;; Agenda clock report parameters
(setq org-agenda-clockreport-parameter-plist
(quote (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80)))
;; Agenda views 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-non-tasks ()
"Show non-project tasks.
Skip project and sub-project tasks, habits, and project related tasks."
(save-restriction
(widen)
(let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
(cond
((bh/is-task-p)
nil)
(t
next-headline)))))
(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)
(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
((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)
((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)
((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)
((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)
(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)))
;; Archive setup
(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))))
;; Helper Functions
;; narrowing to a subtree
(defun bh/org-todo (arg)
(interactive "p")
(if (equal arg 4)
(save-restriction
(bh/narrow-to-org-subtree)
(org-show-todo-tree nil))
(bh/narrow-to-org-subtree)
(org-show-todo-tree nil)))
;; widen
(defun bh/widen ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-agenda-remove-restriction-lock)
(when org-agenda-sticky
(org-agenda-redo)))
(widen)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "W" (lambda () (interactive) (setq bh/hide-scheduled-and-waiting-next-tasks t) (bh/widen))))
'append)
(defun bh/restrict-to-file-or-follow (arg)
"Set agenda restriction to 'file or with argument invoke follow mode.
I don't use follow mode very often but I restrict to file all the time
so change the default 'F' binding in the agenda to allow both"
(interactive "p")
(if (equal arg 4)
(org-agenda-follow-mode)
(widen)
(bh/set-agenda-restriction-lock 4)
(org-agenda-redo)
(beginning-of-buffer)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "F" 'bh/restrict-to-file-or-follow))
'append)
(defun bh/narrow-to-org-subtree ()
(widen)
(org-narrow-to-subtree)
(save-restriction
(org-agenda-set-restriction-lock)))
(defun bh/narrow-to-subtree ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-with-point-at (org-get-at-bol 'org-hd-marker)
(bh/narrow-to-org-subtree))
(when org-agenda-sticky
(org-agenda-redo)))
(bh/narrow-to-org-subtree)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "N" 'bh/narrow-to-subtree))
'append)
(defun bh/narrow-up-one-org-level ()
(widen)
(save-excursion
(outline-up-heading 1 'invisible-ok)
(bh/narrow-to-org-subtree)))
(defun bh/get-pom-from-agenda-restriction-or-point ()
(or (and (marker-position org-agenda-restrict-begin) org-agenda-restrict-begin)
(org-get-at-bol 'org-hd-marker)
(and (equal major-mode 'org-mode) (point))
org-clock-marker))
(defun bh/narrow-up-one-level ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-with-point-at (bh/get-pom-from-agenda-restriction-or-point)
(bh/narrow-up-one-org-level))
(org-agenda-redo))
(bh/narrow-up-one-org-level)))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "U" 'bh/narrow-up-one-level))
'append)
(defun bh/narrow-to-org-project ()
(widen)
(save-excursion
(bh/find-project-task)
(bh/narrow-to-org-subtree)))
(defun bh/narrow-to-project ()
(interactive)
(if (equal major-mode 'org-agenda-mode)
(progn
(org-with-point-at (bh/get-pom-from-agenda-restriction-or-point)
(bh/narrow-to-org-project)
(save-excursion
(bh/find-project-task)
(org-agenda-set-restriction-lock)))
(org-agenda-redo)
(beginning-of-buffer))
(bh/narrow-to-org-project)
(save-restriction
(org-agenda-set-restriction-lock))))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "P" 'bh/narrow-to-project))
'append)
(defvar bh/project-list nil)
(defun bh/view-next-project ()
(interactive)
(let (num-project-left current-project)
(unless (marker-position org-agenda-restrict-begin)
(goto-char (point-min))
; Clear all of the existing markers on the list
(while bh/project-list
(set-marker (pop bh/project-list) nil))
(re-search-forward "Tasks to Refile")
(forward-visible-line 1))
; Build a new project marker list
(unless bh/project-list
(while (< (point) (point-max))
(while (and (< (point) (point-max))
(or (not (org-get-at-bol 'org-hd-marker))
(org-with-point-at (org-get-at-bol 'org-hd-marker)
(or (not (bh/is-project-p))
(bh/is-project-subtree-p)))))
(forward-visible-line 1))
(when (< (point) (point-max))
(add-to-list 'bh/project-list (copy-marker (org-get-at-bol 'org-hd-marker)) 'append))
(forward-visible-line 1)))
; Pop off the first marker on the list and display
(setq current-project (pop bh/project-list))
(when current-project
(org-with-point-at current-project
(setq bh/hide-scheduled-and-waiting-next-tasks nil)
(bh/narrow-to-project))
; Remove the marker
(setq current-project nil)
(org-agenda-redo)
(beginning-of-buffer)
(setq num-projects-left (length bh/project-list))
(if (> num-projects-left 0)
(message "%s projects left to view" num-projects-left)
(beginning-of-buffer)
(setq bh/hide-scheduled-and-waiting-next-tasks t)
(error "All projects viewed.")))))
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "V" 'bh/view-next-project))
'append)
;; Force-show next headline
(setq org-show-entry-below (quote ((default))))
;; limit agenda to a subtree
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "\C-c\C-x<" 'bh/set-agenda-restriction-lock))
'append)
(defun bh/set-agenda-restriction-lock (arg)
"Set restriction lock to current task subtree or file if prefix is specified"
(interactive "p")
(let* ((pom (bh/get-pom-from-agenda-restriction-or-point))
(tags (org-with-point-at pom (org-get-tags-at))))
(let ((restriction-type (if (equal arg 4) 'file 'subtree)))
(save-restriction
(cond
((and (equal major-mode 'org-agenda-mode) pom)
(org-with-point-at pom
(org-agenda-set-restriction-lock restriction-type))
(org-agenda-redo))
((and (equal major-mode 'org-mode) (org-before-first-heading-p))
(org-agenda-set-restriction-lock 'file))
(pom
(org-with-point-at pom
(org-agenda-set-restriction-lock restriction-type))))))))
;; Limit restriction lock highlighting to the headline only
(setq org-agenda-restriction-lock-highlight-subtree nil)
;; Always highlight current agenda line
(add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))
;; Keep tasks with dates on the global todo lists
(setq org-agenda-todo-ignore-with-date nil)
;; Keep tasks with deadlines on the global todo lists
(setq org-agenda-todo-ignore-deadlines nil)
;; Keep tasks with scheduled dates on the global todo lists
(setq org-agenda-todo-ignore-scheduled nil)
;; Keep tasks with timestamps on the global todo lists
(setq org-agenda-todo-ignore-timestamp nil)
;; Remove completed deadline tasks from the agenda view
(setq org-agenda-skip-deadline-if-done t)
;; Remove completed scheduled tasks from the agenda view
(setq org-agenda-skip-scheduled-if-done t)
;; Remove completed items from search results
(setq org-agenda-skip-timestamp-if-done t)
;; Include agenda archive files when searching for things
(setq org-agenda-text-search-extra-files (quote (agenda-archives)))
;; Agenda view tweaks
;; Show all future entries for repeating tasks
(setq org-agenda-repeating-timestamp-show-all t)
;; Show all agenda dates - even if they are empty
(setq org-agenda-show-all-dates t)
;; Sorting order for tasks on the agenda
(setq org-agenda-sorting-strategy
(quote ((agenda habit-down time-up user-defined-up effort-up category-keep)
(todo category-up effort-up)
(tags category-up effort-up)
(search category-up))))
;; Start the weekly agenda on Monday
(setq org-agenda-start-on-weekday 1)
;; Enable display of the time grid so we can see the marker for the current time
(setq org-agenda-time-grid (quote ((daily today remove-match)
#("----------------" 0 16 (org-heading t))
(0900 1100 1300 1500 1700))))
;; Display tags farther right
(setq org-agenda-tags-column -102)
;;
;; Agenda sorting functions
;;
(setq org-agenda-cmp-user-defined 'bh/agenda-sort)
(defun bh/agenda-sort (a b)
"Sorting strategy for agenda items.
Late deadlines first, then scheduled, then non-late deadlines"
(let (result num-a num-b)
(cond
; time specific items are already sorted first by org-agenda-sorting-strategy
; non-deadline and non-scheduled items next
((bh/agenda-sort-test 'bh/is-not-scheduled-or-deadline a b))
; deadlines for today next
((bh/agenda-sort-test 'bh/is-due-deadline a b))
; late deadlines next
((bh/agenda-sort-test-num 'bh/is-late-deadline '> a b))
; scheduled items for today next
((bh/agenda-sort-test 'bh/is-scheduled-today a b))
; late scheduled items next
((bh/agenda-sort-test-num 'bh/is-scheduled-late '> a b))
; pending deadlines last
((bh/agenda-sort-test-num 'bh/is-pending-deadline '< a b))
; finally default to unsorted
(t (setq result nil)))
result))
(defmacro bh/agenda-sort-test (fn a b)
"Test for agenda sort"
`(cond
; if both match leave them unsorted
((and (apply ,fn (list ,a))
(apply ,fn (list ,b)))
(setq result nil))
; if a matches put a first
((apply ,fn (list ,a))
(setq result -1))
; otherwise if b matches put b first
((apply ,fn (list ,b))
(setq result 1))
; if none match leave them unsorted
(t nil)))
(defmacro bh/agenda-sort-test-num (fn compfn a b)
`(cond
((apply ,fn (list ,a))
(setq num-a (string-to-number (match-string 1 ,a)))
(if (apply ,fn (list ,b))
(progn
(setq num-b (string-to-number (match-string 1 ,b)))
(setq result (if (apply ,compfn (list num-a num-b))
-1
1)))
(setq result -1)))
((apply ,fn (list ,b))
(setq result 1))
(t nil)))
(defun bh/is-not-scheduled-or-deadline (date-str)
(and (not (bh/is-deadline date-str))
(not (bh/is-scheduled date-str))))
(defun bh/is-due-deadline (date-str)
(string-match "Deadline:" date-str))
(defun bh/is-late-deadline (date-str)
(string-match "\\([0-9]*\\) d\. ago:" date-str))
(defun bh/is-pending-deadline (date-str)
(string-match "In \\([^-]*\\)d\.:" date-str))
(defun bh/is-deadline (date-str)
(or (bh/is-due-deadline date-str)
(bh/is-late-deadline date-str)
(bh/is-pending-deadline date-str)))
(defun bh/is-scheduled (date-str)
(or (bh/is-scheduled-today date-str)
(bh/is-scheduled-late date-str)))
(defun bh/is-scheduled-today (date-str)
(string-match "Scheduled:" date-str))
(defun bh/is-scheduled-late (date-str)
(string-match "Sched\.\\(.*\\)x:" date-str))
;; Use sticky agenda's so they persist
(setq org-agenda-sticky t)
;; checklist handling
;;(require 'org-checklist)
;; enable task blocking
(setq org-enforce-todo-dependencies t)
;; org indent mode
(setq org-startup-indented t)
;; Handling blank lines
(setq org-cycle-separator-lines 0)
(setq org-blank-before-new-entry (quote ((heading)
(plain-list-item . auto))))
;; Adding new tasks quickly without disturbing the current task content
(setq org-insert-heading-respect-content nil)
;; Notes at the top
(setq org-reverse-note-order nil)
;; Searching and showing results
(setq org-show-following-heading t)
(setq org-show-hierarchy-above t)
(setq org-show-siblings (quote ((default))))
;; Editing and Special key handling
(setq org-special-ctrl-a/e t)
(setq org-special-ctrl-k t)
(setq org-yank-adjusted-subtrees t)
;; Deadlines and Agenda Visibility
(setq org-deadline-warning-days 30)
;; Logging settings
(setq org-log-done (quote time))
(setq org-log-into-drawer t)
(setq org-log-state-notes-insert-after-drawers nil)
;; Return follows links
(setq org-return-follows-link t)
;; Remove indentation on agenda tags view
(setq org-tags-match-list-sublevels t)
;; Agenda persistent filters
(setq org-agenda-persistent-filter t)
;; Use Emacs bookmarks for fast navigation
(global-set-key (kbd "<C-f6>") '(lambda () (interactive) (bookmark-set "SAVED")))
(global-set-key (kbd "<f6>") '(lambda () (interactive) (bookmark-jump "SAVED")))
;; Cycling plain lists
(setq org-cycle-include-plain-lists nil)
;; NEXT is for tasks
(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)
;; Startup in folded view
(setq org-startup-folded t)
;; Allow alphabetical list entries
(setq org-alphabetical-lists t)
;; Prevent editing invisible text
(setq org-catch-invisible-edits 'error)
;; Keep clock durations in hours
(setq org-time-clocksum-format
'(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t))
;;;;;;;;;;;;old bindings
(defun bh/clock-in-email-task ()
(interactive)
(bh/clock-in-task-by-id "gah7sk81qwe0"))
(defun bh/clock-in-organization-task ()
(interactive)
(bh/clock-in-task-by-id "kth92m81qwe0"))
(defun bh/clock-in-journal-review-task ()
(interactive)
(bh/clock-in-task-by-id "tgq4fh776dc2"))
;; Helper functions for projects
(defun bh/is-project-p-with-open-subtasks ()
"Any task with a todo keyword subtask"
(let ((has-subtask)
(subtree-end (save-excursion (org-end-of-subtree t))))
(save-excursion
(forward-line 1)
(while (and (not has-subtask)
(< (point) subtree-end)
(re-search-forward "^\*+ " subtree-end t))
(when (and
(member (org-get-todo-state) org-todo-keywords-1)
(not (member (org-get-todo-state) org-done-keywords)))
(setq has-subtask t))))
has-subtask))
;; Limit agenda to a subtree
(add-hook 'org-agenda-mode-hook
'(lambda () (org-defkey org-agenda-mode-map "\C-c\C-x<" 'bh/set-agenda-restriction-lock))
'append)
(defun bh/set-agenda-restriction-lock (arg)
"Set restriction lock to current task subtree or file if prefix is specified"
(interactive "p")
(let* ((pom (bh/get-pom-from-agenda-restriction-or-point))
(tags (org-with-point-at pom (org-get-tags-at))))
(let ((restriction-type (if (equal arg 4) 'file 'subtree)))
(save-restriction
(cond
((and (equal major-mode 'org-agenda-mode) pom)
(org-with-point-at pom
(org-agenda-set-restriction-lock restriction-type))
(org-agenda-redo))
((and (equal major-mode 'org-mode) (org-before-first-heading-p))
(org-agenda-set-restriction-lock 'file))
(pom
(org-with-point-at pom
(org-agenda-set-restriction-lock restriction-type))))))))
;; function to bind C-u C-c C-x C-i to F10
(defun hist-org-clock-in-select ()
(interactive)
(org-clock-in '(4)))
(setq org-enforce-todo-dependencies t)
(setq org-expiry-keyword "EXPIRED")
;; Color Schemes
;;(add-to-list 'load-path "~/.emacs.d/color-themes/")
;;(add-to-list 'load-path "~/.emacs.d/elpa/")
;;(add-to-list 'custom-theme-load-path "~/.emacs.d/color-themes/")
;;(add-to-list 'custom-theme-load-path "~/.emacs.d/site-elpa/")
;;(require 'color-theme)
;;(color-theme-initialize)
;(;color-theme-calm-forest)
;;(color-theme-subtle-blue)
;;(color-theme-classic)
;;(color-theme-ample-zen)
;;(color-theme-Deviant)
;;(color-theme-cobalt)
;;(load-theme 'Deviant t)
;; Clock set-up
(defun bh/clock-in-task-by-id (id)
"Clock in a task by id"
(require 'org-id)
(save-restriction
(widen)
(org-with-point-at (org-id-find id 'marker)
(org-clock-in nil))))
;; Resume clocking tasks when emacs is restarted
;; Yes it's long... but more is better ;)
(setq org-clock-history-length 24)
;; Resume clocking task on clock-in if the clock is open
(setq org-clock-in-resume t)
;; Change task state to NEXT when clocking in
(setq org-clock-in-switch-to-state (quote bh/clock-in-to-next))
;; Separate drawers for clocking and logs/notes
(setq org-drawers (quote ("PROPERTIES" "LOGBOOK" "CLOCK" "NOTES")))
;; Save notes in the LOGBOOK drawer
(setq org-log-into-drawer "LOGBOOK")
;; Save clock data in the CLOCK drawer
(setq org-clock-into-drawer "CLOCK")
;; Don't clock out when moving task to a done state
(setq org-clock-out-when-done nil)
;; Save the running clock and all clock history when exiting Emacs, load it on startup
(setq org-clock-persist t)
;; Round time to 5 minute increments
(setq org-time-stamp-rounding-minutes (quote (1 5)))
;; Remove clocked tasks with 0:00 duration
(setq org-clock-out-remove-zero-time-clocks t)
;; Agenda log mode items to display (clock time only by default)
(setq org-agenda-log-mode-items (quote (clock)))
;; Show toady's time in clock mode line
(setq org-clock-mode-line-total (quote today))
;; Agenda clock report parameters (no links, 4 levels deep)
(setq org-agenda-clockreport-parameter-plist (quote (:link nil :maxlevel 4)))
;; Set default column view headings: Task Effort Clock_Summary
(setq org-columns-default-format "%40ITEM(Task) %TAGS %TODO %10Effort(Effort){:} %10CLOCKSUM")
;; global Effort estimate values
(setq org-global-properties (quote (("Effort_ALL" . "0:05 0:15 0:30 1:00 1:30 2:00 2:30 3:00 3:30 4:00 4:30 5:00 5:30 6:00 6:30 7:00 7:30 8:00"))))
;; Set-up TAGS
;; Tags with fast selection keys
(setq org-tag-alist (quote (("NEXT" . ?N)
("WAITING" . ?W)
("CANCELLED" . ?C))))
;; For tag searches ignore tasks with scheduled and deadline dates
(setq org-agenda-tags-todo-honor-ignore-options t)
;; Find stuck projects
(setq org-stuck-projects (quote ("LEVEL=2/!-DONE-CANCELLED-OPEN-SOMEDAY-WAITING" nil ("NEXT") "")))
;; Set up org-capture:
(define-key global-map "\C-cc" 'org-capture)
;; re-align tags when finalizing items with tags
(setq org-auto-align-tags t)
;; Agenda Day Separator
;;(setq org-agenda-format-date
;; (concat "__________%a %Y-%m-%d"
;; (make-string (- (window-width) 24) ?_)))
;; use spaces instead of _ since we're in a box here
(setq org-agenda-format-date
(concat " %a %Y-%m-%d"
(make-string (- (window-width) 24) ? )))
;; always show time grid
(setq org-agenda-time-grid
(quote ((daily today) "----------------" (800 1000 1200 1400 1600 1800 2000))))
;; activate calfw
;;(add-to-list 'load-path "~/.emacs.d/site-lisp/calfw1.0/")
;;(require 'calfw-org)
;; Taskjuggler mode for emacs
;;(require 'taskjuggler-mode)
;; ditaa and babel
;;(setq org-ditaa-jar-path "~/.emacs.d/org-mode/contrib/scripts/ditaa.jar")
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(latex . t)
(ditaa . t)))
;; enable pdb-mode
;;(load-file "c:/Users/mheller/AppData/Roaming/.emacs.d/site-lisp/pdb-mode.el")
(setq auto-mode-alist
(cons (cons "pdb$" 'pdb-mode)
auto-mode-alist))
(autoload 'pdb-mode "PDB")
;; set up ELPA
;;(require 'package)
;;(package-initialize)
;;(unless package-archive-contents (package-refresh-contents))
;;(unless (package-installed-p 'org) (package-install 'org))
;;
;;
;;
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(TeX-output-view-style
(quote
(("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" "dvips %d -o && start \"\" %f")
("^dvi$" "." "yap -1 %dS %d")
("^pdf$" "." "gsview64.exe %o")
("^html?$" "." "start \"\" %o"))))
'(TeX-view-program-list (quote (("gsview" "gsview64.exe %o"))))
'(TeX-view-program-selection
(quote
(((output-dvi style-pstricks)
"dvips and start")
(output-dvi "Yap")
(output-pdf "gsview")
(output-html "start"))))
'(ansi-color-names-vector
["#002b36" "#dc322f" "#859900" "#b58900" "#268bd2" "#d33682" "#2aa198" "#839496"])
'(ansi-term-color-vector
[unspecific "#586e75" "#dc322f" "#859900" "#b58900" "#268bd2" "#d33682" "#2aa198" "#002b36"])
'(canlock-password "d956c608d952dc7a21822967382659482ed41a55" t)
'(custom-enabled-themes nil)
'(custom-safe-themes
(quote
("bb749a38c5cb7d13b60fa7fc40db7eced3d00aa93654d150b9627cabd2d9b361" "8c239ccd90e1e4483a9da693bf66dd1b792fe5aff97d0a2f02b016e86fbd8728" "01ce486c3a7c8b37cf13f8c95ca4bb3c11413228b35676025fdf239e77019ea1" "0a90958236c1b6ecb4a8f91ce6b4c13a7c71faf3022d557d9d6b392dc7308e0f" "8aebf25556399b58091e533e455dd50a6a9cba958cc4ebb0aab175863c25b9a4" "3486508cb95981a7003e376c1e6a54593c35c448bc7a8fea07eee37aad41512d" "4ab86c7682db09485a6e046ee0a6c45b5462f514c89844f4ed8b329aa1708067" "12b7ed9b0e990f6d41827c343467d2a6c464094cbcc6d0844df32837b50655f9" default)))
'(package-selected-packages
(quote
(pdb-mode org-bullets org-beautify-theme org-autolist org-alert org-agenda-property org color-theme boxquote batch-mode auctex)))
'(show-paren-mode t))
;;
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
</.emacs>