mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local mpack = vim.mpack
 | 
						|
 | 
						|
local Response = {}
 | 
						|
Response.__index = Response
 | 
						|
 | 
						|
function Response.new(msgpack_rpc_stream, request_id)
 | 
						|
  return setmetatable({
 | 
						|
    _msgpack_rpc_stream = msgpack_rpc_stream,
 | 
						|
    _request_id = request_id,
 | 
						|
  }, Response)
 | 
						|
end
 | 
						|
 | 
						|
function Response:send(value, is_error)
 | 
						|
  local data = self._msgpack_rpc_stream._session:reply(self._request_id)
 | 
						|
  if is_error then
 | 
						|
    data = data .. self._msgpack_rpc_stream._pack(value)
 | 
						|
    data = data .. self._msgpack_rpc_stream._pack(mpack.NIL)
 | 
						|
  else
 | 
						|
    data = data .. self._msgpack_rpc_stream._pack(mpack.NIL)
 | 
						|
    data = data .. self._msgpack_rpc_stream._pack(value)
 | 
						|
  end
 | 
						|
  self._msgpack_rpc_stream._stream:write(data)
 | 
						|
end
 | 
						|
 | 
						|
--- @class test.MsgpackRpcStream
 | 
						|
--- @field private _stream test.Stream
 | 
						|
--- @field private __pack table
 | 
						|
local MsgpackRpcStream = {}
 | 
						|
MsgpackRpcStream.__index = MsgpackRpcStream
 | 
						|
 | 
						|
function MsgpackRpcStream.new(stream)
 | 
						|
  return setmetatable({
 | 
						|
    _stream = stream,
 | 
						|
    _pack = mpack.Packer(),
 | 
						|
    _session = mpack.Session({
 | 
						|
      unpack = mpack.Unpacker({
 | 
						|
        ext = {
 | 
						|
          -- Buffer
 | 
						|
          [0] = function(_c, s)
 | 
						|
            return mpack.decode(s)
 | 
						|
          end,
 | 
						|
          -- Window
 | 
						|
          [1] = function(_c, s)
 | 
						|
            return mpack.decode(s)
 | 
						|
          end,
 | 
						|
          -- Tabpage
 | 
						|
          [2] = function(_c, s)
 | 
						|
            return mpack.decode(s)
 | 
						|
          end,
 | 
						|
        },
 | 
						|
      }),
 | 
						|
    }),
 | 
						|
  }, MsgpackRpcStream)
 | 
						|
end
 | 
						|
 | 
						|
function MsgpackRpcStream:write(method, args, response_cb)
 | 
						|
  local data
 | 
						|
  if response_cb then
 | 
						|
    assert(type(response_cb) == 'function')
 | 
						|
    data = self._session:request(response_cb)
 | 
						|
  else
 | 
						|
    data = self._session:notify()
 | 
						|
  end
 | 
						|
 | 
						|
  data = data .. self._pack(method) .. self._pack(args)
 | 
						|
  self._stream:write(data)
 | 
						|
end
 | 
						|
 | 
						|
function MsgpackRpcStream:read_start(request_cb, notification_cb, eof_cb)
 | 
						|
  self._stream:read_start(function(data)
 | 
						|
    if not data then
 | 
						|
      return eof_cb()
 | 
						|
    end
 | 
						|
    local type, id_or_cb, method_or_error, args_or_result
 | 
						|
    local pos = 1
 | 
						|
    local len = #data
 | 
						|
    while pos <= len do
 | 
						|
      type, id_or_cb, method_or_error, args_or_result, pos = self._session:receive(data, pos)
 | 
						|
      if type == 'request' or type == 'notification' then
 | 
						|
        if type == 'request' then
 | 
						|
          request_cb(method_or_error, args_or_result, Response.new(self, id_or_cb))
 | 
						|
        else
 | 
						|
          notification_cb(method_or_error, args_or_result)
 | 
						|
        end
 | 
						|
      elseif type == 'response' then
 | 
						|
        if method_or_error == mpack.NIL then
 | 
						|
          method_or_error = nil
 | 
						|
        else
 | 
						|
          args_or_result = nil
 | 
						|
        end
 | 
						|
        id_or_cb(method_or_error, args_or_result)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end)
 | 
						|
end
 | 
						|
 | 
						|
function MsgpackRpcStream:read_stop()
 | 
						|
  self._stream:read_stop()
 | 
						|
end
 | 
						|
 | 
						|
function MsgpackRpcStream:close(signal)
 | 
						|
  self._stream:close(signal)
 | 
						|
end
 | 
						|
 | 
						|
return MsgpackRpcStream
 |