From 7f8edb90ad9dd8523de40435685cfc0c110c220f Mon Sep 17 00:00:00 2001 From: Fasamii Date: Sat, 7 Feb 2026 14:15:00 +0100 Subject: Theres no reliable way to get path of netrw file (scrapping the lsp integration completly) --- lua/netrw-icons/init.lua | 227 +++++++++++++++++++--------------------------- lua/netrw-icons/parse.lua | 223 ++++++++++++++++++++++----------------------- 2 files changed, 201 insertions(+), 249 deletions(-) diff --git a/lua/netrw-icons/init.lua b/lua/netrw-icons/init.lua index b9bfe7e..9d7eec8 100644 --- a/lua/netrw-icons/init.lua +++ b/lua/netrw-icons/init.lua @@ -82,93 +82,61 @@ local function get_icon(node) return nil; end -local function get_lsp_diagnostics() - local all_diagnostics = vim.diagnostic.get(nil); - - local file_diagnostics_map = {}; - local dir_diagnostics_map = {}; - - for _, diag in ipairs(all_diagnostics) do - local diag_path = vim.api.nvim_buf_get_name(diag.bufnr); - diag_path = vim.fn.fnamemodify(diag_path, ":p"); - - if not file_diagnostics_map[diag_path] then - file_diagnostics_map[diag_path] = { info = 0, hint = 0, warn = 0, error = 0 }; - end - - if diag.severity == vim.diagnostic.severity.ERROR and M.options.lsp.error then - file_diagnostics_map[diag_path].error = file_diagnostics_map[diag_path].error + 1 - elseif diag.severity == vim.diagnostic.severity.WARN and M.options.lsp.warn then - file_diagnostics_map[diag_path].warn = file_diagnostics_map[diag_path].warn + 1 - elseif diag.severity == vim.diagnostic.severity.INFO and M.options.lsp.info then - file_diagnostics_map[diag_path].info = file_diagnostics_map[diag_path].info + 1 - elseif diag.severity == vim.diagnostic.severity.HINT and M.options.lsp.hint then - file_diagnostics_map[diag_path].hint = file_diagnostics_map[diag_path].hint + 1 - end - end - - if M.options.lsp_sum_dir then - for file_path, counts in pairs(file_diagnostics_map) do - file_path = file_path:gsub("/+$", "") - - local dir = file_path:match("(.+)/[^/]+$") - while dir do - local dir_key = dir .. "/" - - if not dir_diagnostics_map[dir_key] then - dir_diagnostics_map[dir_key] = { - info = 0, - hint = 0, - warn = 0, - error = 0, - } - end - - dir_diagnostics_map[dir_key].info = dir_diagnostics_map[dir_key].info + counts.info - dir_diagnostics_map[dir_key].hint = dir_diagnostics_map[dir_key].hint + counts.hint - dir_diagnostics_map[dir_key].warn = dir_diagnostics_map[dir_key].warn + counts.warn - dir_diagnostics_map[dir_key].error = dir_diagnostics_map[dir_key].error + counts.error - - if dir == "/" then - break - end - - dir = dir:match("(.+)/[^/]+$") - end - end - end - - return file_diagnostics_map, dir_diagnostics_map; -end - -local function format_diagnostic(count, config, hi) - if not config then - return nil; - end - - if count == 0 then - return nil; - end - - local prefix = ""; - if type(config) == "string" then - prefix = config; - end +-- local function get_lsp_diagnostics() +-- local all_diagnostics = vim.diagnostic.get(nil); +-- +-- local file_diagnostics_map = {}; +-- +-- for _, diag in ipairs(all_diagnostics) do +-- local diag_path = vim.api.nvim_buf_get_name(diag.bufnr); +-- diag_path = vim.fn.fnamemodify(diag_path, ":p"); +-- +-- if not file_diagnostics_map[diag_path] then +-- file_diagnostics_map[diag_path] = { info = 0, hint = 0, warn = 0, error = 0 }; +-- end +-- +-- if diag.severity == vim.diagnostic.severity.ERROR and M.options.lsp.error then +-- file_diagnostics_map[diag_path].error = file_diagnostics_map[diag_path].error + 1 +-- elseif diag.severity == vim.diagnostic.severity.WARN and M.options.lsp.warn then +-- file_diagnostics_map[diag_path].warn = file_diagnostics_map[diag_path].warn + 1 +-- elseif diag.severity == vim.diagnostic.severity.INFO and M.options.lsp.info then +-- file_diagnostics_map[diag_path].info = file_diagnostics_map[diag_path].info + 1 +-- elseif diag.severity == vim.diagnostic.severity.HINT and M.options.lsp.hint then +-- file_diagnostics_map[diag_path].hint = file_diagnostics_map[diag_path].hint + 1 +-- end +-- end +-- +-- return file_diagnostics_map; +-- end - return { (prefix .. tostring(count)), hi } -end +-- local function format_diagnostic(count, config, hi) +-- if not config then +-- return nil; +-- end +-- +-- if count == 0 then +-- return nil; +-- end +-- +-- local prefix = ""; +-- if type(config) == "string" then +-- prefix = config; +-- end +-- +-- return { (prefix .. tostring(count)), hi } +-- end local function draw(bufnr) local namespace_icons = vim.api.nvim_create_namespace("netrw-icons") - local namespace_diagnostics = vim.api.nvim_create_namespace("netrw-diagnostics") + -- local namespace_diagnostics = vim.api.nvim_create_namespace("netrw-diagnostics") local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) - local file_diagnostics_map, dir_diagnostics_map = nil, nil; - if M.options.lsp then - file_diagnostics_map, dir_diagnostics_map = get_lsp_diagnostics(); - end + -- local file_diagnostics_map = nil; + -- if M.options.lsp then + -- file_diagnostics_map = get_lsp_diagnostics(); + -- end for i, line in ipairs(lines) do local node = parse.get_node(line) @@ -189,49 +157,44 @@ local function draw(bufnr) virt_text = { virt_text }, }); end - if M.options.lsp then - local diagnostics = nil; - - if node.type == parse.TYPE_DIR and M.options.lsp_sum_dir then - if dir_diagnostics_map then - diagnostics = dir_diagnostics_map[node.path]; - end - else - if file_diagnostics_map then - diagnostics = file_diagnostics_map[node.path]; - end - end - if diagnostics then - local virt_text = { { " " } }; - local diag_items = { - { count = diagnostics.error, config = M.options.lsp.error, hl = "DiagnosticError" }, - { count = diagnostics.warn, config = M.options.lsp.warn, hl = "DiagnosticWarn" }, - { count = diagnostics.hint, config = M.options.lsp.hint, hl = "DiagnosticHint" }, - { count = diagnostics.info, config = M.options.lsp.info, hl = "DiagnosticInfo" }, - }; - - local has_diagnostics = false; - for _, item in ipairs(diag_items) do - local formated = format_diagnostic(item.count, item.config, item.hl); - if formated then - if has_diagnostics then - table.insert(virt_text, { " " }); - end - table.insert(virt_text, formated); - has_diagnostics = true; - end - end - - if has_diagnostics then - vim.api.nvim_buf_set_extmark(bufnr, namespace_diagnostics, i - 1, node.lsp, { - id = i, - virt_text_pos = "inline", - virt_text = virt_text, - }); - end - end - end + -- if M.options.lsp then + -- local diagnostics = nil; + -- + -- if file_diagnostics_map then + -- diagnostics = file_diagnostics_map[node.path]; + -- end + -- + -- if diagnostics then + -- local virt_text = { { " " } }; + -- local diag_items = { + -- { count = diagnostics.error, config = M.options.lsp.error, hl = "DiagnosticError" }, + -- { count = diagnostics.warn, config = M.options.lsp.warn, hl = "DiagnosticWarn" }, + -- { count = diagnostics.hint, config = M.options.lsp.hint, hl = "DiagnosticHint" }, + -- { count = diagnostics.info, config = M.options.lsp.info, hl = "DiagnosticInfo" }, + -- }; + -- + -- local has_diagnostics = false; + -- for _, item in ipairs(diag_items) do + -- local formated = format_diagnostic(item.count, item.config, item.hl); + -- if formated then + -- if has_diagnostics then + -- table.insert(virt_text, { " " }); + -- end + -- table.insert(virt_text, formated); + -- has_diagnostics = true; + -- end + -- end + -- + -- if has_diagnostics then + -- vim.api.nvim_buf_set_extmark(bufnr, namespace_diagnostics, i - 1, node.lsp, { + -- id = i, + -- virt_text_pos = "inline", + -- virt_text = virt_text, + -- }); + -- end + -- end + -- end end end end @@ -249,25 +212,21 @@ local default = { dir = " ", sym = " ", - lsp = { - info = false, - hint = false, - warn = "W-", - error = "E-", - }, - - lsp_sum_dir = true, + -- lsp = { + -- info = false, + -- hint = false, + -- warn = "W-", + -- error = "E-", + -- }, } ---@param options Config|nil function M.setup(options) M.options = vim.tbl_deep_extend("force", {}, default, options or {}) - if M.options.file or M.options.dir then - icon_provider = get_icon_provider(M.options.prefer) - if not icon_provider then - error("No icon provider found"); - end + icon_provider = get_icon_provider(M.options.prefer) + if not icon_provider then + error("[netrw-icons] No icon provider found"); end vim.api.nvim_create_autocmd("BufModifiedSet", { diff --git a/lua/netrw-icons/parse.lua b/lua/netrw-icons/parse.lua index cefb9b2..911a1c6 100644 --- a/lua/netrw-icons/parse.lua +++ b/lua/netrw-icons/parse.lua @@ -12,106 +12,106 @@ M.TYPE_DIR = 0 M.TYPE_FILE = 1 M.TYPE_SYMLINK = 2 ----@alias PWord {dir:string, node:string, link:string|nil, extension:string|nil, type:number, icon_col:number, name_col:number, lsp_col:number} - ----@param line string ----@param curdir string ----@return PWord|nil -local parse_liststyle_0 = function(line, curdir) - local _, _, node, link = string.find(line, "^(.+)@\t%s*%-%->%s*(.+)") - if node then - return { - dir = curdir, - icon_col = 0, - name_col = 0, - lsp_col = #node, - node = node, - extension = vim.fn.fnamemodify(node, ":e"), - link = link, - type = M.TYPE_SYMLINK, - } - end - - local _, _, dir = string.find(line, "^(.*)/") - if dir then - return { - dir = curdir, - icon_col = 0, - name_col = 0, - lsp_col = #dir + 1, -- +1 for the "/" - node = dir, - type = M.TYPE_DIR, - } - end - - local ext = vim.fn.fnamemodify(line, ":e") - local clean_line = line - if string.sub(ext, -1) == "*" then - ext = string.sub(ext, 1, -2) - clean_line = string.sub(line, 1, -2) - end - - return { - dir = curdir, - icon_col = 0, - name_col = 0, - lsp_col = #clean_line, - node = clean_line, - extension = ext, - type = M.TYPE_FILE, - } -end - ----@param line string ----@param curdir string ----@return PWord|nil -local parse_liststyle_1 = function(line, curdir) - local _, _, node, link = string.find(line, "^(.+)@%s+") - if node then - return { - dir = curdir, - icon_col = 0, - name_col = 0, - lsp_col = #node, - node = node, - extension = vim.fn.fnamemodify(node, ":e"), - link = link, - type = M.TYPE_SYMLINK, - } - end - - local _, _, dir = string.find(line, "^(.*)/") - if dir then - return { - dir = curdir, - icon_col = 0, - name_col = 0, - lsp_col = #dir + 1, - node = dir, - type = M.TYPE_DIR, - } - end - - local file = vim.fn.substitute(line, "^\\(\\%(\\S\\+ \\)*\\S\\+\\).\\{-}$", "\\1", "e") - local ext = vim.fn.fnamemodify(file, ":e") - if string.sub(ext, -1) == "*" then - ext = string.sub(ext, 1, -2) - file = string.sub(file, 1, -2) - end - - return { - dir = curdir, - icon_col = 0, - name_col = 0, - lsp_col = #file, - node = file, - extension = ext, - type = M.TYPE_FILE, - } -end +---@alias rwNode{name:string, icon:number, type:number} + +-- ---@param line string +-- ---@param curdir string +-- ---@return rwNode|nil +-- local parse_liststyle_0 = function(line, curdir) +-- local _, _, node, link = string.find(line, "^(.+)@\t%s*%-%->%s*(.+)") +-- if node then +-- return { +-- dir = curdir, +-- icon_col = 0, +-- name_col = 0, +-- lsp_col = #node, +-- node = node, +-- extension = vim.fn.fnamemodify(node, ":e"), +-- link = link, +-- type = M.TYPE_SYMLINK, +-- } +-- end +-- +-- local _, _, dir = string.find(line, "^(.*)/") +-- if dir then +-- return { +-- dir = curdir, +-- icon_col = 0, +-- name_col = 0, +-- lsp_col = #dir + 1, -- +1 for the "/" +-- node = dir, +-- type = M.TYPE_DIR, +-- } +-- end +-- +-- local ext = vim.fn.fnamemodify(line, ":e") +-- local clean_line = line +-- if string.sub(ext, -1) == "*" then +-- ext = string.sub(ext, 1, -2) +-- clean_line = string.sub(line, 1, -2) +-- end +-- +-- return { +-- dir = curdir, +-- icon_col = 0, +-- name_col = 0, +-- lsp_col = #clean_line, +-- node = clean_line, +-- extension = ext, +-- type = M.TYPE_FILE, +-- } +-- end +-- +-- ---@param line string +-- ---@param curdir string +-- ---@return rwNode|nil +-- local parse_liststyle_1 = function(line, curdir) +-- local _, _, node, link = string.find(line, "^(.+)@%s+") +-- if node then +-- return { +-- dir = curdir, +-- icon_col = 0, +-- name_col = 0, +-- lsp_col = #node, +-- node = node, +-- extension = vim.fn.fnamemodify(node, ":e"), +-- link = link, +-- type = M.TYPE_SYMLINK, +-- } +-- end +-- +-- local _, _, dir = string.find(line, "^(.*)/") +-- if dir then +-- return { +-- dir = curdir, +-- icon_col = 0, +-- name_col = 0, +-- lsp_col = #dir + 1, +-- node = dir, +-- type = M.TYPE_DIR, +-- } +-- end +-- +-- local file = vim.fn.substitute(line, "^\\(\\%(\\S\\+ \\)*\\S\\+\\).\\{-}$", "\\1", "e") +-- local ext = vim.fn.fnamemodify(file, ":e") +-- if string.sub(ext, -1) == "*" then +-- ext = string.sub(ext, 1, -2) +-- file = string.sub(file, 1, -2) +-- end +-- +-- return { +-- dir = curdir, +-- icon_col = 0, +-- name_col = 0, +-- lsp_col = #file, +-- node = file, +-- extension = ext, +-- type = M.TYPE_FILE, +-- } +-- end ---@param line string ----@return PWord|nil +---@return rwNode|nil local parse_liststyle_3 = function(line) local current_dir = vim.b.netrw_curdir; local type = M.TYPE_FILE; @@ -123,9 +123,12 @@ local parse_liststyle_3 = function(line) return nil; end + local name = content; + local _, _, link, link_target = string.find(content, "^(.+)@\t%s*%-%->%s*(.+)") if link then type = M.TYPE_SYMLINK; + name = link_target; end local _, _, dir = string.find(content, "^(.*)/") @@ -134,33 +137,23 @@ local parse_liststyle_3 = function(line) end return { - name = link_target or content, - path = current_dir .. "/" .. (link_target or content), + name = name, + -- path = current_dir .. "/" .. name, icon = tree_end, - lsp = tree_end + #content, + -- lsp = tree_end + #content, type = type, } end ---@param line string ----@return PWord|nil +---@return rwNode|nil M.get_node = function(line) - if string.find(line, '^"') then - return nil - end - - if line == "" then - return nil - end + if string.find(line, '^"') then return nil end + if line == "" then return nil end - local curdir = vim.b.netrw_curdir local liststyle = vim.b.netrw_liststyle - if liststyle == 0 then - return parse_liststyle_0(line, curdir) - elseif liststyle == 1 then - return parse_liststyle_1(line, curdir) - elseif liststyle == 3 then + if liststyle == 3 then return parse_liststyle_3(line) end -- cgit v1.3