From 3633e728e0fde3fc2a6beba0c7aeee404c34559e Mon Sep 17 00:00:00 2001 From: kiyan Date: Sun, 26 Sep 2021 14:55:49 +0200 Subject: [PATCH] chore: refacto view setup and simplify the code --- README.md | 143 ++++++++++++++++-------------------- doc/nvim-tree-lua.txt | 154 ++++++++++++++++++++------------------- lua/nvim-tree.lua | 11 +-- lua/nvim-tree/view.lua | 161 ++++++++++++++++------------------------- 4 files changed, 212 insertions(+), 257 deletions(-) diff --git a/README.md b/README.md index 65d85c01..d436d4b6 100644 --- a/README.md +++ b/README.md @@ -71,12 +71,26 @@ require'nvim-tree'.setup { -- the command arguments as a list args = {} }, + + view = { + -- width of the window, can be either a number (columns) or a string in `%` + width = 30, + -- side of the tree, can be one of 'left' | 'right' | 'top' | 'bottom' + side = 'left', + -- if true the tree will resize itself after opening a file + auto_resize = false, + mappings = { + -- custom only false will merge the list with the default mappings + -- if true, it will only use your list to set the mappings + custom_only = false, + -- list of mappings to set on the tree manually + list = {} + } + } } ``` ```vim -let g:nvim_tree_side = 'right' "left by default -let g:nvim_tree_width = 40 "30 by default, can be width_in_columns or 'width_in_percent%' let g:nvim_tree_ignore = [ '.git', 'node_modules', '.cache' ] "empty by default let g:nvim_tree_gitignore = 1 "0 by default let g:nvim_tree_quit_on_open = 1 "0 by default, closes the tree when you open a file @@ -85,7 +99,6 @@ let g:nvim_tree_hide_dotfiles = 1 "0 by default, this option hides files and fol let g:nvim_tree_git_hl = 1 "0 by default, will enable file highlight for git attributes (can be used without the icons). let g:nvim_tree_highlight_opened_files = 1 "0 by default, will enable folder and file icon highlight for opened files/directories. let g:nvim_tree_root_folder_modifier = ':~' "This is the default. See :help filename-modifiers for more options -let g:nvim_tree_auto_resize = 0 "1 by default, will resize the tree to its saved width when opening a file let g:nvim_tree_add_trailing = 1 "0 by default, append a trailing slash to folder names let g:nvim_tree_group_empty = 1 " 0 by default, compact folders that only contain a single folder into one node in the file tree let g:nvim_tree_disable_window_picker = 1 "0 by default, will disable the window picker. @@ -155,7 +168,7 @@ let g:nvim_tree_icons = { nnoremap :NvimTreeToggle nnoremap r :NvimTreeRefresh nnoremap n :NvimTreeFindFile -" NvimTreeOpen, NvimTreeClose and NvimTreeFocus are also available if you need them +" NvimTreeOpen, NvimTreeClose, NvimTreeFocus and NvimTreeResize are also available if you need them set termguicolors " this variable must be enabled for colors to be applied properly @@ -167,7 +180,6 @@ highlight NvimTreeFolderIcon guibg=blue ### Default actions -- move around like in any vim buffer - `` or `o` on `..` will cd in the above directory - `` will cd in the directory under the cursor - `` will close current opened directory or parent @@ -198,88 +210,61 @@ highlight NvimTreeFolderIcon guibg=blue - Double left click acts like `` - Double right click acts like `` -### Setup +### Settings -You can disable default mappings with - -```vim -" let g:nvim_tree_disable_keybindings=1 -``` - -But you won't be able to map any keys from the setup with nvim_tree_bindings. Use with caution. - -You can use only your mappings with - -```vim -let g:nvim_tree_disable_default_keybindings = 1 -``` - -You can define your own keymaps with this syntax: - -```vim -lua <", "o" }, cb = ":lua some_func()"} - { key = "", mode = "v", cb = ":lua some_func()"} - } +The `list` option in `view.mappings.list` is a table of +```lua +-- key can be either a string or a table of string (lhs) +-- cb is the callback that will be called +-- mode is normal by default +local list = { + { key = {"", "o" }, cb = ":lua some_func()", mode = "n"} +} EOF ``` -Notes: - -- `key` can be either a string or a table of strings -- `mode` is `n` by default if you don't specify it -- `cb` is the command that will be called when the keymap is triggered - -If you don't use one of the options above, your keymaps will be added to the default keymaps. - -```vim -lua <", "o", "<2-LeftMouse>"}, cb = tree_cb("edit") }, - { key = {"<2-RightMouse>", ""}, cb = tree_cb("cd") }, - { key = "", cb = tree_cb("vsplit") }, - { key = "", cb = tree_cb("split") }, - { key = "", cb = tree_cb("tabnew") }, - { key = "<", cb = tree_cb("prev_sibling") }, - { key = ">", cb = tree_cb("next_sibling") }, - { key = "P", cb = tree_cb("parent_node") }, - { key = "", cb = tree_cb("close_node") }, - { key = "", cb = tree_cb("close_node") }, - { key = "", cb = tree_cb("preview") }, - { key = "K", cb = tree_cb("first_sibling") }, - { key = "J", cb = tree_cb("last_sibling") }, - { key = "I", cb = tree_cb("toggle_ignored") }, - { key = "H", cb = tree_cb("toggle_dotfiles") }, - { key = "R", cb = tree_cb("refresh") }, - { key = "a", cb = tree_cb("create") }, - { key = "d", cb = tree_cb("remove") }, - { key = "r", cb = tree_cb("rename") }, - { key = "", cb = tree_cb("full_rename") }, - { key = "x", cb = tree_cb("cut") }, - { key = "c", cb = tree_cb("copy") }, - { key = "p", cb = tree_cb("paste") }, - { key = "y", cb = tree_cb("copy_name") }, - { key = "Y", cb = tree_cb("copy_path") }, - { key = "gy", cb = tree_cb("copy_absolute_path") }, - { key = "[c", cb = tree_cb("prev_git_item") }, - { key = "]c", cb = tree_cb("next_git_item") }, - { key = "-", cb = tree_cb("dir_up") }, - { key = "s", cb = tree_cb("system_open") }, - { key = "q", cb = tree_cb("close") }, - { key = "g?", cb = tree_cb("toggle_help") }, - } -EOF +These are the default bindings: +```lua +local tree_cb = require'nvim-tree.config'.nvim_tree_callback +-- default mappings +local list = { + { key = {"", "o", "<2-LeftMouse>"}, cb = tree_cb("edit") }, + { key = {"<2-RightMouse>", ""}, cb = tree_cb("cd") }, + { key = "", cb = tree_cb("vsplit") }, + { key = "", cb = tree_cb("split") }, + { key = "", cb = tree_cb("tabnew") }, + { key = "<", cb = tree_cb("prev_sibling") }, + { key = ">", cb = tree_cb("next_sibling") }, + { key = "P", cb = tree_cb("parent_node") }, + { key = "", cb = tree_cb("close_node") }, + { key = "", cb = tree_cb("close_node") }, + { key = "", cb = tree_cb("preview") }, + { key = "K", cb = tree_cb("first_sibling") }, + { key = "J", cb = tree_cb("last_sibling") }, + { key = "I", cb = tree_cb("toggle_ignored") }, + { key = "H", cb = tree_cb("toggle_dotfiles") }, + { key = "R", cb = tree_cb("refresh") }, + { key = "a", cb = tree_cb("create") }, + { key = "d", cb = tree_cb("remove") }, + { key = "r", cb = tree_cb("rename") }, + { key = "", cb = tree_cb("full_rename") }, + { key = "x", cb = tree_cb("cut") }, + { key = "c", cb = tree_cb("copy") }, + { key = "p", cb = tree_cb("paste") }, + { key = "y", cb = tree_cb("copy_name") }, + { key = "Y", cb = tree_cb("copy_path") }, + { key = "gy", cb = tree_cb("copy_absolute_path") }, + { key = "[c", cb = tree_cb("prev_git_item") }, + { key = "]c", cb = tree_cb("next_git_item") }, + { key = "-", cb = tree_cb("dir_up") }, + { key = "s", cb = tree_cb("system_open") }, + { key = "q", cb = tree_cb("close") }, + { key = "g?", cb = tree_cb("toggle_help") }, +} ``` You can toggle the help UI by pressing `g?`. -## Note - -This plugin is very fast because it uses the `libuv` `scandir` and `scandir_next` functions instead of spawning an `ls` process which can get slow on large files when combining with `stat` to get file informations. - ## Features - Open file in current buffer or in split with FzF like bindings (``, ``, ``, ``) diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index c1e49c88..26f6ea23 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -84,10 +84,19 @@ function. cmd = nil, args = {} }, + view = { + width = 30, + side = 'left', + auto_resize = false, + mappings = { + custom_only = false, + list = {} + } + } } < -As options are currently being migrated, configuration of global options in +As options are currently being migrated, configuration of global options in *nvim-tree-options* should be done BEFORE the setup call. Here is a list of the options available in the setup call: @@ -136,15 +145,15 @@ Here is a list of the options available in the setup call: type: `boolean` default: `false` - - |update_focused_file.update_cwd|: update the root directory of the tree to the one - of the folder containing the file if the file is not under the current root + - |update_focused_file.update_cwd|: update the root directory of the tree to the one + of the folder containing the file if the file is not under the current root directory. Only relevant when |update_focused_file.enable| is `true` type: `boolean` default: `false` - |update_focused_file.ignore_list|: list of buffer names and filetypes that will not - update the root dir of the tree if the file isn't found under the current root - directory. Only relevant when |update_focused_file.update_cwd| is `true` and + update the root dir of the tree if the file isn't found under the current root + directory. Only relevant when |update_focused_file.update_cwd| is `true` and |update_focused_file.enable| is `true`. type: `{string}` default: `{}` @@ -164,6 +173,33 @@ Here is a list of the options available in the setup call: type: `boolean` default: false +- |view|: window / buffer setup + +- |view.width|: width of the window, can be either a `%` string or + a number representing columns + type: `string | number` + default: `30` + +- |view.side|: side of the tree, can be one of 'left' | 'right' | 'bottom' | 'top' + Note that bottom/top are not working correctly yet. + type: `string` + default: 'left' + +- |view.auto_resize|: auto resize the tree after opening a file + type: `boolean` + default: false + +- |view.mappings|: configuration options for keymaps + +- |view.mappings.custom_only|: will use only the provided user mappings and not the default + otherwise, extends the default mappings with the provided user mappings + type: `boolean` + default: false + +- |view,mappings.list|: a list of keymaps that will extend or override the default keymaps + type: list of `{ key: table of strings or string, mode: string (vim-mode), cb: callback function as a string }` + default: {} + ============================================================================== OPTIONS *nvim-tree-options* @@ -214,7 +250,7 @@ to render the icons. The `files` key can only work if `nvim-web-devicons` is installed and in your |runtimepath| (https://github.com/kyazdani42/nvim-web-devicons) if folder is 1, you can also set `folder_arrows = 1` to show small arrows -next to the folder icons but this will not work when you set +next to the folder icons but this will not work when you set |g:nvim_tree_indent_markers| (because of UI conflict). |g:nvim_tree_highlight_opened_files| *g:nvim_tree_highlight_opened_files* @@ -278,17 +314,6 @@ Can be `0` or `1`. When `1`, will close the tree when a file is opened. Applies to: `edit`, `vsplit`, `split`, `tabnew`. Default is 0 -|g:nvim_tree_disable_keybindings| *g:nvim_tree_disable_keybindings* - -Can be `0` or `1`. When `1`, will disable all keybindings by the plugin. -|g:nvim_tree_bindings| as well as default bindings will not take effect. -Default is 0 - -|g:nvim_tree_disable_default_keybindings| *g:nvim_tree_disable_default_keybindings* - -Can be `0` or `1`. When `1`, will disable default keybindings and use only the one you defined. -Default is 0 - |g:nvim_tree_indent_markers| *g:nvim_tree_indent_markers* Can be `0` or `1`. When `1`, will display indent markers when folders are open @@ -306,12 +331,6 @@ In what format to show root folder. See `:help filename-modifiers` for available options. Default is `:~` -|g:nvim_tree_auto_resize| *g:nvim_tree_auto_resize* - -Can be 0 or 1. When 1, it will resize the tree to it's saved width -when opening a new file. -Default is 1 - |g:nvim_tree_add_trailing| *g:nvim_tree_add_trailing* Can be 0 or 1. When 1, appends a trailing slash to folder names. @@ -382,7 +401,7 @@ path to be inside the closed folder when 1, and on the parent folder when 0. ============================================================================== INFORMATIONS *nvim-tree-info* -|KeyBindings| *nvim-tree-keybindings* +|Mappings| *nvim-tree-mappings* - type `g?` to see the help UI with keybindings - move around like in any vim buffer @@ -421,61 +440,46 @@ INFORMATIONS *nvim-tree-info* - Double left click acts like '' - Double right click acts like '' -|g:nvim_tree_bindings| *g:nvim_tree_bindings* - -You can define your own keymaps with this syntax: +Defaults to: > lua <", "o" }, cb = ":lua some_func()"} - { key = "", mode = "v", cb = ":lua some_func()"} - } - EOF + local tree_cb = require'nvim-tree.config'.nvim_tree_callback + local list = { + { key = {"", "o", "<2-LeftMouse>"}, cb = tree_cb("edit") }, + { key = {"<2-RightMouse>", ""}, cb = tree_cb("cd") }, + { key = "", cb = tree_cb("vsplit") }, + { key = "", cb = tree_cb("split") }, + { key = "", cb = tree_cb("tabnew") }, + { key = "<", cb = tree_cb("prev_sibling") }, + { key = ">", cb = tree_cb("next_sibling") }, + { key = "P", cb = tree_cb("parent_node") }, + { key = "", cb = tree_cb("close_node") }, + { key = "", cb = tree_cb("close_node") }, + { key = "", cb = tree_cb("preview") }, + { key = "K", cb = tree_cb("first_sibling") }, + { key = "J", cb = tree_cb("last_sibling") }, + { key = "I", cb = tree_cb("toggle_ignored") }, + { key = "H", cb = tree_cb("toggle_dotfiles") }, + { key = "R", cb = tree_cb("refresh") }, + { key = "a", cb = tree_cb("create") }, + { key = "d", cb = tree_cb("remove") }, + { key = "r", cb = tree_cb("rename") }, + { key = "", cb = tree_cb("full_rename") }, + { key = "x", cb = tree_cb("cut") }, + { key = "c", cb = tree_cb("copy") }, + { key = "p", cb = tree_cb("paste") }, + { key = "y", cb = tree_cb("copy_name") }, + { key = "Y", cb = tree_cb("copy_path") }, + { key = "gy", cb = tree_cb("copy_absolute_path") }, + { key = "[c", cb = tree_cb("prev_git_item") }, + { key = "]c", cb = tree_cb("next_git_item") }, + { key = "-", cb = tree_cb("dir_up") }, + { key = "s", cb = tree_cb("system_open") }, + { key = "q", cb = tree_cb("close") }, + { key = "g?", cb = tree_cb("toggle_help") }, + } < -`key` can be either a string or a table of strings -`mode` is `n` by default if you don't specify it -`cb` is the command that will be called when the keymap is triggered -Default mappings: -> - lua <", "o", "<2-LeftMouse>"}, cb = tree_cb("edit") }, - { key = {"<2-RightMouse>", ""}, cb = tree_cb("cd") }, - { key = "", cb = tree_cb("vsplit") }, - { key = "", cb = tree_cb("split") }, - { key = "", cb = tree_cb("tabnew") }, - { key = "<", cb = tree_cb("prev_sibling") }, - { key = ">", cb = tree_cb("next_sibling") }, - { key = "P", cb = tree_cb("parent_node") }, - { key = "", cb = tree_cb("close_node") }, - { key = "", cb = tree_cb("close_node") }, - { key = "", cb = tree_cb("preview") }, - { key = "K", cb = tree_cb("first_sibling") }, - { key = "J", cb = tree_cb("last_sibling") }, - { key = "I", cb = tree_cb("toggle_ignored") }, - { key = "H", cb = tree_cb("toggle_dotfiles") }, - { key = "R", cb = tree_cb("refresh") }, - { key = "a", cb = tree_cb("create") }, - { key = "d", cb = tree_cb("remove") }, - { key = "r", cb = tree_cb("rename") }, - { key = "", cb = tree_cb("full_rename") }, - { key = "x", cb = tree_cb("cut") }, - { key = "c", cb = tree_cb("copy") }, - { key = "p", cb = tree_cb("paste") }, - { key = "y", cb = tree_cb("copy_name") }, - { key = "Y", cb = tree_cb("copy_path") }, - { key = "gy", cb = tree_cb("copy_absolute_path") }, - { key = "[c", cb = tree_cb("prev_git_item") }, - { key = "]c", cb = tree_cb("next_git_item") }, - { key = "-", cb = tree_cb("dir_up") }, - { key = "s", cb = tree_cb("system_open") }, - { key = "q", cb = tree_cb("close") }, - { key = "g?", cb = tree_cb("toggle_help") }, - } - EOF -< |Features| *nvim-tree-features* File icons with vim-devicons. diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 21192171..b8ef2399 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -370,9 +370,6 @@ local function setup_autocommands(opts) au BufWritePost * lua require'nvim-tree'.refresh() au User FugitiveChanged,NeogitStatusRefreshed lua require'nvim-tree'.refresh() - - """ deletes the existing buffer when saved in a session to avoid conflicts - au SessionLoadPost * lua require'nvim-tree.view'._wipe_rogue_buffer() ]] if opts.lsp_diagnostics then @@ -429,7 +426,7 @@ function M.setup(conf) _config.ignore_ft_on_setup = opts.ignore_ft_on_setup require'nvim-tree.colors'.setup() - require'nvim-tree.view'.setup() + require'nvim-tree.view'.setup(opts.view or {}) require'nvim-tree.diagnostics'.setup(opts) setup_autocommands(opts) @@ -452,7 +449,11 @@ local function startup_check_new_setup() "nvim_tree_system_open_command_args", "nvim_tree_follow", "nvim_tree_follow_update_path", - "nvim_tree_lsp_diagnostics" + "nvim_tree_lsp_diagnostics", + "nvim_tree_auto_resize", + "nvim_tree_bindings", + "nvim_tree_disable_keybindings", + "nvim_tree_disable_default_keybindings", } local x = vim.tbl_filter(function(v) diff --git a/lua/nvim-tree/view.lua b/lua/nvim-tree/view.lua index 958b3208..ca94f389 100644 --- a/lua/nvim-tree/view.lua +++ b/lua/nvim-tree/view.lua @@ -9,8 +9,6 @@ end M.View = { bufnr = nil, tabpages = {}, - width = 30, - side = 'left', winopts = { relativenumber = false, number = false, @@ -42,7 +40,7 @@ M.View = { { name = 'filetype', val = 'NvimTree' }, { name = 'bufhidden', val = 'hide' } }, - bindings = { + mappings = { { key = {"", "o", "<2-LeftMouse>"}, cb = M.nvim_tree_callback("edit") }, { key = {"<2-RightMouse>", ""}, cb = M.nvim_tree_callback("cd") }, { key = "", cb = M.nvim_tree_callback("vsplit") }, @@ -78,91 +76,24 @@ M.View = { } } ----Find a rogue NvimTree buffer that might have been spawned by i.e. a session. ----@return integer|nil -local function find_rogue_buffer() - for _, v in ipairs(a.nvim_list_bufs()) do - if vim.fn.bufname(v) == "NvimTree" then - return v +local function wipe_rogue_buffer() + for _, bn in ipairs(a.nvim_list_bufs()) do + if vim.fn.bufname(bn) == "NvimTree" then + return pcall(a.nvim_buf_delete, bn, { force = true }) end end - return nil end ----Find pre-existing NvimTree buffer, delete its windows then wipe it. ----@private -function M._wipe_rogue_buffer() - local bn = find_rogue_buffer() - if bn then - local win_ids = vim.fn.win_findbuf(bn) - for _, id in ipairs(win_ids) do - if vim.fn.win_gettype(id) ~= "autocmd" then - a.nvim_win_close(id, true) - end - end - - a.nvim_buf_set_name(bn, "") - vim.schedule(function () - pcall(a.nvim_buf_delete, bn, {}) - end) - end -end - -local function warn_wrong_mapping() - local warn_str = "Wrong configuration for keymaps, refer to the new documentation. Keymaps setup aborted" - require'nvim-tree.utils'.echo_warning(warn_str) -end - -local HAS_LOADED = false --- set user options and create tree buffer (should never be wiped) -function M.setup() - M.View.side = vim.g.nvim_tree_side or M.View.side - M.View.width = vim.g.nvim_tree_width or M.View.width - - if not HAS_LOADED then - M.View.bufnr = a.nvim_create_buf(false, false) - HAS_LOADED = true - end - - if not pcall(a.nvim_buf_set_name, M.View.bufnr, 'NvimTree') then - M._wipe_rogue_buffer() - a.nvim_buf_set_name(M.View.bufnr, 'NvimTree') - end +local function create_buffer() + wipe_rogue_buffer() + M.View.bufnr = a.nvim_create_buf(false, false) + a.nvim_buf_set_name(M.View.bufnr, 'NvimTree') for _, opt in ipairs(M.View.bufopts) do vim.bo[M.View.bufnr][opt.name] = opt.val end - vim.cmd "augroup NvimTreeView" - vim.cmd "au!" - vim.cmd "au BufWinEnter,BufWinLeave * lua require'nvim-tree.view'._prevent_buffer_override()" - vim.cmd "au BufEnter,BufNewFile * lua require'nvim-tree'.open_on_directory()" - vim.cmd "augroup END" - - if vim.g.nvim_tree_disable_keybindings == 1 then - return - end - - local user_mappings = vim.g.nvim_tree_bindings or {} - if vim.g.nvim_tree_disable_default_keybindings == 1 then - M.View.bindings = user_mappings - else - local ok, result = pcall(vim.fn.extend, M.View.bindings, user_mappings) - if not ok then - -- TODO: remove this in a few weeks - warn_wrong_mapping() - return - else - M.View.bindings = result - end - end - - for _, b in pairs(M.View.bindings) do - -- TODO: remove this in a few weeks - if type(b) == "string" then - warn_wrong_mapping() - break - end + for _, b in pairs(M.View.mappings) do if type(b.key) == "table" then for _, key in pairs(b.key) do a.nvim_buf_set_keymap(M.View.bufnr, b.mode or 'n', key, b.cb, { noremap = true, silent = true, nowait = true }) @@ -173,7 +104,37 @@ function M.setup() end end -local goto_tbl = { +local DEFAULT_CONFIG = { + width = 30, + side = 'left', + auto_resize = false, + mappings = { + custom_only = false, + list = {} + } +} + +function M.setup(opts) + local options = vim.tbl_deep_extend('force', DEFAULT_CONFIG, opts) + M.View.side = options.side + M.View.width = options.width + M.View.auto_resize = opts.auto_resize + if options.mappings.custom_only then + M.View.mappings = options.mappings.list + else + M.View.mappings = vim.fn.extend(M.View.mappings, options.mappings.list) + end + + vim.cmd "augroup NvimTreeView" + vim.cmd "au!" + vim.cmd "au BufWinEnter,BufWinLeave * lua require'nvim-tree.view'._prevent_buffer_override()" + vim.cmd "au BufEnter,BufNewFile * lua require'nvim-tree'.open_on_directory()" + vim.cmd "augroup END" + + create_buffer() +end + +local move_cmd = { right = 'h', left = 'l', top = 'j', @@ -204,7 +165,7 @@ function M._prevent_buffer_override() if #vim.api.nvim_list_wins() < 2 then vim.cmd("vsplit") else - vim.cmd("wincmd "..goto_tbl[M.View.side]) + vim.cmd("wincmd "..move_cmd[M.View.side]) end vim.cmd("buffer "..curbuf) M.resize() @@ -254,7 +215,7 @@ local function get_width() end function M.resize() - if vim.g.nvim_tree_auto_resize == 0 or not a.nvim_win_is_valid(M.get_winnr()) then + if not M.View.auto_resize or not a.nvim_win_is_valid(M.get_winnr()) then return end @@ -295,15 +256,13 @@ local function open_window() M.View.tabpages[tabpage] = vim.tbl_extend("force", M.View.tabpages[tabpage] or {help = false}, {winnr = winnr}) end -function M.open(options) - options = options or { focus_tree = true } - if not a.nvim_buf_is_valid(M.View.bufnr) then - HAS_LOADED = false - end +local function is_buf_valid(bufnr) + return a.nvim_buf_is_valid(bufnr) and a.nvim_buf_is_loaded(bufnr) +end - if not HAS_LOADED then - M.setup() - HAS_LOADED = true +function M.open(options) + if not is_buf_valid(M.View.bufnr) then + create_buffer() end if not M.win_open() then @@ -315,21 +274,27 @@ function M.open(options) set_local(k, v) end vim.cmd ":wincmd =" - if not options.focus_tree then + + local opts = options or { focus_tree = true } + if not opts.focus_tree then vim.cmd("wincmd p") end end +local function get_existing_buffers() + return vim.tbl_filter( + function(buf) + return a.nvim_buf_is_valid(buf) and vim.fn.buflisted(buf) == 1 + end, + a.nvim_list_bufs() + ) +end + function M.close() if not M.win_open() then return end if #a.nvim_list_wins() == 1 then - local ok_bufs = vim.tbl_filter( - function(buf) - return a.nvim_buf_is_valid(buf) and vim.fn.buflisted(buf) == 1 - end, - a.nvim_list_bufs() - ) - if #ok_bufs > 0 then + local existing_bufs = get_existing_buffers() + if #existing_bufs > 0 then vim.cmd "sbnext" else vim.cmd "new"