aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2024-10-17 12:38:18 -0400
committerStefan Monnier2024-10-17 12:38:18 -0400
commit4690f2f44d38d64d8ebfea98c085844a5723df0f (patch)
treeb98514b2f15959f2f0231df8a7eda10a7fef4cea
parent49084bad7990a614bdd3ea7a24ebab0fc89627e3 (diff)
downloademacs-4690f2f44d38d64d8ebfea98c085844a5723df0f.tar.gz
emacs-4690f2f44d38d64d8ebfea98c085844a5723df0f.zip
mpc.el: Misc tweaks.
* lisp/mpc.el: Require `cl-lib` at run-time. Don't require `subr-x` any more. (mpc-status-callbacks): Improve docstring. (mpc-cover-image-find): Avoid `and-let*`. (mpc-cover-image-p): Use `member-ignore-case` to recover the behavior before last patch. (mpc-cover-image-find, mpc-cover-image-p): Move to later in the file to avoid compiler warning. (mpc-format, mpc-notifications-title, mpc-notifications-body): Tweak docstring. (mpc--notifications-format): Create only one temp buffer and use the faster `cl-some` since we know the arg is a list. (mpc-notifications-notify): Prefer `when-let*` since all the other `*-let` we use are also of the `let*`family.
-rw-r--r--lisp/mpc.el93
1 files changed, 45 insertions, 48 deletions
diff --git a/lisp/mpc.el b/lisp/mpc.el
index a4b576cbd1b..9c0bbaaa0f2 100644
--- a/lisp/mpc.el
+++ b/lisp/mpc.el
@@ -91,9 +91,7 @@
91;; UI-commands : mpc- 91;; UI-commands : mpc-
92;; internal : mpc-- 92;; internal : mpc--
93 93
94(eval-when-compile 94(require 'cl-lib)
95 (require 'cl-lib)
96 (require 'subr-x))
97 95
98(require 'notifications) 96(require 'notifications)
99 97
@@ -470,7 +468,8 @@ which will be concatenated with proper quoting before passing them to MPD."
470 (updating_db . mpc--status-timers-refresh) 468 (updating_db . mpc--status-timers-refresh)
471 (t . mpc-current-refresh)) 469 (t . mpc-current-refresh))
472 "Alist associating properties to the functions that care about them. 470 "Alist associating properties to the functions that care about them.
473Each entry has the form (PROP . FUN) where PROP can be t to mean 471Each entry has the form (PROP . FUN) to call FUN (without arguments)
472whenever property PROP changes. PROP can be t to mean
474to call FUN for any change whatsoever.") 473to call FUN for any change whatsoever.")
475 474
476(defun mpc--status-callback () 475(defun mpc--status-callback ()
@@ -961,20 +960,6 @@ If PLAYLIST is t or nil or missing, use the main playlist."
961 ;; aux) 960 ;; aux)
962 )) 961 ))
963 962
964(defun mpc-cover-image-find (file)
965 "Find cover image for FILE."
966 (and-let* ((default-directory mpc-mpd-music-directory)
967 (dir (mpc-file-local-copy (file-name-directory file)))
968 (files (directory-files dir))
969 (cover (seq-find #'mpc-cover-image-p files))
970 ((expand-file-name cover dir)))))
971
972(defun mpc-cover-image-p (file)
973 "Check if FILE is a cover image."
974 (let ((covers '(".folder.png" "folder.png" "cover.jpg" "folder.jpg")))
975 (or (seq-find (lambda (cover) (string= file cover)) covers)
976 (and mpc-cover-image-re (string-match-p mpc-cover-image-re file)))))
977
978;;; Formatter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 963;;; Formatter ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
979 964
980(defcustom mpc-cover-image-re nil ; (rx (or ".jpg" ".jpeg" ".png") string-end) 965(defcustom mpc-cover-image-re nil ; (rx (or ".jpg" ".jpeg" ".png") string-end)
@@ -1011,11 +996,14 @@ If PLAYLIST is t or nil or missing, use the main playlist."
1011(defun mpc-format (format-spec info &optional hscroll) 996(defun mpc-format (format-spec info &optional hscroll)
1012 "Format the INFO according to FORMAT-SPEC, inserting the result at point. 997 "Format the INFO according to FORMAT-SPEC, inserting the result at point.
1013 998
1014FORMAT-SPEC is a string of the format '%-WIDTH{NAME-POST}' where the first 999FORMAT-SPEC is a string that includes elements of the form
1015'-', WIDTH and -POST are optional. % followed by the optional '-' means 1000'%-WIDTH{NAME-POST}' that get expanded to the value of
1016to right align the output. WIDTH limits the output to the specified 1001property NAME,
1017number of characters by replacing any further output with a horizontal 1002The first '-', WIDTH, and -POST are optional.
1018ellipsis. The optional -POST means to use the empty string if NAME is 1003% followed by the optional '-' means to right align the output.
1004WIDTH limits the output to the specified number of characters by replacing
1005any further output with a horizontal ellipsis.
1006The optional -POST means to use the empty string if NAME is
1019absent or else use the concatenation of the content of NAME with the 1007absent or else use the concatenation of the content of NAME with the
1020string POST." 1008string POST."
1021 (let* ((pos 0) 1009 (let* ((pos 0)
@@ -1143,6 +1131,20 @@ string POST."
1143 (insert (substring format-spec pos)) 1131 (insert (substring format-spec pos))
1144 (put-text-property start (point) 'mpc--uptodate-p pred))) 1132 (put-text-property start (point) 'mpc--uptodate-p pred)))
1145 1133
1134(defun mpc-cover-image-find (file)
1135 "Find cover image for FILE."
1136 (when-let* ((default-directory mpc-mpd-music-directory)
1137 (dir (mpc-file-local-copy (file-name-directory file)))
1138 (files (directory-files dir))
1139 (cover (seq-find #'mpc-cover-image-p files)))
1140 (expand-file-name cover dir)))
1141
1142(defun mpc-cover-image-p (file)
1143 "Check if FILE is a cover image."
1144 (let ((covers '(".folder.png" "folder.png" "cover.jpg" "folder.jpg")))
1145 (or (member-ignore-case file covers)
1146 (and mpc-cover-image-re (string-match-p mpc-cover-image-re file)))))
1147
1146;;; The actual UI code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1148;;; The actual UI code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1147 1149
1148(defvar-keymap mpc-mode-map 1150(defvar-keymap mpc-mode-map
@@ -2798,21 +2800,19 @@ If stopped, start playback."
2798 2800
2799(defcustom mpc-notifications-title 2801(defcustom mpc-notifications-title
2800 '("%{Title}" "Unknown Title") 2802 '("%{Title}" "Unknown Title")
2801 "FORMAT-SPEC used in the notification title. 2803 "List of FORMAT-SPECs used in the notification title.
2802 2804
2803The first element that returns a non-emtpy string is used. The last 2805The first element that expands to a non-empty string is used.
2804element is a plain string to use as fallback for when none of the tags 2806See `mpc-format' for the definition of FORMAT-SPEC."
2805are found. See `mpc-format' for the definition of FORMAT-SPEC."
2806 :version "31.1" 2807 :version "31.1"
2807 :type '(repeat string)) 2808 :type '(repeat string))
2808 2809
2809(defcustom mpc-notifications-body 2810(defcustom mpc-notifications-body
2810 '("%{Artist}" "%{AlbumArtist}" "Unknown Artist") 2811 '("%{Artist}" "%{AlbumArtist}" "Unknown Artist")
2811 "FORMAT-SPEC used in the notification body. 2812 "List of FORMAT-SPEC used in the notification body.
2812 2813
2813The first element that returns a non-emtpy string is used. The last 2814The first element that returns a non-emtpy string is used.
2814element is a plain string to use as fallback for when none of the tags 2815See `mpc-format' for the definition of FORMAT-SPEC."
2815are found. See `mpc-format' for the definition of FORMAT-SPEC."
2816 :version "31.1" 2816 :version "31.1"
2817 :type '(repeat string)) 2817 :type '(repeat string))
2818 2818
@@ -2820,32 +2820,29 @@ are found. See `mpc-format' for the definition of FORMAT-SPEC."
2820 2820
2821(defun mpc--notifications-format (format-specs) 2821(defun mpc--notifications-format (format-specs)
2822 "Use FORMAT-SPECS to get string for use in notification." 2822 "Use FORMAT-SPECS to get string for use in notification."
2823 (seq-some 2823 (with-temp-buffer
2824 (lambda (spec) 2824 (cl-some
2825 (let ((text (with-temp-buffer 2825 (lambda (spec)
2826 (mpc-format spec mpc-status) 2826 (mpc-format spec mpc-status)
2827 (buffer-string)))) 2827 (if (< (point-min) (point-max))
2828 (if (string= "" text) nil text))) 2828 (buffer-string)))
2829 format-specs)) 2829 format-specs)))
2830 2830
2831(defun mpc-notifications-notify () 2831(defun mpc-notifications-notify ()
2832 "Display a notification with information about the current song." 2832 "Display a notification with information about the current song."
2833 (when-let ((mpc-notifications) 2833 (when-let* ((mpc-notifications)
2834 ((notifications-get-server-information)) 2834 ((notifications-get-server-information))
2835 ((string= "play" (alist-get 'state mpc-status))) 2835 ((string= "play" (alist-get 'state mpc-status)))
2836 (title (mpc--notifications-format mpc-notifications-title)) 2836 (title (mpc--notifications-format mpc-notifications-title))
2837 (body (mpc--notifications-format mpc-notifications-body)) 2837 (body (mpc--notifications-format mpc-notifications-body))
2838 (icon (or (mpc-cover-image-find (alist-get 'file mpc-status)) 2838 (icon (or (mpc-cover-image-find (alist-get 'file mpc-status))
2839 notifications-application-icon))) 2839 notifications-application-icon)))
2840 (setq mpc--notifications-id 2840 (setq mpc--notifications-id
2841 (notifications-notify :title title 2841 (notifications-notify :title title
2842 :body body 2842 :body body
2843 :app-icon icon 2843 :app-icon icon
2844 :replaces-id mpc--notifications-id)))) 2844 :replaces-id mpc--notifications-id))))
2845 2845
2846
2847
2848
2849;;; Toplevel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2846;;; Toplevel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2850 2847
2851(defcustom mpc-frame-alist '((name . "MPC") (tool-bar-lines . 1) 2848(defcustom mpc-frame-alist '((name . "MPC") (tool-bar-lines . 1)