Skip to content

Commit

Permalink
fix: deepcopy exception in ColorSchemePre (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
linrongbin16 committed Jan 31, 2024
1 parent 8b912e4 commit 2e18e51
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 32 deletions.
7 changes: 2 additions & 5 deletions lua/colorbox.lua
Original file line number Diff line number Diff line change
Expand Up @@ -883,11 +883,8 @@ local function setup(opts)
and type(Configs.setup[spec.handle]) == "function"
then
local home_dir = vim.fn["colorbox#base_dir"]()
local ok, setup_err = pcall(
Configs.setup[spec.handle],
home_dir,
vim.deepcopy(spec)
)
local ok, setup_err =
pcall(Configs.setup[spec.handle], home_dir, spec)
if not ok then
local logger = logging.get("colorbox") --[[@as commons.logging.Logger]]
logger:err(
Expand Down
191 changes: 166 additions & 25 deletions lua/colorbox/commons/fileios.lua
Original file line number Diff line number Diff line change
Expand Up @@ -153,31 +153,30 @@ M.readfile = function(filename, opts)
return opts.trim and vim.trim(content) or content
end

--- @param filename string file name.
--- @param on_complete fun(data:string?):nil callback on read complete.
--- 1. `data`: the file content.
--- @param opts {trim:boolean?}? options:
--- 1. `trim`: whether to trim whitespaces around text content, by default `false`.
--- @param filename string
--- @param on_complete fun(data:string?):any
--- @param opts {trim:boolean?}?
M.asyncreadfile = function(filename, on_complete, opts)
local uv = require("colorbox.commons.uv")
opts = opts or { trim = false }
opts.trim = type(opts.trim) == "boolean" and opts.trim or false

uv.fs_open(filename, "r", 438, function(open_err, fd)
if open_err then
error(
string.format(
"failed to open(r) file %s: %s",
vim.inspect(filename),
vim.inspect(open_err)
local open_result, open_err = uv.fs_open(
filename,
"r",
438,
function(open_err, fd)
if open_err then
error(
string.format(
"failed to open(r) file %s: %s",
vim.inspect(filename),
vim.inspect(open_err)
)
)
)
return
end
uv.fs_fstat(
---@diagnostic disable-next-line: param-type-mismatch
fd,
function(fstat_err, stat)
return
end
uv.fs_fstat(fd --[[@as integer]], function(fstat_err, stat)
if fstat_err then
error(
string.format(
Expand All @@ -198,8 +197,7 @@ M.asyncreadfile = function(filename, on_complete, opts)
)
return
end
---@diagnostic disable-next-line: param-type-mismatch
uv.fs_read(fd, stat.size, 0, function(read_err, data)
uv.fs_read(fd --[[@as integer]], stat.size, 0, function(read_err, data)
if read_err then
error(
string.format(
Expand All @@ -210,8 +208,7 @@ M.asyncreadfile = function(filename, on_complete, opts)
)
return
end
---@diagnostic disable-next-line: param-type-mismatch
uv.fs_close(fd, function(close_err)
uv.fs_close(fd --[[@as integer]], function(close_err)
on_complete(
(opts.trim and type(data) == "string") and vim.trim(data) or data
)
Expand All @@ -226,9 +223,17 @@ M.asyncreadfile = function(filename, on_complete, opts)
end
end)
end)
end
end)
end
)
assert(
open_result ~= nil,
string.format(
"failed to open(read) file: %s, error: %s",
vim.inspect(filename),
vim.inspect(open_err)
)
end)
)
end

--- @param filename string
Expand All @@ -246,6 +251,142 @@ M.readlines = function(filename)
return results
end

--- @param filename string
--- @param opts {on_line:fun(line:string):any,on_complete:fun(bytes:integer):any,on_error:fun(err:string?):any,batchsize:integer?}
M.asyncreadlines = function(filename, opts)
assert(type(opts) == "table")
assert(type(opts.on_line) == "function")
local batchsize = opts.batchsize or 4096

local function _handle_error(err, msg)
if type(opts.on_error) == "function" then
opts.on_error(err)
else
error(
string.format(
"failed to async read file(%s): %s, error: %s",
vim.inspect(msg),
vim.inspect(filename),
vim.inspect(err)
)
)
end
end

local uv = require("colorbox.commons.uv")
local open_result, open_err = uv.fs_open(
filename,
"r",
438,
function(open_complete_err, fd)
if open_complete_err then
_handle_error(open_complete_err, "fs_open complete")
return
end
local fstat_result, fstat_err = uv.fs_fstat(
fd --[[@as integer]],
function(fstat_complete_err, stat)
if fstat_complete_err then
_handle_error(fstat_complete_err, "fs_fstat complete")
return
end
if stat == nil then
_handle_error("stat is nil", "fs_fstat complete")
return
end

local fsize = stat.size
local offset = 0
local buffer = nil

local function _process(buf, fn_line_processor)
local strings = require("colorbox.commons.strings")

local i = 1
while i <= #buf do
local newline_pos = strings.find(buf, "\n", i)
if not newline_pos then
break
end
local line = buf:sub(i, newline_pos - 1)
fn_line_processor(line)
i = newline_pos + 1
end
return i
end

local function _chunk_read()
local read_result, read_err = uv.fs_read(
fd --[[@as integer]],
batchsize,
offset,
function(read_complete_err, data)
if read_complete_err then
_handle_error(read_complete_err, "fs_read complete")
return
end

if data then
offset = offset + #data

buffer = buffer and (buffer .. data) or data --[[@as string]]
buffer = buffer:gsub("\r\n", "\n")
local pos = _process(buffer, opts.on_line)
-- truncate the processed lines if still exists any
buffer = pos <= #buffer and buffer:sub(pos, #buffer) or nil
else
-- no more data

-- if buffer still has not been processed
if buffer then
local pos = _process(buffer, opts.on_line)
buffer = pos <= #buffer and buffer:sub(pos, #buffer) or nil

-- process all the left buffer till the end of file
if buffer then
opts.on_line(buffer)
end
end

-- close file
local close_result, close_err = uv.fs_close(
fd --[[@as integer]],
function(close_complete_err)
if close_complete_err then
_handle_error(close_complete_err, "fs_close complete")
end
if type(opts.on_complete) == "function" then
opts.on_complete(fsize)
end
end
)
if close_result == nil then
_handle_error(close_err, "fs_close")
end
end
end
)
if read_result == nil then
_handle_error(read_err, "fs_read")
end
end

_chunk_read()
end
)

if fstat_result == nil then
_handle_error(fstat_err, "fs_fstat")
end
end
)
if open_result == nil then
_handle_error(open_err, "fs_open")
end
end

-- AsyncFileLineReader }

--- @param filename string file name.
--- @param content string file content.
--- @return integer returns `0` if success, returns `-1` if failed.
Expand Down
2 changes: 1 addition & 1 deletion lua/colorbox/commons/spawn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ M.run = function(cmd, opts, on_exit)
stdout_buffer = stdout_buffer and (stdout_buffer .. data) or data
-- search buffer and process each line
local i = _process(stdout_buffer, opts.on_stdout)
-- truncate the printed lines if found any
-- truncate the processed lines if still exists any
stdout_buffer = i <= #stdout_buffer
and stdout_buffer:sub(i, #stdout_buffer)
or nil
Expand Down
28 changes: 28 additions & 0 deletions lua/colorbox/commons/strings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,34 @@ M.endswith = function(s, t, opts)
end
end

--- @param s string
--- @param p string
--- @param r string
--- @return string, integer
M.replace = function(s, p, r)
assert(type(s) == "string")
assert(type(p) == "string")
assert(type(r) == "string")

local sn = string.len(s)
local pn = string.len(p)
local pos = 1
local matched = 0
local result = s

while pos <= sn do
pos = M.find(result, p, pos) --[[@as integer]]
if type(pos) ~= "number" then
break
end
result = string.sub(result, 1, pos - 1) .. r .. string.sub(result, pos + pn)
pos = pos + pn
matched = matched + 1
end

return result, matched
end

--- @param c string
--- @return boolean
M.isspace = function(c)
Expand Down
2 changes: 1 addition & 1 deletion lua/colorbox/commons/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.0.0
8.2.0

0 comments on commit 2e18e51

Please sign in to comment.