org-secretary.el 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. ;;; org-secretary.el --- Team management with org-mode
  2. ;; Copyright (C) 2010-2013 Juan Reyero
  3. ;;
  4. ;; Author: Juan Reyero <juan _at_ juanreyero _dot_ com>
  5. ;; Keywords: outlines, tasks, team, management
  6. ;; Homepage: http://juanreyero.com/article/emacs/org-teams.html
  7. ;; Version: 0.02
  8. ;;
  9. ;; This file is not part of GNU Emacs.
  10. ;;
  11. ;; This file is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 3, or (at your option)
  14. ;; any later version.
  15. ;; THis file is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;; GNU General Public License for more details.
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22. ;;
  23. ;;; Commentary:
  24. ;;
  25. ;; This module implements helper functions for team management. It
  26. ;; makes it easy to keep track of the work of several people. It
  27. ;; keeps context (with whom and where you are) and allows you to use
  28. ;; it to metadata to your notes, and to query the tasks associated
  29. ;; with the people you are with and the place.
  30. ;;
  31. ;; See http://juanreyero.com/article/emacs/org-teams.html for a full
  32. ;; explanation and configuration instructions.
  33. ;;
  34. ;;; Configuration
  35. ;;;;;;;;;;;;;;;;;
  36. ;;
  37. ;; In short; your todos use the TODO keyword, your team's use TASK.
  38. ;; Your org-todo-keywords should look something like this:
  39. ;;
  40. ;; (setq org-todo-keywords
  41. ;; '((sequence "TODO(t)" "|" "DONE(d)" "CANCELLED(c)")
  42. ;; (sequence "TASK(f)" "|" "DONE(d)")
  43. ;; (sequence "MAYBE(m)" "|" "CANCELLED(c)")))
  44. ;;
  45. ;; It helps to distinguish them by color, like this:
  46. ;;
  47. ;; (setq org-todo-keyword-faces
  48. ;; '(("TODO" . (:foreground "DarkOrange1" :weight bold))
  49. ;; ("MAYBE" . (:foreground "sea green"))
  50. ;; ("DONE" . (:foreground "light sea green"))
  51. ;; ("CANCELLED" . (:foreground "forest green"))
  52. ;; ("TASK" . (:foreground "blue"))))
  53. ;;
  54. ;; If you want to keep track of stuck projects you should tag your
  55. ;; projects with :prj:, and define:
  56. ;;
  57. ;; (setq org-tags-exclude-from-inheritance '("prj")
  58. ;; org-stuck-projects '("+prj/-MAYBE-DONE"
  59. ;; ("TODO" "TASK") ()))
  60. ;;
  61. ;; Define a tag that marks TASK entries as yours:
  62. ;;
  63. ;; (setq org-sec-me "juanre")
  64. ;;
  65. ;; Finally, you add the special views to your org-agenda-custom-commands:
  66. ;;
  67. ;; (setq org-agenda-custom-commands
  68. ;; '(("h" "Work todos" tags-todo
  69. ;; "-personal-doat={.+}-dowith={.+}/!-TASK"
  70. ;; ((org-agenda-todo-ignore-scheduled t)))
  71. ;; ("H" "All work todos" tags-todo "-personal/!-TASK-MAYBE"
  72. ;; ((org-agenda-todo-ignore-scheduled nil)))
  73. ;; ("A" "Work todos with doat or dowith" tags-todo
  74. ;; "-personal+doat={.+}|dowith={.+}/!-TASK"
  75. ;; ((org-agenda-todo-ignore-scheduled nil)))
  76. ;; ("j" "TODO dowith and TASK with"
  77. ;; ((org-sec-with-view "TODO dowith")
  78. ;; (org-sec-where-view "TODO doat")
  79. ;; (org-sec-assigned-with-view "TASK with")
  80. ;; (org-sec-stuck-with-view "STUCK with")))
  81. ;; ("J" "Interactive TODO dowith and TASK with"
  82. ;; ((org-sec-who-view "TODO dowith")))))
  83. ;;
  84. ;;; Usage
  85. ;;;;;;;;;
  86. ;;
  87. ;; Do C-c w to say with whom you are meeting (a space-separated list
  88. ;; of names). Maybe do also C-c W to say where you are. Then do C-c a
  89. ;; j to see:
  90. ;; - Todo items defined with TODO (ie, mine) in which the
  91. ;; =dowith= property matches any of the people with me.
  92. ;; - Todo items defined with TODO in which the =doat= property
  93. ;; matches my current location.
  94. ;; - Todo items defined with TASK that are tagged with the name
  95. ;; of any of the people with me (this is, assigned to them).
  96. ;; - Stuck projects tagged with the name of the people with me.
  97. ;;
  98. ;; Use C-c j to add meta-data with the people with me, the
  99. ;; location and the time to entries.
  100. (require 'org)
  101. (defvar org-sec-me nil
  102. "Tag that defines TASK todo entries associated to me")
  103. (defvar org-sec-with nil
  104. "Value of the :with: property when doing an
  105. org-sec-tag-entry. Change it with org-sec-set-with,
  106. set to C-c w. Defaults to org-sec-me")
  107. (defvar org-sec-where ""
  108. "Value of the :at: property when doing an
  109. org-sec-tag-entry. Change it with org-sec-set-with,
  110. set to C-c W")
  111. (defvar org-sec-with-history '()
  112. "History list of :with: properties")
  113. (defvar org-sec-where-history '()
  114. "History list of :where: properties")
  115. (defun org-sec-set-with ()
  116. "Changes the value of the org-sec-with variable for use in the
  117. next call of org-sec-tag-entry. Leave it empty to default to
  118. org-sec-me (you)."
  119. (interactive)
  120. (setq org-sec-with (let ((w (read-string "With: " nil
  121. 'org-sec-with-history "")))
  122. (if (string= w "")
  123. nil
  124. w))))
  125. (global-set-key "\C-cw" 'org-sec-set-with)
  126. (defun org-sec-set-where ()
  127. "Changes the value of the org-sec-where variable for use
  128. in the next call of org-sec-tag-entry."
  129. (interactive)
  130. (setq org-sec-where
  131. (read-string "Where: " nil
  132. 'org-sec-where-history "")))
  133. (global-set-key "\C-cW" 'org-sec-set-where)
  134. (defun org-sec-set-dowith ()
  135. "Sets the value of the dowith property."
  136. (interactive)
  137. (let ((do-with
  138. (read-string "Do with: "
  139. nil 'org-sec-dowith-history "")))
  140. (unless (string= do-with "")
  141. (org-entry-put nil "dowith" do-with))))
  142. (global-set-key "\C-cd" 'org-sec-set-dowith)
  143. (defun org-sec-set-doat ()
  144. "Sets the value of the doat property."
  145. (interactive)
  146. (let ((do-at (read-string "Do at: "
  147. nil 'org-sec-doat-history "")))
  148. (unless (string= do-at "")
  149. (org-entry-put nil "doat" do-at))))
  150. (global-set-key "\C-cD" 'org-sec-set-doat)
  151. (defun org-sec-tag-entry ()
  152. "Adds a :with: property with the value of org-sec-with if
  153. defined, an :at: property with the value of org-sec-where
  154. if defined, and an :on: property with the current time."
  155. (interactive)
  156. (save-excursion
  157. (org-entry-put nil "on" (format-time-string
  158. (org-time-stamp-format 'long)
  159. (current-time)))
  160. (unless (string= org-sec-where "")
  161. (org-entry-put nil "at" org-sec-where))
  162. (if org-sec-with
  163. (org-entry-put nil "with" org-sec-with))))
  164. (global-set-key "\C-cj" 'org-sec-tag-entry)
  165. (defun join (lst sep &optional pre post)
  166. (mapconcat (function (lambda (x) (concat pre x post))) lst sep))
  167. (defun org-sec-get-with ()
  168. (if org-sec-with
  169. org-sec-with
  170. org-sec-me))
  171. (defun org-sec-with-view (par &optional who)
  172. "Select tasks marked as dowith=who, where who
  173. defaults to the value of org-sec-with."
  174. (org-tags-view '(4) (join (split-string (if who
  175. who
  176. (org-sec-get-with)))
  177. "|" "dowith=\"" "\"")))
  178. (defun org-sec-where-view (par)
  179. "Select tasks marked as doat=org-sec-where."
  180. (org-tags-view '(4) (concat "doat={" org-sec-where "}")))
  181. (defun org-sec-assigned-with-view (par &optional who)
  182. "Select tasks assigned to who, by default org-sec-with."
  183. (org-tags-view '(4)
  184. (concat (join (split-string (if who
  185. who
  186. (org-sec-get-with)))
  187. "|")
  188. "/TASK")))
  189. (defun org-sec-stuck-with-view (par &optional who)
  190. "Select stuck projects assigned to who, by default
  191. org-sec-with."
  192. (let ((org-stuck-projects
  193. `(,(concat "+prj+"
  194. (join (split-string (if who
  195. who
  196. (org-sec-get-with))) "|")
  197. "/-MAYBE-DONE")
  198. ("TODO" "TASK") ())))
  199. (org-agenda-list-stuck-projects)))
  200. (defun org-sec-who-view (par)
  201. "Builds agenda for a given user. Queried. "
  202. (let ((who (read-string "Build todo for user/tag: "
  203. "" "" "")))
  204. (org-sec-with-view "TODO dowith" who)
  205. (org-sec-assigned-with-view "TASK with" who)
  206. (org-sec-stuck-with-view "STUCK with" who)))
  207. (provide 'org-secretary)
  208. ;;; org-secretary.el ends here