Skip to content

Commit a1a3e7b

Browse files
authored
fix(server): use vim.system instead of jobstart to bypass shell (#560)
Switch the server launch from vim.fn.jobstart to vim.system, passing the binary and JSON settings as a list. Neovim spawns the process directly instead of going through the user's shell, removing the Windows-specific "-escaping hack that only worked for POSIX-style shells, otherwise it prevented the Go server from starting.
1 parent 9c9fc89 commit a1a3e7b

2 files changed

Lines changed: 37 additions & 45 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ To view these help docs and to get more detailed help information, please run `:
1818

1919
## Requirements
2020

21+
- <a href="https://neovim.io/">Neovim</a> >= v0.10
2122
- <a href="https://go.dev/">Go</a> >= v1.25.1
2223

2324
## Quick Start

lua/gitlab/server.lua

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
-- This module contains the logic responsible for building and starting
22
-- the Golang server. The Go server is responsible for making API calls
33
-- to Gitlab and returning the data
4-
local List = require("gitlab.utils.list")
54
local state = require("gitlab.state")
65
local u = require("gitlab.utils")
76
local job = require("gitlab.job")
@@ -62,58 +61,50 @@ M.start = function(callback)
6261
state.chosen_mr_iid = 0 -- Do not let this interfere with subsequent reviewer.open() calls
6362

6463
local settings = vim.json.encode(go_server_settings)
65-
if vim.fn.has("win32") then
66-
settings = settings:gsub('"', '\\"')
67-
end
68-
69-
local command = string.format('"%s" "%s"', state.settings.server.binary, settings)
7064

71-
local job_id = vim.fn.jobstart(command, {
72-
on_stdout = function(_, data)
73-
-- if port was not provided then we need to parse it from output of server
74-
if parsed_port == nil then
75-
for _, line in ipairs(data) do
76-
port = line:match("Server started on port:%s+(%d+)")
77-
if port ~= nil then
78-
parsed_port = port
79-
state.settings.server.port = port
80-
break
81-
end
82-
end
83-
end
65+
local stderr_buf = ""
8466

85-
-- This assumes that first output of server will be parsable and port will be correctly set.
86-
-- Make sure that this actually check if port was correctly parsed based on server output
87-
-- because server outputs port only if it started successfully.
88-
if parsed_port ~= nil and not callback_called then
89-
state.go_server_running = true
90-
callback()
91-
callback_called = true
67+
local ok, err = pcall(vim.system, { state.settings.server.binary, settings }, {
68+
stdout = function(_, data)
69+
if data == nil or parsed_port ~= nil then
70+
return
9271
end
93-
end,
94-
on_stderr = function(_, errors)
95-
local err_msg = List.new(errors):reduce(function(agg, err)
96-
if err ~= "" and err ~= nil then
97-
agg = agg .. err .. "\n"
72+
for line in data:gmatch("[^\r\n]+") do
73+
local matched = line:match("Server started on port:%s+(%d+)")
74+
if matched ~= nil then
75+
parsed_port = matched
76+
vim.schedule(function()
77+
state.settings.server.port = matched
78+
state.go_server_running = true
79+
if not callback_called then
80+
callback_called = true
81+
callback()
82+
end
83+
end)
84+
break
9885
end
99-
return agg
100-
end, "")
101-
102-
if err_msg ~= "" then
103-
u.notify(err_msg, vim.log.levels.ERROR)
10486
end
10587
end,
106-
on_exit = function(job_id, exit_code)
107-
if exit_code ~= 0 then
108-
u.notify(
109-
"Golang gitlab server exited: job_id: " .. job_id .. ", exit_code: " .. exit_code,
110-
vim.log.levels.ERROR
111-
)
88+
stderr = function(_, data)
89+
if data == nil or data == "" then
90+
return
11291
end
92+
stderr_buf = stderr_buf .. data
11393
end,
114-
})
115-
if job_id <= 0 then
116-
u.notify("Could not start gitlab.nvim binary", vim.log.levels.ERROR)
94+
}, function(out)
95+
if out.code ~= 0 then
96+
vim.schedule(function()
97+
local msg = "Golang gitlab server exited: code: " .. out.code .. ", signal: " .. (out.signal or 0)
98+
if stderr_buf ~= "" then
99+
msg = msg .. ", msg: " .. vim.trim(stderr_buf)
100+
end
101+
u.notify(msg, vim.log.levels.ERROR)
102+
end)
103+
end
104+
end)
105+
106+
if not ok then
107+
u.notify("Could not start gitlab.nvim binary: " .. tostring(err), vim.log.levels.ERROR)
117108
end
118109
end
119110

0 commit comments

Comments
 (0)