Skip to content

typescript-language-server completions don't show expandable indicator until selected #1665

Description

@llllvvuu

FAQ

  • I have checked the FAQ and it didn't resolve my problem.

Announcement

Minimal reproducible full config

if has('vim_starting')
  set encoding=utf-8
endif
scriptencoding utf-8

if &compatible
  set nocompatible
endif

let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
  execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end

execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/vim-vsnip'
Plug 'neovim/nvim-lspconfig'
call plug#end()
PlugInstall | quit

" Setup global configuration. More on configuration below.
lua << EOF
vim.opt.completeopt = "menu,menuone,noselect"
local cmp = require "cmp"
cmp.setup {
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },

  mapping = {
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
    ['<Tab>'] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_next_item()
      else
        fallback()
      end
    end, { 'i', 's' }),
  },

  sources = cmp.config.sources({
    { name = "nvim_lsp" },
    { name = "buffer" },
  }),
}
EOF

lua << EOF
local capabilities = require('cmp_nvim_lsp').default_capabilities()

require'lspconfig'.cssls.setup {
  capabilities = capabilities,
}
require'lspconfig'.tsserver.setup {
  capabilities = capabilities,
  settings = {
    completions = {
      completeFunctionCalls = true,
    },
  },
}
EOF

Description

See "Steps to reproduce"

Steps to reproduce

In a new directory:

tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]
    }
  }
}

foo.ts:

export const foooooo = 5
export const foooooo1 = 5
export const foooooo2 = 5
export const foooooo3 = 5

In a new file bar.ts:

  • Write console. -> cycle through function completions. ~ will only appear once an item has been selected:
fn_completion.mp4
  • Write console.log(foo -> cycle through auto-import completions. ~ will only appear once an item has been selected:
auto_import.mp4

Expected behavior

Should show ~ upfront in menu

Actual behavior

See "Steps to reproduce"

Additional context

In typescript-language-server you can tell upfront from completionItem.data.entryNames[0].source that there will be an auto-import, but this seems to be their internal convention and not an LSP convention. additionalTextEdits is not populated until completion is resolved.

Similarly, in typescript-language-server, function snippets do not update insertText until completion resolve. But it does set InsertTextFormat.Snippet upfront.

So, I would propose that in:

nvim-cmp/lua/cmp/entry.lua

Lines 245 to 246 in c4e491a

elseif completion_item.insertTextFormat == types.lsp.InsertTextFormat.Snippet then
is_expandable = self:get_insert_text() ~= word

the following change be made:

-      is_expandable = self:get_insert_text() ~= word
+      is_expandable = self:get_insert_text() ~= completion_item.label

since I assume the indicator is supposed to indicate that you'll get a result which is different from just the label? But IDK how common this even is. The following might be preferable:

-      is_expandable = self:get_insert_text() ~= word
+      is_expandable = true

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions