X-Git-Url: https://iankelling.org/git/?p=spray;a=blobdiff_plain;f=spray.el;h=8e3b9225cf37568d1037e02b3391f4a325daba09;hp=402bf0fa0ccdd4d5b5980dfe05e239449ac66dd4;hb=56e5f215f349620f23022947e00676d29bd38794;hpb=ab71fea6c85c4b6094f25df18cdc2459d65dfddb diff --git a/spray.el b/spray.el index 402bf0f..8e3b922 100644 --- a/spray.el +++ b/spray.el @@ -1,90 +1,249 @@ -;; custom +;;; cedit.el --- a speed reading mode + +;; Copyright (C) 2014 zk_phi + +;; 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 of the License, 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; if not, write to the Free Software +;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +;; Author: zk_phi +;; URL: http://hins11.yu-yake.com/ +;; Author: Ian Kelling +;; Version: 0.0.1 + +;;; Commentary: + +;; Put this script into a "load-path"ed directory, and load it in your +;; init file. +;; +;; (require 'spray) +;; +;; Then you may run spray with "M-x spray-mode". Binding some keys may +;; also be useful. +;; +;; (global-set-key (kbd "") 'spray-mode) +;; +;; For more informations, see Readme.org. + +;;; Change Log: +;; 0.0.0 test release +;; 0.0.1 add spray-set-margins + +;;; Code: + +(require 'face-remap) + +;; * customizable vars + (defvar spray-wpm 400 "words/min") -(defvar spray-text-scale 5) -(defvar spray-orp-face 'error) +(defvar spray-height 400 "height of characters") +(defvar spray-margin-top 1 "character margin at top of buffer. Characters are as big as spray text characters.") +(defvar spray-margin-left 0 "character margin at left of buffer. Characters are as big as spray text characters.") -;; internal variables for spraying -(defvar spray--padding-overlay nil) +(defvar spray-mode-map + (let ((km (make-sparse-keymap))) + (define-key km (kbd "SPC") 'spray-start/stop) + (define-key km (kbd "h") 'spray-backward-word) + (define-key km (kbd "l") 'spray-forward-word) + (define-key km (kbd "") 'spray-backward-word) + (define-key km (kbd "") 'spray-forward-word) + (define-key km (kbd "f") 'spray-faster) + (define-key km (kbd "q") 'spray-quit) + (define-key km (kbd "") 'spray-quit) + km) + "keymap for spray-mode buffers") + +;; * faces + +(make-face 'spray-base-face) +(set-face-attribute 'spray-base-face nil + :background (face-background 'default) + :foreground (face-foreground 'default) + :slant 'normal) + +(make-face 'spray-accent-face) +(set-face-attribute 'spray-accent-face nil + :foreground "red" + :overline (face-foreground 'default) + :underline (face-foreground 'default) + :slant 'normal) + +;; * internal vars + +(defvar spray--margin-string "" + "Currently not used.") +(defvar spray--base-overlay nil) (defvar spray--orp-overlay nil) -(defvar spray--timer nil) +(defvar spray--running nil) (defvar spray--delay 0) - -;; incompatible minor-modes -(defvar spray--saved-global-hl-line-mode nil) -(defvar spray--saved-font-lock-mode nil) -(defvar spray--saved-hl-line-mode nil) (defvar spray--saved-cursor-type nil) +(defvar spray--saved-buffer-face nil) +(defvar spray--saved-restriction nil) + +;; * utility functions + +(defun spray-set-margins () + "Setup spray--margin-string" + (setq spray--margin-string + (concat (make-string spray-margin-top 10) ;; 10 = ascii newline + (make-string spray-margin-left 32)))) ;; 32 = ascii space + +;; * the mode +;;;###autoload (define-minor-mode spray-mode "spray mode" :init nil - :global nil + :keymap spray-mode-map (cond (spray-mode - (setq spray--orp-overlay (make-overlay 0 0) - spray--padding-overlay (make-overlay 0 0) - spray--timer (run-with-timer 0 (/ 60.0 spray-wpm) 'spray-next) - spray--saved-cursor-type cursor-type) + (setq spray--base-overlay (make-overlay (point-min) (point-max)) + spray--orp-overlay (make-overlay 0 0) + spray--saved-cursor-type cursor-type + spray--saved-restriction (and (buffer-narrowed-p) + (cons (point-min) (point-max))) + spray--saved-buffer-face (and (boundp 'buffer-face-mode) + buffer-face-mode + buffer-face-mode-face)) (setq cursor-type nil) - (text-scale-set spray-text-scale) - (overlay-put spray--orp-overlay 'face spray-orp-face) - (add-hook 'pre-command-hook 'turn-off-spray-mode) - ;; disable incompatible minor-modes - (when (boundp 'global-hl-line-mode) - (setq spray--saved-global-hl-line-mode global-hl-line-mode) - (set (make-local-variable 'global-hl-line-mode) nil)) - (when (boundp 'font-lock-mode) - (setq spray--saved-font-lock-mode font-lock-mode) - (font-lock-mode -1)) - (when (boundp 'hl-line-mode) - (setq spray--saved-hl-line-mode hl-line-mode) - (hl-line-mode -1))) + (let ((buffer-face-mode-face `(:height ,spray-height))) + (buffer-face-mode 1)) + (overlay-put spray--base-overlay 'priority 100) + (overlay-put spray--base-overlay 'face 'spray-base-face) + (overlay-put spray--orp-overlay 'priority 101) + (overlay-put spray--orp-overlay 'face 'spray-accent-face) + (spray-start)) (t - (widen) (setq cursor-type spray--saved-cursor-type) - (text-scale-set 0) + (if spray--saved-restriction + (narrow-to-region (car spray--saved-restriction) + (cdr spray--saved-restriction)) + (widen)) + (buffer-face-mode -1) + (if spray--saved-buffer-face + (let ((buffer-face-mode-face spray--saved-buffer-face)) + (buffer-face-mode 1))) + (delete-overlay spray--base-overlay) (delete-overlay spray--orp-overlay) - (delete-overlay spray--padding-overlay) - (cancel-timer spray--timer) - (remove-hook 'pre-command-hook 'turn-off-spray-mode) - ;; restore incompatible minor-modes - (when spray--saved-global-hl-line-mode - (setq global-hl-line-mode spray--saved-global-hl-line-mode)) - (when spray--saved-font-lock-mode - (font-lock-mode 1)) - (when spray--saved-hl-line-mode - (hl-line-mode 1))))) - -(defun turn-on-spray-mode () (interactive) (spray-mode 1)) -(defun turn-off-spray-mode () (interactive) (spray-mode -1)) - -(defun spray-next () + (spray-stop)))) + +(defun spray-quit () + "Exit spray mode." + (interactive) + (spray-mode -1)) + +(defun spray--word-at-point () + (skip-chars-backward "^\s\t\n") + (let* ((beg (point)) + (len (skip-chars-forward "^\s\t\n")) + (end (point)) + (orp (+ beg (cl-case len + ((1) 1) + ((2 3 4 5) 2) + ((6 7 8 9) 3) + ((10 11 12 13) 4) + (t 5))))) + (setq spray--delay (+ (if (> len 9) 1 0) + (if (looking-at "\n[\s\t\n]") 3 0) + (cl-case (char-before) + ((?. ?! ?\? ?\;) 3) + ((?, ?:) 1) + (t 0)))) + (move-overlay spray--orp-overlay (1- orp) orp) + (move-overlay spray--base-overlay beg end) + (spray-set-margins) + (overlay-put spray--base-overlay 'before-string + (concat spray--margin-string + (make-string (- 5 (- orp beg)) ?\s))) + (narrow-to-region beg end))) + +(defun spray--update () (cond ((not (zerop spray--delay)) (setq spray--delay (1- spray--delay)) - (when (and (<= spray--delay 2) - (= (char-before) ?.)) + (when (= spray--delay 2) (narrow-to-region (point) (point)))) (t (widen) (if (eobp) - (turn-off-spray-mode) + (spray-mode -1) (skip-chars-forward "\s\t\n") - (let* ((beg (point)) - (len (skip-chars-forward "^\s\t\n")) - (end (point)) - (orp (+ beg (cl-case len - ((1) 1) - ((2 3 4 5) 2) - ((6 7 8 9) 3) - ((10 11 12 13) 4) - (t 5))))) - (setq spray--delay (+ (if (> len 8) 1 0) (cl-case (char-before) - ((?. ?! ?\? ?\;) 3) - ((?, ?:) 1) - (t 0)))) - (overlay-put spray--padding-overlay - 'before-string (make-string (- 5 (- orp beg)) ?\s)) - (move-overlay spray--padding-overlay beg (1+ beg)) - (move-overlay spray--orp-overlay (1- orp) orp) - (narrow-to-region beg end)))))) + (spray--word-at-point))))) + +;; * interactive commands + +(defun spray-start/stop () + "Toggle pause/unpause spray." + (interactive) + (or (spray-stop) (spray-start))) + +(defun spray-stop () + "Pause spray. +Returns t if spray was unpaused." + (interactive) + (prog1 spray--running + (when spray--running + (cancel-timer spray--running) + (setq spray--running nil)))) + +(defun spray-start () + "Start / resume spray." + (interactive) + (setq spray--running + (run-with-timer 0 (/ 60.0 spray-wpm) 'spray--update))) + + +(defun spray-forward-word () + (interactive) + (spray-stop) + (widen) + (skip-chars-forward "\s\t\n") + (spray--word-at-point)) + +(defun spray-backward-word () + (interactive) + (spray-stop) + (widen) + (skip-chars-backward "^\s\t\n") + (skip-chars-backward "\s\t\n") + (spray--word-at-point)) + +(defun spray-faster () + "Increases speed. + +Increases the wpm (words per minute) parameter. See the variable +`spray-wmp'." + (interactive) + (spray-inc-wpm 20)) + +(defun spray-slower () + "Decreases speed. + +Decreases the wpm (words per minute) parameter. See the variable +`spray-wmp'." + (interactive) + (spray-inc-wpm -20)) + +(defun spray-inc-wpm (delta) + (let ((was-running spray--running)) + (spray-stop) + (when (< 10 (+ spray-wpm delta)) + (setq spray-wpm (+ spray-wpm delta))) + (and was-running (spray-backward-word)) + (message "spray wpm: %d" spray-wpm) + (when was-running + (spray-start)))) + +;; * provide (provide 'spray) + +;;; spray.el ends here