summaryrefslogtreecommitdiff
path: root/bongo.el
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2021-01-09 14:22:00 +0800
committerJSDurand <mmemmew@gmail.com>2021-01-09 14:22:00 +0800
commitdc206ebe9397d656971ba7fc3a092009ef4e797a (patch)
treed963873011122fdf0eafeba89afd487115994bc5 /bongo.el
parenta2f7f2bf9077ba8acfc550575b9e21aa9ffe7bae (diff)
temporary state
Diffstat (limited to 'bongo.el')
-rw-r--r--bongo.el637
1 files changed, 637 insertions, 0 deletions
diff --git a/bongo.el b/bongo.el
new file mode 100644
index 0000000..f5ccd8c
--- /dev/null
+++ b/bongo.el
@@ -0,0 +1,637 @@
+;;; -*- lexical-binding: t; -*-
+
+(use-package "bongo" 'bongo
+
+ (require 'json)
+ (setq volume-electric-mode nil)
+ (setq bongo-default-directory (expand-file-name "~/Desktop/Centre/Musique"))
+ (setq bongo-prefer-library-buffers nil)
+ (setq bongo-insert-whole-directory-trees t)
+ (setq bongo-logo nil)
+ (setq bongo-action-track-icon nil)
+ (setq bongo-display-track-icons nil)
+ (setq bongo-display-track-lengths nil)
+ (setq bongo-display-header-icons nil)
+ (setq bongo-display-playback-mode-indicator t)
+ (setq bongo-display-inline-playback-progress nil)
+ (setq bongo-mark-played-tracks nil)
+ (setq bongo-header-line-mode nil)
+ (setq bongo-header-line-function nil)
+ (setq bongo-mode-line-indicator-mode nil)
+ (setq bongo-enabled-backends '(mpv))
+ (setq bongo-seek-electric-mode nil)
+ (setf bongo-custom-backend-matchers
+ '((mpv local-file "webm" "m4a")))
+ (setq-default bongo-next-action 'durand-bongo-play-next-or-first)
+
+;;;###autoload
+ (defvar durand-bongo-music-dir nil
+ "Directories to store my songs.
+This is used since my music directories used to contain symbolic links.")
+
+ (setq durand-bongo-music-dir
+ (cons bongo-default-directory
+ (delq
+ nil
+ (mapcar
+ (lambda (file)
+ (cond
+ ((let ((attr (car (file-attributes file))))
+ (and (stringp attr)
+ (file-directory-p attr)))
+ file)))
+ (directory-files-recursively
+ bongo-default-directory
+ ".*" t nil t)))
+ ;; (cl-loop for file in (directory-files-recursively
+ ;; bongo-default-directory
+ ;; ".*" t nil t)
+ ;; for attr = (car (file-attributes file))
+ ;; if (and (stringp attr)
+ ;; (file-directory-p attr))
+ ;; collect attr)
+ ))
+
+ (define-key bongo-playlist-mode-map [?n] #'bongo-next-object-line)
+ (define-key bongo-playlist-mode-map [?p] #'bongo-previous-object-line)
+ (define-key bongo-playlist-mode-map [?j] #'durand-bongo-save-playlist)
+ (define-key bongo-playlist-mode-map [tab] #'bongo-show)
+ (define-key bongo-playlist-mode-map [?\C-c ?n] #'durand-bongo-play-next-or-first)
+ (define-key bongo-playlist-mode-map [?\C-c ?p] #'durand-bongo-play-previous-or-last)
+ (define-key bongo-dired-library-mode-map [?\C-j] #'durand-bongo-dired-ivy-find-to-add)
+ (define-key bongo-dired-library-mode-map [?\C-c ?n] #'durand-bongo-play-next-or-first)
+ (define-key bongo-dired-library-mode-map [?\C-c ?p] #'durand-bongo-play-previous-or-last)
+ (define-key bongo-playlist-mode-map [?\C-d] #'prot/bongo-clear-playlist-and-stop)
+ (define-key bongo-playlist-mode-map [?I] #'durand-bongo-insert-delete-playlist)
+ (define-key bongo-dired-library-mode-map [C-return] #'prot/bongo-library-insert-and-play-random)
+
+ (add-hook 'dired-mode-hook #'durand-bongo-dired-library)
+
+ ;; (map! :map durand-view-map
+ ;; [?m] 'bongo
+ ;; :map bongo-dired-library-mode-map
+ ;; [?\C-j] 'durand-bongo-dired-ivy-find-to-add
+ ;; [?\C-c ?n] 'durand-bongo-play-next-or-first
+ ;; [?\C-c ?p] 'durand-bongo-play-previous-or-last
+ ;; :map bongo-playlist-mode-map
+ ;; [?n] 'bongo-next-object-line
+ ;; [?p] 'bongo-previous-object-line
+ ;; [?j] 'durand-bongo-save-playlist
+ ;; "TAB" #'bongo-show
+ ;; [?\C-c ?n] 'durand-bongo-play-next-or-first
+ ;; [?\C-c ?p] 'durand-bongo-play-previous-or-last)
+
+ ;; seek mode map additions
+
+ (define-key bongo-seek-mode-map [?t] 'bongo-seek-to)
+
+ ;;; functions
+
+;;;###autoload
+ (defun contrib/bongo-add-dired-files ()
+ "Add marked files inside of a Dired buffer to the Bongo library."
+ (interactive)
+ (require 'dired)
+ (let (file-point file files)
+ (dired-map-over-marks
+ (setq file-point (dired-move-to-filename)
+ file (dired-get-filename)
+ files (append files (list file)))
+ nil t)
+ (ignore file-point)
+ (with-current-buffer (bongo-playlist-buffer)
+ (let ((beg (point)))
+ (mapc 'bongo-insert-file files)
+ (bongo-maybe-join-inserted-tracks beg (point))))))
+
+;;;###autoload
+ (defun durand-bongo-dired-library ()
+ "Set `bongo-dired-library-mode' when accessing bongo-default-directory.
+This is meant to be hooked to `dired-mode'.
+
+Upon activation, the directory and all its sub-directories become
+a valid library buffer for Bongo, from where we can, among
+others, add tracks to playlists.
+
+The added benefit is that Dired will continue to behave as
+normal, making this a superior alternative to a purpose-specific
+library buffer.
+
+Adapted from Protesilaos' dotemacs."
+ (cond
+ ((let ((temp durand-bongo-music-dir) dir found)
+ (while (and (consp temp) (not found))
+ (setq dir (car temp)
+ temp (cdr temp))
+ (cond
+ ((file-in-directory-p default-directory dir)
+ (setq found t))))
+ found)
+ (set (make-local-variable 'bongo-dired-library-mode) 't))))
+
+;;;###autoload
+ (defun prot/bongo-clear-playlist-and-stop ()
+ "Stop playback and clear the entire `bongo' playlist buffer.
+Contrary to the standard `bongo-erase-buffer', this also removes
+the currently-playing track.
+
+Modified by Durand so that this also runs while not in a bongo
+buffer."
+ (interactive)
+ (with-bongo-playlist-buffer
+ (bongo-stop)
+ (bongo-erase-buffer)))
+
+;;;###autoload
+ (defun prot/bongo-play-random ()
+ "Play a random track with `bongo' and set random playback."
+ (interactive)
+ (when (or (bongo-playlist-buffer-p)
+ (bongo-library-buffer-p))
+ (bongo-play-random)
+ (setf bongo-next-action 'durand-bongo-play-next-or-first)
+ ;; (bongo-random-playback-mode 1)
+ ))
+
+;;;###autoload
+ (defun prot/bongo-library-insert-and-play-random ()
+ "Add directory tree or marked items to the `bongo' playlist.
+Create the playlist buffer if necessary.
+This is meant to work while inside a `dired' buffer that doubles
+as a library buffer (see `prot/bongo-dired-library')."
+ (interactive)
+ (when (bongo-library-buffer-p)
+ (unless (bongo-playlist-buffer-p)
+ (bongo-playlist-buffer))
+ (contrib/bongo-add-dired-files)
+ ;; (prot/bongo-play-random)
+ ))
+
+;;;###autoload
+ (defun durand-bongo-insert-delete-playlist ()
+ "Insert or delete a `bongo' playlist.
+The files are stored in a predetermined path inside the Music
+directory. Upon insertion, playback starts immediately, in
+accordance with `prot/bongo-play-random'.
+
+Adapted from Protesilaos' dotemacs by Durand."
+ (interactive)
+ (let* ((path (file-name-as-directory
+ (expand-file-name
+ "playlists"
+ bongo-default-directory)))
+ (dotless directory-files-no-dot-files-regexp)
+ (playlist (directory-files path t dotless)))
+ (with-bongo-playlist-buffer
+ (bongo-insert-playlist-contents
+ (completing-read "Select playlist: " playlist nil t path))
+ ;; (ivy-read "Choose a playlist file: " playlist
+ ;; :require-match t
+ ;; :caller 'durand-bongo-insert-delete-playlist
+ ;; :action '(1
+ ;; ("i" bongo-insert-playlist-contents "insert playlist")
+ ;; ("d" (lambda (file)
+ ;; (delete-file file)
+ ;; (setf (ivy-state-collection ivy-last)
+ ;; (directory-files
+ ;; (file-name-as-directory
+ ;; (expand-file-name
+ ;; "playlists"
+ ;; bongo-default-directory))
+ ;; t directory-files-no-dot-files-regexp))
+ ;; (ivy--reset-state ivy-last))
+ ;; "delete playlist")
+ ;; ("e" find-file "edit")))
+ ;; (prot/bongo-play-random)
+ )))
+
+;;;###autoload
+ ;; (defun durand-bongo-dired-ivy-find-to-add ()
+ ;; "Use `durand-choose-list' to find files to add to bongo."
+ ;; (interactive)
+ ;; ;; (require 'counsel)
+ ;; (require 'grep)
+ ;; ;; (counsel-require-program find-program)
+ ;; ;; (cl-assert
+ ;; ;; (and (derived-mode-p 'dired-mode)
+ ;; ;; (file-in-directory-p default-directory bongo-default-directory)))
+ ;; (let* ((default-directory
+ ;; (cond
+ ;; ((and (derived-mode-p 'dired-mode)
+ ;; (file-in-directory-p default-directory bongo-default-directory))
+ ;; default-directory)
+ ;; (t
+ ;; bongo-default-directory)))
+ ;; (all-files (counsel--find-return-list counsel-file-jump-args))
+ ;; (base default-directory)
+ ;; (chosen-files (durand-choose-list (mapcar 'list all-files) nil "Choose music to add: " t
+ ;; nil nil t nil t)))
+ ;; (cl-loop for song in chosen-files
+ ;; do
+ ;; (with-bongo-playlist-buffer
+ ;; (bongo-insert-file
+ ;; (file-truename (expand-file-name song base)))))
+ ;; ;; (ivy-read "Choose music to add: " all-files
+ ;; ;; :require-match t
+ ;; ;; :action (lambda (f)
+ ;; ;; (with-current-buffer bongo-default-playlist-buffer-name
+ ;; ;; (bongo-insert-file
+ ;; ;; (file-truename (expand-file-name f base))))))
+ ;; ))
+
+ ;; REVIEW: This is oft not overriding the original function, to the effect that
+ ;; the first time bongo starts, this function does not work, and I have to
+ ;; define this function again, in order to play the music. So I decided to make
+ ;; this into an overriding advice.
+;;;###autoload
+ (defun durand-bongo-compose-remote-option (socket-file)
+ "Get the command line argument for starting mpv's remote interface at SOCKET-FILE.
+This has to be fixed for mpv to work, since its argument parsing
+convention is changed."
+ ;; :override 'bongo-compose-remote-option
+ (when (equal bongo-mpv-remote-option 'unknown)
+ (setq bongo-mpv-remote-option (bongo--mpv-get-remote-option)))
+ (list (concat bongo-mpv-remote-option "=" socket-file)))
+
+ (advice-add #'bongo-compose-remote-option :override 'durand-bongo-compose-remote-option)
+
+;;;###autoload
+ (defvar durand-bongo-save-playlist-hist nil
+ "A variable that holds the history values for saving playlist names.")
+
+;;;###autoload
+ (defun durand-bongo-save-playlist ()
+ "Save the current playlist into a file."
+ (interactive)
+ (let ((playlist-name
+ (expand-file-name
+ (read-string "Playlist name:" nil 'durand-bongo-save-playlist-hist)
+ (expand-file-name "playlists"
+ bongo-default-directory)))
+ (append-p (y-or-n-p "Append? "))
+ files end)
+ (with-current-buffer bongo-default-playlist-buffer-name
+ (save-excursion
+ (goto-char (or (bongo-point-at-first-track-line)
+ (user-error
+ "No tracks in the playlist!")))
+ (push (bongo-line-file-name) files)
+ (while (not end)
+ (if-let ((next-pos (bongo-point-at-next-track-line)))
+ (progn
+ (goto-char next-pos)
+ (push (bongo-line-file-name) files))
+ (setf end t)))))
+ (with-temp-buffer
+ (cl-loop for file in files
+ do (progn
+ (insert file)
+ (newline)))
+ (write-region nil nil playlist-name append-p))))
+
+;;;###autoload
+ (defun durand-bongo-next-or-first (&optional n)
+ "Make the next track current in the nearest playlist buffer.
+If there is no next track, go to the first track.
+With prefix argument N, skip that many tracks."
+ (interactive "P")
+ (if (bongo-playing-p)
+ (durand-bongo-play-next-or-first n)
+ (with-bongo-playlist-buffer
+ (let ((line-move-ignore-invisible nil))
+ (save-excursion
+ (goto-char (or (bongo-point-at-current-track-line)
+ (bongo-point-at-first-track-line)
+ (user-error "No tracks in playlist")))
+ (dotimes (_dummy (prefix-numeric-value n))
+ (goto-char (or (bongo-point-at-next-track-line)
+ (bongo-point-at-first-track-line))))
+ (bongo-set-current-track-position))))))
+
+;;;###autoload
+ (defun durand-bongo-play-next-or-first (&optional n)
+ "Start playing the next track in the nearest Bongo playlist buffer.
+If there is no next track to play, signal an error.
+With numerical prefix argument N, skip that many tracks.
+With \\[universal-argument] as prefix argument, just switch to \
+progressive playback mode.
+With \\[universal-argument] \\[universal-argument] as prefix argument, \
+insert an action track at point."
+ (interactive "P")
+ (cond
+ ((equal n '(16))
+ (bongo-insert-line 'bongo-action '(bongo-progressive-playback-mode)))
+ ((equal n '(4))
+ (bongo-progressive-playback-mode))
+ ((consp n)
+ (user-error "This prefix argument %S is not supported."
+ n))
+ ((< (prefix-numeric-value n) 0)
+ (durand-bongo-play-previous-or-last (- (prefix-numeric-value n))))
+ (t
+ (with-imminent-bongo-player-start
+ (bongo-stop)
+ (when bongo-mark-played-tracks
+ (bongo-mark-current-track-line-as-played))
+ (durand-bongo-next-or-first n)
+ (bongo-start)))))
+
+;;;###autoload
+ (defun durand-bongo-previous-or-last (&optional n)
+ "Make the previous track current in the nearest playlist buffer.
+If there is no previous track, go to the last track.
+With prefix argument N, skip that many tracks."
+ (interactive "p")
+ (if (bongo-playing-p)
+ (durand-bongo-play-previous-or-last n)
+ (with-bongo-playlist-buffer
+ (let ((line-move-ignore-invisible nil))
+ (save-excursion
+ (goto-char (or (bongo-point-at-current-track-line)
+ (bongo-point-at-last-track-line)
+ (user-error "No tracks in playlist")))
+ (dotimes (_dummy (prefix-numeric-value n))
+ (goto-char (or (bongo-point-at-previous-track-line)
+ (bongo-point-at-last-track-line))))
+ (bongo-set-current-track-position))))))
+
+;;;###autoload
+ (defun durand-bongo-play-previous-or-last (&optional n)
+ "Start playing the previous track in the nearest playlist buffer.
+If there is no previous track to play, play the last track.
+With numerical prefix argument N, skip that many tracks.
+With \\[universal-argument] as prefix argument, just switch to \
+regressive playback mode.
+With \\[universal-argument] \\[universal-argument] as prefix argument, \
+insert an action track at point."
+ (interactive "P")
+ (cond
+ ((equal n '(16))
+ (bongo-insert-line 'bongo-action '(bongo-regressive-playback-mode)))
+ ((equal n '(4))
+ (bongo-regressive-playback-mode))
+ ((consp n)
+ (user-error "This prefix argument %S is not supported."
+ n))
+ ((< (prefix-numeric-value n) 0)
+ (durand-bongo-play-next-or-first (- (prefix-numeric-value n))))
+ (t
+ (with-imminent-bongo-player-start
+ (bongo-stop)
+ (when bongo-mark-played-tracks
+ (bongo-mark-current-track-line-as-played))
+ (durand-bongo-previous-or-last n)
+ (bongo-start)))))
+
+;;;###autoload
+ (defun durand-bongo-play-first ()
+ "Play the first song."
+ (interactive)
+ (with-bongo-playlist-buffer
+ (with-imminent-bongo-player-start
+ (bongo-stop)
+ (when bongo-mark-played-tracks
+ (bongo-mark-current-track-line-as-played))
+ (goto-char (or (bongo-point-at-first-track-line)
+ (prog1 (point)
+ (message "No track in the playlist buffer."))))
+ (bongo-set-current-track-position)
+ (bongo-start))))
+
+;;;###autoload
+ (defun durand-bongo-play-last ()
+ "Play the first song."
+ (interactive)
+ (with-bongo-playlist-buffer
+ (with-imminent-bongo-player-start
+ (bongo-stop)
+ (when bongo-mark-played-tracks
+ (bongo-mark-current-track-line-as-played))
+ (goto-char (or (bongo-point-at-last-track-line)
+ (prog1 (point)
+ (message "No track in the playlist buffer."))))
+ (bongo-set-current-track-position)
+ (bongo-start))))
+
+ ;; NOTE: Fix a bug: there is no face called `modeline'; it should be
+ ;; `mode-line'.
+;;;###autoload
+ (defun durand-bongo-seek ()
+ "Interactively seek in the current Bongo track."
+ ;; :override 'bongo-seek
+ (interactive)
+ (setq bongo-seek-buffer (get-buffer-create "*Bongo Seek*"))
+ (if bongo-seek-electric-mode
+ (unwind-protect
+ (save-window-excursion
+ (require 'electric)
+ (message nil)
+ (let ((garbage-collection-messages nil)
+ (bongo-seeking-electrically t))
+ (ignore bongo-seeking-electrically)
+ (set-window-buffer (minibuffer-window) bongo-seek-buffer)
+ (select-window (minibuffer-window))
+ (let ((old-local-map (current-local-map))
+ (old-global-map (current-global-map)))
+ (use-local-map nil)
+ (use-global-map bongo-seek-mode-map)
+ (setq major-mode 'bongo-seek-mode)
+ (unwind-protect
+ (progn
+ (bongo-seek-redisplay)
+ (run-hooks 'bongo-seek-mode-hook)
+ (catch 'bongo-seek-done
+ (Electric-command-loop
+ 'bongo-seek-done
+ ;; Avoid `noprompt' due to
+ ;; a bug in electric.el.
+ '(lambda () 'noprompt)
+ nil
+ (lambda (_x _y) (bongo-seek-redisplay)))))
+ (use-local-map old-local-map)
+ (use-global-map old-global-map)))))
+ (when bongo-seek-buffer
+ (kill-buffer bongo-seek-buffer)
+ (setq bongo-seek-buffer nil)))
+ (cond
+ ((null (get-buffer-window bongo-seek-buffer))
+ (let ((window-min-height 2)
+ (split-window-keep-point nil))
+ (select-window
+ (split-window-vertically
+ (if (and (fboundp 'face-attr-construct)
+ ;; NOTE: bug occurs here.
+ (plist-get (face-attr-construct 'mode-line) :box))
+ -3 -2)))
+ (switch-to-buffer bongo-seek-buffer)))
+ ((not (eq (current-buffer) bongo-seek-buffer))
+ (select-window (get-buffer-window bongo-seek-buffer))))
+ (bongo-seek-mode)
+ ;; NOTE: added by Durand to start always in evil-emacs-state
+ (setq buffer-read-only t)
+ (bongo-seek-redisplay)))
+
+ (advice-add 'bongo-seek :override #'durand-bongo-seek)
+
+;;; HACK: Redefine a function to go to the bongo-default-directory when no track
+;;; is under point.
+;;;
+;;;###autoload
+ (defun durand-bongo-dired-line (&optional point)
+ "Open a Dired buffer containing the track at POINT.
+Modified by Durand."
+ ;; :override 'bongo-dired-line
+ (interactive)
+ ;;; NOTE: The body-form inside condition-case is the original function body.
+ (condition-case nil
+ (save-excursion
+ (bongo-goto-point point)
+ (bongo-snap-to-object-line)
+ (dired (file-name-directory
+ (save-excursion
+ (while (bongo-header-line-p)
+ (bongo-down-section))
+ (if (bongo-local-file-track-line-p)
+ (bongo-line-file-name)
+ (error "No local file track here")))))
+ (bongo-dired-library-mode 1))
+ ('error (dired bongo-default-directory))))
+
+ (advice-add 'bongo-dired-line :override #'durand-bongo-dired-line)
+
+;;; NOTE: I would like bongo to jump to bongo-playlist-buffer immediately,
+;;; otherwise sometimes it jumps to the dired buffer, which is annoying.
+
+;;;###autoload
+ (defun durand-bongo-buffer ()
+ "Return the buffer (bongo-playlist-buffer)."
+ :override 'bongo-buffer
+ (interactive)
+ (bongo-playlist-buffer))
+
+ (advice-add #'bongo-buffer :override #'durand-bongo-buffer)
+
+;;; hydra
+
+ ;; NOTE: I would like to have a hydra to do some basic bongo commands, like go
+ ;; to the next song, or control the volume.
+
+;;;###autoload
+ (defun durand-bongo-next-song (&optional n)
+ "Play the next N song."
+ (interactive "p")
+ (with-bongo-playlist-buffer
+ (durand-bongo-play-next-or-first n)))
+
+;;;###autoload
+ (defun durand-bongo-previous-song (&optional n)
+ "Play the previous N song."
+ (interactive "p")
+ (with-bongo-playlist-buffer
+ (durand-bongo-play-previous-or-last n)))
+
+;;;###autoload
+ (defun durand-bongo-seek-anywhere ()
+ "A wrapper around `durand-bongo-seek'."
+ (interactive)
+ (with-bongo-playlist-buffer
+ (durand-bongo-seek)
+ (setf durand-bongo-hydra-volume-return-p t)))
+
+;;;###autoload
+ (defun bongo-seek-forward-5 (&optional n)
+ "Seek 5 N seconds forward in the currently playing track."
+ (interactive "p")
+ (bongo-seek-forward (* 5 (or n 1))))
+
+;;;###autoload
+ (defun bongo-seek-backward-5 (&optional n)
+ "Seek 5 N seconds backward in the currently playing track."
+ (interactive "p")
+ (bongo-seek-backward (* 5 (or n 1))))
+
+;;;###autoload
+ (defun durand-bongo-kill-line ()
+ "Kill the currently playing bongo line."
+ (interactive)
+ (with-bongo-playlist-buffer
+ (bongo-recenter)
+ (bongo-kill-line)))
+
+ ;; NOTE: I would like to stay in my hydra after setting the volume, so I wrote
+ ;; this hacky workaround.
+
+;;;###autoload
+ ;; (defvar durand-bongo-hydra-volume-return-p nil
+ ;; "Whether to return to the hydra after quitting the volume buffer.")
+
+ ;; ;;;###autoload
+ ;; (defun durand-bongo-volume ()
+ ;; "Stay in the hydra after adjusting the volume."
+ ;; (interactive)
+ ;; (volume)
+ ;; (setf durand-bongo-hydra-volume-return-p t))
+
+ ;; ;;;###autoload
+ ;; (defadvice! durand-bongo-volume-call-hydra-a (&rest _args)
+ ;; "Call `durand-bongo-hydra/body' if `durand-bongo-hydra-volume-return-p' is non-nil."
+ ;; :after '(volume-quit bongo-seek-quit)
+ ;; (when durand-bongo-hydra-volume-return-p
+ ;; (durand-bongo-hydra/body)))
+
+ ;; ;;;###autoload
+ ;; (defhydra durand-bongo-hydra (nil
+ ;; nil
+ ;; :hint nil
+ ;; :color blue
+ ;; :pre (setf durand-bongo-hydra-volume-return-p nil))
+ ;; "
+ ;; _q_: quit _n_: next song _f_ : forward 5 _F_: forward 10 _<tab>_: show
+ ;; _v_: volume _p_: previous song _b_ : backward 5 _B_: backward 10
+ ;; _s_: seek _d_: clear _SPC_: pause / resume _<_: first
+ ;; _m_: bongo _i_: insert _I_ : playlist _>_: last
+ ;; "
+ ;; ("q" nil)
+ ;; ("v" durand-bongo-volume)
+ ;; ("s" durand-bongo-seek-anywhere)
+ ;; ("m" bongo)
+ ;; ("n" durand-bongo-next-song :color amaranth)
+ ;; ("p" durand-bongo-previous-song :color amaranth)
+ ;; ("d" prot/bongo-clear-playlist-and-stop :color amaranth)
+ ;; ("i" durand-bongo-dired-ivy-find-to-add :color amaranth)
+ ;; ("f" bongo-seek-forward-5 :color amaranth)
+ ;; ("b" bongo-seek-backward-5 :color amaranth)
+ ;; ("SPC" bongo-pause/resume :color amaranth)
+ ;; ("I" durand-bongo-insert-delete-playlist :color amaranth)
+ ;; ("F" bongo-seek-forward-10 :color amaranth)
+ ;; ("B" bongo-seek-backward-10 :color amaranth)
+ ;; ("<" durand-bongo-play-first :color amaranth)
+ ;; (">" durand-bongo-play-last :color amaranth)
+ ;; ("<tab>" bongo-show :color amaranth))
+
+ ;; ;;; NOTE: volume-set does not refresh the display, so let's fix that.
+
+ (defun durand-bongo-refresh-after-set-a (&rest _args)
+ "Refresh the display after we set the volume."
+ ;; :after 'volume-set
+ (volume-redisplay))
+
+ (advice-add #'volume-set :after #'durand-bongo-refresh-after-set-a)
+
+;;; Don't insert text in the playlist buffer.
+
+;;;###autoload
+ (defun durand-bongo-default-playlist-buffer-a ()
+ "Don't insert text in the playlist buffer."
+ ;; :override #'bongo-default-playlist-buffer
+ (or (get-buffer bongo-default-playlist-buffer-name)
+ (let ((buffer (get-buffer-create bongo-default-playlist-buffer-name)))
+ (prog1 buffer
+ (with-current-buffer buffer
+ (bongo-playlist-mode))))))
+
+ (advice-add #'bongo-default-playlist-buffer :override #'durand-bongo-default-playlist-buffer-a)
+ )
+
+(use-package "volume" 'volume
+ (define-key volume-mode-map [?s] #'volume-set))