Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lua/copilot/config/server.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---@alias ServerType string<'nodejs', 'binary'>

---@class (exact) ServerConfig
---@field type string<'nodejs', 'binary'> Type of the server
---@field type ServerType Type of the server
---@field custom_server_filepath? string|nil Path to the custom server file, can be absolute, relative or a file name (for PATH)

local server = {
Expand Down
7 changes: 3 additions & 4 deletions lua/copilot/lsp/binary.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local util = require("copilot.util")
local logger = require("copilot.logger")
local nodejs = require("copilot.lsp.nodejs")

local M = {
---@class copilot_server_info
Expand Down Expand Up @@ -269,10 +270,8 @@ end

---@return table
function M.get_execute_command()
return {
M.server_path or M.get_server_path(),
"--stdio",
}
local node_version = nodejs.get_node_version()
return util.get_node_args(M.server_path or M.get_server_path(), "binary", node_version)
end

---@return copilot_server_info
Expand Down
4 changes: 3 additions & 1 deletion lua/copilot/lsp/nodejs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ end

---@return table
function M.get_execute_command()
return util.append_command(M.node_command, { M.server_path or M.get_server_path(), "--stdio" })
local args = util.get_node_args(M.server_path or M.get_server_path(), "nodejs", M.node_version)

return util.append_command(M.node_command, args)
end

---@param node_command? string|string[]
Expand Down
14 changes: 14 additions & 0 deletions lua/copilot/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,18 @@ function M.append_command(cmd, append)
return full_cmd
end

---@param server_path string
---@param server_type ServerType
---@param node_version string|nil
---@return string[]
function M.get_node_args(server_path, server_type, node_version)
local args = { server_path, "--stdio" }
local node_version_major = tonumber(string.match(node_version or "", "^(%d+)%.")) or 0
if (server_type == "nodejs") and (node_version_major < 25) then
table.insert(args, 1, "--experimental-sqlite")
end

return args
end

return M
26 changes: 21 additions & 5 deletions tests/stubs/nodejs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,23 @@ function M.process(stdout, code, fail, callback)
return captured_args
end

M.valid_node_version = "22.0.0"
M.invalid_node_version = "10.0.0"
M.valid_node_version_22 = "22.0.0"
M.valid_node_version_24 = "24.0.0"
M.valid_node_version_25 = "25.0.0"

---Convenience wrapper for Stub.process for a valid Node.js version (>= 22)
function M.valid_node(callback)
return M.process("v" .. M.valid_node_version, 0, false, callback)
function M.valid_node_22(callback)
return M.process("v" .. M.valid_node_version_22, 0, false, callback)
end

---Convenience wrapper for Stub.process for a valid Node.js version (>= 22)
function M.valid_node_24(callback)
return M.process("v" .. M.valid_node_version_24, 0, false, callback)
end

function M.valid_node_25(callback)
return M.process("v" .. M.valid_node_version_25, 0, false, callback)
end

---Convenience wrapper for Stub.process for an invalid Node.js version (< 22)
Expand All @@ -53,8 +64,9 @@ function M.invalid_node(callback)
end

---@param callback function the function to call while vim.api.nvim_get_runtime_file is stubbed
---@param node_function function|nil
---@return string|nil captured_path -- the path vim.api.nvim_get_runtime_file was called with
function M.get_runtime_server_path(callback)
function M.get_runtime_server_path(callback, node_function)
local captured_path = nil

local original_get_file = vim.api.nvim_get_runtime_file
Expand All @@ -70,8 +82,12 @@ function M.get_runtime_server_path(callback)
return 1
end

if node_function == nil then
node_function = M.valid_node_25
end

-- stub valid node version for callback so setup() succeeds
M.valid_node(function()
node_function(function()
-- wrap callback in pcall to ensure vim.api.nvim_get_runtime_file is restored if callback errors
local ok, err = pcall(callback)
vim.api.nvim_get_runtime_file = original_get_file
Expand Down
34 changes: 26 additions & 8 deletions tests/test_nodejs.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,47 @@ local T = MiniTest.new_set({
T["get_node_version()"] = MiniTest.new_set()

T["get_node_version()"]["default node command"] = function()
local captured_args = stub.valid_node(function()
local captured_args = stub.valid_node_22(function()
stub.nodejs.setup()
local version, error = stub.nodejs.get_node_version()

eq(version, stub.valid_node_version)
eq(version, stub.valid_node_version_22)
eq(error, nil)
end)
eq(captured_args, { "node", "--version" })
end

T["get_node_version()"]["custom node command as string"] = function()
local captured_args = stub.valid_node(function()
local captured_args = stub.valid_node_22(function()
stub.nodejs.setup("/usr/local/bin/node")

local version, error = stub.nodejs.get_node_version()

eq(version, stub.valid_node_version)
eq(version, stub.valid_node_version_22)
eq(error, nil)
end)
eq(captured_args, { "/usr/local/bin/node", "--version" })
end

T["get_node_version()"]["custom node command as string with spaces"] = function()
local captured_args = stub.valid_node(function()
local captured_args = stub.valid_node_22(function()
stub.nodejs.setup("/path to/node")

local version, error = stub.nodejs.get_node_version()

eq(version, stub.valid_node_version)
eq(version, stub.valid_node_version_22)
eq(error, nil)
end)
eq(captured_args, { "/path to/node", "--version" })
end

T["get_node_version()"]["custom node command as table"] = function()
local captured_args = stub.valid_node(function()
local captured_args = stub.valid_node_22(function()
stub.nodejs.setup({ "mise", "x", "node@lts", "--", "node" })

local version, error = stub.nodejs.get_node_version()

eq(version, stub.valid_node_version)
eq(version, stub.valid_node_version_22)
eq(error, nil)
end)
eq(captured_args, { "mise", "x", "node@lts", "--", "node", "--version" })
Expand Down Expand Up @@ -99,6 +99,24 @@ end

T["get_execute_command()"] = MiniTest.new_set()

T["get_execute_command()"]["default node command v22, default server path"] = function()
local captured_path = stub.get_runtime_server_path(function()
eq(stub.nodejs.setup(), true)
local cmd = stub.nodejs.get_execute_command()
eq(cmd, { "node", "--experimental-sqlite", vim.fn.expand(stub.default_server_path), "--stdio" })
end, stub.valid_node_22)
eq(captured_path, stub.default_server_path)
end

T["get_execute_command()"]["default node command v24, default server path"] = function()
local captured_path = stub.get_runtime_server_path(function()
eq(stub.nodejs.setup(), true)
local cmd = stub.nodejs.get_execute_command()
eq(cmd, { "node", "--experimental-sqlite", vim.fn.expand(stub.default_server_path), "--stdio" })
end, stub.valid_node_24)
eq(captured_path, stub.default_server_path)
end

T["get_execute_command()"]["default node command, default server path"] = function()
local captured_path = stub.get_runtime_server_path(function()
eq(stub.nodejs.setup(), true)
Expand Down