fordon_greeman / voidfiles

Branch: 2079ec5
Switch branches/tags
main
theidioticdev add emacs 2079ec5 21h ago
258 lines · 9.4 KB Raw Blame History
1 ;;; emms-playing-time.el --- Display emms playing time on mode line -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2005-2024 Free Software Foundation, Inc.
4
5 ;; Author: William Xu <william.xwl@gmail.com>, Yoni Rabkin (yrk@gnu.org)
6
7 ;; This file is part of EMMS.
8
9 ;; EMMS is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13 ;;
14 ;; EMMS is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with EMMS; if not, write to the Free Software Foundation,
21 ;; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
22
23 ;;; Commentary:
24
25 ;; Display playing time on mode line, it looks like: 01:32/04:09.
26
27 ;; Put this file into your load-path and the following into your
28 ;; ~/.emacs:
29 ;; (require 'emms-playing-time)
30 ;; (emms-playing-time 1)
31
32 ;; Note: `(emms-playing-time -1)' will disable emms-playing-time module
33 ;; completely, and is not recommended. (since some other emms modules
34 ;; may rely on it')
35
36 ;; Instead, to toggle displaying playing time on mode line, one could
37 ;; call `emms-playing-time-enable-display' and
38 ;; `emms-playing-time-disable-display'."
39
40 ;;; Code:
41
42 (require 'emms-info)
43 (require 'emms-player-simple)
44
45 ;;; Customizations
46
47 (defgroup emms-playing-time nil
48 "Playing-time module for EMMS."
49 :group 'emms)
50
51 (defcustom emms-playing-time-display-short-p nil
52 "Non-nil will only display elapsed time.
53 e.g., display 02:37 instead of 02:37/05:49."
54 :type 'boolean)
55
56 (defcustom emms-playing-time-display-hours-p t
57 "Non-nil will display hours in all times sixty minutes or longer.
58 e.g., display 1:19:55 instead of 79:55."
59 :type 'boolean)
60
61 (defcustom emms-playing-time-display-format " %s "
62 "Format used for displaying playing time."
63 :type 'string)
64
65 (defcustom emms-playing-time-style 'time
66 "Style used for displaying playing time.
67 Valid styles are `time' (e.g., 01:30/4:20),
68 `bar' (e.g., [===> ]),
69 and `downtime' (e.g. -03:58)."
70 :type 'symbol)
71
72
73 ;;; Emms Playing Time
74
75 (define-obsolete-variable-alias 'emms-playing-time-display-p
76 'emms-playing-time-display-mode "Apr 2021")
77 (defvar emms-playing-time-display-mode)
78
79 (defvar emms-playing-time 0
80 "Time elapsed in current track.")
81
82 (defvar emms-playing-time-string "")
83
84 (defvar emms-playing-time-display-timer nil)
85
86 (define-obsolete-variable-alias 'emms-playing-time-p
87 'emms-playing-time-mode "Apr 2021")
88
89 (defun emms-playing-time-start ()
90 "Get ready for display playing time."
91 (setq emms-playing-time 0)
92 (unless emms-playing-time-display-timer
93 (setq emms-playing-time-display-timer
94 (run-at-time t 1 #'emms-playing-time-display))))
95
96 (defun emms-playing-time-stop ()
97 "Remove playing time on the mode line."
98 (if (or (not emms-player-paused-p)
99 emms-player-stopped-p)
100 (progn
101 (setq emms-playing-time-string "")
102 (force-mode-line-update)))
103 (emms-cancel-timer emms-playing-time-display-timer)
104 (setq emms-playing-time-display-timer nil))
105
106 (defun emms-playing-time-pause ()
107 "Pause playing time."
108 (if emms-player-paused-p
109 (emms-playing-time-stop)
110 (unless emms-playing-time-display-timer
111 (setq emms-playing-time-display-timer
112 (run-at-time t 1 #'emms-playing-time-display)))))
113
114 (defun emms-playing-time-seek (sec)
115 "Seek forward or backward SEC playing time."
116 (setq emms-playing-time (+ emms-playing-time sec))
117 (when (< emms-playing-time 0) ; back to start point
118 (setq emms-playing-time 0)))
119
120 (defun emms-playing-time-set (sec)
121 "Set the playing time to SEC."
122 (setq emms-playing-time sec)
123 (when (< emms-playing-time 0) ; back to start point
124 (setq emms-playing-time 0)))
125
126 (defun emms-playing-time (arg)
127 (declare (obsolete emms-playing-time-mode "Apr 2021"))
128 (emms-playing-time-mode (if (and arg (> arg 0)) 1 -1)))
129
130
131 (define-minor-mode emms-playing-time-mode
132 "Turn on emms playing time if ARG is positive, off otherwise.
133
134 Note: `(emms-playing-time -1)' will disable emms-playing-time
135 module completely, and is not recommended. (since some other emms
136 modules may rely on it.)
137
138 Instead, to toggle displaying playing time on mode line, one
139 could call `emms-playing-time-enable-display' and
140 `emms-playing-time-disable-display'."
141 :global t
142 (if emms-playing-time-mode
143 (progn
144 ;; FIXME: Maybe we shouldn't set this here, and instead the users
145 ;; should call `emms-playing-time-display-mode' if that's what
146 ;; they want.
147 (setq emms-playing-time-display-mode t)
148 (emms-playing-time-mode-line)
149 (add-hook 'emms-player-started-hook #'emms-playing-time-start)
150 (add-hook 'emms-player-stopped-hook #'emms-playing-time-stop)
151 (add-hook 'emms-player-finished-hook #'emms-playing-time-stop)
152 (add-hook 'emms-player-paused-hook #'emms-playing-time-pause)
153 (add-hook 'emms-player-seeked-functions #'emms-playing-time-seek)
154 (add-hook 'emms-player-time-set-functions #'emms-playing-time-set))
155 (setq emms-playing-time-display-mode nil)
156 (emms-playing-time-stop)
157 (emms-playing-time-restore-mode-line)
158 (remove-hook 'emms-player-started-hook #'emms-playing-time-start)
159 (remove-hook 'emms-player-stopped-hook #'emms-playing-time-stop)
160 (remove-hook 'emms-player-finished-hook #'emms-playing-time-stop)
161 (remove-hook 'emms-player-paused-hook #'emms-playing-time-pause)
162 (remove-hook 'emms-player-seeked-functions #'emms-playing-time-seek)
163 (remove-hook 'emms-player-time-set-functions #'emms-playing-time-set)))
164
165 ;;;###autoload
166 (define-minor-mode emms-playing-time-display-mode
167 "Minor mode to display playing time on mode line."
168 :global t
169 ;; When disabling the mode, don't disable `emms-playing-time-display-mode'
170 ;; since that may be used by other packages.
171 (if emms-playing-time-display-mode
172 (emms-playing-time-display-mode 1)))
173
174 ;;;###autoload
175 (defun emms-playing-time-enable-display ()
176 "Display playing time on mode line."
177 (declare (obsolete emms-playing-time-display-mode "Apr 2021"))
178 (interactive)
179 (setq emms-playing-time-display-mode t))
180
181 ;;;###autoload
182 (defun emms-playing-time-disable-display ()
183 "Remove playing time from mode line."
184 (declare (obsolete emms-playing-time-display-mode "Apr 2021"))
185 (interactive)
186 (setq emms-playing-time-display-mode nil))
187
188 (defun emms-playing-time-display ()
189 "Display playing time on the mode line."
190 (setq emms-playing-time (round (1+ emms-playing-time)))
191 (setq emms-playing-time-string
192 (if (null emms-playing-time-display-mode)
193 ""
194 (let* ((total-playing-time
195 (or (emms-track-get
196 (emms-playlist-current-selected-track)
197 'info-playing-time)
198 0))
199 (string
200 (pcase emms-playing-time-style
201 ('downtime ; `downtime' style
202 (if (or emms-playing-time-display-short-p
203 ;; unable to get total playing-time
204 (eq total-playing-time 0))
205 (emms-playing-time-format-time emms-playing-time)
206 (concat "-" (emms-playing-time-format-time
207 (- total-playing-time emms-playing-time)))))
208 ('bar ; `bar' style
209 (if (zerop total-playing-time)
210 "[==>........]"
211 (let (;; percent based on 10
212 (percent (/ (* emms-playing-time 10)
213 total-playing-time)))
214 (concat "["
215 (make-string percent ?=)
216 ">"
217 (make-string (- 10 percent) ?\s)
218 "]"))))
219 (_ ; `time' style
220 (concat
221 (emms-playing-time-format-time emms-playing-time)
222 (unless (or emms-playing-time-display-short-p
223 ;; unable to get total playing-time
224 (eq total-playing-time 0))
225 (concat "/" (emms-playing-time-format-time total-playing-time))))))))
226 (format emms-playing-time-display-format string))))
227 (force-mode-line-update))
228
229 (defun emms-playing-time-format-time (duration)
230 "Format DURATION, a positive number of seconds, into a string.
231
232 The string will show the minutes and seconds and, if
233 `emms-playing-time-display-hours-p' is non-nil and the duration is
234 sixty minutes or more, the hours."
235 (let ((minutes (/ duration 60))
236 (seconds (% duration 60)))
237 (if (and emms-playing-time-display-hours-p (>= minutes 60))
238 (format "%d:%02d:%02d" (/ minutes 60) (% minutes 60) seconds)
239 (format "%02d:%02d" minutes seconds))))
240
241 (defun emms-playing-time-mode-line ()
242 "Add playing time to the mode line."
243 (or global-mode-string (setq global-mode-string '("")))
244 (unless (member 'emms-playing-time-string
245 global-mode-string)
246 (setq global-mode-string
247 (append global-mode-string
248 '(emms-playing-time-string)))))
249
250 (defun emms-playing-time-restore-mode-line ()
251 "Restore the mode line."
252 (setq global-mode-string
253 (remove 'emms-playing-time-string global-mode-string))
254 (force-mode-line-update))
255
256 (provide 'emms-playing-time)
257
258 ;;; emms-playing-time.el ends here