299 lines
7.8 KiB
Lua
299 lines
7.8 KiB
Lua
local util = require("util")
|
|
|
|
local function override_highlights()
|
|
-- File Icon
|
|
local hl = util.get_hl_source("NvimTreeFileIcon")
|
|
vim.api.nvim_set_hl(0, "NvimTreeFileIcon", { fg = hl.fg, bg = nil })
|
|
|
|
-- Symlink Icon
|
|
hl = util.get_hl_source("NvimTreeSymlinkIcon")
|
|
vim.api.nvim_set_hl(0, "NvimTreeSymlinkIcon", { fg = hl.fg, bg = nil })
|
|
end
|
|
|
|
local function disable_highlights()
|
|
-- File types
|
|
vim.cmd.highlight({ "clear NvimTreeExecFile" })
|
|
vim.cmd.highlight({
|
|
"link NvimTreeExecFile NONE",
|
|
bang = true,
|
|
})
|
|
vim.cmd.highlight({ "clear NvimTreeImageFile" })
|
|
vim.cmd.highlight({
|
|
"link NvimTreeImageFile NONE",
|
|
bang = true,
|
|
})
|
|
vim.cmd.highlight({ "clear NvimTreeSpecialFile" })
|
|
vim.cmd.highlight({
|
|
"link NvimTreeSpecialFile NONE",
|
|
bang = true,
|
|
})
|
|
vim.cmd.highlight({ "clear NvimTreeSymlink" })
|
|
vim.cmd.highlight({
|
|
"link NvimTreeSymlink NONE",
|
|
bang = true,
|
|
})
|
|
end
|
|
|
|
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.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
|
|
|
|
---@param node Node
|
|
---@return ow.Git.Status.Entry[]?
|
|
local function entries_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)
|
|
return rel and r.status.entries[rel]
|
|
end
|
|
|
|
---@param node Node
|
|
---@return { str: string, hl: string[] }[]?
|
|
function GitDecorator.icons(_, node)
|
|
local list = entries_for(node)
|
|
if not list then
|
|
return
|
|
end
|
|
local out = {}
|
|
for _, entry in ipairs(list) do
|
|
if entry.kind ~= "ignored" then
|
|
table.insert(out, { str = entry.char, hl = { entry.hl } })
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
---@param node Node
|
|
---@return string?
|
|
function GitDecorator.highlight_group(_, node)
|
|
local list = entries_for(node)
|
|
if not list then
|
|
return
|
|
end
|
|
for _, entry in ipairs(list) do
|
|
if entry.kind == "ignored" then
|
|
return entry.hl
|
|
end
|
|
end
|
|
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.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,
|
|
"Open",
|
|
"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 = true,
|
|
folder = true,
|
|
folder_arrow = false,
|
|
bookmarks = false,
|
|
},
|
|
web_devicons = {
|
|
file = {
|
|
color = 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,
|
|
},
|
|
})
|
|
|
|
override_highlights()
|
|
disable_highlights()
|
|
|
|
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,
|
|
})
|