nvim-cmp icon indicating copy to clipboard operation
nvim-cmp copied to clipboard

Broken replace behavior

Open nmrtv opened this issue 2 years ago • 8 comments

After 27bc575d1ef83fa3260c0b56cf60f3496cfab68d commit, replace behavior no longer works with Pyright LSP server when confirming entries that have auto imports. Instead of replacing text, it behaves like insert. Without auto imports, everything works as expected.

After a little investigation, I found that "2" statement is called with auto imports and "3" without them.

---Return replace range
---@return lsp.Range|nil
entry.get_replace_range = function(self)
  return self.cache:ensure({ 'get_replace_range', self.resolved_completion_item and 1 or 0 }, function()
    local replace_range
    if misc.safe(self:get_completion_item().textEdit) then
      if misc.safe(self:get_completion_item().textEdit.replace) then
        print('1')
        replace_range = self:get_completion_item().textEdit.replace
      else
        print('2') -- Called with auto imports and behaves like insert
        replace_range = self:get_completion_item().textEdit.range
      end
    else
      print('3') -- Called without auto imports and behaves as replace
      replace_range = {
        start = {
          line = self.source_replace_range.start.line,
          character = math.min(misc.to_utfindex(self.context.cursor_line, self:get_offset()), self.source_replace_range.start.character),
        },
        ['end'] = self.source_replace_range['end'],
      }
    end
    return replace_range
  end)
end

After reverting this commit, the issue disappears.

nmrtv avatar Aug 27 '22 00:08 nmrtv

Related: https://github.com/hrsh7th/nvim-cmp/pull/1148

fwiw, the behavior is consistent with vscode (editor.suggest.insertMode set to replace) for both clangd and pylance

Possible patch

diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua
index 6fa5460..7d9e023 100644
--- a/lua/cmp/entry.lua
+++ b/lua/cmp/entry.lua
@@ -339,7 +339,9 @@ entry.get_replace_range = function(self)
       else
         replace_range = self:get_completion_item().textEdit.range
       end
-    else
+    end
+
+    if not replace_range or (self.context.cursor.character == replace_range['end'].character) then
       replace_range = {
         start = {
           line = self.source_replace_range.start.line,

EDIT: nvm, this breaks jsonls.. EDIT2: update

lvimuser avatar Aug 27 '22 01:08 lvimuser

I tried editor.suggest.insertMode = replace and there is one difference. When the word exactly matches the suggestion, vscode does not change it. So behavior is not consistent after all. Sometimes I use autocomplete with exactly the same word for a quick auto import.

nmrtv avatar Aug 27 '22 01:08 nmrtv

The proposed patch resolves the issue.

nmrtv avatar Aug 27 '22 01:08 nmrtv

I tried editor.suggest.insertMode = replace and there is one difference. When the word exactly matches the suggestion, vscode does not change it. So behavior is not consistent after all. Sometimes I use autocomplete with exactly the same word for a quick auto import.

Oh I didn't try that, just wo, accept word -> woword.

Possibly related https://github.com/clangd/clangd/issues/1041 https://github.com/clangd/clangd/issues/613 https://github.com/clangd/clangd/issues/387

EDIT: Can you try the patch again? It broke jsonls, i've updated it.

lvimuser avatar Aug 27 '22 21:08 lvimuser

Finally, I think this vscode behavior is not intentional. This is probably a bug. Otherwise, I can't understand the logic of why replace works like insert. Their own documentation says that:

// Controls whether words are overwritten when accepting completions. Note that this depends on extensions opting into this feature.
  //  - insert: Insert suggestion without overwriting text right of the cursor.
  //  - replace: Insert suggestion and overwrite text right of the cursor.
  "editor.suggest.insertMode": "insert",

nmrtv avatar Aug 27 '22 21:08 nmrtv

Can you try the patch again? It broke jsonls, i've updated it.

Everything works as expected.

nmrtv avatar Aug 27 '22 21:08 nmrtv

Sorry for annoying but the VSCode's implementation is the same as the current main branch. So I think the bug is previous implementation. https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/suggest/browser/suggest.ts#L239 https://github.com/microsoft/vscode/blob/main/src/vs/editor/contrib/suggest/browser/suggest.ts#L101

hrsh7th avatar Aug 30 '22 05:08 hrsh7th

I don't know which branch you are talking about. As for nvim-cmp, it behaves similarly, but not quite the same (there are differences depending on auto-import as I mentioned). Regarding vscode, in the last update, this problem exists and vscode behaves completely unpredictably. Depending on where the cursor is in the word, it sometimes replaces and sometimes inserts (checked with version 1.70.2 2022-08-16). I think the least you need to do is copy vscode because it always had a bunch of problems.

nmrtv avatar Aug 30 '22 22:08 nmrtv