From b4ecf35234a7cc4d6542c76ec4a7fe90669dff21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=84min=20Baumeler?= Date: Fri, 29 Aug 2025 09:24:22 +0200 Subject: [PATCH] outsourced fzf handlers, and handle all inputs keys --- src/main.sh | 459 +++++------------------------------------ src/sh/fzf.sh | 539 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sh/keys.sh | 42 +++- 3 files changed, 625 insertions(+), 415 deletions(-) create mode 100644 src/sh/fzf.sh diff --git a/src/main.sh b/src/main.sh index b9043e9..082e39e 100755 --- a/src/main.sh +++ b/src/main.sh @@ -44,392 +44,36 @@ set -eu # Load list-generating methods . "sh/lists.sh" +# FZF handlers +. "sh/fzf.sh" + if [ "${1:-}" = "--fzf-reload" ]; then - mode=$(cut -d "#" -f 1 "$MODEFILE") - args=$(cut -d "#" -f 2- "$MODEFILE") - case "$mode" in - "$MODE_ARTIST") - list_releasegroups "$args" - ;; - "$MODE_RELEASEGROUP") - list_releases "$args" - ;; - "$MODE_RELEASE") - list_recordings "$args" - ;; - "$MODE_LIST_ARTISTS") - list_local_artists - ;; - "$MODE_LIST_ALBUMS") - list_local_releasegroups - ;; - esac + fzf_handle_reload exit 0 fi if [ "${1:-}" = "--fzf-load" ]; then - mode=$(cut -d "#" -f 1 "$MODEFILE") - args=$(cut -d "#" -f 2- "$MODEFILE") - case "$mode" in - "$MODE_ARTIST") - secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")" - QUERY="$(printf "!%s " "$secsymb")" - name="$(mb_artist "$args" | $JQ -r '.name')" - PROMPT=$(printf "$ARTIST_PROMPT" "$name") - ;; - "$MODE_RELEASEGROUP") - title="$(mb_releasegroup "$args" | - $JQ -r '.title')" - artist="$(mb_releasegroup "$args" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" - QUERY="$(printf "%s " "$FORMAT_STATUS_OFFICIAL")" - PROMPT=$(printf "$FULL_PROMPT" "$artist" "$title") - ;; - "$MODE_RELEASE") - title="$(mb_release "$args" | - $JQ -r '.title')" - artist="$(mb_release "$args" | - $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" - PROMPT=$(printf "$FULL_PROMPT" "$artist" "$title") - ;; - "$MODE_SEARCH_ARTIST") - ENABLE_CHANGE=1 - DISABLE_SEARCH=1 - SHOW_PREVIEW=1 - ;; - "$MODE_SEARCH_ALBUM") - ENABLE_CHANGE=1 - DISABLE_SEARCH=1 - ;; - "$MODE_LIST_ARTISTS") - SHOW_PREVIEW=1 - ;; - "$MODE_LIST_ALBUMS") ;; - esac - printf "+change-query(%s)" "${QUERY:-}" - printf "+change-prompt(%s)" "${PROMPT:-"$SEARCH_PROMPT"}" - [ "${DISABLE_SEARCH:-}" ] && printf "+disable-search" || printf "+enable-search" - [ "${SHOW_PREVIEW:-}" ] && printf "+show-preview" || printf "+hide-preview" - [ "${ENABLE_CHANGE:-}" ] && printf "+rebind(change)" || printf "+unbind(change)" + fzf_handle_load exit 0 fi if [ "${1:-}" = "--fzf-info" ]; then - mode=$(cut -d "#" -f 1 "$MODEFILE") - args=$(cut -d "#" -f 2- "$MODEFILE") - case "$mode" in - "$MODE_SEARCH_ARTIST") - echo "Search music artist on MusicBrainz" - ;; - "$MODE_SEARCH_ALBUM") - echo "Search album on MusicBrainz" - ;; - "$MODE_LIST_ARTISTS") - echo "Search artists" - ;; - "$MODE_LIST_ALBUMS") - echo "Search albums" - ;; - "$MODE_SELECT_ARTIST") - echo "Select artist (WE SHOULDNT SEE THIS; THIS IS A BUG!)" - ;; - *) - if [ "$FZF_KEY" ]; then - printf "[last key: %s] %s/%s" "$FZF_KEY" "$FZF_MATCH_COUNT" "$FZF_TOTAL_COUNT" - else - printf "%s/%s" "$FZF_MATCH_COUNT" "$FZF_TOTAL_COUNT" - fi - ;; - esac + fzf_info exit 0 fi if [ "${1:-}" = "--fzf-change-reload" ]; then - # Wait for async. process to terminate - sleep 1 - while [ -f "$LOCKFILE" ]; do - sleep 1 - done - # Show results - column -t -s "$(printf '\t')" "$RESULTS" | - sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' + fzf_reload_after_change exit 0 fi if [ "${1:-}" = "--fzf-change" ]; then - # Kill any running search - if [ -f "$PIDFILE" ]; then - pid=$(cat "$PIDFILE") - rm -f "$PIDFILE" - kill -9 "$pid" >/dev/null 2>&1 || true - fi - # Stop, if no search string is given - [ "$FZF_QUERY" ] || exit 0 - # Store PID of current process - echo "$$" >"$PIDFILE" - touch "$LOCKFILE" - sleep 1 - mode=$(cut -d "#" -f 1 "$MODEFILE") - if [ "$mode" = "$MODE_SEARCH_ARTIST" ]; then - api_mb_search_artist "$FZF_QUERY" | - $JQ -r '.artists[] | [ - .id, - .type, - .name, - .disambiguation, - .["life-span"].begin, - .["life-span"].end - ] | join("\t")' | - awk \ - -F "\t" \ - -v file_local_artists="${LOCALDATA_ARTISTS:-}" \ - -v format_person="$AV_PERSON" \ - -v format_group="$AV_GROUP" \ - -v format_disambiguation="$AV_DISAMBIGUATION" \ - -v format_local="$FORMAT_LOCAL" \ - "$AWK_ARTISTS" >"$RESULTS" || - true - else - api_mb_search_releasegroup "$FZF_QUERY" | - $JQ -r '."release-groups"[] | [ - .id, - ."primary-type", - (."secondary-types" // []|join(";")), - ."first-release-date", - .title, - (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")) - ] | join("\t")' | - awk \ - -F "\t" \ - -v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \ - -v format_release="$RGV_RELEASE" \ - -v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \ - -v format_year="$RGV_YEAR" \ - -v format_album="$FORMAT_TYPE_ALBUM" \ - -v format_single="$FORMAT_TYPE_SINGLE" \ - -v format_ep="$FORMAT_TYPE_EP" \ - -v format_broadcast="$FORMAT_TYPE_BROADCAST" \ - -v format_other="$FORMAT_TYPE_OTHER" \ - -v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \ - -v format_secondary="$FORMAT_TYPE_SECONDARY" \ - -v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \ - -v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \ - -v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \ - -v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \ - -v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \ - -v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \ - -v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \ - -v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \ - -v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \ - -v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \ - -v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \ - -v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \ - -v format_local="$FORMAT_LOCAL" \ - "$AWK_RELEASEGROUPS" | - cut -d "$(printf '\t')" -f 2- >"$RESULTS" || - true - fi - # Process ends now: Display and quit - rm -f "$LOCKFILE" "$PIDFILE" + fzf_handle_change exit 0 fi if [ "${1:-}" = "--fzf-key" ]; then - parentmbid="${2:-}" - mbid="${3:-}" - path="${4:-}" - mode=$(cut -d "#" -f 1 "$MODEFILE") - args=$(cut -d "#" -f 2- "$MODEFILE") - - case ",$KEYS_PLAY," in - *",$FZF_KEY,"*) - [ "$path" ] || exit 0 - case "$mode" in - "$MODE_RELEASEGROUP") - generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null - ;; - "$MODE_RELEASE") - generate_playlist "$parentmbid" "$path" "$mbid" | mpv_play_list >/dev/null - ;; - "$MODE_PLAYLIST") - generate_playlist "$parentmbid" "$path" "$mbid" | mpv_play_list >/dev/null - MODE_NEXT="$MODE_PLAYLIST" - ACCEPT=1 - ;; - esac - ;; - esac - case ",$KEYS_QUEUE," in - *",$FZF_KEY,"*) - foo "queue key pressed" - [ "$path" ] || exit 0 - case "$mode" in - "$MODE_RELEASEGROUP") - generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null - ;; - "$MODE_RELEASE") - generate_playlist "$parentmbid" "$path" "$mbid" | mpv_queue_list >/dev/null - ;; - "$MODE_PLAYLIST") - generate_playlist "$parentmbid" "$path" "$mbid" | mpv_queue_list >/dev/null - MODE_NEXT="$MODE_PLAYLIST" - ACCEPT=1 - ;; - esac - ;; - esac - case ",$KEYS_TOGGLE_PLAY_PAUSE," in - *",$FZF_KEY,"*) mpv_toggle_pause >/dev/null ;; - esac - case ",$KEYS_PLAY_NEXT," in - *",$FZF_KEY,"*) - mpv_next >/dev/null - [ "$mode" = "$MODE_PLAYLIST" ] && MODE_NEXT="$MODE_PLAYLIST" && ACCEPT=1 - ;; - esac - case ",$KEYS_PLAY_PREV," in - *",$FZF_KEY,"*) - mpv_prev >/dev/null - [ "$mode" = "$MODE_PLAYLIST" ] && MODE_NEXT="$MODE_PLAYLIST" && ACCEPT=1 - ;; - esac - case ",$KEYS_SEEK_FORWARD," in - *",$FZF_KEY,"*) mpv_seek_forward >/dev/null ;; - esac - case ",$KEYS_SEEK_BACKWARD," in - *",$FZF_KEY,"*) mpv_seek_backward >/dev/null ;; - esac - case ",$KEYS_HALFPAGE_DOWN," in - *",$FZF_KEY,"*) printf "half-page-down" ;; - esac - case ",$KEYS_HALFPAGE_UP," in - *",$FZF_KEY,"*) printf "half-page-up" ;; - esac - case ",$KEYS_FILTER_LOCAL," in - *",$FZF_KEY,"*) - case "$mode" in - "$MODE_SEARCH_ARTIST" | "$MODE_SEARCH_ALBUM") ;; - *) QUERY="$FORMAT_LOCAL " ;; - esac - ;; - esac - case ",$KEYS_SWITCH_ARTIST_ALBUM," in - *",$FZF_KEY,"*) - case "$mode" in - "$MODE_SEARCH_ARTIST") MODE_NEXT="$MODE_SEARCH_ALBUM" ;; - "$MODE_SEARCH_ALBUM") MODE_NEXT="$MODE_SEARCH_ARTIST" ;; - "$MODE_LIST_ARTISTS") MODE_NEXT="$MODE_LIST_ALBUMS" ;; - "$MODE_LIST_ALBUMS") MODE_NEXT="$MODE_LIST_ARTISTS" ;; - esac - ;; - esac - case ",$KEYS_SWITCH_LOCAL_REMOTE," in - *",$FZF_KEY,"*) - case "$mode" in - "$MODE_SEARCH_ARTIST") MODE_NEXT="$MODE_LIST_ARTISTS" ;; - "$MODE_SEARCH_ALBUM") MODE_NEXT="$MODE_LIST_ALBUMS" ;; - "$MODE_LIST_ARTISTS") MODE_NEXT="$MODE_SEARCH_ARTIST" ;; - "$MODE_LIST_ALBUMS") MODE_NEXT="$MODE_SEARCH_ALBUM" ;; - esac - ;; - esac - case ",$KEYS_BROWSE," in - *",$FZF_KEY,"*) - [ "$mbid" ] || exit 0 - case "$mode" in - "$MODE_SEARCH_ARTIST" | "$MODE_LIST_ARTISTS") urltype="artist" ;; - "$MODE_ARTIST") urltype="release-group" ;; - "$MODE_RELEASEGROUP") urltype="release" ;; - "$MODE_RELEASE" | "$MODE_PLAYLIST") urltype="track" ;; - esac - [ "${urltype:-}" ] && printf "execute-silent(xdg-open \"https://musicbrainz.org/%s/%s\" &)" "$urltype" "$mbid" - ;; - esac - case ",$KEYS_OUT," in - *",$FZF_KEY,"*) - case "$mode" in - "$MODE_ARTIST") - MODE_NEXT="$MODE_LIST_ARTISTS" - ;; - "$MODE_RELEASEGROUP") - MODE_NEXT="$MODE_SELECT_ARTIST" - MODE_NEXT_ARGS="$(mb_releasegroup "$args" | $JQ -r --compact-output '."artist-credit"')" - ACCEPT=1 - ;; - "$MODE_RELEASE") - MODE_NEXT="$MODE_RELEASEGROUP" - MODE_NEXT_ARGS="$(mb_release "$args" | $JQ -r --compact-output '."release-group".id')" - ;; - "$MODE_PLAYLIST") - MODE_NEXT="$MODE_RELEASE" - MODE_NEXT_ARGS="$parentmbid" - ACCEPT=1 - ;; - esac - ;; - esac - case ",$KEYS_IN," in - *",$FZF_KEY,"*) - [ "$mbid" ] || exit 0 - MODE_NEXT_ARGS="$mbid" - case "$mode" in - "$MODE_LIST_ARTISTS" | "$MODE_SEARCH_ARTIST") - MODE_NEXT="$MODE_ARTIST" - ;; - "$MODE_ARTIST") - MODE_NEXT="$MODE_RELEASEGROUP" - ;; - "$MODE_RELEASEGROUP" | "$MODE_LIST_ALBUMS" | "$MODE_SEARCH_ALBUM") - MODE_NEXT="$MODE_RELEASE" - ;; - esac - ;; - esac - case ",$KEYS_SELECT_ARTIST," in - *",$FZF_KEY,"*) - [ "$mbid" ] || exit 0 - case "$mode" in - "$MODE_ARTIST" | "$MODE_SEARCH_ARTIST" | "$MODE_LIST_ARTISTS") - MODE_NEXT_ARGS="$(mb_releasegroup "$mbid" | $JQ -r --compact-output '."artist-credit"')" - ACCEPT=1 - ;; - "$MODE_RELEASEGROUP" | "$MODE_SEARCH_ALBUM" | "$MODE_LIST_ALBUMS") - MODE_NEXT_ARGS="$(mb_release "$mbid" | $JQ -r --compact-output '."artist-credit"')" - ACCEPT=1 - ;; - "$MODE_RELEASE") - MODE_NEXT_ARGS="$(mb_release "$args" | $JQ -r --compact-output '."artist-credit"')" - ACCEPT=1 - ;; - esac - [ "$MODE_NEXT_ARGS" ] && MODE_NEXT="$MODE_SELECT_ARTIST" - ;; - esac - case ",$KEYS_FILTER_PRIMARY," in - *",$FZF_KEY,"*) - [ "$mode" = "$MODE_ARTIST" ] || exit 0 - secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")" - QUERY="!$secsymb " - ;; - esac - case ",$KEYS_FILTER_SECONDARY," in - *",$FZF_KEY,"*) - [ "$mode" = "$MODE_ARTIST" ] || exit 0 - secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")" - QUERY="$secsymb " - ;; - esac - case ",$KEYS_SHOW_PLAYLIST," in - *",$FZF_KEY,"*) - MODE_NEXT="$MODE_PLAYLIST" - ACCEPT=1 - ;; - esac - [ "${QUERY:-}" ] && printf "+change-query(%s)" "$QUERY" - if [ "$MODE_NEXT" ]; then - printf "%s#%s" "$MODE_NEXT" "${MODE_NEXT_ARGS:-}" >"$MODEFILE" - [ "${ACCEPT:-}" ] && printf "+accept" || printf "+reload:%s" "$0 --fzf-reload" - fi + fzf_handle_key "${2:-}" "${3:-}" "${4:-}" exit 0 fi @@ -489,9 +133,10 @@ tmpdir=$(mktemp -d) LOCKFILE="$tmpdir/lock" RESULTS="$tmpdir/results" PIDFILE="$tmpdir/pid" -MODEFILE="$tmpdir/mode" +STATEFILE="$tmpdir/state" +ARGSFILE="$tmpdir/state-args" trap 'rm -rf "$tmpdir"' EXIT INT -export LOCKFILE RESULTS PIDFILE MODEFILE +export LOCKFILE RESULTS PIDFILE STATEFILE ARGSFILE if [ "${1:-}" = "--ni-search-artist" ]; then $0 --internal-search "artist" "$2" @@ -503,44 +148,53 @@ if [ "${1:-}" = "--ni-search-album" ]; then exit 0 fi -# Modes -MODE_ARTIST="artist" -MODE_RELEASEGROUP="rg" -MODE_RELEASE="release" -MODE_SEARCH_ARTIST="search-artist" -MODE_SEARCH_ALBUM="search-album" -MODE_LIST_ARTISTS="list-artists" -MODE_LIST_ALBUMS="list-albums" -MODE_SELECT_ARTIST="select-artist" -MODE_PLAYLIST="playlist" -export MODE_ARTIST MODE_RELEASEGROUP MODE_RELEASE MODE_SEARCH_ARTIST \ - MODE_SEARCH_ALBUM MODE_LIST_ARTISTS MODE_LIST_ALBUMS MODE_SELECT_ARTIST \ - MODE_PLAYLIST +# Views and modes +VIEW_ARTIST="artist" +VIEW_RELEASEGROUP="rg" +VIEW_RELEASE="release" +VIEW_SEARCH_ARTIST="search-artist" +VIEW_SEARCH_ALBUM="search-album" +VIEW_LIST_ARTISTS="list-artists" +VIEW_LIST_ALBUMS="list-albums" +VIEW_SELECT_ARTIST="select-artist" +VIEW_PLAYLIST="playlist" +MODE_NORMAL="normal" +MODE_INSERT="insert" +export VIEW_ARTIST VIEW_RELEASEGROUP VIEW_RELEASE VIEW_SEARCH_ARTIST \ + VIEW_SEARCH_ALBUM VIEW_LIST_ARTISTS VIEW_LIST_ALBUMS VIEW_SELECT_ARTIST \ + VIEW_PLAYLIST MODE_NORMAL MODE_INSERT case "${1:-}" in "--artist") [ ! "${2:-}" ] && err "MusicBrainz Artist ID not specified (see --help)" && exit 1 - printf "%s#%s" "$MODE_ARTIST" "$2" >"$MODEFILE" + printf "%s#%s" "$VIEW_ARTIST" "$MODE_NORMAL" >"$STATEFILE" + printf "%s" "$2" >"$ARGSFILE" ;; "--releasegroup") [ ! "${2:-}" ] && err "MusicBrainz Release-Group ID not specified (see --help)" && exit 1 - printf "%s#%s" "$MODE_RELEASEGROUP" "$2" >"$MODEFILE" + printf "%s#%s" "$VIEW_RELEASEGROUP" "$MODE_NORMAL" >"$STATEFILE" + printf "%s" "$2" >"$ARGSFILE" ;; "--release") [ ! "${2:-}" ] && err "MusicBrainz Release ID not specified (see --help)" && exit 1 - printf "%s#%s" "$MODE_RELEASE" "$2" >"$MODEFILE" + printf "%s#%s" "$VIEW_RELEASE" "$MODE_NORMAL" >"$STATEFILE" + printf "%s" "$2" >"$ARGSFILE" ;; "--search-artist") - printf "%s#%s" "$MODE_SEARCH_ARTIST" "${2:-}" >"$MODEFILE" + printf "%s#%s" "$VIEW_SEARCH_ARTIST" "$MODE_INSERT" >"$STATEFILE" + printf "%s" "${2:-}" >"$ARGSFILE" ;; "--search-album") - printf "%s#%s" "$MODE_SEARCH_ALBUM" "${2:-}" >"$MODEFILE" + printf "%s#%s" "$VIEW_SEARCH_ALBUM" "$MODE_INSERT" >"$STATEFILE" + printf "%s" "${2:-}" >"$ARGSFILE" ;; "--artists" | "") - printf "%s#" "$MODE_LIST_ARTISTS" >"$MODEFILE" + printf "%s#%s" "$VIEW_LIST_ARTISTS" "$MODE_NORMAL" >"$STATEFILE" + printf "%s" "" >"$ARGSFILE" ;; "--albums") - printf "%s#" "$MODE_LIST_ALBUMS" >"$MODEFILE" + printf "%s#%s" "$VIEW_LIST_ALBUMS" "$MODE_NORMAL" >"$STATEFILE" + printf "%s" "" >"$ARGSFILE" ;; *) err "Unknown option $1 (see --help)" @@ -553,10 +207,11 @@ mpv_start # $KEYS_PLAY main loop while true; do - mode=$(cut -d "#" -f 1 "$MODEFILE") - args=$(cut -d "#" -f 2- "$MODEFILE") - case "$mode" in - "$MODE_SELECT_ARTIST") + view=$(cut -d "#" -f 1 "$STATEFILE") + mode=$(cut -d "#" -f 2 "$STATEFILE") + args=$(cat "$ARGSFILE") + case "$view" in + "$VIEW_SELECT_ARTIST") sel=$( echo "$args" | list_artists_from_json | @@ -574,9 +229,10 @@ $KEYS_FILTER_LOCAL:transform:$0 --fzf-key {2} {3} {4}" \ --accept-nth="{3}" \ --with-nth="{1}" ) - printf "%s#%s" "$MODE_ARTIST" "$sel" >"$MODEFILE" + printf "%s#%s" "$VIEW_ARTIST" "$mode" >"$STATEFILE" + printf "%s" "$sel" >"$ARGSFILE" ;; - "$MODE_PLAYLIST") + "$VIEW_PLAYLIST") list_playlist | $FZF \ --reverse \ @@ -585,13 +241,7 @@ $KEYS_FILTER_LOCAL:transform:$0 --fzf-key {2} {3} {4}" \ --border-label=" Playlist " \ --no-input \ --margin="2%,10%" \ - --bind="$KEYS_HALFPAGE_DOWN,$KEYS_HALFPAGE_UP,\ -$KEYS_BROWSE,\ -$KEYS_OUT,\ -$KEYS_SELECT_ARTIST,\ -$KEYS_PLAY,$KEYS_QUEUE,$KEYS_TOGGLE_PLAY_PAUSE,\ -$KEYS_PLAY_NEXT,$KEYS_PLAY_PREV,\ -$KEYS_SEEK_FORWARD,$KEYS_SEEK_BACKWARD:transform:$0 --fzf-key {2} {3} {4}" \ + --bind="$KEYS_ALL:transform:$0 --fzf-key {2} {3} {4}" \ --delimiter="\t" \ --with-nth="{1}" >/dev/null ;; @@ -601,14 +251,7 @@ $KEYS_SEEK_FORWARD,$KEYS_SEEK_BACKWARD:transform:$0 --fzf-key {2} {3} {4}" \ --bind="start:reload:$0 --fzf-reload" \ --bind="load:transform:$0 --fzf-load" \ --bind="change:execute-silent($0 --fzf-change &)+reload:$0 --fzf-change-reload" \ - --bind="$KEYS_HALFPAGE_DOWN,$KEYS_HALFPAGE_UP,\ -$KEYS_BROWSE,\ -$KEYS_IN,$KEYS_OUT,\ -$KEYS_SELECT_ARTIST,\ -$KEYS_FILTER_LOCAL,$KEYS_FILTER_PRIMARY,$KEYS_FILTER_SECONDARY,\ -$KEYS_SWITCH_ARTIST_ALBUM,$KEYS_SWITCH_LOCAL_REMOTE,\ -$KEYS_PLAY,$KEYS_QUEUE,\ -$KEYS_SHOW_PLAYLIST:transform:$0 --fzf-key {2} {3} {4}" \ + --bind="$KEYS_ALL:transform:$0 --fzf-key {2} {3} {4}" \ --info="inline-right" \ --info-command="$0 --fzf-info" \ --preview-window="right,25%,border-left,wrap,<30(hidden)" \ diff --git a/src/sh/fzf.sh b/src/sh/fzf.sh new file mode 100644 index 0000000..7667583 --- /dev/null +++ b/src/sh/fzf.sh @@ -0,0 +1,539 @@ +# Reload data for FZF +fzf_handle_reload() { + view=$(cut -d "#" -f 1 "$STATEFILE") + mode=$(cut -d "#" -f 2 "$STATEFILE") + args=$(cat "$ARGSFILE") + case "$view" in + "$VIEW_ARTIST") + list_releasegroups "$args" + ;; + "$VIEW_RELEASEGROUP") + list_releases "$args" + ;; + "$VIEW_RELEASE") + list_recordings "$args" + ;; + "$VIEW_LIST_ARTISTS") + list_local_artists + ;; + "$VIEW_LIST_ALBUMS") + list_local_releasegroups + ;; + esac +} + +# Handle for after loading data into FZF +fzf_handle_load() { + view=$(cut -d "#" -f 1 "$STATEFILE") + mode=$(cut -d "#" -f 2 "$STATEFILE") + args=$(cat "$ARGSFILE") + case "$view" in + "$VIEW_ARTIST") + secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")" + QUERY="$(printf "!%s " "$secsymb")" + name="$(mb_artist "$args" | $JQ -r '.name')" + PROMPT=$(printf "$ARTIST_PROMPT" "$name") + ;; + "$VIEW_RELEASEGROUP") + title="$(mb_releasegroup "$args" | + $JQ -r '.title')" + artist="$(mb_releasegroup "$args" | + $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" + QUERY="$(printf "%s " "$FORMAT_STATUS_OFFICIAL")" + PROMPT=$(printf "$FULL_PROMPT" "$artist" "$title") + ;; + "$VIEW_RELEASE") + title="$(mb_release "$args" | + $JQ -r '.title')" + artist="$(mb_release "$args" | + $JQ -r '."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")')" + PROMPT=$(printf "$FULL_PROMPT" "$artist" "$title") + ;; + "$VIEW_SEARCH_ARTIST") + ENABLE_CHANGE=1 + DISABLE_SEARCH=1 + SHOW_PREVIEW=1 + ;; + "$VIEW_SEARCH_ALBUM") + ENABLE_CHANGE=1 + DISABLE_SEARCH=1 + ;; + "$VIEW_LIST_ARTISTS") + SHOW_PREVIEW=1 + ;; + "$VIEW_LIST_ALBUMS") ;; + esac + printf "+change-query(%s)" "${QUERY:-}" + printf "+change-prompt(%s)" "${PROMPT:-"$SEARCH_PROMPT"}" + [ "${DISABLE_SEARCH:-}" ] && printf "+disable-search" || printf "+enable-search" + [ "${SHOW_PREVIEW:-}" ] && printf "+show-preview" || printf "+hide-preview" + [ "${ENABLE_CHANGE:-}" ] && printf "+rebind(change)" || printf "+unbind(change)" +} + +# Print info string for FZF +fzf_info() { + view=$(cut -d "#" -f 1 "$STATEFILE") + mode=$(cut -d "#" -f 2 "$STATEFILE") + args=$(cat "$ARGSFILE") + case "$view" in + "$VIEW_SEARCH_ARTIST") + echo "Search music artist on MusicBrainz" + ;; + "$VIEW_SEARCH_ALBUM") + echo "Search album on MusicBrainz" + ;; + "$VIEW_LIST_ARTISTS") + echo "Search artists" + ;; + "$VIEW_LIST_ALBUMS") + echo "Search albums" + ;; + "$VIEW_SELECT_ARTIST") + echo "Select artist (WE SHOULDNT SEE THIS; THIS IS A BUG!)" + ;; + *) + if [ "$FZF_KEY" ]; then + printf "[last key: %s] %s/%s" "$FZF_KEY" "$FZF_MATCH_COUNT" "$FZF_TOTAL_COUNT" + else + printf "%s/%s" "$FZF_MATCH_COUNT" "$FZF_TOTAL_COUNT" + fi + ;; + esac +} + +# Reload hook that is used after change in query +fzf_reload_after_change() { + # Wait for async. process to terminate + sleep 1 + while [ -f "$LOCKFILE" ]; do + sleep 1 + done + # Show results + column -t -s "$(printf '\t')" "$RESULTS" | + sed 's| \+\([0-9a-f-]\+\) \+\([0-9a-f-]\+\)$|\t\1\t\2|' +} + +# Handle change in query +fzf_handle_change() { + # Kill any running search + if [ -f "$PIDFILE" ]; then + pid=$(cat "$PIDFILE") + rm -f "$PIDFILE" + kill -9 "$pid" >/dev/null 2>&1 || true + fi + # Stop, if no search string is given + [ "$FZF_QUERY" ] || exit 0 + # Store PID of current process + echo "$$" >"$PIDFILE" + touch "$LOCKFILE" + sleep 1 + view=$(cut -d "#" -f 1 "$STATEFILE") + if [ "$view" = "$VIEW_SEARCH_ARTIST" ]; then + api_mb_search_artist "$FZF_QUERY" | + $JQ -r '.artists[] | [ + .id, + .type, + .name, + .disambiguation, + .["life-span"].begin, + .["life-span"].end + ] | join("\t")' | + awk \ + -F "\t" \ + -v file_local_artists="${LOCALDATA_ARTISTS:-}" \ + -v format_person="$AV_PERSON" \ + -v format_group="$AV_GROUP" \ + -v format_disambiguation="$AV_DISAMBIGUATION" \ + -v format_local="$FORMAT_LOCAL" \ + "$AWK_ARTISTS" >"$RESULTS" || + true + else + api_mb_search_releasegroup "$FZF_QUERY" | + $JQ -r '."release-groups"[] | [ + .id, + ."primary-type", + (."secondary-types" // []|join(";")), + ."first-release-date", + .title, + (."artist-credit" | map(([.name, .joinphrase]|join(""))) | join("")) + ] | join("\t")' | + awk \ + -F "\t" \ + -v file_local_releasegroups="${LOCALDATA_RELEASEGROUPS:-}" \ + -v format_release="$RGV_RELEASE" \ + -v format_release_w_artist="$RGV_RELEASE_W_ARTIST" \ + -v format_year="$RGV_YEAR" \ + -v format_album="$FORMAT_TYPE_ALBUM" \ + -v format_single="$FORMAT_TYPE_SINGLE" \ + -v format_ep="$FORMAT_TYPE_EP" \ + -v format_broadcast="$FORMAT_TYPE_BROADCAST" \ + -v format_other="$FORMAT_TYPE_OTHER" \ + -v format_has_secondary="$FORMAT_TYPE_HAS_SECONDARY" \ + -v format_secondary="$FORMAT_TYPE_SECONDARY" \ + -v format_compilation="$FORMAT_TYPE_SECONDARY_COMPILATION" \ + -v format_soundtrack="$FORMAT_TYPE_SECONDARY_SOUNDTRACK" \ + -v format_spokenword="$FORMAT_TYPE_SECONDARY_SPOKENWORD" \ + -v format_interview="$FORMAT_TYPE_SECONDARY_INTERVIEW" \ + -v format_audiobook="$FORMAT_TYPE_SECONDARY_AUDIOBOOK" \ + -v format_audiodrama="$FORMAT_TYPE_SECONDARY_AUDIODRAMA" \ + -v format_live="$FORMAT_TYPE_SECONDARY_LIVE" \ + -v format_remix="$FORMAT_TYPE_SECONDARY_REMIX" \ + -v format_djmix="$FORMAT_TYPE_SECONDARY_DJMIX" \ + -v format_mixtape="$FORMAT_TYPE_SECONDARY_MIXTAPE" \ + -v format_demo="$FORMAT_TYPE_SECONDARY_DEMO" \ + -v format_fieldrec="$FORMAT_TYPE_SECONDARY_FIELDREC" \ + -v format_local="$FORMAT_LOCAL" \ + "$AWK_RELEASEGROUPS" | + cut -d "$(printf '\t')" -f 2- >"$RESULTS" || + true + fi + # Process ends now: Display and quit + rm -f "$LOCKFILE" "$PIDFILE" +} + +# Handle FZF keypress +# @argument $1: MusicBrainz ID of parent object +# @argument $2: MusicBrainz ID of selected object +# @argument $3: Path to decoration file (optional) +fzf_handle_key() { + foo "FZF_KEY=$FZF_KEY" + parentmbid="${1:-}" + mbid="${2:-}" + path="${3:-}" + view=$(cut -d "#" -f 1 "$STATEFILE") + mode=$(cut -d "#" -f 2 "$STATEFILE") + args=$(cat "$ARGSFILE") + + # If we are in the insert mode, and the key pressed is an "input" key, then + # put it and quit. + if [ "$mode" = "$MODE_INSERT" ]; then + case ",$KEYS_INPUT," in + *",$FZF_KEY,"*) + foo "...." + printf "put(%s)" "$FZF_KEY" + return 0 + ;; + esac + fi + + # Handle key press + foo "handle key..." + case ",$KEYS_HALFPAGE_DOWN," in + *",$FZF_KEY,"*) printf "half-page-down" ;; + esac + case ",$KEYS_HALFPAGE_UP," in + *",$FZF_KEY,"*) printf "half-page-up" ;; + esac + case ",$KEYS_BROWSE," in + *",$FZF_KEY,"*) + [ "$mbid" ] || return 0 + case "$view" in + "$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS" | "$VIEW_SELECT_ARTIST") urltype="artist" ;; + "$VIEW_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") urltype="release-group" ;; + "$VIEW_RELEASEGROUP") urltype="release" ;; + "$VIEW_RELEASE" | "$VIEW_PLAYLIST") urltype="track" ;; + esac + [ "${urltype:-}" ] && printf "execute-silent(xdg-open \"https://musicbrainz.org/%s/%s\" &)" "$urltype" "$mbid" + ;; + esac + case ",$KEYS_OUT," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_ARTIST") + VIEW_NEXT="$VIEW_LIST_ARTISTS" + ;; + "$VIEW_RELEASEGROUP") + VIEW_NEXT="$VIEW_SELECT_ARTIST" + VIEW_NEXT_ARGS="$(mb_releasegroup "$args" | $JQ -r --compact-output '."artist-credit"')" + ACCEPT=1 + ;; + "$VIEW_RELEASE") + VIEW_NEXT="$VIEW_RELEASEGROUP" + VIEW_NEXT_ARGS="$(mb_release "$args" | $JQ -r --compact-output '."release-group".id')" + ;; + "$VIEW_PLAYLIST") + VIEW_NEXT="$VIEW_RELEASE" + VIEW_NEXT_ARGS="$parentmbid" + ACCEPT=1 + ;; + esac + ;; + esac + case ",$KEYS_IN," in + *",$FZF_KEY,"*) + [ "$mbid" ] || return 0 + VIEW_NEXT_ARGS="$mbid" + case "$view" in + "$VIEW_LIST_ARTISTS" | "$VIEW_SEARCH_ARTIST") + VIEW_NEXT="$VIEW_ARTIST" + ;; + "$VIEW_ARTIST") + VIEW_NEXT="$VIEW_RELEASEGROUP" + ;; + "$VIEW_RELEASEGROUP" | "$VIEW_LIST_ALBUMS" | "$VIEW_SEARCH_ALBUM") + VIEW_NEXT="$VIEW_RELEASE" + ;; + esac + ;; + esac + case ",$KEYS_SELECT_ARTIST," in + *",$FZF_KEY,"*) + [ "$mbid" ] || return 0 + case "$view" in + "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_LIST_ARTISTS") + VIEW_NEXT_ARGS="$(mb_releasegroup "$mbid" | $JQ -r --compact-output '."artist-credit"')" + ACCEPT=1 + ;; + "$VIEW_RELEASEGROUP" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ALBUMS") + VIEW_NEXT_ARGS="$(mb_release "$mbid" | $JQ -r --compact-output '."artist-credit"')" + ACCEPT=1 + ;; + "$VIEW_RELEASE") + VIEW_NEXT_ARGS="$(mb_release "$args" | $JQ -r --compact-output '."artist-credit"')" + ACCEPT=1 + ;; + "$VIEW_PLAYLIST") + foo "NOT IMPLEMENTED" + ;; + esac + [ "$VIEW_NEXT_ARGS" ] && VIEW_NEXT="$VIEW_SELECT_ARTIST" + ;; + esac + case ",$KEYS_FILTER_LOCAL," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_PLAYLIST") ;; + *) QUERY="$FORMAT_LOCAL " ;; + esac + ;; + esac + case ",$KEYS_FILTER_PRIMARY," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_ARTIST" | "$VIEW_LIST_ALBUMS") + secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")" + QUERY="!$secsymb " + ;; + esac + ;; + esac + case ",$KEYS_FILTER_SECONDARY," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_ARTIST" | "$VIEW_LIST_ALBUMS") + secsymb="$(printf "$FORMAT_TYPE_HAS_SECONDARY" "")" + QUERY="$secsymb " + ;; + esac + ;; + esac + case ",$KEYS_SWITCH_ARTIST_ALBUM," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_SEARCH_ARTIST") VIEW_NEXT="$VIEW_SEARCH_ALBUM" ;; + "$VIEW_SEARCH_ALBUM") VIEW_NEXT="$VIEW_SEARCH_ARTIST" ;; + "$VIEW_LIST_ARTISTS") VIEW_NEXT="$VIEW_LIST_ALBUMS" ;; + "$VIEW_LIST_ALBUMS") VIEW_NEXT="$VIEW_LIST_ARTISTS" ;; + esac + ;; + esac + case ",$KEYS_SWITCH_LOCAL_REMOTE," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_SEARCH_ARTIST") VIEW_NEXT="$VIEW_LIST_ARTISTS" ;; + "$VIEW_SEARCH_ALBUM") VIEW_NEXT="$VIEW_LIST_ALBUMS" ;; + "$VIEW_LIST_ARTISTS") VIEW_NEXT="$VIEW_SEARCH_ARTIST" ;; + "$VIEW_LIST_ALBUMS") VIEW_NEXT="$VIEW_SEARCH_ALBUM" ;; + esac + ;; + esac + case ",$KEYS_SHOW_PLAYLIST," in + *",$FZF_KEY,"*) + VIEW_NEXT="$VIEW_PLAYLIST" + ACCEPT=1 + ;; + esac + case ",$KEYS_PLAY," in + *",$FZF_KEY,"*) + [ "$path" ] || return 0 + case "$view" in + "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") + foo "not implemented" + ;; + "$VIEW_RELEASEGROUP") + generate_playlist "$mbid" "$path" | mpv_play_list >/dev/null + ;; + "$VIEW_RELEASE") + generate_playlist "$parentmbid" "$path" "$mbid" | mpv_play_list >/dev/null + ;; + "$VIEW_PLAYLIST") + generate_playlist "$parentmbid" "$path" "$mbid" | mpv_play_list >/dev/null + VIEW_NEXT="$VIEW_PLAYLIST" + ACCEPT=1 + ;; + esac + ;; + esac + case ",$KEYS_QUEUE," in + *",$FZF_KEY,"*) + [ "$path" ] || return 0 + case "$view" in + "$VIEW_ARTIST" | "$VIEW_SEARCH_ARTIST" | "$VIEW_SEARCH_ALBUM" | "$VIEW_LIST_ARTISTS" | "$VIEW_LIST_ALBUMS") + foo "not implemented" + ;; + "$VIEW_RELEASEGROUP") + generate_playlist "$mbid" "$path" | mpv_queue_list >/dev/null + ;; + "$VIEW_RELEASE") + generate_playlist "$parentmbid" "$path" "$mbid" | mpv_queue_list >/dev/null + ;; + "$VIEW_PLAYLIST") + generate_playlist "$parentmbid" "$path" "$mbid" | mpv_queue_list >/dev/null + VIEW_NEXT="$VIEW_PLAYLIST" + ACCEPT=1 + ;; + esac + ;; + esac + + # Keys in normal mode only + case ",$KEYS_N_DOWN," in + *",$FZF_KEY,"*) [ "$mode" = "$MODE_NORMAL" ] && printf "down" || printf "put(%s)" "$FZF_KEY" ;; + esac + case ",$KEYS_N_UP," in + *",$FZF_KEY,"*) [ "$mode" = "$MODE_NORMAL" ] && printf "up" || printf "put(%s)" "$FZF_KEY" ;; + esac + case ",$KEYS_N_OUT," in + *",$FZF_KEY,"*) + if [ "$mode" = "$MODE_NORMAL" ]; then + case "$view" in + "$VIEW_ARTIST") + VIEW_NEXT="$VIEW_LIST_ARTISTS" + ;; + "$VIEW_RELEASEGROUP") + VIEW_NEXT="$VIEW_SELECT_ARTIST" + VIEW_NEXT_ARGS="$(mb_releasegroup "$args" | $JQ -r --compact-output '."artist-credit"')" + ACCEPT=1 + ;; + "$VIEW_RELEASE") + VIEW_NEXT="$VIEW_RELEASEGROUP" + VIEW_NEXT_ARGS="$(mb_release "$args" | $JQ -r --compact-output '."release-group".id')" + ;; + "$VIEW_PLAYLIST") + VIEW_NEXT="$VIEW_RELEASE" + VIEW_NEXT_ARGS="$parentmbid" + ACCEPT=1 + ;; + esac + else + printf "put(%s)" "$FZF_KEY" + fi + ;; + esac + case ",$KEYS_N_IN," in + *",$FZF_KEY,"*) + if [ "$mode" = "$MODE_NORMAL" ]; then + [ "$mbid" ] || return 0 + VIEW_NEXT_ARGS="$mbid" + case "$view" in + "$VIEW_LIST_ARTISTS" | "$VIEW_SEARCH_ARTIST") + VIEW_NEXT="$VIEW_ARTIST" + ;; + "$VIEW_ARTIST") + VIEW_NEXT="$VIEW_RELEASEGROUP" + ;; + "$VIEW_RELEASEGROUP" | "$VIEW_LIST_ALBUMS" | "$VIEW_SEARCH_ALBUM") + VIEW_NEXT="$VIEW_RELEASE" + ;; + esac + else + printf "put(%s)" "$FZF_KEY" + fi + ;; + esac + case ",$KEYS_N_BOT," in + *",$FZF_KEY,"*) [ "$mode" = "$MODE_NORMAL" ] && printf "last" || printf "put(%s)" "$FZF_KEY" ;; + esac + case ",$KEYS_N_QUIT," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_SELECT_ARTIST" | "$VIEW_PLAYLIST") + [ "$mode" = "$MODE_NORMAL" ] && printf "accept" || printf "put(%s)" "$FZF_KEY" + ;; + *) + [ "$mode" = "$MODE_NORMAL" ] && printf "abort" || printf "put(%s)" "$FZF_KEY" + ;; + esac + ;; + esac + case ",$KEYS_N_INSERT," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_PLAYLIST") ;; + *) + if [ "$mode" = "$MODE_NORMAL" ]; then + printf "%s#%s" "$view" "$MODE_INSERT" >"$STATEFILE" + foo "Do more here?" + else + printf "put(%s)" "$FZF_KEY" + fi + ;; + esac + ;; + esac + case ",$KEYS_N_TOGGLE_PLAY_PAUSE," in + *",$FZF_KEY,"*) [ "$mode" = "$MODE_NORMAL" ] && mpv_toggle_pause >/dev/null || printf "put(%s)" "$FZF_KEY" ;; + esac + + case ",$KEYS_N_PLAY_NEXT," in + *",$FZF_KEY,"*) + if [ "$mode" = "$MODE_NORMAL" ]; then + mpv_next >/dev/null + [ "$view" = "$VIEW_PLAYLIST" ] && VIEW_NEXT="$VIEW_PLAYLIST" && ACCEPT=1 + else + printf "put(%s)" "$FZF_KEY" + fi + ;; + esac + case ",$KEYS_N_PLAY_PREV," in + *",$FZF_KEY,"*) + if [ "$mode" = "$MODE_NORMAL" ]; then + mpv_prev >/dev/null + [ "$view" = "$VIEW_PLAYLIST" ] && VIEW_NEXT="$VIEW_PLAYLIST" && ACCEPT=1 + else + printf "put(%s)" "$FZF_KEY" + fi + ;; + esac + case ",$KEYS_N_SEEK_FORWARD," in + *",$FZF_KEY,"*) "$mode" = "$MODE_NORMAL" ] && mpv_seek_forward >/dev/null || printf "put(%s)" "$FZF_KEY" ;; + esac + case ",$KEYS_N_SEEK_BACKWARD," in + *",$FZF_KEY,"*) "$mode" = "$MODE_NORMAL" ] && mpv_seek_backward >/dev/null || printf "put(%s)" "$FZF_KEY" ;; + esac + + # Keys in insert mode only + case ",$KEYS_I_NORMAL," in + *",$FZF_KEY,"*) + case "$view" in + "$VIEW_PLAYLIST") ;; + *) + if [ "$mode" = "$MODE_INSERT" ]; then + printf "%s#%s" "$view" "$MODE_NORMAL" >"$STATEFILE" + foo "Do more here?" + else + printf "put(%s)" "$FZF_KEY" + fi + ;; + esac + ;; + esac + + # Post processing + [ "${QUERY:-}" ] && printf "+change-query(%s)" "$QUERY" + if [ "${VIEW_NEXT:-}" ]; then + printf "%s#%s" "$VIEW_NEXT" "$mode" >"$STATEFILE" + printf "%s" "${VIEW_NEXT_ARGS:-}" >"$ARGSFILE" + [ "${ACCEPT:-}" ] && printf "+accept" || printf "+reload:%s" "$0 --fzf-reload" + fi +} diff --git a/src/sh/keys.sh b/src/sh/keys.sh index 282278b..777b973 100644 --- a/src/sh/keys.sh +++ b/src/sh/keys.sh @@ -1,3 +1,7 @@ +KEYS_INPUT='0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,!,",#,$,%,&,\,(,),*,+,,,-,.,/,:,;,<,=,>,?,@,[,\,\,],^,_,`,{,|,},~, ' +KEYS_INPUT="$KEYS_INPUT,'" + +# Normal and insert mode KEYS_HALFPAGE_DOWN="${KEYS_HALFPAGE_DOWN:-"ctrl-d"}" KEYS_HALFPAGE_UP="${KEYS_HALFPAGE_UP:-"ctrl-u"}" KEYS_BROWSE="${KEYS_BROWSE:-"alt-b"}" @@ -11,15 +15,39 @@ KEYS_SWITCH_ARTIST_ALBUM="${KEYS_SWITCH_ARTIST_ALBUM:-"tab"}" KEYS_SWITCH_LOCAL_REMOTE="${KEYS_SWITCH_LOCAL_REMOTE:-"ctrl-/"}" KEYS_PLAY="${KEYS_PLAY:-"enter"}" KEYS_QUEUE="${KEYS_QUEUE:-"ctrl-alt-m"}" -KEYS_TOGGLE_PLAY_PAUSE="${KEYS_TOGGLE_PLAY_PAUSE:-"space"}" -KEYS_PLAY_NEXT="${KEYS_PLAY_NEXT:-"l,right"}" -KEYS_PLAY_PREV="${KEYS_PLAY_PREV:-"h,left"}" -KEYS_SEEK_FORWARD="${KEYS_SEEK_FORWARD:-"L,shift-right"}" -KEYS_SEEK_BACKWARD="${KEYS_SEEK_BACKWARD:-"H,shift-left"}" KEYS_SHOW_PLAYLIST="${KEYS_SHOW_PLAYLIST:-"ctrl-p"}" +# Keys in normal mode only +KEYS_N_DOWN="${KEYS_N_DOWN:-"j"}" +KEYS_N_UP="${KEYS_N_UP:-"k"}" +KEYS_N_OUT="${KEYS_N_OUT:-"h"}" +KEYS_N_IN="${KEYS_N_IN:-"l"}" +KEYS_N_BOT="${KEYS_N_BOT:-"G"}" +KEYS_N_QUIT="${KEYS_N_QUIT:-"q"}" +KEYS_N_INSERT="${KEYS_N_INSERT:-"a,i,/"}" +KEYS_N_TOGGLE_PLAY_PAUSE="${KEYS_N_TOGGLE_PLAY_PAUSE:-"space"}" +KEYS_N_PLAY_NEXT="${KEYS_N_PLAY_NEXT:-"right"}" +KEYS_N_PLAY_PREV="${KEYS_N_PLAY_PREV:-"left"}" +KEYS_N_SEEK_FORWARD="${KEYS_N_SEEK_FORWARD:-"shift-right"}" +KEYS_N_SEEK_BACKWARD="${KEYS_N_SEEK_BACKWARD:-"shift-left"}" + +# Keys in insert mode only +KEYS_I_NORMAL="${KEYS_I_NORMAL:-"esc"}" + +# Grouping +KEYS_GROUP_NI="$KEYS_HALFPAGE_DOWN,$KEYS_HALFPAGE_UP,$KEYS_BROWSE,$KEYS_OUT,$KEYS_IN,$KEYS_SELECT_ARTIST,$KEYS_FILTER_LOCAL,$KEYS_FILTER_PRIMARY,$KEYS_FILTER_SECONDARY,$KEYS_SWITCH_ARTIST_ALBUM,$KEYS_SWITCH_LOCAL_REMOTE,$KEYS_PLAY,$KEYS_QUEUE,$KEYS_SHOW_PLAYLIST" + +KEYS_GROUP_N="$KEYS_N_DOWN,$KEYS_N_UP,$KEYS_N_OUT,$KEYS_N_IN,$KEYS_N_BOT,$KEYS_N_QUIT,$KEYS_N_INSERT,$KEYS_N_TOGGLE_PLAY_PAUSE,$KEYS_N_PLAY_NEXT,$KEYS_N_PLAY_PREV,$KEYS_N_SEEK_FORWARD,$KEYS_N_SEEK_BACKWARD" + +KEYS_GROUP_I="$KEYS_I_NORMAL" + +KEYS_ALL="$KEYS_GROUP_NI,$KEYS_GROUP_N,$KEYS_GROUP_I,$KEYS_INPUT" + export KEYS_HALFPAGE_DOWN KEYS_HALFPAGE_UP KEYS_BROWSE KEYS_OUT KEYS_IN \ KEYS_SELECT_ARTIST KEYS_FILTER_LOCAL KEYS_FILTER_PRIMARY KEYS_FILTER_SECONDARY \ KEYS_SWITCH_ARTIST_ALBUM KEYS_SWITCH_LOCAL_REMOTE KEYS_PLAY KEYS_QUEUE \ - KEYS_TOGGLE_PLAY_PAUSE KEYS_PLAY_NEXT KEYS_PLAY_PREV KEYS_SEEK_FORWARD \ - KEYS_SEEK_BACKWARD KEYS_SHOW_PLAYLIST + KEYS_N_DOWN KEYS_N_UP KEYS_N_OUT KEYS_N_IN KEYS_N_BOT KEYS_N_QUIT KEYS_N_INSERT \ + KEYS_N_TOGGLE_PLAY_PAUSE KEYS_N_PLAY_NEXT KEYS_N_PLAY_PREV KEYS_N_SEEK_FORWARD \ + KEYS_N_SEEK_BACKWARD KEYS_SHOW_PLAYLIST \ + KEYS_I_NORMAL \ + KEYS_GROUP_NI KEYS_GROUP_N KEYS_GROUP_I KEYS_ALL