-
-
Notifications
You must be signed in to change notification settings - Fork 93
Implemented paste action #115
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import { | ||
| Action, | ||
| ActionPreferences, | ||
| ActionReturnValue, | ||
| Graph, | ||
| TypedSelection, | ||
| } from "../Types"; | ||
| import displayPendingEditDecorations from "../editDisplayUtils"; | ||
| import { env, Selection } from "vscode"; | ||
| import { runForEachEditor } from "../targetUtils"; | ||
| import { computeChangedOffsets } from "../computeChangedOffsets"; | ||
| import { flatten, zip } from "lodash"; | ||
| import update from "immutability-helper"; | ||
|
|
||
| export default class Paste implements Action { | ||
| targetPreferences: ActionPreferences[] = [{ insideOutsideType: "inside" }]; | ||
|
|
||
| constructor(private graph: Graph) { | ||
| this.run = this.run.bind(this); | ||
| } | ||
|
|
||
| async run([targets]: [TypedSelection[]]): Promise<ActionReturnValue> { | ||
| await displayPendingEditDecorations( | ||
| targets, | ||
| this.graph.editStyles.pendingModification0, | ||
| this.graph.editStyles.pendingLineModification0 | ||
| ); | ||
|
|
||
| const text = await env.clipboard.readText(); | ||
|
|
||
| if (text.length === 0) { | ||
| throw new Error("Can't paste empty clipboard"); | ||
| } | ||
|
|
||
| const lines = text.trim().split("\n"); | ||
|
|
||
| const getText = | ||
| targets.length === lines.length | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we decided to match VSCode behaviour and check that number of lines is divisible by number of targets and if so split clipboard into blocks
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's what line 37 does
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That checks equality, not divisibility, no? What am I missing?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is how vscode paste work. It only splits the clipboard if they are the same amount/length.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope! Try it out. Copy 4 lines, then make 2 cursors and paste. It will split up the 4 lines into 2 blocks of 2
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not on windows at least. I tried it multiple times before I made the implementation and I tried it once again now.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haha wait really? That's really odd that that would differ on platforms. I'll try it one more time today; maybe I messed something up in my testing
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Really strange if it differs. |
||
| ? // Paste each line on each target | ||
| (index: number) => lines[index] | ||
| : // Paste entire clipboard on each target | ||
| () => text; | ||
|
|
||
| const edits = targets.map((target, index) => ({ | ||
| editor: target.selection.editor, | ||
| range: target.selection.selection, | ||
| originalSelection: target, | ||
| newText: getText(index), | ||
| })); | ||
|
|
||
| const thatMark = flatten( | ||
| await runForEachEditor( | ||
| edits, | ||
| (edit) => edit.editor, | ||
| async (editor, edits) => { | ||
| const newEdits = zip(edits, computeChangedOffsets(editor, edits)).map( | ||
| ([originalEdit, changedEdit]) => ({ | ||
| originalRange: originalEdit!.range, | ||
| originalSelection: originalEdit!.originalSelection, | ||
| newText: originalEdit!.newText, | ||
| newStartOffset: changedEdit!.startOffset, | ||
| newEndOffset: changedEdit!.endOffset, | ||
| }) | ||
| ); | ||
|
|
||
| await editor.edit((editBuilder) => { | ||
| newEdits.forEach((edit) => { | ||
| if (edit.originalRange.isEmpty) { | ||
| editBuilder.insert(edit.originalRange.start, edit.newText); | ||
| } else { | ||
| editBuilder.replace(edit.originalRange, edit.newText); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| return newEdits.map((edit) => { | ||
| const start = editor.document.positionAt(edit.newStartOffset); | ||
| const end = editor.document.positionAt(edit.newEndOffset); | ||
| const isReversed = | ||
| edit.originalSelection.selection.selection.isReversed; | ||
| const selection = new Selection( | ||
| isReversed ? end : start, | ||
| isReversed ? start : end | ||
| ); | ||
| return { | ||
| editor, | ||
| typedSelection: update(edit.originalSelection, { | ||
| selection: { | ||
| selection: { $set: selection }, | ||
| }, | ||
| }), | ||
| selection, | ||
| }; | ||
| }); | ||
|
AndreasArvidsson marked this conversation as resolved.
|
||
| } | ||
| ) | ||
| ); | ||
|
|
||
| await displayPendingEditDecorations( | ||
| thatMark.map(({ typedSelection }) => typedSelection), | ||
| this.graph.editStyles.pendingModification0, | ||
| this.graph.editStyles.pendingLineModification0 | ||
| ); | ||
|
|
||
| return { returnValue: null, thatMark }; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.