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

Use get_word so that the word is the same as in core.confirm #1860

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

luozhiya
Copy link

Problem

Build a CompletionResponse in the following way:

local label = cursor_before_line .. suggestions
-- CompletionResponse
{
  label = label,
  word = label,
  textEdit = {
    range = {
      start = { line = line, character = character },
      ['end'] = { line = line, character = character },
    },
    newText = suggestions,
  },
}

When cursor_before_line is e and suggestions is mail, ghost_text will show ail and will be missing a character m.
However, when you preview it from <Tab>, the mail is displayed correctly.

Solution

Use get_word so that the word is the same as in core.confirm

@liskin
Copy link

liskin commented Aug 21, 2024

This only works if there's a word field in the CompletionResponse, but it often isn't—certainly not if the completion comes from cmp-omni.

I've came up with another attempt to fix the same issue:

diff --git a/lua/cmp/view/ghost_text_view.lua b/lua/cmp/view/ghost_text_view.lua
index 19c9513..1af7ad9 100644
--- a/lua/cmp/view/ghost_text_view.lua
+++ b/lua/cmp/view/ghost_text_view.lua
@@ -88,6 +88,12 @@ ghost_text_view.text_gen = function(self, line, cursor_col)
   if self.entry:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then
     word = tostring(snippet.parse(word))
   end
+
+  local irange = self.entry:get_insert_range()
+  if irange and self.entry.source_insert_range.start.line == irange.start.line then
+    word = string.sub(line, self.entry:get_offset(), irange.start.character) .. word
+  end
+
   local word_clen = vim.str_utfindex(word)
   local cword = string.sub(line, self.entry:get_offset(), cursor_col)
   local cword_clen = vim.str_utfindex(cword)

Since cword is set as string.sub(line, self.entry:get_offset(), cursor_col), word also needs to start with the characters between self.entry:get_offset() and the start of the insert range, if the insert range doesn't start at offset. Which it doesn't for completions coming from python3complete#Complete via cmp-omni, those look like this:

  {                                                                                                                                                              
    label = "service_command(service_name)",
    labelDetails = {},
    textEdit = {
      newText = "ice_command(",
      range = {
        ["end"] = {
          character = 12,
          line = 456
        },
        start = {
          character = 12,
          line = 456
        }
      }
    }
  }

This is after typing "serv" and triggering completions. newText doesn't contain the "serv", it just appends stuff to the end.

(Also, with such textEdits, replacing is completely broken because of the silly heuristic introduced in #1177)

liskin added a commit to liskin/dotfiles that referenced this pull request Aug 21, 2024
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 this pull request may close these issues.

2 participants