help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Need help on writing an Emacs extension to help reading text content wit


From: stardiviner
Subject: Need help on writing an Emacs extension to help reading text content with timer
Date: Wed, 29 Jan 2020 23:19:41 +0800
User-agent: mu4e 1.3.2; emacs 27.0.50

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
      



reply via email to

[Prev in Thread] Current Thread [Next in Thread]