Skip to content
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

Snippet expansion and word under cursor #796

Open
3 of 9 tasks
aldantas opened this issue Apr 11, 2019 · 6 comments · May be fixed by #1196
Open
3 of 9 tasks

Snippet expansion and word under cursor #796

aldantas opened this issue Apr 11, 2019 · 6 comments · May be fixed by #1196

Comments

@aldantas
Copy link

aldantas commented Apr 11, 2019

  • Category
    • Question
    • Bug
    • Suggestion
  • OS
    • Linux
    • macOS
    • Windows
    • Etc.
  • Vim
    • Vim
    • Neovim

When the Snippet command is called, the word under cursor is automatically used as initial pattern for the search. The problem is that, once a matching is selected, the snippet keyword is inserted after the current word and hence the snippet expansion fails.

For example, if the word under cursor is 'def', one possible suggestion could be 'defm'. Upon selecting the later, the resulting text becomes 'defdefm', which is not a valid snippet keyword.

So perhaps there could be a way to prevent this, either by deleting the current word under cursor before inserting the selected keyword, or by completing the keyword instead of inserting it whole. The former solution is simpler, just replace

function! s:inject_snippet(line)
  let snip = split(a:line, "\t")[0]
  execute 'normal! a'.s:strip(snip)."\<c-r>=UltiSnips#ExpandSnippet()\<cr>"
endfunction

to

function! s:inject_snippet(line)
  let snip = split(a:line, "\t")[0]
  execute 'normal! diwi'.s:strip(snip)."\<c-r>=UltiSnips#ExpandSnippet()\<cr>"
endfunction
@maamo888
Copy link

Will this functionality change not be reflected?

I also prefer this behavior for :Snippets.

I use it in the insert mode, but now I use it with caution. :(

inoremap <c-f><c-u> <c-\><c-o>:Snippets<CR>

@junegunn @aldantas

@josefson
Copy link

josefson commented May 27, 2020

Came here looking for this as well, i'd really like for this to work out.
Right now i've been using the default g:UltiSnipsListSnippets bind which works well enough, but i dont have anyway of filtering the list down AND i gotta select with numbers.

@liskin
Copy link
Contributor

liskin commented Dec 3, 2020

I observed one additional problem with :Snippets: ultisnips often enters insert mode to let me fill in tabstops/placeholders and jump between them, but after :Snippets, this doesn't work and the cursor is positioned to the left of the first tabstop and vim is in normal mode. This happens e.g. with the vim for snippet. This is most likely because ultisnips uses :startinsert which doesn't work from :normal.

Both problems seem to be fixed by using the following:

function! s:inject_snippet(line)
  startinsert

  let col = col('.')
  if col > 1 && getline('.')[: col-2] =~ "\\S$"
    call feedkeys("\<c-w>", 'n')
  endif

  let snip = split(a:line, "\t")[0]
  call feedkeys(s:strip(snip) . "\<c-r>=UltiSnips#ExpandSnippet()\<cr>", 'n')
endfunction

together with

nnoremap <silent> <C-_> :Snippets<CR>
inoremap <silent> <C-_> <C-\><C-O>:Snippets<CR>

Can you folks please test that before I submit a pull request?

@liskin
Copy link
Contributor

liskin commented Dec 4, 2020

I didn't really like the :startinsert so I figured a better way to fix this:

function! s:inject_snippet(line)
  let ve = &ve
  set ve=onemore
  let del = col('.') > 1 && getline('.')[0 : col('.')-2] =~ "\\S$" ? "\<c-w>" : ""
  let snip = split(a:line, "\t")[0]
  execute 'normal! i'.del.s:strip(snip)
  execute 'normal! l'
  call UltiSnips#ExpandSnippet()
  let &ve = ve
endfunction

It feels solid so I submitted a PR right away: #1196

@liskin
Copy link
Contributor

liskin commented Dec 4, 2020

Oh crap, invoking UltiSnips#ExpandSnippet via call breaks the select mode. :-(

@liskin
Copy link
Contributor

liskin commented Feb 5, 2021

I just updated #1196 with a fix for another glitch, and the select mode problem goes away if the insert mode mapping uses <Cmd> instead of <C-\><C-O> (needs vim 8.2.1978+), e.g.:

inoremap <silent> <C-_> <Cmd>:Snippets<CR>

If any of you still have some problems with fzf.vim + UltiSnips, can you perhaps give my PR a try?
(If you have older vim without <Cmd>, then just revert the latest commit in the PR.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants