From 327b688dc548bb336d6a547d34530ad47fa8553b Mon Sep 17 00:00:00 2001 From: Travis Heppe <heppe@google.com> Date: Wed, 22 Jan 2014 00:14:57 -0800 Subject: [PATCH] [vim] Fix unescaping of escaped strings for search and replace Add unit tests. --- keymap/vim.js | 22 ++++++++++++++++++++-- test/vim_test.js | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/keymap/vim.js b/keymap/vim.js index a08c5c2f7..21c74c4cf 100644 --- a/keymap/vim.js +++ b/keymap/vim.js @@ -2750,10 +2750,28 @@ if (!escapeNextChar && c == '/') { slashes.push(i); } - escapeNextChar = (c == '\\'); + escapeNextChar = !escapeNextChar && (c == '\\'); } return slashes; } + + function unescapeString(str) { + var escapeNextChar = false; + var out = []; + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i); + var next = str.charAt(i+1); + var slashComesNext = (next == '\\') || (next == '/'); + if (c !== '\\' || escapeNextChar || !slashComesNext) { + out.push(c); + escapeNextChar = false; + } else { + escapeNextChar = true; + } + } + return out.join(''); + } + /** * Extract the regular expression from the query and return a Regexp object. * Returns null if the query is blank. @@ -3278,7 +3296,7 @@ var count; var confirm = false; // Whether to confirm each replace. if (slashes[1]) { - replacePart = argString.substring(slashes[1] + 1, slashes[2]); + replacePart = unescapeString(argString.substring(slashes[1] + 1, slashes[2])); } if (slashes[2]) { // After the 3rd slash, we can have flags followed by a space followed diff --git a/test/vim_test.js b/test/vim_test.js index d39753c10..dd88bbf8c 100644 --- a/test/vim_test.js +++ b/test/vim_test.js @@ -2264,6 +2264,8 @@ testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) { helpers.doEx('sort! d'); eq('a3\nb2\nc1\nz\ny', cm.getValue()); }, { value: 'a3\nz\nc1\ny\nb2'}); + + testVim('ex_substitute_same_line', function(cm, vim, helpers) { cm.setCursor(1, 0); helpers.doEx('s/one/two'); @@ -2299,6 +2301,25 @@ testVim('ex_substitute_empty_query', function(cm, vim, helpers) { helpers.doEx('s//b'); eq('abb ab2 ab3', cm.getValue()); }, { value: 'a11 a12 a13' }); +testVim('ex_substitute_slash_regex', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/\\//|'); + eq('one|two \n three|four', cm.getValue()); +}, { value: 'one/two \n three/four'}); +testVim('ex_substitute_backslashslash_regex', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/\\\\/,'); + eq('one,two \n three,four', cm.getValue()); +}, { value: 'one\\two \n three\\four'}); +testVim('ex_substitute_slash_replacement', function(cm, vim, helpers) { + cm.setCursor(1, 0); + helpers.doEx('%s/,/\\/'); + eq('one/two \n three/four', cm.getValue()); +}, { value: 'one,two \n three,four'}); +testVim('ex_substitute_backslash_replacement', function(cm, vim, helpers) { + helpers.doEx('%s/,/\\\\/g'); + eq('one\\two \n three\\four', cm.getValue()); +}, { value: 'one,two \n three,four'}); testVim('ex_substitute_count', function(cm, vim, helpers) { cm.setCursor(1, 0); helpers.doEx('s/\\d/0/i 2'); -- GitLab