-
Notifications
You must be signed in to change notification settings - Fork 1
/
manager.lua
211 lines (175 loc) · 5.41 KB
/
manager.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
local json = require("extern.json.json")
local gfs = require("gears.filesystem")
local Meta = require("meta")
local oop = require("framework.oop")
local Fs = require("framework.fs-simple")
local utils = require("framework.utils")()
local _manager = {}
local DEFAULT_CACHED_ICONS = {
icons = {},
}
local DEFAULT_USER_LIKES = {
navigator = "google-chrome",
terminal = "alacritty",
explorer = "thunar",
launcher = "rofi -show drun",
modkey = "Mod4",
theme = {
scheme = "dark",
accents = {
primary = "blue",
secondary = "cyan",
},
colors = {
background = "#131313",
foreground = "#b6beca",
black = "#202020",
hovered_black = "#2c2c2c",
red = "#c6797c",
green = "#8cc7a9",
yellow = "#dcc89f",
blue = "#89a8d2",
magenta = "#c29eda",
cyan = "#8bb8d2",
white = "#e0e1e4",
},
},
wallpaper = {
filename = gfs.get_configuration_dir() .. "/assets/wallpaper.png",
disable_borders = false,
rounded_corners = {
roundness = 12,
top_left = true,
top_right = true,
bottom_left = true,
bottom_right = true,
},
},
}
local DEFAULT_GENERAL_BEHAVIOR = {
num_tags = 6,
tag_icons = { "", "", "", "", "", "" },
sloppy_focus = true,
}
local DEFAULT_AUTOSTART = {
"bash -c 'pgrep -x pulseaudio || pulseaudio -b'",
"bash -c 'pgrep -x picom || picom -b'",
}
-- utility function to speedup a little bit
local function register_value(filename, content)
return { filename = filename, default_content = content }
end
function _manager:constructor(_)
self.fs = Fs()
self.config_dir = os.getenv("HOME") .. "/.config/" .. Meta.Project.id
self.cache_dir = os.getenv("HOME") .. "/.cache/" .. Meta.Project.id
self.icons_cache = self.cache_dir .. "/icons-cache.json"
self.user_likes = self.config_dir .. "/user-likes.json"
self.autostart = self.config_dir .. "/autostart.json"
self.general_behavior = self.config_dir .. "/general-behavior.json"
self.files = {
["icons_cache"] = register_value(
self.icons_cache,
DEFAULT_CACHED_ICONS
),
["user_likes"] = register_value(self.user_likes, DEFAULT_USER_LIKES),
["autostart"] = register_value(self.autostart, DEFAULT_AUTOSTART),
["general_behavior"] = register_value(
self.general_behavior,
DEFAULT_GENERAL_BEHAVIOR
),
}
self:scaffold_if_needed()
self:make_parsing_functions_shortcuts()
end
-- TODO: Figure out a way to prettify the json
function _manager:write_into(filename, content_table)
local content = json.encode(content_table)
local file = io.open(filename, "w")
if not file then
error("cannot open the file " .. filename)
end
file:write(content)
file:close()
end
function _manager:scaffold_if_needed()
self.fs:xmkdir(self.config_dir)
self.fs:xmkdir(self.cache_dir)
for _, content in pairs(self.files) do
local filename, default_content =
content.filename, content.default_content
if not self.fs:isfile(filename) then
self.fs:touch(filename)
self:write_into(filename, default_content)
end
end
end
function _manager:parse(path)
if not self.fs:isfile(path) then
error(
path
.. " does not exists, did the caller call scaffold_if_needed()?"
)
end
return json.decode(self.fs:read(path))
end
-- generates functions that looks like this for every file:
--- function _manager:parse_general_behavior()
--- return self:parse(self.general_behavior)
--- end
function _manager:make_parsing_functions_shortcuts()
for name, content in pairs(self.files) do
self["parse_" .. name] = function(self)
return self:parse(content.filename)
end
end
end
-- TODO: Use a more sophisticated error instead of `error()`
function _manager:inject_helpers(filename_key, tbl)
local _injected_functions = {
"get_key",
"refresh_content",
}
local manager_self = self
local function resolve_filename()
for key, meta in pairs(manager_self.files) do
local filename = meta.filename
if key == filename_key then
return filename
end
end
return nil
end
local filename = resolve_filename()
if filename == nil then
error("invalid given filename key " .. filename_key)
end
function tbl:get_key(key)
if not utils:key_in_tbl(key, tbl) then
error(
"cannot get required key " .. key .. " from the config files!"
)
end
return self[key]
end
function tbl:refresh_content()
local value = {}
for key, val in pairs(self) do
local is_injected = false
for _, injected_key in ipairs(_injected_functions) do
if key == injected_key then
is_injected = true
goto stop
end
::stop::
end
if not is_injected then
value[key] = val
end
end
manager_self:write_into(filename, value)
return value
end
return tbl
end
return oop(_manager)