From mboxrd@z Thu Jan 1 00:00:00 1970 From: Markus Heller Subject: Re: Clock setup stopped working after update Date: Fri, 3 Mar 2017 10:55:27 -0800 Message-ID: References: <878ton9zor.fsf@nicolasgoaziou.fr> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=001a113f1a7ed4337e0549d81676 Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:43749) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cjsMe-0001w7-PY for emacs-orgmode@gnu.org; Fri, 03 Mar 2017 13:55:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cjsMW-0007RB-JV for emacs-orgmode@gnu.org; Fri, 03 Mar 2017 13:55:40 -0500 Received: from mail-yw0-x22e.google.com ([2607:f8b0:4002:c05::22e]:36490) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cjsMW-0007QT-88 for emacs-orgmode@gnu.org; Fri, 03 Mar 2017 13:55:32 -0500 Received: by mail-yw0-x22e.google.com with SMTP id o4so25059817ywd.3 for ; Fri, 03 Mar 2017 10:55:30 -0800 (PST) In-Reply-To: <878ton9zor.fsf@nicolasgoaziou.fr> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: Nicolas Goaziou Cc: emacs-orgmode@gnu.org --001a113f1a7ed4337e0549d81676 Content-Type: text/plain; charset=UTF-8 This used to work though, before the update. Here is an "ECM" consisting of test.org, 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) (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) ;;(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t) (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 "") 'org-agenda) (global-set-key (kbd "") 'bh/org-todo) (global-set-key (kbd "") 'bh/widen) (global-set-key (kbd "") 'org-cycle-agenda-files) (global-set-key (kbd " c") 'calendar) (global-set-key (kbd " I") 'bh/punch-in) (global-set-key (kbd " O") 'bh/punch-out) (global-set-key (kbd " m") 'bh/clock-in-email-task) (global-set-key (kbd " o") 'bh/clock-in-organization-task) (global-set-key (kbd " r") 'bh/clock-in-journal-review-task) (global-set-key (kbd " q") 'boxquote-region) (global-set-key (kbd " s") 'bh/switch-to-scratch) (global-set-key (kbd " SPC") 'bh/clock-in-last-task) (global-set-key (kbd "C-") 'previous-buffer) (global-set-key (kbd "") 'hist-org-clock-in-select) (global-set-key (kbd "") 'org-clock-goto) (global-set-key (kbd "C-") '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 "") '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 "") '(lambda () (interactive) (bookmark-set "SAVED"))) (global-set-key (kbd "") '(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. ) On Thu, Mar 2, 2017 at 12:44 PM, Nicolas Goaziou wrote: > Hello, > > Markus Heller writes: > > > I just updated emacs to GNU Emacs 25.1.1 (x86_64-w64-mingw32) of > 2016-09-21 > > and orgmode to Org mode version 9.0.5 (9.0.5-elpa @ > > c:/Users/mheller/AppData/Roaming/.emacs.d/elpa/org-20170210/). > > > > I've been using Bernt Hansen's clock setup for over a year now, without > > issues. I realize that this is not readily reproduced, but I'm hoping > that > > somebody will be able to spot what's going on based on experience. So, > > now, after this update, punching in after starting emacs results in an > > error: > > > > org-back-to-heading: Before first headline at position 1121 in buffer > > *Messages* > > > > Debugger: > > > > Debugger entered--Lisp error: (error "Before first headline at position > 71 > > in buffer *GNU Emacs*") > > You are trying to clock in from *GNU Emacs* buffer, which is not in Org > mode. Could you send an ECM for that? > > Regards, > > -- > Nicolas Goaziou > --001a113f1a7ed4337e0549d81676 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
This used to work though, before the update.=C2=A0 Here is= an "ECM" consisting of test.org,= a minimal agenda file, and a .emacs, which I have strip off everything exc= ept org-mode related code including Bernt's clock set up.=C2=A0 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.

<test.org>
#+STARTU= P: content
#+STARTUP: hidestars
#+STARTUP: indent
=

Organization
:PROPERTIES:
:ID: =C2= =A0 =C2=A0 =C2=A0 kth92m81qwe0
:END:

<.emacs>
;; set up ELPA
(require 'package)
(add-to-li= st 'package-archives '("org" . "http://orgmode.org/elpa/") t)
;;(add-to= -list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
=
(package-initialize)

;;
;= ; Org Mode
;;

;; save all org buffers at= 1 minute before the hour
(run-at-time "00:59" 3600 = 9;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
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda nil (setq fill-column 72) (flyspell-mod= e 1))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 turn-on-auto-fill)))
=
;; Standard Key Bindings
(global-set-key "\C-= cl" 'org-store-link)
(global-set-key "\C-ca" &= #39;org-agenda)
(global-set-key "\C-cb" 'org-iswitc= hb)

;; 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 (kb= d "<S-f5>") 'bh/widen)
(global-set-key (kbd &= quot;<f8>") 'org-cycle-agenda-files)
(global-set-k= ey (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)
(glo= bal-set-key (kbd "<f9> o") 'bh/clock-in-organization-ta= sk)
(global-set-key (kbd "<f9> r") 'bh/clock-= in-journal-review-task)
(global-set-key (kbd "<f9> q&q= uot;) 'boxquote-region)
(global-set-key (kbd "<f9>= s") 'bh/switch-to-scratch)
(global-set-key (kbd "&= lt;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)
<= div>(global-set-key (kbd "C-c c") 'org-capture)
;; Functions for Custom Key Bindings
(defun bh/switch= -to-scratch ()
=C2=A0 (interactive)
=C2=A0 (switch-to-b= uffer "*scratch*"))

(defun bh/org-todo (= arg)
=C2=A0 (interactive "p")
=C2=A0 (if (equ= al arg 4)
=C2=A0 =C2=A0 =C2=A0 (save-restriction
=C2=A0= =C2=A0 =C2=A0 =C2=A0 (bh/narrow-to-org-subtree)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (org-show-todo-tree nil))
=C2=A0 =C2=A0 (bh/narrow-= to-org-subtree)
=C2=A0 =C2=A0 (org-show-todo-tree nil)))

(global-set-key (kbd "<S-f5>") 'bh/wid= en)

(defun bh/widen ()
=C2=A0 (interacti= ve)
=C2=A0 (if (equal major-mode 'org-agenda-mode)
= =C2=A0 =C2=A0 =C2=A0 (progn
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agen= da-remove-restriction-lock)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when org= -agenda-sticky
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-red= o)))
=C2=A0 =C2=A0 (widen)))

(add-hook &= #39;org-agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '= (lambda () (org-defkey org-agenda-mode-map "W" (lambda () (intera= ctive) (setq bh/hide-scheduled-and-waiting-next-tasks t) (bh/widen))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append)

<= div>(defun bh/restrict-to-file-or-follow (arg)
=C2=A0 "Set a= genda restriction to 'file or with argument invoke follow mode.
I don't use follow mode very often but I restrict to file all the ti= me
so change the default 'F' binding in the agenda to all= ow both"
=C2=A0 (interactive "p")
=C2=A0= (if (equal arg 4)
=C2=A0 =C2=A0 =C2=A0 (org-agenda-follow-mode)<= /div>
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 (bh/set-agenda-rest= riction-lock 4)
=C2=A0 =C2=A0 (org-agenda-redo)
=C2=A0 = =C2=A0 (beginning-of-buffer)))

(add-hook 'org-= agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda = () (org-defkey org-agenda-mode-map "F" 'bh/restrict-to-file-o= r-follow))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append)
<= div>
(defun bh/narrow-to-org-subtree ()
=C2=A0 (wid= en)
=C2=A0 (org-narrow-to-subtree)
=C2=A0 (save-restric= tion
=C2=A0 =C2=A0 (org-agenda-set-restriction-lock)))
=
(defun bh/narrow-to-subtree ()
=C2=A0 (interactive= )
=C2=A0 (if (equal major-mode 'org-agenda-mode)
= =C2=A0 =C2=A0 =C2=A0 (progn
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with= -point-at (org-get-at-bol 'org-hd-marker)
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 (bh/narrow-to-org-subtree))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 (when org-agenda-sticky
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (org-agenda-redo)))
=C2=A0 =C2=A0 (bh/narrow-to-org-subtre= e)))

(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-agenda-= mode-map "N" 'bh/narrow-to-subtree))
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 'append)

(defun bh/narrow= -up-one-org-level ()
=C2=A0 (widen)
=C2=A0 (save-excurs= ion
=C2=A0 =C2=A0 (outline-up-heading 1 'invisible-ok)
<= div>=C2=A0 =C2=A0 (bh/narrow-to-org-subtree)))

(de= fun bh/get-pom-from-agenda-restriction-or-point ()
=C2=A0 (or (an= d (marker-position org-agenda-restrict-begin) org-agenda-restrict-begin)
=C2=A0 =C2=A0 =C2=A0 (org-get-at-bol 'org-hd-marker)
= =C2=A0 =C2=A0 =C2=A0 (and (equal major-mode 'org-mode) (point))
=C2=A0 =C2=A0 =C2=A0 org-clock-marker))

(defun = bh/narrow-up-one-level ()
=C2=A0 (interactive)
=C2=A0 (= if (equal major-mode 'org-agenda-mode)
=C2=A0 =C2=A0 =C2=A0 (= progn
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with-point-at (bh/get-pom-= from-agenda-restriction-or-point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (bh/narrow-up-one-org-level))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (or= g-agenda-redo))
=C2=A0 =C2=A0 (bh/narrow-up-one-org-level)))

(add-hook 'org-agenda-mode-hook
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-agenda-mode-map= "U" 'bh/narrow-up-one-level))
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 'append)

(defun bh/narrow-to-or= g-project ()
=C2=A0 (widen)
=C2=A0 (save-excursion
=C2=A0 =C2=A0 (bh/find-project-task)
=C2=A0 =C2=A0 (bh/narr= ow-to-org-subtree)))

(defun bh/narrow-to-project (= )
=C2=A0 (interactive)
=C2=A0 (if (equal major-mode = 9;org-agenda-mode)
=C2=A0 =C2=A0 =C2=A0 (progn
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 (org-with-point-at (bh/get-pom-from-agenda-restriction= -or-point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/narrow-to-org-p= roject)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (save-excursion
<= div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/find-project-task)
<= div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-set-restriction-l= ock)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-redo)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 (beginning-of-buffer))
=C2=A0 =C2=A0 = (bh/narrow-to-org-project)
=C2=A0 =C2=A0 (save-restriction
<= div>=C2=A0 =C2=A0 =C2=A0 (org-agenda-set-restriction-lock))))
(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-agenda-mode-map "P&q= uot; 'bh/narrow-to-project))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 'append)

(defvar bh/project-list nil)

(defun bh/view-next-project ()
=C2=A0 (inter= active)
=C2=A0 (let (num-project-left current-project)
= =C2=A0 =C2=A0 (unless (marker-position org-agenda-restrict-begin)
=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))
=C2=A0 =C2=A0 =C2= =A0 ; Clear all of the existing markers on the list
=C2=A0 =C2=A0= =C2=A0 (while bh/project-list
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (set-m= arker (pop bh/project-list) nil))
=C2=A0 =C2=A0 =C2=A0 (re-search= -forward "Tasks to Refile")
=C2=A0 =C2=A0 =C2=A0 (forwa= rd-visible-line 1))

=C2=A0 =C2=A0 ; Build a new pr= oject marker list
=C2=A0 =C2=A0 (unless bh/project-list
=C2=A0 =C2=A0 =C2=A0 (while (< (point) (point-max))
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 (while (and (< (point) (point-max))
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (or (not= (org-get-at-bol 'org-hd-marker))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with-point-at= (org-get-at-bol 'org-hd-marker)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (or (not (bh= /is-project-p))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/is-project-subt= ree-p)))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (forward-visible-li= ne 1))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (< (point) (point-max= ))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (add-to-list 'bh/projec= t-list (copy-marker (org-get-at-bol 'org-hd-marker)) 'append))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (forward-visible-line 1)))

=
=C2=A0 =C2=A0 ; Pop off the first marker on the list and display=
=C2=A0 =C2=A0 (setq current-project (pop bh/project-list))
=
=C2=A0 =C2=A0 (when current-project
=C2=A0 =C2=A0 =C2=A0 (or= g-with-point-at current-project
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq= bh/hide-scheduled-and-waiting-next-tasks nil)
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 (bh/narrow-to-project))
=C2=A0 =C2=A0 =C2=A0 ; Remove = the marker
=C2=A0 =C2=A0 =C2=A0 (setq current-project nil)
<= div>=C2=A0 =C2=A0 =C2=A0 (org-agenda-redo)
=C2=A0 =C2=A0 =C2=A0 (= beginning-of-buffer)
=C2=A0 =C2=A0 =C2=A0 (setq num-projects-left= (length bh/project-list))
=C2=A0 =C2=A0 =C2=A0 (if (> num-pro= jects-left 0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (message "%= s projects left to view" num-projects-left)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (beginning-of-buffer)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (= setq bh/hide-scheduled-and-waiting-next-tasks t)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (error "All projects viewed.")))))

(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 '(lambda () (org-defkey org-agenda-mode-map "V"= ; 'bh/view-next-project))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = 'append)

(setq org-show-entry-below (quote ((d= efault))))

;; TODO keyword sequences
(se= tq org-todo-keywords
=C2=A0 =C2=A0 =C2=A0 (quote ((sequence "= ;TODO(t)" "NEXT(n)" "|" "DONE(d)")
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (sequence "WAITI= NG(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)&q= uot; "PHONE" "MEETING"))))

;; = TODO state triggers and tags
(setq org-todo-state-tags-triggers
=C2=A0 =C2=A0 =C2=A0 (quote (("CANCELLED" ("CANCELL= ED" . t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= "WAITING" ("WAITING" . t))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ("HOLD" ("WAITING") (&q= uot;HOLD" . t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (done ("WAITING") ("HOLD"))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ("TODO" ("WAITING&quo= t;) ("CANCELLED") ("HOLD"))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ("NEXT" ("WAITING") (&q= uot;CANCELLED") ("HOLD"))
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 ("DONE" ("WAITING") ("CAN= CELLED") ("HOLD")))))

;; Custom age= nda command definitions
(defvar bh/hide-scheduled-and-waiting-nex= t-tasks t)

(defun bh/org-auto-exclude-function (ta= g)
=C2=A0 "Automatic task exclusion in the agenda with / RET= "
=C2=A0 (and (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ((= string=3D tag "hold")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(concat "-" tag)))

(setq org-agenda-auto-exclude-function 'bh/org-a= uto-exclude-function)

;; clock setup
;; = Resume clocking task when emacs is restarted
(org-clock-persisten= ce-insinuate)
;;
;; Show lot of clocking history so it&= #39;s easy to pick items off the C-F11 list
(setq org-clock-histo= ry-length 23)
;; Resume clocking task on clock-in if the clock is= open
(setq org-clock-in-resume t)
;; Change tasks to N= EXT when clocking in
(setq org-clock-in-switch-to-state 'bh/c= lock-in-to-next)
;; Separate drawers for clocking and logs
<= div>(setq org-drawers (quote ("PROPERTIES" "LOGBOOK")))=
;; Save clock data and state changes and notes in the LOGBOOK dr= awer
(setq org-clock-into-drawer t)
;; Sometimes I chan= ge tasks I'm clocking quickly - this removes clocked tasks with 0:00 du= ration
(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 fi= nding open clocks
(setq org-clock-auto-clock-resolution (quote wh= en-no-clock-is-running))
;; Include current clocking task in cloc= k reports
(setq org-clock-report-include-clocking-task t)

(setq bh/keep-clock-running nil)

(defun bh/clock-in-to-next (kw)
=C2=A0 "Switch a task from = TODO to NEXT when clocking in.
Skips capture tasks, projects, and= subprojects.
Switch projects and subprojects from NEXT back to T= ODO"
=C2=A0 (when (not (and (boundp 'org-capture-mode) o= rg-capture-mode))
=C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2= =A0((and (member (org-get-todo-state) (list "TODO"))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(bh/is-task-p))
=C2=A0 = =C2=A0 =C2=A0 "NEXT")
=C2=A0 =C2=A0 =C2=A0((and (member= (org-get-todo-state) (list "NEXT"))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(bh/is-project-p))
=C2=A0 =C2=A0 =C2=A0 &= quot;TODO"))))

(defun bh/find-project-task ()=
=C2=A0 "Move point to the parent (project) task if any"= ;
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (widen)
<= div>=C2=A0 =C2=A0 (let ((parent-task (save-excursion (org-back-to-heading &= #39;invisible-ok) (point))))
=C2=A0 =C2=A0 =C2=A0 (while (org-up-= heading-safe)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (member (nth 2 (o= rg-heading-components)) org-todo-keywords-1)
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 (setq parent-task (point))))
=C2=A0 =C2=A0 =C2=A0 = (goto-char parent-task)
=C2=A0 =C2=A0 =C2=A0 parent-task)))
=

(defun bh/punch-in (arg)
=C2=A0 "Start c= ontinuous clocking and set the default task to the
selected task.= =C2=A0 If no task is selected set the Organization task
as the de= fault task."
=C2=A0 (interactive "p")
= =C2=A0 (setq bh/keep-clock-running t)
=C2=A0 (if (equal major-mod= e 'org-agenda-mode)
=C2=A0 =C2=A0 =C2=A0 ;;
=C2=A0 = =C2=A0 =C2=A0 ;; We're in the agenda
=C2=A0 =C2=A0 =C2=A0 ;;<= /div>
=C2=A0 =C2=A0 =C2=A0 (let* ((marker (org-get-at-bol 'org-hd-m= arker))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(tags (or= g-with-point-at marker (org-get-tags-at))))
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 (if (and (eq arg 4) tags)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (org-agenda-clock-in '(16))
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (bh/clock-in-organization-task-as-default)))
=C2=A0= =C2=A0 ;;
=C2=A0 =C2=A0 ;; We are not in the agenda
= =C2=A0 =C2=A0 ;;
=C2=A0 =C2=A0 (save-restriction
=C2=A0= =C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 =C2=A0 ; Find the tags on th= e current task
=C2=A0 =C2=A0 =C2=A0 (if (and (equal major-mode &#= 39;org-mode) (not (org-before-first-heading-p)) (eq arg 4))
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-clock-in '(16))
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 (bh/clock-in-organization-task-as-default)))))

(defun bh/punch-out ()
=C2=A0 (interactive)
=C2=A0 (setq bh/keep-clock-running nil)
=C2=A0 (when (org-= clock-is-active)
=C2=A0 =C2=A0 (org-clock-out))
=C2=A0 = (org-agenda-remove-restriction-lock))

(defun bh/cl= ock-in-default-task ()
=C2=A0 (save-excursion
=C2=A0 = =C2=A0 (org-with-point-at org-clock-default-task
=C2=A0 =C2=A0 = =C2=A0 (org-clock-in))))

(defun bh/clock-in-parent= -task ()
=C2=A0 "Move point to the parent (project) task if = any and clock in"
=C2=A0 (let ((parent-task))
=C2= =A0 =C2=A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0 (save-restriction=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 (while (and (not parent-task) (org-up-heading-safe))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (member (nth 2 (org-heading-compon= ents)) org-todo-keywords-1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (setq parent-task (point))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (= if parent-task
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-wit= h-point-at parent-task
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (org-clock-in))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when b= h/keep-clock-running
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (b= h/clock-in-default-task)))))))

;;(defvar bh/organi= zation-task-id "eb155a82-92b2-4f25-a3c6-0304591af2f9")
= (defvar bh/organization-task-id "kth92m81qwe0")

(defun bh/clock-in-organization-task-as-default ()
=C2=A0= (interactive)
=C2=A0 (org-with-point-at (org-id-find bh/organiza= tion-task-id 'marker)
=C2=A0 =C2=A0 (org-clock-in '(16)))= )

(defun bh/clock-out-maybe ()
=C2=A0 (w= hen (and bh/keep-clock-running
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(not org-clock-clocking-in)
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(marker-buffer org-clock-default-task)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(not org-clock-resolving-c= locks-due-to-idleness))
=C2=A0 =C2=A0 (bh/clock-in-parent-task)))=

(add-hook 'org-clock-out-hook 'bh/clock-o= ut-maybe 'append)

(require 'org-id)
<= div>(defun bh/clock-in-task-by-id (id)
=C2=A0 "Clock in a ta= sk by id"
=C2=A0 (org-with-point-at (org-id-find id 'mar= ker)
=C2=A0 =C2=A0 (org-clock-in nil)))

= (defun bh/clock-in-last-task (arg)
=C2=A0 "Clock in the inte= rrupted task if there is one
Skip the default task and get the ne= xt one.
A prefix arg forces clock in of the default task."
=C2=A0 (interactive "p")
=C2=A0 (let ((clock-i= n-to-task
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cond
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((eq arg 4) org-clock-default-task)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((and (org-clock-is-active)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (equal org-clock-d= efault-task (cadr org-clock-history)))
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(caddr org-clock-history))
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 ((org-clock-is-active) (cadr org-clock-history))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((equal org-clock-default-task (car org-= clock-history)) (cadr org-clock-history))
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (t (car org-clock-history)))))
=C2=A0 =C2=A0 (widen= )
=C2=A0 =C2=A0 (org-with-point-at clock-in-to-task
=C2= =A0 =C2=A0 =C2=A0 (org-clock-in nil))))

;; Sometim= es I change tasks I'm clocking quickly - this removes clocked tasks wit= h 0:00 duration
(setq org-clock-out-remove-zero-time-clocks t)

;; Agenda clock report parameters
(setq or= g-agenda-clockreport-parameter-plist
=C2=A0 =C2=A0 =C2=A0 (quote = (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80)))

;; Agenda views helper functions
(defun bh/is-project-p = ()
=C2=A0 "Any task with a todo keyword subtask"
<= div>=C2=A0 (save-restriction
=C2=A0 =C2=A0 (widen)
=C2= =A0 =C2=A0 (let ((has-subtask)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (subtree-end (save-excursion (org-end-of-subtree t)))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (is-a-task (member (nth 2 (org-heading-components)= ) org-todo-keywords-1)))
=C2=A0 =C2=A0 =C2=A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (forward-line 1)
=C2=A0 =C2=A0= =C2=A0 =C2=A0 (while (and (not has-subtask)
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (< (point) subtree-end= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (re-search-forward "^\*+ " subtree-end t))
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (member (org-get-todo-state) org-todo= -keywords-1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq has-= subtask t))))
=C2=A0 =C2=A0 =C2=A0 (and is-a-task has-subtask))))=

(defun bh/is-project-subtree-p ()
=C2= =A0 "Any task with a todo keyword that is in a project subtree.
<= div>Callers of this function already widen the buffer view."
=C2=A0 (let ((task (save-excursion (org-back-to-heading 'invisible-ok)=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (point))))
=C2=A0 =C2= =A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0 (bh/find-project-task)
=C2=A0 =C2=A0 =C2=A0 (if (equal (point) task)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 nil
=C2=A0 =C2=A0 =C2=A0 =C2=A0 t))))

(defun bh/is-task-p ()
=C2=A0 "Any ta= sk with a todo keyword and no subtask"
=C2=A0 (save-restrict= ion
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 (let ((has-subt= ask)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (subtree-end (save-excurs= ion (org-end-of-subtree t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
=C2=A0 =C2=A0 =C2=A0 (save-excursion
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 (forward-line 1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (while (a= nd (not has-subtask)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (< (point) subtree-end)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (re-search-forw= ard "^\*+ " subtree-end t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 (when (member (org-get-todo-state) org-todo-keywords-1)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq has-subtask t))))
=C2=A0 =C2=A0 =C2=A0 (and is-a-task (not has-subtask)))))

(defun bh/is-subproject-p ()
=C2=A0 "Any task which= is a subtask of another project"
=C2=A0 (let ((is-subprojec= t)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (is-a-task (member (nth 2 (org-hea= ding-components)) org-todo-keywords-1)))
=C2=A0 =C2=A0 (save-excu= rsion
=C2=A0 =C2=A0 =C2=A0 (while (and (not is-subproject) (org-u= p-heading-safe))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (member (nth 2= (org-heading-components)) org-todo-keywords-1)
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 (setq is-subproject t))))
=C2=A0 =C2=A0 (and is= -a-task is-subproject)))

(defun bh/list-sublevels-= for-projects-indented ()
=C2=A0 "Set org-tags-match-list-sub= levels so when restricted to a subtree we list all subtasks.
=C2= =A0 This is normally used by skipping functions where this variable is alre= ady local to the agenda."
=C2=A0 (if (marker-buffer org-agen= da-restrict-begin)
=C2=A0 =C2=A0 =C2=A0 (setq org-tags-match-list= -sublevels 'indented)
=C2=A0 =C2=A0 (setq org-tags-match-list= -sublevels nil))
=C2=A0 nil)

(defun bh/l= ist-sublevels-for-projects ()
=C2=A0 "Set org-tags-match-lis= t-sublevels so when restricted to a subtree we list all subtasks.
=C2=A0 This is normally used by skipping functions where this variable is = already local to the agenda."
=C2=A0 (if (marker-buffer org-= agenda-restrict-begin)
=C2=A0 =C2=A0 =C2=A0 (setq org-tags-match-= list-sublevels t)
=C2=A0 =C2=A0 (setq org-tags-match-list-subleve= ls nil))
=C2=A0 nil)

;;(defvar bh/hide-s= cheduled-and-waiting-next-tasks t)

(defun bh/toggl= e-next-task-display ()
=C2=A0 (interactive)
=C2=A0 (set= q bh/hide-scheduled-and-waiting-next-tasks (not bh/hide-scheduled-and-waiti= ng-next-tasks))
=C2=A0 (when =C2=A0(equal major-mode 'org-age= nda-mode)
=C2=A0 =C2=A0 (org-agenda-redo))
=C2=A0 (mess= age "%s WAITING and SCHEDULED NEXT Tasks" (if bh/hide-scheduled-a= nd-waiting-next-tasks "Hide" "Show")))

(defun bh/skip-stuck-projects ()
=C2=A0 "Skip trees= that are not stuck projects"
=C2=A0 (save-restriction
=
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 (let ((next-headline (sa= ve-excursion (or (outline-next-heading) (point-max)))))
=C2=A0 = =C2=A0 =C2=A0 (if (bh/is-project-p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(has-next = ))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (forward-line 1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (while (and (not ha= s-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT &quo= t; subtree-end t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (unless (member "WAITING" (org-get-tags-at))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq has-n= ext t))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if has-next<= /div>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 next-headline)) ; a s= tuck project, has subtasks but no next task
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 nil))))

(defun bh/skip-non-stuck-projects (= )
=C2=A0 "Skip trees that are not stuck projects"
=
=C2=A0 ;; (bh/list-sublevels-for-projects-indented)
=C2=A0 (= save-restriction
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 (l= et ((next-headline (save-excursion (or (outline-next-heading) (point-max)))= ))
=C2=A0 =C2=A0 =C2=A0 (if (bh/is-project-p)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((subtree-end (save-excursion (org-end-of= -subtree t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(has-next ))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (forward-line 1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (while (and (not has-next) (< (point) subtree-end) (re-search-for= ward "^\\*+ NEXT " subtree-end t))
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (unless (member "WAITING" (or= g-get-tags-at))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (setq has-next t))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (if has-next
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 next-headline
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 nil)) ; a stuck project, has subtasks but no next task
=C2=A0 =C2=A0 =C2=A0 =C2=A0 next-headline))))

<= div>(defun bh/skip-non-projects ()
=C2=A0 "Skip trees that a= re not projects"
=C2=A0 ;; (bh/list-sublevels-for-projects-i= ndented)
=C2=A0 (if (save-excursion (bh/skip-non-stuck-projects))=
=C2=A0 =C2=A0 =C2=A0 (save-restriction
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((subtree-= end (save-excursion (org-end-of-subtree t))))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= ((bh/is-project-p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil)=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((and (bh/is-project-su= btree-p) (not (bh/is-task-p)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 nil)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(t
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree-end))))
=C2= =A0 =C2=A0 (save-excursion (org-end-of-subtree t))))

(defun bh/skip-non-tasks ()
=C2=A0 "Show non-project task= s.
Skip project and sub-project tasks, habits, and project relate= d tasks."
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (= widen)
=C2=A0 =C2=A0 (let ((next-headline (save-excursion (or (ou= tline-next-heading) (point-max)))))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0((bh/is-task-p)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 nil)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(t
=C2=A0= =C2=A0 =C2=A0 =C2=A0 next-headline)))))

(defun bh= /skip-project-trees-and-habits ()
=C2=A0 "Skip trees that ar= e projects"
=C2=A0 (save-restriction
=C2=A0 =C2=A0= (widen)
=C2=A0 =C2=A0 (let ((subtree-end (save-excursion (org-en= d-of-subtree t))))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 = =C2=A0 =C2=A0 =C2=A0((bh/is-project-p)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 subtree-end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(t
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 nil)))))

(defun bh/skip-proje= cts-and-habits-and-single-tasks ()
=C2=A0 "Skip trees that a= re projects, tasks that are habits, single non-project tasks"
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (widen)
=C2=A0= =C2=A0 (let ((next-headline (save-excursion (or (outline-next-heading) (po= int-max)))))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 = =C2=A0 =C2=A0((and bh/hide-scheduled-and-waiting-next-tasks
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(member "WAITING" (o= rg-get-tags-at)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 next-headline)
=C2=A0 =C2=A0 =C2=A0 =C2=A0((bh/is-project-p)
=C2=A0 =C2=A0= =C2=A0 =C2=A0 next-headline)
=C2=A0 =C2=A0 =C2=A0 =C2=A0((and (b= h/is-task-p) (not (bh/is-project-subtree-p)))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 next-headline)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(t
=C2=A0 =C2=A0 =C2=A0 =C2=A0 nil)))))

(defun bh/sk= ip-project-tasks-maybe ()
=C2=A0 "Show tasks related to the = current restriction.
When restricted to a project, skip project a= nd sub project tasks, habits, NEXT tasks, and loose tasks.
When n= ot restricted, skip project and sub-project tasks, habits, and project rela= ted tasks."
=C2=A0 (save-restriction
=C2=A0 =C2=A0= (widen)
=C2=A0 =C2=A0 (let* ((subtree-end (save-excursion (org-e= nd-of-subtree t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(next= -headline (save-excursion (or (outline-next-heading) (point-max))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(limit-to-project (marker-buffe= r org-agenda-restrict-begin)))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0((bh/is-project-p)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 next-headline)
=C2=A0 =C2=A0 =C2=A0 =C2=A0((and (no= t limit-to-project)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0(bh/is-project-subtree-p))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree= -end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0((and limit-to-project
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(bh/is-project-subtree-p)<= /div>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(member (org-get-= todo-state) (list "NEXT")))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= subtree-end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(t
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 nil)))))

(defun bh/skip-project-= tasks ()
=C2=A0 "Show non-project tasks.
Skip proj= ect and sub-project tasks, habits, and project related tasks."
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (widen)
=C2= =A0 =C2=A0 (let* ((subtree-end (save-excursion (org-end-of-subtree t))))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0((b= h/is-project-p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree-end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0((bh/is-project-subtree-p)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 subtree-end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0(t
=C2=A0 =C2=A0 =C2=A0 =C2=A0 nil)))))

(def= un bh/skip-non-project-tasks ()
=C2=A0 "Show project tasks.<= /div>
Skip project and sub-project tasks, habits, and loose non-project= tasks."
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (w= iden)
=C2=A0 =C2=A0 (let* ((subtree-end (save-excursion (org-end-= of-subtree t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(next-he= adline (save-excursion (or (outline-next-heading) (point-max)))))
=C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0((bh/is-pr= oject-p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 next-headline)
=C2= =A0 =C2=A0 =C2=A0 =C2=A0((and (bh/is-project-subtree-p)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(member (org-get-todo-state) (list= "NEXT")))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree-end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0((not (bh/is-project-subtree-p))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree-end)
=C2=A0 =C2=A0 =C2=A0 = =C2=A0(t
=C2=A0 =C2=A0 =C2=A0 =C2=A0 nil)))))

(defun bh/skip-projects-and-habits ()
=C2=A0 "Skip tre= es that are projects and tasks that are habits"
=C2=A0 (save= -restriction
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 (let (= (subtree-end (save-excursion (org-end-of-subtree t))))
=C2=A0 =C2= =A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0((bh/is-project-p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree-end)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0(t
=C2=A0 =C2=A0 =C2=A0 =C2=A0 nil)))))
(defun bh/skip-non-subprojects ()
=C2=A0 "Skip = trees that are not projects"
=C2=A0 (let ((next-headline (sa= ve-excursion (outline-next-heading))))
=C2=A0 =C2=A0 (if (bh/is-s= ubproject-p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 nil
=C2=A0 =C2= =A0 =C2=A0 next-headline)))

;; Archive setup
=
(setq org-archive-mark-done nil)
(setq org-archive-location = "%s_archive::* Archived Tasks")

(defun b= h/skip-non-archivable-tasks ()
=C2=A0 "Skip trees that are n= ot available for archiving"
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 ;; Consider only tasks wit= h done todo headings as archivable candidates
=C2=A0 =C2=A0 (let = ((next-headline (save-excursion (or (outline-next-heading) (point-max))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (subtree-end (save-excursion (o= rg-end-of-subtree t))))
=C2=A0 =C2=A0 =C2=A0 (if (member (org-get= -todo-state) org-todo-keywords-1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (if (member (org-get-todo-state) org-done-keywords)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let* ((daynr (string-to-int (for= mat-time-string "%d" (current-time))))
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(a-month-ago = (* 60 60 24 (+ daynr 1)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(last-month (format-time-string "= ;%Y-%m-" (time-subtract (current-time) (seconds-to-time a-month-ago)))= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(this-month (format-time-string "%Y-%m-" (current-ti= me)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(subtree-is-current (save-excursion
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(forwa= rd-line 1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(and (< (point) subtree-end)
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (re-search-forward (concat last-month "\\|" this-mo= nth) subtree-end t)))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 (if subtree-is-current
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 subtree-end ; Has a date in this= month or last month, skip it
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 nil)) =C2=A0; available to archive
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (or subtree-end (point-max)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 next-headline))))

;; Helper Functions
;; narrowing to a subtree
(defun= bh/org-todo (arg)
=C2=A0 (interactive "p")
= =C2=A0 (if (equal arg 4)
=C2=A0 =C2=A0 =C2=A0 (save-restriction
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/narrow-to-org-subtree)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-show-todo-tree nil))
=C2=A0 =C2= =A0 (bh/narrow-to-org-subtree)
=C2=A0 =C2=A0 (org-show-todo-tree = nil)))

;; widen
(defun bh/widen ()
=
=C2=A0 (interactive)
=C2=A0 (if (equal major-mode 'org-a= genda-mode)
=C2=A0 =C2=A0 =C2=A0 (progn
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (org-agenda-remove-restriction-lock)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (when org-agenda-sticky
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 (org-agenda-redo)))
=C2=A0 =C2=A0 (widen)))
(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-agenda-mode-map "W&q= uot; (lambda () (interactive) (setq bh/hide-scheduled-and-waiting-next-task= s t) (bh/widen))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append= )

(defun bh/restrict-to-file-or-follow (arg)
=
=C2=A0 "Set agenda restriction to 'file or with argument invo= ke follow mode.
I don't use follow mode very often but I rest= rict to file all the time
so change the default 'F' bindi= ng in the agenda to allow both"
=C2=A0 (interactive "p&= quot;)
=C2=A0 (if (equal arg 4)
=C2=A0 =C2=A0 =C2=A0 (o= rg-agenda-follow-mode)
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2= =A0 (bh/set-agenda-restriction-lock 4)
=C2=A0 =C2=A0 (org-agenda-= redo)
=C2=A0 =C2=A0 (beginning-of-buffer)))

<= div>(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 '(lambda () (org-defkey org-agenda-mode-map "F" &#= 39;bh/restrict-to-file-or-follow))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 'append)

(defun bh/narrow-to-org-subtre= e ()
=C2=A0 (widen)
=C2=A0 (org-narrow-to-subtree)
=C2=A0 (save-restriction
=C2=A0 =C2=A0 (org-agenda-set-rest= riction-lock)))

(defun bh/narrow-to-subtree ()
=C2=A0 (interactive)
=C2=A0 (if (equal major-mode 'org= -agenda-mode)
=C2=A0 =C2=A0 =C2=A0 (progn
=C2=A0 =C2=A0= =C2=A0 =C2=A0 (org-with-point-at (org-get-at-bol 'org-hd-marker)
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/narrow-to-org-subtree))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when org-agenda-sticky
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-redo)))
=C2=A0 =C2=A0 (bh/na= rrow-to-org-subtree)))

(add-hook 'org-agenda-m= ode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-= defkey org-agenda-mode-map "N" 'bh/narrow-to-subtree))
<= div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append)

(defun bh/narrow-up-one-org-level ()
=C2=A0 (widen)
= =C2=A0 (save-excursion
=C2=A0 =C2=A0 (outline-up-heading 1 'i= nvisible-ok)
=C2=A0 =C2=A0 (bh/narrow-to-org-subtree)))

(defun bh/get-pom-from-agenda-restriction-or-point ()
=
=C2=A0 (or (and (marker-position org-agenda-restrict-begin) org-agenda= -restrict-begin)
=C2=A0 =C2=A0 =C2=A0 (org-get-at-bol 'org-hd= -marker)
=C2=A0 =C2=A0 =C2=A0 (and (equal major-mode 'org-mod= e) (point))
=C2=A0 =C2=A0 =C2=A0 org-clock-marker))
(defun bh/narrow-up-one-level ()
=C2=A0 (interactive)=
=C2=A0 (if (equal major-mode 'org-agenda-mode)
=C2= =A0 =C2=A0 =C2=A0 (progn
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with-po= int-at (bh/get-pom-from-agenda-restriction-or-point)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 (bh/narrow-up-one-org-level))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 (org-agenda-redo))
=C2=A0 =C2=A0 (bh/narrow-up-= one-org-level)))

(add-hook 'org-agenda-mode-ho= ok
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-defkey= org-agenda-mode-map "U" 'bh/narrow-up-one-level))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append)

(d= efun bh/narrow-to-org-project ()
=C2=A0 (widen)
=C2=A0 = (save-excursion
=C2=A0 =C2=A0 (bh/find-project-task)
= =C2=A0 =C2=A0 (bh/narrow-to-org-subtree)))

(defun = bh/narrow-to-project ()
=C2=A0 (interactive)
=C2=A0 (if= (equal major-mode 'org-agenda-mode)
=C2=A0 =C2=A0 =C2=A0 (pr= ogn
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with-point-at (bh/get-pom-fr= om-agenda-restriction-or-point)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (bh/narrow-to-org-project)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (save-excursion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/fi= nd-project-task)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-a= genda-set-restriction-lock)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-ag= enda-redo)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (beginning-of-buffer))
=C2=A0 =C2=A0 (bh/narrow-to-org-project)
=C2=A0 =C2=A0 (sa= ve-restriction
=C2=A0 =C2=A0 =C2=A0 (org-agenda-set-restriction-l= ock))))

(add-hook 'org-agenda-mode-hook
<= div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-agen= da-mode-map "P" 'bh/narrow-to-project))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 'append)

(defvar bh/p= roject-list nil)

(defun bh/view-next-project ()
=C2=A0 (interactive)
=C2=A0 (let (num-project-left curren= t-project)
=C2=A0 =C2=A0 (unless (marker-position org-agenda-rest= rict-begin)
=C2=A0 =C2=A0 =C2=A0 (goto-char (point-min))
=C2=A0 =C2=A0 =C2=A0 ; Clear all of the existing markers on the list
=C2=A0 =C2=A0 =C2=A0 (while bh/project-list
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (set-marker (pop bh/project-list) nil))
=C2=A0 =C2= =A0 =C2=A0 (re-search-forward "Tasks to Refile")
=C2=A0= =C2=A0 =C2=A0 (forward-visible-line 1))

=C2=A0 = =C2=A0 ; Build a new project marker list
=C2=A0 =C2=A0 (unless bh= /project-list
=C2=A0 =C2=A0 =C2=A0 (while (< (point) (point-ma= x))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (while (and (< (point) (point-= max))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (or (not (org-get-at-bol 'org-hd-marker))
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (org-with-point-at (org-get-at-bol 'org-hd-marker)
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (or (not (bh/is-project-p))
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (bh/is-project-subtree-p)))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (forward-visible-line 1))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (whe= n (< (point) (point-max))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= add-to-list 'bh/project-list (copy-marker (org-get-at-bol 'org-hd-m= arker)) 'append))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (forward-visibl= e-line 1)))

=C2=A0 =C2=A0 ; Pop off the first mark= er on the list and display
=C2=A0 =C2=A0 (setq current-project (p= op bh/project-list))
=C2=A0 =C2=A0 (when current-project
=C2=A0 =C2=A0 =C2=A0 (org-with-point-at current-project
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 (setq bh/hide-scheduled-and-waiting-next-tasks nil)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (bh/narrow-to-project))
=C2= =A0 =C2=A0 =C2=A0 ; Remove the marker
=C2=A0 =C2=A0 =C2=A0 (setq = current-project nil)
=C2=A0 =C2=A0 =C2=A0 (org-agenda-redo)
=
=C2=A0 =C2=A0 =C2=A0 (beginning-of-buffer)
=C2=A0 =C2=A0 =C2= =A0 (setq num-projects-left (length bh/project-list))
=C2=A0 =C2= =A0 =C2=A0 (if (> num-projects-left 0)
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (message "%s projects left to view" num-projects-le= ft)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (beginning-of-buffer)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq bh/hide-scheduled-and-waiting-next-tasks = t)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (error "All projects viewed.&= quot;)))))

(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-a= genda-mode-map "V" 'bh/view-next-project))
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append)

;; Force-= show next headline
(setq org-show-entry-below (quote ((default)))= )

;; limit agenda to a subtree
(add-hook= 'org-agenda-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = 9;(lambda () (org-defkey org-agenda-mode-map "\C-c\C-x<" '= bh/set-agenda-restriction-lock))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 'append)

(defun bh/set-agenda-restriction-= lock (arg)
=C2=A0 "Set restriction lock to current task subt= ree or file if prefix is specified"
=C2=A0 (interactive &quo= t;p")
=C2=A0 (let* ((pom (bh/get-pom-from-agenda-restriction= -or-point))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(tags (org-with-poi= nt-at pom (org-get-tags-at))))
=C2=A0 =C2=A0 (let ((restriction-t= ype (if (equal arg 4) 'file 'subtree)))
=C2=A0 =C2=A0 =C2= =A0 (save-restriction
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((and (equal major-mode 'org-agenda-= mode) pom)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with-point-at = pom
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-set-res= triction-lock restriction-type))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (org-agenda-redo))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((and (e= qual major-mode 'org-mode) (org-before-first-heading-p))
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-set-restriction-lock 'file)= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(pom
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 (org-with-point-at pom
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 (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 list= s
(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 tas= ks with scheduled dates on the global todo lists
(setq org-agenda= -todo-ignore-scheduled nil)

;; Keep tasks with tim= estamps on the global todo lists
(setq org-agenda-todo-ignore-tim= estamp nil)

;; Remove completed deadline tasks fro= m the agenda view
(setq org-agenda-skip-deadline-if-done t)
=

;; Remove completed scheduled tasks from the agenda vie= w
(setq org-agenda-skip-scheduled-if-done t)

=
;; Remove completed items from search results
(setq org-agen= da-skip-timestamp-if-done t)

;; Include agenda arc= hive 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
<= div>(setq org-agenda-repeating-timestamp-show-all t)

;; Show all agenda dates - even if they are empty
(setq org-ag= enda-show-all-dates t)

;; Sorting order for tasks = on the agenda
(setq org-agenda-sorting-strategy
=C2=A0 = =C2=A0 =C2=A0 (quote ((agenda habit-down time-up user-defined-up effort-up = category-keep)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= todo category-up effort-up)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 (tags category-up effort-up)
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 (search category-up))))

;; Start the weekly agenda on Monday
(setq org-agenda-start-on-= weekday 1)

;; Enable display of the time grid so w= e can see the marker for the current time
(setq org-agenda-time-g= rid (quote ((daily today remove-match)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0#("----------------" 0 16 (org-heading= t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(0900 110= 0 1300 1500 1700))))

;; Display tags farther right=
(setq org-agenda-tags-column -102)

;;
;; Agenda sorting functions
;;
(setq org-agend= a-cmp-user-defined 'bh/agenda-sort)

(defun bh/= agenda-sort (a b)
=C2=A0 "Sorting strategy for agenda items.=
Late deadlines first, then scheduled, then non-late deadlines&qu= ot;
=C2=A0 (let (result num-a num-b)
=C2=A0 =C2=A0 (con= d
=C2=A0 =C2=A0 =C2=A0; time specific items are already sorted fi= rst by org-agenda-sorting-strategy

=C2=A0 =C2=A0 = =C2=A0; non-deadline and non-scheduled items next
=C2=A0 =C2=A0 = =C2=A0((bh/agenda-sort-test 'bh/is-not-scheduled-or-deadline a b))

=C2=A0 =C2=A0 =C2=A0; deadlines for today next
=C2=A0 =C2=A0 =C2=A0((bh/agenda-sort-test 'bh/is-due-deadline a b))<= /div>

=C2=A0 =C2=A0 =C2=A0; late deadlines next
=C2=A0 =C2=A0 =C2=A0((bh/agenda-sort-test-num 'bh/is-late-deadline &#= 39;> a b))

=C2=A0 =C2=A0 =C2=A0; scheduled item= s for today next
=C2=A0 =C2=A0 =C2=A0((bh/agenda-sort-test 'b= h/is-scheduled-today a b))

=C2=A0 =C2=A0 =C2=A0; l= ate scheduled items next
=C2=A0 =C2=A0 =C2=A0((bh/agenda-sort-tes= t-num 'bh/is-scheduled-late '> a b))

= =C2=A0 =C2=A0 =C2=A0; pending deadlines last
=C2=A0 =C2=A0 =C2=A0= ((bh/agenda-sort-test-num 'bh/is-pending-deadline '< a b))
=

=C2=A0 =C2=A0 =C2=A0; finally default to unsorted
=
=C2=A0 =C2=A0 =C2=A0(t (setq result nil)))
=C2=A0 =C2=A0 res= ult))

(defmacro bh/agenda-sort-test (fn a b)
=
=C2=A0 "Test for agenda sort"
=C2=A0 `(cond
<= div>=C2=A0 =C2=A0 ; if both match leave them unsorted
=C2=A0 =C2= =A0 ((and (apply ,fn (list ,a))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (apply ,fn (list ,b)))
=C2=A0 =C2=A0 =C2=A0(setq result nil))=
=C2=A0 =C2=A0 ; if a matches put a first
=C2=A0 =C2=A0= ((apply ,fn (list ,a))
=C2=A0 =C2=A0 =C2=A0(setq result -1))
=C2=A0 =C2=A0 ; otherwise if b matches put b first
=C2=A0 = =C2=A0 ((apply ,fn (list ,b))
=C2=A0 =C2=A0 =C2=A0(setq result 1)= )
=C2=A0 =C2=A0 ; if none match leave them unsorted
=C2= =A0 =C2=A0 (t nil)))

(defmacro bh/agenda-sort-test= -num (fn compfn a b)
=C2=A0 `(cond
=C2=A0 =C2=A0 ((appl= y ,fn (list ,a))
=C2=A0 =C2=A0 =C2=A0(setq num-a (string-to-numbe= r (match-string 1 ,a)))
=C2=A0 =C2=A0 =C2=A0(if (apply ,fn (list = ,b))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(progn
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq num-b (string-to-number (match-stri= ng 1 ,b)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq result = (if (apply ,compfn (list num-a num-b))
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -= 1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 1)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0(setq= result -1)))
=C2=A0 =C2=A0 ((apply ,fn (list ,b))
=C2= =A0 =C2=A0 =C2=A0(setq result 1))
=C2=A0 =C2=A0 (t nil)))

(defun bh/is-not-scheduled-or-deadline (date-str)
=C2=A0 (and (not (bh/is-deadline date-str))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0(not (bh/is-scheduled date-str))))

(defu= n bh/is-due-deadline (date-str)
=C2=A0 (string-match "Deadli= ne:" date-str))

(defun bh/is-late-deadline (d= ate-str)
=C2=A0 (string-match "\\([0-9]*\\) d\. ago:" d= ate-str))

(defun bh/is-pending-deadline (date-str)=
=C2=A0 (string-match "In \\([^-]*\\)d\.:" date-str))

(defun bh/is-deadline (date-str)
=C2=A0 (= or (bh/is-due-deadline date-str)
=C2=A0 =C2=A0 =C2=A0 (bh/is-late= -deadline date-str)
=C2=A0 =C2=A0 =C2=A0 (bh/is-pending-deadline = date-str)))

(defun bh/is-scheduled (date-str)
=C2=A0 (or (bh/is-scheduled-today date-str)
=C2=A0 =C2=A0 = =C2=A0 (bh/is-scheduled-late date-str)))

(defun bh= /is-scheduled-today (date-str)
=C2=A0 (string-match "Schedul= ed:" date-str))

(defun bh/is-scheduled-late (= date-str)
=C2=A0 (string-match "Sched\.\\(.*\\)x:" date= -str))

;; Use sticky agenda's so they persist<= /div>
(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-inden= ted t)

;; Handling blank lines
(setq org= -cycle-separator-lines 0)

(setq org-blank-before-n= ew-entry (quote ((heading)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(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 n= il)

;; Searching and showing results
(se= tq 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-adju= sted-subtrees t)

;; Deadlines and Agenda Visibilit= y
(setq org-deadline-warning-days 30)

;;= Logging settings
(setq org-log-done (quote time))
(set= q org-log-into-drawer t)
(setq org-log-state-notes-insert-after-d= rawers nil)

;; Return follows links
(set= q 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 f= ast navigation
(global-set-key (kbd "<C-f6>") = 9;(lambda () (interactive) (bookmark-set "SAVED")))
(gl= obal-set-key (kbd "<f6>") '(lambda () (interactive) (bo= okmark-jump "SAVED")))

;; Cycling plain = lists
(setq org-cycle-include-plain-lists nil)

;; NEXT is for tasks
(defun bh/mark-next-parent-tasks-todo= ()
=C2=A0 "Visit each parent task and change NEXT states to= TODO"
=C2=A0 (let ((mystate (or (and (fboundp 'org-stat= e)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 state)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(nth 2 (org-heading-compone= nts)))))
=C2=A0 =C2=A0 (when mystate
=C2=A0 =C2=A0 =C2= =A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (while (org-up-he= ading-safe)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (member (nth= 2 (org-heading-components)) (list "NEXT"))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-todo "TODO")))))))

(add-hook 'org-after-todo-state-change-hook 'bh/mar= k-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)
<= div>
;; Allow alphabetical list entries
(setq org-a= lphabetical-lists t)

;; Prevent editing invisible = text
(setq org-catch-invisible-edits 'error)

;; Keep clock durations in hours
(setq org-time-clocksum= -format
=C2=A0 =C2=A0 =C2=A0 '(:hours "%d" :require= -hours t :minutes ":%02d" :require-minutes t))


;;;;;;;;;;;;old bindings
(defun bh/clock-in= -email-task ()
=C2=A0 (interactive)
=C2=A0 (bh/clock-in= -task-by-id "gah7sk81qwe0"))

(defun bh/c= lock-in-organization-task ()
=C2=A0 (interactive)
=C2= =A0 (bh/clock-in-task-by-id "kth92m81qwe0"))

=
(defun bh/clock-in-journal-review-task ()
=C2=A0 (interactiv= e)
=C2=A0 (bh/clock-in-task-by-id "tgq4fh776dc2"))

;; Helper functions for projects
(defun bh/i= s-project-p-with-open-subtasks ()
=C2=A0 "Any task with a to= do keyword subtask"
=C2=A0 (let ((has-subtask)
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 (subtree-end (save-excursion (org-end-of-subtree t= ))))
=C2=A0 =C2=A0 (save-excursion
=C2=A0 =C2=A0 =C2=A0= (forward-line 1)
=C2=A0 =C2=A0 =C2=A0 (while (and (not has-subta= sk)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (< (point) subtree-end)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 (re-search-forward "^\*+ " subtree-e= nd t))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (when (and
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(member (org-get-todo-state= ) org-todo-keywords-1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(not (member (org-get-todo-state) org-done-keywords)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (setq has-subtask t))))
=C2= =A0 =C2=A0 has-subtask))

;; Limit agenda to a subt= ree
(add-hook 'org-agenda-mode-hook
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 '(lambda () (org-defkey org-agenda-mode-map "= \C-c\C-x<" 'bh/set-agenda-restriction-lock))
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 'append)

(defun bh= /set-agenda-restriction-lock (arg)
=C2=A0 "Set restriction l= ock to current task subtree or file if prefix is specified"
= =C2=A0 (interactive "p")
=C2=A0 (let* ((pom (bh/get-pom= -from-agenda-restriction-or-point))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0(tags (org-with-point-at pom (org-get-tags-at))))
=C2=A0 = =C2=A0 (let ((restriction-type (if (equal arg 4) 'file 'subtree)))<= /div>
=C2=A0 =C2=A0 =C2=A0 (save-restriction
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 (cond
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((and (equa= l major-mode 'org-agenda-mode) pom)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (org-with-point-at pom
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 (org-agenda-set-restriction-lock restriction-type))
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-redo))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0((and (equal major-mode 'org-mode) (org-before-= first-heading-p))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-= set-restriction-lock 'file))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0(pom
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-with-point-at pom=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (org-agenda-set-restri= ction-lock restriction-type))))))))

;; function to= bind C-u C-c C-x C-i to F10
(defun hist-org-clock-in-select ()
=C2=A0 (interactive)
=C2=A0 (org-clock-in '(4)))

(setq org-enforce-todo-dependencies t)
(set= q org-expiry-keyword "EXPIRED")

;; Color= Schemes
;;(add-to-list 'load-path "~/.emacs.d/color-the= mes/")
;;(add-to-list 'load-path "~/.emacs.d/elpa/&= quot;)
;;(add-to-list 'custom-theme-load-path "~/.emacs.= d/color-themes/")=C2=A0
;;(add-to-list 'custom-theme-loa= d-path "~/.emacs.d/site-elpa/")=C2=A0

;;= (require 'color-theme)
;;(color-theme-initialize)
;= (;color-theme-calm-forest)
;;(color-theme-subtle-blue)
= ;;(color-theme-classic)
;;(color-theme-ample-zen)
;;(co= lor-theme-Deviant)
;;(color-theme-cobalt)
;;(load-theme= 'Deviant t)

;; Clock set-up
(defun = bh/clock-in-task-by-id (id)
=C2=A0 "Clock in a task by id&qu= ot;
=C2=A0 (require 'org-id)
=C2=A0 (save-restricti= on
=C2=A0 =C2=A0 (widen)
=C2=A0 =C2=A0 (org-with-point-= at (org-id-find id 'marker)
=C2=A0 =C2=A0 =C2=A0 (org-clock-i= n nil))))

;; Resume clocking tasks when emacs is r= estarted

;; Yes it's long... but more is bette= r ;)
(setq org-clock-history-length 24)

= ;; Resume clocking task on clock-in if the clock is open
(setq or= g-clock-in-resume t)

;; Change task state to NEXT = when clocking in
(setq org-clock-in-switch-to-state (quote bh/clo= ck-in-to-next))

;; Separate drawers for clocking a= nd logs/notes
(setq org-drawers (quote ("PROPERTIES" &q= uot;LOGBOOK" "CLOCK" "NOTES")))

;; Save notes in the LOGBOOK drawer
(setq org-log-into-dra= wer "LOGBOOK")

;; Save clock data in the= CLOCK drawer
(setq org-clock-into-drawer "CLOCK")

;; Don't clock out when moving task to a done stat= e
(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)

;; R= ound time to 5 minute increments
(setq org-time-stamp-rounding-mi= nutes (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 b= y default)
(setq org-agenda-log-mode-items (quote (clock)))
=

;; Show toady's time in clock mode line
(= setq =C2=A0org-clock-mode-line-total (quote today))

;; Agenda clock report parameters (no links, 4 levels deep)
(se= tq org-agenda-clockreport-parameter-plist (quote (:link nil :maxlevel 4)))<= /div>

;; Set default column view headings: Task Effort C= lock_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"))))
<= br>
;; Set-up TAGS
;; Tags with fast selection keys
(setq org-tag-alist (quote (("NEXT" . ?N)
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 ("WAITING" . ?W)
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 ("CANCELLED" . ?C))))

;; For tag sea= rches ignore tasks with scheduled and deadline dates
(setq org-ag= enda-tags-todo-honor-ignore-options t)

;; Find stu= ck projects
(setq org-stuck-projects (quote ("LEVEL=3D2/!-DO= NE-CANCELLED-OPEN-SOMEDAY-WAITING" nil ("NEXT") ""= )))

;; Set up org-capture:
(define-key g= lobal-map "\C-cc" 'org-capture)

;; r= e-align tags when finalizing items with tags
(setq org-auto-align= -tags t)

;; Agenda Day Separator
;;(setq= org-agenda-format-date
;; =C2=A0(concat "__________%a %Y-%m= -%d"
;; =C2=A0 =C2=A0(make-string (- (window-width) 24) ?_))= )

;; use spaces instead of _ since we're in a = box here
(setq org-agenda-format-date
=C2=A0 (concat &q= uot; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0%a %Y-%m-%d"
=C2=A0 = =C2=A0 (make-string (- (window-width) 24) ? )))

;;= always show time grid
(setq org-agenda-time-grid
=C2= =A0 =C2=A0 =C2=A0 (quote ((daily today) "----------------" (800 1= 000 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-pat= h "~/.emacs.d/org-mode/contrib/scripts/ditaa.jar")

=
(add-hook 'org-babel-after-execute-hook 'org-display-inl= ine-images)

(org-babel-do-load-languages
=C2=A0'org-babel-load-languages
=C2=A0'((emacs-lisp . t)=
=C2=A0 =C2=A0(latex . t)
=C2=A0 =C2=A0(ditaa . t)))

;; enable pdb-mode
;;(load-file "c:/U= sers/mheller/AppData/Roaming/.emacs.d/site-lisp/pdb-mode.el")
(setq auto-mode-alist
=C2=A0 =C2=A0 =C2=A0 (cons (cons "pd= b$" 'pdb-mode)
=C2=A0 =C2=A0auto-mode-alist))
(au= toload 'pdb-mode "PDB")

;; set up EL= PA
;;(require 'package)
;;(package-initialize)
;;(unless package-archive-contents (package-refresh-contents))
<= div>;;(unless (package-installed-p 'org) (package-install 'org))
;;
;;
;;
(custom-set-variables
<= div>=C2=A0;; custom-set-variables was added by Custom.
=C2=A0;; I= f you edit it by hand, you could mess it up, so be careful.
=C2= =A0;; Your init file should contain only one such instance.
=C2= =A0;; If there is more than one, they won't work right.
=C2= =A0'(TeX-output-view-style
=C2=A0 =C2=A0(quote
=C2= =A0 =C2=A0 (("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" &q= uot;dvips %d -o && start \"\" %f")
=C2=A0 = =C2=A0 =C2=A0("^dvi$" "." "yap -1 %dS %d")
=C2=A0 =C2=A0 =C2=A0("^pdf$" "." "gsview64= .exe %o")
=C2=A0 =C2=A0 =C2=A0("^html?$" ".&q= uot; "start \"\" %o"))))
=C2=A0'(TeX-view= -program-list (quote (("gsview" "gsview64.exe %o"))))
=C2=A0'(TeX-view-program-selection
=C2=A0 =C2=A0(quo= te
=C2=A0 =C2=A0 (((output-dvi style-pstricks)
=C2=A0 = =C2=A0 =C2=A0 "dvips and start")
=C2=A0 =C2=A0 =C2=A0(o= utput-dvi "Yap")
=C2=A0 =C2=A0 =C2=A0(output-pdf "= gsview")
=C2=A0 =C2=A0 =C2=A0(output-html "start")= )))
=C2=A0'(ansi-color-names-vector
=C2=A0 =C2=A0[&= quot;#002b36" "#dc322f" "#859900" "#b58900&qu= ot; "#268bd2" "#d33682" "#2aa198" "#8394= 96"])
=C2=A0'(ansi-term-color-vector
=C2=A0 = =C2=A0[unspecific "#586e75" "#dc322f" "#859900&quo= t; "#b58900" "#268bd2" "#d33682" "#2aa19= 8" "#002b36"])
=C2=A0'(canlock-password "= d956c608d952dc7a21822967382659482ed41a55" t)
=C2=A0'(cus= tom-enabled-themes nil)
=C2=A0'(custom-safe-themes
= =C2=A0 =C2=A0(quote
=C2=A0 =C2=A0 ("bb749a38c5cb7d13b60fa7fc= 40db7eced3d00aa93654d150b9627cabd2d9b361" "8c239ccd90e1e4483a9da6= 93bf66dd1b792fe5aff97d0a2f02b016e86fbd8728" "01ce486c3a7c8b37cf13= f8c95ca4bb3c11413228b35676025fdf239e77019ea1" "0a90958236c1b6ecb4= a8f91ce6b4c13a7c71faf3022d557d9d6b392dc7308e0f" "8aebf25556399b58= 091e533e455dd50a6a9cba958cc4ebb0aab175863c25b9a4" "3486508cb95981= a7003e376c1e6a54593c35c448bc7a8fea07eee37aad41512d" "4ab86c7682db= 09485a6e046ee0a6c45b5462f514c89844f4ed8b329aa1708067" "12b7ed9b0e= 990f6d41827c343467d2a6c464094cbcc6d0844df32837b50655f9" default)))
=C2=A0'(package-selected-packages
=C2=A0 =C2=A0(quote<= /div>
=C2=A0 =C2=A0 (pdb-mode org-bullets org-beautify-theme org-autoli= st org-alert org-agenda-property org color-theme boxquote batch-mode auctex= )))
=C2=A0'(show-paren-mode t))
;;
(custo= m-set-faces
=C2=A0;; custom-set-faces was added by Custom.
<= div>=C2=A0;; If you edit it by hand, you could mess it up, so be careful.
=C2=A0;; Your init file should contain only one such instance.
=C2=A0;; If there is more than one, they won't work right.
=
=C2=A0)
</.emacs>


<= /div>
--001a113f1a7ed4337e0549d81676--