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 immutable document = documents[params.textDocument.uri].clone();
15 	string file = document.uri.uriToFile;
16 	auto currOffset = cast(int) document.positionToBytes(params.position);
17 
18 	if (!backend.hasBest!DCDComponent(file))
19 		return fallbackDocumentHighlight(document, currOffset);
20 
21 	DocumentHighlight[] result;
22 	string codeText = document.rawText;
23 
24 	Position cachePos;
25 	size_t cacheBytes;
26 
27 	auto localUse = backend.best!DCDComponent(file).findLocalUse(codeText, currOffset).getYield;
28 	trace("localUse: ", localUse);
29 	if (localUse.declarationFilePath == "stdin")
30 	{
31 		auto range = document.wordRangeAt(localUse.declarationLocation);
32 		auto start = document.nextPositionBytes(cachePos, cacheBytes, range[0]);
33 		auto end = document.nextPositionBytes(cachePos, cacheBytes, range[1]);
34 		result ~= DocumentHighlight(TextRange(start, end), DocumentHighlightKind.write.opt);
35 	}
36 
37 	foreach (use; localUse.uses)
38 	{
39 		auto range = document.wordRangeAt(use);
40 		auto start = document.nextPositionBytes(cachePos, cacheBytes, range[0]);
41 		auto end = document.nextPositionBytes(cachePos, cacheBytes, range[1]);
42 		result ~= DocumentHighlight(TextRange(start, end), DocumentHighlightKind.read.opt);
43 	}
44 
45 	if (!result.length)
46 		return fallbackDocumentHighlight(document, currOffset);
47 
48 	return result;
49 }
50 
51 private DocumentHighlight[] fallbackDocumentHighlight(scope ref immutable(Document) document, int currOffset)
52 {
53 	string file = document.uri.uriToFile;
54 	if (!backend.hasBest!DCDExtComponent(file))
55 		return null;
56 
57 	DocumentHighlight[] result;
58 	string codeText = document.rawText;
59 
60 	Position cachePos;
61 	size_t cacheBytes;
62 
63 	foreach (related; backend.best!DCDExtComponent(file).highlightRelated(codeText, currOffset))
64 	{
65 		auto start = document.nextPositionBytes(cachePos, cacheBytes, related.range[0]);
66 		auto end = document.nextPositionBytes(cachePos, cacheBytes, related.range[1]);
67 		result ~= DocumentHighlight(TextRange(start, end), DocumentHighlightKind.text.opt);
68 	}
69 
70 	return result;
71 }