Download
(require 'emms-mark)
(require 'emms-last-played)
(require 'emms-playlist-mode)
(require 'emms-source-file)
(require 'emms-playlist-sort)
(require 'emms)
(require 'basic-edit-toolkit)
(defadvice emms-play-directory-tree (after emms-random-play-1 activate)
"This advice to make `emms-random' execute after emms-play-directory-tree"
(emms-random))
(defadvice emms-play-directory-tree (after emms-playlist-sort-by-natural-order-1 activate)
"This advice to make `emms-playlist-sort-by-natural-order' execute after emms-play-directory-tree"
(emms-playlist-sort-by-natural-order))
(defadvice emms-history-load (after play-default activate)
"If after `emms-history-load', get empty playlist,
play default music directory."
(when (not emms-player-playing-p)
(emms-play-now)
(message "Emms history load failed, load default music directory...")))
(defun emms-play-matching (pattern)
"Play matching song."
(interactive "sPlay song matching: ")
(unless current-prefix-arg
(with-current-emms-playlist
(emms-playlist-clear)))
(emms-play-find emms-source-file-default-directory pattern))
(defun emms-jump-to-file ()
"Jump to postion of current playing music."
(interactive)
(let* ((music-file (emms-track-name (emms-playlist-current-selected-track)))
(music-folder (file-name-directory music-file)))
(dired-x-find-file music-folder)
(dired-goto-file music-file)))
(defun kid-emms-info-simple (track)
"Parse current singer and song name bases file name."
(when (eq 'file (emms-track-type track))
(let ((regexp "/\\([^/]+\\)/\\([^/]+\\)\\.[^.]+$") (name (emms-track-name track)))
(if (string-match regexp name)
(progn (emms-track-set track 'info-artist (match-string 1 name))
(emms-track-set track 'info-title (match-string 2 name)))
(emms-track-set track 'info-title (file-name-nondirectory name))))))
(defun emms-delete-file-from-disk ()
"Delete this file from disk."
(interactive)
(let* ((current-track (emms-track-name (emms-playlist-track-at))))
(when (yes-or-no-p (format "Are you really want to delete \' %s \' from disk? " current-track))
(if (string-equal current-track (emms-playlist-play-filename))
(emms-stop))
(emms-playlist-mode-kill-entire-track)
(dired-delete-file current-track)
(message (format "Have delete \' %s \' from disk." current-track)))))
(defun emms-playlist-play-filename ()
"Return the filename the current play."
(cdr (assoc 'name (emms-playlist-current-selected-track))))
(defun emms-play-now()
"Play default music directory."
(interactive)
(emms-play-directory-tree emms-source-file-default-directory))
(defun emms-play-online()
"Play online music use emms."
(interactive)
(if (and (require 'w3m nil t)
(w3m-anchor))
(emms-play-url (w3m-anchor))
(message "No valid url in here.")))
(defun lazycat/emms-info-track-description (track)
"Return a description of the current track."
(let* ((name (emms-track-name track))
(type (emms-track-type track))
(short-name (file-name-nondirectory name))
(play-count (or (emms-track-get track 'play-count) 0))
(last-played (or (emms-track-get track 'last-played) '(0 0 0)))
(empty "..."))
(prog1
(case (emms-track-type track)
((file url)
(let* ((artist (or (emms-track-get track 'info-artist) empty))
(year (emms-track-get track 'info-year))
(playing-time (or (emms-track-get track 'info-playing-time) 0))
(min (/ playing-time 60))
(sec (% playing-time 60))
(album (or (emms-track-get track 'info-album) empty))
(tracknumber (emms-track-get track 'info-tracknumber))
(short-name (file-name-sans-extension
(file-name-nondirectory name)))
(title (or (emms-track-get track 'info-title) short-name))
)
(format "%10s %3d │ %-23s %-40s │ %-45s %-4s %-6s %7s"
(emms-last-played-format-date last-played)
play-count
(prettyfy-string artist 18)
(prettyfy-string title 30)
(prettyfy-string
(cond ((string= album empty) "")
(t album)) 40)
(prettyfy-string
(if (and tracknumber
(not (zerop (string-to-number tracknumber))))
(format "%3d" (string-to-number tracknumber))
"") 10)
(or year "....")
(if (or (> min 0) (> sec 0))
(format "%02d:%02d" min sec)
"....."))))
((url)
(concat (symbol-name type) ":" name))
(t
(format "%-3d%s"
play-count
(concat (symbol-name type) ":" name))))
)))
(defun de-kill-covers-and-parents (dir tracks)
"Delete current directory, if not have music file in directory when delete current track."
(when (> (length tracks) 1)
(dolist (cover '("cover.jpg"
"cover_med.jpg"
"cover_small.jpg"
"folder.jpg"))
(condition-case nil
(delete-file (concat dir cover))
(error nil)))
(let (failed)
(while (and (not (string= dir "/"))
(not failed))
(condition-case nil
(delete-directory dir)
(error (setq failed t)))
(setq dir (file-name-directory (directory-file-name dir)))))))
(defun emms-mark-track-and-move-next ()
"Mark the current track, and move next track."
(interactive)
(call-interactively 'emms-mark-track)
(call-interactively 'next-line))
(defun emms-mark-unmark-track-and-move-next ()
"Unmark the current track, and move next track."
(interactive)
(call-interactively 'emms-mark-unmark-track)
(call-interactively 'next-line))
(defun emms-tag-editor-next-same-field (&optional reverse)
"Jump to next same field."
(interactive)
(let (filed-name)
(save-excursion
(beginning-of-line)
(if (search-forward-regexp "^[^ ]*[ \t]+= " (line-end-position) t)
(setq filed-name (buffer-substring (match-beginning 0) (match-end 0)))))
(when filed-name
(if (null reverse)
(search-forward-regexp filed-name (point-max) t)
(beginning-of-line)
(search-backward-regexp filed-name (point-min) t))
(goto-char (match-end 0)))))
(defun emms-tag-editor-prev-same-field ()
"Jump to previous same field."
(interactive)
(emms-tag-editor-next-same-field t))
(defun emms-tag-editor-set-all+ ()
"Set TAG to VALUE in all tracks.
If transient-mark-mode is turned on, you can apply the command to
a selected region.
If `transient-mark-mode' is on and the mark is active, the
changes will only take effect on the tracks in the region.
This function is extension `emms-tag-editor-set-all',
make user can modified TAG content, not just type."
(interactive)
(let (tag current-value value)
(setq tag (completing-read "Set tag: " emms-tag-editor-tags nil t))
(save-excursion
(goto-char (point-min))
(search-forward-regexp (concat "^" tag "[ \t]+= ") (point-max) t 1)
(setq current-value (buffer-substring (match-end 0) (line-end-position))))
(setq value (read-from-minibuffer "To: " current-value))
(save-excursion
(save-restriction
(if (and mark-active transient-mark-mode)
(narrow-to-region (region-beginning) (region-end)))
(goto-char (point-min))
(while (re-search-forward (concat "^" (regexp-quote tag)) nil t)
(skip-chars-forward " \t=")
(delete-region (point) (line-end-position))
(insert value))))))
(defun emms-tag-editor-set-tracknumber ()
"Set `info-tracknumber' tag with a init increment value
and special alternation number."
(interactive)
(let (init-number alternation-number times)
(setq init-number (read-number "Init number: " 1))
(setq alternation-number (read-number "Alternation number: " 1))
(setq times 0)
(save-excursion
(save-restriction
(if (and mark-active transient-mark-mode)
(narrow-to-region (region-beginning) (region-end)))
(goto-char (point-min))
(while (re-search-forward (concat "^info-tracknumber") nil t)
(skip-chars-forward " \t=")
(delete-region (point) (line-end-position))
(insert (format "%s" (+ init-number (* alternation-number times))))
(setq times (1+ times))
)))))
(defun emms-tag-editor-set-tracknumber+ ()
"Set `info-tracknumber' tag with a init increment value
and special alternation number."
(interactive)
(let (init-number alternation-number times)
(setq init-number 1)
(setq alternation-number 1)
(setq times 0)
(save-excursion
(save-restriction
(if (and mark-active transient-mark-mode)
(narrow-to-region (region-beginning) (region-end)))
(goto-char (point-min))
(while (re-search-forward (concat "^info-tracknumber") nil t)
(skip-chars-forward " \t=")
(delete-region (point) (line-end-position))
(insert (format "%s" (+ init-number (* alternation-number times))))
(setq times (1+ times))
)))))
(defun emms-mark-duplicate-track ()
"Mark duplicate track."
(interactive)
(let (have-duplicate-track
current-track-title
next-track-title
original-tracks
selected-point
original-point)
(setq original-point (point))
(emms-playlist-mode-center-current)
(setq selected-point (point))
(setq original-tracks (nreverse
(emms-playlist-tracks-in-region
(point-min) (point-max))))
(emms-playlist-sort-by-info-title)
(goto-char (point-min))
(while (not (eobp))
(save-excursion
(setq current-track-title (emms-playlist-current-title))
(forward-line +1)
(setq next-track-title (emms-playlist-current-title)))
(if (string-equal current-track-title next-track-title)
(progn
(or have-duplicate-track (setq have-duplicate-track t))
(emms-mark-track)
(forward-line +1)
(emms-mark-track))
(forward-line +1)))
(if have-duplicate-track
(emms-first-mark-track)
(emms-playlist-clear)
(dolist (track original-tracks)
(emms-playlist-insert-track track))
(emms-playlist-select selected-point)
(goto-char original-point)
(message "Haven't found duplicate track."))))
(defun emms-first-mark-track ()
"Jump to first mark track."
(interactive)
(let ((original-point (point))
(original-column (current-column)))
(goto-char (point-min))
(if (search-forward-regexp (format "^%c" emms-mark-char) nil t)
(move-to-column original-column t)
(goto-char original-point)
(message "No mark track."))))
(defun emms-last-mark-track ()
"Jump to last mark track."
(interactive)
(let ((original-point (point))
(original-column (current-column)))
(goto-char (point-max))
(if (search-backward-regexp (format "^%c" emms-mark-char) nil t)
(move-to-column original-column t)
(goto-char original-point)
(message "No mark track."))))
(defun emms-next-mark-track ()
"Jump to next mark track."
(interactive)
(let ((original-point (point))
(original-column (current-column)))
(if (bolp)
(forward-char +1))
(if (search-forward-regexp (format "^%c" emms-mark-char) nil t)
(move-to-column original-column t)
(goto-char original-point)
(message "No next mark track."))))
(defun emms-prev-mark-track ()
"Jump to previous mark track."
(interactive)
(let ((original-point (point))
(original-column (current-column)))
(if (not (bolp))
(beginning-of-line))
(if (search-backward-regexp (format "^%c" emms-mark-char) nil t)
(move-to-column original-column t)
(goto-char original-point)
(message "No previous mark track."))))
(defun emms-playlist-current-title ()
"Return the filename the current play."
(cdr (assoc 'info-title (emms-playlist-track-at))))
(provide 'emms-extension)