New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#206 Support for on the fly generation and expansion of snippets during completion #209

merged 13 commits into from Jun 9, 2016
@@ -25,6 +25,10 @@ Omnisharp-vim can now be run with the [omnisharp-roslyn server](https://github.c
* Exact start match (case insensitive)
* CamelCase completions
* Subsequence match completions
* Completion snippets are supported. e.g. Console.WriteLine(TAB) (ENTER) will complete to Console.WriteLine(string value) and expand a dynamic snippet, this will place you in SELECT mode and the first method argument will be selected.
* Requires [UltiSnips]( and supports standard C-x C-o completion, [Supertab]( and [Neocomplete](
* Requires `set completeopt-=preview` when using [Neocomplete]( because of a compatibility issue with [UltiSnips](
* This functionality requires a recent version of Vim, you can check if your version is supported by running `:echo has("patch-7.3-598")`, it should output 1.
* Jump to the definition of a type/variable/method
* Find types/symbols interactively (requires [CtrlP]( plugin or [unite.vim]( plugin)
@@ -336,6 +340,9 @@ nnoremap <leader>sp :OmniSharpStopServer<cr>
nnoremap <leader>th :OmniSharpHighlightTypes<cr>
"Don't ask to save when changing buffers (i.e. when jumping to a type definition)
set hidden
" Enable snippet completion, requires completeopt-=preview
let g:OmniSharp_want_snippet=1
@@ -10,6 +10,7 @@ let s:server_files = '*.sln'
let s:roslyn_server_files = 'project.json'
let s:allUserTypes = ''
let s:allUserInterfaces = ''
let s:generated_snippets = {}
let g:serverSeenRunning = 0
function! OmniSharp#Complete(findstart, base) abort
@@ -26,7 +27,12 @@ function! OmniSharp#Complete(findstart, base) abort
return start
return pyeval('Completion().get_completions("s:column", "a:base")')
let omnisharp_last_completion_result = pyeval('Completion().get_completions("s:column", "a:base")')
let s:omnisharp_last_completion_dictionary = {}
for completion in omnisharp_last_completion_result
let s:omnisharp_last_completion_dictionary[get(completion, 'word')] = completion
return omnisharp_last_completion_result
@@ -583,6 +589,40 @@ function! OmniSharp#AppendCtrlPExtensions() abort
function! OmniSharp#ExpandAutoCompleteSnippet()
if !g:OmniSharp_want_snippet
if !exists("*UltiSnips#AddSnippetWithPriority")
echoerr "g:OmniSharp_want_snippet is enabled but this requires the UltiSnips plugin and it is not installed."
let line = strpart(getline('.'), 0, col('.')-1)
let remove_whitespace_regex = '^\s*\(.\{-}\)\s*$'
let completion = matchstr(line, '.*\zs\s\W.\+(.*)')
let completion = substitute(completion, remove_whitespace_regex, '\1', '')
let should_expand_completion = len(completion) != 0
if should_expand_completion
let completion = split(completion, '\.')[-1]
let completion = split(completion, 'new ')[-1]
if has_key(s:omnisharp_last_completion_dictionary, completion)
let snippet = get(get(s:omnisharp_last_completion_dictionary, completion, ''), 'snip','')
if !has_key(s:generated_snippets, completion)
call UltiSnips#AddSnippetWithPriority(completion, snippet, completion, 'iw', 'cs', 1)
let s:generated_snippets[completion] = snippet
call UltiSnips#CursorMoved()
call UltiSnips#ExpandSnippetOrJump()
function! s:find_solution_files() abort
"get the path for the current buffer
let dir = expand('%:p:h')
@@ -20,6 +20,8 @@ augroup plugin-OmniSharp
\| call OmniSharp#UpdateBuffer()
\| endif
autocmd CompleteDone <buffer> call OmniSharp#ExpandAutoCompleteSnippet()
augroup END
setlocal omnifunc=OmniSharp#Complete
@@ -87,6 +87,9 @@ endif
" Set g:OmniSharp_server_type to 'roslyn' or 'v1'
let g:OmniSharp_server_type = get(g:, 'OmniSharp_server_type', 'v1')
" Set default for snippet based completions
let g:OmniSharp_want_snippet = get(g:, 'OmniSharp_want_snippet', 0)
if !exists('g:OmniSharp_server_path')
if g:OmniSharp_server_type ==# 'v1'
let g:OmniSharp_server_path = join([expand('<sfile>:p:h:h'), 'server', 'OmniSharp', 'bin', 'Debug', 'OmniSharp.exe'], '/')
@@ -8,19 +8,26 @@ def get_completions(self, column, partialWord):
parameters['WantDocumentationForEveryCompletionResult'] = \
want_snippet = \
parameters['WantSnippet'] = want_snippet
parameters['WantMethodHeader'] = want_snippet
parameters['WantReturnType'] = want_snippet
parameters['buffer'] = '\r\n'.join(vim.eval('s:textBuffer')[:])
response = syncrequest.get_response('/autocomplete', parameters)
enc = vim.eval('&encoding')
vim_completions = []
if response is not None:
for completion in response:
complete = {
'word': completion['CompletionText'],
'menu' : completion['DisplayText'] if completion['DisplayText'] is not None else '',
'info': completion['Description'].replace('\r\n', '\n') if completion['Description'] is not None else '',
'snip': completion['Snippet'] or '',
'word': completion['MethodHeader'] or completion['CompletionText'],
'menu': completion['ReturnType'] or completion['DisplayText'],
'info': completion['Description'].replace('\r\n', '\n') or '',
'icase': 1,
ProTip! Use n and p to navigate between commits in a pull request.