Now it works fine. Here is the script with two examples:
Try entering HelloYou in a buffer and do
H<m-x><m-i>
or ,HY<m-x><m-i> which should require exactly two upper letters
When not prefixing with a , .* will be inserted after each uppercase
letter and after each lowertoUpper change
Eg use loweUp to match lowertoUpper
or ,HY to match HelloYou
Propably you want to adjust the ToRegex function to fit your needs.
I'd like to hear about your comments...
============= start ============================================================
"example mapping
inoremap <m-x><m-]> <c-r>=CompleteWithFunc('CompleteTagsWithRegex')<cr>
inoremap <m-x><m-i> <c-r>=CompleteWithFunc('CompleteWordsWithRegex')<cr>
" file completion etc is still to be implemented..
function! StoreUserCompletionFunction(cf)
let g:stored_completion_func = &completefunc
let &completefunc = a:cf
return ""
endfunction
function! RestoreUserCompletionFunction()
let &completefunc = g:stored_completion_func
unlet g:stored_completion_func
return ""
endfunction
" this returns a string which is executed when using "
<c-r>=CompleteWithFunc(func)
function! CompleteWithFunc(func)
let result = "\<c-r>=StoreUserCompletionFunction(".string(a:func).")\<cr>"
" now invoke completion
let result .= "\<c-x>\<c-u>"
let result .= "\<c-r>=RestoreUserCompletionFunction()\<cr>"
return result
endfunction
" only for testing , from vim help
fun! CompleteMonths(findstart, base)
if a:findstart
" locate the start of the word
let line = getline('.')
let start = col('.') - 1
while start > 0 && line[start - 1] =~ '\a'
let start -= 1
endwhile
return start
else
" find months matching with "a:base"
let res = []
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
if m =~ '^' . a:base
call add(res, m)
endif
endfor
return res
endif
endfun
"
fun! CompleteWordsWithRegex(findstart, base)
return CompleteWithRegex(function('GetMatchingWords'),a:findstart,a:base)
endfun
function! CompleteTagsWithRegex(findstart, base)
return CompleteWithRegex(function('GetMatchingTags'),a:findstart,a:base)
endfunction
function! GetMatchingTags(regex_pattern)
let list = taglist(a:regex_pattern)
let res = []
for p in list
call add(res, p['name'])
endfor
let g:res=res
return res
endfunction
function! GetMatchingWords(regex_pattern)
"let startendword = [' ',"\t",".",",",';','!','(',')','^','$',"\n"]
"let startword = '\%('.join(startendword,'\|').'\)'
"let endword = '\%('.join(startendword,'\|').'\)'
"let pat =
'\('.startword.substitute(a:regex_pattern,'\.',endword,'g').endword.'\)*'
"let matches = matchlist(getbufline('%',1,'$'), pat)
"let g:pat = pat
"return join(matches,"\n")
let buf_content = getbufline('%',1,'$')
let nowordpatterns = ['
',"\t",'\.',',',':','!','?','(',')','\[',']','{','}',"\n"]
let splitpattern = '\%('.join(nowordpatterns,'\|').'\)\+'
let words = split(join(buf_content,"\n"), splitpattern)
let matchingwords = filter( words, "v:val =~ '".a:regex_pattern."'")
return matchingwords
endfunction
function! ToRegex(str)
if a:str =~ '^,'
" CamelCase matching, only small letters are allowed between upper case
" letters
let pattern =
'^'.substitute(a:str,',\|\u\zs\ze\|\%(\U\)\+\zs\ze\|\zs\ze\%(\U\)\+\|_\zs\ze','\1\\%(\\U\\|_\\)*','g').'$'
else
let pattern =
'^'.substitute(a:str,'\U\zs\ze\u\|\u\zs\ze\|\zs\ze_','\1.*','g')
endif
return pattern
endfunction
function! CompleteWithRegex(getMatchesFromRegex, findstart, base)
if a:findstart
" locate the start of the word
let line = getline('.')
let start = col('.') - 1
while start > 0 && line[start - 1] =~ '\a\|,\|_'
let start -= 1
endwhile
return start
else
let g:base=a:base
return a:getMatchesFromRegex(ToRegex(a:base))
endif
endfunction
============= end ==============================================================
Marc