Skip to content

Commit 8b0fd23

Browse files
committed
feat(client): better startup error
1 parent 21d8ef6 commit 8b0fd23

File tree

3 files changed

+74
-38
lines changed

3 files changed

+74
-38
lines changed

lua/copilot/client.lua

Lines changed: 69 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ local M = {
99
id = nil,
1010
capabilities = nil,
1111
config = nil,
12+
node_version = nil,
13+
startup_error = nil,
1214
}
1315

1416
---@param id number
@@ -42,29 +44,9 @@ if not lsp_start then
4244
end
4345
end
4446

45-
local copilot_node_version = nil
47+
---@return string|nil
4648
function M.get_node_version()
47-
if not copilot_node_version then
48-
local node_version = string.match(
49-
table.concat(vim.fn.systemlist(config.get("copilot_node_command") .. " --version", nil, false)) or "",
50-
"v(%S+)"
51-
)
52-
53-
if not node_version then
54-
error("[Copilot] Node.js not found")
55-
end
56-
57-
local node_version_major = tonumber(string.match(node_version, "^(%d+)%."))
58-
if node_version_major < 16 then
59-
vim.notify(
60-
string.format("[Copilot] Node.js version 16.x or newer required but found %s", copilot_node_version),
61-
vim.log.levels.ERROR
62-
)
63-
end
64-
65-
copilot_node_version = node_version
66-
end
67-
return copilot_node_version
49+
return M.node_version
6850
end
6951

7052
function M.buf_is_attached(bufnr)
@@ -139,11 +121,67 @@ function M.use_client(callback)
139121
)
140122
end
141123

142-
M.merge_server_opts = function(params)
124+
local function prepare_client_config(overrides)
125+
local node = config.get("copilot_node_command")
126+
127+
if vim.fn.executable(node) ~= 1 then
128+
local err = string.format("copilot_node_command(%s) is not executable", node)
129+
vim.notify("[Copilot] " .. err, vim.log.levels.ERROR)
130+
M.startup_error = err
131+
return
132+
end
133+
134+
if not M.node_version then
135+
local cmd = node .. " --version"
136+
local cmd_output = table.concat(vim.fn.systemlist(cmd, nil, false))
137+
local cmd_exit_code = vim.v.shell_error
138+
139+
local node_version = string.match(cmd_output, "v(%S+)") or ""
140+
local node_version_major = tonumber(string.match(node_version, "^(%d+)%.")) or 0
141+
142+
if node_version_major == 0 then
143+
local err = "Could not determine Node.js version"
144+
vim.notify("[Copilot] " .. err, vim.log.levels.ERROR)
145+
M.startup_error = table.concat({
146+
err,
147+
"\n",
148+
"-----------",
149+
"\n",
150+
"(exit code) ",
151+
tostring(cmd_exit_code),
152+
"\n",
153+
" (output) ",
154+
cmd_output,
155+
"\n",
156+
"-----------",
157+
})
158+
return
159+
end
160+
161+
if node_version_major < 16 then
162+
local err = string.format("Node.js version 16.x or newer required but found %s", node_version)
163+
vim.notify("[Copilot] " .. err, vim.log.levels.ERROR)
164+
M.startup_error = err
165+
return
166+
end
167+
168+
M.node_version = node_version
169+
end
170+
171+
local agent_path = vim.api.nvim_get_runtime_file("copilot/index.js", false)[1]
172+
if vim.fn.filereadable(agent_path) == 0 then
173+
local err = string.format("Could not find agent.js (bad install?) : %s", agent_path)
174+
vim.notify("[Copilot] " .. err, vim.log.levels.ERROR)
175+
M.startup_error = err
176+
return
177+
end
178+
179+
M.startup_error = nil
180+
143181
return vim.tbl_deep_extend("force", {
144182
cmd = {
145-
params.copilot_node_command,
146-
require("copilot.util").get_copilot_path(),
183+
node,
184+
agent_path,
147185
},
148186
root_dir = vim.loop.cwd(),
149187
name = "copilot",
@@ -160,7 +198,7 @@ M.merge_server_opts = function(params)
160198
local set_editor_info_params = util.get_editor_info()
161199
set_editor_info_params.editorInfo.version = set_editor_info_params.editorInfo.version
162200
.. " + Node.js "
163-
.. M.get_node_version()
201+
.. (M.get_node_version() or "")
164202
set_editor_info_params.editorConfiguration = util.get_editor_configuration()
165203
set_editor_info_params.networkProxy = util.get_network_proxy()
166204
api.set_editor_info(client, set_editor_info_params, function(err)
@@ -181,23 +219,19 @@ M.merge_server_opts = function(params)
181219
PanelSolutionsDone = api.handlers.PanelSolutionsDone,
182220
statusNotification = api.handlers.statusNotification,
183221
},
184-
}, params.server_opts_overrides or {})
222+
}, overrides)
185223
end
186224

187225
function M.setup()
188-
is_disabled = false
226+
M.config = prepare_client_config(config.get("server_opts_overrides"))
189227

190-
M.config = M.merge_server_opts(config.get())
191-
192-
if vim.fn.executable(M.config.cmd[1]) ~= 1 then
228+
if not M.config then
193229
is_disabled = true
194-
vim.notify(
195-
string.format("[copilot] copilot_node_command(%s) is not executable", M.config.cmd[1]),
196-
vim.log.levels.ERROR
197-
)
198230
return
199231
end
200232

233+
is_disabled = false
234+
201235
vim.api.nvim_create_augroup(M.augroup, { clear = true })
202236

203237
vim.api.nvim_create_autocmd("FileType", {

lua/copilot/command.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ function mod.version()
2323
lines[#lines + 1] = "copilot/dist/agent.js" .. " " .. "not running"
2424
end
2525

26-
local found_node_version, node_version = pcall(c.get_node_version)
27-
lines[#lines + 1] = "Node.js" .. " " .. (found_node_version and node_version or "not found")
26+
local node_version = c.get_node_version()
27+
lines[#lines + 1] = "Node.js" .. " " .. (node_version or "not found")
2828

2929
vim.api.nvim_echo(
3030
vim.tbl_map(function(line)
@@ -52,7 +52,8 @@ function mod.status()
5252
end
5353

5454
if c.is_disabled() then
55-
flush_lines("Offline")
55+
add_line("Offline")
56+
flush_lines(c.startup_error)
5657
return
5758
end
5859

lua/copilot/util.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ function M.get_network_proxy()
278278
}
279279
end
280280

281+
---@deprecated
281282
M.get_copilot_path = function()
282283
local copilot_path = vim.api.nvim_get_runtime_file("copilot/index.js", false)[1]
283284
if vim.fn.filereadable(copilot_path) ~= 0 then

0 commit comments

Comments
 (0)