Feat/add advanced navigation (#257)
This commit is contained in:
@@ -136,6 +136,8 @@ lua <<EOF
|
|||||||
["<C-v>"] = tree_cb("vsplit"),
|
["<C-v>"] = tree_cb("vsplit"),
|
||||||
["<C-x>"] = tree_cb("split"),
|
["<C-x>"] = tree_cb("split"),
|
||||||
["<C-t>"] = tree_cb("tabnew"),
|
["<C-t>"] = tree_cb("tabnew"),
|
||||||
|
["<"] = tree_cb("prev_sibling"),
|
||||||
|
[">"] = tree_cb("next_sibling"),
|
||||||
["<BS>"] = tree_cb("close_node"),
|
["<BS>"] = tree_cb("close_node"),
|
||||||
["<S-CR>"] = tree_cb("close_node"),
|
["<S-CR>"] = tree_cb("close_node"),
|
||||||
["<Tab>"] = tree_cb("preview"),
|
["<Tab>"] = tree_cb("preview"),
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ INFORMATIONS *nvim-tree-info*
|
|||||||
- '<CR>' on '..' will cd in the above directory
|
- '<CR>' on '..' will cd in the above directory
|
||||||
- typing '<C-]>' will cd in the directory under the cursor
|
- typing '<C-]>' will cd in the directory under the cursor
|
||||||
- typing '<BS>' will close current opened directory or parent
|
- typing '<BS>' will close current opened directory or parent
|
||||||
|
- typing 'P' will move cursor to the parent directory
|
||||||
|
|
||||||
- type 'a' to add a file
|
- type 'a' to add a file
|
||||||
- type 'r' to rename a file
|
- type 'r' to rename a file
|
||||||
@@ -241,6 +242,10 @@ INFORMATIONS *nvim-tree-info*
|
|||||||
- type ']c' to go to next git item
|
- type ']c' to go to next git item
|
||||||
- type '[c' to go to prev git item
|
- type '[c' to go to prev git item
|
||||||
- type '-' to navigate up one directory
|
- type '-' to navigate up one directory
|
||||||
|
- type '<' to navigate to the previous sibling of current file/directory
|
||||||
|
- type '>' to navigate to the next sibling of current file/directory
|
||||||
|
- type 'J' to navigate to the first sibling of current file/directory
|
||||||
|
- type 'K' to navigate to the last sibling of current file/directory
|
||||||
|
|
||||||
- if the file is a directory, '<CR>' will open the directory
|
- if the file is a directory, '<CR>' will open the directory
|
||||||
- otherwise it will open the file in the buffer near the tree
|
- otherwise it will open the file in the buffer near the tree
|
||||||
@@ -280,9 +285,14 @@ Default keybindings can be overriden. You can also define your own keymappings f
|
|||||||
["<C-v>"] = tree_cb("vsplit"),
|
["<C-v>"] = tree_cb("vsplit"),
|
||||||
["<C-x>"] = tree_cb("split"),
|
["<C-x>"] = tree_cb("split"),
|
||||||
["<C-t>"] = tree_cb("tabnew"),
|
["<C-t>"] = tree_cb("tabnew"),
|
||||||
|
["<"] = tree_cb("prev_sibling"),
|
||||||
|
[">"] = tree_cb("next_sibling"),
|
||||||
|
["P"] = tree_cb("parent_node"),
|
||||||
["<BS>"] = tree_cb("close_node"),
|
["<BS>"] = tree_cb("close_node"),
|
||||||
["<S-CR>"] = tree_cb("close_node"),
|
["<S-CR>"] = tree_cb("close_node"),
|
||||||
["<Tab>"] = tree_cb("preview"),
|
["<Tab>"] = tree_cb("preview"),
|
||||||
|
["K"] = tree_cb("first_sibling"),
|
||||||
|
["J"] = tree_cb("last_sibling"),
|
||||||
["I"] = tree_cb("toggle_ignored"),
|
["I"] = tree_cb("toggle_ignored"),
|
||||||
["H"] = tree_cb("toggle_dotfiles"),
|
["H"] = tree_cb("toggle_dotfiles"),
|
||||||
["R"] = tree_cb("refresh"),
|
["R"] = tree_cb("refresh"),
|
||||||
|
|||||||
@@ -71,9 +71,14 @@ local keypress_funcs = {
|
|||||||
cut = fs.cut,
|
cut = fs.cut,
|
||||||
paste = fs.paste,
|
paste = fs.paste,
|
||||||
close_node = lib.close_node,
|
close_node = lib.close_node,
|
||||||
|
parent_node = lib.parent_node,
|
||||||
toggle_ignored = lib.toggle_ignored,
|
toggle_ignored = lib.toggle_ignored,
|
||||||
toggle_dotfiles = lib.toggle_dotfiles,
|
toggle_dotfiles = lib.toggle_dotfiles,
|
||||||
refresh = lib.refresh_tree,
|
refresh = lib.refresh_tree,
|
||||||
|
first_sibling = function(node) lib.sibling(node, -math.huge) end,
|
||||||
|
last_sibling = function(node) lib.sibling(node, math.huge) end,
|
||||||
|
prev_sibling = function(node) lib.sibling(node, -1) end,
|
||||||
|
next_sibling = function(node) lib.sibling(node, 1) end,
|
||||||
prev_git_item = gen_go_to('prev_git_item'),
|
prev_git_item = gen_go_to('prev_git_item'),
|
||||||
next_git_item = gen_go_to('next_git_item'),
|
next_git_item = gen_go_to('next_git_item'),
|
||||||
dir_up = lib.dir_up,
|
dir_up = lib.dir_up,
|
||||||
|
|||||||
@@ -67,9 +67,14 @@ function M.get_bindings()
|
|||||||
["<C-v>"] = M.nvim_tree_callback("vsplit"),
|
["<C-v>"] = M.nvim_tree_callback("vsplit"),
|
||||||
["<C-x>"] = M.nvim_tree_callback("split"),
|
["<C-x>"] = M.nvim_tree_callback("split"),
|
||||||
["<C-t>"] = M.nvim_tree_callback("tabnew"),
|
["<C-t>"] = M.nvim_tree_callback("tabnew"),
|
||||||
|
["<"] = M.nvim_tree_callback("prev_sibling"),
|
||||||
|
[">"] = M.nvim_tree_callback("next_sibling"),
|
||||||
|
["P"] = M.nvim_tree_callback("parent_node"),
|
||||||
["<BS>"] = M.nvim_tree_callback("close_node"),
|
["<BS>"] = M.nvim_tree_callback("close_node"),
|
||||||
["<S-CR>"] = M.nvim_tree_callback("close_node"),
|
["<S-CR>"] = M.nvim_tree_callback("close_node"),
|
||||||
["<Tab>"] = M.nvim_tree_callback("preview"),
|
["<Tab>"] = M.nvim_tree_callback("preview"),
|
||||||
|
["K"] = M.nvim_tree_callback("first_sibling"),
|
||||||
|
["J"] = M.nvim_tree_callback("last_sibling"),
|
||||||
["I"] = M.nvim_tree_callback("toggle_ignored"),
|
["I"] = M.nvim_tree_callback("toggle_ignored"),
|
||||||
["H"] = M.nvim_tree_callback("toggle_dotfiles"),
|
["H"] = M.nvim_tree_callback("toggle_dotfiles"),
|
||||||
["R"] = M.nvim_tree_callback("refresh"),
|
["R"] = M.nvim_tree_callback("refresh"),
|
||||||
|
|||||||
@@ -78,6 +78,30 @@ local function get_node_at_line(line)
|
|||||||
return iter
|
return iter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function get_line_from_node(node, find_parent)
|
||||||
|
local node_path = node.absolute_path
|
||||||
|
|
||||||
|
if find_parent then
|
||||||
|
node_path = node.absolute_path:match("(.*)"..utils.path_separator)
|
||||||
|
end
|
||||||
|
|
||||||
|
local line = 2
|
||||||
|
local function iter(entries, recursive)
|
||||||
|
for _, entry in ipairs(entries) do
|
||||||
|
if node_path:match('^'..entry.match_path..'$') ~= nil then
|
||||||
|
return line, entry
|
||||||
|
end
|
||||||
|
|
||||||
|
line = line + 1
|
||||||
|
if entry.open == true and recursive then
|
||||||
|
local _, child = iter(entry.entries, recursive)
|
||||||
|
if child ~= nil then return line, child end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return iter
|
||||||
|
end
|
||||||
|
|
||||||
function M.get_node_at_cursor()
|
function M.get_node_at_cursor()
|
||||||
local cursor = api.nvim_win_get_cursor(M.Tree.winnr())
|
local cursor = api.nvim_win_get_cursor(M.Tree.winnr())
|
||||||
local line = cursor[1]
|
local line = cursor[1]
|
||||||
@@ -334,37 +358,65 @@ function M.open()
|
|||||||
api.nvim_command('setlocal '..window_opts.split_command)
|
api.nvim_command('setlocal '..window_opts.split_command)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.sibling(node, direction)
|
||||||
|
if not direction then return end
|
||||||
|
|
||||||
|
local iter = get_line_from_node(node, true)
|
||||||
|
local node_path = node.absolute_path
|
||||||
|
|
||||||
|
local line, parent = 0, nil
|
||||||
|
|
||||||
|
-- Check if current node is already at root entries
|
||||||
|
for index, entry in ipairs(M.Tree.entries) do
|
||||||
|
if node_path:match('^'..entry.match_path..'$') ~= nil then
|
||||||
|
line = index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if line > 0 then
|
||||||
|
parent = M.Tree
|
||||||
|
else
|
||||||
|
_, parent = iter(M.Tree.entries, true)
|
||||||
|
if parent ~= nil and #parent.entries > 1 then
|
||||||
|
line, _ = get_line_from_node(node)(parent.entries)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ignore parent line count
|
||||||
|
line = line - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local index = line + direction
|
||||||
|
if index < 1 then
|
||||||
|
index = 1
|
||||||
|
elseif index > #parent.entries then
|
||||||
|
index = #parent.entries
|
||||||
|
end
|
||||||
|
local target_node = parent.entries[index]
|
||||||
|
|
||||||
|
line, _ = get_line_from_node(target_node)(M.Tree.entries, true)
|
||||||
|
api.nvim_win_set_cursor(M.Tree.winnr(), {line, 0})
|
||||||
|
renderer.draw(M.Tree, true)
|
||||||
|
end
|
||||||
|
|
||||||
function M.close_node(node)
|
function M.close_node(node)
|
||||||
|
M.parent_node(node, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.parent_node(node, should_close)
|
||||||
if node.name == '..' then return end
|
if node.name == '..' then return end
|
||||||
|
should_close = should_close or false
|
||||||
|
|
||||||
local sep = package.config:sub(1,1)
|
local iter = get_line_from_node(node, true)
|
||||||
local dname = node.absolute_path:match("(.*"..sep..")")
|
if node.open == true and should_close then
|
||||||
local index = 2
|
|
||||||
|
|
||||||
local function iter(entries)
|
|
||||||
for _, entry in ipairs(entries) do
|
|
||||||
if dname:match('^'..entry.match_path..sep..'$') ~= nil then
|
|
||||||
return entry
|
|
||||||
end
|
|
||||||
|
|
||||||
index = index + 1
|
|
||||||
if entry.open == true then
|
|
||||||
local child = iter(entry.entries)
|
|
||||||
if child ~= nil then return child end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if node.open == true then
|
|
||||||
node.open = false
|
node.open = false
|
||||||
else
|
else
|
||||||
local parent = iter(M.Tree.entries)
|
local line, parent = iter(M.Tree.entries, true)
|
||||||
if parent == nil then
|
if parent == nil then
|
||||||
index = 1
|
line = 1
|
||||||
else
|
elseif should_close then
|
||||||
parent.open = false
|
parent.open = false
|
||||||
end
|
end
|
||||||
api.nvim_win_set_cursor(M.Tree.winnr(), {index, 0})
|
api.nvim_win_set_cursor(M.Tree.winnr(), {line, 0})
|
||||||
end
|
end
|
||||||
renderer.draw(M.Tree, true)
|
renderer.draw(M.Tree, true)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user