1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-12 10:33:40 +08:00
SpaceVim/bundle/cmp-dictionary/lua/cmp_dictionary/kit/Thread/Server/init.lua

112 lines
2.8 KiB
Lua
Raw Normal View History

local uv = require('luv')
local Async = require('cmp_dictionary.kit.Async')
local Session = require('cmp_dictionary.kit.Thread.Server.Session')
---Return current executing file directory.
---@return string
local function dirname()
return debug.getinfo(2, "S").source:sub(2):match("(.*)/")
end
---@class cmp_dictionary.kit.Thread.Server
---@field private stdin uv.uv_pipe_t
---@field private stdout uv.uv_pipe_t
---@field private stderr uv.uv_pipe_t
---@field private dispatcher fun(session: cmp_dictionary.kit.Thread.Server.Session): nil
---@field private process? uv.uv_process_t
---@field private session? cmp_dictionary.kit.Thread.Server.Session
local Server = {}
Server.__index = Server
---Create new server instance.
---@param dispatcher fun(session: cmp_dictionary.kit.Thread.Server.Session): nil
---@return cmp_dictionary.kit.Thread.Server
function Server.new(dispatcher)
local self = setmetatable({}, Server)
self.dispatcher = dispatcher
self.session = Session.new()
self.process = nil
return self
end
---Connect to server.
---@return cmp_dictionary.kit.Async.AsyncTask
function Server:connect()
return Async.run(function()
Async.schedule():await()
local stdin = uv.new_pipe()
local stdout = uv.new_pipe()
local stderr = uv.new_pipe()
self.process = uv.spawn('nvim', {
cwd = uv.cwd(),
args = {
'--headless',
'--noplugin',
'-l',
('%s/_bootstrap.lua'):format(dirname()),
vim.o.runtimepath
},
stdio = { stdin, stdout, stderr }
})
stderr:read_start(function(err, data)
if err then
error(err)
end
print(data)
end)
self.session:connect(stdout, stdin)
return self.session:request('connect', {
dispatcher = string.dump(self.dispatcher)
}):await()
end)
end
---Add request handler.
---@param method string
---@param callback fun(params: table): any
function Server:on_request(method, callback)
self.session:on_request(method, callback)
end
---Add notification handler.
---@param method string
---@param callback fun(params: table)
function Server:on_notification(method, callback)
self.session:on_notification(method, callback)
end
--- Send request.
---@param method string
---@param params table
function Server:request(method, params)
if not self.process then
error('Server is not connected.')
end
return self.session:request(method, params)
end
---Send notification.
---@param method string
---@param params table
function Server:notify(method, params)
if not self.process then
error('Server is not connected.')
end
self.session:notify(method, params)
end
---Kill server process.
function Server:kill()
if self.process then
local ok, err = self.process:kill('SIGINT')
if not ok then
error(err)
end
self.process = nil
end
end
return Server