1 module served.commands.highlight;
2 
3 import std.experimental.logger;
4 
5 import served.types;
6 
7 import workspaced.api;
8 import workspaced.com.dcd;
9 import workspaced.com.dcdext;
10 
11 @protocolMethod("textDocument/documentHighlight")
12 DocumentHighlight[] provideDocumentHighlight(DocumentHighlightParams params)
13 {
14 	scope document = cast(immutable)documents[params.textDocument.uri].clone();
15 	auto currOffset = cast(int) document.positionToBytes(params.position);
16 
17 	auto result = documentHighlightImpl(document, currOffset);
18 
19 	if (!result.length)
20 		return fallbackDocumentHighlight(document, currOffset);
21 
22 	return result;
23 }
24 
25 package DocumentHighlight[] documentHighlightImpl(scope ref immutable(Document) document, int currOffset)
26 {
27 	string file = document.uri.uriToFile;
28 	string codeText = document.rawText;
29 
30 	if (!backend.hasBest!DCDComponent(file))
31 		return null;
32 
33 	DocumentHighlight[] result;
34 
35 	Position cachePos;
36 	size_t cacheBytes;
37 
38 	auto localUse = backend.best!DCDComponent(file).findLocalUse(codeText, currOffset).getYield;
39 	trace("localUse: ", localUse);
40 	if (localUse.declarationFilePath == "stdin")
41 	{
42 		auto range = document.wordRangeAt(localUse.declarationLocation);
43 		auto start = document.nextPositionBytes(cachePos, cacheBytes, range[0]);
44 		auto end = document.nextPositionBytes(cachePos, cacheBytes, range[1]);
45 		result ~= DocumentHighlight(TextRange(start, end), DocumentHighlightKind.write.opt);
46 	}
47 
48 	foreach (use; localUse.uses)
49 	{
50 		auto range = document.wordRangeAt(use);
51 		auto start = document.nextPositionBytes(cachePos, cacheBytes, range[0]);
52 		auto end = document.nextPositionBytes(cachePos, cacheBytes, range[1]);
53 		result ~= DocumentHighlight(TextRange(start, end), DocumentHighlightKind.read.opt);
54 	}
55 
56 	return result;
57 }
58 
59 package DocumentHighlight[] fallbackDocumentHighlight(scope ref immutable(Document) document, int currOffset)
60 {
61 	string file = document.uri.uriToFile;
62 	if (!backend.hasBest!DCDExtComponent(file))
63 		return null;
64 
65 	DocumentHighlight[] result;
66 	string codeText = document.rawText;
67 
68 	Position cachePos;
69 	size_t cacheBytes;
70 
71 	foreach (related; backend.best!DCDExtComponent(file).highlightRelated(codeText, currOffset))
72 	{
73 		auto start = document.nextPositionBytes(cachePos, cacheBytes, related.range[0]);
74 		auto end = document.nextPositionBytes(cachePos, cacheBytes, related.range[1]);
75 		result ~= DocumentHighlight(TextRange(start, end), DocumentHighlightKind.text.opt);
76 	}
77 
78 	return result;
79 }