Skip to content

Commit 2c3d15c

Browse files
committed
fix: multiple buffers opened cause incorrect should_attach logic
Take 2
1 parent 2d7261d commit 2c3d15c

16 files changed

+461
-67
lines changed

lua/copilot/auth/init.lua

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ local function check_status(client, callback)
210210

211211
if not err and status and status.user then
212212
auth_cache.authenticated = true
213-
else
213+
elseif not err then
214214
auth_cache.authenticated = false
215215
end
216216

@@ -224,6 +224,10 @@ end
224224
function M.is_authenticated(callback)
225225
local current_time = vim.loop.now()
226226

227+
if not c.initialized then
228+
return false
229+
end
230+
227231
if auth_cache.authenticated ~= nil then
228232
local ttl = get_cache_ttl(auth_cache.authenticated)
229233
if (current_time - auth_cache.timestamp) < ttl then
@@ -233,8 +237,6 @@ function M.is_authenticated(callback)
233237

234238
local client = c.get()
235239
if not client then
236-
auth_cache.authenticated = false
237-
auth_cache.timestamp = current_time
238240
return false
239241
end
240242

lua/copilot/client/config.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ function M.prepare_client_config(overrides, client)
116116
for _, callback in ipairs(callbacks) do
117117
callback(lsp_client)
118118
end
119+
120+
local token_env_set = (os.getenv("GITHUB_COPILOT_TOKEN") ~= nil) or (os.getenv("GH_COPILOT_TOKEN") ~= nil)
121+
122+
if token_env_set then
123+
require("copilot.auth").signin()
124+
end
119125
end)
120126
end,
121127
on_exit = function(code, _, client_id)

lua/copilot/client/init.lua

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ end
3939

4040
---@param force? boolean
4141
function M.buf_attach(force)
42+
local bufnr = vim.api.nvim_get_current_buf()
43+
4244
if lsp.initialization_failed() then
4345
logger.error("copilot-language-server failed to initialize")
4446
M.startup_error = "initialization of copilot-language-server failed"
@@ -60,21 +62,14 @@ function M.buf_attach(force)
6062
return
6163
end
6264

63-
-- In case it has changed, we update it
64-
M.config.root_dir = utils.get_root_dir(config.root_dir)
65-
6665
logger.trace("attaching to buffer")
67-
local ok, client_id_or_err = pcall(vim.lsp.start, M.config)
68-
if not ok then
69-
logger.error(string.format("failed to start LSP client: %s", client_id_or_err))
70-
return
71-
end
7266

73-
if client_id_or_err then
74-
store_client_id(client_id_or_err)
75-
else
76-
logger.error("LSP client failed to start (no client ID returned)")
67+
-- This could cause slowdowns when going into Insert mode
68+
if not vim.lsp.buf_is_attached(bufnr, M.id) then
69+
vim.lsp.buf_attach_client(bufnr, M.id)
70+
logger.trace("explicitly attached client to buffer")
7771
end
72+
7873
logger.trace("buffer attached")
7974
end
8075

@@ -89,43 +84,45 @@ function M.get()
8984
return vim.lsp.get_client_by_id(M.id)
9085
end
9186

87+
---@return boolean
9288
function M.is_disabled()
9389
return is_disabled
9490
end
9591

96-
---@param callback fun(client:table):nil
97-
function M.use_client(callback)
92+
function M.ensure_client_started()
93+
if M.id then
94+
return
95+
end
96+
9897
if is_disabled then
9998
logger.notify("copilot is offline")
10099
return
101100
end
102101

103-
local client = M.get()
104-
105-
if not client then
106-
if not M.config then
107-
logger.error("copilot.setup is not called yet")
108-
return
109-
end
102+
if not M.config then
103+
M.config = client_config.create(config)
104+
end
110105

111-
client_config.add_callback(callback)
106+
if not M.config then
107+
logger.error("copilot.setup is not called yet")
108+
return
109+
end
112110

113-
if not util.should_attach() then
114-
logger.debug("not attaching to buffer based on should_attach criteria")
115-
return
116-
end
111+
M.config.root_dir = utils.get_root_dir(config.root_dir)
112+
local client_id, err = vim.lsp.start(M.config)
117113

118-
local client_id, err = vim.lsp.start(M.config)
114+
if not client_id then
115+
logger.error(string.format("error starting LSP client: %s", err))
116+
return
117+
end
119118

120-
if not client_id then
121-
logger.error(string.format("error starting LSP client: %s", err))
122-
return
123-
end
119+
store_client_id(client_id)
120+
end
124121

125-
store_client_id(client_id)
126-
elseif not client.initialized then
127-
client_config.add_callback(callback)
128-
else
122+
---@param callback fun(client:table):nil
123+
function M.use_client(callback)
124+
local client = M.get()
125+
if client then
129126
callback(client)
130127
end
131128
end
@@ -153,9 +150,7 @@ function M.setup()
153150
end),
154151
})
155152

156-
vim.schedule(function()
157-
M.buf_attach()
158-
end)
153+
M.ensure_client_started()
159154
end
160155

161156
function M.teardown()

lua/copilot/init.lua

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ M.setup = function(opts)
2020
-- logged here to ensure the logger is setup
2121
logger.debug("active LSP config (may change runtime):", client.config)
2222

23-
local token_env_set = (os.getenv("GITHUB_COPILOT_TOKEN") ~= nil) or (os.getenv("GH_COPILOT_TOKEN") ~= nil)
24-
25-
if token_env_set then
26-
vim.schedule(auth.signin)
27-
end
28-
2923
M.setup_done = true
3024
end
3125

lua/copilot/suggestion/init.lua

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,14 @@ local function advance(count, ctx)
485485
end
486486

487487
local function schedule(ctx)
488-
-- in case we need to call the lsp API to know if we are authenticated,
489-
-- we want to retry this method after the authentication check
490-
local is_authenticated = auth.is_authenticated(function()
491-
schedule(ctx)
492-
end)
488+
local function is_authenticated()
489+
return auth.is_authenticated(function()
490+
schedule(ctx)
491+
end)
492+
end
493493

494-
if not is_enabled() or not c.initialized or not is_authenticated then
494+
-- We do not want to solve auth.is_authenticated() unless the others are true
495+
if not is_enabled() or not c.initialized or not is_authenticated() then
495496
clear()
496497
return
497498
end
@@ -723,12 +724,14 @@ end
723724
local function on_insert_enter()
724725
if should_auto_trigger() then
725726
logger.trace("suggestion on insert enter")
727+
c.buf_attach()
726728
schedule()
727729
end
728730
end
729731

730732
local function on_buf_enter()
731733
if vim.fn.mode():match("^[iR]") then
734+
logger.trace("suggestion on buf enter")
732735
on_insert_enter()
733736
end
734737
end

tests/child_helper.lua

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,23 @@ function M.new_child_neovim(test_name)
7272
for k, v in pairs(child.config) do
7373
if v ~= "" and v ~= nil then
7474
if type(v) == "string" then
75-
script = string.format(
76-
[[%s%s = {
77-
%s
78-
},
79-
]],
80-
script,
81-
k,
82-
v
83-
)
75+
if v:sub(1, 8) == "function" then
76+
script = string.format(
77+
[[%s
78+
%s = %s,]],
79+
script,
80+
k,
81+
v
82+
)
83+
else
84+
script = string.format(
85+
[[%s
86+
%s = { %s },]],
87+
script,
88+
k,
89+
v
90+
)
91+
end
8492
end
8593
end
8694
end
@@ -93,6 +101,16 @@ function M.new_child_neovim(test_name)
93101
script
94102
)
95103

104+
-- write to temporary file for debugging purposes
105+
local tmpfile = string.format("./tests/logs/test_config.txt")
106+
local file = io.open(tmpfile, "w")
107+
if file then
108+
file:write(script)
109+
file:close()
110+
else
111+
error("Could not open temporary file for writing: " .. tmpfile)
112+
end
113+
96114
child.lua(script)
97115

98116
child.lua([[
@@ -101,13 +119,13 @@ function M.new_child_neovim(test_name)
101119
return client.initialized
102120
end
103121
104-
vim.wait(30000, copilot_is_initialized, 10)
122+
vim.wait(5000, copilot_is_initialized, 10)
105123
]])
106124
end
107125

108126
function child.wait_for_suggestion()
109127
child.lua([[
110-
vim.wait(30000, function()
128+
vim.wait(5000, function()
111129
return M.suggested
112130
end, 10)
113131
]])
@@ -120,7 +138,7 @@ function M.new_child_neovim(test_name)
120138
return lines[1] and lines[1] ~= ""
121139
end
122140
123-
vim.wait(30000, function()
141+
vim.wait(5000, function()
124142
return suggestion_is_visible()
125143
end, 50)
126144
]])

tests/files/file1.txt

Whitespace-only changes.

tests/files/file2.txt

Whitespace-only changes.

tests/files/file3.txt

Whitespace-only changes.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--|---------|---------|---------|---------|---------|---------|---------|---------|
2+
01|123
3+
02|456
4+
03|7
5+
04|~
6+
05|~
7+
06|~
8+
07|~
9+
08|~
10+
09|~
11+
10|~
12+
11|~
13+
12|~
14+
13|~
15+
14|~
16+
15|~
17+
16|~
18+
17|~
19+
18|~
20+
19|~
21+
20|~
22+
21|~
23+
22|~
24+
23|tests/files/file2.txt [+] 3,2 All
25+
24|-- INSERT --
26+
27+
--|---------|---------|---------|---------|---------|---------|---------|---------|
28+
01|00000000000000000000000000000000000000000000000000000000000000000000000000000000
29+
02|00000000000000000000000000000000000000000000000000000000000000000000000000000000
30+
03|00000000000000000000000000000000000000000000000000000000000000000000000000000000
31+
04|11111111111111111111111111111111111111111111111111111111111111111111111111111111
32+
05|11111111111111111111111111111111111111111111111111111111111111111111111111111111
33+
06|11111111111111111111111111111111111111111111111111111111111111111111111111111111
34+
07|11111111111111111111111111111111111111111111111111111111111111111111111111111111
35+
08|11111111111111111111111111111111111111111111111111111111111111111111111111111111
36+
09|11111111111111111111111111111111111111111111111111111111111111111111111111111111
37+
10|11111111111111111111111111111111111111111111111111111111111111111111111111111111
38+
11|11111111111111111111111111111111111111111111111111111111111111111111111111111111
39+
12|11111111111111111111111111111111111111111111111111111111111111111111111111111111
40+
13|11111111111111111111111111111111111111111111111111111111111111111111111111111111
41+
14|11111111111111111111111111111111111111111111111111111111111111111111111111111111
42+
15|11111111111111111111111111111111111111111111111111111111111111111111111111111111
43+
16|11111111111111111111111111111111111111111111111111111111111111111111111111111111
44+
17|11111111111111111111111111111111111111111111111111111111111111111111111111111111
45+
18|11111111111111111111111111111111111111111111111111111111111111111111111111111111
46+
19|11111111111111111111111111111111111111111111111111111111111111111111111111111111
47+
20|11111111111111111111111111111111111111111111111111111111111111111111111111111111
48+
21|11111111111111111111111111111111111111111111111111111111111111111111111111111111
49+
22|11111111111111111111111111111111111111111111111111111111111111111111111111111111
50+
23|22222222222222222222222222222222222222222222222222222222222222222222222222222222
51+
24|33333333333344444444444444444444444444444444444444444444444444444444444444444444

0 commit comments

Comments
 (0)