Skip to content

Commit 2910a20

Browse files
authored
feat(policy): add 'by filetype' policy (#72)
1 parent 7c58dba commit 2910a20

File tree

2 files changed

+119
-42
lines changed

2 files changed

+119
-42
lines changed

README.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ It allow you play them with multiple playback settings (policies):
5959
And multiple trigger timings (colorschemes don't have end time):
6060

6161
- On startup.
62-
- Fixed interval (todo).
62+
- Fixed interval.
6363
- Date time (todo).
64-
- By filetype (todo).
65-
- Manual (todo).
64+
- By filetype.
6665

6766
## 📖 Table of contents
6867

@@ -182,7 +181,7 @@ require('colorbox').setup({
182181
--- @alias colorbox.BuiltinPolicyConfig "shuffle"|"in_order"|"reverse_order"|"single"
183182
---
184183
-- by filetype policy: buffer filetype => color name
185-
--- @alias colorbox.ByFileTypePolicyConfig {implement:colorbox.BuiltinPolicyConfig|table<string, string>}
184+
--- @alias colorbox.ByFileTypePolicyConfig {mapping:table<string, string>,fallback:string}
186185
---
187186
-- fixed interval seconds
188187
--- @alias colorbox.FixedIntervalPolicyConfig {seconds:integer,implement:colorbox.BuiltinPolicyConfig}
@@ -191,7 +190,7 @@ require('colorbox').setup({
191190
--- @type colorbox.PolicyConfig
192191
policy = "shuffle",
193192

194-
--- @type "startup"|"interval"|"filetype"
193+
--- @type "startup"|"interval"|"bufferchanged"
195194
timing = "startup",
196195

197196
-- (Optional) filters that disable some colors that you don't want.
@@ -264,11 +263,11 @@ require('colorbox').setup({
264263

265264
Timing and policy configs have to work together.
266265

267-
- `timing`: 'startup' (on nvim start), 'interval' (fixed interval seconds), 'filetype' (by buffer filetype, todo).
266+
- `timing`: 'startup', 'interval', 'bufferchanged'.
268267
- `policy`:
269-
- Builtin policies (see `colorbox.BuiltinPolicyConfig`): 'shuffle' (random select), 'in_order' ('A-Z' color names), 'reverse_order' ('Z-A' color names), 'single' (don't change).
270-
- Fixed interval policies (see `colorbox.ByFileTypePolicyConfig`): todo.
271-
- By buffer filetype policies (see ``)
268+
- Builtin policies (see `colorbox.BuiltinPolicyConfig`): working with 'startup' timing.
269+
- Fixed interval policies (see `colorbox.FixedIntervalPolicyConfig`): working with 'interval' timing.
270+
- By filetype policies (see `colorbox.ByFileTypePolicyConfig`): working with 'bufferchanged' timing.
272271

273272
To choose a fixed colorscheme on nvim start, please use:
274273

@@ -289,6 +288,23 @@ require('colorbox').setup({
289288
})
290289
```
291290

291+
To choose a colorscheme by file type, please use:
292+
293+
```lua
294+
require('colorbox').setup({
295+
policy = {
296+
mapping = {
297+
lua = "PaperColor",
298+
yaml = "everforest",
299+
markdown = "kanagawa",
300+
python = "iceberg",
301+
},
302+
fallback = "solarized8",
303+
},
304+
timing = "bufferchanged",
305+
})
306+
```
307+
292308
To choose a colorscheme on fixed interval per seconds, please use:
293309

294310
```lua

lua/colorbox.lua

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ local Defaults = {
1212
--- @alias colorbox.BuiltinPolicyConfig "shuffle"|"in_order"|"reverse_order"|"single"
1313
---
1414
-- by filetype policy: buffer filetype => color name
15-
--- @alias colorbox.ByFileTypePolicyConfig {implement:colorbox.BuiltinPolicyConfig|table<string, string>}
15+
--- @alias colorbox.ByFileTypePolicyConfig {mapping:table<string, string>,fallback:string}
1616
---
1717
-- fixed interval seconds
1818
--- @alias colorbox.FixedIntervalPolicyConfig {seconds:integer,implement:colorbox.BuiltinPolicyConfig}
@@ -21,7 +21,7 @@ local Defaults = {
2121
--- @type colorbox.PolicyConfig
2222
policy = "shuffle",
2323

24-
--- @type "startup"|"interval"|"filetype"
24+
--- @type "startup"|"interval"|"bufferchanged"
2525
timing = "startup",
2626

2727
-- (Optional) filters that disable some colors that you don't want.
@@ -132,8 +132,8 @@ end
132132

133133
local function _init()
134134
local home_dir = vim.fn["colorbox#base_dir"]()
135-
local pack_dir = "pack/colorbox/start"
136-
local full_pack_dir = string.format("%s/%s", home_dir, pack_dir)
135+
-- local pack_dir = "pack/colorbox/start"
136+
-- local full_pack_dir = string.format("%s/%s", home_dir, pack_dir)
137137
-- logger.debug(
138138
-- "|colorbox.init| home_dir:%s, pack_dir:%s, full_pack_dir:%s",
139139
-- vim.inspect(home_dir),
@@ -169,23 +169,19 @@ local function _init()
169169
-- )
170170
end
171171

172-
local function _update_background()
173-
if Configs.background == "dark" or Configs.background == "light" then
174-
vim.opt.background = Configs.background
175-
end
176-
end
177-
178172
local function _force_sync_syntax()
179173
vim.cmd([[syntax sync fromstart]])
180174
end
181175

182176
--- @alias PreviousTrack {color_name:string,color_number:integer}
183177
--- @param color_name string
184178
local function _save_track(color_name)
185-
assert(
186-
type(color_name) == "string" and string.len(vim.trim(color_name)) > 0,
187-
string.format("invalid color name %s", vim.inspect(color_name))
188-
)
179+
if
180+
type(color_name) ~= "string"
181+
or string.len(vim.trim(color_name)) == 0
182+
then
183+
return
184+
end
189185
-- start from 0, end with #FilteredColorNamesList-1
190186
local color_number = FilteredColorNameToIndexMap[color_name] or 0
191187
vim.schedule(function()
@@ -238,8 +234,9 @@ local function _policy_shuffle()
238234
-- vim.inspect(ColorNames),
239235
-- vim.inspect()
240236
-- )
241-
_update_background()
242-
vim.cmd(string.format([[color %s]], color))
237+
---@diagnostic disable-next-line: param-type-mismatch
238+
local ok, err = pcall(vim.cmd, string.format([[color %s]], color))
239+
assert(ok, err)
243240
end
244241
end
245242

@@ -248,8 +245,9 @@ local function _policy_in_order()
248245
local previous_track = _load_previous_track() --[[@as PreviousTrack]]
249246
local i = previous_track ~= nil and previous_track.color_number or 0
250247
local color = _get_next_color_name_by_idx(i)
251-
_update_background()
252-
vim.cmd(string.format([[color %s]], color))
248+
---@diagnostic disable-next-line: param-type-mismatch
249+
local ok, err = pcall(vim.cmd, string.format([[color %s]], color))
250+
assert(ok, err)
253251
end
254252
end
255253

@@ -259,8 +257,9 @@ local function _policy_reverse_order()
259257
local i = previous_track ~= nil and previous_track.color_number
260258
or (#FilteredColorNamesList + 1)
261259
local color = _get_prev_color_name_by_idx(i)
262-
_update_background()
263-
vim.cmd(string.format([[color %s]], color))
260+
---@diagnostic disable-next-line: param-type-mismatch
261+
local ok, err = pcall(vim.cmd, string.format([[color %s]], color))
262+
assert(ok, err)
264263
end
265264
end
266265

@@ -274,13 +273,15 @@ local function _policy_single()
274273
color = _get_next_color_name_by_idx(0)
275274
end
276275
if color ~= vim.g.colors_name then
277-
_update_background()
278-
vim.cmd(string.format([[color %s]], color))
276+
---@diagnostic disable-next-line: param-type-mismatch
277+
local ok, err = pcall(vim.cmd, string.format([[color %s]], color))
278+
assert(ok, err)
279279
end
280280
end
281281
end
282282

283283
--- @param po colorbox.Options?
284+
--- @return boolean
284285
local function _is_fixed_interval_policy(po)
285286
return type(po) == "table"
286287
and type(po.seconds) == "number"
@@ -312,6 +313,39 @@ local function _policy_fixed_interval()
312313
impl()
313314
end
314315

316+
--- @param po colorbox.Options?
317+
--- @return boolean
318+
local function _is_by_filetype_policy(po)
319+
return type(po) == "table"
320+
and type(po.mapping) == "table"
321+
and type(po.fallback) == "string"
322+
and string.len(po.fallback) > 0
323+
end
324+
325+
local function _policy_by_filetype()
326+
vim.defer_fn(function()
327+
local ft = vim.bo.filetype or ""
328+
329+
if Configs.policy.mapping[ft] then
330+
local ok, err = pcall(
331+
---@diagnostic disable-next-line: param-type-mismatch
332+
vim.cmd,
333+
string.format([[color %s]], Configs.policy.mapping[ft])
334+
)
335+
assert(ok, err)
336+
else
337+
local ok, err =
338+
---@diagnostic disable-next-line: param-type-mismatch
339+
pcall(
340+
vim.cmd,
341+
string.format([[color %s]], Configs.policy.fallback)
342+
)
343+
assert(ok, err)
344+
end
345+
_force_sync_syntax()
346+
end, 200)
347+
end
348+
315349
local function _policy()
316350
if Configs.policy == "shuffle" then
317351
_policy_shuffle()
@@ -321,8 +355,16 @@ local function _policy()
321355
_policy_reverse_order()
322356
elseif Configs.policy == "single" then
323357
_policy_single()
324-
elseif _is_fixed_interval_policy(Configs.policy) then
358+
elseif
359+
Configs.timing == "interval"
360+
and _is_fixed_interval_policy(Configs.policy)
361+
then
325362
_policy_fixed_interval()
363+
elseif
364+
Configs.timing == "bufferchanged"
365+
and _is_by_filetype_policy(Configs.policy)
366+
then
367+
_policy_by_filetype()
326368
end
327369
end
328370

@@ -332,8 +374,10 @@ local function _timing_startup()
332374
})
333375
end
334376

335-
local function _timing_interval()
336-
-- Configs.timing
377+
local function _timing_buffer_changed()
378+
vim.api.nvim_create_autocmd({ "BufNew", "BufReadPre", "BufNewFile" }, {
379+
callback = _policy,
380+
})
337381
end
338382

339383
local function _timing()
@@ -348,6 +392,17 @@ local function _timing()
348392
)
349393
)
350394
_policy_fixed_interval()
395+
elseif Configs.timing == "bufferchanged" then
396+
assert(
397+
_is_by_filetype_policy(Configs.policy),
398+
string.format(
399+
"invalid policy %s for 'bufferchanged' timing!",
400+
vim.inspect(Configs.policy)
401+
)
402+
)
403+
_timing_buffer_changed()
404+
else
405+
error(string.format("invalid timing %s!", vim.inspect(Configs.timing)))
351406
end
352407
end
353408

@@ -682,10 +737,10 @@ local function setup(opts)
682737

683738
vim.api.nvim_create_autocmd("ColorSchemePre", {
684739
callback = function(event)
685-
logger.debug(
686-
"|colorbox.setup| ColorSchemePre event:%s",
687-
vim.inspect(event)
688-
)
740+
-- logger.debug(
741+
-- "|colorbox.setup| ColorSchemePre event:%s",
742+
-- vim.inspect(event)
743+
-- )
689744
local ColorNameToColorSpecsMap =
690745
require("colorbox.db").get_color_name_to_color_specs_map()
691746
if
@@ -702,15 +757,21 @@ local function setup(opts)
702757
then
703758
Configs.setup[spec.handle]()
704759
end
760+
if
761+
Configs.background == "dark"
762+
or Configs.background == "light"
763+
then
764+
vim.opt.background = Configs.background
765+
end
705766
end,
706767
})
707768

708769
vim.api.nvim_create_autocmd("ColorScheme", {
709770
callback = function(event)
710-
logger.debug(
711-
"|colorbox.setup| ColorScheme event:%s",
712-
vim.inspect(event)
713-
)
771+
-- logger.debug(
772+
-- "|colorbox.setup| ColorScheme event:%s",
773+
-- vim.inspect(event)
774+
-- )
714775
_save_track(event.match)
715776
end,
716777
})

0 commit comments

Comments
 (0)