From 82037f5da77b4c4c09ce81c289e75c98a452dd46 Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Sun, 3 Dec 2017 18:35:45 +0300 Subject: [PATCH 1/7] Add sed command to vim --- package.json | 4 +- plugins/c9.ide.ace.keymaps/cli.js | 123 +++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 94fdda7f..cd351a1c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "c9", "description": "New Cloud9 Client", - "version": "3.1.4029", + "version": "3.1.5000", "author": "Ajax.org B.V. ", "private": true, "main": "bin/c9", @@ -58,4 +58,4 @@ "msgpack-js", "c9" ] -} \ No newline at end of file +} diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index 7922b4bf..15c6d9ff 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -187,6 +187,112 @@ define(function(require, exports, module) { } }; + function getCmdLineRange(editor, range, parts) { + if (!range) { + var cursor = editor.selection.getCursor(); + return [cursor.row, cursor.row]; + } + + range = range.split(','); + if (range.length === 1) { + return [0, parts.length - 1]; + } + + if (range[0] === "'<") { + var selRange = editor.getSelectionRange(); + return [selRange.start.row, selRange.end.row]; + } else { + var result = []; + for (let i = 0; i < range.length; i++) { + var v = range[i]; + var rangeVal = v === '.' ? + editor.selection.getCursor().row + : v === '$' ? + parts.length - 1 + : v[0] === '+' ? + result[0] + parseInt(v.slice(1), 10) + : parseInt(v, 10); + result.push(rangeVal); + } + + return result; + } + } + + cliCmds[':'].reCommands = { + /** + * @see {@link http://vim.wikia.com/wiki/Search_and_replace|Vim wiki - sed} + */ + 'sed': { + regex: /^(%|'<,'>|(?:\d+|\.),(?:\+?\d+|\$|\.))?s(\/|#)(.+?)\2(.*?)\2([giIc])*$/, + action: function (editor, cmd, data) { + // todo: if not data.match[3] get previous search result + var pattern = data.match[3] + .replace(/(\\)?(\(|\)|\+|\?|\||\&|\{)/g, function (m, m1, m2) { + // Revert regular syntax + return m1 ? m2 : '\\' + m2; + }); + + /** + * g - global by row + * i - ignorecase + * I - noignorecase + * todo: c - confirm + */ + var flags = (data.match[5] || '').replace(/[cI]/g, ''); + var re = new RegExp(pattern, flags); + + var replacement = data.match[4] || ''; + var text = editor.getValue(); + var parts = text.split('\n'); + var range = getCmdLineRange(editor, data.match[1], parts); + range[1] = range[1] >= parts.length ? + parts.length - 1 + : range[1]; + + var lastReplaceRange; + var lineCount = 0; + var subCount = 0; + + for (var i = range[0]; i <= range[1]; i++) { + var isChanged = false; + parts[i] = parts[i].replace(re, function () { + var args = [].slice.call(arguments, 0); + var offset = args[args.length - 2]; + if (!isChanged) { + lineCount += 1; + isChanged = true; + } + + subCount += 1; + lastReplaceRange = { + 'row': i, + 'column': offset + }; + + return replacement.replace(/\\(\d+)/, function (m, m1) { + return args[parseInt(m1, 10)] || ''; + }); + }); + } + + if (lastReplaceRange) { + editor.setValue(parts.join('\n'), -1); + editor.selection.moveCursorToPosition(lastReplaceRange); + editor.scrollToLine(lastReplaceRange.row, true, false); + + editor.cmdLine.setTimedMessage( + subCount + ' substitutions on ' + lineCount + ' lines', + 15000); + } else { + editor.cmdLine.setTimedMessage( + 'E486: Pattern not found: ' + pattern, + 15000); + } + } + } + }; + cliCmds[":"].commands = { w: function(editor, data, callback) { var tab = tabManager.focussedTab; @@ -375,8 +481,19 @@ define(function(require, exports, module) { ed.gotoLine(cmd, 0, true); } else { - ed.cmdLine.setTimedMessage("Vim command '" - + cmd + "' not implemented.", 1500); + for (var key in this.reCommands) { + var reCmd = this.reCommands[key]; + var match = reCmd.regex.exec(cmd); + if (match) { + return reCmd.action(ed, cmd, { + 'match': match, + 'argv': cmd.split(match[0], 1).slice(-1)[0].split(/\s+/) + }); + } + } + + ed.cmdLine.setTimedMessage( + 'Vim command "' + cmd + '" not implemented.', 3500); } }; @@ -800,4 +917,4 @@ define(function(require, exports, module) { "vim.cli": plugin }); } -}); \ No newline at end of file +}); From 43ebb42108efa0d37e657b63186a2360a3f271af Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Sun, 3 Dec 2017 18:41:36 +0300 Subject: [PATCH 2/7] Fix bug Require full command for regexp command --- plugins/c9.ide.ace.keymaps/cli.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index 15c6d9ff..a9d94568 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -463,10 +463,10 @@ define(function(require, exports, module) { cmd += last.value; cmd = cmd.substr(1).trim(); var args = cmd.split(/\s+/); - cmd = args[0]; + var firstCmd = args[0]; - if (this.commands[cmd]) { - cmd = this.commands[cmd]; + if (this.commands[firstCmd]) { + cmd = this.commands[firstCmd]; if (typeof cmd == "string") return commands.exec(cmd, null, { argv: args }); else if (typeof cmd == "function") @@ -474,8 +474,8 @@ define(function(require, exports, module) { else if (cmd.exec) return cmd.exec(ed, { argv: args }); } - else if (commands.commands[cmd]) { - commands.exec(cmd, null, { argv: args }); + else if (commands.commands[firstCmd]) { + commands.exec(firstCmd, null, { argv: args }); } else if (/^\d+$/.test(cmd)) { ed.gotoLine(cmd, 0, true); From 92e439fd9f04f078942a5ed37fce55124249aa49 Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Mon, 4 Dec 2017 00:35:52 +0300 Subject: [PATCH 3/7] Update cli.js --- plugins/c9.ide.ace.keymaps/cli.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index a9d94568..0a69fc35 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -224,7 +224,7 @@ define(function(require, exports, module) { * @see {@link http://vim.wikia.com/wiki/Search_and_replace|Vim wiki - sed} */ 'sed': { - regex: /^(%|'<,'>|(?:\d+|\.),(?:\+?\d+|\$|\.))?s(\/|#)(.+?)\2(.*?)\2([giIc])*$/, + regex: /^(%|'<,'>|(?:\d+|\.),(?:\+?\d+|\$|\.))?s(\/|#)(.+?)\2(.*?)\2([giIc]*)$/, action: function (editor, cmd, data) { // todo: if not data.match[3] get previous search result var pattern = data.match[3] @@ -271,7 +271,8 @@ define(function(require, exports, module) { }; return replacement.replace(/\\(\d+)/, function (m, m1) { - return args[parseInt(m1, 10)] || ''; + var i = parseInt(m1, 10); + return i < args.length - 2 ? args[i] : ''; }); }); } From 94f5cd8c3d61b7064a995d1c13396a6b7ecbda2f Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Mon, 4 Dec 2017 23:06:03 +0300 Subject: [PATCH 4/7] Add default pattern from last search regexp --- plugins/c9.ide.ace.keymaps/cli.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index 0a69fc35..e393367c 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -224,14 +224,23 @@ define(function(require, exports, module) { * @see {@link http://vim.wikia.com/wiki/Search_and_replace|Vim wiki - sed} */ 'sed': { - regex: /^(%|'<,'>|(?:\d+|\.),(?:\+?\d+|\$|\.))?s(\/|#)(.+?)\2(.*?)\2([giIc]*)$/, + regex: /^(%|'<,'>|(?:\d+|\.),(?:\+?\d+|\$|\.))?s(\/|#)(.*?)\2(.*?)\2([giIc]*)$/, action: function (editor, cmd, data) { - // todo: if not data.match[3] get previous search result - var pattern = data.match[3] + var pattern = ( + data.match[3] + || (editor.state.cm + && editor.state.cm.$searchHighlight + && editor.state.cm.$searchHighlight.regExp.source) + || '') .replace(/(\\)?(\(|\)|\+|\?|\||\&|\{)/g, function (m, m1, m2) { // Revert regular syntax return m1 ? m2 : '\\' + m2; }); + if (!pattern) { + return editor.cmdLine.setTimedMessage( + 'E35: No previous regular expression', + 15000); + } /** * g - global by row From b5c3f025daecb773ca34060554fe74448bd54e2b Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Mon, 4 Dec 2017 23:23:20 +0300 Subject: [PATCH 5/7] Fix bad line range --- plugins/c9.ide.ace.keymaps/cli.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index e393367c..076d2a78 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -212,6 +212,10 @@ define(function(require, exports, module) { : v[0] === '+' ? result[0] + parseInt(v.slice(1), 10) : parseInt(v, 10); + if (rangeVal >= parts.length) { + rangeVal = parts.length - 1; + } + result.push(rangeVal); } @@ -255,10 +259,6 @@ define(function(require, exports, module) { var text = editor.getValue(); var parts = text.split('\n'); var range = getCmdLineRange(editor, data.match[1], parts); - range[1] = range[1] >= parts.length ? - parts.length - 1 - : range[1]; - var lastReplaceRange; var lineCount = 0; var subCount = 0; From 1d9303b8944b306e1f2a2150b63fb8637c6b4a19 Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Fri, 8 Dec 2017 17:39:57 +0300 Subject: [PATCH 6/7] Fix bug --- plugins/c9.ide.ace.keymaps/cli.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index 076d2a78..cc6286b7 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -279,7 +279,7 @@ define(function(require, exports, module) { 'column': offset }; - return replacement.replace(/\\(\d+)/, function (m, m1) { + return replacement.replace(/\\(\d+)/g, function (m, m1) { var i = parseInt(m1, 10); return i < args.length - 2 ? args[i] : ''; }); From 3430c9e29b78a3c132321e302b2ac748f692862f Mon Sep 17 00:00:00 2001 From: Pleshevskiy Dima Date: Wed, 20 Dec 2017 11:22:29 +0300 Subject: [PATCH 7/7] Replace to native vim function `substitute` --- plugins/c9.ide.ace.keymaps/cli.js | 111 ++---------------------------- 1 file changed, 4 insertions(+), 107 deletions(-) diff --git a/plugins/c9.ide.ace.keymaps/cli.js b/plugins/c9.ide.ace.keymaps/cli.js index cc6286b7..23369715 100644 --- a/plugins/c9.ide.ace.keymaps/cli.js +++ b/plugins/c9.ide.ace.keymaps/cli.js @@ -18,6 +18,7 @@ define(function(require, exports, module) { var tabManager = imports.tabManager; var ace = imports.ace; + var Vim = require('ace/keyboard/vim').Vim; var Editor = require("ace/editor").Editor; var lang = require("ace/lib/lang"); var pathLib = require("path"); @@ -187,42 +188,6 @@ define(function(require, exports, module) { } }; - function getCmdLineRange(editor, range, parts) { - if (!range) { - var cursor = editor.selection.getCursor(); - return [cursor.row, cursor.row]; - } - - range = range.split(','); - if (range.length === 1) { - return [0, parts.length - 1]; - } - - if (range[0] === "'<") { - var selRange = editor.getSelectionRange(); - return [selRange.start.row, selRange.end.row]; - } else { - var result = []; - for (let i = 0; i < range.length; i++) { - var v = range[i]; - var rangeVal = v === '.' ? - editor.selection.getCursor().row - : v === '$' ? - parts.length - 1 - : v[0] === '+' ? - result[0] + parseInt(v.slice(1), 10) - : parseInt(v, 10); - if (rangeVal >= parts.length) { - rangeVal = parts.length - 1; - } - - result.push(rangeVal); - } - - return result; - } - } - cliCmds[':'].reCommands = { /** * @see {@link http://vim.wikia.com/wiki/Search_and_replace|Vim wiki - sed} @@ -230,75 +195,7 @@ define(function(require, exports, module) { 'sed': { regex: /^(%|'<,'>|(?:\d+|\.),(?:\+?\d+|\$|\.))?s(\/|#)(.*?)\2(.*?)\2([giIc]*)$/, action: function (editor, cmd, data) { - var pattern = ( - data.match[3] - || (editor.state.cm - && editor.state.cm.$searchHighlight - && editor.state.cm.$searchHighlight.regExp.source) - || '') - .replace(/(\\)?(\(|\)|\+|\?|\||\&|\{)/g, function (m, m1, m2) { - // Revert regular syntax - return m1 ? m2 : '\\' + m2; - }); - if (!pattern) { - return editor.cmdLine.setTimedMessage( - 'E35: No previous regular expression', - 15000); - } - - /** - * g - global by row - * i - ignorecase - * I - noignorecase - * todo: c - confirm - */ - var flags = (data.match[5] || '').replace(/[cI]/g, ''); - var re = new RegExp(pattern, flags); - - var replacement = data.match[4] || ''; - var text = editor.getValue(); - var parts = text.split('\n'); - var range = getCmdLineRange(editor, data.match[1], parts); - var lastReplaceRange; - var lineCount = 0; - var subCount = 0; - - for (var i = range[0]; i <= range[1]; i++) { - var isChanged = false; - parts[i] = parts[i].replace(re, function () { - var args = [].slice.call(arguments, 0); - var offset = args[args.length - 2]; - if (!isChanged) { - lineCount += 1; - isChanged = true; - } - - subCount += 1; - lastReplaceRange = { - 'row': i, - 'column': offset - }; - - return replacement.replace(/\\(\d+)/g, function (m, m1) { - var i = parseInt(m1, 10); - return i < args.length - 2 ? args[i] : ''; - }); - }); - } - - if (lastReplaceRange) { - editor.setValue(parts.join('\n'), -1); - editor.selection.moveCursorToPosition(lastReplaceRange); - editor.scrollToLine(lastReplaceRange.row, true, false); - - editor.cmdLine.setTimedMessage( - subCount + ' substitutions on ' + lineCount + ' lines', - 15000); - } else { - editor.cmdLine.setTimedMessage( - 'E486: Pattern not found: ' + pattern, - 15000); - } + Vim.handleEx(editor.state.cm, cmd); } } }; @@ -496,8 +393,8 @@ define(function(require, exports, module) { var match = reCmd.regex.exec(cmd); if (match) { return reCmd.action(ed, cmd, { - 'match': match, - 'argv': cmd.split(match[0], 1).slice(-1)[0].split(/\s+/) + match: match, + argv: cmd.split(match[0], 1).slice(-1)[0].split(/\s+/) }); } }