New patches: [refinements-and-docs-for-emms-history.dpatch Tassilo Horn **20070815080114 This path makes some refinements in emms-history.el: - Start playback after `emms-history-load' only if `emms-history-start-playing' is non-nil. - Added customization group emms-history - defvar -> defcustom - better docstrings and commentary - Added Info docs. (Node "Persistent Playlists") ] { hunk ./emms-history.el 1 -;;; emms-history.el -- save playlist when exit emacs +;;; emms-history.el -- save all playlists when exiting emacs hunk ./emms-history.el 25 -;; Save playlists when exit emacs. -;; Next time use M-x emms-history-load to load saved playlist +;; Saves all playlists when you close emacs. When you start it up again use +;; M-x emms-history-load to restore all saved playlists. hunk ./emms-history.el 28 -;; Put this file into your load-path and the following into your ~/.emacs: +;; To use it put the following into your ~/.emacs: +;; hunk ./emms-history.el 31 +;; +;; If all playlists should be restored on startup add this, too: +;; +;; (emms-history-load) hunk ./emms-history.el 38 -(provide 'emms-history) hunk ./emms-history.el 42 -(defvar emms-history-file "~/.emacs.d/.emms-history" - "File to save playlists") +(defgroup emms-history nil + "Saving and restoring all playlists when closing/restarting +Emacs." + :prefix "emms-history-" + :group 'emms) + +(defcustom emms-history-file "~/.emacs.d/emms-history" + "The file to save playlists in." + :type 'string + :group 'emms-history) + +(defcustom emms-history-start-playing nil + "If non-nil emms starts playing the current track after +`emms-history-load' was invoked." + :type 'boolean + :group 'emms-history) hunk ./emms-history.el 60 - "Save all playlists that open in this emacs session when exit. Use -`emms-history-load' to load saved playlists." + "Save all playlists that are open in this Emacs session." hunk ./emms-history.el 100 + "Restore all playlists in `emms-history-file'." hunk ./emms-history.el 121 - (emms-start)))))) + (when emms-history-start-playing + (emms-start))))))) hunk ./emms-history.el 124 +(provide 'emms-history) hunk ./emms.texinfo 71 -* The Browser:: Advanced metadata browsing. -* Sorting Playlists:: Sorting the order of the tracks. -* Editing Tracks:: Editing track information from within Emms. -* Emms Mode Line:: Emms information on the mode line. -* Music Player Daemon:: Interface to Music Player Daemon. -* Streaming Audio:: Interface to streaming audio. -* Lyrics:: Displaying lyrics synchronously. -* Volume:: Changing the volume. -* Last.fm:: Interact with http://www.last.fm's services. -* Extending Emms:: How to define new players and modules. +* The Browser:: Advanced metadata browsing. +* Sorting Playlists:: Sorting the order of the tracks. +* Persistent Playlists:: Restoring playlists on emacs startup. +* Editing Tracks:: Editing track information from within Emms. +* Emms Mode Line:: Emms information on the mode line. +* Music Player Daemon:: Interface to Music Player Daemon. +* Streaming Audio:: Interface to streaming audio. +* Lyrics:: Displaying lyrics synchronously. +* Volume:: Changing the volume. +* Last.fm:: Interact with http://www.last.fm's services. +* Extending Emms:: How to define new players and modules. hunk ./emms.texinfo 1703 address@hidden Persistent Playlists address@hidden Persistent Playlists + +The Emms module @file{emms-history.el} makes playlists persistent over +emacs sessions. To make use of this feature put this into your +~/.emacs. + address@hidden +(require 'emms-history) address@hidden lisp + +When you kill emacs all playlists will be saved in the file given by the +variable: + address@hidden emms-history-file +The file to save playlists in. It defaults to +"~/.emacs.d/emms-history". address@hidden defopt + +After you started up emacs again, you can restore all saved playlists +with this function. + address@hidden emms-history-load +Restore all playlists in `emms-history-file'. address@hidden defun + +If that should be done automatically on each startup, put these lines +into your ~/.emacs. + address@hidden +(require 'emms-history) +(emms-history-load) address@hidden lisp + +Normally @code{emms-history} only restores playlists. If you want it to +start playback afterwards, you can tweak this variable. + address@hidden emms-history-start-playing +If non-nil emms starts playing the current track after +`emms-history-load' was invoked. The default value is nil. address@hidden defopt + } [support-for-renaming-files-with-tag-editor.dpatch Tassilo Horn **20070815183247 With `R' in a playlist (calls `emms-tag-editor-rename') the file(s) corresponding to the (marked) track(s) or the track at point will be renamed according to the format specified in `emms-tag-editor-rename-format'. Work ok for me, but there's a little problem maybe someone can fix: - If users use the cache it has to be updated somehow. `emms-cache-sync' seems to remove the renamed files. So you have to re-insert all renamed tracks to get them into the cache again. ] { hunk ./emms-tag-editor.el 30 -(provide 'emms-tag-editor) hunk ./emms-tag-editor.el 641 -;;; emms-tag-editor.el ends here +;; +;; Renaming files according their tags +;; + +(defvar emms-tag-editor-rename-format "%a - %l - %n - %t" + "When `emms-tag-editor-rename' is invoked the track's file will +be renamed according this format specification. The file +extension will be added automatically. + +It uses the format specs defined in `emms-tag-editor-tags'.") + +(defun emms-tag-editor-rename () + "Rename the file corresponding to track at point or all marked +tracks according to the value of +`emms-tag-editor-rename-format'." + (interactive) + (if (emms-mark-has-markedp) + (emms-tag-editor-rename-marked-tracks) + (emms-tag-editor-rename-track (emms-tag-editor-track-at)))) + +(defun emms-tag-editor-rename-track (track) + "Rename TRACK's file according `emms-tag-editor-rename-format's +value." + (let* ((file (or (emms-track-get track 'info-file) + (emms-track-get track 'name))) + (path (file-name-directory file)) + (suffix (file-name-extension file)) + (new-file (concat + path + (format-spec + emms-tag-editor-rename-format + (apply 'format-spec-make + (apply 'append + (mapcar (lambda (tag) + (list (string-to-char (cdr tag)) + (or (emms-track-get track (car tag)) ""))) + emms-tag-editor-tags)))) + "." suffix))) + (rename-file file new-file) + (message "Renamed \"%s\" to \"%s\"." file new-file))) + +(defun emms-tag-editor-rename-marked-tracks () + "Rename the files corresponding to all marked tracks according +`emms-tag-editor-rename-format's value." + (let ((tracks (emms-mark-mapcar-marked-track + 'emms-tag-editor-track-at t))) + (if (null tracks) + (message "No track marked!") + (progn + (dolist (track tracks) + (emms-tag-editor-rename-track track)))))) + +(define-key emms-playlist-mode-map "R" 'emms-tag-editor-rename) + +(provide 'emms-tag-editor) +;;; Emms-tag-editor.el ends here } [fix-cache-problem-when-renaming-tracks.dpatch Tassilo Horn **20070816070106 I fixed the problem with the cache I mentioned in my last patch. ] { hunk ./emms-tag-editor.el 664 - (let* ((file (or (emms-track-get track 'info-file) - (emms-track-get track 'name))) - (path (file-name-directory file)) - (suffix (file-name-extension file)) - (new-file (concat - path - (format-spec - emms-tag-editor-rename-format - (apply 'format-spec-make - (apply 'append - (mapcar (lambda (tag) - (list (string-to-char (cdr tag)) - (or (emms-track-get track (car tag)) ""))) - emms-tag-editor-tags)))) - "." suffix))) - (rename-file file new-file) - (message "Renamed \"%s\" to \"%s\"." file new-file))) + (if (eq (emms-track-get track 'type) 'file) + (let* ((old-file (or (emms-track-get track 'info-file) + (emms-track-get track 'name))) + (path (file-name-directory old-file)) + (suffix (file-name-extension old-file)) + (new-file (concat + path + (format-spec + emms-tag-editor-rename-format + (apply 'format-spec-make + (apply 'append + (mapcar + (lambda (tag) + (list (string-to-char (cdr tag)) + (or (emms-track-get track (car tag)) + ""))) + emms-tag-editor-tags)))) + "." suffix))) + ;; Rename the file... + (rename-file old-file new-file) + ;; ... and update the track and the cache (if used) if the renaming + ;; worked. + (dolist (info '(name info-file)) + (emms-track-set track info new-file)) + (when (featurep 'emms-cache) + (emms-cache-del old-file) ;; delete the old one and... + (emms-cache-set 'file new-file track)) ;; ... insert the new one + (message "Renamed \"%s\" to \"%s\"." old-file new-file)) + (message "Only files can be renamed."))) } [use-existing-functionality-for-renaming-files.dpatch Tassilo Horn **20070817100310 When I implemented the renaming stuff, I was not aware that Ye already thought of this feature. When editing a track, one can edit the filename and the file will be renamed and the cache updated. Now renaming by hitting `R' (`emms-tag-editor-rename') in the playlist makes use of this functionality instead of doing it on its own. ] { hunk ./emms-tag-editor.el 525 - (let ((tracks (funcall emms-tag-editor-parse-function)) - filename func exit old pos val need-sync) + (let ((tracks (funcall emms-tag-editor-parse-function))) hunk ./emms-tag-editor.el 529 - (message "Setting 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)) - ;; rename local file - (when (and (emms-track-get track 'newname) - (eq (emms-track-get track 'type) 'file) - (file-writable-p (emms-track-name track)) - (y-or-n-p (format "Rename %s to %s" - (emms-track-name track) - (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 - (emms-track-set track 'name filename) - (setq need-sync t) - ;; register to emms-cache-db - (when (boundp 'emms-cache-modified-function) - (funcall emms-cache-modified-function) - (funcall emms-cache-set-function 'file filename old))) - (emms-track-set track 'newname nil) - ;; set tags to original track - (dolist (tag emms-tag-editor-tags) - (when (setq val (emms-track-get track (car tag))) - (emms-track-set old (car tag) val))) - ;; use mp3info to change tag in mp3 file - (when (and (eq (emms-track-get track 'type) 'file) - (file-writable-p (emms-track-name track)) - (setq func (assoc (file-name-extension filename) emms-tag-editor-tagfile-functions))) - (setq exit - (if (functionp (cdr func)) - (funcall (cdr func) track) - (emms-tag-editor-tag-file track (cadr func) (nth 2 func)))) - (if (zerop exit) - (emms-track-get track 'info-mtime (butlast (current-time))) - (emms-tag-editor-log - "Changing tags of %s failed with exit value %d" - filename exit))) - ;; update track in playlist - (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)) - ;; clear modified tag - (emms-track-set track 'tag-modified nil)))) - (if (and (featurep 'emms-cache) - need-sync - (y-or-n-p "You have changed some track names; sync the cache? ")) - (and (fboundp 'emms-cache-sync) ; silence byte-compiler - (emms-cache-sync))) - (unless (emms-tag-editor-display-log-buffer-maybe) - (message "Setting tags...done")))) + (emms-tag-editor-apply tracks))) hunk ./emms-tag-editor.el 532 +(defun emms-tag-editor-apply (tracks) + "Apply all changes made to TRACKS." + (message "Setting tags...") + (let (filename func exit old pos val need-sync) + (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)) + ;; rename local file + (when (and (emms-track-get track 'newname) + (eq (emms-track-get track 'type) 'file) + (file-writable-p (emms-track-name track)) + (y-or-n-p (format "Rename %s to %s? " + (emms-track-name track) + (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 + (emms-track-set track 'name filename) + (setq need-sync t) + ;; register to emms-cache-db + (when (boundp 'emms-cache-modified-function) + (funcall emms-cache-modified-function) + (funcall emms-cache-set-function 'file filename old))) + (emms-track-set track 'newname nil) + ;; set tags to original track + (dolist (tag emms-tag-editor-tags) + (when (setq val (emms-track-get track (car tag))) + (emms-track-set old (car tag) val))) + ;; use mp3info to change tag in mp3 file + (when (and (eq (emms-track-get track 'type) 'file) + (file-writable-p (emms-track-name track)) + (setq func (assoc (file-name-extension filename) + emms-tag-editor-tagfile-functions))) + (setq exit + (if (functionp (cdr func)) + (funcall (cdr func) track) + (emms-tag-editor-tag-file track (cadr func) (nth 2 func)))) + (if (zerop exit) + (emms-track-get track 'info-mtime (butlast (current-time))) + (emms-tag-editor-log + "Changing tags of %s failed with exit value %d" + filename exit))) + ;; update track in playlist + (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)) + ;; clear modified tag + (emms-track-set track 'tag-modified nil)))) + (if (and (featurep 'emms-cache) + need-sync + (y-or-n-p "You have changed some track names; sync the cache? ")) + (and (fboundp 'emms-cache-sync) ; silence byte-compiler + (emms-cache-sync))) + (unless (emms-tag-editor-display-log-buffer-maybe) + (message "Setting tags...done")))) + hunk ./emms-tag-editor.el 666 -(defun emms-tag-editor-rename-track (track) +(defun emms-tag-editor-rename-track (track &optional dont-apply) hunk ./emms-tag-editor.el 668 -value." +value. + +If DONT-APPLY is non-nil the changes won't be applied directly. +Then it's the callers job to apply them afterwards with +`emms-tag-editor-apply'." hunk ./emms-tag-editor.el 674 - (let* ((old-file (or (emms-track-get track 'info-file) - (emms-track-get track 'name))) + (let* ((old-file (emms-track-name track)) hunk ./emms-tag-editor.el 690 - ;; Rename the file... - (rename-file old-file new-file) - ;; ... and update the track and the cache (if used) if the renaming - ;; worked. - (dolist (info '(name info-file)) - (emms-track-set track info new-file)) - (when (featurep 'emms-cache) - (emms-cache-del old-file) ;; delete the old one and... - (emms-cache-set 'file new-file track)) ;; ... insert the new one - (message "Renamed \"%s\" to \"%s\"." old-file new-file)) + (emms-track-set track 'newname new-file) + (emms-track-set track 'tag-modified t) + (unless dont-apply + (emms-tag-editor-apply (list track)))) hunk ./emms-tag-editor.el 703 - (progn - (dolist (track tracks) - (emms-tag-editor-rename-track track)))))) + (dolist (track tracks) + (emms-tag-editor-rename-track track t)) + (emms-tag-editor-apply tracks)))) } Context: [emms-score.el: change score-file to something more sane address@hidden ~/.emms can be an EMMS config file, whereas ~/.emacs.d/ is already used to store the stream bookmarks file, so use it for the score file too. ] [make-S-prefix-key-for-sorting-functions.dpatch Tassilo Horn **20070802200758] [Fix compiler warning in emms-setup Michael Olson **20070723023532] [emms-playlist-limit: Use standard enable/disable/toggle interface Michael Olson **20070723023452] [emms-streams: New option emms-stream-repeat-p Michael Olson **20070723020304 Instead of assuming that everyone will want to automatically repeat a streamlist if it runs out of tracks, make this controlled by the `emms-stream-repeat-p' option, which defaults to nil. ] [emms-player-mpd: Fix bug with selecting an individual URL track to play from a streamlist Michael Olson **20070723015956] [emms-player-mpd: Make callback arg for emms-player-mpd-sync-from-emms optional Michael Olson **20070723015722] [emms-playlist-sort.el: Bind "s s" to emms-playlist-sort-by-score. William Xu **20070719065003] [emms-setup.el: Enable emms-score in emms-devel. William Xu **20070717131538] [emms-lyrics.el: Set default value for emms-lyrics-dir to ~/music/lyrics. William Xu **20070717100946] [emms-playlist-sort.el: Remove emms-playlist-sort-prefix to make the William Xu **20070717095454 codes more clean. And steal "s" prefix key from `emms-playlist-mode'. (An alternative for emms-playlist-mode could be "v", same as XMMS) ] [emms-playlist-limit.el: (define-emms-playlist-limit) Fix prompt string bug. William Xu **20070717082536] [make-number-of-secs-to-seek-configurable.dpatch Tassilo Horn **20070712062052 Patch sent by "Alfred M. Szmidt" in on the emms-users list (with slight modifications). ] [Avoid even the most remote possibility of a conflict with color-theme.el and its very bad replace-in-string function Michael Olson **20070712211444] [emms-playlist-limit.el: Add missing line: (define-emms-playlist-limit info-title). William Xu **20070711071022] [emms-playlist-limit.el: Minor updates. William Xu **20070709103714] [emms-playlist-limit.el: Update Copyright to GPLv3. William Xu **20070708140012] [emms-playlist-sort.el: Minor updates. William Xu **20070708120050] [emms-playlist-limit.el: Redefine functions emms-playlist-limit-to-* with William Xu **20070708115907 macro: define-emms-playlist-limit. ] [emms-playlist-limit.el: Add default value based on track at point for William Xu **20070708040809 emms-playlist-limit-to-*. ] [New file: emms-playlist-limit.el. And minor updates to emms-playlist-sort. William Xu **20070705160221] [emms-player-mplayer.el: Add "eng.srt", "chs.srt", "cht.srt" to William Xu **20070630124728 emms-player-mplayer-subtitle-extensions. ] [Updated NEWS for post-3.0 address@hidden [TAG 3.0 address@hidden Patch bundle hash: 3fcff1b5989b300ff466240ac0b778a3d5f7bcb5