Add vim plugins
This commit is contained in:
parent
1f6117d004
commit
256b0cc80f
2
.vim/after/ftplugin/c.vim
Normal file
2
.vim/after/ftplugin/c.vim
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
" OmniCppComplete initialization
|
||||||
|
call omni#cpp#complete#Init()
|
2
.vim/after/ftplugin/cpp.vim
Normal file
2
.vim/after/ftplugin/cpp.vim
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
" OmniCppComplete initialization
|
||||||
|
call omni#cpp#complete#Init()
|
32
.vim/autoload/omni/common/debug.vim
Normal file
32
.vim/autoload/omni/common/debug.vim
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
" Description: Omni completion debug functions
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
let s:CACHE_DEBUG_TRACE = []
|
||||||
|
|
||||||
|
" Start debug, clear the debug file
|
||||||
|
function! omni#common#debug#Start()
|
||||||
|
let s:CACHE_DEBUG_TRACE = []
|
||||||
|
call extend(s:CACHE_DEBUG_TRACE, ['============ Debug Start ============'])
|
||||||
|
call writefile(s:CACHE_DEBUG_TRACE, "Omni.dbg")
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" End debug, write to debug file
|
||||||
|
function! omni#common#debug#End()
|
||||||
|
call extend(s:CACHE_DEBUG_TRACE, ["============= Debug End ============="])
|
||||||
|
call extend(s:CACHE_DEBUG_TRACE, [""])
|
||||||
|
call writefile(s:CACHE_DEBUG_TRACE, "Omni.dbg")
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Debug trace function
|
||||||
|
function! omni#common#debug#Trace(szFuncName, ...)
|
||||||
|
let szTrace = a:szFuncName
|
||||||
|
let paramNum = a:0
|
||||||
|
if paramNum>0
|
||||||
|
let szTrace .= ':'
|
||||||
|
endif
|
||||||
|
for i in range(paramNum)
|
||||||
|
let szTrace = szTrace .' ('. string(eval('a:'.string(i+1))).')'
|
||||||
|
endfor
|
||||||
|
call extend(s:CACHE_DEBUG_TRACE, [szTrace])
|
||||||
|
endfunc
|
67
.vim/autoload/omni/common/utils.vim
Normal file
67
.vim/autoload/omni/common/utils.vim
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
" Description: Omni completion utils
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
" For sort numbers in list
|
||||||
|
function! omni#common#utils#CompareNumber(i1, i2)
|
||||||
|
let num1 = eval(a:i1)
|
||||||
|
let num2 = eval(a:i2)
|
||||||
|
return num1 == num2 ? 0 : num1 > num2 ? 1 : -1
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" TagList function calling the vim taglist() with try catch
|
||||||
|
" The only throwed exception is 'TagList:UserInterrupt'
|
||||||
|
" We also force the noignorecase option to avoid linear search when calling
|
||||||
|
" taglist()
|
||||||
|
function! omni#common#utils#TagList(szTagQuery)
|
||||||
|
let result = []
|
||||||
|
let bUserIgnoreCase = &ignorecase
|
||||||
|
" Forcing noignorecase search => binary search can be used in taglist()
|
||||||
|
" if tags in the tag file are sorted
|
||||||
|
if bUserIgnoreCase
|
||||||
|
set noignorecase
|
||||||
|
endif
|
||||||
|
try
|
||||||
|
let result = taglist(a:szTagQuery)
|
||||||
|
catch /^Vim:Interrupt$/
|
||||||
|
" Restoring user's setting
|
||||||
|
if bUserIgnoreCase
|
||||||
|
set ignorecase
|
||||||
|
endif
|
||||||
|
throw 'TagList:UserInterrupt'
|
||||||
|
catch
|
||||||
|
"Note: it seems that ctags can generate corrupted files, in this case
|
||||||
|
"taglist() will fail to read the tagfile and an exception from
|
||||||
|
"has_add() is thrown
|
||||||
|
endtry
|
||||||
|
|
||||||
|
" Restoring user's setting
|
||||||
|
if bUserIgnoreCase
|
||||||
|
set ignorecase
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Same as TagList but don't throw exception
|
||||||
|
function! omni#common#utils#TagListNoThrow(szTagQuery)
|
||||||
|
let result = []
|
||||||
|
try
|
||||||
|
let result = omni#common#utils#TagList(a:szTagQuery)
|
||||||
|
catch
|
||||||
|
endtry
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the word under the cursor
|
||||||
|
function! omni#common#utils#GetWordUnderCursor()
|
||||||
|
let szLine = getline('.')
|
||||||
|
let startPos = getpos('.')[2]-1
|
||||||
|
let startPos = (startPos < 0)? 0 : startPos
|
||||||
|
if szLine[startPos] =~ '\w'
|
||||||
|
let startPos = searchpos('\<\w\+', 'cbn', line('.'))[1] - 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let startPos = (startPos < 0)? 0 : startPos
|
||||||
|
let szResult = matchstr(szLine, '\w\+', startPos)
|
||||||
|
return szResult
|
||||||
|
endfunc
|
569
.vim/autoload/omni/cpp/complete.vim
Normal file
569
.vim/autoload/omni/cpp/complete.vim
Normal file
@ -0,0 +1,569 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 27 sept. 2007
|
||||||
|
|
||||||
|
if v:version < 700
|
||||||
|
echohl WarningMsg
|
||||||
|
echomsg "omni#cpp#complete.vim: Please install vim 7.0 or higher for omni-completion"
|
||||||
|
echohl None
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
call omni#cpp#settings#Init()
|
||||||
|
let s:OmniCpp_ShowScopeInAbbr = g:OmniCpp_ShowScopeInAbbr
|
||||||
|
let s:OmniCpp_ShowPrototypeInAbbr = g:OmniCpp_ShowPrototypeInAbbr
|
||||||
|
let s:OmniCpp_ShowAccess = g:OmniCpp_ShowAccess
|
||||||
|
let s:szCurrentWorkingDir = getcwd()
|
||||||
|
|
||||||
|
" Cache data
|
||||||
|
let s:CACHE_TAG_POPUP_ITEMS = {}
|
||||||
|
let s:CACHE_TAG_FILES = {}
|
||||||
|
let s:CACHE_TAG_ENV = ''
|
||||||
|
let s:CACHE_OVERLOADED_FUNCTIONS = {}
|
||||||
|
|
||||||
|
" Has preview window?
|
||||||
|
let s:hasPreviewWindow = match(&completeopt, 'preview')>=0
|
||||||
|
let s:hasPreviewWindowOld = s:hasPreviewWindow
|
||||||
|
|
||||||
|
" Popup item list
|
||||||
|
let s:popupItemResultList = []
|
||||||
|
|
||||||
|
" May complete indicator
|
||||||
|
let s:bMayComplete = 0
|
||||||
|
|
||||||
|
" Init mappings
|
||||||
|
function! omni#cpp#complete#Init()
|
||||||
|
call omni#cpp#settings#Init()
|
||||||
|
set omnifunc=omni#cpp#complete#Main
|
||||||
|
inoremap <expr> <C-X><C-O> omni#cpp#maycomplete#Complete()
|
||||||
|
inoremap <expr> . omni#cpp#maycomplete#Dot()
|
||||||
|
inoremap <expr> > omni#cpp#maycomplete#Arrow()
|
||||||
|
inoremap <expr> : omni#cpp#maycomplete#Scope()
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Find the start position of the completion
|
||||||
|
function! s:FindStartPositionOfCompletion()
|
||||||
|
" Locate the start of the item, including ".", "->" and "[...]".
|
||||||
|
let line = getline('.')
|
||||||
|
let start = col('.') - 1
|
||||||
|
|
||||||
|
let lastword = -1
|
||||||
|
while start > 0
|
||||||
|
if line[start - 1] =~ '\w'
|
||||||
|
let start -= 1
|
||||||
|
elseif line[start - 1] =~ '\.'
|
||||||
|
" Searching for dot '.'
|
||||||
|
if lastword == -1
|
||||||
|
let lastword = start
|
||||||
|
endif
|
||||||
|
let start -= 1
|
||||||
|
elseif start > 1 && line[start - 2] == '-' && line[start - 1] == '>'
|
||||||
|
" Searching for '->'
|
||||||
|
if lastword == -1
|
||||||
|
let lastword = start
|
||||||
|
endif
|
||||||
|
let start -= 2
|
||||||
|
elseif start > 1 && line[start - 2] == ':' && line[start - 1] == ':'
|
||||||
|
" Searching for '::' for namespaces and class
|
||||||
|
if lastword == -1
|
||||||
|
let lastword = start
|
||||||
|
endif
|
||||||
|
let start -= 2
|
||||||
|
elseif line[start - 1] == ']'
|
||||||
|
" Skip over [...].
|
||||||
|
let n = 0
|
||||||
|
let start -= 1
|
||||||
|
while start > 0
|
||||||
|
let start -= 1
|
||||||
|
if line[start] == '['
|
||||||
|
if n == 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
let n -= 1
|
||||||
|
elseif line[start] == ']' " nested []
|
||||||
|
let n += 1
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
if lastword==-1
|
||||||
|
" For completion on the current scope
|
||||||
|
let lastword = start
|
||||||
|
endif
|
||||||
|
return lastword
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Returns if szKey1.szKey2 is in the cache
|
||||||
|
" @return
|
||||||
|
" - 0 = key not found
|
||||||
|
" - 1 = szKey1.szKey2 found
|
||||||
|
" - 2 = szKey1.[part of szKey2] found
|
||||||
|
function! s:IsCached(cache, szKey1, szKey2)
|
||||||
|
" Searching key in the result cache
|
||||||
|
let szResultKey = a:szKey1 . a:szKey2
|
||||||
|
let result = [0, szResultKey]
|
||||||
|
if a:szKey2 != ''
|
||||||
|
let szKey = a:szKey2
|
||||||
|
while len(szKey)>0
|
||||||
|
if has_key(a:cache, a:szKey1 . szKey)
|
||||||
|
let result[1] = a:szKey1 . szKey
|
||||||
|
if szKey != a:szKey2
|
||||||
|
let result[0] = 2
|
||||||
|
else
|
||||||
|
let result[0] = 1
|
||||||
|
endif
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
let szKey = szKey[:-2]
|
||||||
|
endwhile
|
||||||
|
else
|
||||||
|
if has_key(a:cache, szResultKey)
|
||||||
|
let result[0] = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Extend a tag item to a popup item
|
||||||
|
function! s:ExtendTagItemToPopupItem(tagItem, szTypeName)
|
||||||
|
let tagItem = a:tagItem
|
||||||
|
|
||||||
|
" Add the access
|
||||||
|
let szItemMenu = ''
|
||||||
|
let accessChar = {'public': '+','protected': '#','private': '-'}
|
||||||
|
if g:OmniCpp_ShowAccess
|
||||||
|
if has_key(tagItem, 'access') && has_key(accessChar, tagItem.access)
|
||||||
|
let szItemMenu = szItemMenu.accessChar[tagItem.access]
|
||||||
|
else
|
||||||
|
let szItemMenu = szItemMenu." "
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Formating optional menu string we extract the scope information
|
||||||
|
let szName = substitute(tagItem.name, '.*::', '', 'g')
|
||||||
|
let szItemWord = szName
|
||||||
|
let szAbbr = szName
|
||||||
|
|
||||||
|
if !g:OmniCpp_ShowScopeInAbbr
|
||||||
|
let szScopeOfTag = omni#cpp#utils#ExtractScope(tagItem)
|
||||||
|
let szItemMenu = szItemMenu.' '.szScopeOfTag[2:]
|
||||||
|
let szItemMenu = substitute(szItemMenu, '\s\+$', '', 'g')
|
||||||
|
else
|
||||||
|
let szAbbr = tagItem.name
|
||||||
|
endif
|
||||||
|
if g:OmniCpp_ShowAccess
|
||||||
|
let szItemMenu = substitute(szItemMenu, '^\s\+$', '', 'g')
|
||||||
|
else
|
||||||
|
let szItemMenu = substitute(szItemMenu, '\(^\s\+\)\|\(\s\+$\)', '', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Formating information for the preview window
|
||||||
|
if index(['f', 'p'], tagItem.kind[0])>=0
|
||||||
|
let szItemWord .= '('
|
||||||
|
if g:OmniCpp_ShowPrototypeInAbbr && has_key(tagItem, 'signature')
|
||||||
|
let szAbbr .= tagItem.signature
|
||||||
|
else
|
||||||
|
let szAbbr .= '('
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
let szItemInfo = ''
|
||||||
|
if s:hasPreviewWindow
|
||||||
|
let szItemInfo = omni#cpp#utils#GetPreviewWindowStringFromTagItem(tagItem)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" If a function is a ctor we add a new key in the tagItem
|
||||||
|
if index(['f', 'p'], tagItem.kind[0])>=0
|
||||||
|
if match(szName, '^\~') < 0 && a:szTypeName =~ '\C\<'.szName.'$'
|
||||||
|
" It's a ctor
|
||||||
|
let tagItem['ctor'] = 1
|
||||||
|
elseif has_key(tagItem, 'access') && tagItem.access == 'friend'
|
||||||
|
" Friend function
|
||||||
|
let tagItem['friendfunc'] = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Extending the tag item to a popup item
|
||||||
|
let tagItem['word'] = szItemWord
|
||||||
|
let tagItem['abbr'] = szAbbr
|
||||||
|
let tagItem['menu'] = szItemMenu
|
||||||
|
let tagItem['info'] = szItemInfo
|
||||||
|
let tagItem['dup'] = (s:hasPreviewWindow && index(['f', 'p', 'm'], tagItem.kind[0])>=0)
|
||||||
|
return tagItem
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get tag popup item list
|
||||||
|
function! s:TagPopupList(szTypeName, szBase)
|
||||||
|
let result = []
|
||||||
|
|
||||||
|
" Searching key in the result cache
|
||||||
|
let cacheResult = s:IsCached(s:CACHE_TAG_POPUP_ITEMS, a:szTypeName, a:szBase)
|
||||||
|
|
||||||
|
" Building the tag query, we don't forget dtors when a:szBase==''
|
||||||
|
if a:szTypeName!=''
|
||||||
|
" Scope search
|
||||||
|
let szTagQuery = '^' . a:szTypeName . '::' . a:szBase . '\~\?\w\+$'
|
||||||
|
else
|
||||||
|
" Global search
|
||||||
|
let szTagQuery = '^' . a:szBase . '\w\+$'
|
||||||
|
endif
|
||||||
|
|
||||||
|
" If the result is already in the cache we return it
|
||||||
|
if cacheResult[0]
|
||||||
|
let result = s:CACHE_TAG_POPUP_ITEMS[ cacheResult[1] ]
|
||||||
|
if cacheResult[0] == 2
|
||||||
|
let result = filter(copy(result), 'v:val.name =~ szTagQuery' )
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
" Getting tags
|
||||||
|
let result = omni#common#utils#TagList(szTagQuery)
|
||||||
|
|
||||||
|
" We extend tag items to popup items
|
||||||
|
call map(result, 's:ExtendTagItemToPopupItem(v:val, a:szTypeName)')
|
||||||
|
|
||||||
|
" We store the result in a cache
|
||||||
|
if cacheResult[1] != ''
|
||||||
|
let s:CACHE_TAG_POPUP_ITEMS[ cacheResult[1] ] = result
|
||||||
|
endif
|
||||||
|
catch /^TagList:UserInterrupt$/
|
||||||
|
endtry
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Find complete matches for a completion on the global scope
|
||||||
|
function! s:SearchGlobalMembers(szBase)
|
||||||
|
if a:szBase != ''
|
||||||
|
let tagPopupList = s:TagPopupList('', a:szBase)
|
||||||
|
let tagPopupList = filter(copy(tagPopupList), g:omni#cpp#utils#szFilterGlobalScope)
|
||||||
|
call extend(s:popupItemResultList, tagPopupList)
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Search class, struct, union members
|
||||||
|
" @param resolvedTagItem: a resolved tag item
|
||||||
|
" @param szBase: string base
|
||||||
|
" @return list of tag items extended to popup items
|
||||||
|
function! s:SearchMembers(resolvedTagItem, szBase)
|
||||||
|
let result = []
|
||||||
|
if a:resolvedTagItem == {}
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Get type info without the starting '::'
|
||||||
|
let szTagName = omni#cpp#utils#ExtractTypeInfoFromTag(a:resolvedTagItem)[2:]
|
||||||
|
|
||||||
|
" Unnamed type case. A tag item representing an unnamed type is a variable
|
||||||
|
" ('v') a member ('m') or a typedef ('t')
|
||||||
|
if index(['v', 't', 'm'], a:resolvedTagItem.kind[0])>=0 && has_key(a:resolvedTagItem, 'typeref')
|
||||||
|
" We remove the 'struct:' or 'class:' etc...
|
||||||
|
let szTagName = substitute(a:resolvedTagItem.typeref, '^\w\+:', '', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return copy(s:TagPopupList(szTagName, a:szBase))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Return if the tag env has changed
|
||||||
|
function! s:HasTagEnvChanged()
|
||||||
|
if s:CACHE_TAG_ENV == &tags
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
let s:CACHE_TAG_ENV = &tags
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Return if a tag file has changed in tagfiles()
|
||||||
|
function! s:HasATagFileOrTagEnvChanged()
|
||||||
|
if s:HasTagEnvChanged()
|
||||||
|
let s:CACHE_TAG_FILES = {}
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = 0
|
||||||
|
for tagFile in tagfiles()
|
||||||
|
if tagFile == ""
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(s:CACHE_TAG_FILES, tagFile)
|
||||||
|
let currentFiletime = getftime(tagFile)
|
||||||
|
if currentFiletime > s:CACHE_TAG_FILES[tagFile]
|
||||||
|
" The file has changed, updating the cache
|
||||||
|
let s:CACHE_TAG_FILES[tagFile] = currentFiletime
|
||||||
|
let result = 1
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" We store the time of the file
|
||||||
|
let s:CACHE_TAG_FILES[tagFile] = getftime(tagFile)
|
||||||
|
let result = 1
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
" Initialization
|
||||||
|
call s:HasATagFileOrTagEnvChanged()
|
||||||
|
|
||||||
|
" Filter same function signatures of base classes
|
||||||
|
function! s:FilterOverloadedFunctions(tagPopupList)
|
||||||
|
let result = []
|
||||||
|
for tagPopupItem in a:tagPopupList
|
||||||
|
if has_key(tagPopupItem, 'kind') && index(['f', 'p'], tagPopupItem.kind[0])>=0 && has_key(tagPopupItem, 'signature')
|
||||||
|
if !has_key(s:CACHE_OVERLOADED_FUNCTIONS, tagPopupItem.word . tagPopupItem.signature)
|
||||||
|
let s:CACHE_OVERLOADED_FUNCTIONS[tagPopupItem.word . tagPopupItem.signature] = 1
|
||||||
|
call extend(result, [tagPopupItem])
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
call extend(result, [tagPopupItem])
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Access filter
|
||||||
|
function! s:GetAccessFilter(szFilter, szAccessFilter)
|
||||||
|
let szFilter = a:szFilter
|
||||||
|
if g:OmniCpp_DisplayMode == 0
|
||||||
|
if a:szAccessFilter == 'public'
|
||||||
|
" We only get public members
|
||||||
|
let szFilter .= "&& v:val.access == 'public'"
|
||||||
|
elseif a:szAccessFilter == 'protected'
|
||||||
|
" We get public and protected members
|
||||||
|
let szFilter .= "&& v:val.access != 'private'"
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return szFilter
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Filter class members in the popup menu after a completion with -> or .
|
||||||
|
function! s:FilterClassMembers(tagPopupList, szAccessFilter)
|
||||||
|
let szFilter = "(!has_key(v:val, 'friendfunc') && !has_key(v:val, 'ctor') && has_key(v:val, 'kind') && index(['m', 'p', 'f'], v:val.kind[0])>=0 && has_key(v:val, 'access'))"
|
||||||
|
call filter(a:tagPopupList, s:GetAccessFilter(szFilter, a:szAccessFilter))
|
||||||
|
call extend(s:popupItemResultList, s:FilterOverloadedFunctions(a:tagPopupList))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Filter class scope members in the popup menu after a completion with ::
|
||||||
|
" We only display attribute and functions members that
|
||||||
|
" have an access information. We also display nested
|
||||||
|
" class, struct, union, and enums, typedefs
|
||||||
|
function! s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
|
||||||
|
let szFilter = "!has_key(v:val, 'friendfunc') && has_key(v:val, 'kind') && (index(['m', 'p', 'f'], v:val.kind[0])>=0 && has_key(v:val, 'access'))"
|
||||||
|
let szFilter = s:GetAccessFilter(szFilter, a:szAccessFilter)
|
||||||
|
let szFilter .= "|| index(['c','e','g','s','t','u'], v:val.kind[0])>=0"
|
||||||
|
call filter(a:tagPopupList, szFilter)
|
||||||
|
call extend(s:popupItemResultList, s:FilterOverloadedFunctions(a:tagPopupList))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Filter static class members in the popup menu
|
||||||
|
function! s:FilterStaticClassMembers(tagPopupList, szAccessFilter)
|
||||||
|
let szFilter = "!has_key(v:val, 'friendfunc') && has_key(v:val, 'kind') && (index(['m', 'p', 'f'], v:val.kind[0])>=0 && has_key(v:val, 'access') && match(v:val.cmd, '\\Cstatic')!=-1)"
|
||||||
|
let szFilter = s:GetAccessFilter(szFilter, a:szAccessFilter)
|
||||||
|
let szFilter = szFilter . "|| index(['c','e','g','n','s','t','u','v'], v:val.kind[0])>=0"
|
||||||
|
call filter(a:tagPopupList, szFilter)
|
||||||
|
call extend(s:popupItemResultList, s:FilterOverloadedFunctions(a:tagPopupList))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Filter scope members in the popup menu
|
||||||
|
function! s:FilterNamespaceScopeMembers(tagPopupList)
|
||||||
|
call extend(s:popupItemResultList, a:tagPopupList)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Init data at the start of completion
|
||||||
|
function! s:InitComplete()
|
||||||
|
" Reset the popup item list
|
||||||
|
let s:popupItemResultList = []
|
||||||
|
let s:CACHE_OVERLOADED_FUNCTIONS = {}
|
||||||
|
|
||||||
|
" Reset includes cache when the current working directory has changed
|
||||||
|
let szCurrentWorkingDir = getcwd()
|
||||||
|
if s:szCurrentWorkingDir != szCurrentWorkingDir
|
||||||
|
let s:szCurrentWorkingDir = szCurrentWorkingDir
|
||||||
|
let g:omni#cpp#includes#CACHE_INCLUDES = {}
|
||||||
|
let g:omni#cpp#includes#CACHE_FILE_TIME = {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Has preview window ?
|
||||||
|
let s:hasPreviewWindow = match(&completeopt, 'preview')>=0
|
||||||
|
|
||||||
|
let bResetCache = 0
|
||||||
|
|
||||||
|
" Reset tag env or tag files dependent caches
|
||||||
|
if s:HasATagFileOrTagEnvChanged()
|
||||||
|
let bResetCache = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (s:OmniCpp_ShowScopeInAbbr != g:OmniCpp_ShowScopeInAbbr)
|
||||||
|
\|| (s:OmniCpp_ShowPrototypeInAbbr != g:OmniCpp_ShowPrototypeInAbbr)
|
||||||
|
\|| (s:OmniCpp_ShowAccess != g:OmniCpp_ShowAccess)
|
||||||
|
|
||||||
|
let s:OmniCpp_ShowScopeInAbbr = g:OmniCpp_ShowScopeInAbbr
|
||||||
|
let s:OmniCpp_ShowPrototypeInAbbr = g:OmniCpp_ShowPrototypeInAbbr
|
||||||
|
let s:OmniCpp_ShowAccess = g:OmniCpp_ShowAccess
|
||||||
|
let bResetCache = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:hasPreviewWindow != s:hasPreviewWindowOld
|
||||||
|
let s:hasPreviewWindowOld = s:hasPreviewWindow
|
||||||
|
let bResetCache = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if bResetCache
|
||||||
|
let g:omni#cpp#namespaces#CacheResolve = {}
|
||||||
|
let s:CACHE_TAG_POPUP_ITEMS = {}
|
||||||
|
let g:omni#cpp#utils#CACHE_TAG_INHERITS = {}
|
||||||
|
call garbagecollect()
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Check for updates
|
||||||
|
for szIncludeName in keys(g:omni#cpp#includes#CACHE_INCLUDES)
|
||||||
|
let fTime = getftime(szIncludeName)
|
||||||
|
let bNeedUpdate = 0
|
||||||
|
if has_key(g:omni#cpp#includes#CACHE_FILE_TIME, szIncludeName)
|
||||||
|
if fTime != g:omni#cpp#includes#CACHE_FILE_TIME[szIncludeName]
|
||||||
|
let bNeedUpdate = 1
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let g:omni#cpp#includes#CACHE_FILE_TIME[szIncludeName] = fTime
|
||||||
|
let bNeedUpdate = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if bNeedUpdate
|
||||||
|
" We have to update include list and namespace map of this file
|
||||||
|
call omni#cpp#includes#GetList(szIncludeName, 1)
|
||||||
|
call omni#cpp#namespaces#GetMapFromBuffer(szIncludeName, 1)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let s:bDoNotComplete = 0
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
" This function is used for the 'omnifunc' option.
|
||||||
|
function! omni#cpp#complete#Main(findstart, base)
|
||||||
|
if a:findstart
|
||||||
|
"call omni#common#debug#Start()
|
||||||
|
|
||||||
|
call s:InitComplete()
|
||||||
|
|
||||||
|
" Note: if s:bMayComplete==1 g:omni#cpp#items#data is build by MayComplete functions
|
||||||
|
if !s:bMayComplete
|
||||||
|
" If the cursor is in a comment we go out
|
||||||
|
if omni#cpp#utils#IsCursorInCommentOrString()
|
||||||
|
" Returning -1 is not enough we have to set a variable to let
|
||||||
|
" the second call of omni#cpp#complete knows that the
|
||||||
|
" cursor was in a comment
|
||||||
|
" Why is there a second call when the first call returns -1 ?
|
||||||
|
let s:bDoNotComplete = 1
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We get items here (whend a:findstart==1) because GetItemsToComplete()
|
||||||
|
" depends on the cursor position.
|
||||||
|
" When a:findstart==0 the cursor position is modified
|
||||||
|
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction())
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Get contexts stack
|
||||||
|
let s:contextStack = omni#cpp#namespaces#GetContexts()
|
||||||
|
|
||||||
|
" Reinit of may complete indicator
|
||||||
|
let s:bMayComplete = 0
|
||||||
|
return s:FindStartPositionOfCompletion()
|
||||||
|
endif
|
||||||
|
|
||||||
|
" If the cursor is in a comment we return an empty result
|
||||||
|
if s:bDoNotComplete
|
||||||
|
let s:bDoNotComplete = 0
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(g:omni#cpp#items#data)==0
|
||||||
|
" A) CURRENT_SCOPE_COMPLETION_MODE
|
||||||
|
|
||||||
|
" 1) Displaying data of each context
|
||||||
|
let szAccessFilter = 'all'
|
||||||
|
for szCurrentContext in s:contextStack
|
||||||
|
if szCurrentContext == '::'
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resolvedTagItem = omni#cpp#utils#GetResolvedTagItem(s:contextStack, omni#cpp#utils#CreateTypeInfo(szCurrentContext))
|
||||||
|
if resolvedTagItem != {}
|
||||||
|
" We don't search base classes because bases classes are
|
||||||
|
" already in the context stack
|
||||||
|
let tagPopupList = s:SearchMembers(resolvedTagItem, a:base)
|
||||||
|
if index(['c','s'], resolvedTagItem.kind[0])>=0
|
||||||
|
" It's a class or struct
|
||||||
|
call s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
|
||||||
|
let szAccessFilter = 'protected'
|
||||||
|
else
|
||||||
|
" It's a namespace or union, we display all members
|
||||||
|
call s:FilterNamespaceScopeMembers(tagPopupList)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" 2) Displaying global scope members
|
||||||
|
if g:OmniCpp_GlobalScopeSearch
|
||||||
|
call s:SearchGlobalMembers(a:base)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let typeInfo = omni#cpp#items#ResolveItemsTypeInfo(s:contextStack, g:omni#cpp#items#data)
|
||||||
|
|
||||||
|
if typeInfo != {}
|
||||||
|
if g:omni#cpp#items#data[-1].kind == 'itemScope'
|
||||||
|
" B) SCOPE_COMPLETION_MODE
|
||||||
|
if omni#cpp#utils#GetTypeInfoString(typeInfo)==''
|
||||||
|
call s:SearchGlobalMembers(a:base)
|
||||||
|
else
|
||||||
|
for resolvedTagItem in omni#cpp#utils#GetResolvedTags(s:contextStack, typeInfo)
|
||||||
|
let tagPopupList = s:SearchMembers(resolvedTagItem, a:base)
|
||||||
|
if index(['c','s'], resolvedTagItem.kind[0])>=0
|
||||||
|
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTag(resolvedTagItem)
|
||||||
|
if g:OmniCpp_DisplayMode==0
|
||||||
|
" We want to complete a class or struct
|
||||||
|
" If this class is a base class so we display all class members
|
||||||
|
if index(s:contextStack, szTypeInfo)<0
|
||||||
|
let szAccessFilter = 'public'
|
||||||
|
call s:FilterStaticClassMembers(tagPopupList, szAccessFilter)
|
||||||
|
else
|
||||||
|
let szAccessFilter = (s:contextStack[0] == szTypeInfo)? 'all' : 'protected'
|
||||||
|
call s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
if index(s:contextStack, szTypeInfo)<0
|
||||||
|
let szAccessFilter = 'public'
|
||||||
|
else
|
||||||
|
let szAccessFilter = (s:contextStack[0] == szTypeInfo)? 'all' : 'protected'
|
||||||
|
endif
|
||||||
|
call s:FilterClassScopeMembers(tagPopupList, szAccessFilter)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" We want to complete a namespace
|
||||||
|
call s:FilterNamespaceScopeMembers(tagPopupList)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" C) CLASS_MEMBERS_COMPLETION_MODE
|
||||||
|
for resolvedTagItem in omni#cpp#utils#GetResolvedTags(s:contextStack, typeInfo)
|
||||||
|
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTag(resolvedTagItem)
|
||||||
|
if index(s:contextStack, szTypeInfo)<0
|
||||||
|
let szAccessFilter = 'public'
|
||||||
|
else
|
||||||
|
let szAccessFilter = (s:contextStack[0] == szTypeInfo)? 'all' : 'protected'
|
||||||
|
endif
|
||||||
|
call s:FilterClassMembers(s:SearchMembers(resolvedTagItem, a:base), szAccessFilter)
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
"call omni#common#debug#End()
|
||||||
|
|
||||||
|
return s:popupItemResultList
|
||||||
|
endfunc
|
126
.vim/autoload/omni/cpp/includes.vim
Normal file
126
.vim/autoload/omni/cpp/includes.vim
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
let g:omni#cpp#includes#CACHE_INCLUDES = {}
|
||||||
|
let g:omni#cpp#includes#CACHE_FILE_TIME = {}
|
||||||
|
|
||||||
|
let s:rePreprocIncludePart = '\C#\s*include\s*'
|
||||||
|
let s:reIncludeFilePart = '\(<\|"\)\(\f\|\s\)\+\(>\|"\)'
|
||||||
|
let s:rePreprocIncludeFile = s:rePreprocIncludePart . s:reIncludeFilePart
|
||||||
|
|
||||||
|
" Get the include list of a file
|
||||||
|
function! omni#cpp#includes#GetList(...)
|
||||||
|
if a:0 > 0
|
||||||
|
return s:GetIncludeListFromFile(a:1, (a:0 > 1)? a:2 : 0 )
|
||||||
|
else
|
||||||
|
return s:GetIncludeListFromCurrentBuffer()
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the include list from the current buffer
|
||||||
|
function! s:GetIncludeListFromCurrentBuffer()
|
||||||
|
let listIncludes = []
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
|
||||||
|
call setpos('.', [0, 1, 1, 0])
|
||||||
|
let curPos = [1,1]
|
||||||
|
let alreadyInclude = {}
|
||||||
|
while curPos != [0,0]
|
||||||
|
let curPos = searchpos('\C\(^'.s:rePreprocIncludeFile.'\)', 'W')
|
||||||
|
if curPos != [0,0]
|
||||||
|
let szLine = getline('.')
|
||||||
|
let startPos = curPos[1]
|
||||||
|
let endPos = matchend(szLine, s:reIncludeFilePart, startPos-1)
|
||||||
|
if endPos!=-1
|
||||||
|
let szInclusion = szLine[startPos-1:endPos-1]
|
||||||
|
let szIncludeFile = substitute(szInclusion, '\('.s:rePreprocIncludePart.'\)\|[<>""]', '', 'g')
|
||||||
|
let szResolvedInclude = omni#cpp#utils#ResolveFilePath(szIncludeFile)
|
||||||
|
|
||||||
|
" Protection over self inclusion
|
||||||
|
if szResolvedInclude != '' && szResolvedInclude != omni#cpp#utils#ResolveFilePath(getreg('%'))
|
||||||
|
let includePos = curPos
|
||||||
|
if !has_key(alreadyInclude, szResolvedInclude)
|
||||||
|
call extend(listIncludes, [{'pos' : includePos, 'include' : szResolvedInclude}])
|
||||||
|
let alreadyInclude[szResolvedInclude] = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
return listIncludes
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the include list from a file
|
||||||
|
function! s:GetIncludeListFromFile(szFilePath, bUpdate)
|
||||||
|
let listIncludes = []
|
||||||
|
if a:szFilePath == ''
|
||||||
|
return listIncludes
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !a:bUpdate && has_key(g:omni#cpp#includes#CACHE_INCLUDES, a:szFilePath)
|
||||||
|
return copy(g:omni#cpp#includes#CACHE_INCLUDES[a:szFilePath])
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:omni#cpp#includes#CACHE_FILE_TIME[a:szFilePath] = getftime(a:szFilePath)
|
||||||
|
|
||||||
|
let szFixedPath = escape(a:szFilePath, g:omni#cpp#utils#szEscapedCharacters)
|
||||||
|
execute 'silent! lvimgrep /\C\(^'.s:rePreprocIncludeFile.'\)/gj '.szFixedPath
|
||||||
|
|
||||||
|
let listQuickFix = getloclist(0)
|
||||||
|
let alreadyInclude = {}
|
||||||
|
for qf in listQuickFix
|
||||||
|
let szLine = qf.text
|
||||||
|
let startPos = qf.col
|
||||||
|
let endPos = matchend(szLine, s:reIncludeFilePart, startPos-1)
|
||||||
|
if endPos!=-1
|
||||||
|
let szInclusion = szLine[startPos-1:endPos-1]
|
||||||
|
let szIncludeFile = substitute(szInclusion, '\('.s:rePreprocIncludePart.'\)\|[<>""]', '', 'g')
|
||||||
|
let szResolvedInclude = omni#cpp#utils#ResolveFilePath(szIncludeFile)
|
||||||
|
|
||||||
|
" Protection over self inclusion
|
||||||
|
if szResolvedInclude != '' && szResolvedInclude != a:szFilePath
|
||||||
|
let includePos = [qf.lnum, qf.col]
|
||||||
|
if !has_key(alreadyInclude, szResolvedInclude)
|
||||||
|
call extend(listIncludes, [{'pos' : includePos, 'include' : szResolvedInclude}])
|
||||||
|
let alreadyInclude[szResolvedInclude] = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let g:omni#cpp#includes#CACHE_INCLUDES[a:szFilePath] = listIncludes
|
||||||
|
|
||||||
|
return copy(listIncludes)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" For debug purpose
|
||||||
|
function! omni#cpp#includes#Display()
|
||||||
|
let szPathBuffer = omni#cpp#utils#ResolveFilePath(getreg('%'))
|
||||||
|
call s:DisplayIncludeTree(szPathBuffer, 0)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" For debug purpose
|
||||||
|
function! s:DisplayIncludeTree(szFilePath, indent, ...)
|
||||||
|
let includeGuard = {}
|
||||||
|
if a:0 >0
|
||||||
|
let includeGuard = a:1
|
||||||
|
endif
|
||||||
|
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
|
||||||
|
if has_key(includeGuard, szFilePath)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
let includeGuard[szFilePath] = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let szIndent = repeat(' ', a:indent)
|
||||||
|
echo szIndent . a:szFilePath
|
||||||
|
let incList = omni#cpp#includes#GetList(a:szFilePath)
|
||||||
|
for inc in incList
|
||||||
|
call s:DisplayIncludeTree(inc.include, a:indent+1, includeGuard)
|
||||||
|
endfor
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
660
.vim/autoload/omni/cpp/items.vim
Normal file
660
.vim/autoload/omni/cpp/items.vim
Normal file
@ -0,0 +1,660 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
" Build the item list of an instruction
|
||||||
|
" An item is an instruction between a -> or . or ->* or .*
|
||||||
|
" We can sort an item in different kinds:
|
||||||
|
" eg: ((MyClass1*)(pObject))->_memberOfClass1.get() ->show()
|
||||||
|
" | cast | | member | | method | | method |
|
||||||
|
" @return a list of item
|
||||||
|
" an item is a dictionnary where keys are:
|
||||||
|
" tokens = list of token
|
||||||
|
" kind = itemVariable|itemCast|itemCppCast|itemTemplate|itemFunction|itemUnknown|itemThis|itemScope
|
||||||
|
function! omni#cpp#items#Get(tokens, ...)
|
||||||
|
let bGetWordUnderCursor = (a:0>0)? a:1 : 0
|
||||||
|
|
||||||
|
let result = []
|
||||||
|
let itemsDelimiters = ['->', '.', '->*', '.*']
|
||||||
|
|
||||||
|
let tokens = reverse(omni#cpp#utils#BuildParenthesisGroups(a:tokens))
|
||||||
|
|
||||||
|
" fsm states:
|
||||||
|
" 0 = initial state
|
||||||
|
" TODO: add description of fsm states
|
||||||
|
let state=(bGetWordUnderCursor)? 1 : 0
|
||||||
|
let item = {'tokens' : [], 'kind' : 'itemUnknown'}
|
||||||
|
let parenGroup=-1
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
if index(itemsDelimiters, token.value)>=0
|
||||||
|
let item = {'tokens' : [], 'kind' : 'itemUnknown'}
|
||||||
|
let state = 1
|
||||||
|
elseif token.value=='::'
|
||||||
|
let state = 9
|
||||||
|
let item.kind = 'itemScope'
|
||||||
|
" Maybe end of tokens
|
||||||
|
elseif token.kind =='cppOperatorPunctuator'
|
||||||
|
" If it's a cppOperatorPunctuator and the current token is not
|
||||||
|
" a itemsDelimiters or '::' we can exit
|
||||||
|
let state=-1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
if token.kind=='cppWord'
|
||||||
|
" It's an attribute member or a variable
|
||||||
|
let item.kind = 'itemVariable'
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of tokens
|
||||||
|
elseif token.value=='this'
|
||||||
|
let item.kind = 'itemThis'
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of tokens
|
||||||
|
elseif token.value==')'
|
||||||
|
let parenGroup = token.group
|
||||||
|
let state = 3
|
||||||
|
elseif token.value==']'
|
||||||
|
let parenGroup = token.group
|
||||||
|
let state = 4
|
||||||
|
elseif token.kind == 'cppDigit'
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==2
|
||||||
|
if index(itemsDelimiters, token.value)>=0
|
||||||
|
call insert(result, item)
|
||||||
|
let item = {'tokens' : [], 'kind' : 'itemUnknown'}
|
||||||
|
let state = 1
|
||||||
|
elseif token.value == '::'
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
" We have to get namespace or classscope
|
||||||
|
let state = 8
|
||||||
|
" Maybe end of tokens
|
||||||
|
else
|
||||||
|
call insert(result, item)
|
||||||
|
let state=-1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==3
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
if token.value=='(' && token.group == parenGroup
|
||||||
|
let state = 5
|
||||||
|
" Maybe end of tokens
|
||||||
|
endif
|
||||||
|
elseif state==4
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
if token.value=='[' && token.group == parenGroup
|
||||||
|
let state = 1
|
||||||
|
endif
|
||||||
|
elseif state==5
|
||||||
|
if token.kind=='cppWord'
|
||||||
|
" It's a function or method
|
||||||
|
let item.kind = 'itemFunction'
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of tokens
|
||||||
|
elseif token.value == '>'
|
||||||
|
" Maybe a cpp cast or template
|
||||||
|
let item.kind = 'itemTemplate'
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
let parenGroup = token.group
|
||||||
|
let state = 6
|
||||||
|
else
|
||||||
|
" Perhaps it's a C cast eg: ((void*)(pData)) or a variable eg:(*pData)
|
||||||
|
let item.kind = omni#cpp#utils#GetCastType(item.tokens)
|
||||||
|
let state=-1
|
||||||
|
call insert(result, item)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==6
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
if token.value == '<' && token.group == parenGroup
|
||||||
|
" Maybe a cpp cast or template
|
||||||
|
let state = 7
|
||||||
|
endif
|
||||||
|
elseif state==7
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
if token.kind=='cppKeyword'
|
||||||
|
" It's a cpp cast
|
||||||
|
let item.kind = omni#cpp#utils#GetCastType(item.tokens)
|
||||||
|
let state=-1
|
||||||
|
call insert(result, item)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
" Template ?
|
||||||
|
let state=-1
|
||||||
|
call insert(result, item)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==8
|
||||||
|
if token.kind=='cppWord'
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of tokens
|
||||||
|
else
|
||||||
|
let state=-1
|
||||||
|
call insert(result, item)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==9
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
let state = 10
|
||||||
|
" Maybe end of tokens
|
||||||
|
else
|
||||||
|
let state=-1
|
||||||
|
call insert(result, item)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==10
|
||||||
|
if token.value == '::'
|
||||||
|
call insert(item.tokens, token)
|
||||||
|
let state = 9
|
||||||
|
" Maybe end of tokens
|
||||||
|
else
|
||||||
|
let state=-1
|
||||||
|
call insert(result, item)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if index([2, 5, 8, 9, 10], state)>=0
|
||||||
|
if state==5
|
||||||
|
let item.kind = omni#cpp#utils#GetCastType(item.tokens)
|
||||||
|
endif
|
||||||
|
call insert(result, item)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve type information of items
|
||||||
|
" @param namespaces: list of namespaces used in the file
|
||||||
|
" @param szCurrentClassScope: the current class scope, only used for the first
|
||||||
|
" item to detect if this item is a class member (attribute, method)
|
||||||
|
" @param items: list of item, can be an empty list @see GetItemsToComplete
|
||||||
|
function! omni#cpp#items#ResolveItemsTypeInfo(contextStack, items)
|
||||||
|
" Note: kind = itemVariable|cCast|cppCast|template|function|itemUnknown|this
|
||||||
|
" For the first item, if it's a variable we try to detect the type of the
|
||||||
|
" variable with the function searchdecl. If it fails, thanks to the
|
||||||
|
" current class scope, we try to detect if the variable is an attribute
|
||||||
|
" member.
|
||||||
|
" If the kind of the item is a function, we have to first check if the
|
||||||
|
" function is a method of the class, if it fails we try to get a match in
|
||||||
|
" the global namespace. After that we get the returned type of the
|
||||||
|
" function.
|
||||||
|
" It the kind is a C cast or C++ cast, there is no problem, it's the
|
||||||
|
" easiest case. We just extract the type of the cast.
|
||||||
|
|
||||||
|
let szCurrentContext = ''
|
||||||
|
let typeInfo = {}
|
||||||
|
" Note: We search the decl only for the first item
|
||||||
|
let bSearchDecl = 1
|
||||||
|
for item in a:items
|
||||||
|
let curItem = item
|
||||||
|
if index(['itemVariable', 'itemFunction'], curItem.kind)>=0
|
||||||
|
" Note: a variable can be : MyNs::MyClass::_var or _var or (*pVar)
|
||||||
|
" or _var[0][0]
|
||||||
|
let szSymbol = s:GetSymbol(curItem.tokens)
|
||||||
|
|
||||||
|
" If we have MyNamespace::myVar
|
||||||
|
" We add MyNamespace in the context stack set szSymbol to myVar
|
||||||
|
if match(szSymbol, '::\w\+$') >= 0
|
||||||
|
let szCurrentContext = substitute(szSymbol, '::\w\+$', '', 'g')
|
||||||
|
let szSymbol = matchstr(szSymbol, '\w\+$')
|
||||||
|
endif
|
||||||
|
let tmpContextStack = a:contextStack
|
||||||
|
if szCurrentContext != ''
|
||||||
|
let tmpContextStack = [szCurrentContext] + a:contextStack
|
||||||
|
endif
|
||||||
|
|
||||||
|
if curItem.kind == 'itemVariable'
|
||||||
|
let typeInfo = s:GetTypeInfoOfVariable(tmpContextStack, szSymbol, bSearchDecl)
|
||||||
|
else
|
||||||
|
let typeInfo = s:GetTypeInfoOfReturnedType(tmpContextStack, szSymbol)
|
||||||
|
endif
|
||||||
|
|
||||||
|
elseif curItem.kind == 'itemThis'
|
||||||
|
if len(a:contextStack)
|
||||||
|
let typeInfo = omni#cpp#utils#CreateTypeInfo(substitute(a:contextStack[0], '^::', '', 'g'))
|
||||||
|
endif
|
||||||
|
elseif curItem.kind == 'itemCast'
|
||||||
|
let typeInfo = omni#cpp#utils#CreateTypeInfo(s:ResolveCCast(curItem.tokens))
|
||||||
|
elseif curItem.kind == 'itemCppCast'
|
||||||
|
let typeInfo = omni#cpp#utils#CreateTypeInfo(s:ResolveCppCast(curItem.tokens))
|
||||||
|
elseif curItem.kind == 'itemScope'
|
||||||
|
let typeInfo = omni#cpp#utils#CreateTypeInfo(substitute(s:TokensToString(curItem.tokens), '\s', '', 'g'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if omni#cpp#utils#IsTypeInfoValid(typeInfo)
|
||||||
|
let szCurrentContext = omni#cpp#utils#GetTypeInfoString(typeInfo)
|
||||||
|
endif
|
||||||
|
let bSearchDecl = 0
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return typeInfo
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get symbol name
|
||||||
|
function! s:GetSymbol(tokens)
|
||||||
|
let szSymbol = ''
|
||||||
|
let state = 0
|
||||||
|
for token in a:tokens
|
||||||
|
if state == 0
|
||||||
|
if token.value == '::'
|
||||||
|
let szSymbol .= token.value
|
||||||
|
let state = 1
|
||||||
|
elseif token.kind == 'cppWord'
|
||||||
|
let szSymbol .= token.value
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of token
|
||||||
|
endif
|
||||||
|
elseif state == 1
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
let szSymbol .= token.value
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of token
|
||||||
|
else
|
||||||
|
" Error
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state == 2
|
||||||
|
if token.value == '::'
|
||||||
|
let szSymbol .= token.value
|
||||||
|
let state = 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return szSymbol
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Search a declaration.
|
||||||
|
" eg: std::map
|
||||||
|
" can be empty
|
||||||
|
" Note: The returned type info can be a typedef
|
||||||
|
" The typedef resolution is done later
|
||||||
|
" @return
|
||||||
|
" - a dictionnary where keys are
|
||||||
|
" - type: the type of value same as type()
|
||||||
|
" - value: the value
|
||||||
|
function! s:GetTypeInfoOfVariable(contextStack, szVariable, bSearchDecl)
|
||||||
|
let result = {}
|
||||||
|
|
||||||
|
if a:bSearchDecl
|
||||||
|
" Search type of declaration
|
||||||
|
"let result = s:SearchTypeInfoOfDecl(a:szVariable)
|
||||||
|
let result = s:SearchDecl(a:szVariable)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if result=={}
|
||||||
|
let szFilter = "index(['m', 'v'], v:val.kind[0])>=0"
|
||||||
|
let tagItem = s:ResolveSymbol(a:contextStack, a:szVariable, szFilter)
|
||||||
|
if tagItem=={}
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
let szCmdWithoutVariable = substitute(omni#cpp#utils#ExtractCmdFromTagItem(tagItem), '\C\<'.a:szVariable.'\>.*', '', 'g')
|
||||||
|
let tokens = omni#cpp#tokenizer#Tokenize(omni#cpp#utils#GetCodeFromLine(szCmdWithoutVariable))
|
||||||
|
let result = omni#cpp#utils#CreateTypeInfo(omni#cpp#utils#ExtractTypeInfoFromTokens(tokens))
|
||||||
|
" TODO: Namespace resolution for result
|
||||||
|
|
||||||
|
if result != {} && result.value==''
|
||||||
|
" result.value==''
|
||||||
|
" eg:
|
||||||
|
" struct
|
||||||
|
" {
|
||||||
|
" }gVariable;
|
||||||
|
if has_key(tagItem, 'typeref')
|
||||||
|
" Maybe the variable is a global var of an
|
||||||
|
" unnamed class, struct or union.
|
||||||
|
" eg:
|
||||||
|
" 1)
|
||||||
|
" struct
|
||||||
|
" {
|
||||||
|
" }gVariable;
|
||||||
|
" In this case we need the tags (the patched version)
|
||||||
|
" Note: We can have a named type like this:
|
||||||
|
" 2)
|
||||||
|
" class A
|
||||||
|
" {
|
||||||
|
" }gVariable;
|
||||||
|
if s:IsUnnamedType(tagItem)
|
||||||
|
" It's an unnamed type we are in the case 1)
|
||||||
|
let result = omni#cpp#utils#CreateTypeInfo(tagItem)
|
||||||
|
else
|
||||||
|
" It's not an unnamed type we are in the case 2)
|
||||||
|
|
||||||
|
" eg: tagItem.typeref = 'struct:MY_STRUCT::MY_SUBSTRUCT'
|
||||||
|
let szTypeRef = substitute(tagItem.typeref, '^\w\+:', '', '')
|
||||||
|
|
||||||
|
" eg: szTypeRef = 'MY_STRUCT::MY_SUBSTRUCT'
|
||||||
|
let result = omni#cpp#utils#CreateTypeInfo(szTypeRef)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the type info string from the returned type of function
|
||||||
|
function! s:GetTypeInfoOfReturnedType(contextStack, szFunctionName)
|
||||||
|
let result = {}
|
||||||
|
|
||||||
|
let szFilter = "index(['f', 'p'], v:val.kind[0])>=0"
|
||||||
|
let tagItem = s:ResolveSymbol(a:contextStack, a:szFunctionName, szFilter)
|
||||||
|
|
||||||
|
if tagItem != {}
|
||||||
|
let szCmdWithoutVariable = substitute(omni#cpp#utils#ExtractCmdFromTagItem(tagItem), '\C\<'.a:szFunctionName.'\>.*', '', 'g')
|
||||||
|
let tokens = omni#cpp#tokenizer#Tokenize(omni#cpp#utils#GetCodeFromLine(szCmdWithoutVariable))
|
||||||
|
let result = omni#cpp#utils#CreateTypeInfo(omni#cpp#utils#ExtractTypeInfoFromTokens(tokens))
|
||||||
|
" TODO: Namespace resolution for result
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve a symbol, return a tagItem
|
||||||
|
" Gets the first symbol found in the context stack
|
||||||
|
function! s:ResolveSymbol(contextStack, szSymbol, szTagFilter)
|
||||||
|
let tagItem = {}
|
||||||
|
for szCurrentContext in a:contextStack
|
||||||
|
if szCurrentContext != '::'
|
||||||
|
let szTagQuery = substitute(szCurrentContext, '^::', '', 'g').'::'.a:szSymbol
|
||||||
|
else
|
||||||
|
let szTagQuery = a:szSymbol
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
|
||||||
|
call filter(tagList, a:szTagFilter)
|
||||||
|
if len(tagList)
|
||||||
|
let tagItem = tagList[0]
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return tagItem
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Return if the tag item represent an unnamed type
|
||||||
|
function! s:IsUnnamedType(tagItem)
|
||||||
|
let bResult = 0
|
||||||
|
if has_key(a:tagItem, 'typeref')
|
||||||
|
" Note: Thanks for __anon !
|
||||||
|
let bResult = match(a:tagItem.typeref, '\C\<__anon') >= 0
|
||||||
|
endif
|
||||||
|
return bResult
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Search the declaration of a variable and return the type info
|
||||||
|
function! s:SearchTypeInfoOfDecl(szVariable)
|
||||||
|
let szReVariable = '\C\<'.a:szVariable.'\>'
|
||||||
|
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
let origPos = originalPos[1:2]
|
||||||
|
let curPos = origPos
|
||||||
|
let stopPos = origPos
|
||||||
|
|
||||||
|
while curPos !=[0,0]
|
||||||
|
" We go to the start of the current scope
|
||||||
|
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
if curPos != [0,0]
|
||||||
|
let matchPos = curPos
|
||||||
|
" Now want to search our variable but we don't want to go in child
|
||||||
|
" scope
|
||||||
|
while matchPos != [0,0]
|
||||||
|
let matchPos = searchpos('{\|'.szReVariable, 'W', stopPos[0])
|
||||||
|
if matchPos != [0,0]
|
||||||
|
" We ignore matches under comment
|
||||||
|
if omni#cpp#utils#IsCursorInCommentOrString()
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Getting the current line
|
||||||
|
let szLine = getline('.')
|
||||||
|
if match(szLine, szReVariable)>=0
|
||||||
|
" We found our variable
|
||||||
|
" Check if the current instruction is a decl instruction
|
||||||
|
let tokens = omni#cpp#utils#TokenizeCurrentInstruction()
|
||||||
|
let szTypeInfo = s:ExtractTypeInfoFromDecl(tokens)
|
||||||
|
if szTypeInfo != ''
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
return omni#cpp#utils#CreateTypeInfo(szTypeInfo)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" We found a child scope, we don't want to go in, thus
|
||||||
|
" we search for the end } of this child scope
|
||||||
|
let bracketEnd = searchpairpos('{', '', '}', 'nW', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
if bracketEnd == [0,0]
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
if bracketEnd[0] >= stopPos[0]
|
||||||
|
" The end of the scope is after our cursor we stop
|
||||||
|
" the search
|
||||||
|
break
|
||||||
|
else
|
||||||
|
" We move the cursor and continue to search our
|
||||||
|
" variable
|
||||||
|
call setpos('.', [0, bracketEnd[0], bracketEnd[1], 0])
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Backing to the start of the scope
|
||||||
|
call setpos('.', [0,curPos[0], curPos[1], 0])
|
||||||
|
let stopPos = curPos
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let result = {}
|
||||||
|
if s:LocalSearchDecl(a:szVariable)==0 && !omni#cpp#utils#IsCursorInCommentOrString()
|
||||||
|
let tokens = omni#cpp#utils#TokenizeCurrentInstruction()
|
||||||
|
let szTypeInfo = s:ExtractTypeInfoFromDecl(tokens)
|
||||||
|
if szTypeInfo != ''
|
||||||
|
let result = omni#cpp#utils#CreateTypeInfo(szTypeInfo)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Search a declaration
|
||||||
|
" @return
|
||||||
|
" - tokens of the current instruction if success
|
||||||
|
" - empty list if failure
|
||||||
|
function! s:SearchDecl(szVariable)
|
||||||
|
let result = {}
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
let searchResult = s:LocalSearchDecl(a:szVariable)
|
||||||
|
if searchResult==0
|
||||||
|
" searchdecl() may detect a decl if the variable is in a conditional
|
||||||
|
" instruction (if, elseif, while etc...)
|
||||||
|
" We have to check if the detected decl is really a decl instruction
|
||||||
|
let tokens = omni#cpp#utils#TokenizeCurrentInstruction()
|
||||||
|
|
||||||
|
for token in tokens
|
||||||
|
" Simple test
|
||||||
|
if index(['if', 'elseif', 'while', 'for', 'switch'], token.value)>=0
|
||||||
|
" Invalid declaration instruction
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let szTypeInfo = s:ExtractTypeInfoFromDecl(tokens)
|
||||||
|
if szTypeInfo != ''
|
||||||
|
let result = omni#cpp#utils#CreateTypeInfo(szTypeInfo)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Extract the type info string from an instruction.
|
||||||
|
" We use a small parser to extract the type
|
||||||
|
" We parse the code according to a C++ BNF from: http://www.nongnu.org/hcb/#basic.link
|
||||||
|
" @param tokens: token list of the current instruction
|
||||||
|
function! s:ExtractTypeInfoFromDecl(tokens)
|
||||||
|
return omni#cpp#utils#ExtractTypeInfoFromTokens(a:tokens)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Convert tokens to string
|
||||||
|
function! s:TokensToString(tokens)
|
||||||
|
let result = ''
|
||||||
|
for token in a:tokens
|
||||||
|
let result = result . token.value . ' '
|
||||||
|
endfor
|
||||||
|
return result[:-2]
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve a cast.
|
||||||
|
" Resolve a C++ cast
|
||||||
|
" @param list of token. tokens must be a list that represents
|
||||||
|
" a cast expression (C++ cast) the function does not control
|
||||||
|
" if it's a cast or not
|
||||||
|
" eg: static_cast<MyClass*>(something)
|
||||||
|
" @return type info string
|
||||||
|
function! s:ResolveCppCast(tokens)
|
||||||
|
return omni#cpp#utils#ExtractTypeInfoFromTokens(s:ResolveCast(a:tokens, '<', '>'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve a cast.
|
||||||
|
" Resolve a C cast
|
||||||
|
" @param list of token. tokens must be a list that represents
|
||||||
|
" a cast expression (C cast) the function does not control
|
||||||
|
" if it's a cast or not
|
||||||
|
" eg: (MyClass*)something
|
||||||
|
" @return type info string
|
||||||
|
function! s:ResolveCCast(tokens)
|
||||||
|
return omni#cpp#utils#ExtractTypeInfoFromTokens(s:ResolveCast(a:tokens, '(', ')'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve a cast.
|
||||||
|
" Resolve a C cast
|
||||||
|
" @param list of token. tokens must be a list that represents
|
||||||
|
" a cast expression (C cast) the function does not control
|
||||||
|
" if it's a cast or not
|
||||||
|
" eg: (MyClass*)something
|
||||||
|
" @return type tokens
|
||||||
|
function! s:ResolveCast(tokens, startChar, endChar)
|
||||||
|
let tokens = omni#cpp#utils#BuildParenthesisGroups(a:tokens)
|
||||||
|
|
||||||
|
" We remove useless parenthesis eg: (((MyClass)))
|
||||||
|
let tokens = omni#cpp#utils#SimplifyParenthesis(tokens)
|
||||||
|
|
||||||
|
let countItem=0
|
||||||
|
let startIndex = -1
|
||||||
|
let endIndex = -1
|
||||||
|
let i = 0
|
||||||
|
for token in tokens
|
||||||
|
if startIndex==-1
|
||||||
|
if token.value==a:startChar
|
||||||
|
let countItem += 1
|
||||||
|
let startIndex = i
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
if token.value==a:startChar
|
||||||
|
let countItem += 1
|
||||||
|
elseif token.value==a:endChar
|
||||||
|
let countItem -= 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if countItem==0
|
||||||
|
let endIndex = i
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
let i+=1
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return tokens[startIndex+1 : endIndex-1]
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Replacement for build-in function 'searchdecl'
|
||||||
|
" It does not require that the upper-level bracket is in the first column.
|
||||||
|
" Otherwise it should be equal to 'searchdecl(name, 0, 1)'
|
||||||
|
" @param name: name of variable to find declaration for
|
||||||
|
function! s:LocalSearchDecl(name)
|
||||||
|
|
||||||
|
if g:OmniCpp_LocalSearchDecl == 0
|
||||||
|
let bUserIgnoreCase = &ignorecase
|
||||||
|
|
||||||
|
" Forcing the noignorecase option
|
||||||
|
" avoid bug when, for example, if we have a declaration like this : "A a;"
|
||||||
|
set noignorecase
|
||||||
|
|
||||||
|
let result = searchdecl(a:name, 0, 1)
|
||||||
|
|
||||||
|
" Restoring user's setting
|
||||||
|
let &ignorecase = bUserIgnoreCase
|
||||||
|
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lastpos = getpos('.')
|
||||||
|
let winview = winsaveview()
|
||||||
|
let lastfoldenable = &foldenable
|
||||||
|
let &foldenable = 0
|
||||||
|
|
||||||
|
" We add \C (noignorecase) to
|
||||||
|
" avoid bug when, for example, if we have a declaration like this : "A a;"
|
||||||
|
let varname = "\\C\\<" . a:name . "\\>"
|
||||||
|
|
||||||
|
" Go to first blank line before begin of highest scope
|
||||||
|
normal 99[{
|
||||||
|
let scopepos = getpos('.')
|
||||||
|
while (line('.') > 1) && (len(split(getline('.'))) > 0)
|
||||||
|
call cursor(line('.')-1, 0)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let declpos = [ 0, 0, 0, 0 ]
|
||||||
|
while search(varname, '', scopepos[1]) > 0
|
||||||
|
" Check if we are a string or a comment
|
||||||
|
if omni#cpp#utils#IsCursorInCommentOrString()
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Remember match
|
||||||
|
let declpos = getpos('.')
|
||||||
|
endwhile
|
||||||
|
if declpos[1] != 0
|
||||||
|
" We found a match
|
||||||
|
call winrestview(winview)
|
||||||
|
call setpos('.', declpos)
|
||||||
|
let &foldenable = lastfoldenable
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
while search(varname, '', lastpos[1]) > 0
|
||||||
|
" Check if current scope is ending before variable
|
||||||
|
let old_cur = getpos('.')
|
||||||
|
normal ]}
|
||||||
|
let new_cur = getpos('.')
|
||||||
|
call setpos('.', old_cur)
|
||||||
|
if (new_cur[1] < lastpos[1]) || ((new_cur[1] == lastpos[1]) && (new_cur[2] < lastpos[2]))
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Check if we are a string or a comment
|
||||||
|
if omni#cpp#utils#IsCursorInCommentOrString()
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We found match
|
||||||
|
call winrestview(winview)
|
||||||
|
call setpos('.', old_cur)
|
||||||
|
let &foldenable = lastfoldenable
|
||||||
|
return 0
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" No match found.
|
||||||
|
call winrestview(winview)
|
||||||
|
let &foldenable = lastfoldenable
|
||||||
|
return 1
|
||||||
|
endfunc
|
82
.vim/autoload/omni/cpp/maycomplete.vim
Normal file
82
.vim/autoload/omni/cpp/maycomplete.vim
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
" Check if we can use omni completion in the current buffer
|
||||||
|
function! s:CanUseOmnicompletion()
|
||||||
|
" For C and C++ files and only if the omnifunc is omni#cpp#complete#Main
|
||||||
|
return (index(['c', 'cpp'], &filetype)>=0 && &omnifunc == 'omni#cpp#complete#Main' && !omni#cpp#utils#IsCursorInCommentOrString())
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Return the mapping of omni completion
|
||||||
|
function! omni#cpp#maycomplete#Complete()
|
||||||
|
let szOmniMapping = "\<C-X>\<C-O>"
|
||||||
|
|
||||||
|
" 0 = don't select first item
|
||||||
|
" 1 = select first item (inserting it to the text, default vim behaviour)
|
||||||
|
" 2 = select first item (without inserting it to the text)
|
||||||
|
if g:OmniCpp_SelectFirstItem == 0
|
||||||
|
" We have to force the menuone option to avoid confusion when there is
|
||||||
|
" only one popup item
|
||||||
|
set completeopt-=menu
|
||||||
|
set completeopt+=menuone
|
||||||
|
let szOmniMapping .= "\<C-P>"
|
||||||
|
elseif g:OmniCpp_SelectFirstItem == 2
|
||||||
|
" We have to force the menuone option to avoid confusion when there is
|
||||||
|
" only one popup item
|
||||||
|
set completeopt-=menu
|
||||||
|
set completeopt+=menuone
|
||||||
|
let szOmniMapping .= "\<C-P>"
|
||||||
|
let szOmniMapping .= "\<C-R>=pumvisible() ? \"\\<down>\" : \"\"\<cr>"
|
||||||
|
endif
|
||||||
|
return szOmniMapping
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" May complete function for dot
|
||||||
|
function! omni#cpp#maycomplete#Dot()
|
||||||
|
if s:CanUseOmnicompletion() && g:OmniCpp_MayCompleteDot
|
||||||
|
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction('.'))
|
||||||
|
if len(g:omni#cpp#items#data)
|
||||||
|
let s:bMayComplete = 1
|
||||||
|
return '.' . omni#cpp#maycomplete#Complete()
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return '.'
|
||||||
|
endfunc
|
||||||
|
" May complete function for arrow
|
||||||
|
function! omni#cpp#maycomplete#Arrow()
|
||||||
|
if s:CanUseOmnicompletion() && g:OmniCpp_MayCompleteArrow
|
||||||
|
let index = col('.') - 2
|
||||||
|
if index >= 0
|
||||||
|
let char = getline('.')[index]
|
||||||
|
if char == '-'
|
||||||
|
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction('>'))
|
||||||
|
if len(g:omni#cpp#items#data)
|
||||||
|
let s:bMayComplete = 1
|
||||||
|
return '>' . omni#cpp#maycomplete#Complete()
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return '>'
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" May complete function for double points
|
||||||
|
function! omni#cpp#maycomplete#Scope()
|
||||||
|
if s:CanUseOmnicompletion() && g:OmniCpp_MayCompleteScope
|
||||||
|
let index = col('.') - 2
|
||||||
|
if index >= 0
|
||||||
|
let char = getline('.')[index]
|
||||||
|
if char == ':'
|
||||||
|
let g:omni#cpp#items#data = omni#cpp#items#Get(omni#cpp#utils#TokenizeCurrentInstruction(':'))
|
||||||
|
if len(g:omni#cpp#items#data)
|
||||||
|
if len(g:omni#cpp#items#data[-1].tokens) && g:omni#cpp#items#data[-1].tokens[-1].value != '::'
|
||||||
|
let s:bMayComplete = 1
|
||||||
|
return ':' . omni#cpp#maycomplete#Complete()
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return ':'
|
||||||
|
endfunc
|
838
.vim/autoload/omni/cpp/namespaces.vim
Normal file
838
.vim/autoload/omni/cpp/namespaces.vim
Normal file
@ -0,0 +1,838 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
let g:omni#cpp#namespaces#CacheResolve = {}
|
||||||
|
let g:omni#cpp#namespaces#CacheUsing = {}
|
||||||
|
" TODO: For the next release
|
||||||
|
"let g:omni#cpp#namespaces#CacheAlias = {}
|
||||||
|
|
||||||
|
" Get the using namespace list from a line
|
||||||
|
function! s:GetNamespaceAliasListFromLine(szLine)
|
||||||
|
let result = {}
|
||||||
|
let tokens = omni#cpp#tokenizer#Tokenize(a:szLine)
|
||||||
|
let szAlias = ''
|
||||||
|
let szNamespace = ''
|
||||||
|
let state = 0
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
let szAlias = ''
|
||||||
|
let szNamespace = ''
|
||||||
|
if token.value == '/*'
|
||||||
|
let state = 1
|
||||||
|
elseif token.value == '//'
|
||||||
|
" It's a comment
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
elseif token.value == 'namespace'
|
||||||
|
let state = 2
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
if token.value == '*/'
|
||||||
|
let state=0
|
||||||
|
endif
|
||||||
|
elseif state==2
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
let szAlias .= token.value
|
||||||
|
let state = 3
|
||||||
|
else
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state == 3
|
||||||
|
if token.value == '='
|
||||||
|
let state = 4
|
||||||
|
else
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state == 4
|
||||||
|
if token.value == '::'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 5
|
||||||
|
elseif token.kind == 'cppWord'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 6
|
||||||
|
" Maybe end of tokens
|
||||||
|
endif
|
||||||
|
elseif state==5
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 6
|
||||||
|
" Maybe end of tokens
|
||||||
|
else
|
||||||
|
" Error, we can't have 'namespace ALIAS = Something::'
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==6
|
||||||
|
if token.value == '::'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 5
|
||||||
|
else
|
||||||
|
call extend(result, {szAlias : szNamespace})
|
||||||
|
let state = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if state == 6
|
||||||
|
call extend(result, {szAlias : szNamespace})
|
||||||
|
endif
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the using namespace list from a line
|
||||||
|
function! s:GetNamespaceListFromLine(szLine)
|
||||||
|
let result = []
|
||||||
|
let tokens = omni#cpp#tokenizer#Tokenize(a:szLine)
|
||||||
|
let szNamespace = ''
|
||||||
|
let state = 0
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
let szNamespace = ''
|
||||||
|
if token.value == '/*'
|
||||||
|
let state = 1
|
||||||
|
elseif token.value == '//'
|
||||||
|
" It's a comment
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
elseif token.value == 'using'
|
||||||
|
let state = 2
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
if token.value == '*/'
|
||||||
|
let state=0
|
||||||
|
endif
|
||||||
|
elseif state==2
|
||||||
|
if token.value == 'namespace'
|
||||||
|
let state = 3
|
||||||
|
else
|
||||||
|
" Error, 'using' must be followed by 'namespace'
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==3
|
||||||
|
if token.value == '::'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 4
|
||||||
|
elseif token.kind == 'cppWord'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 5
|
||||||
|
" Maybe end of tokens
|
||||||
|
endif
|
||||||
|
elseif state==4
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 5
|
||||||
|
" Maybe end of tokens
|
||||||
|
else
|
||||||
|
" Error, we can't have 'using namespace Something::'
|
||||||
|
let state = -1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==5
|
||||||
|
if token.value == '::'
|
||||||
|
let szNamespace .= token.value
|
||||||
|
let state = 4
|
||||||
|
else
|
||||||
|
call extend(result, [szNamespace])
|
||||||
|
let state = 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if state == 5
|
||||||
|
call extend(result, [szNamespace])
|
||||||
|
endif
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the namespace list from a namespace map
|
||||||
|
function! s:GetUsingNamespaceListFromMap(namespaceMap, ...)
|
||||||
|
let stopLine = 0
|
||||||
|
if a:0>0
|
||||||
|
let stopLine = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = []
|
||||||
|
let keys = sort(keys(a:namespaceMap), 'omni#common#utils#CompareNumber')
|
||||||
|
for i in keys
|
||||||
|
if stopLine != 0 && i > stopLine
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
call extend(result, a:namespaceMap[i])
|
||||||
|
endfor
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get global using namespace list from the current buffer
|
||||||
|
function! omni#cpp#namespaces#GetListFromCurrentBuffer(...)
|
||||||
|
let namespaceMap = s:GetAllUsingNamespaceMapFromCurrentBuffer()
|
||||||
|
let result = []
|
||||||
|
if namespaceMap != {}
|
||||||
|
let result = s:GetUsingNamespaceListFromMap(namespaceMap, (a:0 > 0)? a:1 : line('.'))
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get global using namespace map from the current buffer and include files recursively
|
||||||
|
function! s:GetAllUsingNamespaceMapFromCurrentBuffer(...)
|
||||||
|
let includeGuard = (a:0>0)? a:1 : {}
|
||||||
|
|
||||||
|
let szBufferName = getreg("%")
|
||||||
|
let szFilePath = omni#cpp#utils#ResolveFilePath(szBufferName)
|
||||||
|
let szFilePath = (szFilePath=='')? szBufferName : szFilePath
|
||||||
|
|
||||||
|
let namespaceMap = {}
|
||||||
|
if has_key(includeGuard, szFilePath)
|
||||||
|
return namespaceMap
|
||||||
|
else
|
||||||
|
let includeGuard[szFilePath] = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let namespaceMap = omni#cpp#namespaces#GetMapFromCurrentBuffer()
|
||||||
|
|
||||||
|
if g:OmniCpp_NamespaceSearch != 2
|
||||||
|
" We don't search included files if OmniCpp_NamespaceSearch != 2
|
||||||
|
return namespaceMap
|
||||||
|
endif
|
||||||
|
|
||||||
|
for inc in omni#cpp#includes#GetList()
|
||||||
|
let lnum = inc.pos[0]
|
||||||
|
let tmpMap = s:GetAllUsingNamespaceMapFromFile(inc.include, includeGuard)
|
||||||
|
if tmpMap != {}
|
||||||
|
if has_key(namespaceMap, lnum)
|
||||||
|
call extend(namespaceMap[lnum], s:GetUsingNamespaceListFromMap(tmpMap))
|
||||||
|
else
|
||||||
|
let namespaceMap[lnum] = s:GetUsingNamespaceListFromMap(tmpMap)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return namespaceMap
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get global using namespace map from a file and include files recursively
|
||||||
|
function! s:GetAllUsingNamespaceMapFromFile(szFilePath, ...)
|
||||||
|
let includeGuard = {}
|
||||||
|
if a:0 >0
|
||||||
|
let includeGuard = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
|
||||||
|
let szFilePath = (szFilePath=='')? a:szFilePath : szFilePath
|
||||||
|
|
||||||
|
let namespaceMap = {}
|
||||||
|
if has_key(includeGuard, szFilePath)
|
||||||
|
return namespaceMap
|
||||||
|
else
|
||||||
|
let includeGuard[szFilePath] = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" If g:OmniCpp_NamespaceSearch == 1 (search namespaces only in the current
|
||||||
|
" buffer) we don't use cache for the current buffer
|
||||||
|
let namespaceMap = omni#cpp#namespaces#GetMapFromBuffer(szFilePath, g:OmniCpp_NamespaceSearch==1)
|
||||||
|
|
||||||
|
if g:OmniCpp_NamespaceSearch != 2
|
||||||
|
" We don't search included files if OmniCpp_NamespaceSearch != 2
|
||||||
|
return namespaceMap
|
||||||
|
endif
|
||||||
|
|
||||||
|
for inc in omni#cpp#includes#GetList(szFilePath)
|
||||||
|
let lnum = inc.pos[0]
|
||||||
|
let tmpMap = s:GetAllUsingNamespaceMapFromFile(inc.include, includeGuard)
|
||||||
|
if tmpMap != {}
|
||||||
|
if has_key(namespaceMap, lnum)
|
||||||
|
call extend(namespaceMap[lnum], s:GetUsingNamespaceListFromMap(tmpMap))
|
||||||
|
else
|
||||||
|
let namespaceMap[lnum] = s:GetUsingNamespaceListFromMap(tmpMap)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return namespaceMap
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get global using namespace map from a the current buffer
|
||||||
|
function! omni#cpp#namespaces#GetMapFromCurrentBuffer()
|
||||||
|
let namespaceMap = {}
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
|
||||||
|
call setpos('.', [0, 1, 1, 0])
|
||||||
|
let curPos = [1,1]
|
||||||
|
while curPos != [0,0]
|
||||||
|
let curPos = searchpos('\C^using\s\+namespace', 'W')
|
||||||
|
if curPos != [0,0]
|
||||||
|
let szLine = getline('.')
|
||||||
|
let startPos = curPos[1]
|
||||||
|
let endPos = match(szLine, ';', startPos-1)
|
||||||
|
if endPos!=-1
|
||||||
|
" We get the namespace list from the line
|
||||||
|
let namespaceMap[curPos[0]] = s:GetNamespaceListFromLine(szLine)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
return namespaceMap
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get global using namespace map from a file
|
||||||
|
function! omni#cpp#namespaces#GetMapFromBuffer(szFilePath, ...)
|
||||||
|
let bUpdate = 0
|
||||||
|
if a:0 > 0
|
||||||
|
let bUpdate = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
|
||||||
|
let szFilePath = (szFilePath=='')? a:szFilePath : szFilePath
|
||||||
|
|
||||||
|
if !bUpdate && has_key(g:omni#cpp#namespaces#CacheUsing, szFilePath)
|
||||||
|
return copy(g:omni#cpp#namespaces#CacheUsing[szFilePath])
|
||||||
|
endif
|
||||||
|
|
||||||
|
let namespaceMap = {}
|
||||||
|
" The file exists, we get the global namespaces in this file
|
||||||
|
let szFixedPath = escape(szFilePath, g:omni#cpp#utils#szEscapedCharacters)
|
||||||
|
execute 'silent! lvimgrep /\C^using\s\+namespace/gj '.szFixedPath
|
||||||
|
|
||||||
|
" key = line number
|
||||||
|
" value = list of namespaces
|
||||||
|
let listQuickFix = getloclist(0)
|
||||||
|
for qf in listQuickFix
|
||||||
|
let szLine = qf.text
|
||||||
|
let startPos = qf.col
|
||||||
|
let endPos = match(szLine, ';', startPos-1)
|
||||||
|
if endPos!=-1
|
||||||
|
" We get the namespace list from the line
|
||||||
|
let namespaceMap[qf.lnum] = s:GetNamespaceListFromLine(szLine)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if szFixedPath != ''
|
||||||
|
let g:omni#cpp#namespaces#CacheUsing[szFixedPath] = namespaceMap
|
||||||
|
endif
|
||||||
|
|
||||||
|
return copy(namespaceMap)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the stop position when searching for local variables
|
||||||
|
function! s:GetStopPositionForLocalSearch()
|
||||||
|
" Stop position when searching a local variable
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
let origPos = originalPos[1:2]
|
||||||
|
let stopPosition = origPos
|
||||||
|
let curPos = origPos
|
||||||
|
while curPos !=[0,0]
|
||||||
|
let stopPosition = curPos
|
||||||
|
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
endwhile
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
|
||||||
|
return stopPosition
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get namespaces alias used at the cursor postion in a vim buffer
|
||||||
|
" Note: The result depends on the current cursor position
|
||||||
|
" @return
|
||||||
|
" - Map of namespace alias
|
||||||
|
function! s:GetNamespaceAliasMap()
|
||||||
|
" We store the cursor position because searchpairpos() moves the cursor
|
||||||
|
let result = {}
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
let origPos = originalPos[1:2]
|
||||||
|
|
||||||
|
let stopPos = s:GetStopPositionForLocalSearch()
|
||||||
|
let stopLine = stopPos[0]
|
||||||
|
let curPos = origPos
|
||||||
|
let lastLine = 0
|
||||||
|
let nextStopLine = origPos[0]
|
||||||
|
let szReAlias = '\Cnamespace\s\+\w\+\s\+='
|
||||||
|
while curPos !=[0,0]
|
||||||
|
let curPos = searchpos('}\|\('. szReAlias .'\)', 'bW',stopLine)
|
||||||
|
if curPos!=[0,0] && curPos[0]!=lastLine
|
||||||
|
let lastLine = curPos[0]
|
||||||
|
|
||||||
|
let szLine = getline('.')
|
||||||
|
if origPos[0] == curPos[0]
|
||||||
|
" We get the line until cursor position
|
||||||
|
let szLine = szLine[:origPos[1]]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let szLine = omni#cpp#utils#GetCodeFromLine(szLine)
|
||||||
|
if match(szLine, szReAlias)<0
|
||||||
|
" We found a '}'
|
||||||
|
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
else
|
||||||
|
" We get the namespace alias from the line
|
||||||
|
call extend(result, s:GetNamespaceAliasListFromLine(szLine))
|
||||||
|
let nextStopLine = curPos[0]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Setting the cursor to the original position
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
|
||||||
|
call s:ResolveAliasKeys(result)
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve an alias
|
||||||
|
" eg: namespace IAmAnAlias1 = Ns1
|
||||||
|
" eg: namespace IAmAnAlias2 = IAmAnAlias1::Ns2
|
||||||
|
" => IAmAnAlias2 = Ns1::Ns2
|
||||||
|
function! s:ResolveAliasKey(mapNamespaceAlias, szAlias)
|
||||||
|
let szResult = a:mapNamespaceAlias[a:szAlias]
|
||||||
|
" ::Ns1::Ns2::Ns3 => ['Ns1', 'Ns2', 'Ns3']
|
||||||
|
let listNamespace = split(szResult, '::')
|
||||||
|
if len(listNamespace)
|
||||||
|
" szBeginPart = 'Ns1'
|
||||||
|
let szBeginPart = remove(listNamespace, 0)
|
||||||
|
|
||||||
|
" Is 'Ns1' an alias ?
|
||||||
|
if has_key(a:mapNamespaceAlias, szBeginPart) && szBeginPart != a:szAlias
|
||||||
|
" Resolving alias 'Ns1'
|
||||||
|
" eg: Ns1 = NsResolved
|
||||||
|
let szResult = s:ResolveAliasKey(a:mapNamespaceAlias, szBeginPart)
|
||||||
|
" szEndPart = 'Ns2::Ns3'
|
||||||
|
let szEndPart = join(listNamespace, '::')
|
||||||
|
if szEndPart != ''
|
||||||
|
" Concatenation => szResult = 'NsResolved::Ns2::Ns3'
|
||||||
|
let szResult .= '::' . szEndPart
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return szResult
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve all keys in the namespace alias map
|
||||||
|
function! s:ResolveAliasKeys(mapNamespaceAlias)
|
||||||
|
let mapNamespaceAlias = a:mapNamespaceAlias
|
||||||
|
call map(mapNamespaceAlias, 's:ResolveAliasKey(mapNamespaceAlias, v:key)')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve namespace alias
|
||||||
|
function! omni#cpp#namespaces#ResolveAlias(mapNamespaceAlias, szNamespace)
|
||||||
|
let szResult = a:szNamespace
|
||||||
|
" ::Ns1::Ns2::Ns3 => ['Ns1', 'Ns2', 'Ns3']
|
||||||
|
let listNamespace = split(a:szNamespace, '::')
|
||||||
|
if len(listNamespace)
|
||||||
|
" szBeginPart = 'Ns1'
|
||||||
|
let szBeginPart = remove(listNamespace, 0)
|
||||||
|
|
||||||
|
" Is 'Ns1' an alias ?
|
||||||
|
if has_key(a:mapNamespaceAlias, szBeginPart)
|
||||||
|
" Resolving alias 'Ns1'
|
||||||
|
" eg: Ns1 = NsResolved
|
||||||
|
let szResult = a:mapNamespaceAlias[szBeginPart]
|
||||||
|
" szEndPart = 'Ns2::Ns3'
|
||||||
|
let szEndPart = join(listNamespace, '::')
|
||||||
|
if szEndPart != ''
|
||||||
|
" Concatenation => szResult = 'NsResolved::Ns2::Ns3'
|
||||||
|
let szResult .= '::' . szEndPart
|
||||||
|
endif
|
||||||
|
|
||||||
|
" If a:szNamespace starts with '::' we add '::' to the beginning
|
||||||
|
" of the result
|
||||||
|
if match(a:szNamespace, '^::')>=0
|
||||||
|
let szResult = omni#cpp#utils#SimplifyScope('::' . szResult)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return szResult
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve namespace alias
|
||||||
|
function! s:ResolveAliasInNamespaceList(mapNamespaceAlias, listNamespaces)
|
||||||
|
call map(a:listNamespaces, 'omni#cpp#namespaces#ResolveAlias(a:mapNamespaceAlias, v:val)')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get namespaces used at the cursor postion in a vim buffer
|
||||||
|
" Note: The result depends on the current cursor position
|
||||||
|
" @return
|
||||||
|
" - List of namespace used in the reverse order
|
||||||
|
function! omni#cpp#namespaces#GetUsingNamespaces()
|
||||||
|
" We have to get local using namespace declarations
|
||||||
|
" We need the current cursor position and the position of the start of the
|
||||||
|
" current scope
|
||||||
|
|
||||||
|
" We store the cursor position because searchpairpos() moves the cursor
|
||||||
|
let result = []
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
let origPos = originalPos[1:2]
|
||||||
|
|
||||||
|
let stopPos = s:GetStopPositionForLocalSearch()
|
||||||
|
|
||||||
|
let stopLine = stopPos[0]
|
||||||
|
let curPos = origPos
|
||||||
|
let lastLine = 0
|
||||||
|
let nextStopLine = origPos[0]
|
||||||
|
while curPos !=[0,0]
|
||||||
|
let curPos = searchpos('\C}\|\(using\s\+namespace\)', 'bW',stopLine)
|
||||||
|
if curPos!=[0,0] && curPos[0]!=lastLine
|
||||||
|
let lastLine = curPos[0]
|
||||||
|
|
||||||
|
let szLine = getline('.')
|
||||||
|
if origPos[0] == curPos[0]
|
||||||
|
" We get the line until cursor position
|
||||||
|
let szLine = szLine[:origPos[1]]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let szLine = omni#cpp#utils#GetCodeFromLine(szLine)
|
||||||
|
if match(szLine, '\Cusing\s\+namespace')<0
|
||||||
|
" We found a '}'
|
||||||
|
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
else
|
||||||
|
" We get the namespace list from the line
|
||||||
|
let result = s:GetNamespaceListFromLine(szLine) + result
|
||||||
|
let nextStopLine = curPos[0]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Setting the cursor to the original position
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
|
||||||
|
" 2) Now we can get all global using namespace declaration from the
|
||||||
|
" beginning of the file to nextStopLine
|
||||||
|
let result = omni#cpp#namespaces#GetListFromCurrentBuffer(nextStopLine) + result
|
||||||
|
|
||||||
|
" Resolving alias in the namespace list
|
||||||
|
" TODO: For the next release
|
||||||
|
"let g:omni#cpp#namespaces#CacheAlias= s:GetNamespaceAliasMap()
|
||||||
|
"call s:ResolveAliasInNamespaceList(g:omni#cpp#namespaces#CacheAlias, result)
|
||||||
|
|
||||||
|
return ['::'] + result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve a using namespace regarding the current context
|
||||||
|
" For each namespace used:
|
||||||
|
" - We get all possible contexts where the namespace
|
||||||
|
" can be define
|
||||||
|
" - We do a comparison test of each parent contexts with the current
|
||||||
|
" context list
|
||||||
|
" - If one and only one parent context is present in the
|
||||||
|
" current context list we add the namespace in the current
|
||||||
|
" context
|
||||||
|
" - If there is more than one of parent contexts in the
|
||||||
|
" current context the namespace is ambiguous
|
||||||
|
" @return
|
||||||
|
" - result item
|
||||||
|
" - kind = 0|1
|
||||||
|
" - 0 = unresolved or error
|
||||||
|
" - 1 = resolved
|
||||||
|
" - value = resolved namespace
|
||||||
|
function! s:ResolveNamespace(namespace, mapCurrentContexts)
|
||||||
|
let result = {'kind':0, 'value': ''}
|
||||||
|
|
||||||
|
" If the namespace is already resolved we add it in the list of
|
||||||
|
" current contexts
|
||||||
|
if match(a:namespace, '^::')>=0
|
||||||
|
let result.kind = 1
|
||||||
|
let result.value = a:namespace
|
||||||
|
return result
|
||||||
|
elseif match(a:namespace, '\w\+::\w\+')>=0
|
||||||
|
let mapCurrentContextsTmp = copy(a:mapCurrentContexts)
|
||||||
|
let resolvedItem = {}
|
||||||
|
for nsTmp in split(a:namespace, '::')
|
||||||
|
let resolvedItem = s:ResolveNamespace(nsTmp, mapCurrentContextsTmp)
|
||||||
|
if resolvedItem.kind
|
||||||
|
" Note: We don't extend the map
|
||||||
|
let mapCurrentContextsTmp = {resolvedItem.value : 1}
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
if resolvedItem!={} && resolvedItem.kind
|
||||||
|
let result.kind = 1
|
||||||
|
let result.value = resolvedItem.value
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We get all possible parent contexts of this namespace
|
||||||
|
let listTagsOfNamespace = []
|
||||||
|
if has_key(g:omni#cpp#namespaces#CacheResolve, a:namespace)
|
||||||
|
let listTagsOfNamespace = g:omni#cpp#namespaces#CacheResolve[a:namespace]
|
||||||
|
else
|
||||||
|
let listTagsOfNamespace = omni#common#utils#TagList('^'.a:namespace.'$')
|
||||||
|
let g:omni#cpp#namespaces#CacheResolve[a:namespace] = listTagsOfNamespace
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(listTagsOfNamespace)==0
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
call filter(listTagsOfNamespace, 'v:val.kind[0]=="n"')
|
||||||
|
|
||||||
|
" We extract parent context from tags
|
||||||
|
" We use a map to avoid multiple entries
|
||||||
|
let mapContext = {}
|
||||||
|
for tagItem in listTagsOfNamespace
|
||||||
|
let szParentContext = omni#cpp#utils#ExtractScope(tagItem)
|
||||||
|
let mapContext[szParentContext] = 1
|
||||||
|
endfor
|
||||||
|
let listParentContext = keys(mapContext)
|
||||||
|
|
||||||
|
" Now for each parent context we test if the context is in the current
|
||||||
|
" contexts list
|
||||||
|
let listResolvedNamespace = []
|
||||||
|
for szParentContext in listParentContext
|
||||||
|
if has_key(a:mapCurrentContexts, szParentContext)
|
||||||
|
call extend(listResolvedNamespace, [omni#cpp#utils#SimplifyScope(szParentContext.'::'.a:namespace)])
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" Now we know if the namespace is ambiguous or not
|
||||||
|
let len = len(listResolvedNamespace)
|
||||||
|
if len==1
|
||||||
|
" Namespace resolved
|
||||||
|
let result.kind = 1
|
||||||
|
let result.value = listResolvedNamespace[0]
|
||||||
|
elseif len > 1
|
||||||
|
" Ambiguous namespace, possible matches are in listResolvedNamespace
|
||||||
|
else
|
||||||
|
" Other cases
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Resolve namespaces
|
||||||
|
"@return
|
||||||
|
" - List of resolved namespaces
|
||||||
|
function! omni#cpp#namespaces#ResolveAll(namespacesUsed)
|
||||||
|
|
||||||
|
" We add the default context '::'
|
||||||
|
let contextOrder = 0
|
||||||
|
let mapCurrentContexts = {}
|
||||||
|
|
||||||
|
" For each namespace used:
|
||||||
|
" - We get all possible contexts where the namespace
|
||||||
|
" can be define
|
||||||
|
" - We do a comparison test of each parent contexts with the current
|
||||||
|
" context list
|
||||||
|
" - If one and only one parent context is present in the
|
||||||
|
" current context list we add the namespace in the current
|
||||||
|
" context
|
||||||
|
" - If there is more than one of parent contexts in the
|
||||||
|
" current context the namespace is ambiguous
|
||||||
|
for ns in a:namespacesUsed
|
||||||
|
let resolvedItem = s:ResolveNamespace(ns, mapCurrentContexts)
|
||||||
|
if resolvedItem.kind
|
||||||
|
let contextOrder+=1
|
||||||
|
let mapCurrentContexts[resolvedItem.value] = contextOrder
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" Build the list of current contexts from the map, we have to keep the
|
||||||
|
" order
|
||||||
|
let mapReorder = {}
|
||||||
|
for key in keys(mapCurrentContexts)
|
||||||
|
let mapReorder[ mapCurrentContexts[key] ] = key
|
||||||
|
endfor
|
||||||
|
let result = []
|
||||||
|
for key in sort(keys(mapReorder))
|
||||||
|
call extend(result, [mapReorder[key]])
|
||||||
|
endfor
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Build the context stack
|
||||||
|
function! s:BuildContextStack(namespaces, szCurrentScope)
|
||||||
|
let result = copy(a:namespaces)
|
||||||
|
if a:szCurrentScope != '::'
|
||||||
|
let tagItem = omni#cpp#utils#GetResolvedTagItem(a:namespaces, omni#cpp#utils#CreateTypeInfo(a:szCurrentScope))
|
||||||
|
if has_key(tagItem, 'inherits')
|
||||||
|
let listBaseClass = omni#cpp#utils#GetClassInheritanceList(a:namespaces, omni#cpp#utils#CreateTypeInfo(a:szCurrentScope))
|
||||||
|
let result = listBaseClass + result
|
||||||
|
elseif has_key(tagItem, 'kind') && index(['c', 's', 'u', 'n'], tagItem.kind[0])>=0
|
||||||
|
call insert(result, omni#cpp#utils#ExtractTypeInfoFromTag(tagItem))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Returns the class scope at the current position of the cursor
|
||||||
|
" @return a string that represents the class scope
|
||||||
|
" eg: ::NameSpace1::Class1
|
||||||
|
" The returned string always starts with '::'
|
||||||
|
" Note: In term of performance it's the weak point of the script
|
||||||
|
function! s:GetClassScopeAtCursor()
|
||||||
|
" We store the cursor position because searchpairpos() moves the cursor
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
let endPos = originalPos[1:2]
|
||||||
|
let listCode = []
|
||||||
|
let result = {'namespaces': [], 'scope': ''}
|
||||||
|
|
||||||
|
while endPos!=[0,0]
|
||||||
|
let endPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
let szReStartPos = '[;{}]\|\%^'
|
||||||
|
let startPos = searchpairpos(szReStartPos, '', '{', 'bWn', g:omni#cpp#utils#expIgnoreComments)
|
||||||
|
|
||||||
|
" If the file starts with a comment so the startPos can be [0,0]
|
||||||
|
" we change it to [1,1]
|
||||||
|
if startPos==[0,0]
|
||||||
|
let startPos = [1,1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Get lines backward from cursor position to last ; or { or }
|
||||||
|
" or when we are at the beginning of the file.
|
||||||
|
" We store lines in listCode
|
||||||
|
if endPos!=[0,0]
|
||||||
|
" We remove the last character which is a '{'
|
||||||
|
" We also remove starting { or } or ; if exits
|
||||||
|
let szCodeWithoutComments = substitute(omni#cpp#utils#GetCode(startPos, endPos)[:-2], '^[;{}]', '', 'g')
|
||||||
|
call insert(listCode, {'startLine' : startPos[0], 'code' : szCodeWithoutComments})
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
" Setting the cursor to the original position
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
|
||||||
|
let listClassScope = []
|
||||||
|
let bResolved = 0
|
||||||
|
let startLine = 0
|
||||||
|
" Now we can check in the list of code if there is a function
|
||||||
|
for code in listCode
|
||||||
|
" We get the name of the namespace, class, struct or union
|
||||||
|
" and we store it in listClassScope
|
||||||
|
let tokens = omni#cpp#tokenizer#Tokenize(code.code)
|
||||||
|
let bContinue=0
|
||||||
|
let bAddNamespace = 0
|
||||||
|
let state=0
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
if index(['namespace', 'class', 'struct', 'union'], token.value)>=0
|
||||||
|
if token.value == 'namespace'
|
||||||
|
let bAddNamespace = 1
|
||||||
|
endif
|
||||||
|
let state= 1
|
||||||
|
" Maybe end of tokens
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
" eg: namespace MyNs { class MyCl {}; }
|
||||||
|
" => listClassScope = [MyNs, MyCl]
|
||||||
|
call extend( listClassScope , [token.value] )
|
||||||
|
|
||||||
|
" Add the namespace in result
|
||||||
|
if bAddNamespace
|
||||||
|
call extend(result.namespaces, [token.value])
|
||||||
|
let bAddNamespace = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let bContinue=1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
if bContinue==1
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Simple test to check if we have a chance to find a
|
||||||
|
" class method
|
||||||
|
let aPos = matchend(code.code, '::\s*\~*\s*\w\+\s*(')
|
||||||
|
if aPos ==-1
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
let startLine = code.startLine
|
||||||
|
let listTmp = []
|
||||||
|
" eg: 'void MyNamespace::MyClass::foo('
|
||||||
|
" => tokens = ['MyClass', '::', 'MyNamespace', 'void']
|
||||||
|
let tokens = reverse(omni#cpp#tokenizer#Tokenize(code.code[:aPos-1])[:-4])
|
||||||
|
let state = 0
|
||||||
|
" Reading tokens backward
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
if token.kind=='cppWord'
|
||||||
|
call insert(listTmp, token.value)
|
||||||
|
let state=1
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
if token.value=='::'
|
||||||
|
let state=2
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==2
|
||||||
|
if token.kind=='cppWord'
|
||||||
|
call insert(listTmp, token.value)
|
||||||
|
let state=1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if len(listTmp)
|
||||||
|
if len(listClassScope)
|
||||||
|
let bResolved = 1
|
||||||
|
" Merging class scopes
|
||||||
|
" eg: current class scope = 'MyNs::MyCl1'
|
||||||
|
" method class scope = 'MyCl1::MyCl2'
|
||||||
|
" If we add the method class scope to current class scope
|
||||||
|
" we'll have MyNs::MyCl1::MyCl1::MyCl2 => it's wrong
|
||||||
|
" we want MyNs::MyCl1::MyCl2
|
||||||
|
let index = 0
|
||||||
|
for methodClassScope in listTmp
|
||||||
|
if methodClassScope==listClassScope[-1]
|
||||||
|
let listTmp = listTmp[index+1:]
|
||||||
|
break
|
||||||
|
else
|
||||||
|
let index+=1
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
call extend(listClassScope, listTmp)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let szClassScope = '::'
|
||||||
|
if len(listClassScope)
|
||||||
|
if bResolved
|
||||||
|
let szClassScope .= join(listClassScope, '::')
|
||||||
|
else
|
||||||
|
let szClassScope = join(listClassScope, '::')
|
||||||
|
|
||||||
|
" The class scope is not resolved, we have to check using
|
||||||
|
" namespace declarations and search the class scope in each
|
||||||
|
" namespace
|
||||||
|
if startLine != 0
|
||||||
|
let namespaces = ['::'] + omni#cpp#namespaces#GetListFromCurrentBuffer(startLine)
|
||||||
|
let namespaces = omni#cpp#namespaces#ResolveAll(namespaces)
|
||||||
|
let tagItem = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(szClassScope))
|
||||||
|
if tagItem != {}
|
||||||
|
let szClassScope = omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result.scope = szClassScope
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get all contexts at the cursor position
|
||||||
|
function! omni#cpp#namespaces#GetContexts()
|
||||||
|
" Get the current class scope at the cursor, the result depends on the current cursor position
|
||||||
|
let scopeItem = s:GetClassScopeAtCursor()
|
||||||
|
let listUsingNamespace = copy(g:OmniCpp_DefaultNamespaces)
|
||||||
|
call extend(listUsingNamespace, scopeItem.namespaces)
|
||||||
|
if g:OmniCpp_NamespaceSearch && &filetype != 'c'
|
||||||
|
" Get namespaces used in the file until the cursor position
|
||||||
|
let listUsingNamespace = omni#cpp#namespaces#GetUsingNamespaces() + listUsingNamespace
|
||||||
|
" Resolving namespaces, removing ambiguous namespaces
|
||||||
|
let namespaces = omni#cpp#namespaces#ResolveAll(listUsingNamespace)
|
||||||
|
else
|
||||||
|
let namespaces = ['::'] + listUsingNamespace
|
||||||
|
endif
|
||||||
|
call reverse(namespaces)
|
||||||
|
|
||||||
|
" Building context stack from namespaces and the current class scope
|
||||||
|
return s:BuildContextStack(namespaces, scopeItem.scope)
|
||||||
|
endfunc
|
96
.vim/autoload/omni/cpp/settings.vim
Normal file
96
.vim/autoload/omni/cpp/settings.vim
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
function! omni#cpp#settings#Init()
|
||||||
|
" Global scope search on/off
|
||||||
|
" 0 = disabled
|
||||||
|
" 1 = enabled
|
||||||
|
if !exists('g:OmniCpp_GlobalScopeSearch')
|
||||||
|
let g:OmniCpp_GlobalScopeSearch = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Sets the namespace search method
|
||||||
|
" 0 = disabled
|
||||||
|
" 1 = search namespaces in the current file
|
||||||
|
" 2 = search namespaces in the current file and included files
|
||||||
|
if !exists('g:OmniCpp_NamespaceSearch')
|
||||||
|
let g:OmniCpp_NamespaceSearch = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set the class scope completion mode
|
||||||
|
" 0 = auto
|
||||||
|
" 1 = show all members (static, public, protected and private)
|
||||||
|
if !exists('g:OmniCpp_DisplayMode')
|
||||||
|
let g:OmniCpp_DisplayMode = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set if the scope is displayed in the abbr column of the popup
|
||||||
|
" 0 = no
|
||||||
|
" 1 = yes
|
||||||
|
if !exists('g:OmniCpp_ShowScopeInAbbr')
|
||||||
|
let g:OmniCpp_ShowScopeInAbbr = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set if the function prototype is displayed in the abbr column of the popup
|
||||||
|
" 0 = no
|
||||||
|
" 1 = yes
|
||||||
|
if !exists('g:OmniCpp_ShowPrototypeInAbbr')
|
||||||
|
let g:OmniCpp_ShowPrototypeInAbbr = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set if the access (+,#,-) is displayed
|
||||||
|
" 0 = no
|
||||||
|
" 1 = yes
|
||||||
|
if !exists('g:OmniCpp_ShowAccess')
|
||||||
|
let g:OmniCpp_ShowAccess = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set the list of default namespaces
|
||||||
|
" eg: ['std']
|
||||||
|
if !exists('g:OmniCpp_DefaultNamespaces')
|
||||||
|
let g:OmniCpp_DefaultNamespaces = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set MayComplete to '.'
|
||||||
|
" 0 = disabled
|
||||||
|
" 1 = enabled
|
||||||
|
" default = 1
|
||||||
|
if !exists('g:OmniCpp_MayCompleteDot')
|
||||||
|
let g:OmniCpp_MayCompleteDot = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set MayComplete to '->'
|
||||||
|
" 0 = disabled
|
||||||
|
" 1 = enabled
|
||||||
|
" default = 1
|
||||||
|
if !exists('g:OmniCpp_MayCompleteArrow')
|
||||||
|
let g:OmniCpp_MayCompleteArrow = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Set MayComplete to dot
|
||||||
|
" 0 = disabled
|
||||||
|
" 1 = enabled
|
||||||
|
" default = 0
|
||||||
|
if !exists('g:OmniCpp_MayCompleteScope')
|
||||||
|
let g:OmniCpp_MayCompleteScope = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" When completeopt does not contain longest option, this setting
|
||||||
|
" controls the behaviour of the popup menu selection when starting the completion
|
||||||
|
" 0 = don't select first item
|
||||||
|
" 1 = select first item (inserting it to the text)
|
||||||
|
" 2 = select first item (without inserting it to the text)
|
||||||
|
" default = 0
|
||||||
|
if !exists('g:OmniCpp_SelectFirstItem')
|
||||||
|
let g:OmniCpp_SelectFirstItem= 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Use local search function for variable definitions
|
||||||
|
" 0 = use standard vim search function
|
||||||
|
" 1 = use local search function
|
||||||
|
" default = 0
|
||||||
|
if !exists('g:OmniCpp_LocalSearchDecl')
|
||||||
|
let g:OmniCpp_LocalSearchDecl= 0
|
||||||
|
endif
|
||||||
|
endfunc
|
93
.vim/autoload/omni/cpp/tokenizer.vim
Normal file
93
.vim/autoload/omni/cpp/tokenizer.vim
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
" Description: Omni completion tokenizer
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
" TODO: Generic behaviour for Tokenize()
|
||||||
|
|
||||||
|
" From the C++ BNF
|
||||||
|
let s:cppKeyword = ['asm', 'auto', 'bool', 'break', 'case', 'catch', 'char', 'class', 'const', 'const_cast', 'continue', 'default', 'delete', 'do', 'double', 'dynamic_cast', 'else', 'enum', 'explicit', 'export', 'extern', 'false', 'float', 'for', 'friend', 'goto', 'if', 'inline', 'int', 'long', 'mutable', 'namespace', 'new', 'operator', 'private', 'protected', 'public', 'register', 'reinterpret_cast', 'return', 'short', 'signed', 'sizeof', 'static', 'static_cast', 'struct', 'switch', 'template', 'this', 'throw', 'true', 'try', 'typedef', 'typeid', 'typename', 'union', 'unsigned', 'using', 'virtual', 'void', 'volatile', 'wchar_t', 'while', 'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not', 'not_eq', 'or', 'or_eq', 'xor', 'xor_eq']
|
||||||
|
|
||||||
|
let s:reCppKeyword = '\C\<'.join(s:cppKeyword, '\>\|\<').'\>'
|
||||||
|
|
||||||
|
" The order of items in this list is very important because we use this list to build a regular
|
||||||
|
" expression (see below) for tokenization
|
||||||
|
let s:cppOperatorPunctuator = ['->*', '->', '--', '-=', '-', '!=', '!', '##', '#', '%:%:', '%=', '%>', '%:', '%', '&&', '&=', '&', '(', ')', '*=', '*', ',', '...', '.*', '.', '/=', '/', '::', ':>', ':', ';', '?', '[', ']', '^=', '^', '{', '||', '|=', '|', '}', '~', '++', '+=', '+', '<<=', '<%', '<:', '<<', '<=', '<', '==', '=', '>>=', '>>', '>=', '>']
|
||||||
|
|
||||||
|
" We build the regexp for the tokenizer
|
||||||
|
let s:reCComment = '\/\*\|\*\/'
|
||||||
|
let s:reCppComment = '\/\/'
|
||||||
|
let s:reComment = s:reCComment.'\|'.s:reCppComment
|
||||||
|
let s:reCppOperatorOrPunctuator = escape(join(s:cppOperatorPunctuator, '\|'), '*./^~[]')
|
||||||
|
|
||||||
|
|
||||||
|
" Tokenize a c++ code
|
||||||
|
" a token is dictionary where keys are:
|
||||||
|
" - kind = cppKeyword|cppWord|cppOperatorPunctuator|unknown|cComment|cppComment|cppDigit
|
||||||
|
" - value = 'something'
|
||||||
|
" Note: a cppWord is any word that is not a cpp keyword
|
||||||
|
function! omni#cpp#tokenizer#Tokenize(szCode)
|
||||||
|
let result = []
|
||||||
|
|
||||||
|
" The regexp to find a token, a token is a keyword, word or
|
||||||
|
" c++ operator or punctuator. To work properly we have to put
|
||||||
|
" spaces and tabs to our regexp.
|
||||||
|
let reTokenSearch = '\(\w\+\)\|\s\+\|'.s:reComment.'\|'.s:reCppOperatorOrPunctuator
|
||||||
|
" eg: 'using namespace std;'
|
||||||
|
" ^ ^
|
||||||
|
" start=0 end=5
|
||||||
|
let startPos = 0
|
||||||
|
let endPos = matchend(a:szCode, reTokenSearch)
|
||||||
|
let len = endPos-startPos
|
||||||
|
while endPos!=-1
|
||||||
|
" eg: 'using namespace std;'
|
||||||
|
" ^ ^
|
||||||
|
" start=0 end=5
|
||||||
|
" token = 'using'
|
||||||
|
" We also remove space and tabs
|
||||||
|
let token = substitute(strpart(a:szCode, startPos, len), '\s', '', 'g')
|
||||||
|
|
||||||
|
" eg: 'using namespace std;'
|
||||||
|
" ^ ^
|
||||||
|
" start=5 end=15
|
||||||
|
let startPos = endPos
|
||||||
|
let endPos = matchend(a:szCode, reTokenSearch, startPos)
|
||||||
|
let len = endPos-startPos
|
||||||
|
|
||||||
|
" It the token is empty we continue
|
||||||
|
if token==''
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Building the token
|
||||||
|
let resultToken = {'kind' : 'unknown', 'value' : token}
|
||||||
|
|
||||||
|
" Classify the token
|
||||||
|
if token =~ '^\d\+'
|
||||||
|
" It's a digit
|
||||||
|
let resultToken.kind = 'cppDigit'
|
||||||
|
elseif token=~'^\w\+$'
|
||||||
|
" It's a word
|
||||||
|
let resultToken.kind = 'cppWord'
|
||||||
|
|
||||||
|
" But maybe it's a c++ keyword
|
||||||
|
if match(token, s:reCppKeyword)>=0
|
||||||
|
let resultToken.kind = 'cppKeyword'
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
if match(token, s:reComment)>=0
|
||||||
|
if index(['/*','*/'],token)>=0
|
||||||
|
let resultToken.kind = 'cComment'
|
||||||
|
else
|
||||||
|
let resultToken.kind = 'cppComment'
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" It's an operator
|
||||||
|
let resultToken.kind = 'cppOperatorPunctuator'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We have our token, let's add it to the result list
|
||||||
|
call extend(result, [resultToken])
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
587
.vim/autoload/omni/cpp/utils.vim
Normal file
587
.vim/autoload/omni/cpp/utils.vim
Normal file
@ -0,0 +1,587 @@
|
|||||||
|
" Description: Omni completion script for cpp files
|
||||||
|
" Maintainer: Vissale NEANG
|
||||||
|
" Last Change: 26 sept. 2007
|
||||||
|
|
||||||
|
let g:omni#cpp#utils#CACHE_TAG_INHERITS = {}
|
||||||
|
let g:omni#cpp#utils#szFilterGlobalScope = "(!has_key(v:val, 'class') && !has_key(v:val, 'struct') && !has_key(v:val, 'union') && !has_key(v:val, 'namespace')"
|
||||||
|
let g:omni#cpp#utils#szFilterGlobalScope .= "&& (!has_key(v:val, 'enum') || (has_key(v:val, 'enum') && v:val.enum =~ '^\\w\\+$')))"
|
||||||
|
|
||||||
|
" Expression used to ignore comments
|
||||||
|
" Note: this expression drop drastically the performance
|
||||||
|
"let omni#cpp#utils#expIgnoreComments = 'match(synIDattr(synID(line("."), col("."), 1), "name"), '\CcComment')!=-1'
|
||||||
|
" This one is faster but not really good for C comments
|
||||||
|
let omni#cpp#utils#reIgnoreComment = escape('\/\/\|\/\*\|\*\/', '*/\')
|
||||||
|
let omni#cpp#utils#expIgnoreComments = 'getline(".") =~ g:omni#cpp#utils#reIgnoreComment'
|
||||||
|
|
||||||
|
" Characters to escape in a filename for vimgrep
|
||||||
|
"TODO: Find more characters to escape
|
||||||
|
let omni#cpp#utils#szEscapedCharacters = ' %#'
|
||||||
|
|
||||||
|
" Resolve the path of the file
|
||||||
|
" TODO: absolute file path
|
||||||
|
function! omni#cpp#utils#ResolveFilePath(szFile)
|
||||||
|
let result = ''
|
||||||
|
let listPath = split(globpath(&path, a:szFile), "\n")
|
||||||
|
if len(listPath)
|
||||||
|
let result = listPath[0]
|
||||||
|
endif
|
||||||
|
return simplify(result)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get code without comments and with empty strings
|
||||||
|
" szSingleLine must not have carriage return
|
||||||
|
function! omni#cpp#utils#GetCodeFromLine(szSingleLine)
|
||||||
|
" We set all strings to empty strings, it's safer for
|
||||||
|
" the next of the process
|
||||||
|
let szResult = substitute(a:szSingleLine, '".*"', '""', 'g')
|
||||||
|
|
||||||
|
" Removing c++ comments, we can use the pattern ".*" because
|
||||||
|
" we are modifying a line
|
||||||
|
let szResult = substitute(szResult, '\/\/.*', '', 'g')
|
||||||
|
|
||||||
|
" Now we have the entire code in one line and we can remove C comments
|
||||||
|
return s:RemoveCComments(szResult)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Remove C comments on a line
|
||||||
|
function! s:RemoveCComments(szLine)
|
||||||
|
let result = a:szLine
|
||||||
|
|
||||||
|
" We have to match the first '/*' and first '*/'
|
||||||
|
let startCmt = match(result, '\/\*')
|
||||||
|
let endCmt = match(result, '\*\/')
|
||||||
|
while startCmt!=-1 && endCmt!=-1 && startCmt<endCmt
|
||||||
|
if startCmt>0
|
||||||
|
let result = result[ : startCmt-1 ] . result[ endCmt+2 : ]
|
||||||
|
else
|
||||||
|
" Case where '/*' is at the start of the line
|
||||||
|
let result = result[ endCmt+2 : ]
|
||||||
|
endif
|
||||||
|
let startCmt = match(result, '\/\*')
|
||||||
|
let endCmt = match(result, '\*\/')
|
||||||
|
endwhile
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get a c++ code from current buffer from [lineStart, colStart] to
|
||||||
|
" [lineEnd, colEnd] without c++ and c comments, without end of line
|
||||||
|
" and with empty strings if any
|
||||||
|
" @return a string
|
||||||
|
function! omni#cpp#utils#GetCode(posStart, posEnd)
|
||||||
|
let posStart = a:posStart
|
||||||
|
let posEnd = a:posEnd
|
||||||
|
if a:posStart[0]>a:posEnd[0]
|
||||||
|
let posStart = a:posEnd
|
||||||
|
let posEnd = a:posStart
|
||||||
|
elseif a:posStart[0]==a:posEnd[0] && a:posStart[1]>a:posEnd[1]
|
||||||
|
let posStart = a:posEnd
|
||||||
|
let posEnd = a:posStart
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Getting the lines
|
||||||
|
let lines = getline(posStart[0], posEnd[0])
|
||||||
|
let lenLines = len(lines)
|
||||||
|
|
||||||
|
" Formatting the result
|
||||||
|
let result = ''
|
||||||
|
if lenLines==1
|
||||||
|
let sStart = posStart[1]-1
|
||||||
|
let sEnd = posEnd[1]-1
|
||||||
|
let line = lines[0]
|
||||||
|
let lenLastLine = strlen(line)
|
||||||
|
let sEnd = (sEnd>lenLastLine)?lenLastLine : sEnd
|
||||||
|
if sStart >= 0
|
||||||
|
let result = omni#cpp#utils#GetCodeFromLine(line[ sStart : sEnd ])
|
||||||
|
endif
|
||||||
|
elseif lenLines>1
|
||||||
|
let sStart = posStart[1]-1
|
||||||
|
let sEnd = posEnd[1]-1
|
||||||
|
let lenLastLine = strlen(lines[-1])
|
||||||
|
let sEnd = (sEnd>lenLastLine)?lenLastLine : sEnd
|
||||||
|
if sStart >= 0
|
||||||
|
let lines[0] = lines[0][ sStart : ]
|
||||||
|
let lines[-1] = lines[-1][ : sEnd ]
|
||||||
|
for aLine in lines
|
||||||
|
let result = result . omni#cpp#utils#GetCodeFromLine(aLine)." "
|
||||||
|
endfor
|
||||||
|
let result = result[:-2]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Now we have the entire code in one line and we can remove C comments
|
||||||
|
return s:RemoveCComments(result)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Extract the scope (context) of a tag item
|
||||||
|
" eg: ::MyNamespace
|
||||||
|
" @return a string of the scope. a scope from tag always starts with '::'
|
||||||
|
function! omni#cpp#utils#ExtractScope(tagItem)
|
||||||
|
let listKindScope = ['class', 'struct', 'union', 'namespace', 'enum']
|
||||||
|
let szResult = '::'
|
||||||
|
for scope in listKindScope
|
||||||
|
if has_key(a:tagItem, scope)
|
||||||
|
let szResult = szResult . a:tagItem[scope]
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return szResult
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Simplify scope string, remove consecutive '::' if any
|
||||||
|
function! omni#cpp#utils#SimplifyScope(szScope)
|
||||||
|
let szResult = substitute(a:szScope, '\(::\)\+', '::', 'g')
|
||||||
|
if szResult=='::'
|
||||||
|
return szResult
|
||||||
|
else
|
||||||
|
return substitute(szResult, '::$', '', 'g')
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Check if the cursor is in comment
|
||||||
|
function! omni#cpp#utils#IsCursorInCommentOrString()
|
||||||
|
return match(synIDattr(synID(line("."), col(".")-1, 1), "name"), '\C\<cComment\|\<cCppString\|\<cIncluded')>=0
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Tokenize the current instruction until the cursor position.
|
||||||
|
" @return list of tokens
|
||||||
|
function! omni#cpp#utils#TokenizeCurrentInstruction(...)
|
||||||
|
let szAppendText = ''
|
||||||
|
if a:0>0
|
||||||
|
let szAppendText = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let startPos = searchpos('[;{}]\|\%^', 'bWn')
|
||||||
|
let curPos = getpos('.')[1:2]
|
||||||
|
" We don't want the character under the cursor
|
||||||
|
let column = curPos[1]-1
|
||||||
|
let curPos[1] = (column<1)?1:column
|
||||||
|
return omni#cpp#tokenizer#Tokenize(omni#cpp#utils#GetCode(startPos, curPos)[1:] . szAppendText)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Tokenize the current instruction until the word under the cursor.
|
||||||
|
" @return list of tokens
|
||||||
|
function! omni#cpp#utils#TokenizeCurrentInstructionUntilWord()
|
||||||
|
let startPos = searchpos('[;{}]\|\%^', 'bWn')
|
||||||
|
|
||||||
|
" Saving the current cursor pos
|
||||||
|
let originalPos = getpos('.')
|
||||||
|
|
||||||
|
" We go at the end of the word
|
||||||
|
execute 'normal gee'
|
||||||
|
let curPos = getpos('.')[1:2]
|
||||||
|
|
||||||
|
" Restoring the original cursor pos
|
||||||
|
call setpos('.', originalPos)
|
||||||
|
|
||||||
|
let szCode = omni#cpp#utils#GetCode(startPos, curPos)[1:]
|
||||||
|
return omni#cpp#tokenizer#Tokenize(szCode)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Build parenthesis groups
|
||||||
|
" add a new key 'group' in the token
|
||||||
|
" where value is the group number of the parenthesis
|
||||||
|
" eg: (void*)(MyClass*)
|
||||||
|
" group1 group0
|
||||||
|
" if a parenthesis is unresolved the group id is -1
|
||||||
|
" @return a copy of a:tokens with parenthesis group
|
||||||
|
function! omni#cpp#utils#BuildParenthesisGroups(tokens)
|
||||||
|
let tokens = copy(a:tokens)
|
||||||
|
let kinds = {'(': '()', ')' : '()', '[' : '[]', ']' : '[]', '<' : '<>', '>' : '<>', '{': '{}', '}': '{}'}
|
||||||
|
let unresolved = {'()' : [], '[]': [], '<>' : [], '{}' : []}
|
||||||
|
let groupId = 0
|
||||||
|
|
||||||
|
" Note: we build paren group in a backward way
|
||||||
|
" because we can often have parenthesis unbalanced
|
||||||
|
" instruction
|
||||||
|
" eg: doSomething(_member.get()->
|
||||||
|
for token in reverse(tokens)
|
||||||
|
if index([')', ']', '>', '}'], token.value)>=0
|
||||||
|
let token['group'] = groupId
|
||||||
|
call extend(unresolved[kinds[token.value]], [token])
|
||||||
|
let groupId+=1
|
||||||
|
elseif index(['(', '[', '<', '{'], token.value)>=0
|
||||||
|
if len(unresolved[kinds[token.value]])
|
||||||
|
let tokenResolved = remove(unresolved[kinds[token.value]], -1)
|
||||||
|
let token['group'] = tokenResolved.group
|
||||||
|
else
|
||||||
|
let token['group'] = -1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return reverse(tokens)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Determine if tokens represent a C cast
|
||||||
|
" @return
|
||||||
|
" - itemCast
|
||||||
|
" - itemCppCast
|
||||||
|
" - itemVariable
|
||||||
|
" - itemThis
|
||||||
|
function! omni#cpp#utils#GetCastType(tokens)
|
||||||
|
" Note: a:tokens is not modified
|
||||||
|
let tokens = omni#cpp#utils#SimplifyParenthesis(omni#cpp#utils#BuildParenthesisGroups(a:tokens))
|
||||||
|
|
||||||
|
if tokens[0].value == '('
|
||||||
|
return 'itemCast'
|
||||||
|
elseif index(['static_cast', 'dynamic_cast', 'reinterpret_cast', 'const_cast'], tokens[0].value)>=0
|
||||||
|
return 'itemCppCast'
|
||||||
|
else
|
||||||
|
for token in tokens
|
||||||
|
if token.value=='this'
|
||||||
|
return 'itemThis'
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return 'itemVariable'
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Remove useless parenthesis
|
||||||
|
function! omni#cpp#utils#SimplifyParenthesis(tokens)
|
||||||
|
"Note: a:tokens is not modified
|
||||||
|
let tokens = a:tokens
|
||||||
|
" We remove useless parenthesis eg: (((MyClass)))
|
||||||
|
if len(tokens)>2
|
||||||
|
while tokens[0].value=='(' && tokens[-1].value==')' && tokens[0].group==tokens[-1].group
|
||||||
|
let tokens = tokens[1:-2]
|
||||||
|
endwhile
|
||||||
|
endif
|
||||||
|
return tokens
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Function create a type info
|
||||||
|
function! omni#cpp#utils#CreateTypeInfo(param)
|
||||||
|
let type = type(a:param)
|
||||||
|
return {'type': type, 'value':a:param}
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Extract type info from a tag item
|
||||||
|
" eg: ::MyNamespace::MyClass
|
||||||
|
function! omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
|
||||||
|
let szTypeInfo = omni#cpp#utils#ExtractScope(a:tagItem) . '::' . substitute(a:tagItem.name, '.*::', '', 'g')
|
||||||
|
return omni#cpp#utils#SimplifyScope(szTypeInfo)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Build a class inheritance list
|
||||||
|
function! omni#cpp#utils#GetClassInheritanceList(namespaces, typeInfo)
|
||||||
|
let result = []
|
||||||
|
for tagItem in omni#cpp#utils#GetResolvedTags(a:namespaces, a:typeInfo)
|
||||||
|
call extend(result, [omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)])
|
||||||
|
endfor
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get class inheritance list where items in the list are tag items.
|
||||||
|
" TODO: Verify inheritance order
|
||||||
|
function! omni#cpp#utils#GetResolvedTags(namespaces, typeInfo)
|
||||||
|
let result = []
|
||||||
|
let tagItem = omni#cpp#utils#GetResolvedTagItem(a:namespaces, a:typeInfo)
|
||||||
|
if tagItem!={}
|
||||||
|
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
|
||||||
|
if has_key(g:omni#cpp#utils#CACHE_TAG_INHERITS, szTypeInfo)
|
||||||
|
let result = g:omni#cpp#utils#CACHE_TAG_INHERITS[szTypeInfo]
|
||||||
|
else
|
||||||
|
call extend(result, [tagItem])
|
||||||
|
if has_key(tagItem, 'inherits')
|
||||||
|
for baseClassTypeInfo in split(tagItem.inherits, ',')
|
||||||
|
let namespaces = [omni#cpp#utils#ExtractScope(tagItem), '::']
|
||||||
|
call extend(result, omni#cpp#utils#GetResolvedTags(namespaces, omni#cpp#utils#CreateTypeInfo(baseClassTypeInfo)))
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
let g:omni#cpp#utils#CACHE_TAG_INHERITS[szTypeInfo] = result
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get a tag item after a scope resolution and typedef resolution
|
||||||
|
function! omni#cpp#utils#GetResolvedTagItem(namespaces, typeInfo)
|
||||||
|
let typeInfo = {}
|
||||||
|
if type(a:typeInfo) == 1
|
||||||
|
let typeInfo = omni#cpp#utils#CreateTypeInfo(a:typeInfo)
|
||||||
|
else
|
||||||
|
let typeInfo = a:typeInfo
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = {}
|
||||||
|
if !omni#cpp#utils#IsTypeInfoValid(typeInfo)
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Unnamed type case eg: '1::2'
|
||||||
|
if typeInfo.type == 4
|
||||||
|
" Here there is no typedef or namespace to resolve, the tagInfo.value is a tag item
|
||||||
|
" representing a variable ('v') a member ('m') or a typedef ('t') and the typename is
|
||||||
|
" always in global scope
|
||||||
|
return typeInfo.value
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Named type case eg: 'MyNamespace::MyClass'
|
||||||
|
let szTypeInfo = omni#cpp#utils#GetTypeInfoString(typeInfo)
|
||||||
|
|
||||||
|
" Resolving namespace alias
|
||||||
|
" TODO: For the next release
|
||||||
|
"let szTypeInfo = omni#cpp#namespaces#ResolveAlias(g:omni#cpp#namespaces#CacheAlias, szTypeInfo)
|
||||||
|
|
||||||
|
if szTypeInfo=='::'
|
||||||
|
return result
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We can only get members of class, struct, union and namespace
|
||||||
|
let szTagFilter = "index(['c', 's', 'u', 'n', 't'], v:val.kind[0])>=0"
|
||||||
|
let szTagQuery = szTypeInfo
|
||||||
|
|
||||||
|
if s:IsTypeInfoResolved(szTypeInfo)
|
||||||
|
" The type info is already resolved, we remove the starting '::'
|
||||||
|
let szTagQuery = substitute(szTypeInfo, '^::', '', 'g')
|
||||||
|
if len(split(szTagQuery, '::'))==1
|
||||||
|
" eg: ::MyClass
|
||||||
|
" Here we have to get tags that have no parent scope
|
||||||
|
" That's why we change the szTagFilter
|
||||||
|
let szTagFilter .= '&& ' . g:omni#cpp#utils#szFilterGlobalScope
|
||||||
|
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
|
||||||
|
call filter(tagList, szTagFilter)
|
||||||
|
if len(tagList)
|
||||||
|
let result = tagList[0]
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" eg: ::MyNamespace::MyClass
|
||||||
|
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
|
||||||
|
call filter(tagList, szTagFilter)
|
||||||
|
|
||||||
|
if len(tagList)
|
||||||
|
let result = tagList[0]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" The type is not resolved
|
||||||
|
let tagList = omni#common#utils#TagListNoThrow('^'.szTagQuery.'$')
|
||||||
|
call filter(tagList, szTagFilter)
|
||||||
|
|
||||||
|
if len(tagList)
|
||||||
|
" Resolving scope (namespace, nested class etc...)
|
||||||
|
let szScopeOfTypeInfo = s:ExtractScopeFromTypeInfo(szTypeInfo)
|
||||||
|
if s:IsTypeInfoResolved(szTypeInfo)
|
||||||
|
let result = s:GetTagOfSameScope(tagList, szScopeOfTypeInfo)
|
||||||
|
else
|
||||||
|
" For each namespace of the namespace list we try to get a tag
|
||||||
|
" that can be in the same scope
|
||||||
|
if g:OmniCpp_NamespaceSearch && &filetype != 'c'
|
||||||
|
for scope in a:namespaces
|
||||||
|
let szTmpScope = omni#cpp#utils#SimplifyScope(scope.'::'.szScopeOfTypeInfo)
|
||||||
|
let result = s:GetTagOfSameScope(tagList, szTmpScope)
|
||||||
|
if result!={}
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
else
|
||||||
|
let szTmpScope = omni#cpp#utils#SimplifyScope('::'.szScopeOfTypeInfo)
|
||||||
|
let result = s:GetTagOfSameScope(tagList, szTmpScope)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if result!={}
|
||||||
|
" We have our tagItem but maybe it's a typedef or an unnamed type
|
||||||
|
if result.kind[0]=='t'
|
||||||
|
" Here we can have a typedef to another typedef, a class, struct, union etc
|
||||||
|
" but we can also have a typedef to an unnamed type, in that
|
||||||
|
" case the result contains a 'typeref' key
|
||||||
|
let namespaces = [omni#cpp#utils#ExtractScope(result), '::']
|
||||||
|
if has_key(result, 'typeref')
|
||||||
|
let result = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(result))
|
||||||
|
else
|
||||||
|
let szCmd = omni#cpp#utils#ExtractCmdFromTagItem(result)
|
||||||
|
let szCode = substitute(omni#cpp#utils#GetCodeFromLine(szCmd), '\C\<'.result.name.'\>.*', '', 'g')
|
||||||
|
let szTypeInfo = omni#cpp#utils#ExtractTypeInfoFromTokens(omni#cpp#tokenizer#Tokenize(szCode))
|
||||||
|
let result = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(szTypeInfo))
|
||||||
|
" TODO: Namespace resolution for result
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return result
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Returns if the type info is valid
|
||||||
|
" @return
|
||||||
|
" - 1 if valid
|
||||||
|
" - 0 otherwise
|
||||||
|
function! omni#cpp#utils#IsTypeInfoValid(typeInfo)
|
||||||
|
if a:typeInfo=={}
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
if a:typeInfo.type == 1 && a:typeInfo.value==''
|
||||||
|
" String case
|
||||||
|
return 0
|
||||||
|
elseif a:typeInfo.type == 4 && a:typeInfo.value=={}
|
||||||
|
" Dictionary case
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the string of the type info
|
||||||
|
function! omni#cpp#utils#GetTypeInfoString(typeInfo)
|
||||||
|
if a:typeInfo.type == 1
|
||||||
|
return a:typeInfo.value
|
||||||
|
else
|
||||||
|
return substitute(a:typeInfo.value.typeref, '^\w\+:', '', 'g')
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" A resolved type info starts with '::'
|
||||||
|
" @return
|
||||||
|
" - 1 if type info starts with '::'
|
||||||
|
" - 0 otherwise
|
||||||
|
function! s:IsTypeInfoResolved(szTypeInfo)
|
||||||
|
return match(a:szTypeInfo, '^::')!=-1
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" A returned type info's scope may not have the global namespace '::'
|
||||||
|
" eg: '::NameSpace1::NameSpace2::MyClass' => '::NameSpace1::NameSpace2'
|
||||||
|
" 'NameSpace1::NameSpace2::MyClass' => 'NameSpace1::NameSpace2'
|
||||||
|
function! s:ExtractScopeFromTypeInfo(szTypeInfo)
|
||||||
|
let szScope = substitute(a:szTypeInfo, '\w\+$', '', 'g')
|
||||||
|
if szScope =='::'
|
||||||
|
return szScope
|
||||||
|
else
|
||||||
|
return substitute(szScope, '::$', '', 'g')
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" @return
|
||||||
|
" - the tag with the same scope
|
||||||
|
" - {} otherwise
|
||||||
|
function! s:GetTagOfSameScope(listTags, szScopeToMatch)
|
||||||
|
for tagItem in a:listTags
|
||||||
|
let szScopeOfTag = omni#cpp#utils#ExtractScope(tagItem)
|
||||||
|
if szScopeOfTag == a:szScopeToMatch
|
||||||
|
return tagItem
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return {}
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Extract the cmd of a tag item without regexp
|
||||||
|
function! omni#cpp#utils#ExtractCmdFromTagItem(tagItem)
|
||||||
|
let line = a:tagItem.cmd
|
||||||
|
let re = '\(\/\^\)\|\(\$\/\)'
|
||||||
|
if match(line, re)!=-1
|
||||||
|
let line = substitute(line, re, '', 'g')
|
||||||
|
return line
|
||||||
|
else
|
||||||
|
" TODO: the cmd is a line number
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Extract type from tokens.
|
||||||
|
" eg: examples of tokens format
|
||||||
|
" 'const MyClass&'
|
||||||
|
" 'const map < int, int >&'
|
||||||
|
" 'MyNs::MyClass'
|
||||||
|
" '::MyClass**'
|
||||||
|
" 'MyClass a, *b = NULL, c[1] = {};
|
||||||
|
" 'hello(MyClass a, MyClass* b'
|
||||||
|
" @return the type info string eg: ::std::map
|
||||||
|
" can be empty
|
||||||
|
function! omni#cpp#utils#ExtractTypeInfoFromTokens(tokens)
|
||||||
|
let szResult = ''
|
||||||
|
let state = 0
|
||||||
|
|
||||||
|
let tokens = omni#cpp#utils#BuildParenthesisGroups(a:tokens)
|
||||||
|
|
||||||
|
" If there is an unbalanced parenthesis we are in a parameter list
|
||||||
|
let bParameterList = 0
|
||||||
|
for token in tokens
|
||||||
|
if token.value == '(' && token.group==-1
|
||||||
|
let bParameterList = 1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if bParameterList
|
||||||
|
let tokens = reverse(tokens)
|
||||||
|
let state = 0
|
||||||
|
let parenGroup = -1
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
if token.value=='>'
|
||||||
|
let parenGroup = token.group
|
||||||
|
let state=1
|
||||||
|
elseif token.kind == 'cppWord'
|
||||||
|
let szResult = token.value.szResult
|
||||||
|
let state=2
|
||||||
|
elseif index(['*', '&'], token.value)<0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
if token.value=='<' && token.group==parenGroup
|
||||||
|
let state=0
|
||||||
|
endif
|
||||||
|
elseif state==2
|
||||||
|
if token.value=='::'
|
||||||
|
let szResult = token.value.szResult
|
||||||
|
let state=3
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==3
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
let szResult = token.value.szResult
|
||||||
|
let state=2
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return szResult
|
||||||
|
endif
|
||||||
|
|
||||||
|
for token in tokens
|
||||||
|
if state==0
|
||||||
|
if token.value == '::'
|
||||||
|
let szResult .= token.value
|
||||||
|
let state = 1
|
||||||
|
elseif token.kind == 'cppWord'
|
||||||
|
let szResult .= token.value
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of token
|
||||||
|
endif
|
||||||
|
elseif state==1
|
||||||
|
if token.kind == 'cppWord'
|
||||||
|
let szResult .= token.value
|
||||||
|
let state = 2
|
||||||
|
" Maybe end of token
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
elseif state==2
|
||||||
|
if token.value == '::'
|
||||||
|
let szResult .= token.value
|
||||||
|
let state = 1
|
||||||
|
else
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return szResult
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the preview window string
|
||||||
|
function! omni#cpp#utils#GetPreviewWindowStringFromTagItem(tagItem)
|
||||||
|
let szResult = ''
|
||||||
|
|
||||||
|
let szResult .= 'name: '.a:tagItem.name."\n"
|
||||||
|
for tagKey in keys(a:tagItem)
|
||||||
|
if index(['name', 'static'], tagKey)>=0
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
let szResult .= tagKey.': '.a:tagItem[tagKey]."\n"
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return substitute(szResult, "\n$", '', 'g')
|
||||||
|
endfunc
|
980
.vim/doc/NERD_tree.txt
Normal file
980
.vim/doc/NERD_tree.txt
Normal file
@ -0,0 +1,980 @@
|
|||||||
|
*NERD_tree.txt* A tree explorer plugin that owns your momma!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
________ ________ _ ____________ ____ __________ ____________~
|
||||||
|
/_ __/ / / / ____/ / | / / ____/ __ \/ __ \ /_ __/ __ \/ ____/ ____/~
|
||||||
|
/ / / /_/ / __/ / |/ / __/ / /_/ / / / / / / / /_/ / __/ / __/ ~
|
||||||
|
/ / / __ / /___ / /| / /___/ _, _/ /_/ / / / / _, _/ /___/ /___ ~
|
||||||
|
/_/ /_/ /_/_____/ /_/ |_/_____/_/ |_/_____/ /_/ /_/ |_/_____/_____/ ~
|
||||||
|
|
||||||
|
|
||||||
|
Reference Manual~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
CONTENTS *NERDTree-contents*
|
||||||
|
|
||||||
|
1.Intro...................................|NERDTree|
|
||||||
|
2.Functionality provided..................|NERDTreeFunctionality|
|
||||||
|
2.1 Commands..........................|NERDTreeCommands|
|
||||||
|
2.2 NERD tree mappings................|NERDTreeMappings|
|
||||||
|
2.3 The filesystem menu...............|NERDTreeFilesysMenu|
|
||||||
|
3.Options.................................|NERDTreeOptions|
|
||||||
|
3.1 Option summary....................|NERDTreeOptionSummary|
|
||||||
|
3.2 Option details....................|NERDTreeOptionDetails|
|
||||||
|
4.Public functions........................|NERDTreePublicFunctions|
|
||||||
|
5.TODO list...............................|NERDTreeTodo|
|
||||||
|
6.The Author..............................|NERDTreeAuthor|
|
||||||
|
7.Changelog...............................|NERDTreeChangelog|
|
||||||
|
8.Credits.................................|NERDTreeCredits|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
1. Intro *NERDTree*
|
||||||
|
|
||||||
|
What is this "NERD tree"??
|
||||||
|
|
||||||
|
The NERD tree allows you to explore your filesystem and to open files and
|
||||||
|
directories. It presents the filesystem to you in the form of a tree which you
|
||||||
|
manipulate with the keyboard and/or mouse. It also allows you to perform
|
||||||
|
simple filesystem operations so you can alter the tree dynamically.
|
||||||
|
|
||||||
|
The following features and functionality are provided by the NERD tree:
|
||||||
|
* Files and directories are displayed in a hierarchical tree structure
|
||||||
|
* Different highlighting is provided for the following types of nodes:
|
||||||
|
* files
|
||||||
|
* directories
|
||||||
|
* sym-links
|
||||||
|
* windows .lnk files
|
||||||
|
* read-only files
|
||||||
|
* Many (customisable) mappings are provided to manipulate the tree:
|
||||||
|
* Mappings to open/close/explore directory nodes
|
||||||
|
* Mappings to open files in new/existing windows/tabs
|
||||||
|
* Mappings to change the current root of the tree
|
||||||
|
* Mappings to navigate around the tree
|
||||||
|
* ...
|
||||||
|
* Most NERD tree navigation can also be done with the mouse
|
||||||
|
* Dynamic customisation of tree content
|
||||||
|
* custom file filters to prevent e.g. vim backup files being displayed
|
||||||
|
* optional displaying of hidden files (. files)
|
||||||
|
* files can be "turned off" so that only directories are displayed
|
||||||
|
* A textual filesystem menu is provided which allows you to
|
||||||
|
create/delete/rename file and directory nodes
|
||||||
|
* The position and size of the NERD tree window can be customised
|
||||||
|
* The order in which the nodes in the tree are listed can be customised.
|
||||||
|
* A model of your filesystem is created/maintained as you explore it. This
|
||||||
|
has several advantages:
|
||||||
|
* All filesystem information is cached and is only re-read on demand
|
||||||
|
* If you revisit a part of the tree that you left earlier in your
|
||||||
|
session, the directory nodes will be opened/closed as you left them
|
||||||
|
* The script remembers the cursor position and window position in the NERD
|
||||||
|
tree so you can toggle it off (or just close the tree window) and then
|
||||||
|
reopen it (with NERDTreeToggle) the NERD tree window will appear EXACTLY
|
||||||
|
as you left it
|
||||||
|
* You can have a separate NERD tree for each tab
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
2. Functionality provided *NERDTreeFunctionality*
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
2.1. Commands *NERDTreeCommands*
|
||||||
|
|
||||||
|
:NERDTree [start-directory] *:NERDTree*
|
||||||
|
Opens a fresh NERD tree in [start-directory] or the current
|
||||||
|
directory if [start-directory] isn't specified.
|
||||||
|
For example: >
|
||||||
|
:NERDTree /home/marty/vim7/src
|
||||||
|
< will open a NERD tree in /home/marty/vim7/src.
|
||||||
|
|
||||||
|
:NERDTreeToggle [start-directory] *:NERDTreeToggle*
|
||||||
|
If a NERD tree already exists for this tab, it is reopened and
|
||||||
|
rendered again. If no NERD tree exists for this tab then this
|
||||||
|
command acts the same as the |:NERDTree| command.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
2.2. NERD tree Mappings *NERDTreeMappings*
|
||||||
|
|
||||||
|
Default Description~ help-tag~
|
||||||
|
Key~
|
||||||
|
|
||||||
|
o.......Open selected file, or expand selected dir...............|NERDTree-o|
|
||||||
|
go......Open selected file, but leave cursor in the NERDTree.....|NERDTree-go|
|
||||||
|
t.......Open selected node in a new tab..........................|NERDTree-t|
|
||||||
|
T.......Same as 't' but keep the focus on the current tab........|NERDTree-T|
|
||||||
|
<tab>...Open selected file in a split window.....................|NERDTree-tab|
|
||||||
|
g<tab>..Same as <tab>, but leave the cursor on the NERDTree......|NERDTree-gtab|
|
||||||
|
!.......Execute the current file.................................|NERDTree-!|
|
||||||
|
O.......Recursively open the selected directory..................|NERDTree-O|
|
||||||
|
x.......Close the current nodes parent...........................|NERDTree-x|
|
||||||
|
X.......Recursively close all children of the current node.......|NERDTree-X|
|
||||||
|
e.......Open a netrw for the current dir.........................|NERDTree-e|
|
||||||
|
|
||||||
|
double-click.......same as the |NERDTree-o| map.
|
||||||
|
middle-click.......same as |NERDTree-tab| for files, same as
|
||||||
|
|NERDTree-e| for dirs.
|
||||||
|
|
||||||
|
P.......Jump to the root node....................................|NERDTree-P|
|
||||||
|
p.......Jump to current nodes parent.............................|NERDTree-p|
|
||||||
|
K.......Jump up inside directories at the current tree depth.....|NERDTree-K|
|
||||||
|
J.......Jump down inside directories at the current tree depth...|NERDTree-J|
|
||||||
|
<C-j>...Jump down to the next sibling of the current directory...|NERDTree-c-j|
|
||||||
|
<C-k>...Jump up to the previous sibling of the current directory.|NERDTree-c-k|
|
||||||
|
|
||||||
|
C.......Change the tree root to the selected dir.................|NERDTree-C|
|
||||||
|
u.......Move the tree root up one directory......................|NERDTree-u|
|
||||||
|
U.......Same as 'u' except the old root node is left open........|NERDTree-U|
|
||||||
|
r.......Recursively refresh the current directory................|NERDTree-r|
|
||||||
|
R.......Recursively refresh the current root.....................|NERDTree-R|
|
||||||
|
m.......Display the filesystem menu..............................|NERDTree-m|
|
||||||
|
cd......Change the CWD to the dir of the selected node...........|NERDTree-cd|
|
||||||
|
|
||||||
|
H.......Toggle whether hidden files displayed....................|NERDTree-H|
|
||||||
|
f.......Toggle whether the file filters are used.................|NERDTree-f|
|
||||||
|
F.......Toggle whether files are displayed.......................|NERDTree-F|
|
||||||
|
|
||||||
|
q.......Close the NERDTree window................................|NERDTree-q|
|
||||||
|
?.......Toggle the display of the quick help.....................|NERDTree-?|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-o*
|
||||||
|
Default key: o
|
||||||
|
Map option: NERDTreeMapActivateNode
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
If a file node is selected, it is opened in the previous window. If a
|
||||||
|
directory is selected it is opened or closed depending on its current state.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-go*
|
||||||
|
Default key: go
|
||||||
|
Map option: None
|
||||||
|
Applies to: files.
|
||||||
|
|
||||||
|
If a file node is selected, it is opened in the previous window, but the
|
||||||
|
cursor does not move.
|
||||||
|
|
||||||
|
The key combo for this mapping is always "g" + NERDTreeMapActivateNode (see
|
||||||
|
|NERDTree-o|).
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-t*
|
||||||
|
Default key: t
|
||||||
|
Map option: NERDTreeMapOpenInTab
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Opens the selected file in a new tab. If a directory is selected, a netrw is
|
||||||
|
opened in a new tab.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-T*
|
||||||
|
Default key: T
|
||||||
|
Map option: NERDTreeMapOpenInTabSilent
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
The same as |NERDTree-t| except that the focus is kept in the current tab.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-tab*
|
||||||
|
Default key: <tab>
|
||||||
|
Map option: NERDTreeMapOpenSplit
|
||||||
|
Applies to: files.
|
||||||
|
|
||||||
|
Opens the selected file in a new split window and puts the cursor in the new
|
||||||
|
window.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-gtab*
|
||||||
|
Default key: g<tab>
|
||||||
|
Map option: None
|
||||||
|
Applies to: files.
|
||||||
|
|
||||||
|
The same as |NERDTree-tab| except that the cursor is not moved.
|
||||||
|
|
||||||
|
The key combo for this mapping is always "g" + NERDTreeMapOpenSplit (see
|
||||||
|
|NERDTree-tab|).
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-!*
|
||||||
|
Default key: !
|
||||||
|
Map option: NERDTreeMapExecute
|
||||||
|
Applies to: files.
|
||||||
|
|
||||||
|
Executes the selected file, prompting for arguments first.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-O*
|
||||||
|
Default key: O
|
||||||
|
Map option: NERDTreeMapOpenRecursively
|
||||||
|
Applies to: directories.
|
||||||
|
|
||||||
|
Recursively opens the selelected directory.
|
||||||
|
|
||||||
|
All files and directories are cached, but if a directory would not be
|
||||||
|
displayed due to file filters (see |NERDTreeIgnore| |NERDTree-f|) or the
|
||||||
|
hidden file filter (see |NERDTreeShowHidden|) then it is not opened. This is
|
||||||
|
handy, especially if you have .svn directories.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-x*
|
||||||
|
Default key: x
|
||||||
|
Map option: NERDTreeMapCloseDir
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Closes the parent of the selected node.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-X*
|
||||||
|
Default key: X
|
||||||
|
Map option: NERDTreeMapCloseChildren
|
||||||
|
Applies to: directories.
|
||||||
|
|
||||||
|
Recursively closes all children of the selected directory.
|
||||||
|
|
||||||
|
Tip: To quickly "reset" the tree, use |NERDTree-P| with this mapping.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-e*
|
||||||
|
Default key: e
|
||||||
|
Map option: NERDTreeMapOpenExpl
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Opens a netrw on the selected directory, or the selected file's directory.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-P*
|
||||||
|
Default key: P
|
||||||
|
Map option: NERDTreeMapJumpRoot
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Jump to the tree root.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-p*
|
||||||
|
Default key: p
|
||||||
|
Map option: NERDTreeMapJumpParent
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Jump to the parent node of the selected node.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-K*
|
||||||
|
Default key: K
|
||||||
|
Map option: NERDTreeMapJumpFirstChild
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Jump to the first child of the current nodes parent.
|
||||||
|
|
||||||
|
If the cursor is already on the first node then do the following:
|
||||||
|
* loop back thru the siblings of the current nodes parent until we find an
|
||||||
|
open dir with children
|
||||||
|
* go to the first child of that node
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-J*
|
||||||
|
Default key: J
|
||||||
|
Map option: NERDTreeMapJumpLastChild
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Jump to the last child of the current nodes parent.
|
||||||
|
|
||||||
|
If the cursor is already on the last node then do the following:
|
||||||
|
* loop forward thru the siblings of the current nodes parent until we find
|
||||||
|
an open dir with children
|
||||||
|
* go to the last child of that node
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-c-j*
|
||||||
|
Default key: <C-j>
|
||||||
|
Map option: NERDTreeMapJumpNextSibling
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
If a dir node is selected, jump to the next sibling of that node.
|
||||||
|
If a file node is selected, jump to the next sibling of that nodes parent.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-c-k*
|
||||||
|
Default key: <C-k>
|
||||||
|
Map option: NERDTreeMapJumpPrevSibling
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
If a dir node is selected, jump to the previous sibling of that node.
|
||||||
|
If a file node is selected, jump to the previous sibling of that nodes parent.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-C*
|
||||||
|
Default key: C
|
||||||
|
Map option: NERDTreeMapChdir
|
||||||
|
Applies to: directories.
|
||||||
|
|
||||||
|
Made the selected directory node the new tree root.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-u*
|
||||||
|
Default key: u
|
||||||
|
Map option: NERDTreeMapUpdir
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Move the tree root up a dir (like doing a "cd ..").
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-U*
|
||||||
|
Default key: U
|
||||||
|
Map option: NERDTreeMapUpdirKeepOpen
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Like |NERDTree-u| except that the old tree root is kept open.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-r*
|
||||||
|
Default key: r
|
||||||
|
Map option: NERDTreeMapRefresh
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
If a dir is selected, recursively refresh that dir, i.e. scan the filesystem
|
||||||
|
for changes and represent them in the tree.
|
||||||
|
|
||||||
|
If a file node is selected then the above is done on it's parent.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-R*
|
||||||
|
Default key: R
|
||||||
|
Map option: NERDTreeMapRefreshRoot
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Recursively refresh the tree root.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-m*
|
||||||
|
Default key: m
|
||||||
|
Map option: NERDTreeMapFilesystemMenu
|
||||||
|
Applies to: files and directories.
|
||||||
|
|
||||||
|
Display the filesystem menu. See |NERDTreeFilesysMenu| for details.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-H*
|
||||||
|
Default key: H
|
||||||
|
Map option: NERDTreeMapToggleHidden
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Toggles whether hidden files are displayed. Hidden files are any
|
||||||
|
file/directory that starts with a "."
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-f*
|
||||||
|
Default key: f
|
||||||
|
Map option: NERDTreeMapToggleFilters
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Toggles whether file filters are used. See |NERDTreeIgnore| for details.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-F*
|
||||||
|
Default key: F
|
||||||
|
Map option: NERDTreeMapToggleFiles
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Toggles whether file nodes are displayed.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-q*
|
||||||
|
Default key: q
|
||||||
|
Map option: NERDTreeMapQuit
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Closes the NERDtree window.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTree-?*
|
||||||
|
Default key: ?
|
||||||
|
Map option: NERDTreeMapHelp
|
||||||
|
Applies to: no restrictions.
|
||||||
|
|
||||||
|
Toggles whether the quickhelp is displayed.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
2.3. The filesystem menu *NERDTreeFilesysMenu*
|
||||||
|
|
||||||
|
The purpose of the filesystem menu is to allow you to perform basic filesystem
|
||||||
|
operations quickly from the NERD tree rather than the console.
|
||||||
|
|
||||||
|
The filesystem menu can be accessed with 'm' mapping and has four supported
|
||||||
|
operations: >
|
||||||
|
1. Adding nodes.
|
||||||
|
2. Move nodes.
|
||||||
|
3. Deleting nodes.
|
||||||
|
3. Copying nodes.
|
||||||
|
<
|
||||||
|
1. Adding nodes:
|
||||||
|
To add a node move the cursor onto (or anywhere inside) the directory you wish
|
||||||
|
to create the new node inside. Select the 'add node' option from the
|
||||||
|
filesystem menu and type a filename. If the filename you type ends with a '/'
|
||||||
|
character then a directory will be created. Once the operation is completed,
|
||||||
|
the cursor is placed on the new node.
|
||||||
|
|
||||||
|
2. Move nodes:
|
||||||
|
To move/rename a node, put the cursor on it and select the 'move' option from
|
||||||
|
the filesystem menu. Enter the new location for the node and it will be
|
||||||
|
moved. If the old file is open in a buffer, you will be asked if you wish to
|
||||||
|
delete that buffer. Once the operation is complete the cursor will be placed
|
||||||
|
on the renamed node.
|
||||||
|
|
||||||
|
3. Deleting nodes:
|
||||||
|
To delete a node put the cursor on it and select the 'delete' option from the
|
||||||
|
filesystem menu. After confirmation the node will be deleted. If a file is
|
||||||
|
deleted but still exists as a buffer you will be given the option to delete
|
||||||
|
that buffer.
|
||||||
|
|
||||||
|
4. Copying nodes:
|
||||||
|
To copy a node put the cursor on it and select the 'copy' option from the
|
||||||
|
filesystem menu. Enter the new location and you're done. Note: copying is
|
||||||
|
currently only supported for *nix operating systems. If someone knows a
|
||||||
|
one line copying command for windows that doesnt require user confirmation
|
||||||
|
then id be grateful if you'd email me.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
3. Customisation *NERDTreeOptions*
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
3.1. Customisation summary *NERDTreeOptionSummary*
|
||||||
|
|
||||||
|
The script provides the following options that can customise the behaviour the
|
||||||
|
NERD tree. These options should be set in your vimrc.
|
||||||
|
|
||||||
|
|loaded_nerd_tree| Turns off the script.
|
||||||
|
|
||||||
|
|NERDChristmasTree| Tells the NERD tree to make itself colourful
|
||||||
|
and pretty.
|
||||||
|
|
||||||
|
|NERDTreeAutoCenter| Controls whether the NERD tree window centers
|
||||||
|
when the cursor moves within a specified
|
||||||
|
distance to the top/bottom of the window.
|
||||||
|
|NERDTreeAutoCenterThreshold| Controls the sensitivity of autocentering.
|
||||||
|
|
||||||
|
|NERDTreeCaseSensitiveSort| Tells the NERD tree whether to be case
|
||||||
|
sensitive or not when sorting nodes.
|
||||||
|
|
||||||
|
|NERDTreeChDirMode| Tells the NERD tree if/when it should change
|
||||||
|
vim's current working directory.
|
||||||
|
|
||||||
|
|NERDTreeHighlightCursorline| Tell the NERD tree whether to highlight the
|
||||||
|
current cursor line.
|
||||||
|
|
||||||
|
|NERDTreeIgnore| Tells the NERD tree which files to ignore.
|
||||||
|
|
||||||
|
|NERDTreeMouseMode| Tells the NERD tree how to handle mouse
|
||||||
|
clicks.
|
||||||
|
|
||||||
|
|NERDTreeShowFiles| Tells the NERD tree whether to display files
|
||||||
|
in the tree on startup.
|
||||||
|
|
||||||
|
|NERDTreeShowHidden| Tells the NERD tree whether to display hidden
|
||||||
|
files on startup.
|
||||||
|
|
||||||
|
|NERDTreeSortOrder| Tell the NERD tree how to sort the nodes in
|
||||||
|
the tree.
|
||||||
|
|
||||||
|
|NERDTreeSplitVertical| Tells the script whether the NERD tree should
|
||||||
|
be created by splitting the window vertically
|
||||||
|
or horizontally.
|
||||||
|
|
||||||
|
|NERDTreeWinPos| Tells the script where to put the NERD tree
|
||||||
|
window.
|
||||||
|
|
||||||
|
|
||||||
|
|NERDTreeWinSize| Sets the window size when the NERD tree is
|
||||||
|
opened.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
3.2. Customisation details *NERDTreeOptionDetails*
|
||||||
|
|
||||||
|
To enable any of the below options you should put the given line in your
|
||||||
|
~/.vimrc
|
||||||
|
|
||||||
|
*loaded_nerd_tree*
|
||||||
|
If this plugin is making you feel homicidal, it may be a good idea to turn it
|
||||||
|
off with this line in your vimrc: >
|
||||||
|
let loaded_nerd_tree=1
|
||||||
|
<
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDChristmasTree*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
If this option is set to 1 then some extra syntax highlighting elements are
|
||||||
|
added to the nerd tree to make it more colourful.
|
||||||
|
|
||||||
|
Set it to 0 for a more vanilla looking tree.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeAutoCenter*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 1
|
||||||
|
|
||||||
|
If set to 1, the NERD tree window will center around the cursor if it moves to
|
||||||
|
within |NERDTreeAutoCenterThreshold| lines of the top/bottom of the window.
|
||||||
|
|
||||||
|
This is ONLY done in response to tree navigation mappings,
|
||||||
|
i.e. |NERDTree-J| |NERDTree-K| |NERDTree-C-J| |NERDTree-c-K| |NERDTree-p|
|
||||||
|
|NERDTree-P|
|
||||||
|
|
||||||
|
The centering is done with a |zz| operation.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeAutoCenterThreshold*
|
||||||
|
Values: Any natural number.
|
||||||
|
Default: 3
|
||||||
|
|
||||||
|
This option controls the "sensitivity" of the NERD tree auto centering. See
|
||||||
|
|NERDTreeAutoCenter| for details.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeCaseSensitiveSort*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 0.
|
||||||
|
|
||||||
|
By default the NERD tree does not sort nodes case sensitively, i.e. nodes
|
||||||
|
could appear like this: >
|
||||||
|
bar.c
|
||||||
|
Baz.c
|
||||||
|
blarg.c
|
||||||
|
boner.c
|
||||||
|
Foo.c
|
||||||
|
<
|
||||||
|
But, if you set this option to 1 then the case of the nodes will be taken into
|
||||||
|
account. The above nodes would then be sorted like this: >
|
||||||
|
Baz.c
|
||||||
|
Foo.c
|
||||||
|
bar.c
|
||||||
|
blarg.c
|
||||||
|
boner.c
|
||||||
|
<
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeChDirMode*
|
||||||
|
|
||||||
|
Values: 0, 1 or 2.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
Use this option to tell the script when (if at all) to change the current
|
||||||
|
working directory (CWD) for vim.
|
||||||
|
|
||||||
|
If it is set to 0 then the CWD is never changed by the NERD tree.
|
||||||
|
|
||||||
|
If set to 1 then the CWD is changed when the NERD tree is first loaded to the
|
||||||
|
directory it is initialized in. For example, if you start the NERD tree with >
|
||||||
|
:NERDTree /home/marty/foobar
|
||||||
|
<
|
||||||
|
then the CWD will be changed to /home/marty/foobar and will not be changed
|
||||||
|
again unless you init another NERD tree with a similar command.
|
||||||
|
|
||||||
|
If the option is set to 2 then it behaves the same as if set to 1 except that
|
||||||
|
the CWD is changed whenever the tree root is changed. For example, if the CWD
|
||||||
|
is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new
|
||||||
|
root then the CWD will become /home/marty/foobar/baz.
|
||||||
|
|
||||||
|
Note to windows users: it is highly recommended that you have this option set
|
||||||
|
to either 1 or 2 or else the script wont function properly if you attempt to
|
||||||
|
open a NERD tree on a different drive to the one vim is currently in.
|
||||||
|
|
||||||
|
Authors note: at work i have this option set to 1 because i have a giant ctags
|
||||||
|
file in the root dir of my project. This way i can initialise the NERD tree
|
||||||
|
with the root dir of my project and always have ctags available to me --- no
|
||||||
|
matter where i go with the NERD tree.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeHighlightCursorline*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
If set to 1, the current cursor line in the NERD tree buffer will be
|
||||||
|
highlighted. This is done using the |cursorline| option.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeIgnore*
|
||||||
|
Values: a list of regular expressions.
|
||||||
|
Default: ['\~$'].
|
||||||
|
|
||||||
|
This option is used to specify which files the NERD tree should ignore. It
|
||||||
|
must be a list of regular expressions. When the NERD tree is rendered, any
|
||||||
|
files/dirs that match any of the regex's in NERDTreeIgnore wont be displayed.
|
||||||
|
|
||||||
|
For example if you put the following line in your vimrc: >
|
||||||
|
let NERDTreeIgnore=['\.vim$', '\~$']
|
||||||
|
<
|
||||||
|
then all files ending in .vim or ~ will be ignored.
|
||||||
|
|
||||||
|
Note: to tell the NERD tree not to ignore any files you must use the following
|
||||||
|
line: >
|
||||||
|
let NERDTreeIgnore=[]
|
||||||
|
<
|
||||||
|
|
||||||
|
The file filters can be turned on and off dynamically with the |NERDTree-f|
|
||||||
|
mapping.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeMouseMode*
|
||||||
|
Values: 1, 2 or 3.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
If set to 1 then a double click on a node is required to open it.
|
||||||
|
If set to 2 then a single click will open directory nodes, while a double
|
||||||
|
click will still be required for file nodes.
|
||||||
|
If set to 3 then a single click will open any node.
|
||||||
|
|
||||||
|
Note: a double click anywhere on a line that a tree node is on will
|
||||||
|
activate it, but all single-click activations must be done on name of the node
|
||||||
|
itself. For example, if you have the following node: >
|
||||||
|
| | |-application.rb
|
||||||
|
<
|
||||||
|
then (to single click activate it) you must click somewhere in
|
||||||
|
'application.rb'.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeShowFiles*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
If this option is set to 1 then files are displayed in the NERD tree. If it is
|
||||||
|
set to 0 then only directories are displayed.
|
||||||
|
|
||||||
|
This option can be toggled dynamically with the |NERDTree-F| mapping and is
|
||||||
|
useful for drastically shrinking the tree when you are navigating to a
|
||||||
|
different part of the tree.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeShowHidden*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 0.
|
||||||
|
|
||||||
|
This option tells vim whether to display hidden files by default. This option
|
||||||
|
can be dynamically toggled with the |NERDTree-H| mapping.
|
||||||
|
Use one of the follow lines to set this option: >
|
||||||
|
let NERDTreeShowHidden=0
|
||||||
|
let NERDTreeShowHidden=1
|
||||||
|
<
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeSortOrder*
|
||||||
|
Values: a list of regular expressions.
|
||||||
|
Default: ['\/$', '*', '\.swp$', '\.bak$', '\~$']
|
||||||
|
|
||||||
|
This option is set to a list of regular expressions which are used to
|
||||||
|
specify the order of nodes under their parent.
|
||||||
|
|
||||||
|
For example, if the option is set to: >
|
||||||
|
['\.vim$', '\.c$', '\.h$', '*', 'foobar']
|
||||||
|
<
|
||||||
|
then all .vim files will be placed at the top, followed by all .c files then
|
||||||
|
all .h files. All files containing the string 'foobar' will be placed at the
|
||||||
|
end. The star is a special flag: it tells the script that every node that
|
||||||
|
doesnt match any of the other regexps should be placed here.
|
||||||
|
|
||||||
|
If no star is present in NERDTreeSortOrder then one is automatically appended
|
||||||
|
to the array.
|
||||||
|
|
||||||
|
The regex '\/$' should be used to match directory nodes.
|
||||||
|
|
||||||
|
After this sorting is done, the files in each group are sorted alphabetically.
|
||||||
|
|
||||||
|
Other examples: >
|
||||||
|
(1) ['*', '\/$']
|
||||||
|
(2) []
|
||||||
|
(3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$']
|
||||||
|
<
|
||||||
|
1. Directories will appear last, everything else will appear above.
|
||||||
|
2. Every will simply appear in alphabetical order.
|
||||||
|
3. Dirs will appear first, then ruby and php. Swap files, bak files and vim
|
||||||
|
backup files will appear last with everything else preceding them.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeSplitVertical*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
This option, along with |NERDTreeWinPos|, is used to determine where the NERD
|
||||||
|
tree window appears.
|
||||||
|
|
||||||
|
If it is set to 1 then the NERD tree window will appear on either the left or
|
||||||
|
right side of the screen (depending on the |NERDTreeWinPos| option).
|
||||||
|
|
||||||
|
If it set to 0 then the NERD tree window will appear at the top of the screen.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeWinPos*
|
||||||
|
Values: 0 or 1.
|
||||||
|
Default: 1.
|
||||||
|
|
||||||
|
This option works in conjunction with the |NERDTreeSplitVertical| option to
|
||||||
|
determine where NERD tree window is placed on the screen.
|
||||||
|
|
||||||
|
If the option is set to 1 then the NERD tree will appear on the left or top of
|
||||||
|
the screen (depending on the value of |NERDTreeSplitVertical|). If set to 0,
|
||||||
|
the window will appear on the right or bottom of the screen.
|
||||||
|
|
||||||
|
This option is makes it possible to use two different explorer type
|
||||||
|
plugins simultaneously. For example, you could have the taglist plugin on the
|
||||||
|
left of the window and the NERD tree on the right.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*NERDTreeWinSize*
|
||||||
|
Values: a positive integer.
|
||||||
|
Default: 31.
|
||||||
|
|
||||||
|
This option is used to change the size of the NERD tree when it is loaded.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
*NERDTreePublicFunctions*
|
||||||
|
5. Public functions ~
|
||||||
|
|
||||||
|
The script provides 2 public functions for your hacking pleasure. Their
|
||||||
|
signatures are: >
|
||||||
|
function! NERDTreeGetCurrentNode()
|
||||||
|
function! NERDTreeGetCurrentPath()
|
||||||
|
<
|
||||||
|
The first returns the node object that the cursor is currently on, while the
|
||||||
|
second returns the corresponding path object.
|
||||||
|
|
||||||
|
This is probably a good time to mention that the script implements prototype
|
||||||
|
style OO. To see the functions that each class provides you can read look at
|
||||||
|
the code.
|
||||||
|
|
||||||
|
Use the node objects to manipulate the structure of the tree. Use the path
|
||||||
|
objects to access the data the tree represents and to make changes to the
|
||||||
|
filesystem.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
5. TODO list *NERDTreeTodo*
|
||||||
|
|
||||||
|
Window manager integration?
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
6. The Author *NERDTreeAuthor*
|
||||||
|
|
||||||
|
The author of the NERD tree is a terrible terrible monster called Martyzilla
|
||||||
|
who gobbles up small children with milk and sugar for breakfast. He has an odd
|
||||||
|
love/hate relationship with computers (but monsters hate everything by nature
|
||||||
|
you know...) which can be awkward for him since he is a pro computer nerd for
|
||||||
|
a living.
|
||||||
|
|
||||||
|
He can be reached at martin_grenfell at msn.com. He would love to hear from
|
||||||
|
you, so feel free to send him suggestions and/or comments about this plugin.
|
||||||
|
Don't be shy --- the worst he can do is slaughter you and stuff you in the
|
||||||
|
fridge for later ;)
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
7. Changelog *NERDTreeChangelog*
|
||||||
|
|
||||||
|
2.7.1
|
||||||
|
- Changed the keys for the filesystem menu to be mnemonic rather than
|
||||||
|
arbitrary integers
|
||||||
|
- Documented the copying functionality in the filesystem menu
|
||||||
|
|
||||||
|
2.7.0
|
||||||
|
- Bug fix: Now when you have the tree on the right and you open it with
|
||||||
|
multiple windows stacked, it will take up the full height of the vim
|
||||||
|
window.
|
||||||
|
- Now line numbers always turned off in the tree by default
|
||||||
|
- Implemented copying of nodes (via the filesystem menu) for *nix/macosx
|
||||||
|
- took the help doc out of the script and repackaged the whole thing as a
|
||||||
|
zip
|
||||||
|
|
||||||
|
2.6.2
|
||||||
|
- Now when you try to open a file node into a window that is modified, the
|
||||||
|
window is not split if the &hidden option is set. Thanks to Niels Aan
|
||||||
|
de Brugh for this suggestion.
|
||||||
|
|
||||||
|
2.6.1
|
||||||
|
- Fixed a major bug with the <tab> mapping. Thanks to Zhang Weiwu for
|
||||||
|
emailing me.
|
||||||
|
|
||||||
|
2.6.0
|
||||||
|
- Extended the behaviour of <c-j/k>. Now if the cursor is on a file node
|
||||||
|
and you use <c-j/k> the cursor will jump to its PARENTS next/previous
|
||||||
|
sibling. Go :help NERDTree-c-j and :help NERDTree-c-k for info.
|
||||||
|
- Extended the behaviour of the J/K mappings. Now if the cursor is on the
|
||||||
|
last child of a node and you push J/K it will jump down to the last child
|
||||||
|
of the next/prev of its parents siblings that is open and has children.
|
||||||
|
Go :help NERDTree-J and :help NERDTree-K for info.
|
||||||
|
- The goal of these changes is to make tree navigation faster.
|
||||||
|
- Reorganised the help page a bit.
|
||||||
|
- Removed the E mapping.
|
||||||
|
- bugfixes
|
||||||
|
|
||||||
|
2.5.0
|
||||||
|
- Added an option to enforce case sensitivity when sorting tree nodes.
|
||||||
|
Read :help NERDTreeCaseSensitiveSort for details. (thanks to Michael
|
||||||
|
Madsen for emailing me about this). Case sensitivity defaults to off.
|
||||||
|
- Made the script echo a "please wait" style message when opening large
|
||||||
|
directories. Thanks to AOYAMA Shotaro for this suggestion.
|
||||||
|
- Added 2 public functions that can be used to retrieve the treenode and
|
||||||
|
path that the cursor is on. Read :help NERDTreePublicFunctions for
|
||||||
|
details (thanks again to AOYAMA Shotaro for the idea :).
|
||||||
|
- added 2 new mappings for file nodes: "g<tab>" and "go". These are the
|
||||||
|
same as the "<tab>" and "o" maps except that the cursor stays in the
|
||||||
|
NERDTree. Note: these maps are slaved to the o and <tab> mappings, so if
|
||||||
|
eg you remap "<tab>" to "i" then the "g<tab>" map will also be changed
|
||||||
|
to "gi".
|
||||||
|
- Renamed many of the help tags to be simpler.
|
||||||
|
- Simplified the ascii "graphics" for the filesystem menu
|
||||||
|
- Fixed bugs.
|
||||||
|
- Probably created bugs.
|
||||||
|
- Refactoring.
|
||||||
|
|
||||||
|
2.4.0
|
||||||
|
- Added the P mapping to jump to the tree root.
|
||||||
|
- Added window centering functionality that can be triggered when doing
|
||||||
|
using any of the tree nav mappings. Essentially, if the cursor comes
|
||||||
|
within a certain distance of the top/bottom of the window then a zz is
|
||||||
|
done in the window. Two related options were added: NERDTreeAutoCenter
|
||||||
|
to turn this functionality on/off, and NERDTreeAutoCenterThreshold to
|
||||||
|
control how close the cursor has to be to the window edge to trigger the
|
||||||
|
centering.
|
||||||
|
|
||||||
|
2.3.0
|
||||||
|
- Tree navigation changes:
|
||||||
|
- Added J and K mappings to jump to last/first child of the current dir.
|
||||||
|
Options to customise these mappings have also been added.
|
||||||
|
- Remapped the jump to next/prev sibling commands to be <C-j> and <C-k> by
|
||||||
|
default.
|
||||||
|
These changes should hopefully make tree navigation mappings easier to
|
||||||
|
remember and use as the j and k keys are simply reused 3 times (twice
|
||||||
|
with modifier keys).
|
||||||
|
|
||||||
|
- Made it so that, when any of the tree filters are toggled, the cursor
|
||||||
|
stays with the selected node (or goes to its parent/grandparent/... if
|
||||||
|
that node is no longer visible)
|
||||||
|
- Fixed an error in the doc for the mouse mode option.
|
||||||
|
- Made the quickhelp correctly display the current single/double click
|
||||||
|
mappings for opening nodes as specified by the NERDTreeMouseMode option.
|
||||||
|
- Fixed a bug where the script was spazzing after prompting you to delete
|
||||||
|
a modified buffer when using the filesystem menu.
|
||||||
|
- Refactoring
|
||||||
|
2.2.3
|
||||||
|
- Refactored the :echo output from the script.
|
||||||
|
- Fixed some minor typos in the doc.
|
||||||
|
- Made some minor changes to the output of the 'Tree filtering mappings'
|
||||||
|
part of the quickhelp
|
||||||
|
|
||||||
|
2.2.2
|
||||||
|
- More bugfixes... doh.
|
||||||
|
|
||||||
|
2.2.1
|
||||||
|
- Bug fix that was causing an exception when closing the nerd tree. Thanks
|
||||||
|
to Tim carey-smith and Yu Jun for pointing this out.
|
||||||
|
|
||||||
|
2.2.0
|
||||||
|
- Now 'cursorline' is set in the NERD tree buffer by default. See :help
|
||||||
|
NERDTreeHighlightCursorline for how to disable it.
|
||||||
|
|
||||||
|
2.1.2
|
||||||
|
- Stopped the script from clobbering the 1,2,3 .. 9 registers.
|
||||||
|
- Made it "silent!"ly delete buffers when renaming/deleting file nodes.
|
||||||
|
- Minor correction to the doc
|
||||||
|
- Fixed a bug when refreshing that was occurring when the node you
|
||||||
|
refreshed had been deleted externally.
|
||||||
|
- Fixed a bug that was occurring when you open a file that is already open
|
||||||
|
and modified.
|
||||||
|
|
||||||
|
2.1.1
|
||||||
|
- Added a bit more info about the buffers you are prompted to delete when
|
||||||
|
renaming/deleting nodes from the filesystem menu that are already loaded
|
||||||
|
into buffers.
|
||||||
|
- Refactoring and bugfixes
|
||||||
|
|
||||||
|
2.1.0
|
||||||
|
- Finally removed the blank line that always appears at the top of the
|
||||||
|
NERDTree buffer
|
||||||
|
- Added NERDTreeMouseMode option. If set to 1, then a double click is
|
||||||
|
required to activate all nodes, if set to 2 then a single click will
|
||||||
|
activate directory nodes, if set to 3 then a single click will activate
|
||||||
|
all nodes.
|
||||||
|
- Now if you delete a file node and have it open in a buffer you are given
|
||||||
|
the option to delete that buffer as well. Similarly if you rename a file
|
||||||
|
you are given the option to delete any buffers containing the old file
|
||||||
|
(if any exist)
|
||||||
|
- When you rename or create a node, the cursor is now put on the new node,
|
||||||
|
this makes it easy immediately edit the new file.
|
||||||
|
- Fixed a bug with the ! mapping that was occurring on windows with paths
|
||||||
|
containing spaces.
|
||||||
|
- Made all the mappings customisable. See |NERD_tree-mappings| for
|
||||||
|
details. A side effect is that a lot of the "double mappings" have
|
||||||
|
disappeared. E.g 'o' is now the key that is used to activate a node,
|
||||||
|
<CR> is no longer mapped to the same.
|
||||||
|
- Made the script echo warnings in some places rather than standard echos
|
||||||
|
- Insane amounts of refactoring all over the place.
|
||||||
|
|
||||||
|
2.0.0
|
||||||
|
- Added two new NERDChristmasTree decorations. First person to spot them
|
||||||
|
and email me gets a free copy of the NERDTree.
|
||||||
|
- Made it so that when you jump around the tree (with the p, s and S
|
||||||
|
mappings) it is counted as a jump by vim. This means if you, eg, push
|
||||||
|
'p' one too many times then you can go `` or ctrl-o.
|
||||||
|
- Added a new option called NERDTreeSortOrder which takes an array of
|
||||||
|
regexs and is used to determine the order that the treenodes are listed
|
||||||
|
in. Go :help NERDTreeSortOrder for details.
|
||||||
|
- Removed the NERDTreeSortDirs option because it is consumed by
|
||||||
|
NERDTreeSortOrder
|
||||||
|
- Added the 'i' mapping which is the same as <tab> but requires less
|
||||||
|
effort to reach.
|
||||||
|
- Added the ! mapping which is used to execute file in the tree (after it
|
||||||
|
prompts you for arguments etc)
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
8. Credits *NERDTreeCredits*
|
||||||
|
|
||||||
|
Thanks to Tim Carey-Smith for testing/using the NERD tree from the first
|
||||||
|
pre-beta version, for his many suggestions and for his constant stream of bug
|
||||||
|
complaints.
|
||||||
|
|
||||||
|
Thanks to Vigil for trying it out before the first release :) and suggesting
|
||||||
|
that mappings to open files in new tabs should be implemented.
|
||||||
|
|
||||||
|
Thanks to Nick Brettell for testing, fixing my spelling and suggesting i put a
|
||||||
|
.. (up a directory)
|
||||||
|
line in the gui.
|
||||||
|
|
||||||
|
Thanks to Thomas Scott Urban - the author of the vtreeexplorer plugin - whose
|
||||||
|
gui code i borrowed from.
|
||||||
|
|
||||||
|
Thanks to Terrance Cohen for pointing out a bug where the script was changing
|
||||||
|
vims CWD all over the show.
|
||||||
|
|
||||||
|
Thanks to Yegappan Lakshmanan (author of Taglist and other orgasmically
|
||||||
|
wonderful plugins) for telling me how to fix a bug that was causing vim to go
|
||||||
|
into visual mode everytime you double clicked a node :)
|
||||||
|
|
||||||
|
Thanks to Jason Mills for sending me a fix that allows windows paths to use
|
||||||
|
forward slashes as well as backward.
|
||||||
|
|
||||||
|
Thanks to Michael Geddes (frogonwheels on #vim at freenode) for giving me some
|
||||||
|
tips about syntax highlighting when i was doing highlighting for the
|
||||||
|
quickhelp.
|
||||||
|
|
||||||
|
Thanks to Yu Jun for emailing me about a bug that was occurring when closing
|
||||||
|
the tree.
|
||||||
|
|
||||||
|
Thanks to Michael Madsen for emailing me about making case sensitivity
|
||||||
|
optional when sorting nodes.
|
||||||
|
|
||||||
|
Thanks to AOYAMA Shotaro for suggesting that i echo a "please wait" message
|
||||||
|
when opening large directories.
|
||||||
|
|
||||||
|
Thanks to Michael Madsen for requesting the NERDTreeCaseSensitiveSort option.
|
||||||
|
|
||||||
|
Thanks to AOYAMA Shotaro for suggesting that a "please wait" style message be
|
||||||
|
echoed when opening large directories. Also, thanks for the suggestion of
|
||||||
|
having public functions in the script to access the internal data :D
|
||||||
|
|
||||||
|
Thanks to Zhang Weiwu for emailing me about a bug with the the <tab> mapping
|
||||||
|
in 2.6.0
|
||||||
|
|
||||||
|
Thanks to Niels Aan de Brugh for the suggestion that the script now split the
|
||||||
|
window if you try to open a file in a window containing a modified buffer when
|
||||||
|
the &hidden option is set.
|
1078
.vim/doc/omnicppcomplete.txt
Normal file
1078
.vim/doc/omnicppcomplete.txt
Normal file
File diff suppressed because it is too large
Load Diff
710
.vim/doc/project.txt
Normal file
710
.vim/doc/project.txt
Normal file
@ -0,0 +1,710 @@
|
|||||||
|
*project.txt* Plugin for managing multiple projects with multiple sources
|
||||||
|
For Vim version 6.x and Vim version 7.x.
|
||||||
|
Last Change: Fri 13 Oct 2006 10:20:13 AM EDT
|
||||||
|
|
||||||
|
|
||||||
|
By Aric Blumer
|
||||||
|
aricvim email-at-sign charter.net
|
||||||
|
|
||||||
|
*project* *project-plugin*
|
||||||
|
Contents:
|
||||||
|
|
||||||
|
Commands...................|project-invoking|
|
||||||
|
Inheritance.............|project-inheritance|
|
||||||
|
Mappings...................|project-mappings|
|
||||||
|
Adding Mappings.....|project-adding-mappings|
|
||||||
|
Settings...................|project-settings|
|
||||||
|
Example File................|project-example|
|
||||||
|
Tips...........................|project-tips|
|
||||||
|
|
||||||
|
|
||||||
|
You can use this plugin's basic functionality to set up a list of
|
||||||
|
frequently-accessed files for easy navigation. The list of files will be
|
||||||
|
displayed in a window on the left side of the Vim window, and you can press
|
||||||
|
<Return> or double-click on filenames in the list to open the files. I find
|
||||||
|
this easier to use than having to navigate a directory hierarchy with the
|
||||||
|
|file-explorer|.
|
||||||
|
|
||||||
|
You can also instruct the Plugin to change to a directory and to run Vim
|
||||||
|
scripts when you select a file. These scripts can, for example, modify the
|
||||||
|
environment to include compilers in $PATH. This makes it very easy to use
|
||||||
|
quickfix with multiple projects that use different environments.
|
||||||
|
|
||||||
|
Other features include:
|
||||||
|
o Loading/Unloading all the files in a Project (\l, \L, \w, and \W)
|
||||||
|
o Grepping all the files in a Project (\g and \G)
|
||||||
|
o Running a user-specified script on a file (can be used to launch an
|
||||||
|
external program on the file) (\1 through \9)
|
||||||
|
o Running a user-specified script on all the files in a Project
|
||||||
|
(\f1-\f9 and \F1-\F9)
|
||||||
|
o High degree of user-configurability
|
||||||
|
o Also works with |netrw| using the XXXX://... notation where XXXX is
|
||||||
|
ftp, rcp, scp, or http.
|
||||||
|
|
||||||
|
All of this is specified within a simple text file and a few global variables
|
||||||
|
in your vimrc file.
|
||||||
|
|
||||||
|
You must set 'nocompatible' in your |vimrc| file to use this plugin. You can
|
||||||
|
stop the plugin from being loaded by setting the "loaded_project" variable: >
|
||||||
|
:let loaded_project = 1
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
COMMANDS *project-invoking*
|
||||||
|
|
||||||
|
You can use the plugin by placing it in your plugin directory (e.g.,
|
||||||
|
~/.vim/plugin). See |add-global-plugin|. When you start vim the next time, you
|
||||||
|
then enter the command >
|
||||||
|
:Project
|
||||||
|
or >
|
||||||
|
:Project {file}
|
||||||
|
|
||||||
|
If you do not specify the filename, $HOME/.vimprojects is used.
|
||||||
|
|
||||||
|
To have Vim come up with the Project Window enabled automatically (say, from a
|
||||||
|
GUI launcher), run Vim like this: [g]vim +Project
|
||||||
|
|
||||||
|
Note that you can invoke :Project on only one file at a time. If you wish to
|
||||||
|
change the Project File, do a :bwipe in the Project Buffer, then re-invoke the
|
||||||
|
Plugin as described above.
|
||||||
|
|
||||||
|
Several Projects can be kept and displayed in the same file, each in a fold
|
||||||
|
delimited by { and } (see |fold.txt|). There can be any number of nested
|
||||||
|
folds to provide you with a Project hierarchy. Any line without a { or a } in
|
||||||
|
the file is considered to be a filename. Blank lines are ignored, and any
|
||||||
|
text after a # is ignored.
|
||||||
|
|
||||||
|
Because the plugin uses standard Vim folds, you can use any of the
|
||||||
|
|fold-commands|. You can double-click on the first line of a fold to open and
|
||||||
|
close it. You can select a file to open by putting the cursor on its name and
|
||||||
|
pressing <Return> or by double-clicking on it. The plugin will create a new
|
||||||
|
window to the right or use the |CTRL-W_p| equivalent if it exists.
|
||||||
|
|
||||||
|
*project-syntax*
|
||||||
|
Each Project Entry has this form:
|
||||||
|
|
||||||
|
project_entry ::=
|
||||||
|
<Description>={projpath} [{options}] {
|
||||||
|
[ filename ]
|
||||||
|
[ project_entry ]
|
||||||
|
}
|
||||||
|
|
||||||
|
{options} is one or more of the following (on the same line):
|
||||||
|
CD={path}
|
||||||
|
in={filename}
|
||||||
|
out={filename}
|
||||||
|
filter="{pat}"
|
||||||
|
flags={flag}
|
||||||
|
|
||||||
|
Note that a project_entry can reside within a project_entry. This allows you
|
||||||
|
to set up a hierarchy within your Project.
|
||||||
|
|
||||||
|
The <Description> will be displayed in the foldtext and cannot contain "=".
|
||||||
|
There can be no space character directly on either side of the =.
|
||||||
|
|
||||||
|
The {projpath} is the path in which the files listed in the Project's fold
|
||||||
|
will be found, and it may contain environment variables. If the path is a
|
||||||
|
relative path, then the plugin constructs the whole path from the Project's
|
||||||
|
parent, grandparent, etc., all the way up the hierarchy. An outermost
|
||||||
|
project_entry must have an absolute path. See the |project-inheritance|
|
||||||
|
example below. {projpath} may contain spaces, but they must be escaped like
|
||||||
|
normal Vim escapes. Here are two examples of the same directory:
|
||||||
|
>
|
||||||
|
Example=/my/directory/with\ spaces {
|
||||||
|
}
|
||||||
|
Example="/my/directory/with spaces" {
|
||||||
|
}
|
||||||
|
|
||||||
|
I recommend this for Windows®: >
|
||||||
|
|
||||||
|
Example="c:\My Documents" {
|
||||||
|
}
|
||||||
|
|
||||||
|
But Vim is smart enough to do this, too: >
|
||||||
|
|
||||||
|
Example=c:\My\ Documents {
|
||||||
|
}
|
||||||
|
|
||||||
|
CD= provides the directory that Vim will change to when you select a file in
|
||||||
|
that fold (using |:cd|). This allows you, for example, to enter |:make| to use
|
||||||
|
the local Makefile. A CD=. means that Vim will make {projpath} or its
|
||||||
|
inherited equivalent the current working directory. When CD is omitted, the
|
||||||
|
directory is not changed. There can be no space on either side of the =. The
|
||||||
|
value of CD can also be a relative path from a parent's CD. See the
|
||||||
|
|project-inheritance| example below. This directive is ignored for |netrw|
|
||||||
|
projects. Spaces are allowed in the path as for {projpath}.
|
||||||
|
|
||||||
|
in= and out= provide the means to run arbitrary Vim scripts whenever you enter
|
||||||
|
or leave a file's buffer (see the |BufEnter| and |BufLeave| autocommand
|
||||||
|
events). The idea is to have a Vim script that sets up or tears down the
|
||||||
|
environment for the Project like this:
|
||||||
|
|
||||||
|
in.vim: >
|
||||||
|
let $PROJECT_HOME='~/my_project'
|
||||||
|
" Put the compiler in $PATH
|
||||||
|
if $PATH !~ '/path/to/my/compiler'
|
||||||
|
let $PATH=$PATH.':/path/to/my/compiler'
|
||||||
|
endif
|
||||||
|
|
||||||
|
out.vim: >
|
||||||
|
" Remove compiler from $PATH
|
||||||
|
if $PATH =~ '/path/to/my/compiler'
|
||||||
|
let $PATH=substitute($PATH, ':/path/to/my/compiler', '', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
Then you can use :make with the proper environment depending on what file you
|
||||||
|
are currently editing. If the path to the script is relative, then it is
|
||||||
|
relative from {projpath}. These directives are inherited by Subprojects
|
||||||
|
unless the Subproject specifies its own. For use with |netrw| projects, the
|
||||||
|
paths specified for in= and out= must be absolute and local.
|
||||||
|
|
||||||
|
filter= specifies a |glob()| file pattern. It is used to regenerate the list
|
||||||
|
of files in a Project fold when using the \r (<LocalLeader>r) map in the
|
||||||
|
Project Window. The filter value must be in quotes because it can contain
|
||||||
|
multiple file patterns. If filter is omitted, then the * pattern is used.
|
||||||
|
There can be no space on either side of the =. A Subproject will inherit the
|
||||||
|
filter of its parent unless it specifies its own filter.
|
||||||
|
|
||||||
|
flags= provides the means to enable/disable features for a particular fold.
|
||||||
|
The general mnemonic scheme is for lower case to turn something off and upper
|
||||||
|
case to turn something on. {flag} can contain any of the following
|
||||||
|
characters:
|
||||||
|
|
||||||
|
flag Description ~
|
||||||
|
|
||||||
|
l Turn off recursion for this fold for \L. Subfolds are also
|
||||||
|
blocked from the recursion.
|
||||||
|
|
||||||
|
r Turn off refresh. When present, do not refresh this fold when
|
||||||
|
\r or \R is used. This does not affect subfold recursion.
|
||||||
|
|
||||||
|
S Turn on sorting for refresh and create.
|
||||||
|
|
||||||
|
s Turn off sorting for refresh and create.
|
||||||
|
|
||||||
|
T Turn on top gravity. Forces folds to the top of the current
|
||||||
|
fold when refreshing. It has the same affect as the 'T' flag
|
||||||
|
in g:proj_flags, but controls the feature on a per-fold basis.
|
||||||
|
|
||||||
|
t Turn off top gravity. Forces folds to the bottom of the
|
||||||
|
current fold when refreshing.
|
||||||
|
|
||||||
|
w Turn off recursion for this fold for \W. Subfolds are also
|
||||||
|
blocked from the recursion.
|
||||||
|
|
||||||
|
|
||||||
|
Flags are not inherited by Subprojects.
|
||||||
|
|
||||||
|
Any text outside a fold is ignored.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
INHERITANCE *project-inheritance*
|
||||||
|
|
||||||
|
It's best to show inheritance by comparing these two Project Files:
|
||||||
|
>
|
||||||
|
Parent=~/my_project CD=. filter="Make* *.mk" flags=r {
|
||||||
|
Child1=c_code {
|
||||||
|
}
|
||||||
|
Child2=include CD=. filter="*.h" {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Child1's path is "~/my_project/c_code" because ~/my_project is inherited. It
|
||||||
|
also inherits the CD from Parent. Since Parent has CD=., the Parent's cwd is
|
||||||
|
"~/my_project". Child1 therefore inherits a CD of "~/my_project". Finally,
|
||||||
|
Child1 inherits the filter from Parent. The flags are not inherited.
|
||||||
|
|
||||||
|
Child2 only inherits the "~/my_project" from Parent.
|
||||||
|
|
||||||
|
Thus, the example above is exactly equivalent to this:
|
||||||
|
>
|
||||||
|
Parent=~/my_project CD=. filter="Make* *.mk" flags=r {
|
||||||
|
Child1=~/my_project/c_code CD=~/my_project filter="Make* *.mk" {
|
||||||
|
}
|
||||||
|
Child2=~/my_project/include CD=~/my_project/include filter="*.h" {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(For a real Project, Child1 would not want to inherit its parent's filter, but
|
||||||
|
this example shows the concept.) You can always enter \i to display what the
|
||||||
|
cursor's project inherits.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
MAPPINGS *project-mappings*
|
||||||
|
|
||||||
|
Map Action ~
|
||||||
|
|
||||||
|
\r Refreshes the Project fold that the cursor is in by placing in the
|
||||||
|
fold all the files that match the filter. The Project is refreshed
|
||||||
|
using an indent of one space for every foldlevel in the hierarchy.
|
||||||
|
|
||||||
|
You may place a "# pragma keep" (without the quotes) at the end of a
|
||||||
|
line, and the file entry on that line will not be removed when you
|
||||||
|
refresh. This is useful, for example, when you have . as an entry so
|
||||||
|
you can easily browse the directory.
|
||||||
|
|
||||||
|
Note that this mapping is actually <LocalLeader>r, and the default of
|
||||||
|
|<LocalLeader>| is \.
|
||||||
|
|
||||||
|
This does not work for Projects using |netrw|.
|
||||||
|
|
||||||
|
\R Executes \r recursively in the current fold and all folds below.
|
||||||
|
This does not work for Projects using |netrw|.
|
||||||
|
|
||||||
|
\c Creates a Project fold entry. It asks for the description, the path
|
||||||
|
to the files, the CD parameter, and the filename |glob()| pattern.
|
||||||
|
From this information, it will create the Project Entry below the
|
||||||
|
cursor.
|
||||||
|
|
||||||
|
This does not work for Projects using |netrw|.
|
||||||
|
|
||||||
|
\C Creates a Project fold entry like \c, but recursively includes all the
|
||||||
|
subdirectories.
|
||||||
|
|
||||||
|
<Return>
|
||||||
|
Select a file to open in the |CTRL-W_p| window or in a new window. If
|
||||||
|
the cursor is on a fold, open or close it.
|
||||||
|
|
||||||
|
<S-Return>
|
||||||
|
\s
|
||||||
|
Same as <Return> but horizontally split the target window.
|
||||||
|
<LocalLeader>s is provided for those terminals that don't recognize
|
||||||
|
<S-Return>.
|
||||||
|
|
||||||
|
\S
|
||||||
|
Load all files in a project by doing horizontal splits.
|
||||||
|
|
||||||
|
<C-Return>
|
||||||
|
\o
|
||||||
|
Same as <Return> but ensure that the opened file is the only other
|
||||||
|
window. <LocalLeader>o is provided for those terminals that don't
|
||||||
|
recognize <C-Return>.
|
||||||
|
|
||||||
|
<M-Return>
|
||||||
|
\v
|
||||||
|
Same as <Return> but only display the file--the cursor stays in the
|
||||||
|
Project Window.
|
||||||
|
|
||||||
|
<2-LeftMouse>
|
||||||
|
(Double-click) If on a closed fold, open it. If on an open fold
|
||||||
|
boundary, close it. If on a filename, open the file in the |CTRL-W_p|
|
||||||
|
window or in a new window.
|
||||||
|
|
||||||
|
<S-2-LeftMouse>
|
||||||
|
Same as <S-Return>.
|
||||||
|
|
||||||
|
<C-2-LeftMouse>
|
||||||
|
Same as <C-Return>.
|
||||||
|
|
||||||
|
<RightMouse>
|
||||||
|
Increase the width of the Project Window by g:proj_window_increment or
|
||||||
|
toggle between a width of
|
||||||
|
g:proj_window_width + g:proj_window_increment
|
||||||
|
and
|
||||||
|
g:proj_window_width.
|
||||||
|
|
||||||
|
Whether you toggle or monotonically increase the width is determined
|
||||||
|
by the 't' flag of the g:proj_flags variable (see |project-flags|).
|
||||||
|
|
||||||
|
Note that a Right Mouse click will not automatically place the cursor
|
||||||
|
in the Project Window if it is in a different window. The window will
|
||||||
|
go back to the g:proj_window_width width when you leave the window.
|
||||||
|
|
||||||
|
<space> Same as <RightMouse>
|
||||||
|
|
||||||
|
<CTRL-Up>
|
||||||
|
\<Up>
|
||||||
|
Move the text or fold under the cursor up one row. This may not work
|
||||||
|
in a terminal because the terminal is unaware of this key combination.
|
||||||
|
<LocalLeader><Up> is provided for those terminals that don't recognize
|
||||||
|
<C-Up>.
|
||||||
|
|
||||||
|
|
||||||
|
<CTRL-Down>
|
||||||
|
\<Down>
|
||||||
|
Move the text or fold under the cursor down one row. This may not work
|
||||||
|
in a terminal because the terminal is unaware of this key combination.
|
||||||
|
<LocalLeader><Down> is provided for those terminals that don't
|
||||||
|
recognize <C-Down>.
|
||||||
|
|
||||||
|
\i Show in the status line the completely resolved and inherited
|
||||||
|
parameters for the fold the cursor is in. This is intended for
|
||||||
|
debugging your relative path and inherited parameters for manually
|
||||||
|
entered Projects.
|
||||||
|
|
||||||
|
\I Show in the status line the completely resolved filename. Uses the
|
||||||
|
Project_GetFname(line('.')) function.
|
||||||
|
|
||||||
|
\1 - \9
|
||||||
|
Run the command specified in g:proj_run{x} where {x} is the number
|
||||||
|
of the key. See the documentation of g:proj_run1 below.
|
||||||
|
|
||||||
|
\f1-\f9
|
||||||
|
Run the command specified in g:proj_run_fold{x} where {x} is the
|
||||||
|
number of the key. The command is run on the files at the current
|
||||||
|
Project level. See the |project-settings| below.
|
||||||
|
|
||||||
|
\F1-\F9
|
||||||
|
Run the command specified in g:proj_run_fold{x} where {x} is the
|
||||||
|
number of the key. The command is run on the files at the current
|
||||||
|
Project level and all Subprojects. See the |project-settings| below.
|
||||||
|
|
||||||
|
\0 Display the commands that are defined for \1 through \9.
|
||||||
|
|
||||||
|
\f0 Display the commands that are defined for \f1 through \f9 and \F1
|
||||||
|
through \F0. Same as \F0.
|
||||||
|
|
||||||
|
\l Load all the files in the current Project level into Vim. While files
|
||||||
|
are being loaded, you may press any key to stop.
|
||||||
|
|
||||||
|
\L Load all the files in the current Project and all Subprojects into
|
||||||
|
Vim. Use this mapping with caution--I wouldn't suggest using \L to
|
||||||
|
load a Project with thousands of files. (BTW, my Project file has more
|
||||||
|
than 5,300 files in it!) While files are being loaded, you may press
|
||||||
|
any key to stop.
|
||||||
|
|
||||||
|
\w Wipe all the files in the current Project level from Vim. (If files
|
||||||
|
are modified, they will be saved first.) While files are being wiped,
|
||||||
|
you may press any key to stop.
|
||||||
|
|
||||||
|
\W Wipe all the files in the current Project and all Subprojects from
|
||||||
|
Vim. (If files are modified, they will be saved first.) While files
|
||||||
|
are being wiped, you may press any key to stop.
|
||||||
|
|
||||||
|
\g Grep all the files in the current Project level.
|
||||||
|
|
||||||
|
\G Grep all the files in the current Project level and all Subprojects.
|
||||||
|
|
||||||
|
\e Set up the Environment for the Project File as though you had selected
|
||||||
|
it with <Return>. This allows you to do a \e and a :make without
|
||||||
|
having to open any files in the project.
|
||||||
|
|
||||||
|
\E Explore (using |file-explorer|) the directory of the project the
|
||||||
|
cursor is in. Does not work with netrw.
|
||||||
|
|
||||||
|
<F12> When the 'g' flag is present in g:proj_flags (see |project-flags|)
|
||||||
|
this key toggles the Project Window open and closed. You may remap
|
||||||
|
this toggle function by putting the following in your vimrc and
|
||||||
|
replacing <Leader>P with whatever key combination you wish:
|
||||||
|
|
||||||
|
nmap <silent> <Leader>P <Plug>ToggleProject
|
||||||
|
|
||||||
|
Note that the Project Plugin remaps :help because the Help Window and the
|
||||||
|
Project Window get into a fight over placement. The mapping avoids the
|
||||||
|
problem.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
ADDING MAPPINGS *project-adding-mappings*
|
||||||
|
|
||||||
|
You can add your own mappings or change the mappings of the plugin by placing
|
||||||
|
them in the file $HOME/.vimproject_mappings. This file, if it exists, will be
|
||||||
|
sourced when the plugin in loaded. Here is an example that will count the
|
||||||
|
number of entries in a project when you press \K (Kount, C is taken :-): >
|
||||||
|
|
||||||
|
function! s:Wc()
|
||||||
|
let b:loadcount=0
|
||||||
|
function! SpawnExec(infoline, fname, lineno, data)
|
||||||
|
let b:loadcount = b:loadcount + 1
|
||||||
|
if getchar(0) != 0 | let b:stop_everything=1 | endif
|
||||||
|
endfunction
|
||||||
|
call Project_ForEach(1, line('.'), "*SpawnExec", 0, '')
|
||||||
|
delfunction SpawnExec
|
||||||
|
echon b:loadcount." Files\r"
|
||||||
|
unlet b:loadcount
|
||||||
|
if exists("b:stop_everything")
|
||||||
|
unlet b:stop_everything
|
||||||
|
echon "Aborted.\r"
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
nnoremap <buffer> <silent> <LocalLeader>K :call <SID>Wc()<CR>
|
||||||
|
|
||||||
|
Here's another example of how I integrated the use of perforce with the plugin
|
||||||
|
in my $HOME/.vimproject_mappings:
|
||||||
|
>
|
||||||
|
function! s:DoP4(cmd)
|
||||||
|
let name=Project_GetFname(line('.'))
|
||||||
|
let dir=substitute(name, '\(.*\)/.*', '\1', 'g')
|
||||||
|
exec 'cd '.dir
|
||||||
|
exec "!".a:cmd.' '.Project_GetFname(line('.'))
|
||||||
|
cd -
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
nmap <buffer> <silent> \pa :call <SID>DoP4("p4add")<CR>
|
||||||
|
nmap <buffer> <silent> \pe :call <SID>DoP4("p4edit")<CR>
|
||||||
|
<
|
||||||
|
(Note that I CD to the directory the file is in so I can pick of the $P4CONFIG
|
||||||
|
file. See the perforce documentation.)
|
||||||
|
|
||||||
|
This creates the mappings \pe to check out the file for edit and \pa to add
|
||||||
|
the file to the depot.
|
||||||
|
|
||||||
|
Here is another example where I remap the <Return> mapping to use an external
|
||||||
|
program to launch a special kind of file (in this case, it launches ee to view
|
||||||
|
a jpg file). It is a bit contrived, but it works.
|
||||||
|
>
|
||||||
|
let s:sid = substitute(maparg('<Return>', 'n'), '.*\(<SNR>.\{-}\)_.*', '\1', '')
|
||||||
|
function! s:LaunchOrWhat()
|
||||||
|
let fname=Project_GetFname(line('.'))
|
||||||
|
if fname =~ '\.jpg$'
|
||||||
|
exec 'silent! !ee "'.fname.'"&'
|
||||||
|
else
|
||||||
|
call {s:sid}_DoFoldOrOpenEntry('', 'e')
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
nnoremap <buffer> <silent> <Return> \|:call <SID>LaunchOrWhat()<CR>
|
||||||
|
<
|
||||||
|
If the file ends in .jpg, the external program is launched, otherwise the
|
||||||
|
original mapping of <Return> is run.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
SETTINGS *project-settings*
|
||||||
|
|
||||||
|
You can set these variables in your vimrc file before the plugin is loaded to
|
||||||
|
change its default behavior
|
||||||
|
|
||||||
|
g:proj_window_width
|
||||||
|
The width of the Project Window that the plugin attempts to maintain.
|
||||||
|
Default: 24
|
||||||
|
|
||||||
|
The Project Plugin is not always successful in keeping the window
|
||||||
|
where I want it with the size specified here, but it does a decent
|
||||||
|
job.
|
||||||
|
|
||||||
|
g:proj_window_increment
|
||||||
|
The increment by which to increase the width of the Project Window
|
||||||
|
when pressing <space> or clicking the <LeftMouse>. Default: 100
|
||||||
|
(See |project-mappings|.)
|
||||||
|
|
||||||
|
*project-flags*
|
||||||
|
g:proj_flags
|
||||||
|
Default: "imst"
|
||||||
|
Various flags to control the behavior of the Project Plugin. This
|
||||||
|
variable can contain any of the following character flags.
|
||||||
|
|
||||||
|
flag Description ~
|
||||||
|
|
||||||
|
b When present, use the |browse()| when selecting directories
|
||||||
|
for \c and \C. This is off by default for Windows, because
|
||||||
|
the windows browser does not allow you to select directories.
|
||||||
|
|
||||||
|
c When present, the Project Window will automatically close when
|
||||||
|
you select a file.
|
||||||
|
|
||||||
|
F Float the Project Window. That is, turn off automatic
|
||||||
|
resizing and placement. This allows placement between other
|
||||||
|
windows that wish to share similar placement at the side of
|
||||||
|
the screen. It is also particularly helpful for external
|
||||||
|
window managers.
|
||||||
|
|
||||||
|
g When present, the mapping for <F12> will be created to toggle
|
||||||
|
the Project Window open and closed.
|
||||||
|
|
||||||
|
i When present, display the filename and the current working
|
||||||
|
directory in the command line when a file is selected for
|
||||||
|
opening.
|
||||||
|
|
||||||
|
l When present, the Project Plugin will use the |:lcd| command
|
||||||
|
rather than |:cd| to change directories when you select a file
|
||||||
|
to open. This flag is really obsolete and not of much use
|
||||||
|
because of L below.
|
||||||
|
|
||||||
|
L Similar to l, but install a BufEnter/Leave |:autocommand| to
|
||||||
|
ensure that the current working directory is changed to the
|
||||||
|
one specified in the fold CD specification whenever that
|
||||||
|
buffer is active. (|:lcd| only changes the CWD for a window,
|
||||||
|
not a buffer.)
|
||||||
|
|
||||||
|
m Turn on mapping of the |CTRL-W_o| and |CTRL-W_CTRL_O| normal
|
||||||
|
mode commands to make the current buffer the only visible
|
||||||
|
buffer, but keep the Project Window visible, too.
|
||||||
|
|
||||||
|
n When present, numbers will be turned on for the project
|
||||||
|
window.
|
||||||
|
|
||||||
|
s When present, the Project Plugin will use syntax highlighting
|
||||||
|
in the Project Window.
|
||||||
|
|
||||||
|
S Turn on sorting for refresh and create.
|
||||||
|
|
||||||
|
t When present, toggle the size of the window rather than just
|
||||||
|
increase the size when pressing <space> or right-clicking.
|
||||||
|
See the entry for <RightMouse> in |project-mappings|.
|
||||||
|
|
||||||
|
T When present, put Subproject folds at the top of the fold when
|
||||||
|
refreshing.
|
||||||
|
|
||||||
|
v When present, use :vimgrep rather than :grep when using \G.
|
||||||
|
|
||||||
|
g:proj_run1 ... g:proj_run9
|
||||||
|
Contains a Vim command to execute on the file. See the
|
||||||
|
mappings of \1 to \9 above.
|
||||||
|
|
||||||
|
%f is replaced with the full path and filename
|
||||||
|
%F is replaced with the full path and filename with spaces
|
||||||
|
quoted
|
||||||
|
%n is replaced with the filename alone
|
||||||
|
%N is replaced with the filename alone with spaces quoted
|
||||||
|
%h is replaced with the home directory
|
||||||
|
%H is replaced with the home directory with spaces quoted
|
||||||
|
%r is replaced with the directory relative to the CD path
|
||||||
|
%R is replaced with the directory relative to the CD path
|
||||||
|
with spaces quoted
|
||||||
|
%d is replaced with the CD directory.
|
||||||
|
%D is replaced with the CD directory.with spaces quoted
|
||||||
|
%% is replaced with a single % that is not used in
|
||||||
|
expansion.
|
||||||
|
|
||||||
|
(Deprecated: %s is also replaced with the full path and
|
||||||
|
filename for backward compatibility.)
|
||||||
|
|
||||||
|
For example, gvim will be launched on the file under the
|
||||||
|
cursor when you enter \3 if the following is in your vimrc
|
||||||
|
file: >
|
||||||
|
let g:proj_run3='silent !gvim %f'
|
||||||
|
< Here are a few other examples: >
|
||||||
|
let g:proj_run1='!p4 edit %f'
|
||||||
|
let g:proj_run2='!p4 add %f'
|
||||||
|
let g:proj_run4="echo 'Viewing %f'|sil !xterm -e less %f &"
|
||||||
|
<
|
||||||
|
On Windows systems you will want to put the %f, %h, and %d in
|
||||||
|
single quotes to avoid \ escaping.
|
||||||
|
|
||||||
|
g:proj_run_fold1 ... g:proj_run_fold9
|
||||||
|
Contains a Vim command to execute on the files in a fold. See
|
||||||
|
the mappings of \f1 to \f9 and \F1 to \F9 above.
|
||||||
|
|
||||||
|
%f is the filename, %h is replaced with the project home
|
||||||
|
directory, and %d is replaced with the CD directory. Multiple
|
||||||
|
filenames can be handled in two ways:
|
||||||
|
|
||||||
|
The first (default) way is to have %f replaced with all the
|
||||||
|
absolute filenames, and the command is run once. The second
|
||||||
|
is to have the command run for each of the non-absolute
|
||||||
|
filenames (%f is replaced with one filename at a time). To
|
||||||
|
select the second behavior, put an '*' character at the
|
||||||
|
beginning of the g:proj_run_fold{x} variable. (The '*' is
|
||||||
|
stripped before the command is run.)
|
||||||
|
|
||||||
|
For example, note the difference between the following: >
|
||||||
|
let g:proj_run_fold3="*echo '%h/%f'"
|
||||||
|
let g:proj_run_fold4="echo '%f'"
|
||||||
|
<
|
||||||
|
Note that on Windows systems, you will want the %f, %h, and %c
|
||||||
|
within single quotes, or the \ in the paths will cause
|
||||||
|
problems. The alternative is to put them in |escape()|.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
PROJECT EXAMPLE FILE *project-example*
|
||||||
|
|
||||||
|
Here is an example ~/.vimprojects file: >
|
||||||
|
|
||||||
|
1 My Project=~/c/project CD=. in=in.vim out=out.vim flags=r {
|
||||||
|
2 Makefile
|
||||||
|
3 in.vim
|
||||||
|
4 out.vim
|
||||||
|
5 GUI Files=. filter="gui*.c gui*.h" {
|
||||||
|
6 gui_window.c
|
||||||
|
7 gui_dialog.c
|
||||||
|
8 gui_list.c
|
||||||
|
9 gui.h # Header file
|
||||||
|
10 }
|
||||||
|
11 Database Files=. filter="data*.c data*.h" {
|
||||||
|
12 data_read.c
|
||||||
|
13 data_write.c
|
||||||
|
14 data.h
|
||||||
|
15 }
|
||||||
|
16 OS-Specific Files {
|
||||||
|
17 Win32=. filter="os_win32*.c os_win32*.h" {
|
||||||
|
18 os_win32_gui.c
|
||||||
|
19 os_win32_io.c
|
||||||
|
20 }
|
||||||
|
21 Unix=. filter="os_unix*.c os_unix*.h" {
|
||||||
|
22 os_unix_gui.c
|
||||||
|
23 os_unix_io.c
|
||||||
|
24 }
|
||||||
|
25 }
|
||||||
|
26 }
|
||||||
|
|
||||||
|
(Don't type in the line numbers, of course.)
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
TIPS ON USING PROJECT PLUGIN *project-tips*
|
||||||
|
|
||||||
|
1. You can create a Project Entry by entering this: >
|
||||||
|
|
||||||
|
Label=~/wherever CD=. filter="*.c *.h" {
|
||||||
|
}
|
||||||
|
<
|
||||||
|
Then you can put the cursor in the fold and press \r. The script will fill
|
||||||
|
in the files (C files in this case) from this directory for you. This is
|
||||||
|
equivalent to \c without any dialogs.
|
||||||
|
|
||||||
|
2. You can edit the Project File at any time to add, remove, or reorder files
|
||||||
|
in the Project list.
|
||||||
|
|
||||||
|
3. If the Project Window ever gets closed, you can just enter >
|
||||||
|
:Project
|
||||||
|
< to bring it back again. (You don't need to give it the filename; the
|
||||||
|
plugin remembers.)
|
||||||
|
|
||||||
|
If you have the 'm' flag set in g:proj_flags, then you get the Project
|
||||||
|
Window to show up again by pressing |CTRL-W_o|. This, of course, will
|
||||||
|
close any other windows that may be open that the cursor is not in.
|
||||||
|
|
||||||
|
4. Adding files to a Project is very easy. To add, for example, the 'more.c'
|
||||||
|
file to the Project, just insert the filename in the Project Entry then
|
||||||
|
hit <Return> on it.
|
||||||
|
|
||||||
|
5. When |quickfix| loads files, it is not equivalent to pressing <Return> on
|
||||||
|
a filename, so the directory will not be changed and the scripts will not
|
||||||
|
be run. (If I could make this otherwise, I would.) The solution is to use
|
||||||
|
the \L key to load all of the files in the Project before running
|
||||||
|
quickfix.
|
||||||
|
|
||||||
|
6. If the Project window gets a bit cluttered with folds partially
|
||||||
|
open/closed, you can press |zM| to close everything and tidy it up.
|
||||||
|
|
||||||
|
7. For advanced users, I am exporting the function Project_GetAllFnames()
|
||||||
|
which returns all the filenames within a fold and optionally all its
|
||||||
|
Subprojects. Also, I export Project_ForEach() for running a function for
|
||||||
|
each filename in the project. See the code for examples on how to use
|
||||||
|
these. Finally, I export Project_GetFname(line_number) so that you can
|
||||||
|
write your own mappings and get the filename for it.
|
||||||
|
|
||||||
|
8. Some people have asked how to do a global mapping to take the cursor to
|
||||||
|
the Project window. One of my goals for the plugin is for it to be as
|
||||||
|
self-contained as possible, so I'm not going to add it by default. But you
|
||||||
|
can put this in your vimrc:
|
||||||
|
>
|
||||||
|
nmap <silent> <Leader>P :Project<CR>
|
||||||
|
|
||||||
|
<
|
||||||
|
9. You can put the . entry in a project, and it will launch the
|
||||||
|
|file-explorer| plugin on the directory. To avoid removal when you
|
||||||
|
refresh, make the entry look like this:
|
||||||
|
>
|
||||||
|
. # pragma keep
|
||||||
|
<
|
||||||
|
==============================================================================
|
||||||
|
THANKS
|
||||||
|
|
||||||
|
The following people have sent me patches to help with the Project
|
||||||
|
Plugin development:
|
||||||
|
|
||||||
|
Tomas Zellerin
|
||||||
|
Lawrence Kesteloot
|
||||||
|
Dave Eggum
|
||||||
|
A Harrison
|
||||||
|
Thomas Link
|
||||||
|
Richard Bair
|
||||||
|
Eric Arnold
|
||||||
|
Peter Jones
|
||||||
|
Eric Van Dewoestine
|
||||||
|
|
||||||
|
|
||||||
|
vim:ts=8 sw=8 noexpandtab tw=78 ft=help:
|
1501
.vim/doc/taglist.txt
Normal file
1501
.vim/doc/taglist.txt
Normal file
File diff suppressed because it is too large
Load Diff
229
.vim/doc/tags
Normal file
229
.vim/doc/tags
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
'Tlist_Auto_Highlight_Tag' taglist.txt /*'Tlist_Auto_Highlight_Tag'*
|
||||||
|
'Tlist_Auto_Open' taglist.txt /*'Tlist_Auto_Open'*
|
||||||
|
'Tlist_Auto_Update' taglist.txt /*'Tlist_Auto_Update'*
|
||||||
|
'Tlist_Close_On_Select' taglist.txt /*'Tlist_Close_On_Select'*
|
||||||
|
'Tlist_Compact_Format' taglist.txt /*'Tlist_Compact_Format'*
|
||||||
|
'Tlist_Ctags_Cmd' taglist.txt /*'Tlist_Ctags_Cmd'*
|
||||||
|
'Tlist_Display_Prototype' taglist.txt /*'Tlist_Display_Prototype'*
|
||||||
|
'Tlist_Display_Tag_Scope' taglist.txt /*'Tlist_Display_Tag_Scope'*
|
||||||
|
'Tlist_Enable_Fold_Column' taglist.txt /*'Tlist_Enable_Fold_Column'*
|
||||||
|
'Tlist_Exit_OnlyWindow' taglist.txt /*'Tlist_Exit_OnlyWindow'*
|
||||||
|
'Tlist_File_Fold_Auto_Close' taglist.txt /*'Tlist_File_Fold_Auto_Close'*
|
||||||
|
'Tlist_GainFocus_On_ToggleOpen' taglist.txt /*'Tlist_GainFocus_On_ToggleOpen'*
|
||||||
|
'Tlist_Highlight_Tag_On_BufEnter' taglist.txt /*'Tlist_Highlight_Tag_On_BufEnter'*
|
||||||
|
'Tlist_Inc_Winwidth' taglist.txt /*'Tlist_Inc_Winwidth'*
|
||||||
|
'Tlist_Max_Submenu_Items' taglist.txt /*'Tlist_Max_Submenu_Items'*
|
||||||
|
'Tlist_Max_Tag_Length' taglist.txt /*'Tlist_Max_Tag_Length'*
|
||||||
|
'Tlist_Process_File_Always' taglist.txt /*'Tlist_Process_File_Always'*
|
||||||
|
'Tlist_Show_Menu' taglist.txt /*'Tlist_Show_Menu'*
|
||||||
|
'Tlist_Show_One_File' taglist.txt /*'Tlist_Show_One_File'*
|
||||||
|
'Tlist_Sort_Type' taglist.txt /*'Tlist_Sort_Type'*
|
||||||
|
'Tlist_Use_Horiz_Window' taglist.txt /*'Tlist_Use_Horiz_Window'*
|
||||||
|
'Tlist_Use_Right_Window' taglist.txt /*'Tlist_Use_Right_Window'*
|
||||||
|
'Tlist_Use_SingleClick' taglist.txt /*'Tlist_Use_SingleClick'*
|
||||||
|
'Tlist_WinHeight' taglist.txt /*'Tlist_WinHeight'*
|
||||||
|
'Tlist_WinWidth' taglist.txt /*'Tlist_WinWidth'*
|
||||||
|
:CVSEdit vcscommand.txt /*:CVSEdit*
|
||||||
|
:CVSEditors vcscommand.txt /*:CVSEditors*
|
||||||
|
:CVSUnedit vcscommand.txt /*:CVSUnedit*
|
||||||
|
:CVSWatch vcscommand.txt /*:CVSWatch*
|
||||||
|
:CVSWatchAdd vcscommand.txt /*:CVSWatchAdd*
|
||||||
|
:CVSWatchOff vcscommand.txt /*:CVSWatchOff*
|
||||||
|
:CVSWatchOn vcscommand.txt /*:CVSWatchOn*
|
||||||
|
:CVSWatchRemove vcscommand.txt /*:CVSWatchRemove*
|
||||||
|
:CVSWatchers vcscommand.txt /*:CVSWatchers*
|
||||||
|
:NERDTree NERD_tree.txt /*:NERDTree*
|
||||||
|
:NERDTreeToggle NERD_tree.txt /*:NERDTreeToggle*
|
||||||
|
:TlistAddFiles taglist.txt /*:TlistAddFiles*
|
||||||
|
:TlistAddFilesRecursive taglist.txt /*:TlistAddFilesRecursive*
|
||||||
|
:TlistClose taglist.txt /*:TlistClose*
|
||||||
|
:TlistDebug taglist.txt /*:TlistDebug*
|
||||||
|
:TlistHighlightTag taglist.txt /*:TlistHighlightTag*
|
||||||
|
:TlistLock taglist.txt /*:TlistLock*
|
||||||
|
:TlistMessages taglist.txt /*:TlistMessages*
|
||||||
|
:TlistOpen taglist.txt /*:TlistOpen*
|
||||||
|
:TlistSessionLoad taglist.txt /*:TlistSessionLoad*
|
||||||
|
:TlistSessionSave taglist.txt /*:TlistSessionSave*
|
||||||
|
:TlistShowPrototype taglist.txt /*:TlistShowPrototype*
|
||||||
|
:TlistShowTag taglist.txt /*:TlistShowTag*
|
||||||
|
:TlistToggle taglist.txt /*:TlistToggle*
|
||||||
|
:TlistUndebug taglist.txt /*:TlistUndebug*
|
||||||
|
:TlistUnlock taglist.txt /*:TlistUnlock*
|
||||||
|
:TlistUpdate taglist.txt /*:TlistUpdate*
|
||||||
|
:VCSAdd vcscommand.txt /*:VCSAdd*
|
||||||
|
:VCSAnnotate vcscommand.txt /*:VCSAnnotate*
|
||||||
|
:VCSBlame vcscommand.txt /*:VCSBlame*
|
||||||
|
:VCSCommit vcscommand.txt /*:VCSCommit*
|
||||||
|
:VCSDelete vcscommand.txt /*:VCSDelete*
|
||||||
|
:VCSDiff vcscommand.txt /*:VCSDiff*
|
||||||
|
:VCSGotoOriginal vcscommand.txt /*:VCSGotoOriginal*
|
||||||
|
:VCSInfo vcscommand.txt /*:VCSInfo*
|
||||||
|
:VCSLock vcscommand.txt /*:VCSLock*
|
||||||
|
:VCSLog vcscommand.txt /*:VCSLog*
|
||||||
|
:VCSRemove vcscommand.txt /*:VCSRemove*
|
||||||
|
:VCSRevert vcscommand.txt /*:VCSRevert*
|
||||||
|
:VCSReview vcscommand.txt /*:VCSReview*
|
||||||
|
:VCSStatus vcscommand.txt /*:VCSStatus*
|
||||||
|
:VCSUnlock vcscommand.txt /*:VCSUnlock*
|
||||||
|
:VCSUpdate vcscommand.txt /*:VCSUpdate*
|
||||||
|
:VCSVimDiff vcscommand.txt /*:VCSVimDiff*
|
||||||
|
NERDChristmasTree NERD_tree.txt /*NERDChristmasTree*
|
||||||
|
NERDTree NERD_tree.txt /*NERDTree*
|
||||||
|
NERDTree-! NERD_tree.txt /*NERDTree-!*
|
||||||
|
NERDTree-? NERD_tree.txt /*NERDTree-?*
|
||||||
|
NERDTree-C NERD_tree.txt /*NERDTree-C*
|
||||||
|
NERDTree-F NERD_tree.txt /*NERDTree-F*
|
||||||
|
NERDTree-H NERD_tree.txt /*NERDTree-H*
|
||||||
|
NERDTree-J NERD_tree.txt /*NERDTree-J*
|
||||||
|
NERDTree-K NERD_tree.txt /*NERDTree-K*
|
||||||
|
NERDTree-O NERD_tree.txt /*NERDTree-O*
|
||||||
|
NERDTree-P NERD_tree.txt /*NERDTree-P*
|
||||||
|
NERDTree-R NERD_tree.txt /*NERDTree-R*
|
||||||
|
NERDTree-T NERD_tree.txt /*NERDTree-T*
|
||||||
|
NERDTree-U NERD_tree.txt /*NERDTree-U*
|
||||||
|
NERDTree-X NERD_tree.txt /*NERDTree-X*
|
||||||
|
NERDTree-c-j NERD_tree.txt /*NERDTree-c-j*
|
||||||
|
NERDTree-c-k NERD_tree.txt /*NERDTree-c-k*
|
||||||
|
NERDTree-contents NERD_tree.txt /*NERDTree-contents*
|
||||||
|
NERDTree-e NERD_tree.txt /*NERDTree-e*
|
||||||
|
NERDTree-f NERD_tree.txt /*NERDTree-f*
|
||||||
|
NERDTree-go NERD_tree.txt /*NERDTree-go*
|
||||||
|
NERDTree-gtab NERD_tree.txt /*NERDTree-gtab*
|
||||||
|
NERDTree-m NERD_tree.txt /*NERDTree-m*
|
||||||
|
NERDTree-o NERD_tree.txt /*NERDTree-o*
|
||||||
|
NERDTree-p NERD_tree.txt /*NERDTree-p*
|
||||||
|
NERDTree-q NERD_tree.txt /*NERDTree-q*
|
||||||
|
NERDTree-r NERD_tree.txt /*NERDTree-r*
|
||||||
|
NERDTree-t NERD_tree.txt /*NERDTree-t*
|
||||||
|
NERDTree-tab NERD_tree.txt /*NERDTree-tab*
|
||||||
|
NERDTree-u NERD_tree.txt /*NERDTree-u*
|
||||||
|
NERDTree-x NERD_tree.txt /*NERDTree-x*
|
||||||
|
NERDTreeAuthor NERD_tree.txt /*NERDTreeAuthor*
|
||||||
|
NERDTreeAutoCenter NERD_tree.txt /*NERDTreeAutoCenter*
|
||||||
|
NERDTreeAutoCenterThreshold NERD_tree.txt /*NERDTreeAutoCenterThreshold*
|
||||||
|
NERDTreeCaseSensitiveSort NERD_tree.txt /*NERDTreeCaseSensitiveSort*
|
||||||
|
NERDTreeChDirMode NERD_tree.txt /*NERDTreeChDirMode*
|
||||||
|
NERDTreeChangelog NERD_tree.txt /*NERDTreeChangelog*
|
||||||
|
NERDTreeCommands NERD_tree.txt /*NERDTreeCommands*
|
||||||
|
NERDTreeCredits NERD_tree.txt /*NERDTreeCredits*
|
||||||
|
NERDTreeFilesysMenu NERD_tree.txt /*NERDTreeFilesysMenu*
|
||||||
|
NERDTreeFunctionality NERD_tree.txt /*NERDTreeFunctionality*
|
||||||
|
NERDTreeHighlightCursorline NERD_tree.txt /*NERDTreeHighlightCursorline*
|
||||||
|
NERDTreeIgnore NERD_tree.txt /*NERDTreeIgnore*
|
||||||
|
NERDTreeMappings NERD_tree.txt /*NERDTreeMappings*
|
||||||
|
NERDTreeMouseMode NERD_tree.txt /*NERDTreeMouseMode*
|
||||||
|
NERDTreeOptionDetails NERD_tree.txt /*NERDTreeOptionDetails*
|
||||||
|
NERDTreeOptionSummary NERD_tree.txt /*NERDTreeOptionSummary*
|
||||||
|
NERDTreeOptions NERD_tree.txt /*NERDTreeOptions*
|
||||||
|
NERDTreePublicFunctions NERD_tree.txt /*NERDTreePublicFunctions*
|
||||||
|
NERDTreeShowFiles NERD_tree.txt /*NERDTreeShowFiles*
|
||||||
|
NERDTreeShowHidden NERD_tree.txt /*NERDTreeShowHidden*
|
||||||
|
NERDTreeSortOrder NERD_tree.txt /*NERDTreeSortOrder*
|
||||||
|
NERDTreeSplitVertical NERD_tree.txt /*NERDTreeSplitVertical*
|
||||||
|
NERDTreeTodo NERD_tree.txt /*NERDTreeTodo*
|
||||||
|
NERDTreeWinPos NERD_tree.txt /*NERDTreeWinPos*
|
||||||
|
NERDTreeWinSize NERD_tree.txt /*NERDTreeWinSize*
|
||||||
|
NERD_tree.txt NERD_tree.txt /*NERD_tree.txt*
|
||||||
|
OmniCpp_DefaultNamespaces omnicppcomplete.txt /*OmniCpp_DefaultNamespaces*
|
||||||
|
OmniCpp_DisplayMode omnicppcomplete.txt /*OmniCpp_DisplayMode*
|
||||||
|
OmniCpp_GlobalScopeSearch omnicppcomplete.txt /*OmniCpp_GlobalScopeSearch*
|
||||||
|
OmniCpp_LocalSearchDecl omnicppcomplete.txt /*OmniCpp_LocalSearchDecl*
|
||||||
|
OmniCpp_MayCompleteArrow omnicppcomplete.txt /*OmniCpp_MayCompleteArrow*
|
||||||
|
OmniCpp_MayCompleteDot omnicppcomplete.txt /*OmniCpp_MayCompleteDot*
|
||||||
|
OmniCpp_MayCompleteScope omnicppcomplete.txt /*OmniCpp_MayCompleteScope*
|
||||||
|
OmniCpp_NamespaceSearch omnicppcomplete.txt /*OmniCpp_NamespaceSearch*
|
||||||
|
OmniCpp_SelectFirstItem omnicppcomplete.txt /*OmniCpp_SelectFirstItem*
|
||||||
|
OmniCpp_ShowAccess omnicppcomplete.txt /*OmniCpp_ShowAccess*
|
||||||
|
OmniCpp_ShowPrototypeInAbbr omnicppcomplete.txt /*OmniCpp_ShowPrototypeInAbbr*
|
||||||
|
OmniCpp_ShowScopeInAbbr omnicppcomplete.txt /*OmniCpp_ShowScopeInAbbr*
|
||||||
|
Tlist_Get_Tag_Prototype_By_Line() taglist.txt /*Tlist_Get_Tag_Prototype_By_Line()*
|
||||||
|
Tlist_Get_Tagname_By_Line() taglist.txt /*Tlist_Get_Tagname_By_Line()*
|
||||||
|
Tlist_Set_App() taglist.txt /*Tlist_Set_App()*
|
||||||
|
Tlist_Update_File_Tags() taglist.txt /*Tlist_Update_File_Tags()*
|
||||||
|
VCSCommandCVSDiffOpt vcscommand.txt /*VCSCommandCVSDiffOpt*
|
||||||
|
VCSCommandCVSExec vcscommand.txt /*VCSCommandCVSExec*
|
||||||
|
VCSCommandCommitOnWrite vcscommand.txt /*VCSCommandCommitOnWrite*
|
||||||
|
VCSCommandDeleteOnHide vcscommand.txt /*VCSCommandDeleteOnHide*
|
||||||
|
VCSCommandDiffSplit vcscommand.txt /*VCSCommandDiffSplit*
|
||||||
|
VCSCommandDisableExtensionMappings vcscommand.txt /*VCSCommandDisableExtensionMappings*
|
||||||
|
VCSCommandDisableMappings vcscommand.txt /*VCSCommandDisableMappings*
|
||||||
|
VCSCommandEdit vcscommand.txt /*VCSCommandEdit*
|
||||||
|
VCSCommandEnableBufferSetup vcscommand.txt /*VCSCommandEnableBufferSetup*
|
||||||
|
VCSCommandResultBufferNameExtension vcscommand.txt /*VCSCommandResultBufferNameExtension*
|
||||||
|
VCSCommandResultBufferNameFunction vcscommand.txt /*VCSCommandResultBufferNameFunction*
|
||||||
|
VCSCommandSVKExec vcscommand.txt /*VCSCommandSVKExec*
|
||||||
|
VCSCommandSVNDiffExt vcscommand.txt /*VCSCommandSVNDiffExt*
|
||||||
|
VCSCommandSVNDiffOpt vcscommand.txt /*VCSCommandSVNDiffOpt*
|
||||||
|
VCSCommandSVNExec vcscommand.txt /*VCSCommandSVNExec*
|
||||||
|
VCSCommandSplit vcscommand.txt /*VCSCommandSplit*
|
||||||
|
b:VCSCommandCommand vcscommand.txt /*b:VCSCommandCommand*
|
||||||
|
b:VCSCommandOriginalBuffer vcscommand.txt /*b:VCSCommandOriginalBuffer*
|
||||||
|
b:VCSCommandSourceFile vcscommand.txt /*b:VCSCommandSourceFile*
|
||||||
|
b:VCSCommandVCSType vcscommand.txt /*b:VCSCommandVCSType*
|
||||||
|
cvscommand-changes vcscommand.txt /*cvscommand-changes*
|
||||||
|
loaded_nerd_tree NERD_tree.txt /*loaded_nerd_tree*
|
||||||
|
omnicpp-download omnicppcomplete.txt /*omnicpp-download*
|
||||||
|
omnicpp-faq omnicppcomplete.txt /*omnicpp-faq*
|
||||||
|
omnicpp-features omnicppcomplete.txt /*omnicpp-features*
|
||||||
|
omnicpp-history omnicppcomplete.txt /*omnicpp-history*
|
||||||
|
omnicpp-installation omnicppcomplete.txt /*omnicpp-installation*
|
||||||
|
omnicpp-limitations omnicppcomplete.txt /*omnicpp-limitations*
|
||||||
|
omnicpp-may-complete omnicppcomplete.txt /*omnicpp-may-complete*
|
||||||
|
omnicpp-options omnicppcomplete.txt /*omnicpp-options*
|
||||||
|
omnicpp-overview omnicppcomplete.txt /*omnicpp-overview*
|
||||||
|
omnicpp-popup omnicppcomplete.txt /*omnicpp-popup*
|
||||||
|
omnicpp-thanks omnicppcomplete.txt /*omnicpp-thanks*
|
||||||
|
omnicppcomplete omnicppcomplete.txt /*omnicppcomplete*
|
||||||
|
omnicppcomplete.txt omnicppcomplete.txt /*omnicppcomplete.txt*
|
||||||
|
project project.txt /*project*
|
||||||
|
project-adding-mappings project.txt /*project-adding-mappings*
|
||||||
|
project-example project.txt /*project-example*
|
||||||
|
project-flags project.txt /*project-flags*
|
||||||
|
project-inheritance project.txt /*project-inheritance*
|
||||||
|
project-invoking project.txt /*project-invoking*
|
||||||
|
project-mappings project.txt /*project-mappings*
|
||||||
|
project-plugin project.txt /*project-plugin*
|
||||||
|
project-settings project.txt /*project-settings*
|
||||||
|
project-syntax project.txt /*project-syntax*
|
||||||
|
project-tips project.txt /*project-tips*
|
||||||
|
project.txt project.txt /*project.txt*
|
||||||
|
taglist-commands taglist.txt /*taglist-commands*
|
||||||
|
taglist-debug taglist.txt /*taglist-debug*
|
||||||
|
taglist-extend taglist.txt /*taglist-extend*
|
||||||
|
taglist-faq taglist.txt /*taglist-faq*
|
||||||
|
taglist-functions taglist.txt /*taglist-functions*
|
||||||
|
taglist-install taglist.txt /*taglist-install*
|
||||||
|
taglist-internet taglist.txt /*taglist-internet*
|
||||||
|
taglist-intro taglist.txt /*taglist-intro*
|
||||||
|
taglist-keys taglist.txt /*taglist-keys*
|
||||||
|
taglist-license taglist.txt /*taglist-license*
|
||||||
|
taglist-menu taglist.txt /*taglist-menu*
|
||||||
|
taglist-options taglist.txt /*taglist-options*
|
||||||
|
taglist-requirements taglist.txt /*taglist-requirements*
|
||||||
|
taglist-session taglist.txt /*taglist-session*
|
||||||
|
taglist-todo taglist.txt /*taglist-todo*
|
||||||
|
taglist-using taglist.txt /*taglist-using*
|
||||||
|
taglist.txt taglist.txt /*taglist.txt*
|
||||||
|
vcscommand vcscommand.txt /*vcscommand*
|
||||||
|
vcscommand-buffer-management vcscommand.txt /*vcscommand-buffer-management*
|
||||||
|
vcscommand-buffer-variables vcscommand.txt /*vcscommand-buffer-variables*
|
||||||
|
vcscommand-bugs vcscommand.txt /*vcscommand-bugs*
|
||||||
|
vcscommand-commands vcscommand.txt /*vcscommand-commands*
|
||||||
|
vcscommand-config vcscommand.txt /*vcscommand-config*
|
||||||
|
vcscommand-contents vcscommand.txt /*vcscommand-contents*
|
||||||
|
vcscommand-customize vcscommand.txt /*vcscommand-customize*
|
||||||
|
vcscommand-events vcscommand.txt /*vcscommand-events*
|
||||||
|
vcscommand-install vcscommand.txt /*vcscommand-install*
|
||||||
|
vcscommand-intro vcscommand.txt /*vcscommand-intro*
|
||||||
|
vcscommand-manual vcscommand.txt /*vcscommand-manual*
|
||||||
|
vcscommand-mappings vcscommand.txt /*vcscommand-mappings*
|
||||||
|
vcscommand-mappings-override vcscommand.txt /*vcscommand-mappings-override*
|
||||||
|
vcscommand-naming vcscommand.txt /*vcscommand-naming*
|
||||||
|
vcscommand-options vcscommand.txt /*vcscommand-options*
|
||||||
|
vcscommand-ssh vcscommand.txt /*vcscommand-ssh*
|
||||||
|
vcscommand-ssh-config vcscommand.txt /*vcscommand-ssh-config*
|
||||||
|
vcscommand-ssh-env vcscommand.txt /*vcscommand-ssh-env*
|
||||||
|
vcscommand-ssh-other vcscommand.txt /*vcscommand-ssh-other*
|
||||||
|
vcscommand-ssh-wrapper vcscommand.txt /*vcscommand-ssh-wrapper*
|
||||||
|
vcscommand-statusline vcscommand.txt /*vcscommand-statusline*
|
||||||
|
vcscommand.txt vcscommand.txt /*vcscommand.txt*
|
771
.vim/doc/vcscommand.txt
Normal file
771
.vim/doc/vcscommand.txt
Normal file
@ -0,0 +1,771 @@
|
|||||||
|
*vcscommand.txt* vcscommand
|
||||||
|
Copyright (c) 2007 Bob Hiestand
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For instructions on installing this file, type
|
||||||
|
:help add-local-help
|
||||||
|
inside Vim.
|
||||||
|
|
||||||
|
Author: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
Credits: Benji Fisher's excellent MatchIt documentation
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
1. Contents *vcscommand-contents*
|
||||||
|
|
||||||
|
Installation : |vcscommand-install|
|
||||||
|
vcscommand Intro : |vcscommand|
|
||||||
|
vcscommand Manual : |vcscommand-manual|
|
||||||
|
Customization : |vcscommand-customize|
|
||||||
|
SSH "integration" : |vcscommand-ssh|
|
||||||
|
Changes from cvscommand : |cvscommand-changes|
|
||||||
|
Bugs : |vcscommand-bugs|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
2. vcscommand Installation *vcscommand-install*
|
||||||
|
|
||||||
|
The vcscommand plugin comprises five files: vcscommand.vim, vcssvn.vim,
|
||||||
|
vcscvs.vim, vcssvk.vim and vcscommand.txt (this file). In order to install
|
||||||
|
the plugin, place the vcscommand.vim, vcssvn.vim, vcssvk.vim, and vcscvs.vim
|
||||||
|
files into a plugin directory in your runtime path (please see
|
||||||
|
|add-global-plugin| and |'runtimepath'|.
|
||||||
|
|
||||||
|
This help file can be included in the VIM help system by copying it into a
|
||||||
|
'doc' directory in your runtime path and then executing the |:helptags|
|
||||||
|
command, specifying the full path of the 'doc' directory. Please see
|
||||||
|
|add-local-help| for more details.
|
||||||
|
|
||||||
|
vcscommand may be customized by setting variables, creating maps, and
|
||||||
|
specifying event handlers. Please see |vcscommand-customize| for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
3. vcscommand Intro *vcscommand*
|
||||||
|
*vcscommand-intro*
|
||||||
|
|
||||||
|
The vcscommand plugin provides global ex commands for manipulating
|
||||||
|
version-controlled source files, currently those controlled either by CVS or
|
||||||
|
Subversion. In general, each command operates on the current buffer and
|
||||||
|
accomplishes a separate source control function, such as update, commit, log,
|
||||||
|
and others (please see |vcscommand-commands| for a list of all available
|
||||||
|
commands). The results of each operation are displayed in a scratch buffer.
|
||||||
|
Several buffer variables are defined for those scratch buffers (please see
|
||||||
|
|vcscommand-buffer-variables|).
|
||||||
|
|
||||||
|
The notion of "current file" means either the current buffer, or, in the case
|
||||||
|
of a directory buffer (such as Explorer or netrw buffers), the directory (and
|
||||||
|
all subdirectories) represented by the the buffer.
|
||||||
|
|
||||||
|
For convenience, any vcscommand invoked on a vcscommand scratch buffer acts as
|
||||||
|
though it was invoked on the original file and splits the screen so that the
|
||||||
|
output appears in a new window.
|
||||||
|
|
||||||
|
Many of the commands accept revisions as arguments. By default, most operate
|
||||||
|
on the most recent revision on the current branch if no revision is specified.
|
||||||
|
|
||||||
|
Each vcscommand is mapped to a key sequence starting with the <Leader>
|
||||||
|
keystroke. The default mappings may be overridden by supplying different
|
||||||
|
mappings before the plugin is loaded, such as in the vimrc, in the standard
|
||||||
|
fashion for plugin mappings. For examples, please see
|
||||||
|
|vcscommand-mappings-override|.
|
||||||
|
|
||||||
|
The vcscommand plugin may be configured in several ways. For more details,
|
||||||
|
please see |vcscommand-customize|.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
4. vcscommand Manual *vcscommand-manual*
|
||||||
|
|
||||||
|
4.1 vcscommand commands *vcscommand-commands*
|
||||||
|
|
||||||
|
vcscommand defines the following commands:
|
||||||
|
|
||||||
|
|:VCSAdd|
|
||||||
|
|:VCSAnnotate|
|
||||||
|
|:VCSBlame|
|
||||||
|
|:VCSCommit|
|
||||||
|
|:VCSDelete|
|
||||||
|
|:VCSDiff|
|
||||||
|
|:VCSGotoOriginal|
|
||||||
|
|:VCSLog|
|
||||||
|
|:VCSRemove|
|
||||||
|
|:VCSRevert|
|
||||||
|
|:VCSReview|
|
||||||
|
|:VCSStatus|
|
||||||
|
|:VCSUpdate|
|
||||||
|
|:VCSVimDiff|
|
||||||
|
|
||||||
|
The following commands are specific to CVS files:
|
||||||
|
|
||||||
|
|:CVSEdit|
|
||||||
|
|:CVSEditors|
|
||||||
|
|:CVSUnedit|
|
||||||
|
|:CVSWatch|
|
||||||
|
|:CVSWatchAdd|
|
||||||
|
|:CVSWatchOn|
|
||||||
|
|:CVSWatchOff|
|
||||||
|
|:CVSWatchRemove|
|
||||||
|
|:CVSWatchers|
|
||||||
|
|
||||||
|
:VCSAdd *:VCSAdd*
|
||||||
|
|
||||||
|
This command adds the current file to source control. Please note, this does
|
||||||
|
not commit the newly-added file. All parameters to the command are passed to
|
||||||
|
the underlying VCS.
|
||||||
|
|
||||||
|
:VCSAnnotate *:VCSAnnotate*
|
||||||
|
|
||||||
|
This command displays the current file with each line annotated with the
|
||||||
|
version in which it was most recently changed. If an argument is given, the
|
||||||
|
argument is used as a revision number to display. If not given an argument,
|
||||||
|
it uses the most recent version of the file (on the current branch, if under
|
||||||
|
CVS control). Additionally, if the current buffer is a VCSAnnotate buffer
|
||||||
|
already, the version number on the current line is used.
|
||||||
|
|
||||||
|
For CVS buffers, the 'VCSCommandCVSAnnotateParent' option, if set to non-zero,
|
||||||
|
will cause the above behavior to change. Instead of annotating the version on
|
||||||
|
the current line, the parent revision is used instead, crossing branches if
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
The filetype of the vcscommand scratch buffer is set to one of 'CVSAnnotate',
|
||||||
|
'SVNAnnotate', or 'SVKAnnotate' as appropriate, to take advantage of the
|
||||||
|
bundled syntax files.
|
||||||
|
|
||||||
|
:VCSBlame *:VCSBlame*
|
||||||
|
|
||||||
|
Alias for |:VCSAnnotate|.
|
||||||
|
|
||||||
|
:VCSCommit[!] *:VCSCommit*
|
||||||
|
|
||||||
|
This command commits changes to the current file to source control.
|
||||||
|
|
||||||
|
If called with arguments, the arguments are the log message.
|
||||||
|
|
||||||
|
If '!' is used, an empty log message is committed.
|
||||||
|
|
||||||
|
If called with no arguments, this is a two-step command. The first step opens
|
||||||
|
a buffer to accept a log message. When that buffer is written, it is
|
||||||
|
automatically closed and the file is committed using the information from that
|
||||||
|
log message. The commit can be abandoned if the log message buffer is deleted
|
||||||
|
or wiped before being written.
|
||||||
|
|
||||||
|
Alternatively, the mapping that is used to invoke :VCSCommit (by default
|
||||||
|
<Leader>cc) can be used in the log message buffer to immediately commit. This
|
||||||
|
is useful if the |VCSCommandCommitOnWrite| variable is set to 0 to disable the
|
||||||
|
normal commit-on-write behavior.
|
||||||
|
|
||||||
|
:VCSDelete *:VCSDelete*
|
||||||
|
|
||||||
|
Deletes the current file and removes it from source control. All parameters
|
||||||
|
to the command are passed to the underlying VCS.
|
||||||
|
|
||||||
|
:VCSDiff *:VCSDiff*
|
||||||
|
|
||||||
|
With no arguments, this displays the differences between the current file and
|
||||||
|
its parent version under source control in a new scratch buffer.
|
||||||
|
|
||||||
|
With one argument, the diff is performed on the current file against the
|
||||||
|
specified revision.
|
||||||
|
|
||||||
|
With two arguments, the diff is performed between the specified revisions of
|
||||||
|
the current file.
|
||||||
|
|
||||||
|
For CVS, this command uses the |VCSCommandCVSDiffOpt| variable to specify diff
|
||||||
|
options. If that variable does not exist, a plugin-specific default is used.
|
||||||
|
If you wish to have no options, then set it to the empty string.
|
||||||
|
|
||||||
|
For SVN, this command uses the |VCSCommandSVNDiffOpt| variable to specify diff
|
||||||
|
options. If that variable does not exist, the SVN default is used.
|
||||||
|
Additionally, |VCSCommandSVNDiffExt| can be used to select an external diff
|
||||||
|
application.
|
||||||
|
|
||||||
|
:VCSGotoOriginal *:VCSGotoOriginal*
|
||||||
|
|
||||||
|
This command jumps to the source buffer if the current buffer is a VCS scratch
|
||||||
|
buffer.
|
||||||
|
|
||||||
|
:VCSGotoOriginal!
|
||||||
|
|
||||||
|
Like ":VCSGotoOriginal" but also executes :bufwipeout on all VCS scrach
|
||||||
|
buffers associated with the original file.
|
||||||
|
|
||||||
|
:VCSInfo *:VCSInfo*
|
||||||
|
|
||||||
|
This command displays extended information about the current file in a new
|
||||||
|
scratch buffer.
|
||||||
|
|
||||||
|
:VCSLock *:VCSLock*
|
||||||
|
|
||||||
|
This command locks the current file in order to prevent other users from
|
||||||
|
concurrently modifying it. The exact semantics of this command depend on the
|
||||||
|
underlying VCS. This does nothing in CVS. All parameters are passed to the
|
||||||
|
underlying VCS.
|
||||||
|
|
||||||
|
:VCSLog *:VCSLog*
|
||||||
|
|
||||||
|
Displays the version history of the current file in a new scratch buffer. If
|
||||||
|
there is one parameter supplied, it is taken as as a revision parameters to be
|
||||||
|
passed through to the underlying VCS. Otherwise, all parameters are passed to
|
||||||
|
the underlying VCS.
|
||||||
|
|
||||||
|
:VCSRemove *:VCSRemove*
|
||||||
|
|
||||||
|
Alias for |:VCSDelete|.
|
||||||
|
|
||||||
|
:VCSRevert *:VCSRevert*
|
||||||
|
|
||||||
|
This command replaces the current file with the most recent version from the
|
||||||
|
repository in order to wipe out any undesired changes.
|
||||||
|
|
||||||
|
:VCSReview *:VCSReview*
|
||||||
|
|
||||||
|
Displays a particular version of the current file in a new scratch buffer. If
|
||||||
|
no argument is given, the most recent version of the file on the current
|
||||||
|
branch is retrieved.
|
||||||
|
|
||||||
|
:VCSStatus *:VCSStatus*
|
||||||
|
|
||||||
|
Displays versioning information about the current file in a new scratch
|
||||||
|
buffer. All parameters are passed to the underlying VCS.
|
||||||
|
|
||||||
|
|
||||||
|
:VCSUnlock *:VCSUnlock*
|
||||||
|
|
||||||
|
Unlocks the current file in order to allow other users from concurrently
|
||||||
|
modifying it. The exact semantics of this command depend on the underlying
|
||||||
|
VCS. All parameters are passed to the underlying VCS.
|
||||||
|
|
||||||
|
:VCSUpdate *:VCSUpdate*
|
||||||
|
|
||||||
|
Updates the current file with any relevant changes from the repository. This
|
||||||
|
intentionally does not automatically reload the current buffer, though vim
|
||||||
|
should prompt the user to do so if the underlying file is altered by this
|
||||||
|
command.
|
||||||
|
|
||||||
|
:VCSVimDiff *:VCSVimDiff*
|
||||||
|
|
||||||
|
Uses vimdiff to display differences between versions of the current file.
|
||||||
|
|
||||||
|
If no revision is specified, the most recent version of the file on the
|
||||||
|
current branch is used. With one argument, that argument is used as the
|
||||||
|
revision as above. With two arguments, the differences between the two
|
||||||
|
revisions is displayed using vimdiff.
|
||||||
|
|
||||||
|
With either zero or one argument, the original buffer is used to perform the
|
||||||
|
vimdiff. When the scratch buffer is closed, the original buffer will be
|
||||||
|
returned to normal mode.
|
||||||
|
|
||||||
|
Once vimdiff mode is started using the above methods, additional vimdiff
|
||||||
|
buffers may be added by passing a single version argument to the command.
|
||||||
|
There may be up to 4 vimdiff buffers total.
|
||||||
|
|
||||||
|
Using the 2-argument form of the command resets the vimdiff to only those 2
|
||||||
|
versions. Additionally, invoking the command on a different file will close
|
||||||
|
the previous vimdiff buffers.
|
||||||
|
|
||||||
|
:CVSEdit *:CVSEdit*
|
||||||
|
|
||||||
|
This command performs "cvs edit" on the current file. Yes, the output buffer
|
||||||
|
in this case is almost completely useless.
|
||||||
|
|
||||||
|
:CVSEditors *:CVSEditors*
|
||||||
|
|
||||||
|
This command performs "cvs edit" on the current file.
|
||||||
|
|
||||||
|
:CVSUnedit *:CVSUnedit*
|
||||||
|
|
||||||
|
Performs "cvs unedit" on the current file. Again, yes, the output buffer here
|
||||||
|
is basically useless.
|
||||||
|
|
||||||
|
:CVSWatch *:CVSWatch*
|
||||||
|
|
||||||
|
This command takes an argument which must be one of [on|off|add|remove]. The
|
||||||
|
command performs "cvs watch" with the given argument on the current file.
|
||||||
|
|
||||||
|
:CVSWatchAdd *:CVSWatchAdd*
|
||||||
|
|
||||||
|
This command is an alias for ":CVSWatch add"
|
||||||
|
|
||||||
|
:CVSWatchOn *:CVSWatchOn*
|
||||||
|
|
||||||
|
This command is an alias for ":CVSWatch on"
|
||||||
|
|
||||||
|
:CVSWatchOff *:CVSWatchOff*
|
||||||
|
|
||||||
|
This command is an alias for ":CVSWatch off"
|
||||||
|
|
||||||
|
:CVSWatchRemove *:CVSWatchRemove*
|
||||||
|
|
||||||
|
This command is an alias for ":CVSWatch remove"
|
||||||
|
|
||||||
|
:CVSWatchers *:CVSWatchers*
|
||||||
|
|
||||||
|
This command performs "cvs watchers" on the current file.
|
||||||
|
|
||||||
|
4.2 Mappings *vcscommand-mappings*
|
||||||
|
|
||||||
|
By default, a mapping is defined for each command. These mappings execute the
|
||||||
|
default (no-argument) form of each command.
|
||||||
|
|
||||||
|
<Leader>ca VCSAdd
|
||||||
|
<Leader>cn VCSAnnotate
|
||||||
|
<Leader>cc VCSCommit
|
||||||
|
<Leader>cD VCSDelete
|
||||||
|
<Leader>cd VCSDiff
|
||||||
|
<Leader>cg VCSGotoOriginal
|
||||||
|
<Leader>cG VCSGotoOriginal!
|
||||||
|
<Leader>ci VCSInfo
|
||||||
|
<Leader>cl VCSLog
|
||||||
|
<Leader>cL VCSLock
|
||||||
|
<Leader>cr VCSReview
|
||||||
|
<Leader>cs VCSStatus
|
||||||
|
<Leader>cu VCSUpdate
|
||||||
|
<Leader>cU VCSUnlock
|
||||||
|
<Leader>cv VCSVimDiff
|
||||||
|
|
||||||
|
Only for CVS buffers:
|
||||||
|
|
||||||
|
<Leader>ce CVSEdit
|
||||||
|
<Leader>cE CVSEditors
|
||||||
|
<Leader>ct CVSUnedit
|
||||||
|
<Leader>cwv CVSWatchers
|
||||||
|
<Leader>cwa CVSWatchAdd
|
||||||
|
<Leader>cwn CVSWatchOn
|
||||||
|
<Leader>cwf CVSWatchOff
|
||||||
|
<Leader>cwf CVSWatchRemove
|
||||||
|
|
||||||
|
*vcscommand-mappings-override*
|
||||||
|
|
||||||
|
The default mappings can be overriden by user-provided instead by mapping to
|
||||||
|
<Plug>CommandName. This is especially useful when these mappings collide with
|
||||||
|
other existing mappings (vim will warn of this during plugin initialization,
|
||||||
|
but will not clobber the existing mappings).
|
||||||
|
|
||||||
|
For instance, to override the default mapping for :VCSAdd to set it to '\add',
|
||||||
|
add the following to the vimrc:
|
||||||
|
|
||||||
|
nmap \add <Plug>VCSAdd
|
||||||
|
|
||||||
|
4.3 Automatic buffer variables *vcscommand-buffer-variables*
|
||||||
|
|
||||||
|
Several buffer variables are defined in each vcscommand result buffer. These
|
||||||
|
may be useful for additional customization in callbacks defined in the event
|
||||||
|
handlers (please see |vcscommand-events|).
|
||||||
|
|
||||||
|
The following variables are automatically defined:
|
||||||
|
|
||||||
|
b:VCSCommandOriginalBuffer *b:VCSCommandOriginalBuffer*
|
||||||
|
|
||||||
|
This variable is set to the buffer number of the source file.
|
||||||
|
|
||||||
|
b:VCSCommandCommand *b:VCSCommandCommand*
|
||||||
|
|
||||||
|
This variable is set to the name of the vcscommand that created the result
|
||||||
|
buffer.
|
||||||
|
|
||||||
|
b:VCSCommandSourceFile *b:VCSCommandSourceFile*
|
||||||
|
|
||||||
|
This variable is set to the name of the original file under source control.
|
||||||
|
|
||||||
|
b:VCSCommandVCSType *b:VCSCommandVCSType*
|
||||||
|
|
||||||
|
This variable is set to the type of the source control. This variable is also
|
||||||
|
set on the original file itself.
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
5. Configuration and customization *vcscommand-customize*
|
||||||
|
*vcscommand-config*
|
||||||
|
|
||||||
|
The vcscommand plugin can be configured in several ways: by setting
|
||||||
|
configuration variables (see |vcscommand-options|) or by defining vcscommand
|
||||||
|
event handlers (see |vcscommand-events|). Additionally, the vcscommand plugin
|
||||||
|
supports a customized status line (see |vcscommand-statusline| and
|
||||||
|
|vcscommand-buffer-management|).
|
||||||
|
|
||||||
|
5.1 vcscommand configuration variables *vcscommand-options*
|
||||||
|
|
||||||
|
Several variables affect the plugin's behavior. These variables are checked
|
||||||
|
at time of execution, and may be defined at the window, buffer, or global
|
||||||
|
level and are checked in that order of precedence.
|
||||||
|
|
||||||
|
|
||||||
|
The following variables are available:
|
||||||
|
|
||||||
|
|VCSCommandCommitOnWrite|
|
||||||
|
|VCSCommandCVSDiffOpt|
|
||||||
|
|VCSCommandCVSExec|
|
||||||
|
|VCSCommandDeleteOnHide|
|
||||||
|
|VCSCommandDiffSplit|
|
||||||
|
|VCSCommandDisableMappings|
|
||||||
|
|VCSCommandDisableExtensionMappings|
|
||||||
|
|VCSCommandEdit|
|
||||||
|
|VCSCommandEnableBufferSetup|
|
||||||
|
|VCSCommandResultBufferNameExtension|
|
||||||
|
|VCSCommandResultBufferNameFunction|
|
||||||
|
|VCSCommandSplit|
|
||||||
|
|VCSCommandSVKExec|
|
||||||
|
|VCSCommandSVNDiffExt|
|
||||||
|
|VCSCommandSVNDiffOpt|
|
||||||
|
|VCSCommandSVNExec|
|
||||||
|
|
||||||
|
VCSCommandCommitOnWrite *VCSCommandCommitOnWrite*
|
||||||
|
|
||||||
|
This variable, if set to a non-zero value, causes the pending commit
|
||||||
|
to take place immediately as soon as the log message buffer is written.
|
||||||
|
If set to zero, only the VCSCommit mapping will cause the pending commit to
|
||||||
|
occur. If not set, it defaults to 1.
|
||||||
|
|
||||||
|
VCSCommandCVSExec *VCSCommandCVSExec*
|
||||||
|
|
||||||
|
This variable controls the executable used for all CVS commands If not set,
|
||||||
|
it defaults to "cvs".
|
||||||
|
|
||||||
|
VCSCommandDeleteOnHide *VCSCommandDeleteOnHide*
|
||||||
|
|
||||||
|
This variable, if set to a non-zero value, causes the temporary result buffers
|
||||||
|
to automatically delete themselves when hidden.
|
||||||
|
|
||||||
|
VCSCommandCVSDiffOpt *VCSCommandCVSDiffOpt*
|
||||||
|
|
||||||
|
This variable, if set, determines the options passed to the diff command of
|
||||||
|
CVS. If not set, it defaults to 'u'.
|
||||||
|
|
||||||
|
VCSCommandDiffSplit *VCSCommandDiffSplit*
|
||||||
|
|
||||||
|
This variable overrides the |VCSCommandSplit| variable, but only for buffers
|
||||||
|
created with |:VCSVimDiff|.
|
||||||
|
|
||||||
|
VCSCommandDisableMappings *VCSCommandDisableMappings*
|
||||||
|
|
||||||
|
This variable, if set to a non-zero value, prevents the default command
|
||||||
|
mappings from being set. This supercedes
|
||||||
|
|VCSCommandDisableExtensionMappings|.
|
||||||
|
|
||||||
|
VCSCommandDisableExtensionMappings *VCSCommandDisableExtensionMappings*
|
||||||
|
|
||||||
|
This variable, if set to a non-zero value, prevents the default command
|
||||||
|
mappings from being set for commands specific to an individual VCS.
|
||||||
|
|
||||||
|
VCSCommandEdit *VCSCommandEdit*
|
||||||
|
|
||||||
|
This variable controls whether the original buffer is replaced ('edit') or
|
||||||
|
split ('split'). If not set, it defaults to 'split'.
|
||||||
|
|
||||||
|
VCSCommandEnableBufferSetup *VCSCommandEnableBufferSetup*
|
||||||
|
|
||||||
|
This variable, if set to a non-zero value, activates VCS buffer management
|
||||||
|
mode see (|vcscommand-buffer-management|). This mode means that the
|
||||||
|
'VCSCommandBufferInfo' variable is filled with version information if the file
|
||||||
|
is VCS-controlled. This is useful for displaying version information in the
|
||||||
|
status bar.
|
||||||
|
|
||||||
|
VCSCommandResultBufferNameExtension *VCSCommandResultBufferNameExtension*
|
||||||
|
|
||||||
|
This variable, if set to a non-blank value, is appended to the name of the VCS
|
||||||
|
command output buffers. For example, '.vcs'. Using this option may help
|
||||||
|
avoid problems caused by autocommands dependent on file extension.
|
||||||
|
|
||||||
|
VCSCommandResultBufferNameFunction *VCSCommandResultBufferNameFunction*
|
||||||
|
|
||||||
|
This variable, if set, specifies a custom function for naming VCS command
|
||||||
|
output buffers. This function is expected to return the new buffer name, and
|
||||||
|
will be passed the following arguments:
|
||||||
|
|
||||||
|
command - name of the VCS command being executed (such as 'Log' or
|
||||||
|
'Diff').
|
||||||
|
|
||||||
|
originalBuffer - buffer number of the source file.
|
||||||
|
|
||||||
|
vcsType - type of VCS controlling this file (such as 'CVS' or 'SVN').
|
||||||
|
|
||||||
|
statusText - extra text associated with the VCS action (such as version
|
||||||
|
numbers).
|
||||||
|
|
||||||
|
VCSCommandSplit *VCSCommandSplit*
|
||||||
|
|
||||||
|
This variable controls the orientation of the various window splits that
|
||||||
|
may occur.
|
||||||
|
|
||||||
|
If set to 'horizontal', the resulting windows will be on stacked on top of
|
||||||
|
one another. If set to 'vertical', the resulting windows will be
|
||||||
|
side-by-side. If not set, it defaults to 'horizontal' for all but
|
||||||
|
VCSVimDiff windows.
|
||||||
|
|
||||||
|
VCSCommandSVKExec *VCSCommandSVKExec*
|
||||||
|
|
||||||
|
This variable controls the executable used for all SVK commands If not set,
|
||||||
|
it defaults to "svk".
|
||||||
|
|
||||||
|
VCSCommandSVNDiffExt *VCSCommandSVNDiffExt*
|
||||||
|
|
||||||
|
This variable, if set, is passed to SVN via the --diff-cmd command to select
|
||||||
|
an external application for performing the diff.
|
||||||
|
|
||||||
|
VCSCommandSVNDiffOpt *VCSCommandSVNDiffOpt*
|
||||||
|
|
||||||
|
This variable, if set, determines the options passed with the '-x' parameter
|
||||||
|
to the SVN diff command. If not set, no options are passed.
|
||||||
|
|
||||||
|
VCSCommandSVNExec *VCSCommandSVNExec*
|
||||||
|
|
||||||
|
This variable controls the executable used for all SVN commands If not set,
|
||||||
|
it defaults to "svn".
|
||||||
|
|
||||||
|
5.2 VCSCommand events *vcscommand-events*
|
||||||
|
|
||||||
|
For additional customization, vcscommand can trigger user-defined events.
|
||||||
|
Event handlers are provided by defining User event autocommands (see
|
||||||
|
|autocommand|, |User|) in the vcscommand group with patterns matching the
|
||||||
|
event name.
|
||||||
|
|
||||||
|
For instance, the following could be added to the vimrc to provide a 'q'
|
||||||
|
mapping to quit a vcscommand scratch buffer:
|
||||||
|
|
||||||
|
augroup VCSCommand
|
||||||
|
au User VCSBufferCreated silent! nmap <unique> <buffer> q: bwipeout<cr>
|
||||||
|
augroup END
|
||||||
|
|
||||||
|
The following hooks are available:
|
||||||
|
|
||||||
|
VCSBufferCreated This event is fired just after a vcscommand
|
||||||
|
result buffer is created and populated. It is
|
||||||
|
executed within the context of the vcscommand
|
||||||
|
buffer. The vcscommand buffer variables may
|
||||||
|
be useful for handlers of this event (please
|
||||||
|
see |vcscommand-buffer-variables|).
|
||||||
|
|
||||||
|
VCSBufferSetup This event is fired just after vcscommand buffer
|
||||||
|
setup occurs, if enabled.
|
||||||
|
|
||||||
|
VCSPluginInit This event is fired when the vcscommand plugin
|
||||||
|
first loads.
|
||||||
|
|
||||||
|
VCSPluginFinish This event is fired just after the vcscommand
|
||||||
|
plugin loads.
|
||||||
|
|
||||||
|
VCSVimDiffFinish This event is fired just after the VCSVimDiff
|
||||||
|
command executes to allow customization of,
|
||||||
|
for instance, window placement and focus.
|
||||||
|
|
||||||
|
Additionally, there is another hook which is used internally to handle loading
|
||||||
|
the multiple scripts in order. This hook should probably not be used by an
|
||||||
|
end user without a good idea of how it works. Among other things, any events
|
||||||
|
associated with this hook are cleared after they are executed (during
|
||||||
|
vcscommand.vim script initialization).
|
||||||
|
|
||||||
|
VCSLoadExtensions This event is fired just before the
|
||||||
|
VCSPluginFinish. It is used internally to
|
||||||
|
execute any commands from the VCS
|
||||||
|
implementation plugins that needs to be
|
||||||
|
deferred until the primary plugin is
|
||||||
|
initialized.
|
||||||
|
|
||||||
|
5.3 vcscommand buffer naming *vcscommand-naming*
|
||||||
|
|
||||||
|
vcscommand result buffers use the following naming convention:
|
||||||
|
[{VCS type} {VCS command} {Source file name}]
|
||||||
|
|
||||||
|
If additional buffers are created that would otherwise conflict, a
|
||||||
|
distinguishing number is added:
|
||||||
|
|
||||||
|
[{VCS type} {VCS command} {Source file name}] (1,2, etc)
|
||||||
|
|
||||||
|
5.4 vcscommand status line support *vcscommand-statusline*
|
||||||
|
|
||||||
|
It is intended that the user will customize the |'statusline'| option to
|
||||||
|
include vcscommand result buffer attributes. A sample function that may be
|
||||||
|
used in the |'statusline'| option is provided by the plugin,
|
||||||
|
VCSCommandGetStatusLine(). In order to use that function in the status line, do
|
||||||
|
something like the following:
|
||||||
|
|
||||||
|
set statusline=%<%f\ %{VCSCommandGetStatusLine()}\ %h%m%r%=%l,%c%V\ %P
|
||||||
|
|
||||||
|
of which %{VCSCommandGetStatusLine()} is the relevant portion.
|
||||||
|
|
||||||
|
The sample VCSCommandGetStatusLine() function handles both vcscommand result
|
||||||
|
buffers and VCS-managed files if vcscommand buffer management is enabled
|
||||||
|
(please see |vcscommand-buffer-management|).
|
||||||
|
|
||||||
|
5.5 vcscommand buffer management *vcscommand-buffer-management*
|
||||||
|
|
||||||
|
The vcscommand plugin can operate in buffer management mode, which means that
|
||||||
|
it attempts to set a buffer variable ('VCSCommandBufferInfo') upon entry into
|
||||||
|
a buffer. This is rather slow because it means that the VCS will be invoked
|
||||||
|
at each entry into a buffer (during the |BufEnter| autocommand).
|
||||||
|
|
||||||
|
This mode is disabled by default. In order to enable it, set the
|
||||||
|
|VCSCommandEnableBufferSetup| variable to a true (non-zero) value. Enabling
|
||||||
|
this mode simply provides the buffer variable mentioned above. The user must
|
||||||
|
explicitly include information from the variable in the |'statusline'| option
|
||||||
|
if they are to appear in the status line (but see |vcscommand-statusline| for
|
||||||
|
a simple way to do that).
|
||||||
|
|
||||||
|
The 'VCSCommandBufferInfo' variable is a list which contains, in order, the
|
||||||
|
revision of the current file, the latest revision of the file in the
|
||||||
|
repository, and (for CVS) the name of the branch. If those values cannot be
|
||||||
|
determined, the list is a single element: 'Unknown'.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
6. SSH "integration" *vcscommand-ssh*
|
||||||
|
|
||||||
|
The following instructions are intended for use in integrating the
|
||||||
|
vcscommand.vim plugin with an SSH-based CVS environment.
|
||||||
|
|
||||||
|
Familiarity with SSH and CVS are assumed.
|
||||||
|
|
||||||
|
These instructions assume that the intent is to have a message box pop up in
|
||||||
|
order to allow the user to enter a passphrase. If, instead, the user is
|
||||||
|
comfortable using certificate-based authentication, then only instructions
|
||||||
|
6.1.1 and 6.1.2 (and optionally 6.1.4) need to be followed; ssh should then
|
||||||
|
work transparently.
|
||||||
|
|
||||||
|
6.1 Environment settings *vcscommand-ssh-env*
|
||||||
|
|
||||||
|
6.1.1 CVSROOT should be set to something like:
|
||||||
|
|
||||||
|
:ext:user@host:/path_to_repository
|
||||||
|
|
||||||
|
6.1.2 CVS_RSH should be set to:
|
||||||
|
|
||||||
|
ssh
|
||||||
|
|
||||||
|
Together, those settings tell CVS to use ssh as the transport when
|
||||||
|
performing CVS calls.
|
||||||
|
|
||||||
|
6.1.3 SSH_ASKPASS should be set to the password-dialog program. In my case,
|
||||||
|
running gnome, it's set to:
|
||||||
|
|
||||||
|
/usr/libexec/openssh/gnome-ssh-askpass
|
||||||
|
|
||||||
|
This tells SSH how to get passwords if no input is available.
|
||||||
|
|
||||||
|
6.1.4 OPTIONAL. You may need to set SSH_SERVER to the location of the cvs
|
||||||
|
executable on the remote (server) machine.
|
||||||
|
|
||||||
|
6.2 CVS wrapper program *vcscommand-ssh-wrapper*
|
||||||
|
|
||||||
|
Now you need to convince SSH to use the password-dialog program. This means
|
||||||
|
you need to execute SSH (and therefore CVS) without standard input. The
|
||||||
|
following script is a simple perl wrapper that dissasociates the CVS command
|
||||||
|
from the current terminal. Specific steps to do this may vary from system to
|
||||||
|
system; the following example works for me on linux.
|
||||||
|
|
||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use POSIX qw(setsid);
|
||||||
|
open STDIN, '/dev/null';
|
||||||
|
fork and do {wait; exit;};
|
||||||
|
setsid;
|
||||||
|
exec('cvs', @ARGV);
|
||||||
|
|
||||||
|
6.3 Configuring vcscommand.vim *vcscommand-ssh-config*
|
||||||
|
|
||||||
|
At this point, you should be able to use your wrapper script to invoke CVS with
|
||||||
|
various commands, and get the password dialog. All that's left is to make CVS
|
||||||
|
use your newly-created wrapper script.
|
||||||
|
|
||||||
|
6.3.1 Tell vcscommand.vim what CVS executable to use. The easiest way to do this
|
||||||
|
is globally, by putting the following in your .vimrc:
|
||||||
|
|
||||||
|
let VCSCommandCVSExec=/path/to/cvs/wrapper/script
|
||||||
|
|
||||||
|
6.4 Where to go from here *vcscommand-ssh-other*
|
||||||
|
|
||||||
|
The script given above works even when non-SSH CVS connections are used,
|
||||||
|
except possibly when interactively entering the message for CVS commit log
|
||||||
|
(depending on the editor you use... VIM works fine). Since the vcscommand.vim
|
||||||
|
plugin handles that message without a terminal, the wrapper script can be used
|
||||||
|
all the time.
|
||||||
|
|
||||||
|
This allows mixed-mode operation, where some work is done with SSH-based CVS
|
||||||
|
repositories, and others with pserver or local access.
|
||||||
|
|
||||||
|
It is possible, though beyond the scope of the plugin, to dynamically set the
|
||||||
|
CVS executable based on the CVSROOT for the file being edited. The user
|
||||||
|
events provided (such as VCSBufferCreated and VCSBufferSetup) can be used to
|
||||||
|
set a buffer-local value (b:VCSCommandCVSExec) to override the CVS executable
|
||||||
|
on a file-by-file basis. Alternatively, much the same can be done (less
|
||||||
|
automatically) by the various project-oriented plugins out there.
|
||||||
|
|
||||||
|
It is highly recommended for ease-of-use that certificates with no passphrase
|
||||||
|
or ssh-agent are employed so that the user is not given the password prompt
|
||||||
|
too often.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
7. Changes from cvscommandi *cvscommand-changes*
|
||||||
|
|
||||||
|
1. Require Vim 7 in order to leverage several convenient features; also
|
||||||
|
because I wanted to play with Vim 7.
|
||||||
|
|
||||||
|
2. Renamed commands to start with 'VCS' instead of 'CVS'. The exceptions are
|
||||||
|
the 'CVSEdit' and 'CVSWatch' family of commands, which are specific to CVS.
|
||||||
|
|
||||||
|
3. Renamed options, events to start with 'VCSCommand'.
|
||||||
|
|
||||||
|
4. Removed option to jump to the parent version of the current line in an
|
||||||
|
annotated buffer, as opposed to the version on the current line. This made
|
||||||
|
little sense in the branching scheme used by subversion, where jumping to a
|
||||||
|
parent branch required finding a different location in the repository. It
|
||||||
|
didn't work consistently in CVS anyway.
|
||||||
|
|
||||||
|
5. Removed option to have nameless scratch buffers.
|
||||||
|
|
||||||
|
6. Changed default behavior of scratch buffers to split the window instead of
|
||||||
|
displaying in the current window. This may still be overridden using the
|
||||||
|
'VCSCommandEdit' option.
|
||||||
|
|
||||||
|
7. Split plugin into multiple plugins.
|
||||||
|
|
||||||
|
8. Added 'VCSLock' and 'VCSUnlock' commands. These are implemented for
|
||||||
|
subversion but not for CVS. These were not kept specific to subversion as they
|
||||||
|
seemed more general in nature and more likely to be supported by any future VCS
|
||||||
|
supported by this plugin.
|
||||||
|
|
||||||
|
9. Changed name of buffer variables set by commands.
|
||||||
|
|
||||||
|
'b:cvsOrigBuffNR' became 'b:VCSCommandOriginalBuffer'
|
||||||
|
'b:cvscmd' became 'b:VCSCommandCommand'
|
||||||
|
|
||||||
|
10. Added new automatic variables to command result buffers.
|
||||||
|
|
||||||
|
'b:VCSCommandSourceFile'
|
||||||
|
'b:VCSCommandVCSType'
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
8. Known bugs *vcscommand-bugs*
|
||||||
|
|
||||||
|
Please let me know if you run across any.
|
||||||
|
|
||||||
|
CVSUnedit may, if a file is changed from the repository, provide prompt text
|
||||||
|
to determine whether the changes should be thrown away. Currently, that text
|
||||||
|
shows up in the CVS result buffer as information; there is no way for the user
|
||||||
|
to actually respond to the prompt and the CVS unedit command does nothing. If
|
||||||
|
this really bothers anyone, please let me know.
|
||||||
|
|
||||||
|
VCSVimDiff, when using the original (real) source buffer as one of the diff
|
||||||
|
buffers, uses some hacks to try to restore the state of the original buffer
|
||||||
|
when the scratch buffer containing the other version is destroyed. There may
|
||||||
|
still be bugs in here, depending on many configuration details.
|
||||||
|
|
||||||
|
vim:tw=78:ts=8:ft=help
|
70
.vim/ftplugin/git.vim
Normal file
70
.vim/ftplugin/git.vim
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
"=============================================================================
|
||||||
|
" Copyright: Copyright © Pierre Habouzit
|
||||||
|
" Permission is hereby granted to use and distribute this code,
|
||||||
|
" with or without modifications, provided that this copyright
|
||||||
|
" notice is copied with it. Like anything else that's free,
|
||||||
|
" bufexplorer.vim is provided *as is* and comes with no
|
||||||
|
" warranty of any kind, either expressed or implied. In no
|
||||||
|
" event will the copyright holder be liable for any damages
|
||||||
|
" resulting from the use of this software.
|
||||||
|
" Description: git-commit(1) helper
|
||||||
|
" Maintainer: Pierre Habouzit <madcoder@debian.org>
|
||||||
|
" Last Changed: Mon, 26 Nov 2007 10:06:15 +0100
|
||||||
|
" Usage: This file should live in your ftplugin directory.
|
||||||
|
"
|
||||||
|
" The configurations variables are:
|
||||||
|
"
|
||||||
|
" g:git_diff_opts - options to add to git diff,
|
||||||
|
" (default "-C -C")
|
||||||
|
" g:git_diff_spawn_mode - use auto-split on commit ?
|
||||||
|
" * 1 == hsplit
|
||||||
|
" * 2 == vsplit
|
||||||
|
" * none else (default)
|
||||||
|
"
|
||||||
|
" The default keymaping is:
|
||||||
|
"
|
||||||
|
" <Leader>gd - view the diff in a hsplit
|
||||||
|
" <Leader>ghd - view the diff in a hsplit
|
||||||
|
" <Leader>gvd - view the diff in a vsplit
|
||||||
|
"========================================================================={{{=
|
||||||
|
|
||||||
|
if exists("b:did_ftplugin") | finish | endif
|
||||||
|
|
||||||
|
let b:did_ftplugin = 1
|
||||||
|
|
||||||
|
setlocal tw=74
|
||||||
|
setlocal nowarn nowb
|
||||||
|
|
||||||
|
function! Git_diff_windows(vertsplit, auto, opts)
|
||||||
|
if a:vertsplit
|
||||||
|
rightbelow vnew
|
||||||
|
else
|
||||||
|
rightbelow new
|
||||||
|
endif
|
||||||
|
silent! setlocal ft=diff previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile
|
||||||
|
exe "normal :r!LANG=C git diff --stat -p --cached ".a:opts."\no\<esc>1GddO\<esc>"
|
||||||
|
setlocal nomodifiable
|
||||||
|
noremap <buffer> q :bw<cr>
|
||||||
|
if a:auto
|
||||||
|
redraw!
|
||||||
|
wincmd p
|
||||||
|
redraw!
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
noremap <buffer> <Leader>gd :call Git_diff_windows(0, 0, g:git_diff_opts)<cr>
|
||||||
|
noremap <buffer> <Leader>ghd :call Git_diff_windows(0, 0, g:git_diff_opts)<cr>
|
||||||
|
noremap <buffer> <Leader>gvd :call Git_diff_windows(1, 0, g:git_diff_opts)<cr>
|
||||||
|
|
||||||
|
if !exists("g:git_diff_opts")
|
||||||
|
let g:git_diff_opts = "-C -C"
|
||||||
|
endif
|
||||||
|
if exists("g:git_diff_spawn_mode")
|
||||||
|
if g:git_diff_spawn_mode == 1
|
||||||
|
call Git_diff_windows(0, 1, g:git_diff_opts)
|
||||||
|
elseif g:git_diff_spawn_mode == 2
|
||||||
|
call Git_diff_windows(1, 1, g:git_diff_opts)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" }}}
|
57
.vim/ftplugin/svn.vim
Normal file
57
.vim/ftplugin/svn.vim
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
" made by Michael Scherer ( misc@mandrake.org )
|
||||||
|
" $Id: svn.vim 282 2005-01-31 21:24:55Z misc $
|
||||||
|
"
|
||||||
|
" 2004-09-13 : Lukas Ruf ( lukas.ruf@lpr.ch )
|
||||||
|
" - re-ordered windows
|
||||||
|
" - set focus on svn-commit.tmp (that's where one has to write)
|
||||||
|
" - set buffer type of new window to 'nofile' to fix 'TODO'
|
||||||
|
"
|
||||||
|
" 2005-01-31 :
|
||||||
|
" - autoclose on exit, thanks to Gintautas Miliauskas ( gintas@akl.lt )
|
||||||
|
" and tips from Marius Gedminas ( mgedmin@b4net.lt )
|
||||||
|
"
|
||||||
|
" 2005-02-08 :
|
||||||
|
" - rewrite in pure vim function, from Kyosuke Takayama ( support@mc.neweb.ne.jp )
|
||||||
|
" - simplified installation instruction, from Marius Gedminas ( mgedmin@b4net.lt )
|
||||||
|
"
|
||||||
|
" 2005-02-11 :
|
||||||
|
" - reindent with space, asked by Marius Gedminas ( mgedmin@b4net.lt )
|
||||||
|
" - do not preview if no file are diffed, patch from Marius Gedminas.
|
||||||
|
"
|
||||||
|
" to use it, place it in ~/.vim/ftplugins
|
||||||
|
|
||||||
|
function! Svn_diff_windows()
|
||||||
|
let i = 0
|
||||||
|
let list_of_files = ''
|
||||||
|
|
||||||
|
while i <= line('$')
|
||||||
|
let line = getline(i)
|
||||||
|
if line =~ '^M'
|
||||||
|
|
||||||
|
let file = substitute(line, '\v^MM?\s*(.*)\s*$', '\1', '')
|
||||||
|
let list_of_files = list_of_files . ' '.file
|
||||||
|
endif
|
||||||
|
|
||||||
|
let i = i + 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if list_of_files == ""
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
new
|
||||||
|
silent! setlocal ft=diff previewwindow bufhidden=delete nobackup noswf nobuflisted nowrap buftype=nofile
|
||||||
|
exe 'normal :r!LANG=C svn diff ' . list_of_files . "\n"
|
||||||
|
setlocal nomodifiable
|
||||||
|
goto 1
|
||||||
|
redraw!
|
||||||
|
wincmd R
|
||||||
|
wincmd p
|
||||||
|
goto 1
|
||||||
|
redraw!
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
set nowarn
|
||||||
|
set nosplitbelow
|
||||||
|
call Svn_diff_windows()
|
||||||
|
set nowb
|
2913
.vim/plugin/NERD_tree.vim
Normal file
2913
.vim/plugin/NERD_tree.vim
Normal file
File diff suppressed because it is too large
Load Diff
1293
.vim/plugin/project.vim
Normal file
1293
.vim/plugin/project.vim
Normal file
File diff suppressed because it is too large
Load Diff
1255
.vim/plugin/vcscommand.vim
Normal file
1255
.vim/plugin/vcscommand.vim
Normal file
File diff suppressed because it is too large
Load Diff
437
.vim/plugin/vcscvs.vim
Normal file
437
.vim/plugin/vcscvs.vim
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
" vim600: set foldmethod=marker:
|
||||||
|
"
|
||||||
|
" CVS extension for VCSCommand.
|
||||||
|
"
|
||||||
|
" Version: VCS development
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
"
|
||||||
|
" Section: Documentation {{{1
|
||||||
|
"
|
||||||
|
" Command documentation {{{2
|
||||||
|
"
|
||||||
|
" The following commands only apply to files under CVS source control.
|
||||||
|
"
|
||||||
|
" CVSEdit Performs "cvs edit" on the current file.
|
||||||
|
"
|
||||||
|
" CVSEditors Performs "cvs editors" on the current file.
|
||||||
|
"
|
||||||
|
" CVSUnedit Performs "cvs unedit" on the current file.
|
||||||
|
"
|
||||||
|
" CVSWatch Takes an argument which must be one of [on|off|add|remove].
|
||||||
|
" Performs "cvs watch" with the given argument on the current
|
||||||
|
" file.
|
||||||
|
"
|
||||||
|
" CVSWatchers Performs "cvs watchers" on the current file.
|
||||||
|
"
|
||||||
|
" CVSWatchAdd Alias for "CVSWatch add"
|
||||||
|
"
|
||||||
|
" CVSWatchOn Alias for "CVSWatch on"
|
||||||
|
"
|
||||||
|
" CVSWatchOff Alias for "CVSWatch off"
|
||||||
|
"
|
||||||
|
" CVSWatchRemove Alias for "CVSWatch remove"
|
||||||
|
"
|
||||||
|
" Mapping documentation: {{{2
|
||||||
|
"
|
||||||
|
" By default, a mapping is defined for each command. User-provided mappings
|
||||||
|
" can be used instead by mapping to <Plug>CommandName, for instance:
|
||||||
|
"
|
||||||
|
" nnoremap ,ce <Plug>CVSEdit
|
||||||
|
"
|
||||||
|
" The default mappings are as follow:
|
||||||
|
"
|
||||||
|
" <Leader>ce CVSEdit
|
||||||
|
" <Leader>cE CVSEditors
|
||||||
|
" <Leader>ct CVSUnedit
|
||||||
|
" <Leader>cwv CVSWatchers
|
||||||
|
" <Leader>cwa CVSWatchAdd
|
||||||
|
" <Leader>cwn CVSWatchOn
|
||||||
|
" <Leader>cwf CVSWatchOff
|
||||||
|
" <Leader>cwr CVSWatchRemove
|
||||||
|
"
|
||||||
|
" Options documentation: {{{2
|
||||||
|
"
|
||||||
|
" VCSCommandCVSExec
|
||||||
|
" This variable specifies the CVS executable. If not set, it defaults to
|
||||||
|
" 'cvs' executed from the user's executable path.
|
||||||
|
"
|
||||||
|
" VCSCommandCVSDiffOpt
|
||||||
|
" This variable, if set, determines the options passed to the cvs diff
|
||||||
|
" command. If not set, it defaults to 'u'.
|
||||||
|
|
||||||
|
" Section: Plugin header {{{1
|
||||||
|
|
||||||
|
if v:version < 700
|
||||||
|
echohl WarningMsg|echomsg 'VCSCommand requires at least VIM 7.0'|echohl None
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
runtime plugin/vcscommand.vim
|
||||||
|
|
||||||
|
if !executable(VCSCommandGetOption('VCSCommandCVSExec', 'cvs'))
|
||||||
|
" CVS is not installed
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:save_cpo=&cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Section: Variable initialization {{{1
|
||||||
|
|
||||||
|
let s:cvsFunctions = {}
|
||||||
|
|
||||||
|
" Section: Utility functions {{{1
|
||||||
|
|
||||||
|
" Function: s:DoCommand(cmd, cmdName, statusText, options) {{{2
|
||||||
|
" Wrapper to VCSCommandDoCommand to add the name of the CVS executable to the
|
||||||
|
" command argument.
|
||||||
|
function! s:DoCommand(cmd, cmdName, statusText, options)
|
||||||
|
if VCSCommandGetVCSType(expand('%')) == 'CVS'
|
||||||
|
let fullCmd = VCSCommandGetOption('VCSCommandCVSExec', 'cvs') . ' ' . a:cmd
|
||||||
|
return VCSCommandDoCommand(fullCmd, a:cmdName, a:statusText, a:options)
|
||||||
|
else
|
||||||
|
throw 'CVS VCSCommand plugin called on non-CVS item.'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: GetRevision() {{{2
|
||||||
|
" Function for retrieving the current buffer's revision number.
|
||||||
|
" Returns: Revision number or an empty string if an error occurs.
|
||||||
|
|
||||||
|
function! GetRevision()
|
||||||
|
if !exists('b:VCSCommandBufferInfo')
|
||||||
|
let b:VCSCommandBufferInfo = s:cvsFunctions.GetBufferInfo()
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(b:VCSCommandBufferInfo) > 0
|
||||||
|
return b:VCSCommandBufferInfo[0]
|
||||||
|
else
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: VCS function implementations {{{1
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Identify(buffer) {{{2
|
||||||
|
function! s:cvsFunctions.Identify(buffer)
|
||||||
|
let fileName = resolve(bufname(a:buffer))
|
||||||
|
if isdirectory(fileName)
|
||||||
|
let directoryName = fileName
|
||||||
|
else
|
||||||
|
let directoryName = fnamemodify(fileName, ':h')
|
||||||
|
endif
|
||||||
|
if strlen(directoryName) > 0
|
||||||
|
let CVSRoot = directoryName . '/CVS/Root'
|
||||||
|
else
|
||||||
|
let CVSRoot = 'CVS/Root'
|
||||||
|
endif
|
||||||
|
if filereadable(CVSRoot)
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Add(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Add(argList)
|
||||||
|
return s:DoCommand(join(['add'] + a:argList, ' '), 'add', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Annotate(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Annotate(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
if &filetype == 'CVSAnnotate'
|
||||||
|
" This is a CVSAnnotate buffer. Perform annotation of the version
|
||||||
|
" indicated by the current line.
|
||||||
|
let caption = matchstr(getline('.'),'\v^[0-9.]+')
|
||||||
|
|
||||||
|
if VCSCommandGetOption('VCSCommandCVSAnnotateParent', 0) != 0
|
||||||
|
if caption != '1.1'
|
||||||
|
let revmaj = matchstr(caption,'\v[0-9.]+\ze\.[0-9]+')
|
||||||
|
let revmin = matchstr(caption,'\v[0-9.]+\.\zs[0-9]+') - 1
|
||||||
|
if revmin == 0
|
||||||
|
" Jump to ancestor branch
|
||||||
|
let caption = matchstr(revmaj,'\v[0-9.]+\ze\.[0-9]+')
|
||||||
|
else
|
||||||
|
let caption = revmaj . "." . revmin
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let options = ['-r' . caption]
|
||||||
|
else
|
||||||
|
" CVS defaults to pulling HEAD, regardless of current branch.
|
||||||
|
" Therefore, always pass desired revision.
|
||||||
|
let caption = ''
|
||||||
|
let options = ['-r' . GetRevision()]
|
||||||
|
endif
|
||||||
|
elseif len(a:argList) == 1 && a:argList[0] !~ '^-'
|
||||||
|
let caption = a:argList[0]
|
||||||
|
let options = ['-r' . caption]
|
||||||
|
else
|
||||||
|
let caption = join(a:argList)
|
||||||
|
let options = a:argList
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['-q', 'annotate'] + options), 'annotate', caption, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=CVSAnnotate
|
||||||
|
" Remove header lines from standard error
|
||||||
|
silent v/^\d\+\%(\.\d\+\)\+/d
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Commit(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Commit(argList)
|
||||||
|
let resultBuffer = s:DoCommand('commit -F "' . a:argList[0] . '"', 'commit', '', {})
|
||||||
|
if resultBuffer == 0
|
||||||
|
echomsg 'No commit needed.'
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Delete() {{{2
|
||||||
|
" By default, use the -f option to remove the file first. If options are
|
||||||
|
" passed in, use those instead.
|
||||||
|
function! s:cvsFunctions.Delete(argList)
|
||||||
|
let options = ['-f']
|
||||||
|
let caption = ''
|
||||||
|
if len(a:argList) > 0
|
||||||
|
let options = a:argList
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
endif
|
||||||
|
return s:DoCommand(join(['remove'] + options, ' '), 'delete', caption, {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Diff(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Diff(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let revOptions = []
|
||||||
|
let caption = ''
|
||||||
|
elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
|
||||||
|
let revOptions = ['-r' . join(a:argList, ' -r')]
|
||||||
|
let caption = '(' . a:argList[0] . ' : ' . get(a:argList, 1, 'current') . ')'
|
||||||
|
else
|
||||||
|
" Pass-through
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
let revOptions = a:argList
|
||||||
|
endif
|
||||||
|
|
||||||
|
let cvsDiffOpt = VCSCommandGetOption('VCSCommandCVSDiffOpt', 'u')
|
||||||
|
if cvsDiffOpt == ''
|
||||||
|
let diffOptions = []
|
||||||
|
else
|
||||||
|
let diffOptions = ['-' . cvsDiffOpt]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['diff'] + diffOptions + revOptions), 'diff', caption, {'allowNonZeroExit': 1})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=diff
|
||||||
|
else
|
||||||
|
echomsg 'No differences found'
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.GetBufferInfo() {{{2
|
||||||
|
" Provides version control details for the current file. Current version
|
||||||
|
" number and current repository version number are required to be returned by
|
||||||
|
" the vcscommand plugin. This CVS extension adds branch name to the return
|
||||||
|
" list as well.
|
||||||
|
" Returns: List of results: [revision, repository, branch]
|
||||||
|
|
||||||
|
function! s:cvsFunctions.GetBufferInfo()
|
||||||
|
let originalBuffer = VCSCommandGetOriginalBuffer(bufnr('%'))
|
||||||
|
let fileName = bufname(originalBuffer)
|
||||||
|
if isdirectory(fileName)
|
||||||
|
let tag = ''
|
||||||
|
if filereadable(fileName . '/CVS/Tag')
|
||||||
|
let tagFile = readfile(fileName . '/CVS/Tag')
|
||||||
|
if len(tagFile) == 1
|
||||||
|
let tag = substitute(tagFile[0], '^T', '', '')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return [tag]
|
||||||
|
endif
|
||||||
|
let realFileName = fnamemodify(resolve(fileName), ':t')
|
||||||
|
if !filereadable(fileName)
|
||||||
|
return ['Unknown']
|
||||||
|
endif
|
||||||
|
let oldCwd = VCSCommandChangeToCurrentFileDir(fileName)
|
||||||
|
try
|
||||||
|
let statusText=system(VCSCommandGetOption('VCSCommandCVSExec', 'cvs') . ' status "' . realFileName . '"')
|
||||||
|
if(v:shell_error)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
let revision=substitute(statusText, '^\_.*Working revision:\s*\(\d\+\%(\.\d\+\)\+\|New file!\)\_.*$', '\1', '')
|
||||||
|
|
||||||
|
" We can still be in a CVS-controlled directory without this being a CVS
|
||||||
|
" file
|
||||||
|
if match(revision, '^New file!$') >= 0
|
||||||
|
let revision='New'
|
||||||
|
elseif match(revision, '^\d\+\.\d\+\%(\.\d\+\.\d\+\)*$') <0
|
||||||
|
return ['Unknown']
|
||||||
|
endif
|
||||||
|
|
||||||
|
let branch=substitute(statusText, '^\_.*Sticky Tag:\s\+\(\d\+\%(\.\d\+\)\+\|\a[A-Za-z0-9-_]*\|(none)\).*$', '\1', '')
|
||||||
|
let repository=substitute(statusText, '^\_.*Repository revision:\s*\(\d\+\%(\.\d\+\)\+\|New file!\|No revision control file\)\_.*$', '\1', '')
|
||||||
|
let repository=substitute(repository, '^New file!\|No revision control file$', 'New', '')
|
||||||
|
return [revision, repository, branch]
|
||||||
|
finally
|
||||||
|
call VCSCommandChdir(oldCwd)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Log() {{{2
|
||||||
|
function! s:cvsFunctions.Log(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let options = []
|
||||||
|
let caption = ''
|
||||||
|
elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
|
||||||
|
let options = ['-r' . join(a:argList, ':')]
|
||||||
|
let caption = options[0]
|
||||||
|
else
|
||||||
|
" Pass-through
|
||||||
|
let options = a:argList
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer=s:DoCommand(join(['log'] + options), 'log', caption, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=rcslog
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Revert(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Revert(argList)
|
||||||
|
return s:DoCommand('update -C', 'revert', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Review(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Review(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let versiontag = '(current)'
|
||||||
|
let versionOption = ''
|
||||||
|
else
|
||||||
|
let versiontag = a:argList[0]
|
||||||
|
let versionOption = ' -r ' . versiontag . ' '
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand('-q update -p' . versionOption, 'review', versiontag, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
let &filetype=getbufvar(b:VCSCommandOriginalBuffer, '&filetype')
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Status(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Status(argList)
|
||||||
|
return s:DoCommand(join(['status'] + a:argList, ' '), 'status', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:cvsFunctions.Update(argList) {{{2
|
||||||
|
function! s:cvsFunctions.Update(argList)
|
||||||
|
return s:DoCommand('update', 'update', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: CVS-specific functions {{{1
|
||||||
|
|
||||||
|
" Function: s:CVSEdit() {{{2
|
||||||
|
function! s:CVSEdit()
|
||||||
|
return s:DoCommand('edit', 'cvsedit', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:CVSEditors() {{{2
|
||||||
|
function! s:CVSEditors()
|
||||||
|
return s:DoCommand('editors', 'cvseditors', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:CVSUnedit() {{{2
|
||||||
|
function! s:CVSUnedit()
|
||||||
|
return s:DoCommand('unedit', 'cvsunedit', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:CVSWatch(onoff) {{{2
|
||||||
|
function! s:CVSWatch(onoff)
|
||||||
|
if a:onoff !~ '^\c\%(on\|off\|add\|remove\)$'
|
||||||
|
echoerr 'Argument to CVSWatch must be one of [on|off|add|remove]'
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
return s:DoCommand('watch ' . tolower(a:onoff), 'cvswatch', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:CVSWatchers() {{{2
|
||||||
|
function! s:CVSWatchers()
|
||||||
|
return s:DoCommand('watchers', 'cvswatchers', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: Command definitions {{{1
|
||||||
|
" Section: Primary commands {{{2
|
||||||
|
com! CVSEdit call s:CVSEdit()
|
||||||
|
com! CVSEditors call s:CVSEditors()
|
||||||
|
com! CVSUnedit call s:CVSUnedit()
|
||||||
|
com! -nargs=1 CVSWatch call s:CVSWatch(<f-args>)
|
||||||
|
com! CVSWatchAdd call s:CVSWatch('add')
|
||||||
|
com! CVSWatchOn call s:CVSWatch('on')
|
||||||
|
com! CVSWatchOff call s:CVSWatch('off')
|
||||||
|
com! CVSWatchRemove call s:CVSWatch('remove')
|
||||||
|
com! CVSWatchers call s:CVSWatchers()
|
||||||
|
|
||||||
|
" Section: Plugin command mappings {{{1
|
||||||
|
|
||||||
|
let s:cvsExtensionMappings = {}
|
||||||
|
let mappingInfo = [
|
||||||
|
\['CVSEdit', 'CVSEdit', 'ce'],
|
||||||
|
\['CVSEditors', 'CVSEditors', 'cE'],
|
||||||
|
\['CVSUnedit', 'CVSUnedit', 'ct'],
|
||||||
|
\['CVSWatchers', 'CVSWatchers', 'cwv'],
|
||||||
|
\['CVSWatchAdd', 'CVSWatch add', 'cwa'],
|
||||||
|
\['CVSWatchOff', 'CVSWatch off', 'cwf'],
|
||||||
|
\['CVSWatchOn', 'CVSWatch on', 'cwn'],
|
||||||
|
\['CVSWatchRemove', 'CVSWatch remove', 'cwr']
|
||||||
|
\]
|
||||||
|
|
||||||
|
for [pluginName, commandText, shortCut] in mappingInfo
|
||||||
|
execute 'nnoremap <silent> <Plug>' . pluginName . ' :' . commandText . '<CR>'
|
||||||
|
if !hasmapto('<Plug>' . pluginName)
|
||||||
|
let s:cvsExtensionMappings[shortCut] = commandText
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" Section: Menu items {{{1
|
||||||
|
silent! aunmenu Plugin.VCS.CVS
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.&Edit <Plug>CVSEdit
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.Ed&itors <Plug>CVSEditors
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.Unedi&t <Plug>CVSUnedit
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.&Watchers <Plug>CVSWatchers
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.WatchAdd <Plug>CVSWatchAdd
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.WatchOn <Plug>CVSWatchOn
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.WatchOff <Plug>CVSWatchOff
|
||||||
|
amenu <silent> &Plugin.VCS.CVS.WatchRemove <Plug>CVSWatchRemove
|
||||||
|
|
||||||
|
" Section: Plugin Registration {{{1
|
||||||
|
call VCSCommandRegisterModule('CVS', expand('<sfile>'), s:cvsFunctions, s:cvsExtensionMappings)
|
||||||
|
|
||||||
|
let &cpo = s:save_cpo
|
254
.vim/plugin/vcsgit.vim
Executable file
254
.vim/plugin/vcsgit.vim
Executable file
@ -0,0 +1,254 @@
|
|||||||
|
" vim600: set foldmethod=marker:
|
||||||
|
"
|
||||||
|
" git extension for VCSCommand.
|
||||||
|
"
|
||||||
|
" Version: VCS development
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2008 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
"
|
||||||
|
" Section: Documentation {{{1
|
||||||
|
"
|
||||||
|
" Options documentation: {{{2
|
||||||
|
"
|
||||||
|
" VCSCommandGitExec
|
||||||
|
" This variable specifies the git executable. If not set, it defaults to
|
||||||
|
" 'git' executed from the user's executable path.
|
||||||
|
"
|
||||||
|
" VCSCommandGitDiffOpt
|
||||||
|
" This variable, if set, determines the default options passed to the
|
||||||
|
" VCSDiff command. If any options (starting with '-') are passed to the
|
||||||
|
" command, this variable is not used.
|
||||||
|
|
||||||
|
" Section: Plugin header {{{1
|
||||||
|
|
||||||
|
if v:version < 700
|
||||||
|
echohl WarningMsg|echomsg 'VCSCommand requires at least VIM 7.0'|echohl None
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
runtime plugin/vcscommand.vim
|
||||||
|
|
||||||
|
if !executable(VCSCommandGetOption('VCSCommandGitExec', 'git'))
|
||||||
|
" git is not installed
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:save_cpo=&cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Section: Variable initialization {{{1
|
||||||
|
|
||||||
|
let s:gitFunctions = {}
|
||||||
|
|
||||||
|
" Section: Utility functions {{{1
|
||||||
|
|
||||||
|
" Function: s:DoCommand(cmd, cmdName, statusText, options) {{{2
|
||||||
|
" Wrapper to VCSCommandDoCommand to add the name of the git executable to the
|
||||||
|
" command argument.
|
||||||
|
function! s:DoCommand(cmd, cmdName, statusText, options)
|
||||||
|
if VCSCommandGetVCSType(expand('%')) == 'git'
|
||||||
|
let fullCmd = VCSCommandGetOption('VCSCommandGitExec', 'git',) . ' ' . a:cmd
|
||||||
|
return VCSCommandDoCommand(fullCmd, a:cmdName, a:statusText, a:options)
|
||||||
|
else
|
||||||
|
throw 'git VCSCommand plugin called on non-git item.'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: VCS function implementations {{{1
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Identify(buffer) {{{2
|
||||||
|
" This function only returns an inexact match due to the detection method used
|
||||||
|
" by git, which simply traverses the directory structure upward.
|
||||||
|
function! s:gitFunctions.Identify(buffer)
|
||||||
|
let oldCwd = VCSCommandChangeToCurrentFileDir(resolve(bufname(a:buffer)))
|
||||||
|
try
|
||||||
|
call system(VCSCommandGetOption('VCSCommandGitExec', 'git') . ' rev-parse --is-inside-work-tree')
|
||||||
|
if(v:shell_error)
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return g:VCSCOMMAND_IDENTIFY_INEXACT
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
call VCSCommandChdir(oldCwd)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Add(argList) {{{2
|
||||||
|
function! s:gitFunctions.Add(argList)
|
||||||
|
return s:DoCommand(join(['add'] + ['-v'] + a:argList, ' '), 'add', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Annotate(argList) {{{2
|
||||||
|
function! s:gitFunctions.Annotate(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
if &filetype == 'gitAnnotate'
|
||||||
|
" Perform annotation of the version indicated by the current line.
|
||||||
|
let options = matchstr(getline('.'),'^\x\+')
|
||||||
|
else
|
||||||
|
let options = ''
|
||||||
|
endif
|
||||||
|
elseif len(a:argList) == 1 && a:argList[0] !~ '^-'
|
||||||
|
let options = a:argList[0]
|
||||||
|
else
|
||||||
|
let options = join(a:argList, ' ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand('blame ' . options . ' -- ', 'annotate', options, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
normal 1G
|
||||||
|
set filetype=gitAnnotate
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Commit(argList) {{{2
|
||||||
|
function! s:gitFunctions.Commit(argList)
|
||||||
|
let resultBuffer = s:DoCommand('commit -F "' . a:argList[0] . '"', 'commit', '', {})
|
||||||
|
if resultBuffer == 0
|
||||||
|
echomsg 'No commit needed.'
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Delete() {{{2
|
||||||
|
" All options are passed through.
|
||||||
|
function! s:gitFunctions.Delete(argList)
|
||||||
|
let options = a:argList
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
return s:DoCommand(join(['rm'] + options, ' '), 'delete', caption, {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Diff(argList) {{{2
|
||||||
|
" Pass-through call to git-diff. If no options (starting with '-') are found,
|
||||||
|
" then the options in the 'VCSCommandGitDiffOpt' variable are added.
|
||||||
|
function! s:gitFunctions.Diff(argList)
|
||||||
|
let gitDiffOpt = VCSCommandGetOption('VCSCommandGitDiffOpt', '')
|
||||||
|
if gitDiffOpt == ''
|
||||||
|
let diffOptions = []
|
||||||
|
else
|
||||||
|
let diffOptions = [gitDiffOpt]
|
||||||
|
for arg in a:argList
|
||||||
|
if arg =~ '^-'
|
||||||
|
let diffOptions = []
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['diff'] + diffOptions + a:argList), 'diff', join(a:argList), {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=diff
|
||||||
|
else
|
||||||
|
echomsg 'No differences found'
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.GetBufferInfo() {{{2
|
||||||
|
" Provides version control details for the current file. Current version
|
||||||
|
" number and current repository version number are required to be returned by
|
||||||
|
" the vcscommand plugin. This CVS extension adds branch name to the return
|
||||||
|
" list as well.
|
||||||
|
" Returns: List of results: [revision, repository, branch]
|
||||||
|
|
||||||
|
function! s:gitFunctions.GetBufferInfo()
|
||||||
|
let oldCwd = VCSCommandChangeToCurrentFileDir(resolve(bufname('%')))
|
||||||
|
try
|
||||||
|
let branch = substitute(system(VCSCommandGetOption('VCSCommandGitExec', 'git') . ' symbolic-ref -q HEAD'), '\n$', '', '')
|
||||||
|
if v:shell_error
|
||||||
|
let branch = 'DETACHED'
|
||||||
|
else
|
||||||
|
let branch = substitute(branch, '^refs/heads/', '', '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let info = [branch]
|
||||||
|
|
||||||
|
for method in split(VCSCommandGetOption('VCSCommandGitDescribeArgList', (',tags,all,always')), ',', 1)
|
||||||
|
if method != ''
|
||||||
|
let method = ' --' . method
|
||||||
|
endif
|
||||||
|
let tag = substitute(system(VCSCommandGetOption('VCSCommandGitExec', 'git') . ' describe' . method), '\n$', '', '')
|
||||||
|
if !v:shell_error
|
||||||
|
call add(info, tag)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return info
|
||||||
|
finally
|
||||||
|
call VCSCommandChdir(oldCwd)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Log() {{{2
|
||||||
|
function! s:gitFunctions.Log(argList)
|
||||||
|
let resultBuffer=s:DoCommand(join(['log'] + a:argList), 'log', join(a:argList, ' '), {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=gitlog
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Revert(argList) {{{2
|
||||||
|
function! s:gitFunctions.Revert(argList)
|
||||||
|
return s:DoCommand('checkout', 'revert', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Review(argList) {{{2
|
||||||
|
function! s:gitFunctions.Review(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let revision = 'HEAD'
|
||||||
|
else
|
||||||
|
let revision = a:argList[0]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let oldCwd = VCSCommandChangeToCurrentFileDir(resolve(bufname(VCSCommandGetOriginalBuffer('%'))))
|
||||||
|
try
|
||||||
|
let prefix = system(VCSCommandGetOption('VCSCommandGitExec', 'git') . ' rev-parse --show-prefix')
|
||||||
|
finally
|
||||||
|
call VCSCommandChdir(oldCwd)
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let prefix = substitute(prefix, '\n$', '', '')
|
||||||
|
let blob = '"' . revision . ':' . prefix . '<VCSCOMMANDFILE>"'
|
||||||
|
let resultBuffer = s:DoCommand('show ' . blob, 'review', revision, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
let &filetype=getbufvar(b:VCSCommandOriginalBuffer, '&filetype')
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Status(argList) {{{2
|
||||||
|
function! s:gitFunctions.Status(argList)
|
||||||
|
return s:DoCommand(join(['status'] + a:argList), 'status', join(a:argList), {'allowNonZeroExit': 1})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:gitFunctions.Update(argList) {{{2
|
||||||
|
function! s:gitFunctions.Update(argList)
|
||||||
|
throw "This command is not implemented for git because file-by-file update doesn't make much sense in that context. If you have an idea for what it should do, please let me know."
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Section: Plugin Registration {{{1
|
||||||
|
call VCSCommandRegisterModule('git', expand('<sfile>'), s:gitFunctions, [])
|
||||||
|
|
||||||
|
let &cpo = s:save_cpo
|
258
.vim/plugin/vcssvk.vim
Normal file
258
.vim/plugin/vcssvk.vim
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
" vim600: set foldmethod=marker:
|
||||||
|
"
|
||||||
|
" SVK extension for VCSCommand.
|
||||||
|
"
|
||||||
|
" Version: VCS development
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
"
|
||||||
|
" Section: Documentation {{{1
|
||||||
|
"
|
||||||
|
" Options documentation: {{{2
|
||||||
|
"
|
||||||
|
" VCSCommandSVKExec
|
||||||
|
" This variable specifies the SVK executable. If not set, it defaults to
|
||||||
|
" 'svk' executed from the user's executable path.
|
||||||
|
|
||||||
|
" Section: Plugin header {{{1
|
||||||
|
|
||||||
|
if v:version < 700
|
||||||
|
echohl WarningMsg|echomsg 'VCSCommand requires at least VIM 7.0'|echohl None
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
runtime plugin/vcscommand.vim
|
||||||
|
|
||||||
|
if !executable(VCSCommandGetOption('VCSCommandSVKExec', 'svk'))
|
||||||
|
" SVK is not installed
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:save_cpo=&cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Section: Variable initialization {{{1
|
||||||
|
|
||||||
|
let s:svkFunctions = {}
|
||||||
|
|
||||||
|
" Section: Utility functions {{{1
|
||||||
|
|
||||||
|
" Function: s:DoCommand(cmd, cmdName, statusText, options) {{{2
|
||||||
|
" Wrapper to VCSCommandDoCommand to add the name of the SVK executable to the
|
||||||
|
" command argument.
|
||||||
|
function! s:DoCommand(cmd, cmdName, statusText, options)
|
||||||
|
if VCSCommandGetVCSType(expand('%')) == 'SVK'
|
||||||
|
let fullCmd = VCSCommandGetOption('VCSCommandSVKExec', 'svk') . ' ' . a:cmd
|
||||||
|
return VCSCommandDoCommand(fullCmd, a:cmdName, a:statusText, a:options)
|
||||||
|
else
|
||||||
|
throw 'SVK VCSCommand plugin called on non-SVK item.'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: VCS function implementations {{{1
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Identify(buffer) {{{2
|
||||||
|
function! s:svkFunctions.Identify(buffer)
|
||||||
|
let fileName = resolve(bufname(a:buffer))
|
||||||
|
if isdirectory(fileName)
|
||||||
|
let directoryName = fileName
|
||||||
|
else
|
||||||
|
let directoryName = fnamemodify(fileName, ':p:h')
|
||||||
|
endif
|
||||||
|
let statusText = system(VCSCommandGetOption('VCSCommandSVKExec', 'svk') . ' info "' . directoryName . '"')
|
||||||
|
if(v:shell_error)
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Add() {{{2
|
||||||
|
function! s:svkFunctions.Add(argList)
|
||||||
|
return s:DoCommand(join(['add'] + a:argList, ' '), 'add', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Annotate(argList) {{{2
|
||||||
|
function! s:svkFunctions.Annotate(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
if &filetype == 'SVKAnnotate'
|
||||||
|
" Perform annotation of the version indicated by the current line.
|
||||||
|
let caption = matchstr(getline('.'),'\v^\s+\zs\d+')
|
||||||
|
let options = ' -r' . caption
|
||||||
|
else
|
||||||
|
let caption = ''
|
||||||
|
let options = ''
|
||||||
|
endif
|
||||||
|
elseif len(a:argList) == 1 && a:argList[0] !~ '^-'
|
||||||
|
let caption = a:argList[0]
|
||||||
|
let options = ' -r' . caption
|
||||||
|
else
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
let options = ' ' . caption
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand('blame' . options, 'annotate', caption, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
normal 1G2dd
|
||||||
|
set filetype=SVKAnnotate
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Commit(argList) {{{2
|
||||||
|
function! s:svkFunctions.Commit(argList)
|
||||||
|
let resultBuffer = s:DoCommand('commit -F "' . a:argList[0] . '"', 'commit', '', {})
|
||||||
|
if resultBuffer == 0
|
||||||
|
echomsg 'No commit needed.'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Delete() {{{2
|
||||||
|
function! s:svkFunctions.Delete(argList)
|
||||||
|
return s:DoCommand(join(['delete'] + a:argList, ' '), 'delete', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Diff(argList) {{{2
|
||||||
|
function! s:svkFunctions.Diff(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let revOptions = []
|
||||||
|
let caption = ''
|
||||||
|
elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
|
||||||
|
let revOptions = ['-r' . join(a:argList, ':')]
|
||||||
|
let caption = '(' . a:argList[0] . ' : ' . get(a:argList, 1, 'current') . ')'
|
||||||
|
else
|
||||||
|
" Pass-through
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
let revOptions = a:argList
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['diff'] + revOptions), 'diff', caption, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=diff
|
||||||
|
else
|
||||||
|
echomsg 'No differences found'
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.GetBufferInfo() {{{2
|
||||||
|
" Provides version control details for the current file. Current version
|
||||||
|
" number and current repository version number are required to be returned by
|
||||||
|
" the vcscommand plugin.
|
||||||
|
" Returns: List of results: [revision, repository]
|
||||||
|
|
||||||
|
function! s:svkFunctions.GetBufferInfo()
|
||||||
|
let originalBuffer = VCSCommandGetOriginalBuffer(bufnr('%'))
|
||||||
|
let fileName = resolve(bufname(originalBuffer))
|
||||||
|
let statusText = system(VCSCommandGetOption('VCSCommandSVKExec', 'svk') . ' status -v "' . fileName . '"')
|
||||||
|
if(v:shell_error)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
" File not under SVK control.
|
||||||
|
if statusText =~ '^?'
|
||||||
|
return ['Unknown']
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [flags, revision, repository] = matchlist(statusText, '^\(.\{3}\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s')[1:3]
|
||||||
|
if revision == ''
|
||||||
|
" Error
|
||||||
|
return ['Unknown']
|
||||||
|
elseif flags =~ '^A'
|
||||||
|
return ['New', 'New']
|
||||||
|
else
|
||||||
|
return [revision, repository]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Info(argList) {{{2
|
||||||
|
function! s:svkFunctions.Info(argList)
|
||||||
|
return s:DoCommand(join(['info'] + a:argList, ' '), 'info', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Lock(argList) {{{2
|
||||||
|
function! s:svkFunctions.Lock(argList)
|
||||||
|
return s:DoCommand(join(['lock'] + a:argList, ' '), 'lock', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Log() {{{2
|
||||||
|
function! s:svkFunctions.Log(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let options = []
|
||||||
|
let caption = ''
|
||||||
|
elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
|
||||||
|
let options = ['-r' . join(a:argList, ':')]
|
||||||
|
let caption = options[0]
|
||||||
|
else
|
||||||
|
" Pass-through
|
||||||
|
let options = a:argList
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['log', '-v'] + options), 'log', caption, {})
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Revert(argList) {{{2
|
||||||
|
function! s:svkFunctions.Revert(argList)
|
||||||
|
return s:DoCommand('revert', 'revert', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Review(argList) {{{2
|
||||||
|
function! s:svkFunctions.Review(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let versiontag = '(current)'
|
||||||
|
let versionOption = ''
|
||||||
|
else
|
||||||
|
let versiontag = a:argList[0]
|
||||||
|
let versionOption = ' -r ' . versiontag . ' '
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand('cat' . versionOption, 'review', versiontag, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
let &filetype=getbufvar(b:VCSCommandOriginalBuffer, '&filetype')
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Status(argList) {{{2
|
||||||
|
function! s:svkFunctions.Status(argList)
|
||||||
|
let options = ['-v']
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let options = a:argList
|
||||||
|
endif
|
||||||
|
return s:DoCommand(join(['status'] + options, ' '), 'status', join(options, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svkFunctions.Unlock(argList) {{{2
|
||||||
|
function! s:svkFunctions.Unlock(argList)
|
||||||
|
return s:DoCommand(join(['unlock'] + a:argList, ' '), 'unlock', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
" Function: s:svkFunctions.Update(argList) {{{2
|
||||||
|
function! s:svkFunctions.Update(argList)
|
||||||
|
return s:DoCommand('update', 'update', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: Plugin Registration {{{1
|
||||||
|
call VCSCommandRegisterModule('SVK', expand('<sfile>'), s:svkFunctions, [])
|
||||||
|
|
||||||
|
let &cpo = s:save_cpo
|
284
.vim/plugin/vcssvn.vim
Normal file
284
.vim/plugin/vcssvn.vim
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
" vim600: set foldmethod=marker:
|
||||||
|
"
|
||||||
|
" SVN extension for VCSCommand.
|
||||||
|
"
|
||||||
|
" Version: VCS development
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
"
|
||||||
|
" Section: Documentation {{{1
|
||||||
|
"
|
||||||
|
" Options documentation: {{{2
|
||||||
|
"
|
||||||
|
" VCSCommandSVNExec
|
||||||
|
" This variable specifies the SVN executable. If not set, it defaults to
|
||||||
|
" 'svn' executed from the user's executable path.
|
||||||
|
"
|
||||||
|
" VCSCommandSVNDiffExt
|
||||||
|
" This variable, if set, sets the external diff program used by Subversion.
|
||||||
|
"
|
||||||
|
" VCSCommandSVNDiffOpt
|
||||||
|
" This variable, if set, determines the options passed to the svn diff
|
||||||
|
" command (such as 'u', 'w', or 'b').
|
||||||
|
|
||||||
|
" Section: Plugin header {{{1
|
||||||
|
|
||||||
|
if v:version < 700
|
||||||
|
echohl WarningMsg|echomsg 'VCSCommand requires at least VIM 7.0'|echohl None
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
runtime plugin/vcscommand.vim
|
||||||
|
|
||||||
|
if !executable(VCSCommandGetOption('VCSCommandSVNExec', 'svn'))
|
||||||
|
" SVN is not installed
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:save_cpo=&cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Section: Variable initialization {{{1
|
||||||
|
|
||||||
|
let s:svnFunctions = {}
|
||||||
|
|
||||||
|
" Section: Utility functions {{{1
|
||||||
|
|
||||||
|
" Function: s:DoCommand(cmd, cmdName, statusText, options) {{{2
|
||||||
|
" Wrapper to VCSCommandDoCommand to add the name of the SVN executable to the
|
||||||
|
" command argument.
|
||||||
|
function! s:DoCommand(cmd, cmdName, statusText, options)
|
||||||
|
if VCSCommandGetVCSType(expand('%')) == 'SVN'
|
||||||
|
let fullCmd = VCSCommandGetOption('VCSCommandSVNExec', 'svn') . ' ' . a:cmd
|
||||||
|
return VCSCommandDoCommand(fullCmd, a:cmdName, a:statusText, a:options)
|
||||||
|
else
|
||||||
|
throw 'SVN VCSCommand plugin called on non-SVN item.'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: VCS function implementations {{{1
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Identify(buffer) {{{2
|
||||||
|
function! s:svnFunctions.Identify(buffer)
|
||||||
|
let fileName = resolve(bufname(a:buffer))
|
||||||
|
if isdirectory(fileName)
|
||||||
|
let directoryName = fileName
|
||||||
|
else
|
||||||
|
let directoryName = fnamemodify(fileName, ':h')
|
||||||
|
endif
|
||||||
|
if strlen(directoryName) > 0
|
||||||
|
let svnDir = directoryName . '/.svn'
|
||||||
|
else
|
||||||
|
let svnDir = '.svn'
|
||||||
|
endif
|
||||||
|
if isdirectory(svnDir)
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Add() {{{2
|
||||||
|
function! s:svnFunctions.Add(argList)
|
||||||
|
return s:DoCommand(join(['add'] + a:argList, ' '), 'add', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Annotate(argList) {{{2
|
||||||
|
function! s:svnFunctions.Annotate(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
if &filetype == 'SVNAnnotate'
|
||||||
|
" Perform annotation of the version indicated by the current line.
|
||||||
|
let caption = matchstr(getline('.'),'\v^\s+\zs\d+')
|
||||||
|
let options = ' -r' . caption
|
||||||
|
else
|
||||||
|
let caption = ''
|
||||||
|
let options = ''
|
||||||
|
endif
|
||||||
|
elseif len(a:argList) == 1 && a:argList[0] !~ '^-'
|
||||||
|
let caption = a:argList[0]
|
||||||
|
let options = ' -r' . caption
|
||||||
|
else
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
let options = ' ' . caption
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand('blame' . options, 'annotate', caption, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=SVNAnnotate
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Commit(argList) {{{2
|
||||||
|
function! s:svnFunctions.Commit(argList)
|
||||||
|
let resultBuffer = s:DoCommand('commit -F "' . a:argList[0] . '"', 'commit', '', {})
|
||||||
|
if resultBuffer == 0
|
||||||
|
echomsg 'No commit needed.'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Delete() {{{2
|
||||||
|
function! s:svnFunctions.Delete(argList)
|
||||||
|
return s:DoCommand(join(['delete'] + a:argList, ' '), 'delete', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Diff(argList) {{{2
|
||||||
|
function! s:svnFunctions.Diff(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let revOptions = []
|
||||||
|
let caption = ''
|
||||||
|
elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
|
||||||
|
let revOptions = ['-r' . join(a:argList, ':')]
|
||||||
|
let caption = '(' . a:argList[0] . ' : ' . get(a:argList, 1, 'current') . ')'
|
||||||
|
else
|
||||||
|
" Pass-through
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
let revOptions = a:argList
|
||||||
|
endif
|
||||||
|
|
||||||
|
let svnDiffExt = VCSCommandGetOption('VCSCommandSVNDiffExt', '')
|
||||||
|
if svnDiffExt == ''
|
||||||
|
let diffExt = []
|
||||||
|
else
|
||||||
|
let diffExt = ['--diff-cmd ' . svnDiffExt]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let svnDiffOpt = VCSCommandGetOption('VCSCommandSVNDiffOpt', '')
|
||||||
|
if svnDiffOpt == ''
|
||||||
|
let diffOptions = []
|
||||||
|
else
|
||||||
|
let diffOptions = ['-x -' . svnDiffOpt]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['diff'] + diffExt + diffOptions + revOptions), 'diff', caption, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
set filetype=diff
|
||||||
|
else
|
||||||
|
if svnDiffExt == ''
|
||||||
|
echomsg 'No differences found'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.GetBufferInfo() {{{2
|
||||||
|
" Provides version control details for the current file. Current version
|
||||||
|
" number and current repository version number are required to be returned by
|
||||||
|
" the vcscommand plugin.
|
||||||
|
" Returns: List of results: [revision, repository, branch]
|
||||||
|
|
||||||
|
function! s:svnFunctions.GetBufferInfo()
|
||||||
|
let originalBuffer = VCSCommandGetOriginalBuffer(bufnr('%'))
|
||||||
|
let fileName = bufname(originalBuffer)
|
||||||
|
let statusText = system(VCSCommandGetOption('VCSCommandSVNExec', 'svn') . ' status -vu "' . fileName . '"')
|
||||||
|
if(v:shell_error)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
" File not under SVN control.
|
||||||
|
if statusText =~ '^?'
|
||||||
|
return ['Unknown']
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [flags, revision, repository] = matchlist(statusText, '^\(.\{8}\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s')[1:3]
|
||||||
|
if revision == ''
|
||||||
|
" Error
|
||||||
|
return ['Unknown']
|
||||||
|
elseif flags =~ '^A'
|
||||||
|
return ['New', 'New']
|
||||||
|
else
|
||||||
|
return [revision, repository]
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Info(argList) {{{2
|
||||||
|
function! s:svnFunctions.Info(argList)
|
||||||
|
return s:DoCommand(join(['info'] + a:argList, ' '), 'info', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Lock(argList) {{{2
|
||||||
|
function! s:svnFunctions.Lock(argList)
|
||||||
|
return s:DoCommand(join(['lock'] + a:argList, ' '), 'lock', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Log(argList) {{{2
|
||||||
|
function! s:svnFunctions.Log(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let options = []
|
||||||
|
let caption = ''
|
||||||
|
elseif len(a:argList) <= 2 && match(a:argList, '^-') == -1
|
||||||
|
let options = ['-r' . join(a:argList, ':')]
|
||||||
|
let caption = options[0]
|
||||||
|
else
|
||||||
|
" Pass-through
|
||||||
|
let options = a:argList
|
||||||
|
let caption = join(a:argList, ' ')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand(join(['log', '-v'] + options), 'log', caption, {})
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Revert(argList) {{{2
|
||||||
|
function! s:svnFunctions.Revert(argList)
|
||||||
|
return s:DoCommand('revert', 'revert', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Review(argList) {{{2
|
||||||
|
function! s:svnFunctions.Review(argList)
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let versiontag = '(current)'
|
||||||
|
let versionOption = ''
|
||||||
|
else
|
||||||
|
let versiontag = a:argList[0]
|
||||||
|
let versionOption = ' -r ' . versiontag . ' '
|
||||||
|
endif
|
||||||
|
|
||||||
|
let resultBuffer = s:DoCommand('cat' . versionOption, 'review', versiontag, {})
|
||||||
|
if resultBuffer > 0
|
||||||
|
let &filetype = getbufvar(b:VCSCommandOriginalBuffer, '&filetype')
|
||||||
|
endif
|
||||||
|
return resultBuffer
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Status(argList) {{{2
|
||||||
|
function! s:svnFunctions.Status(argList)
|
||||||
|
let options = ['-u', '-v']
|
||||||
|
if len(a:argList) == 0
|
||||||
|
let options = a:argList
|
||||||
|
endif
|
||||||
|
return s:DoCommand(join(['status'] + options, ' '), 'status', join(options, ' '), {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Function: s:svnFunctions.Unlock(argList) {{{2
|
||||||
|
function! s:svnFunctions.Unlock(argList)
|
||||||
|
return s:DoCommand(join(['unlock'] + a:argList, ' '), 'unlock', join(a:argList, ' '), {})
|
||||||
|
endfunction
|
||||||
|
" Function: s:svnFunctions.Update(argList) {{{2
|
||||||
|
function! s:svnFunctions.Update(argList)
|
||||||
|
return s:DoCommand('update', 'update', '', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Section: Plugin Registration {{{1
|
||||||
|
call VCSCommandRegisterModule('SVN', expand('<sfile>'), s:svnFunctions, [])
|
||||||
|
|
||||||
|
let &cpo = s:save_cpo
|
45
.vim/syntax/CVSAnnotate.vim
Normal file
45
.vim/syntax/CVSAnnotate.vim
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
" Vim syntax file
|
||||||
|
" Language: CVS annotate output
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" Remark: Used by the cvscommand plugin. Originally written by Mathieu
|
||||||
|
" Clabaut
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
|
||||||
|
if version < 600
|
||||||
|
syntax clear
|
||||||
|
elseif exists("b:current_syntax")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
syn match cvsDate /\d\d-...-\d\d/ contained
|
||||||
|
syn match cvsName /(\S* /hs=s+1,he=e-1 contained nextgroup=cvsDate
|
||||||
|
syn match cvsVer /^\d\+\(\.\d\+\)\+/ contained nextgroup=cvsName
|
||||||
|
syn region cvsHead start="^\d\+\.\d\+" end="):" contains=cvsVer,cvsName,cvsDate
|
||||||
|
|
||||||
|
if !exists("did_cvsannotate_syntax_inits")
|
||||||
|
let did_cvsannotate_syntax_inits = 1
|
||||||
|
hi link cvsDate Comment
|
||||||
|
hi link cvsName Type
|
||||||
|
hi link cvsVer Statement
|
||||||
|
endif
|
||||||
|
|
||||||
|
let b:current_syntax="CVSAnnotate"
|
42
.vim/syntax/SVKAnnotate.vim
Normal file
42
.vim/syntax/SVKAnnotate.vim
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
" Vim syntax file
|
||||||
|
" Language: SVK annotate output
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" Remark: Used by the vcscommand plugin.
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
|
||||||
|
if exists("b:current_syntax")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
syn match svkDate /\d\{4}-\d\{1,2}-\d\{1,2}/ skipwhite contained
|
||||||
|
syn match svkName /(\s*\zs\S\+/ contained nextgroup=svkDate skipwhite
|
||||||
|
syn match svkVer /^\s*\d\+/ contained nextgroup=svkName skipwhite
|
||||||
|
syn region svkHead start=/^/ end="):" contains=svkVer,svkName,svkDate oneline
|
||||||
|
|
||||||
|
if !exists("did_svkannotate_syntax_inits")
|
||||||
|
let did_svkannotate_syntax_inits = 1
|
||||||
|
hi link svkName Type
|
||||||
|
hi link svkDate Comment
|
||||||
|
hi link svkVer Statement
|
||||||
|
endif
|
||||||
|
|
||||||
|
let b:current_syntax="svkAnnotate"
|
40
.vim/syntax/SVNAnnotate.vim
Normal file
40
.vim/syntax/SVNAnnotate.vim
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
" Vim syntax file
|
||||||
|
" Language: SVN annotate output
|
||||||
|
" Maintainer: Bob Hiestand <bob.hiestand@gmail.com>
|
||||||
|
" Remark: Used by the vcscommand plugin.
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
|
||||||
|
if exists("b:current_syntax")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
syn match svnName /\S\+/ contained
|
||||||
|
syn match svnVer /^\s\+\zs\d\+/ contained nextgroup=svnName skipwhite
|
||||||
|
syn match svnHead /^\s\+\d\+\s\+\S\+/ contains=svnVer,svnName
|
||||||
|
|
||||||
|
if !exists("did_svnannotate_syntax_inits")
|
||||||
|
let did_svnannotate_syntax_inits = 1
|
||||||
|
hi link svnName Type
|
||||||
|
hi link svnVer Statement
|
||||||
|
endif
|
||||||
|
|
||||||
|
let b:current_syntax="svnAnnotate"
|
36
.vim/syntax/git.vim
Normal file
36
.vim/syntax/git.vim
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
" Vim syntax file
|
||||||
|
" Language: git commit message
|
||||||
|
|
||||||
|
" Quit when a (custom) syntax file was already loaded
|
||||||
|
if exists("b:current_syntax")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
syn region gitSignedOff start=/^Signed-off-by:/ end=/$/ contains=gitAuthor,gitEmail
|
||||||
|
syn region gitAuthor contained start=/\s/ end=/$/
|
||||||
|
|
||||||
|
syn region gitLine start=/^#/ end=/$/
|
||||||
|
syn region gitCommit start=/^# Changes to be committed:$/ end=/^#$/ contains=gitHead,gitCommitFile
|
||||||
|
syn region gitHead contained start=/^# (.*)/ end=/^#$/
|
||||||
|
syn region gitChanged start=/^# Changed but not updated:/ end=/^#$/ contains=gitHead,gitChangedFile
|
||||||
|
syn region gitUntracked start=/^# Untracked files:/ end=/^#$/ contains=gitHead,gitUntrackedFile
|
||||||
|
|
||||||
|
syn match gitCommitFile contained /^#\t.*/hs=s+2
|
||||||
|
syn match gitChangedFile contained /^#\t.*/hs=s+2
|
||||||
|
syn match gitUntrackedFile contained /^#\t.*/hs=s+2
|
||||||
|
|
||||||
|
hi def link gitSignedOff Keyword
|
||||||
|
hi def link gitAuthor Normal
|
||||||
|
|
||||||
|
hi def link gitLine Comment
|
||||||
|
hi def link gitCommit Comment
|
||||||
|
hi def link gitChanged Comment
|
||||||
|
hi def link gitHead Comment
|
||||||
|
hi def link gitUntracked Comment
|
||||||
|
hi def link gitCommitFile Type
|
||||||
|
hi def link gitChangedFile Constant
|
||||||
|
hi def link gitUntrackedFile Constant
|
||||||
|
|
||||||
|
let b:current_syntax = "git"
|
||||||
|
|
||||||
|
" vim: ts=8 sw=2
|
31
.vim/syntax/vcscommit.vim
Normal file
31
.vim/syntax/vcscommit.vim
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
" Vim syntax file
|
||||||
|
" Language: VCS commit file
|
||||||
|
" Maintainer: Bob Hiestand (bob.hiestand@gmail.com)
|
||||||
|
" License:
|
||||||
|
" Copyright (c) 2007 Bob Hiestand
|
||||||
|
"
|
||||||
|
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
" of this software and associated documentation files (the "Software"), to
|
||||||
|
" deal in the Software without restriction, including without limitation the
|
||||||
|
" rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
" sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
" furnished to do so, subject to the following conditions:
|
||||||
|
"
|
||||||
|
" The above copyright notice and this permission notice shall be included in
|
||||||
|
" all copies or substantial portions of the Software.
|
||||||
|
"
|
||||||
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
" IN THE SOFTWARE.
|
||||||
|
|
||||||
|
if exists("b:current_syntax")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
syntax region vcsComment start="^VCS: " end="$"
|
||||||
|
highlight link vcsComment Comment
|
||||||
|
let b:current_syntax = "vcscommit"
|
Loading…
Reference in New Issue
Block a user