From a67f6e1b0ee652b50c7a2ab8c877220c647395b2 Mon Sep 17 00:00:00 2001
From: binny <hackbinnyarora@gmail.com>
Date: Thu, 13 Mar 2014 15:07:30 +0530
Subject: [PATCH] [vim] Update :substitute to use last substitution if no
 arguments

---
 keymap/vim.js    | 68 +++++++++++++++++++++++++++---------------------
 test/vim_test.js |  7 +++++
 2 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/keymap/vim.js b/keymap/vim.js
index bb6c55b12..899c6c0e8 100644
--- a/keymap/vim.js
+++ b/keymap/vim.js
@@ -603,6 +603,8 @@
         searchQuery: null,
         // Whether we are searching backwards.
         searchIsReversed: false,
+        // Replace part of the last substituted pattern
+        lastSubstituteReplacePart: undefined,
         jumpList: createCircularJumpList(),
         macroModeState: new MacroModeState,
         // Recording latest f, t, F or T motion command.
@@ -3608,38 +3610,41 @@
               'any other getSearchCursor implementation.');
         }
         var argString = params.argString;
-        var slashes = findUnescapedSlashes(argString);
-        if (slashes[0] !== 0) {
-          showConfirm(cm, 'Substitutions should be of the form ' +
-              ':s/pattern/replace/');
-          return;
-        }
-        var regexPart = argString.substring(slashes[0] + 1, slashes[1]);
+        var slashes = argString ? findUnescapedSlashes(argString) : [];
         var replacePart = '';
-        var flagsPart;
-        var count;
-        var confirm = false; // Whether to confirm each replace.
-        if (slashes[1]) {
-          replacePart = argString.substring(slashes[1] + 1, slashes[2]);
-          if (getOption('pcre')) {
-            replacePart = unescapeRegexReplace(replacePart);
-          } else {
-            replacePart = translateRegexReplace(replacePart);
+        if (slashes.length) {
+          if (slashes[0] !== 0) {
+            showConfirm(cm, 'Substitutions should be of the form ' +
+                ':s/pattern/replace/');
+            return;
           }
-        }
-        if (slashes[2]) {
-          // After the 3rd slash, we can have flags followed by a space followed
-          // by count.
-          var trailing = argString.substring(slashes[2] + 1).split(' ');
-          flagsPart = trailing[0];
-          count = parseInt(trailing[1]);
-        }
-        if (flagsPart) {
-          if (flagsPart.indexOf('c') != -1) {
-            confirm = true;
-            flagsPart.replace('c', '');
+          var regexPart = argString.substring(slashes[0] + 1, slashes[1]);
+          var flagsPart;
+          var count;
+          var confirm = false; // Whether to confirm each replace.
+          if (slashes[1]) {
+            replacePart = argString.substring(slashes[1] + 1, slashes[2]);
+            if (getOption('pcre')) {
+              replacePart = unescapeRegexReplace(replacePart);
+            } else {
+              replacePart = translateRegexReplace(replacePart);
+            }
+            vimGlobalState.lastSubstituteReplacePart = replacePart;
+          }
+          if (slashes[2]) {
+            // After the 3rd slash, we can have flags followed by a space followed
+            // by count.
+            var trailing = argString.substring(slashes[2] + 1).split(' ');
+            flagsPart = trailing[0];
+            count = parseInt(trailing[1]);
+          }
+          if (flagsPart) {
+            if (flagsPart.indexOf('c') != -1) {
+              confirm = true;
+              flagsPart.replace('c', '');
+            }
+            regexPart = regexPart + '/' + flagsPart;
           }
-          regexPart = regexPart + '/' + flagsPart;
         }
         if (regexPart) {
           // If regex part is empty, then use the previous query. Otherwise use
@@ -3652,6 +3657,11 @@
             return;
           }
         }
+        replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart;
+        if (replacePart === undefined) {
+          showConfirm(cm, 'No previous substitute regular expression');
+          return;
+        }
         var state = getSearchState(cm);
         var query = state.getQuery();
         var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;
diff --git a/test/vim_test.js b/test/vim_test.js
index b51d47cd8..4d9525e15 100644
--- a/test/vim_test.js
+++ b/test/vim_test.js
@@ -2550,6 +2550,13 @@ testVim('ex_substitute_javascript', function(cm, vim, helpers) {
   helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/')
   eq('a $$ $\' $` $& 0 b', cm.getValue());
 }, { value: 'a 0 b' });
+testVim('ex_substitute_empty_arguments', function(cm,vim,helpers) {
+  cm.setCursor(0, 0);
+  helpers.doEx('s/a/b');
+  cm.setCursor(1, 0);
+  helpers.doEx('s');
+  eq('b b\nb b', cm.getValue());
+}, {value: 'a a\na a'});
 
 // More complex substitute tests that test both pcre and nopcre options.
 function testSubstitute(name, options) {
-- 
GitLab