Skip to content

Commit

Permalink
Live-updating regex scopes
Browse files Browse the repository at this point in the history
  • Loading branch information
pokey committed Oct 25, 2023
1 parent 4eca605 commit a90ea9c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/cursorless-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
} from "./ScopeVisualizerCommandApi";
import { StatusBarItem } from "./StatusBarItem";
import { vscodeApi } from "./vscodeApi";
import { revisualizeOnCustomRegexChange } from "./revisualizeOnCustomRegexChange";

/**
* Extension entrypoint called by VSCode on Cursorless startup.
Expand Down Expand Up @@ -97,6 +98,9 @@ export async function activate(
const statusBarItem = StatusBarItem.create("cursorless.showQuickPick");
const keyboardCommands = KeyboardCommands.create(context, statusBarItem);
const scopeVisualizer = createScopeVisualizer(normalizedIde, scopeProvider);
context.subscriptions.push(
revisualizeOnCustomRegexChange(scopeVisualizer, scopeProvider),
);

ScopeTreeProvider.create(
vscodeApi,
Expand Down
62 changes: 62 additions & 0 deletions packages/cursorless-vscode/src/revisualizeOnCustomRegexChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
Disposable,
Disposer,
ScopeProvider,
ScopeTypeInfo,
} from "@cursorless/common";
import {
ScopeVisualizer,
VisualizationType,
} from "./ScopeVisualizerCommandApi";
import { isEqual } from "lodash";

/**
* Attempts to ensure that the scope visualizer is still visualizing the same
* scope type after the user changes one of their custom regexes. Because custom
* regexes don't have a unique identifier, we have to do some guesswork to
* figure out which custom regex the user changed. This function look for a
* custom regex with the same spoken form as the one that was changed, and if it
* finds one, it starts visualizing that one instead.
*
* @param scopeVisualizer The scope visualizer to listen to
* @param scopeProvider Provides scope information
* @returns A {@link Disposable} which will stop the callback from running
*/
export function revisualizeOnCustomRegexChange(
scopeVisualizer: ScopeVisualizer,
scopeProvider: ScopeProvider,
): Disposable {
let currentRegexScopeInfo: ScopeTypeInfo | undefined;
let currentVisualizationType: VisualizationType | undefined;

return new Disposer(
scopeVisualizer.onDidChangeScopeType((scopeType, visualizationType) => {
currentRegexScopeInfo =
scopeType?.type === "customRegex"
? scopeProvider.getScopeInfo(scopeType)
: undefined;
currentVisualizationType = visualizationType;
}),

scopeProvider.onDidChangeScopeInfo((scopeInfos) => {
if (
currentRegexScopeInfo != null &&
!scopeInfos.some((scopeInfo) =>
isEqual(scopeInfo.scopeType, currentRegexScopeInfo!.scopeType),
)
) {
const replacement = scopeInfos.find(
(scopeInfo) =>
scopeInfo.scopeType.type === "customRegex" &&
isEqual(scopeInfo.spokenForm, currentRegexScopeInfo!.spokenForm),
);
if (replacement != null) {
scopeVisualizer.start(
replacement.scopeType,
currentVisualizationType!,
);
}
}
}),
);
}

0 comments on commit a90ea9c

Please sign in to comment.