diff --git a/lib/repl.js b/lib/repl.js index 75d09d70314..9fea5826142 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -60,27 +60,14 @@ module.filename = process.cwd() + '/repl'; // hack for repl require to work properly with node_modules folders module.paths = require('module')._nodeModulePaths(module.filename); - -function resetContext() { - context = vm.createContext(); - for (var i in global) context[i] = global[i]; - context.module = module; - context.require = require; - context.global = context; - context.global.global = context; - for (var i in require.cache) delete require.cache[i]; -} - - // Can overridden with custom print functions, such as `probe` or `eyes.js` exports.writer = util.inspect; function REPLServer(prompt, stream) { var self = this; - if (!context) resetContext(); - if (!exports.repl) exports.repl = this; - self.context = context; + + self.resetContext(); self.bufferedCommand = ''; if (stream) { @@ -159,7 +146,7 @@ function REPLServer(prompt, stream) { // First we attempt to eval as expression with parens. // This catches '{a : 1}' properly. ret = vm.runInContext('(' + self.bufferedCommand + ')', - context, + self.context, 'repl'); if (typeof ret !== 'function') success = true; } catch (e) { @@ -168,11 +155,11 @@ function REPLServer(prompt, stream) { if (!success) { // Now as statement without parens. - ret = vm.runInContext(self.bufferedCommand, context, 'repl'); + ret = vm.runInContext(self.bufferedCommand, self.context, 'repl'); } if (ret !== undefined) { - context._ = ret; + self.context._ = ret; self.outputStream.write(exports.writer(ret) + '\n'); } @@ -215,10 +202,33 @@ exports.REPLServer = REPLServer; // prompt is a string to print on each line for the prompt, // source is a stream to use for I/O, defaulting to stdin/stdout. exports.start = function(prompt, source) { - return new REPLServer(prompt, source); + var repl = new REPLServer(prompt, source); + if (!exports.repl) exports.repl = repl; + return repl; }; +REPLServer.prototype.createContext = function() { + var context = vm.createContext(); + + for (var i in global) context[i] = global[i]; + context.module = module; + context.require = require; + context.global = context; + context.global.global = context; + + return context; +}; + +REPLServer.prototype.resetContext = function(force) { + if (!context || force) { + context = this.createContext(); + for (var i in require.cache) delete require.cache[i]; + } + + this.context = context; +}; + REPLServer.prototype.displayPrompt = function() { this.rli.setPrompt(this.bufferedCommand.length ? '... ' : this.prompt); this.rli.prompt(); @@ -503,7 +513,7 @@ function defineDefaultCommands(repl) { action: function() { this.outputStream.write('Clearing context...\n'); this.bufferedCommand = ''; - resetContext(); + this.resetContext(true); this.displayPrompt(); } });