diff options
Diffstat (limited to 'emacs.d/nxhtml/util/pause.el')
-rw-r--r-- | emacs.d/nxhtml/util/pause.el | 794 |
1 files changed, 794 insertions, 0 deletions
diff --git a/emacs.d/nxhtml/util/pause.el b/emacs.d/nxhtml/util/pause.el new file mode 100644 index 0000000..2e98d36 --- /dev/null +++ b/emacs.d/nxhtml/util/pause.el @@ -0,0 +1,794 @@ +;;; pause.el --- Take a break! +;; +;; Author: Lennart Borgman (lennart O borgman A gmail O com) +;; Created: 2008-01-19 Sat +(defconst pause:version "0.70");; Version: +;; Last-Updated: 2010-01-18 Mon +;; URL: +;; Keywords: +;; Compatibility: +;; +;; Features that might be required by this library: +;; +;; None +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; If you are using Emacs then don't you need a little reminder to +;; take a pause? This library makes Emacs remind you of that. And +;; gives you a link to a yoga exercise to try in the pause. +;; +;; There are essentially two different ways to use this library. +;; Either you run a separate Emacs process that just reminds you of +;; pauses. To use it that way see `pause-start-in-new-emacs'. +;; +;; Or run it in the current Emacs. To do that add to your .emacs +;; +;; (require 'pause) +;; +;; and do +;; +;; M-x customize-group RET pause RET +;; +;; and set `pause-mode' to t. +;; +;; +;; Note: I am unsure if it works on all systems to use a separate +;; Emacs process. It does work on w32 though. Please tell me +;; about other systems. +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program 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 program 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 this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;;;###autoload +(defgroup pause nil + "Customize your health personal Emacs health saver!" + :group 'convenience) + +(defcustom pause-after-minutes 15 + "Pause after this number of minutes." + :type 'number + :group 'pause) + +(defcustom pause-1-minute-delay 60 + "Number of seconds to wait in 1 minutes delay." + :type 'number + :group 'pause) + +(defcustom pause-idle-delay 5 + "Seconds to wait for user to be idle before pause." + :type 'number + :group 'pause) + +(defcustom pause-even-if-not-in-emacs t + "Jump up pause even if not in Emacs." + :type 'boolean + :group 'pause) + +(defcustom pause-restart-anyway-after 2 + "If user does not use Emacs restart timer after this minutes. +This is used when a user has clicked a link." + :type 'number + :group 'pause) + +(defcustom pause-tell-again-after 2 + "If user does not exit pause tell again after this minutes." + :type 'number + :group 'pause) + +(defcustom pause-extra-fun 'pause-start-get-yoga-poses + "Function to call for extra fun when pausing. +Default is to show a link to a yoga exercise (recommended!). + +Set this variable to nil if you do not want any extra fun. + +If this variable's value is a function it will be called when the +pause frame has just been shown." + :type '(choice (function :tag "Extra function") + (const :tag "No extra function" nil)) + :group 'pause) + +(defvar pause-exited-from-button nil) + +(defcustom pause-background-color "orange" + "Background color during pause." + :type 'color + :group 'pause) + +(defcustom pause-mode-line-color "sienna" + "Mode line color during pause." + :type 'color + :group 'pause) + +(defcustom pause-1-minute-mode-line-color "yellow" + "Mode line color during 1 minute phase of pause." + :type 'color + :group 'pause) + +(defface pause-text-face + '((t (:foreground "sienna" :height 1.5 :bold t))) + "Face main text in pause buffer." + :group 'pause) + +(defface pause-info-text-face + '((t (:foreground "yellow"))) + "Face info text in pause buffer." + :group 'pause) + +(defface pause-message-face + '((t (:inherit secondary-selection))) + "Face for pause messages." + :group 'pause) + +(defface pause-1-minute-message-face + '((t (:inherit mode-line-inactive))) + "Face for pause messages." + :group 'pause) + +(defcustom pause-break-text + (concat "\n\tHi there," + "\n\tYou are worth a PAUSE!" + "\n\nTry some mindfulness:" + "\n\t- Look around and observe." + "\n\t- Listen." + "\n\t- Feel your body.") + "Text to show during pause." + :type 'integer + :group 'pause) + +(defvar pause-el-file (or load-file-name + (when (boundp 'bytecomp-filename) bytecomp-filename) + buffer-file-name)) + +(defvar pause-default-img-dir + (let ((this-dir (file-name-directory pause-el-file))) + (expand-file-name "../etc/img/pause/" this-dir))) + +(defcustom pause-img-dir pause-default-img-dir + "Image directory for pause. +A random image is choosen from this directory for pauses." + :type 'directory + :group 'pause) + + + +(defvar pause-timer nil) + +;;(defvar pause-break-exit-calls nil) + +(defun pause-start-timer () + (pause-start-timer-1 (* 60 pause-after-minutes))) + +(defun pause-start-timer-1 (sec) + (pause-cancel-timer) + (setq pause-timer (run-with-timer sec nil 'pause-pre-break))) + +(defun pause-one-minute () + "Give you another minute ..." + (pause-start-timer-1 pause-1-minute-delay) + (message (propertize " OK, I will come back in a minute! -- greatings from pause" + 'face 'pause-message-face))) + +(defun pause-save-me () + (pause-start-timer) + (message (propertize " OK, I will save you again in %d minutes! -- greatings from pause " + 'face 'pause-message-face) + pause-after-minutes)) + +(defun pause-pre-break () + (condition-case err + (save-match-data ;; runs in timer + (pause-cancel-timer) + (setq pause-timer (run-with-idle-timer pause-idle-delay nil 'pause-break-in-timer))) + (error + (lwarn 'pause-pre-break + :error "%s" (error-message-string err))))) + +(defvar pause-break-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [(control meta shift ?p)] 'pause-break-exit) + (define-key map [tab] 'forward-button) + (define-key map [(meta tab)] 'backward-button) + (define-key map [(shift tab)] 'backward-button) + (define-key map [backtab] 'backward-button) + map)) + +(defvar pause-buffer nil) +(defvar pause-frame nil) + +(define-derived-mode pause-break-mode nil "Pause" + "Mode used during pause in pause buffer. + +It defines the following key bindings: + +\\{pause-break-mode-map}" + (set (make-local-variable 'buffer-read-only) t) + (setq show-trailing-whitespace nil) + ;;(set (make-local-variable 'cursor-type) nil) + ;; Fix-me: workaround for emacs bug + ;;(run-with-idle-timer 0 nil 'pause-hide-cursor) + ) + +;; Fix-me: make one state var +(defvar pause-break-exit-active nil) +(defvar pause-break-1-minute-state nil) + + +(defun pause-break () + (pause-cancel-timer) + (let ((wcfg (current-frame-configuration)) + (old-mode-line-bg (face-attribute 'mode-line :background)) + old-frame-bg-color + old-frame-left-fringe + old-frame-right-fringe + old-frame-tool-bar-lines + old-frame-menu-bar-lines + old-frame-vertical-scroll-bars) + (dolist (f (frame-list)) + (add-to-list 'old-frame-bg-color (cons f (frame-parameter f 'background-color))) + (add-to-list 'old-frame-left-fringe (cons f (frame-parameter f 'left-fringe))) + (add-to-list 'old-frame-right-fringe (cons f (frame-parameter f 'right-fringe))) + (add-to-list 'old-frame-tool-bar-lines (cons f (frame-parameter f 'tool-bar-lines))) + (add-to-list 'old-frame-menu-bar-lines (cons f (frame-parameter f 'menu-bar-lines))) + (add-to-list 'old-frame-vertical-scroll-bars (cons f (frame-parameter f 'vertical-scroll-bars)))) + + ;; Fix-me: Something goes wrong with the window configuration, try a short pause + (remove-hook 'window-configuration-change-hook 'pause-break-exit) + (run-with-idle-timer 0.2 nil 'pause-break-show) + (setq pause-break-exit-active nil) + (setq pause-break-1-minute-state nil) ;; set in `pause-break-show' + (setq pause-exited-from-button nil) + (unwind-protect + (let ((n 0) + (debug-on-error nil)) + (while (and (> 3 (setq n (1+ n))) + (not pause-break-exit-active) + (not pause-break-1-minute-state)) + (condition-case err + (recursive-edit) + (error (message "%s" (error-message-string err)))) + (unless (or pause-break-exit-active + pause-break-1-minute-state) + (when (> 2 n) (message "Too early to pause (%s < 2)" n)) + (add-hook 'window-configuration-change-hook 'pause-break-exit)))) + + (remove-hook 'window-configuration-change-hook 'pause-break-exit) + (pause-tell-again-cancel-timer) + ;;(set-frame-parameter nil 'background-color "white") + (dolist (f (frame-list)) + (set-frame-parameter f 'background-color (cdr (assq f old-frame-bg-color))) + (set-frame-parameter f 'left-fringe (cdr (assq f old-frame-left-fringe))) + (set-frame-parameter f 'right-fringe (cdr (assq f old-frame-right-fringe))) + (set-frame-parameter f 'tool-bar-lines (cdr (assq f old-frame-tool-bar-lines))) + (set-frame-parameter f 'menu-bar-lines (cdr (assq f old-frame-menu-bar-lines))) + (set-frame-parameter f 'vertical-scroll-bars (cdr (assq f old-frame-vertical-scroll-bars)))) + ;; Fix-me: The frame grows unless we do redisplay here: + (redisplay t) + (set-frame-configuration wcfg t) + (when pause-frame(lower-frame pause-frame)) + (set-face-attribute 'mode-line nil :background old-mode-line-bg) + (run-with-idle-timer 2.0 nil 'run-hooks 'pause-break-exit-hook) + (kill-buffer pause-buffer) + (cond (pause-exited-from-button + ;; Do not start timer until we start working again. + (run-with-idle-timer 1 nil 'add-hook 'post-command-hook 'pause-save-me-post-command) + ;; But if we do not do that within some minutes then start timer anyway. + (run-with-idle-timer (* 60 pause-restart-anyway-after) nil 'pause-save-me)) + (pause-break-1-minute-state + (run-with-idle-timer 0 nil 'pause-one-minute)) + (t + (run-with-idle-timer 0 nil 'pause-save-me)))))) + +(defun pause-save-me-post-command () + (pause-start-timer)) + +(defvar pause-break-exit-hook nil + "Hook run after break exit. +Frame configuration has been restored when this is run. +Please note that it is run in a timer.") + +(defun pause-break-show () + ;; In timer + (save-match-data + (condition-case err + (pause-break-show-1) + (error + ;;(remove-hook 'window-configuration-change-hook 'pause-break-exit) + (pause-break-exit) + (message "pause-break-show error: %s" (error-message-string err)))))) + +(defvar pause-break-last-wcfg-change (float-time)) + +(defun pause-break-show-1 () + ;; Do these first if something goes wrong. + (setq pause-break-last-wcfg-change (float-time)) + ;;(run-with-idle-timer (* 1.5 (length (frame-list))) nil 'add-hook 'window-configuration-change-hook 'pause-break-exit) + + ;; fix-me: temporary: + ;;(add-hook 'window-configuration-change-hook 'pause-break-exit) + (unless pause-extra-fun (run-with-idle-timer 1 nil 'pause-break-message)) + (run-with-idle-timer 10 nil 'pause-break-exit-activate) + (setq pause-break-1-minute-state t) + (set-face-attribute 'mode-line nil :background pause-1-minute-mode-line-color) + (with-current-buffer (setq pause-buffer + (get-buffer-create "* P A U S E *")) + (let ((inhibit-read-only t)) + (erase-buffer) + (pause-break-mode) + (setq left-margin-width 25) + (pause-insert-img) + (insert (propertize pause-break-text 'face 'pause-text-face)) + (goto-char (point-min)) + (when (search-forward "mindfulness" nil t) + (make-text-button (- (point) 11) (point) + 'face '(:inherit pause-text-face :underline t) + 'action (lambda (btn) + (browse-url "http://www.jimhopper.com/mindfulness/")))) + (goto-char (point-max)) + (insert (propertize "\n\nClick on a link below to exit pause\n" 'face 'pause-info-text-face)) + ;;(add-text-properties (point-min) (point-max) (list 'keymap (make-sparse-keymap))) + (insert-text-button "Exit pause" + 'action `(lambda (button) + (condition-case err + (pause-break-exit-from-button) + (error (message "%s" (error-message-string err)))))) + (insert "\n") + (dolist (m '(hl-needed-mode)) + (when (and (boundp m) (symbol-value m)) + (funcall m -1))))) + (dolist (f (frame-list)) + (pause-max-frame f)) + (pause-tell-again) + (when pause-extra-fun (funcall pause-extra-fun)) + ;;(setq pause-break-exit-calls 0) + (setq pause-break-last-wcfg-change (float-time)) + (pause-tell-again-start-timer)) + +(defun pause-max-frame (f) + (let* ((avail-width (- (display-pixel-width) + (* 2 (frame-parameter f 'border-width)) + (* 2 (frame-parameter f 'internal-border-width)))) + (avail-height (- (display-pixel-height) + (* 2 (frame-parameter f 'border-width)) + (* 2 (frame-parameter f 'internal-border-width)))) + (cols (/ avail-width (frame-char-width))) + (rows (- (/ avail-height (frame-char-height)) 2))) + ;;(set-frame-parameter (selected-frame) 'fullscreen 'fullboth) + ;;(set-frame-parameter (selected-frame) 'fullscreen 'maximized) + (setq pause-break-last-wcfg-change (float-time)) + (with-selected-frame f + (delete-other-windows (frame-first-window f)) + (with-selected-window (frame-first-window) + (switch-to-buffer pause-buffer) + (goto-char (point-max)))) + (modify-frame-parameters f + `((background-color . ,pause-background-color) + (left-fringe . 0) + (right-fringe . 0) + (tool-bar-lines . 0) + (menu-bar-lines . 0) + (vertical-scroll-bars . nil) + (left . 0) + (top . 0) + (width . ,cols) + (height . ,rows) + )))) + +(defvar pause-tell-again-timer nil) + +(defun pause-tell-again-start-timer () + (pause-tell-again-cancel-timer) + (setq pause-tell-again-timer + (run-with-idle-timer (* 60 pause-tell-again-after) t 'pause-tell-again))) + +(defun pause-tell-again-cancel-timer () + (when (timerp pause-tell-again-timer) + (cancel-timer pause-tell-again-timer)) + (setq pause-tell-again-timer nil)) + +(defun pause-tell-again () + (when (and window-system pause-even-if-not-in-emacs) + (pause-max-frame pause-frame) + (raise-frame pause-frame))) + + +(defun pause-break-message () + (when (/= 0 (recursion-depth)) + (message "%s" (propertize "Please take a pause! (Or exit now to take it in 1 minute.)" + 'face 'pause-1-minute-message-face)))) + +(defun pause-break-exit-activate () + (when (/= 0 (recursion-depth)) + (setq pause-break-exit-active t) + (setq pause-break-1-minute-state nil) + (set-face-attribute 'mode-line nil :background pause-mode-line-color) + (message nil) + (with-current-buffer pause-buffer + (let ((inhibit-read-only t)) + ;; Fix-me: This interfere with text buttons. + ;;(add-text-properties (point-min) (point-max) (list 'keymap nil)) + )))) + +(defun pause-break-exit () + (interactive) + (let ((elapsed (- (float-time) pause-break-last-wcfg-change))) + ;;(message "elapsed=%s pause-break-last-wcfg-change=%s" elapsed pause-break-last-wcfg-change) + (setq pause-break-last-wcfg-change (float-time)) + (when (> elapsed 1.0) + (setq pause-break-exit-active t) + (remove-hook 'window-configuration-change-hook 'pause-break-exit) + ;;(pause-tell-again-cancel-timer) + (when (/= 0 (recursion-depth)) + (exit-recursive-edit))))) + +(defun pause-break-exit-from-button () + (setq pause-break-1-minute-state nil) + (setq pause-exited-from-button t) + (pause-break-exit)) + +(defun pause-insert-img () + (let* ((inhibit-read-only t) + img + src + (slice '(0 0 200 300)) + (imgs (directory-files pause-img-dir nil nil t)) + skip + ) + (setq imgs (delete nil + (mapcar (lambda (d) + (unless (file-directory-p d) d)) + imgs))) + (if (not imgs) + (setq img "No images found") + (setq skip (random (length imgs))) + (while (> skip 0) + (setq skip (1- skip)) + (setq imgs (cdr imgs))) + (setq src (expand-file-name (car imgs) pause-img-dir)) + (if (file-exists-p src) + (condition-case err + (setq img (create-image src nil nil + :relief 1 + ;;:margin inlimg-margins + )) + (error (setq img (error-message-string err)))) + (setq img (concat "Image not found: " src)))) + (if (stringp img) + (insert img) + (insert-image img nil 'left-margin slice) + ) + )) + +(defun pause-hide-cursor () + ;; runs in timer, save-match-data + (with-current-buffer pause-buffer + (set (make-local-variable 'cursor-type) nil))) + +(defun pause-cancel-timer () + (remove-hook 'post-command-hook 'pause-save-me-post-command) + (when (timerp pause-timer) (cancel-timer pause-timer)) + (setq pause-timer nil)) + +(defun pause-break-in-timer () + (save-match-data ;; runs in timer + (pause-cancel-timer) + (if (or (active-minibuffer-window) + (and (boundp 'edebug-active) + edebug-active)) + (let ((pause-idle-delay 5)) + (pause-pre-break)) + (let ((there-was-an-error nil)) + (condition-case err + (pause-break) + (error + (setq there-was-an-error t))) + (when there-was-an-error + (condition-case err + (progn + (select-frame last-event-frame) + (let ((pause-idle-delay nil)) + (pause-pre-break))) + (error + (lwarn 'pause-break-in-timer2 :error "%s" (error-message-string err)) + ))))))) + +(defcustom pause-only-when-server-mode t + "Allow `pause-mode' inly in the Emacs that has server-mode enabled. +This is to prevent multiple Emacs with `pause-mode'." + :type 'boolean + :group 'pause) + +;;;###autoload +(define-minor-mode pause-mode + "This minor mode tries to make you take a break. +It will jump up and temporary stop your work - even if you are +not in Emacs. If you are in Emacs it will however try to be +gentle and wait until you have been idle with the keyboard for a +short while. \(If you are not in Emacs it can't be gentle. How +could it?) + +Then it will show you a special screen with a link to a yoga +exercise you can do when you pause. + +After the pause you continue your work where you were +interrupted." + :global t + :group 'pause + :set-after '(server-mode) + (if pause-mode + (if (and pause-only-when-server-mode + (not server-mode) + (not (with-no-warnings (called-interactively-p)))) + (progn + (setq pause-mode nil) + (message "Pause mode canceled because not server-mode")) + (pause-start-timer)) + (pause-cancel-timer))) + +;; (emacs-Q "-l" buffer-file-name "--eval" "(pause-temp-err)") +;; (emacs-Q "-l" buffer-file-name "--eval" "(run-with-timer 1 nil 'pause-temp-err)") +;; (pause-temp-err) +(defun pause-temp-err () + (switch-to-buffer (get-buffer-create "pause-temp-err buffer")) + (setq buffer-read-only t) + (let ((inhibit-read-only t)) + (add-text-properties (point-min) (point-max) (list 'keymap nil)) + (insert-text-button "click to test" + 'action (lambda (btn) + (message "Click worked"))) + ;;(add-text-properties (point-min) (point-max) (list 'keymap nil)) + )) + +;; (customize-group-other-window 'pause) +;; (apply 'custom-set-variables (pause-get-group-saved-customizations 'pause custom-file)) +;; (pause-get-group-saved-customizations 'w32shell custom-file) +(defun pause-get-group-saved-customizations (group cus-file) + "Return customizations saved for GROUP in CUS-FILE." + (let* ((cus-buf (find-buffer-visiting cus-file)) + (cus-old cus-buf) + (cus-point (when cus-old (with-current-buffer cus-old (point)))) + (cusg-all (get group 'custom-group)) + (cusg-vars (delq nil (mapcar (lambda (elt) + (when (eq (nth 1 elt) 'custom-variable) + (car elt))) + cusg-all))) + cus-vars-form + cus-face-form + cus-saved-vars + cus-saved-face) + (unless cus-buf (setq cus-buf (find-file-noselect cus-file))) + (with-current-buffer cus-buf + (save-restriction + (widen) + (goto-char (point-min)) + (while (progn + (while (progn (skip-chars-forward " \t\n\^l") + (looking-at ";")) + (forward-line 1)) + (not (eobp))) + (let ((form (read (current-buffer)))) + (cond + ((eq (car form) 'custom-set-variables) + (setq cus-vars-form form)) + ((eq (car form) 'custom-set-faces) + (setq cus-face-form form)) + ))))) + (dolist (vl (cdr cus-vars-form)) + (when (memq (car (cadr vl)) cusg-vars) + (setq cus-saved-vars (cons (cadr vl) cus-saved-vars)))) + cus-saved-vars)) + +;; (emacs-Q "-l" buffer-file-name "--eval" "(pause-start 0.1 nil)") +(defun pause-start (after-minutes cus-file) + "Start `pause-mode' with interval AFTER-MINUTES. +This bypasses `pause-only-when-server-mode'. + +You can use this funciton to start a separate Emacs process that +handles pause, for example like this if you want a pause every 15 +minutes: + + emacs -Q -l pause --eval \"(pause-start 15 nil)\" + +Note: Another easier alternative might be to use + `pause-start-in-new-emacs'." + (interactive "nPause after how many minutes: ") + (pause-start-1 after-minutes cus-file)) + +(defun pause-start-1 (after-minutes cus-file) + (setq debug-on-error t) + (pause-cancel-timer) + (when (and cus-file (file-exists-p cus-file)) + (let ((args (pause-get-group-saved-customizations 'pause cus-file))) + ;;(message "cus-file=%S" cus-file) + ;;(message "args=%S" args) + (apply 'custom-set-variables args))) + (setq pause-after-minutes after-minutes) + (let ((pause-only-when-server-mode nil)) + (pause-mode 1)) + (switch-to-buffer (get-buffer-create "Pause information")) + (insert (propertize "Emacs pause\n" + 'face '(:inherit variable-pitch :height 1.5))) + (insert (format "Pausing every %d minute.\n" after-minutes)) + (insert "Or, ") + (insert-text-button "pause now" + 'action `(lambda (button) + (condition-case err + (pause-break) + (error (message "%s" (error-message-string err)))))) + (insert "!\n") + ;;(setq buffer-read-only t) + (pause-break-mode) + (delete-other-windows) + (setq mode-line-format nil) + (setq pause-frame (selected-frame)) + (message nil) + (set-frame-parameter nil 'background-color pause-background-color)) + +;; (pause-start-in-new-emacs 0.3) +;; (pause-start-in-new-emacs 15) +;;;###autoload +(defun pause-start-in-new-emacs (after-minutes) + "Start pause with interval AFTER-MINUTES in a new Emacs instance. +The new Emacs instance will be started with -Q. However if +`custom-file' is non-nil it will be loaded so you can still +customize pause. + +One way of using this function may be to put in your .emacs +something like + + ;; for just one Emacs running pause + (when server-mode (pause-start-in-new-emacs 15)) + +See `pause-start' for more info. + +" + (interactive (list pause-after-minutes)) + (let* ((this-emacs (locate-file invocation-name + (list invocation-directory) + exec-suffixes)) + (cus-file (if custom-file custom-file "~/.emacs")) + (args `("-l" ,pause-el-file + "--geometry=40x3" + "-D" + "--eval" ,(format "(pause-start %s %S)" after-minutes cus-file)))) + (setq args (cons "-Q" args)) + (apply 'call-process this-emacs nil 0 nil args))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Link to yoga poses + +;; (defun w3-download-callback (fname) +;; (let ((coding-system-for-write 'binary)) +;; (goto-char (point-min)) +;; (search-forward "\n\n" nil t) +;; (write-region (point) (point-max) fname)) +;; (url-mark-buffer-as-dead (current-buffer)) +;; (message "Download of %s complete." (url-view-url t)) +;; (sit-for 3)) + +;;(run-with-idle-timer 0 nil 'pause-get-yoga-poses) +(defvar pause-yoga-poses-host-url "http://www.abc-of-yoga.com/") + +;;(pause-start-get-yoga-poses) +(defun pause-start-get-yoga-poses () + (require 'url-vars) + (let ((url-show-status nil)) ;; do not show download messages + (url-retrieve (concat pause-yoga-poses-host-url "yogapractice/mountain.asp") + 'pause-callback-get-yoga-poses))) + +(defun pause-callback-get-yoga-poses (status) + (let ((pose (pause-random-yoga-pose (pause-get-yoga-poses-1 (current-buffer))))) + (message nil) + (when (and pose (buffer-live-p pause-buffer)) + (pause-insert-yoga-link pose)))) + +(defun pause-insert-yoga-link (pose) + (with-current-buffer pause-buffer + (let ((here (point)) + (inhibit-read-only t) + (pose-url (concat pause-yoga-poses-host-url (car pose)))) + (goto-char (point-max)) + (insert "Link to yoga posture for you: ") + (insert-text-button (cdr pose) + 'action `(lambda (button) + (condition-case err + (progn + (browse-url ,pose-url) + (run-with-idle-timer 1 nil 'pause-break-exit-from-button)) + (error (message "%s" (error-message-string err)))))) + (insert "\n") + (pause-break-message)))) + +(defun pause-get-yoga-poses () + (let* ((url-show-status nil) ;; do not show download messages + (buf (url-retrieve-synchronously "http://www.abc-of-yoga.com/yogapractice/mountain.asp"))) + (pause-get-yoga-poses-1 buf))) + +;; (setq x (url-retrieve-synchronously "http://www.abc-of-yoga.com/yogapractice/mountain.asp")) +;; (setq x (url-retrieve-synchronously "http://www.emacswiki.org/emacs/EmacsFromBazaar")) + +;; (defun temp-y () +;; (message "before y") +;; ;;(setq y (url-retrieve-synchronously "http://www.emacswiki.org/emacs/EmacsFromBazaar")) +;; (setq x (url-retrieve-synchronously "http://www.abc-of-yoga.com/yogapractice/mountain.asp")) +;; (message "after x") +;; ) +;; (run-with-idle-timer 0 nil 'temp-y) + +(defun pause-get-yoga-poses-1 (buf) + (require 'url) + (setq url-debug t) + ;; url-insert-file-contents + (let* ((first-marker "<p>These are all the Yoga Poses covered in this section:</p>") + (table-patt "<table\\(?:.\\|\n\\)*?</table>") + table-beg + table-end + (pose-patt "<A HREF=\"\\([^\"]*?\\)\" class=\"LinkBold\">\\([^<]*?\\)</A>") + poses + (trouble-msg + (catch 'trouble + ;;(switch-to-buffer-other-window buf) + (with-current-buffer buf + (goto-char 1) + (rename-buffer "YOGA" t) + (unless (search-forward first-marker nil t) + (throw 'trouble "Can't find marker for the poses on the page")) + (backward-char 10) + (unless (re-search-forward table-patt nil t) + (throw 'trouble "Can't find table with poses on the page")) + (setq table-beg (match-beginning 0)) + (setq table-end (match-end 0)) + (goto-char table-beg) + (while (re-search-forward pose-patt table-end t) + (setq poses (cons (cons (match-string 1) (match-string 2)) + poses))) + (unless poses + (throw 'trouble "Can't find poses in table on the page")) + (kill-buffer) + nil)))) + (if trouble-msg + (progn + (message "%s" trouble-msg) + nil) + (message "Number of yoga poses found=%s" (length poses)) + poses))) + +(defun pause-random-yoga-pose (poses) + (when poses + (random t) + (let* ((n-poses (length poses)) + (pose-num (random (1- n-poses))) + (the-pose (nth pose-num poses))) + the-pose))) + +;;(pause-random-yoga-pose (pause-get-yoga-poses)) + +(provide 'pause) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; pause.el ends here |