Browse Source

fzmp: better config parsing

DanielFGray 2 years ago
parent
commit
acbdca658b
1 changed files with 63 additions and 34 deletions
  1. 63
    34
      fzmp

+ 63
- 34
fzmp View File

@@ -4,8 +4,10 @@ declare -r esc=$'\033'
4 4
 declare -r c_reset="${esc}[0m"
5 5
 declare -r c_red="${esc}[31m"
6 6
 declare -r config_file="${XDG_CONFIG_DIR:-$HOME/.config}/fzmp/conf"
7
+declare verbose
7 8
 declare default_filter='filter_all_songs'
8 9
 declare track_format='[[[%artist% / ][[(%date%) ]%album% / ][[%track% - ][%title%]]]|%file%]'
10
+declare -a config_err
9 11
 
10 12
 usage() {
11 13
   LESS=-FEXR less <<'HELP'
@@ -19,18 +21,19 @@ fzmp [OPTIONS]
19 21
                    >   go to the next song in the playlist
20 22
                    <   go to the previous song in the playlist
21 23
                    C-d delete the selected songs from the playlist
24
+    -v --verbose   print errors when parsing the config file
22 25
     -h --help      print this help
23 26
 
24 27
   CONFIGURATION:
25
-    a configuration file can be defined at $XDG_CONFIG_DIR (defaults to ~/.config)
26
-    configuration options must be defined in the format of key=value
27
-    the configuration file reads the following variables:
28
+    A configuration file can be defined at $XDG_CONFIG_DIR (defaults to ~/.config)
29
+    If a line begins with '#' it is treated as a comment and ignored
30
+    The configuration file reads the following options:
28 31
 
29
-    default_view=      must be 'artists' 'songs' or 'playlist'
30
-    full_song_format=  a format string to be passed directly to `mpc format -f` in 'playlist' and 'all' views
32
+    default_view       must be 'artists' 'songs' or 'playlist'
33
+    full_song_format   a format string to be passed directly to `mpc format -f` in 'playlist' and 'all' views
31 34
                        defaults to '[[[%artist% / ][[(%date%) ]%album% / ][[%track% - ][%title%]]]|%file%]'
32 35
                        for colorized output try: '[[[\e\[32m%artist%\e\[0m / ][\e\[31m[(%date%) ]%album%\e\[0m / ][\e\[34m[%track% - ][%title%]\e\[0m]]|%file%]'
33
-    fzf_options=       command line options to be passed directly to fzf
36
+    fzf_options        command line options to be passed directly to fzf
34 37
                        changing this will override the default options: '+s -e -i --reverse --cycle'
35 38
                        to use the jump feature of fzf you can try '+s -e -i --reverse --cycle --bind=`:jump'
36 39
                        this can also be overridden with the environment variable FZMP_FZF_OPTIONS
@@ -69,15 +72,33 @@ fzf() {
69 72
 }
70 73
 
71 74
 parse_config_file() {
72
-  local default_view full_song_format fzf_options
73
-  source "$config_file"
74
-  [[ -v default_view ]] && case "$default_view" in
75
-    playlist) default_filter='filter_playlist' ;;
76
-    songs) default_filter='filter_all_songs' ;;
77
-    artists) default_filter='filter_by_artist' ;;
78
-  esac
79
-  [[ -v full_song_format ]] && track_format="$full_song_format"
80
-  [[ ! -v FZMP_FZF_OPTIONS && -v fzf_options ]] && FZMP_FZF_OPTIONS="$fzf_options"
75
+  local line key val nr=0
76
+  while IFS= read -r line; do
77
+    (( ++nr ))
78
+    [[ -z "$line" || "$line" = '#'* ]] && continue
79
+    read -r key <<< "${line%% *}"
80
+    read -r val <<< "${line#* }"
81
+    if [[ -z "$val" ]]; then
82
+      config_err+=( "missing value for \"$key\" in config file on line $nr" )
83
+      continue
84
+    fi
85
+    case "$key" in
86
+      full_song_format) track_format="$val" ;;
87
+      fzf_options) [[ ! -v FZMP_FZF_OPTIONS ]] && FZMP_FZF_OPTIONS="$val" ;;
88
+      default_view)
89
+        if [[ "$val" =~ playlist|songs|artists ]]; then
90
+          case "$val" in
91
+            playlist) default_filter='filter_by_playlist' ;;
92
+            songs) default_filter='filter_all_songs' ;;
93
+            artists) default_filter='filter_by_artist' ;;
94
+          esac
95
+        else
96
+          config_err+=( "unknown format \"$val\" in config file on line $nr" )
97
+        fi
98
+        ;;
99
+      *) config_err+=( "unknown key \"$key\" in config file on line $nr" )
100
+    esac
101
+  done
81 102
 }
82 103
 
83 104
 filter_all_songs() {
@@ -90,7 +111,7 @@ filter_all_songs() {
90 111
     cut -f1)
91 112
   case "${choice[0]}" in
92 113
     'f2') filter_by_artist ;;
93
-    'f3') filter_playlist ;;
114
+    'f3') filter_by_playlist ;;
94 115
     'enter') printf '%s\n' "${choice[@]:1}" | play_songs ;;
95 116
   esac
96 117
 }
@@ -102,11 +123,11 @@ filter_by_artist() {
102 123
     fzf \
103 124
       --preview='mpc list album artist {}' \
104 125
       --expect='f1,f3,enter')
105
-  (( "${#choice[@]}" > 0 )) || die
126
+  (( ${#choice[@]} > 0 )) || die
106 127
   case "${choice[0]}" in
107
-    'f1') filter_all_songs ;;
108
-    'f3') filter_playlist ;;
109
-    'enter') filter_by_album_from_artist "${choice[1]}" ;;
128
+    f1) filter_all_songs ;;
129
+    f3) filter_by_playlist ;;
130
+    enter) filter_by_album_from_artist "${choice[1]}" ;;
110 131
   esac
111 132
 }
112 133
 
@@ -123,7 +144,7 @@ filter_by_album_from_artist() {
123 144
       cut -f2)
124 145
   case "${choice[0]}" in
125 146
     'f1') filter_all_songs ;;
126
-    'f3') filter_playlist ;;
147
+    'f3') filter_by_playlist ;;
127 148
     'enter') filter_songs_from_album "$artist" "${choice[1]}" ;;
128 149
     *) filter_by_artist ;;
129 150
   esac
@@ -144,14 +165,14 @@ filter_songs_from_album() {
144 165
     cut -f1)
145 166
   case "${choice[0]}" in
146 167
     'f1') filter_all_songs ;;
147
-    'f3') filter_playlist ;;
168
+    'f3') filter_by_playlist ;;
148 169
     'enter') printf '%s\n' "${choice[@]:1}" | play_songs ;;
149 170
     *) filter_by_album_from_artist "$artist" ;;
150 171
   esac
151 172
 }
152 173
 
153
-filter_playlist() {
154
-  local choice 
174
+filter_by_playlist() {
175
+  local choice
155 176
   current_song=$(mpc current -f "$track_format")
156 177
   mapfile -t choice < <(mpc playlist -f "%position%\t$track_format" |
157 178
     fzf --prompt='playlist > ' \
@@ -164,10 +185,10 @@ filter_playlist() {
164 185
   case "${choice[0]}" in
165 186
     'f1') filter_all_songs ;;
166 187
     'f2') filter_by_artist ;;
167
-    '>') mpc -q next ; filter_playlist ;;
168
-    '<') mpc -q prev ; filter_playlist ;;
169
-    'ctrl-d') [[ -n "${choice[1]}" ]] && mpc -q del "${choice[@]:1}" ; filter_playlist ;;
170
-    'enter') [[ -n "${choice[1]}" ]] && mpc -q play "${choice[@]:1}" ; filter_playlist ;;
188
+    '>') mpc -q next; filter_by_playlist ;;
189
+    '<') mpc -q prev; filter_by_playlist ;;
190
+    'ctrl-d') [[ -n "${choice[1]}" ]] && mpc -q del "${choice[@]:1}"; filter_by_playlist ;;
191
+    'enter') [[ -n "${choice[1]}" ]] && mpc -q play "${choice[@]:1}"; filter_by_playlist ;;
171 192
   esac
172 193
 }
173 194
 
@@ -179,17 +200,25 @@ play_songs() {
179 200
   (( ${#songs[@]} > 1 )) &&
180 201
     index=$(( index - ${#songs[@]} + 1))
181 202
   mpc -q play "$index"
182
-  filter_playlist
203
+  filter_by_playlist
183 204
 }
184 205
 
185
-[[ -s "$config_file" ]] && parse_config_file
206
+[[ -s "$config_file" ]] && parse_config_file < "$config_file"
207
+
208
+if (( verbose > 0 && ${#config_err[@]} > 0 )); then
209
+  err 'there were errors parsing config file:'
210
+  for e in "${config_err[@]}"; do
211
+    err "$e"
212
+  done
213
+fi
186 214
 
187 215
 while :; do
188 216
   case "$1" in
189
-    -A|--all) default_filter='filter_all_songs' ; shift ;;
190
-    -a|--artist) default_filter='filter_by_artist' ; shift ;;
191
-    -p|--playlist) default_filter='filter_playlist' ; shift ;;
192
-    -h|--help) usage ; exit ;;
217
+    -A|--all) default_filter='filter_all_songs'; shift ;;
218
+    -a|--artist) default_filter='filter_by_artist'; shift ;;
219
+    -p|--playlist) default_filter='filter_by_playlist'; shift ;;
220
+    -h|--help) usage; exit ;;
221
+    -v|--verbose) (( verbose++ )); shift ;;
193 222
     *) break
194 223
   esac
195 224
 done

Loading…
Cancel
Save