diff options
author | Franck Cuny <fcuny@twitter.com> | 2019-10-06 15:11:19 -0700 |
---|---|---|
committer | Franck Cuny <fcuny@twitter.com> | 2019-10-06 15:11:19 -0700 |
commit | 7a08b36af4d442fd11e9e4cf14fc1ed507f56e02 (patch) | |
tree | 3471496675ea1da5ea27d5b816d216eb94e5e003 /emacs.d/custom | |
parent | [emacs] dropped the :columns information (diff) | |
download | emacs.d-7a08b36af4d442fd11e9e4cf14fc1ed507f56e02.tar.gz |
[org] a lot of changes.
Adding a menu for hydra, to jump quickly to some files. I'm also adding a few custom commands for the agenda. After that many experiment, I think this is what I'm missing to be more efficient. This allows me to ignore completely how the file *looks* and focus on getting through the tasks. I'm also adding a few keywords for managing tasks: - PROJECT is for large tasks (e.g. an epic). This can be transitioned to PROJECTDONE - MEETING and NOTES are tasks that are completed, and I use them to keep track of various things in a project.
Diffstat (limited to 'emacs.d/custom')
-rw-r--r-- | emacs.d/custom/fcuny-org.el | 274 |
1 files changed, 187 insertions, 87 deletions
diff --git a/emacs.d/custom/fcuny-org.el b/emacs.d/custom/fcuny-org.el index 35d673a..5c15ef6 100644 --- a/emacs.d/custom/fcuny-org.el +++ b/emacs.d/custom/fcuny-org.el @@ -6,16 +6,12 @@ (use-package org :after (dash) :ensure t - :hook ((org-mode . visual-line-mode) (org-mode . org-indent-mode) - (org-capture-mode-hook . delete-other-windows) - (org-mode . fcuny/org-mode-setup)) - + (org-capture-mode-hook . delete-other-windows)) :bind (("C-c c" . org-capture) ("C-c a" . org-agenda) ("C-c o" . hydra-org-menu/body)) - :config (progn () (org-babel-do-load-languages @@ -24,37 +20,161 @@ (python . t) (emacs-lisp . t)))) + (defhydra hydra-org-menu (:hint nil) + " +^go to ^ ^action ^ +^-------------------^ ^---------------^ +_g i_: go to inbox _s_: save files +_g p_: go to personal +_g w_: go to work +_g n_: go to notes +" + ("g i" (find-file-other-window org-default-inbox-file)) + ("g p" (find-file-other-window org-default-personal-file)) + ("g w" (find-file-other-window org-default-work-file)) + ("g n" (find-file-other-windw org-default-notes-file)) + ("s" (org-save-all-org-buffers))) + :custom ;; cosmetic (org-pretty-entities t) - (org-startup-indented t) - (org-tags-column -120) + (org-startup-indented nil) + (org-tags-column -97) + + ;; + (org-log-done 'time) + + ;; priorities + (org-priority-start-cycle-with-default nil) ;; Start one over/under default value. + (org-lowest-priority ?D) + (org-default-priority ?D) ;; Ensures unset tasks have low priority. + (org-priority-faces '((?A . "#ff2600") + (?B . "#ff5900") + (?C . "#ff9200") + (?D . "#747474"))) ;; files (org-directory (expand-file-name "~/Documents/notebooks")) (org-archive-dir (concat org-directory "/archive/")) - (org-default-projects-dir (concat org-directory "/projects")) - (org-default-personal-dir (concat org-directory "/personal")) - (org-default-completed-dir (concat org-directory "/completed")) - (org-default-technical-dir (concat org-directory "/technical")) - - (org-default-completed-file nil) + (org-default-personal-file (concat org-directory "/personal.org")) + (org-default-work-file (concat org-directory "/twitter.org")) + (org-default-journal-file (concat org-directory "/journal.org")) (org-default-inbox-file (concat org-directory "/inbox.org")) - (org-default-tasks-file (concat org-directory "/tasks.org")) - (org-default-incubate-file (concat org-directory "/incubate.org")) - (org-default-media-file (concat org-directory "/media.org")) (org-default-notes-file (concat org-directory "/notes.org")) ;; how to manage tasks - (org-todo-keywords '((sequence "TODO(t)" "DOING(g)" "|" "DONE(d)") - (sequence "|" "CANCELED(c)"))) + (org-todo-keywords '((sequence "TODO(t)" "STARTED(s)" "DELEGATED(D)" "|" "DONE(d)") + (sequence "|" "MEETING(m)" "NOTE(n)") + (sequence "PROJECT" "|" "PROJECTDONE") + (sequence "SOMEDAY" "|" "CANCELED(c)"))) ;; agenda related (org-agenda-start-on-weekday 1) - (org-agenda-files `(,org-default-projects-dir - ,org-default-inbox-file - ,org-default-tasks-file)) + (org-agenda-files `(,org-default-personal-file + ,org-default-work-file)) + + (org-agenda-custom-commands + (quote + (("w" . "Work...") + ("wt" "Work Today" + ((tags-todo "DEADLINE=\"<+0d>\"" + ((org-agenda-overriding-header "Due today") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'notdeadline)) + (org-agenda-sorting-strategy '(priority-down)))) + (tags-todo "DEADLINE<\"<+0d>\"" + ((org-agenda-overriding-header "Overdue") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'notdeadline)) + (org-agenda-sorting-strategy '(priority-down)))) + (tags-todo "TODO={STARTED}" + ((org-agenda-overriding-header "Started") + (org-agenda-sorting-strategy '(priority-down)))) + (tags "TODO={MEETING}+CREATED>\"<-7d>\"" + ((org-agenda-overriding-header "Recent meetings (last 7 days)"))) + (tags "TODO={NOTE}+CREATED>\"<-7d>\"" + ((org-agenda-overriding-header "Recent notes (last 7 days)"))) + (agenda "" + ((org-agenda-entry-types '(:scheduled)) + (org-agenda-overriding-header "Scheduled") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'todo 'done)) + (org-agenda-sorting-strategy + '(priority-down time-down)) + (org-agenda-span 'day) + (org-agenda-start-on-weekday nil) + (org-agenda-time-grid nil)))) + ((org-agenda-files `(,org-default-work-file)) + (org-agenda-sorting-strategy '(deadline-up)))) + + ("wp" "For 1:1" + ((tags "people&TODO={TODO\\|STARTED}" + ((org-agenda-overriding-header "Tasks for 1:1"))))) + + ("p" . "Personal ...") + ("pt" "Personal Today" + ((tags-todo "DEADLINE=\"<+0d>\"" + ((org-agenda-overriding-header "Due today") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'notdeadline)) + (org-agenda-sorting-strategy '(priority-down)))) + (tags-todo "DEADLINE<\"<+0d>\"" + ((org-agenda-overriding-header "Overdue") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'notdeadline)) + (org-agenda-sorting-strategy '(priority-down)))) + (tags-todo "TODO={STARTED}" + ((org-agenda-overriding-header "Started") + (org-agenda-sorting-strategy '(priority-down)))) + (tags "TODO={NOTE}+CREATED>\"<-7d>\"" + ((org-agenda-overriding-header "Recent notes (last 7 days)"))) + (agenda "" + ((org-agenda-entry-types '(:scheduled)) + (org-agenda-overriding-header "Scheduled") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'todo 'done)) + (org-agenda-sorting-strategy + '(priority-down time-down)) + (org-agenda-span 'day) + (org-agenda-start-on-weekday nil) + (org-agenda-time-grid nil)))) + ((org-agenda-files `(,org-default-personal-file + ,org-default-notes-file)) + (org-agenda-sorting-strategy '(deadline-up)))) + + ("r" . "Review ...") + ("rt" "Triage (unscheduled tasks)" + ((tags "TODO<>\"\"&TODO<>{DONE\\|CANCELED\\|NOTE\\|MEETING\\|PROJECT}" + ((org-agenda-overriding-header "Unscheduled tasks: ") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote scheduled) + (quote deadline) + (quote timestamp) + (quote regexp) + "\\* \\(SOMEDAY\\)"))) + (org-agenda-sorting-strategy + (quote + (category-up))) + (org-agenda-prefix-format "%-11c%5(org-todo-age) "))))) + + ("rs" "Someday tasks" + ((tags-todo "TODO={SOMEDAY}" + ((org-agenda-overriding-header "NO DUE DATE / SOMEDAY") + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'deadline)))))) + + ("h" "Hotlist (what's important and due soon)" + ((tags-todo "DEADLINE<\"<+0d>\"" + ((org-agenda-overriding-header "OVERDUE"))) + (tags-todo "DEADLINE>=\"<+0d>\"+DEADLINE<=\"<+1w>\"" + ((org-agenda-overriding-header "DUE IN NEXT 7 DAYS"))) + (tags-todo "DEADLINE=\"\"+PRIORITY={A}|DEADLINE>\"<+1w>\"+PRIORITY={A}" + ((org-agenda-overriding-header "HIGH PRIORITY")))) + ((org-agenda-todo-ignore-scheduled 'future) + (org-agenda-sorting-strategy '(deadline-up))))))) ;; org babel related ;; prevent the conversion of spaces into tabs (necessary for Python code exports) @@ -87,78 +207,58 @@ (org-refile-use-outline-path 'file) (org-outline-path-complete-in-steps nil) (org-refile-allow-creating-parent-nodes 'confirm) - (org-refile-targets (append '((org-default-media-file :level . 1) - (org-default-notes-file :level . 0)) - (->> - (directory-files org-default-projects-dir nil ".org$") - (-remove-item (file-name-base org-default-media-file)) - (--remove (s-starts-with? "." it)) - (--map (format "%s/%s" org-default-projects-dir it)) - (--map (cons it (cons :level 1)))))) + (org-refile-targets (quote ((org-agenda-files :todo . "PROJECT") + (org-default-notes-file :maxlevel . 1)))) + + (org-stuck-projects (quote ("TODO=\"PROJECT\"" ("TODO") nil ""))) + + (org-reverse-note-order t) + + (org-todo-keyword-faces + (quote + (("TODO" :foreground "medium blue" :weight bold) + ("STARTED" :foreground "dark orange" :weight bold) + ("WAITING" :foreground "red" :weight bold) + ("DELEGATED" :foreground "dark violet" :weight bold) + ("NOTE" :foreground "purple" :weight bold) + ("PROJECT" :foreground "#088e8e" :weight bold))) + ("SOMEDAY" :foreground "dark blue" :weight bold) + ("MEETING" :foreground "deep sky blue" :weight bold)) (org-capture-templates - `(("t" "task entry" entry - (file ,org-default-inbox-file ) - "* %?\n:PROPERTIES:\n:CREATED: %U\n:END:\n%i"))) + `(("t" "Add task" entry + (file ,org-default-inbox-file) + "* TODO %?\n:PROPERTIES:\n:ID: %(shell-command-to-string \"uuidgen\"):CREATED: %U\n:END:\n") - :config - (defhydra hydra-org-menu (:columns 6) - " - ^Navigate^ ^Refile^ ^Move^ ^Update^ ^Go To^ ^Dired^ - ^^^^^^^^^^--------------------------------------------------------------------------------------- - _k_: ↑ previous _t_: tasks _m X_: projects _T_: todo task _g t_: tasks _g X_: projects - _j_: ↓ next _p_: personal _m P_: personal _S_: schedule _g i_: incubate _g P_: personal - _c_: archive _r_: refile _m T_: technical _D_: deadline _g n_: notes _g T_: technical - _d_: delete _i_: incubate _R_: rename _g x_: inbox _g C_: completed - " - ("<up>" org-previous-visible-heading) - ("<down>" org-next-visible-heading) - ("k" org-previous-visible-heading) - ("j" org-next-visible-heading) - ("c" fcuny/org-archive-subtree-as-completed) - ("d" org-cut-subtree) - ("t" fcuny/org-refile-to-task) - ("i" fcuny/org-refile-to-incubate) - ("p" fcuny/org-refile-to-personal-notes) - ("r" org-refile) - ("m X" fcuny/org-refile-to-projects-dir) - ("m P" fcuny/org-refile-to-personal-dir) - ("m T" fcuny/org-refile-to-technical-dir) - ("T" org-todo) - ("S" org-schedule) - ("D" org-deadline) - ("R" org-rename-header) - ("g t" (find-file-other-window org-default-tasks-file)) - ("g i" (find-file-other-window org-default-incubate-file)) - ("g x" (find-file-other-window org-default-inbox-file)) - ("g c" (find-file-other-window org-default-completed-file)) - ("g n" (find-file-other-window org-default-notes-file)) - ("g X" (dired org-default-projects-dir)) - ("g P" (dired org-default-personal-dir)) - ("g T" (dired org-default-technical-dir)) - ("g C" (dired org-default-completed-dir)) - ("[\t]" (org-cycle)) - ("s" (org-save-all-org-buffers) "save") - ("q" nil "quit")) - - :init - (defun fcuny/org-mode-setup () - (let* ((base-font-color (face-foreground 'default nil 'default)) - (headline `(:inherit default :weight bold :foreground ,base-font-color))) - (custom-theme-set-faces 'user `(org-document-title ((t (,@headline :height 1.5))))) - (custom-theme-set-faces 'user `(org-level-1 ((t (,@headline :height 1.3))))) - (custom-theme-set-faces 'user `(org-level-2 ((t (:height 1.1)))))))) + ("m" "Meeting" entry + (file ,org-default-inbox-file) + "* MEETING %u %?\n:PROPERTIES:\n:ID: %(shell-command-to-string \"uuidgen\"):CREATED: %U\n:END:\n") + + ("n" "Note" entry + (file ,org-default-inbox-file) + "* NOTE %?\n:PROPERTIES:\n:ID: %(shell-command-to-string \"uuidgen\"):CREATED: %U\n:END:\n") + + ("j" "Journal" entry + (file+olp+datetree ,org-default-journal-file) + "* %?" :tree-type month)))) (use-package htmlize :ensure t) -(use-package org-journal - :ensure t - :after (org) - :custom - (org-journal-file-format "%Y-%m.org") - (org-journal-dir "~/Documents/notebooks/journal/") - (org-journal-date-format 'fcuny/org-journal-date-format-func) - (org-journal-file-type `monthly)) +(defun fcuny/org-todo-age-time (&optional pos) + (let ((stamp (org-entry-get (or pos (point)) "CREATED" t))) + (when stamp + (time-subtract (current-time) + (org-time-string-to-time + (org-entry-get (or pos (point)) "CREATED" t)))))) + +(defun fcuny/org-todo-age (&optional pos) + (let ((days (time-to-number-of-days (fcuny/org-todo-age-time pos)))) + (cond + ((< days 1) "today") + ((< days 7) (format "%dd" days)) + ((< days 30) (format "%.1fw" (/ days 7.0))) + ((< days 358) (format "%.1fM" (/ days 30.0))) + (t (format "%.1fY" (/ days 365.0)))))) (provide 'fcuny-org) |