Skip to content

Instantly share code, notes, and snippets.

@vegetablesalad
Created March 25, 2025 10:53
Show Gist options
  • Save vegetablesalad/1b6d7715b2e4203d459ac55fd355e337 to your computer and use it in GitHub Desktop.
Save vegetablesalad/1b6d7715b2e4203d459ac55fd355e337 to your computer and use it in GitHub Desktop.
neo tree config to switch quickly between root/buffer/git quickly
--------------------------------------------------------------------------------
-- 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