refactor: lsp read_locationlink
This commit is contained in:
parent
e9d336e336
commit
618719cdc2
1 changed files with 52 additions and 65 deletions
117
src/Project.zig
117
src/Project.zig
|
|
@ -940,46 +940,23 @@ fn send_goto_request(self: *Self, from: tp.pid_ref, file_path: []const u8, row:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn navigate_to_location_link(from: tp.pid_ref, location_link: []const u8) (ClientError || InvalidMessageError || cbor.Error)!void {
|
fn navigate_to_location_link(from: tp.pid_ref, location_link: []const u8) (ClientError || InvalidMessageError || cbor.Error)!void {
|
||||||
var iter = location_link;
|
const location: LocationLink = try read_locationlink(location_link);
|
||||||
var targetUri: ?[]const u8 = null;
|
if (location.targetUri == null or location.targetRange == null) return error.InvalidMessageField;
|
||||||
var targetRange: ?Range = null;
|
if (!std.mem.eql(u8, location.targetUri.?[0..7], "file://")) return error.InvalidTargetURI;
|
||||||
var targetSelectionRange: ?Range = null;
|
|
||||||
var len = try cbor.decodeMapHeader(&iter);
|
|
||||||
while (len > 0) : (len -= 1) {
|
|
||||||
var field_name: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchString(&iter, &field_name))) return error.InvalidMessage;
|
|
||||||
if (std.mem.eql(u8, field_name, "targetUri") or std.mem.eql(u8, field_name, "uri")) {
|
|
||||||
var value: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchValue(&iter, cbor.extract(&value)))) return error.InvalidMessageField;
|
|
||||||
targetUri = value;
|
|
||||||
} else if (std.mem.eql(u8, field_name, "targetRange") or std.mem.eql(u8, field_name, "range")) {
|
|
||||||
var range: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&range)))) return error.InvalidMessageField;
|
|
||||||
targetRange = try read_range(range);
|
|
||||||
} else if (std.mem.eql(u8, field_name, "targetSelectionRange")) {
|
|
||||||
var range: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&range)))) return error.InvalidMessageField;
|
|
||||||
targetSelectionRange = try read_range(range);
|
|
||||||
} else {
|
|
||||||
try cbor.skipValue(&iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (targetUri == null or targetRange == null) return error.InvalidMessageField;
|
|
||||||
if (!std.mem.eql(u8, targetUri.?[0..7], "file://")) return error.InvalidTargetURI;
|
|
||||||
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
var file_path = std.Uri.percentDecodeBackwards(&file_path_buf, targetUri.?[7..]);
|
var file_path = std.Uri.percentDecodeBackwards(&file_path_buf, location.targetUri.?[7..]);
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
if (file_path[0] == '/') file_path = file_path[1..];
|
if (file_path[0] == '/') file_path = file_path[1..];
|
||||||
for (file_path, 0..) |c, i| if (c == '/') {
|
for (file_path, 0..) |c, i| if (c == '/') {
|
||||||
file_path[i] = '\\';
|
file_path[i] = '\\';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (targetSelectionRange) |sel| {
|
if (location.targetSelectionRange) |sel| {
|
||||||
from.send(.{ "cmd", "navigate", .{
|
from.send(.{ "cmd", "navigate", .{
|
||||||
.file = file_path,
|
.file = file_path,
|
||||||
.goto = .{
|
.goto = .{
|
||||||
targetSelectionRange.?.start.line + 1,
|
location.targetSelectionRange.?.start.line + 1,
|
||||||
targetSelectionRange.?.start.character + 1,
|
location.targetSelectionRange.?.start.character + 1,
|
||||||
sel.start.line,
|
sel.start.line,
|
||||||
sel.start.character,
|
sel.start.character,
|
||||||
sel.end.line,
|
sel.end.line,
|
||||||
|
|
@ -990,8 +967,8 @@ fn navigate_to_location_link(from: tp.pid_ref, location_link: []const u8) (Clien
|
||||||
from.send(.{ "cmd", "navigate", .{
|
from.send(.{ "cmd", "navigate", .{
|
||||||
.file = file_path,
|
.file = file_path,
|
||||||
.goto = .{
|
.goto = .{
|
||||||
targetRange.?.start.line + 1,
|
location.targetRange.?.start.line + 1,
|
||||||
targetRange.?.start.character + 1,
|
location.targetRange.?.start.character + 1,
|
||||||
},
|
},
|
||||||
} }) catch return error.ClientFailed;
|
} }) catch return error.ClientFailed;
|
||||||
}
|
}
|
||||||
|
|
@ -1085,43 +1062,20 @@ fn send_reference_list(tag: []const u8, to: tp.pid_ref, locations: []const u8, n
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_reference(tag: []const u8, to: tp.pid_ref, location: []const u8, name: []const u8) (ClientError || InvalidMessageError || GetLineOfFileError || cbor.Error)!void {
|
fn send_reference(tag: []const u8, to: tp.pid_ref, location_: []const u8, name: []const u8) (ClientError || InvalidMessageError || GetLineOfFileError || cbor.Error)!void {
|
||||||
const allocator = std.heap.c_allocator;
|
const allocator = std.heap.c_allocator;
|
||||||
var iter = location;
|
const location: LocationLink = try read_locationlink(location_);
|
||||||
var targetUri: ?[]const u8 = null;
|
if (location.targetUri == null or location.targetRange == null) return error.InvalidMessageField;
|
||||||
var targetRange: ?Range = null;
|
if (!std.mem.eql(u8, location.targetUri.?[0..7], "file://")) return error.InvalidTargetURI;
|
||||||
var targetSelectionRange: ?Range = null;
|
|
||||||
var len = try cbor.decodeMapHeader(&iter);
|
|
||||||
while (len > 0) : (len -= 1) {
|
|
||||||
var field_name: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchString(&iter, &field_name))) return error.InvalidMessage;
|
|
||||||
if (std.mem.eql(u8, field_name, "targetUri") or std.mem.eql(u8, field_name, "uri")) {
|
|
||||||
var value: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchValue(&iter, cbor.extract(&value)))) return error.InvalidMessageField;
|
|
||||||
targetUri = value;
|
|
||||||
} else if (std.mem.eql(u8, field_name, "targetRange") or std.mem.eql(u8, field_name, "range")) {
|
|
||||||
var range: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&range)))) return error.InvalidMessageField;
|
|
||||||
targetRange = try read_range(range);
|
|
||||||
} else if (std.mem.eql(u8, field_name, "targetSelectionRange")) {
|
|
||||||
var range: []const u8 = undefined;
|
|
||||||
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&range)))) return error.InvalidMessageField;
|
|
||||||
targetSelectionRange = try read_range(range);
|
|
||||||
} else {
|
|
||||||
try cbor.skipValue(&iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (targetUri == null or targetRange == null) return error.InvalidMessageField;
|
|
||||||
if (!std.mem.eql(u8, targetUri.?[0..7], "file://")) return error.InvalidTargetURI;
|
|
||||||
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
var file_path = std.Uri.percentDecodeBackwards(&file_path_buf, targetUri.?[7..]);
|
var file_path = std.Uri.percentDecodeBackwards(&file_path_buf, location.targetUri.?[7..]);
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
if (file_path[0] == '/') file_path = file_path[1..];
|
if (file_path[0] == '/') file_path = file_path[1..];
|
||||||
for (file_path, 0..) |c, i| if (c == '/') {
|
for (file_path, 0..) |c, i| if (c == '/') {
|
||||||
file_path[i] = '\\';
|
file_path[i] = '\\';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const line = try get_line_of_file(allocator, file_path, targetRange.?.start.line);
|
const line = try get_line_of_file(allocator, file_path, location.targetRange.?.start.line);
|
||||||
defer allocator.free(line);
|
defer allocator.free(line);
|
||||||
const file_path_ = if (file_path.len > name.len and std.mem.eql(u8, name, file_path[0..name.len]))
|
const file_path_ = if (file_path.len > name.len and std.mem.eql(u8, name, file_path[0..name.len]))
|
||||||
file_path[name.len + 1 ..]
|
file_path[name.len + 1 ..]
|
||||||
|
|
@ -1130,10 +1084,10 @@ fn send_reference(tag: []const u8, to: tp.pid_ref, location: []const u8, name: [
|
||||||
to.send(.{
|
to.send(.{
|
||||||
tag,
|
tag,
|
||||||
file_path_,
|
file_path_,
|
||||||
targetRange.?.start.line + 1,
|
location.targetRange.?.start.line + 1,
|
||||||
targetRange.?.start.character,
|
location.targetRange.?.start.character,
|
||||||
targetRange.?.end.line + 1,
|
location.targetRange.?.end.line + 1,
|
||||||
targetRange.?.end.character,
|
location.targetRange.?.end.character,
|
||||||
line,
|
line,
|
||||||
}) catch return error.ClientFailed;
|
}) catch return error.ClientFailed;
|
||||||
}
|
}
|
||||||
|
|
@ -1722,6 +1676,39 @@ fn send_clear_diagnostics(_: *Self, to: tp.pid_ref, file_path: []const u8) Clien
|
||||||
to.send(.{ "cmd", "clear_diagnostics", .{file_path} }) catch return error.ClientFailed;
|
to.send(.{ "cmd", "clear_diagnostics", .{file_path} }) catch return error.ClientFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LocationLink = struct {
|
||||||
|
targetUri: ?[]const u8 = null,
|
||||||
|
targetRange: ?Range = null,
|
||||||
|
targetSelectionRange: ?Range = null,
|
||||||
|
};
|
||||||
|
fn read_locationlink(location_link: []const u8) !LocationLink {
|
||||||
|
var iter = location_link;
|
||||||
|
var targetUri: ?[]const u8 = null;
|
||||||
|
var targetRange: ?Range = null;
|
||||||
|
var targetSelectionRange: ?Range = null;
|
||||||
|
var len = try cbor.decodeMapHeader(&iter);
|
||||||
|
while (len > 0) : (len -= 1) {
|
||||||
|
var field_name: []const u8 = undefined;
|
||||||
|
if (!(try cbor.matchString(&iter, &field_name))) return error.InvalidMessage;
|
||||||
|
if (std.mem.eql(u8, field_name, "targetUri") or std.mem.eql(u8, field_name, "uri")) {
|
||||||
|
var uri_: []const u8 = undefined;
|
||||||
|
if (!(try cbor.matchValue(&iter, cbor.extract(&uri_)))) return error.InvalidMessageField;
|
||||||
|
targetUri = uri_;
|
||||||
|
} else if (std.mem.eql(u8, field_name, "targetRange") or std.mem.eql(u8, field_name, "range")) {
|
||||||
|
var range_: []const u8 = undefined;
|
||||||
|
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&range_)))) return error.InvalidMessageField;
|
||||||
|
targetRange = try read_range(range_);
|
||||||
|
} else if (std.mem.eql(u8, field_name, "targetSelectionRange")) {
|
||||||
|
var range_: []const u8 = undefined;
|
||||||
|
if (!(try cbor.matchValue(&iter, cbor.extract_cbor(&range_)))) return error.InvalidMessageField;
|
||||||
|
targetSelectionRange = try read_range(range_);
|
||||||
|
} else {
|
||||||
|
try cbor.skipValue(&iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .{ .targetUri = targetUri, .targetRange = targetRange, .targetSelectionRange = targetSelectionRange };
|
||||||
|
}
|
||||||
|
|
||||||
const Range = struct { start: Position, end: Position };
|
const Range = struct { start: Position, end: Position };
|
||||||
fn read_range(range: []const u8) !Range {
|
fn read_range(range: []const u8) !Range {
|
||||||
var iter = range;
|
var iter = range;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue