diff --git a/src/actions/Clear.ts b/src/actions/Clear.ts index c51d64d404..bb57eeed7e 100644 --- a/src/actions/Clear.ts +++ b/src/actions/Clear.ts @@ -1,4 +1,4 @@ -import PlainTarget from "../processTargets/targets/PlainTarget"; +import { PlainTarget } from "../processTargets/targets"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { setSelectionsAndFocusEditor } from "../util/setSelectionsAndFocusEditor"; diff --git a/src/actions/CutCopy.ts b/src/actions/CutCopy.ts index fa540683c6..a60051647f 100644 --- a/src/actions/CutCopy.ts +++ b/src/actions/CutCopy.ts @@ -1,4 +1,4 @@ -import PlainTarget from "../processTargets/targets/PlainTarget"; +import { PlainTarget } from "../processTargets/targets"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { getOutsideOverflow } from "../util/targetUtils"; diff --git a/src/actions/EditNew/runNotebookCellTargets.ts b/src/actions/EditNew/runNotebookCellTargets.ts index dfd58107bd..f8ac4bdc7a 100644 --- a/src/actions/EditNew/runNotebookCellTargets.ts +++ b/src/actions/EditNew/runNotebookCellTargets.ts @@ -1,5 +1,5 @@ import { commands, Selection } from "vscode"; -import { NotebookCellPositionTarget } from "../../processTargets/targets/NotebookCellTarget"; +import { NotebookCellPositionTarget } from "../../processTargets/targets"; import { Target } from "../../typings/target.types"; import { Graph } from "../../typings/Types"; import { createThatMark, ensureSingleTarget } from "../../util/targetUtils"; diff --git a/src/processTargets/marks/CursorStage.ts b/src/processTargets/marks/CursorStage.ts index 71a4727fb8..3c2e8e9363 100644 --- a/src/processTargets/marks/CursorStage.ts +++ b/src/processTargets/marks/CursorStage.ts @@ -4,17 +4,21 @@ import { ProcessedTargetsContext } from "../../typings/Types"; import { isReversed } from "../../util/selectionUtils"; import { MarkStage } from "../PipelineStages.types"; import WeakTarget from "../targets/WeakTarget"; +import TokenTarget from "../targets/TokenTarget"; export default class CursorStage implements MarkStage { constructor(_modifier: CursorMark) {} run(context: ProcessedTargetsContext): Target[] { return context.currentSelections.map((selection) => { - return new WeakTarget({ + const parameters = { editor: selection.editor, isReversed: isReversed(selection.selection), contentRange: selection.selection, - }); + }; + return selection.selection.isEmpty + ? new WeakTarget(parameters) + : new TokenTarget(parameters); }); } } diff --git a/src/processTargets/marks/DecoratedSymbolStage.ts b/src/processTargets/marks/DecoratedSymbolStage.ts index 76050d95a3..59b25dacd6 100644 --- a/src/processTargets/marks/DecoratedSymbolStage.ts +++ b/src/processTargets/marks/DecoratedSymbolStage.ts @@ -2,7 +2,7 @@ import { Target } from "../../typings/target.types"; import { DecoratedSymbolMark } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; import { MarkStage } from "../PipelineStages.types"; -import WeakTarget from "../targets/WeakTarget"; +import { WeakTarget } from "../targets"; export default class implements MarkStage { constructor(private modifier: DecoratedSymbolMark) {} diff --git a/src/processTargets/modifiers/ItemStage/ItemStage.ts b/src/processTargets/modifiers/ItemStage/ItemStage.ts index 6d0d83feaf..b7d2b7e77a 100644 --- a/src/processTargets/modifiers/ItemStage/ItemStage.ts +++ b/src/processTargets/modifiers/ItemStage/ItemStage.ts @@ -10,7 +10,7 @@ import { ProcessedTargetsContext } from "../../../typings/Types"; import { getInsertionDelimiter } from "../../../util/nodeSelectors"; import { getRangeLength } from "../../../util/rangeUtils"; import { ModifierStage } from "../../PipelineStages.types"; -import ScopeTypeTarget from "../../targets/ScopeTypeTarget"; +import { ScopeTypeTarget } from "../../targets"; import ContainingSyntaxScopeStage, { SimpleContainingScopeModifier, } from "../scopeTypeStages/ContainingSyntaxScopeStage"; diff --git a/src/processTargets/modifiers/LeadingTrailingStages.ts b/src/processTargets/modifiers/LeadingTrailingStages.ts index 0494e08290..961b1088ff 100644 --- a/src/processTargets/modifiers/LeadingTrailingStages.ts +++ b/src/processTargets/modifiers/LeadingTrailingStages.ts @@ -5,16 +5,19 @@ import { } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; import { ModifierStage } from "../PipelineStages.types"; +import { weakContainingTokenStage } from "./commonWeakContainingScopeStages"; export class LeadingStage implements ModifierStage { constructor(private modifier: LeadingModifier) {} run(context: ProcessedTargetsContext, target: Target): Target[] { - const leading = target.getLeadingDelimiterTarget(); - if (leading == null) { - throw Error("No available leading range"); - } - return [leading]; + return weakContainingTokenStage.run(context, target).map((target) => { + const leading = target.getLeadingDelimiterTarget(); + if (leading == null) { + throw Error("No available leading delimiter range"); + } + return leading; + }); } } @@ -22,10 +25,12 @@ export class TrailingStage implements ModifierStage { constructor(private modifier: TrailingModifier) {} run(context: ProcessedTargetsContext, target: Target): Target[] { - const trailing = target.getTrailingDelimiterTarget(); - if (trailing == null) { - throw Error("No available trailing range"); - } - return [trailing]; + return weakContainingTokenStage.run(context, target).map((target) => { + const trailing = target.getTrailingDelimiterTarget(); + if (trailing == null) { + throw Error("No available trailing delimiter range"); + } + return trailing; + }); } } diff --git a/src/processTargets/modifiers/commonWeakContainingScopeStages.ts b/src/processTargets/modifiers/commonWeakContainingScopeStages.ts index 7f6d45e6f9..487d76dd08 100644 --- a/src/processTargets/modifiers/commonWeakContainingScopeStages.ts +++ b/src/processTargets/modifiers/commonWeakContainingScopeStages.ts @@ -15,3 +15,11 @@ export const weakContainingLineStage = new ModifyIfWeakStage({ scopeType: { type: "line" }, }, }); + +export const weakContainingTokenStage = new ModifyIfWeakStage({ + type: "modifyIfWeak", + modifier: { + type: "containingScope", + scopeType: { type: "token" }, + }, +}); diff --git a/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts b/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts index bcd15861f2..233064a2d8 100644 --- a/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts @@ -7,7 +7,7 @@ import { import { ProcessedTargetsContext } from "../../../typings/Types"; import { getTokensInRange, PartialToken } from "../../../util/getTokensInRange"; import { ModifierStage } from "../../PipelineStages.types"; -import TokenTarget from "../../targets/TokenTarget"; +import { TokenTarget } from "../../targets"; export default class implements ModifierStage { constructor(private modifier: ContainingScopeModifier | EveryScopeModifier) {} diff --git a/src/processTargets/processTargets.ts b/src/processTargets/processTargets.ts index ec51362e61..bb56993ed7 100644 --- a/src/processTargets/processTargets.ts +++ b/src/processTargets/processTargets.ts @@ -12,8 +12,7 @@ import { ensureSingleEditor } from "../util/targetUtils"; import getMarkStage from "./getMarkStage"; import getModifierStage from "./getModifierStage"; import { ModifierStage } from "./PipelineStages.types"; -import PlainTarget from "./targets/PlainTarget"; -import PositionTarget from "./targets/PositionTarget"; +import { PlainTarget, PositionTarget } from "./targets"; /** * Converts the abstract target descriptions provided by the user to a concrete diff --git a/src/processTargets/targets/TokenTarget.ts b/src/processTargets/targets/TokenTarget.ts index c19c77f175..fab6e3992f 100644 --- a/src/processTargets/targets/TokenTarget.ts +++ b/src/processTargets/targets/TokenTarget.ts @@ -1,11 +1,11 @@ import { Range } from "vscode"; +import { BaseTarget } from "."; import { Target } from "../../typings/target.types"; import { getTokenLeadingDelimiterTarget, getTokenRemovalRange, getTokenTrailingDelimiterTarget, } from "../targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior"; -import BaseTarget from "./BaseTarget"; export default class TokenTarget extends BaseTarget { insertionDelimiter = " "; diff --git a/src/test/suite/fixtures/recorded/selectionTypes/clearLeading.yml b/src/test/suite/fixtures/recorded/selectionTypes/clearLeading.yml new file mode 100644 index 0000000000..c985780699 --- /dev/null +++ b/src/test/suite/fixtures/recorded/selectionTypes/clearLeading.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: clear leading + version: 2 + targets: + - type: primitive + modifiers: + - {type: leading} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaa bbb ccc + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: aaabbb ccc + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: leading}]}] diff --git a/src/test/suite/fixtures/recorded/selectionTypes/clearTrailing.yml b/src/test/suite/fixtures/recorded/selectionTypes/clearTrailing.yml new file mode 100644 index 0000000000..3a40f79e01 --- /dev/null +++ b/src/test/suite/fixtures/recorded/selectionTypes/clearTrailing.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: clear trailing + version: 2 + targets: + - type: primitive + modifiers: + - {type: trailing} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaa bbb ccc + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} +finalState: + documentContents: aaa bbbccc + selections: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} + thatMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: trailing}]}] diff --git a/src/util/tryConstructTarget.ts b/src/util/tryConstructTarget.ts index 220489f7c2..3a2bb0af29 100644 --- a/src/util/tryConstructTarget.ts +++ b/src/util/tryConstructTarget.ts @@ -1,7 +1,9 @@ import { Range, TextEditor } from "vscode"; -import { CommonTargetParameters } from "../processTargets/targets/BaseTarget"; -import LineTarget from "../processTargets/targets/LineTarget"; -import PlainTarget from "../processTargets/targets/PlainTarget"; +import { + CommonTargetParameters, + LineTarget, + PlainTarget, +} from "../processTargets/targets"; import { Target } from "../typings/target.types"; type TargetConstructor = new (