diff --git a/src/main.sh b/src/main.sh index 9e6ddbf..30d3cb9 100755 --- a/src/main.sh +++ b/src/main.sh @@ -36,6 +36,9 @@ MODE_INSERT="show" # Load playback helper . "sh/playback.sh" +# Load playlist tools +. "sh/playlist.sh" + # Load AWK scripts . "sh/awk.sh" @@ -97,7 +100,6 @@ case "${1:-}" in mbid_current="${3:-}" mbid="${4:-}" path="${5:-}" - debug "call to $*" pbcmd=$(playback_cmd_from_key "$FZF_KEY") case "$pbcmd" in "$PLAYBACK_CMD_PLAY") @@ -106,7 +108,7 @@ case "${1:-}" in "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") debug "not implemented" ;; "$VIEW_RELEASEGROUP") generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null ;; "$VIEW_RELEASE") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;; - "$VIEW_PLAYLIST") generate_playlist "$mbid_current" "$path" "$mbid" | mpv_play_list >/dev/null ;; + "$VIEW_PLAYLIST") mpv_play_index $((FZF_POS - 1)) >/dev/null ;; esac ;; "$PLAYBACK_CMD_QUEUE") @@ -152,9 +154,13 @@ case "${1:-}" in case "$view" in "$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") j="$(mb_releasegroup "$mbid" | $JQ -r --compact-output '."artist-credit"')" ;; "$VIEW_RELEASEGROUP") j="$(mb_release "$mbid" | $JQ -r --compact-output '."artist-credit"')" ;; - "$VIEW_RELEASE") j="$(mb_release "$mbid_cur" | $JQ -r --compact-output ".media | map(.tracks) | flatten[] | select(.id == \"$mbid\") | .\"artist-credit\"")" ;; + "$VIEW_RELEASE" | "$VIEW_PLAYLIST") j="$(mb_release "$mbid_cur" | $JQ -r --compact-output ".media | map(.tracks) | flatten[] | select(.id == \"$mbid\") | .\"artist-credit\"")" ;; "$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS") aid="$mbid" ;; esac + if [ "$view" = "$VIEW_PLAYLIST" ]; then + printf "print(%s)+print(%s)+accept" "$VIEW_SELECT_ARTIST" "$j" + exit 0 + fi if [ "${j:-}" ]; then cnt=$(echo "$j" | $JQ 'length') [ "$cnt" -eq 1 ] && aid="$(echo "$j" | $JQ -r '.[0].artist.id')" @@ -163,7 +169,6 @@ case "${1:-}" in exit 0 ;; "--draw") - debug "call to $*" # Generate fzf command to draw screen. # # @argument $2: mode (default `normal`) @@ -304,6 +309,27 @@ case "${1:-}" in __preview_artist "$2" exit 0 ;; +"--playlistcmd") + case "$2" in + "$PLAYLIST_CMD_REMOVE") mpv_rm_index $((FZF_POS - 1)) ;; + "$PLAYLIST_CMD_UP") mpv_playlist_move $((FZF_POS - 1)) $((FZF_POS - 2)) ;; + "$PLAYLIST_CMD_DOWN") mpv_playlist_move $((FZF_POS - 0)) $((FZF_POS - 1)) ;; + "$PLAYLIST_CMD_CLEAR") mpv_playlist_clear ;; + "$PLAYLIST_CMD_CLEAR_ABOVE") + for i in $(seq "$FZF_POS"); do + mpv_rm_index 0 + done + ;; + "$PLAYLIST_CMD_CLEAR_BELOW") + cnt=$(mpv_playlist_count) + rem=$((cnt - FZF_POS + 1)) + for i in $(seq "$rem"); do + mpv_rm_index $((FZF_POS - 1)) + done + ;; + esac + exit 0 + ;; "--playlist") list_playlist exit 0 @@ -457,19 +483,42 @@ $KEYS_FILTER_LOCAL:transform:$0 --fzf-key {2} {3} {4}" \ MBID="$sel" ;; "$VIEW_PLAYLIST") - list_playlist | - $FZF \ + sel=$( + list_playlist | $FZF \ --reverse \ --no-sort \ --border=double \ - --border-label=" Playlist " \ + --border-label="╢ Playlist ╟" \ --no-input \ --margin="2%,10%" \ - --bind="r,ctrl-r:reload:$0 --playlist" \ - --bind="q:accept" \ + --bind="$KEYS_DOWN,$KEYS_N_DOWN:down" \ + --bind="$KEYS_UP,$KEYS_N_UP:up" \ + --bind="$KEYS_HALFPAGE_DOWN:half-page-down" \ + --bind="$KEYS_HALFPAGE_UP:half-page-up" \ + --bind="$KEYS_N_BOT:last" \ + --bind="$KEYS_N_TOP:first" \ + --bind="$KEYS_SELECT_ARTIST:transform:$0 --jumpto-artist $MODE_NORMAL $VIEW_PLAYLIST {2} {3}" \ + --bind="$KEYS_LIST_ARTISTS:print($VIEW_LIST_ARTISTS)+accept" \ + --bind="$KEYS_LIST_ALBUMS:print($VIEW_LIST_ALBUMS)+accept" \ + --bind="$KEYS_SEARCH_ARTIST:print($VIEW_SEARCH_ARTIST)+accept" \ + --bind="$KEYS_SEARCH_ALBUM:print($VIEW_SEARCH_ALBUM)+accept" \ + --bind="$KEYS_BROWSE:execute-silent:open \"https://musicbrainz.org/\track/{r3}\"" \ + --bind="$KEYS_OPEN:execute-silent:open \"\$(dirname {4})\"" \ + --bind="$KEYS_PLAYBACK,$KEYS_N_PLAYBACK:transform($0 --playback $VIEW_PLAYLIST {2} {3} {4})+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_RELOAD:reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_REMOVE:execute-silent($0 --playlistcmd $PLAYLIST_CMD_REMOVE)+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_UP:execute-silent($0 --playlistcmd $PLAYLIST_CMD_UP)+up+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_DOWN:execute-silent($0 --playlistcmd $PLAYLIST_CMD_DOWN)+down+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_CLEAR:execute-silent($0 --playlistcmd $PLAYLIST_CMD_CLEAR)+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_CLEAR_ABOVE:execute-silent($0 --playlistcmd $PLAYLIST_CMD_CLEAR_ABOVE)+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_CLEAR_BELOW:execute-silent($0 --playlistcmd $PLAYLIST_CMD_CLEAR_BELOW)+reload:$0 --playlist" \ + --bind="$KEYS_PLAYLIST_QUIT:print($VIEW_LIST_ARTISTS)+accept" \ --delimiter="\t" \ - --with-nth="{1}" >/dev/null - VIEW="" + --with-nth="{1}" || true + ) + VIEW="$(echo "$sel" | head -1)" + ARGS="$(echo "$sel" | head -2 | tail -1)" + debug "playlist terminated: view=$VIEW, ARGS=$ARGS" ;; "$VIEW_QUIT") debug "Quitting..." diff --git a/src/sh/keys.sh b/src/sh/keys.sh index 5259499..a150fc3 100644 --- a/src/sh/keys.sh +++ b/src/sh/keys.sh @@ -64,7 +64,18 @@ # - KEYS_N_SEEK_FORWARD: Seek forward # - KEYS_N_SEEK_BACKWARD: Seek backward # -# Playlist: +# Playlist (in the playlist, there is no `insert` mode): +# - KEYS_PLAYLIST_RELOAD: Manually reload playlist +# - KEYS_PLAYLIST_REMOVE: Remove item from playlist +# - KEYS_PLAYLIST_UP: Move item one position up +# - KEYS_PLAYLIST_DOWN: Move item one position down +# - KEYS_PLAYLIST_CLEAR: Clear playlist +# - KEYS_PLAYLIST_CLEAR_ABOVE: Remove all items above incl. the selected one +# - KEYS_PLAYLIST_CLEAR_BELOW: Remove all items below incl. the selected one +# - KEYS_PLAYLIST_GOTO_RELEASE: Jump to release or seleted enry +# - KEYS_PLAYLIST_STORE: Store current playlist as file +# - KEYS_PLAYLIST_LOAD: Load playlist from file +# - KEYS_PLAYLIST_QUIT: Quit playlist view # # Mode selection: @@ -135,6 +146,19 @@ KEYS_N_SEEK_FORWARD="${KEYS_N_SEEK_FORWARD:-"N,f"}" KEYS_N_SEEK_BACKWARD="${KEYS_N_SEEK_BACKWARD:-"P,b"}" KEYS_N_PLAYBACK="$KEYS_N_PLAY,$KEYS_N_QUEUE,$KEYS_N_QUEUE_NEXT,$KEYS_N_TOGGLE_PLAYBACK,$KEYS_N_PLAY_NEXT,$KEYS_N_PLAY_PREV,$KEYS_N_SEEK_FORWARD,$KEYS_N_SEEK_BACKWARD" +# Playlist (in the playlist, there is no `insert` mode): +KEYS_PLAYLIST_RELOAD="${KEYS_PLAYLIST_RELOAD:-"r,ctrl-r"}" +KEYS_PLAYLIST_REMOVE="${KEYS_PLAYLIST_REMOVE:-"x,delete"}" +KEYS_PLAYLIST_UP="${KEYS_PLAYLIST_UP:-"u"}" +KEYS_PLAYLIST_DOWN="${KEYS_PLAYLIST_DOWN:-"d"}" +KEYS_PLAYLIST_CLEAR="${KEYS_PLAYLIST_CLEAR:-"C"}" +KEYS_PLAYLIST_CLEAR_ABOVE="${KEYS_PLAYLIST_CLEAR_ABOVE:-"U"}" +KEYS_PLAYLIST_CLEAR_BELOW="${KEYS_PLAYLIST_CLEAR_BELOW:-"D"}" +KEYS_PLAYLIST_GOTO_RELEASE="${KEYS_PLAYLIST_GOTO_RELEASE:-"ctrl-g"}" +KEYS_PLAYLIST_STORE="${KEYS_PLAYLIST_STORE:-"ctrl-s"}" +KEYS_PLAYLIST_LOAD="${KEYS_PLAYLIST_LOAD:-"ctrl-o"}" +KEYS_PLAYLIST_QUIT="${KEYS_PLAYLIST_QUIT:-"q,ctrl-c,esc"}" + ## Not yet characterized ########################## diff --git a/src/sh/mpv.sh b/src/sh/mpv.sh index 7f083e1..aa4a04a 100644 --- a/src/sh/mpv.sh +++ b/src/sh/mpv.sh @@ -23,8 +23,11 @@ mpv_playlist_position() { } mpv_playlist_move() { - debug "moving $1 -> $2" - __mpv_command_with_args2 "playlist-move" "$1" "$2" >>/tmp/foo 2>/dev/stdout + __mpv_command_with_args2 "playlist-move" "$1" "$2" >>/tmp/foo +} + +mpv_playlist_clear() { + __mpv_command "playlist-clear" } mpv_quit() { @@ -37,10 +40,17 @@ mpv_start() { $MPV --no-config --no-terminal --input-ipc-server="$MPV_SOCKET" --idle --no-osc --no-input-default-bindings & } +mpv_play_index() { + __mpv_command_with_arg "playlist-play-index" "$1" +} + +mpv_rm_index() { + __mpv_command_with_arg "playlist-remove" "$1" +} + mpv_play_list() { t=$(mktemp) cat >"$t" - debug "Playing $(cat "$t")" __mpv_command_with_arg "loadlist" "$t" rm -f "$t" } diff --git a/src/sh/playlist.sh b/src/sh/playlist.sh new file mode 100644 index 0000000..511ed7e --- /dev/null +++ b/src/sh/playlist.sh @@ -0,0 +1,6 @@ +PLAYLIST_CMD_REMOVE="rm" +PLAYLIST_CMD_UP="up" +PLAYLIST_CMD_DOWN="down" +PLAYLIST_CMD_CLEAR="clear" +PLAYLIST_CMD_CLEAR_ABOVE="clear-above" +PLAYLIST_CMD_CLEAR_BELOW="clear-below"