;;; empc.el --- A simple elisp wrapper for mpd and mpc.
;;; Commentary:
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, version 3.
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <
http://www.gnu.org/licenses/>.
;; This is a single window, single playlist, no thrills, bare-bones
;; mpc client for EMACS.
;;; Code:
(define-derived-mode empc-mode fundamental-mode "Empc")
(defvar empc-buffer-name "*empc*")
(defvar empc-search-initial-input "")
(defun empc ()
"Create a new empc buffer. If it already exists switch to it."
(interactive)
(if (get-buffer empc-buffer-name)
(set-window-buffer (selected-window) empc-buffer-name)
(empc-create-playlist)))
(defun empc-create-playlist ()
"Create the playlist buffer and set it to empc-mode."
(get-buffer-create empc-buffer-name)
(set-window-buffer (selected-window) empc-buffer-name)
(with-current-buffer empc-buffer-name
(empc-mode)
(insert (shell-command-to-string "mpc playlist"))
(rectangle-number-lines (point-min) (- (point-max) 1) 1 "%-5d ")
(empc-finalize-buffer)))
(defun empc-finalize-buffer ()
"Set some final settings for the empc buffer."
(read-only-mode t)
(toggle-truncate-lines t)
(hl-line-mode t)
(goto-char (point-min))
(message "Hello :3"))
(defun empc-revert-playlist ()
"Reread the playlist."
(interactive)
(when (y-or-n-p "Revert playlist buffer?" )
(kill-buffer "*empc*")
(empc)))
(defun empc-update-database ()
"Run a databse update and revert the playlist buffer."
(interactive)
(when (y-or-n-p "Run database update?" )
(shell-command-to-string "mpc clear && mpc update --wait && mpc add /")
(empc-revert-playlist)))
(defun empc-play-highlighted ()
"Play the currently highlighted song."
(interactive)
(let ((pos (number-to-string (line-number-at-pos))))
(shell-command-to-string (concat "mpc -q play " pos))
(message (concat "Playing #" pos))))
(defun empc-search-playlist ()
"Provide a jump box to search for specific songs."
(interactive)
(let* ((playlist
(split-string
(with-current-buffer empc-buffer-name
(buffer-string))
"\n"))
(song-id (completing-read "Song: " playlist nil t
empc-search-initial-input)))
(shell-command-to-string (concat "mpc -q play "
(car (split-string song-id " "))))
(empc-follow)))
(defun empc-follow ()
"Recenter the currently played/paused song."
(interactive)
(goto-char (point-min))
(forward-line (1- (string-to-number
(shell-command-to-string "mpc current -f %position%"))))
(recenter))
(defmacro empc-generic-command (cmd quiet follow)
"Macro to generate functions for simple mpc commands.
Call command CMD. If QUIET is non-nil print the mpc status
message. If FOLLOW is non-nil follow the currently playing song."
`(defun ,(intern (concat "empc-" cmd)) ()
"This function was generated by the empc-generic-command
macro."
(interactive)
(shell-command (concat "mpc " (when ,quiet "-q ") ,cmd))
(when ,follow (empc-follow))))
(defun empc-define-keymaps ()
"Define keys in ‘empc-mode-map’."
(setq empc-mode-map (make-sparse-keymap))
(define-key empc-mode-map "\r" 'empc-play-highlighted)
(define-key empc-mode-map "p" (empc-generic-command "toggle" t nil))
(define-key empc-mode-map "n" (empc-generic-command "next" t t))
(define-key empc-mode-map "b" (empc-generic-command "prev" t t))
(define-key empc-mode-map "c" (empc-generic-command "seek +5" nil nil))
(define-key empc-mode-map "x" (empc-generic-command "seek -5" nil nil))
(define-key empc-mode-map "r" (empc-generic-command "random" nil nil))
(define-key empc-mode-map "R" (empc-generic-command "repeat" nil nil))
(define-key empc-mode-map "s" (empc-generic-command "single" nil nil))
(define-key empc-mode-map "." (empc-generic-command "status" nil nil))
(define-key empc-mode-map "+" (empc-generic-command "volume +5" nil nil))
(define-key empc-mode-map "-" (empc-generic-command "volume -5" nil nil))
(define-key empc-mode-map "f" 'empc-follow)
(define-key empc-mode-map "g" 'empc-revert-playlist)
(define-key empc-mode-map "U" 'empc-update-database)
(define-key empc-mode-map "q" 'quit-window)
(define-key empc-mode-map "j" 'empc-search-playlist))
(empc-define-keymaps)
(provide 'empc)
;;; empc.el ends here