suppress warning on the first invocation
[spray] / spray.el
1 (require 'face-remap)
2
3 ;; custom
4 (defvar spray-wpm 400 "words/min")
5 (defvar spray-height 400 "height of characters")
6
7 (make-face 'spray-base-face)
8 (set-face-attribute 'spray-base-face nil
9 :background (face-background 'default)
10 :foreground (face-foreground 'default))
11
12 (make-face 'spray-orp-face)
13 (set-face-attribute 'spray-orp-face nil
14 :foreground "red"
15 :overline (face-foreground 'default)
16 :underline (face-foreground 'default))
17
18 ;; internal variables
19 (defvar spray--base-overlay nil)
20 (defvar spray--orp-overlay nil)
21 (defvar spray--timer nil)
22 (defvar spray--delay 0)
23 (defvar spray--saved-cursor-type nil)
24
25 (define-minor-mode spray-mode
26 "spray mode"
27 :init nil
28 :global nil
29 (cond (spray-mode
30 (let ((buffer-face-mode-face `(:height ,spray-height)))
31 (buffer-face-mode 1))
32 (setq spray--base-overlay (make-overlay (point-min) (point-max))
33 spray--orp-overlay (make-overlay 0 0)
34 spray--timer (run-with-timer 0 (/ 60.0 spray-wpm) 'spray-next)
35 spray--saved-cursor-type cursor-type)
36 (setq cursor-type nil)
37 (overlay-put spray--base-overlay 'priority 100)
38 (overlay-put spray--base-overlay 'face 'spray-base-face)
39 (overlay-put spray--orp-overlay 'priority 101)
40 (overlay-put spray--orp-overlay 'face 'spray-orp-face)
41 (add-hook 'pre-command-hook 'turn-off-spray-mode))
42 (t
43 (buffer-face-mode -1)
44 (widen)
45 (setq cursor-type spray--saved-cursor-type)
46 (delete-overlay spray--base-overlay)
47 (delete-overlay spray--orp-overlay)
48 (cancel-timer spray--timer)
49 (remove-hook 'pre-command-hook 'turn-off-spray-mode))))
50
51 (defun turn-on-spray-mode () (interactive) (spray-mode 1))
52 (defun turn-off-spray-mode () (interactive) (spray-mode -1))
53
54 (defun spray-next ()
55 (cond ((not (zerop spray--delay))
56 (setq spray--delay (1- spray--delay))
57 (when (= spray--delay 2)
58 (narrow-to-region (point) (point))))
59 (t
60 (widen)
61 (if (eobp)
62 (turn-off-spray-mode)
63 (skip-chars-forward "\s\t\n")
64 (let* ((beg (point))
65 (len (skip-chars-forward "^\s\t\n"))
66 (end (point))
67 (orp (+ beg (cl-case len
68 ((1) 1)
69 ((2 3 4 5) 2)
70 ((6 7 8 9) 3)
71 ((10 11 12 13) 4)
72 (t 5)))))
73 (setq spray--delay (+ (if (> len 9) 1 0)
74 (if (eql (char-after) ?\n) 3 0)
75 (cl-case (char-before)
76 ((?. ?! ?\? ?\;) 3)
77 ((?, ?:) 1)
78 (t 0))))
79 (move-overlay spray--orp-overlay (1- orp) orp)
80 (move-overlay spray--base-overlay beg end)
81 (overlay-put spray--base-overlay
82 'before-string (make-string (- 5 (- orp beg)) ?\s))
83 (narrow-to-region beg end))))))
84
85 (provide 'spray)