Skip to content

Commit

Permalink
Merge pull request #4469 from taikamurmeli/master
Browse files Browse the repository at this point in the history
Fix vim replace in range command where replacement includes line breaks
  • Loading branch information
nightwing authored Apr 12, 2021
2 parents 94422a4 + 7fb421b commit 554831e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 17 deletions.
40 changes: 23 additions & 17 deletions lib/ace/keyboard/vim.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ define(function(require, exports, module) {
TextModeTokenRe.lastIndex = 0;
return TextModeTokenRe.test(ch);
};

(function() {
oop.implement(CodeMirror.prototype, EventEmitter);

this.destroy = function() {
this.ace.off('change', this.onChange);
this.ace.off('changeSelection', this.onSelectionChange);
Expand Down Expand Up @@ -263,7 +263,7 @@ define(function(require, exports, module) {
r.cursor = Range.comparePoints(r.start, head) ? r.end : r.start;
return r;
});

if (this.ace.inVirtualSelectionMode) {
this.ace.selection.fromOrientedRange(ranges[0]);
return;
Expand Down Expand Up @@ -306,7 +306,7 @@ define(function(require, exports, module) {
var rowShift = (end.row - start.row) * (isInsert ? 1 : -1);
var colShift = (end.column - start.column) * (isInsert ? 1 : -1);
if (isInsert) end = start;

for (var i in this.marks) {
var point = this.marks[i];
var cmp = Range.comparePoints(point, start);
Expand Down Expand Up @@ -473,7 +473,7 @@ define(function(require, exports, module) {
if (!e) e = s;
return this.ace.session.replace(new Range(s.line, s.ch, e.line, e.ch), text);
};
this.replaceSelection =
this.replaceSelection =
this.replaceSelections = function(p) {
var sel = this.ace.selection;
if (this.ace.inVirtualSelectionMode) {
Expand Down Expand Up @@ -790,12 +790,12 @@ dom.importCssString(".normal-mode .ace_cursor{\
inp.value = newVal;
} else {
if (closed) return;

if (newVal && newVal.type == "blur") {
if (document.activeElement === inp)
return;
}

me.state.dialog = null;
closed = true;
dialog.parentNode.removeChild(dialog);
Expand Down Expand Up @@ -869,7 +869,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
});
})();


var defaultKeymap = [
// Key to key mapping. This goes first to make it possible to override
// existing mappings.
Expand Down Expand Up @@ -5883,10 +5883,16 @@ dom.importCssString(".normal-mode .ace_cursor{\
stop();
});
}
function lineBreakCount(text) {
return (text.match(/[\n\r]/g) || []).length;
}
function replace() {
var text = cm.getRange(searchCursor.from(), searchCursor.to());
var newText = text.replace(query, replaceWith);
searchCursor.replace(newText);
var lineBreakDifference = lineBreakCount(newText) - lineBreakCount(text);
lineEnd += lineBreakDifference
lastPos.line += lineBreakDifference
}
function next() {
// The below only loops to skip over multiple occurrences on the same
Expand Down Expand Up @@ -6378,7 +6384,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
} else if (wasMultiselect && vim.visualBlock) {
vim.wasInVisualBlock = true;
}

if (key == '<Esc>' && !vim.insertMode && !vim.visualMode && wasMultiselect) {
cm.ace.exitMultiSelectMode();
} else if (visualBlock || !wasMultiselect || cm.ace.inVirtualSelectionMode) {
Expand All @@ -6397,7 +6403,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
anchor = offsetCursor(anchor, 0, anchorOffset);
cm.state.vim.sel.head = head;
cm.state.vim.sel.anchor = anchor;

isHandled = handleKey(cm, key, origin);
sel.$desiredColumn = cm.state.vim.lastHPos == -1 ? null : cm.state.vim.lastHPos;
if (cm.virtualSelectionMode()) {
Expand Down Expand Up @@ -6425,12 +6431,12 @@ dom.importCssString(".normal-mode .ace_cursor{\
var top = pixelPos.top;
var left = pixelPos.left;
if (!vim.insertMode) {
var isbackwards = !sel.cursor
var isbackwards = !sel.cursor
? session.selection.isBackwards() || session.selection.isEmpty()
: Range.comparePoints(sel.cursor, sel.start) <= 0;
if (!isbackwards && left > w)
left -= w;
}
}
if (!vim.insertMode && vim.status) {
h = h / 2;
top += h;
Expand All @@ -6444,7 +6450,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
var cm = editor.state.cm;
var vim = getVim(cm);
if (keyCode == -1) return;

// in non-insert mode we try to find the ascii key corresponding to the text in textarea
// this is needed because in languages that use latin alphabet we want to get the key that browser sends to the textarea
// and in non
Expand Down Expand Up @@ -6475,7 +6481,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
data.inputChar = data.inputKey = null;
}
}

// ctrl-c is special it both exits mode and copies text
if (key == "c" && hashId == 1) { // key == "ctrl-c"
if (!useragent.isMac && editor.getCopyText()) {
Expand All @@ -6485,13 +6491,13 @@ dom.importCssString(".normal-mode .ace_cursor{\
return {command: "null", passEvent: true};
}
}

if (key == "esc" && !vim.insertMode && !vim.visualMode && !cm.ace.inMultiSelectMode) {
var searchState = getSearchState(cm);
var overlay = searchState.getOverlay();
if (overlay) cm.removeOverlay(overlay);
}

if (hashId == -1 || hashId & 1 || hashId === 0 && key.length > 1) {
var insertMode = vim.insertMode;
var name = lookupKey(hashId, key, e || {});
Expand Down Expand Up @@ -6590,7 +6596,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
{ keys: 'zA', type: 'action', action: 'fold', actionArgs: { toggle: true, all: true } },
{ keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },
{ keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },

{ keys: '<C-A-k>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAbove" } },
{ keys: '<C-A-j>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelow" } },
{ keys: '<C-A-S-k>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAboveSkipCurrent" } },
Expand Down
20 changes: 20 additions & 0 deletions lib/ace/keyboard/vim_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3969,6 +3969,26 @@ testVim('ex_substitute_alternate_separator', function(cm, vim, helpers) {
helpers.doEx('s#o/e#two#g');
eq('o/e o/e\n two two', cm.getValue());
}, { value: 'o/e o/e\n o/e o/e'});
testVim('ex_substitute_with_newline (\\n)', function(cm, vim, helpers) {
cm.setCursor(1, 0);
helpers.doEx('s/\\.\\s/.\\n/');
eq('a. b. c.\n1.\n2. 3.', cm.getValue());
}, { value: 'a. b. c.\n1. 2. 3.'});
testVim('ex_substitute_all_in_range_with_newline (\\n)', function(cm, vim, helpers) {
cm.setCursor(1, 0);
helpers.doEx('1,2s/\\.\\s/.\\n/g');
eq('a.\nb.\nc.\n1.\n2.\n3.', cm.getValue());
}, { value: 'a. b. c.\n1. 2. 3.'});
testVim('ex_substitute_all_in_range_with_newline (\\r)', function(cm, vim, helpers) {
cm.setCursor(1, 0);
helpers.doEx('1,2s/\\.\\s/.\\r/g');
eq('a.\rb.\rc.\r1.\r2.\r3.', cm.getValue());
}, { value: 'a. b. c.\r1. 2. 3.'});
testVim('ex_substitute_all_in_range_with_multiple newlines (\\r)', function(cm, vim, helpers) {
cm.setCursor(1, 0);
helpers.doEx('1,2s/\\.\\s/.\\r\\r/g');
eq('a.\r\rb.\r\rc.\r1.\r\r2.\r\r3.', cm.getValue());
}, { value: 'a. b. c.\r1. 2. 3.'});
testVim('ex_substitute_full_file', function(cm, vim, helpers) {
cm.setCursor(1, 0);
helpers.doEx('%s/one/two/g');
Expand Down

0 comments on commit 554831e

Please sign in to comment.