Strange issue with LSP and nvim-compe

I’ve been having a really odd issue with my LSP auto-complete, which I believe is likely caused by either my nvim-compe settings, or the typescript language server (or maybe just some bug?). Essentially, whenever I select an LSP completion option from compe, if I perform any action quickly afterwards, strange issues happen and my text gets all messed up.

The most reliable way I can reproduce this is to select the completion option, and then immediately exit insert mode. When I do this the last letter of the word I completed always gets repeated. In the example gif this is the first error I demo: as soon as I select test I immediately press escape to leave insert mode and then an extra t gets added to the end of test.

vimerrorexample

In the second demo, I try to type const again = test + test, but as soon as I select the first test completion and keep tying, weird things happen and some of my letters get deleted.

I have tried disabling all my plugins except for compe and my LSP related plugins and this issue persists. This issue only seems to occur from completions that come from the typescript LSP; I’ve tried with a python and lua LSP and can’t reproduce and completions that come from other sources like Buffer don’t cause the issue either. Those other completion sources all seem faster than the typescript lsp, which might be why they don’t cause the issue.

Here is my setup related to LSP and compe from my init.vim:

-- lsp setup
require'lspinstall'.setup()
local servers = require'lspinstall'.installed_servers()
for _, server in pairs(servers) do
  require'lspconfig'[server].setup{}
end


-- compe setup
require'compe'.setup {
  enabled = true;
  autocomplete = true;
  debug = false;
  min_length = 1;
  preselect = 'disable';
  throttle_time = 100;
  source_timeout = 200;
  resolve_timeout = 800;
  incomplete_delay = 400;
  max_abbr_width = 100;
  max_kind_width = 100;
  max_menu_width = 100;
  documentation = {
    border = { '', '' ,'', ' ', '', '', '', ' ' }, -- the border option is the same as `|help nvim_open_win|`
    winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder",
    max_width = 120,
    min_width = 60,
    max_height = math.floor(vim.o.lines * 0.3),
    min_height = 1,
  };

  source = {
    path = true;
    buffer = true;
    calc = false;
    nvim_lsp = true;
    nvim_lua = true;
    luasnip = true;
  };
}

-- stuff related to using tab for completion (from https://github.com/hrsh7th/nvim-compe#how-to-use-tab-to-navigate-completion-menu)
local t = function(str)
  return api.nvim_replace_termcodes(str, true, true, true)
end

local check_back_space = function()
    local col = fn.col('.') - 1
    return col == 0 or fn.getline('.'):sub(col, col):match('%s') ~= nil
end

_G.tab_complete = function()
  if fn.pumvisible() == 1 then
    return fn['compe#confirm']({keys = '<Tab>', select = true})
  elseif check_back_space() then
    return t "<Tab>"
  else
    return fn['compe#complete']()
  end
end

And here is my entire init.lua:

Has anyone dealt with something similar? I would greatly appreciate any idea or tips about anything that might be causing this issue, I’ve been pulling my hair out over this for weeks now.

Line 385 and 387 have the extra t you are going mad over.

return t "<Tab>"

Ah, that t is actually a function (defined on line 371) and isn’t what causes the extra t to show up in the example. It’s just a coincidence that the word I was demoing this with ended in a t.

For example here is the same issue, but with a repeating e:
anotheex

Great eye though! Do you have any other ideas about what could cause this?