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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Provides the necessary building blocks to develop Language Server Protocol imple
# Installation

> [!NOTE]
> The default branch requires Zig `0.16.0-dev.1458+755a3d957` or later. Checkout the `0.15.x` branch when using Zig 0.15
> The default branch requires Zig `0.16.0-dev.1859+212968c57` or later. Checkout the `0.15.x` branch when using Zig 0.15

```bash
# Initialize a `zig build` project if you haven't already
Expand Down
1 change: 1 addition & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub fn build(b: *std.Build) void {
.root_module = b.addModule("lsp-codegen", .{
.root_source_file = b.path("src/codegen/codegen.zig"),
.target = b.graph.host,
.single_threaded = true,
}),
});
// The metaModel.json file should be removed once https://github.com/ziglang/zig/issues/17895 has been resolved.
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.{
.name = .lsp_kit,
.version = "0.1.0",
.minimum_zig_version = "0.16.0-dev.1458+755a3d957",
.minimum_zig_version = "0.16.0-dev.1859+212968c57",
.dependencies = .{},
.paths = .{
"build.zig",
Expand Down
17 changes: 7 additions & 10 deletions examples/hello_client.zig
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn main() !void {
_ = debug_allocator.deinit();
};

var threaded: std.Io.Threaded = .init(gpa);
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.ioBasic();

Expand All @@ -66,10 +66,7 @@ pub fn main() !void {

if (args.len < 3) fatalWithUsage("expected at least 2 arguments but got {d}", .{args.len - 1});

const input_file = (if (@hasDecl(std, "io"))
std.fs.cwd().readFileAlloc(gpa, args[1], std.math.maxInt(u32))
else
std.fs.cwd().readFileAlloc(args[1], gpa, .limited(std.math.maxInt(u32)))) catch |err|
const input_file = std.Io.Dir.cwd().readFileAlloc(io, args[1], gpa, .limited(std.math.maxInt(u32))) catch |err|
fatal("failed to read file '{s}': {}", .{ args[1], err });
defer gpa.free(input_file);

Expand All @@ -79,7 +76,7 @@ pub fn main() !void {
child_process.stdout_behavior = .Pipe;
child_process.stderr_behavior = if (show_langauge_server_stderr) .Inherit else .Ignore;

child_process.spawn() catch |err| fatal("child process could not be created: {}", .{err});
child_process.spawn(io) catch |err| fatal("child process could not be created: {}", .{err});
child_process.waitForSpawn() catch |err| fatal("child process could not be created: {}", .{err});

// Language servers can support multiple communication channels (e.g. stdio, pipes, sockets).
Expand Down Expand Up @@ -211,14 +208,14 @@ pub fn main() !void {
);

// The "exit" notification will ask the server to exit its process. Ideally we should wait with a timeout in case the server is not behaving correctly.
_ = try child_process.wait();
_ = try child_process.wait(io);
}

fn fatalWithUsage(comptime format: []const u8, args: anytype) noreturn {
{
const stderr, _ = std.debug.lockStderrWriter(&.{});
defer std.debug.unlockStderrWriter();
stderr.writeAll(usage) catch {};
const stderr = std.debug.lockStderr(&.{}).terminal();
defer std.debug.unlockStderr();
stderr.writer.writeAll(usage) catch {};
}
std.log.err(format, args);
std.process.exit(1);
Expand Down
2 changes: 1 addition & 1 deletion examples/hello_server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn main() !void {
_ = debug_allocator.deinit();
};

var threaded: std.Io.Threaded = .init(gpa);
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.ioBasic();

Expand Down
2 changes: 1 addition & 1 deletion examples/my_first_server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn main() !void {
_ = debug_allocator.deinit();
};

var threaded: std.Io.Threaded = .init(gpa);
var threaded: std.Io.Threaded = .init(gpa, .{});
defer threaded.deinit();
const io = threaded.ioBasic();

Expand Down
13 changes: 8 additions & 5 deletions src/codegen/codegen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub fn main() !u8 {

const gpa = debug_allocator.allocator();

var threaded: std.Io.Threaded = .init_single_threaded;
const io = threaded.ioBasic();

var arg_it: std.process.ArgIterator = try .initWithAllocator(gpa);
defer arg_it.deinit();

Expand All @@ -26,18 +29,18 @@ pub fn main() !u8 {
var zig_tree: std.zig.Ast = try .parse(gpa, source, .zig);
defer zig_tree.deinit(gpa);

std.fs.cwd().makePath(std.fs.path.dirname(out_file_path) orelse ".") catch {};
std.Io.Dir.cwd().createDirPath(io, std.fs.path.dirname(out_file_path) orelse ".") catch {};

var out_file = try std.fs.cwd().createFile(out_file_path, .{});
defer out_file.close();
var out_file = try std.Io.Dir.cwd().createFile(io, out_file_path, .{});
defer out_file.close(io);

if (zig_tree.errors.len != 0) {
std.log.warn("generated file contains syntax errors! (cannot format file)", .{});
try out_file.writeAll(source);
try out_file.writeStreamingAll(io, source);
return 1;
} else {
var buf: [1024]u8 = undefined;
var out = out_file.writer(&buf);
var out = out_file.writer(io, &buf);
const w = &out.interface;
try zig_tree.render(gpa, w, .{});
try w.flush();
Expand Down
20 changes: 8 additions & 12 deletions src/lsp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1089,22 +1089,22 @@ pub const Transport = struct {
writeJsonMessage: *const fn (transport: *Transport, json_message: []const u8) WriteError!void,
};

pub const ReadError = std.posix.ReadError || error{EndOfStream} || BaseProtocolHeader.ParseError || std.mem.Allocator.Error;
pub const WriteError = std.posix.WriteError;
pub const ReadError = std.Io.File.Reader.Error || error{EndOfStream} || BaseProtocolHeader.ParseError || std.mem.Allocator.Error;
pub const WriteError = std.Io.File.Writer.Error;

pub const Stdio = struct {
transport: Transport,
io: std.Io,
reader: std.Io.Reader,
read_from: std.Io.File,
write_to: std.fs.File,
write_to: std.Io.File,

pub fn init(
io: std.Io,
/// See `BaseProtocolHeader.parse`
read_buffer: []u8,
read_from: std.Io.File,
write_to: std.fs.File,
write_to: std.Io.File,
) Stdio {
return .{
.transport = .{
Expand All @@ -1122,12 +1122,8 @@ pub const Transport = struct {

fn readJsonMessage(transport: *Transport, allocator: std.mem.Allocator) ReadError![]u8 {
const stdio: *Stdio = @fieldParentPtr("transport", transport);
var file_reader: std.Io.File.Reader = .{
.io = stdio.io,
.file = stdio.read_from,
.mode = .streaming_reading,
.interface = stdio.reader,
};
var file_reader: std.Io.File.Reader = .initStreaming(stdio.read_from, stdio.io, stdio.reader.buffer);
file_reader.interface = stdio.reader;
defer stdio.reader = file_reader.interface;
return lsp.readJsonMessage(&file_reader.interface, allocator) catch |err| switch (err) {
error.ReadFailed => return file_reader.err.?,
Expand All @@ -1137,8 +1133,8 @@ pub const Transport = struct {

fn writeJsonMessage(transport: *Transport, json_message: []const u8) WriteError!void {
const stdio: *Stdio = @fieldParentPtr("transport", transport);
var file_writer: std.fs.File.Writer = .initStreaming(stdio.write_to, &.{});
return lsp.writeJsonMessage(&file_writer.interface, json_message) catch |err| switch (err) {
var file_writer: std.Io.File.Writer = .initStreaming(stdio.write_to, stdio.io, &.{});
lsp.writeJsonMessage(&file_writer.interface, json_message) catch |err| switch (err) {
error.WriteFailed => return file_writer.err.?,
};
}
Expand Down