summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/readline.js8
-rw-r--r--lib/repl.js9
-rw-r--r--test/parallel/test-repl-.editor.js56
3 files changed, 71 insertions, 2 deletions
diff --git a/lib/readline.js b/lib/readline.js
index f7591b7cc1..e45fb2938e 100644
--- a/lib/readline.js
+++ b/lib/readline.js
@@ -41,6 +41,7 @@ function Interface(input, output, completer, terminal) {
this._sawReturn = false;
this.isCompletionEnabled = true;
+ this._sawKeyPress = false;
this._previousKey = null;
EventEmitter.call(this);
@@ -247,6 +248,9 @@ Interface.prototype._addHistory = function() {
// if the history is disabled then return the line
if (this.historySize === 0) return this.line;
+ // if the trimmed line is empty then return the line
+ if (this.line.trim().length === 0) return this.line;
+
if (this.history.length === 0 || this.history[0] !== this.line) {
this.history.unshift(this.line);
@@ -947,6 +951,10 @@ function emitKeypressEvents(stream, iface) {
if (r) {
clearTimeout(timeoutId);
+ if (iface) {
+ iface._sawKeyPress = r.length === 1;
+ }
+
for (var i = 0; i < r.length; i++) {
if (r[i] === '\t' && typeof r[i + 1] === 'string' && iface) {
iface.isCompletionEnabled = false;
diff --git a/lib/repl.js b/lib/repl.js
index 1d678e6711..e93b710266 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -471,6 +471,15 @@ function REPLServer(prompt,
if (self.editorMode) {
self.bufferedCommand += cmd + '\n';
+
+ // code alignment
+ const matches = self._sawKeyPress ? cmd.match(/^\s+/) : null;
+ if (matches) {
+ const prefix = matches[0];
+ self.inputStream.write(prefix);
+ self.line = prefix;
+ self.cursor = prefix.length;
+ }
self.memory(cmd);
return;
}
diff --git a/test/parallel/test-repl-.editor.js b/test/parallel/test-repl-.editor.js
index 15765ad517..556662181f 100644
--- a/test/parallel/test-repl-.editor.js
+++ b/test/parallel/test-repl-.editor.js
@@ -9,7 +9,7 @@ const repl = require('repl');
// \u001b[3G - Moves the cursor to 3rd column
const terminalCode = '\u001b[1G\u001b[0J> \u001b[3G';
-function run(input, output, event) {
+function run({input, output, event}) {
const stream = new common.ArrayStream();
let found = '';
@@ -49,7 +49,59 @@ const tests = [
input: 'var i = 1;\ni + 3',
output: '\n4',
event: {ctrl: true, name: 'd'}
+ },
+ {
+ input: ' var i = 1;\ni + 3',
+ output: '\n4',
+ event: {ctrl: true, name: 'd'}
+ }
+];
+
+tests.forEach(run);
+
+// Auto code alignment for .editor mode
+function testCodeAligment({input, cursor = 0, line = ''}) {
+ const stream = new common.ArrayStream();
+
+ const replServer = repl.start({
+ prompt: '> ',
+ terminal: true,
+ input: stream,
+ output: stream,
+ useColors: false
+ });
+
+ stream.emit('data', '.editor\n');
+ input.split('').forEach((ch) => stream.emit('data', ch));
+ // Test the content of current line and the cursor position
+ assert.strictEqual(line, replServer.line);
+ assert.strictEqual(cursor, replServer.cursor);
+
+ replServer.write('', {ctrl: true, name: 'd'});
+ replServer.close();
+ // Ensure that empty lines are not saved in history
+ assert.notStrictEqual(replServer.history[0].trim(), '');
+}
+
+const codeAlignmentTests = [
+ {
+ input: 'var i = 1;\n'
+ },
+ {
+ input: ' var i = 1;\n',
+ cursor: 2,
+ line: ' '
+ },
+ {
+ input: ' var i = 1;\n',
+ cursor: 5,
+ line: ' '
+ },
+ {
+ input: ' var i = 1;\n var j = 2\n',
+ cursor: 2,
+ line: ' '
}
];
-tests.forEach(({input, output, event}) => run(input, output, event));
+codeAlignmentTests.forEach(testCodeAligment);