diff --git a/lua/oil/init.lua b/lua/oil/init.lua index f744a26..7b9472f 100644 --- a/lua/oil/init.lua +++ b/lua/oil/init.lua @@ -551,6 +551,7 @@ M.select = function(opts, callback) local cache = require("oil.cache") local config = require("oil.config") local constants = require("oil.constants") + local log = require("oil.log") local util = require("oil.util") local FIELD_META = constants.FIELD_META opts = vim.tbl_extend("keep", opts or {}, {}) @@ -585,12 +586,10 @@ M.select = function(opts, callback) if not adapter then return finish("Not an oil buffer") end - print( - "0 buf name:", + log.info( + "0 buf name: %s current bufnr: %d current buffer name: %s", vim.api.nvim_buf_get_name(0), - "current bufnr:", vim.api.nvim_get_current_buf(), - "current buffer name:", vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf()) ) @@ -649,12 +648,10 @@ M.select = function(opts, callback) local prev_win = vim.api.nvim_get_current_win() local oil_bufnr = vim.api.nvim_get_current_buf() - print( - "oil_bufnr:", + log.info( + "oil_bufnr: %d name: %s 0 buf name: %s", oil_bufnr, - "name:", vim.api.nvim_buf_get_name(oil_bufnr), - "0 buf name:", vim.api.nvim_buf_get_name(0) ) diff --git a/lua/oil/log.lua b/lua/oil/log.lua new file mode 100644 index 0000000..6793279 --- /dev/null +++ b/lua/oil/log.lua @@ -0,0 +1,124 @@ +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.INFO + +---@return string +Log.get_logfile = function() + local fs = require("oil.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, "oil.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)) + local timestr = vim.fn.strftime("%H:%M:%S") + 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) + vim.fn.mkdir(parent, "p") + + local logfile, openerr = io.open(filepath, "a+") + if not logfile then + local err_msg = string.format("Failed to open oil.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