diff --git a/data/fixtures/recorded/actions/bringTokenToLine.yml b/data/fixtures/recorded/actions/bringTokenToLine.yml new file mode 100644 index 0000000000..bd2718387d --- /dev/null +++ b/data/fixtures/recorded/actions/bringTokenToLine.yml @@ -0,0 +1,45 @@ +languageId: plaintext +command: + version: 7 + spokenForm: bring token to line + action: + name: replaceWithTarget + source: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: token} + destination: + type: primitive + insertionMode: to + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: line} + usePrePhraseSnapshot: false +initialState: + documentContents: a b c + selections: + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + marks: {} +finalState: + documentContents: b + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - type: UntypedTarget + contentRange: + start: {line: 0, character: 0} + end: {line: 0, character: 1} + isReversed: false + hasExplicitRange: true + sourceMark: + - type: UntypedTarget + contentRange: + start: {line: 0, character: 1} + end: {line: 0, character: 1} + isReversed: false + hasExplicitRange: true diff --git a/data/fixtures/recorded/actions/moveTokenToLine.yml b/data/fixtures/recorded/actions/moveTokenToLine.yml new file mode 100644 index 0000000000..a50cbe8abb --- /dev/null +++ b/data/fixtures/recorded/actions/moveTokenToLine.yml @@ -0,0 +1,39 @@ +languageId: plaintext +command: + version: 7 + spokenForm: move token to line + action: + name: moveToTarget + source: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: token} + destination: + type: primitive + insertionMode: to + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: line} + usePrePhraseSnapshot: false +initialState: + documentContents: a b c + selections: + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + marks: {} +finalState: + documentContents: b + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - type: UntypedTarget + contentRange: + start: {line: 0, character: 0} + end: {line: 0, character: 1} + isReversed: false + hasExplicitRange: true + sourceMark: [] diff --git a/packages/cursorless-engine/src/actions/BringMoveSwap.ts b/packages/cursorless-engine/src/actions/BringMoveSwap.ts index 982e28bf7f..5681afb061 100644 --- a/packages/cursorless-engine/src/actions/BringMoveSwap.ts +++ b/packages/cursorless-engine/src/actions/BringMoveSwap.ts @@ -103,7 +103,13 @@ abstract class BringMoveSwap { // Add source edit // Prevent multiple instances of the same expanded source. if (!usedSources.includes(source)) { - usedSources.push(source); + // Allow move where the destination contains the source. eg "bring token to line" + if ( + this.type !== "move" || + !destination.target.getRemovalRange().contains(source.contentRange) + ) { + usedSources.push(source); + } if (this.type === "bring") { results.push({ edit: source diff --git a/packages/cursorless-engine/src/util/unifyRanges.ts b/packages/cursorless-engine/src/util/unifyRanges.ts index 23d1ec1b32..7d97039c09 100644 --- a/packages/cursorless-engine/src/util/unifyRanges.ts +++ b/packages/cursorless-engine/src/util/unifyRanges.ts @@ -56,5 +56,7 @@ function mergeTargets(targets: Target[]): Target { } function intersects(targetA: Target, targetB: Target) { - return !!targetA.getRemovalRange().intersection(targetB.getRemovalRange()); + return ( + targetA.getRemovalRange().intersection(targetB.getRemovalRange()) != null + ); }