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

Expand snippet placeholders #188

Open
martskins opened this issue Nov 27, 2020 · 8 comments
Open

Expand snippet placeholders #188

martskins opened this issue Nov 27, 2020 · 8 comments

Comments

@martskins
Copy link

Sorry if this has been documented, I have tried a few different things but I can't seem to make it work as I expect it.

What I'm trying to do is expand the completion item snippets I get from LanguageClient-neovim via a keybinding but the results I've got so far are either have it expand on CompleteDone, which doesn't really work for me because I get expansion on situations were I don't really want to expand (for example when pressing while pum is visible to delete the word I just type and try something else), or it completes and expands but it inserts the placeholders, or it doesn't do any expanding.

In order to reproduce what I'm getting you'd need this vimrc:

set nocompatible
filetype off

call plug#begin()
Plug 'autozimu/LanguageClient-neovim', { 'branch': 'next', 'do': 'bash install.sh' }
Plug 'Shougo/neosnippet.vim'
Plug 'Shougo/neosnippet-snippets'
Plug 'ervandew/supertab'
Plug 'lifepillar/vim-mucomplete'
call plug#end()

filetype plugin indent on

let g:LanguageClient_serverCommands = {}
let g:LanguageClient_serverCommands.go = ['gopls']
let g:LanguageClient_completionPreferTextEdit = 1

set completeopt=noinsert,menuone,noselect
let g:mucomplete#enable_auto_at_startup = 1
smap <C-k>     <Plug>(neosnippet_expand_or_jump)
xmap <C-k>     <Plug>(neosnippet_expand_target)
imap <expr><C-k> pumvisible() ?
  \ mucomplete#neosnippet#expand_snippet("\<c-k>")
	\ : "\<Plug>(neosnippet_expand_or_jump)"

And here's a gif of what I'm getting:

Kapture 2020-11-26 at 21 50 16

Basically what's going on there is I type log.Pri, then move to the Println entry with tab, and press <C-k>. What I would expect there is that it expands the snippet, removes the gibberish from the placeholders and then lets me jump to the placeholders with another press of <C-k>.

Note that if I comment out the LanguageClient_completionPreferTextEdit setting then <C-k> simply closes the pum, which I don't really understand why either, as I would expect it to expand the snippet anyways.

For reference, here's how that looks (even with the setting above commented) with ncm2, which I would love to replace with mucomplete, as it seems a lot simpler and lighter.

Kapture 2020-11-26 at 21 59 04

On another note, I haven't been able to figure out how to configure mucomplete to get more results in the completion menu, as you can see I only get 3 or 4 results but I would like to get more (maybe even all?) completion items there.

@lifepillar
Copy link
Owner

Does the information in :help mucomplete-compatibility (LanguageClient-neovim and Neosnippet sections) help?

@martskins
Copy link
Author

I don't think it does, no. Or at least adding those two options mentioned there doesn't seem to change anything.

@lifepillar
Copy link
Owner

What do I need on the server side to enable Go completion?

@martskins
Copy link
Author

martskins commented Nov 27, 2020

You mean which server? If that's the case then: gopls which you can find here https://github.com/golang/tools/blob/master/gopls/doc/user.md

Also, just realised that you will also need to create a .vim/settings.json file in the project directory with the following for it to use the placeholders:

{
    "initializationOptions": {
        "usePlaceholders": true
    }
}

That's for LanguageClient-neovim to pass that initialization options to gopls so that it uses the placeholders that you saw on my gif.

So the project structure to reproduce this would be something like this:

.
├── .vim
│   └── settings.json
├── go.mod
├── go.sum
└── main.go

The go.mod and go.sum files are created by the go package manager, you can create those by running go mod init.

Sorry for the incomplete instructions in the original message.

@lifepillar
Copy link
Owner

lifepillar commented Nov 29, 2020

I need more details, because expanding snippets in general appears to work for me.

Why do you need supertab? It has a mapping conflict with MUcomplete. Can you reproduce your issue without it?

Why haven't you added the 'nsnp' completion method to MUcomplete's chain? That is what allows MUcomplete to offer Neosnippets snippets as completions.

I type log.Pri, then move to the Println entry with tab, and press <C-k>. What I would expect there is that it expands the snippet, removes the gibberish from the placeholders and then lets me jump to the placeholders with another press of <C-k>.

What happens instead? I cannot find a snippet for log.Println in neosnippet-snippets/neosnippets/go.snip, hence when I type log.Println and press CTRL-K it does not expand anything. Is that a snippet you have added yourself?

Anyway, from your top animated GIF above it seems that it has expanded the snippet, so, what exactly is wrong there? I see that the placeholder has the form ${1:v…}, whereas when I expand a snippet the placeholder looks like

<`1…`>

Is that the issue? Also, in your top GIF, some error messages are shown as you are typing. I don't think that has anything to do with MUcomplete.

@martskins
Copy link
Author

Yeah sorry, supertab is not really needed here. I removed it and it's still reproducible.

About the nsnp source, I didn't add it because what I'm trying to expand is not a snippet from neosnippet, it's a snippet that is associated with a completion item, it comes from the go's language server, not neosnippet. So log.Println there is not a snippet from neosnippet, it's a completion item provided by LanguageClient-neovim and gopls.

What I'm trying to achieve here is that pressing ctrl-k completes the completion item snippet and then jumps between the arguments of the function (in this case). Here's another gif that might make things clearer:

Kapture 2020-11-29 at 10 06 46

Note that when I first press Ctrl-K the completion item snippet is expanded and the first argumet of the function is selected so that I can replace it by just typing. Pressing Ctrl-K a second time will jump to the second argument.

As for the errors, that's fine, that's just LanguageClient-neovim showing me syntax errors because the file has invalid syntax while I'm completing the snippet.

@martskins
Copy link
Author

I guess what I'm looking to do with mucomplete is what ncm2-neosnippet provides https://github.com/ncm2/ncm2-neosnippet.

trigger dynamic snippet of completed item, e.g. parameter expansion.

@martskins
Copy link
Author

martskins commented Nov 29, 2020

I managed to make this work by changing mucomplete#neosnippet#do_expand a little, here's how it ended up looking.

fun! mucomplete#neosnippet#do_expand(keys)
  let l:completed_item = v:completed_item
  let l:newtext = s:lsp_snippet(l:completed_item)
  if l:newtext !=# ''
    return neosnippet#anonymous(l:newtext)
  endif

  if get(l:completed_item, 'menu', '') =~# '[neosnippet]'
    return neosnippet#expand(l:completed_item['word'])
  endif

  return a:keys
endf

fun! s:lsp_snippet(completed_item)
  if !has_key(a:completed_item, 'user_data')
    return ''
  endif

  let l:user_data = json_decode(a:completed_item['user_data'])
  if !has_key(l:user_data, 'lspitem')
    return ''
  endif

  let l:lspitem = get(l:user_data, 'lspitem')
  if !has_key(l:lspitem, 'textEdit')
    return ''
  endif

  let l:lspitem = get(l:user_data, 'lspitem', {})
  let l:filter_text = get(l:lspitem, 'filterText')
  let l:new_text = get(l:lspitem['textEdit'], 'newText', '')
  let l:new_text = substitute(l:new_text, l:filter_text, '', '')
  return l:new_text
endf

I'm not sure of the correctness of this and if there are any other things that I should be taking into account, but that seems to work exactly the way I expected it to work for the few tests that I have ran so far.

EDIT: Well, kinda 😁 . It freezes a little while getting the suggestions for Rust this way. And there are some completion items that don't expand as expected, not sure why yet.

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

No branches or pull requests

2 participants