node/test/fixtures/repl-tab-completion-nested-repls.js
Ruben Bridgewater 6c542d1c26
repl: improve completion
This improves the completion output by removing the nested special
handling. It never fully worked as expected and required a lot of
hacks to even keep it working halfway reliable. Our tests did not
cover syntax errors though and those can not be handled by this
implementation. Those break the layout and confuse the REPL.

Besides that the completion now also works in case the current line
has leading whitespace.

Also improve the error output in case the completion fails.

PR-URL: https://github.com/nodejs/node/pull/30907
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
2019-12-15 16:24:00 +01:00

50 lines
1.3 KiB
JavaScript

// Tab completion sometimes uses a separate REPL instance under the hood.
// That REPL instance has its own domain. Make sure domain errors trickle back
// up to the main REPL.
//
// Ref: https://github.com/nodejs/node/issues/21586
'use strict';
const { Stream } = require('stream');
function noop() {}
// A stream to push an array into a REPL
function ArrayStream() {
this.run = function(data) {
data.forEach((line) => {
this.emit('data', `${line}\n`);
});
};
}
Object.setPrototypeOf(ArrayStream.prototype, Stream.prototype);
Object.setPrototypeOf(ArrayStream, Stream);
ArrayStream.prototype.readable = true;
ArrayStream.prototype.writable = true;
ArrayStream.prototype.pause = noop;
ArrayStream.prototype.resume = noop;
ArrayStream.prototype.write = noop;
const repl = require('repl');
const putIn = new ArrayStream();
const testMe = repl.start('', putIn);
// Some errors are passed to the domain, but do not callback.
testMe._domain.on('error', function(err) {
throw err;
});
// Nesting of structures causes REPL to use a nested REPL for completion.
putIn.run([
'var top = function() {',
'r = function test (',
' one, two) {',
'var inner = {',
' one:1',
'};'
]);
// In Node.js 10.11.0, this next line will terminate the repl silently...
testMe.complete('inner.o', () => { throw new Error('fhqwhgads'); });