all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Need help on writing an Emacs extension to help reading text content with timer
@ 2020-01-29 15:19 stardiviner
  2020-01-29 15:50 ` Stephen Berman
  0 siblings, 1 reply; 3+ messages in thread
From: stardiviner @ 2020-01-29 15:19 UTC (permalink / raw)
  To: Emacs Help


When I read a long paragraph, move around text, leave for a while, then get back
to read it will lost the position. So I want to combine package =Spritz (speed
read)= and =beacon=. Make the cursor move animation like =beacon=, and switch buffer
into read-only state, and move around the cursor. Or use =overlay= for simplity.
Make the cursor big and obvious like =beacon=. The inner core logic is like Spritz
speed read.

After reading spray.el source code, I use following code loginc:

  - ~spray-start~
    - ~(run-with-timer 0 (/ 60.0 spray-wpm) 'spray--update)~
      - ~spray--word-at-point~
        - ~make-overlay~ + ~overlay-put~

And here is my source code:

#+begin_src emacs-lisp
(defcustom amread-wps 2
  "Read words per second."
  :type 'number
  :safe #'numberp
  :group 'amread)

(defvar amread--running nil)
(defvar amread--overlay nil)

(defun amread--update ()
  "Moving amread cursor forward."
  (let* ((begin (point))
         (length (+ (skip-chars-forward "^\s\t\n—") (skip-chars-forward "—")))
         (end (point)))
    (if (eobp)
        (amread-stop)
      ;; create the overlay if does not exist
      (unless amread--overlay
        (setq amread--overlay (make-overlay begin end)))
      ;; move forward overlay
      (when amread--overlay
        ;; (delete-overlay amread--overlay)
        (move-overlay amread--overlay begin end))
      (overlay-put amread--overlay
                   'face '((foreground-color . "white")
                           (background-color . "dark green")))
      (skip-chars-forward "\s\t\n—"))))

(defun amread-start ()
  "Start / resume amread."
  (interactive)
  (setq qamread--running
        (run-with-timer 0 (/ 1.0 amread-wps) #'amread--update)))

(defun amread-stop ()
  "Stop amread."
  (interactive)
  (prog1 amread--running
    (when amread--running
      (cancel-timer amread--running)
      (setq amread--running nil)
      (delete-overlay amread--overlay))))

(defvar amread-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "q") 'amread-stop)
    (define-key map [remap keyaobrd-quit] 'amread-stop)
    map)
  "Keymap for amread-mode buffers.")

(define-minor-mode amread-mode
  "I'm reading qmode."
  :init nil
  :keymap amread-mode-map
  (if amread--running
      (amread-stop)
    (amread-start)))
#+end_src

But the problem is that I can't stop this timer with defined keybinding =[q]= nor
with minor mode toggle command =amread-mode=.

I don't know where is the problem. can someone help me to review my code?

BTW, if someone can have better solution to integrate =beacon.el= package, it
might be an alternative solution, will looks better with animation. Even though
using property on words is simple and clean.

-- 
[ stardiviner ]
       I try to make every word tell the meaning what I want to express.

       Blog: https://stardiviner.github.io/
       IRC(freenode): stardiviner, Matrix: stardiviner
       GPG: F09F650D7D674819892591401B5DF1C95AE89AC3
      



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-01-30  6:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-29 15:19 Need help on writing an Emacs extension to help reading text content with timer stardiviner
2020-01-29 15:50 ` Stephen Berman
2020-01-30  6:25   ` [SOLVED] " stardiviner

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.