Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Introduce a new snippets API.

The snippets plugins are now fully written in python.

Total completion time went from 0.220s to 0.160s.
  • Loading branch information...
commit d14eb8739cc2e52d17dda2084962c586af2757f8 1 parent 0f7bbb1
@Rip-Rip authored
View
113 autoload/snippets/clang_complete.vim
@@ -1,113 +0,0 @@
-" clang_complete clang_complete's snippet generator
-" Author: Xavier Deguillard, Philippe Vaucher
-
-function! snippets#clang_complete#init()
- noremap <expr> <silent> <buffer> <tab> UpdateSnips()
- snoremap <expr> <silent> <buffer> <tab> UpdateSnips()
- if g:clang_conceal_snippets == 1
- augroup ClangCompleteSnippets
- " the check for b:clang_user_options is to do not define anything on
- " buffers that are not supported by clang_complete
- autocmd! Syntax *
- \ if exists('b:clang_user_options') |
- \ call <SID>UpdateConcealSyntax() |
- \ endif
- augroup END
- call s:UpdateConcealSyntax()
- endif
-endfunction
-
-function! s:UpdateConcealSyntax()
- syntax match Conceal /<#/ conceal
- syntax match Conceal /#>/ conceal
-endfunction
-
-" fullname = strcat(char *dest, const char *src)
-" args_pos = [ [8, 17], [20, 34] ]
-function! snippets#clang_complete#add_snippet(fullname, args_pos)
- let l:res = ''
- let l:prev_idx = 0
- for elt in a:args_pos
- let l:res .= a:fullname[l:prev_idx : elt[0] - 1] . '<#' . a:fullname[elt[0] : elt[1] - 1] . '#>'
- let l:prev_idx = elt[1]
- endfor
-
- let l:res .= a:fullname[l:prev_idx : ]
- if g:clang_trailing_placeholder == 1 && len(a:args_pos) > 0
- let l:res .= '<##>'
- endif
-
- return l:res
-endfunction
-
-function! snippets#clang_complete#trigger()
- call s:BeginSnips()
-endfunction
-
-function! snippets#clang_complete#reset()
-endfunction
-
-
-" ---------------- Helpers ----------------
-
-function! UpdateSnips()
- let l:line = getline('.')
- let l:pattern = '<#[^#]*#>'
- if match(l:line, l:pattern) == -1
- return "\<c-i>"
- endif
-
- let l:commands = ""
- if mode() != 'n'
- let l:commands .= "\<esc>"
- endif
-
- let l:commands .= ":call MoveToCCSnippetBegin()\<CR>"
- let l:commands .= "m'"
- let l:commands .= ":call MoveToCCSnippetEnd()\<CR>"
-
- if &selection == "exclusive"
- let l:commands .= "ll"
- else
- let l:commands .= "l"
- endif
-
- let l:commands .= "v`'o\<C-G>"
-
- return l:commands
-endfunction
-
-function! MoveToCCSnippetBegin()
- let l:pattern = '<#'
- let l:line = getline('.')
- let l:startpos = col('.') + 1
- let l:ind = match(l:line, l:pattern, l:startpos)
- if l:ind == -1
- let l:ind = match(l:line, l:pattern, 0)
- endif
- call cursor(line('.'), l:ind + 1)
-endfunction
-
-function! MoveToCCSnippetEnd()
- let l:line = getline('.')
- let l:pattern = '#>'
- let l:startpos = col('.') + 1
-
- call cursor(line('.'), match(l:line, l:pattern, l:startpos) + 1)
-endfunction
-
-function! s:BeginSnips()
- if pumvisible() != 0
- return
- endif
-
- " Do we need to launch UpdateSnippets()?
- let l:line = getline('.')
- let l:pattern = '<#[^#]*#>'
- if match(l:line, l:pattern) == -1
- return
- endif
- call feedkeys("\<esc>^\<tab>")
-endfunction
-
-" vim: set ts=2 sts=2 sw=2 expandtab :
View
24 autoload/snippets/dummy.vim
@@ -1,24 +0,0 @@
-" Prepare the snippet engine
-function! snippets#dummy#init()
- echo 'Initializing stuffs'
-endfunction
-
-" Add a snippet to be triggered
-" fullname: contain an unmangled name. ex: strcat(char *dest, const char *src)
-" args_pos: contain the position of the argument in fullname. ex [ [8, 17], [20, 34] ]
-" Returns: text to be inserted for when trigger() is called
-function! snippets#dummy#add_snippet(fullname, args_pos)
- echo 'Creating snippet for "' . a:fullname
- return a:fullname
-endfunction
-
-" Trigger the snippet
-" Note: usually as simple as triggering the tab key
-function! snippets#dummy#trigger()
- echo 'Triggering snippet'
-endfunction
-
-" Remove all snippets
-function! snippets#dummy#reset()
- echo 'Resetting all snippets'
-endfunction
View
38 autoload/snippets/ultisnips.vim
@@ -1,38 +0,0 @@
-" clang_complete ultisnips's snippet generator
-" Author: Philippe Vaucher
-
-function! snippets#ultisnips#init()
- exe "UltiSnipsAddFiletypes ".&filetype.".clang_complete"
- call snippets#ultisnips#reset()
-endfunction
-
-" fullname = strcat(char *dest, const char *src)
-" args_pos = [ [8, 17], [20, 34] ]
-function! snippets#ultisnips#add_snippet(fullname, args_pos)
- let l:snip = ''
- let l:prev_idx = 0
- let l:snip_idx = 1
- for elt in a:args_pos
- let l:snip .= a:fullname[l:prev_idx : elt[0] - 1] . '${' . l:snip_idx . ':' . a:fullname[elt[0] : elt[1] - 1] . '}'
- let l:snip_idx += 1
- let l:prev_idx = elt[1]
- endfor
-
- let l:snip .= a:fullname[l:prev_idx : ] . '${' . l:snip_idx . '}'
-
- let l:snippet_id = substitute(a:fullname, ' ', '_', 'g')
-
- call UltiSnips_AddSnippet(l:snippet_id, l:snip, a:fullname, 'i', "clang_complete")
-
- return l:snippet_id
-endfunction
-
-function! snippets#ultisnips#trigger()
- call UltiSnips_ExpandSnippet()
-endfunction
-
-function! snippets#ultisnips#reset()
- python UltiSnips_Manager.clear_snippets(ft="clang_complete")
-endfunction
-
-" vim: set ts=2 sts=2 sw=2 expandtab :
View
4 doc/clang_complete.txt
@@ -131,8 +131,8 @@ Default: "clang_complete"
*clang_complete-conceal_snippets*
*g:clang_conceal_snippets*
Note: This option is specific to clang_complete snippets engine.
-If equal to 1, clang_complete will use vim 7.3 conceal feature to hide <#
-and #> which delimit snippet placeholders.
+If equal to 1, clang_complete will use vim 7.3 conceal feature to hide the
+snippet placeholders.
Example of conceal configuration (see |'concealcursor'| and |'conceallevel'|
for details): >
View
64 plugin/clang_complete.vim
@@ -53,8 +53,8 @@ function! s:ClangCompleteInit()
let g:clang_periodic_quickfix = 0
endif
- if !exists('g:clang_snippets')
- let g:clang_snippets = 0
+ if !exists('g:clang_snippets') || g:clang_snippets == 0
+ let g:clang_snippets_engine = 'dummy'
endif
if !exists('g:clang_snippets_engine')
@@ -134,6 +134,8 @@ function! s:ClangCompleteInit()
return
endif
+ python snippetsInit()
+
inoremap <expr> <buffer> <C-X><C-U> <SID>LaunchCompletion()
inoremap <expr> <buffer> . <SID>CompleteDot()
inoremap <expr> <buffer> > <SID>CompleteArrow()
@@ -142,10 +144,6 @@ function! s:ClangCompleteInit()
nnoremap <buffer> <silent> <C-]> :call <SID>GotoDeclaration()<CR><Esc>
nnoremap <buffer> <silent> <C-T> <C-O>
- if g:clang_snippets == 1
- call g:ClangSetSnippetEngine(g:clang_snippets_engine)
- endif
-
" Force menuone. Without it, when there's only one completion result,
" it can be confusing (not completing and no popup)
if g:clang_auto_select != 2
@@ -258,6 +256,21 @@ function! s:initClangCompletePython()
exe 'python sys.path = ["' . s:plugin_path . '"] + sys.path'
exe 'pyfile ' . fnameescape(s:plugin_path) . '/libclang.py'
+
+ try
+ exe 'python from snippets.' . g:clang_snippets_engine . ' import *'
+ let l:snips_loaded = 1
+ catch
+ let l:snips_loaded = 0
+ endtry
+ if l:snips_loaded == 0
+ " Oh yeah, vimscript rocks!
+ " Putting that echoe inside the catch, will throw an error, and
+ " display spurious unwanted errors…
+ echoe 'Snippets engine ' . g:clang_snippets_engine . ' not found'
+ return 0
+ endif
+
py vim.command('let l:res = ' + str(initClangComplete(vim.eval('g:clang_complete_lib_flags'), vim.eval('g:clang_compilation_database'), vim.eval('g:clang_library_path'))))
if l:res == 0
return 0
@@ -337,27 +350,18 @@ function! ClangComplete(findstart, base)
let l:time_start = reltime()
endif
- if g:clang_snippets == 1
- call b:ResetSnip()
- endif
+ python snippetsReset()
python completions, timer = getCurrentCompletions(vim.eval('a:base'))
python vim.command('let l:res = ' + completions)
python timer.registerEvent("Load into vimscript")
- if g:clang_snippets == 1
- for item in l:res
- let item['word'] = b:AddSnip(item['info'], item['args_pos'])
- endfor
- endif
-
inoremap <expr> <buffer> <C-Y> <SID>HandlePossibleSelectionCtrlY()
augroup ClangComplete
au CursorMovedI <buffer> call <SID>TriggerSnippet()
augroup end
let b:snippet_chosen = 0
- python timer.registerEvent("vimscript + snippets")
python timer.finish()
if g:clang_debug == 1
@@ -388,16 +392,14 @@ function! s:TriggerSnippet()
return
endif
- if g:clang_snippets == 1
- " Stop monitoring as we'll trigger a snippet
- silent! iunmap <buffer> <C-Y>
- augroup ClangComplete
- au! CursorMovedI <buffer>
- augroup end
+ " Stop monitoring as we'll trigger a snippet
+ silent! iunmap <buffer> <C-Y>
+ augroup ClangComplete
+ au! CursorMovedI <buffer>
+ augroup end
- " Trigger the snippet
- call b:TriggerSnip()
- endif
+ " Trigger the snippet
+ python snippetsTrigger()
if g:clang_close_preview
pclose
@@ -472,16 +474,4 @@ function! g:ClangUpdateQuickFix()
return ''
endfunction
-function! g:ClangSetSnippetEngine(engine_name)
- try
- call eval('snippets#' . a:engine_name . '#init()')
- let b:AddSnip = function('snippets#' . a:engine_name . '#add_snippet')
- let b:ResetSnip = function('snippets#' . a:engine_name . '#reset')
- let b:TriggerSnip = function('snippets#' . a:engine_name . '#trigger')
- catch /^Vim\%((\a\+)\)\=:E117/
- echoe 'Snippets engine ' . a:engine_name . ' not found.'
- let g:clang_snippets = 0
- endtry
-endfunction
-
" vim: set ts=2 sts=2 sw=2 expandtab :
View
19 plugin/libclang.py
@@ -364,9 +364,8 @@ def formatResult(result):
completion = dict()
returnValue = None
abbr = ""
- args_pos = []
- cur_pos = 0
word = ""
+ info = ""
for chunk in result.string:
@@ -382,22 +381,22 @@ def formatResult(result):
if chunk.isKindTypedText():
abbr = chunk_spelling
- chunk_len = len(chunk_spelling)
if chunk.isKindPlaceHolder():
- args_pos += [[ cur_pos, cur_pos + chunk_len ]]
- cur_pos += chunk_len
- word += chunk_spelling
+ word += snippetsFormatPlaceHolder(chunk_spelling)
+ else:
+ word += chunk_spelling
+
+ info += chunk_spelling
- menu = word
+ menu = info
if returnValue:
menu = returnValue.spelling + " " + menu
- completion['word'] = abbr
+ completion['word'] = snippetsAddSnippet(info, word, abbr)
completion['abbr'] = abbr
completion['menu'] = menu
- completion['info'] = word
- completion['args_pos'] = args_pos
+ completion['info'] = info
completion['dup'] = 1
# Replace the number that represents a specific kind with a better
View
1  plugin/snippets/__init__.py
@@ -0,0 +1 @@
+__all__ = ['clang_complete', 'ultisnips', 'dummy']
View
47 plugin/snippets/clang_complete.py
@@ -0,0 +1,47 @@
+import re
+import vim
+
+def snippetsInit():
+ vim.command("noremap <silent> <buffer> <tab> :python updateSnips()<CR>")
+ vim.command("snoremap <silent> <buffer> <tab> <ESC>:python updateSnips()<CR>")
+ if int(vim.eval("g:clang_conceal_snippets")) == 1:
+ vim.command("syntax match placeHolder /\$`[^`]*`/ contains=placeHolderMark")
+ vim.command("syntax match placeHolderMark contained /\$`/ conceal")
+ vim.command("syntax match placeHolderMark contained /`/ conceal")
+
+# The two following function are performance sensitive, do _nothing_
+# more that the strict necessary.
+
+def snippetsFormatPlaceHolder(word):
+ return "$`%s`" % word
+
+def snippetsAddSnippet(fullname, word, abbr):
+ return word
+
+r = re.compile('\$`[^`]*`')
+
+def snippetsTrigger():
+ if r.search(vim.current.line) is None:
+ return
+ vim.command('call feedkeys("\<esc>^\<tab>")')
+
+def snippetsReset():
+ pass
+
+def updateSnips():
+ line = vim.current.line
+ row, col = vim.current.window.cursor
+
+ result = r.search(line, col)
+ if result is None:
+ result = r.search(line)
+ if result is None:
+ vim.command('call feedkeys("\<c-i>", "n")')
+ return
+
+ start, end = result.span()
+ vim.current.window.cursor = row, start
+ isInclusive = vim.eval("&selection") == "inclusive"
+ vim.command('call feedkeys("\<ESC>v%dl\<C-G>", "n")' % (end - start - isInclusive))
+
+# vim: set ts=2 sts=2 sw=2 expandtab :
View
16 plugin/snippets/dummy.py
@@ -0,0 +1,16 @@
+def snippetsInit():
+ pass
+
+def snippetsFormatPlaceHolder(word):
+ return ''
+
+def snippetsAddSnippet(fullname, word, abbr):
+ return abbr
+
+def snippetsTrigger():
+ pass
+
+def snippetsReset():
+ pass
+
+# vim: set ts=2 sts=2 sw=2 expandtab :
View
29 plugin/snippets/ultisnips.py
@@ -0,0 +1,29 @@
+import vim
+import re
+from UltiSnips import UltiSnips_Manager
+
+def snippetsInit():
+ global ultisnips_idx
+ ultisnips_idx = 0
+ UltiSnips_Manager.add_buffer_filetypes('%s.clang_complete' % vim.eval('&filetype'))
+
+def snippetsFormatPlaceHolder(word):
+ # Better way to do that?
+ global ultisnips_idx
+ ultisnips_idx += 1
+ return '${%d:%s}' % (ultisnips_idx, word)
+
+def snippetsAddSnippet(fullname, word, abbr):
+ global ultisnips_idx
+ ultisnips_idx = 0
+ UltiSnips_Manager.add_snippet(fullname, word, fullname, "i", "clang_complete")
+ return fullname
+
+def snippetsTrigger():
+ print vim.current.line
+ UltiSnips_Manager.expand()
+
+def snippetsReset():
+ UltiSnips_Manager.clear_snippets(ft="clang_complete")
+
+# vim: set ts=2 sts=2 sw=2 expandtab :
Please sign in to comment.
Something went wrong with that request. Please try again.