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

Reply via email to