You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fzmp 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/env bash
  2. declare esc=$(printf '\033')
  3. declare c_reset="${esc}[0m"
  4. declare c_red="${esc}[31m"
  5. isRunning() {
  6. pgrep "$1" &> /dev/null
  7. }
  8. err() {
  9. echo -e "${c_red}$1${c_reset}" >&2
  10. }
  11. die() {
  12. [[ -n "$1" ]] && err "$1"
  13. exit 1
  14. }
  15. has() {
  16. local verbose=false
  17. if [[ $1 == '-v' ]]; then
  18. verbose=true
  19. shift
  20. fi
  21. for c in "$@"; do c="${c%% *}"
  22. if ! command -v "$c" &> /dev/null; then
  23. [[ "$verbose" == true ]] && err "$c not found"
  24. return 1
  25. fi
  26. done
  27. }
  28. fzf() {
  29. command fzf -e --reverse --cycle +s --inline-info "$@"
  30. }
  31. filterAll() {
  32. mpc search -f '[[[%artist% / ][[(%date%) ]%album% / ][%track%] [%title%]]|%file%] \t%file%' filename '' |
  33. fzf -m --with-nth='..-2' --delimiter='\t' |
  34. cut -f2
  35. }
  36. filterByArtist() {
  37. local artist
  38. artist=$(mpc list artist | sort -h | fzf)
  39. [[ -z "$artist" ]] && die
  40. filterByAlbum "$artist"
  41. }
  42. filterByAlbum() {
  43. local album artist
  44. [[ -z "$1" ]] && die
  45. artist="$1"
  46. album=$(mpc search -f '[(%date%)]\t%album%' artist "${artist}" |
  47. sort -u |
  48. fzf --prompt="$artist > " |
  49. cut -f2 )
  50. if [[ -z "$album" ]]; then
  51. filterByArtist
  52. return 0
  53. fi
  54. filterBySong "$artist" "$album"
  55. }
  56. filterBySong() {
  57. local album artist
  58. [[ -z "$1" || -z "$2" ]] && die
  59. artist="$1"
  60. album="$2"
  61. songs=$(mpc search -f '[[[%track% - ][%title%]]|%file%] \t%file%' artist "${artist}" album "${album}" |
  62. fzf --prompt="$artist - $album > " -m --with-nth='..-2' --delimiter='\t' |
  63. cut -f2)
  64. if [[ -z "$songs" ]]; then
  65. filterByAlbum "$artist"
  66. return 0
  67. fi
  68. echo "$songs"
  69. }
  70. filterByPlayist() {
  71. mpc playlist -f '[%artist% / ][[(%date%) ]%album% / ][%title%|%file%] \t%file%' |
  72. fzf --prompt='playlist> ' -m --with-nth='..-2' --delimiter='\t' |
  73. cut -f2
  74. }
  75. has -v fzf mpc || die
  76. isRunning mpd || die 'mpd not running'
  77. declare filter='filterAll'
  78. while true; do
  79. case "$1" in
  80. -a|--artist) filter='filterByArtist' ; shift ;;
  81. -p|--playlist) filter='filterByPlayist' ; shift ;;
  82. *) break
  83. esac
  84. done
  85. mapfile -t songs < <("$filter")
  86. (( ${#songs[@]} > 0 )) || die
  87. printf '%s\n' "${songs[@]}" | mpc -q add
  88. index=$(mpc playlist | wc -l)
  89. if (( ${#songs[@]} > 1 )); then
  90. index=$(( index - ${#songs[@]} + 1))
  91. fi
  92. mpc play "$index"