add git integration

This commit is contained in:
kiyan42 2020-02-18 18:22:05 +01:00
parent 0ed31e065e
commit f8fb6de9c6
6 changed files with 92 additions and 22 deletions

View File

@ -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.
- 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
- [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] 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)
- [ ] refresh tree (for git) on file save
- [ ] find a good way to display git info
- [ ] better parsing of the git porcelain results
- [ ] quickly find file in the directory structure
- [ ] 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 not disappear when only the tree is opened
- [ ] symbolic links
- [ ] handle symbolic links

View File

@ -108,6 +108,15 @@ local HIGHLIGHT_GROUPS = {
['^.*%.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(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.name ~= '..' then
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
highlight('LuaTreeFolderName', line, 0, -1)
end
return
elseif is_special(node.name) == true then
highlight('LuaTreeSpecialFile', line, 0, -1)
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
if string.match(node.name, k) ~= nil then
highlight('LuaTree' .. v, line, 0, text_start)
break
highlight_git(highlight, node, line, text_start)
return
end
end
end
highlight_git(highlight, node, line, text_start - 4)
end
end

44
lua/lib/git.lua Normal file
View 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;
}

View File

@ -1,6 +1,7 @@
local api = vim.api
local function syslist(v) return api.nvim_call_function('systemlist', { v }) end
local get_root_path = require 'lib/conf'.get_root_path
local get_git_attr = require 'lib/git'.get_git_attr
local Tree = {}
@ -44,13 +45,16 @@ local function create_nodes(path, depth, dirs)
if not string.find(path, '^.*/$') then path = path .. '/' end
for i, name in pairs(dirs) do
local full_path = path..name
local dir = is_dir(full_path)
tree[i] = {
path = path,
name = name,
depth = depth,
dir = is_dir(path .. name),
open = false, -- only relevant when its a dir
icon = true
dir = dir,
open = false,
icon = true,
git = get_git_attr(full_path, dir)
}
end
@ -67,7 +71,8 @@ local function init_tree()
depth = 0,
dir = true,
open = false,
icon = false
icon = false,
git = ''
})
end
end
@ -129,4 +134,5 @@ return {
get_tree = get_tree;
refresh_tree = refresh_tree;
open_dir = open_dir;
check_dir_access = check_dir_access;
}

View File

@ -66,16 +66,14 @@ local function open()
end
local function close()
local BUF_NAME = get_buf_name()
local win = get_win(BUF_NAME)
local win = get_win()
if not win then return end
api.nvim_win_close(win, true)
end
local function update_view(update_cursor)
local BUF_NAME = get_buf_name()
local buf = get_buf(BUF_NAME);
local buf = get_buf();
if not buf then return end
local cursor = api.nvim_win_get_cursor(0)

View File

@ -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 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()
let &cpo = s:save_cpo