# ret next
beetag() {
local last_genre_i fstring tag id char new_item char_i genre tag remove doplay i j random
- local do_rare_genres read_wait help line lsout tmp ls_line
+ local do_rare_genres read_wait help line lsout tmp ls_line skip_lookback
local escape_char escaped_input expected_input skip_input_regex
local -a pl_tags buttons button_map ids tags rare_genres tmp_tags initial_ls ls_lines
local -A button_i
- local -i i j volume scrolled id_count line_int skip_start pre_j_count head_count
+ local -i i j volume scrolled id_count line_int skip_start pre_j_count head_count skip_lookback
+ local -i overflow_lines overflow
escape_char=$(printf "\u1b")
# for reusing later, so we can pickup where we left off in a playlist.
# shellcheck disable=SC2016 # obvious reason
- mapfile -t initial_ls < <(beet ls -f '$id %ifdef{rating,$rating }'"$fstring"'$genre | $artist - $album - $title $length' "$@" | { if $random; then sort -R; else cat; fi; } )
+ mapfile -t initial_ls < <(beet ls -f '%ifdef{rating,$rating }'"$fstring"'$genre | $artist - $album - $title $length $id' "$@" | { if $random; then sort -R; else cat; fi; } )
j=0
# i only care to see the head of the list.
- head_count=$(( LINES - 14 ))
+ head_count=$(( LINES - 20 ))
for line in "${initial_ls[@]}"; do
- id="${line%% *}"
+ id="${line##* }"
ids+=("$id")
- ls_line="${line#* }"
- ls_line="$ls_line $id"
+ right_pad="${line%% |*}"
+ ls_line="$(printf %-11s "$right_pad")${line#$right_pad}"
ls_lines+=("$ls_line")
if (( j < head_count )); then
echo "$ls_line"
expected_input=true
read -rsn2 escaped_input
skip_input_regex="^[0-9]+$"
- skip_back=false
case $escaped_input in
'[D')
- # skip backward
- if (( j == 0 )); then
- echo "no earlier songs"
- continue
- fi
- skip_back=true
- {
- line_int=0
- for (( i=j-1; i >= 0; i-- )); do
- echo "$line_int | ${ls_lines[i]}"
- line_int+=1
- done
- } | less -F
- scrolled+=$j
- ;;
- '[C')
- # skip forward, but show the last few songs anyways.
+ skip_lookback=5
skip_start=0
- if (( j - 3 > skip_start )); then
- skip_start=$(( j - 3 ))
+ if (( j - skip_lookback > skip_start )); then
+ skip_start=$(( j - skip_lookback ))
fi
{
line_int=0
} | less -F
scrolled+=$(( id_count - skip_start - 1 ))
;;
+ '[C')
+ # 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
+ line_int=0
+ overflow_lines=$LINES
+ for (( i=skip_start; i < overflow_lines - 1; 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
+ scrolled+=$(( id_count - skip_start - 1 ))
+ ;;
*)
expected_input=false
;;
esac
if $expected_input; then
read -r skip_input
+ case skip_input in
+ q)
+ kill %%; wait %% 2>/dev/null ||:
+ return
+ ;;
+ esac
if [[ $skip_input =~ $skip_input_regex ]]; then
- if $skip_back; then
- j=$(( j - skip_input - 2 ))
- else
- pre_j_count=$(( j - skip_start ))
- j=$(( j + skip_input - pre_j_count ))
- if (( skip_input < pre_j_count )); then
- j=$(( j - 1 ))
- fi
+ pre_j_count=$(( j - skip_start ))
+ j=$(( j + skip_input - pre_j_count ))
+ if (( skip_input < pre_j_count )); then
+ j=$(( j - 1 ))
fi
- kill %%; wait %% 2>/dev/null ||:
- break
fi
+ kill %%; wait %% 2>/dev/null ||:
+ break
fi
;;
esac