Skip to content

Commit 9372112

Browse files
authored
fix(policy): fix 'shuffle' random (#141)
1 parent fc14ceb commit 9372112

File tree

5 files changed

+129
-82
lines changed

5 files changed

+129
-82
lines changed

lua/colorbox.lua

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local jsons = require("colorbox.commons.jsons")
44
local uv = require("colorbox.commons.uv")
55
local numbers = require("colorbox.commons.numbers")
66
local fileios = require("colorbox.commons.fileios")
7+
local strings = require("colorbox.commons.strings")
78

89
--- @alias colorbox.Options table<any, any>
910
--- @type colorbox.Options
@@ -146,6 +147,7 @@ local function _init()
146147
-- vim.opt.packpath:append(cwd .. "/pack/colorbox/opt")
147148
-- vim.cmd([[packadd catppuccin-nvim]])
148149

150+
local logger = logging.get("colorbox") --[[@as commons.logging.Logger]]
149151
local ColorNameToColorSpecsMap =
150152
require("colorbox.db").get_color_name_to_color_specs_map()
151153
local ColorNamesList = require("colorbox.db").get_color_names_list()
@@ -159,14 +161,14 @@ local function _init()
159161
for i, color_name in ipairs(FilteredColorNamesList) do
160162
FilteredColorNameToIndexMap[color_name] = i
161163
end
162-
-- logger.debug(
163-
-- "|colorbox._init| FilteredColorNamesList:%s",
164-
-- vim.inspect(FilteredColorNamesList)
165-
-- )
166-
-- logger.debug(
167-
-- "|colorbox._init| FilteredColorNameToIndexMap:%s",
168-
-- vim.inspect(FilteredColorNameToIndexMap)
169-
-- )
164+
logger:debug(
165+
"|_init| FilteredColorNamesList:%s",
166+
vim.inspect(FilteredColorNamesList)
167+
)
168+
logger:debug(
169+
"|_init| FilteredColorNameToIndexMap:%s",
170+
vim.inspect(FilteredColorNameToIndexMap)
171+
)
170172
end
171173

172174
local function _force_sync_syntax()
@@ -224,18 +226,40 @@ local function _get_prev_color_name_by_idx(idx)
224226
return FilteredColorNamesList[idx]
225227
end
226228

229+
local function randint(n)
230+
local secs, millis = uv.gettimeofday()
231+
local pid = uv.os_getpid()
232+
233+
secs = tonumber(secs) or math.random(n)
234+
millis = tonumber(millis) or math.random(n)
235+
pid = tonumber(pid) or math.random(n)
236+
237+
local total = numbers.mod(
238+
numbers.mod(secs + millis, numbers.INT32_MAX) + pid,
239+
numbers.INT32_MAX
240+
)
241+
242+
local chars = strings.tochars(tostring(total)) --[[@as string[] ]]
243+
chars = numbers.shuffle(chars) --[[@as string[] ]]
244+
return numbers.mod(tonumber(table.concat(chars, "")) or math.random(n), n)
245+
+ 1
246+
end
247+
227248
local function _policy_shuffle()
228249
if #FilteredColorNamesList > 0 then
229-
local i = math.random(#FilteredColorNamesList)
250+
local i = randint(#FilteredColorNamesList)
230251
local color = _get_next_color_name_by_idx(i)
231-
-- logger.debug(
232-
-- "|colorbox._policy_shuffle| color:%s, ColorNames:%s (%d), r:%d",
233-
-- vim.inspect(color),
234-
-- vim.inspect(ColorNames),
235-
-- vim.inspect()
236-
-- )
237-
---@diagnostic disable-next-line: param-type-mismatch
238-
local ok, err = pcall(vim.cmd, string.format([[color %s]], color))
252+
logging.get("colorbox"):debug(
253+
"|_policy_shuffle| color:%s, FilteredColorNamesList:%s (%d), i:%d",
254+
vim.inspect(color),
255+
vim.inspect(FilteredColorNamesList),
256+
vim.inspect(#FilteredColorNamesList),
257+
vim.inspect(i)
258+
)
259+
local ok, err = pcall(
260+
vim.cmd --[[@as function]],
261+
string.format([[color %s]], color)
262+
)
239263
assert(ok, err)
240264
end
241265
end
@@ -421,6 +445,7 @@ local function update(opts)
421445
file_log_name = "colorbox_update.log",
422446
file_log_mode = "w",
423447
})
448+
local logger = logging.get("colorbox-update") --[[@as commons.logging.Logger]]
424449

425450
local home_dir = vim.fn["colorbox#base_dir"]()
426451
-- local packstart = string.format("%s/pack/colorbox/start", home_dir)
@@ -459,21 +484,21 @@ local function update(opts)
459484
for handle, spec in pairs(HandleToColorSpecsMap) do
460485
local function _on_output(chanid, data, name)
461486
if type(data) == "table" then
462-
logging.get("colorbox-update"):debug(
487+
logger:debug(
463488
"(%s) %s: %s",
464489
vim.inspect(name),
465490
vim.inspect(handle),
466491
vim.inspect(data)
467492
)
468493
for _, d in ipairs(data) do
469494
if type(d) == "string" and string.len(vim.trim(d)) > 0 then
470-
logging.get("colorbox-update"):info("%s: %s", handle, d)
495+
logger:info("%s: %s", handle, d)
471496
end
472497
end
473498
end
474499
end
475500
local function _on_exit(jid, exitcode, name)
476-
logging.get("colorbox-update"):debug(
501+
logger:debug(
477502
"(%s-%s) %s: exit with %s",
478503
vim.inspect(name),
479504
vim.inspect(jid),
@@ -490,14 +515,14 @@ local function update(opts)
490515
end
491516
end
492517
if not removed_from_working_queue then
493-
logging.get("colorbox-update"):err(
518+
logger:err(
494519
"failed to remove job id %s from jobs_working_queue: %s",
495520
vim.inspect(jid),
496521
vim.inspect(jobs_working_queue)
497522
)
498523
end
499524
if jobid_to_jobs_map[jid] == nil then
500-
logging.get("colorbox-update"):err(
525+
logger:err(
501526
"failed to remove job id %s from jobid_to_jobs_map: %s",
502527
vim.inspect(jid),
503528
vim.inspect(jobid_to_jobs_map)
@@ -606,6 +631,7 @@ local function _clean()
606631
-- )
607632
return
608633
end
634+
local logger = logging.get("colorbox") --[[@as commons.logging.Logger]]
609635
if vim.fn.executable("rm") > 0 then
610636
local jobid = vim.fn.jobstart({ "rm", "-rf", full_pack_dir }, {
611637
detach = false,
@@ -634,9 +660,9 @@ local function _clean()
634660
end,
635661
})
636662
vim.fn.jobwait({ jobid })
637-
logging.get("colorbox"):info("cleaned directory: %s", shorten_pack_dir)
663+
logger:info("cleaned directory: %s", shorten_pack_dir)
638664
else
639-
logging.get("colorbox"):warn("no 'rm' command found, skip cleaning...")
665+
logger:warn("no 'rm' command found, skip cleaning...")
640666
end
641667
end
642668

@@ -699,6 +725,8 @@ local function setup(opts)
699725
vim.api.nvim_create_user_command(
700726
Configs.command.name,
701727
function(command_opts)
728+
local logger = logging.get("colorbox") --[[@as commons.logging.Logger]]
729+
702730
-- logger.debug(
703731
-- "|colorbox.setup| command opts:%s",
704732
-- vim.inspect(command_opts)
@@ -712,17 +740,15 @@ local function setup(opts)
712740
-- vim.inspect(args_splits)
713741
-- )
714742
if #args_splits == 0 then
715-
logging.get("colorbox"):warn("missing parameter.")
743+
logger:warn("missing parameter.")
716744
return
717745
end
718746
if type(CONTROLLERS_MAP[args_splits[1]]) == "function" then
719747
local fn = CONTROLLERS_MAP[args_splits[1]]
720748
local sub_args = args:sub(string.len(args_splits[1]) + 1)
721749
fn(sub_args)
722750
else
723-
logging
724-
.get("colorbox")
725-
:warn("unknown parameter %s.", args_splits[1])
751+
logger:warn("unknown parameter %s.", args_splits[1])
726752
end
727753
end,
728754
{

lua/colorbox/commons/numbers.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,24 @@ M.min = function(f, a, ...)
124124
return minimal_item, minimal_index
125125
end
126126

127+
--- @param l any[]|string
128+
--- @return any[]|string
129+
M.shuffle = function(l)
130+
assert(type(l) == "table")
131+
local n = #l
132+
133+
local new_l = {}
134+
for i = 1, n do
135+
table.insert(new_l, l[i])
136+
end
137+
138+
for i = n, 1, -1 do
139+
local j = math.random(n)
140+
local tmp = new_l[j]
141+
new_l[j] = new_l[i]
142+
new_l[i] = tmp
143+
end
144+
return new_l
145+
end
146+
127147
return M

lua/colorbox/commons/strings.lua

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -85,69 +85,36 @@ M.rfind = function(s, t, rstart)
8585
end
8686

8787
--- @param s string
88-
--- @param t string? by default t is whitespace
88+
--- @param t string? by default is whitespace
8989
--- @return string
9090
M.ltrim = function(s, t)
9191
assert(type(s) == "string")
9292
assert(type(t) == "string" or t == nil)
9393

94-
local function has(idx)
95-
if not t then
96-
return M.isspace(s:sub(idx, idx))
97-
end
98-
99-
local c = string.byte(s, idx)
100-
local found = false
101-
for j = 1, #t do
102-
if string.byte(t, j) == c then
103-
found = true
104-
break
105-
end
106-
end
107-
return found
108-
end
109-
110-
local i = 1
111-
while i <= #s do
112-
if not has(i) then
113-
break
114-
end
115-
i = i + 1
116-
end
117-
return s:sub(i, #s)
94+
t = t or "%s+"
95+
---@diagnostic disable-next-line: redundant-return-value
96+
return string.gsub(s, "^" .. t, "")
11897
end
11998

12099
--- @param s string
121-
--- @param t string? by default t is whitespace
100+
--- @param t string? by default is whitespace
122101
--- @return string
123102
M.rtrim = function(s, t)
124103
assert(type(s) == "string")
125104
assert(type(t) == "string" or t == nil)
126105

127-
local function has(idx)
128-
if not t then
129-
return M.isspace(s:sub(idx, idx))
130-
end
131-
132-
local c = string.byte(s, idx)
133-
local found = false
134-
for j = 1, #t do
135-
if string.byte(t, j) == c then
136-
found = true
137-
break
138-
end
139-
end
140-
return found
141-
end
106+
t = t or "%s+"
107+
---@diagnostic disable-next-line: redundant-return-value
108+
return string.gsub(s, t .. "$", "")
109+
end
142110

143-
local i = #s
144-
while i >= 1 do
145-
if not has(i) then
146-
break
147-
end
148-
i = i - 1
149-
end
150-
return s:sub(1, i)
111+
--- @param s string
112+
--- @param t string? by default is whitespace
113+
--- @return string
114+
M.trim = function(s, t)
115+
assert(type(s) == "string")
116+
assert(type(t) == "string" or t == nil)
117+
return M.rtrim(M.ltrim(s, t), t)
151118
end
152119

153120
--- @param s string
@@ -261,4 +228,41 @@ M.isupper = function(c)
261228
return c:match("%u") ~= nil
262229
end
263230

231+
--- @param s string
232+
--- @param pos integer
233+
--- @param ch string
234+
--- @return string
235+
M.setchar = function(s, pos, ch)
236+
assert(type(s) == "string")
237+
assert(type(pos) == "number")
238+
assert(type(ch) == "string")
239+
assert(string.len(ch) == 1)
240+
241+
local n = string.len(s)
242+
pos = require("colorbox.commons.tables").list_index(pos, n)
243+
244+
local buffer = ""
245+
if pos > 1 then
246+
buffer = string.sub(s, 1, pos - 1)
247+
end
248+
buffer = buffer .. ch
249+
if pos < n then
250+
buffer = buffer .. string.sub(s, pos + 1)
251+
end
252+
253+
return buffer
254+
end
255+
256+
--- @param s string
257+
--- @return string[]
258+
M.tochars = function(s)
259+
assert(type(s) == "string")
260+
local l = {}
261+
local n = string.len(s)
262+
for i = 1, n do
263+
table.insert(l, string.sub(s, i, i))
264+
end
265+
return l
266+
end
267+
264268
return M

lua/colorbox/commons/tables.lua

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ M.tbl_not_empty = function(t)
1212
return type(t) == "table" and not vim.tbl_isempty(t)
1313
end
1414

15-
-- retrieve value from table like json field indexing via dot `.` delimiter.
16-
-- for example when parameter `t = { a = { b = 1 } }` and `field = 'a.b'`, it will return `1`.
17-
--
1815
--- @param t any?
1916
--- @param ... any
2017
--- @return any
2118
M.tbl_get = function(t, ...)
2219
if vim.fn.has("nvim-0.10") > 0 and type(vim.tbl_get) == "function" then
23-
return vim.tbl_get(t, ...)
20+
return type(t) == "table" and vim.tbl_get(t, ...) or nil
2421
end
2522

2623
local e = t --[[@as table]]

lua/colorbox/commons/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.1.4
1+
3.3.0

0 commit comments

Comments
 (0)