(cm, inserted, deleted, sel)
| 1077 | var lastCopied = null; |
| 1078 | |
| 1079 | function applyTextInput(cm, inserted, deleted, sel) { |
| 1080 | var doc = cm.doc; |
| 1081 | cm.display.shift = false; |
| 1082 | if (!sel) sel = doc.sel; |
| 1083 | |
| 1084 | var textLines = splitLines(inserted), multiPaste = null; |
| 1085 | // When pasing N lines into N selections, insert one line per selection |
| 1086 | if (cm.state.pasteIncoming && sel.ranges.length > 1) { |
| 1087 | if (lastCopied && lastCopied.join("\n") == inserted) |
| 1088 | multiPaste = sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines); |
| 1089 | else if (textLines.length == sel.ranges.length) |
| 1090 | multiPaste = map(textLines, function(l) { return [l]; }); |
| 1091 | } |
| 1092 | |
| 1093 | // Normal behavior is to insert the new text into every selection |
| 1094 | for (var i = sel.ranges.length - 1; i >= 0; i--) { |
| 1095 | var range = sel.ranges[i]; |
| 1096 | var from = range.from(), to = range.to(); |
| 1097 | if (range.empty()) { |
| 1098 | if (deleted && deleted > 0) // Handle deletion |
| 1099 | from = Pos(from.line, from.ch - deleted); |
| 1100 | else if (cm.state.overwrite && !cm.state.pasteIncoming) // Handle overwrite |
| 1101 | to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); |
| 1102 | } |
| 1103 | var updateInput = cm.curOp.updateInput; |
| 1104 | var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, |
| 1105 | origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"}; |
| 1106 | makeChange(cm.doc, changeEvent); |
| 1107 | signalLater(cm, "inputRead", cm, changeEvent); |
| 1108 | // When an 'electric' character is inserted, immediately trigger a reindent |
| 1109 | if (inserted && !cm.state.pasteIncoming && cm.options.electricChars && |
| 1110 | cm.options.smartIndent && range.head.ch < 100 && |
| 1111 | (!i || sel.ranges[i - 1].head.line != range.head.line)) { |
| 1112 | var mode = cm.getModeAt(range.head); |
| 1113 | var end = changeEnd(changeEvent); |
| 1114 | if (mode.electricChars) { |
| 1115 | for (var j = 0; j < mode.electricChars.length; j++) |
| 1116 | if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { |
| 1117 | indentLine(cm, end.line, "smart"); |
| 1118 | break; |
| 1119 | } |
| 1120 | } else if (mode.electricInput) { |
| 1121 | if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch))) |
| 1122 | indentLine(cm, end.line, "smart"); |
| 1123 | } |
| 1124 | } |
| 1125 | } |
| 1126 | ensureCursorVisible(cm); |
| 1127 | cm.curOp.updateInput = updateInput; |
| 1128 | cm.curOp.typing = true; |
| 1129 | cm.state.pasteIncoming = cm.state.cutIncoming = false; |
| 1130 | } |
| 1131 | |
| 1132 | function copyableRanges(cm) { |
| 1133 | var text = [], ranges = []; |
no test coverage detected
searching dependent graphs…