canola.nvim/lua/canola/log.lua
Barrett Ruth e6b42168c9
refactor: rename oil to canola across entire codebase
Problem: the codebase still used the upstream \`oil\` naming everywhere —
URL schemes, the \`:Oil\` command, highlight groups, user events, module
paths, filetypes, buffer/window variables, LuaCATS type annotations,
vimdoc help tags, syntax groups, and internal identifiers.

Solution: mechanical rename of every reference. URL schemes now use
\`canola://\` (plus \`canola-ssh://\`, \`canola-s3://\`, \`canola-sss://\`,
\`canola-trash://\`, \`canola-test://\`). The \`:Canola\` command replaces
\`:Oil\`. All highlight groups, user events, augroups, namespaces,
filetypes, require paths, type annotations, help tags, and identifiers
follow suit. The \`upstream\` remote to \`stevearc/oil.nvim\` has been
removed and the \`vim.g.oil\` deprecation shim dropped.
2026-03-05 14:49:25 -05:00

126 lines
2.7 KiB
Lua

local uv = vim.uv or vim.loop
local levels_reverse = {}
for k, v in pairs(vim.log.levels) do
levels_reverse[v] = k
end
local Log = {}
---@type integer
Log.level = vim.log.levels.WARN
---@return string
Log.get_logfile = function()
local fs = require('canola.fs')
local ok, stdpath = pcall(vim.fn.stdpath, 'log')
if not ok then
stdpath = vim.fn.stdpath('cache')
end
assert(type(stdpath) == 'string')
return fs.join(stdpath, 'canola.log')
end
---@param level integer
---@param msg string
---@param ... any[]
---@return string
local function format(level, msg, ...)
local args = vim.F.pack_len(...)
for i = 1, args.n do
local v = args[i]
if type(v) == 'table' then
args[i] = vim.inspect(v)
elseif v == nil then
args[i] = 'nil'
end
end
local ok, text = pcall(string.format, msg, vim.F.unpack_len(args))
-- TODO figure out how to get formatted time inside luv callback
-- local timestr = vim.fn.strftime("%Y-%m-%d %H:%M:%S")
local timestr = ''
if ok then
local str_level = levels_reverse[level]
return string.format('%s[%s] %s', timestr, str_level, text)
else
return string.format(
"%s[ERROR] error formatting log line: '%s' args %s",
timestr,
vim.inspect(msg),
vim.inspect(args)
)
end
end
---@param line string
local function write(line)
-- This will be replaced during initialization
end
local initialized = false
local function initialize()
if initialized then
return
end
initialized = true
local filepath = Log.get_logfile()
local stat = uv.fs_stat(filepath)
if stat and stat.size > 10 * 1024 * 1024 then
local backup = filepath .. '.1'
uv.fs_unlink(backup)
uv.fs_rename(filepath, backup)
end
local parent = vim.fs.dirname(filepath)
require('canola.fs').mkdirp(parent)
local logfile, openerr = io.open(filepath, 'a+')
if not logfile then
local err_msg = string.format('Failed to open canola.nvim log file: %s', openerr)
vim.notify(err_msg, vim.log.levels.ERROR)
else
write = function(line)
logfile:write(line)
logfile:write('\n')
logfile:flush()
end
end
end
---Override the file handler e.g. for tests
---@param handler fun(line: string)
function Log.set_handler(handler)
write = handler
initialized = true
end
function Log.log(level, msg, ...)
if Log.level <= level then
initialize()
local text = format(level, msg, ...)
write(text)
end
end
function Log.trace(...)
Log.log(vim.log.levels.TRACE, ...)
end
function Log.debug(...)
Log.log(vim.log.levels.DEBUG, ...)
end
function Log.info(...)
Log.log(vim.log.levels.INFO, ...)
end
function Log.warn(...)
Log.log(vim.log.levels.WARN, ...)
end
function Log.error(...)
Log.log(vim.log.levels.ERROR, ...)
end
return Log