Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(type): add type annotation for defaults.lua #1333

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
014f98a
refactor(type): add type annotation for defaults.lua
pysan3 Feb 2, 2024
efcefd7
ci(lua_ls): add lua_ls actions to check type annotation
pysan3 Feb 2, 2024
fde92b3
chore: autoformat with stylua
pysan3 Feb 2, 2024
0c048b4
ci(lua_ls): force run type check on all branches for now
pysan3 Feb 2, 2024
5b8f58c
Merge branch 'add-type-annotations' of github.com:pysan3/neo-tree.nvi…
pysan3 Feb 2, 2024
f5d2207
fix(ci): fix typo
pysan3 Feb 2, 2024
913d998
ci(lua_ls): refer to types defined in the repo
pysan3 Feb 2, 2024
adee9b9
fix(type): better organized type names
pysan3 Feb 2, 2024
72776bc
refactor(type): move config types to another file
pysan3 Feb 3, 2024
ead7513
refactor(type): add types to log.lua
pysan3 Feb 3, 2024
e6236b9
refactor(type): add type for merge_config
pysan3 Feb 5, 2024
c331b7b
ci(lua_ls): add more files to check types
pysan3 Feb 5, 2024
4cfcbe2
refactor(defaults): move event_handler examples to wiki
pysan3 Feb 5, 2024
4b68620
refactor(types): add type files to library
pysan3 Feb 5, 2024
7744d57
refactor(types): ignore wrong or deprecated types
pysan3 Feb 5, 2024
e85fdcc
ci(lua_ls): remove unnecessary types to check
pysan3 Feb 5, 2024
a28b905
refactor(types): remove collections.lua from type check
pysan3 Feb 5, 2024
c4ab2c3
ci(lua_ls): make lua_ls typecheck run on PRs
pysan3 Feb 5, 2024
9ce9563
fix(type): add lacking field
pysan3 Feb 6, 2024
b42cefe
refactor(type): delete types to prevent lua_ls performance issue
pysan3 Feb 9, 2024
12a67ae
refactor(type): move component types to separate file
pysan3 Feb 9, 2024
710ddaf
refactor(type): add types to functions in common/components
pysan3 Feb 9, 2024
c1eaadb
refactor(type): capitalize all enum keys
pysan3 Feb 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(type): add types to log.lua
  • Loading branch information
pysan3 committed Feb 3, 2024
commit ead7513ef8570791e1d99e4813f2e03f89b12da9
124 changes: 77 additions & 47 deletions lua/neo-tree/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.

local vim = vim
-- User configuration section
---@class NeotreeLogConfig
local default_config = {
-- Name of the plugin. Prepended to log messages
plugin = "neo-tree.nvim",
Expand All @@ -22,9 +22,11 @@ local default_config = {
use_file = false,

-- Any messages above this level will be logged.
---@type string
level = "info",

-- Level configuration
---@type NeotreeLogLevel[]
modes = {
{ name = "trace", hl = "None", level = vim.log.levels.TRACE },
{ name = "debug", hl = "None", level = vim.log.levels.DEBGUG },
Expand All @@ -38,11 +40,37 @@ local default_config = {
float_precision = 0.01,
}

-- {{{ NO NEED TO CHANGE
local log = {}

local unpack = unpack or table.unpack
---Round float at a certain precision
---@param x number
---@param increment number # The smallest digit where `x` will be rounded. `0.1` will output `nn.n`.
---@return number
local round = function(x, increment)
increment = increment or 1
x = x / increment
return (x > 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)) * increment
end

---@class NeotreeLogLevel
---@field name string # Name of the log level
---@field hl NeotreeConfig.highlight # Highlight group to use to notify
---@field level integer # One of `vim.log.levels`

---@alias NeotreeLogFunc fun(...: string|integer|boolean)
---@alias NeotreeLogFmt "fmt_trace"|"fmt_debug"|"fmt_info"|"fmt_warn"|"fmt_error"|"fmt_fatal"

---@class NeotreeLog
---@field _use_file boolean|nil
---@field outfile NeotreePathString
---@field config NeotreeLogConfig
---@field level table<string, integer>
---@field [NeotreeConfig.log_level] NeotreeLogFunc
---@field [NeotreeLogFmt] NeotreeLogFunc
local log = {}

---Wrapper function for `vim.notify` to add opts when possible.
---@param message string
---@param level_config NeotreeLogLevel
local notify = function(message, level_config)
if type(vim.notify) == "table" then
-- probably using nvim-notify
Expand All @@ -54,67 +82,68 @@ local notify = function(message, level_config)
end
end

log.new = function(config, standalone)
config = vim.tbl_deep_extend("force", default_config, config)
---Set or unset file to output logs.
---@param file NeotreePathString|boolean # If false, unsets file, or set to file. If true, uses default path.
---@param quiet boolean|nil # If true, logs when file is set.
log.use_file = function(file, quiet)
error(string.format("Neotree log: call `log.new` first. %s, %s", file, quiet))
end

local outfile =
string.format("%s/%s.log", vim.api.nvim_call_function("stdpath", { "data" }), config.plugin)
---Set log level.
---@param level string # Any messages above this level will be logged.
log.set_level = function(level)
error(string.format("Neotree log: call `log.new` first. %s", level))
end

local obj
if standalone then
obj = log
else
obj = {}
---Initiate a log instance.
---@param config NeotreeLogConfig
---@param standalone boolean # If true, returns a global log object that is shared among others.
log.new = function(config, standalone)
---@class NeotreeLog
local obj = log
if not standalone then
obj = setmetatable({}, log)
obj.__index = log
end
obj.outfile = string.format("%s/%s.log", vim.fn.stdpath("data"), config.plugin)
---@class NeotreeLogConfig
obj.config = vim.tbl_deep_extend("force", default_config, config)
obj.levels = {}
for i, v in ipairs(config.modes) do
obj.levels[v.name] = i
end
obj.outfile = outfile

obj.use_file = function(file, quiet)
obj.config.use_file = file ~= false ---@diagnostic disable-line
if file == false then
if not quiet then
obj.info("[neo-tree] Logging to file disabled")
end
config.use_file = false
else
if type(file) == "string" then
obj.outfile = file
else
obj.outfile = outfile
end
config.use_file = true
if not quiet then
obj.info("[neo-tree] Logging to file: " .. obj.outfile)
end
if type(file) == "string" then
obj.outfile = file
end
end
end

local levels = {}
for i, v in ipairs(config.modes) do
levels[v.name] = i
end

obj.set_level = function(level)
if levels[level] then
if config.level ~= level then
config.level = level
if obj.levels[level] then
if obj.config.level ~= level then
obj.config.level = level
end
else
notify("Invalid log level: " .. level, config.modes[5])
end
end

local round = function(x, increment)
increment = increment or 1
x = x / increment
return (x > 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)) * increment
end

local make_string = function(...)
local t = {}
for i = 1, select("#", ...) do
local x = select(i, ...)

if type(x) == "number" and config.float_precision then
x = tostring(round(x, config.float_precision))
if type(x) == "number" and obj.config.float_precision then
x = tostring(round(x, obj.config.float_precision))
elseif type(x) == "table" then
x = vim.inspect(x)
if #x > 300 then
Expand All @@ -129,9 +158,14 @@ log.new = function(config, standalone)
return table.concat(t, " ")
end

---Decide whether to log
---@param level integer # index in `obj.levels`
---@param level_config NeotreeLogLevel
---@param message_maker fun(...): string
---@vararg ... string|integer|number|boolean|nil
local log_at_level = function(level, level_config, message_maker, ...)
-- Return early if we're below the config.level
if level < levels[config.level] then
if level < obj.levels[obj.config.level] then
return
end
-- Ignnore this if vim is exiting
Expand All @@ -143,8 +177,6 @@ log.new = function(config, standalone)
local msg = message_maker(...)
local info = debug.getinfo(2, "Sl")
local lineinfo = info.short_src .. ":" .. info.currentline

-- Output to log file
if config.use_file then
local str = string.format("[%-6s%s] %s: %s\n", nameupper, os.date(), lineinfo, msg)
local fp = io.open(obj.outfile, "a")
Expand All @@ -155,8 +187,6 @@ log.new = function(config, standalone)
print("[neo-tree] Could not open log file: " .. obj.outfile)
end
end

-- Output to console
if config.use_console and level > 2 then
vim.schedule(function()
notify(msg, level_config)
Expand All @@ -168,8 +198,7 @@ log.new = function(config, standalone)
obj[x.name] = function(...)
return log_at_level(i, x, make_string, ...)
end

obj[("fmt_%s"):format(x.name)] = function()
obj["fmt_" .. x.name] = function()
return log_at_level(i, x, function(...)
local passed = { ... }
local fmt = table.remove(passed, 1)
Expand All @@ -181,9 +210,10 @@ log.new = function(config, standalone)
end)
end
end

return obj
end

log.new(default_config, true)
-- }}}

return log
18 changes: 18 additions & 0 deletions lua/neo-tree/types.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
---@alias NeotreePathString string # Special type for string which represents a file path

---@class NeotreeState
---@field TODO nil # Figure out the fields

---@class NeotreeNode
---@field TODO nil # Figure out the fields

---@class NeotreeAutocmdArg
---@field id number # autocommand id
---@field event string # name of the triggered event `autocmd-events`
---@field group number`nil # autocommand group id, if any
---@field match string # expanded value of `<amatch>`
---@field buf number # expanded value of `<abuf>`
---@field file string # expanded value of `<afile>`
---@field data any # arbitrary data passed from `nvim_exec_autocmds()`

---@alias NeotreeTypes.sort_function fun(a: NeotreeNode, b: NeotreeNode): boolean
---@alias NeotreeConfig.highlight string # Name of a highlight group
---@alias NeotreeConfig.wh integer|string|nil
---@alias NeotreeConfig.log_level "trace"|"debug"|"info"|"warn"|"error"|"fatal"
---@alias NeotreeConfig.diagnostics_keys "hint"|"info"|"warn"|"error"
---@alias NeotreeConfig.components.align "left"|"right"
8 changes: 1 addition & 7 deletions lua/neo-tree/types/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
---IF the root node is hidden, keep the indentation anyhow.
---This is needed if you use expanders because they render in the indent.
---@field retain_hidden_root_indent boolean|nil (false)
---@field log_level string|nil ("info") "trace", "debug", "info", "warn", "error", "fatal"
---@field log_level NeotreeConfig.log_level|nil ("info") "trace", "debug", "info", "warn", "error", "fatal"
---@field log_to_file boolean|nil (false) true, false, "/path/to/file.log", use :NeoTreeLogs to show the file
---@field open_files_in_last_window boolean|nil (true) false = open files in top left window
---@field open_files_do_not_replace_types string[]|nil ({ "terminal", "Trouble", "qf", "edgy" }) when opening files, do not use windows containing these filetypes or buftypes
Expand Down Expand Up @@ -58,12 +58,6 @@
---@field nesting_rules table<string, NeotreeConfig.nesting_rule>|nil
---@field event_handlers NeotreeConfig.event_handler[]|nil

---@alias NeotreeTypes.sort_function fun(a: NeotreeNode, b: NeotreeNode): boolean
---@alias NeotreeConfig.highlight string # Name of a highlight group
---@alias NeotreeConfig.wh integer|string|nil
---@alias NeotreeConfig.diagnostics_keys "hint"|"info"|"warn"|"error"
---@alias NeotreeConfig.components.align "left"|"right"

---@class NeotreeConfig.git_status_async_options
---@field batch_size integer|nil (1000) how many lines of git status results to process at a time
---@field batch_delay integer|nil (10) delay in ms between batches. Spreads out the workload to let other processes run.
Expand Down