From e231a7ba98650c70d2a2f912f92916904b20d78e Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sat, 1 Mar 2025 17:59:46 -0500 Subject: [PATCH] fix longstanding bug with skip back. yay --- beetag | 181 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 102 insertions(+), 79 deletions(-) diff --git a/beetag b/beetag index bd9b98b..56ad3b4 100755 --- a/beetag +++ b/beetag @@ -59,7 +59,7 @@ beetag-help() { y other genres z fg player ' = toggle play 1-5 rate ] repeat1 -; previous _ = delete up/down skip mpv vol,pause,seek +; previous _ delete j/k skip mpv_keys vol,pause,seek EOF hr scrolled=10 @@ -312,6 +312,41 @@ beetag-head-playlist() { done } +beetag-advance-maybe() { + if ! $repeat1; then + j=$(( ( j + 1 ) % id_count )) + fi +} + +# Input vars: j, skip_start +# +# Output vars: j, got_track +beetag-track-select() { + local skip_input + local -i new_j + local -r skip_input_regex="^[0-9]+$" + read -r skip_input + got_track=true + if [[ ! $skip_input =~ $skip_input_regex ]]; then + got_track=false + # maybe we changed our mind, so just ignore it. + return + fi + + # example: + # 0 skip_start=5 + # 1 + # * j=7 + # 2 + # 3 + + new_j=$(( skip_start + skip_input )) + if (( new_j >= j )); then + new_j+=1 + fi + j=$new_j +} + # tag with beets. # usage: beetag [-r] [-s] QUERY # it lists the query, reads an input char for tagging one by one. @@ -320,7 +355,7 @@ beetag-head-playlist() { # by immediately jumping forward into the song. this is set in the beets # config yaml. # -# (available buttons: ` \ ) ] [ and non-printing chars, see +# (available buttons: ` ) ] [ and non-printing chars, see # https://stackoverflow.com/questions/10679188/casing-arrow-keys-in-bash # # @@ -347,8 +382,7 @@ beetag() { # constants local escape_char pl_state_path pl_seed_path - local -ar buttons=( {a..p} {r..w} {6..8} , . / - "=") - local -r skip_input_regex="^[0-9]+$" + local -ar buttons=( {a..i} {l..p} {r..w} {6..8} , . / - "=" '\' ) # song list vars: local -a ids ls_lines paths @@ -359,7 +393,7 @@ beetag() { local -a tags # boolean state vars - local expected_input remove first_play=true erasable_line=false + local expected_input remove got_track first_play=true erasable_line=false # iterator vars local ls_line tag @@ -423,6 +457,9 @@ beetag() { if $first_play; then first_play=false; mpvrpc-wait-idle; fi mpvrpc-loadfile "$path" erasable_line=false + if [[ $playlist ]]; then + echo $j >$pl_state_path + fi fi while true; do @@ -438,6 +475,7 @@ beetag() { [[ $(mpvrpco '{ "command": ["get_property", "idle-active"] }' | jq .data) == false ]]; then continue else + beetag-advance-maybe break fi fi @@ -446,11 +484,16 @@ beetag() { fi beetag-help if [[ $char == $'\n' ]]; then + beetag-advance-maybe break fi case $char in ";") - j=$(( j - 2 )) + if (( j == 0 )); then + j=$(( id_count - 1 )) + else + j=$(( j - 1 )) + fi break ;; "'") @@ -468,6 +511,7 @@ beetag() { _) m beet rm --delete --force "id:$id" beetag-nostatus 4 # guessing. dont want to test atm + j=$(( ( j + 1 ) % id_count )) break ;; [1-5]) @@ -501,6 +545,57 @@ beetag() { echo repeat1=$repeat1 continue ;; + j) + # skip forward, but show the last few songs anyways. + skip_start=0 + skip_lookback=3 + if (( j - skip_lookback > skip_start )); then + skip_start=$(( j - skip_lookback )) + fi + beetag-nostatus $(( id_count - skip_start - 1 )) + + line_int=0 + overflow_lines=$LINES + for (( i=skip_start; i < overflow_lines - 1 && i < id_count; i++ )); do + ls_line="${ls_lines[i]}" + overflow=$(( ${#ls_line} / ( COLUMNS - 1 ) )) + overflow_lines=$(( overflow_lines - overflow )) + if (( i == j )); then + echo " * $ls_line" + continue + fi + echo "$line_int | $ls_line" + line_int+=1 + done + beetag-track-select + if $got_track; then + break + else + continue + fi + ;; + k) + # skip back. show all the songs, use less + skip_start=0 + beetag-nostatus $(( id_count - skip_start - 1 )) + { + line_int=0 + for (( i=skip_start; i < id_count; i++ )); do + if (( i == j )); then + echo " * ${ls_lines[i]}" + continue + fi + echo "$line_int | ${ls_lines[i]}" + line_int+=1 + done + } | less -F + beetag-track-select + if $got_track; then + break + else + continue + fi + ;; q) kill-bg-quiet return @@ -545,52 +640,7 @@ beetag() { expected_input=true read -rsn2 escaped_input case $escaped_input in - # up char: show all the songs, use less - '[A') - skip_start=0 - skip_lookback=5 - if (( j - skip_lookback > skip_start )); then - skip_start=$(( j - skip_lookback )) - fi - beetag-nostatus $(( id_count - skip_start - 1 )) - { - line_int=0 - for (( i=skip_start; i < id_count; i++ )); do - if (( i == j )); then - echo " * ${ls_lines[i]}" - continue - fi - echo "$line_int | ${ls_lines[i]}" - line_int+=1 - done - } | less -F - ;; - # down char - '[B') - echo ok >>/tmp/x - - # skip forward, but show the last few songs anyways. - skip_start=0 - skip_lookback=3 - if (( j - skip_lookback > skip_start )); then - skip_start=$(( j - skip_lookback )) - fi - beetag-nostatus $(( id_count - skip_start - 1 )) - - line_int=0 - overflow_lines=$LINES - for (( i=skip_start; i < overflow_lines - 1 && i < id_count; i++ )); do - ls_line="${ls_lines[i]}" - overflow=$(( ${#ls_line} / ( COLUMNS - 1 ) )) - overflow_lines=$(( overflow_lines - overflow )) - if (( i == j )); then - echo " * $ls_line" - continue - fi - echo "$line_int | $ls_line" - line_int+=1 - done - ;; + # it was buggy to differentiate between up and down, '[A' and '[B' # left key '[D') seek_sec=-8 @@ -610,23 +660,6 @@ beetag() { expected_input=false ;; esac - if $expected_input; then - read -r skip_input - case $skip_input in - q) - kill-bg-quiet - return - ;; - esac - if [[ $skip_input =~ $skip_input_regex ]]; then - pre_j_count=$(( j - skip_start )) - j=$(( j + skip_input - pre_j_count )) - if (( skip_input < pre_j_count )); then - j=$(( j - 1 )) - fi - fi - break - fi ;; esac char_i=${button_i[$char]} @@ -653,15 +686,5 @@ beetag() { fi fi done - if ! $repeat1; then - if (( j < id_count - 1 )); then - j+=1 - else - j=0 - fi - fi - if [[ $playlist ]]; then - echo $j >$pl_state_path - fi done } -- 2.30.2