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

Suggestions for empty line. #5

Closed
vishfrnds opened this issue Apr 8, 2022 · 31 comments
Closed

Suggestions for empty line. #5

vishfrnds opened this issue Apr 8, 2022 · 31 comments

Comments

@vishfrnds
Copy link

Common use case of copilot is
1 write a comment
2 go to next line
3 accept suggestion

This is not working, even when I force trigger cmp (cmp.mapping.complete()) then also it does not show any completion from copilot, but has other sources like buffer.
If I write a character copilot suggestion works, but not on empty line.

@zbirenbaum
Copy link
Owner

zbirenbaum commented Apr 8, 2022

Common use case of copilot is

1 write a comment

2 go to next line

3 accept suggestion

This is not working, even when I force trigger cmp (cmp.mapping.complete()) then also it does not show any completion from copilot, but has other sources like buffer.

If I write a character copilot suggestion works, but not on empty line.

This is part of cmp. I believe cmp has a controllable number of characters required to trigger completion. Setting that to 0 may give you what you want, but there's nothing I can do on my end to force them to appear unless @hrsh7th knows something about this I am unaware of.

@vishfrnds
Copy link
Author

This is awesome plugin, but sorry for reopening this issue, as this in the main patern I use copilot as.
setting completion.keyword_length and sources[n].keyword_length as 0 makes other sources start suggesting for empty line, but not copilot.
I have also made copilot as sources[n].group_index=1 and rest as 2, still copilot needs atleast one character to trigger whereas other sources don't.

@zbirenbaum
Copy link
Owner

I did some testing. I set a hotkey to trigger copilot completions and tested it with no content on the line. The completion function triggers, but copilot returns no completions. Are you certain that copilot does this? If i type a comment character copilot completes comments fine. I guess I may be able to spoof a comment char on an empty line, but that seems weird.

@vishfrnds
Copy link
Author

Yes, it does. For example: https://youtu.be/FL70Locz6oY?t=299
Basically you type comment of what you want something like "# get current price of stocks" and then go on next line and copilot brings up funtions for it.

@zbirenbaum
Copy link
Owner

Yes, it does. For example: https://youtu.be/FL70Locz6oY?t=299

Basically you type comment of what you want something like "# get current price of stocks" and then go on next line and copilot brings up funtions for it.

I'll look into this. It may take a bit though.

@zbirenbaum
Copy link
Owner

zbirenbaum commented May 29, 2022

@vishfrnds Quick update on this. The other day I actually managed to get copilot to get a completion on a newline, but cmp refused to show it, stating something along the lines of 'no prior character to complete' even when I try to manually trigger the menu. I think that this functionality is just incompatible with the way cmp is written. Unfortunately this is just an upstream problem I don't really have control over.

I am debating attempting to make a somewhat sizable PR to cmp which would fix this, but due to the scope of what is involved it would likely sit in the development branch for ages if it gets merged at all. I'll try digging into it at some point and see if there isn't an easier way, but I really wouldn't get your hopes up.

I am working on a few mechanical things that would make this type of feature work more smoothly which will be part of a rather sizable update coming soon:tm: but I think that for the time being getting this to integrate with cmp like the other results do is simply unrealistic. I'll continue to leave this open so that I can address it with the solution once said update is out, and I will probably put it in the docs as well.

As for the example implementations, I am happy to take input. Currently I was thinking that I would create a preview window triggerable by some command with selections and code previews.

Edit: Sorry if this notifies someone who saw it on a different thread, I was on mobile and posted this comment to the wrong one a bit ago...

@jiriks74
Copy link

@zbirenbaum
Would be glad to help, but sadly I don't really know lua and don't really know how to program a neovim extension.

I was just wondering: have you figured out what was preventing copilot from creating the suggestions? From my usage I see that the popup with completion appears and then if "refreshes" with copilot completions.

What's preventing this from happening on new line?

@zbirenbaum
Copy link
Owner

zbirenbaum commented Oct 30, 2022

@zbirenbaum

Would be glad to help, but sadly I don't really know lua and don't really know how to program a neovim extension.

I was just wondering: have you figured out what was preventing copilot from creating the suggestions? From my usage I see that the popup with completion appears and then if "refreshes" with copilot completions.

What's preventing this from happening on new line?

I'm a bit confused here. You should definitely not have any problems with completions appearing. If you are, you should check your node version.

For empty lines, that's more of a cmp issue than anything. Cmp requires a prefix to trigger a completion. I got it working at one point, but it was rough because pressing tab which I think most people use to navigate completions could no longer indent.

@jiriks74
Copy link

I have no problems with completions appearing, I was just wondering why it cannot be done with an empty line.

@lysandroc
Copy link

This fix will still be appreciated

It's hard for me to understand why the cmp.complete() returns true when it should return valid entries instead from the cmp-copilot/copilot.lua.

image

@lpoto
Copy link

lpoto commented Jan 23, 2023

Hello, I have had some time to try and tackle this issue. I think something odd may happen when calling

-- line: 66, completion_functions.lua
 callback(format_completions({}, params.context, self.formatters))

Commenting this line gives the following example result (the completion is triggered immediately on the blank line):
Screenshot from 2023-01-23 16-45-45
@vishfrnds This is the desired functionality right?

@zbirenbaum I understand the point of the callback with the empty collections, but is there a way to go around this?

NOBLES5E added a commit to NOBLES5E/copilot-cmp that referenced this issue Feb 10, 2023
@lysandroc
Copy link

@zbirenbaum @vishfrnds deleting the line mentioned by @lpoto it worked for me

@lysandroc
Copy link

  • copilot autocompletion based in the existent line

image

  • copilot suggestion without any token in the line.

image

@JoseConseco
Copy link

Something is bonkers with copilot not showing any entries on empty input:
image
With "zbirenbaum/copilot.lua" -> suggestion = { enabled = true, auto_trigger=true },
you can see the virtual text is shown, but cmp popup does not have this entry (it does not have any copilot entry actually) .
Even stranger thing - ultisnip and lsp has keyword_length=2, so they should not be visible but they are. Copilot source has no keyword_length set, and it is not visible anyway.... Will check Ipoot suggestion

@JoseConseco
Copy link

Lpoto suggestion did fix the issue:
image
Cmp suggestion is now in sync with virtual text suggestion.

@zbirenbaum
Copy link
Owner

Closing since this is implemented

@ImNotaGit
Copy link

ImNotaGit commented Sep 22, 2023

Hi I see that the last comment with fix was in February and it seems that the code in completion_functions.lua has changed quite a bit since then. For some reason in the current newest commit version (72fbaa0) this issue is still present.

Edit: OK I found that on empty lines (e.g. right after a comment line) I could get the complete menu containing Copilot suggestions to show up by typing a <Space> (and then wait for about a second). When I then accept a suggestion the space would be automatically removed (this latter behavior could be specific to my settings though -- I have no clue as to which setting/plugin is responsible for removing the space).

@Zik42
Copy link

Zik42 commented Sep 25, 2023

Still having this issue. I have no suggestions on start of a blank line.

@jiriks74
Copy link

@Zik42

Still having this issue. I have no suggestions on start of a blank line.

Could you post your config?
I didn't get it either when I set it up and it was because I forgot to add copilot to cmp sources

@Zik42
Copy link

Zik42 commented Sep 25, 2023

@jiriks74 I have it added and it works in cases. When I type some symbols.
I use nvchad. This is my cmp config.


dofile(vim.g.base46_cache .. "cmp")

local cmp_ui = require("core.utils").load_config().ui.cmp
local cmp_style = cmp_ui.style

local field_arrangement = {
  atom = { "kind", "abbr", "menu" },
  atom_colored = { "kind", "abbr", "menu" },
}

local formatting_style = {
  -- default fields order i.e completion word + item.kind + item.kind icons
  fields = field_arrangement[cmp_style] or { "abbr", "kind", "menu" },

  format = function(_, item)
    local icons = require "nvchad.icons.lspkind"
    local icon = (cmp_ui.icons and icons[item.kind]) or ""

    if cmp_style == "atom" or cmp_style == "atom_colored" then
      icon = " " .. icon .. " "
      item.menu = cmp_ui.lspkind_text and "   (" .. item.kind .. ")" or ""
      item.kind = icon
    else
      icon = cmp_ui.lspkind_text and (" " .. icon .. " ") or icon
      item.kind = string.format("%s %s", icon, cmp_ui.lspkind_text and item.kind or "")
    end

    return item
  end,
}

local function border(hl_name)
  return {
    { "╭", hl_name },
    { "─", hl_name },
    { "╮", hl_name },
    { "│", hl_name },
    { "╯", hl_name },
    { "─", hl_name },
    { "╰", hl_name },
    { "│", hl_name },
  }
end

local has_words_before = function()
  if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then
    return false
  end
  local line, col = unpack(vim.api.nvim_win_get_cursor(0))
  return col ~= 0 and vim.api.nvim_buf_get_text(0, line - 1, 0, line - 1, col, {})[1]:match "^%s*$" == nil
end

local options = {
  completion = {
    completeopt = "menu,menuone",
  },

  window = {
    completion = {
      side_padding = (cmp_style ~= "atom" and cmp_style ~= "atom_colored") and 1 or 0,
      winhighlight = "Normal:CmpPmenu,CursorLine:CmpSel,Search:PmenuSel",
      scrollbar = false,
    },
    documentation = {
      border = border "CmpDocBorder",
      winhighlight = "Normal:CmpDoc",
    },
  },
  snippet = {
    expand = function(args)
      require("luasnip").lsp_expand(args.body)
    end,
  },

  formatting = formatting_style,

  mapping = {
    ["<C-p>"] = cmp.mapping.select_prev_item(),
    ["<C-n>"] = cmp.mapping.select_next_item(),
    ["<C-d>"] = cmp.mapping.scroll_docs(-4),
    ["<C-f>"] = cmp.mapping.scroll_docs(4),
    ["<C-Space>"] = cmp.mapping.complete(),
    ["<C-e>"] = cmp.mapping.close(),
    ["<CR>"] = cmp.mapping.confirm {
      behavior = cmp.ConfirmBehavior.Insert,
      select = true,
    },
    ["<Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() and has_words_before() then
        cmp.select_next_item { behavior = cmp.SelectBehavior.Select }
      elseif cmp.visible() then
        cmp.select_next_item()
      elseif require("luasnip").expand_or_jumpable() then
        vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>luasnip-expand-or-jump", true, true, true), "")
      else
        fallback()
      end
    end, {
      "i",
      "s",
    }),
    ["<S-Tab>"] = cmp.mapping(function(fallback)
      if cmp.visible() then
        cmp.select_prev_item()
      elseif require("luasnip").jumpable(-1) then
        vim.fn.feedkeys(vim.api.nvim_replace_termcodes("<Plug>luasnip-jump-prev", true, true, true), "")
      else
        fallback()
      end
    end, {
      "i",
      "s",
    }),
  },
  sources = {
    { name = "copilot" },
    { name = "nvim_lsp" },
    { name = "luasnip" },
    { name = "buffer" },
    { name = "nvim_lua" },
    { name = "path" },
  },
}

if cmp_style ~= "atom" and cmp_style ~= "atom_colored" then
  options.window.completion.border = border "CmpBorder"
end

return options

@jiriks74
Copy link

jiriks74 commented Sep 25, 2023

@Zik42

Please use ``` to create a codeblock and <details> to hide the code until clicked (you can copy-paste from below):

<details>
<summary>DescriptionOfTheCode</summary>

```
code here
```

</details>

@jiriks74
Copy link

jiriks74 commented Sep 26, 2023

@Zik42
The config looks ok afaik. Do you get copilot suggestions when the line is not empty or do you get only the other ones?

@aep
Copy link

aep commented Dec 19, 2023

Edit: OK I found that on empty lines (e.g. right after a comment line) I could get the complete menu containing Copilot suggestions to show up by typing a <Space>

this works for me, but it's somewhat annoying because for me it actually breaks indentation (astronvim),

confusingly, i'm not even sure if this is related to copilot-cmp. i think it might be copilot.lua which has different behaviour here compared to the OG github plugin

@andreykaipov
Copy link

So this might've been fixed in the past, but it's definitely not working with the current version of the code.

I dug into it and added some print statements after the Copilot API call here:

local items = vim.tbl_map(function(item)
return format.format_item(item, params.context, methods.opts)
end, vim.tbl_values(response.completions))

And when forcing a manual completion, it definitely returns results. So I don't think copilot.lua is the issue. For whatever reason cmp doesn't seem to render the completions in the menu though.

I also found that by changing the label here to something like 'a' .. multi_line.text:

label = multi_line.label,

I was able to get a Copilot completion by just idling on an empty new line:

image

Of course the indentation is off, but at least cmp now shows it.

So is it just an upstream issue with cmp? I'm not so sure because if I take the old fix above NOBLES5E@8c12903#diff-5be4b7ceb2cb4e7373fba2cdc1d29a636eb8c9a48bb5efdcd85d5286a7f3ffdf and check that out, cmp properly renders it:

image

The old version of the code is not very useable but this suggests it's not entirely cmp's issue.

I'm not sure if there's any nicer solutions. However this issue definitely still exists and should probably be reopened.

@devshoe
Copy link

devshoe commented Apr 14, 2024

@andreykaipov just used your solution and it appears to be working. I think this issue should be reopened as well

@TrustlyHampus
Copy link

I also have this issue

@JosefLitos
Copy link

JosefLitos commented Apr 17, 2024

I have spent hours to find what's happening and also found out that the suggesions are received, just don't show up.
It shouldn't be a cmp issue at all since all other sources display entries on empty/indent-only lines no problem.

The weirdest part for me is that the completion shows up for a split second when I press Backspace (with keyword_length=0). So it seems like copilot-cmp requires a non-whitespace keypress or something else weird like that?

It seems, though, that the author of this repo isn't really active anymore.

@devshoe
Copy link

devshoe commented Apr 17, 2024

Currently making do with @andreykaipov solution, modified that line. Atleast it shows after pressing space now.

@JosefLitos
Copy link

JosefLitos commented Apr 17, 2024

I tried to figure what's going on, unfortunately it seems that cmp is kind of retarded.

It forbids modifying text before the cursor, that's why indented lines don't work, because this plugin tries to replace the entire line, instead of just pasting the completion.

The second issue is a harder one to figure out. After any change to the indentation, the copilot results stop appearing.

There might be a race condition - completion function returns immediately with response isIncomplete. Commenting the isIncomplete return makes the result show up just also when there is no indentation. Whereas before without indentation I couldn't get any results to show up - ever. That doesn't look like a race condition behaviour though - it wouldn't be dependent on indentation.

I can get the completion show up twice (once more after hiding/ESCaping the completion menu), but not after that for as long as I have indentation before the cursor (but no indentation works after commenting the line mentioned above).

Also for whatever reason copilot source shows for me always as if it was group_index=0, meaning my lsp results go away unless I set nvim_lsp source to group_index=0, though I've set copilot to 2 - it just seems to ignore the value. Also the sorting stopped working - copilot always appears at the bottom (if I set everything else to groupindex 0, to show up at all.)

@JosefLitos
Copy link

JosefLitos commented Apr 18, 2024

So, I managed to find all the issues I experienced myself and fix them, though there may be some usecases I missed. I made a PR (#105) with more detailed explanation of what is actually happening.

But because it seems that this repo is kind of stale, I will try to keep up a fork myself (at least until this repo becomes active again). Right now, I just merged all other PRs (#104, #102) waiting in this repo and did a small refactor to conform to the standard cmp plugin naming conventions.

If anyone would like to try it out, and should any other issues be found, I will do my best to help.

@andreykaipov
Copy link

Thank you for your work and thorough investigation @JosefLitos. Your fork works for me! 🙏

I think I can finally migrate from copilot.vim now!

image

andreykaipov added a commit to andreykaipov/nix that referenced this issue Apr 25, 2024
a fork of copilot-cmp can now show results on empty lines

zbirenbaum/copilot-cmp#5 (comment)
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