From 37c9d875e1b858b5a8a4aea753f3a7bcc5be46fb Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 20 Oct 2016 16:47:33 +0200 Subject: [PATCH 1/3] repl: make `key` of `repl.write()` optional always MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In `.editor` mode, `repl.write()` would have crashed when the `key` argument was not present, because the overwritten `_ttyWrite` of REPLs doesn’t check for the absence of a second argument like `readline.write()` does. Since the docs indicate that the argument is optional, add a check paralleling the one in `readline.write()`. --- lib/repl.js | 1 + test/parallel/test-repl-.editor.js | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 470b42a0b7a94f..399bcba979660d 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -601,6 +601,7 @@ function REPLServer(prompt, // Wrap readline tty to enable editor mode const ttyWrite = self._ttyWrite.bind(self); self._ttyWrite = (d, key) => { + key = key || {}; if (!self.editorMode || !self.terminal) { ttyWrite(d, key); return; diff --git a/test/parallel/test-repl-.editor.js b/test/parallel/test-repl-.editor.js index 556662181f7831..6d53bba5b6bb7a 100644 --- a/test/parallel/test-repl-.editor.js +++ b/test/parallel/test-repl-.editor.js @@ -9,15 +9,15 @@ 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, checkTerminalCodes = true}) { const stream = new common.ArrayStream(); let found = ''; stream.write = (msg) => found += msg.replace('\r', ''); - const expected = `${terminalCode}.editor\n` + - '// Entering editor mode (^D to finish, ^C to cancel)\n' + - `${input}${output}\n${terminalCode}`; + let expected = `${terminalCode}.editor\n` + + '// Entering editor mode (^D to finish, ^C to cancel)\n' + + `${input}${output}\n${terminalCode}`; const replServer = repl.start({ prompt: '> ', @@ -31,6 +31,17 @@ function run({input, output, event}) { stream.emit('data', input); replServer.write('', event); replServer.close(); + + if (!checkTerminalCodes) { + while (found.includes(terminalCode)) + found = found.replace(terminalCode, ''); + while (expected.includes(terminalCode)) + expected = expected.replace(terminalCode, ''); + + found = found.replace(/\n/g, ''); + expected = expected.replace(/\n/g, ''); + } + assert.strictEqual(found, expected); } @@ -54,6 +65,12 @@ const tests = [ input: ' var i = 1;\ni + 3', output: '\n4', event: {ctrl: true, name: 'd'} + }, + { + input: '', + output: '', + checkTerminalCodes: false, + event: null, } ]; From d19782764698a431e0558a56bda98455d7c8f884 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 20 Oct 2016 17:27:52 +0200 Subject: [PATCH 2/3] [squash] use regex for control code + prompt stripping --- test/parallel/test-repl-.editor.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/test/parallel/test-repl-.editor.js b/test/parallel/test-repl-.editor.js index 6d53bba5b6bb7a..4077840c596376 100644 --- a/test/parallel/test-repl-.editor.js +++ b/test/parallel/test-repl-.editor.js @@ -8,6 +8,7 @@ const repl = require('repl'); // \u001b[0J - Clear screen // \u001b[3G - Moves the cursor to 3rd column const terminalCode = '\u001b[1G\u001b[0J> \u001b[3G'; +const terminalCodeRegex = new RegExp(terminalCode.replace(/\[/g, '\\['), 'g'); function run({input, output, event, checkTerminalCodes = true}) { const stream = new common.ArrayStream(); @@ -33,13 +34,8 @@ function run({input, output, event, checkTerminalCodes = true}) { replServer.close(); if (!checkTerminalCodes) { - while (found.includes(terminalCode)) - found = found.replace(terminalCode, ''); - while (expected.includes(terminalCode)) - expected = expected.replace(terminalCode, ''); - - found = found.replace(/\n/g, ''); - expected = expected.replace(/\n/g, ''); + found = found.replace(terminalCodeRegex, '').replace(/\n/g, ''); + expected = expected.replace(terminalCodeRegex, '').replace(/\n/g, ''); } assert.strictEqual(found, expected); From 979528dd535e5fef51bf2786f474ff95a6b3a9a9 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 20 Oct 2016 16:57:40 +0200 Subject: [PATCH 3/3] =?UTF-8?q?repl:=20don=E2=80=99t=20write=20to=20input?= =?UTF-8?q?=20stream=20in=20editor=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of writing to the REPL’s input stream for the alignment spaces in `.editor` mode, let `readline` handle the spaces properly (echoing them using `_ttyWrite` and adding them to the current line buffer). Fixes: https://github.com/nodejs/node/issues/9189 --- lib/repl.js | 2 +- test/parallel/test-repl-.editor.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 399bcba979660d..cac79c5e2188f3 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -476,7 +476,7 @@ function REPLServer(prompt, const matches = self._sawKeyPress ? cmd.match(/^\s+/) : null; if (matches) { const prefix = matches[0]; - self.inputStream.write(prefix); + self.write(prefix); self.line = prefix; self.cursor = prefix.length; } diff --git a/test/parallel/test-repl-.editor.js b/test/parallel/test-repl-.editor.js index 4077840c596376..678d6d5c6d94f8 100644 --- a/test/parallel/test-repl-.editor.js +++ b/test/parallel/test-repl-.editor.js @@ -75,12 +75,15 @@ tests.forEach(run); // Auto code alignment for .editor mode function testCodeAligment({input, cursor = 0, line = ''}) { const stream = new common.ArrayStream(); + const outputStream = new common.ArrayStream(); + + stream.write = () => { throw new Error('Writing not allowed!'); }; const replServer = repl.start({ prompt: '> ', terminal: true, input: stream, - output: stream, + output: outputStream, useColors: false });