diff options
Diffstat (limited to 'emacs/.emacs.d/lisp/my/my-emms.el')
-rw-r--r-- | emacs/.emacs.d/lisp/my/my-emms.el | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/emacs/.emacs.d/lisp/my/my-emms.el b/emacs/.emacs.d/lisp/my/my-emms.el index cdbe57a..054d3d9 100644 --- a/emacs/.emacs.d/lisp/my/my-emms.el +++ b/emacs/.emacs.d/lisp/my/my-emms.el @@ -421,12 +421,66 @@ under /zzz-seren/." (defun my-emms-playlist-random-album () (interactive) (with-current-emms-playlist - (goto-line (1+ (random (count-lines (point-min) (point-max))))) - (let ((album-name (my-emms-playlist-album-name-at-point))) - (goto-char (point-min)) - (search-forward album-name) - (beginning-of-line) - (emms-playlist-mode-play-current-track)))) + (goto-line (1+ (random (count-lines (point-min) (point-max))))) + (let ((album-name (my-emms-playlist-album-name-at-point))) + (goto-char (point-min)) + (search-forward album-name) + (beginning-of-line) + (emms-playlist-mode-play-current-track)))) + +(defvar my-emms-playlist-group-length 20 + "Length of a track group in an album.") + +(defvar my-emms-playlist-tail-group-length 10 + "Min length of a tail track group in an album.") + +(defun my-emms-playlist-group-bounds () + "Return (GROUP-START . GROUP-END) of the group the current track belongs to." + (save-excursion + (let* ((album-name (my-emms-playlist-album-name-at-point)) + (current-ln (line-number-at-pos)) + (start-ln (progn (goto-char (point-min)) + (re-search-forward (concat "^" (regexp-quote album-name))) + (line-number-at-pos))) + (end-ln (progn (goto-char (point-max)) + (re-search-backward (concat "^" (regexp-quote album-name))) + (1+ (line-number-at-pos)))) + ;; How many tracks have been from the start of the album + ;; (exclusive) + (past (- current-ln start-ln)) + ;; How many tracks to go (inclusive) + (remain (- end-ln current-ln)) + (idx (/ past my-emms-playlist-group-length)) + (maybe-group-start (+ start-ln (* idx my-emms-playlist-group-length))) + (group-start + (if (< (- end-ln maybe-group-start) my-emms-playlist-tail-group-length) + ;; Too close to the end of the album + (max start-ln (- maybe-group-start my-emms-playlist-group-length)) + maybe-group-start)) + (group-end + (if (<= remain my-emms-playlist-tail-group-length) + end-ln + (min end-ln (+ group-start my-emms-playlist-group-length))))) + (cons group-start group-end)))) + +(defun my-emms-playlist-random-group () + (interactive) + (with-current-emms-playlist + (goto-line (1+ (random (count-lines (point-min) (point-max))))) + (pcase-let ((`(,group-start . ,group-end) (my-emms-playlist-group-bounds))) + (goto-line group-start) + (emms-playlist-mode-play-current-track)))) + +(defun my-emms-next-track-or-random-group () + (interactive) + (with-current-buffer emms-playlist-buffer + (emms-playlist-mode-center-current) + (pcase-let ((`(,group-start . ,group-end) (my-emms-playlist-group-bounds))) + (when emms-player-playing-p (emms-stop)) + (if (>= (1+ (line-number-at-pos)) group-end) + (my-emms-playlist-random-group) + (emms-playlist-current-select-next) + (emms-start))))) ;;; override the minor mode ;;;###autoload |