aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/xtext/HighlightingService.ts
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-10-30 20:14:50 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-10-31 19:26:14 +0100
commitcbf442d8fd9f72c567ebf9f036a219a9ff100487 (patch)
treea128345d9a9863bef7f3670da585bcb62d13cb34 /language-web/src/main/js/xtext/HighlightingService.ts
parentfeat(web): show error count on generate button (diff)
downloadrefinery-cbf442d8fd9f72c567ebf9f036a219a9ff100487.tar.gz
refinery-cbf442d8fd9f72c567ebf9f036a219a9ff100487.tar.zst
refinery-cbf442d8fd9f72c567ebf9f036a219a9ff100487.zip
feat(web): semantic highlighting
Diffstat (limited to 'language-web/src/main/js/xtext/HighlightingService.ts')
-rw-r--r--language-web/src/main/js/xtext/HighlightingService.ts43
1 files changed, 43 insertions, 0 deletions
diff --git a/language-web/src/main/js/xtext/HighlightingService.ts b/language-web/src/main/js/xtext/HighlightingService.ts
new file mode 100644
index 00000000..b8ceed20
--- /dev/null
+++ b/language-web/src/main/js/xtext/HighlightingService.ts
@@ -0,0 +1,43 @@
1import { Decoration } from '@codemirror/view';
2import { Range, RangeSet } from '@codemirror/rangeset';
3
4import type { EditorStore } from '../editor/EditorStore';
5import type { UpdateService } from './UpdateService';
6import { getLogger } from '../utils/logger';
7import { isHighlightingResult } from './xtextServiceResults';
8
9const log = getLogger('xtext.ValidationService');
10
11export class HighlightingService {
12 private store: EditorStore;
13
14 private updateService: UpdateService;
15
16 constructor(store: EditorStore, updateService: UpdateService) {
17 this.store = store;
18 this.updateService = updateService;
19 }
20
21 onPush(push: unknown): void {
22 if (!isHighlightingResult(push)) {
23 log.error('Invalid highlighting result', push);
24 return;
25 }
26 const allChanges = this.updateService.computeChangesSinceLastUpdate();
27 const decorations: Range<Decoration>[] = [];
28 push.regions.forEach(({ offset, length, styleClasses }) => {
29 if (styleClasses.length === 0) {
30 return;
31 }
32 const from = allChanges.mapPos(offset);
33 const to = allChanges.mapPos(offset + length);
34 if (to <= from) {
35 return;
36 }
37 decorations.push(Decoration.mark({
38 class: styleClasses.map((c) => `cmt-problem-${c}`).join(' '),
39 }).range(from, to));
40 });
41 this.store.updateSemanticHighlighting(RangeSet.of(decorations, true));
42 }
43}