Fixed selection bug and added source mark to copy lines (#384)

* Fix so clone up moves selection

* Added source mark to copy lines

* Added tests for clone linesg

* Updated tests
This commit is contained in:
Andreas Arvidsson 2021-12-12 15:04:50 +01:00 committed by GitHub
parent 0712ee8fa9
commit 9df55b699c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 230 additions and 82 deletions

View File

@ -46,14 +46,20 @@ class CopyLines implements Action {
return ranges.map(({ range, isParagraph }) => {
const delimiter = isParagraph ? "\n\n" : "\n";
let text = editor.document.getText(range);
text = this.isUp ? `${text}${delimiter}` : `${delimiter}${text}`;
const length = text.length;
text = this.isUp ? `${delimiter}${text}` : `${text}${delimiter}`;
const newRange = this.isUp
? new Range(range.start, range.start)
: new Range(range.end, range.end);
? new Range(range.end, range.end)
: new Range(range.start, range.start);
return {
editor,
range: newRange,
text,
edit: {
editor,
range: newRange,
text,
isReplace: this.isUp,
},
offset: delimiter.length,
length,
};
});
}
@ -62,27 +68,44 @@ class CopyLines implements Action {
const results = flatten(
await runOnTargetsForEachEditor(targets, async (editor, targets) => {
const ranges = this.getRanges(editor, targets);
const edits = this.getEdits(editor, ranges);
const editWrappers = this.getEdits(editor, ranges);
const rangeSelections = ranges.map(
({ range }) => new Selection(range.start, range.end)
);
const [updatedSelections, copySelections] =
const [editorSelections, copySelections] =
await performEditsAndUpdateSelections(
this.graph.rangeUpdater,
editor,
edits,
[
targets.map((target) => target.selection.selection),
ranges.map(({ range }) => new Selection(range.start, range.end)),
]
editWrappers.map((wrapper) => wrapper.edit),
[editor.selections, rangeSelections]
);
editor.revealRange(updatedSelections[0]);
editor.selections = editorSelections;
editor.revealRange(copySelections[0]);
let sourceSelections;
if (this.isUp) {
sourceSelections = editWrappers.map((wrapper) => {
const startIndex =
editor.document.offsetAt(wrapper.edit.range.start) +
wrapper.offset;
const endIndex = startIndex + wrapper.length;
return new Selection(
editor.document.positionAt(startIndex),
editor.document.positionAt(endIndex)
);
});
} else {
sourceSelections = rangeSelections;
}
return {
thatMark: updatedSelections.map((selection) => ({
sourceMark: sourceSelections.map((selection) => ({
editor,
selection,
})),
copySelections: copySelections.map((selection) => ({
thatMark: copySelections.map((selection) => ({
editor,
selection,
})),
@ -91,24 +114,25 @@ class CopyLines implements Action {
);
await displayPendingEditDecorationsForSelection(
results.flatMap((result) => result.copySelections),
results.flatMap((result) => result.thatMark),
this.graph.editStyles.justAdded.token
);
const sourceMark = results.flatMap((result) => result.sourceMark);
const thatMark = results.flatMap((result) => result.thatMark);
return { thatMark };
return { sourceMark, thatMark };
}
}
export class CopyLinesUp extends CopyLines {
constructor(graph: Graph) {
super(graph, false);
super(graph, true);
}
}
export class CopyLinesDown extends CopyLines {
constructor(graph: Graph) {
super(graph, true);
super(graph, false);
}
}

View File

@ -0,0 +1,31 @@
languageId: plaintext
command:
version: 1
spokenForm: clone harp
action: insertCopyAfter
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: h}
initialState:
documentContents: hello
selections:
- anchor: {line: 0, character: 5}
active: {line: 0, character: 5}
marks:
default.h:
start: {line: 0, character: 0}
end: {line: 0, character: 5}
finalState:
documentContents: |-
hello
hello
selections:
- anchor: {line: 1, character: 5}
active: {line: 1, character: 5}
thatMark:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 5}
sourceMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 5}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: h}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]

View File

@ -0,0 +1,31 @@
languageId: plaintext
command:
version: 1
spokenForm: clone harp
action: insertCopyAfter
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: h}
initialState:
documentContents: hello
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
marks:
default.h:
start: {line: 0, character: 0}
end: {line: 0, character: 5}
finalState:
documentContents: |-
hello
hello
selections:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 0}
thatMark:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 5}
sourceMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 5}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: h}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]

View File

@ -0,0 +1,31 @@
languageId: plaintext
command:
version: 1
spokenForm: clone up harp
action: insertCopyBefore
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: h}
initialState:
documentContents: hello
selections:
- anchor: {line: 0, character: 5}
active: {line: 0, character: 5}
marks:
default.h:
start: {line: 0, character: 0}
end: {line: 0, character: 5}
finalState:
documentContents: |-
hello
hello
selections:
- anchor: {line: 0, character: 5}
active: {line: 0, character: 5}
thatMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 5}
sourceMark:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 5}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: h}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]

View File

@ -0,0 +1,31 @@
languageId: plaintext
command:
version: 1
spokenForm: clone up harp
action: insertCopyBefore
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: h}
initialState:
documentContents: hello
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
marks:
default.h:
start: {line: 0, character: 0}
end: {line: 0, character: 5}
finalState:
documentContents: |-
hello
hello
selections:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 0}
thatMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 5}
sourceMark:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 5}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: h}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]

View File

@ -0,0 +1,31 @@
languageId: plaintext
command:
version: 1
spokenForm: clone up vest
action: insertCopyBefore
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: v}
initialState:
documentContents: " const value = \"Hello world\";"
selections:
- anchor: {line: 0, character: 15}
active: {line: 0, character: 15}
marks:
default.v:
start: {line: 0, character: 10}
end: {line: 0, character: 15}
finalState:
documentContents: |2-
const value = "Hello world";
const value = "Hello world";
selections:
- anchor: {line: 0, character: 15}
active: {line: 0, character: 15}
thatMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 32}
sourceMark:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 32}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: v}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]

View File

@ -0,0 +1,31 @@
languageId: plaintext
command:
version: 1
spokenForm: clone vest
action: insertCopyAfter
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: v}
initialState:
documentContents: " const value = \"Hello world\";"
selections:
- anchor: {line: 0, character: 15}
active: {line: 0, character: 15}
marks:
default.v:
start: {line: 0, character: 10}
end: {line: 0, character: 15}
finalState:
documentContents: |2-
const value = "Hello world";
const value = "Hello world";
selections:
- anchor: {line: 1, character: 15}
active: {line: 1, character: 15}
thatMark:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 32}
sourceMark:
- anchor: {line: 0, character: 0}
active: {line: 0, character: 32}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: v}, selectionType: token, position: contents, insideOutsideType: inside, modifier: {type: identity}}]

View File

@ -1,31 +0,0 @@
languageId: typescript
command:
version: 1
spokenForm: dupe up vest
action: insertCopyBefore
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: v}
initialState:
documentContents: |
const value = "Hello world";
selections:
- anchor: {line: 1, character: 11}
active: {line: 1, character: 11}
marks:
default.v:
start: {line: 1, character: 6}
end: {line: 1, character: 11}
finalState:
documentContents: |
const value = "Hello world";
const value = "Hello world";
selections:
- anchor: {line: 1, character: 11}
active: {line: 1, character: 11}
thatMark:
- anchor: {line: 1, character: 6}
active: {line: 1, character: 11}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: v}, selectionType: token, position: contents, modifier: {type: identity}, insideOutsideType: inside}]

View File

@ -1,31 +0,0 @@
languageId: typescript
command:
version: 1
spokenForm: dupe vest
action: insertCopyAfter
targets:
- type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: v}
initialState:
documentContents: |
const value = "Hello world";
selections:
- anchor: {line: 1, character: 11}
active: {line: 1, character: 11}
marks:
default.v:
start: {line: 1, character: 6}
end: {line: 1, character: 11}
finalState:
documentContents: |
const value = "Hello world";
const value = "Hello world";
selections:
- anchor: {line: 2, character: 11}
active: {line: 2, character: 11}
thatMark:
- anchor: {line: 2, character: 6}
active: {line: 2, character: 11}
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: v}, selectionType: token, position: contents, modifier: {type: identity}, insideOutsideType: inside}]