Skip to content

Commit 8a2d3e8

Browse files
committed
feat: redirect other files that try to open in a neo-tree window
1 parent c56ab13 commit 8a2d3e8

File tree

3 files changed

+96
-42
lines changed

3 files changed

+96
-42
lines changed

lua/neo-tree.lua

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ local define_events = function()
4747
if events_setup then
4848
return
4949
end
50+
5051
local v = vim.version()
5152
local diag_autocmd = "DiagnosticChanged"
5253
if v.major < 1 and v.minor < 6 then
@@ -57,14 +58,13 @@ local define_events = function()
5758
end)
5859

5960
events.define_autocmd_event(events.VIM_BUFFER_CHANGED, { "BufWritePost", "BufFilePost" }, 200)
60-
6161
events.define_autocmd_event(events.VIM_BUFFER_ADDED, { "BufAdd" }, 200)
62-
6362
events.define_autocmd_event(events.VIM_BUFFER_DELETED, { "BufDelete" }, 200)
6463
events.define_autocmd_event(events.VIM_BUFFER_ENTER, { "BufEnter", "BufWinEnter" }, 0)
6564
events.define_autocmd_event(events.VIM_WIN_ENTER, { "WinEnter" }, 0)
6665
events.define_autocmd_event(events.VIM_DIR_CHANGED, { "DirChanged" }, 200)
6766
events.define_autocmd_event(events.VIM_TAB_CLOSED, { "TabClosed" })
67+
6868
events_setup = true
6969
end
7070

@@ -170,9 +170,7 @@ end
170170

171171
M.win_enter_event = function()
172172
local win_id = vim.api.nvim_get_current_win()
173-
local cfg = vim.api.nvim_win_get_config(win_id)
174-
if cfg.relative > "" or cfg.external then
175-
-- floating window, ignore
173+
if utils.is_floating(win_id) then
176174
return
177175
end
178176
if vim.o.filetype == "neo-tree" then
@@ -239,6 +237,40 @@ M.setup = function(config)
239237

240238
events.clear_all_events()
241239
define_events()
240+
241+
-- Prevent accidentally opening another file in the neo-tree window.
242+
events.subscribe({
243+
event = events.VIM_BUFFER_ENTER,
244+
handler = function(args)
245+
if utils.is_floating() then
246+
return
247+
end
248+
local prior_buf = vim.fn.bufnr("#")
249+
if prior_buf < 1 then
250+
return
251+
end
252+
local prior_type = vim.api.nvim_buf_get_option(prior_buf, "filetype")
253+
if prior_type == "neo-tree" and vim.bo.filetype ~= "neo-tree" then
254+
local bufname = vim.fn.bufname()
255+
vim.cmd("b#")
256+
-- Using schedule at this point fixes problem with syntax
257+
-- highlighting in the buffer. I also prevents errors with diagnostics
258+
-- trying to work with gthe buffer as it's being closed.
259+
vim.schedule(function()
260+
-- try to delete the buffer, only because if it was new it would take
261+
-- on options from the neo-tree window that are undesirable.
262+
pcall(vim.cmd, "bdelete " .. bufname)
263+
local fake_state = {
264+
window = {
265+
position = "left",
266+
},
267+
}
268+
utils.open_file(fake_state, bufname)
269+
end)
270+
end
271+
end,
272+
})
273+
242274
if config.event_handlers ~= nil then
243275
for _, handler in ipairs(config.event_handlers) do
244276
events.subscribe(handler)

lua/neo-tree/sources/common/commands.lua

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -169,43 +169,8 @@ local open_with_cmd = function(state, open_cmd, toggle_directory)
169169
end
170170
return nil
171171
else
172-
-- use last window if possible
173-
local suitable_window_found = false
174-
local nt = require("neo-tree")
175-
if nt.config.open_files_in_last_window then
176-
local prior_window = nt.get_prior_window()
177-
if prior_window > 0 then
178-
local success = pcall(vim.api.nvim_set_current_win, prior_window)
179-
if success then
180-
suitable_window_found = true
181-
end
182-
end
183-
end
184-
-- find a suitable window to open the file in
185-
if not suitable_window_found then
186-
if state.window.position == "right" then
187-
vim.cmd("wincmd t")
188-
else
189-
vim.cmd("wincmd w")
190-
end
191-
end
192-
local attempts = 0
193-
while attempts < 4 and vim.bo.filetype == "neo-tree" do
194-
attempts = attempts + 1
195-
vim.cmd("wincmd w")
196-
end
197-
-- TODO: make this configurable, see issue #43
198-
if vim.bo.filetype == "neo-tree" then
199-
-- Neo-tree must be the only window, restore it's status as a sidebar
200-
local winid = vim.api.nvim_get_current_win()
201-
local width = utils.get_value(state, "window.width", 40)
202-
vim.cmd("vsplit " .. node:get_id())
203-
vim.api.nvim_win_set_width(winid, width)
204-
else
205-
vim.cmd(open_cmd .. " " .. node:get_id())
206-
end
207-
local events = require("neo-tree.events")
208-
events.fire_event(events.FILE_OPENED, node:get_id())
172+
local path = node:get_id()
173+
utils.open_file(state, path, open_cmd)
209174
end
210175
end
211176

lua/neo-tree/utils.lua

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,15 @@ M.get_value = function(sourceObject, valuePath, defaultValue, strict_type_check)
269269
end
270270
end
271271

272+
M.is_floating = function(win_id)
273+
win_id = win_id or vim.api.nvim_get_current_win()
274+
local cfg = vim.api.nvim_win_get_config(win_id)
275+
if cfg.relative > "" or cfg.external then
276+
return true
277+
end
278+
return false
279+
end
280+
272281
M.map = function(tbl, fn)
273282
local t = {}
274283
for k, v in pairs(tbl) do
@@ -277,6 +286,53 @@ M.map = function(tbl, fn)
277286
return t
278287
end
279288

289+
---Open file in the appropriate window.
290+
---@param state table The state of the source
291+
---@param path string The file to open
292+
---@param open_cmd string The vimcommand to use to open the file
293+
M.open_file = function(state, path, open_cmd)
294+
open_cmd = open_cmd or "edit"
295+
if M.truthy(path) then
296+
-- use last window if possible
297+
local suitable_window_found = false
298+
local nt = require("neo-tree")
299+
if nt.config.open_files_in_last_window then
300+
local prior_window = nt.get_prior_window()
301+
if prior_window > 0 then
302+
local success = pcall(vim.api.nvim_set_current_win, prior_window)
303+
if success then
304+
suitable_window_found = true
305+
end
306+
end
307+
end
308+
-- find a suitable window to open the file in
309+
if not suitable_window_found then
310+
if state.window.position == "right" then
311+
vim.cmd("wincmd t")
312+
else
313+
vim.cmd("wincmd w")
314+
end
315+
end
316+
local attempts = 0
317+
while attempts < 4 and vim.bo.filetype == "neo-tree" do
318+
attempts = attempts + 1
319+
vim.cmd("wincmd w")
320+
end
321+
-- TODO: make this configurable, see issue #43
322+
if vim.bo.filetype == "neo-tree" then
323+
-- Neo-tree must be the only window, restore it's status as a sidebar
324+
local winid = vim.api.nvim_get_current_win()
325+
local width = M.get_value(state, "window.width", 40)
326+
vim.cmd("vsplit " .. path)
327+
vim.api.nvim_win_set_width(winid, width)
328+
else
329+
vim.cmd(open_cmd .. " " .. path)
330+
end
331+
local events = require("neo-tree.events")
332+
events.fire_event(events.FILE_OPENED, path)
333+
end
334+
end
335+
280336
M.reduce = function(list, memo, func)
281337
for _, i in ipairs(list) do
282338
memo = func(memo, i)
@@ -298,6 +354,7 @@ M.resolve_config_option = function(state, config_option, default_value)
298354
return opt
299355
end
300356
end
357+
301358
---The file system path separator for the current platform.
302359
M.path_separator = "/"
303360
M.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1

0 commit comments

Comments
 (0)