From 2443d832265c7d1cfd48a4161455c9692342e6c2 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 15 Jan 2015 11:14:29 -0500 Subject: [PATCH] Reenable tab-completion of global variable names in `meteor shell`. Summary: Before this commit you could type `Meteor.is` in a `meteor shell` session and then tab to see a list of possible completions (e.g. `Meteor.isClient`, `Meteor.isServer`), but typing a prefix of a global variable name like `Mete` followed by tab has been broken ever since we stopped using the global object as the REPL context: https://github.com/meteor/meteor/commit/7c7e52f2d2 The reason for that commit was to prevent the REPL from overwriting the global `_` variable (which most Meteor developers expect to be bound to `require("underscore")`): https://github.com/meteor/meteor/3227 This commit solves #3227 by making `repl.context._` a read-only property that is permanently "bound" to underscore. As a bonus, we now intercept assignments to `_` and store those values as `repl.context.__`, so you still have access to the last result in the shell via `__`. Test Plan: Run `meteor shell`, evaluate a few expressions, and see that (1) global variables can be tab-completed, (2) `_` remains bound to underscore, and (3) `__` gets bound to the result of the evaluated expressions. Reviewers: avital, stubailo, glasser Reviewed By: glasser Differential Revision: https://phabricator.meteor.io/D12 --- tools/server/shell.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/server/shell.js b/tools/server/shell.js index 4bf4b07a91..18ed0f7896 100644 --- a/tools/server/shell.js +++ b/tools/server/shell.js @@ -56,7 +56,7 @@ function onConnection(socket) { prompt: "> ", terminal: true, useColors: true, - useGlobal: false, + useGlobal: true, ignoreUndefined: true, }); @@ -77,6 +77,19 @@ function startREPL(options) { // History persists across shell sessions! initializeHistory(repl); + Object.defineProperty(repl.context, "_", { + // Force the global _ variable to remain bound to underscore. + get: function () { return _; }, + + // Expose the last REPL result as __ instead of _. + set: function(lastResult) { + repl.context.__ = lastResult; + }, + + enumerable: true, + configurable: false + }); + // Use the same `require` function and `module` object visible to the // shell.js module. repl.context.require = require;