diff --git a/.luarc.json b/.luarc.json index 8c49d56db19..5daf9f55e10 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,17 +1,17 @@ { "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", - "runtime.version" : "Lua 5.1", + "runtime.version": "Lua 5.1", "workspace": { "library": [ - "$VIMRUNTIME/lua/vim/lsp", + "$VIMRUNTIME/lua/vim", "${3rd}/luv/library" ] }, "diagnostics": { "libraryFiles": "Disable", - "globals": [ - "vim" - ], + "severity": { + "deprecated": "Hint" + }, "neededFileStatus": { "ambiguity-1": "Any", "assign-type-mismatch": "Any", @@ -23,7 +23,7 @@ "code-after-break": "Any", "codestyle-check": "None", "count-down-loop": "Any", - "deprecated": "Any", + "deprecated": "None", "different-requires": "Any", "discard-returns": "Any", "doc-field-no-class": "Any", @@ -33,11 +33,19 @@ "duplicate-index": "Any", "duplicate-set-field": "Any", "empty-block": "Any", + "global-element": "Any", "global-in-nil-env": "Any", + "incomplete-signature-doc": "None", + "inject-field": "Any", + "invisible": "Any", "lowercase-global": "Any", + "missing-fields": "Any", + "missing-global-doc": "Any", + "missing-local-export-doc": "None", "missing-parameter": "Any", "missing-return": "Any", "missing-return-value": "Any", + "name-style-check": "None", "need-check-nil": "Any", "newfield-call": "Any", "newline-call": "Any", @@ -70,4 +78,3 @@ } } } - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d9f3602803..90c0ecb4b04 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,6 +61,15 @@ Assumes `$VIMRUNTIME` is `/usr/share/nvim/runtime`. Adjust as necessary e.g. VIMRUNTIME="/my/path/to/runtime" make check ``` +If `lua-language-server` is not available or `--check` doesn't function (e.g. Arch Linux 3.9.1-1) you can manually install it as per `ci.yml` e.g. + +```sh +mkdir luals +curl -L "https://github.com/LuaLS/lua-language-server/releases/download/3.9.1/lua-language-server-3.9.1-linux-x64.tar.gz" | tar zx --directory luals + +PATH="luals/bin:${PATH}" make check +``` + # Adding New Actions To add a new action, add a file in `actions/name-of-the-action.lua`. You should export a `setup` function if some configuration is needed. diff --git a/lua/nvim-tree/actions/fs/create-file.lua b/lua/nvim-tree/actions/fs/create-file.lua index 410e88eeb0a..4e5b59c2849 100644 --- a/lua/nvim-tree/actions/fs/create-file.lua +++ b/lua/nvim-tree/actions/fs/create-file.lua @@ -12,7 +12,7 @@ local M = {} local function create_and_notify(file) events._dispatch_will_create_file(file) local ok, fd = pcall(vim.loop.fs_open, file, "w", 420) - if not ok then + if not ok or type(fd) ~= "number" then notify.error("Couldn't create file " .. notify.render_path(file)) return end diff --git a/lua/nvim-tree/actions/fs/remove-file.lua b/lua/nvim-tree/actions/fs/remove-file.lua index b05ab775c49..3ff5877bb54 100644 --- a/lua/nvim-tree/actions/fs/remove-file.lua +++ b/lua/nvim-tree/actions/fs/remove-file.lua @@ -49,9 +49,9 @@ end ---@param cwd string ---@return boolean|nil local function remove_dir(cwd) - local handle = vim.loop.fs_scandir(cwd) - if type(handle) == "string" then - notify.error(handle) + local handle, err = vim.loop.fs_scandir(cwd) + if not handle then + notify.error(err) return end diff --git a/lua/nvim-tree/actions/node/file-popup.lua b/lua/nvim-tree/actions/node/file-popup.lua index 23ae8cc2e29..5736b3ee0d6 100644 --- a/lua/nvim-tree/actions/node/file-popup.lua +++ b/lua/nvim-tree/actions/node/file-popup.lua @@ -56,7 +56,7 @@ end function M.close_popup() if current_popup ~= nil then - vim.api.nvim_win_close(current_popup.winnr, { force = true }) + vim.api.nvim_win_close(current_popup.winnr, true) vim.cmd "augroup NvimTreeRemoveFilePopup | au! CursorMoved | augroup END" current_popup = nil diff --git a/lua/nvim-tree/actions/node/open-file.lua b/lua/nvim-tree/actions/node/open-file.lua index 1ebd974a916..60a6d9aad9b 100644 --- a/lua/nvim-tree/actions/node/open-file.lua +++ b/lua/nvim-tree/actions/node/open-file.lua @@ -33,7 +33,7 @@ local function usable_win_ids() end local win_config = vim.api.nvim_win_get_config(id) - return id ~= tree_winid and win_config.focusable and not win_config.external + return id ~= tree_winid and win_config.focusable and not win_config.external or false end, win_ids) end @@ -265,8 +265,7 @@ local function open_in_new_window(filename, mode) end end - local fname = vim.fn.fnameescape(filename) - fname = utils.escape_special_chars(fname) + local fname = utils.escape_special_chars(vim.fn.fnameescape(filename)) local command if create_new_window then @@ -287,7 +286,7 @@ local function open_in_new_window(filename, mode) set_current_win_no_autocmd(target_winid, { "BufEnter" }) end - pcall(vim.cmd, command) + pcall(vim.api.nvim_cmd, command, { output = false }) lib.set_target_win() end diff --git a/lua/nvim-tree/actions/tree/find-file.lua b/lua/nvim-tree/actions/tree/find-file.lua index 610c534989a..3ba7b13421a 100644 --- a/lua/nvim-tree/actions/tree/find-file.lua +++ b/lua/nvim-tree/actions/tree/find-file.lua @@ -24,18 +24,19 @@ function M.fn(opts) local bufnr, path -- (optional) buffer number and path - if type(opts.buf) == "nil" then + local opts_buf = opts.buf + if type(opts_buf) == "nil" then bufnr = vim.api.nvim_get_current_buf() path = vim.api.nvim_buf_get_name(bufnr) - elseif type(opts.buf) == "number" then - if not vim.api.nvim_buf_is_valid(opts.buf) then + elseif type(opts_buf) == "number" then + if not vim.api.nvim_buf_is_valid(opts_buf) then return end - bufnr = tonumber(opts.buf) + bufnr = opts_buf path = vim.api.nvim_buf_get_name(bufnr) - elseif type(opts.buf) == "string" then + elseif type(opts_buf) == "string" then bufnr = nil - path = tostring(opts.buf) + path = tostring(opts_buf) else return end diff --git a/lua/nvim-tree/buffers.lua b/lua/nvim-tree/buffers.lua index 04f48a05fcc..7327428350a 100644 --- a/lua/nvim-tree/buffers.lua +++ b/lua/nvim-tree/buffers.lua @@ -6,7 +6,7 @@ M._modified = {} ---refresh M._modified function M.reload_modified() M._modified = {} - local bufs = vim.fn.getbufinfo { bufmodified = true, buflisted = true } + local bufs = vim.fn.getbufinfo { bufmodified = 1, buflisted = 1 } for _, buf in pairs(bufs) do local path = buf.name if path ~= "" then -- not a [No Name] buffer diff --git a/lua/nvim-tree/diagnostics.lua b/lua/nvim-tree/diagnostics.lua index 6d0e1354149..e26bef0d823 100644 --- a/lua/nvim-tree/diagnostics.lua +++ b/lua/nvim-tree/diagnostics.lua @@ -46,12 +46,11 @@ local function from_nvim_lsp() if not is_disabled then for _, diagnostic in ipairs(vim.diagnostic.get(nil, { severity = M.severity })) do - local buf = diagnostic.bufnr - if vim.api.nvim_buf_is_valid(buf) then - local bufname = uniformize_path(vim.api.nvim_buf_get_name(buf)) - local severity = diagnostic.severity - local highest_severity = buffer_severity[bufname] or severity - buffer_severity[bufname] = math.min(highest_severity, severity) + if diagnostic.severity and diagnostic.bufnr and vim.api.nvim_buf_is_valid(diagnostic.bufnr) then + local bufname = uniformize_path(vim.api.nvim_buf_get_name(diagnostic.bufnr)) + if not buffer_severity[bufname] or diagnostic.severity < buffer_severity[bufname] then + buffer_severity[bufname] = diagnostic.severity + end end end end diff --git a/lua/nvim-tree/explorer/init.lua b/lua/nvim-tree/explorer/init.lua index 3e98b00dc71..6b150359fde 100644 --- a/lua/nvim-tree/explorer/init.lua +++ b/lua/nvim-tree/explorer/init.lua @@ -1,4 +1,5 @@ local git = require "nvim-tree.git" +local notify = require "nvim-tree.notify" local watch = require "nvim-tree.explorer.watch" local explorer_node = require "nvim-tree.explorer.node" @@ -15,14 +16,24 @@ M.reload = require("nvim-tree.explorer.reload").reload local Explorer = {} Explorer.__index = Explorer ----@param cwd string|nil ----@return Explorer -function Explorer.new(cwd) - cwd = vim.loop.fs_realpath(cwd or vim.loop.cwd()) +---@param path string|nil +---@return Explorer|nil +function Explorer.new(path) + local err + + if path then + path, err = vim.loop.fs_realpath(path) + else + path, err = vim.loop.cwd() + end + if not path then + notify.error(err) + return + end ---@class Explorer local explorer = setmetatable({ - absolute_path = cwd, + absolute_path = path, nodes = {}, open = true, }, Explorer) diff --git a/lua/nvim-tree/explorer/node-builders.lua b/lua/nvim-tree/explorer/node-builders.lua index 9ac04ff9009..c9d5517c3d5 100644 --- a/lua/nvim-tree/explorer/node-builders.lua +++ b/lua/nvim-tree/explorer/node-builders.lua @@ -77,7 +77,7 @@ function M.link(parent, absolute_path, name, fs_stat) local is_dir_link = (link_to ~= nil) and vim.loop.fs_stat(link_to).type == "directory" - if is_dir_link then + if is_dir_link and link_to then local handle = vim.loop.fs_scandir(link_to) has_children = handle and vim.loop.fs_scandir_next(handle) ~= nil open = false diff --git a/lua/nvim-tree/explorer/reload.lua b/lua/nvim-tree/explorer/reload.lua index 8c5f14872fd..9d2ddcab5b7 100644 --- a/lua/nvim-tree/explorer/reload.lua +++ b/lua/nvim-tree/explorer/reload.lua @@ -91,7 +91,7 @@ function M.reload(node, git_status) ---@type table local nodes_by_path = utils.key_by(node.nodes, "absolute_path") while true do - local name, t = vim.loop.fs_scandir_next(handle, cwd) + local name, t = vim.loop.fs_scandir_next(handle) if not name then break end diff --git a/lua/nvim-tree/lib.lua b/lua/nvim-tree/lib.lua index 40a3903ff3d..7bbe867e5e4 100644 --- a/lua/nvim-tree/lib.lua +++ b/lua/nvim-tree/lib.lua @@ -3,6 +3,7 @@ local view = require "nvim-tree.view" local core = require "nvim-tree.core" local utils = require "nvim-tree.utils" local events = require "nvim-tree.events" +local notify = require "nvim-tree.notify" local explorer_node = require "nvim-tree.explorer.node" ---@class LibOpenOpts @@ -243,7 +244,16 @@ function M.open(opts) M.set_target_win() if not core.get_explorer() or opts.path then - core.init(opts.path or vim.loop.cwd()) + if opts.path then + core.init(opts.path) + else + local cwd, err = vim.loop.cwd() + if not cwd then + notify.error(string.format("current working directory unavailable: %s", err)) + return + end + core.init(cwd) + end end if should_hijack_current_buf() then view.close_this_tab_only() diff --git a/lua/nvim-tree/live-filter.lua b/lua/nvim-tree/live-filter.lua index 2f60610657c..d8a0cb0fdf5 100644 --- a/lua/nvim-tree/live-filter.lua +++ b/lua/nvim-tree/live-filter.lua @@ -27,8 +27,8 @@ local function reset_filter(node_) :iterate() end -local overlay_bufnr = nil -local overlay_winnr = nil +local overlay_bufnr = 0 +local overlay_winnr = 0 local function remove_overlay() if view.View.float.enable and view.View.float.quit_on_focus_loss then @@ -46,8 +46,8 @@ local function remove_overlay() vim.api.nvim_win_close(overlay_winnr, true) vim.api.nvim_buf_delete(overlay_bufnr, { force = true }) - overlay_bufnr = nil - overlay_winnr = nil + overlay_bufnr = 0 + overlay_winnr = 0 if M.filter == "" then M.clear_filter() diff --git a/lua/nvim-tree/renderer/builder.lua b/lua/nvim-tree/renderer/builder.lua index fef2fc2bd73..34a1e91ba84 100644 --- a/lua/nvim-tree/renderer/builder.lua +++ b/lua/nvim-tree/renderer/builder.lua @@ -396,11 +396,11 @@ function Builder:format_root_name(root_label) local label = root_label(self.root_cwd) if type(label) == "string" then return label - else - return "???" end + elseif type(root_label) == "string" then + return utils.path_remove_trailing(vim.fn.fnamemodify(self.root_cwd, root_label)) end - return utils.path_remove_trailing(vim.fn.fnamemodify(self.root_cwd, root_label)) + return "???" end ---@private diff --git a/lua/nvim-tree/renderer/components/full-name.lua b/lua/nvim-tree/renderer/components/full-name.lua index 9dde3c88a7a..40c3f431972 100644 --- a/lua/nvim-tree/renderer/components/full-name.lua +++ b/lua/nvim-tree/renderer/components/full-name.lua @@ -67,12 +67,19 @@ local function show() }) local ns_id = vim.api.nvim_get_namespaces()["NvimTreeHighlights"] - local extmarks = vim.api.nvim_buf_get_extmarks(0, ns_id, { line_nr - 1, 0 }, { line_nr - 1, -1 }, { details = 1 }) + local extmarks = vim.api.nvim_buf_get_extmarks(0, ns_id, { line_nr - 1, 0 }, { line_nr - 1, -1 }, { details = true }) vim.api.nvim_win_call(M.popup_win, function() vim.api.nvim_buf_set_lines(0, 0, -1, true, { line }) for _, extmark in ipairs(extmarks) do - local hl = extmark[4] - vim.api.nvim_buf_add_highlight(0, ns_id, hl.hl_group, 0, extmark[3], hl.end_col) + -- nvim 0.10 luadoc is incorrect: vim.api.keyset.get_extmark_item is missing the extmark_id at the start + + ---@cast extmark table + ---@type integer + local col = extmark[3] + ---@type vim.api.keyset.extmark_details + local details = extmark[4] + + vim.api.nvim_buf_add_highlight(0, ns_id, details.hl_group, 0, col, details.end_col) end vim.cmd [[ setlocal nowrap cursorline noswapfile nobuflisted buftype=nofile bufhidden=hide ]] end) diff --git a/lua/nvim-tree/renderer/init.lua b/lua/nvim-tree/renderer/init.lua index daffc104166..320a225a57b 100644 --- a/lua/nvim-tree/renderer/init.lua +++ b/lua/nvim-tree/renderer/init.lua @@ -51,7 +51,7 @@ function M.draw() local profile = log.profile_start "draw" - local cursor = vim.api.nvim_win_get_cursor(view.get_winnr()) + local cursor = vim.api.nvim_win_get_cursor(view.get_winnr() or 0) icon_component.reset_config() local builder = Builder:new():build() @@ -59,7 +59,7 @@ function M.draw() _draw(bufnr, builder.lines, builder.hl_args, builder.signs) if cursor and #builder.lines >= cursor[1] then - vim.api.nvim_win_set_cursor(view.get_winnr(), cursor) + vim.api.nvim_win_set_cursor(view.get_winnr() or 0, cursor) end view.grow_from_content() diff --git a/lua/nvim-tree/utils.lua b/lua/nvim-tree/utils.lua index 6e20bdfa98b..bdd8c76c49a 100644 --- a/lua/nvim-tree/utils.lua +++ b/lua/nvim-tree/utils.lua @@ -406,6 +406,9 @@ function M.debounce(context, timeout, callback) end local timer = vim.loop.new_timer() + if not timer then + return + end debouncer.timer = timer timer:start(timeout, 0, function() timer_stop_close(timer) diff --git a/lua/nvim-tree/view.lua b/lua/nvim-tree/view.lua index 4923cd2992d..3eeed4c1963 100644 --- a/lua/nvim-tree/view.lua +++ b/lua/nvim-tree/view.lua @@ -108,7 +108,7 @@ local function create_buffer(bufnr) events._dispatch_tree_attached_post(M.get_bufnr()) end ----@param size number|fun():number +---@param size (fun():integer)|integer|string ---@return integer local function get_size(size) if type(size) == "number" then @@ -121,10 +121,13 @@ local function get_size(size) return math.floor(vim.o.columns * percent_as_decimal) end ----@param size number|function|nil +---@param size (fun():integer)|integer|nil local function get_width(size) - size = size or M.View.width - return get_size(size) + if size then + return get_size(size) + else + return get_size(M.View.width) + end end local move_tbl = { @@ -140,7 +143,7 @@ local function setup_tabpage(tabpage) end local function set_window_options_and_buffer() - pcall(vim.cmd, "buffer " .. M.get_bufnr()) + pcall(vim.api.nvim_command, "buffer " .. M.get_bufnr()) local eventignore = vim.opt.eventignore:get() vim.opt.eventignore = "all" for k, v in pairs(M.View.winopts) do @@ -204,7 +207,7 @@ end ---@param tabnr integer local function save_tab_state(tabnr) local tabpage = tabnr or vim.api.nvim_get_current_tabpage() - M.View.cursors[tabpage] = vim.api.nvim_win_get_cursor(M.get_winnr(tabpage)) + M.View.cursors[tabpage] = vim.api.nvim_win_get_cursor(M.get_winnr(tabpage) or 0) end ---@param tabpage integer @@ -222,8 +225,8 @@ local function close(tabpage) if tree_win == current_win and prev_win > 0 then vim.api.nvim_set_current_win(vim.fn.win_getid(prev_win)) end - if vim.api.nvim_win_is_valid(tree_win) then - vim.api.nvim_win_close(tree_win, true) + if vim.api.nvim_win_is_valid(tree_win or 0) then + vim.api.nvim_win_close(tree_win or 0, true) end events._dispatch_on_tree_close() return @@ -343,7 +346,7 @@ function M.resize(size) end local new_size = get_width() - vim.api.nvim_win_set_width(M.get_winnr(), new_size) + vim.api.nvim_win_set_width(M.get_winnr() or 0, new_size) -- TODO #1545 remove similar check from setup_autocommands -- We let nvim handle sending resize events after 0.9 @@ -420,7 +423,7 @@ function M.is_visible(opts) return false end - return M.get_winnr() ~= nil and vim.api.nvim_win_is_valid(M.get_winnr()) + return M.get_winnr() ~= nil and vim.api.nvim_win_is_valid(M.get_winnr() or 0) end ---@param opts table|nil @@ -443,7 +446,9 @@ function M.focus(winnr, open_if_closed) M.open() end - vim.api.nvim_set_current_win(wnr) + if wnr then + vim.api.nvim_set_current_win(wnr) + end end --- Retrieve the winid of the open tree. @@ -541,7 +546,8 @@ end -- used on ColorScheme event function M.reset_winhl() - if M.get_winnr() and vim.api.nvim_win_is_valid(M.get_winnr()) then + local winnr = M.get_winnr() + if winnr and vim.api.nvim_win_is_valid(winnr) then vim.wo[M.get_winnr()].winhl = M.View.winopts.winhl end end