X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=emus.el;h=cfa674a86ea8b49a1142003d5b40738dbeb3d607;hb=2da3ca6418339e37c7ba8c801492b99ac6faed37;hp=7e2e64e99089d8bfb38372b477ddd00a43b26cc7;hpb=bc2e732f5d42c26776a282b04483a5f914345ee1;p=emus.git diff --git a/emus.el b/emus.el index 7e2e64e..cfa674a 100644 --- a/emus.el +++ b/emus.el @@ -57,11 +57,13 @@ :type '(string)) (defface emus-artist - '((t :inherit font-lock-string-face :background "#333")) + '(((background dark) :inherit font-lock-string-face :inverse-video t :extend t) + (t :inherit font-lock-string-face :background "#ddd" :extend t)) "Face used for artist names in browser.") (defface emus-album - '((t :inherit font-lock-constant-face :background "#222")) + '(((background dark) :inherit font-lock-constant-face :inverse-video t :extend t) + (t :inherit font-lock-constant-face :background "#eee" :extend t)) "Face used for album names in browser.") (defface emus-track @@ -76,13 +78,33 @@ '((t :inherit bold)) "Face used for current track cursor") -;;; mpg123 process -;; + +;;; Global variables (defvar emus--proc-in-use nil "If non-nil, disables `emus-send-cmd'. Used to prevent commands from interfering with library construction.") +(defvar emus-tracks nil + "Emus audio library.") + +(defvar emus-current-track nil + "Currently-selected emus track.") + +(defvar emus-state 'stopped + "Current playback state.") + +(defvar emus-continuous-playback t + "If non-nil, emus will automatically play the next track when the current track is finished.") + +(defvar emus-current-volume 100 + "The current playback volume.") + + +;;; mpg123 process +;; + + (defun emus-get-process () "Return current or new mpg123 process." (let* ((emus-process-raw (get-process "emus-process")) @@ -95,7 +117,6 @@ Used to prevent commands from interfering with library construction.") emus-process (let ((proc (make-process :name "emus-process" - ;; :buffer (get-buffer-create "*emus-process*") :command `(,emus-mpg123-program "-R")))) (set-process-query-on-exit-flag proc nil) (process-send-string proc "silence\n") @@ -121,10 +142,10 @@ be used by `emus--load-library'." (defun emus-get-audio-files () "Get all mp3 files in main emus directory." - (directory-files-recursively emus-directory ".*\\.mp3")) - -(defvar emus-tracks nil - "Emus audio library.") + (mapcar + (lambda (f) + (expand-file-name f)) + (directory-files-recursively emus-directory ".*\\.mp3"))) (defun emus-make-track (artist album title filename &optional pos) "Create an object representing an emus track. @@ -221,7 +242,7 @@ by the filesystem." (defmacro emus--with-library (&rest body) "Evaluate BODY with the library initialized." `(if emus-tracks - (progn ,@body) + (unless emus--proc-in-use ,@body) (emus--load-library (lambda () ,@body)))) @@ -229,10 +250,6 @@ by the filesystem." ;;; Playback ;; -(defvar emus-current-track nil) -(defvar emus-state 'stopped) -(defvar emus-continuous-playback t) - (defun emus--suspend-cp () "Suspend continuous playback." (setq emus-continuous-playback nil)) @@ -256,7 +273,8 @@ by the filesystem." (setq emus-current-track track) (emus--update-track old-track) (emus--update-track track) - (emus--resume-cp)))) + (emus--resume-cp) + (emus-goto-current)))) (defun emus-select-track (track) "Set TRACK as current, but do not start playing." @@ -267,7 +285,8 @@ by the filesystem." (emus--update-track old-track) (emus--update-track track) (emus-send-cmd "o") - (emus--resume-cp)))) + (emus--resume-cp) + (emus-goto-current)))) (defun emus-stop () "Stop playback of the current track." @@ -293,9 +312,6 @@ If the track is currently paused, resume playback." (unless (eq emus-state 'paused))) (emus--update-track emus-current-track)))) -(defvar emus-current-volume 100 - "The current playback volume.") - (defun emus-set-volume (pct) "Set the playback volume to PCT %." (emus--with-library @@ -411,10 +427,18 @@ If PREV is non-nil, plays the last track of the previous album." ;; (defun emus--insert-track (track &optional prev-track first) + "Insert a button representing TRACK into the current buffer. + +When provided, PREV-TRACK is used to determine whether to insert additional +headers representing the artist or the album title. + +If non-nil, FIRST indicates that the track is the first in the library +and thus requires both artist and album headers." (let* ((artist (emus-track-artist track)) (album (emus-track-album track)) (title (emus-track-title track)) - (help-str (format "mouse-1, RET: Play '%.30s' (%.20s)" title artist))) + (help-str (format "mouse-1, RET: Play '%.30s' (%.20s)" title artist)) + (field (intern album))) ;Allows easy jumping between albums with cursor. (when (or prev-track first) (unless (equal (emus-track-artist prev-track) artist) (insert-text-button @@ -422,16 +446,22 @@ If PREV is non-nil, plays the last track of the previous album." 'action #'emus--click-track 'follow-link t 'help-echo help-str - 'emus-track track) - (insert (propertize "\n" 'face 'emus-artist))) + 'emus-track track + 'field field) + (insert (propertize "\n" + 'face 'emus-artist + 'field field))) (unless (equal (emus-track-album prev-track) album) (insert-text-button (propertize (concat " " album) 'face 'emus-album) 'action #'emus--click-track 'follow-link t 'help-echo help-str - 'emus-track track) - (insert (propertize "\n" 'face 'emus-album)))) + 'emus-track track + 'field field) + (insert (propertize "\n" + 'face 'emus-album + 'field field)))) (emus-set-track-browser-pos track (point)) (let ((is-current (equal track emus-current-track))) (insert-text-button @@ -451,13 +481,17 @@ If PREV is non-nil, plays the last track of the previous album." 'action #'emus--click-track 'follow-link t 'help-echo help-str - 'emus-track track) + 'emus-track track + 'field field) (insert (propertize "\n" 'face (if is-current 'emus-track-current - 'emus-track)))))) + 'emus-track) + 'field field))))) (defun emus--update-track (track) + "Rerender entry for TRACK in emus browser buffer. +Used to update browser display when `emus-current-track' and/or `emus-state' changes." (let ((track-pos (emus-track-browser-pos track))) (when (and (get-buffer "*emus*") (emus-track-browser-pos track)) @@ -472,6 +506,7 @@ If PREV is non-nil, plays the last track of the previous album." (goto-char old-point)))))) (defun emus--render-tracks () + "Render all library tracks in emus browser buffer." (with-current-buffer "*emus*" (let ((inhibit-read-only t) (old-pos (point))) @@ -484,44 +519,106 @@ If PREV is non-nil, plays the last track of the previous album." (goto-char old-pos)))) (defun emus--click-track (button) + "Begin playback of track indicated by BUTTON." (emus-play-track (button-get button 'emus-track)) (emus-display-status)) -(defun emus-centre-current () +(defun emus-goto-current () + "Move point to the current track in the browser buffer, if available." (interactive) - (when (get-buffer "*emus*") - (when emus-current-track - (goto-char (emus-track-browser-pos emus-current-track)) - (recenter)))) + (when (and (get-buffer "*emus*") + emus-current-track) + (with-current-buffer "*emus*" + (goto-char (emus-track-browser-pos emus-current-track))))) (defun emus-browse () "Switch to *emus* audio library browser." (interactive) (emus--with-library - (switch-to-buffer "*emus*") + (pop-to-buffer-same-window "*emus*") (emus-browser-mode) (emus--render-tracks) - (emus-centre-current))) + (emus-goto-current))) (defun emus-refresh () + "Refresh the emus library." (interactive) (emus-stop) (setq emus-tracks nil) (emus-browse)) -(defun emus-playpause-status () (interactive) (emus-playpause) (emus-display-status)) -(defun emus-stop-status () (interactive) (emus-stop) (emus-display-status)) -(defun emus-volume-up-status () (interactive) (emus-volume-up) (emus-display-status)) -(defun emus-volume-down-status () (interactive) (emus-volume-down) (emus-display-status)) -(defun emus-play-next-status () (interactive) (emus-play-next) (emus-display-status)) -(defun emus-play-prev-status () (interactive) (emus-play-prev) (emus-display-status)) -(defun emus-play-next-album-status () (interactive) (emus-play-next-album) (emus-display-status)) -(defun emus-play-prev-album-status () (interactive) (emus-play-prev-album) (emus-display-status)) -(defun emus-jump-10s-forward-status () (interactive) (emus-jump-10s-forward) (emus-display-status)) -(defun emus-jump-10s-backward-status () (interactive) (emus-jump-10s-backward) (emus-display-status)) -(defun emus-centre-current-status () (interactive) (emus-centre-current) (emus-display-status)) + +;;; Playback + status display commands +;; + +(defun emus-playpause-status () + "Start, pause or resume playback, then display the emus status in the minibuffer." + (interactive) + (emus-playpause) + (emus-display-status)) + +(defun emus-stop-status () + "Stop playback, then display the emus status in the minibuffer." + (interactive) + (emus-stop) + (emus-display-status)) + +(defun emus-volume-up-status () + "Increase volume by 10%, then display the emus status in the minibuffer." + (interactive) + (emus-volume-up) + (emus-display-status)) + +(defun emus-volume-down-status () + "Decrease volume by 10%, then display the emus status in the minibuffer." + (interactive) + (emus-volume-down) + (emus-display-status)) + +(defun emus-play-next-status () + "Play next track, then display the emus status in the minibuffer." + (interactive) + (emus-play-next) + (emus-display-status)) + +(defun emus-play-prev-status () + "Play previous track, then display the emus status in the minibuffer." + (interactive) + (emus-play-prev) + (emus-display-status)) + +(defun emus-play-next-album-status () + "Play first track of next album, then display the emus status in the minibuffer." + (interactive) + (emus-play-next-album) + (emus-display-status)) + +(defun emus-play-prev-album-status () + "Play last track of previous album, then display the emus status in the minibuffer." + (interactive) + (emus-play-prev-album) + (emus-display-status)) + +(defun emus-jump-10s-forward-status () + "Jump 10s forward in current track, then display the emus status in the minibuffer." + (interactive) + (emus-jump-10s-forward) + (emus-display-status)) + +(defun emus-jump-10s-backward-status () + "Jump 10s backward in current track, then display the emus status in the minibuffer." + (interactive) + (emus-jump-10s-backward) + (emus-display-status)) + +(defun emus-goto-current-status () + "Move point to the current track, then display the emus status in the minibuffer." + (interactive) + (emus-goto-current) + (emus-display-status)) (defun emus-refresh-status () + "Refresh the emus library, then display the emus status in the minibuffer." (interactive) (emus-stop) (setq emus-tracks nil) @@ -543,7 +640,7 @@ If PREV is non-nil, plays the last track of the previous album." (define-key map (kbd "P") 'emus-play-prev-album-status) (define-key map (kbd ",") 'emus-jump-10s-backward-status) (define-key map (kbd ".") 'emus-jump-10s-forward-status) - (define-key map (kbd "c") 'emus-centre-current-status) + (define-key map (kbd "c") 'emus-goto-current-status) (when (fboundp 'evil-define-key*) (evil-define-key* 'motion map (kbd "SPC") 'emus-playpause-status @@ -558,9 +655,9 @@ If PREV is non-nil, plays the last track of the previous album." (kbd "P") 'emus-play-prev-album-status (kbd ",") 'emus-jump-10s-backward-status (kbd ".") 'emus-jump-10s-forward-status - (kbd "c") 'emus-centre-current-status)) + (kbd "c") 'emus-goto-current-status)) map) - "Keymap for emus.") + "Keymap for emus browser.") (define-derived-mode emus-browser-mode special-mode "emus-browser" "Major mode for EMUS music player file browser.")