Kyle Sexton <k...@mocker.org> writes: > Nick Dokos <ndo...@gmail.com> writes: > >> I don't think the feature exists but it should be buildable - although I >> think it is not exactly simple. >> >> It should be easy to write a function that uses the org mapping API to >> produce a string of the form "[Work: 3/10 Home: 2/20]" and assign it to >> a variable, say mode-line-org-tasks. The variable can be added to >> mode-line-format. > > That part is beyond my elisp ability, but good to know that the feature > doesn't currently exist. >
Here is an implementation of the above. If you paste the code into a buffer, change the paths appropriately and M-x eval-buffer, you should get a mode line with the stats. mode-line-format is buffer-local so you can get rid of the modified mode-line-format by just killing the buffer. --8<---------------cut here---------------start------------->8--- (defun org-agenda-mode-line (&optional files) "Construct a string of the form [<file>:<todo-today>/<todo> ...] for all the files in the argument list (or all the agenda files if the argument is nil)." (let ((afiles)) (setq afiles (if (not files) (org-agenda-files) files)) (concat "[" (mapconcat (function org-mode-line-stats) afiles " ") "]"))) (defun org-count-todo () "If the current headline is SCHEDULED and its scheduled date is on or before today then count it in todo-today. Count it unconditionally in todo-total." (let ((sched (org-entry-get (point) "SCHEDULED"))) (if (and sched (<= (time-to-days (org-time-string-to-time sched)) (org-today))) (incf todo-today)) (incf todo-total))) (defun org-mode-line-stats (file) "Use org-map-entries to step through the TODO headlines. Apply the org-count-todo function on each headline and return a string of the form <file>:<todo-today>/<todo>." (let ((buffer (get-file-buffer file)) (todo-today 0) (todo-total 0)) (if buffer (save-excursion (set-buffer buffer) ;; do the org mapping API dance (org-map-entries (function org-count-todo) "/+TODO" 'file))) (concat (file-name-base file) (format ":%d/%d" todo-today todo-total)))) (setq mode-line-org-agenda-stats (org-agenda-mode-line '("/home/nick/lib/org/home.org" "/home/nick/lib/org/work.org"))) (nconc mode-line-format '(mode-line-org-agenda-stats)) --8<---------------cut here---------------end--------------->8--- The code assumes that the relevant files are already visited (e.g. you've already done C-c a a or M-x org-agenda-list). Otherwise, get-file-buffer will return nil and the counting will be skipped: you'll get 0/0 values. Also, what to search for is hardwired but it should be clear how to change it to use different criteria. The update problem below is still TBD. >> The problem is to force mode-line redisplay when things change, >> e.g. when you mark a TODO task DONE, or add another task to work.org. >> If the file gets modified, then filenotify.el can be used, but since the >> agenda files are kept open, the buffer is modified but the file is not >> (until the buffer is saved) and I'm not sure how to detect such changes >> and propagate them to the mode line. I thought there must be a hook to >> allow this, but I haven't found one yet. >> >> The rather yucky alternative is to poll the relevant buffers (say once a >> minute) to see if they are modified and if so, run the function to set >> the variable and force mode-line redisplay. > > I already have a function for org-mobile to sync, could something like > that be hooked into? > > #+BEGIN_SRC emacs-lisp > ;; Push to mobile-org > ;; moble sync > (defvar org-mobile-sync-timer nil) > (defvar org-mobile-sync-idle-secs (* 60 10)) > (defun org-mobile-sync () > (interactive) > (org-mobile-pull) > (org-mobile-push)) > (defun org-mobile-sync-enable () > "enable mobile org idle sync" > (interactive) > (setq org-mobile-sync-timer > (run-with-idle-timer org-mobile-sync-idle-secs t > 'org-mobile-sync))) > (defun org-mobile-sync-disable () > "disable mobile org idle sync" > (interactive) > (cancel-timer org-mobile-sync-timer)) > (org-mobile-sync-enable) > #+END_SRC -- Nick