feat: add basic support for responding to requests from a language server
This commit is contained in:
		
							parent
							
								
									9cff9717c0
								
							
						
					
					
						commit
						79ba5d32cd
					
				
					 1 changed files with 39 additions and 2 deletions
				
			
		
							
								
								
									
										41
									
								
								src/LSP.zig
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								src/LSP.zig
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -29,14 +29,19 @@ pub fn term(self: *Self) void {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
pub fn send_request(self: Self, allocator: std.mem.Allocator, method: []const u8, m: anytype) !tp.message {
 | 
			
		||||
    // const frame = tracy.initZone(@src(), .{ .name = module_name ++ ".send_request" });
 | 
			
		||||
    // defer frame.deinit();
 | 
			
		||||
    var cb = std.ArrayList(u8).init(self.allocator);
 | 
			
		||||
    defer cb.deinit();
 | 
			
		||||
    try cbor.writeValue(cb.writer(), m);
 | 
			
		||||
    return self.pid.call(allocator, lsp_request_timeout, .{ "REQ", method, cb.items });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn send_response(self: Self, id: i32, m: anytype) !tp.message {
 | 
			
		||||
    var cb = std.ArrayList(u8).init(self.allocator);
 | 
			
		||||
    defer cb.deinit();
 | 
			
		||||
    try cbor.writeValue(cb.writer(), m);
 | 
			
		||||
    return self.pid.send(.{ "RSP", id, cb.items });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn send_notification(self: Self, method: []const u8, m: anytype) !void {
 | 
			
		||||
    var cb = std.ArrayList(u8).init(self.allocator);
 | 
			
		||||
    defer cb.deinit();
 | 
			
		||||
| 
						 | 
				
			
			@ -149,9 +154,12 @@ const Process = struct {
 | 
			
		|||
        var bytes: []u8 = "";
 | 
			
		||||
        var err: []u8 = "";
 | 
			
		||||
        var code: u32 = 0;
 | 
			
		||||
        var id: i32 = 0;
 | 
			
		||||
 | 
			
		||||
        if (try m.match(.{ "REQ", tp.extract(&method), tp.extract(&bytes) })) {
 | 
			
		||||
            try self.send_request(from, method, bytes);
 | 
			
		||||
        } else if (try m.match(.{ "RSP", tp.extract(&id), tp.extract(&bytes) })) {
 | 
			
		||||
            try self.send_response(id, bytes);
 | 
			
		||||
        } else if (try m.match(.{ "NTFY", tp.extract(&method), tp.extract(&bytes) })) {
 | 
			
		||||
            try self.send_notification(method, bytes);
 | 
			
		||||
        } else if (try m.match(.{"close"})) {
 | 
			
		||||
| 
						 | 
				
			
			@ -277,6 +285,35 @@ const Process = struct {
 | 
			
		|||
        try self.requests.put(id, from.clone());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn send_response(self: *Process, id: i32, result_cb: []const u8) !void {
 | 
			
		||||
        const sp = if (self.sp) |*sp| sp else return error.Closed;
 | 
			
		||||
 | 
			
		||||
        var msg = std.ArrayList(u8).init(self.allocator);
 | 
			
		||||
        defer msg.deinit();
 | 
			
		||||
        const msg_writer = msg.writer();
 | 
			
		||||
        try cbor.writeMapHeader(msg_writer, 3);
 | 
			
		||||
        try cbor.writeValue(msg_writer, "jsonrpc");
 | 
			
		||||
        try cbor.writeValue(msg_writer, "2.0");
 | 
			
		||||
        try cbor.writeValue(msg_writer, "id");
 | 
			
		||||
        try cbor.writeValue(msg_writer, id);
 | 
			
		||||
        try cbor.writeValue(msg_writer, "result");
 | 
			
		||||
        _ = try msg_writer.write(result_cb);
 | 
			
		||||
 | 
			
		||||
        const json = try cbor.toJsonAlloc(self.allocator, msg.items);
 | 
			
		||||
        defer self.allocator.free(json);
 | 
			
		||||
        var output = std.ArrayList(u8).init(self.allocator);
 | 
			
		||||
        defer output.deinit();
 | 
			
		||||
        const writer = output.writer();
 | 
			
		||||
        const terminator = "\r\n";
 | 
			
		||||
        const content_length = json.len + terminator.len;
 | 
			
		||||
        try writer.print("Content-Length: {d}\r\nContent-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n", .{content_length});
 | 
			
		||||
        _ = try writer.write(json);
 | 
			
		||||
        _ = try writer.write(terminator);
 | 
			
		||||
 | 
			
		||||
        try sp.send(output.items);
 | 
			
		||||
        self.write_log("### SEND response:\n{s}\n###\n", .{output.items});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn send_notification(self: *Process, method: []const u8, params_cb: []const u8) !void {
 | 
			
		||||
        const sp = if (self.sp) |*sp| sp else return error.Closed;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue