;;; Planner Mode Settings (require 'planner) ;;; Basic Config (setq planner-carry-tasks-forward 1) (setq planner-project "clintons-plans") (setq planner-use-other-window nil) ;;; Planner template (setq planner-day-page-template "* Tasks\n\n\n* Schedule\n\n\n* Notes\n\n\n* Timeclock\n\n\n* Accomplishments\n\n") ;;; General Key Bindings (global-set-key [?\C-c ?p ?p] #'plan) (global-set-key [?\C-c ?p ?d] #'planner-goto-today) (global-set-key [?\C-c ?p ?b] #'planner-create-task-from-buffer) (global-set-key [?\C-c ?p ?B] #'cke-planner-create-task-from-buffer-extended) (global-set-key [?\C-c ?p ?t] #'planner-create-task) (global-set-key [?\C-c ?p ?T] #'cke-planner-create-task-extended) (global-set-key [?\C-c ?r] #'remember) ;; My emacs runs continually and this ensures that my todo list will ;; be in front of me when I wake up in the morning (add-hook 'midnight-hook #'(lambda () ;; Rebind hook to nil to supress prompts ;; for auto created cyclic tasks (let ((planner-create-task-hook nil) ;; Only try to create cyclic tasks ;; when new page is created ;; automatically because it is ;; annoying as hell to have the ;; prompts for my cyclic tasks to ;; come up when scheduling future ;; tasks. (planner-mode-hook (cons #'planner-cyclic-create-tasks-maybe planner-mode-hook))) (plan)))) ;;; Extra task interfaces (require 'planner-w3m) (require 'planner-bibtex) (require 'planner-bookmark) (require 'planner-publish) (setq planner-html-inner-header "") (setq planner-calendar-prev-month-button "<<") (setq planner-calendar-next-month-button ">>") ;;; Remember (require 'remember-planner) (setq remember-handler-functions '(remember-planner-append)) (setq remember-annotation-functions planner-annotation-functions) ;; Local Keybindings (define-key planner-mode-map [?\C-c ?n] #'planner-create-note-from-task) (define-key planner-mode-map [?\C-c ?d] #'planner-deadline-change) (require 'planner-gnus) (planner-gnus-insinuate) ;; Prompt for a deadline in addition to start date when creating new tasks (require 'planner-deadline) (planner-calendar-insinuate) (define-key global-map [?\C-c ?p ?c] #'calendar) ;;; Ranking customizations (require 'planner-rank) ;; Asks for importance before deadline to allow adding importance to ;; tasks without a deadline. (defun cke-planner-deadline-add (date) (interactive (list (planner-read-date nil t))) ;; Overload this for the extent because I don't care ;; about manually setting the urgency; a task lacking a ;; deadline is for me one with 'average' urgency. (cond (date (planner-deadline-add date)) (t (flet ((planner-rank-read-importance-and-urgency () (list (string-to-number (read-string "Importance: " nil nil (number-to-string planner-rank-default-importance))) planner-rank-default-urgency))) (planner-rank-change))))) (defun cke-planner-call-extended (fun) (let ((planner-create-task-hook (cons #'(lambda () (call-interactively #'cke-planner-deadline-add)) planner-create-task-hook))) (call-interactively fun))) (defun cke-planner-create-task-extended () "Prompt for deadline and/or importance when creating a task" (interactive) (cke-planner-call-extended #'planner-create-task)) (defun cke-planner-create-task-from-buffer-extended () "Prompt for deadline and/or importance when creating a task from a buffer" (interactive) (cke-planner-call-extended #'planner-create-task-from-buffer)) (setq planner-sort-tasks-key-function #'planner-sort-tasks-by-rank) (setq planner-rank-importance-vs-urgency-factor 1.5) (setq planner-rank-priority-A-valve 6.49) (setq planner-rank-priority-B-valve 4.49) ;;; note: tenative (setq planner-rank-deadline-urgency-map-list '(-1 0 4 10 21 30 90 180 365)) (define-key planner-mode-map [?\C-c ?i] #'planner-rank-change) ;;; Cyclic Tasks (require 'planner-cyclic) (setq planner-cyclic-diary-file "~/plans/diary.cyclic-tasks") ;; Cyclic tasks are only created when #'plan is run by midnight-mode (remove-hook 'planner-mode-hook 'planner-cyclic-create-tasks-maybe) ;;; Task IDs (require 'planner-id) (setq planner-id-tracking-file "~/plans/.planner-id") ;;; Experimental (defun cke-planner-get-annot () (interactive) (kill-new (or (run-hook-with-args-until-success 'planner-annotation-functions) ""))) (define-key global-map [?\C-c ?p ?a] #'cke-planner-get-annot) (require 'planner-schedule) (require 'planner-timeclock) (require 'planner-timeclock-summary) (setq timeclock-file (cke-personal-file "timelog")) (planner-timeclock-summary-insinuate) (define-key planner-mode-map [?\C-c ?\C-o] #'(lambda () (interactive) (planner-task-open) (timeclock-out))) (require 'planner-calendar) (setq planner-calendar-today-page-name "index") (eval-after-load "muse-publish" '(add-hook 'muse-after-publish-hook 'planner-calendar-create-today-link)) (require 'planner-accomplishments) (setq planner-accomplishments-status-display '(("_" . "Unfinished") ; ("o" . "In progress") ; ("D" . "Delegated") ("P" . "Postponed") ("X" . "Completed") ("C" . "Cancelled"))) (planner-accomplishments-insinuate) ;;; Special task creation functions (defun cke-planner-create-book-tasks-range (title start end) "Create undated tasks for reading individual sections of a book" (interactive "MTitle: \nnStart: \nnEnd: ") (dotimes (chapter-base (- (1+ end) start)) (planner-create-task (format "Reading: %s: Chapter %d" title (+ chapter-base start)) nil nil "Reading" "P"))) (defun cke-planner-create-book-tasks (title chapters) "Create undated tasks for reading individual sections of a book" (interactive "MTitle: \nnChapters: ") (cke-planner-create-book-tasks-range title 1 chapters)) (defun cke-planner-create-bicycle-light-tasks () (interactive) (let ((cke-date (planner-read-date)) (planner-default-task-priority "A")) (mapc (lambda (task-description) (planner-create-task task-description cke-date nil "Bicycle")) '("Charge headlight" "Charge LD-600 AAAs" "Charge LD-1000 AAs")))) (global-set-key [?\C-c ?p ?e ?b] #'cke-planner-create-book-tasks) (global-set-key [?\C-c ?p ?e ?B] #'cke-planner-create-book-tasks-range) (global-set-key [?\C-c ?p ?e ?l] #'cke-planner-create-bicycle-light-tasks) ;;; Diary Integration ;; (require 'planner-diary) (setq diary-file "~/plans/diary") ;; (add-hook 'diary-display-hook 'fancy-diary-display) ;; (setq planner-diary-string "* Schedule") ;; (setq planner-diary-use-diary t) ;; (planner-diary-insinuate) ;;; Appointments (require 'planner-appt) (setq planner-appt-task-use-appointments-section-flag t) (planner-appt-use-tasks) (planner-appt-insinuate) ;;; BBDB (require 'planner-bbdb) ;;; VC Integration (require 'planner-log-edit) ;;; Misc Local Keybindings (define-key planner-mode-map [?\C-c (control shift ?p)] #'planner-task-pending) ;;; Works in Progress ;; Next ;; 1. overlay modification hooks ;; a. behavior ;; b. modifying overlay when text length changes ;; 2. regex matching ;; a. match groups ;; 3. integrate with planner ;; a. use planner deadline functions to match task deadline ;; b. insert overlay ;; i. manage overlay size when task is changed ;; c. hook into planner ;; 4. Cleanup ;; a. create a category for the deadline overlay ;; i. move properties from function to plist on category (defun cke-planner-overlay-test () (save-selected-window (switch-to-buffer (get-buffer-create "*foo*")) (let ((cke-overlay (or (car (overlays-at 8)) (make-overlay 8 13)))) (overlay-put cke-overlay 'before-string "foo1") (overlay-put cke-overlay 'invisible t)))) ;; Version control integration (defun vc-darcs-init-version () nil) ;; this needs to only try to check in new files of the planner ;; project, and then only when they are real files and not transient ;; report buffers (defadvice planner-prepare-file (after cke-planner-darcs-add disable) "Add empty planner files to the current darcs repo if the planner projects under vc" (set-buffer-modified-p t) (save-buffer) (when (and (buffer-file-name) (eq (muse-project-of-file (buffer-file-name)) planner-project)) (let ((vc-default-init-version nil)) (if (not (condition-case nil (vc-register nil nil) (error t))) (vc-checkin (buffer-file-name) nil "Initial Checkin"))))) (ad-unadvise #'planner-prepare-file)