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