some refacto and start adding file creation/removal..
This commit is contained in:
parent
d649119146
commit
ef6f338cce
10
README.md
10
README.md
@ -2,20 +2,20 @@
|
|||||||
|
|
||||||
## Notice
|
## Notice
|
||||||
|
|
||||||
- I am working on this plugin to learn lua, learn neovim api and create a **simple** file explorer with features i need.
|
- I am working on this plugin to learn lua, learn neovim api and create a file explorer with features i need.
|
||||||
- I really don't like any of the vim trees, they are all too complicated for their purposes and are kind of buggy. I have my shell to do most commands.
|
- I really don't like any of the vim trees, they are all too complicated for their purposes and are kind of buggy. I have my shell to do most commands.
|
||||||
- This plugin does not work on windows.
|
- This plugin will not work on windows.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [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)
|
||||||
- [ ] add / delete file in directory
|
|
||||||
- [x] icons for files
|
- [x] icons for files
|
||||||
|
- [ ] add / delete file in directory
|
||||||
- [ ] syntax highlighting
|
- [ ] syntax highlighting
|
||||||
- [ ] quickly find file in the directory structure
|
|
||||||
- [ ] simple git integration (color of file changing when staged/changed)
|
- [ ] simple git integration (color of file changing when staged/changed)
|
||||||
- [ ] update automatically on window change
|
- [ ] quickly find file in the directory structure
|
||||||
|
- [ ] update tree automatically on window change
|
||||||
|
|
||||||
## TOFIX
|
## TOFIX
|
||||||
|
|
||||||
|
|||||||
97
lua/lib/file.lua
Normal file
97
lua/lib/file.lua
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
local api = vim.api
|
||||||
|
local buf, win
|
||||||
|
|
||||||
|
local function scratch_buffer()
|
||||||
|
buf = api.nvim_create_buf(false, true)
|
||||||
|
api.nvim_buf_set_option(buf, 'bufhidden', 'wipe')
|
||||||
|
|
||||||
|
local width = api.nvim_get_option("columns")
|
||||||
|
local height = api.nvim_get_option("lines")
|
||||||
|
|
||||||
|
local win_height = 2
|
||||||
|
local win_width = 90
|
||||||
|
|
||||||
|
local row = math.ceil((height - win_height) / 2 - 1)
|
||||||
|
local col = math.ceil((width - win_width) / 2)
|
||||||
|
|
||||||
|
local opts = {
|
||||||
|
style = "minimal",
|
||||||
|
relative = "editor",
|
||||||
|
width = win_width,
|
||||||
|
height = win_height,
|
||||||
|
row = row,
|
||||||
|
col = col
|
||||||
|
}
|
||||||
|
|
||||||
|
local border_buf = api.nvim_create_buf(false, true)
|
||||||
|
|
||||||
|
local border_opts = {
|
||||||
|
style = "minimal",
|
||||||
|
relative = "editor",
|
||||||
|
width = win_width + 2,
|
||||||
|
height = win_height + 2,
|
||||||
|
row = row - 1,
|
||||||
|
col = col - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
local border_lines = { '┌' .. string.rep('─', win_width) .. '┐' }
|
||||||
|
local middle_line = '│' .. string.rep(' ', win_width) .. '│'
|
||||||
|
for _ = 1, win_height do
|
||||||
|
table.insert(border_lines, middle_line)
|
||||||
|
end
|
||||||
|
table.insert(border_lines, '└' .. string.rep('─', win_width) .. '┘')
|
||||||
|
api.nvim_buf_set_lines(border_buf, 0, -1, false, border_lines)
|
||||||
|
|
||||||
|
api.nvim_open_win(border_buf, true, border_opts)
|
||||||
|
api.nvim_command('setlocal nocursorline winhighlight=Normal:LuaNoEndOfBufferPopup')
|
||||||
|
win = api.nvim_open_win(buf, true, opts)
|
||||||
|
api.nvim_command('setlocal nocursorline winhighlight=Normal:LuaTreePopup')
|
||||||
|
api.nvim_command('au BufWipeout <buffer> exe "silent bwipeout! "'..border_buf)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_mappings()
|
||||||
|
local chars = {
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'h', 'j', 'l', 'q', 'k', 'g', 'i', 'n', 'o', 'p', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
|
||||||
|
}
|
||||||
|
for _,v in ipairs(chars) do
|
||||||
|
api.nvim_buf_set_keymap(buf, 'n', v, '', { nowait = true, noremap = true, silent = true })
|
||||||
|
api.nvim_buf_set_keymap(buf, 'n', v:upper(), '', { nowait = true, noremap = true, silent = true })
|
||||||
|
api.nvim_buf_set_keymap(buf, 'n', '<c-'..v..'>', '', { nowait = true, noremap = true, silent = true })
|
||||||
|
api.nvim_buf_set_keymap(buf, 'i', '<c-'..v..'>', '', { nowait = true, noremap = true, silent = true })
|
||||||
|
api.nvim_buf_set_keymap(buf, 'i', '<c-' ..v:upper()..'>', '', { nowait = true, noremap = true, silent = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function update_view(...)
|
||||||
|
api.nvim_buf_set_lines(buf, 0, -1, false, ...)
|
||||||
|
api.nvim_command('normal G')
|
||||||
|
api.nvim_command('startinsert!')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wrapper(...)
|
||||||
|
scratch_buffer()
|
||||||
|
update_view(...)
|
||||||
|
set_mappings()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function add_file(path)
|
||||||
|
wrapper({ "Create File", path })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove_file(filename, path, isdir)
|
||||||
|
local name = "File"
|
||||||
|
if isdir == true then name = "Directory" end
|
||||||
|
wrapper({ "Remove " .. name .. " " .. filename .. " ?", "y/n: " })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rename_file(filename, path, isdir)
|
||||||
|
local name = "File"
|
||||||
|
if isdir == true then name = "Directory" end
|
||||||
|
wrapper({ "Rename " .. name, path .. filename })
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
add_file = add_file;
|
||||||
|
remove_file = remove_file;
|
||||||
|
rename_file = rename_file;
|
||||||
|
}
|
||||||
53
lua/lib/format.lua
Normal file
53
lua/lib/format.lua
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
local api = vim.api
|
||||||
|
|
||||||
|
local function get_padding(depth)
|
||||||
|
local str = ""
|
||||||
|
|
||||||
|
while 0 < depth do
|
||||||
|
str = str .. " "
|
||||||
|
depth = depth - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
local function default_icons(_, isdir, open)
|
||||||
|
if isdir == true then
|
||||||
|
if open == true then return " " end
|
||||||
|
return " "
|
||||||
|
end
|
||||||
|
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dev_icons(pathname, isdir, open)
|
||||||
|
if isdir == true then return default_icons(pathname, isdir, open) end
|
||||||
|
|
||||||
|
return api.nvim_call_function('WebDevIconsGetFileTypeSymbol', { pathname, isdir }) .. " "
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_icon_func_gen()
|
||||||
|
if api.nvim_call_function('exists', { "WebDevIconsGetFileTypeSymbol" }) == 0 then
|
||||||
|
return dev_icons
|
||||||
|
else
|
||||||
|
return default_icons
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_icon = get_icon_func_gen()
|
||||||
|
|
||||||
|
local function format_tree(tree)
|
||||||
|
local dirs = {}
|
||||||
|
|
||||||
|
for i, node in pairs(tree) do
|
||||||
|
local padding = get_padding(node.depth)
|
||||||
|
local icon = get_icon(node.path .. node.name, node.dir, node.open)
|
||||||
|
dirs[i] = padding .. icon .. node.name
|
||||||
|
end
|
||||||
|
|
||||||
|
return dirs
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
format_tree = format_tree;
|
||||||
|
}
|
||||||
100
lua/tree.lua
100
lua/tree.lua
@ -1,9 +1,13 @@
|
|||||||
local api = vim.api
|
local lib_file = require 'lib/file'
|
||||||
local function sys(v) return vim.fn.system(v) end
|
local format = require 'lib/format'.format_tree
|
||||||
local function syslist(v) return vim.fn.systemlist(v) end
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
-- get rid of \n and add leading '/'
|
||||||
|
local ROOT_PATH = string.sub(sys('pwd'), 1, -2) .. '/'
|
||||||
local BUF_NAME = '_LuaTree_'
|
local BUF_NAME = '_LuaTree_'
|
||||||
local ROOT_PATH = string.sub(sys('pwd'), 1, -2) .. '/' -- get rid of \n and add leading '/'
|
|
||||||
|
|
||||||
local function is_dir(path)
|
local function is_dir(path)
|
||||||
local stat = vim.loop.fs_stat(path)
|
local stat = vim.loop.fs_stat(path)
|
||||||
@ -43,55 +47,6 @@ end
|
|||||||
|
|
||||||
local Tree = create_dirs(ROOT_PATH, 0, syslist('ls'))
|
local Tree = create_dirs(ROOT_PATH, 0, syslist('ls'))
|
||||||
|
|
||||||
local function get_padding(depth)
|
|
||||||
local str = ""
|
|
||||||
|
|
||||||
while 0 < depth do
|
|
||||||
str = str .. " "
|
|
||||||
depth = depth - 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return str
|
|
||||||
end
|
|
||||||
|
|
||||||
local function default_icons(_, isdir, open)
|
|
||||||
if isdir == true then
|
|
||||||
if open == true then return " " end
|
|
||||||
return " "
|
|
||||||
end
|
|
||||||
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dev_icons(pathname, isdir, open)
|
|
||||||
if isdir == true then return default_icons(pathname, isdir, open) end
|
|
||||||
|
|
||||||
return api.nvim_call_function('WebDevIconsGetFileTypeSymbol', { pathname, isdir }) .. " "
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_icon_func_gen()
|
|
||||||
if api.nvim_call_function('exists', { "WebDevIconsGetFileTypeSymbol" }) == 0 then
|
|
||||||
return dev_icons
|
|
||||||
else
|
|
||||||
return default_icons
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local get_icon = get_icon_func_gen()
|
|
||||||
|
|
||||||
local function format_tree(tree)
|
|
||||||
local dirs = {}
|
|
||||||
local previous_parent_index = -1
|
|
||||||
|
|
||||||
for i, node in pairs(tree) do
|
|
||||||
local padding = get_padding(node.depth)
|
|
||||||
local icon = get_icon(node.path .. node.name, node.dir, node.open)
|
|
||||||
dirs[i] = padding .. icon .. node.name
|
|
||||||
end
|
|
||||||
|
|
||||||
return dirs
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_buf()
|
local function get_buf()
|
||||||
local regex = '.*'..BUF_NAME..'$';
|
local regex = '.*'..BUF_NAME..'$';
|
||||||
|
|
||||||
@ -118,8 +73,7 @@ end
|
|||||||
|
|
||||||
local function buf_setup()
|
local function buf_setup()
|
||||||
api.nvim_command('setlocal nonumber norelativenumber winfixwidth winfixheight')
|
api.nvim_command('setlocal nonumber norelativenumber winfixwidth winfixheight')
|
||||||
api.nvim_command('hi NoEndOfBuffer guifg=bg')
|
api.nvim_command('setlocal winhighlight=EndOfBuffer:LuaTreeEndOfBuffer')
|
||||||
api.nvim_command('setlocal winhighlight=EndOfBuffer:NoEndOfBuffer')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function open()
|
local function open()
|
||||||
@ -156,7 +110,7 @@ local function update_view()
|
|||||||
|
|
||||||
local cursor_pos = api.nvim_win_get_cursor(0)
|
local cursor_pos = 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(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)
|
api.nvim_win_set_cursor(0, cursor_pos)
|
||||||
end
|
end
|
||||||
@ -200,6 +154,9 @@ 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")';
|
||||||
|
a = 'edit_file("add")';
|
||||||
|
d = 'edit_file("delete")';
|
||||||
|
r = 'edit_file("rename")';
|
||||||
f = 'find_file()';
|
f = 'find_file()';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +165,19 @@ local function set_mappings()
|
|||||||
nowait = true, noremap = true, silent = true
|
nowait = true, noremap = true, silent = true
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local maps = {
|
||||||
|
j = 'j$B',
|
||||||
|
k = 'k$B',
|
||||||
|
l = '<Nop>',
|
||||||
|
h = '<Nop>'
|
||||||
|
}
|
||||||
|
|
||||||
|
for k,v in pairs(maps) do
|
||||||
|
api.nvim_buf_set_keymap(buf, 'n', k, v, {
|
||||||
|
nowait = true, noremap = true, silent = true
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function toggle()
|
local function toggle()
|
||||||
@ -220,8 +190,26 @@ local function toggle()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function edit_file(edit_type)
|
||||||
|
local tree_index = api.nvim_win_get_cursor(0)[1]
|
||||||
|
local node = Tree[tree_index]
|
||||||
|
|
||||||
|
if edit_type == 'add' then
|
||||||
|
if node.dir == true then
|
||||||
|
lib_file.add_file(node.path .. node.name .. '/')
|
||||||
|
else
|
||||||
|
lib_file.add_file(node.path)
|
||||||
|
end
|
||||||
|
elseif edit_type == 'delete' then
|
||||||
|
lib_file.remove_file(node.name, node.path, node.dir)
|
||||||
|
elseif edit_type == 'rename' then
|
||||||
|
lib_file.rename_file(node.name, node.path, node.dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
toggle = toggle;
|
toggle = toggle;
|
||||||
open_file = open_file;
|
open_file = open_file;
|
||||||
|
edit_file = edit_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,9 @@ if exists('g:loaded_tree') | finish | endif
|
|||||||
let s:save_cpo = &cpo
|
let s:save_cpo = &cpo
|
||||||
set cpo&vim
|
set cpo&vim
|
||||||
|
|
||||||
|
hi def link LuaTreePopup Normal
|
||||||
|
hi def LuaTreeEndOfBuffer guifg=bg
|
||||||
|
|
||||||
command! LuaTree lua require'tree'.toggle()
|
command! LuaTree lua require'tree'.toggle()
|
||||||
|
|
||||||
let &cpo = s:save_cpo
|
let &cpo = s:save_cpo
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user