@@ -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
4345end
4446
45- local copilot_node_version = nil
47+ --- @return string | nil
4648function 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
6850end
6951
7052function M .buf_is_attached (bufnr )
@@ -139,11 +121,67 @@ function M.use_client(callback)
139121 )
140122end
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 )
185223end
186224
187225function 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" , {
0 commit comments