Skip to content

Commit

Permalink
repl: make REPLServer.bufferedCommand private
Browse files Browse the repository at this point in the history
The `REPLServer.bufferedCommand` property was undocumented, except
for its usage appearing, unexplained, in an example for
`REPLServer.defineCommand`. This commit deprecates that property,
privatizes it, and adds a `REPLServer.clearBufferedCommand()`
function that will clear the buffer.

PR-URL: nodejs#13687
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: James Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <mhdawson@ibm.com>
Reviewed-By: Ruben Bridgewater <ruben.bridgewater@fintura.de>

Refs: nodejs#12686
  • Loading branch information
lance authored and addaleax committed Aug 1, 2017
1 parent 98ddab4 commit 2ca9f94
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 18 deletions.
9 changes: 9 additions & 0 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,14 @@ with inappropriate names has been deprecated.
*Note*: As the original API was undocumented and not generally useful for
non-internal code, no replacement API is provided.

<a id="DEP0074"></a>
### DEP0074: REPLServer.bufferedCommand

Type: Runtime

The `REPLServer.bufferedCommand` property was deprecated in favor of
[`REPLServer.clearBufferedCommand()`][].

[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
[`Buffer.from(buffer)`]: buffer.html#buffer_class_method_buffer_from_buffer
Expand Down Expand Up @@ -708,3 +716,4 @@ non-internal code, no replacement API is provided.
[alloc_unsafe_size]: buffer.html#buffer_class_method_buffer_allocunsafe_size
[from_arraybuffer]: buffer.html#buffer_class_method_buffer_from_arraybuffer_byteoffset_length
[from_string_encoding]: buffer.html#buffer_class_method_buffer_from_string_encoding
[`REPLServer.clearBufferedCommand()`]: repl.html#repl_replserver_clearbufferedcommand
12 changes: 11 additions & 1 deletion doc/api/repl.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ const replServer = repl.start({ prompt: '> ' });
replServer.defineCommand('sayhello', {
help: 'Say hello',
action(name) {
this.bufferedCommand = '';
this.clearBufferedCommand();
console.log(`Hello, ${name}!`);
this.displayPrompt();
}
Expand Down Expand Up @@ -375,6 +375,16 @@ The `replServer.displayPrompt` method is primarily intended to be called from
within the action function for commands registered using the
`replServer.defineCommand()` method.

### replServer.clearBufferedCommand()
<!-- YAML
added: REPLACEME
-->

The `replServer.clearBufferedComand()` method clears any command that has been
buffered but not yet executed. This method is primarily intended to be
called from within the action function for commands registered using the
`replServer.defineCommand()` method.

## repl.start([options])
<!-- YAML
added: v0.1.91
Expand Down
49 changes: 32 additions & 17 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ for (var n = 0; n < GLOBAL_OBJECT_PROPERTIES.length; n++) {
GLOBAL_OBJECT_PROPERTY_MAP[GLOBAL_OBJECT_PROPERTIES[n]] =
GLOBAL_OBJECT_PROPERTIES[n];
}
const kBufferedCommandSymbol = Symbol('bufferedCommand');

try {
// hack for require.resolve("./relative") to work properly.
Expand Down Expand Up @@ -300,7 +301,7 @@ function REPLServer(prompt,
} else {
top.outputStream.write(`Thrown: ${String(e)}\n`);
}
top.bufferedCommand = '';
top.clearBufferedCommand();
top.lines.level = [];
top.displayPrompt();
});
Expand All @@ -326,9 +327,17 @@ function REPLServer(prompt,
self.outputStream = output;

self.resetContext();
self.bufferedCommand = '';
self.lines.level = [];

self.clearBufferedCommand();
Object.defineProperty(this, 'bufferedCommand', {
get: util.deprecate(() => self[kBufferedCommandSymbol],
'REPLServer.bufferedCommand is deprecated', 'DEP0074'),
set: util.deprecate((val) => self[kBufferedCommandSymbol] = val,
'REPLServer.bufferedCommand is deprecated', 'DEP0074'),
enumerable: true
});

// Figure out which "complete" function to use.
self.completer = (typeof options.completer === 'function') ?
options.completer : completer;
Expand Down Expand Up @@ -376,7 +385,8 @@ function REPLServer(prompt,
self.clearLine();
self.turnOffEditorMode();

if (!(self.bufferedCommand && self.bufferedCommand.length > 0) && empty) {
const cmd = self[kBufferedCommandSymbol];
if (!(cmd && cmd.length > 0) && empty) {
if (sawSIGINT) {
self.close();
sawSIGINT = false;
Expand All @@ -388,7 +398,7 @@ function REPLServer(prompt,
sawSIGINT = false;
}

self.bufferedCommand = '';
self.clearBufferedCommand();
self.lines.level = [];
self.displayPrompt();
});
Expand All @@ -399,7 +409,7 @@ function REPLServer(prompt,
sawSIGINT = false;

if (self.editorMode) {
self.bufferedCommand += cmd + '\n';
self[kBufferedCommandSymbol] += cmd + '\n';

// code alignment
const matches = self._sawKeyPress ? cmd.match(/^\s+/) : null;
Expand Down Expand Up @@ -427,15 +437,15 @@ function REPLServer(prompt,
if (self.parseREPLKeyword(keyword, rest) === true) {
return;
}
if (!self.bufferedCommand) {
if (!self[kBufferedCommandSymbol]) {
self.outputStream.write('Invalid REPL keyword\n');
finish(null);
return;
}
}
}

const evalCmd = self.bufferedCommand + cmd + '\n';
const evalCmd = self[kBufferedCommandSymbol] + cmd + '\n';

debug('eval %j', evalCmd);
self.eval(evalCmd, self.context, 'repl', finish);
Expand All @@ -444,11 +454,11 @@ function REPLServer(prompt,
debug('finish', e, ret);
self.memory(cmd);

if (e && !self.bufferedCommand && cmd.trim().startsWith('npm ')) {
if (e && !self[kBufferedCommandSymbol] && cmd.trim().startsWith('npm ')) {
self.outputStream.write('npm should be run outside of the ' +
'node repl, in your normal shell.\n' +
'(Press Control-D to exit.)\n');
self.bufferedCommand = '';
self.clearBufferedCommand();
self.displayPrompt();
return;
}
Expand All @@ -460,7 +470,7 @@ function REPLServer(prompt,
// {
// ... x: 1
// ... }
self.bufferedCommand += cmd + '\n';
self[kBufferedCommandSymbol] += cmd + '\n';
self.displayPrompt();
return;
} else {
Expand All @@ -469,7 +479,7 @@ function REPLServer(prompt,
}

// Clear buffer if no SyntaxErrors
self.bufferedCommand = '';
self.clearBufferedCommand();
sawCtrlD = false;

// If we got any output - print it (if no error)
Expand All @@ -495,7 +505,7 @@ function REPLServer(prompt,
self.outputStream.write(`${self._initialPrompt}.editor\n`);
self.outputStream.write(
'// Entering editor mode (^D to finish, ^C to cancel)\n');
self.outputStream.write(`${self.bufferedCommand}\n`);
self.outputStream.write(`${self[kBufferedCommandSymbol]}\n`);
self.prompt(true);
} else {
self.displayPrompt(true);
Expand Down Expand Up @@ -569,6 +579,10 @@ exports.start = function(prompt,
return repl;
};

REPLServer.prototype.clearBufferedCommand = function clearBufferedCommand() {
this[kBufferedCommandSymbol] = '';
};

REPLServer.prototype.close = function close() {
if (this.terminal && this._flushing && !this._closingOnFlush) {
this._closingOnFlush = true;
Expand Down Expand Up @@ -647,7 +661,7 @@ REPLServer.prototype.resetContext = function() {

REPLServer.prototype.displayPrompt = function(preserveCursor) {
var prompt = this._initialPrompt;
if (this.bufferedCommand.length) {
if (this[kBufferedCommandSymbol].length) {
prompt = '...';
const len = this.lines.level.length ? this.lines.level.length - 1 : 0;
const levelInd = '..'.repeat(len);
Expand Down Expand Up @@ -742,7 +756,8 @@ REPLServer.prototype.complete = function() {
// getter code.
function complete(line, callback) {
// There may be local variables to evaluate, try a nested REPL
if (this.bufferedCommand !== undefined && this.bufferedCommand.length) {
if (this[kBufferedCommandSymbol] !== undefined &&
this[kBufferedCommandSymbol].length) {
// Get a new array of inputted lines
var tmp = this.lines.slice();
// Kill off all function declarations to push all local variables into
Expand All @@ -759,7 +774,7 @@ function complete(line, callback) {
flat.run(tmp); // eval the flattened code
// all this is only profitable if the nested REPL
// does not have a bufferedCommand
if (!magic.bufferedCommand) {
if (!magic[kBufferedCommandSymbol]) {
return magic.complete(line, callback);
}
}
Expand Down Expand Up @@ -1172,7 +1187,7 @@ function defineDefaultCommands(repl) {
repl.defineCommand('break', {
help: 'Sometimes you get stuck, this gets you out',
action: function() {
this.bufferedCommand = '';
this.clearBufferedCommand();
this.displayPrompt();
}
});
Expand All @@ -1186,7 +1201,7 @@ function defineDefaultCommands(repl) {
repl.defineCommand('clear', {
help: clearMessage,
action: function() {
this.bufferedCommand = '';
this.clearBufferedCommand();
if (!this.useGlobal) {
this.outputStream.write('Clearing context...\n');
this.resetContext();
Expand Down

0 comments on commit 2ca9f94

Please sign in to comment.