- change vim root and update tree
- create / rename / delete file and folders
This commit is contained in:
kiyan42 2020-02-10 14:22:51 +01:00
parent a3c4fcc6fe
commit 0bb2a99f55
4 changed files with 109 additions and 35 deletions

View File

@ -11,13 +11,17 @@
- [x] moving around the file structure like any basic tree - [x] moving around the file structure like any basic tree
- [x] open file in current buffer or in split with FzF like bindings (CR, C-v, C-x) - [x] open file in current buffer or in split with FzF like bindings (CR, C-v, C-x)
- [x] icons for files - [x] icons for files
- [ ] add / delete file in directory
- [x] change directory base
- [x] add / rename / delete file in directory
- [ ] update tree when altering the FS
- [ ] syntax highlighting - [ ] syntax highlighting
- [ ] simple git integration (color of file changing when staged/changed) - [ ] simple git integration (color of file changing when staged/changed)
- [ ] quickly find file in the directory structure - [ ] quickly find file in the directory structure
- [ ] update tree automatically on window change - [ ] update tree automatically on window change
## TOFIX - [ ] handle permissions properly (TODO: display error on Read access denied)
- [ ] buffer / window should always stay on the left and never change size (open a file with only the tree open to reproduce this bug)
- [ ] handle permissions properly - [ ] buffer / window should not disappear when only the tree is opened
- [ ] buffer / window should always stay on the left and never disappear (open a file with only the tree open to reproduce this bug)

View File

@ -1,5 +1,8 @@
local api = vim.api local api = vim.api
local buf, win local buf, win
local system = function(v) api.nvim_call_function('system', { v }) end
local EDIT_FILE = nil
local function scratch_buffer() local function scratch_buffer()
buf = api.nvim_create_buf(false, true) buf = api.nvim_create_buf(false, true)
@ -49,7 +52,7 @@ local function scratch_buffer()
api.nvim_command('au BufWipeout <buffer> exe "silent bwipeout! "'..border_buf) api.nvim_command('au BufWipeout <buffer> exe "silent bwipeout! "'..border_buf)
end end
local function set_mappings(path) local function set_mappings(edit_type)
local chars = { local chars = {
'a', 'b', 'd', 'e', 'f', 'h', 'l', 'j', 'q', 'k', 'g', 'i', 'n', 'o', 'p', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' 'a', 'b', 'd', 'e', 'f', 'h', 'l', 'j', 'q', 'k', 'g', 'i', 'n', 'o', 'p', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
} }
@ -62,7 +65,13 @@ local function set_mappings(path)
end end
-- TODO: launch different functions here -- TODO: launch different functions here
api.nvim_buf_set_keymap(buf, 'i', '<CR>', "<esc>:lua require'lib/file'.add_file(vim.api.nvim_get_current_line())<CR>", { nowait = true, noremap = true, silent = true }) if edit_type == 'add' then
api.nvim_buf_set_keymap(buf, 'i', '<CR>', "<esc>:lua require'lib/file'.add_file(vim.api.nvim_get_current_line())<CR>", { nowait = true, noremap = true, silent = true })
elseif edit_type == 'rename' then
api.nvim_buf_set_keymap(buf, 'i', '<CR>', "<esc>:lua require'lib/file'.rename_file(vim.api.nvim_get_current_line())<CR>", { nowait = true, noremap = true, silent = true })
elseif edit_type == 'delete' then
api.nvim_buf_set_keymap(buf, 'i', '<CR>', "<esc>:lua require'lib/file'.remove_file(vim.api.nvim_get_current_line())<CR>", { nowait = true, noremap = true, silent = true })
end
api.nvim_buf_set_keymap(buf, 'i', '<esc>', "<esc>:q!<CR>", { nowait = true, noremap = true, silent = true }) api.nvim_buf_set_keymap(buf, 'i', '<esc>', "<esc>:q!<CR>", { nowait = true, noremap = true, silent = true })
api.nvim_buf_set_keymap(buf, 'i', '<C-c>', "<esc>:q!<CR>", { nowait = true, noremap = true, silent = true }) api.nvim_buf_set_keymap(buf, 'i', '<C-c>', "<esc>:q!<CR>", { nowait = true, noremap = true, silent = true })
api.nvim_buf_set_keymap(buf, 'i', '<C-[>', "<esc>:q!<CR>", { nowait = true, noremap = true, silent = true }) api.nvim_buf_set_keymap(buf, 'i', '<C-[>', "<esc>:q!<CR>", { nowait = true, noremap = true, silent = true })
@ -74,39 +83,47 @@ local function update_view(...)
api.nvim_command('startinsert!') api.nvim_command('startinsert!')
end end
local function wrapper(path, ...) local function wrapper(edit_type, ...)
scratch_buffer() scratch_buffer()
update_view(...) update_view(...)
set_mappings(path) set_mappings(edit_type)
end end
local function edit_add(path) local function edit_add(path)
wrapper(path, { "Create File", path }) wrapper("add", { "Create File", path })
end end
local function edit_remove(filename, path, isdir) local function edit_remove(filename, path)
local name = "File" EDIT_FILE = path .. filename
if isdir == true then name = "Directory" end wrapper("delete", { "Remove " .. filename .. " ?", "y/n: " })
wrapper(path .. filename, { "Remove " .. name .. " " .. filename .. " ?", "y/n: " })
end end
local function edit_rename(filename, path, isdir) local function edit_rename(filename, path)
local name = "File" EDIT_FILE = path .. filename
if isdir == true then name = "Directory" end wrapper("rename", { "Rename " .. path, path .. filename })
wrapper(path .. filename, { "Rename " .. name, path .. filename })
end end
local function add_file(path) local function add_file(path)
print(path) if string.match(path, '.*/$') then
system('mkdir -p ' .. path)
else
system('touch ' .. path)
end
api.nvim_command("q!") api.nvim_command("q!")
end end
local function remove_file(path, confirm) local function remove_file(confirmation)
print(path) if string.match(confirmation, '^y/n: y.*$') ~= nil then
system('rm -rf ' .. EDIT_FILE)
end
EDIT_FILE = nil
api.nvim_command("q!") api.nvim_command("q!")
end end
local function rename_file(path) local function rename_file(path)
system('mv '..EDIT_FILE..' '..path)
EDIT_FILE = nil
api.nvim_command("q!")
end end
return { return {

View File

@ -41,7 +41,10 @@ local function format_tree(tree)
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 icon = get_icon(node.path .. node.name, node.dir, node.open) local icon = ""
if node.icon == true then
icon = get_icon(node.path .. node.name, node.dir, node.open)
end
dirs[i] = padding .. icon .. node.name dirs[i] = padding .. icon .. node.name
end end

View File

@ -2,11 +2,10 @@ local lib_file = require 'lib/file'
local format = require 'lib/format'.format_tree local format = require 'lib/format'.format_tree
local api = vim.api local api = vim.api
local function sys(v) return api.nvim_call_function('system', { v }) end
local function syslist(v) return api.nvim_call_function('systemlist', { v }) end local function syslist(v) return api.nvim_call_function('systemlist', { v }) end
-- get rid of \n and add leading '/' local ROOT_PATH = vim.loop.cwd() .. '/'
local ROOT_PATH = string.sub(sys('pwd'), 1, -2) .. '/' local Tree = {}
local BUF_NAME = '_LuaTree_' local BUF_NAME = '_LuaTree_'
local function is_dir(path) local function is_dir(path)
@ -14,6 +13,21 @@ local function is_dir(path)
return stat and stat.type == 'directory' or false return stat and stat.type == 'directory' or false
end end
local function check_dir_access(path)
return vim.loop.fs_access(path, 'R') == true
end
local function list_dirs(path)
if path == nil then
return syslist('ls')
elseif check_dir_access(path) == false then
-- TODO: display an error here (permission denied)
return {}
else
return syslist('ls ' .. path)
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
@ -27,7 +41,7 @@ local function sort_dirs(dirs)
return sorted_tree return sorted_tree
end end
local function create_dirs(path, depth, dirs) local function create_nodes(path, depth, dirs)
local tree = {} local tree = {}
if not string.find(path, '^.*/$') then path = path .. '/' end if not string.find(path, '^.*/$') then path = path .. '/' end
@ -38,14 +52,30 @@ local function create_dirs(path, depth, dirs)
name = name, name = name,
depth = depth, depth = depth,
dir = is_dir(path .. name), dir = is_dir(path .. name),
open = false -- only relevant when its a dir open = false, -- only relevant when its a dir
icon = true
} }
end end
return sort_dirs(tree) return sort_dirs(tree)
end end
local Tree = create_dirs(ROOT_PATH, 0, syslist('ls'))
local function init_tree()
Tree = create_nodes(ROOT_PATH, 0, list_dirs())
if ROOT_PATH ~= '/' then
table.insert(Tree, 1, {
path = ROOT_PATH,
name = '..',
depth = 0,
dir = true,
open = false,
icon = false
})
end
end
init_tree()
local function get_buf() local function get_buf()
local regex = '.*'..BUF_NAME..'$'; local regex = '.*'..BUF_NAME..'$';
@ -104,15 +134,19 @@ local function close()
api.nvim_win_close(win, true) api.nvim_win_close(win, true)
end end
local function update_view() local function update_view(update_cursor)
local buf = get_buf(); local buf = get_buf();
if not buf then return end if not buf then return end
local cursor_pos = api.nvim_win_get_cursor(0) local cursor = api.nvim_win_get_cursor(0)
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))
api.nvim_buf_set_option(buf, 'modifiable', false) api.nvim_buf_set_option(buf, 'modifiable', false)
api.nvim_win_set_cursor(0, cursor_pos)
if update_cursor == true then
api.nvim_win_set_cursor(0, cursor)
end
end end
local function is_win_open() local function is_win_open()
@ -123,7 +157,22 @@ local function 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 node = Tree[tree_index] local node = Tree[tree_index]
if node.dir == true then if node.name == '..' then
api.nvim_command('cd ..')
if vim.loop.cwd() == '/' then
ROOT_PATH = '/'
else
ROOT_PATH = vim.loop.cwd() .. '/'
end
init_tree()
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)
ROOT_PATH = vim.loop.cwd() .. '/'
init_tree()
update_view()
elseif node.dir == true then
local index = tree_index + 1; local index = tree_index + 1;
node.open = not node.open node.open = not node.open
local next_node = Tree[index] local next_node = Tree[index]
@ -133,14 +182,14 @@ local function open_file(open_type)
next_node = Tree[index] next_node = Tree[index]
end end
else else
local dirlist = syslist('ls ' .. node.path .. node.name) local dirlist = list_dirs(node.path .. node.name)
local child_dirs = create_dirs(node.path .. node.name .. '/', node.depth + 1, dirlist) local child_dirs = create_nodes(node.path .. node.name .. '/', node.depth + 1, dirlist)
for i, n in pairs(child_dirs) do for i, n in pairs(child_dirs) do
table.insert(Tree, tree_index + i, n) table.insert(Tree, tree_index + i, n)
end end
end end
update_view() update_view(true)
else else
api.nvim_command('wincmd l | '..open_type..' '.. node.path .. node.name) api.nvim_command('wincmd l | '..open_type..' '.. node.path .. node.name)
end end
@ -154,6 +203,7 @@ local function set_mappings()
['<CR>'] = 'open_file("edit")'; ['<CR>'] = 'open_file("edit")';
['<C-v>'] = 'open_file("vsplit")'; ['<C-v>'] = 'open_file("vsplit")';
['<C-x>'] = 'open_file("split")'; ['<C-x>'] = 'open_file("split")';
['<C-[>'] = 'open_file("chdir")';
a = 'edit_file("add")'; a = 'edit_file("add")';
d = 'edit_file("delete")'; d = 'edit_file("delete")';
r = 'edit_file("rename")'; r = 'edit_file("rename")';