;;; temperature.el --- Show the current temperature in the modeline ;; Copyright (C) 2009 Mark Triggs ;; Author: Mark Triggs ;; 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 3, 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., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. (defun temperature-shell-command-to-string (callback cmd &rest args) (lexical-let ((proc (apply 'start-process "cmd" nil cmd args)) (output "") (fn callback)) (set-process-sentinel proc (lambda (proc str) (funcall fn output))) (set-process-filter proc (lambda (proc str) (setq output (concat output str)))))) (defun temperature-update () (temperature-shell-command-to-string (lambda (str) (let ((bits (split-string str "\0"))) (setq *current-temperature* (car (read-from-string (car bits)))) (setq *current-forecast* (cadr bits))) (force-mode-line-update)) "temperature.pl")) (defvar *temperature-colours* '(("blue" . "#0000FF") ("dark-blue" . "#0000CC") ("orange" . "#FF9900") ("dark-orange" . "#E86400") ("red" . "#FF0000") ("dark-red" . "#C40000"))) (defun weather-dot (colour) "Return an XPM string representing a dot whose colour is COLOUR." (format "/* XPM */ static char * weather_dot[] = { \"18 13 4 1\", \" c None\", \". c #000000\", \"+ c %s\", \"c c %s\", \" \", \" ..... \", \" .ccccc. \", \" .cc+++cc. \", \" .cc+++++cc. \", \" .c+++++++c. \", \" .c+++++++c. \", \" .c+++++++c. \", \" .cc+++++cc. \", \" .cc+++cc. \", \" .ccccc. \", \" ..... \", \" \"};" (cdr (assoc colour *temperature-colours*)) (cdr (assoc (concat "dark-"colour) *temperature-colours*)))) (defvar *temperature-ranges* `(((lambda (temp) (< temp 20)) . ,(weather-dot "blue")) ((lambda (temp) (< temp 30)) . ,(weather-dot "orange")) ((lambda (temp) t) . ,(weather-dot "red")))) (defun temperature-icon (temperature) (cdr (find-if (lambda (range) (funcall (first range) temperature)) *temperature-ranges*))) (defvar *current-temperature* 0) (defvar *current-forecast* "") (defun weather-show-on-modeline () `(" " (:propertize "!" help-echo ,*current-forecast* display (image :type xpm :data ,(temperature-icon *current-temperature*) :ascent center)) ,(format "%s%sC " *current-temperature* (if window-system (string 176) "'")))) (defvar *temperature-timer* nil) (setq *temperature-timer* (run-at-time nil (* 15 60) 'temperature-update)) (push '(:eval (weather-show-on-modeline)) global-mode-string) (provide 'temperature) ;;; temperature.el ends here