Skip to content

Add factories for stages and scope handlers #1396

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 41 additions & 10 deletions packages/cursorless-engine/src/actions/Actions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Snippets } from "../core/Snippets";
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
import { ModifierStageFactory } from "../processTargets/ModifierStageFactory";
import { Bring, Move, Swap } from "./BringMoveSwap";
import Call from "./Call";
import Clear from "./Clear";
Expand Down Expand Up @@ -58,16 +59,28 @@ import { ActionRecord } from "./actions.types";
* Keeps a map from action names to objects that implement the given action
*/
export class Actions implements ActionRecord {
constructor(private snippets: Snippets, private rangeUpdater: RangeUpdater) {}
constructor(
private snippets: Snippets,
private rangeUpdater: RangeUpdater,
private modifierStageFactory: ModifierStageFactory,
) {}

callAsFunction = new Call(this);
clearAndSetSelection = new Clear(this);
copyToClipboard = new CopyToClipboard(this.rangeUpdater);
cutToClipboard = new CutToClipboard(this);
deselect = new Deselect();
editNew = new EditNew(this.rangeUpdater, this);
editNewLineAfter = new EditNewAfter(this.rangeUpdater, this);
editNewLineBefore = new EditNewBefore(this.rangeUpdater, this);
editNew = new EditNew(this.rangeUpdater, this, this.modifierStageFactory);
editNewLineAfter = new EditNewAfter(
this.rangeUpdater,
this,
this.modifierStageFactory,
);
editNewLineBefore = new EditNewBefore(
this.rangeUpdater,
this,
this.modifierStageFactory,
);
executeCommand = new ExecuteCommand(this.rangeUpdater);
extractVariable = new ExtractVariable(this.rangeUpdater);
findInWorkspace = new FindInWorkspace(this);
Expand All @@ -77,12 +90,23 @@ export class Actions implements ActionRecord {
getText = new GetText();
highlight = new Highlight();
indentLine = new IndentLine(this.rangeUpdater);
insertCopyAfter = new InsertCopyAfter(this.rangeUpdater);
insertCopyBefore = new InsertCopyBefore(this.rangeUpdater);
insertCopyAfter = new InsertCopyAfter(
this.rangeUpdater,
this.modifierStageFactory,
);
insertCopyBefore = new InsertCopyBefore(
this.rangeUpdater,
this.modifierStageFactory,
);
insertEmptyLineAfter = new InsertEmptyLineAfter(this.rangeUpdater);
insertEmptyLineBefore = new InsertEmptyLineBefore(this.rangeUpdater);
insertEmptyLinesAround = new InsertEmptyLinesAround(this.rangeUpdater);
insertSnippet = new InsertSnippet(this.rangeUpdater, this.snippets, this);
insertSnippet = new InsertSnippet(
this.rangeUpdater,
this.snippets,
this,
this.modifierStageFactory,
);
moveToTarget = new Move(this.rangeUpdater);
outdentLine = new OutdentLine(this.rangeUpdater);
pasteFromClipboard = new PasteFromClipboard(this.rangeUpdater, this);
Expand All @@ -94,7 +118,10 @@ export class Actions implements ActionRecord {
revealDefinition = new RevealDefinition(this.rangeUpdater);
revealTypeDefinition = new RevealTypeDefinition(this.rangeUpdater);
reverseTargets = new Reverse(this);
rewrapWithPairedDelimiter = new Rewrap(this.rangeUpdater);
rewrapWithPairedDelimiter = new Rewrap(
this.rangeUpdater,
this.modifierStageFactory,
);
scrollToBottom = new ScrollToBottom();
scrollToCenter = new ScrollToCenter();
scrollToTop = new ScrollToTop();
Expand All @@ -107,9 +134,13 @@ export class Actions implements ActionRecord {
showReferences = new ShowReferences(this.rangeUpdater);
sortTargets = new Sort(this);
swapTargets = new Swap(this.rangeUpdater);
toggleLineBreakpoint = new ToggleBreakpoint();
toggleLineBreakpoint = new ToggleBreakpoint(this.modifierStageFactory);
toggleLineComment = new ToggleLineComment(this.rangeUpdater);
unfoldRegion = new Unfold(this.rangeUpdater);
wrapWithPairedDelimiter = new Wrap(this.rangeUpdater);
wrapWithSnippet = new WrapWithSnippet(this.rangeUpdater, this.snippets);
wrapWithSnippet = new WrapWithSnippet(
this.rangeUpdater,
this.snippets,
this.modifierStageFactory,
);
}
11 changes: 8 additions & 3 deletions packages/cursorless-engine/src/actions/EditNew/EditNew.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { RangeUpdater } from "../../core/updateSelections/RangeUpdater";
import { containingLineIfUntypedStage } from "../../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { containingLineIfUntypedModifier } from "../../processTargets/modifiers/commonContainingScopeIfUntypedModifiers";
import PositionStage from "../../processTargets/modifiers/PositionStage";
import { ModifierStageFactory } from "../../processTargets/ModifierStageFactory";
import { ModifierStage } from "../../processTargets/PipelineStages.types";
import { ide } from "../../singletons/ide.singleton";
import { Target } from "../../typings/target.types";
Expand All @@ -15,10 +16,14 @@ import { runEditNewNotebookCellTargets } from "./runNotebookCellTargets";

export class EditNew implements Action {
getFinalStages(): ModifierStage[] {
return [containingLineIfUntypedStage];
return [this.modifierStageFactory.create(containingLineIfUntypedModifier)];
}

constructor(private rangeUpdater: RangeUpdater, private actions: Actions) {
constructor(
private rangeUpdater: RangeUpdater,
private actions: Actions,
private modifierStageFactory: ModifierStageFactory,
) {
this.run = this.run.bind(this);
}

Expand Down
27 changes: 20 additions & 7 deletions packages/cursorless-engine/src/actions/InsertCopy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,24 @@ import {
import { flatten, zip } from "lodash";
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
import { performEditsAndUpdateSelectionsWithBehavior } from "../core/updateSelections/updateSelections";
import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { ModifierStageFactory } from "../processTargets/ModifierStageFactory";
import { containingLineIfUntypedModifier } from "../processTargets/modifiers/commonContainingScopeIfUntypedModifiers";
import { ide } from "../singletons/ide.singleton";
import { Target } from "../typings/target.types";
import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor";
import { createThatMark, runOnTargetsForEachEditor } from "../util/targetUtils";
import { Action, ActionReturnValue } from "./actions.types";

class InsertCopy implements Action {
getFinalStages = () => [containingLineIfUntypedStage];
getFinalStages = () => [
this.modifierStageFactory.create(containingLineIfUntypedModifier),
];

constructor(private rangeUpdater: RangeUpdater, private isBefore: boolean) {
constructor(
private rangeUpdater: RangeUpdater,
private modifierStageFactory: ModifierStageFactory,
private isBefore: boolean,
) {
this.run = this.run.bind(this);
this.runForEditor = this.runForEditor.bind(this);
}
Expand Down Expand Up @@ -90,13 +97,19 @@ class InsertCopy implements Action {
}

export class CopyContentBefore extends InsertCopy {
constructor(rangeUpdater: RangeUpdater) {
super(rangeUpdater, true);
constructor(
rangeUpdater: RangeUpdater,
modifierStageFactory: ModifierStageFactory,
) {
super(rangeUpdater, modifierStageFactory, true);
}
}

export class CopyContentAfter extends InsertCopy {
constructor(rangeUpdater: RangeUpdater) {
super(rangeUpdater, false);
constructor(
rangeUpdater: RangeUpdater,
modifierStageFactory: ModifierStageFactory,
) {
super(rangeUpdater, modifierStageFactory, false);
}
}
4 changes: 3 additions & 1 deletion packages/cursorless-engine/src/actions/InsertSnippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
callFunctionAndUpdateSelectionInfos,
getSelectionInfo,
} from "../core/updateSelections/updateSelections";
import { ModifierStageFactory } from "../processTargets/ModifierStageFactory";
import { ModifyIfUntypedExplicitStage } from "../processTargets/modifiers/ConditionalModifierStages";
import { ide } from "../singletons/ide.singleton";
import {
Expand Down Expand Up @@ -43,6 +44,7 @@ export default class InsertSnippet implements Action {
private rangeUpdater: RangeUpdater,
private snippets: Snippets,
private actions: Actions,
private modifierStageFactory: ModifierStageFactory,
) {
this.run = this.run.bind(this);
}
Expand All @@ -53,7 +55,7 @@ export default class InsertSnippet implements Action {
return defaultScopeTypes.length === 0
? []
: [
new ModifyIfUntypedExplicitStage({
new ModifyIfUntypedExplicitStage(this.modifierStageFactory, {
type: "cascading",
modifiers: defaultScopeTypes.map((scopeType) => ({
type: "containingScope",
Expand Down
14 changes: 11 additions & 3 deletions packages/cursorless-engine/src/actions/Rewrap.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { FlashStyle } from "@cursorless/common";
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
import { performEditsAndUpdateRanges } from "../core/updateSelections/updateSelections";
import { containingSurroundingPairIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { ModifierStageFactory } from "../processTargets/ModifierStageFactory";
import { containingSurroundingPairIfUntypedModifier } from "../processTargets/modifiers/commonContainingScopeIfUntypedModifiers";
import { ide } from "../singletons/ide.singleton";
import { Target } from "../typings/target.types";
import {
Expand All @@ -12,9 +13,16 @@ import {
import { Action, ActionReturnValue } from "./actions.types";

export default class Rewrap implements Action {
getFinalStages = () => [containingSurroundingPairIfUntypedStage];
getFinalStages = () => [
this.modifierStageFactory.create(
containingSurroundingPairIfUntypedModifier,
),
];

constructor(private rangeUpdater: RangeUpdater) {
constructor(
private rangeUpdater: RangeUpdater,
private modifierStageFactory: ModifierStageFactory,
) {
this.run = this.run.bind(this);
}

Expand Down
11 changes: 7 additions & 4 deletions packages/cursorless-engine/src/actions/ToggleBreakpoint.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { BreakpointDescriptor, FlashStyle } from "@cursorless/common";
import { ModifierStageFactory } from "../processTargets/ModifierStageFactory";
import { containingLineIfUntypedModifier } from "../processTargets/modifiers/commonContainingScopeIfUntypedModifiers";
import { ide } from "../singletons/ide.singleton";
import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { Target } from "../typings/target.types";
import { flashTargets, runOnTargetsForEachEditor } from "../util/targetUtils";
import { Action, ActionReturnValue } from "./actions.types";
import { BreakpointDescriptor, FlashStyle } from "@cursorless/common";

export default class ToggleBreakpoint implements Action {
getFinalStages = () => [containingLineIfUntypedStage];
getFinalStages = () => [
this.modifierStageFactory.create(containingLineIfUntypedModifier),
];

constructor() {
constructor(private modifierStageFactory: ModifierStageFactory) {
this.run = this.run.bind(this);
}

Expand Down
9 changes: 7 additions & 2 deletions packages/cursorless-engine/src/actions/WrapWithSnippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FlashStyle, ScopeType } from "@cursorless/common";
import { Snippets } from "../core/Snippets";
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
import { callFunctionAndUpdateSelections } from "../core/updateSelections/updateSelections";
import { ModifierStageFactory } from "../processTargets/ModifierStageFactory";
import { ModifyIfUntypedStage } from "../processTargets/modifiers/ConditionalModifierStages";
import { ide } from "../singletons/ide.singleton";
import {
Expand Down Expand Up @@ -29,7 +30,11 @@ type WrapWithSnippetArg = NamedSnippetArg | CustomSnippetArg;
export default class WrapWithSnippet implements Action {
private snippetParser = new SnippetParser();

constructor(private rangeUpdater: RangeUpdater, private snippets: Snippets) {
constructor(
private rangeUpdater: RangeUpdater,
private snippets: Snippets,
private modifierStageFactory: ModifierStageFactory,
) {
this.run = this.run.bind(this);
}

Expand All @@ -41,7 +46,7 @@ export default class WrapWithSnippet implements Action {
}

return [
new ModifyIfUntypedStage({
new ModifyIfUntypedStage(this.modifierStageFactory, {
type: "modifyIfUntyped",
modifier: {
type: "containingScope",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,26 @@ import { ActionRecord } from "../../actions/actions.types";
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports
import { Actions } from "../../actions/Actions";
import { TestCaseRecorder } from "../../index";
import processTargets from "../../processTargets";
import { TargetPipeline } from "../../processTargets";
import { MarkStageFactory } from "../../processTargets/MarkStageFactory";
import { ModifierStageFactory } from "../../processTargets/ModifierStageFactory";
import { ide } from "../../singletons/ide.singleton";
import { Target } from "../../typings/target.types";
import { TreeSitter } from "../../typings/TreeSitter";
import {
ProcessedTargetsContext,
SelectionWithEditor,
} from "../../typings/Types";
import { Target } from "../../typings/target.types";
import { isString } from "../../util/type";
import { Debug } from "../Debug";
import { ThatMark } from "../ThatMark";
import {
canonicalizeAndValidateCommand,
checkForOldInference,
} from "../commandVersionUpgrades/canonicalizeAndValidateCommand";
import { Debug } from "../Debug";
import inferFullTargets from "../inferFullTargets";
import { ThatMark } from "../ThatMark";
import { selectionToThatTarget } from "./selectionToThatTarget";

// TODO: Do this using the graph once we migrate its dependencies onto the graph
export class CommandRunner {
constructor(
private treeSitter: TreeSitter,
Expand All @@ -37,6 +38,8 @@ export class CommandRunner {
private actions: ActionRecord,
private thatMark: ThatMark,
private sourceMark: ThatMark,
private modifierStageFactory: ModifierStageFactory,
private markStageFactory: MarkStageFactory,
) {
this.runCommandBackwardCompatible =
this.runCommandBackwardCompatible.bind(this);
Expand Down Expand Up @@ -137,11 +140,17 @@ export class CommandRunner {
// warning.
checkForOldInference(partialTargetDescriptors);

const targets = processTargets(
// FIXME: Construct this on a per-request basis in the composition root.
// Then we don't need `CommandRunner` to depend on these factories and be
// tightly coupled to `TargetPipeline`.
const pipeline = new TargetPipeline(
this.modifierStageFactory,
this.markStageFactory,
processedTargetsContext,
targetDescriptors,
);

const targets = pipeline.processTargets(targetDescriptors);

const {
returnValue,
thatSelections: newThatSelections,
Expand Down
12 changes: 11 additions & 1 deletion packages/cursorless-engine/src/cursorlessEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { Debug } from "./core/Debug";
import { HatTokenMapImpl } from "./core/HatTokenMapImpl";
import { Snippets } from "./core/Snippets";
import { RangeUpdater } from "./core/updateSelections/RangeUpdater";
import { MarkStageFactoryImpl } from "./processTargets/MarkStageFactoryImpl";
import { ModifierStageFactoryImpl } from "./processTargets/ModifierStageFactoryImpl";
import { ScopeHandlerFactoryImpl } from "./processTargets/modifiers/scopeHandlers";
import { injectIde } from "./singletons/ide.singleton";

export function createCursorlessEngine(
Expand Down Expand Up @@ -33,7 +36,12 @@ export function createCursorlessEngine(

const testCaseRecorder = new TestCaseRecorder(hatTokenMap);

const actions = new Actions(snippets, rangeUpdater);
const scopeHandlerFactory = new ScopeHandlerFactoryImpl();
const markStageFactory = new MarkStageFactoryImpl();
const modifierStageFactory = new ModifierStageFactoryImpl(
scopeHandlerFactory,
);
const actions = new Actions(snippets, rangeUpdater, modifierStageFactory);

const thatMark = new ThatMark();
const sourceMark = new ThatMark();
Expand All @@ -46,6 +54,8 @@ export function createCursorlessEngine(
actions,
thatMark,
sourceMark,
modifierStageFactory,
markStageFactory,
);

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Mark } from "@cursorless/common";
import { MarkStage } from "./PipelineStages.types";

export interface MarkStageFactory {
create(mark: Mark): MarkStage;
}
Loading