Skip to content

Commit 9730ac5

Browse files
authored
Live-updating regex scopes (#1943)
- Depends on #1942 ## Checklist - [-] I have added [tests](https://www.cursorless.org/docs/contributing/test-case-recorder/) - [-] I have updated the [docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and [cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet) - [-] I have not broken the cheatsheet
1 parent 1260235 commit 9730ac5

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

packages/cursorless-vscode/src/extension.ts

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
import { KeyboardCommands } from "./keyboard/KeyboardCommands";
3939
import { registerCommands } from "./registerCommands";
4040
import { ReleaseNotes } from "./ReleaseNotes";
41+
import { revisualizeOnCustomRegexChange } from "./revisualizeOnCustomRegexChange";
4142
import { ScopeTreeProvider } from "./ScopeTreeProvider";
4243
import {
4344
ScopeVisualizer,
@@ -100,6 +101,9 @@ export async function activate(
100101
const statusBarItem = StatusBarItem.create("cursorless.showQuickPick");
101102
const keyboardCommands = KeyboardCommands.create(context, statusBarItem);
102103
const scopeVisualizer = createScopeVisualizer(normalizedIde, scopeProvider);
104+
context.subscriptions.push(
105+
revisualizeOnCustomRegexChange(scopeVisualizer, scopeProvider),
106+
);
103107

104108
new ScopeTreeProvider(
105109
vscodeApi,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {
2+
Disposable,
3+
ScopeProvider,
4+
ScopeTypeInfo,
5+
disposableFrom,
6+
} from "@cursorless/common";
7+
import { isEqual } from "lodash";
8+
import {
9+
ScopeVisualizer,
10+
VisualizationType,
11+
} from "./ScopeVisualizerCommandApi";
12+
13+
/**
14+
* Attempts to ensure that the scope visualizer is still visualizing the same
15+
* scope type after the user changes one of their custom regexes. Because custom
16+
* regexes don't have a unique identifier, we have to do some guesswork to
17+
* figure out which custom regex the user changed. This function look for a
18+
* custom regex with the same spoken form as the one that was changed, and if it
19+
* finds one, it starts visualizing that one instead.
20+
*
21+
* @param scopeVisualizer The scope visualizer to listen to
22+
* @param scopeProvider Provides scope information
23+
* @returns A {@link Disposable} which will stop the callback from running
24+
*/
25+
export function revisualizeOnCustomRegexChange(
26+
scopeVisualizer: ScopeVisualizer,
27+
scopeProvider: ScopeProvider,
28+
): Disposable {
29+
let currentRegexScopeInfo: ScopeTypeInfo | undefined;
30+
let currentVisualizationType: VisualizationType | undefined;
31+
32+
return disposableFrom(
33+
scopeVisualizer.onDidChangeScopeType((scopeType, visualizationType) => {
34+
currentRegexScopeInfo =
35+
scopeType?.type === "customRegex"
36+
? scopeProvider.getScopeInfo(scopeType)
37+
: undefined;
38+
currentVisualizationType = visualizationType;
39+
}),
40+
41+
scopeProvider.onDidChangeScopeInfo((scopeInfos) => {
42+
if (
43+
currentRegexScopeInfo != null &&
44+
!scopeInfos.some((scopeInfo) =>
45+
isEqual(scopeInfo.scopeType, currentRegexScopeInfo!.scopeType),
46+
)
47+
) {
48+
const replacement = scopeInfos.find(
49+
(scopeInfo) =>
50+
scopeInfo.scopeType.type === "customRegex" &&
51+
isEqual(scopeInfo.spokenForm, currentRegexScopeInfo!.spokenForm),
52+
);
53+
if (replacement != null) {
54+
scopeVisualizer.start(
55+
replacement.scopeType,
56+
currentVisualizationType!,
57+
);
58+
}
59+
}
60+
}),
61+
);
62+
}

0 commit comments

Comments
 (0)