branch: elpa/subed commit 56b2ff242c45dab912bbe8a1181da97b0e5e233d Author: Random User <rnd...@posteo.de> Commit: Random User <rnd...@posteo.de>
Move most of the insertion complexity to subed.el Subtitle format implementations now only need to be able to insert a single subtitle with a given ID, start time, stop time and text. All the complexity of parsing the pargument, managing subtitle length and spacing, dealing with edge cases (e.g. before first/after last subtitle), etc are now handled generically in `subed-insert-subtitle`. --- subed/subed-config.el | 6 +- subed/subed-srt.el | 136 +++++----- subed/subed.el | 86 ++++++- tests/test-subed-srt.el | 643 ++++++++++++++++++++++++++++++++---------------- tests/test-subed.el | 237 ++++++++++++++++++ 5 files changed, 812 insertions(+), 296 deletions(-) diff --git a/subed/subed-config.el b/subed/subed-config.el index 8ae7294..c03c067 100644 --- a/subed/subed-config.el +++ b/subed/subed-config.el @@ -41,7 +41,7 @@ (define-key subed-mode-map (kbd "C-M-p") #'subed-move-subtitle-backward) (define-key subed-mode-map (kbd "C-M-f") #'subed-shift-subtitle-forward) (define-key subed-mode-map (kbd "C-M-b") #'subed-shift-subtitle-backward) - (define-key subed-mode-map (kbd "M-i") #'subed-subtitle-insert) + (define-key subed-mode-map (kbd "M-i") #'subed-insert-subtitle) (define-key subed-mode-map (kbd "M-k") #'subed-subtitle-kill) (define-key subed-mode-map (kbd "M-s") #'subed-sort) (define-key subed-mode-map (kbd "M-SPC") #'subed-mpv-toggle-pause) @@ -166,8 +166,8 @@ If set to zero or smaller, playback is paused." :type 'integer :group 'subed) -(defcustom subed-default-subtitle-length 1.0 - "How long to make subtitles in seconds when inserted after the last subtitle." +(defcustom subed-default-subtitle-length 1000 + "How long to make subtitles in milliseconds when inserted after the last subtitle." :type 'float :group 'subed) diff --git a/subed/subed-srt.el b/subed/subed-srt.el index fc3453d..c873ddb 100644 --- a/subed/subed-srt.el +++ b/subed/subed-srt.el @@ -345,86 +345,66 @@ Return the new subtitle stop time in milliseconds." (when (looking-at subed-srt--regexp-timestamp) (replace-match (subed-srt--msecs-to-timestamp msecs)))))) -(defun subed-srt--subtitle-insert (&optional arg) - "Insert subtitle(s). - -ARG, usually provided by `universal-argument', is used in the -following manner: - \\[subed-subtitle-insert] Insert 1 subtitle after the current subtitle - \\[universal-argument] \\[subed-subtitle-insert] Insert 1 subtitle before the current subtitle - \\[universal-argument] 5 \\[subed-subtitle-insert] Insert 5 subtitles after the current subtitle - \\[universal-argument] - 5 \\[subed-subtitle-insert] Insert 5 subtitles before the current subtitle - \\[universal-argument] \\[universal-argument] \\[subed-subtitle-insert] Insert 2 subtitles before the current subtitle" +(defun subed-srt--make-subtitle (&optional id start stop text) + "Generate new subtitle string. + +ID, START default to 0. +STOP defaults to (+ START `subed-subtitle-spacing') +TEXT defaults to an empty string. + +A newline is appended to TEXT, meaning you'll get two trailing +newlines if TEXT is nil or empty." + (interactive "P") + (format "%s\n%s --> %s\n%s\n" + (or id 0) + (subed-srt--msecs-to-timestamp (or start 0)) + (subed-srt--msecs-to-timestamp (or stop (+ (or start 0) + subed-default-subtitle-length))) + (or text ""))) + +(defun subed-srt--prepend-subtitle (&optional id start stop text) + "Insert new subtitle before the subtitle at point. + +ID, START default to 0. +STOP defaults to (+ START `subed-subtitle-spacing') +TEXT defaults to an empty string. + +Move point to the text of the inserted subtitle. +Return new point." (interactive "P") + (subed-srt--jump-to-subtitle-id) + (insert (subed-srt--make-subtitle id start stop text)) (save-match-data - (let* ((number-of-subs (cond ((not arg) 1) ;; M-i - ((integerp arg) arg) ;; C-u N M-i / C-u - N M-i - ;; C-u [C-u ...] M-i / C-u - [C-u ...] M-i - ((consp arg) (* (truncate (log (abs (car arg)) 4)) ;; ([-]64) -> 3 - (/ (car arg) (abs (car arg))))) ;; Restore sign - (t 1))) ;; C-u - M-i (Is there anything else is left?) - (insert-before (or (< number-of-subs 0) ;; C-u - N M-i - (eq arg '-) ;; C-u - M-i - (consp arg))) ;; C-u [C-u ...] M-i - ;; Ensure number-of-subs is positive, now that we figured out `insert-before' - (number-of-subs (abs number-of-subs))) - (subed-debug "Inserting %s subtitle(s) %s the current" number-of-subs (if insert-before "before" "after")) - (subed-srt--jump-to-subtitle-id) - ;; Move to the ID of the subtitle we're prepending subtitles to so that we - ;; can do (insert "<new subtitle>") - (if insert-before - (subed-srt--jump-to-subtitle-id) - (when (and (not (subed-srt--forward-subtitle-id)) ;; Appending after last subtitle - (> (buffer-size) 0)) ;; Buffer is not empty - ;; There is no ID because we're appending to the last subtitle. We just - ;; have to make sure there is a subtitle delimiter ("\n\n") after the - ;; last subtitle and point is where the new ID will go. - (subed-srt--jump-to-subtitle-end) - (forward-line) - (insert "\n"))) - ;; Insert subtitles - (save-excursion - ;; Find out how much time we have per subtitle - (let* - ;; nil when there's no previous subtitle - ((prev-stop-msecs (save-excursion - (if (looking-at "^[0-9]$") - ;; We're inserting between subtitles or - ;; before the first one - (when (subed-srt--backward-subtitle-id) - (subed-srt--subtitle-msecs-stop)) - ;; We're append after the last subtitle - (subed-srt--subtitle-msecs-stop)))) - ;; nil when there's no next subtitle - (next-start-msecs (when (looking-at "^[0-9]$") - (subed-srt--subtitle-msecs-start))) - ;; nil when there's no next subtitle - (available-msecs (when next-start-msecs - (- next-start-msecs (or prev-stop-msecs 0)))) - ;; Calculate milliseconds per inserted subtitle or use default value - ;; if we're appending to the last subtitle - (sub-msecs (if available-msecs (/ available-msecs number-of-subs) - (* subed-default-subtitle-length 1000)))) - (dotimes (i number-of-subs) - (let* ((start-msecs (+ (or prev-stop-msecs 0) (* sub-msecs i))) - (stop-msecs (+ start-msecs sub-msecs)) - ;; Apply `subed-subtitle-spacing' - (start-msecs-spaced (if (= i 0) - (+ start-msecs subed-subtitle-spacing) - (+ start-msecs (/ subed-subtitle-spacing 2)))) - (stop-msecs-spaced (if (= i (1- number-of-subs)) - (- stop-msecs subed-subtitle-spacing) - (- stop-msecs (/ subed-subtitle-spacing 2))))) - (insert (format "0\n%s --> %s\n\n\n" - (subed-srt--msecs-to-timestamp start-msecs-spaced) - (subed-srt--msecs-to-timestamp stop-msecs-spaced)))))) - ;; If we're not on an ID, that means we added one or more subtitles after - ;; the last one and we can remove the trailing extra newline - (when (looking-at "^[[:blank:]]*$") - (forward-line -1) - (kill-whole-line))) - (subed-srt--regenerate-ids-soon) - (subed-srt--jump-to-subtitle-text)))) + (when (looking-at "\\([[:space:]]*\\|^\\)[0-9]+$") + (insert "\n"))) + (forward-line -2) + (subed-srt--jump-to-subtitle-text)) + +(defun subed-srt--append-subtitle (&optional id start stop text) + "Insert new subtitle after the subtitle at point. + +ID, START default to 0. +STOP defaults to (+ START `subed-subtitle-spacing') +TEXT defaults to an empty string. + +Move point to the text of the inserted subtitle. +Return new point." + (interactive "P") + (unless (subed-srt--forward-subtitle-id) + ;; Point is on last subtitle or buffer is empty + (subed-srt--jump-to-subtitle-end) + ;; Moved point to end of last subtitle; ensure separator exists + (while (not (looking-at "\\(\\`\\|[[:blank:]]*\n[[:blank:]]*\n\\)")) + (save-excursion (insert ?\n))) + ;; Move to end of separator + (goto-char (match-end 0))) + (insert (subed-srt--make-subtitle id start stop text)) + ;; Complete separator with another newline unless we inserted at the end + (save-match-data + (when (looking-at "\\([[:space:]]*\\|^\\)[0-9]+$") + (insert ?\n))) + (forward-line -2) + (subed-srt--jump-to-subtitle-text)) (defun subed-srt--subtitle-kill () "Remove subtitle at point." diff --git a/subed/subed.el b/subed/subed.el index 40ae25d..55b192b 100644 --- a/subed/subed.el +++ b/subed/subed.el @@ -47,15 +47,14 @@ (defalias 'subed-subtitle-msecs-stop #'subed-srt--subtitle-msecs-stop) (defalias 'subed-subtitle-text #'subed-srt--subtitle-text) (defalias 'subed-subtitle-relative-point #'subed-srt--subtitle-relative-point) -(defalias 'subed-set-subtitle-time-start #'subed-srt--set-subtitle-time-start) -(defalias 'subed-set-subtitle-time-stop #'subed-srt--set-subtitle-time-stop) (defalias 'subed-jump-to-subtitle-id #'subed-srt--jump-to-subtitle-id) (defalias 'subed-jump-to-subtitle-time-start #'subed-srt--jump-to-subtitle-time-start) (defalias 'subed-jump-to-subtitle-time-stop #'subed-srt--jump-to-subtitle-time-stop) -(defalias 'subed-jump-to-subtitle-text-at-msecs #'subed-srt--jump-to-subtitle-text-at-msecs) (defalias 'subed-jump-to-subtitle-text #'subed-srt--jump-to-subtitle-text) (defalias 'subed-jump-to-subtitle-end #'subed-srt--jump-to-subtitle-end) +(defalias 'subed-jump-to-subtitle-id-at-msecs #'subed-srt--jump-to-subtitle-id-at-msecs) +(defalias 'subed-jump-to-subtitle-text-at-msecs #'subed-srt--jump-to-subtitle-text-at-msecs) (defalias 'subed-forward-subtitle-id #'subed-srt--forward-subtitle-id) (defalias 'subed-backward-subtitle-id #'subed-srt--backward-subtitle-id) @@ -66,9 +65,14 @@ (defalias 'subed-forward-subtitle-time-stop #'subed-srt--forward-subtitle-time-stop) (defalias 'subed-backward-subtitle-time-stop #'subed-srt--backward-subtitle-time-stop) -(defalias 'subed-subtitle-insert #'subed-srt--subtitle-insert) +(defalias 'subed-set-subtitle-time-start #'subed-srt--set-subtitle-time-start) +(defalias 'subed-set-subtitle-time-stop #'subed-srt--set-subtitle-time-stop) +(defalias 'subed-prepend-subtitle #'subed-srt--prepend-subtitle) +(defalias 'subed-append-subtitle #'subed-srt--append-subtitle) (defalias 'subed-subtitle-kill #'subed-srt--subtitle-kill) (defalias 'subed-sanitize #'subed-srt--sanitize) +(defalias 'subed-regenerate-ids #'subed-srt--regenerate-ids) +(defalias 'subed-regenerate-ids-soon #'subed-srt--regenerate-ids-soon) (defalias 'subed-sort #'subed-srt--sort) @@ -499,6 +503,80 @@ See `subed-move-subtitle-forward' about ARG." (subed-move-subtitles msecs beg))) +;;; Inserting + +(defun subed-insert-subtitle (&optional arg) + "Insert subtitle(s). + +ARG, usually provided by `universal-argument', is used in the +following manner: + \\[subed-insert-subtitle] Insert 1 subtitle after the current subtitle + \\[universal-argument] \\[subed-insert-subtitle] Insert 1 subtitle before the current subtitle + \\[universal-argument] 5 \\[subed-insert-subtitle] Insert 5 subtitles after the current subtitle + \\[universal-argument] - 5 \\[subed-insert-subtitle] Insert 5 subtitles before the current subtitle + \\[universal-argument] \\[universal-argument] \\[subed-insert-subtitle] Insert 2 subtitles before the current subtitle" + (interactive "P") + ;; Parse arg + (atomic-change-group + (let* ((number-of-subs (cond ((not arg) 1) ;; M-i + ((integerp arg) arg) ;; C-u N M-i / C-u - N M-i + ;; C-u [C-u ...] M-i / C-u - [C-u ...] M-i + ((consp arg) (* (truncate (log (abs (car arg)) 4)) ;; ([-]64) -> 3 + (/ (car arg) (abs (car arg))))) ;; Restore sign + (t 1))) ;; C-u - M-i + (insert-before-current (or (< number-of-subs 0) ;; C-u - N M-i + (eq arg '-) ;; C-u - M-i + (consp arg))) ;; C-u [C-u ...] M-i + ;; Ensure number-of-subs is positive, now that we figured out `insert-before-current' + (number-of-subs (abs number-of-subs))) + (subed-debug "Inserting %s subtitle(s) %s the current" + number-of-subs (if insert-before-current "before" "after")) + (let* + ;; Find out how much time there is available + ((msecs-min (save-excursion (if insert-before-current + (when (subed-srt--backward-subtitle-id) + (subed-srt--subtitle-msecs-stop)) + (subed-srt--subtitle-msecs-stop)))) + (msecs-max (save-excursion (if insert-before-current + (subed-srt--subtitle-msecs-start) + (when (subed-srt--forward-subtitle-id) + (subed-srt--subtitle-msecs-start))))) + (msecs-avail (cond ((and msecs-min msecs-max) (- msecs-max msecs-min)) + (msecs-max msecs-max) + (t nil))) ;; Unlimited + (msecs-per-sub (if msecs-avail + (min (/ msecs-avail number-of-subs) + subed-default-subtitle-length) + subed-default-subtitle-length))) + (subed-debug " Available time: min=%S max=%S avail=%S sublen=%S" msecs-min msecs-max msecs-avail msecs-per-sub) + (cl-flet ((insert-subtitle (if insert-before-current + #'subed-prepend-subtitle + #'subed-append-subtitle))) + (dotimes (i number-of-subs) + (let* ((multiplier (if insert-before-current + (- number-of-subs i) + (1+ i))) + (msecs-start (if msecs-avail + ;; Inserting anywhere before the last subtitle + (+ (or msecs-min 0) + (* multiplier (/ msecs-avail (1+ number-of-subs)))) + (if msecs-min + ;; Inserting after the last subtitle + (+ msecs-min + subed-subtitle-spacing + (* (1- multiplier) (+ msecs-per-sub subed-subtitle-spacing))) + ;; Inserting in empty buffer + (* (1- multiplier) (+ msecs-per-sub subed-subtitle-spacing))))) + (msecs-stop (+ msecs-start msecs-per-sub))) + (subed-debug " Inserting new subtitle at %S - %S" msecs-start msecs-stop) + (insert-subtitle nil msecs-start msecs-stop nil))))) + (unless insert-before-current + (dotimes (_ (1- number-of-subs)) + (subed-backward-subtitle-text)))) + (subed-regenerate-ids-soon)) + (point)) + + ;;; Replay time-adjusted subtitle (defun subed-replay-adjusted-subtitle-p () diff --git a/tests/test-subed-srt.el b/tests/test-subed-srt.el index d4d83b4..15efcc3 100644 --- a/tests/test-subed-srt.el +++ b/tests/test-subed-srt.el @@ -675,224 +675,445 @@ Baz. ) -(describe "Inserting" - (before-each - (spy-on 'subed-srt--regenerate-ids-soon)) - (describe "in an empty buffer," - (describe "appending" - (it "a single subtile." - (cl-loop for arg in (list nil 1) do - (with-temp-buffer - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "0\n" - "00:00:00,100 --> 00:00:00,900\n\n")) - (expect (point) :to-equal 33)))) - (it "multiple subtiles." - (cl-loop for arg in (list 2) do - (with-temp-buffer - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "0\n" - "00:00:00,100 --> 00:00:00,950\n\n\n" - "0\n" - "00:00:01,050 --> 00:00:01,900\n\n")) - (expect (point) :to-equal 33))))) - (describe "prepending" - (it "a single subtile." - (cl-loop for arg in (list '- -1 (list 4)) do - (with-temp-buffer - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "0\n" - "00:00:00,100 --> 00:00:00,900\n\n")) - (expect (point) :to-equal 33)))) - (it "multiple subtiles." - (cl-loop for arg in (list -2 (list -16)) do - (with-temp-buffer - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "0\n" - "00:00:00,100 --> 00:00:00,950\n\n\n" - "0\n" - "00:00:01,050 --> 00:00:01,900\n\n")) - (expect (point) :to-equal 33))))) +(describe "Inserting a subtitle" + (describe "in an empty buffer" + (describe "before" + (it "passing nothing." + (with-temp-buffer + (expect (subed-srt--prepend-subtitle) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID." + (with-temp-buffer + (expect (subed-srt--prepend-subtitle 2) :to-equal 33) + (expect (buffer-string) :to-equal (concat "2\n" + "00:00:00,000 --> 00:00:01,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID and start time." + (with-temp-buffer + (expect (subed-srt--prepend-subtitle 3 60000) :to-equal 33) + (expect (buffer-string) :to-equal (concat "3\n" + "00:01:00,000 --> 00:01:01,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID, start time and stop time." + (with-temp-buffer + (expect (subed-srt--prepend-subtitle 4 60000 65000) :to-equal 33) + (expect (buffer-string) :to-equal (concat "4\n" + "00:01:00,000 --> 00:01:05,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID, start time, stop time and text." + (with-temp-buffer + (expect (subed-srt--prepend-subtitle 5 60000 65000 "Foo, bar\nbaz.") :to-equal 33) + (expect (buffer-string) :to-equal (concat "5\n" + "00:01:00,000 --> 00:01:05,000\n" + "Foo, bar\nbaz.\n")) + (expect (point) :to-equal 33))) + ) + (describe "after" + (it "passing nothing." + (with-temp-buffer + (expect (subed-srt--append-subtitle) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID." + (with-temp-buffer + (expect (subed-srt--append-subtitle 2) :to-equal 33) + (expect (buffer-string) :to-equal (concat "2\n" + "00:00:00,000 --> 00:00:01,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID and start time." + (with-temp-buffer + (expect (subed-srt--append-subtitle 3 60000) :to-equal 33) + (expect (buffer-string) :to-equal (concat "3\n" + "00:01:00,000 --> 00:01:01,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID, start time and stop time." + (with-temp-buffer + (expect (subed-srt--append-subtitle 4 60000 65000) :to-equal 33) + (expect (buffer-string) :to-equal (concat "4\n" + "00:01:00,000 --> 00:01:05,000\n\n")) + (expect (point) :to-equal 33))) + (it "passing ID, start time, stop time and text." + (with-temp-buffer + (expect (subed-srt--append-subtitle 5 60000 65000 "Foo, bar\nbaz.") :to-equal 33) + (expect (buffer-string) :to-equal (concat "5\n" + "00:01:00,000 --> 00:01:05,000\n" + "Foo, bar\nbaz.\n")) + (expect (point) :to-equal 33))) + ) ) (describe "in a non-empty buffer" (describe "before the current subtitle" - (it "a single subtitle." - (cl-loop for arg in (list '- -1 (list 4)) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 2) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "0\n" - "00:01:05,223 --> 00:02:02,134\n" - "\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n")) - (expect (point) :to-equal 71)))) - (it "multiple subtitles." - (cl-loop for arg in (list -2 (list 16)) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 2) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "0\n" - "00:01:05,223 --> 00:01:33,628\n" - "\n\n" - "0\n" - "00:01:33,728 --> 00:02:02,133\n" - "\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n")) - (expect (point) :to-equal 71)))) + (describe "with point on the first subtitle" + (it "passing nothing." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-time-stop) + (expect (subed-srt--prepend-subtitle) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (expect (point) :to-equal 33))) + (it "passing ID." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-time-stop) + (expect (subed-srt--prepend-subtitle 7) :to-equal 33) + (expect (buffer-string) :to-equal (concat "7\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (expect (point) :to-equal 33))) + (it "passing ID and start time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-time-stop) + (expect (subed-srt--prepend-subtitle 6 1500) :to-equal 33) + (expect (buffer-string) :to-equal (concat "6\n" + "00:00:01,500 --> 00:00:02,500\n" + "\n\n" + "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (expect (point) :to-equal 33))) + (it "passing ID, start time and stop time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-time-stop) + (expect (subed-srt--prepend-subtitle 5 1500 2000) :to-equal 33) + (expect (buffer-string) :to-equal (concat "5\n" + "00:00:01,500 --> 00:00:02,000\n" + "\n\n" + "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (expect (point) :to-equal 33))) + (it "passing ID, start time, stop time and text." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-time-stop) + (expect (subed-srt--prepend-subtitle 4 1500 3000 "Bar.") :to-equal 33) + (expect (buffer-string) :to-equal (concat "4\n" + "00:00:01,500 --> 00:00:03,000\n" + "Bar.\n\n" + "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (expect (point) :to-equal 33))) + ) + (describe "with point on a non-first subtitle" + (it "passing nothing." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-text 2) + (expect (subed-srt--prepend-subtitle) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-text 2) + (expect (subed-srt--prepend-subtitle 9) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "9\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID and start time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-text 2) + (expect (subed-srt--prepend-subtitle 9 7000) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "9\n" + "00:00:07,000 --> 00:00:08,000\n" + "\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID, start time and stop time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-text 2) + (expect (subed-srt--prepend-subtitle 9 7000 7123) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "9\n" + "00:00:07,000 --> 00:00:07,123\n" + "\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID, start time, stop time and text." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-text 2) + (expect (subed-srt--prepend-subtitle 9 7000 7123 "Baz.") :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "9\n" + "00:00:07,000 --> 00:00:07,123\n" + "Baz.\n\n" + "2\n" + "00:00:10,000 --> 00:00:12,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + ) ) (describe "after the current subtitle" - (it "a single subtitle." - (cl-loop for arg in (list nil 1) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 1) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "0\n" - "00:01:05,223 --> 00:02:02,134\n" - "\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n")) - (expect (point) :to-equal 71)))) - (it "multiple subtitles." - (cl-loop for arg in (list 2) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 1) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "0\n" - "00:01:05,223 --> 00:01:33,628\n" - "\n\n" - "0\n" - "00:01:33,728 --> 00:02:02,133\n" - "\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n")) - (expect (point) :to-equal 71)))) - ) - (describe "before the first subtitle" - (it "a single subtitle." - (cl-loop for arg in (list '- -1 (list 4)) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 1) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "0\n" - "00:00:00,100 --> 00:01:00,900\n" - "\n\n" - "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n")) - (expect (point) :to-equal 33)))) - (it "multiple subtitles." - (cl-loop for arg in (list -2 (list 16)) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 1) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "0\n" - "00:00:00,100 --> 00:00:30,450\n" - "\n\n" - "0\n" - "00:00:30,550 --> 00:01:00,900\n" - "\n\n" - "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n")) - (expect (point) :to-equal 33)))) - ) - (describe "after the last subtitle" - (it "a single subtitle." - (cl-loop for arg in (list nil 1) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 3) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n\n" - "0\n" - "00:03:15,600 --> 00:03:16,400\n" - "\n")) - (expect (point) :to-equal 144)))) - (it "multiple subtitles." - (cl-loop for arg in (list 2) do - (with-temp-buffer - (insert mock-srt-data) - (subed-srt--jump-to-subtitle-text 3) - (subed-srt--subtitle-insert arg) - (expect (buffer-string) :to-equal (concat "1\n" - "00:01:01,000 --> 00:01:05,123\n" - "Foo.\n\n" - "2\n" - "00:02:02,234 --> 00:02:10,345\n" - "Bar.\n\n" - "3\n" - "00:03:03,45 --> 00:03:15,5\n" - "Baz.\n\n" - "0\n" - "00:03:15,600 --> 00:03:16,450\n" - "\n\n" - "0\n" - "00:03:16,550 --> 00:03:17,400\n" - "\n")) - (expect (point) :to-equal 144)))) + (describe "with point on the last subtitle" + (it "passing nothing." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text) + (expect (subed-srt--append-subtitle) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n")) + (expect (point) :to-equal 71))) + (it "passing ID." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text) + (expect (subed-srt--append-subtitle 5) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "5\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n")) + (expect (point) :to-equal 71))) + (it "passing ID and start time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text) + (expect (subed-srt--append-subtitle 5 12345) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "5\n" + "00:00:12,345 --> 00:00:13,345\n" + "\n")) + (expect (point) :to-equal 71))) + (it "passing ID, start time and stop time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text) + (expect (subed-srt--append-subtitle 5 12345 15000) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "5\n" + "00:00:12,345 --> 00:00:15,000\n" + "\n")) + (expect (point) :to-equal 71))) + (it "passing ID, start time, stop time and text." + (with-temp-buffer + (insert (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text) + (expect (subed-srt--append-subtitle 5 12345 15000 "Bar.") :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:05,000 --> 00:00:06,000\n" + "Foo.\n\n" + "5\n" + "00:00:12,345 --> 00:00:15,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + ) + (describe "with point on a non-last subtitle" + (it "passing nothing." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-time-start 1) + (expect (subed-srt--append-subtitle) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-time-start 1) + (expect (subed-srt--append-subtitle 7) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "7\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID and start time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-time-start 1) + (expect (subed-srt--append-subtitle 7 2500) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "7\n" + "00:00:02,500 --> 00:00:03,500\n" + "\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID, start time and stop time." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-time-start 1) + (expect (subed-srt--append-subtitle 7 2500 4000) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "7\n" + "00:00:02,500 --> 00:00:04,000\n" + "\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + (it "passing ID, start time, stop time and text." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (subed-srt--jump-to-subtitle-time-start 1) + (expect (subed-srt--append-subtitle 7 2500 4000 "Baz.") :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "Foo.\n\n" + "7\n" + "00:00:02,500 --> 00:00:04,000\n" + "Baz.\n\n" + "2\n" + "00:00:05,000 --> 00:00:06,000\n" + "Bar.\n")) + (expect (point) :to-equal 71))) + ) ) + (it "when point is on empty text." + (with-temp-buffer + (insert (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "\n")) + (subed-jump-to-subtitle-text) + ;; (expect (subed-srt--append-subtitle) :to-equal 67) + (subed-srt--append-subtitle) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:01,000 --> 00:00:02,000\n" + "\n\n" + "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n")) + ;; (expect (point) :to-equal 67) + )) ) - (it "schedules ID regeneration." - (with-temp-buffer - (subed-srt--subtitle-insert) - (expect #'subed-srt--regenerate-ids-soon :to-have-been-called-times 1) - (expect #'subed-srt--regenerate-ids :not :to-have-been-called))) ) (describe "Killing a subtitle" diff --git a/tests/test-subed.el b/tests/test-subed.el index 8965361..947b658 100644 --- a/tests/test-subed.el +++ b/tests/test-subed.el @@ -804,6 +804,243 @@ (expect 'subed-mpv-jump :to-have-been-called-with '60800)))) ) +(describe "Inserting" + (before-each + (spy-on 'subed-regenerate-ids-soon)) + (describe "in an empty buffer," + (describe "appending" + (it "a single subtile." + (cl-loop for arg in (list nil 1) do + (with-temp-buffer + (expect (subed-insert-subtitle arg) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n")) + (expect (point) :to-equal 33) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + (it "multiple subtiles." + (cl-loop for arg in (list 2) do + (with-temp-buffer + (expect (subed-insert-subtitle arg) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "0\n" + "00:00:01,100 --> 00:00:02,100\n" + "\n")) + (expect (point) :to-equal 33) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + ) + (describe "prepending" + (it "a single subtile." + (cl-loop for arg in (list '- -1 (list 4)) do + (with-temp-buffer + (expect (subed-insert-subtitle arg) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n")) + (expect (point) :to-equal 33) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + (it "multiple subtiles." + (cl-loop for arg in (list -2 (list -16)) do + (with-temp-buffer + (expect (subed-insert-subtitle arg) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:00,000 --> 00:00:01,000\n" + "\n\n" + "0\n" + "00:00:01,100 --> 00:00:02,100\n" + "\n")) + (expect (point) :to-equal 33) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + ) + ) + (describe "in a non-empty buffer" + (describe "before a non-first subtitle" + (it "a single subtitle." + (cl-loop for arg in (list '- -1 (list 4)) do + (with-temp-buffer + (insert (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (subed-jump-to-subtitle-text 2) + (expect (subed-insert-subtitle arg) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "0\n" + "00:01:30,000 --> 00:01:31,000\n" + "\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (expect (point) :to-equal 71) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + (it "multiple subtitles." + (cl-loop for arg in (list -2 (list 16)) do + (with-temp-buffer + (insert (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (subed-jump-to-subtitle-text 2) + (expect (subed-insert-subtitle arg) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "0\n" + "00:01:20,000 --> 00:01:21,000\n" + "\n\n" + "0\n" + "00:01:40,000 --> 00:01:41,000\n" + "\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (expect (point) :to-equal 71) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + ) + (describe "after a non-last subtitle" + (it "a single subtitle." + (cl-loop for arg in (list nil 1) do + (with-temp-buffer + (insert (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (subed-jump-to-subtitle-text 1) + (expect (subed-insert-subtitle arg) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "0\n" + "00:01:30,000 --> 00:01:31,000\n" + "\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (expect (point) :to-equal 71) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + (it "multiple subtitles." + (cl-loop for arg in (list 2) do + (with-temp-buffer + (insert (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (subed-jump-to-subtitle-text 1) + (expect (subed-insert-subtitle arg) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:00:59,000 --> 00:01:00,000\n" + "Foo.\n\n" + "0\n" + "00:01:20,000 --> 00:01:21,000\n" + "\n\n" + "0\n" + "00:01:40,000 --> 00:01:41,000\n" + "\n\n" + "2\n" + "00:02:00,000 --> 00:02:01,000\n" + "Bar.\n")) + (expect (point) :to-equal 71) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + ) + (describe "before the first subtitle" + (it "a single subtitle." + (cl-loop for arg in (list '- -1 (list 4)) do + (with-temp-buffer + (insert (concat "1\n" + "00:01:00,000 --> 00:01:01,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text 1) + (expect (subed-insert-subtitle arg) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:30,000 --> 00:00:31,000\n" + "\n\n" + "1\n" + "00:01:00,000 --> 00:01:01,000\n" + "Foo.\n")) + (expect (point) :to-equal 33) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + (it "multiple subtitles." + (cl-loop for arg in (list -2 (list 16)) do + (with-temp-buffer + (insert (concat "1\n" + "00:01:00,000 --> 00:01:01,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text 1) + (expect (subed-insert-subtitle arg) :to-equal 33) + (expect (buffer-string) :to-equal (concat "0\n" + "00:00:20,000 --> 00:00:21,000\n" + "\n\n" + "0\n" + "00:00:40,000 --> 00:00:41,000\n" + "\n\n" + "1\n" + "00:01:00,000 --> 00:01:01,000\n" + "Foo.\n")) + (expect (point) :to-equal 33) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + ) + (describe "after the last subtitle" + (it "a single subtitle." + (cl-loop for arg in (list nil 1) do + (with-temp-buffer + (insert (concat "1\n" + "00:59:00,000 --> 00:01:00,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text 1) + (expect (subed-insert-subtitle arg) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:59:00,000 --> 00:01:00,000\n" + "Foo.\n\n" + "0\n" + "00:01:00,100 --> 00:01:01,100\n" + "\n")) + (expect (point) :to-equal 71) + (expect 'subed-regenerate-ids-soon :to-have-been-called-times 1) + (spy-calls-reset 'subed-regenerate-ids-soon)))) + (it "multiple subtitles." + (cl-loop for arg in (list 2) do + (with-temp-buffer + (insert (concat "1\n" + "00:59:00,000 --> 00:01:00,000\n" + "Foo.\n")) + (subed-srt--jump-to-subtitle-text 3) + (expect (subed-insert-subtitle arg) :to-equal 71) + (expect (buffer-string) :to-equal (concat "1\n" + "00:59:00,000 --> 00:01:00,000\n" + "Foo.\n\n" + "0\n" + "00:01:00,100 --> 00:01:01,100\n" + "\n\n" + "0\n" + "00:01:01,200 --> 00:01:02,200\n" + "\n")) + (expect (point) :to-equal 71)))) + ) + ) + ) + (describe "Syncing player to point" :var (subed-mpv-playback-position) (before-each