add git integration
This commit is contained in:
24
README.md
24
README.md
@@ -6,18 +6,18 @@
|
|||||||
- 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 will not work on windows.
|
- This plugin will not work on windows.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- [x] open file in current buffer or in split with FzF like bindings (`CR`, `C-v`, `C-x`)
|
||||||
|
- [x] file icons with vim-devicons
|
||||||
|
- [x] syntax highlighting ([exa](https://github.com/ogham/exa) like)
|
||||||
|
- [x] Change directory with `C-[`
|
||||||
|
- [x] Add / Rename / delete files
|
||||||
|
- [x] Git integration
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
- [ ] refresh tree (for git) on file save
|
||||||
- [x] moving around the file structure like any basic tree
|
- [ ] find a good way to display git info
|
||||||
- [x] open file in current buffer or in split with FzF like bindings (CR, C-v, C-x)
|
- [ ] better parsing of the git porcelain results
|
||||||
- [x] icons for files
|
|
||||||
|
|
||||||
- [x] change directory base
|
|
||||||
- [x] add / rename / delete file in directory
|
|
||||||
- [x] update tree when altering the FS
|
|
||||||
|
|
||||||
- [x] syntax highlighting ([exa](https://github.com/ogham/exa) like) and file icons with vim-devicons
|
|
||||||
- [ ] 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
|
||||||
@@ -26,4 +26,4 @@
|
|||||||
- [ ] buffer / window should always stay on the left and never change size (open a file with only the tree open to reproduce this bug)
|
- [ ] buffer / window should always stay on the left and never change size (open a file with only the tree open to reproduce this bug)
|
||||||
- [ ] buffer / window should not disappear when only the tree is opened
|
- [ ] buffer / window should not disappear when only the tree is opened
|
||||||
|
|
||||||
- [ ] symbolic links
|
- [ ] handle symbolic links
|
||||||
|
|||||||
@@ -108,6 +108,15 @@ local HIGHLIGHT_GROUPS = {
|
|||||||
['^.*%.html?$'] = 'HtmlFile';
|
['^.*%.html?$'] = 'HtmlFile';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local function highlight_git(highlight, node, line, col_start)
|
||||||
|
if node.git ~= '' then
|
||||||
|
highlight('LuaTreeGit'..node.git, line, col_start, -1)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
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)
|
vim.api.nvim_buf_add_highlight(buffer, -1, group, line, from, to)
|
||||||
@@ -117,10 +126,14 @@ local function highlight_line(buffer)
|
|||||||
if node.dir then
|
if node.dir then
|
||||||
if node.name ~= '..' then
|
if node.name ~= '..' then
|
||||||
highlight('LuaTreeFolderIcon', line, 0, text_start)
|
highlight('LuaTreeFolderIcon', line, 0, text_start)
|
||||||
highlight('LuaTreeFolderName', line, text_start, -1)
|
|
||||||
|
if highlight_git(highlight, node, line, text_start) == false then
|
||||||
|
highlight('LuaTreeFolderName', line, text_start, -1)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
highlight('LuaTreeFolderName', line, 0, -1)
|
highlight('LuaTreeFolderName', line, 0, -1)
|
||||||
end
|
end
|
||||||
|
return
|
||||||
elseif is_special(node.name) == true then
|
elseif is_special(node.name) == true then
|
||||||
highlight('LuaTreeSpecialFile', line, 0, -1)
|
highlight('LuaTreeSpecialFile', line, 0, -1)
|
||||||
elseif is_executable(node.path .. node.name) then
|
elseif is_executable(node.path .. node.name) then
|
||||||
@@ -131,10 +144,12 @@ local function highlight_line(buffer)
|
|||||||
for k, v in pairs(HIGHLIGHT_GROUPS) do
|
for k, v in pairs(HIGHLIGHT_GROUPS) do
|
||||||
if string.match(node.name, k) ~= nil then
|
if string.match(node.name, k) ~= nil then
|
||||||
highlight('LuaTree' .. v, line, 0, text_start)
|
highlight('LuaTree' .. v, line, 0, text_start)
|
||||||
break
|
highlight_git(highlight, node, line, text_start)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
highlight_git(highlight, node, line, text_start - 4)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
44
lua/lib/git.lua
Normal file
44
lua/lib/git.lua
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
local function system(v) return vim.api.nvim_call_function('system', { v }) end
|
||||||
|
|
||||||
|
local function is_git_repo()
|
||||||
|
local is_git = system('git rev-parse')
|
||||||
|
return string.match(is_git, 'fatal') == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local GIT_CMD = 'git status --porcelain=v1 '
|
||||||
|
|
||||||
|
local function is_folder_dirty(path)
|
||||||
|
local ret = system(GIT_CMD..path)
|
||||||
|
return ret ~= nil and ret ~= ''
|
||||||
|
end
|
||||||
|
|
||||||
|
local function create_git_checker(pattern)
|
||||||
|
return function(path)
|
||||||
|
local ret = system(GIT_CMD..path)
|
||||||
|
return string.match(ret, pattern) ~= nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local is_modified = create_git_checker('^ ?MM?')
|
||||||
|
local is_staged = create_git_checker('^ ?A')
|
||||||
|
local is_unmerged = create_git_checker('^ ?UU')
|
||||||
|
local is_untracked = create_git_checker('^%?%?')
|
||||||
|
|
||||||
|
local function get_git_attr(path, is_dir)
|
||||||
|
if is_git_repo() == false then return '' end
|
||||||
|
if is_dir then
|
||||||
|
if is_folder_dirty(path) == true then return 'Dirty' end
|
||||||
|
else
|
||||||
|
if is_modified(path) then return 'Modified'
|
||||||
|
elseif is_staged(path) then return 'Staged'
|
||||||
|
elseif is_unmerged(path) then return 'Unmerged'
|
||||||
|
elseif is_untracked(path) then return 'Untracked'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
get_git_attr = get_git_attr;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
local api = vim.api
|
local api = vim.api
|
||||||
local function syslist(v) return api.nvim_call_function('systemlist', { v }) end
|
local function syslist(v) return api.nvim_call_function('systemlist', { v }) end
|
||||||
local get_root_path = require 'lib/conf'.get_root_path
|
local get_root_path = require 'lib/conf'.get_root_path
|
||||||
|
local get_git_attr = require 'lib/git'.get_git_attr
|
||||||
|
|
||||||
local Tree = {}
|
local Tree = {}
|
||||||
|
|
||||||
@@ -44,13 +45,16 @@ local function create_nodes(path, depth, dirs)
|
|||||||
if not string.find(path, '^.*/$') then path = path .. '/' end
|
if not string.find(path, '^.*/$') then path = path .. '/' end
|
||||||
|
|
||||||
for i, name in pairs(dirs) do
|
for i, name in pairs(dirs) do
|
||||||
|
local full_path = path..name
|
||||||
|
local dir = is_dir(full_path)
|
||||||
tree[i] = {
|
tree[i] = {
|
||||||
path = path,
|
path = path,
|
||||||
name = name,
|
name = name,
|
||||||
depth = depth,
|
depth = depth,
|
||||||
dir = is_dir(path .. name),
|
dir = dir,
|
||||||
open = false, -- only relevant when its a dir
|
open = false,
|
||||||
icon = true
|
icon = true,
|
||||||
|
git = get_git_attr(full_path, dir)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -67,7 +71,8 @@ local function init_tree()
|
|||||||
depth = 0,
|
depth = 0,
|
||||||
dir = true,
|
dir = true,
|
||||||
open = false,
|
open = false,
|
||||||
icon = false
|
icon = false,
|
||||||
|
git = ''
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -129,4 +134,5 @@ return {
|
|||||||
get_tree = get_tree;
|
get_tree = get_tree;
|
||||||
refresh_tree = refresh_tree;
|
refresh_tree = refresh_tree;
|
||||||
open_dir = open_dir;
|
open_dir = open_dir;
|
||||||
|
check_dir_access = check_dir_access;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,16 +66,14 @@ local function open()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function close()
|
local function close()
|
||||||
local BUF_NAME = get_buf_name()
|
local win = get_win()
|
||||||
local win = get_win(BUF_NAME)
|
|
||||||
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)
|
local function update_view(update_cursor)
|
||||||
local BUF_NAME = get_buf_name()
|
local buf = get_buf();
|
||||||
local buf = get_buf(BUF_NAME);
|
|
||||||
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)
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ execute 'hi def LuaTreeRustFile guifg='.g:terminal_color_11
|
|||||||
execute 'hi def LuaTreeVimFile guifg='.g:terminal_color_10
|
execute 'hi def LuaTreeVimFile guifg='.g:terminal_color_10
|
||||||
execute 'hi def LuaTreeTypescriptFile guifg='.g:terminal_color_12
|
execute 'hi def LuaTreeTypescriptFile guifg='.g:terminal_color_12
|
||||||
|
|
||||||
|
" TODO: fix those colors to be better or maybe info git with letters instead of colors
|
||||||
|
execute 'hi def LuaTreeGitModified gui=NONE guifg='.g:terminal_color_13
|
||||||
|
execute 'hi def LuaTreeGitStaged gui=NONE guifg='.g:terminal_color_2
|
||||||
|
execute 'hi def LuaTreeGitUntracked gui=NONE guifg='.g:terminal_color_6
|
||||||
|
execute 'hi def LuaTreeGitUnmerged gui=NONE guifg='.g:terminal_color_3
|
||||||
|
execute 'hi def LuaTreeGitDirty gui=NONE guifg='.g:terminal_color_13
|
||||||
|
|
||||||
command! LuaTree lua require'tree'.toggle()
|
command! LuaTree lua require'tree'.toggle()
|
||||||
|
|
||||||
let &cpo = s:save_cpo
|
let &cpo = s:save_cpo
|
||||||
|
|||||||
Reference in New Issue
Block a user