From 1e67a7c6f4d25e91c107dda5646f1cdcfcedeb28 Mon Sep 17 00:00:00 2001 From: kyazdani42 Date: Mon, 8 Jun 2020 11:09:53 +0200 Subject: [PATCH 1/5] refacto: export window options in config --- lua/lib/config.lua | 17 +++++++++++++++++ lua/lib/tree.lua | 28 ++++++---------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lua/lib/config.lua b/lua/lib/config.lua index 59fffdd5..97c2b2ee 100644 --- a/lua/lib/config.lua +++ b/lua/lib/config.lua @@ -57,4 +57,21 @@ function M.get_bindings() } end +function M.window_options() + local opts = {} + if vim.g.lua_tree_side == 'right' then + opts.side = 'L' + opts.open_command = 'h' + opts.preview_command = 'l' + opts.split_command = 'nosplitright' + else + opts.side = 'H' + opts.open_command = 'l' + opts.preview_command = 'h' + opts.split_command = 'splitright' + end + + return opts +end + return M diff --git a/lua/lib/tree.lua b/lua/lib/tree.lua index 476dc69b..e73bb692 100644 --- a/lua/lib/tree.lua +++ b/lua/lib/tree.lua @@ -8,6 +8,8 @@ local pops = require'lib.populate' local populate = pops.populate local refresh_entries = pops.refresh_entries +local window_opts = config.window_options() + local M = {} M.Tree = { @@ -16,7 +18,6 @@ M.Tree = { cwd = nil, win_width = vim.g.lua_tree_width or 30, loaded = false, - side = 'H', bufnr = nil, winnr = nil, buf_options = { @@ -36,10 +37,6 @@ M.Tree = { } } -if vim.g.lua_tree_side == 'right' then - M.Tree.side = 'L' -end - function M.init(with_open, with_render) M.Tree.cwd = luv.cwd() populate(M.Tree.entries, M.Tree.cwd, M.Tree) @@ -178,18 +175,10 @@ function M.set_index_and_redraw(fname) end function M.open_file(mode, filename) - if vim.g.lua_tree_side == 'right' then - api.nvim_command('noautocmd wincmd h') - else - api.nvim_command('noautocmd wincmd l') - end + api.nvim_command('noautocmd wincmd '..window_opts.open_command) if mode == 'preview' then api.nvim_command(string.format("edit %s", filename)) - if vim.g.lua_tree_side == 'right' then - api.nvim_command('noautocmd wincmd l') - else - api.nvim_command('noautocmd wincmd h') - end + api.nvim_command('noautocmd wincmd '..window_opts.preview_command) else api.nvim_command(string.format("%s %s", mode, filename)) end @@ -246,18 +235,13 @@ local function create_buf() api.nvim_command('setlocal '..opt) end - if M.Tree.side == 'L' then - api.nvim_command('setlocal nosplitright') - else - api.nvim_command('setlocal splitright') - end - + api.nvim_command('setlocal '..window_opts.split_command) set_mappings() end local function create_win() api.nvim_command("vsplit") - api.nvim_command("wincmd "..M.Tree.side) + api.nvim_command("wincmd "..window_opts.side) api.nvim_command("vertical resize "..M.Tree.win_width) M.Tree.winnr = api.nvim_get_current_win() From 18dac0ed84f08d9f508997052af3496d2f4768f9 Mon Sep 17 00:00:00 2001 From: kyazdani42 Date: Mon, 8 Jun 2020 11:23:30 +0200 Subject: [PATCH 2/5] add .luacheckrc and fix linter issues --- .luacheckrc | 13 +++++++++++++ lua/lib/colors.lua | 4 ++-- lua/lib/fs.lua | 4 ++-- lua/lib/git.lua | 4 ++-- lua/lib/populate.lua | 2 +- lua/lib/renderer.lua | 27 +++++++++++++-------------- lua/lib/tree.lua | 10 +++++++--- 7 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 00000000..92d06f7b --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,13 @@ +-- vim: ft=lua tw=80 + +-- Don't report unused self arguments of methods. +self = false + +ignore = { + "631", -- max_line_length +} + +-- Global objects defined by the C code +read_globals = { + "vim", +} diff --git a/lua/lib/colors.lua b/lua/lib/colors.lua index 297577d5..0e691bed 100644 --- a/lua/lib/colors.lua +++ b/lua/lib/colors.lua @@ -25,7 +25,7 @@ local function get_colors() } end -local function get_hl_groups() +local function get_hl_groups() local colors = get_colors() return { @@ -96,7 +96,7 @@ M.hl_groups = { ['ejs'] = 'HtmlIcon'; } -local function get_links() +local function get_links() return { FolderName = 'Directory', Normal = 'Normal', diff --git a/lua/lib/fs.lua b/lua/lib/fs.lua index 9282e58b..75dcc364 100644 --- a/lua/lib/fs.lua +++ b/lua/lib/fs.lua @@ -28,7 +28,7 @@ local function create_file(file) end local function get_num_entries(iter) - i = 0 + local i = 0 for _ in iter do i = i + 1 end @@ -37,7 +37,7 @@ end function M.create(node) if node.name == '..' then return end - + local add_into if node.entries ~= nil then add_into = node.absolute_path..'/' diff --git a/lua/lib/git.lua b/lua/lib/git.lua index b4328f55..80ccb06e 100644 --- a/lua/lib/git.lua +++ b/lua/lib/git.lua @@ -51,8 +51,8 @@ local function create_root(cwd) return true end -function M.update_status(entries, cwd) - local cwd = cwd:gsub(' ', '\\ ') +function M.update_status(entries, _cwd) + local cwd = _cwd:gsub(' ', '\\ ') local git_root, git_status = get_git_root(cwd) if not git_root then if not create_root(cwd) then diff --git a/lua/lib/populate.lua b/lua/lib/populate.lua index c6d24bf2..3784e0a0 100644 --- a/lua/lib/populate.lua +++ b/lua/lib/populate.lua @@ -125,7 +125,7 @@ function M.refresh_entries(entries, cwd) if not named_entries[name] then local n = e.fn(cwd, name) - local idx = 1 + idx = 1 if prev then idx = entries_idx[prev] + 1 end diff --git a/lua/lib/renderer.lua b/lua/lib/renderer.lua index 05552015..388bd2c1 100644 --- a/lua/lib/renderer.lua +++ b/lua/lib/renderer.lua @@ -11,8 +11,8 @@ local namespace_id = api.nvim_create_namespace('LuaTreeHighlights') local icon_state = config.get_icon_state() local get_folder_icon = function() return "" end -local set_folder_hl = function(index, depth, git_icon_len) - table.insert(hl, {'LuaTreeFolderName', index, depth+git_icon_len, -1}) +local set_folder_hl = function(line, depth, git_icon_len) + table.insert(hl, {'LuaTreeFolderName', line, depth+git_icon_len, -1}) end if icon_state.show_folder_icon then @@ -23,9 +23,9 @@ if icon_state.show_folder_icon then return icon_state.icons.folder_icons.default .. " " end end - set_folder_hl = function(index, depth, icon_len, name_len) - table.insert(hl, {'LuaTreeFolderName', index, depth+icon_len, depth+icon_len+name_len}) - table.insert(hl, {'LuaTreeFolderIcon', index, depth, depth+icon_len}) + set_folder_hl = function(line, depth, icon_len, name_len) + table.insert(hl, {'LuaTreeFolderName', line, depth+icon_len, depth+icon_len+name_len}) + table.insert(hl, {'LuaTreeFolderIcon', line, depth, depth+icon_len}) end end @@ -33,8 +33,9 @@ local get_file_icon = function() return "" end if icon_state.show_file_icon then local web_devicons = require'nvim-web-devicons' - get_file_icon = function(fname, extension, index, depth) - local icon, hl_group = web_devicons.get_icon(fname, extension) + get_file_icon = function(fname, extension, line, depth) + local hl_group + local icon, _ = web_devicons.get_icon(fname, extension) -- TODO: remove this hl_group and make this in nvim-web-devicons if #extension == 0 then hl_group = colors.hl_groups[fname] @@ -42,7 +43,7 @@ if icon_state.show_file_icon then hl_group = colors.hl_groups[extension] end if hl_group and icon then - table.insert(hl, { 'LuaTree'..hl_group, index, depth, depth + #icon }) + table.insert(hl, { 'LuaTree'..hl_group, line, depth, depth + #icon }) return icon.." " else return icon_state.icons.default and icon_state.icons.default.." " or "" @@ -52,10 +53,8 @@ if icon_state.show_file_icon then end local get_git_icons = function() return "" end -local git_icon_state = {} if icon_state.show_git_icon then - - git_icon_state = { + local git_icon_state = { ["M "] = { { icon = icon_state.icons.git_icons.staged, hl = "LuaTreeGitStaged" } }, [" M"] = { { icon = icon_state.icons.git_icons.unstaged, hl = "LuaTreeGitDirty" } }, ["MM"] = { @@ -77,14 +76,14 @@ if icon_state.show_git_icon then dirty = { { icon = icon_state.icons.git_icons.unstaged, hl = "LuaTreeGitDirty" } }, } - get_git_icons = function(node, index, depth, icon_len) + get_git_icons = function(node, line, depth, icon_len) local git_status = node.git_status if not git_status then return "" end local icon = "" local icons = git_icon_state[git_status] for _, v in ipairs(icons) do - table.insert(hl, { v.hl, index, depth+icon_len+#icon, depth+icon_len+#icon+#v.icon }) + table.insert(hl, { v.hl, line, depth+icon_len+#icon, depth+icon_len+#icon+#v.icon }) icon = icon..v.icon.." " end @@ -166,7 +165,7 @@ function M.draw(tree, reload) update_draw_data(tree, 0) end - api.nvim_buf_set_lines(tree.bufnr, 0, -1, false, lines) + api.nvim_buf_set_lines(tree.bufnr, 0, -1, false, lines) M.render_hl(tree.bufnr) if #lines > cursor[1] then api.nvim_win_set_cursor(tree.winnr, cursor) diff --git a/lua/lib/tree.lua b/lua/lib/tree.lua index e73bb692..78543032 100644 --- a/lua/lib/tree.lua +++ b/lua/lib/tree.lua @@ -21,8 +21,12 @@ M.Tree = { bufnr = nil, winnr = nil, buf_options = { - 'sidescroll=5', 'noswapfile', 'splitbelow', - 'noruler', 'noshowmode', 'noshowcmd' + 'sidescroll=5', + 'noswapfile', + 'splitbelow', + 'noruler', + 'noshowmode', + 'noshowcmd' }, win_options = { relativenumber = false, @@ -114,7 +118,7 @@ local function refresh_nodes(node) end function M.refresh_tree() - local stat = luv.fs_stat(M.Tree.cwd) + -- local stat = luv.fs_stat(M.Tree.cwd) -- if stat.mtime.sec ~= M.Tree.last_modified then refresh_nodes(M.Tree) -- end From 25c32283b8b0aa03cbbdd3616c683b79f1d3fd15 Mon Sep 17 00:00:00 2001 From: kyazdani42 Date: Mon, 8 Jun 2020 11:41:57 +0200 Subject: [PATCH 3/5] rename lib/tree.lua to lib/lib.lua --- lua/lib/{tree.lua => lib.lua} | 0 lua/tree.lua | 50 +++++++++++++++++------------------ 2 files changed, 25 insertions(+), 25 deletions(-) rename lua/lib/{tree.lua => lib.lua} (100%) diff --git a/lua/lib/tree.lua b/lua/lib/lib.lua similarity index 100% rename from lua/lib/tree.lua rename to lua/lib/lib.lua diff --git a/lua/tree.lua b/lua/tree.lua index 6e6f3c63..fff830b4 100644 --- a/lua/tree.lua +++ b/lua/tree.lua @@ -1,5 +1,5 @@ local luv = vim.loop -local tree = require'lib.tree' +local lib = require'lib.lib' local colors = require'lib.colors' local renderer = require'lib.renderer' local fs = require'lib.fs' @@ -8,27 +8,27 @@ local api = vim.api local M = {} function M.toggle() - if tree.win_open() then - tree.close() + if lib.win_open() then + lib.close() else - tree.open() + lib.open() end end function M.close() - if tree.win_open() then - tree.close() + if lib.win_open() then + lib.close() end end function M.open() - if not tree.win_open() then - tree.open() + if not lib.win_open() then + lib.open() end end function M.on_keypress(mode) - local node = tree.get_node_at_cursor() + local node = lib.get_node_at_cursor() if not node then return end if mode == 'create' then @@ -41,13 +41,13 @@ function M.on_keypress(mode) if mode == 'preview' then if node.entries ~= nil or node.name == '..' then return end - return tree.open_file(mode, node.absolute_path) + return lib.open_file(mode, node.absolute_path) end if node.name == ".." then - return tree.change_dir("..") + return lib.change_dir("..") elseif mode == "cd" and node.entries ~= nil then - return tree.change_dir(node.absolute_path) + return lib.change_dir(node.absolute_path) elseif mode == "cd" then return end @@ -56,16 +56,16 @@ function M.on_keypress(mode) local stat = luv.fs_stat(node.link_to) -- TODO: potentially CD here if stat.type == 'directory' then return end - tree.open_file(mode, node.link_to) + lib.open_file(mode, node.link_to) elseif node.entries ~= nil then - tree.unroll_dir(node) + lib.unroll_dir(node) else - tree.open_file(mode, node.absolute_path) + lib.open_file(mode, node.absolute_path) end end function M.refresh() - tree.refresh_tree() + lib.refresh_tree() end function M.on_enter() @@ -79,7 +79,7 @@ function M.on_enter() end local should_open = vim.g.lua_tree_auto_open == 1 and (bufname == '' or is_dir) colors.setup() - tree.init(should_open, should_open) + lib.init(should_open, should_open) end local function is_file_readable(fname) @@ -92,12 +92,12 @@ local function find_file() local bufname = api.nvim_buf_get_name(api.nvim_get_current_buf()) if not is_file_readable(bufname) then return end - tree.set_index_and_redraw(bufname) + lib.set_index_and_redraw(bufname) end function M.on_leave() vim.defer_fn(function() - if #api.nvim_list_wins() == 1 and tree.win_open() then + if #api.nvim_list_wins() == 1 and lib.win_open() then api.nvim_command(':qa!') end end, 50) @@ -105,18 +105,18 @@ end local function update_root_dir() local bufname = api.nvim_buf_get_name(api.nvim_get_current_buf()) - if not is_file_readable(bufname) or not tree.Tree.cwd then return end + if not is_file_readable(bufname) or not lib.Tree.cwd then return end -- this logic is a hack -- depending on vim-rooter or autochdir, it would not behave the same way when those two are not enabled -- until i implement multiple workspaces/project, it should stay like this - if bufname:match(tree.Tree.cwd:gsub('(%-)', '(%%-)'):gsub('(%.)', '(%%.)')) ~= nil then + if bufname:match(lib.Tree.cwd:gsub('(%-)', '(%%-)'):gsub('(%.)', '(%%.)')) ~= nil then return end local new_cwd = luv.cwd() - if tree.Tree.cwd == new_cwd then return end + if lib.Tree.cwd == new_cwd then return end - tree.change_dir(new_cwd) + lib.change_dir(new_cwd) end function M.buf_enter() @@ -128,11 +128,11 @@ end function M.reset_highlight() colors.setup() - renderer.render_hl(tree.Tree.bufnr) + renderer.render_hl(lib.Tree.bufnr) end function M.xdg_open() - local node = tree.get_node_at_cursor() + local node = lib.get_node_at_cursor() -- TODO: this should open symlink targets if not node or node.entries or node.link_to then return end From 899fb177e0e3a308fe6fa9e27b38160952ce74f4 Mon Sep 17 00:00:00 2001 From: kyazdani42 Date: Mon, 8 Jun 2020 12:33:42 +0200 Subject: [PATCH 4/5] use path to matching str in lua/tree.lua --- lua/tree.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lua/tree.lua b/lua/tree.lua index fff830b4..99c7872f 100644 --- a/lua/tree.lua +++ b/lua/tree.lua @@ -3,6 +3,7 @@ local lib = require'lib.lib' local colors = require'lib.colors' local renderer = require'lib.renderer' local fs = require'lib.fs' +local utils = require'lib.utils' local api = vim.api local M = {} @@ -110,7 +111,7 @@ local function update_root_dir() -- this logic is a hack -- depending on vim-rooter or autochdir, it would not behave the same way when those two are not enabled -- until i implement multiple workspaces/project, it should stay like this - if bufname:match(lib.Tree.cwd:gsub('(%-)', '(%%-)'):gsub('(%.)', '(%%.)')) ~= nil then + if bufname:match(utils.path_to_matching_str(lib.Tree.cwd)) then return end local new_cwd = luv.cwd() From 896cc1619aa554e4310ac0b9662ef5272784d2b8 Mon Sep 17 00:00:00 2001 From: kyazdani42 Date: Tue, 9 Jun 2020 18:59:32 +0200 Subject: [PATCH 5/5] fix various issues, and add a comment because of a bug in glibc --- lua/lib/git.lua | 2 +- lua/lib/populate.lua | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lua/lib/git.lua b/lua/lib/git.lua index 80ccb06e..3bbb6ae6 100644 --- a/lua/lib/git.lua +++ b/lua/lib/git.lua @@ -52,7 +52,7 @@ local function create_root(cwd) end function M.update_status(entries, _cwd) - local cwd = _cwd:gsub(' ', '\\ ') + local cwd = _cwd:gsub(' ', '\\ '):gsub('%[', '\\['):gsub('%(', '\\(') local git_root, git_status = get_git_root(cwd) if not git_root then if not create_root(cwd) then diff --git a/lua/lib/populate.lua b/lua/lib/populate.lua index 3784e0a0..365e89fc 100644 --- a/lua/lib/populate.lua +++ b/lua/lib/populate.lua @@ -37,6 +37,11 @@ local function file_new(cwd, name) } end +-- TODO-INFO: sometimes fs_realpath returns nil +-- I expect this be a bug in glibc, because it fails to retrieve the path for some +-- links (for instance libr2.so in /usr/lib) and thus even with a C program realpath fails +-- when it has no real reason to. Maybe there is a reason, but errno is definitely wrong. +-- So we need to check for link_to ~= nil when adding new links to the main tree local function link_new(cwd, name) local absolute_path = cwd..'/'..name local link_to = luv.fs_realpath(absolute_path) @@ -114,9 +119,9 @@ function M.refresh_entries(entries, cwd) end local all = { - { entries = dirs, fn = dir_new }, - { entries = links, fn = link_new }, - { entries = files, fn = file_new } + { entries = dirs, fn = dir_new, check = function(_, abs) return luv.fs_access(abs, 'R') end }, + { entries = links, fn = link_new, check = function(name) return name ~= nil end }, + { entries = files, fn = file_new, check = function() return true end } } local prev = nil @@ -124,6 +129,9 @@ function M.refresh_entries(entries, cwd) for _, name in ipairs(e.entries) do if not named_entries[name] then local n = e.fn(cwd, name) + if not e.check(n.link_to, n.absolute_path) then + goto continue + end idx = 1 if prev then @@ -134,6 +142,7 @@ function M.refresh_entries(entries, cwd) cached_entries[idx] = name end prev = name + ::continue:: end end end @@ -152,6 +161,7 @@ function M.populate(entries, cwd) while true do local name, t = luv.fs_scandir_next(handle) if not name then break end + if should_ignore(name) then goto continue end if t == 'directory' then table.insert(dirs, name) @@ -160,29 +170,29 @@ function M.populate(entries, cwd) elseif t == 'link' then table.insert(links, name) end + + ::continue:: end -- Create Nodes -- for _, dirname in ipairs(dirs) do local dir = dir_new(cwd, dirname) - if not should_ignore(dir.name) and luv.fs_access(dir.absolute_path, 'R') then + if luv.fs_access(dir.absolute_path, 'R') then table.insert(entries, dir) end end for _, linkname in ipairs(links) do local link = link_new(cwd, linkname) - if not should_ignore(link.name) then + if link.link_to ~= nil then table.insert(entries, link) end end for _, filename in ipairs(files) do local file = file_new(cwd, filename) - if not should_ignore(file.name) then - table.insert(entries, file) - end + table.insert(entries, file) end if not icon_config.show_git_icon then