-
-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { ActionType } from "@cursorless/common"; | ||
import { invertBy } from "lodash"; | ||
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / test-docs-build
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (macos-latest, stable)
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (ubuntu-latest, stable)
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (macos-latest, stable)
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / test-docs-build
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (windows-latest, stable)
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (ubuntu-latest, stable)
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (windows-latest, stable)
Check failure on line 2 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (ubuntu-latest, legacy)
|
||
import { CustomSpokenFormGeneratorImpl } from "../generateSpokenForm/CustomSpokenFormGeneratorImpl"; | ||
import { defaultSpokenFormMap } from "../spokenForms/defaultSpokenFormMap"; | ||
import { StepComponent, StepComponentParser } from "./StepComponent"; | ||
|
||
export class ActionComponentHandler implements StepComponentParser { | ||
private actionMap: Record<string, ActionType[]> = invertBy( | ||
defaultSpokenFormMap.action, | ||
(val) => val.spokenForms[0], | ||
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / test-docs-build
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (macos-latest, stable)
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (ubuntu-latest, stable)
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (macos-latest, stable)
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / test-docs-build
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (windows-latest, stable)
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (ubuntu-latest, stable)
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (windows-latest, stable)
Check failure on line 10 in packages/cursorless-engine/src/core/ActionComponentHandler.ts GitHub Actions / Test (ubuntu-latest, legacy)
|
||
) as Record<string, ActionType[]>; | ||
|
||
constructor( | ||
private customSpokenFormGenerator: CustomSpokenFormGeneratorImpl, | ||
) {} | ||
|
||
async parse(arg: string): Promise<StepComponent> { | ||
return { | ||
content: { | ||
type: "term", | ||
value: this.getActionSpokenForm(this.parseActionId(arg)), | ||
}, | ||
}; | ||
} | ||
|
||
private getActionSpokenForm(actionId: ActionType) { | ||
const spokenForm = | ||
this.customSpokenFormGenerator.actionIdToSpokenForm(actionId); | ||
|
||
return spokenForm.spokenForms[0]; | ||
} | ||
|
||
private parseActionId(arg: string): ActionType { | ||
const actionIds = this.actionMap[arg]; | ||
|
||
if (actionIds == null || actionIds.length === 0) { | ||
throw new Error(`Unknown action: ${arg}`); | ||
} | ||
|
||
return actionIds[0]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { CommandComplete, TutorialId, loadFixture } from "@cursorless/common"; | ||
import path from "path"; | ||
import { CustomSpokenFormGeneratorImpl } from "../generateSpokenForm/CustomSpokenFormGeneratorImpl"; | ||
import { canonicalizeAndValidateCommand } from "./commandVersionUpgrades/canonicalizeAndValidateCommand"; | ||
import { StepComponent, StepComponentParser } from "./StepComponent"; | ||
import { TutorialError } from "./TutorialError"; | ||
|
||
export class CursorlessCommandHandler implements StepComponentParser { | ||
constructor( | ||
private tutorialRootDir: string, | ||
private tutorialId: TutorialId, | ||
private customSpokenFormGenerator: CustomSpokenFormGeneratorImpl, | ||
) {} | ||
|
||
async parse(arg: string): Promise<StepComponent> { | ||
const fixture = await loadFixture( | ||
path.join(this.tutorialRootDir, this.tutorialId, arg), | ||
); | ||
const command = canonicalizeAndValidateCommand(fixture.command); | ||
|
||
return { | ||
initialState: fixture.initialState, | ||
languageId: fixture.languageId, | ||
trigger: { | ||
type: "command", | ||
command, | ||
}, | ||
content: { | ||
type: "command", | ||
value: this.getCommandSpokenForm(command), | ||
}, | ||
}; | ||
} | ||
|
||
/** | ||
* Handle the argument of a "{step:cloneStateInk.yml}"" | ||
*/ | ||
private getCommandSpokenForm(command: CommandComplete) { | ||
// command to be said for moving to the next step | ||
const spokenForm = | ||
this.customSpokenFormGenerator.commandToSpokenForm(command); | ||
|
||
if (spokenForm.type === "error") { | ||
throw new TutorialError( | ||
`Error while processing spoken form for command: ${spokenForm.reason}`, | ||
{ requiresTalonUpdate: spokenForm.requiresTalonUpdate }, | ||
); | ||
} | ||
|
||
return spokenForm.spokenForms[0]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { CustomSpokenFormGeneratorImpl } from "../generateSpokenForm/CustomSpokenFormGeneratorImpl"; | ||
import { StepComponent, StepComponentParser } from "./StepComponent"; | ||
|
||
export class GraphemeComponentHandler implements StepComponentParser { | ||
constructor( | ||
private customSpokenFormGenerator: CustomSpokenFormGeneratorImpl, | ||
) {} | ||
|
||
async parse(arg: string): Promise<StepComponent> { | ||
return { | ||
content: { | ||
type: "term", | ||
value: this.getGraphemeSpokenForm(arg), | ||
}, | ||
}; | ||
} | ||
|
||
private getGraphemeSpokenForm(grapheme: string) { | ||
const spokenForm = | ||
this.customSpokenFormGenerator.graphemeToSpokenForm(grapheme); | ||
|
||
return spokenForm.spokenForms[0]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { TestCaseSnapshot, TutorialStepFragment } from "@cursorless/common"; | ||
import { TutorialStepTrigger } from "../api/Tutorial"; | ||
|
||
export interface StepComponent { | ||
initialState?: TestCaseSnapshot; | ||
languageId?: string; | ||
trigger?: TutorialStepTrigger; | ||
content: TutorialStepFragment; | ||
} | ||
|
||
export interface StepComponentParser { | ||
parse(arg: string): Promise<StepComponent>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export class TutorialError extends Error { | ||
public readonly requiresTalonUpdate: boolean; | ||
|
||
constructor( | ||
message: string, | ||
{ requiresTalonUpdate }: { requiresTalonUpdate: boolean }, | ||
) { | ||
super(message); | ||
|
||
this.requiresTalonUpdate = requiresTalonUpdate; | ||
} | ||
} |