#+TITLE: Different roles
#+DATE: 2013-01-10
#+COLESLAW_TAGS: org-mode, emacs, todo

The other day I noticed that when I'm working I find it very annoying
to have tasks for my personal projects appear in either my agenda or
my todo list, so I was thinking if I couldn't make it somewhat more
flexible.

First I've added some separation between my org files, I've split
them into ~personal-org-agenda-files~, ~work-org-agenda-files~ and
~common-org-agenda-files~, since there are also /some/ tasks that I would
like to know about in either situation.

#+BEGIN_SRC emacs-lisp
  (defvar oni:personal-agenda-files
    (list (expand-file-name "~/documents/org/tasks"))
    "My personal agenda, should only show up at times I don't have
    to work.")

  (defvar oni:work-agenda-files
    (list (expand-file-name "~/documents/org/work"))
    "My work agenda, should only show up at times I work.")

  (defvar oni:common-agenda-files
    (list (expand-file-name "~/documents/org/misc"))
    "Agenda files that are work-agnostic, should always show up.")
#+END_SRC

At first I only seperated them with ~org-agenda-custom-commands~:

#+BEGIN_SRC emacs-lisp
  (setq org-agenda-custom-commands
        '(("P" . "Personal only")
          ("Pa" "Personal agenda" agenda ""
           ((org-agenda-files (append oni:personal-agenda-files
                                      oni:common-agenda-files))))
          ("Pt" "Personal todo" agenda ""
           ((org-agenda-files (append oni:personal-agenda-files
                                      oni:common-agenda-files))))
          ("W" . "Work only")
          ("Wa" "Work agenda" agenda ""
           ((org-agenda-files (append oni:work-agenda-files
                                      oni:common-agenda-files))))
          ("Wt" "Work todo" todo ""
           ((org-agenda-files (append oni:work-agenda-files
                                      oni:common-agenda-files))))))
#+END_SRC

But it's clunky to have to use a separate command just to see a clean
todo list.  Then I thought, and tried, to have a function that checks
the time to see which it should use, since I work from 09:00 to
17:00, if the current time is between those times I should only look
at my work todo list, most of the time, outside of those hours I
don't really care what I have to do for work.

#+BEGIN_SRC emacs-lisp
  (defun oni:set-org-agenda-files ()
    (interactive)
    (let ((current-time (current-time-string))
          (start-time (format-time-string "%a %b %e 09:00:00 %Y"))
          (end-time (format-time-string "%a %b %e 17:00:00 %Y")))
      (if (or (and (string< current-time start-time)
                   (string< current-time end-time))
              (and (string< start-time current-time)
                   (string< end-time current-time)))
          (setq org-agenda-files
                (append oni:personal-agenda-files
                        oni:common-agenda-files))
        (setq org-agenda-files
              (append oni:work-agenda-files
                      oni:common-agenda-files)))))
#+END_SRC

It's weird, but since Emacs doesn't have any real datetime functions
for creation/comparison, for as far as I know, it seemed easiest to
just create some strings representing the time and compare these.

Then it should be, if the current time is either before both start
and end time or after both start and end time it should return my
personal todo list, otherwise it should return my work todo list.

Now, it would be silly to have to call that manually every so-often,
so I've set it up to do so automatically.

#+BEGIN_SRC emacs-lisp
  (oni:set-org-agenda-files)
  (run-at-time "09:01" nil 'oni:set-org-agenda-files)
  (run-at-time "17:01" nil 'oni:set-org-agenda-files)
#+END_SRC

First, I set my agenda files to whatevers they should be *right now*.
Then I have this function run at 09:01 and 17:01, if either or both
have already passed, they won't be executed today.  This effectively
tells Emacs to switch to my work "role" after 09:00 and back to my
personal "role" after 17:00.

It's not perfect yet, but I felt like writing something.  The things
I would change might include:

- Check the times for either ~<~ or ~=~ the start/end times, so I don't
  have to check for ~:01~ every time, but Emacs doesn't have a ~string<=~
  function so I'll have to mimic it.

- Always set it to my personal "role" during weekends.

- Have them repeat every 24 hours, just in case I don't turn off my
  PC for a few days.

I'll fix those soon, they're not hard to do, but this works for now.
It has worked well for me today, but I might throw it out again
tomorrow, as I sometimes tend to do.
