Implement textDocument/documentHighlight
This commit is contained in:
parent
ab62e58515
commit
94770b86c6
@ -1135,6 +1135,7 @@ fn referencesDefinitionGlobal(
|
|||||||
handle: *DocumentStore.Handle,
|
handle: *DocumentStore.Handle,
|
||||||
pos_index: usize,
|
pos_index: usize,
|
||||||
include_decl: bool,
|
include_decl: bool,
|
||||||
|
comptime highlight: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const tracy_zone = tracy.trace(@src());
|
const tracy_zone = tracy.trace(@src());
|
||||||
defer tracy_zone.end();
|
defer tracy_zone.end();
|
||||||
@ -1151,9 +1152,21 @@ fn referencesDefinitionGlobal(
|
|||||||
std.ArrayList(types.Location).append,
|
std.ArrayList(types.Location).append,
|
||||||
server.config.skip_std_references,
|
server.config.skip_std_references,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const result: types.ResponseParams = if (highlight) result: {
|
||||||
|
var highlights = try std.ArrayList(types.DocumentHighlight).initCapacity(arena.allocator(), locs.items.len);
|
||||||
|
for (locs.items) |loc| {
|
||||||
|
highlights.appendAssumeCapacity(.{
|
||||||
|
.range = loc.range,
|
||||||
|
.kind = .Text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break :result .{ .DocumentHighlight = highlights.items };
|
||||||
|
} else .{ .Locations = locs.items };
|
||||||
|
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.id = id,
|
||||||
.result = .{ .Locations = locs.items },
|
.result = result,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,6 +1178,7 @@ fn referencesDefinitionFieldAccess(
|
|||||||
position: offsets.DocumentPosition,
|
position: offsets.DocumentPosition,
|
||||||
range: analysis.SourceRange,
|
range: analysis.SourceRange,
|
||||||
include_decl: bool,
|
include_decl: bool,
|
||||||
|
comptime highlight: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const tracy_zone = tracy.trace(@src());
|
const tracy_zone = tracy.trace(@src());
|
||||||
defer tracy_zone.end();
|
defer tracy_zone.end();
|
||||||
@ -1172,9 +1186,19 @@ fn referencesDefinitionFieldAccess(
|
|||||||
const decl = (try server.getSymbolFieldAccess(handle, arena, position, range)) orelse return try respondGeneric(id, null_result_response);
|
const decl = (try server.getSymbolFieldAccess(handle, arena, position, range)) orelse return try respondGeneric(id, null_result_response);
|
||||||
var locs = std.ArrayList(types.Location).init(arena.allocator());
|
var locs = std.ArrayList(types.Location).init(arena.allocator());
|
||||||
try references.symbolReferences(arena, &server.document_store, decl, server.offset_encoding, include_decl, &locs, std.ArrayList(types.Location).append, server.config.skip_std_references);
|
try references.symbolReferences(arena, &server.document_store, decl, server.offset_encoding, include_decl, &locs, std.ArrayList(types.Location).append, server.config.skip_std_references);
|
||||||
|
const result: types.ResponseParams = if (highlight) result: {
|
||||||
|
var highlights = try std.ArrayList(types.DocumentHighlight).initCapacity(arena.allocator(), locs.items.len);
|
||||||
|
for (locs.items) |loc| {
|
||||||
|
highlights.appendAssumeCapacity(.{
|
||||||
|
.range = loc.range,
|
||||||
|
.kind = .Text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break :result .{ .DocumentHighlight = highlights.items };
|
||||||
|
} else .{ .Locations = locs.items };
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.id = id,
|
||||||
.result = .{ .Locations = locs.items },
|
.result = result,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,6 +1209,7 @@ fn referencesDefinitionLabel(
|
|||||||
handle: *DocumentStore.Handle,
|
handle: *DocumentStore.Handle,
|
||||||
pos_index: usize,
|
pos_index: usize,
|
||||||
include_decl: bool,
|
include_decl: bool,
|
||||||
|
comptime highlight: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const tracy_zone = tracy.trace(@src());
|
const tracy_zone = tracy.trace(@src());
|
||||||
defer tracy_zone.end();
|
defer tracy_zone.end();
|
||||||
@ -1192,9 +1217,19 @@ fn referencesDefinitionLabel(
|
|||||||
const decl = (try getLabelGlobal(pos_index, handle)) orelse return try respondGeneric(id, null_result_response);
|
const decl = (try getLabelGlobal(pos_index, handle)) orelse return try respondGeneric(id, null_result_response);
|
||||||
var locs = std.ArrayList(types.Location).init(arena.allocator());
|
var locs = std.ArrayList(types.Location).init(arena.allocator());
|
||||||
try references.labelReferences(arena, decl, server.offset_encoding, include_decl, &locs, std.ArrayList(types.Location).append);
|
try references.labelReferences(arena, decl, server.offset_encoding, include_decl, &locs, std.ArrayList(types.Location).append);
|
||||||
|
const result: types.ResponseParams = if (highlight) result: {
|
||||||
|
var highlights = try std.ArrayList(types.DocumentHighlight).initCapacity(arena.allocator(), locs.items.len);
|
||||||
|
for (locs.items) |loc| {
|
||||||
|
highlights.appendAssumeCapacity(.{
|
||||||
|
.range = loc.range,
|
||||||
|
.kind = .Text,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break :result .{ .DocumentHighlight = highlights.items };
|
||||||
|
} else .{ .Locations = locs.items };
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.id = id,
|
||||||
.result = .{ .Locations = locs.items },
|
.result = result,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1747,7 +1782,7 @@ fn initializeHandler(server: *Server, arena: *std.heap.ArenaAllocator, id: types
|
|||||||
.textDocumentSync = .Full,
|
.textDocumentSync = .Full,
|
||||||
.renameProvider = true,
|
.renameProvider = true,
|
||||||
.completionProvider = .{ .resolveProvider = false, .triggerCharacters = &[_][]const u8{ ".", ":", "@" }, .completionItem = .{ .labelDetailsSupport = true } },
|
.completionProvider = .{ .resolveProvider = false, .triggerCharacters = &[_][]const u8{ ".", ":", "@" }, .completionItem = .{ .labelDetailsSupport = true } },
|
||||||
.documentHighlightProvider = false,
|
.documentHighlightProvider = true,
|
||||||
.hoverProvider = true,
|
.hoverProvider = true,
|
||||||
.codeActionProvider = false,
|
.codeActionProvider = false,
|
||||||
.declarationProvider = true,
|
.declarationProvider = true,
|
||||||
@ -2268,9 +2303,33 @@ fn referencesHandler(server: *Server, arena: *std.heap.ArenaAllocator, id: types
|
|||||||
|
|
||||||
const include_decl = req.params.context.includeDeclaration;
|
const include_decl = req.params.context.includeDeclaration;
|
||||||
switch (pos_context) {
|
switch (pos_context) {
|
||||||
.var_access => try server.referencesDefinitionGlobal(arena, id, handle, doc_position.absolute_index, include_decl),
|
.var_access => try server.referencesDefinitionGlobal(arena, id, handle, doc_position.absolute_index, include_decl, false),
|
||||||
.field_access => |range| try server.referencesDefinitionFieldAccess(arena, id, handle, doc_position, range, include_decl),
|
.field_access => |range| try server.referencesDefinitionFieldAccess(arena, id, handle, doc_position, range, include_decl, false),
|
||||||
.label => try server.referencesDefinitionLabel(arena, id, handle, doc_position.absolute_index, include_decl),
|
.label => try server.referencesDefinitionLabel(arena, id, handle, doc_position.absolute_index, include_decl, false),
|
||||||
|
else => try respondGeneric(id, null_result_response),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try respondGeneric(id, null_result_response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn documentHighlightHandler(server: *Server, arena: *std.heap.ArenaAllocator, id: types.RequestId, req: requests.DocumentHighlight) !void {
|
||||||
|
const tracy_zone = tracy.trace(@src());
|
||||||
|
defer tracy_zone.end();
|
||||||
|
|
||||||
|
const handle = server.document_store.getHandle(req.params.textDocument.uri) orelse {
|
||||||
|
logger.warn("Trying to highlight references in non existent document {s}", .{req.params.textDocument.uri});
|
||||||
|
return try respondGeneric(id, null_result_response);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (req.params.position.character >= 0) {
|
||||||
|
const doc_position = try offsets.documentPosition(handle.document, req.params.position, server.offset_encoding);
|
||||||
|
const pos_context = try analysis.documentPositionContext(arena, handle.document, doc_position);
|
||||||
|
|
||||||
|
switch (pos_context) {
|
||||||
|
.var_access => try server.referencesDefinitionGlobal(arena, id, handle, doc_position.absolute_index, true, true),
|
||||||
|
.field_access => |range| try server.referencesDefinitionFieldAccess(arena, id, handle, doc_position, range, true, true),
|
||||||
|
.label => try server.referencesDefinitionLabel(arena, id, handle, doc_position.absolute_index, true, true),
|
||||||
else => try respondGeneric(id, null_result_response),
|
else => try respondGeneric(id, null_result_response),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2375,6 +2434,7 @@ fn processJsonRpc(server: *Server, arena: *std.heap.ArenaAllocator, parser: *std
|
|||||||
.{ "textDocument/formatting", requests.Formatting, formattingHandler },
|
.{ "textDocument/formatting", requests.Formatting, formattingHandler },
|
||||||
.{ "textDocument/rename", requests.Rename, renameHandler },
|
.{ "textDocument/rename", requests.Rename, renameHandler },
|
||||||
.{ "textDocument/references", requests.References, referencesHandler },
|
.{ "textDocument/references", requests.References, referencesHandler },
|
||||||
|
.{ "textDocument/documentHighlight", requests.DocumentHighlight, documentHighlightHandler },
|
||||||
.{ "workspace/didChangeConfiguration", std.json.Value, didChangeConfigurationHandler },
|
.{ "workspace/didChangeConfiguration", std.json.Value, didChangeConfigurationHandler },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2414,7 +2474,6 @@ fn processJsonRpc(server: *Server, arena: *std.heap.ArenaAllocator, parser: *std
|
|||||||
// needs a response) or false if the method is a notification (in which
|
// needs a response) or false if the method is a notification (in which
|
||||||
// case it should be silently ignored)
|
// case it should be silently ignored)
|
||||||
const unimplemented_map = std.ComptimeStringMap(bool, .{
|
const unimplemented_map = std.ComptimeStringMap(bool, .{
|
||||||
.{ "textDocument/documentHighlight", true },
|
|
||||||
.{ "textDocument/codeAction", true },
|
.{ "textDocument/codeAction", true },
|
||||||
.{ "textDocument/codeLens", true },
|
.{ "textDocument/codeLens", true },
|
||||||
.{ "textDocument/documentLink", true },
|
.{ "textDocument/documentLink", true },
|
||||||
|
@ -165,6 +165,7 @@ pub const Initialize = struct {
|
|||||||
documentationFormat: MaybeStringArray,
|
documentationFormat: MaybeStringArray,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
documentHighlight: Exists,
|
||||||
},
|
},
|
||||||
offsetEncoding: MaybeStringArray,
|
offsetEncoding: MaybeStringArray,
|
||||||
};
|
};
|
||||||
@ -244,6 +245,7 @@ pub const GotoDeclaration = TextDocumentIdentifierPositionRequest;
|
|||||||
pub const Hover = TextDocumentIdentifierPositionRequest;
|
pub const Hover = TextDocumentIdentifierPositionRequest;
|
||||||
pub const DocumentSymbols = TextDocumentIdentifierRequest;
|
pub const DocumentSymbols = TextDocumentIdentifierRequest;
|
||||||
pub const Formatting = TextDocumentIdentifierRequest;
|
pub const Formatting = TextDocumentIdentifierRequest;
|
||||||
|
pub const DocumentHighlight = TextDocumentIdentifierPositionRequest;
|
||||||
pub const Rename = struct {
|
pub const Rename = struct {
|
||||||
params: struct {
|
params: struct {
|
||||||
textDocument: TextDocumentIdentifier,
|
textDocument: TextDocumentIdentifier,
|
||||||
|
@ -45,6 +45,7 @@ pub const ResponseParams = union(enum) {
|
|||||||
InitializeResult: InitializeResult,
|
InitializeResult: InitializeResult,
|
||||||
ConfigurationParams: ConfigurationParams,
|
ConfigurationParams: ConfigurationParams,
|
||||||
RegistrationParams: RegistrationParams,
|
RegistrationParams: RegistrationParams,
|
||||||
|
DocumentHighlight: []DocumentHighlight,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// JSONRPC notifications
|
/// JSONRPC notifications
|
||||||
@ -412,3 +413,18 @@ pub const RegistrationParams = struct {
|
|||||||
// registerOptions?: LSPAny;
|
// registerOptions?: LSPAny;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const DocumentHighlightKind = enum(u8) {
|
||||||
|
Text = 1,
|
||||||
|
Read = 2,
|
||||||
|
Write = 3,
|
||||||
|
|
||||||
|
pub fn jsonStringify(value: DocumentHighlightKind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
||||||
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DocumentHighlight = struct {
|
||||||
|
range: Range,
|
||||||
|
kind: ?DocumentHighlightKind,
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user