;; -*- emacs-lisp -*- ;;; diary-countdown.el --- a variation on standard diary-mode output ;; Author: Mark Triggs ;; $Id: diary-countdown.el,v 1.12 2004/05/22 05:59:58 mst Exp $ ;; Keywords: calendar ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; This code provides a celebrat-style output format for diary-mode. Output ;; could be something like "Buy pet duck named Gerald in 5 days". ;; To use it, add the following form to your ~/.emacs: ;; ;; (add-hook 'diary-display-hook 'mst-diary-display) ;; ;; I use a shell script to show upcoming stuff when I login. This is available ;; via http://dishevelled.net/misc/my-life.sh ;;; Code: (require 'cl) (defvar mst-diary-display-terms '((0 . "today") (1 . "tomorrow") (2 . "the day after tomorrow") (7 . "one week from now") (14 . "one fortnight from now")) "A mapping of 'days from now' numbers to natural language") (defun mst-diary-make-buffer () (prog1 (set-buffer (get-buffer-create "*Your Life*")) (setq buffer-read-only nil) (erase-buffer) (set-buffer-modified-p nil))) (defun mst-diary-trim-string (s) (replace-regexp-in-string "^[ \t]+\\|[ \t]+$" "" s)) (defun mst-diary-display () (let ((buffer (mst-diary-make-buffer))) (mapc (lambda (entry) (insert (if (assoc (car entry) mst-diary-display-terms) (format "%s %s\n" (mst-diary-trim-string (cadr entry)) (cdr (assoc (car entry) mst-diary-display-terms))) (format "%s in %s days\n" (mst-diary-trim-string (cadr entry)) (car entry))))) ;; For recurring events, only show the upcoming one (remove-duplicates (mst-diary-grok) :key 'cadr :test 'string= :from-end t)) (set-buffer-modified-p nil) (view-mode) (pop-to-buffer buffer))) (defun mst-diary-grok () (require 'time-stamp) (let* ((timestamp (split-string (time-stamp-yyyy/mm/dd) "/")) (today (calendar-absolute-from-gregorian (list (string-to-number (nth 1 timestamp)) (string-to-number (nth 2 timestamp)) (string-to-number (nth 0 timestamp)))))) (sort (mapcar (lambda (diary-entry) (list ;; days from now (- (calendar-absolute-from-gregorian (car diary-entry)) today) ;; the diary entry string (cadr diary-entry))) (remove-duplicates diary-entries-list :test (lambda (e1 e2) (and (string-match "diary-cyclic" e1) (string= e1 e2))) :key #'caddr :from-end t)) (lambda (rec1 rec2) (< (car rec1) (car rec2)))))) (provide 'diary-countdown) ;;; diary-countdown.el ends here