Browse Source

updated fzmp

DanielFGray 1 year ago
parent
commit
38d6cabae1
1 changed files with 91 additions and 80 deletions
  1. 91
    80
      fzmp

+ 91
- 80
fzmp View File

@@ -9,6 +9,7 @@ OPTIONS:
9 9
     search all songs in the library (or F1 when running)
10 10
   -a --artist
11 11
     search artist then filter by album (or F2 when running)
12
+    
12 13
   -p --playlist
13 14
     search the current playlist (or F3 when running)
14 15
     playlist view has the following keybinds:
@@ -59,11 +60,40 @@ declare track_format='[[[%artist% / ][[(%date%) ]%album% / ][[%track% - ][%title
59 60
 declare -r album_listing="mpc search -f '%album%\t%title%' artist {} | awk -F'\t' '{ if(album != \$1) { album=\$1; print album } printf \"  %s\n\", \$2 }'"
60 61
 declare -a config_err
61 62
 
62
-declare playlist_view_key='f1'
63
-declare track_view_key='f2'
64
-declare artist_view_key='f3'
65
-declare genre_view_key='f4'
66
-declare findadd_key='ctrl-x'
63
+declare key_bindings
64
+declare -A bindings
65
+bindings=(
66
+  [playlist]='f1'
67
+  [track]='f2'
68
+  [artist]='f3'
69
+  [genre]='f4'
70
+  [findadd]='ctrl-x'
71
+)
72
+
73
+do_binding() {
74
+  local b
75
+  b=$(action_from_keybind "$1")
76
+  shift
77
+  echo "$b"
78
+  case "$b" in
79
+    playlist) filter_by_playlist ;;
80
+    track) filter_by_songs ;;
81
+    artist) filter_by_artists ;;
82
+    genre) filter_by_genres ;;
83
+    *) [[ -n $1 ]] && { "$@"; return 0; } ;;
84
+  esac
85
+  return 1
86
+}
87
+
88
+action_from_keybind() {
89
+  for a in "${!bindings[@]}"; do
90
+    if [[ $1 == "${bindings[$a]}" ]]; then
91
+      printf "$a"
92
+      return 0
93
+    fi
94
+  done
95
+  return 1
96
+}
67 97
 
68 98
 declare -A colors
69 99
 colors[red]=$(tput setaf 1)
@@ -71,10 +101,6 @@ colors[green]=$(tput setaf 2)
71 101
 colors[blue]=$(tput setaf 4)
72 102
 colors[reset]=$(tput sgr0)
73 103
 
74
-is_running() {
75
-  pgrep "$1" &> /dev/null
76
-}
77
-
78 104
 info() {
79 105
   color green "$@" >&2
80 106
 }
@@ -111,8 +137,15 @@ has() {
111 137
   done
112 138
 }
113 139
 
140
+is_running() {
141
+  pgrep "$1" &> /dev/null
142
+}
143
+
114 144
 fzf() {
115
-  command fzf ${FZMP_FZF_OPTIONS:-+s -e -i --reverse --cycle} \
145
+  local opts
146
+  opts=( +s -e -i --reverse --cycle )
147
+  [[ -v FZMP_FZF_OPTIONS ]] && opts=( $FZMP_FZF_OPTIONS )
148
+  command fzf "${opts[@]}" \
116 149
     --inline-info \
117 150
     --ansi \
118 151
     --no-clear \
@@ -132,26 +165,24 @@ parse_config_file() {
132 165
     fi
133 166
     case "$key" in
134 167
       full_song_format) track_format="$val" ;;
135
-      fzf_options) [[ ! -v FZMP_FZF_OPTIONS ]] && FZMP_FZF_OPTIONS="$val" ;;
168
+      fzf_options) [[ -z FZMP_FZF_OPTIONS ]] && FZMP_FZF_OPTIONS="$val" ;;
136 169
       default_view)
137 170
         if [[ "$val" =~ ^playlist$|^songs$|^artists$|^genres$ ]]; then
138
-          case "$val" in
139
-            playlist) default_filter='filter_by_playlist' ;;
140
-            songs) default_filter='filter_all_songs' ;;
141
-            artists) default_filter='filter_by_artist' ;;
142
-            genres) default_filter='filter_by_genre' ;;
143
-          esac
171
+          default_filter="filter_by_$val"
144 172
         else
145 173
           config_err+=( "unknown format \"$val\" in config file on line $nr" )
174
+          config_err+=( "default_view must be 'playlist' 'songs' 'artists' or 'genres'" )
146 175
         fi ;;
147
-      playlist_view_key) playlist_view_key="$val" ;;
148
-      artist_view_key) artist_view_key="$val" ;;
149
-      track_view_key) track_view_key="$val" ;;
150
-      genre_view_key) genre_view_key="$val" ;;
151
-      findadd_key) findadd_key="$val" ;;
176
+      playlist_view_key) bindings[playlist]="$val" ;;
177
+      artist_view_key) bindings[artist]="$val" ;;
178
+      track_view_key) bindings[track]="$val" ;;
179
+      genre_view_key) bindings[genre]="$val" ;;
180
+      findadd_key) bindings[findadd]="$val" ;;
152 181
       *) config_err+=( "unknown key \"$key\" in config file on line $nr" )
153 182
     esac
154
-  done
183
+  done < "$config_file"
184
+  IFS=',' key_bindings="${bindings[*]}"
185
+  findadd_key="${bindings[findadd]}"
155 186
   if (( ${#config_err[@]} > 0 )); then
156 187
     err 'there were errors parsing config file:'
157 188
     for e in "${config_err[@]}"; do
@@ -160,99 +191,82 @@ parse_config_file() {
160 191
   fi
161 192
 }
162 193
 
163
-filter_all_songs() {
194
+filter_by_songs() {
164 195
   local choice
165 196
   mapfile -t choice < <(mpc search -f "%file%\t$track_format" filename '' |
166 197
     fzf --prompt='songs > ' \
167 198
       --multi \
168 199
       --with-nth='2..' \
169 200
       --delimiter='\t' \
170
-      --expect='f1,f2,f3,f4,enter' |
201
+      --expect="${key_bindings},enter" |
171 202
     cut -f1)
172 203
   case "${choice[0]}" in
173
-    "$playlist_view_key") filter_by_playlist ;;
174
-    "$artist_view_key") filter_by_artist ;;
175
-    "$track_view_key") filter_all_songs ;;
176
-    "$genre_view_key") filter_by_genre ;;
177 204
     'enter') printf '%s\n' "${choice[@]:1}" | add_songs play ;;
205
+    *) do_binding "${choice[0]}" || exit
178 206
   esac
179 207
 }
180 208
 
181
-filter_by_genre() {
209
+filter_by_genres() {
182 210
   local choice
183
-  mapfile -t choice < <(mpc search -f '%genre%' genre '' | awk 'NF' | sort | uniq -ic | sort -rn |
211
+  mapfile -t choice < <(mpc search -f '%genre%' genre '' |
212
+    awk 'NF' | sort | uniq -ic | sort -rn |
184 213
     fzf --prompt='genres > ' \
185 214
       --preview='mpc search -f "%artist%" genre {2..} | sort -u' \
186
-      --bind="$findadd_key:execute:mpc findadd genre {2..}" \
187
-      --expect='f1,f2,f3,f4,enter' | sed -r 's/^\s*[0-9]+\s*//')
215
+      --bind="$findadd_key:execute-silent:mpc findadd genre {2..}" \
216
+      --expect="${key_bindings},enter" |
217
+    sed -r 's/^\s*[0-9]+\s*//')
188 218
   (( ${#choice[@]} > 0 )) || die
189 219
   case "${choice[0]}" in
190
-    "$playlist_view_key") filter_by_playlist ;;
191
-    "$artist_view_key") filter_by_artist ;;
192
-    "$track_view_key") filter_all_songs ;;
193
-    "$genre_view_key") filter_by_genre ;;
194 220
     enter) filter_by_artist_from_genre "${choice[1]}" ;;
195
-    *) $default_filter ;;
221
+    *) do_binding "${choice[0]}" || exit ;;
196 222
   esac
197 223
 }
198 224
 
199 225
 filter_by_artist_from_genre() {
200 226
   local artist genre choice
201 227
   genre="$1"
202
-  mapfile -t choice < <(mpc search -f '%artist%' genre "$genre" | sort -u |
203
-    awk 'NF' | sort -u |
228
+  mapfile -t choice < <(mpc search -f '%artist%' genre "$genre" |
229
+    sort -u | awk 'NF' | sort -u |
204 230
     fzf --prompt="$genre > " \
205 231
       --preview="$album_listing" \
206
-      --expect='f1,f2,f3,f4,enter' \
207
-      --bind="$findadd_key:execute:mpc findadd artist {}")
208
-  (( ${#choice[@]} > 0 )) || filter_by_genre
232
+      --expect="${key_bindings},enter" \
233
+      --bind="$findadd_key:execute-silent:mpc findadd artist {}")
234
+  (( ${#choice[@]} > 0 )) || filter_by_genres
209 235
   case "${choice[0]}" in
210
-    "$playlist_view_key") filter_by_playlist ;;
211
-    "$artist_view_key") filter_by_artist ;;
212
-    "$track_view_key") filter_all_songs ;;
213
-    "$genre_view_key") filter_by_genre ;;
214 236
     enter) filter_by_album_from_artist "${choice[1]}" ;;
215
-    *) "$filter_by_genre" ;;
237
+    *) do_binding "${choice[0]}" || "$filter_by_genres" ;;
216 238
   esac
217 239
 }
218 240
 
219
-filter_by_artist() {
241
+filter_by_artists() {
220 242
   local choice
221 243
   mapfile -t choice < <(mpc list artist |
222 244
     fzf --prompt='artists > ' \
223 245
       --preview="$album_listing" \
224
-      --bind="$findadd_key:execute:mpc findadd artist {}" \
225
-      --expect='f1,f2,f3,f4,enter')
246
+      --bind="$findadd_key:execute-silent:mpc findadd artist {}" \
247
+      --expect="${key_bindings},enter")
226 248
   (( ${#choice[@]} > 0 )) || die
227 249
   case "${choice[0]}" in
228
-    "$playlist_view_key") filter_by_playlist ;;
229
-    "$artist_view_key") filter_by_artist ;;
230
-    "$track_view_key") filter_all_songs ;;
231
-    "$genre_view_key") filter_by_genre ;;
232 250
     'enter') filter_by_album_from_artist "${choice[1]}" ;;
233
-    *) $default_filter ;;
251
+    *) do_binding "${choice[0]}" || "$default_filter" ;;
234 252
   esac
235 253
 }
236 254
 
237 255
 filter_by_album_from_artist() {
238 256
   local album artist choice
239
-  [[ -z "$1" ]] && filter_by_artist
257
+  [[ -z "$1" ]] && filter_by_artists
240 258
   artist="$1"
241 259
   mapfile -t choice < <(mpc search -f '[(%date%)]\t[%album%]' artist "$artist" |
242 260
     sort -h | uniq |
243 261
     fzf --prompt="$artist > " \
244 262
       --preview="mpc search -f '[[[%track% - ][%title%]]|%file%]' artist '$artist' album {2}" \
245
-      --expect="f1,f2,f3,f4,enter,$findadd_key" \
263
+      --expect="${key_bindings},enter" \
264
+      --bind="$findadd_key:execute-silent:mpc findadd album {2..}" \
246 265
       --delimiter='\t' |
247 266
       cut -f2)
248 267
   case "${choice[0]}" in
249
-    "$playlist_view_key") filter_by_playlist ;;
250
-    "$artist_view_key") filter_by_artist ;;
251
-    "$track_view_key") filter_all_songs ;;
252
-    "$genre_view_key") filter_by_genre ;;
253 268
     'enter') filter_songs_from_album "$artist" "${choice[1]}" ;;
254
-    "$findadd_key") mpc findadd album "${choice[1]}"; filter_by_album_from_artist "$artist" ;;
255
-    *) filter_by_artist ;;
269
+    *) do_binding "${choice[0]}" || filter_by_artists ;;
256 270
   esac
257 271
 }
258 272
 
@@ -269,13 +283,8 @@ filter_songs_from_album() {
269 283
       --expect='f1,f2,f3,enter' |
270 284
     cut -f1)
271 285
   case "${choice[0]}" in
272
-    "$playlist_view_key") filter_by_playlist ;;
273
-    "$artist_view_key") filter_by_artist ;;
274
-    "$track_view_key") filter_all_songs ;;
275
-    "$genre_view_key") filter_by_genre ;;
276
-    'enter') filter_songs_from_album "$artist" "${choice[1]}" ;;
277 286
     'enter') printf '%s\n' "${choice[@]:1}" | add_songs play ;;
278
-    *) filter_by_album_from_artist "$artist" ;;
287
+    *) do_binding "${choice[0]}" || filter_by_album_from_artist "$artist" ;;
279 288
   esac
280 289
 }
281 290
 
@@ -288,18 +297,15 @@ filter_by_playlist() {
288 297
       ${current_song:+--header="now playing: ${current_song}"} \
289 298
       --delimiter='\t' \
290 299
       --with-nth='2..' \
291
-      --expect='f1,f2,f3,f4,>,<,ctrl-d,enter,ctrl-z' |
300
+      --expect="${key_bindings},>,<,ctrl-d,enter,ctrl-z" |
292 301
     cut -f1) || die
293 302
   case "${choice[0]}" in
294
-    "$playlist_view_key") filter_by_playlist ;;
295
-    "$artist_view_key") filter_by_artist ;;
296
-    "$track_view_key") filter_all_songs ;;
297
-    "$genre_view_key") filter_by_genre ;;
298 303
     '>') mpc -q next; filter_by_playlist ;;
299 304
     '<') mpc -q prev; filter_by_playlist ;;
300 305
     'ctrl-d') [[ -n "${choice[1]}" ]] && mpc -q del "${choice[@]:1}"& filter_by_playlist ;;
301 306
     'enter') [[ -n "${choice[1]}" ]] && mpc -q play "${choice[@]:1}"& filter_by_playlist ;;
302
-    'ctrl-z') mpc clear; filter_by_artist  ;;
307
+    'ctrl-z') mpc clear; filter_by_artists  ;;
308
+    *) do_binding "${choice[0]}" || exit ;;
303 309
   esac
304 310
 }
305 311
 
@@ -315,14 +321,14 @@ add_songs() {
315 321
   filter_by_playlist
316 322
 }
317 323
 
318
-[[ -s "$config_file" ]] && parse_config_file < "$config_file"
324
+[[ -s "$config_file" ]] && parse_config_file
319 325
 
320 326
 while :; do
321 327
   case "$1" in
322
-    -A|--all) default_filter='filter_all_songs'; shift ;;
323
-    -a|--artist) default_filter='filter_by_artist'; shift ;;
328
+    -A|--all) default_filter='filter_by_songs'; shift ;;
329
+    -a|--artist) default_filter='filter_by_artists'; shift ;;
324 330
     -p|--playlist) default_filter='filter_by_playlist'; shift ;;
325
-    -g|--genre) default_filter='filter_by_genre'; shift ;;
331
+    -g|--genre) default_filter='filter_by_genres'; shift ;;
326 332
     -h|--help) usage; exit ;;
327 333
     *) break
328 334
   esac
@@ -331,4 +337,9 @@ done
331 337
 has -v fzf mpc || die
332 338
 is_running mpd || [[ -v MPD_HOST ]] || die "can't connect to mpd"
333 339
 
340
+finish() {
341
+  tput rmcup
342
+}
343
+
344
+trap finish EXIT SIGINT SIGTERM
334 345
 $default_filter

Loading…
Cancel
Save