Created
March 25, 2025 10:53
-
-
Save vegetablesalad/1b6d7715b2e4203d459ac55fd355e337 to your computer and use it in GitHub Desktop.
neo tree config to switch quickly between root/buffer/git quickly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-------------------------------------------------------------------------------- | |
-- Minimal, self-contained Neo-tree keymap setup | |
-- Project tree: <leader>ee | |
-- Buffer tree: <leader>eb | |
-- Git tree: <leader>ee | |
-- Close tree: <leader>eq | |
-- Toggle between buffer and tree: q | |
-- disable some of the default neo tree keys for this to work | |
-- ["q"] = false, -- remove default 'q' | |
-- ["e"] = false, -- remove default 'e' | |
-------------------------------------------------------------------------------- | |
-- Track which source was last opened. Defaults to "filesystem" if none was opened | |
local last_neo_tree_source = "filesystem" | |
-- Track the last *non-Neo-tree* window we were in, | |
-- so pressing `q` from Neo-tree can bounce you back | |
local last_win = nil | |
-------------------------------------------------------------------------------- | |
-- Helper: Check if ANY Neo-tree (filesystem, buffers, or git_status) is open | |
-------------------------------------------------------------------------------- | |
local function is_any_neo_tree_open() | |
local manager = require("neo-tree.sources.manager") | |
for _, src in ipairs({ "filesystem", "buffers", "git_status" }) do | |
local state = manager.get_state(src) | |
if state and state.winid and vim.api.nvim_win_is_valid(state.winid) then | |
return true | |
end | |
end | |
return false | |
end | |
-------------------------------------------------------------------------------- | |
-- Helper: Return the first open Neo-tree source & its winid (or nil if none open) | |
-------------------------------------------------------------------------------- | |
local function get_open_source_and_window() | |
local manager = require("neo-tree.sources.manager") | |
for _, src in ipairs({ "filesystem", "buffers", "git_status" }) do | |
local state = manager.get_state(src) | |
if state and state.winid and vim.api.nvim_win_is_valid(state.winid) then | |
return src, state.winid | |
end | |
end | |
return nil, nil | |
end | |
-------------------------------------------------------------------------------- | |
-- Focus/Open a specific Neo-tree source (filesystem/buffers/git_status) | |
-------------------------------------------------------------------------------- | |
local function focus_neo_tree_source(source) | |
local manager = require("neo-tree.sources.manager") | |
local current_win = vim.api.nvim_get_current_win() | |
-- Check if we're *already* in a Neo-tree window | |
local in_neo_tree = false | |
for _, src in ipairs({ "filesystem", "buffers", "git_status" }) do | |
local st = manager.get_state(src) | |
if st and st.winid == current_win then | |
in_neo_tree = true | |
break | |
end | |
end | |
-- Only update 'last_win' if we're in a "normal" buffer | |
if not in_neo_tree then | |
last_win = current_win | |
end | |
-- 1) Open or focus the desired source | |
vim.cmd("Neotree focus " .. source) | |
-- 2) Explicitly move the cursor to that window | |
local state = manager.get_state(source) | |
if state and state.winid and vim.api.nvim_win_is_valid(state.winid) then | |
vim.api.nvim_set_current_win(state.winid) | |
end | |
-- Remember this was the "last used" source | |
last_neo_tree_source = source | |
end | |
-------------------------------------------------------------------------------- | |
-- 1) Keymap: 'q' | |
-- Behavior: | |
-- • If you're IN a Neo-tree window, jump back to `last_win`. | |
-- • If you're in a buffer and a Neo-tree is open, jump to it. | |
-- • If no Neo-tree is open, open the last-used source (fallback to "filesystem"). | |
-------------------------------------------------------------------------------- | |
local function toggle_neo_tree_focus() | |
local current_win = vim.api.nvim_get_current_win() | |
local open_src, open_win = get_open_source_and_window() | |
if open_src and open_win then | |
-- There's at least one open Neo-tree | |
if current_win == open_win then | |
-- Currently in Neo-tree → jump back to last buffer | |
if last_win and vim.api.nvim_win_is_valid(last_win) then | |
vim.api.nvim_set_current_win(last_win) | |
else | |
vim.cmd("wincmd p") -- fallback | |
end | |
else | |
-- Currently in a buffer → jump to the open Neo-tree | |
last_win = current_win | |
vim.api.nvim_set_current_win(open_win) | |
end | |
else | |
-- No Neo-tree open → open last-used source | |
last_win = current_win | |
vim.cmd("Neotree focus " .. last_neo_tree_source) | |
end | |
end | |
-------------------------------------------------------------------------------- | |
-- 2) Keymap: <leader>eq | |
-- Behavior: | |
-- • If any Neo-tree is open, close them. | |
-- • Else, open the last-used source (default "filesystem"). | |
-------------------------------------------------------------------------------- | |
local function toggle_neo_tree_open_close() | |
if is_any_neo_tree_open() then | |
vim.cmd("Neotree close") | |
else | |
vim.cmd("Neotree focus " .. last_neo_tree_source) | |
end | |
end | |
-------------------------------------------------------------------------------- | |
-- Keymaps | |
-------------------------------------------------------------------------------- | |
vim.keymap.set("n", "q", toggle_neo_tree_focus, { desc = "Toggle focus with Neo-tree" }) | |
vim.keymap.set("n", "<leader>eq", toggle_neo_tree_open_close, { desc = "Open/close Neo-tree" }) | |
vim.keymap.set("n", "<leader>ee", function() | |
focus_neo_tree_source("filesystem") | |
end, { desc = "Neo-tree: Filesystem" }) | |
vim.keymap.set("n", "<leader>eb", function() | |
focus_neo_tree_source("buffers") | |
end, { desc = "Neo-tree: Buffers" }) | |
vim.keymap.set("n", "<leader>eg", function() | |
focus_neo_tree_source("git_status") | |
end, { desc = "Neo-tree: Git Status" }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment