dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

org-secretary.el (8505B)


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