local tree = require 'nvim-tree' -- Disable NetRw vim.g.loaded_netrw = 1 vim.g.loaded_netrwPlugin = 1 -- Keyboard shortcuts vim.keymap.set('n', 'U', vim.cmd.NvimTreeToggle, { silent = true }) -- Configure Nvim Tree tree.setup { sync_root_with_cwd = true, update_focused_file = { enable = true }, git = { ignore = false }, renderer = { highlight_git = true, highlight_opened_files = "icon", root_folder_label = ":~:s?$?", }, on_attach = function(buf) -- Mapping helpers local api = require 'nvim-tree.api' local function opts(desc) return { desc = 'nvim-tree: ' .. desc, buffer = buf, noremap = true, silent = true, nowait = true, } end -- Directories vim.keymap.set('n', 'C', api.tree.change_root_to_node, opts('Change Directory')) vim.keymap.set('n', '-', api.tree.change_root_to_parent, opts('Up')) vim.keymap.set('n', 'P', api.node.navigate.parent, opts('Parent Directory')) -- Open vim.keymap.set('n', '', api.node.open.edit, opts('Open: Toggle')) vim.keymap.set('n', '', api.node.open.edit, opts('Open: Toggle')) vim.keymap.set('n', 'v', api.node.open.vertical, opts('Open: Vertical Split')) vim.keymap.set('n', 's', api.node.open.horizontal, opts('Open: Horizontal Split')) vim.keymap.set('n', '', api.node.open.preview, opts('Open: Preview')) vim.keymap.set('n', 'i', api.node.show_info_popup, opts('Info')) -- File operations vim.keymap.set('n', 'r', api.fs.rename_sub, opts('Rename')) vim.keymap.set('n', 'R', api.fs.rename_basename, opts('Rename: Basename')) vim.keymap.set('n', 'a', api.fs.create, opts('Create')) vim.keymap.set('n', 'c', api.fs.copy.node, opts('Copy')) vim.keymap.set('n', 'x', api.fs.cut, opts('Cut')) vim.keymap.set('n', 'p', api.fs.paste, opts('Paste')) vim.keymap.set('n', 'd', api.fs.remove, opts('Delete')) vim.keymap.set('n', '.', api.node.run.cmd, opts('Run Command')) -- Path copying vim.keymap.set('n', 'y', api.fs.copy.relative_path, opts('Copy Relative Path')) vim.keymap.set('n', 'Y', api.fs.copy.absolute_path, opts('Copy Absolute Path')) -- Navigation vim.keymap.set('n', 'q', api.tree.close, opts('Close')) vim.keymap.set('n', '/', api.tree.search_node, opts('Search')) vim.keymap.set('n', '?', api.tree.toggle_help, opts('Help')) -- Filtering vim.keymap.set('n', 'f', api.live_filter.start, opts('Filter')) vim.keymap.set('n', 'F', api.live_filter.clear, opts('Clean Filter')) vim.keymap.set('n', 'H', api.tree.toggle_hidden_filter, opts('Toggle Dotfiles')) vim.keymap.set('n', 'T', api.tree.toggle_git_clean_filter, opts('Toggle Git Clean')) vim.keymap.set('n', 'Z', api.tree.collapse_all, opts('Collapse')) vim.keymap.set('n', 'z', api.tree.expand_all, opts('Expand All')) -- Bookmarks vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark')) vim.keymap.set('n', 'M', api.marks.bulk.move, opts('Move Bookmarked')) -- Custom open and close vim.keymap.set('n', 'l', function() local node = api.tree.get_node_under_cursor() if node.type == 'directory' then if not node.open then api.node.open.edit() end else api.node.open.edit() end end, opts('Open')) vim.keymap.set('n', 'h', function() local node = api.tree.get_node_under_cursor() if node.type == 'directory' then if node.open then api.node.open.edit() end else local path = node.absolute_path if vim.fn.buflisted(path) == 1 then if vim.fn.getbufinfo(path)[1].changed == 0 then vim.cmd.bdelete(path) else vim.notify('Buffer has unsaved changes', vim.log.levels.ERROR) end end end end, opts('Close')) vim.keymap.set('n', 'o', function() local node = api.tree.get_node_under_cursor() if node.type == 'file' then api.node.open.edit() api.tree.focus() end end, opts('Open: Keep Focus')) end }