(cm, inserted, deleted, sel, origin)
| 21 | } |
| 22 | |
| 23 | export function applyTextInput(cm, inserted, deleted, sel, origin) { |
| 24 | let doc = cm.doc |
| 25 | cm.display.shift = false |
| 26 | if (!sel) sel = doc.sel |
| 27 | |
| 28 | let recent = +new Date - 200 |
| 29 | let paste = origin == "paste" || cm.state.pasteIncoming > recent |
| 30 | let textLines = splitLinesAuto(inserted), multiPaste = null |
| 31 | // When pasting N lines into N selections, insert one line per selection |
| 32 | if (paste && sel.ranges.length > 1) { |
| 33 | if (lastCopied && lastCopied.text.join("\n") == inserted) { |
| 34 | if (sel.ranges.length % lastCopied.text.length == 0) { |
| 35 | multiPaste = [] |
| 36 | for (let i = 0; i < lastCopied.text.length; i++) |
| 37 | multiPaste.push(doc.splitLines(lastCopied.text[i])) |
| 38 | } |
| 39 | } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) { |
| 40 | multiPaste = map(textLines, l => [l]) |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | let updateInput = cm.curOp.updateInput |
| 45 | // Normal behavior is to insert the new text into every selection |
| 46 | for (let i = sel.ranges.length - 1; i >= 0; i--) { |
| 47 | let range = sel.ranges[i] |
| 48 | let from = range.from(), to = range.to() |
| 49 | if (range.empty()) { |
| 50 | if (deleted && deleted > 0) // Handle deletion |
| 51 | from = Pos(from.line, from.ch - deleted) |
| 52 | else if (cm.state.overwrite && !paste) // Handle overwrite |
| 53 | to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)) |
| 54 | else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == textLines.join("\n")) |
| 55 | from = to = Pos(from.line, 0) |
| 56 | } |
| 57 | let changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, |
| 58 | origin: origin || (paste ? "paste" : cm.state.cutIncoming > recent ? "cut" : "+input")} |
| 59 | makeChange(cm.doc, changeEvent) |
| 60 | signalLater(cm, "inputRead", cm, changeEvent) |
| 61 | } |
| 62 | if (inserted && !paste) |
| 63 | triggerElectric(cm, inserted) |
| 64 | |
| 65 | ensureCursorVisible(cm) |
| 66 | if (cm.curOp.updateInput < 2) cm.curOp.updateInput = updateInput |
| 67 | cm.curOp.typing = true |
| 68 | cm.state.pasteIncoming = cm.state.cutIncoming = -1 |
| 69 | } |
| 70 | |
| 71 | export function handlePaste(e, cm) { |
| 72 | let pasted = e.clipboardData && e.clipboardData.getData("Text") |
no test coverage detected