reformat, refactor code, run fs command with luv.spawn

This commit is contained in:
kiyan42
2020-04-26 14:13:09 +02:00
parent 81ee46e41d
commit 697912429c
9 changed files with 679 additions and 704 deletions

View File

@@ -1,59 +1,58 @@
local api = vim.api
local colors = require 'lib/config'.colors local colors = require 'lib/config'.colors
local cmd = vim.api.nvim_command local M = {}
local HIGHLIGHTS = { local HIGHLIGHTS = {
Symlink = { gui = 'bold', fg = colors.cyan }, Symlink = { gui = 'bold', fg = colors.cyan },
FolderName = { gui = 'bold', fg = colors.blue }, FolderName = { gui = 'bold', fg = colors.blue },
FolderIcon = { fg = '#90a4ae' }, FolderIcon = { fg = '#90a4ae' },
ExecFile = { gui = 'bold', fg = colors.green }, ExecFile = { gui = 'bold', fg = colors.green },
SpecialFile = { gui = 'bold,underline', fg = colors.yellow }, SpecialFile = { gui = 'bold,underline', fg = colors.yellow },
ImageFile = { gui = 'bold', fg = colors.purple }, ImageFile = { gui = 'bold', fg = colors.purple },
MarkdownFile = { fg = colors.purple }, MarkdownFile = { fg = colors.purple },
LicenseIcon = { fg = colors.yellow }, LicenseIcon = { fg = colors.yellow },
YamlIcon = { fg = colors.yellow }, YamlIcon = { fg = colors.yellow },
TomlIcon = { fg = colors.yellow }, TomlIcon = { fg = colors.yellow },
GitignoreIcon = { fg = colors.yellow }, GitignoreIcon = { fg = colors.yellow },
JsonIcon = { fg = colors.yellow }, JsonIcon = { fg = colors.yellow },
LuaIcon = { fg = '#42a5f5' }, LuaIcon = { fg = '#42a5f5' },
PythonIcon = { fg = colors.green }, PythonIcon = { fg = colors.green },
ShellIcon = { fg = colors.green }, ShellIcon = { fg = colors.green },
JavascriptIcon = { fg = colors.yellow }, JavascriptIcon = { fg = colors.yellow },
CIcon = { fg = colors.blue }, CIcon = { fg = colors.blue },
ReactIcon = { fg = colors.cyan }, ReactIcon = { fg = colors.cyan },
HtmlIcon = { fg = colors.orange }, HtmlIcon = { fg = colors.orange },
RustIcon = { fg = colors.orange }, RustIcon = { fg = colors.orange },
VimIcon = { fg = colors.green }, VimIcon = { fg = colors.green },
TypescriptIcon = { fg = colors.blue }, TypescriptIcon = { fg = colors.blue },
GitDirty = { fg = colors.dark_red }, GitDirty = { fg = colors.dark_red },
GitStaged = { fg = colors.green }, GitStaged = { fg = colors.green },
GitMerge = { fg = colors.orange }, GitMerge = { fg = colors.orange },
GitRenamed = { fg = colors.purple }, GitRenamed = { fg = colors.purple },
GitNew = { fg = colors.yellow } GitNew = { fg = colors.yellow }
} }
local LINKS = { local LINKS = {
Normal = 'Normal', Normal = 'Normal',
EndOfBuffer = 'EndOfBuffer', EndOfBuffer = 'EndOfBuffer',
CursorLine = 'CursorLine', CursorLine = 'CursorLine',
VertSplit = 'VertSplit', VertSplit = 'VertSplit',
CursorColumn = 'CursorColumn' CursorColumn = 'CursorColumn'
} }
local function init_colors() function M.init_colors()
for k, d in pairs(HIGHLIGHTS) do for k, d in pairs(HIGHLIGHTS) do
local gui = d.gui or 'NONE' local gui = d.gui or 'NONE'
vim.api.nvim_command('hi def LuaTree'..k..' gui='..gui..' guifg='..d.fg) api.nvim_command('hi def LuaTree'..k..' gui='..gui..' guifg='..d.fg)
end end
for k, d in pairs(LINKS) do for k, d in pairs(LINKS) do
vim.api.nvim_command('hi def link LuaTree'..k..' '..d) api.nvim_command('hi def link LuaTree'..k..' '..d)
end end
end end
return { return M
init_colors = init_colors
}

View File

@@ -1,50 +1,45 @@
local api = vim.api local api = vim.api
local M = {}
local function get(var, fallback) local function get(var, fallback)
if vim.api.nvim_call_function('exists', { var }) == 1 then if api.nvim_call_function('exists', { var }) == 1 then
return vim.api.nvim_get_var(var) return api.nvim_get_var(var)
else else
return fallback return fallback
end end
end end
local HAS_DEV_ICONS = api.nvim_call_function('exists', { "*WebDevIconsGetFileTypeSymbol" }) == 1 local HAS_DEV_ICONS = api.nvim_call_function('exists', { "*WebDevIconsGetFileTypeSymbol" }) == 1
local show_icons = get('lua_tree_show_icons', { git = 1, folders = 1, files = 1 }) local show_icons = get('lua_tree_show_icons', { git = 1, folders = 1, files = 1 })
local SHOW_FILE_ICON = HAS_DEV_ICONS and show_icons.files == 1 M.SHOW_FILE_ICON = HAS_DEV_ICONS and show_icons.files == 1
local SHOW_FOLDER_ICON = show_icons.folders == 1 M.SHOW_FOLDER_ICON = show_icons.folders == 1
local SHOW_GIT_ICON = show_icons.git == 1 M.SHOW_GIT_ICON = show_icons.git == 1
local colors = { M.colors = {
red = get('terminal_color_1', 'Red'), red = get('terminal_color_1', 'Red'),
green = get('terminal_color_2', 'Green'), green = get('terminal_color_2', 'Green'),
yellow = get('terminal_color_3', 'Yellow'), yellow = get('terminal_color_3', 'Yellow'),
blue = get('terminal_color_4', 'Blue'), blue = get('terminal_color_4', 'Blue'),
purple = get('terminal_color_5', 'Purple'), purple = get('terminal_color_5', 'Purple'),
cyan = get('terminal_color_6', 'Cyan'), cyan = get('terminal_color_6', 'Cyan'),
orange = get('terminal_color_11', 'Orange'), orange = get('terminal_color_11', 'Orange'),
dark_red = get('terminal_color_9', 'DarkRed'), dark_red = get('terminal_color_9', 'DarkRed'),
} }
local keybindings = get('lua_tree_bindings', {}); local keybindings = get('lua_tree_bindings', {});
local bindings = { M.bindings = {
edit = keybindings.edit or '<CR>', edit = keybindings.edit or '<CR>',
edit_vsplit = keybindings.edit_vsplit or '<C-v>', edit_vsplit = keybindings.edit_vsplit or '<C-v>',
edit_split = keybindings.edit_split or '<C-x>', edit_split = keybindings.edit_split or '<C-x>',
edit_tab = keybindings.edit_tab or '<C-t>', edit_tab = keybindings.edit_tab or '<C-t>',
cd = keybindings.cd or '.', cd = keybindings.cd or '.',
create = keybindings.create or 'a', create = keybindings.create or 'a',
remove = keybindings.remove or 'd', remove = keybindings.remove or 'd',
rename = keybindings.rename or 'r', rename = keybindings.rename or 'r',
}
return {
SHOW_FOLDER_ICON = SHOW_FOLDER_ICON,
SHOW_FILE_ICON = SHOW_FILE_ICON,
SHOW_GIT_ICON = SHOW_GIT_ICON,
colors = colors,
bindings = bindings
} }
return M

View File

@@ -1,34 +1,35 @@
local api = vim.api
local config = require 'lib/config' local config = require 'lib/config'
local api = vim.api local M = {}
local function get_padding(depth) local function get_padding(depth)
local str = "" local str = ""
while 0 < depth do while 0 < depth do
str = str .. " " str = str .. " "
depth = depth - 1 depth = depth - 1
end end
return str return str
end end
local function default_icons(_, isdir, open) local function default_icons(_, isdir, open)
if isdir == true and config.SHOW_FOLDER_ICON then if isdir == true and config.SHOW_FOLDER_ICON then
if open == true then return "" end if open == true then return "" end
return "" return ""
end end
return "" return ""
end end
local function create_matcher(arr) local function create_matcher(arr)
return function(name) return function(name)
for _, n in pairs(arr) do for _, n in pairs(arr) do
if name:match(n) then return true end if name:match(n) then return true end
end
return false
end end
return false
end
end end
local is_special = create_matcher({ local is_special = create_matcher({
@@ -36,150 +37,147 @@ local is_special = create_matcher({
'readme', 'readme',
'Makefile', 'Makefile',
'Cargo%.toml', 'Cargo%.toml',
}) })
local is_pic = create_matcher({ local is_pic = create_matcher({
'%.jpe?g$', '%.jpe?g$',
'%.png', '%.png',
'%.gif' '%.gif'
}) })
local function is_executable(name) local function is_executable(name)
return api.nvim_call_function('executable', { name }) == 1 return api.nvim_call_function('executable', { name }) == 1
end end
local function dev_icons(pathname, isdir, open) local function dev_icons(pathname, isdir, open)
if isdir == true or is_special(pathname) == true or is_executable(pathname) == true or is_pic(pathname) == true then if isdir == true or is_special(pathname) == true or is_executable(pathname) == true or is_pic(pathname) == true then
return default_icons(pathname, isdir, open) return default_icons(pathname, isdir, open)
end end
local icon = api.nvim_call_function('WebDevIconsGetFileTypeSymbol', { pathname, isdir }) local icon = api.nvim_call_function('WebDevIconsGetFileTypeSymbol', { pathname, isdir })
if icon == "" then return "" end if icon == "" then return "" end
return icon .. " " return icon .. " "
end end
local function get_icon_func_gen() local function get_icon_func_gen()
if config.SHOW_FILE_ICON then if config.SHOW_FILE_ICON then
return dev_icons return dev_icons
else else
return default_icons return default_icons
end end
end end
local get_icon = get_icon_func_gen() local get_icon = get_icon_func_gen()
local function format_tree(tree) function M.format_tree(tree)
local dirs = {} local dirs = {}
for i, node in pairs(tree) do for i, node in pairs(tree) do
local padding = get_padding(node.depth) local padding = get_padding(node.depth)
local git = node.git local git = node.git
local icon = "" local icon = ""
local name = node.name local name = node.name
if node.link == true then if node.link == true then
name = name .. '' .. node.linkto name = name .. '' .. node.linkto
elseif node.icon == true then elseif node.icon == true then
icon = get_icon(node.path .. node.name, node.dir, node.open) icon = get_icon(node.path .. node.name, node.dir, node.open)
end
dirs[i] = padding .. icon .. git .. name
end end
dirs[i] = padding .. icon .. git .. name
end
return dirs return dirs
end end
local HIGHLIGHT_ICON_GROUPS = { local HIGHLIGHT_ICON_GROUPS = {
['^LICENSE$'] = 'LicenseIcon'; ['^LICENSE$'] = 'LicenseIcon';
['^%.?vimrc$'] = 'VimIcon'; ['^%.?vimrc$'] = 'VimIcon';
['%.vim$'] = 'VimIcon'; ['%.vim$'] = 'VimIcon';
['%.c$'] = 'CIcon'; ['%.c$'] = 'CIcon';
['%.cpp$'] = 'CIcon'; ['%.cpp$'] = 'CIcon';
['%.cxx$'] = 'CIcon'; ['%.cxx$'] = 'CIcon';
['%.h$'] = 'CIcon'; ['%.h$'] = 'CIcon';
['%.hpp$'] = 'CIcon'; ['%.hpp$'] = 'CIcon';
['%.py$'] = 'PythonIcon'; ['%.py$'] = 'PythonIcon';
['%.lua$'] = 'LuaIcon'; ['%.lua$'] = 'LuaIcon';
['%.rs$'] = 'RustIcon'; ['%.rs$'] = 'RustIcon';
['%.[cz]?sh$'] = 'ShellIcon'; ['%.[cz]?sh$'] = 'ShellIcon';
['%.md$'] = 'MarkdownIcon'; ['%.md$'] = 'MarkdownIcon';
['%.json$'] = 'JsonIcon'; ['%.json$'] = 'JsonIcon';
['%.toml$'] = 'TomlIcon'; ['%.toml$'] = 'TomlIcon';
['%.yml$'] = 'YamlIcon'; ['%.yml$'] = 'YamlIcon';
['%.gitignore$'] = 'GitignoreIcon'; ['%.gitignore$'] = 'GitignoreIcon';
['%.js$'] = 'JavascriptIcon'; ['%.js$'] = 'JavascriptIcon';
['%.ts$'] = 'TypescriptIcon'; ['%.ts$'] = 'TypescriptIcon';
['%.[tj]sx$'] = 'ReactIcon'; ['%.[tj]sx$'] = 'ReactIcon';
['%.html?$'] = 'HtmlIcon'; ['%.html?$'] = 'HtmlIcon';
} }
local function highlight_line(buffer) local function highlight_line(buffer)
local function highlight(group, line, from, to) local function highlight(group, line, from, to)
vim.api.nvim_buf_add_highlight(buffer, -1, group, line, from, to) api.nvim_buf_add_highlight(buffer, -1, group, line, from, to)
end end
return function(line, node) return function(line, node)
local text_start = node.depth * 2 local text_start = node.depth * 2
local gitlen = string.len(node.git) local gitlen = string.len(node.git)
if node.name == '..' then if node.name == '..' then
highlight('LuaTreeFolderName', line, 0, -1) highlight('LuaTreeFolderName', line, 0, -1)
elseif node.dir == true then elseif node.dir == true then
if config.SHOW_FOLDER_ICON then if config.SHOW_FOLDER_ICON then
text_start = text_start + 4 text_start = text_start + 4
highlight('LuaTreeFolderIcon', line, 0, text_start) highlight('LuaTreeFolderIcon', line, 0, text_start)
end end
highlight('LuaTreeFolderName', line, text_start + gitlen, -1) highlight('LuaTreeFolderName', line, text_start + gitlen, -1)
elseif node.link == true then elseif node.link == true then
highlight('LuaTreeSymlink', line, 0, -1) highlight('LuaTreeSymlink', line, 0, -1)
elseif is_special(node.name) == true then elseif is_special(node.name) == true then
highlight('LuaTreeSpecialFile', line, text_start + gitlen, -1) highlight('LuaTreeSpecialFile', line, text_start + gitlen, -1)
elseif is_executable(node.path .. node.name) then elseif is_executable(node.path .. node.name) then
highlight('LuaTreeExecFile', line, text_start + gitlen, -1) highlight('LuaTreeExecFile', line, text_start + gitlen, -1)
elseif is_pic(node.path .. node.name) then elseif is_pic(node.path .. node.name) then
highlight('LuaTreeImageFile', line, text_start + gitlen, -1) highlight('LuaTreeImageFile', line, text_start + gitlen, -1)
elseif config.SHOW_FILE_ICON then elseif config.SHOW_FILE_ICON then
for k, v in pairs(HIGHLIGHT_ICON_GROUPS) do for k, v in pairs(HIGHLIGHT_ICON_GROUPS) do
if node.name:match(k) ~= nil then if node.name:match(k) ~= nil then
text_start = text_start + 4 text_start = text_start + 4
highlight('LuaTree' .. v, line, 0, text_start) highlight('LuaTree' .. v, line, 0, text_start)
break break
end
end
end
if node.git == '' then return end
if node.git == '' then
highlight('LuaTreeGitDirty', line, text_start, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitStaged', line, text_start, text_start + gitlen)
elseif node.git == '✓★ ' then
highlight('LuaTreeGitStaged', line, text_start, text_start + 3)
highlight('LuaTreeGitNew', line, text_start + 3, text_start + gitlen)
elseif node.git == '✓✗ ' then
highlight('LuaTreeGitStaged', line, text_start, text_start + 3)
highlight('LuaTreeGitDirty', line, text_start + 3, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitMerge', line, text_start, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitRenamed', line, text_start, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitNew', line, text_start, text_start + gitlen)
end end
end
end end
if node.git == '' then return end
if node.git == '' then
highlight('LuaTreeGitDirty', line, text_start, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitStaged', line, text_start, text_start + gitlen)
elseif node.git == '✓★ ' then
highlight('LuaTreeGitStaged', line, text_start, text_start + 3)
highlight('LuaTreeGitNew', line, text_start + 3, text_start + gitlen)
elseif node.git == '✓✗ ' then
highlight('LuaTreeGitStaged', line, text_start, text_start + 3)
highlight('LuaTreeGitDirty', line, text_start + 3, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitMerge', line, text_start, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitRenamed', line, text_start, text_start + gitlen)
elseif node.git == '' then
highlight('LuaTreeGitNew', line, text_start, text_start + gitlen)
end
end
end end
local function highlight_buffer(buffer, tree) function M.highlight_buffer(buffer, tree)
local highlight = highlight_line(buffer) local highlight = highlight_line(buffer)
for i, node in pairs(tree) do for i, node in pairs(tree) do
highlight(i - 1, node) highlight(i - 1, node)
end end
end end
return { return M
format_tree = format_tree;
highlight_buffer = highlight_buffer;
}

View File

@@ -1,63 +1,77 @@
local api = vim.api local api = vim.api
local luv = vim.loop local luv = vim.loop
local function get_cwd() return luv.cwd() end local M = {}
local function is_dir(path) function M.get_cwd() return luv.cwd() end
local stat = luv.fs_lstat(path)
return stat and stat.type == 'directory' or false function M.is_dir(path)
local stat = luv.fs_lstat(path)
return stat and stat.type == 'directory' or false
end end
local function is_symlink(path) function M.is_symlink(path)
local stat = luv.fs_lstat(path) local stat = luv.fs_lstat(path)
return stat and stat.type == 'link' or false return stat and stat.type == 'link' or false
end end
local function link_to(path) function M.link_to(path)
return luv.fs_readlink(path) or '' return luv.fs_readlink(path) or ''
end end
local function print_err(err) function M.check_dir_access(path)
if err then if luv.fs_access(path, 'R') == true then
api.nvim_err_writeln(err) return true
else
api.nvim_err_writeln('Permission denied: ' .. path)
return false
end end
end end
local function system(v) local handle = nil
print_err(api.nvim_call_function('system', { v }))
end
local function check_dir_access(path) local function run_process(opt, err, cb)
if luv.fs_access(path, 'R') == true then handle = luv.spawn(opt.cmd, { args = opt.args }, vim.schedule_wrap(function(code)
return true handle:close()
else if code ~= 0 then
print_err('Permission denied: ' .. path) return api.nvim_err_writeln(err)
return false
end end
cb()
end))
end end
-- TODO: better handling of path removal, rename and file creation with luv calls function M.rm(path, cb)
-- it will take some time so leave it for a dedicated PR local opt = { cmd='rm', args = {'-rf', path } };
local function rm(path) run_process(opt, 'Error removing '..path, cb)
system('rm -rf ' ..path)
end end
local function rename(file, new_path)
system('mv '..file..' '..new_path) function M.rename(file, new_path, cb)
local opt = { cmd='mv', args = {file, new_path } };
run_process(opt, 'Error renaming '..file..' to '..new_path, cb)
end end
local function create(path, file, folders) function M.create(path, file, folders, cb)
if folders ~= "" then system('mkdir -p '..path..folders) end local opt_file = nil
if file ~= nil then system('touch '..path..folders..file) end local file_path = nil
if file ~= nil then
file_path = path..folders..file
opt_file = { cmd='touch', args = {file_path} }
end
if folders ~= "" then
local folder_path = path..folders
local opt = {cmd = 'mkdir', args = {'-p', folder_path }}
run_process(opt, 'Error creating folder '..folder_path, function()
if opt_file then
run_process(opt, 'Error creating file '..file_path, cb)
else
cb()
end
end)
elseif opt_file then
run_process(opt_file, 'Error creating file '..file_path, cb)
end
end end
return { return M
check_dir_access = check_dir_access;
is_symlink = is_symlink;
link_to = link_to;
get_cwd = get_cwd;
is_dir = is_dir;
rename = rename;
rm = rm;
create = create;
}

View File

@@ -1,72 +1,68 @@
local api = vim.api local api = vim.api
local fs = require 'lib/fs'
local update_view = require 'lib/winutils'.update_view local update_view = require 'lib/winutils'.update_view
local refresh_tree = require 'lib/state'.refresh_tree local refresh_tree = require 'lib/state'.refresh_tree
local refresh_git = require 'lib/git'.refresh_git local refresh_git = require 'lib/git'.refresh_git
local utils = require'lib/utils'
local fs = require 'lib/fs' local M = {}
local rm = fs.rm
local rename = fs.rename
local create = fs.create
local function input(v) local function input(v)
local param local param
if type(v) == 'string' then param = { v } else param = v end if type(v) == 'string' then param = { v } else param = v end
return api.nvim_call_function('input', param) return api.nvim_call_function('input', param)
end end
local function clear_prompt() local function clear_prompt()
api.nvim_command('normal :<esc>') api.nvim_command('normal :<esc>')
end end
local function create_file(path) function M.create_file(path)
local new_file = input("Create file: " .. path) local new_file = input("Create file: " .. path)
local file = nil local file = nil
if not new_file:match('.*/$') then if not new_file:match('.*/$') then
file = new_file:reverse():gsub('/.*$', ''):reverse() file = new_file:reverse():gsub('/.*$', ''):reverse()
new_file = new_file:gsub('[^/]*$', '') new_file = new_file:gsub('[^/]*$', '')
end
local folders = ""
if #new_file ~= 0 then
for p in new_file:gmatch('[^/]*') do
if p and p ~= "" then
folders = folders .. p .. '/'
end
end end
end
local folders = "" clear_prompt()
if #new_file ~= 0 then fs.create(path, file, folders, function()
for p in new_file:gmatch('[^/]*') do
if p and p ~= "" then
folders = folders .. p .. '/'
end
end
end
clear_prompt()
create(path, file, folders)
refresh_git() refresh_git()
refresh_tree() refresh_tree()
update_view() update_view()
end)
end end
local function remove_file(filename, path) function M.remove_file(filename, path)
local ans = input("Remove " .. filename .. " ? y/n: ") local ans = input("Remove " .. filename .. " ? y/n: ")
clear_prompt() clear_prompt()
if ans == "y" then if ans == "y" then
rm(path .. filename) fs.rm(path .. filename, function()
refresh_git() refresh_git()
refresh_tree() refresh_tree()
update_view() update_view()
end end)
end
end end
local function rename_file(filename, path) function M.rename_file(filename, path)
local new_path = input({"Rename file " .. filename .. ": ", path .. filename}) local new_path = input({"Rename file " .. filename .. ": ", path .. filename})
clear_prompt() clear_prompt()
rename(path .. filename, new_path) fs.rename(path .. filename, new_path, function()
refresh_git() refresh_git()
refresh_tree() refresh_tree()
update_view() update_view()
end)
end end
return { return M
create_file = create_file;
remove_file = remove_file;
rename_file = rename_file;
}

View File

@@ -1,50 +1,53 @@
local api = vim.api
local config = require 'lib/config' local config = require 'lib/config'
local utils = require'lib.utils' local utils = require'lib.utils'
local function system(v) return vim.api.nvim_call_function('system', { v }) end local M = {}
local function systemlist(v) return vim.api.nvim_call_function('systemlist', { v }) end
local function system(v) return api.nvim_call_function('system', { v }) end
local function systemlist(v) return api.nvim_call_function('systemlist', { v }) end
local function is_git_repo() local function is_git_repo()
local is_git = system('git rev-parse') local is_git = system('git rev-parse')
return is_git:match('fatal') == nil return is_git:match('fatal') == nil
end end
local IS_GIT_REPO = is_git_repo() local IS_GIT_REPO = is_git_repo()
local function set_git_status() local function set_git_status()
if IS_GIT_REPO == false then return '' end if IS_GIT_REPO == false then return '' end
return systemlist('git status --porcelain=v1') return systemlist('git status --porcelain=v1')
end end
local GIT_STATUS = set_git_status() local GIT_STATUS = set_git_status()
local function refresh_git() function M.refresh_git()
if IS_GIT_REPO == false then return false end if IS_GIT_REPO == false then return false end
GIT_STATUS = set_git_status() GIT_STATUS = set_git_status()
return true return true
end end
local function force_refresh_git() function M.force_refresh_git()
IS_GIT_REPO = is_git_repo() IS_GIT_REPO = is_git_repo()
refresh_git() M.refresh_git()
end end
local function is_folder_dirty(relpath) local function is_folder_dirty(relpath)
for _, status in pairs(GIT_STATUS) do for _, status in pairs(GIT_STATUS) do
if status:match(utils.path_to_matching_str(relpath)) ~= nil then if status:match(utils.path_to_matching_str(relpath)) ~= nil then
return true return true
end
end end
end
end end
local function create_git_checker(pattern) local function create_git_checker(pattern)
return function(relpath) return function(relpath)
for _, status in pairs(GIT_STATUS) do for _, status in pairs(GIT_STATUS) do
local ret = status:match('^.. .*' .. utils.path_to_matching_str(relpath)) local ret = status:match('^.. .*' .. utils.path_to_matching_str(relpath))
if ret ~= nil and ret:match(pattern) ~= nil then return true end if ret ~= nil and ret:match(pattern) ~= nil then return true end
end
return false
end end
return false
end
end end
local unstaged = create_git_checker('^ ') local unstaged = create_git_checker('^ ')
@@ -55,26 +58,22 @@ local unmerged = create_git_checker('^[U ][U ]')
local renamed = create_git_checker('^R') local renamed = create_git_checker('^R')
local untracked = create_git_checker('^%?%?') local untracked = create_git_checker('^%?%?')
local function get_git_attr(path, is_dir) function M.get_git_attr(path, is_dir)
if IS_GIT_REPO == false or not config.SHOW_GIT_ICON then return '' end if IS_GIT_REPO == false or not config.SHOW_GIT_ICON then return '' end
if is_dir then if is_dir then
if is_folder_dirty(path) == true then return '' end if is_folder_dirty(path) == true then return '' end
else else
if unstaged(path) then return '' if unstaged(path) then return ''
elseif staged(path) then return '' elseif staged(path) then return ''
elseif staged_new(path) then return '✓★ ' elseif staged_new(path) then return '✓★ '
elseif staged_mod(path) then return '✓✗ ' elseif staged_mod(path) then return '✓✗ '
elseif unmerged(path) then return '' elseif unmerged(path) then return ''
elseif renamed(path) then return '' elseif renamed(path) then return ''
elseif untracked(path) then return '' elseif untracked(path) then return ''
end
end end
end
return '' return ''
end end
return { return M
get_git_attr = get_git_attr;
refresh_git = refresh_git;
force_refresh_git = force_refresh_git;
}

View File

@@ -1,19 +1,14 @@
local api = vim.api local api = vim.api
local utils = require'lib.utils' local utils = require'lib.utils'
local gitutils = require 'lib.git'
local fs = require 'lib.fs'
local function syslist(v) return api.nvim_call_function('systemlist', { v }) end local M = {}
local get_git_attr = require 'lib/git'.get_git_attr local ROOT_PATH = fs.get_cwd() .. '/'
local fs = require 'lib/fs'
local is_dir = fs.is_dir
local is_symlink = fs.is_symlink
local get_cwd = fs.get_cwd
local link_to = fs.link_to
local ROOT_PATH = get_cwd() .. '/' function M.set_root_path(path)
ROOT_PATH = path
local function set_root_path(path)
ROOT_PATH = path
end end
local Tree = {} local Tree = {}
@@ -24,100 +19,99 @@ local MACOS = api.nvim_call_function('has', { 'macunix' }) == 1
-- --ignore does not work with mac ls -- --ignore does not work with mac ls
if not MACOS and api.nvim_call_function('exists', { 'g:lua_tree_ignore' }) == 1 then if not MACOS and api.nvim_call_function('exists', { 'g:lua_tree_ignore' }) == 1 then
local ignore_patterns = api.nvim_get_var('lua_tree_ignore') local ignore_patterns = api.nvim_get_var('lua_tree_ignore')
if type(ignore_patterns) == 'table' then if type(ignore_patterns) == 'table' then
for _, pattern in pairs(ignore_patterns) do for _, pattern in pairs(ignore_patterns) do
IGNORE_LIST = IGNORE_LIST .. '--ignore='..pattern..' ' IGNORE_LIST = IGNORE_LIST .. '--ignore='..pattern..' '
end
end end
end
end end
local function list_dirs(path) local function list_dirs(path)
local ls_cmd = 'ls -A '..IGNORE_LIST..path return api.nvim_call_function('systemlist', { 'ls -A '..IGNORE_LIST..path })
return syslist(ls_cmd)
end end
local function sort_dirs(dirs) local function sort_dirs(dirs)
local sorted_tree = {} local sorted_tree = {}
for _, node in pairs(dirs) do for _, node in pairs(dirs) do
if node.dir == true then if node.dir == true then
table.insert(sorted_tree, 1, node) table.insert(sorted_tree, 1, node)
else else
table.insert(sorted_tree, node) table.insert(sorted_tree, node)
end
end end
end
return sorted_tree return sorted_tree
end end
local function create_nodes(path, relpath, depth, dirs) local function create_nodes(path, relpath, depth, dirs)
local tree = {} local tree = {}
if not path:find('^.*/$') then path = path .. '/' end if not path:find('^.*/$') then path = path .. '/' end
if not relpath:find('^.*/$') and depth > 0 then relpath = relpath .. '/' end if not relpath:find('^.*/$') and depth > 0 then relpath = relpath .. '/' end
for i, name in pairs(dirs) do for i, name in pairs(dirs) do
local full_path = path..name local full_path = path..name
local dir = is_dir(full_path) local dir = fs.is_dir(full_path)
local link = is_symlink(full_path) local link = fs.is_symlink(full_path)
local linkto = link == true and link_to(full_path) or nil local linkto = link == true and fs.link_to(full_path) or nil
local rel_path = relpath ..name local rel_path = relpath ..name
tree[i] = { tree[i] = {
path = path, path = path,
relpath = rel_path, relpath = rel_path,
link = link, link = link,
linkto = linkto, linkto = linkto,
name = name, name = name,
depth = depth, depth = depth,
dir = dir, dir = dir,
open = false, open = false,
icon = true, icon = true,
git = get_git_attr(rel_path, dir) git = gitutils.get_git_attr(rel_path, dir)
} }
end end
return sort_dirs(tree) return sort_dirs(tree)
end end
local function init_tree() function M.init_tree()
Tree = create_nodes(ROOT_PATH, '', 0, list_dirs(ROOT_PATH)) Tree = create_nodes(ROOT_PATH, '', 0, list_dirs(ROOT_PATH))
if ROOT_PATH ~= '/' then if ROOT_PATH ~= '/' then
table.insert(Tree, 1, { table.insert(Tree, 1, {
path = ROOT_PATH, path = ROOT_PATH,
name = '..', name = '..',
depth = 0, depth = 0,
dir = true, dir = true,
open = false, open = false,
icon = false, icon = false,
git = '' git = ''
}) })
end end
end end
local function refresh_tree() function M.refresh_tree()
local cache = {} local cache = {}
for _, v in pairs(Tree) do for _, v in pairs(Tree) do
if v.dir == true and v.open == true then if v.dir == true and v.open == true then
table.insert(cache, v.path .. v.name) table.insert(cache, v.path .. v.name)
end
end end
end
init_tree() M.init_tree()
for i, node in pairs(Tree) do for i, node in pairs(Tree) do
if node.dir == true then if node.dir == true then
for _, path in pairs(cache) do for _, path in pairs(cache) do
if node.path .. node.name == path then if node.path .. node.name == path then
node.open = true node.open = true
local dirs = list_dirs(path) local dirs = list_dirs(path)
for j, n in pairs(create_nodes(path, node.relpath, node.depth + 1, dirs)) do for j, n in pairs(create_nodes(path, node.relpath, node.depth + 1, dirs)) do
table.insert(Tree, i + j, n) table.insert(Tree, i + j, n)
end end
end
end
end end
end
end end
end
end end
local function clone(obj) local function clone(obj)
@@ -127,63 +121,55 @@ local function clone(obj)
return res return res
end end
local function find_file(path) function M.find_file(path)
local relpath = string.sub(path, #ROOT_PATH + 1, -1) local relpath = string.sub(path, #ROOT_PATH + 1, -1)
local tree_copy = clone(Tree) local tree_copy = clone(Tree)
for i, node in pairs(tree_copy) do for i, node in pairs(tree_copy) do
if node.relpath and relpath:find(utils.path_to_matching_str(node.relpath)) then if node.relpath and relpath:find(utils.path_to_matching_str(node.relpath)) then
if node.relpath == relpath then if node.relpath == relpath then
Tree = clone(tree_copy) Tree = clone(tree_copy)
return i return i
end end
if node.dir and not node.open then if node.dir and not node.open then
local path = node.path .. node.name local dirpath = node.path .. node.name
node.open = true node.open = true
local dirs = list_dirs(path) local dirs = list_dirs(dirpath)
for j, n in pairs(create_nodes(path, node.relpath, node.depth + 1, dirs)) do for j, n in pairs(create_nodes(dirpath, node.relpath, node.depth + 1, dirs)) do
table.insert(tree_copy, i + j, n) table.insert(tree_copy, i + j, n)
end
end
end end
end
end end
end
return nil return nil
end end
local function open_dir(tree_index) function M.open_dir(tree_index)
local node = Tree[tree_index]; local node = Tree[tree_index];
node.open = not node.open node.open = not node.open
if node.open == false then if node.open == false then
local next_index = tree_index + 1; local next_index = tree_index + 1;
local next_node = Tree[next_index] local next_node = Tree[next_index]
while next_node ~= nil and next_node.depth > node.depth do while next_node ~= nil and next_node.depth > node.depth do
table.remove(Tree, next_index) table.remove(Tree, next_index)
next_node = Tree[next_index] next_node = Tree[next_index]
end
else
local dirlist = list_dirs('"' .. node.path .. node.name ..'"')
local child_dirs = create_nodes(node.path .. node.name .. '/', node.relpath, node.depth + 1, dirlist)
for i, n in pairs(child_dirs) do
table.insert(Tree, tree_index + i, n)
end
end end
else
local dirlist = list_dirs(tostring(node.path .. node.name))
local child_dirs = create_nodes(node.path .. node.name .. '/', node.relpath, node.depth + 1, dirlist)
for i, n in pairs(child_dirs) do
table.insert(Tree, tree_index + i, n)
end
end
end end
local function get_tree() function M.get_tree()
return Tree return Tree
end end
return { return M
init_tree = init_tree;
get_tree = get_tree;
refresh_tree = refresh_tree;
open_dir = open_dir;
set_root_path = set_root_path;
get_cwd = get_cwd;
find_file = find_file;
}

View File

@@ -1,4 +1,3 @@
local BUF_NAME = 'LuaTree'
local api = vim.api local api = vim.api
local libformat = require 'lib/format' local libformat = require 'lib/format'
@@ -10,160 +9,156 @@ local get_tree = stateutils.get_tree
local bindings = require 'lib/config'.bindings local bindings = require 'lib/config'.bindings
local function get_buf() local M = {
local regex = '.*'..BUF_NAME..'$'; BUF_NAME = 'LuaTree'
}
for _, win in pairs(api.nvim_list_wins()) do
local buf = api.nvim_win_get_buf(win)
local buf_name = api.nvim_buf_get_name(buf)
if string.match(buf_name, regex) ~= nil then return buf end function M.get_buf()
end local regex = '.*'..M.BUF_NAME..'$';
return nil for _, win in pairs(api.nvim_list_wins()) do
local buf = api.nvim_win_get_buf(win)
local buf_name = api.nvim_buf_get_name(buf)
if string.match(buf_name, regex) ~= nil then return buf end
end
return nil
end end
local function get_win() function M.get_win()
local regex = '.*'..BUF_NAME..'$'; local regex = '.*'..M.BUF_NAME..'$';
for _, win in pairs(api.nvim_list_wins()) do for _, win in pairs(api.nvim_list_wins()) do
local buf_name = api.nvim_buf_get_name(api.nvim_win_get_buf(win)) local buf_name = api.nvim_buf_get_name(api.nvim_win_get_buf(win))
if string.match(buf_name, regex) ~= nil then return win end if string.match(buf_name, regex) ~= nil then return win end
end end
return nil return nil
end end
local BUF_OPTIONS = { local BUF_OPTIONS = {
'nowrap', 'sidescroll=5', 'nospell', 'nolist', 'nofoldenable', 'nowrap', 'sidescroll=5', 'nospell', 'nolist', 'nofoldenable',
'foldmethod=manual', 'foldcolumn=0', 'nonumber', 'norelativenumber', 'foldmethod=manual', 'foldcolumn=0', 'nonumber', 'norelativenumber',
'winfixwidth', 'winfixheight', 'noswapfile', 'splitbelow', 'noruler', 'winfixwidth', 'winfixheight', 'noswapfile', 'splitbelow', 'noruler',
'noshowmode', 'noshowcmd' 'noshowmode', 'noshowcmd'
} }
local WIN_WIDTH = 30 local WIN_WIDTH = 30
local SIDE = 'H' local SIDE = 'H'
if api.nvim_call_function('exists', { 'g:lua_tree_width' }) == 1 then if api.nvim_call_function('exists', { 'g:lua_tree_width' }) == 1 then
WIN_WIDTH = api.nvim_get_var('lua_tree_width') WIN_WIDTH = api.nvim_get_var('lua_tree_width')
end end
if api.nvim_call_function('exists', { 'g:lua_tree_side' }) == 1 then if api.nvim_call_function('exists', { 'g:lua_tree_side' }) == 1 then
if api.nvim_get_var('lua_tree_side') == 'right' then if api.nvim_get_var('lua_tree_side') == 'right' then
SIDE = 'L' SIDE = 'L'
end end
end end
local function open() function M.open()
local options = { local options = {
bufhidden = 'wipe'; bufhidden = 'wipe';
buftype = 'nowrite'; buftype = 'nowrite';
modifiable = false; modifiable = false;
} }
local buf = api.nvim_create_buf(false, true) local buf = api.nvim_create_buf(false, true)
api.nvim_buf_set_name(buf, BUF_NAME) api.nvim_buf_set_name(buf, M.BUF_NAME)
for opt, val in pairs(options) do for opt, val in pairs(options) do
api.nvim_buf_set_option(buf, opt, val) api.nvim_buf_set_option(buf, opt, val)
end end
api.nvim_command('vsplit') api.nvim_command('vsplit')
api.nvim_command('wincmd '..SIDE) api.nvim_command('wincmd '..SIDE)
api.nvim_command('vertical resize '..WIN_WIDTH) api.nvim_command('vertical resize '..WIN_WIDTH)
api.nvim_win_set_buf(0, buf) api.nvim_win_set_buf(0, buf)
api.nvim_command('setlocal winhighlight=EndOfBuffer:LuaTreeEndOfBuffer,Normal:LuaTreeNormal,CursorLine:LuaTreeCursorLine,VertSplit:LuaTreeVertSplit') api.nvim_command('setlocal winhighlight=EndOfBuffer:LuaTreeEndOfBuffer,Normal:LuaTreeNormal,CursorLine:LuaTreeCursorLine,VertSplit:LuaTreeVertSplit')
for _, opt in pairs(BUF_OPTIONS) do for _, opt in pairs(BUF_OPTIONS) do
api.nvim_command('setlocal '..opt) api.nvim_command('setlocal '..opt)
end end
if SIDE == 'L' then if SIDE == 'L' then
api.nvim_command('setlocal nosplitright') api.nvim_command('setlocal nosplitright')
else else
api.nvim_command('setlocal splitright') api.nvim_command('setlocal splitright')
end end
end end
local function replace_tree() function M.replace_tree()
local win = get_win() local win = M.get_win()
if not win then return end if not win then return end
local tree_position = api.nvim_win_get_position(win) local tree_position = api.nvim_win_get_position(win)
local win_width = api.nvim_win_get_width(win) local win_width = api.nvim_win_get_width(win)
if win_width == WIN_WIDTH then if win_width == WIN_WIDTH then
if SIDE == 'H' and tree_position[2] == 0 then return end if SIDE == 'H' and tree_position[2] == 0 then return end
local columns = api.nvim_get_option('columns') local columns = api.nvim_get_option('columns')
if SIDE == 'L' and tree_position[2] ~= columns - win_width then return end if SIDE == 'L' and tree_position[2] ~= columns - win_width then return end
end end
local current_win = api.nvim_get_current_win() local current_win = api.nvim_get_current_win()
api.nvim_set_current_win(win) api.nvim_set_current_win(win)
api.nvim_command('wincmd '..SIDE) api.nvim_command('wincmd '..SIDE)
api.nvim_command('vertical resize '..WIN_WIDTH) api.nvim_command('vertical resize '..WIN_WIDTH)
api.nvim_set_current_win(current_win) api.nvim_set_current_win(current_win)
end end
local function close() function M.close()
local win = get_win() local win = M.get_win()
if not win then return end if not win then return end
api.nvim_win_close(win, true) api.nvim_win_close(win, true)
end end
local function update_view(update_cursor) function M.update_view(update_cursor)
local buf = get_buf(); local buf = M.get_buf();
if not buf then return end if not buf then return end
local cursor = api.nvim_win_get_cursor(0) local cursor = api.nvim_win_get_cursor(0)
local tree = get_tree() local tree = get_tree()
api.nvim_buf_set_option(buf, 'modifiable', true) api.nvim_buf_set_option(buf, 'modifiable', true)
api.nvim_buf_set_lines(buf, 0, -1, false, format(tree)) api.nvim_buf_set_lines(buf, 0, -1, false, format(tree))
highlight(buf, tree) highlight(buf, tree)
api.nvim_buf_set_option(buf, 'modifiable', false) api.nvim_buf_set_option(buf, 'modifiable', false)
if update_cursor == true then if update_cursor == true then
api.nvim_win_set_cursor(0, cursor) api.nvim_win_set_cursor(0, cursor)
end end
end end
local function set_mappings() function M.set_mappings()
local buf = get_buf() local buf = M.get_buf()
if not buf then return end if not buf then return end
local mappings = { local mappings = {
['<2-LeftMouse>'] = 'open_file("edit")'; ['<2-LeftMouse>'] = 'open_file("edit")';
['<2-RightMouse>'] = 'open_file("chdir")'; ['<2-RightMouse>'] = 'open_file("chdir")';
[bindings.edit] = 'open_file("edit")'; [bindings.edit] = 'open_file("edit")';
[bindings.edit_vsplit] = 'open_file("vsplit")'; [bindings.edit_vsplit] = 'open_file("vsplit")';
[bindings.edit_split] = 'open_file("split")'; [bindings.edit_split] = 'open_file("split")';
[bindings.edit_tab] = 'open_file("tabnew")'; [bindings.edit_tab] = 'open_file("tabnew")';
[bindings.cd] = 'open_file("chdir")'; [bindings.cd] = 'open_file("chdir")';
[bindings.create] = 'edit_file("create")'; [bindings.create] = 'edit_file("create")';
[bindings.remove] = 'edit_file("remove")'; [bindings.remove] = 'edit_file("remove")';
[bindings.rename] = 'edit_file("rename")'; [bindings.rename] = 'edit_file("rename")';
} }
for k,v in pairs(mappings) do for k,v in pairs(mappings) do
api.nvim_buf_set_keymap(buf, 'n', k, ':lua require"tree".'..v..'<cr>', { api.nvim_buf_set_keymap(buf, 'n', k, ':lua require"tree".'..v..'<cr>', {
nowait = true, noremap = true, silent = true nowait = true, noremap = true, silent = true
}) })
end end
end end
local function is_win_open() function M.is_win_open()
return get_buf() ~= nil return M.get_buf() ~= nil
end end
return { return M
open = open;
close = close;
is_win_open = is_win_open;
update_view = update_view;
get_buf = get_buf;
get_win = get_win;
set_mappings = set_mappings;
replace_tree = replace_tree;
}

View File

@@ -24,7 +24,6 @@ local is_win_open = winutils.is_win_open
local close = winutils.close local close = winutils.close
local open = winutils.open local open = winutils.open
local set_mappings = winutils.set_mappings local set_mappings = winutils.set_mappings
local replace_tree = winutils.replace_tree
local get_win = winutils.get_win local get_win = winutils.get_win
local git = require 'lib/git' local git = require 'lib/git'
@@ -33,161 +32,155 @@ local force_refresh_git = git.force_refresh_git
require 'lib/colors'.init_colors() require 'lib/colors'.init_colors()
local M = {}
M.replace_tree = winutils.replace_tree
init_tree() init_tree()
local function toggle() function M.toggle()
if is_win_open() == true then if is_win_open() == true then
local wins = api.nvim_list_wins() local wins = api.nvim_list_wins()
if #wins > 1 then close() end if #wins > 1 then close() end
else else
open() open()
update_view() update_view()
set_mappings() set_mappings()
end end
end end
local MOVE_TO = 'l' local MOVE_TO = 'l'
if api.nvim_call_function('exists', { 'g:lua_tree_side' }) == 1 then if api.nvim_call_function('exists', { 'g:lua_tree_side' }) == 1 then
if api.nvim_get_var('lua_tree_side') == 'right' then if api.nvim_get_var('lua_tree_side') == 'right' then
MOVE_TO = 'h' MOVE_TO = 'h'
end end
end end
local function create_new_buf(open_type, bufname) local function create_new_buf(open_type, bufname)
if open_type == 'edit' or open_type == 'split' then if open_type == 'edit' or open_type == 'split' then
api.nvim_command('wincmd '..MOVE_TO..' | '..open_type..' '..bufname) api.nvim_command('wincmd '..MOVE_TO..' | '..open_type..' '..bufname)
elseif open_type == 'vsplit' then elseif open_type == 'vsplit' then
local windows = api.nvim_list_wins(); local windows = api.nvim_list_wins();
api.nvim_command(#windows..'wincmd '..MOVE_TO..' | vsplit '..bufname) api.nvim_command(#windows..'wincmd '..MOVE_TO..' | vsplit '..bufname)
elseif open_type == 'tabnew' then elseif open_type == 'tabnew' then
api.nvim_command('tabnew '..bufname) api.nvim_command('tabnew '..bufname)
end end
end end
local function open_file(open_type) function M.open_file(open_type)
local tree_index = api.nvim_win_get_cursor(0)[1] local tree_index = api.nvim_win_get_cursor(0)[1]
local tree = get_tree() local tree = get_tree()
local node = tree[tree_index] local node = tree[tree_index]
if node.name == '..' then if node.name == '..' then
api.nvim_command('cd ..') api.nvim_command('cd ..')
local new_path = get_cwd() local new_path = get_cwd()
if new_path ~= '/' then if new_path ~= '/' then
new_path = new_path .. '/' new_path = new_path .. '/'
end
set_root_path(new_path)
force_refresh_git()
init_tree(new_path)
update_view()
elseif open_type == 'chdir' then
if node.dir == false or check_dir_access(node.path .. node.name) == false then return end
api.nvim_command('cd ' .. node.path .. node.name)
local new_path = get_cwd() .. '/'
set_root_path(new_path)
force_refresh_git()
init_tree(new_path)
update_view()
elseif node.link == true then
local link_to_dir = is_dir(node.linkto)
if link_to_dir == true and check_dir_access(node.linkto) == false then return end
if link_to_dir == true then
api.nvim_command('cd ' .. node.linkto)
local new_path = get_cwd() .. '/'
set_root_path(new_path)
force_refresh_git()
init_tree(new_path)
update_view()
else
create_new_buf(open_type, node.link_to);
end
elseif node.dir == true then
if check_dir_access(node.path .. node.name) == false then return end
open_dir(tree_index)
update_view(true)
else
create_new_buf(open_type, node.path .. node.name);
end end
end
local function edit_file(edit_type)
local tree = get_tree()
local tree_index = api.nvim_win_get_cursor(0)[1]
local node = tree[tree_index]
if edit_type == 'create' then
if node.dir == true then
create_file(node.path .. node.name .. '/')
else
create_file(node.path)
end
elseif edit_type == 'remove' then
remove_file(node.name, node.path)
elseif edit_type == 'rename' then
rename_file(node.name, node.path)
end
end
local function refresh()
if refresh_git() == true then
refresh_tree()
update_view()
end
end
local function check_windows_and_close()
local wins = api.nvim_list_wins()
if #wins == 1 and is_win_open() then
api.nvim_command('q!')
end
end
local function check_buffer_and_open()
local bufname = api.nvim_buf_get_name(0)
if bufname == '' then
toggle()
elseif is_dir(bufname) then
api.nvim_command('cd ' .. bufname)
local new_path = get_cwd()
if new_path ~= '/' then
new_path = new_path .. '/'
end
set_root_path(new_path)
init_tree()
toggle()
end
end
local function find()
local line = find_file(api.nvim_buf_get_name(0))
if not line then return end
set_root_path(new_path)
force_refresh_git()
init_tree(new_path)
update_view() update_view()
local win = get_win() elseif open_type == 'chdir' then
if win then if node.dir == false or check_dir_access(node.path .. node.name) == false then return end
api.nvim_win_set_cursor(win, { line, 0 })
api.nvim_command('cd ' .. node.path .. node.name)
local new_path = get_cwd() .. '/'
set_root_path(new_path)
force_refresh_git()
init_tree(new_path)
update_view()
elseif node.link == true then
local link_to_dir = is_dir(node.linkto)
if link_to_dir == true and check_dir_access(node.linkto) == false then return end
if link_to_dir == true then
api.nvim_command('cd ' .. node.linkto)
local new_path = get_cwd() .. '/'
set_root_path(new_path)
force_refresh_git()
init_tree(new_path)
update_view()
else
create_new_buf(open_type, node.link_to);
end end
elseif node.dir == true then
if check_dir_access(node.path .. node.name) == false then return end
open_dir(tree_index)
update_view(true)
else
create_new_buf(open_type, node.path .. node.name);
end
end
function M.edit_file(edit_type)
local tree = get_tree()
local tree_index = api.nvim_win_get_cursor(0)[1]
local node = tree[tree_index]
if edit_type == 'create' then
if node.dir == true then
create_file(node.path .. node.name .. '/')
else
create_file(node.path)
end
elseif edit_type == 'remove' then
remove_file(node.name, node.path)
elseif edit_type == 'rename' then
rename_file(node.name, node.path)
end
end
function M.refresh()
if refresh_git() == true then
refresh_tree()
update_view()
end
end
function M.check_windows_and_close()
local wins = api.nvim_list_wins()
if #wins == 1 and is_win_open() then
api.nvim_command('q!')
end
end
function M.check_buffer_and_open()
local bufname = api.nvim_buf_get_name(0)
if bufname == '' then
M.toggle()
elseif is_dir(bufname) then
api.nvim_command('cd ' .. bufname)
local new_path = get_cwd()
if new_path ~= '/' then
new_path = new_path .. '/'
end
set_root_path(new_path)
init_tree()
M.toggle()
end
end
function M.find()
local line = find_file(api.nvim_buf_get_name(0))
if not line then return end
update_view()
local win = get_win()
if win then
api.nvim_win_set_cursor(win, { line, 0 })
end
end end
return { return M
toggle = toggle;
open_file = open_file;
edit_file = edit_file;
refresh = refresh;
check_windows_and_close = check_windows_and_close;
check_buffer_and_open = check_buffer_and_open;
replace_tree = replace_tree;
find = find;
}