(define-key map (kbd "TAB") 'completion-at-point)
map))
+(defun squeeze-unhex-string (string)
+ (with-temp-buffer
+ (let ((case-fold-search t)
+ (start 0))
+ (while (string-match "%[0-9a-f][0-9a-f]" string start)
+ (let* ((s (match-beginning 0))
+ (ch1 (url-unhex (elt string (+ s 1))))
+ (code (+ (* 16 ch1)
+ (url-unhex (elt string (+ s 2))))))
+ (insert (substring string start s)
+ (byte-to-string code))
+ (setq start (match-end 0))))
+ (insert (substring string start)))
+ (buffer-string)))
+
(defun squeeze-unhex-and-decode-utf8-string (string)
- (decode-coding-string (url-unhex-string string) 'utf-8))
+ (decode-coding-string (squeeze-unhex-string string) 'utf-8))
(define-derived-mode squeeze-mode comint-mode "Squeeze"
"Major mode for interacting with the Squeezebox Server CLI.\\<squeeze-mode-map>"
(defvar squeeze-control-inhibit-display nil)
-(lexical-let ((buffer ""))
+(lexical-let ((buffer (get-buffer-create " *squeeze-update-state*")))
(defun squeeze-update-state (string)
+ ;; FIXME: we could make this a lot more elegant by using the
+ ;; buffer abstraction more
(if (cl-position ?\n string)
(let (done-something)
- (setq string (concat buffer string))
+ (with-current-buffer buffer
+ (insert string)
+ (setq string (buffer-string))
+ (erase-buffer))
(dolist (line (split-string string "\n"))
(when (squeeze-update-state-from-line line)
(setq done-something t)))
(when done-something
(unless squeeze-control-inhibit-display
- (squeeze-control-display-players)))
- (setq buffer ""))
- (setq buffer (concat buffer string)))
+ (squeeze-control-display-players))))
+ (with-current-buffer buffer
+ (insert string)))
string))
(defconst squeeze-player-line-regexp
(save-match-data
(let (result)
(loop
- (if (string-match "\\([a-z]+\\)%3A\\([^ \n]+\\)" string start)
+ (if (string-match "\\([a-z_]+\\)%3A\\([^ \n]+\\)" string start)
(let ((mend (match-end 0)))
(when (> mend end)
(return))
"serverstatus" "status" "displaystatus" "readdirectory"
;; Notifications
-
+
;; Alarm commands and queries
"alarm" "alarms"