Fix indentation
This commit is contained in:
parent
b96930ddeb
commit
4005c3fc2c
1 changed files with 241 additions and 241 deletions
482
empc.el
482
empc.el
|
|
@ -17,19 +17,19 @@
|
|||
(defcustom empc-server-password nil
|
||||
"The password for the MPD server."
|
||||
:type '(choice (const :tag "None" nil)
|
||||
string)
|
||||
string)
|
||||
:group 'empc)
|
||||
|
||||
(defcustom empc-stream-url nil
|
||||
"The url of the stream to play when asking MPD to start."
|
||||
:type '(choice (const :tag "None" nil)
|
||||
string)
|
||||
string)
|
||||
:group 'empc)
|
||||
|
||||
(defcustom empc-stream-program "mplayer"
|
||||
"The program to launch to play the stream."
|
||||
:type '(choice (const :tag "None" nil)
|
||||
string)
|
||||
string)
|
||||
:group 'empc)
|
||||
|
||||
(defcustom empc-default-crossfade 5
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
(defcustom empc-buffer-name nil
|
||||
"The name of the buffer for server responses."
|
||||
:type '(choice (const :tag "None" nil)
|
||||
string)
|
||||
string)
|
||||
:group 'empc-debug)
|
||||
|
||||
(defconst empc-buffer-name "*empc-process*"
|
||||
|
|
@ -110,22 +110,22 @@ Leave the idle state beforehand if necessary."
|
|||
(when (empc-process object)
|
||||
(when command
|
||||
(with-current-buffer (empc-log object)
|
||||
(goto-char (point-max))
|
||||
(insert command)))
|
||||
(goto-char (point-max))
|
||||
(insert command)))
|
||||
(if (empc-queue object)
|
||||
(when (string= (empc-queue-head-command object) "idle\n")
|
||||
(setcar (caaar object) "noidle\n")
|
||||
(process-send-string (empc-process object) "noidle\n"))
|
||||
(when (string= (empc-queue-head-command object) "idle\n")
|
||||
(setcar (caaar object) "noidle\n")
|
||||
(process-send-string (empc-process object) "noidle\n"))
|
||||
(when command
|
||||
(process-send-string (empc-process object) command))))
|
||||
(process-send-string (empc-process object) command))))
|
||||
(setcar (car object)
|
||||
(nconc (empc-queue object)
|
||||
(list (cons command (cons closure fn))))))
|
||||
(nconc (empc-queue object)
|
||||
(list (cons command (cons closure fn))))))
|
||||
|
||||
(defun empc-queue-sync (object)
|
||||
"Empty object's queue synchronously."
|
||||
(while (and (not (string= (empc-queue-head-command object) "idle\n"))
|
||||
(accept-process-output (empc-process object) 10))))
|
||||
(accept-process-output (empc-process object) 10))))
|
||||
|
||||
(defun empc-queue-pop (object)
|
||||
"Pop the head of the queue then send the next command.
|
||||
|
|
@ -133,19 +133,19 @@ If there is no command left to send, put the client in idle state."
|
|||
(setcar (car object) (cdr (empc-queue object)))
|
||||
(if (empc-queue object)
|
||||
(progn
|
||||
(when (> (length (empc-queue object)) 1)
|
||||
(empc-queue-merge object))
|
||||
(when (empc-queue-head-command object)
|
||||
(process-send-string (empc-process object) (empc-queue-head-command object))))
|
||||
(when (> (length (empc-queue object)) 1)
|
||||
(empc-queue-merge object))
|
||||
(when (empc-queue-head-command object)
|
||||
(process-send-string (empc-process object) (empc-queue-head-command object))))
|
||||
(empc-queue-push object "idle\n" 'empc-response-idle 'empc-handle-response)))
|
||||
|
||||
(defun empc-queue-merge (object)
|
||||
"Merge all commands in the queue as a single command_list."
|
||||
(let ((command "command_list_ok_begin\n")
|
||||
(closures nil))
|
||||
(closures nil))
|
||||
(setq closures (dolist (cell (empc-queue object) (reverse closures))
|
||||
(setq command (concat command (car cell)))
|
||||
(setq closures (cons (cadr cell) closures))))
|
||||
(setq command (concat command (car cell)))
|
||||
(setq closures (cons (cadr cell) closures))))
|
||||
(setq command (concat command "command_list_end\n"))
|
||||
(setcar (car object) (list (cons command (cons closures 'empc-handle-response-list))))))
|
||||
|
||||
|
|
@ -166,18 +166,18 @@ If there is no command left to send, put the client in idle state."
|
|||
(defun empc-update-playlistsongs (object)
|
||||
"Fix songs position in the playlist."
|
||||
(let ((i 0)
|
||||
hash-items)
|
||||
hash-items)
|
||||
(mapcar (lambda (id)
|
||||
(puthash id (plist-put (empc-song-by-id object id) :pos i) (empc-playlist-songs object))
|
||||
(incf i))
|
||||
(empc-playlist object))
|
||||
(puthash id (plist-put (empc-song-by-id object id) :pos i) (empc-playlist-songs object))
|
||||
(incf i))
|
||||
(empc-playlist object))
|
||||
(let ((playlist-items (append (empc-playlist object) nil)))
|
||||
(maphash (lambda (key value)
|
||||
(unless (memq key playlist-items)
|
||||
(setq hash-items (cons key hash-items))))
|
||||
(empc-playlist-songs object)))
|
||||
(unless (memq key playlist-items)
|
||||
(setq hash-items (cons key hash-items))))
|
||||
(empc-playlist-songs object)))
|
||||
(mapcar (lambda (id)
|
||||
(remhash id (empc-playlist-songs object))) hash-items)))
|
||||
(remhash id (empc-playlist-songs object))) hash-items)))
|
||||
|
||||
(defun empc-create (name buffer host service)
|
||||
"Create and return a new object for empc. The parameters are as follows:
|
||||
|
|
@ -192,15 +192,15 @@ SERVICE is the name of the service desired, or an integer specifying
|
|||
a port number to connect to."
|
||||
|
||||
(let* ((process (open-network-stream name buffer host service))
|
||||
(object `((nil ,process ,(generate-new-buffer "*empc-log*") . ("password" "commands" "status" "playlistinfo" "idle")) nil nil))) ;; this weird form represents an empty object as described in empc-object
|
||||
; (empc-commands-set object '("password" "commands" "status" "playlistinfo" "idle"))
|
||||
(object `((nil ,process ,(generate-new-buffer "*empc-log*") . ("password" "commands" "status" "playlistinfo" "idle")) nil nil))) ;; this weird form represents an empty object as described in empc-object
|
||||
; (empc-commands-set object '("password" "commands" "status" "playlistinfo" "idle"))
|
||||
(empc-queue-push object nil nil `(lambda (command closure msg)
|
||||
(message "Connection to %s established" ',host)))
|
||||
(message "Connection to %s established" ',host)))
|
||||
(set-process-filter process `(lambda (proc string)
|
||||
(empc-process-filter ',object string)))
|
||||
(empc-process-filter ',object string)))
|
||||
(set-process-sentinel process 'empc-process-sentinel)
|
||||
(if (fboundp 'set-process-query-on-exit-flag)
|
||||
(set-process-query-on-exit-flag process nil)
|
||||
(set-process-query-on-exit-flag process nil)
|
||||
(process-kill-without-query process))
|
||||
(set-process-coding-system process 'utf-8-unix 'utf-8-unix)
|
||||
(buffer-disable-undo (process-buffer process))
|
||||
|
|
@ -222,10 +222,10 @@ You can use the following already defined variables:
|
|||
genre, composer, performer, disc, comment, pos, full-pos.")
|
||||
|
||||
(defvar empc-mode-line-format '((if (string= state "play")
|
||||
(concat " [" pos "/" playlistlength "] " (if (and artist title)
|
||||
(concat artist " - " title)
|
||||
file))
|
||||
(concat " " state)))
|
||||
(concat " [" pos "/" playlistlength "] " (if (and artist title)
|
||||
(concat artist " - " title)
|
||||
file))
|
||||
(concat " " state)))
|
||||
"Format used to display empc state in mode-line.
|
||||
The construction is the same as `mode-line-format'.
|
||||
You can use the following already defined variables:
|
||||
|
|
@ -247,19 +247,19 @@ For status:
|
|||
"Return a string representing a song formatted for the playlist buffer."
|
||||
(when song
|
||||
(concat (empc-time-to-string (plist-get song :time)) "\t"
|
||||
(if (and (plist-member song :artist) (plist-member song :title))
|
||||
(concat (plist-get song :artist) " - " (plist-get song :title))
|
||||
(plist-get song :file)))))
|
||||
(if (and (plist-member song :artist) (plist-member song :title))
|
||||
(concat (plist-get song :artist) " - " (plist-get song :title))
|
||||
(plist-get song :file)))))
|
||||
|
||||
(defun empc-mode-line-to-string ()
|
||||
"Return a string to write to the mode-line."
|
||||
(if (eq (empc-status-get empc-object :state) 'play)
|
||||
(concat " [" (number-to-string (1+ (empc-status-get empc-object :song))) "/" (number-to-string (empc-status-get empc-object :playlistlength)) "] "
|
||||
(if (and (plist-member (empc-current-song empc-object) :artist)
|
||||
(plist-member (empc-current-song empc-object) :title))
|
||||
(concat (plist-get (empc-current-song empc-object) :artist)
|
||||
" - " (plist-get (empc-current-song empc-object) :title))
|
||||
(plist-get (empc-current-song empc-object) :file)))
|
||||
(if (and (plist-member (empc-current-song empc-object) :artist)
|
||||
(plist-member (empc-current-song empc-object) :title))
|
||||
(concat (plist-get (empc-current-song empc-object) :artist)
|
||||
" - " (plist-get (empc-current-song empc-object) :title))
|
||||
(plist-get (empc-current-song empc-object) :file)))
|
||||
(concat " " (symbol-name (empc-status-get empc-object :state)))))
|
||||
|
||||
(defvar empc-last-crossfade nil)
|
||||
|
|
@ -300,11 +300,11 @@ For status:
|
|||
(defun empc-process-filter (object string)
|
||||
"Append STRING to the process buffer then process the data."
|
||||
(let ((debug-on-error t)
|
||||
(buffer (process-buffer (empc-process object))))
|
||||
(buffer (process-buffer (empc-process object))))
|
||||
(when (buffer-live-p buffer)
|
||||
(with-current-buffer buffer
|
||||
(goto-char (point-max))
|
||||
(insert string))
|
||||
(goto-char (point-max))
|
||||
(insert string))
|
||||
(empc-process-buffer object))))
|
||||
|
||||
(defun empc-process-buffer (object)
|
||||
|
|
@ -313,39 +313,39 @@ For status:
|
|||
stored at the head of the queue with the associated closure and
|
||||
the output as parameters."
|
||||
(let ((buffer (process-buffer (empc-process object)))
|
||||
(complete-response))
|
||||
(complete-response))
|
||||
(when (buffer-live-p buffer)
|
||||
(with-current-buffer buffer
|
||||
(unless (= 0 (buffer-size))
|
||||
(if (not (empc-queue object))
|
||||
(let ((buf (generate-new-buffer "*spurious*")))
|
||||
(copy-to-buffer buf (point-min) (point-max))
|
||||
(delete-region (point-min) (point))
|
||||
(pop-to-buffer buf nil)
|
||||
(error "Spurious communication from process %s, see buffer %s"
|
||||
(process-name (empc-process object))
|
||||
(buffer-name buf)))
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward empc-response-regexp nil t)
|
||||
(setq complete-response (buffer-substring (point-min) (point)))
|
||||
(delete-region (point-min) (point)))))))
|
||||
(unless (= 0 (buffer-size))
|
||||
(if (not (empc-queue object))
|
||||
(let ((buf (generate-new-buffer "*spurious*")))
|
||||
(copy-to-buffer buf (point-min) (point-max))
|
||||
(delete-region (point-min) (point))
|
||||
(pop-to-buffer buf nil)
|
||||
(error "Spurious communication from process %s, see buffer %s"
|
||||
(process-name (empc-process object))
|
||||
(buffer-name buf)))
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward empc-response-regexp nil t)
|
||||
(setq complete-response (buffer-substring (point-min) (point)))
|
||||
(delete-region (point-min) (point)))))))
|
||||
(when complete-response
|
||||
(unwind-protect
|
||||
(funcall (empc-queue-head-fn object)
|
||||
(empc-queue-head-command object)
|
||||
(empc-queue-head-closure object) complete-response)
|
||||
(empc-queue-pop object))
|
||||
(funcall (empc-queue-head-fn object)
|
||||
(empc-queue-head-command object)
|
||||
(empc-queue-head-closure object) complete-response)
|
||||
(empc-queue-pop object))
|
||||
(empc-process-buffer object))))
|
||||
|
||||
(defun empc-stream-process-sentinel (proc event)
|
||||
"Process sentinel for `empc-stream-process'."
|
||||
(let ((debug-on-error t)
|
||||
(process (empc-process empc-object)))
|
||||
(process (empc-process empc-object)))
|
||||
(when (and (eq (process-status proc) 'exit)
|
||||
process
|
||||
(processp process)
|
||||
(eq (process-status process) 'open)
|
||||
(eq (empc-status-get empc-object :state) 'play))
|
||||
process
|
||||
(processp process)
|
||||
(eq (process-status process) 'open)
|
||||
(eq (empc-status-get empc-object :state) 'play))
|
||||
(empc-toggle-pause 1)))
|
||||
(setq empc-stream-process nil))
|
||||
|
||||
|
|
@ -353,8 +353,8 @@ For status:
|
|||
"Print the response into the minibuffer if EMPC-VERBOSE is non nil."
|
||||
(when empc-verbose
|
||||
(message "empc: %s" (if (string= (substring msg -1) "\n")
|
||||
(substring msg 0 -1)
|
||||
msg))))
|
||||
(substring msg 0 -1)
|
||||
msg))))
|
||||
|
||||
(defun empc-echo-notify (msg)
|
||||
"Notify MSG using notification system if available, in echo area if not."
|
||||
|
|
@ -369,10 +369,10 @@ For status:
|
|||
(setq song (empc-current-song empc-object)))
|
||||
(when song
|
||||
(empc-echo-notify (concat "[" (int-to-string (+ (plist-get song :pos) 1))
|
||||
"/" (int-to-string (empc-status-get empc-object :playlistlength)) "] "
|
||||
(if (and (plist-get song :artist) (plist-get song :title))
|
||||
(concat (plist-get song :artist) " - " (plist-get song :title))
|
||||
(plist-get song :file))))))
|
||||
"/" (int-to-string (empc-status-get empc-object :playlistlength)) "] "
|
||||
(if (and (plist-get song :artist) (plist-get song :title))
|
||||
(concat (plist-get song :artist) " - " (plist-get song :title))
|
||||
(plist-get song :file))))))
|
||||
|
||||
(defun empc-mode-line-update ()
|
||||
"Change the string to write in the mode-line and force-update it."
|
||||
|
|
@ -385,7 +385,7 @@ If the line is not of the form \"key: value\",
|
|||
check if it matches \"list_OK\"."
|
||||
(if (string-match "\\([^:\n]+\\):\\s-*\\(.+\\)" line)
|
||||
(cons (downcase (match-string 1 line))
|
||||
(match-string 2 line))
|
||||
(match-string 2 line))
|
||||
(string= line "list_OK")))
|
||||
|
||||
(defun empc-response-parse-message (msg)
|
||||
|
|
@ -394,23 +394,23 @@ If the command resulted in an error, return a plist of the
|
|||
form '('error (error-code . error-message))."
|
||||
(save-match-data
|
||||
(let* ((data (split-string msg "\n" t))
|
||||
(status (car (last data))))
|
||||
(status (car (last data))))
|
||||
(when (and (stringp (car data))
|
||||
(string-match "^OK\\( MPD \\)?" (car data)))
|
||||
(setq data (cdr data)))
|
||||
(string-match "^OK\\( MPD \\)?" (car data)))
|
||||
(setq data (cdr data)))
|
||||
(if (and (stringp status)
|
||||
(string-match "^ACK \\[\\([0-9]+\\)@[0-9]+\\] \\(.+\\)" status))
|
||||
(cons 'error (cons (match-string 1 status)
|
||||
(match-string 2 status)))
|
||||
(let ((result nil)
|
||||
(response nil))
|
||||
(dolist (line data (if result (reverse result) response))
|
||||
(let ((cell (empc-response-parse-line line)))
|
||||
(when cell
|
||||
(if (consp cell)
|
||||
(setq response (cons cell response))
|
||||
(setq result (cons response result)
|
||||
response nil))))))))))
|
||||
(string-match "^ACK \\[\\([0-9]+\\)@[0-9]+\\] \\(.+\\)" status))
|
||||
(cons 'error (cons (match-string 1 status)
|
||||
(match-string 2 status)))
|
||||
(let ((result nil)
|
||||
(response nil))
|
||||
(dolist (line data (if result (reverse result) response))
|
||||
(let ((cell (empc-response-parse-line line)))
|
||||
(when cell
|
||||
(if (consp cell)
|
||||
(setq response (cons cell response))
|
||||
(setq result (cons response result)
|
||||
response nil))))))))))
|
||||
|
||||
(defun empc-response-get-commands (command data)
|
||||
"Parse DATA to get the available commands."
|
||||
|
|
@ -430,34 +430,34 @@ According to what is in the diff, several actions can be performed:
|
|||
if :state or :songid is changed, report it to the user,
|
||||
if :state is set to 'play, start the streaming process."
|
||||
(let ((status-diff (empc-diff-status data))
|
||||
(notify nil))
|
||||
(notify nil))
|
||||
(when (plist-get status-diff :songid)
|
||||
(setq notify '(lambda ()
|
||||
(when (empc-playlist-songs empc-object)
|
||||
(empc-echo-song))
|
||||
(empc-playlist-goto-current-song))))
|
||||
(when (empc-playlist-songs empc-object)
|
||||
(empc-echo-song))
|
||||
(empc-playlist-goto-current-song))))
|
||||
(when (plist-get status-diff :state)
|
||||
(if (eq (plist-get status-diff :state) 'play)
|
||||
(progn
|
||||
(unless notify
|
||||
(setq notify '(lambda () (when (empc-playlist-songs empc-object)
|
||||
(empc-echo-song)))))
|
||||
(empc-stream-start))
|
||||
(setq notify '(lambda () (empc-echo-notify (symbol-name (plist-get status-diff :state)))))))
|
||||
(progn
|
||||
(unless notify
|
||||
(setq notify '(lambda () (when (empc-playlist-songs empc-object)
|
||||
(empc-echo-song)))))
|
||||
(empc-stream-start))
|
||||
(setq notify '(lambda () (empc-echo-notify (symbol-name (plist-get status-diff :state)))))))
|
||||
(when (or (plist-member status-diff :repeat) (plist-member status-diff :random)
|
||||
(plist-member status-diff :single) (plist-member status-diff :consume)
|
||||
(plist-member status-diff :xfade))
|
||||
(plist-member status-diff :single) (plist-member status-diff :consume)
|
||||
(plist-member status-diff :xfade))
|
||||
(setq notify '(lambda () (empc-echo-notify (format "repeat: %s, random: %s, single: %s, consume: %s, crossfade: %s"
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :repeat)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :random)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :single)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :consume)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :xfade))))))
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :repeat)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :random)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :single)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :consume)
|
||||
(empc-status-on/off-stringify (empc-status empc-object) :xfade))))))
|
||||
(while status-diff
|
||||
(let ((attr (car status-diff))
|
||||
(value (cadr status-diff)))
|
||||
(setq status-diff (cddr status-diff))
|
||||
(empc-status-put empc-object attr value)))
|
||||
(value (cadr status-diff)))
|
||||
(setq status-diff (cddr status-diff))
|
||||
(empc-status-put empc-object attr value)))
|
||||
(when (empc-playlist-songs empc-object)
|
||||
(empc-mode-line-update))
|
||||
(when notify
|
||||
|
|
@ -468,35 +468,35 @@ According to what is in the diff, several actions can be performed:
|
|||
(cond
|
||||
((eq value nil) nil)
|
||||
((memq attr '(:volume :repeat :random :single :consume :playlist :playlistlength
|
||||
:song :songid :nextsong :nextsongid :bitrate :xfade :mixrampdb
|
||||
:mixrampdelay :updating_db))
|
||||
:song :songid :nextsong :nextsongid :bitrate :xfade :mixrampdb
|
||||
:mixrampdelay :updating_db))
|
||||
(string-to-number value))
|
||||
((and (eq attr :state) (member value '("play" "pause" "stop")))
|
||||
(intern value))
|
||||
((and (eq attr :time) (string-match "^\\([0-9]*\\):\\([0-9]*\\)$" value))
|
||||
(cons (string-to-number (match-string 1 value))
|
||||
(string-to-number (match-string 2 value))))
|
||||
(string-to-number (match-string 2 value))))
|
||||
(t value)))
|
||||
|
||||
(defun empc-diff-status (data)
|
||||
"Get the diff from `empc-current-status' and server response."
|
||||
(let ((status-diff nil)
|
||||
(attributes '(:volume :repeat :random :single :consume :playlist :playlistlength :state
|
||||
:song :songid :nextsong :nextsongid :time :elapsed :bitrate :xfade
|
||||
:mixrampdb :mixrampdelay :audio :updating_db :error)))
|
||||
(attributes '(:volume :repeat :random :single :consume :playlist :playlistlength :state
|
||||
:song :songid :nextsong :nextsongid :time :elapsed :bitrate :xfade
|
||||
:mixrampdb :mixrampdelay :audio :updating_db :error)))
|
||||
(dolist (attr attributes status-diff)
|
||||
(let ((value (empc-parse-status-attr attr (cdr (assoc (substring (symbol-name attr) 1) data)))))
|
||||
(unless (equal (empc-status-get empc-object attr) value)
|
||||
(setq status-diff (plist-put status-diff attr value)))))))
|
||||
(unless (equal (empc-status-get empc-object attr) value)
|
||||
(setq status-diff (plist-put status-diff attr value)))))))
|
||||
|
||||
(defun empc-playlist-get-songs (begin &optional end)
|
||||
"Retreive a list of songs' id between BEGIN and END."
|
||||
(when (eq major-mode 'empc-playlist-mode)
|
||||
(let* ((bpos (1- (line-number-at-pos begin)))
|
||||
(epos (if end (count-lines begin end) 1))
|
||||
ids)
|
||||
(epos (if end (count-lines begin end) 1))
|
||||
ids)
|
||||
(dotimes (i epos ids)
|
||||
(setq ids (cons (empc-song-by-pos empc-object (+ bpos i)) ids))))))
|
||||
(setq ids (cons (empc-song-by-pos empc-object (+ bpos i)) ids))))))
|
||||
|
||||
(defun empc-playlist-goto-current-song ()
|
||||
"Put point at currently playing song."
|
||||
|
|
@ -504,22 +504,22 @@ According to what is in the diff, several actions can be performed:
|
|||
(when (get-buffer "*empc*")
|
||||
(let ((buffer nil))
|
||||
(unless (called-interactively-p)
|
||||
(dolist (frame (frame-list))
|
||||
(with-selected-frame frame
|
||||
(let ((bwindow (get-buffer-window "*empc*")))
|
||||
(when bwindow
|
||||
(with-selected-window bwindow
|
||||
(goto-char (point-min))
|
||||
(forward-line (empc-status-get empc-object :song))
|
||||
(when (and (not buffer) empc-may-pulse)
|
||||
(pulse-momentary-highlight-one-line (point))))
|
||||
(setq buffer bwindow))))))
|
||||
(dolist (frame (frame-list))
|
||||
(with-selected-frame frame
|
||||
(let ((bwindow (get-buffer-window "*empc*")))
|
||||
(when bwindow
|
||||
(with-selected-window bwindow
|
||||
(goto-char (point-min))
|
||||
(forward-line (empc-status-get empc-object :song))
|
||||
(when (and (not buffer) empc-may-pulse)
|
||||
(pulse-momentary-highlight-one-line (point))))
|
||||
(setq buffer bwindow))))))
|
||||
(unless buffer
|
||||
(with-current-buffer "*empc*"
|
||||
(goto-char (point-min))
|
||||
(forward-line (empc-status-get empc-object :song))
|
||||
(when (and (called-interactively-p) empc-may-pulse)
|
||||
(pulse-momentary-highlight-one-line (point))))))))
|
||||
(with-current-buffer "*empc*"
|
||||
(goto-char (point-min))
|
||||
(forward-line (empc-status-get empc-object :song))
|
||||
(when (and (called-interactively-p) empc-may-pulse)
|
||||
(pulse-momentary-highlight-one-line (point))))))))
|
||||
|
||||
(defun empc-populate-playlist-buffer ()
|
||||
"Write playlist into the *empc* buffer."
|
||||
|
|
@ -528,9 +528,9 @@ According to what is in the diff, several actions can be performed:
|
|||
(let ((buffer-read-only nil))
|
||||
(erase-buffer)
|
||||
(when (empc-playlist-songs empc-object)
|
||||
(mapcar (lambda (id)
|
||||
(empc-playlist-insert-song (empc-song-by-id empc-object id)))
|
||||
(empc-playlist empc-object))))))
|
||||
(mapcar (lambda (id)
|
||||
(empc-playlist-insert-song (empc-song-by-id empc-object id)))
|
||||
(empc-playlist empc-object))))))
|
||||
|
||||
(defmacro empc-with-current-playlist (&rest body)
|
||||
"Set the playlist buffer as the current one."
|
||||
|
|
@ -538,7 +538,7 @@ According to what is in the diff, several actions can be performed:
|
|||
(empc-switch-to-playlist)
|
||||
(save-excursion
|
||||
(let ((buffer-read-only nil))
|
||||
,@body))))
|
||||
,@body))))
|
||||
|
||||
(defmacro empc-with-song-at-point (song &rest body)
|
||||
"Retreive the song at point if applicable."
|
||||
|
|
@ -553,7 +553,7 @@ According to what is in the diff, several actions can be performed:
|
|||
(let ((needed-lines (forward-line (plist-get song :pos))))
|
||||
(when (or (> needed-lines 0) (eq (point) (point-max)))
|
||||
(dotimes (i (1+ needed-lines))
|
||||
(insert "\n"))
|
||||
(insert "\n"))
|
||||
(forward-line -1)))
|
||||
(kill-region (line-beginning-position) (line-end-position))
|
||||
(insert (empc-song-to-string song))))
|
||||
|
|
@ -562,12 +562,12 @@ According to what is in the diff, several actions can be performed:
|
|||
"Kill SONG from the playlist."
|
||||
(empc-with-current-playlist
|
||||
(let ((songs (if (listp (car song)) song
|
||||
(list song))))
|
||||
(list song))))
|
||||
(mapcar (lambda (song)
|
||||
(goto-char (point-min))
|
||||
(forward-line (plist-get song :pos))
|
||||
(kill-line 1))
|
||||
songs))))
|
||||
(goto-char (point-min))
|
||||
(forward-line (plist-get song :pos))
|
||||
(kill-line 1))
|
||||
songs))))
|
||||
|
||||
(defun empc-playlist-clean-after-playlist (pos)
|
||||
"Kill all the songs appearing in the playlist buffer that are
|
||||
|
|
@ -582,19 +582,19 @@ According to what is in the diff, several actions can be performed:
|
|||
active."
|
||||
(interactive)
|
||||
(let (ids
|
||||
(songs (if (and mark-active (use-region-p))
|
||||
(call-interactively (lambda (begin end)
|
||||
(interactive "r")
|
||||
(empc-playlist-get-songs begin end)))
|
||||
(empc-playlist-get-songs (point)))))
|
||||
(songs (if (and mark-active (use-region-p))
|
||||
(call-interactively (lambda (begin end)
|
||||
(interactive "r")
|
||||
(empc-playlist-get-songs begin end)))
|
||||
(empc-playlist-get-songs (point)))))
|
||||
(when songs
|
||||
(mapcar (lambda (song)
|
||||
(empc-send-deleteid (plist-get song :id))
|
||||
(empc-playlist-kill-song song)
|
||||
(setq ids (cons (plist-get song :id) ids)))
|
||||
songs)
|
||||
(empc-send-deleteid (plist-get song :id))
|
||||
(empc-playlist-kill-song song)
|
||||
(setq ids (cons (plist-get song :id) ids)))
|
||||
songs)
|
||||
(empc-playlist-set empc-object (delete-if (lambda (id) (memq id ids))
|
||||
(empc-playlist empc-object)))
|
||||
(empc-playlist empc-object)))
|
||||
(empc-update-playlistsongs empc-object))))
|
||||
|
||||
(defun empc-response-get-playlist (command data)
|
||||
|
|
@ -602,22 +602,22 @@ According to what is in the diff, several actions can be performed:
|
|||
hash table `empc-current-playlist-songs'sorted by songid.
|
||||
songs order is kept into an avector `empc-current-playlist'."
|
||||
(let* ((playlist-songs (make-hash-table :rehash-threshold 1.0 :size (empc-status-get empc-object :playlistlength)))
|
||||
(playlist (make-vector (empc-status-get empc-object :playlistlength) nil))
|
||||
(song nil)
|
||||
(index (- (length playlist) 1)))
|
||||
(playlist (make-vector (empc-status-get empc-object :playlistlength) nil))
|
||||
(song nil)
|
||||
(index (- (length playlist) 1)))
|
||||
(dolist (cell data)
|
||||
(let ((field (intern (concat ":" (car cell)))))
|
||||
(when (and (eq field :id) song)
|
||||
(puthash (plist-get song :id) song playlist-songs)
|
||||
(aset playlist index (plist-get song :id))
|
||||
(setq song nil)
|
||||
(decf index))
|
||||
(cond
|
||||
((memq field '(:time :track :date :pos :id))
|
||||
(setq song (plist-put song field (string-to-number (cdr cell)))))
|
||||
(t (if (plist-get song field)
|
||||
(setq song (plist-put song field (concat (plist-get song field) ", " (cdr cell))))
|
||||
(setq song (plist-put song field (cdr cell))))))))
|
||||
(when (and (eq field :id) song)
|
||||
(puthash (plist-get song :id) song playlist-songs)
|
||||
(aset playlist index (plist-get song :id))
|
||||
(setq song nil)
|
||||
(decf index))
|
||||
(cond
|
||||
((memq field '(:time :track :date :pos :id))
|
||||
(setq song (plist-put song field (string-to-number (cdr cell)))))
|
||||
(t (if (plist-get song field)
|
||||
(setq song (plist-put song field (concat (plist-get song field) ", " (cdr cell))))
|
||||
(setq song (plist-put song field (cdr cell))))))))
|
||||
(when (and song (>= index 0))
|
||||
(puthash (plist-get song :id) song playlist-songs)
|
||||
(aset playlist index (plist-get song :id)))
|
||||
|
|
@ -630,12 +630,12 @@ songs order is kept into an avector `empc-current-playlist'."
|
|||
(let (song)
|
||||
(dolist (cell data song)
|
||||
(let ((field (intern (concat ":" (car cell)))))
|
||||
(cond
|
||||
((memq field '(:time :track :date :pos :id))
|
||||
(setq song (plist-put song field (string-to-number (cdr cell)))))
|
||||
(t (if (plist-get song field)
|
||||
(setq song (plist-put song field (concat (plist-get song field) ", " (cdr cell))))
|
||||
(setq song (plist-put song field (cdr cell))))))))))
|
||||
(cond
|
||||
((memq field '(:time :track :date :pos :id))
|
||||
(setq song (plist-put song field (string-to-number (cdr cell)))))
|
||||
(t (if (plist-get song field)
|
||||
(setq song (plist-put song field (concat (plist-get song field) ", " (cdr cell))))
|
||||
(setq song (plist-put song field (cdr cell))))))))))
|
||||
|
||||
(defun empc-response-get-playlistid (command data)
|
||||
"Parse a single song and insert it into playlist-songs."
|
||||
|
|
@ -649,39 +649,39 @@ songs order is kept into an avector `empc-current-playlist'."
|
|||
(empc-send command 'empc-response-get-plchangesposid)
|
||||
(let ((new-pl (make-vector (empc-status-get empc-object :playlistlength) nil)))
|
||||
(dotimes (i (min (length new-pl) (length (empc-playlist empc-object))))
|
||||
(aset new-pl i (aref (empc-playlist empc-object) i)))
|
||||
(aset new-pl i (aref (empc-playlist empc-object) i)))
|
||||
(empc-playlist-clean-after-playlist (length new-pl))
|
||||
(empc-playlist-set empc-object new-pl)
|
||||
(while data
|
||||
(let ((id (string-to-number (cdar data)))
|
||||
(cpos (string-to-number (cdadr data))))
|
||||
(setq data (cddr data))
|
||||
(let ((song (gethash id (empc-playlist-songs empc-object))))
|
||||
(if (not song)
|
||||
(empc-send-playlistid id)
|
||||
(puthash id (setq song (plist-put song :pos cpos)) (empc-playlist-songs empc-object))
|
||||
(empc-playlist-insert-song song)))
|
||||
(aset (empc-playlist empc-object) cpos id))))))
|
||||
(let ((id (string-to-number (cdar data)))
|
||||
(cpos (string-to-number (cdadr data))))
|
||||
(setq data (cddr data))
|
||||
(let ((song (gethash id (empc-playlist-songs empc-object))))
|
||||
(if (not song)
|
||||
(empc-send-playlistid id)
|
||||
(puthash id (setq song (plist-put song :pos cpos)) (empc-playlist-songs empc-object))
|
||||
(empc-playlist-insert-song song)))
|
||||
(aset (empc-playlist empc-object) cpos id))))))
|
||||
|
||||
(defun empc-response-idle (command data)
|
||||
"React from idle interruption."
|
||||
(dolist (cell data)
|
||||
(when (string= (car cell) "changed")
|
||||
(let ((changed (cdr cell)))
|
||||
(cond
|
||||
((member changed '("player" "options"))
|
||||
(empc-send-status))
|
||||
((member changed '("playlist"))
|
||||
(empc-send-status)
|
||||
(empc-send-plchangesposid (empc-status-get empc-object :playlist))))))))
|
||||
(cond
|
||||
((member changed '("player" "options"))
|
||||
(empc-send-status))
|
||||
((member changed '("playlist"))
|
||||
(empc-send-status)
|
||||
(empc-send-plchangesposid (empc-status-get empc-object :playlist))))))))
|
||||
|
||||
(defun empc-handle-closure-call (command closures data)
|
||||
"If CLOSURES is a list of function, call them in turn with DATA
|
||||
as parameter."
|
||||
(when closures
|
||||
(if (and (listp closures) (not (memq (car closures) '(quote lambda))))
|
||||
(dolist (closure closures)
|
||||
(funcall closure command data))
|
||||
(dolist (closure closures)
|
||||
(funcall closure command data))
|
||||
(funcall closures command data))))
|
||||
|
||||
(defun empc-handle-response (command closures msg)
|
||||
|
|
@ -689,7 +689,7 @@ songs order is kept into an avector `empc-current-playlist'."
|
|||
Check the error code and process it using CLOSURES."
|
||||
(let ((data (empc-response-parse-message msg)))
|
||||
(if (eq (car data) 'error)
|
||||
(empc-echo-notify (cdr data))
|
||||
(empc-echo-notify (cdr data))
|
||||
(empc-handle-closure-call command closures data))))
|
||||
|
||||
(defun empc-handle-response-list (command closures msg)
|
||||
|
|
@ -697,13 +697,13 @@ Check the error code and process it using CLOSURES."
|
|||
Check the error code and process the different responses to the
|
||||
commands send as command_list."
|
||||
(let ((data (empc-response-parse-message msg))
|
||||
(commands (cdr (split-string command "\n"))))
|
||||
(commands (cdr (split-string command "\n"))))
|
||||
(if (eq (car data) 'error)
|
||||
(empc-echo-notify (cddr data))
|
||||
(empc-echo-notify (cddr data))
|
||||
(dolist (closure closures)
|
||||
(empc-handle-closure-call (car commands) closure (car data))
|
||||
(setq commands (cdr commands))
|
||||
(setq data (cdr data))))))
|
||||
(empc-handle-closure-call (car commands) closure (car data))
|
||||
(setq commands (cdr commands))
|
||||
(setq data (cdr data))))))
|
||||
|
||||
(defun empc-mode-line (arg)
|
||||
"Add empc info to the mode-line if ARG is non-nil, remove if
|
||||
|
|
@ -728,8 +728,8 @@ Send the password or retrieve available commands."
|
|||
"Make sure empc is connected and ready to talk to mpd."
|
||||
(let ((process (empc-process empc-object)))
|
||||
(unless (and process
|
||||
(processp process)
|
||||
(eq (process-status process) 'open))
|
||||
(processp process)
|
||||
(eq (process-status process) 'open))
|
||||
(setq empc-object (empc-create "empc" empc-buffer-name empc-server-host empc-server-port))
|
||||
(empc-initialize))))
|
||||
|
||||
|
|
@ -757,7 +757,7 @@ Send the password or retrieve available commands."
|
|||
(when (get-buffer "*empc*")
|
||||
(kill-buffer "*empc*"))
|
||||
(setq empc-object nil
|
||||
empc-last-crossfade nil))
|
||||
empc-last-crossfade nil))
|
||||
|
||||
(defun empc ()
|
||||
"Emacs MPC (not really the most original name, but oh well…)."
|
||||
|
|
@ -772,17 +772,17 @@ CLOSURE will be called on the parsed response."
|
|||
(empc-ensure-connected)
|
||||
(if (member (car (split-string command)) (empc-commands empc-object))
|
||||
(progn
|
||||
(unless (string= (substring command -1) "\n")
|
||||
(setq command (concat command "\n")))
|
||||
(empc-queue-push empc-object command closure
|
||||
(if handler handler 'empc-handle-response)))
|
||||
(unless (string= (substring command -1) "\n")
|
||||
(setq command (concat command "\n")))
|
||||
(empc-queue-push empc-object command closure
|
||||
(if handler handler 'empc-handle-response)))
|
||||
(message "empc: Command `%s' is not available (not supported by the server or forbidden to you)" command)))
|
||||
|
||||
(defun empc-send-retry ()
|
||||
"Resend the last command."
|
||||
(empc-send (empc-queue-head-command empc-object)
|
||||
(empc-queue-head-closure empc-object)
|
||||
(empc-queue-head-fn empc-object)))
|
||||
(empc-queue-head-closure empc-object)
|
||||
(empc-queue-head-fn empc-object)))
|
||||
|
||||
(defun empc-send-sync (command &optional closure handler)
|
||||
"Send COMMAND synchronously. That means empc will push the
|
||||
|
|
@ -801,7 +801,7 @@ CLOSURE will be called on the parsed response."
|
|||
If the stream process is killed for whatever the reason, pause mpd if possible."
|
||||
(let ((stream-process (empc-stream empc-object)))
|
||||
(when (and (not stream-process)
|
||||
empc-stream-url empc-stream-program)
|
||||
empc-stream-url empc-stream-program)
|
||||
(setq stream-process (start-process "empc-stream" nil empc-stream-program empc-stream-url))
|
||||
(set-process-sentinel stream-process 'empc-stream-process-sentinel)
|
||||
(setq empc-stream-process stream-process))))
|
||||
|
|
@ -820,7 +820,7 @@ If the stream process is killed for whatever the reason, pause mpd if possible."
|
|||
(select-window (get-buffer-window "*empc*")))
|
||||
(t
|
||||
(switch-to-buffer "*empc*")))
|
||||
(empc-playlist-mode))
|
||||
(empc-playlist-mode))
|
||||
|
||||
(defmacro empc-with-updated-status (&rest body)
|
||||
"Update the status and execute the forms in BODY."
|
||||
|
|
@ -835,8 +835,8 @@ If the stream process is killed for whatever the reason, pause mpd if possible."
|
|||
(interactive)
|
||||
(let ((debug-on-error t))
|
||||
(empc-send (concat ,command (when arg (concat " " (if (stringp arg)
|
||||
arg (number-to-string arg)))))
|
||||
,closure))))
|
||||
arg (number-to-string arg)))))
|
||||
,closure))))
|
||||
|
||||
(defmacro empc-define-toggle-command (command &optional state-name attr &rest body)
|
||||
"Define a command that toggle a state."
|
||||
|
|
@ -846,18 +846,18 @@ If the stream process is killed for whatever the reason, pause mpd if possible."
|
|||
,(concat "Toggle " command ".")
|
||||
(interactive)
|
||||
(let ((debug-on-error t))
|
||||
(if state
|
||||
(,(intern (concat "empc-send-" command)) (int-to-string state))
|
||||
(empc-with-updated-status
|
||||
(let ((,(if attr attr
|
||||
(intern command))
|
||||
(empc-status-get empc-object ,(intern (concat ":" (if state-name
|
||||
state-name
|
||||
command))))))
|
||||
,(if body
|
||||
`(progn ,@body)
|
||||
`(,(intern (concat "empc-send-" command)) (% (1+ ,(if attr attr
|
||||
(intern command))) 2))))))))))
|
||||
(if state
|
||||
(,(intern (concat "empc-send-" command)) (int-to-string state))
|
||||
(empc-with-updated-status
|
||||
(let ((,(if attr attr
|
||||
(intern command))
|
||||
(empc-status-get empc-object ,(intern (concat ":" (if state-name
|
||||
state-name
|
||||
command))))))
|
||||
,(if body
|
||||
`(progn ,@body)
|
||||
`(,(intern (concat "empc-send-" command)) (% (1+ ,(if attr attr
|
||||
(intern command))) 2))))))))))
|
||||
|
||||
;; Querying MPD's status
|
||||
(empc-define-simple-command "clearerror")
|
||||
|
|
@ -868,13 +868,13 @@ If the stream process is killed for whatever the reason, pause mpd if possible."
|
|||
;; Playback options
|
||||
(empc-define-toggle-command "consume")
|
||||
(empc-define-toggle-command "crossfade" "xfade" xfade
|
||||
(if (= xfade 0)
|
||||
(empc-send-crossfade (if empc-last-crossfade
|
||||
empc-last-crossfade
|
||||
empc-default-crossfade))
|
||||
(progn
|
||||
(setq empc-last-crossfade xfade)
|
||||
(empc-send-crossfade 0))))
|
||||
(if (= xfade 0)
|
||||
(empc-send-crossfade (if empc-last-crossfade
|
||||
empc-last-crossfade
|
||||
empc-default-crossfade))
|
||||
(progn
|
||||
(setq empc-last-crossfade xfade)
|
||||
(empc-send-crossfade 0))))
|
||||
(empc-define-toggle-command "random")
|
||||
(empc-define-toggle-command "repeat")
|
||||
(empc-define-simple-command "setvol")
|
||||
|
|
@ -883,12 +883,12 @@ If the stream process is killed for whatever the reason, pause mpd if possible."
|
|||
;; Controlling playback
|
||||
(empc-define-simple-command "next")
|
||||
(empc-define-toggle-command "pause" "state" state
|
||||
(cond
|
||||
((eq state 'play)
|
||||
(empc-send-pause 1))
|
||||
((eq state 'pause)
|
||||
(empc-send-pause 0))
|
||||
(t (empc-send-play))))
|
||||
(cond
|
||||
((eq state 'play)
|
||||
(empc-send-pause 1))
|
||||
((eq state 'pause)
|
||||
(empc-send-pause 0))
|
||||
(t (empc-send-play))))
|
||||
(empc-define-simple-command "playid")
|
||||
(empc-define-simple-command "previous")
|
||||
(empc-define-simple-command "stop")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue