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