diff --git a/CHANGELOG.md b/CHANGELOG.md index 39e8a5620b..76fdea072a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 2026 +- 2026-09-01: Visualize modifiers on the documentation page. ([#3328](https://github.com/cursorless-dev/cursorless/pull/3328)) - 2026-08-30: Overhauled the user documentation with generated and grouped action, modifier, and scope reference pages, richer descriptions and examples, dedicated paired-delimiter and target guides, and a streamlined landing page. ([#3303](https://github.com/cursorless-dev/cursorless/pull/3303); [#3304](https://github.com/cursorless-dev/cursorless/pull/3304); [#3305](https://github.com/cursorless-dev/cursorless/pull/3305); [#3306](https://github.com/cursorless-dev/cursorless/pull/3306); [#3307](https://github.com/cursorless-dev/cursorless/pull/3307); [#3308](https://github.com/cursorless-dev/cursorless/pull/3308); [#3309](https://github.com/cursorless-dev/cursorless/pull/3309); [#3310](https://github.com/cursorless-dev/cursorless/pull/3310); [#3311](https://github.com/cursorless-dev/cursorless/pull/3311); [#3312](https://github.com/cursorless-dev/cursorless/pull/3312); [#3313](https://github.com/cursorless-dev/cursorless/pull/3313); [#3314](https://github.com/cursorless-dev/cursorless/pull/3314); [#3315](https://github.com/cursorless-dev/cursorless/pull/3315); [#3316](https://github.com/cursorless-dev/cursorless/pull/3316)) - 2026-05-03: Add support for if and for statements in Talon-script. [`#3274`](https://github.com/cursorless-dev/cursorless/pull/3274) - 2026-03-12: Added `userColor3` and `userColor4` as additional user-configurable hat colors. They are disabled by default until you enable and name them. ([#3206](https://github.com/cursorless-dev/cursorless/pull/3206)) diff --git a/packages/app-web-docs/docusaurus.config.mts b/packages/app-web-docs/docusaurus.config.mts index 33131f9ece..78fbf256ae 100644 --- a/packages/app-web-docs/docusaurus.config.mts +++ b/packages/app-web-docs/docusaurus.config.mts @@ -165,7 +165,11 @@ const config: Config = { ], ], - plugins: ["docusaurus-plugin-sass", "./src/plugins/scope-tests-plugin.ts"], + plugins: [ + "docusaurus-plugin-sass", + "./src/plugins/recorded-tests-plugin.ts", + "./src/plugins/scope-tests-plugin.ts", + ], themeConfig: { navbar: { diff --git a/packages/app-web-docs/src/docs/components/Code.css b/packages/app-web-docs/src/docs/components/Code.css index 1d03e36be8..9d85b134ef 100644 --- a/packages/app-web-docs/src/docs/components/Code.css +++ b/packages/app-web-docs/src/docs/components/Code.css @@ -71,3 +71,43 @@ background-color: #444; } } + +.code-cursor-before, +.code-cursor-after { + position: relative; +} + +.code-cursor-before::before, +.code-cursor-after::after { + content: ""; + position: absolute; + top: 0; + bottom: 0; + width: 0; + pointer-events: none; + opacity: 1; + animation: code-cursor-blink 1s step-end infinite; +} + +.code-cursor-before::before { + left: -1px; + border-left: 2px solid white; +} + +.code-cursor-after::after { + right: -1px; + border-right: 2px solid white; +} + +@keyframes code-cursor-blink { + 50% { + opacity: 0; + } +} + +@media (prefers-reduced-motion: reduce) { + .code-cursor-before::before, + .code-cursor-after::after { + animation: none; + } +} diff --git a/packages/app-web-docs/src/docs/components/Code.tsx b/packages/app-web-docs/src/docs/components/Code.tsx index 3b6428638c..b2fbdd288c 100644 --- a/packages/app-web-docs/src/docs/components/Code.tsx +++ b/packages/app-web-docs/src/docs/components/Code.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from "react"; -import type { DecorationItem } from "shiki"; +import type { DecorationItem, OffsetOrPosition } from "shiki"; import { codeToHtml } from "shiki"; import "./Code.css"; @@ -35,6 +35,28 @@ export function Code({ lang: getFallbackLanguage(languageId), theme: "nord", decorations, + transformers: [ + // Shiki omits decorations for empty lines. This transformation adds the cursor class to the line itself if needed. + { + name: "cursor-lines", + line(node, line) { + if (node.children.length === 0 && decorations != null) { + const hasDecoration = decorations.some((d) => { + return ( + arePositionsEqual(d.start, d.end) && + // line is 1-indexed, but the Position is 0-indexed + isPositionAtStartOfLine(d.start, line - 1) + ); + }); + if (hasDecoration) { + // oxlint-disable-next-line react/todo + this.addClassToHast(node, "code-cursor-after"); + } + } + return node; + }, + }, + ], }); if (renderWhitespace) { html = html @@ -108,3 +130,19 @@ function getFallbackLanguage(languageId: string): string { return languageId; } } + +function arePositionsEqual(a: OffsetOrPosition, b: OffsetOrPosition) { + if (typeof a === "number" || typeof b === "number") { + return a === b; + } + return a.line === b.line && a.character === b.character; +} + +function isPositionAtStartOfLine( + pos: OffsetOrPosition, + lineNumber: number, +): boolean { + return ( + typeof pos !== "number" && pos.line === lineNumber && pos.character === 0 + ); +} diff --git a/packages/app-web-docs/src/docs/components/RecordedTestVisualizer.tsx b/packages/app-web-docs/src/docs/components/RecordedTestVisualizer.tsx new file mode 100644 index 0000000000..870e91d302 --- /dev/null +++ b/packages/app-web-docs/src/docs/components/RecordedTestVisualizer.tsx @@ -0,0 +1,206 @@ +import { usePluginData } from "@docusaurus/useGlobalData"; +import type { Dispatch, JSX, ReactNode, SetStateAction } from "react"; +import { createContext, useContext, useMemo, useState } from "react"; +import type { DecorationItem } from "shiki"; +import type { + SelectionPlainObject, + TestCaseSnapshot, +} from "@cursorless/lib-common"; +import { BorderStyle, plainObjectToSelection } from "@cursorless/lib-common"; +import { Code } from "./Code"; +import { highlightColors } from "./highlightColors"; +import { highlightToDecoration } from "./highlightsToDecorations"; +import type { RecordedTest } from "./types"; + +interface RecordedTestVisualizerContextValue { + fixtures: ReadonlyMap; + renderWhitespace: boolean; + setRenderWhitespace: Dispatch>; +} + +const RecordedTestVisualizerContext = createContext< + RecordedTestVisualizerContextValue | undefined +>(undefined); + +export function RecordedTestVisualizerProvider({ + children, +}: { + children: ReactNode; +}) { + const recordedTests = usePluginData( + "recorded-tests-plugin", + ) as RecordedTest[]; + const [renderWhitespace, setRenderWhitespace] = useState(true); + const fixtures = useMemo( + () => + new Map( + recordedTests.map((recordedTest) => [recordedTest.name, recordedTest]), + ), + [recordedTests], + ); + const value = useMemo( + () => ({ + fixtures, + renderWhitespace, + setRenderWhitespace, + }), + [fixtures, renderWhitespace], + ); + + return ( + + {children} + + ); +} + +export function RecordedTestVisualizerOptions() { + const { renderWhitespace, setRenderWhitespace } = useRecordedTestVisualizer(); + + return ( +
+ +
+ ); +} + +interface ModifierProps { + fixtureName: string; +} + +export function RecordedTestVisualizer({ fixtureName }: ModifierProps) { + const { fixtures, renderWhitespace } = useRecordedTestVisualizer(); + const test = fixtures.get(fixtureName); + + if (test == null) { + throw new Error(`Unknown recorded test fixture: ${fixtureName}`); + } + + const { fixture, path } = test; + const { languageId, initialState, finalState } = fixture; + + if (finalState == null) { + throw new Error(`Fixture ${fixtureName} does not have a final state`); + } + + // oxlint-disable-next-line react_perf/jsx-no-new-object-as-prop + const link = { + name: "GitHub", + url: `https://github.com/cursorless-dev/cursorless/blob/main/resources/fixtures/recorded/docs/${path}`, + }; + + return ( +
+
+ Input + +
+
+ Output + +
+
+ ); +} + +function CodeState({ + renderWhitespace, + languageId, + link, + state, +}: { + renderWhitespace: boolean; + languageId: string; + link: { + name: string; + url: string; + }; + state: TestCaseSnapshot; +}): JSX.Element { + return ( + + {state.documentContents} + + ); +} + +function toDecoration(plainSelection: SelectionPlainObject): DecorationItem { + const selection = plainObjectToSelection(plainSelection); + + if (selection.isEmpty) { + return { + start: selection.start, + end: selection.start, + properties: { + className: ["code-cursor-before"], + }, + }; + } + + const decoration = highlightToDecoration({ + range: selection, + style: { + backgroundColor: highlightColors.content.background, + borderColorSolid: highlightColors.content.borderSolid, + borderColorPorous: highlightColors.content.borderPorous, + borderStyle: { + top: BorderStyle.solid, + bottom: BorderStyle.solid, + left: BorderStyle.solid, + right: BorderStyle.solid, + }, + borderRadius: { + topLeft: true, + topRight: true, + bottomRight: true, + bottomLeft: true, + }, + }, + }); + + const className = selection.isReversed + ? "code-cursor-before" + : "code-cursor-after"; + + return { + ...decoration, + properties: { + ...decoration.properties, + className: [className], + }, + }; +} + +function useRecordedTestVisualizer(): RecordedTestVisualizerContextValue { + const value = useContext(RecordedTestVisualizerContext); + if (value == null) { + throw new Error( + "Recorded test visualizer components must be used within RecordedTestVisualizerProvider", + ); + } + return value; +} diff --git a/packages/app-web-docs/src/docs/components/ScopeVisualizer.tsx b/packages/app-web-docs/src/docs/components/ScopeVisualizer.tsx index 4ebee6090f..3a09317016 100644 --- a/packages/app-web-docs/src/docs/components/ScopeVisualizer.tsx +++ b/packages/app-web-docs/src/docs/components/ScopeVisualizer.tsx @@ -1,9 +1,9 @@ import { usePluginData } from "@docusaurus/useGlobalData"; -import React, { createContext, useContext, useMemo, useState } from "react"; import type { Dispatch, ReactNode, SetStateAction } from "react"; +import { createContext, useContext, useMemo, useState } from "react"; import { generateDecorations } from "./calculateHighlights"; import { Code } from "./Code"; -import type { Fixture, RangeType, ScopeTests } from "./types"; +import type { Fixture, RangeType } from "./types"; import { getFacetInfo } from "./util"; interface ScopeVisualizerContextValue { @@ -19,13 +19,12 @@ const ScopeVisualizerContext = createContext< >(undefined); export function ScopeVisualizerProvider({ children }: { children: ReactNode }) { - const scopeTests = usePluginData("scope-tests-plugin") as ScopeTests; + const scopeTests = usePluginData("scope-tests-plugin") as Fixture[]; const [rangeType, setRangeType] = useState("content"); const [renderWhitespace, setRenderWhitespace] = useState(true); const fixtures = useMemo( - () => - new Map(scopeTests.fixtures.map((fixture) => [fixture.name, fixture])), - [scopeTests.fixtures], + () => new Map(scopeTests.map((fixture) => [fixture.name, fixture])), + [scopeTests], ); const value = useMemo( () => ({ diff --git a/packages/app-web-docs/src/docs/components/highlightsToDecorations.ts b/packages/app-web-docs/src/docs/components/highlightsToDecorations.ts index 40647ca471..0c4c3340d0 100644 --- a/packages/app-web-docs/src/docs/components/highlightsToDecorations.ts +++ b/packages/app-web-docs/src/docs/components/highlightsToDecorations.ts @@ -10,17 +10,19 @@ import type { BorderRadius, Highlight, Style } from "./types"; export function highlightsToDecorations( highlights: Highlight[], ): DecorationItem[] { - return highlights.map((highlight): DecorationItem => { - const { start, end } = highlight.range; - return { - start, - end, - alwaysWrap: true, - properties: { - style: getStyleString(highlight.style), - }, - }; - }); + return highlights.map(highlightToDecoration); +} + +export function highlightToDecoration(highlight: Highlight): DecorationItem { + const { start, end } = highlight.range; + return { + start, + end, + alwaysWrap: true, + properties: { + style: getStyleString(highlight.style), + }, + }; } function getStyleString(style: Style): string { diff --git a/packages/app-web-docs/src/docs/components/types.ts b/packages/app-web-docs/src/docs/components/types.ts index b5e09b6a03..bfd32cb205 100644 --- a/packages/app-web-docs/src/docs/components/types.ts +++ b/packages/app-web-docs/src/docs/components/types.ts @@ -3,14 +3,16 @@ import type { PlaintextScopeSupportFacet, ScopeSupportFacet, Range, + TestCaseFixtureLegacy, } from "@cursorless/lib-common"; export type RangeType = "content" | "removal" | "blend"; export type FacetValue = ScopeSupportFacet | PlaintextScopeSupportFacet; -export interface ScopeTests { - imports: Record; - fixtures: Fixture[]; +export interface RecordedTest { + path: string; + name: string; + fixture: TestCaseFixtureLegacy; } export interface Fixture { diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/disqualifyDelimiter.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/disqualifyDelimiter.mdx index ce3165a338..bfc6584956 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/disqualifyDelimiter.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/disqualifyDelimiter.mdx @@ -20,9 +20,9 @@ Default: `disqualify delimiter` - `"take disqualify delimiter blue air"` - Selects the disqualify delimiter containing the token containing letter `a` with a blue hat. - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/fieldAccess.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/fieldAccess.mdx index a4cf93fe0d..7a7bdb835c 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/fieldAccess.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/fieldAccess.mdx @@ -20,9 +20,9 @@ Default: `access` - `"take access blue air"` - Selects the field access containing the token containing letter `a` with a blue hat. - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/interior.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/interior.mdx index 7cdec957f1..9a921c1a6f 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/interior.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/interior.mdx @@ -20,9 +20,9 @@ Default: `interior` - `"take interior blue air"` - Selects the interior containing the token containing letter `a` with a blue hat. - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/pairDelimiter.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/pairDelimiter.mdx index 8609da3817..b247f91bdc 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/pairDelimiter.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/pairDelimiter.mdx @@ -20,9 +20,9 @@ Default: `pair delimiter` - `"take pair delimiter blue air"` - Selects the pair delimiter containing the token containing letter `a` with a blue hat. - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/string.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/string.mdx index f0b9fb3a2b..d9b418bac6 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/string.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/string.mdx @@ -20,9 +20,9 @@ Default: `parse tree string` - `"take parse tree string blue air"` - Selects the string containing the token containing letter `a` with a blue hat. - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/surroundingPairInterior.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/surroundingPairInterior.mdx index 3630656d37..93633b3643 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/surroundingPairInterior.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/surroundingPairInterior.mdx @@ -4,9 +4,9 @@ import { ScopeVisualizer, ScopeVisualizerOptions, ScopeVisualizerProvider } from Cursorless ID: `surroundingPairInterior` - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/contributing/private-scopes/textFragment.mdx b/packages/app-web-docs/src/docs/contributing/private-scopes/textFragment.mdx index 60dd56cdab..f43e2d5189 100644 --- a/packages/app-web-docs/src/docs/contributing/private-scopes/textFragment.mdx +++ b/packages/app-web-docs/src/docs/contributing/private-scopes/textFragment.mdx @@ -20,9 +20,9 @@ Default: `text fragment` - `"take text fragment blue air"` - Selects the text fragment containing the token containing letter `a` with a blue hat. - +## Visualization -## Internal scopes + The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality. diff --git a/packages/app-web-docs/src/docs/user/modifiers/ancestor.mdx b/packages/app-web-docs/src/docs/user/modifiers/ancestor.mdx index 06863dee41..b2d1cc00e4 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/ancestor.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/ancestor.mdx @@ -2,6 +2,8 @@ sidebar_label: Grand --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Grand (Ancestor) Selects the parent of a containing scope. Repeat `"grand"` to walk up more than one parent level. @@ -20,3 +22,19 @@ Default: `grand` - `"take grand state blue air"` - Selects the parent statement of the statement containing the token containing letter `a` with a blue hat. - `"take grand grand state blue air"` - Selects the grandparent statement of the statement containing the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take grand item"` + + + +### `"take grand grand item"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/containingScope.mdx b/packages/app-web-docs/src/docs/user/modifiers/containingScope.mdx index 199f716299..99f6e1379f 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/containingScope.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/containingScope.mdx @@ -1,3 +1,5 @@ +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Containing scope Expands a target to the containing instance of a scope. When the input is `"this"` with multiple selections, Cursorless expands each selection independently. @@ -11,3 +13,15 @@ Cursorless ID: `containingScope` ## Examples - `"take state blue air"` - Selects the statement containing the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take token"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/endOf.mdx b/packages/app-web-docs/src/docs/user/modifiers/endOf.mdx index 2555451ceb..4eecace75e 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/endOf.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/endOf.mdx @@ -2,6 +2,8 @@ sidebar_label: End of --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # End of Cursorless ID: `endOf` @@ -17,3 +19,15 @@ Default: `end of` ## Examples - `"take end of blue air"` - Places the cursor at the end of the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take end of token"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/everyScope.mdx b/packages/app-web-docs/src/docs/user/modifiers/everyScope.mdx index c22f80210e..860ae0804a 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/everyScope.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/everyScope.mdx @@ -2,6 +2,8 @@ sidebar_label: Every --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Every (Every scope) Selects all matching sibling scopes. It can also prefix an ordinal or relative modifier to return separate targets instead of one contiguous range. @@ -19,3 +21,15 @@ Default: `every` ## Examples - `"take every item blue air"` - Selects every item in the map containing the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take every item"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx b/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx index 5df036a40b..faa8b47f9d 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/excludeInterior.mdx @@ -2,6 +2,8 @@ sidebar_label: Bounds --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Bounds (Exclude interior) Cursorless ID: `excludeInterior` @@ -17,3 +19,15 @@ Default: `bounds` ## Examples - `"take bounds round blue air"` - Selects only the parentheses containing the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take bounds"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/extendThroughEndOf.mdx b/packages/app-web-docs/src/docs/user/modifiers/extendThroughEndOf.mdx index 9158780a9b..32023d5904 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/extendThroughEndOf.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/extendThroughEndOf.mdx @@ -2,6 +2,8 @@ sidebar_label: Tail --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Tail (Extend through end of) Extends a target through the end of its line. Inside a surrounding pair, it stops at the end of the pair's interior; use an explicit scope such as `"tail line"` to override that boundary. @@ -21,3 +23,15 @@ Default: `tail` - `"take tail blue air"` - Selects from the token containing letter `a` with a blue hat through the end of its line or surrounding pair. - `"take tail state blue air"` - Selects from the token containing letter `a` with a blue hat through the end of its containing statement. + +## Visualization + + + + + +### `"take tail"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/extendThroughStartOf.mdx b/packages/app-web-docs/src/docs/user/modifiers/extendThroughStartOf.mdx index 792e41ec66..ae1e17fb07 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/extendThroughStartOf.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/extendThroughStartOf.mdx @@ -2,6 +2,8 @@ sidebar_label: Head --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Head (Extend through start of) Extends a target through the start of its line. Inside a surrounding pair, it stops at the start of the pair's interior; use an explicit scope such as `"head line"` to override that boundary. @@ -21,3 +23,15 @@ Default: `head` - `"take head blue air"` - Selects from the token containing letter `a` with a blue hat through the start of its line or surrounding pair. - `"take head state blue air"` - Selects from the token containing letter `a` with a blue hat through the start of its containing statement. + +## Visualization + + + + + +### `"take head"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/inferPreviousMark.mdx b/packages/app-web-docs/src/docs/user/modifiers/inferPreviousMark.mdx index 7018709cff..2460a2b296 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/inferPreviousMark.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/inferPreviousMark.mdx @@ -2,6 +2,8 @@ sidebar_label: Its --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Its (Infer previous mark) Within a compound target, applies the following modifier to the previously mentioned mark. Without `"its"`, an implicit target such as `"line"` is resolved relative to the current selection instead. @@ -19,4 +21,25 @@ Default: `its` ## Examples - `"take blue air past end of its line"` - Selects from the token containing letter `a` with a blue hat through the end of the line containing that token. +- `"bring blue air to its line"` - Replaces the line containing the token containing letter `a` with a blue hat with that token. - `"bring blue air to its value"` - Replaces the value containing the token containing letter `a` with a blue hat with that token. + +## Visualization + + + + + +### `"take air past end of its line"` + + + +### `"bring air to its line"` + + + +### `"bring air to its value"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/interiorOnly.mdx b/packages/app-web-docs/src/docs/user/modifiers/interiorOnly.mdx index eef213b06c..90f5209923 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/interiorOnly.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/interiorOnly.mdx @@ -2,6 +2,8 @@ sidebar_label: Inside --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Inside (Interior only) Cursorless ID: `interiorOnly` @@ -17,3 +19,15 @@ Default: `inside` ## Examples - `"take inside round blue air"` - Selects the contents of the parentheses containing the token containing letter `a` with a blue hat, excluding the parentheses. + +## Visualization + + + + + +### `"take inside"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/keepContentFilter.mdx b/packages/app-web-docs/src/docs/user/modifiers/keepContentFilter.mdx index 13d682c6c9..0b117c57ec 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/keepContentFilter.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/keepContentFilter.mdx @@ -2,6 +2,8 @@ sidebar_label: Content --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Content (Keep content filter) Cursorless ID: `keepContentFilter` @@ -17,3 +19,15 @@ Default: `content` ## Examples - `"take content"` - Selects only the nonempty selections when there are multiple selections. + +## Visualization + + + + + +### `"take content"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/keepEmptyFilter.mdx b/packages/app-web-docs/src/docs/user/modifiers/keepEmptyFilter.mdx index 3d9beb4d0d..9d4fab7e8c 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/keepEmptyFilter.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/keepEmptyFilter.mdx @@ -2,6 +2,8 @@ sidebar_label: Empty --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Empty (Keep empty filter) Cursorless ID: `keepEmptyFilter` @@ -17,3 +19,15 @@ Default: `empty` ## Examples - `"take empty"` - Selects only the empty selections when there are multiple selections. + +## Visualization + + + + + +### `"take empty"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/leading.mdx b/packages/app-web-docs/src/docs/user/modifiers/leading.mdx index 7e4ad356f1..4f0d57bb2e 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/leading.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/leading.mdx @@ -2,6 +2,8 @@ sidebar_label: Leading --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Leading Cursorless ID: `leading` @@ -17,3 +19,19 @@ Default: `leading` ## Examples - `"take leading item blue air"` - Selects the leading delimiter of the item containing the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take leading"` + + + +### `"take leading item"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/ordinalScope.mdx b/packages/app-web-docs/src/docs/user/modifiers/ordinalScope.mdx index 38abda6d09..9dafaf169d 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/ordinalScope.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/ordinalScope.mdx @@ -1,3 +1,5 @@ +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Ordinal scope The iteration scope depends on the scope type. For example, functions iterate within a class, tokens within a line, and characters within a token. @@ -29,3 +31,35 @@ Cursorless ID: `ordinalScope` - `"take every first three states"` - Selects the first three statements in the iteration scope as individual targets. - `"take last three states"` - Selects a contiguous range containing the last three statements in the iteration scope. - `"take every last three states"` - Selects the last three statements in the iteration scope as individual targets. + +## Visualization + + + + + +### `"take first item"` + + + +### `"take last item"` + + + +### `"take first two items"` + + + +### `"take last two items"` + + + +### `"take first past second item"` + + + +### `"take second past third item"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/relativeScope.mdx b/packages/app-web-docs/src/docs/user/modifiers/relativeScope.mdx index 41e098c72c..f77b67aacf 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/relativeScope.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/relativeScope.mdx @@ -1,3 +1,5 @@ +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Relative scope The iteration scope depends on the scope type. For example, functions iterate within a class, tokens within a line, and characters within a token. @@ -39,3 +41,27 @@ Cursorless ID: `relativeScope` - `"take every previous three states blue air"` - Selects the previous three statements before the statement containing the token containing letter `a` with a blue hat as individual targets. - `"take next three states blue air"` - Selects the next three statements after the statement containing the token containing letter `a` with a blue hat as a contiguous range. - `"take every next three states blue air"` - Selects the next three statements after the statement containing the token containing letter `a` with a blue hat as individual targets. + +## Visualization + + + + + +### `"take next item"` + + + +### `"take previous item"` + + + +### `"take next two items"` + + + +### `"take previous two items"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/startOf.mdx b/packages/app-web-docs/src/docs/user/modifiers/startOf.mdx index 18ec551e08..9a723b12ec 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/startOf.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/startOf.mdx @@ -2,6 +2,8 @@ sidebar_label: Start of --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Start of Cursorless ID: `startOf` @@ -17,3 +19,15 @@ Default: `start of` ## Examples - `"take start of blue air"` - Places the cursor at the start of the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take start of token"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/toRawSelection.mdx b/packages/app-web-docs/src/docs/user/modifiers/toRawSelection.mdx index bd1d2c8ae6..3171ef6e31 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/toRawSelection.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/toRawSelection.mdx @@ -2,6 +2,8 @@ sidebar_label: Just --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Just (Raw selection) Strips semantic information from a target and treats it as a raw range. Cursorless will not use the target's removal delimiters, insertion delimiters, or scope type. This means deletion leaves adjacent whitespace and line endings untouched, insertion adds no automatic separator, and instance matching is not restricted to targets of the original scope type. When a raw target is the destination of a `"bring"` command, it inherits insertion delimiters from the source. @@ -22,3 +24,15 @@ Default: `just` - `"chuck just line"` - Deletes only the line content, leaving its line ending and therefore a blank line. - `"paste after just blue air"` - Pastes directly after the token containing letter `a` with a blue hat without inserting a separator. - `"take every instance just blue air"` - Selects every matching text occurrence of the token containing letter `a` with a blue hat, including occurrences that are not full tokens. + +## Visualization + + + + + +### `"chuck just token"` + + + + diff --git a/packages/app-web-docs/src/docs/user/modifiers/trailing.mdx b/packages/app-web-docs/src/docs/user/modifiers/trailing.mdx index 32d5a85bdc..0aa072b22f 100644 --- a/packages/app-web-docs/src/docs/user/modifiers/trailing.mdx +++ b/packages/app-web-docs/src/docs/user/modifiers/trailing.mdx @@ -2,6 +2,8 @@ sidebar_label: Trailing --- +import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer"; + # Trailing Cursorless ID: `trailing` @@ -17,3 +19,19 @@ Default: `trailing` ## Examples - `"take trailing item blue air"` - Selects the trailing delimiter of the item containing the token containing letter `a` with a blue hat. + +## Visualization + + + + + +### `"take trailing"` + + + +### `"take trailing item"` + + + + diff --git a/packages/app-web-docs/src/docs/user/scopes/anonymousFunction.mdx b/packages/app-web-docs/src/docs/user/scopes/anonymousFunction.mdx index e493b64df6..e58ff4af71 100644 --- a/packages/app-web-docs/src/docs/user/scopes/anonymousFunction.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/anonymousFunction.mdx @@ -20,9 +20,9 @@ Default: `lambda` - `"take lambda blue air"` - Selects the anonymous function containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/argumentList.mdx b/packages/app-web-docs/src/docs/user/scopes/argumentList.mdx index 0006c2d32d..bfe37ed077 100644 --- a/packages/app-web-docs/src/docs/user/scopes/argumentList.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/argumentList.mdx @@ -20,9 +20,9 @@ Default: `arg list` - `"take arg list blue air"` - Selects the argument list containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/argumentOrParameter.mdx b/packages/app-web-docs/src/docs/user/scopes/argumentOrParameter.mdx index 60920af2b2..1797e0e507 100644 --- a/packages/app-web-docs/src/docs/user/scopes/argumentOrParameter.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/argumentOrParameter.mdx @@ -20,9 +20,9 @@ Default: `arg` - `"take arg blue air"` - Selects the argument or parameter containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/attribute.mdx b/packages/app-web-docs/src/docs/user/scopes/attribute.mdx index 5e31f7aec2..60c152e3d0 100644 --- a/packages/app-web-docs/src/docs/user/scopes/attribute.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/attribute.mdx @@ -20,9 +20,9 @@ Default: `attribute` - `"take attribute blue air"` - Selects the attribute containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/boundedNonWhitespaceSequence.mdx b/packages/app-web-docs/src/docs/user/scopes/boundedNonWhitespaceSequence.mdx index 8e6cf8940d..2b38fbe67e 100644 --- a/packages/app-web-docs/src/docs/user/scopes/boundedNonWhitespaceSequence.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/boundedNonWhitespaceSequence.mdx @@ -22,9 +22,9 @@ Default: `short paint` - `"take short paint blue air"` - Selects the bounded non-whitespace sequence containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/boundedParagraph.mdx b/packages/app-web-docs/src/docs/user/scopes/boundedParagraph.mdx index d42744dcab..55d1f17fe0 100644 --- a/packages/app-web-docs/src/docs/user/scopes/boundedParagraph.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/boundedParagraph.mdx @@ -22,9 +22,9 @@ Default: `short block` - `"take short block blue air"` - Selects the bounded paragraph containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/branch.mdx b/packages/app-web-docs/src/docs/user/scopes/branch.mdx index 770dca39df..93c076ed8d 100644 --- a/packages/app-web-docs/src/docs/user/scopes/branch.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/branch.mdx @@ -20,9 +20,9 @@ Default: `branch` - `"take branch blue air"` - Selects the branch containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/chapter.mdx b/packages/app-web-docs/src/docs/user/scopes/chapter.mdx index 414beb5535..58dc44af1c 100644 --- a/packages/app-web-docs/src/docs/user/scopes/chapter.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/chapter.mdx @@ -20,9 +20,9 @@ Default: `chapter` - `"take chapter blue air"` - Selects the chapter containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/character.mdx b/packages/app-web-docs/src/docs/user/scopes/character.mdx index 8739b25106..ca919d8b4e 100644 --- a/packages/app-web-docs/src/docs/user/scopes/character.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/character.mdx @@ -20,9 +20,9 @@ Default: `char` - `"take first char blue air"` - Selects the first character in the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/class.mdx b/packages/app-web-docs/src/docs/user/scopes/class.mdx index 4e48046c88..4a9e563ed0 100644 --- a/packages/app-web-docs/src/docs/user/scopes/class.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/class.mdx @@ -20,9 +20,9 @@ Default: `class` - `"take class blue air"` - Selects the class containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx b/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx index ca263ec914..9be4239b4c 100644 --- a/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx @@ -20,9 +20,9 @@ Default: `item` - `"take item blue air"` - Selects the collection item containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/collectionKey.mdx b/packages/app-web-docs/src/docs/user/scopes/collectionKey.mdx index c22a6af372..bf947e7d12 100644 --- a/packages/app-web-docs/src/docs/user/scopes/collectionKey.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/collectionKey.mdx @@ -20,9 +20,9 @@ Default: `key` - `"take key blue air"` - Selects the collection key containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/command.mdx b/packages/app-web-docs/src/docs/user/scopes/command.mdx index f3437ea410..4d8424bf37 100644 --- a/packages/app-web-docs/src/docs/user/scopes/command.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/command.mdx @@ -20,9 +20,9 @@ Default: `command` - `"take command blue air"` - Selects the command containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/comment.mdx b/packages/app-web-docs/src/docs/user/scopes/comment.mdx index 6da0ff40d4..d76f45b806 100644 --- a/packages/app-web-docs/src/docs/user/scopes/comment.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/comment.mdx @@ -20,9 +20,9 @@ Default: `comment` - `"take comment blue air"` - Selects the comment containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/condition.mdx b/packages/app-web-docs/src/docs/user/scopes/condition.mdx index 11dd93185d..17a826a304 100644 --- a/packages/app-web-docs/src/docs/user/scopes/condition.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/condition.mdx @@ -20,9 +20,9 @@ Default: `condition` - `"take condition blue air"` - Selects the condition containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/document.mdx b/packages/app-web-docs/src/docs/user/scopes/document.mdx index 730eaad5aa..26becb3a56 100644 --- a/packages/app-web-docs/src/docs/user/scopes/document.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/document.mdx @@ -22,9 +22,9 @@ Default: `file` - `"take file blue air"` - Selects the document containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/environment.mdx b/packages/app-web-docs/src/docs/user/scopes/environment.mdx index f226299e6d..47093baa4c 100644 --- a/packages/app-web-docs/src/docs/user/scopes/environment.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/environment.mdx @@ -20,9 +20,9 @@ Default: `environment` - `"take environment blue air"` - Selects the environment containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/fullLine.mdx b/packages/app-web-docs/src/docs/user/scopes/fullLine.mdx index df895054e3..231857bb2d 100644 --- a/packages/app-web-docs/src/docs/user/scopes/fullLine.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/fullLine.mdx @@ -20,9 +20,9 @@ Default: `full line` - `"take full line blue air"` - Selects the full line containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/functionCall.mdx b/packages/app-web-docs/src/docs/user/scopes/functionCall.mdx index 47e9fb7d7d..aabc53d19a 100644 --- a/packages/app-web-docs/src/docs/user/scopes/functionCall.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/functionCall.mdx @@ -20,9 +20,9 @@ Default: `call` - `"take call blue air"` - Selects the function call containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/functionCallee.mdx b/packages/app-web-docs/src/docs/user/scopes/functionCallee.mdx index 11d8e47f82..bf4ce81cbc 100644 --- a/packages/app-web-docs/src/docs/user/scopes/functionCallee.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/functionCallee.mdx @@ -20,9 +20,9 @@ Default: `callee` - `"take callee blue air"` - Selects the function callee containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/glyph.mdx b/packages/app-web-docs/src/docs/user/scopes/glyph.mdx index 593eca25f4..a4d7258fe1 100644 --- a/packages/app-web-docs/src/docs/user/scopes/glyph.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/glyph.mdx @@ -21,9 +21,9 @@ Default: `glyph` - `"take next glyph air"` - Selects the next `a`. - `"take every glyph dollar"` - Selects every `$`. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/identifier.mdx b/packages/app-web-docs/src/docs/user/scopes/identifier.mdx index d840964258..6b4de6d1cc 100644 --- a/packages/app-web-docs/src/docs/user/scopes/identifier.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/identifier.mdx @@ -22,9 +22,9 @@ Default: `identifier` - `"take identifier blue air"` - Selects the identifier containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/ifStatement.mdx b/packages/app-web-docs/src/docs/user/scopes/ifStatement.mdx index 36336c97be..6cdef96aa4 100644 --- a/packages/app-web-docs/src/docs/user/scopes/ifStatement.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/ifStatement.mdx @@ -20,9 +20,9 @@ Default: `if state` - `"take if state blue air"` - Selects the if statement containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/line.mdx b/packages/app-web-docs/src/docs/user/scopes/line.mdx index 1a3a24d1e4..75e5a4b325 100644 --- a/packages/app-web-docs/src/docs/user/scopes/line.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/line.mdx @@ -20,9 +20,9 @@ Default: `line` - `"take line blue air"` - Selects the line containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/list.mdx b/packages/app-web-docs/src/docs/user/scopes/list.mdx index 3f55aba239..b387680985 100644 --- a/packages/app-web-docs/src/docs/user/scopes/list.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/list.mdx @@ -20,9 +20,9 @@ Default: `list` - `"take list blue air"` - Selects the list containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/map.mdx b/packages/app-web-docs/src/docs/user/scopes/map.mdx index 057d3e06af..d68daf6ea8 100644 --- a/packages/app-web-docs/src/docs/user/scopes/map.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/map.mdx @@ -20,9 +20,9 @@ Default: `map` - `"take map blue air"` - Selects the map containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/name.mdx b/packages/app-web-docs/src/docs/user/scopes/name.mdx index 0062a46bc4..d77e314446 100644 --- a/packages/app-web-docs/src/docs/user/scopes/name.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/name.mdx @@ -20,9 +20,9 @@ Default: `name` - `"take name blue air"` - Selects the name containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/namedFunction.mdx b/packages/app-web-docs/src/docs/user/scopes/namedFunction.mdx index 8e0831a0c5..6cff4ae910 100644 --- a/packages/app-web-docs/src/docs/user/scopes/namedFunction.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/namedFunction.mdx @@ -20,9 +20,9 @@ Default: `funk` - `"take funk blue air"` - Selects the named function containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/namedParagraph.mdx b/packages/app-web-docs/src/docs/user/scopes/namedParagraph.mdx index 408f3297c9..7acc1311e1 100644 --- a/packages/app-web-docs/src/docs/user/scopes/namedParagraph.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/namedParagraph.mdx @@ -20,9 +20,9 @@ Default: `paragraph` - `"take paragraph blue air"` - Selects the named paragraph containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/nonWhitespaceSequence.mdx b/packages/app-web-docs/src/docs/user/scopes/nonWhitespaceSequence.mdx index af2184a807..e63866d335 100644 --- a/packages/app-web-docs/src/docs/user/scopes/nonWhitespaceSequence.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/nonWhitespaceSequence.mdx @@ -22,9 +22,9 @@ Default: `paint` - `"take paint blue air"` - Selects the non-whitespace sequence containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/notebookCell.mdx b/packages/app-web-docs/src/docs/user/scopes/notebookCell.mdx index 61ada95876..cd3e430703 100644 --- a/packages/app-web-docs/src/docs/user/scopes/notebookCell.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/notebookCell.mdx @@ -20,9 +20,9 @@ Default: `cell` - `"take cell blue air"` - Selects the notebook cell containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/paragraph.mdx b/packages/app-web-docs/src/docs/user/scopes/paragraph.mdx index 4560ef6fcf..70579081c7 100644 --- a/packages/app-web-docs/src/docs/user/scopes/paragraph.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/paragraph.mdx @@ -22,9 +22,9 @@ Default: `block` - `"take block blue air"` - Selects the paragraph containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/part.mdx b/packages/app-web-docs/src/docs/user/scopes/part.mdx index 209e3fd6bf..d92ffde674 100644 --- a/packages/app-web-docs/src/docs/user/scopes/part.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/part.mdx @@ -20,9 +20,9 @@ Default: `part` - `"take part blue air"` - Selects the part containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/regularExpression.mdx b/packages/app-web-docs/src/docs/user/scopes/regularExpression.mdx index 7b6639d7cd..1752f8d9d7 100644 --- a/packages/app-web-docs/src/docs/user/scopes/regularExpression.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/regularExpression.mdx @@ -20,9 +20,9 @@ Default: `regex` - `"take regex blue air"` - Selects the regular expression containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/section.mdx b/packages/app-web-docs/src/docs/user/scopes/section.mdx index cdc32cc82c..ae32c08c1c 100644 --- a/packages/app-web-docs/src/docs/user/scopes/section.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/section.mdx @@ -20,9 +20,9 @@ Default: `section` - `"take section blue air"` - Selects the section containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sectionLevelFive.mdx b/packages/app-web-docs/src/docs/user/scopes/sectionLevelFive.mdx index 8006e0108c..6bad2c5ef3 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sectionLevelFive.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sectionLevelFive.mdx @@ -21,9 +21,9 @@ Default: `five section`\ - `"take five section blue air"` - Selects the section level five containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sectionLevelFour.mdx b/packages/app-web-docs/src/docs/user/scopes/sectionLevelFour.mdx index e1f1695b54..d4a07bbc4c 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sectionLevelFour.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sectionLevelFour.mdx @@ -21,9 +21,9 @@ Default: `four section`\ - `"take four section blue air"` - Selects the section level four containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sectionLevelOne.mdx b/packages/app-web-docs/src/docs/user/scopes/sectionLevelOne.mdx index b4a741635e..ea02c73b79 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sectionLevelOne.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sectionLevelOne.mdx @@ -21,9 +21,9 @@ Default: `one section`\ - `"take one section blue air"` - Selects the section level one containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sectionLevelSix.mdx b/packages/app-web-docs/src/docs/user/scopes/sectionLevelSix.mdx index 28f885aab7..3e4fa0b032 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sectionLevelSix.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sectionLevelSix.mdx @@ -21,9 +21,9 @@ Default: `six section`\ - `"take six section blue air"` - Selects the section level six containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sectionLevelThree.mdx b/packages/app-web-docs/src/docs/user/scopes/sectionLevelThree.mdx index 2995bfee60..7632af119a 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sectionLevelThree.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sectionLevelThree.mdx @@ -21,9 +21,9 @@ Default: `three section`\ - `"take three section blue air"` - Selects the section level three containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sectionLevelTwo.mdx b/packages/app-web-docs/src/docs/user/scopes/sectionLevelTwo.mdx index 726a4ae035..60f7e8c3b5 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sectionLevelTwo.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sectionLevelTwo.mdx @@ -21,9 +21,9 @@ Default: `two section`\ - `"take two section blue air"` - Selects the section level two containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/selector.mdx b/packages/app-web-docs/src/docs/user/scopes/selector.mdx index ce05ffd69f..90c963552d 100644 --- a/packages/app-web-docs/src/docs/user/scopes/selector.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/selector.mdx @@ -20,9 +20,9 @@ Default: `selector` - `"take selector blue air"` - Selects the selector containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/sentence.mdx b/packages/app-web-docs/src/docs/user/scopes/sentence.mdx index b4b449a51a..02aeb72ad6 100644 --- a/packages/app-web-docs/src/docs/user/scopes/sentence.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/sentence.mdx @@ -20,9 +20,9 @@ Default: `sentence` - `"take sentence blue air"` - Selects the sentence containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/statement.mdx b/packages/app-web-docs/src/docs/user/scopes/statement.mdx index 6c33ecca6f..ac4ee3196f 100644 --- a/packages/app-web-docs/src/docs/user/scopes/statement.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/statement.mdx @@ -20,9 +20,9 @@ Default: `state` - `"take state blue air"` - Selects the statement containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/subParagraph.mdx b/packages/app-web-docs/src/docs/user/scopes/subParagraph.mdx index 7e353ee7e4..681682fb38 100644 --- a/packages/app-web-docs/src/docs/user/scopes/subParagraph.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/subParagraph.mdx @@ -20,9 +20,9 @@ Default: `subparagraph` - `"take subparagraph blue air"` - Selects the subparagraph containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/subSection.mdx b/packages/app-web-docs/src/docs/user/scopes/subSection.mdx index 787d7babb3..e6156d04e3 100644 --- a/packages/app-web-docs/src/docs/user/scopes/subSection.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/subSection.mdx @@ -20,9 +20,9 @@ Default: `subsection` - `"take subsection blue air"` - Selects the subsection containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/subSubSection.mdx b/packages/app-web-docs/src/docs/user/scopes/subSubSection.mdx index 2a7174d8ac..16643b6cf5 100644 --- a/packages/app-web-docs/src/docs/user/scopes/subSubSection.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/subSubSection.mdx @@ -20,9 +20,9 @@ Default: `subsubsection` - `"take subsubsection blue air"` - Selects the subsubsection containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/surroundingPair.mdx b/packages/app-web-docs/src/docs/user/scopes/surroundingPair.mdx index c1fa69d24c..9cb24b0145 100644 --- a/packages/app-web-docs/src/docs/user/scopes/surroundingPair.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/surroundingPair.mdx @@ -16,9 +16,9 @@ Cursorless ID: `surroundingPair` - `"take round blue air"` - Selects the parentheses containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/token.mdx b/packages/app-web-docs/src/docs/user/scopes/token.mdx index 44283b1374..6dc03f87af 100644 --- a/packages/app-web-docs/src/docs/user/scopes/token.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/token.mdx @@ -22,9 +22,9 @@ Default: `token` - `"take token blue air"` - Selects the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/type.mdx b/packages/app-web-docs/src/docs/user/scopes/type.mdx index 5a9154d94c..8be90d6397 100644 --- a/packages/app-web-docs/src/docs/user/scopes/type.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/type.mdx @@ -20,9 +20,9 @@ Default: `type` - `"take type blue air"` - Selects the type containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/unit.mdx b/packages/app-web-docs/src/docs/user/scopes/unit.mdx index f1482a0389..43a082ed3f 100644 --- a/packages/app-web-docs/src/docs/user/scopes/unit.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/unit.mdx @@ -20,9 +20,9 @@ Default: `unit` - `"take unit blue air"` - Selects the unit containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/url.mdx b/packages/app-web-docs/src/docs/user/scopes/url.mdx index 3ad9b75c26..3cf53090ec 100644 --- a/packages/app-web-docs/src/docs/user/scopes/url.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/url.mdx @@ -20,9 +20,9 @@ Default: `link` - `"take link blue air"` - Selects the url containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/value.mdx b/packages/app-web-docs/src/docs/user/scopes/value.mdx index f11399eee8..934357b352 100644 --- a/packages/app-web-docs/src/docs/user/scopes/value.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/value.mdx @@ -20,9 +20,9 @@ Default: `value` - `"take value blue air"` - Selects the value containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/word.mdx b/packages/app-web-docs/src/docs/user/scopes/word.mdx index bcd71a92ae..fd0eb98a1a 100644 --- a/packages/app-web-docs/src/docs/user/scopes/word.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/word.mdx @@ -24,9 +24,9 @@ Legacy: `word` - `"take first sub blue air"` - Selects the first sub token word in the token containing letter `a` with a blue hat. - `"take second past fourth sub blue air"` - Selects the second through fourth sub token words in the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/xmlBothTags.mdx b/packages/app-web-docs/src/docs/user/scopes/xmlBothTags.mdx index 88b07eb2c0..242b7f3a1a 100644 --- a/packages/app-web-docs/src/docs/user/scopes/xmlBothTags.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/xmlBothTags.mdx @@ -20,9 +20,9 @@ Default: `tags` - `"take tags blue air"` - Selects both tags of the XML element containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/xmlElement.mdx b/packages/app-web-docs/src/docs/user/scopes/xmlElement.mdx index 5c9a43ab56..83c74e0f92 100644 --- a/packages/app-web-docs/src/docs/user/scopes/xmlElement.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/xmlElement.mdx @@ -20,9 +20,9 @@ Default: `element` - `"take element blue air"` - Selects the XML element containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/xmlEndTag.mdx b/packages/app-web-docs/src/docs/user/scopes/xmlEndTag.mdx index 1334a66573..b9e8cedd4c 100644 --- a/packages/app-web-docs/src/docs/user/scopes/xmlEndTag.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/xmlEndTag.mdx @@ -20,9 +20,9 @@ Default: `end tag` - `"take end tag blue air"` - Selects the XML end tag containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/docs/user/scopes/xmlStartTag.mdx b/packages/app-web-docs/src/docs/user/scopes/xmlStartTag.mdx index 8272e87b05..61c7873143 100644 --- a/packages/app-web-docs/src/docs/user/scopes/xmlStartTag.mdx +++ b/packages/app-web-docs/src/docs/user/scopes/xmlStartTag.mdx @@ -20,9 +20,9 @@ Default: `start tag` - `"take start tag blue air"` - Selects the XML start tag containing the token containing letter `a` with a blue hat. - +## Visualization -## Scopes + diff --git a/packages/app-web-docs/src/plugins/recorded-tests-plugin.ts b/packages/app-web-docs/src/plugins/recorded-tests-plugin.ts new file mode 100644 index 0000000000..f0463341aa --- /dev/null +++ b/packages/app-web-docs/src/plugins/recorded-tests-plugin.ts @@ -0,0 +1,47 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import type { LoadContext, Plugin, PluginOptions } from "@docusaurus/types"; +import { + getRecordedDocsDirPath, + getRecordedDocsPaths, + loadFixture, +} from "@cursorless/lib-node-common"; +import type { RecordedTest } from "../docs/components/types"; + +// oxlint-disable-next-line unicorn/prefer-import-meta-properties +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// oxlint-disable-next-line import/no-default-export +export default function recordedTestsPlugin( + _context: LoadContext, + _options: PluginOptions, +): Plugin { + return { + name: "recorded-tests-plugin", + + loadContent(): Promise { + const repoRoot = path.join(__dirname, "../../../.."); + // oxlint-disable-next-line node/no-process-env + process.env.CURSORLESS_REPO_ROOT = repoRoot; + + const recordedTestsDir = getRecordedDocsDirPath(); + const recordedTestPaths = getRecordedDocsPaths(); + + return Promise.all( + recordedTestPaths.map(async (test) => { + return { + path: path + .relative(recordedTestsDir, test.path) + .replaceAll(path.sep, "/"), + name: test.name, + fixture: await loadFixture(test.path), + }; + }), + ); + }, + + contentLoaded({ content, actions }) { + actions.setGlobalData(content); + }, + }; +} diff --git a/packages/app-web-docs/src/plugins/scope-tests-plugin.ts b/packages/app-web-docs/src/plugins/scope-tests-plugin.ts index 6eba614734..6396e113cd 100644 --- a/packages/app-web-docs/src/plugins/scope-tests-plugin.ts +++ b/packages/app-web-docs/src/plugins/scope-tests-plugin.ts @@ -3,16 +3,8 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import type { LoadContext, Plugin, PluginOptions } from "@docusaurus/types"; import type { ScopeTestPath } from "@cursorless/lib-node-common"; -import { - getScopeTestLanguagesRecursively, - getScopeTestPaths, -} from "@cursorless/lib-node-common"; -import type { - Fixture, - Scope, - ScopeTests, - Target, -} from "../docs/components/types"; +import { getScopeTestPaths } from "@cursorless/lib-node-common"; +import type { Fixture, Scope, Target } from "../docs/components/types"; // oxlint-disable-next-line unicorn/prefer-import-meta-properties const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -21,15 +13,25 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default function prepareAssetsPlugin( _context: LoadContext, _options: PluginOptions, -): Plugin { +): Plugin { return { name: "scope-tests-plugin", - loadContent(): ScopeTests { + loadContent(): Fixture[] { const repoRoot = path.join(__dirname, "../../../.."); // oxlint-disable-next-line node/no-process-env process.env.CURSORLESS_REPO_ROOT = repoRoot; - return prepareAssets(); + + const fixtures: Fixture[] = []; + + for (const test of getScopeTestPaths()) { + const fixture = parseTest(test); + if (fixture != null) { + fixtures.push(fixture); + } + } + + return fixtures; }, contentLoaded({ content, actions }) { @@ -38,24 +40,6 @@ export default function prepareAssetsPlugin( }; } -function prepareAssets(): ScopeTests { - const fixtures: Fixture[] = []; - - const importedLanguages = getScopeTestLanguagesRecursively(); - - for (const test of getScopeTestPaths()) { - const fixture = parseTest(test); - if (fixture != null) { - fixtures.push(fixture); - } - } - - return { - imports: importedLanguages, - fixtures, - }; -} - function parseTest(test: ScopeTestPath) { const fixture = fs .readFileSync(test.path, "utf8") diff --git a/packages/lib-common/src/references/modifierReferences.ts b/packages/lib-common/src/references/modifierReferences.ts index 2c9fac5300..69cc475802 100644 --- a/packages/lib-common/src/references/modifierReferences.ts +++ b/packages/lib-common/src/references/modifierReferences.ts @@ -642,6 +642,10 @@ Relative modifiers select scopes before or after the input target. Without \`"ev command: `${SET_SELECTION} ${TARGET} ${EXTEND_THROUGH_END_OF} ${VAR_SPOKEN_FORM} ${LINE}`, description: `Selects from the ${TARGET_DESC} through the end of the line containing that token.`, }, + { + command: `${BRING} ${TARGET} ${TO} ${VAR_SPOKEN_FORM} ${LINE}`, + description: `Replaces the line containing the ${TARGET_DESC} with that token.`, + }, { command: `${BRING} ${TARGET} ${TO} ${VAR_SPOKEN_FORM} ${VALUE}`, description: `Replaces the value containing the ${TARGET_DESC} with that token.`, diff --git a/packages/lib-node-common/src/getFixturePaths.ts b/packages/lib-node-common/src/getFixturePaths.ts index e0b6a699ad..568ee3cf19 100644 --- a/packages/lib-node-common/src/getFixturePaths.ts +++ b/packages/lib-node-common/src/getFixturePaths.ts @@ -6,6 +6,18 @@ import type { import { getCursorlessRepoRoot } from "./getCursorlessRepoRoot"; import { walkFilesSync } from "./walkSync"; +export interface RecordedTestPath { + path: string; + name: string; +} + +export interface ScopeTestPath { + path: string; + name: string; + languageId: string; + facet: ScopeSupportFacet | PlaintextScopeSupportFacet; +} + export function getFixturesPath() { return path.join(getCursorlessRepoRoot(), "resources", "fixtures"); } @@ -22,11 +34,14 @@ export function getRecordedTestsDirPath() { return path.join(getFixturesPath(), "recorded"); } +export function getRecordedDocsDirPath() { + return path.join(getFixturesPath(), "recorded", "docs"); +} export function getScopeTestsDirPath() { return path.join(getFixturesPath(), "scopes"); } -export function getRecordedTestPaths() { +export function getRecordedTestPaths(): RecordedTestPath[] { const directory = getRecordedTestsDirPath(); const relativeDir = path.dirname(directory); @@ -38,11 +53,16 @@ export function getRecordedTestPaths() { })); } -export interface ScopeTestPath { - path: string; - name: string; - languageId: string; - facet: ScopeSupportFacet | PlaintextScopeSupportFacet; +export function getRecordedDocsPaths(): RecordedTestPath[] { + const directory = getRecordedDocsDirPath(); + const relativeDir = path.dirname(directory); + + return walkFilesSync(directory) + .filter((p) => p.endsWith(".yml") || p.endsWith(".yaml")) + .map((p) => ({ + path: p, + name: pathToName(relativeDir, p), + })); } export function getScopeTestPaths(): ScopeTestPath[] { diff --git a/packages/tool-meta-updater/package.json b/packages/tool-meta-updater/package.json index 4f983d4f2a..8d390828b9 100644 --- a/packages/tool-meta-updater/package.json +++ b/packages/tool-meta-updater/package.json @@ -11,6 +11,7 @@ }, "devDependencies": { "@cursorless/lib-common": "workspace:*", + "@cursorless/lib-node-common": "workspace:*", "@pnpm/lockfile-file": "^9.1.3", "@types/lodash-es": "^4.17.12", "@types/normalize-path": "^3.0.2", diff --git a/packages/tool-meta-updater/src/metaUpdater.ts b/packages/tool-meta-updater/src/metaUpdater.ts index bfd22d6d9c..794c862f6c 100644 --- a/packages/tool-meta-updater/src/metaUpdater.ts +++ b/packages/tool-meta-updater/src/metaUpdater.ts @@ -17,6 +17,8 @@ import { scopeReferences, unsafeKeys, } from "@cursorless/lib-common"; +import { getRecordedDocsPaths } from "@cursorless/lib-node-common"; +import type { RecordedTestPath } from "@cursorless/lib-node-common"; import type { Context } from "./Context"; import { createScopeFixtureGroups } from "./scopeFixtureGroups"; import { textFormat } from "./textFormat"; @@ -45,9 +47,13 @@ export const updater = async (workspaceDir: string) => { workspaceDir, }; + // oxlint-disable-next-line node/no-process-env + process.env.CURSORLESS_REPO_ROOT = workspaceDir; + const userDir = "src/docs/user"; const contributingDir = "src/docs/contributing"; const scopeFixtureGroups = createScopeFixtureGroups(workspaceDir); + const recordedDocsPaths = getRecordedDocsPaths(); const languageIds = unsafeKeys(languageReferences); return createUpdateOptions({ @@ -95,7 +101,13 @@ export const updater = async (workspaceDir: string) => { .filter(([_, entry]) => !isPrivate(entry)) .map(([id, entry]) => [ `${userDir}/actions/${cleanId(id)}.mdx`, - updateReferenceMdx.bind(null, id, entry, undefined), + updateReferenceMdx.bind( + null, + id, + entry, + filterRecordedDocsPaths(recordedDocsPaths, "actions", id), + undefined, + ), ]), ), ...Object.fromEntries( @@ -103,7 +115,13 @@ export const updater = async (workspaceDir: string) => { .filter(([_, entry]) => !isPrivate(entry)) .map(([id, entry]) => [ `${userDir}/modifiers/${cleanId(id)}.mdx`, - updateReferenceMdx.bind(null, id, entry, undefined), + updateReferenceMdx.bind( + null, + id, + entry, + filterRecordedDocsPaths(recordedDocsPaths, "modifiers", id), + undefined, + ), ]), ), ...Object.fromEntries( @@ -115,6 +133,7 @@ export const updater = async (workspaceDir: string) => { null, id, entry, + [], scopeFixtureGroups.forScope(id as ScopeTypeType), ), ]), @@ -128,6 +147,7 @@ export const updater = async (workspaceDir: string) => { null, id, entry, + [], scopeFixtureGroups.forScope(id as ScopeTypeType), ), ]), @@ -140,6 +160,16 @@ export const updater = async (workspaceDir: string) => { }); }; +function filterRecordedDocsPaths( + recordedDocsPaths: RecordedTestPath[], + folder: "actions" | "modifiers", + id: string, +): RecordedTestPath[] { + return recordedDocsPaths.filter((path) => + new RegExp(`^docs/${folder}/${id}\\d*$`, "u").test(path.name), + ); +} + function isPrivate(entry: object): boolean { return "visibility" in entry && entry.visibility === "private"; } diff --git a/packages/tool-meta-updater/src/renderRecordedTestVisualizer.ts b/packages/tool-meta-updater/src/renderRecordedTestVisualizer.ts new file mode 100644 index 0000000000..c87a713b7e --- /dev/null +++ b/packages/tool-meta-updater/src/renderRecordedTestVisualizer.ts @@ -0,0 +1,40 @@ +import { loadFixture } from "@cursorless/lib-node-common"; +import type { RecordedTestPath } from "@cursorless/lib-node-common"; + +export const recordedTestVisualizerImport = `import { RecordedTestVisualizer, RecordedTestVisualizerOptions, RecordedTestVisualizerProvider } from "@site/src/docs/components/RecordedTestVisualizer";`; + +export async function renderRecordedTestVisualizer( + recordedDocsPaths: RecordedTestPath[], +): Promise { + if (recordedDocsPaths.length === 0) { + return undefined; + } + + const lines = [ + "## Visualization", + "", + "", + "", + "", + "", + ]; + + for (const path of recordedDocsPaths) { + const fixture = await loadFixture(path.path); + + if (fixture.command.spokenForm == null) { + throw new Error(`Fixture ${path.name} has no spoken form`); + } + + lines.push( + `### \`"${fixture.command.spokenForm}"\``, + "", + ``, + "", + ); + } + + lines.push(""); + + return lines.join("\n"); +} diff --git a/packages/tool-meta-updater/src/renderScopeVisualizerMdx.ts b/packages/tool-meta-updater/src/renderScopeVisualizerMdx.ts index 8d86caf647..23123e080b 100644 --- a/packages/tool-meta-updater/src/renderScopeVisualizerMdx.ts +++ b/packages/tool-meta-updater/src/renderScopeVisualizerMdx.ts @@ -42,32 +42,30 @@ export function renderLanguageScopeVisualizer( } lines.push(""); + return lines.join("\n"); } export function renderScopeVisualizer( groups: ScopeFixtureGroup[], ): string | undefined { - const scope = groups[0]; - if (scope == null) { + if (groups.length === 0) { return undefined; } if (groups.length > 1) { throw new Error("Expected fixtures for exactly one scope"); } - const lines = [ - "", - "", - scope.private ? "## Internal scopes" : "## Scopes", - "", - ]; + const scope = groups[0]; + const lines = ["## Visualization", "", "", ""]; + if (scope.private) { lines.push( "The following are internal scopes. They are not intended for user interaction or spoken use. These scopes exist solely for internal Cursorless functionality.", "", ); } + lines.push("", ""); renderFacets(lines, scope.facets, {}); lines.push(""); diff --git a/packages/tool-meta-updater/src/updateReferenceMdx.ts b/packages/tool-meta-updater/src/updateReferenceMdx.ts index 74aeeba485..92cae38f5d 100644 --- a/packages/tool-meta-updater/src/updateReferenceMdx.ts +++ b/packages/tool-meta-updater/src/updateReferenceMdx.ts @@ -1,6 +1,11 @@ import type { FormatPluginFnOptions } from "@pnpm/meta-updater"; import type { ReferenceEntry } from "@cursorless/lib-common"; import { capitalize } from "@cursorless/lib-common"; +import type { RecordedTestPath } from "@cursorless/lib-node-common"; +import { + recordedTestVisualizerImport, + renderRecordedTestVisualizer, +} from "./renderRecordedTestVisualizer"; import { renderScopeVisualizer, scopeVisualizerImport, @@ -10,13 +15,14 @@ import { DISABLED_BY_DEFAULT } from "./util/constants"; import { formatVariables } from "./util/formatVariables"; import { injectSpokenForm } from "./util/injectSpokenForm"; -export function updateReferenceMdx( +export async function updateReferenceMdx( id: string, entry: ReferenceEntry, + recordedDocsPaths: RecordedTestPath[], scopeFixtureGroups: ScopeFixtureGroup[] | undefined, actual: string | null, options: FormatPluginFnOptions, -): string | null { +): Promise { if (options.manifest.name !== "@cursorless/app-web-docs") { return null; } @@ -27,6 +33,8 @@ export function updateReferenceMdx( ); } + const recordedTestVisualizer = + await renderRecordedTestVisualizer(recordedDocsPaths); const scopeVisualizer = renderScopeVisualizer(scopeFixtureGroups ?? []); const expected: string[] = []; let title = entry.name; @@ -39,6 +47,9 @@ export function updateReferenceMdx( } } + if (recordedTestVisualizer != null) { + expected.push(recordedTestVisualizerImport, ""); + } if (scopeVisualizer != null) { expected.push(scopeVisualizerImport, ""); } @@ -95,6 +106,10 @@ export function updateReferenceMdx( expected.push(""); } + if (recordedTestVisualizer != null) { + expected.push(recordedTestVisualizer, ""); + } + if (scopeVisualizer != null) { expected.push(scopeVisualizer, ""); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6b852a513..c960d6c00a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -752,6 +752,9 @@ importers: '@cursorless/lib-common': specifier: workspace:* version: link:../lib-common + '@cursorless/lib-node-common': + specifier: workspace:* + version: link:../lib-node-common '@pnpm/lockfile-file': specifier: ^9.1.3 version: 9.1.3(@pnpm/logger@1001.0.1) diff --git a/resources/fixtures/recorded/docs/modifiers/ancestor.yml b/resources/fixtures/recorded/docs/modifiers/ancestor.yml new file mode 100644 index 0000000000..e1f399b875 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ancestor.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take grand item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: collectionItem} + ancestorIndex: 1 + usePrePhraseSnapshot: false +initialState: + documentContents: "[0, [1, [2], 3], 4]" + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + marks: {} +finalState: + documentContents: "[0, [1, [2], 3], 4]" + selections: + - anchor: {line: 0, character: 8} + active: {line: 0, character: 11} diff --git a/resources/fixtures/recorded/docs/modifiers/ancestor2.yml b/resources/fixtures/recorded/docs/modifiers/ancestor2.yml new file mode 100644 index 0000000000..dd004fbb7a --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ancestor2.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take grand grand item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: collectionItem} + ancestorIndex: 2 + usePrePhraseSnapshot: false +initialState: + documentContents: "[0, [1, [2], 3], 4]" + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + marks: {} +finalState: + documentContents: "[0, [1, [2], 3], 4]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 15} diff --git a/resources/fixtures/recorded/docs/modifiers/containingScope.yml b/resources/fixtures/recorded/docs/modifiers/containingScope.yml new file mode 100644 index 0000000000..bab69e2129 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/containingScope.yml @@ -0,0 +1,23 @@ +languageId: typescript +command: + version: 7 + spokenForm: take token + action: + name: setSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/endOf.yml b/resources/fixtures/recorded/docs/modifiers/endOf.yml new file mode 100644 index 0000000000..3076b94d3c --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/endOf.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take end of token + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: endOf} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 8} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/everyScope.yml b/resources/fixtures/recorded/docs/modifiers/everyScope.yml new file mode 100644 index 0000000000..5a32f5e82c --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/everyScope.yml @@ -0,0 +1,27 @@ +languageId: typescript +command: + version: 7 + spokenForm: take every item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: everyScope + scopeType: {type: collectionItem} + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 2} + - anchor: {line: 0, character: 4} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/excludeInterior.yml b/resources/fixtures/recorded/docs/modifiers/excludeInterior.yml new file mode 100644 index 0000000000..bf53857e52 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/excludeInterior.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take bounds + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: excludeInterior} + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 1} + - anchor: {line: 0, character: 8} + active: {line: 0, character: 9} diff --git a/resources/fixtures/recorded/docs/modifiers/extendThroughEndOf.yml b/resources/fixtures/recorded/docs/modifiers/extendThroughEndOf.yml new file mode 100644 index 0000000000..cb3ef46b82 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/extendThroughEndOf.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 7 + spokenForm: take tail + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: extendThroughEndOf} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 15} diff --git a/resources/fixtures/recorded/docs/modifiers/extendThroughStartOf.yml b/resources/fixtures/recorded/docs/modifiers/extendThroughStartOf.yml new file mode 100644 index 0000000000..f0f58b10c1 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/extendThroughStartOf.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 7 + spokenForm: take head + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: extendThroughStartOf} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 0} diff --git a/resources/fixtures/recorded/docs/modifiers/inferPreviousMark.yml b/resources/fixtures/recorded/docs/modifiers/inferPreviousMark.yml new file mode 100644 index 0000000000..f9a0c2dd60 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/inferPreviousMark.yml @@ -0,0 +1,39 @@ +languageId: typescript +command: + version: 7 + spokenForm: take air past end of its line + action: + name: setSelection + target: + type: range + anchor: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + active: + type: primitive + modifiers: + - {type: endOf} + - {type: inferPreviousMark} + - type: containingScope + scopeType: {type: line} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: false +initialState: + documentContents: |- + // Hello world + const aaa = 0; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 1, character: 6} + end: {line: 1, character: 9} +finalState: + documentContents: |- + // Hello world + const aaa = 0; + selections: + - anchor: {line: 1, character: 6} + active: {line: 1, character: 14} diff --git a/resources/fixtures/recorded/docs/modifiers/inferPreviousMark2.yml b/resources/fixtures/recorded/docs/modifiers/inferPreviousMark2.yml new file mode 100644 index 0000000000..1f52251395 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/inferPreviousMark2.yml @@ -0,0 +1,37 @@ +languageId: typescript +command: + version: 7 + spokenForm: bring air to its line + action: + name: replaceWithTarget + source: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + destination: + type: primitive + insertionMode: to + target: + type: primitive + modifiers: + - {type: inferPreviousMark} + - type: containingScope + scopeType: {type: line} + usePrePhraseSnapshot: false +initialState: + documentContents: |- + // Hello world + const aaa = 0; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 1, character: 6} + end: {line: 1, character: 9} +finalState: + documentContents: |- + // Hello world + aaa + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/resources/fixtures/recorded/docs/modifiers/inferPreviousMark3.yml b/resources/fixtures/recorded/docs/modifiers/inferPreviousMark3.yml new file mode 100644 index 0000000000..a115509666 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/inferPreviousMark3.yml @@ -0,0 +1,37 @@ +languageId: typescript +command: + version: 7 + spokenForm: bring air to its value + action: + name: replaceWithTarget + source: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + destination: + type: primitive + insertionMode: to + target: + type: primitive + modifiers: + - {type: inferPreviousMark} + - type: containingScope + scopeType: {type: value} + usePrePhraseSnapshot: false +initialState: + documentContents: |- + // Hello world + const aaa = 0; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 1, character: 6} + end: {line: 1, character: 9} +finalState: + documentContents: |- + // Hello world + const aaa = aaa; + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/resources/fixtures/recorded/docs/modifiers/interiorOnly.yml b/resources/fixtures/recorded/docs/modifiers/interiorOnly.yml new file mode 100644 index 0000000000..e8791b34c8 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/interiorOnly.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 7 + spokenForm: take inside + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: interiorOnly} + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/keepContentFilter.yml b/resources/fixtures/recorded/docs/modifiers/keepContentFilter.yml new file mode 100644 index 0000000000..16a09c9458 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/keepContentFilter.yml @@ -0,0 +1,34 @@ +languageId: typescript +command: + version: 7 + spokenForm: take content + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: keepContentFilter} + usePrePhraseSnapshot: false +initialState: + documentContents: |- + // Hello + + // world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 8} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 8} + marks: {} +finalState: + documentContents: |- + // Hello + + // world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 8} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/keepEmptyFilter.yml b/resources/fixtures/recorded/docs/modifiers/keepEmptyFilter.yml new file mode 100644 index 0000000000..d17f11884b --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/keepEmptyFilter.yml @@ -0,0 +1,32 @@ +languageId: typescript +command: + version: 7 + spokenForm: take empty + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: keepEmptyFilter} + usePrePhraseSnapshot: false +initialState: + documentContents: |- + // Hello + + // world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 8} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 8} + marks: {} +finalState: + documentContents: |- + // Hello + + // world + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} diff --git a/resources/fixtures/recorded/docs/modifiers/leading.yml b/resources/fixtures/recorded/docs/modifiers/leading.yml new file mode 100644 index 0000000000..892b5485a0 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/leading.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 7 + spokenForm: take leading + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: leading} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 2} + active: {line: 0, character: 3} diff --git a/resources/fixtures/recorded/docs/modifiers/leading2.yml b/resources/fixtures/recorded/docs/modifiers/leading2.yml new file mode 100644 index 0000000000..510b5a5584 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/leading2.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take leading item + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: leading} + - type: containingScope + scopeType: {type: collectionItem} + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 2} + active: {line: 0, character: 4} diff --git a/resources/fixtures/recorded/docs/modifiers/ordinalScope.yml b/resources/fixtures/recorded/docs/modifiers/ordinalScope.yml new file mode 100644 index 0000000000..c0baf16248 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ordinalScope.yml @@ -0,0 +1,25 @@ +languageId: typescript +command: + version: 7 + spokenForm: take first item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: ordinalScope + scopeType: {type: collectionItem} + start: 0 + length: 1 + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 2} diff --git a/resources/fixtures/recorded/docs/modifiers/ordinalScope2.yml b/resources/fixtures/recorded/docs/modifiers/ordinalScope2.yml new file mode 100644 index 0000000000..dde71ff245 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ordinalScope2.yml @@ -0,0 +1,25 @@ +languageId: typescript +command: + version: 7 + spokenForm: take last item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: ordinalScope + scopeType: {type: collectionItem} + start: -1 + length: 1 + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/ordinalScope3.yml b/resources/fixtures/recorded/docs/modifiers/ordinalScope3.yml new file mode 100644 index 0000000000..a2bbecfe38 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ordinalScope3.yml @@ -0,0 +1,25 @@ +languageId: typescript +command: + version: 7 + spokenForm: take first two items + action: + name: setSelection + target: + type: primitive + modifiers: + - type: ordinalScope + scopeType: {type: collectionItem} + start: 0 + length: 2 + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 5} diff --git a/resources/fixtures/recorded/docs/modifiers/ordinalScope4.yml b/resources/fixtures/recorded/docs/modifiers/ordinalScope4.yml new file mode 100644 index 0000000000..3f4fa887a9 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ordinalScope4.yml @@ -0,0 +1,25 @@ +languageId: typescript +command: + version: 7 + spokenForm: take last two items + action: + name: setSelection + target: + type: primitive + modifiers: + - type: ordinalScope + scopeType: {type: collectionItem} + start: -2 + length: 2 + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/ordinalScope5.yml b/resources/fixtures/recorded/docs/modifiers/ordinalScope5.yml new file mode 100644 index 0000000000..b791f60427 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ordinalScope5.yml @@ -0,0 +1,34 @@ +languageId: typescript +command: + version: 7 + spokenForm: take first past second item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: range + anchor: + type: ordinalScope + scopeType: {type: collectionItem} + start: 0 + length: 1 + active: + type: ordinalScope + scopeType: {type: collectionItem} + start: 1 + length: 1 + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 5} diff --git a/resources/fixtures/recorded/docs/modifiers/ordinalScope6.yml b/resources/fixtures/recorded/docs/modifiers/ordinalScope6.yml new file mode 100644 index 0000000000..5a5c374d9e --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/ordinalScope6.yml @@ -0,0 +1,34 @@ +languageId: typescript +command: + version: 7 + spokenForm: take second past third item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: range + anchor: + type: ordinalScope + scopeType: {type: collectionItem} + start: 1 + length: 1 + active: + type: ordinalScope + scopeType: {type: collectionItem} + start: 2 + length: 1 + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/relativeScope.yml b/resources/fixtures/recorded/docs/modifiers/relativeScope.yml new file mode 100644 index 0000000000..e5d6a955a3 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/relativeScope.yml @@ -0,0 +1,26 @@ +languageId: typescript +command: + version: 7 + spokenForm: take next item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: relativeScope + scopeType: {type: collectionItem} + offset: 1 + length: 1 + direction: forward + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/relativeScope2.yml b/resources/fixtures/recorded/docs/modifiers/relativeScope2.yml new file mode 100644 index 0000000000..30a1f299aa --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/relativeScope2.yml @@ -0,0 +1,26 @@ +languageId: typescript +command: + version: 7 + spokenForm: take previous item + action: + name: setSelection + target: + type: primitive + modifiers: + - type: relativeScope + scopeType: {type: collectionItem} + offset: 1 + length: 1 + direction: backward + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 2} diff --git a/resources/fixtures/recorded/docs/modifiers/relativeScope3.yml b/resources/fixtures/recorded/docs/modifiers/relativeScope3.yml new file mode 100644 index 0000000000..0a167f471f --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/relativeScope3.yml @@ -0,0 +1,26 @@ +languageId: typescript +command: + version: 7 + spokenForm: take next two items + action: + name: setSelection + target: + type: primitive + modifiers: + - type: relativeScope + scopeType: {type: collectionItem} + offset: 1 + length: 2 + direction: forward + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 8} diff --git a/resources/fixtures/recorded/docs/modifiers/relativeScope4.yml b/resources/fixtures/recorded/docs/modifiers/relativeScope4.yml new file mode 100644 index 0000000000..3f5b865b77 --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/relativeScope4.yml @@ -0,0 +1,26 @@ +languageId: typescript +command: + version: 7 + spokenForm: take previous two items + action: + name: setSelection + target: + type: primitive + modifiers: + - type: relativeScope + scopeType: {type: collectionItem} + offset: 1 + length: 2 + direction: backward + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 5} diff --git a/resources/fixtures/recorded/docs/modifiers/startOf.yml b/resources/fixtures/recorded/docs/modifiers/startOf.yml new file mode 100644 index 0000000000..114206779c --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/startOf.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take start of token + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: startOf} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} diff --git a/resources/fixtures/recorded/docs/modifiers/toRawSelection.yml b/resources/fixtures/recorded/docs/modifiers/toRawSelection.yml new file mode 100644 index 0000000000..268a4e593a --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/toRawSelection.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: chuck just token + action: + name: remove + target: + type: primitive + modifiers: + - {type: toRawSelection} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: // world + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} diff --git a/resources/fixtures/recorded/docs/modifiers/trailing.yml b/resources/fixtures/recorded/docs/modifiers/trailing.yml new file mode 100644 index 0000000000..58849c086e --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/trailing.yml @@ -0,0 +1,22 @@ +languageId: typescript +command: + version: 7 + spokenForm: take trailing + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: trailing} + usePrePhraseSnapshot: false +initialState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: // Hello world + selections: + - anchor: {line: 0, character: 8} + active: {line: 0, character: 9} diff --git a/resources/fixtures/recorded/docs/modifiers/trailing2.yml b/resources/fixtures/recorded/docs/modifiers/trailing2.yml new file mode 100644 index 0000000000..73985cd35e --- /dev/null +++ b/resources/fixtures/recorded/docs/modifiers/trailing2.yml @@ -0,0 +1,24 @@ +languageId: typescript +command: + version: 7 + spokenForm: take trailing item + action: + name: setSelection + target: + type: primitive + modifiers: + - {type: trailing} + - type: containingScope + scopeType: {type: collectionItem} + usePrePhraseSnapshot: false +initialState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[1, 2, 3]" + selections: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 7}