|  | 
|  | 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