1
1
-- https://github.com/erento/lua-schema-validation
2
2
local log = hs .logger .new (' sline.conf' )
3
3
log .setLogLevel (' info' )
4
- log .i (" Loading module" )
4
+ log .i (' Loading module' )
5
5
6
6
local M = {}
7
7
@@ -15,8 +15,8 @@ local is_color = v.is_table { -- {{{
15
15
blue = o (v .is_number ()),
16
16
alpha = o (v .is_number ()),
17
17
} -- }}}
18
- local function unknownTypeValidator (v ) -- {{{
19
- log .i (" Not validating: " , schemaType )
18
+ local function unknownTypeValidator (val ) -- {{{
19
+ log .i (' Not validating: ' , val )
20
20
return true
21
21
end -- }}}
22
22
@@ -51,7 +51,7 @@ M.types = { -- {{{
51
51
},
52
52
} -- }}}
53
53
54
- local defaultOnChangeEvt = { -- {{{
54
+ local defaultOnChangeEvt = { -- {{{
55
55
__index = function () stackline .queryWindowState :start () end
56
56
} -- }}}
57
57
@@ -67,7 +67,7 @@ M.events = setmetatable({ -- {{{
67
67
dynamicLuminosity = nil ,
68
68
},
69
69
advanced = {
70
- maxRefreshRate = function () print (' Needs implemented' ) end ,
70
+ maxRefreshRate = function () print (' Needs implemented' ) end ,
71
71
},
72
72
}, defaultOnChangeEvt ) -- }}}
73
73
@@ -108,39 +108,30 @@ M.schema = { -- {{{
108
108
109
109
function M :getPathSchema (path ) -- {{{
110
110
local _type = u .getfield (path , self .schema ) -- lookup type in schema
111
- if not _type then
112
- return false
113
- end
111
+ if not _type then return false end
114
112
local validator = self .types [_type ].validator ()
113
+
115
114
return _type , validator
116
115
end -- }}}
117
116
118
117
function M .generateValidator (schemaType ) -- {{{
119
- if type (schemaType ) == ' table' then
118
+ if type (schemaType )== ' table' then -- recursively build validator
120
119
local children = u .map (schemaType , M .generateValidator )
121
120
log .d (' validator children:\n ' , hs .inspect (children ))
122
121
return v .is_table (children )
123
- else
124
- log .i (' schemaType:' , schemaType )
125
- return
126
- M .types [schemaType ] and M .types [schemaType ].validator () -- returns a fn to be called with value to validate
127
- or unknownTypeValidator -- unknown types are assumed-valid
128
122
end
123
+
124
+ -- otherwise, return validation fn forgiven type
125
+ log .i (' schemaType:' , schemaType )
126
+ return M .types [schemaType ] -- if schemaType is a known config type..
127
+ and M .types [schemaType ].validator () -- then return validation fn
128
+ or unknownTypeValidator -- otherwise, unknown types are assumed valid
129
129
end -- }}}
130
130
131
131
-- Config manager
132
132
function M :init (conf ) -- {{{
133
133
log .i (' Initializing configmanager…' )
134
134
self :validate (conf )
135
- ipcConfigPort = hs .ipc .localPort (' stackline-config' ,
136
- function (_ , msgID , msg )
137
- if msgID == 900 then
138
- return " version:2.0a" -- if this is not returned, *ipc msgs will NOT work*
139
- elseif msgID == 500 then
140
- self :handleMsg (msg )
141
- end
142
- end )
143
-
144
135
self .__index = self
145
136
return self
146
137
end -- }}}
@@ -155,18 +146,17 @@ function M:validate(conf) -- {{{
155
146
self .conf = conf
156
147
self .autosuggestions = u .keys (u .flatten (self .conf ))
157
148
else
158
- local invalidKeys = table.concat (u .keys (u .flatten (err )), " , " )
149
+ local invalidKeys = table.concat (u .keys (u .flatten (err )), ' , ' )
150
+ log .e (' Invalid stackline config:\n ' , hs .inspect (err ))
159
151
hs .notify .new (nil , {
160
152
title = ' Invalid stackline config!' ,
161
- subTitle = ' invalid keys:' .. invalidKeys ,
153
+ subTitle = ' invalid keys:' .. invalidKeys ,
162
154
informativeText = ' Please refer to the default conf file.' ,
163
155
withdrawAfter = 10
164
156
}):send ()
165
-
166
- log .e (' Invalid stackline config:\n ' , hs .inspect (err ))
167
157
end
168
158
169
- return valid , err
159
+ return isValid , err
170
160
end -- }}}
171
161
172
162
function M :autosuggest (path ) -- {{{
@@ -178,7 +168,9 @@ function M:autosuggest(path) -- {{{
178
168
local function asc (a , b )
179
169
return a [1 ] < b [1 ]
180
170
end
171
+
181
172
table.sort (scores , asc )
173
+
182
174
log .d (hs .inspect (scores ))
183
175
184
176
local result1 , result2 = scores [1 ][2 ], scores [2 ][2 ] -- return the best 2 matches
@@ -189,15 +181,14 @@ function M:autosuggest(path) -- {{{
189
181
informativeText = string.format (' "%s" is not a default stackline config path' , path ),
190
182
withdrawAfter = 10
191
183
}):send ()
192
-
193
184
end -- }}}
194
185
195
186
function M :getOrSet (path , val ) -- {{{
196
- if path == nil or val == nil then
197
- return self :get (path )
198
- else
187
+ if path and val then
199
188
return self :set (path , val )
200
189
end
190
+
191
+ return self :get (path )
201
192
end -- }}}
202
193
203
194
function M :get (path ) -- {{{
@@ -221,93 +212,36 @@ function M:set(path, val) -- {{{
221
212
222
213
if _type == nil then
223
214
self :autosuggest (path )
224
- else
225
- local typedVal = self .types [_type ].coerce (val )
226
- local isValid , err = validator (typedVal ) -- validate val is appropriate type
227
- log .d (' \n val:' , typedVal )
228
- log .d (' val type:' , type (typedVal ))
229
- if isValid then
230
- log .d (' Setting' , path , ' to' , typedVal )
231
- u .setfield (path , typedVal , self .conf )
232
-
233
- local onChange = u .getfield (path , self .events , true )
234
- if type (onChange ) == ' function' then onChange () end
235
- else
236
- log .e (hs .inspect (err ))
237
- end
238
- return self , val
215
+ return self
239
216
end
240
217
241
- end -- }}}
218
+ local typedVal = self .types [_type ].coerce (val )
219
+ local isValid , err = validator (typedVal ) -- validate val is appropriate type
242
220
243
- function M :toggle (key ) -- {{{
244
- local toggledVal = not self :get (key )
245
- log .d (' Toggling' , key , ' from ' , self :get (key ), ' to ' , toggledVal )
246
- self :set (key , toggledVal )
247
- return self
248
- end -- }}}
249
-
250
- -- TODO: Add m:Increment(delta)
251
- -- TODO: Add m:Decrement(delta)
221
+ log .d (' \n val:' , typedVal , ' \n val type:' , type (typedVal ))
252
222
253
- function M :parseMsg (msg ) -- {{{
254
- local _ , path , val = table.unpack (msg :split (' :' ))
255
- path = path :gsub (" _(.)" , string.upper ) -- convert snake_case to camelCase
256
- log .d (' path parsed from ipc port' , path )
257
-
258
- if type (val ) == ' string' then
259
- val = val :gsub (" %W" , " " ) -- remove all whitespace
223
+ if not isValid then
224
+ log .e (hs .inspect (err ))
225
+ return self
260
226
end
261
227
262
- -- TODO: resolve 'chicken & egg' problem: need type to fully parse, need to fully parse to get type w/o error
263
- -- local _type, validator = self:getPathSchema(path)
264
-
265
- local parsedMsg = {
266
- path = path ,
267
- val = val ,
268
- _type = _type ,
269
- validator = validator ,
270
- isGet = (path ~= nil ) and (val == nil ),
271
- isSet = (path ~= nil ) and (val ~= nil ),
272
- isToggle = path :match (" toggle" ) ~= nil , -- TODO: add and _type == 'boolean' when todo above is complete
273
- }
274
-
275
- log .d (' Parsed msg:\n ' , hs .inspect (parsedMsg ))
228
+ log .d (' Setting' , path , ' to' , typedVal )
276
229
277
- return parsedMsg
278
- end -- }}}
230
+ u .setfield (path , typedVal , self .conf )
279
231
280
- function M :handleMsg (msg ) -- {{{
281
- log .d (' msg' , msg )
282
- local m = self :parseMsg (msg )
283
- log .d (m )
284
-
285
- if m .isToggle then
286
- log .d (' isToggle' )
287
- local key = m .path
288
- :gsub (' toggle' , ' ' ) -- strip leading 'toggle'
289
- :gsub (" ^%L" , string.lower ) -- lowercase 1st character
290
- self :toggle (key )
291
- return self :get (key )
292
-
293
- elseif m .isSet then
294
- log .d (' isSet' )
295
- local _ , setVal = self :set (m .path , m .val )
296
- return setVal
297
-
298
- elseif m .isGet then
299
- log .d (' isGet' )
300
- local val = self :get (m .path )
301
- return val
232
+ local onChange = u .getfield (path , self .events , true )
233
+ if type (onChange ) == ' function' then onChange () end
234
+ return self , val
302
235
303
- else
304
- log .e (' Unparsable IPC message. Try:' )
305
- log .i ( ' `echo ":toggle_appearance.show_icons:" | hs -m stackline-config"`' )
306
- log .i ( ' `echo ":get_appearance.show_icons:" | hs -m stackline-config"`' )
307
- end
308
-
309
- return " ok"
310
236
end -- }}}
311
237
238
+ function M :toggle (key ) -- {{{
239
+ local val = self :get (key )
240
+ if type (val )~= ' boolean' then log .w (key , ' cannot be toggled because it is not boolean' ) end
241
+ local toggledVal = not val
242
+ log .d (' Toggling' , key , ' from ' , val , ' to ' , toggledVal )
243
+ self :set (key , toggledVal )
244
+ return self
245
+ end -- }}}
312
246
313
247
return M
0 commit comments