-
-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathVscodeScopeVisualizer.ts
More file actions
99 lines (88 loc) · 3.01 KB
/
VscodeScopeVisualizer.ts
File metadata and controls
99 lines (88 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import type {
Disposable,
IDE,
ScopeProvider,
ScopeType,
TextEditor,
} from "@cursorless/lib-common";
import { DOCS_URL, ScopeSupport, showError } from "@cursorless/lib-common";
import type {
ScopeRangeType,
ScopeVisualizerColorConfig,
} from "@cursorless/lib-vscode-common";
import { vscodeApi } from "../../../vscodeApi";
import { getColorsFromConfig } from "./getColorsFromConfig";
import { VscodeScopeRenderer } from "./VscodeScopeRenderer";
/**
* Base class for the different kinds of scope visualizer, eg content, removal,
* iteration.
*/
export abstract class VscodeScopeVisualizer {
protected renderer!: VscodeScopeRenderer;
private scopeListenerDisposable!: Disposable;
private disposables: Disposable[] = [];
protected abstract registerListener(): Disposable;
protected abstract getNestedScopeRangeType(): ScopeRangeType;
protected abstract getScopeSupport(editor: TextEditor): ScopeSupport;
constructor(
private ide: IDE,
protected scopeProvider: ScopeProvider,
protected scopeType: ScopeType,
) {
this.disposables.push(
vscodeApi.workspace.onDidChangeConfiguration(
({ affectsConfiguration }) => {
if (affectsConfiguration("cursorless.scopeVisualizer.colors")) {
this.initialize();
}
},
),
);
}
start() {
this.initialize();
this.checkScopeSupport();
}
/**
* Checks if the scope type is supported in the active editor, and shows an
* error if not.
*/
private checkScopeSupport(): void {
const editor = this.ide.activeTextEditor;
if (editor == null) {
return;
}
switch (this.getScopeSupport(editor)) {
case ScopeSupport.supportedAndPresentInEditor:
case ScopeSupport.supportedButNotPresentInEditor:
return;
case ScopeSupport.unsupported:
void showError(
this.ide.messages,
"ScopeVisualizer.scopeTypeNotSupported",
`Scope type not supported for ${editor.document.languageId}. See ${DOCS_URL}/contributing/adding-a-new-language for more about how to update your language.`,
);
}
}
/** This function is called initially, as well as whenever color config changes */
private initialize() {
const colorConfig = vscodeApi.workspace
.getConfiguration("cursorless.scopeVisualizer")
.get<ScopeVisualizerColorConfig>("colors")!;
this.renderer?.dispose();
this.renderer = new VscodeScopeRenderer(
getColorsFromConfig(colorConfig, "domain"),
getColorsFromConfig(colorConfig, this.getNestedScopeRangeType()),
);
// Note that on color config change, we want to re-register the listener
// so that the provider will call us again with the current scope ranges
// so that we can re-render them with the new colors.
this.scopeListenerDisposable?.dispose();
this.scopeListenerDisposable = this.registerListener();
}
dispose() {
this.disposables.forEach((disposable) => disposable.dispose());
this.renderer?.dispose();
this.scopeListenerDisposable?.dispose();
}
}