Skip to content

Commit 5fd5092

Browse files
committed
Document highlights
1 parent 21bba84 commit 5fd5092

File tree

4 files changed

+86
-10
lines changed

4 files changed

+86
-10
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const assert = require('node:assert');
2+
const path = require('node:path');
3+
const vscode = require('vscode');
4+
const { showFile, sleepCI } = require('../util');
5+
6+
const stylesUri = vscode.Uri.file(
7+
path.resolve(__dirname, 'fixtures', 'styles.scss')
8+
);
9+
10+
before(async () => {
11+
await showFile(stylesUri);
12+
await sleepCI();
13+
});
14+
15+
after(async () => {
16+
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
17+
});
18+
19+
/**
20+
* @param {import('vscode').Uri} documentUri
21+
* @returns {Promise<Array<import('vscode').DocumentHighlight>>}
22+
*/
23+
async function getHighlights(documentUri, position) {
24+
const result = await vscode.commands.executeCommand(
25+
'vscode.executeDocumentHighlights',
26+
documentUri,
27+
position
28+
);
29+
return result;
30+
}
31+
32+
test('gets document highlights', async () => {
33+
const [first, second] = await getHighlights(
34+
stylesUri,
35+
new vscode.Position(7, 5)
36+
);
37+
38+
assert.ok(first, 'Should have found highlights');
39+
assert.ok(second, 'Should have found two highlights');
40+
41+
assert.equal(first.range.start.line, 7);
42+
assert.equal(first.range.start.character, 2);
43+
44+
assert.equal(first.range.end.line, 7);
45+
assert.equal(first.range.end.character, 14);
46+
47+
assert.equal(second.range.start.line, 11);
48+
assert.equal(second.range.start.character, 13);
49+
50+
assert.equal(second.range.end.line, 11);
51+
assert.equal(second.range.end.character, 25);
52+
});

extension/test/electron/definition/fixtures/styles.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@
33
.a {
44
@extend %brand;
55
}
6+
7+
:root {
8+
--color-text: #000;
9+
}
10+
11+
body {
12+
color: var(--color-text);
13+
}

pkgs/sass_language_services/lib/src/features/document_highlights/document_highlights_feature.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import 'package:lsp_server/lsp_server.dart' as lsp;
22
import 'package:sass_api/sass_api.dart' as sass;
33
import 'package:sass_language_services/sass_language_services.dart';
44
import 'package:sass_language_services/src/features/find_references/find_references_visitor.dart';
5-
import 'package:sass_language_services/src/utils/sass_lsp_utils.dart';
65

76
import '../go_to_definition/scope_visitor.dart';
87
import '../go_to_definition/scoped_symbols.dart';
@@ -39,17 +38,21 @@ class DocumentHighlightsFeature extends LanguageFeature {
3938
var symbol = symbols.findSymbolFromNode(node);
4039

4140
var result = <lsp.DocumentHighlight>[];
42-
var references = FindReferencesVisitor(
41+
var visitor = FindReferencesVisitor(
4342
document,
4443
name,
4544
includeDeclaration: true,
4645
);
4746

48-
for (var reference in references.candidates) {
47+
stylesheet.accept(visitor);
48+
49+
for (var reference in visitor.candidates) {
4950
if (symbol != null) {
50-
if (symbol.referenceKind == reference.kind &&
51-
symbol.name == reference.name &&
52-
isSameRange(symbol.range, reference.location.range)) {
51+
if (symbols.matchesSymbol(
52+
reference,
53+
document.offsetAt(reference.location.range.start),
54+
symbol,
55+
)) {
5356
result.add(
5457
lsp.DocumentHighlight(range: reference.location.range),
5558
);

pkgs/sass_language_services/lib/src/features/go_to_definition/scoped_symbols.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import 'package:sass_api/sass_api.dart' as sass;
2+
import 'package:sass_language_services/src/utils/sass_lsp_utils.dart';
23

34
import '../document_symbols/stylesheet_document_symbol.dart';
5+
import '../find_references/reference.dart';
46
import 'scope.dart';
57
import 'scope_visitor.dart';
68

@@ -123,20 +125,20 @@ class ScopedSymbols {
123125

124126
var referenceKind = getNodeReferenceKind(node);
125127
if (referenceKind != null) {
126-
return _findSymbol(node, referenceKind);
128+
return _findSymbol(
129+
getNodeName(node), node.span.start.offset, referenceKind);
127130
}
128131

129132
return null;
130133
}
131134

132135
StylesheetDocumentSymbol? _findSymbol(
133-
sass.AstNode node, ReferenceKind referenceKind) {
134-
var name = getNodeName(node);
136+
String? name, int offset, ReferenceKind referenceKind) {
135137
if (name == null) {
136138
return null;
137139
}
138140

139-
var scope = globalScope.findScope(offset: node.span.start.offset);
141+
var scope = globalScope.findScope(offset: offset);
140142
while (scope != null) {
141143
var symbol = scope.getSymbol(name: name, referenceKind: referenceKind);
142144
if (symbol != null) {
@@ -167,4 +169,15 @@ class ScopedSymbols {
167169
}
168170
return result;
169171
}
172+
173+
bool matchesSymbol(
174+
Reference reference, int offset, StylesheetDocumentSymbol symbol) {
175+
var referenceSymbol = _findSymbol(reference.name, offset, reference.kind);
176+
if (referenceSymbol == null) {
177+
return false;
178+
}
179+
return referenceSymbol.name == symbol.name &&
180+
referenceSymbol.kind == symbol.kind &&
181+
isSameRange(referenceSymbol.range, symbol.range);
182+
}
170183
}

0 commit comments

Comments
 (0)