in lib/ace/keyboard/vim.js [3515:3665]
paste: function(cm, actionArgs, vim) {
var cur = copyCursor(cm.getCursor());
var register = vimGlobalState.registerController.getRegister(
actionArgs.registerName);
var text = register.toString();
if (!text) {
return;
}
if (actionArgs.matchIndent) {
var tabSize = cm.getOption("tabSize");
// length that considers tabs and tabSize
var whitespaceLength = function(str) {
var tabs = (str.split("\t").length - 1);
var spaces = (str.split(" ").length - 1);
return tabs * tabSize + spaces * 1;
};
var currentLine = cm.getLine(cm.getCursor().line);
var indent = whitespaceLength(currentLine.match(/^\s*/)[0]);
// chomp last newline b/c don't want it to match /^\s*/gm
var chompedText = text.replace(/\n$/, '');
var wasChomped = text !== chompedText;
var firstIndent = whitespaceLength(text.match(/^\s*/)[0]);
var text = chompedText.replace(/^\s*/gm, function(wspace) {
var newIndent = indent + (whitespaceLength(wspace) - firstIndent);
if (newIndent < 0) {
return "";
}
else if (cm.getOption("indentWithTabs")) {
var quotient = Math.floor(newIndent / tabSize);
return Array(quotient + 1).join('\t');
}
else {
return Array(newIndent + 1).join(' ');
}
});
text += wasChomped ? "\n" : "";
}
if (actionArgs.repeat > 1) {
var text = Array(actionArgs.repeat + 1).join(text);
}
var linewise = register.linewise;
var blockwise = register.blockwise;
if (blockwise) {
text = text.split('\n');
if (linewise) {
text.pop();
}
for (var i = 0; i < text.length; i++) {
text[i] = (text[i] == '') ? ' ' : text[i];
}
cur.ch += actionArgs.after ? 1 : 0;
cur.ch = Math.min(lineLength(cm, cur.line), cur.ch);
} else if (linewise) {
if(vim.visualMode) {
text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n';
} else if (actionArgs.after) {
// Move the newline at the end to the start instead, and paste just
// before the newline character of the line we are on right now.
text = '\n' + text.slice(0, text.length - 1);
cur.ch = lineLength(cm, cur.line);
} else {
cur.ch = 0;
}
} else {
cur.ch += actionArgs.after ? 1 : 0;
}
var curPosFinal;
var idx;
if (vim.visualMode) {
// save the pasted text for reselection if the need arises
vim.lastPastedText = text;
var lastSelectionCurEnd;
var selectedArea = getSelectedAreaRange(cm, vim);
var selectionStart = selectedArea[0];
var selectionEnd = selectedArea[1];
var selectedText = cm.getSelection();
var selections = cm.listSelections();
var emptyStrings = new Array(selections.length).join('1').split('1');
// save the curEnd marker before it get cleared due to cm.replaceRange.
if (vim.lastSelection) {
lastSelectionCurEnd = vim.lastSelection.headMark.find();
}
// push the previously selected text to unnamed register
vimGlobalState.registerController.unnamedRegister.setText(selectedText);
if (blockwise) {
// first delete the selected text
cm.replaceSelections(emptyStrings);
// Set new selections as per the block length of the yanked text
selectionEnd = new Pos(selectionStart.line + text.length-1, selectionStart.ch);
cm.setCursor(selectionStart);
selectBlock(cm, selectionEnd);
cm.replaceSelections(text);
curPosFinal = selectionStart;
} else if (vim.visualBlock) {
cm.replaceSelections(emptyStrings);
cm.setCursor(selectionStart);
cm.replaceRange(text, selectionStart, selectionStart);
curPosFinal = selectionStart;
} else {
cm.replaceRange(text, selectionStart, selectionEnd);
curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1);
}
// restore the the curEnd marker
if(lastSelectionCurEnd) {
vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd);
}
if (linewise) {
curPosFinal.ch=0;
}
} else {
if (blockwise) {
cm.setCursor(cur);
for (var i = 0; i < text.length; i++) {
var line = cur.line+i;
if (line > cm.lastLine()) {
cm.replaceRange('\n', new Pos(line, 0));
}
var lastCh = lineLength(cm, line);
if (lastCh < cur.ch) {
extendLineToColumn(cm, line, cur.ch);
}
}
cm.setCursor(cur);
selectBlock(cm, new Pos(cur.line + text.length-1, cur.ch));
cm.replaceSelections(text);
curPosFinal = cur;
} else {
cm.replaceRange(text, cur);
// Now fine tune the cursor to where we want it.
if (linewise && actionArgs.after) {
curPosFinal = new Pos(
cur.line + 1,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));
} else if (linewise && !actionArgs.after) {
curPosFinal = new Pos(
cur.line,
findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));
} else if (!linewise && actionArgs.after) {
idx = cm.indexFromPos(cur);
curPosFinal = cm.posFromIndex(idx + text.length - 1);
} else {
idx = cm.indexFromPos(cur);
curPosFinal = cm.posFromIndex(idx + text.length);
}
}
}
if (vim.visualMode) {
exitVisualMode(cm, false);
}
cm.setCursor(curPosFinal);
},