Adding new stuff
This commit is contained in:
parent
0074feeaf2
commit
57684cdc5c
1582 changed files with 205558 additions and 0 deletions
75
vim-plugins/bundle/nerdtree-git-plugin/README.md
Normal file
75
vim-plugins/bundle/nerdtree-git-plugin/README.md
Normal 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.
|
||||
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue