Files
nvim/plugins/nvim-tree.lua
T

280 lines
7.2 KiB
Lua

vim.keymap.set("n", "<leader>tt", function()
require("nvim-tree.api").tree.toggle({ find_file = true, focus = false })
end)
---@class nvim_tree.api.decorator.UserDecorator
local Decorator = require("nvim-tree.api").Decorator
local repo = require("git.core.repo")
repo.on("refresh", function()
require("nvim-tree.api").tree.reload()
end)
do
local events = require("nvim-tree.api").events
local function on_change(data)
if not data then
return
end
local seen = {}
local function fire(path)
if not path then
return
end
local r = repo.find(path)
if r and not seen[r] then
seen[r] = true
r:refresh()
end
end
fire(data.fname)
fire(data.folder_name)
fire(data.old_name)
fire(data.new_name)
end
events.subscribe(events.Event.FileCreated, on_change)
events.subscribe(events.Event.FileRemoved, on_change)
events.subscribe(events.Event.FolderCreated, on_change)
events.subscribe(events.Event.FolderRemoved, on_change)
events.subscribe(events.Event.NodeRenamed, on_change)
end
---@class ow.GitDecorator: nvim_tree.api.Decorator
local GitDecorator = Decorator:extend()
function GitDecorator:new()
self.enabled = true
self.icon_placement = "after"
self.highlight_range = "name"
end
local status = require("git.core.status")
---@param node Node
---@return ow.Git.Status.Mark[]?
local function marks_for(node)
local r = repo.find(node.absolute_path)
if not r then
return
end
local rel = vim.fs.relpath(r.worktree, node.absolute_path)
if not rel then
return
end
if node.type == "directory" then
local list = r.status:aggregate_at(rel)
return #list > 0 and list or nil
end
local entry = r.status.entries[rel]
if not entry then
return
end
return status.marks_for(entry)
end
---@param node Node
---@return { str: string, hl: string[] }[]?
function GitDecorator.icons(_, node)
local list = marks_for(node)
if not list then
return
end
local out = {}
for _, mark in ipairs(list) do
if mark.hl ~= "GitIgnored" then
table.insert(out, { str = mark.char, hl = { mark.hl } })
end
end
return out
end
---@param node Node
---@return string?
function GitDecorator.highlight_group(_, node)
local list = marks_for(node)
if not list then
return
end
local hl
for _, mark in ipairs(list) do
if mark.hl ~= "GitIgnored" then
return
end
hl = hl or mark.hl
end
return hl
end
local signs = require("lsp.diagnostic").signs
require("nvim-tree").setup({
on_attach = function(bufnr)
local function opts(desc)
return {
desc = "nvim-tree: " .. desc,
buffer = bufnr,
noremap = true,
silent = true,
nowait = true,
}
end
local api = require("nvim-tree.api")
api.map.on_attach.default(bufnr)
vim.keymap.del("n", "D", { buffer = bufnr })
vim.keymap.del("n", "bt", { buffer = bufnr })
vim.keymap.set("n", "d", api.fs.trash, opts("Trash"))
vim.keymap.set(
"n",
"bd",
api.marks.bulk.trash,
opts("Trash Bookmarked")
)
vim.keymap.set("n", "<C-l>", api.node.open.edit, opts("Open"))
vim.keymap.set(
"n",
"<C-h>",
api.node.navigate.parent_close,
opts("Close Directory")
)
end,
hijack_cursor = true,
hijack_netrw = false,
view = {
width = 50,
preserve_window_proportions = true,
},
renderer = {
full_name = true,
root_folder_label = function(path)
local label = vim.fn.fnamemodify(path, ":~")
local r = require("git.core.repo").resolve(path)
local git_head = r and r:head()
if git_head then
label = label .. ("  %s"):format(git_head)
end
return label
end,
special_files = {},
decorators = {
GitDecorator,
"Modified",
"Bookmark",
"Diagnostics",
"Copied",
"Cut",
},
highlight_modified = "icon",
highlight_bookmarks = "name",
highlight_clipboard = "all",
indent_markers = {
enable = true,
icons = {
corner = "",
none = "",
},
},
icons = {
diagnostics_placement = "signcolumn",
bookmarks_placement = "after",
symlink_arrow = " -> ",
show = {
file = false,
folder = false,
folder_arrow = false,
bookmarks = false,
},
glyphs = {
modified = "*",
},
},
},
update_focused_file = {
enable = true,
},
diagnostics = {
enable = true,
show_on_dirs = true,
icons = {
hint = signs.text[vim.diagnostic.severity.HINT],
info = signs.text[vim.diagnostic.severity.INFO],
warning = signs.text[vim.diagnostic.severity.WARN],
error = signs.text[vim.diagnostic.severity.ERROR],
},
},
modified = {
enable = true,
},
filters = {
custom = { "^\\.git$" },
},
live_filter = {
prefix = "Filter: ",
always_show_folders = false,
},
filesystem_watchers = {
enable = true,
},
actions = {
use_system_clipboard = false,
change_dir = {
enable = false,
},
expand_all = {
exclude = { ".venv", "build" },
},
open_file = {
window_picker = {
enable = false,
},
},
},
notify = {
threshold = vim.log.levels.WARN,
absolute_path = false,
},
help = {
sort_by = "desc",
},
sync_root_with_cwd = true,
git = {
enable = false,
},
})
local function clear_hl(hl)
vim.cmd.highlight({ args = { "clear", hl } })
vim.cmd.highlight({ args = { "link", hl, "NONE" }, bang = true })
end
clear_hl("NvimTreeExecFile")
clear_hl("NvimTreeSpecialFile")
clear_hl("NvimTreeSymlink")
clear_hl("NvimTreeImageFile")
vim.api.nvim_create_autocmd("QuitPre", {
callback = function()
local tree_wins = {}
local floating_wins = {}
local wins = vim.api.nvim_list_wins()
for _, w in ipairs(wins) do
local bufname =
vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(w))
if bufname:match("NvimTree_") ~= nil then
table.insert(tree_wins, w)
end
if vim.api.nvim_win_get_config(w).relative ~= "" then
table.insert(floating_wins, w)
end
end
if 1 == #wins - #floating_wins - #tree_wins then
-- Should quit, so we close all invalid windows.
for _, w in ipairs(tree_wins) do
vim.api.nvim_win_close(w, true)
end
end
end,
})