emms-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emms-patches] darcs patch: Add emms-mark and emms-history (and 2 more)


From: Wenbin Ye
Subject: [Emms-patches] darcs patch: Add emms-mark and emms-history (and 2 more)
Date: Tue, 05 Dec 2006 19:26:53 +0800

Tue Nov 21 17:39:51 CST 2006  address@hidden
  * Add emms-mark and emms-history

Tue Dec  5 14:54:07 CST 2006  Wenbin Ye <address@hidden>
  * Add emms-mp3tag and emms-i18n

Tue Dec  5 19:22:09 CST 2006  Wenbin Ye <address@hidden>
  * Edit all track, set tag to file for mp3
New patches:

[Add emms-mark and emms-history
address@hidden {
addfile ./emms-history.el
hunk ./emms-history.el 1
+;;; emms-history.el.gz ---
+
+;; Copyright 2006 Ye Wenbin
+;;
+;; Author: address@hidden
+;; Time-stamp: <Ye Wenbin 2006-11-21 16:57:59>
+;; Version: $Id: emms-history.el,v 0.0 <2006-11-21 16:30:22> ywb Exp $
+;; Keywords: 
+;; X-URL: not distributed yet
+
+;; 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; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; Save playlists when exit emacs.
+;; Next time use M-x emms-playlist-load-saved-list to load saved
+;; playlist
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'emms-history)
+
+;;; Code:
+
+(provide 'emms-history)
+(require 'emms)
+(eval-when-compile
+  (require 'cl))
+
+(defvar emms-history-saved-list-file "~/.emacs.d/.emms-history")
+
+(defun emms-history-save-on-exit ()
+  (when (stringp emms-history-saved-list-file)
+    (let ((oldbuf emms-playlist-buffer)
+          emms-playlist-buffer playlists)
+      (save-excursion
+        (dolist (buf (remove-if-not 'buffer-live-p
+                                    (emms-playlist-buffer-list)))
+          (set-buffer buf)
+          (when (> (buffer-size) 0) ; make sure there is track in the buffer
+            (setq emms-playlist-buffer buf
+                  playlists
+                  (cons
+                   (list (buffer-name)
+                         (or
+                          (and emms-playlist-selected-marker
+                               (marker-position emms-playlist-selected-marker))
+                          (point-min))
+                         (save-excursion
+                           (widen)
+                           (nreverse
+                            (emms-playlist-tracks-in-region (point-min)
+                                                            (point-max)))))
+                   playlists))))
+        (with-temp-buffer
+          (insert "(\n;; active playlist\n")
+          (prin1 (buffer-name oldbuf) (current-buffer))
+          (insert "\n;; playlists: ((BUFFER_NAME SELECT_POSITION TRACKS) 
...)\n")
+          (prin1 playlists (current-buffer))
+          (insert "\n;; play method\n")
+          (prin1 `((emms-repeat-track . ,emms-repeat-track)
+                   (emms-repeat-playlist . ,emms-repeat-playlist))
+                 (current-buffer))
+          (insert "\n)")
+          (write-file emms-history-saved-list-file))))))
+
+(add-hook 'kill-emacs-hook 'emms-history-save-on-exit)
+
+(defun emms-history-load-saved-list ()
+  (interactive)
+  (when (and (stringp emms-history-saved-list-file)
+             (file-exists-p emms-history-saved-list-file))
+    (let (history buf)
+      (with-temp-buffer
+        (insert-file-contents emms-history-saved-list-file)
+        (setq history (read (current-buffer)))
+        (dolist (playlist (cadr history))
+          (with-current-buffer (emms-playlist-new (car playlist))
+            (setq emms-playlist-buffer (current-buffer))
+            (if (string= (car playlist) (car history))
+                (setq buf (current-buffer)))
+            (mapc 'emms-playlist-insert-track
+                  (nth 2 playlist))
+            (condition-case nil
+                (emms-playlist-select (cadr playlist))
+              (error nil))))
+        (setq emms-playlist-buffer buf)
+        (dolist (method (nth 2 history))
+          (set (car method) (cdr method)))
+        (emms-start)))))
+
+;;; emms-history.el ends here
addfile ./emms-mark.el
hunk ./emms-mark.el 1
+;;; emms-mark.el.gz ---
+
+;; Copyright 2006 Ye Wenbin
+;;
+;; Author: address@hidden
+;; Time-stamp: <Ye Wenbin 2006-11-21 17:02:28>
+;; Version: $Id: emms-mark.el,v 0.0 <2006-11-21 14:06:38> ywb Exp $
+;; Keywords: 
+;; X-URL: not distributed yet
+
+;; 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; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; Provide mark operation to tracks
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'emms-mark)
+
+;;; Code:
+
+(provide 'emms-mark)
+(require 'emms)
+(eval-when-compile
+  (require 'cl))
+
+;;{{{  set new description-function
+(defun emms-mark-track-description (track)
+  "Return a description of the current track."
+  (concat "  "                          ; for mark char
+          (let ((artist (emms-track-get track 'info-artist))
+                (title (emms-track-get track 'info-title)))
+            (if (and artist title)
+                (format "%s - %s" artist title)
+              (emms-track-simple-description track)))))
+
+(setq emms-track-description-function 'emms-mark-track-description)
+;;}}}
+
+;;{{{ functions to mark tracks
+(defvar emms-mark-char ?*)
+(defvar emms-mark-face-alist
+  '((?* . font-lock-warning-face)
+    (?\040 . emms-playlist-track-face)))
+
+(defun emms-mark-track (&optional arg)
+  (interactive "p")
+  (or arg (setq arg 1))
+  (let ((face (assoc-default emms-mark-char emms-mark-face-alist))
+        buffer-read-only track)
+    (save-excursion
+      (beginning-of-line)
+      (while (and (not (eobp))
+                  (> arg 0))
+        (setq track (get-text-property (point) 'emms-track))
+        (delete-char 1)
+        (insert (propertize (string emms-mark-char)
+                            'emms-track track))
+        (backward-char 1)
+        (put-text-property (point) (progn (forward-line 1) (point))
+                           'face face)
+        (setq arg (1- arg))))))
+
+(defun emms-mark-unmark-track (&optional arg)
+  (interactive "p")
+  (let ((emms-mark-char ?\040))
+    (emms-mark-track arg)))
+
+(defun emms-mark-forward (arg)
+  (interactive "p")
+  (emms-mark-track arg)
+  (forward-line arg))
+
+(defun emms-mark-unmark-forward (arg)
+  (interactive "p")
+  (emms-mark-unmark-track arg)
+  (forward-line arg))
+
+(defun emms-mark-all ()
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (emms-mark-track (count-lines (point-min) (point-max)))))
+
+(defun emms-mark-unmark-all ()
+  (interactive)
+  (emms-mark-do-with-marked-track 'emms-mark-unmark-track))
+
+(defun emms-mark-regexp (regexp)
+  (interactive "sMark track match: ")
+  (save-excursion
+    (goto-char (point-min))
+    (while (re-search-forward regexp nil t)
+      (emms-mark-track 1)
+      (forward-line 1))))
+
+(defun emms-mark-unmark-regexp (regexp)
+  (interactive "sUnmark track match: ")
+  (let ((emms-mark-char ?\040))
+    (emms-mark-regexp regexp)))
+
+(defun emms-mark-toggle ()
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (let (buffer-read-only)
+      (while (not (eobp))
+        (if (eq ?\040 (following-char))
+            (emms-mark-track)
+          (emms-mark-unmark-track))
+        (forward-line 1)))))
+;;}}}
+
+;;{{{ functions to operate marked tracks
+(defun emms-mark-do-with-marked-track (func)
+  (let ((regexp (format "^[%c]" emms-mark-char)))
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward regexp nil t)
+        (backward-char 1)               ; move to beginning of line
+        (funcall func)))))
+
+(defun emms-mark-mapcar-marked-track (func)
+  (let (result)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward "^[*]" nil t)
+        (backward-char 1)               ; move to beginning of line
+        (setq result (cons (funcall func) result)))
+      (nreverse result))))
+
+(defun emms-mark-delete-marked-tracks ()
+  (interactive)
+  (emms-with-inhibit-read-only-t
+   (emms-mark-do-with-marked-track
+    (lambda nil (delete-region (point)
+                               (progn (forward-line 1) (point)))))))
+
+(defun emms-mark-kill-marked-tracks ()
+  (interactive)
+  (let (tracks buffer-read-only)
+    (emms-mark-do-with-marked-track
+     (lambda nil
+       (setq tracks
+             (concat tracks
+                     (delete-and-extract-region (point)
+                                                (progn (forward-line 1) 
(point)))))))
+    (kill-new tracks)))
+
+(defun emms-mark-copy-marked-tracks ()
+  (interactive)
+  (let (tracks)
+    (emms-mark-do-with-marked-track
+     (lambda nil
+       (setq tracks
+             (concat tracks
+                     (buffer-substring (point)
+                                       (progn (forward-line 1) (point)))))))
+    (kill-new tracks)))
+;;}}}
+
+(let ((map emms-playlist-mode-map))
+  (define-key map "m" 'emms-mark-forward)
+  (define-key map "u" 'emms-mark-unmark-forward)
+  (define-key map "U" 'emms-mark-unmark-all)
+  (define-key map "t" 'emms-mark-toggle)
+  (define-key map "%m" 'emms-mark-regexp)
+  (define-key map "%u" 'emms-mark-unmark-regexp))
+
+;;; emms-mark.el ends here
}

[Add emms-mp3tag and emms-i18n
Wenbin Ye <address@hidden>**20061205065407] {
addfile ./emms-i18n.el
hunk ./emms-i18n.el 1
+;;; emms-i18n.el --- 
+
+;; Copyright 2006 Ye Wenbin
+;;
+;; Author: address@hidden
+;; Time-stamp: <Ye Wenbin 2006-12-05 08:33:11>
+;; Version: $Id: emms-i18n.el,v 1.2 2006/12/04 13:38:17 ywb Exp $
+;; Keywords: 
+;; X-URL: not distributed yet
+
+;; 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; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; When read from process, first check the CAR part of
+;; `emms-default-coding-system', if non-nil, use this for decode, and
+;; nerver detect coding system, if nil, first call
+;; `emms-coding-dectect-functions' to get coding system, if success,
+;; decode the result, otherwise, use `emms-detect-coding-function',
+;; the emacs detect coding function, if the coding detected is not in
+;; `emms-nerver-used-coding-system', decode it, otherwise use
+;; locale-coding-system.
+;;
+;; When write send data to process, first check the CDR part of
+;; `emms-default-coding-system', if non-nil, use this to encode data,
+;; otherwise do nothing, that means use `default-process-coding-system' or
+;; `process-coding-system-alist' to encode data.
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'emms-i18n)
+
+;;; Code:
+
+(provide 'emms-i18n)
+(eval-when-compile
+  (require 'cl))
+
+(defun emms-iconv (from to str)
+  "Convert STR from FROM coding to TO coding."
+  (if (and from to)
+      (decode-coding-string
+       (encode-coding-string str to)
+       from)
+    str))
+
+(defun emms-iconv-region (beg end from to)
+  (when (and from to)
+    (save-restriction
+      (narrow-to-region beg end)
+      (encode-coding-region (point-min) (point-max) to)
+      (decode-coding-region (point-min) (point-max) from))))
+
+(defun emms-iconv-buffer (from to &optional buf)
+  (save-excursion
+    (and buf (set-buffer buf))
+    (emms-iconv-region-1 (point-min) (point-max) from to)))
+
+(defun emms-set-default-coding-system (read-coding write-coding)
+  "Set `emms-default-coding-system'"
+  (interactive "zSet coding system for read: \nzSet coding system for write: ")
+  (setq emms-default-coding-system
+        (cons
+         (and (coding-system-p read-coding) read-coding)
+         (and (coding-system-p write-coding) write-coding)))
+  (message (concat
+            (if (car emms-default-coding-system)
+                (format "The coding system for read is %S." (car 
emms-default-coding-system))
+              "Good, you want detect coding system by me!")
+            (format " The coding system for write is %S."
+                    (or (cdr emms-default-coding-system)
+                        (cdr default-process-coding-system))))))
+
+(defun emms-call-process-to-string (program &rest args)
+  (with-temp-buffer
+    (let ((default-process-coding-system (copy-tree 
default-process-coding-system))
+          (process-coding-system-alist nil) exit)
+      (setcar default-process-coding-system (car emms-default-coding-system))
+      (setq exit (apply 'call-process  (append (list program nil t nil) args)))
+      (when (and (zerop exit) (null (car emms-default-coding-system)))
+        (setq coding (emms-detect-buffer-coding-system))
+        (decode-coding-region (point-min) (point-max) coding))
+      (and (zerop exit) (buffer-string)))))
+
+(defun emms-call-process (program &rest args)
+  (with-temp-buffer
+    (if (cdr emms-default-coding-system)
+        (let ((default-process-coding-system emms-default-coding-system)
+              (process-coding-system-alist nil))
+          (apply 'call-process (append (list program nil t nil) args)))
+      (apply 'call-process (append (list program nil t nil) args)))))
+  
+(defvar emms-nerver-used-coding-system
+  '(raw-text undecided)
+  "If the `emms-coding-dectect-functions' return coding system in
+this list, use `emms-default-coding-system' instead.")
+
+(defvar emms-coding-system-for-read 'utf-8
+  "If coding detect failed, use this for decode")
+
+(defvar emms-default-coding-system nil
+  "If non-nil, used for decode and encode")
+
+(defvar emms-coding-dectect-functions nil
+  "A list of function to call to detect codings")
+
+(defvar emms-detect-max-size 10000
+  "Max bytes to detect coding system. Nil mean scan whole buffer.")
+
+(defun emms-detect-coding-function (size)
+  (detect-coding-region (point)
+                        (+ (if (null emms-detect-max-size)
+                               size
+                             (min size emms-detect-max-size))
+                           (point)) t))
+
+(defun emms-detect-buffer-coding-system (&optional buf)
+  "Before call this function, make sure the buffer is literal"
+  (let ((size (buffer-size))
+        (func (append emms-coding-dectect-functions 
'emms-detect-coding-function))
+        coding)
+    (save-excursion
+      (and buf (set-buffer buf))
+      (goto-char (point-min))
+      (when (> size 0)
+        (setq coding (run-hook-with-args-until-success 'func size))
+        (if (member (coding-system-base coding) emms-nerver-used-coding-system)
+            (setq coding (emms-detect-coding-function size))))
+      (if (or (null coding) (member (coding-system-base coding) 
emms-nerver-used-coding-system))
+          emms-coding-system-for-read
+        coding))))
+
+;;; emms-i18n.el ends here
hunk ./emms-mark.el 1
-;;; emms-mark.el.gz ---
+;;; emms-mark.el ---
hunk ./emms-mark.el 6
-;; Time-stamp: <Ye Wenbin 2006-11-21 17:02:28>
-;; Version: $Id: emms-mark.el,v 0.0 <2006-11-21 14:06:38> ywb Exp $
+;; Time-stamp: <Ye Wenbin 2006-12-04 22:54:28>
+;; Version: $Id: emms-mark.el,v 1.3 2006/12/04 14:54:33 ywb Exp $
hunk ./emms-mark.el 39
+(defvar emms-mark-track-desc-functions
+  '(emms-track-simple-description
+    emms-info-track-description)
+  "A list of track description function. If you want emms support
+mark, you should add your favorite track description function to this
+list and use `emms-mark-select-desc-function' to set the new track
+description function.")
+
+(defvar emms-mark-selected-desc-function
+  emms-track-description-function)
+
hunk ./emms-mark.el 53
-  (concat "  "                          ; for mark char
-          (let ((artist (emms-track-get track 'info-artist))
-                (title (emms-track-get track 'info-title)))
-            (if (and artist title)
-                (format "%s - %s" artist title)
-              (emms-track-simple-description track)))))
+  (assert (not (eq emms-mark-selected-desc-function
+                   'emms-mark-track-description))
+          nil "Should never set emms-mark-selected-desc-function to 
emms-mark-track-description.")
+  (concat "  " (funcall emms-mark-selected-desc-function track)))
hunk ./emms-mark.el 59
+
+(defun emms-mark-select-desc-function (func)
+  (interactive
+   (list (intern
+          (completing-read "Set description function to: "
+                           (mapcar 'list
+                                   emms-mark-track-desc-functions) nil
+                           t "emms-"))))
+  (setq emms-mark-selected-desc-function func
+        emms-track-description-function 'emms-mark-track-description)
+  (emms-with-inhibit-read-only-t
+   (save-excursion
+     (dolist (buf (remove-if-not 'buffer-live-p
+                                 (emms-playlist-buffer-list)))
+       (set-buffer buf)
+       (let ((tracks (nreverse
+                      (emms-playlist-tracks-in-region (point-min)
+                                                      (point-max)))))
+         (erase-buffer)
+         (emms-with-inhibit-read-only-t
+          (mapc 'emms-playlist-insert-track
+                tracks)))))))
hunk ./emms-mark.el 155
+
+(defsubst emms-mark-has-markedp ()
+  (save-excursion
+    (goto-char (point-min))
+    (re-search-forward (format "^[%c]" emms-mark-char) nil t)))
+
hunk ./emms-mark.el 164
-(defun emms-mark-do-with-marked-track (func)
-  (let ((regexp (format "^[%c]" emms-mark-char)))
+(defun emms-mark-do-with-marked-track (func &optional move)
+  "If your function don't move forward, set move to non-nil."
+  (let ((regexp (format "^[%c]" emms-mark-char))
+        (newfunc func))
+    (if move
+        (setq newfunc (lambda () (funcall func) (forward-line 1))))
hunk ./emms-mark.el 174
-        (funcall func)))))
+        (funcall newfunc)))))
hunk ./emms-mark.el 176
-(defun emms-mark-mapcar-marked-track (func)
-  (let (result)
+(defun emms-mark-mapcar-marked-track (func &optional move)
+  (let ((regexp (format "^[%c]" emms-mark-char))
+        result (newfunc func))
+    (if move
+        (setq newfunc (lambda () (let ((res (funcall func)))
+                                   (forward-line 1) res))))
hunk ./emms-mark.el 184
-      (while (re-search-forward "^[*]" nil t)
+      (while (re-search-forward regexp nil t)
hunk ./emms-mark.el 186
-        (setq result (cons (funcall func) result)))
+        (setq result (cons (funcall newfunc) result)))
addfile ./emms-mp3tag.el
hunk ./emms-mp3tag.el 1
+;;; emms-mp3tag.el ---
+
+;; Copyright 2006 Ye Wenbin
+;;
+;; Author: address@hidden
+;; Time-stamp: <Ye Wenbin 2006-12-05 14:52:46>
+;; Version: $Id: emms-mp3tag.el,v 1.5 2006/12/05 00:57:14 ywb Exp ywb $
+;; Keywords:
+;; X-URL: not distributed yet
+
+;; 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; either version 2, or (at your option)
+;; any later version.
+;;
+;; 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, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;;
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;;   (require 'emms-mp3tag)
+
+;;; Code:
+
+(provide 'emms-mp3tag)
+(eval-when-compile
+  (require 'cl))
+(require 'emms)
+(require 'emms-info-mp3info)
+(require 'emms-playlist-mode)
+(require 'emms-i18n)
+(require 'emms-mark)
+(require 'format-spec)
+
+(defvar emms-mp3tag-tags
+  '((info-artist      . "a")
+    (info-title       . "t")
+    (info-album       . "l")
+    (info-tracknumber . "n")
+    (info-year        . "y")
+    (info-genre       . "g")
+    (info-note        . "c")))
+
+(defvar emms-mp3tag-edit-buffer "*EMMS-TAGS*"
+  "Buffer name to edit mp3 tags")
+(defvar emms-mp3tag-log-buffer "*EMMS-LOG*"
+  "Buffer name of mp3tag edit log")
+
+(defvar emms-mp3tag-format
+  `(("default"
+     ,(format "%%m\n%s\n\n"
+              (mapconcat
+               (lambda (tag)
+                 (concat (propertize (format "%-16s = " (symbol-name (car 
tag)))
+                                     'read-only t 'rear-nonsticky t)
+                         "%" (cdr tag)))
+               (append '((name . "f")) emms-mp3tag-tags) "\n"))
+     emms-mp3tag-default-parser))
+  "The contents of this variable should look like:
+ ((NAME FORMATER PARSER) ...)
+
+The NAME is use to select proper format, and FORMATER should be a
+string or a function. When it is a string, it can use specification
+as:
+ m     --     Track description
+ f     --     Track name
+ a     --     Track info-artist
+ t     --     Track info-title
+ l     --     Track info-album
+ n     --     Track info-tracknumber
+ y     --     Track info-year
+ g     --     Track info-genre
+ c     --     Track info-note
+
+When it is a function, it recept a parameter, the track, and should
+return a string that to insert to `emms-mp3tag-edit-buffer'.
+
+The PARSER is a function to collect all track info in
+`emms-mp3tag-edit-buffer'. It should return the new tracks. If
+the track tag changed, it should add a new property tag-modified
+and set to non-nil. If the track name change, it should set new
+newname to the new file name.
+")
+
+(defvar emms-mp3tag-selected-format
+  (assoc "default" emms-mp3tag-format))
+
+(defun emms-mp3tag-select-format (format)
+  (interactive
+   (list (completing-read "Set edit format to: "
+                          emms-mp3tag-format nil t)))
+  (setq emms-mp3tag-select-format (assoc "default" emms-mp3tag-format)))
+
+(defun emms-mp3tag-format-track (format track)
+  (if (stringp format)
+      (format-spec
+       format
+       (apply 'format-spec-make
+              ?m (emms-propertize (emms-track-force-description track)
+                                  'face 'emms-playlist-track-face
+                                  'emms-track (copy-sequence track))
+              ?f (emms-track-name track)
+              (apply 'append
+                     (mapcar
+                      (lambda (pair)
+                        (list (aref (cdr pair) 0)
+                              (or (emms-track-get track (car pair)) "")))
+                      emms-mp3tag-tags))))
+    (funcall format track)))
+
+(defun emms-mp3tag-track-at (&optional pos)
+  (let ((track (emms-playlist-track-at pos))
+        newtrack)
+    (setq newtrack (copy-sequence track))
+    (emms-track-set newtrack 'position (point-marker))
+    (emms-track-set newtrack 'orig-track track)
+    newtrack))
+
+(defsubst emms-mp3tag-erase-buffer (&optional buf)
+  (let ((inhibit-read-only t))
+    (save-excursion
+      (set-buffer (get-buffer-create buf))
+      (erase-buffer))))
+
+(defun emms-mp3tag-insert-track (track)
+  (cond ((null track) nil)
+        ((not (eq (emms-track-get track 'type) 'file))
+         (emms-mp3tag-log "Track %s is not a local file!" (emms-track-name 
track)))
+        ((not (file-writable-p (emms-track-name track)))
+         (emms-mp3tag-log "The file %s is not writable" (emms-track-name 
track)))
+        (t (insert (emms-mp3tag-format-track
+                    (cadr emms-mp3tag-selected-format) track)))))
+
+(defun emms-mp3tag-insert-tracks (tracks)
+  (save-excursion
+    (emms-mp3tag-erase-buffer emms-mp3tag-log-buffer)
+    (emms-mp3tag-erase-buffer emms-mp3tag-edit-buffer)
+    (set-buffer (get-buffer emms-mp3tag-edit-buffer))
+    (mapc 'emms-mp3tag-insert-track tracks)
+    (emms-mp3tag-mode 1)
+    (pop-to-buffer (current-buffer))
+    (goto-char (point-min))
+    (emms-mp3tag-display-log-buffer-maybe)))
+
+(defun emms-mp3tag-edit-track (track)
+  (interactive (list (emms-mp3tag-track-at)))
+  (if (null track)
+      (message "No track at point!")
+    (emms-mp3tag-insert-tracks (list track))))
+
+(defun emms-mp3tag-edit-marked-tracks ()
+  (interactive)
+  (let ((tracks (emms-mark-mapcar-marked-track 'emms-mp3tag-track-at t)))
+    (if (null tracks)
+        (message "No track marked!")
+      (emms-mp3tag-insert-tracks tracks))))
+
+(defun emms-mp3tag-edit ()
+  (interactive)
+  (if (emms-mark-has-markedp)
+      (emms-mp3tag-edit-marked-tracks)
+    (emms-mp3tag-edit-track (emms-mp3tag-track-at))))
+
+(defsubst emms-mp3tag-display-log-buffer-maybe ()
+  (if (> (buffer-size (get-buffer emms-mp3tag-log-buffer)) 0)
+      (display-buffer emms-mp3tag-log-buffer)))
+
+(defvar emms-mp3tag-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [tab] 'emms-mp3tag-next-field)
+    (define-key map [backtab] 'emms-mp3tag-prev-field)
+    (define-key map "\C-c\C-n" 'emms-mp3tag-next-track)
+    (define-key map "\C-c\C-p" 'emms-mp3tag-prev-track)
+    (define-key map "\C-c\C-c" 'emms-mp3tag-submit)
+    (define-key map "\C-c\C-r" 'emms-mp3tag-replace-all)
+    map))
+(define-key emms-playlist-mode-map "E" 'emms-mp3tag-edit)
+
+(define-minor-mode emms-mp3tag-mode
+  "A minor mode to edit mp3tag.
+\\{emms-mp3tag-mode-map}"
+  :lighter " MP3Tag"
+  :keymap emms-mp3tag-mode-map)
+
+(defun emms-mp3tag-replace-all (name value)
+  (interactive
+   (list (completing-read "Replace tag: "
+                          emms-mp3tag-tags nil t)
+         (read-from-minibuffer "Set tag to: ")))
+  (save-excursion
+    (goto-char (point-min))
+    (while (re-search-forward (concat "^" (regexp-quote name)) nil t)
+      (skip-chars-forward " \t=")
+      (delete-region (point) (line-end-position))
+      (insert value))))
+
+(defun emms-mp3tag-next-field (arg)
+  (interactive "p")
+  (if (> arg 0)
+      (re-search-forward "\\s-*=[ \t]*" nil nil arg)
+    (emms-mp3tag-prev-field (- arg))))
+
+(defun emms-mp3tag-prev-field (arg)
+  (interactive "p")
+  (if (< arg 0)
+      (emms-mp3tag-next-field (- arg))
+    (skip-chars-backward " \t=")
+    (re-search-backward "\\s-*=[ \t]*" nil nil arg)
+    (skip-chars-forward " \t=")))
+
+(defun emms-mp3tag-prev-track ()
+  (interactive)
+  (let ((prev (previous-single-property-change (point)
+                                               'emms-track)))
+    (when (not prev)
+      (error "No previous track"))
+    (when (not (get-text-property prev 'emms-track))
+      (setq prev (or (previous-single-property-change prev 'emms-track)
+                     (point-min))))
+    (when (or (not prev)
+              (not (get-text-property prev 'emms-track)))
+      (error "No previous track"))
+    (goto-char prev)))
+
+(defun emms-mp3tag-next-track ()
+  (interactive)
+  (let ((next (next-single-property-change (point)
+                                           'emms-track)))
+    (when (not next)
+      (error "No next track"))
+    (when (not (get-text-property next 'emms-track))
+      (setq next (next-single-property-change next 'emms-track)))
+    (when (or (not next)
+              (= next (point-max)))
+      (error "No next track"))
+    (goto-char next)))
+
+(defun emms-mp3tag-submit ()
+  (interactive)
+  (let ((tracks (funcall (nth 2 emms-mp3tag-selected-format)))
+        filename exit old pos args val need-sync)
+    (if (not (and tracks (y-or-n-p "Submit changes? ")))
+        (message "Nothing have to do!")
+      (emms-mp3tag-erase-buffer emms-mp3tag-log-buffer)
+      (message "Wait while set tags...")
+      (save-excursion
+        (dolist (track tracks)
+          (when (emms-track-get track 'tag-modified)
+            (setq filename (emms-track-name track)
+                  old (emms-track-get track 'orig-track))
+            (when (emms-track-get track 'newname)
+              (setq filename (emms-track-get track 'newname))
+              (rename-file (emms-track-name track) filename)
+              (emms-track-set old 'name filename)
+              ;; for re-enter this function
+              (setq need-sync t)
+              (emms-track-set track 'newname nil)
+              (emms-track-set track 'name filename))
+            (setq args nil)
+            (dolist (tag emms-mp3tag-tags)
+              (when (setq val (emms-track-get track (car tag)))
+                (emms-track-set old (car tag) val)
+                (setq args (append args (list (concat "-" (cdr tag)) val)))))
+            (unless (zerop (setq exit
+                                 (apply 'call-process 
emms-info-mp3info-program-name
+                                        nil nil nil
+                                        filename args)))
+              (emms-mp3tag-log "Change tags of %s failed with exit value %d" 
filename exit))
+            (when (and (setq pos (emms-track-get track 'position))
+                       (marker-position pos))
+              (set-buffer (marker-buffer pos))
+              (goto-char pos)
+              (funcall emms-playlist-update-track-function))
+            (emms-track-set track 'tag-modified nil))))
+      (if (and need-sync (y-or-n-p "You have change some track names, sync the 
cache? "))
+          (emms-cache-sync))
+      (emms-mp3tag-display-log-buffer-maybe)
+      (message "Set all mp3 tag done!"))))
+
+(defun emms-mp3tag-default-parser ()
+  (let (next tracks track key val)
+    (goto-char (point-min))
+    (if (get-text-property (point) 'emms-track)
+        (setq next (point))
+      (setq next (next-single-property-change (point)
+                                              'emms-track)))
+    (when next
+      (while
+          (progn
+            (goto-char next)
+            (setq track (get-text-property (point) 'emms-track))
+            (forward-line 1)
+            (mapc (lambda (pair)
+                    (when (string-match "\\s-*=\\s-*" pair)
+                      (setq key (intern-soft (substring pair 0 
(match-beginning 0)))
+                            val (substring pair (match-end 0)))
+                      (when (and key
+                                 (> (length val) 0)
+                                 (not (string= val (emms-track-get track 
key))))
+                        (if (eq key 'name)
+                            (emms-track-set track 'newname val)
+                          (emms-track-set track key val))
+                        (emms-track-set track 'tag-modified t))))
+                  (split-string (buffer-substring (point)
+                                                  (or
+                                                   (setq next 
(next-single-property-change (point) 'emms-track))
+                                                   (point-max)))
+                                "\n"))
+            (if (emms-track-get track 'tag-modified)
+                (push track tracks))
+            next))
+      tracks)))
+
+(defun emms-mp3tag-log (&rest args)
+  (with-current-buffer (get-buffer-create emms-mp3tag-log-buffer)
+    (goto-char (point-max))
+    (insert (apply 'format args) "\n")))
+
+;;; emms-mp3tagedit.el ends here
}

[Edit all track, set tag to file for mp3
Wenbin Ye <address@hidden>**20061205112209] {
hunk ./emms-mp3tag.el 6
-;; Time-stamp: <Ye Wenbin 2006-12-05 14:52:46>
+;; Time-stamp: <Ye Wenbin 2006-12-05 19:07:12>
hunk ./emms-mp3tag.el 40
-(require 'emms-i18n)
hunk ./emms-mp3tag.el 122
-    (setq newtrack (copy-sequence track))
-    (emms-track-set newtrack 'position (point-marker))
-    (emms-track-set newtrack 'orig-track track)
-    newtrack))
+    (when track
+      (setq newtrack (copy-sequence track))
+      (emms-track-set newtrack 'position (point-marker))
+      (emms-track-set newtrack 'orig-track track)
+      newtrack)))
hunk ./emms-mp3tag.el 134
-(defun emms-mp3tag-insert-track (track)
-  (cond ((null track) nil)
-        ((not (eq (emms-track-get track 'type) 'file))
-         (emms-mp3tag-log "Track %s is not a local file!" (emms-track-name 
track)))
-        ((not (file-writable-p (emms-track-name track)))
-         (emms-mp3tag-log "The file %s is not writable" (emms-track-name 
track)))
-        (t (insert (emms-mp3tag-format-track
-                    (cadr emms-mp3tag-selected-format) track)))))
+;; (defun emms-mp3tag-insert-track (track)
+;;   (cond ((null track) nil)
+;;         ((not (eq (emms-track-get track 'type) 'file))
+;;          (emms-mp3tag-log "Track %s is not a local file!" (emms-track-name 
track)))
+;;         ((not (file-writable-p (emms-track-name track)))
+;;          (emms-mp3tag-log "The file %s is not writable" (emms-track-name 
track)))
+;;         (t (insert (emms-mp3tag-format-track
+;;                     (cadr emms-mp3tag-selected-format) track)))))
+
+(defsubst emms-mp3tag-insert-track (track)
+  (and track
+       (insert (emms-mp3tag-format-track
+                (cadr emms-mp3tag-selected-format) track))))
hunk ./emms-mp3tag.el 265
-            (when (emms-track-get track 'newname)
+            ;; rename local file
+            (when (and (emms-track-get track 'newname)
+                       (eq (emms-track-get track 'type) 'file)
+                       (file-writable-p (emms-track-name track)))
hunk ./emms-mp3tag.el 273
-              (setq need-sync t)
hunk ./emms-mp3tag.el 274
-              (emms-track-set track 'name filename))
+              (emms-track-set track 'name filename)
+              (setq need-sync t)
+              ;; register to emms-cache-db
+              (funcall emms-cache-modified-function)
+              (funcall emms-cache-set-function filename 'file old))
+            ;; set tags to original track
hunk ./emms-mp3tag.el 285
-            (unless (zerop (setq exit
+            ;; use mp3info to change tag in mp3 file
+            (if (and (eq (emms-track-get track 'type) 'file)
+                     (file-writable-p (emms-track-name track))
+                     (string-match filename "\\.mp3\\'"))
+                (if (zerop (setq exit
hunk ./emms-mp3tag.el 293
-              (emms-mp3tag-log "Change tags of %s failed with exit value %d" 
filename exit))
+                    ;; for `emms-cache-sync' not call `emms-info-functions' 
again
+                    (emms-track-get track 'info-mtime (butlast (current-time)))
+                  (emms-mp3tag-log "Change tags of %s failed with exit value 
%d" filename exit)))
+            ;; update track in playlist
hunk ./emms-mp3tag.el 302
+            ;; clear modified tag
}

Context:

[emms-info-mp3info.el: Replace `emms-iconv' with decode-coding-string and
address@hidden
 encode-coding-string.
] 
[emms.el: Fix bug introduced by recent changes to 
emms-playlist-set-playlist-buffer
Michael Olson <address@hidden>**20061119204738] 
[Default to current buffer when setting the current EMMS playlist buffer.
Michael Olson <address@hidden>**20061119053410] 
[manual: Add documentation for new emms-playlist-mode keybindings
Michael Olson <address@hidden>**20061119052935] 
[emms-playlist-mode: Bind "b" key to emms-playlist-set-playlist-buffer.
Michael Olson <address@hidden>**20061119052907] 
[emms-playlist-mode: Implement adding the thing at point to the current 
playlist.  If it is a playlist, add its contents instead.  Map this to the "a" 
key.
Michael Olson <address@hidden>**20061119052254] 
[emms.el: In emms-playlist-set-playlist-buffer, prompt user from available EMMS 
playlist buffers rather than all buffers, and display feedback upon setting the 
current buffer, since this is not an easy change to see
Michael Olson <address@hidden>**20061119052023] 
[emms.el: Fix compiler warning
Michael Olson <address@hidden>**20061119051946] 
[Don't add subdirectories for directory and playlist-directory source insert 
methods
Michael Olson <address@hidden>**20061119041900] 
[emms-playing-time.el: New variable `emms-playing-time-style', it
address@hidden
 supports two styles at present, `time' and `bar'.
] 
[bind SPC to `scroll-up' in emms-playlist-mode and update manual.
address@hidden 
[emms-player-mpd: Deal with change in output when getting supported file types
Michael Olson <address@hidden>**20061028042119] 
[emms.el: Move macros to the top of the file.
address@hidden 
[NEWS: Add entry for recent emms-player-mpd change
Michael Olson <address@hidden>**20061023125738] 
[emms-player-mpd: Handle errors that occur when we begin playback
Michael Olson <address@hidden>**20061022215310] 
[NEWS: Version 2 is version 2.0
address@hidden 
[emms-playlist-mode: Handle case where selection has not been set but user 
wants to delete a region
Michael Olson <address@hidden>**20061022201724] 
[emms-playlist-mode: Fix typo in hook name
Michael Olson <address@hidden>**20061022022812] 
[emms-player-mpd: Update version recommendation
Michael Olson <address@hidden>**20061022012223] 
[emms-player-mpd: Work properly with tracks inserted by emms-browser
Michael Olson <address@hidden>**20061022011050] 
[Add NEWS items since version 2.1
Michael Olson <address@hidden>**20061017222117] 
[emms-player-mplayer.el: Mplayer also supports .vob files.
address@hidden 
[emms-player-mpd: When using the emms-volume interface, allow the user to 
specify the amount of change in the volume
Michael Olson <address@hidden>**20061017220404] 
[Documentation cleanups in emms-player-mpd and emms-source-playlist
Michael Olson <address@hidden>**20061017215345] 
[Since emms-player-seeked-to-functions and emms-player-time-set-functions hooks 
do the same thing, replace the former with the latter
Michael Olson <address@hidden>**20061017210238] 
[emms-browser: Fix compiler warning
Michael Olson <address@hidden>**20061017205310] 
[emms-player-mpd: Implement seek-to support
Michael Olson <address@hidden>**20061017205106] 
[FluidSynth midi file player
address@hidden 
[Added delYsid
address@hidden 
[jackd-support-for-emacs
address@hidden
 jackd is a pro-audio server which can be used as a backend for
 alsaplayer, mplayer, and lots of other linux audio apps.
 This module allows to start jackd from within emacs, and
 connect/disconnect jack client ports.
] 
[browser: ensure the RNG is seeded before use
Damien Elmes <address@hidden>**20061011151535] 
[browser: require sort (fixes bug with sort-fold-case being void)
Damien Elmes <address@hidden>**20061010125718] 
[fix faulty emms-playlist-mode keybinding, fix due to William and Damien.
address@hidden 
[Added seeking to the playlist keymap, and updated the manual.
address@hidden 
[emms-player-mpd: Only display error if we are certain that url.el is not 
up-to-date
Michael Olson <address@hidden>**20061004032213] 
[seek-for-alsaplayer
address@hidden
 Add relative seek support for alsaplayer
] 
[midi-files-via-timidity
address@hidden
 A simple-player definition for timidity
] 
[emms-playing-time.el: Minor cleanups.
address@hidden 
[emms-lyrics.el: Minor Cleanups.
address@hidden 
[pause-for-alsaplayer
address@hidden
 Get pause/resume working for alsaplayer
] 
[mms-for-mplayer
address@hidden
 mplayer also supports mms:// URLs
] 
[DoTheRightThing with player pausing and emms-bookmarks.el
address@hidden 
[Added emms-bookmarks.el
address@hidden 
[Added `emms-pause' to emms-playlist-mode.el bound to to ``P''.
address@hidden 
[browser: add deletion started/finished message
Damien Elmes <address@hidden>**20060923051128] 
[Added a link to the online version of the manual.
address@hidden 
[emms-playing-time.el now works with `seek-to'.
address@hidden 
[Added `seek-to' to emms.el and emms-player-mplayer.el.
address@hidden 
[browser/cache: support deleting files, make emms-cache-dirty a defsubst
Damien Elmes <address@hidden>**20060922090553] 
[TAG 2.1
address@hidden 
Patch bundle hash:
2cef296e0c49d5899300a94cf01185a226ba70fe

reply via email to

[Prev in Thread] Current Thread [Next in Thread]