Adding new stuff

This commit is contained in:
ViktorBarzin 2017-07-09 00:26:06 +03:00
parent 0074feeaf2
commit 57684cdc5c
1582 changed files with 205558 additions and 0 deletions

View file

@ -0,0 +1,75 @@
nerdtree-git-plugin
===================
A plugin of NERDTree showing git status flags. Works with the **LATEST** version of NERDTree.
The original project [git-nerdtree](https://github.com/Xuyuanp/git-nerdtree) will not be maintained any longer.
![Imgur](http://i.imgur.com/jSCwGjU.gif?1)
## Installation
For Pathogen
`git clone https://github.com/Xuyuanp/nerdtree-git-plugin.git ~/.vim/bundle/nerdtree-git-plugin`
Now reload the `vim`
For Vundle
`Plugin 'scrooloose/nerdtree'`
`Plugin 'Xuyuanp/nerdtree-git-plugin'`
For NeoBundle
`NeoBundle 'scrooloose/nerdtree'`
`NeoBundle 'Xuyuanp/nerdtree-git-plugin'`
For Plug
`Plug 'scrooloose/nerdtree'`
`Plug 'Xuyuanp/nerdtree-git-plugin'`
## FAQ
> Got error message like `Error detected while processing function
177[2]..178[22]..181[7]..144[9]..142[36]..238[4]..NERDTreeGitStatusRefreshListener[2]..NERDTreeGitStatusRefresh:
line 6:
E484: Can't open file /tmp/vZEZ6gM/1` while nerdtree opening in fish, how to resolve this problem?
This was because that vim couldn't execute `system` function in `fish`. Add `set shell=sh` in your vimrc.
This issue has been fixed.
> How to config custom symbols?
Use this variable to change symbols.
```vimscript
let g:NERDTreeIndicatorMapCustom = {
\ "Modified" : "✹",
\ "Staged" : "✚",
\ "Untracked" : "✭",
\ "Renamed" : "➜",
\ "Unmerged" : "═",
\ "Deleted" : "✖",
\ "Dirty" : "✗",
\ "Clean" : "✔︎",
\ 'Ignored' : '☒',
\ "Unknown" : "?"
\ }
```
> How to show `ignored` status?
`let g:NERDTreeShowIgnoredStatus = 1` (a heavy feature may cost much more time)
## Credits
* [scrooloose](https://github.com/scrooloose): Open API for me.
* [git_nerd](https://github.com/swerner/git_nerd): Where my idea comes from.
* [PickRelated](https://github.com/PickRelated): Add custom indicators & Review code.

View file

@ -0,0 +1,359 @@
" ============================================================================
" File: git_status.vim
" Description: plugin for NERD Tree that provides git status support
" Maintainer: Xuyuan Pang <xuyuanp at gmail dot com>
" Last Change: 4 Apr 2014
" License: This program is free software. It comes without any warranty,
" to the extent permitted by applicable law. You can redistribute
" it and/or modify it under the terms of the Do What The Fuck You
" Want To Public License, Version 2, as published by Sam Hocevar.
" See http://sam.zoy.org/wtfpl/COPYING for more details.
" ============================================================================
if exists('g:loaded_nerdtree_git_status')
finish
endif
let g:loaded_nerdtree_git_status = 1
if !exists('g:NERDTreeShowGitStatus')
let g:NERDTreeShowGitStatus = 1
endif
if g:NERDTreeShowGitStatus == 0
finish
endif
if !exists('g:NERDTreeMapNextHunk')
let g:NERDTreeMapNextHunk = ']c'
endif
if !exists('g:NERDTreeMapPrevHunk')
let g:NERDTreeMapPrevHunk = '[c'
endif
if !exists('g:NERDTreeUpdateOnWrite')
let g:NERDTreeUpdateOnWrite = 1
endif
if !exists('g:NERDTreeUpdateOnCursorHold')
let g:NERDTreeUpdateOnCursorHold = 1
endif
if !exists('g:NERDTreeShowIgnoredStatus')
let g:NERDTreeShowIgnoredStatus = 0
endif
if !exists('s:NERDTreeIndicatorMap')
let s:NERDTreeIndicatorMap = {
\ 'Modified' : '✹',
\ 'Staged' : '✚',
\ 'Untracked' : '✭',
\ 'Renamed' : '➜',
\ 'Unmerged' : '═',
\ 'Deleted' : '✖',
\ 'Dirty' : '✗',
\ 'Clean' : '✔︎',
\ 'Ignored' : '☒',
\ 'Unknown' : '?'
\ }
endif
function! NERDTreeGitStatusRefreshListener(event)
if !exists('b:NOT_A_GIT_REPOSITORY')
call g:NERDTreeGitStatusRefresh()
endif
let l:path = a:event.subject
let l:flag = g:NERDTreeGetGitStatusPrefix(l:path)
call l:path.flagSet.clearFlags('git')
if l:flag !=# ''
call l:path.flagSet.addFlag('git', l:flag)
endif
endfunction
" FUNCTION: g:NERDTreeGitStatusRefresh() {{{2
" refresh cached git status
function! g:NERDTreeGitStatusRefresh()
let b:NERDTreeCachedGitFileStatus = {}
let b:NERDTreeCachedGitDirtyDir = {}
let b:NOT_A_GIT_REPOSITORY = 1
let l:root = b:NERDTree.root.path.str()
let l:gitcmd = 'git -c color.status=false status -s'
if g:NERDTreeShowIgnoredStatus
let l:gitcmd = l:gitcmd . ' --ignored'
endif
if exists('g:NERDTreeGitStatusIgnoreSubmodules')
let l:gitcmd = l:gitcmd . ' --ignore-submodules'
if g:NERDTreeGitStatusIgnoreSubmodules ==# 'all' || g:NERDTreeGitStatusIgnoreSubmodules ==# 'dirty' || g:NERDTreeGitStatusIgnoreSubmodules ==# 'untracked'
let l:gitcmd = l:gitcmd . '=' . g:NERDTreeGitStatusIgnoreSubmodules
endif
endif
let l:statusesStr = system(l:gitcmd . ' ' . l:root)
let l:statusesSplit = split(l:statusesStr, '\n')
if l:statusesSplit != [] && l:statusesSplit[0] =~# 'fatal:.*'
let l:statusesSplit = []
return
endif
let b:NOT_A_GIT_REPOSITORY = 0
for l:statusLine in l:statusesSplit
" cache git status of files
let l:pathStr = substitute(l:statusLine, '...', '', '')
let l:pathSplit = split(l:pathStr, ' -> ')
if len(l:pathSplit) == 2
call s:NERDTreeCacheDirtyDir(l:pathSplit[0])
let l:pathStr = l:pathSplit[1]
else
let l:pathStr = l:pathSplit[0]
endif
let l:pathStr = s:NERDTreeTrimDoubleQuotes(l:pathStr)
if l:pathStr =~# '\.\./.*'
continue
endif
let l:statusKey = s:NERDTreeGetFileGitStatusKey(l:statusLine[0], l:statusLine[1])
let b:NERDTreeCachedGitFileStatus[fnameescape(l:pathStr)] = l:statusKey
if l:statusKey == 'Ignored'
if isdirectory(l:pathStr)
let b:NERDTreeCachedGitDirtyDir[fnameescape(l:pathStr)] = l:statusKey
endif
else
call s:NERDTreeCacheDirtyDir(l:pathStr)
endif
endfor
endfunction
function! s:NERDTreeCacheDirtyDir(pathStr)
" cache dirty dir
let l:dirtyPath = s:NERDTreeTrimDoubleQuotes(a:pathStr)
if l:dirtyPath =~# '\.\./.*'
return
endif
let l:dirtyPath = substitute(l:dirtyPath, '/[^/]*$', '/', '')
while l:dirtyPath =~# '.\+/.*' && has_key(b:NERDTreeCachedGitDirtyDir, fnameescape(l:dirtyPath)) == 0
let b:NERDTreeCachedGitDirtyDir[fnameescape(l:dirtyPath)] = 'Dirty'
let l:dirtyPath = substitute(l:dirtyPath, '/[^/]*/$', '/', '')
endwhile
endfunction
function! s:NERDTreeTrimDoubleQuotes(pathStr)
let l:toReturn = substitute(a:pathStr, '^"', '', '')
let l:toReturn = substitute(l:toReturn, '"$', '', '')
return l:toReturn
endfunction
" FUNCTION: g:NERDTreeGetGitStatusPrefix(path) {{{2
" return the indicator of the path
" Args: path
let s:GitStatusCacheTimeExpiry = 2
let s:GitStatusCacheTime = 0
function! g:NERDTreeGetGitStatusPrefix(path)
if localtime() - s:GitStatusCacheTime > s:GitStatusCacheTimeExpiry
let s:GitStatusCacheTime = localtime()
call g:NERDTreeGitStatusRefresh()
endif
let l:pathStr = a:path.str()
let l:cwd = b:NERDTree.root.path.str() . a:path.Slash()
if nerdtree#runningWindows()
let l:pathStr = a:path.WinToUnixPath(l:pathStr)
let l:cwd = a:path.WinToUnixPath(l:cwd)
endif
let l:pathStr = substitute(l:pathStr, fnameescape(l:cwd), '', '')
let l:statusKey = ''
if a:path.isDirectory
let l:statusKey = get(b:NERDTreeCachedGitDirtyDir, fnameescape(l:pathStr . '/'), '')
else
let l:statusKey = get(b:NERDTreeCachedGitFileStatus, fnameescape(l:pathStr), '')
endif
return s:NERDTreeGetIndicator(l:statusKey)
endfunction
" FUNCTION: s:NERDTreeGetCWDGitStatus() {{{2
" return the indicator of cwd
function! g:NERDTreeGetCWDGitStatus()
if b:NOT_A_GIT_REPOSITORY
return ''
elseif b:NERDTreeCachedGitDirtyDir == {} && b:NERDTreeCachedGitFileStatus == {}
return s:NERDTreeGetIndicator('Clean')
endif
return s:NERDTreeGetIndicator('Dirty')
endfunction
function! s:NERDTreeGetIndicator(statusKey)
if exists('g:NERDTreeIndicatorMapCustom')
let l:indicator = get(g:NERDTreeIndicatorMapCustom, a:statusKey, '')
if l:indicator !=# ''
return l:indicator
endif
endif
let l:indicator = get(s:NERDTreeIndicatorMap, a:statusKey, '')
if l:indicator !=# ''
return l:indicator
endif
return ''
endfunction
function! s:NERDTreeGetFileGitStatusKey(us, them)
if a:us ==# '?' && a:them ==# '?'
return 'Untracked'
elseif a:us ==# ' ' && a:them ==# 'M'
return 'Modified'
elseif a:us =~# '[MAC]'
return 'Staged'
elseif a:us ==# 'R'
return 'Renamed'
elseif a:us ==# 'U' || a:them ==# 'U' || a:us ==# 'A' && a:them ==# 'A' || a:us ==# 'D' && a:them ==# 'D'
return 'Unmerged'
elseif a:them ==# 'D'
return 'Deleted'
elseif a:us ==# '!'
return 'Ignored'
else
return 'Unknown'
endif
endfunction
" FUNCTION: s:jumpToNextHunk(node) {{{2
function! s:jumpToNextHunk(node)
let l:position = search('\[[^{RO}].*\]', '')
if l:position
call nerdtree#echo('Jump to next hunk ')
endif
endfunction
" FUNCTION: s:jumpToPrevHunk(node) {{{2
function! s:jumpToPrevHunk(node)
let l:position = search('\[[^{RO}].*\]', 'b')
if l:position
call nerdtree#echo('Jump to prev hunk ')
endif
endfunction
" Function: s:SID() {{{2
function s:SID()
if !exists('s:sid')
let s:sid = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
endif
return s:sid
endfun
" FUNCTION: s:NERDTreeGitStatusKeyMapping {{{2
function! s:NERDTreeGitStatusKeyMapping()
let l:s = '<SNR>' . s:SID() . '_'
call NERDTreeAddKeyMap({
\ 'key': g:NERDTreeMapNextHunk,
\ 'scope': 'Node',
\ 'callback': l:s.'jumpToNextHunk',
\ 'quickhelpText': 'Jump to next git hunk' })
call NERDTreeAddKeyMap({
\ 'key': g:NERDTreeMapPrevHunk,
\ 'scope': 'Node',
\ 'callback': l:s.'jumpToPrevHunk',
\ 'quickhelpText': 'Jump to prev git hunk' })
endfunction
augroup nerdtreegitplugin
autocmd CursorHold * silent! call s:CursorHoldUpdate()
augroup END
" FUNCTION: s:CursorHoldUpdate() {{{2
function! s:CursorHoldUpdate()
if g:NERDTreeUpdateOnCursorHold != 1
return
endif
if !g:NERDTree.IsOpen()
return
endif
" Do not update when a special buffer is selected
if !empty(&l:buftype)
return
endif
let l:winnr = winnr()
let l:altwinnr = winnr('#')
call g:NERDTree.CursorToTreeWin()
call b:NERDTree.root.refreshFlags()
call NERDTreeRender()
exec l:altwinnr . 'wincmd w'
exec l:winnr . 'wincmd w'
endfunction
augroup nerdtreegitplugin
autocmd BufWritePost * call s:FileUpdate(expand('%:p'))
augroup END
" FUNCTION: s:FileUpdate(fname) {{{2
function! s:FileUpdate(fname)
if g:NERDTreeUpdateOnWrite != 1
return
endif
if !g:NERDTree.IsOpen()
return
endif
let l:winnr = winnr()
let l:altwinnr = winnr('#')
call g:NERDTree.CursorToTreeWin()
let l:node = b:NERDTree.root.findNode(g:NERDTreePath.New(a:fname))
if l:node == {}
return
endif
call l:node.refreshFlags()
let l:node = l:node.parent
while !empty(l:node)
call l:node.refreshDirFlags()
let l:node = l:node.parent
endwhile
call NERDTreeRender()
exec l:altwinnr . 'wincmd w'
exec l:winnr . 'wincmd w'
endfunction
augroup AddHighlighting
autocmd FileType nerdtree call s:AddHighlighting()
augroup END
function! s:AddHighlighting()
let l:synmap = {
\ 'NERDTreeGitStatusModified' : s:NERDTreeGetIndicator('Modified'),
\ 'NERDTreeGitStatusStaged' : s:NERDTreeGetIndicator('Staged'),
\ 'NERDTreeGitStatusUntracked' : s:NERDTreeGetIndicator('Untracked'),
\ 'NERDTreeGitStatusRenamed' : s:NERDTreeGetIndicator('Renamed'),
\ 'NERDTreeGitStatusIgnored' : s:NERDTreeGetIndicator('Ignored'),
\ 'NERDTreeGitStatusDirDirty' : s:NERDTreeGetIndicator('Dirty'),
\ 'NERDTreeGitStatusDirClean' : s:NERDTreeGetIndicator('Clean')
\ }
for l:name in keys(l:synmap)
exec 'syn match ' . l:name . ' #' . escape(l:synmap[l:name], '~') . '# containedin=NERDTreeFlags'
endfor
hi def link NERDTreeGitStatusModified Special
hi def link NERDTreeGitStatusStaged Function
hi def link NERDTreeGitStatusRenamed Title
hi def link NERDTreeGitStatusUnmerged Label
hi def link NERDTreeGitStatusUntracked Comment
hi def link NERDTreeGitStatusDirDirty Tag
hi def link NERDTreeGitStatusDirClean DiffAdd
" TODO: use diff color
hi def link NERDTreeGitStatusIgnored DiffAdd
endfunction
function! s:SetupListeners()
call g:NERDTreePathNotifier.AddListener('init', 'NERDTreeGitStatusRefreshListener')
call g:NERDTreePathNotifier.AddListener('refresh', 'NERDTreeGitStatusRefreshListener')
call g:NERDTreePathNotifier.AddListener('refreshFlags', 'NERDTreeGitStatusRefreshListener')
endfunction
if g:NERDTreeShowGitStatus && executable('git')
call s:NERDTreeGitStatusKeyMapping()
call s:SetupListeners()
endif