readline: custom streams support
This commit is contained in:
parent
a4e10cdb07
commit
2010071339
@ -29,13 +29,23 @@ var util = require('util'),
|
|||||||
|
|
||||||
exports.port = 5858;
|
exports.port = 5858;
|
||||||
|
|
||||||
exports.start = function() {
|
exports.start = function(argv, stdin, stdout) {
|
||||||
if (process.argv.length < 3) {
|
argv || (argv = process.argv.slice(2));
|
||||||
|
|
||||||
|
if (argv.length < 1) {
|
||||||
console.error('Usage: node debug script.js');
|
console.error('Usage: node debug script.js');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var interface = new Interface();
|
// Setup input/output streams
|
||||||
|
stdin = stdin || process.openStdin();
|
||||||
|
stdout = stdout || process.stdout;
|
||||||
|
|
||||||
|
var args = ['--debug-brk'].concat(argv),
|
||||||
|
interface = new Interface(stdin, stdout, args);
|
||||||
|
|
||||||
|
stdin.resume();
|
||||||
|
|
||||||
process.on('uncaughtException', function(e) {
|
process.on('uncaughtException', function(e) {
|
||||||
console.error("There was an internal error in Node's debugger. " +
|
console.error("There was an internal error in Node's debugger. " +
|
||||||
'Please report this bug.');
|
'Please report this bug.');
|
||||||
@ -653,14 +663,14 @@ var helpMessage = 'Commands: ' + commands.map(function(group) {
|
|||||||
}).join(',\n');
|
}).join(',\n');
|
||||||
|
|
||||||
|
|
||||||
function SourceUnderline(sourceText, position) {
|
function SourceUnderline(sourceText, position, tty) {
|
||||||
if (!sourceText) return '';
|
if (!sourceText) return '';
|
||||||
|
|
||||||
var head = sourceText.slice(0, position),
|
var head = sourceText.slice(0, position),
|
||||||
tail = sourceText.slice(position);
|
tail = sourceText.slice(position);
|
||||||
|
|
||||||
// Colourize char if stdout supports colours
|
// Colourize char if stdout supports colours
|
||||||
if (process.stdout.isTTY) {
|
if (tty) {
|
||||||
tail = tail.replace(/(.+?)([^\w]|$)/, '\033[32m$1\033[39m$2');
|
tail = tail.replace(/(.+?)([^\w]|$)/, '\033[32m$1\033[39m$2');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,13 +708,21 @@ function SourceInfo(body) {
|
|||||||
|
|
||||||
// This class is the repl-enabled debugger interface which is invoked on
|
// This class is the repl-enabled debugger interface which is invoked on
|
||||||
// "node debug"
|
// "node debug"
|
||||||
function Interface() {
|
function Interface(stdin, stdout) {
|
||||||
var self = this,
|
var self = this,
|
||||||
child;
|
child;
|
||||||
|
|
||||||
|
this.stdin = stdin;
|
||||||
|
this.stdout = stdout;
|
||||||
|
|
||||||
|
var streams = {
|
||||||
|
stdin: stdin,
|
||||||
|
stdout: stdout
|
||||||
|
};
|
||||||
|
|
||||||
// Two eval modes are available: controlEval and debugEval
|
// Two eval modes are available: controlEval and debugEval
|
||||||
// But controlEval is used by default
|
// But controlEval is used by default
|
||||||
this.repl = new repl.REPLServer('debug> ', null,
|
this.repl = new repl.REPLServer('debug> ', streams,
|
||||||
this.controlEval.bind(this));
|
this.controlEval.bind(this));
|
||||||
|
|
||||||
// Kill child process when repl closed or main process is dead
|
// Kill child process when repl closed or main process is dead
|
||||||
@ -788,7 +806,7 @@ function Interface() {
|
|||||||
Interface.prototype.pause = function() {
|
Interface.prototype.pause = function() {
|
||||||
if (this.killed || this.paused++ > 0) return false;
|
if (this.killed || this.paused++ > 0) return false;
|
||||||
this.repl.rli.pause();
|
this.repl.rli.pause();
|
||||||
process.stdin.pause();
|
this.stdin.pause();
|
||||||
};
|
};
|
||||||
|
|
||||||
Interface.prototype.resume = function(silent) {
|
Interface.prototype.resume = function(silent) {
|
||||||
@ -797,7 +815,7 @@ Interface.prototype.resume = function(silent) {
|
|||||||
if (silent !== true) {
|
if (silent !== true) {
|
||||||
this.repl.displayPrompt();
|
this.repl.displayPrompt();
|
||||||
}
|
}
|
||||||
process.stdin.resume();
|
this.stdin.resume();
|
||||||
|
|
||||||
if (this.waiting) {
|
if (this.waiting) {
|
||||||
this.waiting();
|
this.waiting();
|
||||||
@ -808,9 +826,9 @@ Interface.prototype.resume = function(silent) {
|
|||||||
|
|
||||||
// Clear current line
|
// Clear current line
|
||||||
Interface.prototype.clearline = function() {
|
Interface.prototype.clearline = function() {
|
||||||
if (process.stdout.isTTY) {
|
if (this.stdout.isTTY) {
|
||||||
process.stdout.cursorTo(0);
|
this.stdout.cursorTo(0);
|
||||||
process.stdout.clearLine(1);
|
this.stdout.clearLine(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -819,10 +837,10 @@ Interface.prototype.print = function(text, oneline) {
|
|||||||
if (this.killed) return;
|
if (this.killed) return;
|
||||||
this.clearline();
|
this.clearline();
|
||||||
|
|
||||||
process.stdout.write(typeof text === 'string' ? text : util.inspect(text));
|
this.stdout.write(typeof text === 'string' ? text : util.inspect(text));
|
||||||
|
|
||||||
if (oneline !== true) {
|
if (oneline !== true) {
|
||||||
process.stdout.write('\n');
|
this.stdout.write('\n');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1062,7 +1080,9 @@ Interface.prototype.list = function(delta) {
|
|||||||
// Highlight executing statement
|
// Highlight executing statement
|
||||||
var line;
|
var line;
|
||||||
if (current) {
|
if (current) {
|
||||||
line = SourceUnderline(lines[i], client.currentSourceColumn)
|
line = SourceUnderline(lines[i],
|
||||||
|
client.currentSourceColumn,
|
||||||
|
self.stdout.isTTY);
|
||||||
} else {
|
} else {
|
||||||
line = lines[i];
|
line = lines[i];
|
||||||
}
|
}
|
||||||
@ -1404,7 +1424,7 @@ Interface.prototype.trySpawn = function(cb) {
|
|||||||
connectionAttempts = 0;
|
connectionAttempts = 0;
|
||||||
|
|
||||||
client.once('ready', function() {
|
client.once('ready', function() {
|
||||||
process.stdout.write(' ok\n');
|
self.stdout.write(' ok\n');
|
||||||
|
|
||||||
// since we did debug-brk, we're hitting a break point immediately
|
// since we did debug-brk, we're hitting a break point immediately
|
||||||
// continue before anything else.
|
// continue before anything else.
|
||||||
@ -1449,7 +1469,7 @@ Interface.prototype.trySpawn = function(cb) {
|
|||||||
|
|
||||||
function attemptConnect() {
|
function attemptConnect() {
|
||||||
++connectionAttempts;
|
++connectionAttempts;
|
||||||
process.stdout.write('.');
|
self.stdout.write('.');
|
||||||
client.connect(exports.port);
|
client.connect(exports.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,13 @@ function REPLServer(prompt, stream, eval) {
|
|||||||
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
// We're given a duplex socket
|
// We're given a duplex socket
|
||||||
|
if (stream.stdin || stream.stdout) {
|
||||||
|
self.outputStream = stream.stdout;
|
||||||
|
self.inputStream = stream.stdin;
|
||||||
|
} else {
|
||||||
self.outputStream = stream;
|
self.outputStream = stream;
|
||||||
self.inputStream = stream;
|
self.inputStream = stream;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.outputStream = process.stdout;
|
self.outputStream = process.stdout;
|
||||||
self.inputStream = process.stdin;
|
self.inputStream = process.stdin;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user