Permalink
Browse files

repl: Auto alignment for .editor mode

When in `.editor` mode, current line whitespace prefixes
are preserved in the subsequent line. User can hit backspace
to clean the whitespace

```js
node šŸ™ˆ ā‚¹ node
> .editor
// Entering editor mode (^D to finish, ^C to cancel)
function test() {
  console.log('tested!'); //On enter, cursor will be after 2 spaces
  _
```

PR-URL: #8241
Reviewed-By: James M Snell <jasnell@gmail.com>

 Conflicts:
	lib/readline.js
  • Loading branch information...
princejwesley authored and Fishrock123 committed Aug 23, 2016
1 parent b6f5104 commit 6f20f477c4511a024ddef6df9754ef5dafa00338
Showing with 71 additions and 2 deletions.
  1. +8 āˆ’0 lib/readline.js
  2. +9 āˆ’0 lib/repl.js
  3. +54 āˆ’2 test/parallel/test-repl-.editor.js
View
@@ -42,6 +42,7 @@ function Interface(input, output, completer, terminal) {
this._sawReturn = false;
this.isCompletionEnabled = true;
this._sawKeyPress = false;
EventEmitter.call(this);
var historySize;
@@ -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);
@@ -946,6 +950,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;
View
@@ -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;
}
@@ -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);

0 comments on commit 6f20f47

Please sign in to comment.