Closed raine closed 1 year ago
You can do something like this...
Set initial vim.g.copilot_status
:
vim.api.nvim_set_var("copilot_status", "")
After calling require("copilot").setup()
:
local api = require("copilot.api")
api.register_status_notification_handler(function (data)
vim.api.nvim_set_var("copilot_status", data.status)
end)
Then in your statusline you can use that value:
local copilot_status = vim.api.nvim_get_var("copilot_status")
if copilot_status == "Normal" then
-- idle
elseif copilot_status == "InProgress" then
-- processing
elseif copilot_status == "Warning" then
-- something went wrong
else
-- unknown
end
Thanks @MunifTanjim.
I'm trying to make that work with lualine.nvim, but I think the issue left is that lualine only refreshes periodically and you won't get real time updates on copilot's status. I tried to work around it like so:
vim.keymap.set("i", "<M-]>", function ()
require("copilot.suggestion").next()
require("lualine").refresh()
end, {
desc = "[copilot] next suggestion",
silent = true,
})
It doesn't seem to work. I wonder if the issue is that call on next()
blocks until suggestion is ready.
edit: Okay, I wasn't thinking. Of course I can just call require('lualine').refresh()
on api.register_status_notification_handler
callback.
@raine did you manage to get it working? I think mine is more or less working
on copilot.config I do:
vim.api.nvim_set_var("copilot_status", "")
api.register_status_notification_handler(function(data)
vim.api.nvim_set_var("copilot_status", data.status)
lualine.refresh()
end)
And on my lualine module I have:
lualine_x = {
{
function()
local _, copilot_status = pcall(vim.api.nvim_get_var("copilot_status"))
if copilot_status == "Normal" then
return "O"
elseif copilot_status == "InProgress" then
return "!"
elseif copilot_status == "Error" then
return "X"
else
return ""
end
end
}
},
but it's not really showing anything
If you set vim.api.nvim_set_var("copilot_status", "")
before that variable is ever read, you can get rid of the pcall
(which is kinda slow).
but it's not really showing anything
I think your pcall
syntax is not correct... it should be pcall(vim.api.nvim_get_var, "copilot_status")
.
@brunobmello25
hey @MunifTanjim , thanks for the help! indeed it was a problem in the pcall
syntax, I'm not really good with lua hehehe
now it's working fine. I think it's best to maintain that pcall because I have no way of guaranteeing that there will be no call to that variable before it's initialized
thanks a lot! Now I just have to find better icons lol
Btw, I think that this might be a nice feature to integrate within this plugin. I'll see if I can work on this integration a bit better and open a PR at some time
Well the feature is already there, kinda. You subscribe to the status change using api.register_status_notification_handler
and then use the value in your statusline plugin of choice.
Although, it would be nice if the virtual text could display a loading indicator when suggestions are loading.
I thought that maybe we could add an easier integration feature? like for example:
copilot.setup({
integrations = {
lualine = true
}
})
and then maybe we could provide customization options, like:
copilot.setup({
integrations = {
lualine = {
idle_icon = "...",
loading_icon = "...",
}
}
})
There are a whole bunch of statusline plugins 😂 lualine / feline / galaxyline / expressline / neoline / windline / nougat and many more.
I wouldn't want to add integration with any specific statusline plugin, because that opens the door to other statusline plugins as well. It'll not be good for maintenance.
Maybe it could provide building blocks for integrating it yourself:
Expose a function that returns the current status, perhaps in a way that can be plugged into status line as is, if you can think of good defaults what it would show. For example with lualine, you could use the function like so:
local lualine = require 'lualine'
local config = {
sections = {
-- ...
lualine_c = {'filename', require('copilot.api').get_status_line_text},
},
}
Allow passing copilot.lua
 the function as an option that should be called when status line should be updated.
copilot.setup({
on_status_update = require('lualine').refresh
})
By the way, yes, I got it working and it's definitely on improvement, but it still feels like something is missing. It's probably the case when you ask for next suggestion and nothing just happens, no change in status or anything. It leaves you a bit confused because you can't tell what the issue is; copilot just doesn't have any results or what. Maybe the virtual text way @MunifTanjim mentioned could also say something if no results were found or any other reason why nothing gets suggested.
There are a whole bunch of statusline plugins joy lualine / feline / galaxyline / expressline / neoline / windline / nougat and many more.
I wouldn't want to add integration with any specific statusline plugin, because that opens the door to other statusline plugins as well. It'll not be good for maintenance.
This is 100% correct. The purpose of copilot.lua has always been to provide the out of the box functionality provided by copilot.vim + a general api for other people to build on top of which copilot.vim lacks. That's why despite being the most popular use case, cmp integration is in its own repo.
For the record, this is already pretty easy to implement in every status line I know of. If your statusline doesn't allow you to update components by providing a function, I would recommend using something more modern. Lualine, Heirline, and Feline all support this.
It should be plenty for almost modern statuslines to do the following:
local M = { init = false }
local status = ''
local setup = function ()
local api = require('copilot.api')
api.register_status_notification_handler(function(data)
-- customize your message however you want
if data.status == 'Normal' then
status = 'Ready'
elseif data.status == 'InProgress' then
status = 'Pending'
else
status = data.status or 'Offline' -- might never actually be nil but just in case
end
status = 'Copilot: ' .. status
end)
end
M.get_status = function ()
if not M.init then
setup()
M.init = true
end
return status
end
return M
Inside your statusline config:
copilot_status = require('above_module').get_status
For lualine:
sections = { lualine_a = { copilot_status } }
For Feline:
copilot_component = {
provider = copilot_status,
hl = { fg = colors.vibrant_green, bg = 'NONE'},
left_sep = {
str = ' ',
hl = { fg = 'NONE', bg = 'NONE', },
},
right_sep = {
str = ' ',
hl = { fg = 'NONE', bg = 'NONE', },
}
}
`components.active[1] = { copilot_component }
For the record, I pulled the feline example straight from my config, and it updates in realtime with virtually no delay regardless of if I'm using copilot-cmp, panel completions, etc.
Since this feature is out of the scope of the project, I am going to close this, but if the users here would like a wiki linked in the docs that people can PR with examples of integrating copilot.lua with various individual plugins, I would be open to that. If that's something you would like to see, please open a new issue titled 'Feature: User Integrations Wiki' or similar and just link this issue in the description.
Hello,
Would it be possible to get some kind of indicator in for example statusbar, that copilot is fetching a suggestion?
Sometimes on hitting next suggestion I keep waiting and waiting and nothing ever comes up, and you can never be sure if it's just slow or not doing anything at all.
Thoughts? Thanks.