branch: externals/greader
commit f5adb0c0c5849b488b12288bf3b64f2d1c8b0b25
Author: Michelangelo Rodriguez <[email protected]>
Commit: Michelangelo Rodriguez <[email protected]>

    greader: add time-based cursor movement API
    
    * greader.el (greader-move-default-seconds): New defcustom.
    Default seconds for time-based seek commands (30).
    (greader-move-default-minutes): New defcustom.
    Default minutes for time-based seek commands (1).
    (greader-move-by-time): New function.  Move point by TIME seconds
    using the backend WPM rate to compute a word offset, then snap to
    the nearest sentence boundary via greader-forward-sentence or
    greader-backward-sentence so reading always resumes at a complete
    sentence.
    (greader--seek): New internal function.  Stop reading, call
    greader-move-by-time, update the register, and resume reading.
    (greader-move-by-seconds-backward, greader-move-by-seconds-forward)
    (greader-move-by-minutes-backward, greader-move-by-minutes-forward):
    New interactive commands.  Accept an optional numeric prefix
    argument; fall back to greader-move-default-seconds or
    greader-move-default-minutes when omitted.
---
 greader.el | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/greader.el b/greader.el
index 152dd6a128..46228e8d3f 100644
--- a/greader.el
+++ b/greader.el
@@ -1886,5 +1886,72 @@ to the next sentence, or when you stop the reading."
 (define-obsolete-function-alias 'greader-toggle-auto-tired-mode
   'greader-auto-tired-mode "0.16")
 
+(defcustom greader-move-default-seconds 30
+  "Default number of seconds used by time-based cursor movement commands."
+  :type 'number)
+
+(defcustom greader-move-default-minutes 1
+  "Default number of minutes used by time-based cursor movement commands."
+  :type 'number)
+
+(defun greader-move-by-time (time)
+  "Move point by TIME seconds, using the backend reading rate.
+TIME is in seconds; positive values move forward, negative values move 
backward.
+The number of words to skip is computed as: rate * abs(TIME) / 60, where
+rate is the backend WPM value returned by `greader-get-rate'.
+After the word-level skip, point is snapped to the nearest sentence boundary
+so that reading always resumes at the start of a complete sentence.
+Movement stops at buffer boundaries."
+  (let* ((rate (greader-get-rate))
+         (words (round (* rate (/ (abs time) 60.0)))))
+    (forward-word (if (>= time 0) words (- words)))
+    (if (>= time 0)
+        (greader-forward-sentence)
+      (greader-backward-sentence))))
+
+(defun greader--seek (time)
+  "Stop reading, move point by TIME seconds, and resume.
+Calls `greader-move-by-time' to compute the word offset from the WPM rate."
+  (greader-tts-stop)
+  (greader-move-by-time time)
+  (greader-set-register)
+  (greader-read))
+
+(defun greader-move-by-seconds-backward (&optional seconds)
+  "Move point backward by SECONDS seconds and resume reading.
+Word count is derived from the backend WPM rate via `greader-move-by-time'.
+If SECONDS is omitted, use `greader-move-default-seconds'.
+With a numeric prefix argument, skip that many seconds instead."
+  (interactive "P")
+  (greader--seek (- (if seconds (prefix-numeric-value seconds)
+                      greader-move-default-seconds))))
+
+(defun greader-move-by-minutes-backward (&optional minutes)
+  "Move point backward by MINUTES minutes and resume reading.
+Word count is derived from the backend WPM rate via `greader-move-by-time'.
+If MINUTES is omitted, use `greader-move-default-minutes'.
+With a numeric prefix argument, skip that many minutes instead."
+  (interactive "P")
+  (greader--seek (* -60 (if minutes (prefix-numeric-value minutes)
+                           greader-move-default-minutes))))
+
+(defun greader-move-by-seconds-forward (&optional seconds)
+  "Move point forward by SECONDS seconds and resume reading.
+Word count is derived from the backend WPM rate via `greader-move-by-time'.
+If SECONDS is omitted, use `greader-move-default-seconds'.
+With a numeric prefix argument, skip that many seconds instead."
+  (interactive "P")
+  (greader--seek (if seconds (prefix-numeric-value seconds)
+                   greader-move-default-seconds)))
+
+(defun greader-move-by-minutes-forward (&optional minutes)
+  "Move point forward by MINUTES minutes and resume reading.
+Word count is derived from the backend WPM rate via `greader-move-by-time'.
+If MINUTES is omitted, use `greader-move-default-minutes'.
+With a numeric prefix argument, skip that many minutes instead."
+  (interactive "P")
+  (greader--seek (* 60 (if minutes (prefix-numeric-value minutes)
+                          greader-move-default-minutes))))
+
 (provide 'greader)
 ;;; greader.el ends here

Reply via email to