debugger: run last command on presssing enter
PR-URL: https://github.com/nodejs/node/pull/6090 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Claudio Rodriguez <cjrodr@yahoo.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Fixes: https://github.com/nodejs/node/issues/2895
This commit is contained in:
parent
b68827b1d1
commit
1df84f4f75
@ -84,6 +84,9 @@ The `repl` command allows code to be evaluated remotely. The `next` command
|
||||
steps over to the next line. Type `help` to see what other commands are
|
||||
available.
|
||||
|
||||
Pressing `enter` without typing a command will repeat the previous debugger
|
||||
command.
|
||||
|
||||
## Watchers
|
||||
|
||||
It is possible to watch expression and variable values while debugging. On
|
||||
|
@ -674,6 +674,9 @@ var helpMessage = 'Commands: ' + commands.map(function(group) {
|
||||
return group.join(', ');
|
||||
}).join(',\n');
|
||||
|
||||
// Previous command received. Initialize to empty command.
|
||||
var lastCommand = '\n';
|
||||
|
||||
|
||||
function SourceUnderline(sourceText, position, repl) {
|
||||
if (!sourceText) return '';
|
||||
@ -945,10 +948,10 @@ Interface.prototype.requireConnection = function() {
|
||||
Interface.prototype.controlEval = function(code, context, filename, callback) {
|
||||
try {
|
||||
// Repeat last command if empty line are going to be evaluated
|
||||
if (this.repl.rli.history && this.repl.rli.history.length > 0) {
|
||||
if (code === '\n') {
|
||||
code = this.repl.rli.history[0] + '\n';
|
||||
}
|
||||
if (code === '\n') {
|
||||
code = lastCommand;
|
||||
} else {
|
||||
lastCommand = code;
|
||||
}
|
||||
|
||||
// exec process.title => exec("process.title");
|
||||
|
38
lib/repl.js
38
lib/repl.js
@ -224,6 +224,10 @@ function REPLServer(prompt,
|
||||
function defaultEval(code, context, file, cb) {
|
||||
var err, result, retry = false, input = code, wrappedErr;
|
||||
// first, create the Script object to check the syntax
|
||||
|
||||
if (code === '\n')
|
||||
return cb(null);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
if (!/^\s*$/.test(code) &&
|
||||
@ -421,28 +425,24 @@ function REPLServer(prompt,
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd || self.bufferedCommand) {
|
||||
var evalCmd = self.bufferedCommand + cmd;
|
||||
if (/^\s*\{/.test(evalCmd) && /\}\s*$/.test(evalCmd)) {
|
||||
// It's confusing for `{ a : 1 }` to be interpreted as a block
|
||||
// statement rather than an object literal. So, we first try
|
||||
// to wrap it in parentheses, so that it will be interpreted as
|
||||
// an expression.
|
||||
evalCmd = '(' + evalCmd + ')\n';
|
||||
self.wrappedCmd = true;
|
||||
} else {
|
||||
// otherwise we just append a \n so that it will be either
|
||||
// terminated, or continued onto the next expression if it's an
|
||||
// unexpected end of input.
|
||||
evalCmd = evalCmd + '\n';
|
||||
}
|
||||
|
||||
debug('eval %j', evalCmd);
|
||||
self.eval(evalCmd, self.context, 'repl', finish);
|
||||
var evalCmd = self.bufferedCommand + cmd;
|
||||
if (/^\s*\{/.test(evalCmd) && /\}\s*$/.test(evalCmd)) {
|
||||
// It's confusing for `{ a : 1 }` to be interpreted as a block
|
||||
// statement rather than an object literal. So, we first try
|
||||
// to wrap it in parentheses, so that it will be interpreted as
|
||||
// an expression.
|
||||
evalCmd = '(' + evalCmd + ')\n';
|
||||
self.wrappedCmd = true;
|
||||
} else {
|
||||
finish(null);
|
||||
// otherwise we just append a \n so that it will be either
|
||||
// terminated, or continued onto the next expression if it's an
|
||||
// unexpected end of input.
|
||||
evalCmd = evalCmd + '\n';
|
||||
}
|
||||
|
||||
debug('eval %j', evalCmd);
|
||||
self.eval(evalCmd, self.context, 'repl', finish);
|
||||
|
||||
function finish(e, ret) {
|
||||
debug('finish', e, ret);
|
||||
self.memory(cmd);
|
||||
|
7
test/fixtures/debugger-repeat-last.js
vendored
Normal file
7
test/fixtures/debugger-repeat-last.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
var a = 1;
|
||||
|
||||
var b = 2;
|
||||
|
||||
var c = 3;
|
||||
|
||||
b = c;
|
46
test/parallel/test-debugger-repeat-last.js
Normal file
46
test/parallel/test-debugger-repeat-last.js
Normal file
@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
const path = require('path');
|
||||
const spawn = require('child_process').spawn;
|
||||
const assert = require('assert');
|
||||
|
||||
const common = require('../common');
|
||||
|
||||
const fixture = path.join(
|
||||
common.fixturesDir,
|
||||
'debugger-repeat-last.js'
|
||||
);
|
||||
|
||||
const args = [
|
||||
'debug',
|
||||
fixture
|
||||
];
|
||||
|
||||
const proc = spawn(process.execPath, args, { stdio: 'pipe' });
|
||||
proc.stdout.setEncoding('utf8');
|
||||
|
||||
var stdout = '';
|
||||
|
||||
var sentCommand = false;
|
||||
var sentEmpty = false;
|
||||
var sentExit = false;
|
||||
|
||||
proc.stdout.on('data', (data) => {
|
||||
stdout += data;
|
||||
if (!sentCommand && stdout.includes('> 1')) {
|
||||
setImmediate(() => {proc.stdin.write('n\n');});
|
||||
return sentCommand = true;
|
||||
}
|
||||
if (!sentEmpty && stdout.includes('> 3')) {
|
||||
setImmediate(() => {proc.stdin.write('\n');});
|
||||
return sentEmpty = true;
|
||||
}
|
||||
if (!sentExit && sentCommand && sentEmpty) {
|
||||
setTimeout(() => {proc.stdin.write('\n\n\n.exit\n\n\n');}, 1);
|
||||
return sentExit = true;
|
||||
}
|
||||
});
|
||||
|
||||
process.on('exit', (exitCode) => {
|
||||
assert.strictEqual(exitCode, 0);
|
||||
console.log(stdout);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user