mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
repl: filter integer keys from repl tab complete list
Refactored version of https://github.com/joyent/node/pull/25819 Removes integer keys (and keys starting with numbers) from candidate list on repl tab complete. Refactored the originally submitted change to simplify and ensure that the integer keys do not show up on objects either. Reviewed By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com> PR-URL: https://github.com/nodejs/node/pull/2409
This commit is contained in:
17
lib/repl.js
17
lib/repl.js
@@ -561,6 +561,15 @@ const requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/;
|
||||
const simpleExpressionRE =
|
||||
/(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/;
|
||||
|
||||
function intFilter(item) {
|
||||
// filters out anything not starting with A-Z, a-z, $ or _
|
||||
return /^[A-Za-z_$]/.test(item);
|
||||
}
|
||||
|
||||
function filteredOwnPropertyNames(obj) {
|
||||
if (!obj) return [];
|
||||
return Object.getOwnPropertyNames(obj).filter(intFilter);
|
||||
}
|
||||
|
||||
// Provide a list of completions for the given leading text. This is
|
||||
// given to the readline interface for handling tab completion.
|
||||
@@ -705,9 +714,9 @@ REPLServer.prototype.complete = function(line, callback) {
|
||||
if (this.useGlobal || vm.isContext(this.context)) {
|
||||
var contextProto = this.context;
|
||||
while (contextProto = Object.getPrototypeOf(contextProto)) {
|
||||
completionGroups.push(Object.getOwnPropertyNames(contextProto));
|
||||
completionGroups.push(filteredOwnPropertyNames(contextProto));
|
||||
}
|
||||
completionGroups.push(Object.getOwnPropertyNames(this.context));
|
||||
completionGroups.push(filteredOwnPropertyNames(this.context));
|
||||
addStandardGlobals(completionGroups, filter);
|
||||
completionGroupsLoaded();
|
||||
} else {
|
||||
@@ -733,7 +742,7 @@ REPLServer.prototype.complete = function(line, callback) {
|
||||
if (obj != null) {
|
||||
if (typeof obj === 'object' || typeof obj === 'function') {
|
||||
try {
|
||||
memberGroups.push(Object.getOwnPropertyNames(obj));
|
||||
memberGroups.push(filteredOwnPropertyNames(obj));
|
||||
} catch (ex) {
|
||||
// Probably a Proxy object without `getOwnPropertyNames` trap.
|
||||
// We simply ignore it here, as we don't want to break the
|
||||
@@ -751,7 +760,7 @@ REPLServer.prototype.complete = function(line, callback) {
|
||||
p = obj.constructor ? obj.constructor.prototype : null;
|
||||
}
|
||||
while (p !== null) {
|
||||
memberGroups.push(Object.getOwnPropertyNames(p));
|
||||
memberGroups.push(filteredOwnPropertyNames(p));
|
||||
p = Object.getPrototypeOf(p);
|
||||
// Circular refs possible? Let's guard against that.
|
||||
sentinel--;
|
||||
|
||||
@@ -248,3 +248,73 @@ testMe.complete('proxy.', common.mustCall(function(error, data) {
|
||||
assert.strictEqual(error, null);
|
||||
assert.deepEqual(data, [[], 'proxy.']);
|
||||
}));
|
||||
|
||||
// Make sure tab completion does not include integer members of an Array
|
||||
var array_elements = [ [
|
||||
'ary.__defineGetter__',
|
||||
'ary.__defineSetter__',
|
||||
'ary.__lookupGetter__',
|
||||
'ary.__lookupSetter__',
|
||||
'ary.__proto__',
|
||||
'ary.constructor',
|
||||
'ary.hasOwnProperty',
|
||||
'ary.isPrototypeOf',
|
||||
'ary.propertyIsEnumerable',
|
||||
'ary.toLocaleString',
|
||||
'ary.toString',
|
||||
'ary.valueOf',
|
||||
'',
|
||||
'ary.concat',
|
||||
'ary.entries',
|
||||
'ary.every',
|
||||
'ary.filter',
|
||||
'ary.forEach',
|
||||
'ary.indexOf',
|
||||
'ary.join',
|
||||
'ary.keys',
|
||||
'ary.lastIndexOf',
|
||||
'ary.length',
|
||||
'ary.map',
|
||||
'ary.pop',
|
||||
'ary.push',
|
||||
'ary.reduce',
|
||||
'ary.reduceRight',
|
||||
'ary.reverse',
|
||||
'ary.shift',
|
||||
'ary.slice',
|
||||
'ary.some',
|
||||
'ary.sort',
|
||||
'ary.splice',
|
||||
'ary.unshift' ],
|
||||
'ary.'];
|
||||
|
||||
putIn.run(['.clear']);
|
||||
|
||||
putIn.run(['var ary = [1,2,3];']);
|
||||
testMe.complete('ary.', common.mustCall(function(error, data) {
|
||||
assert.deepEqual(data, array_elements);
|
||||
}));
|
||||
|
||||
// Make sure tab completion does not include integer keys in an object
|
||||
var obj_elements = [ [
|
||||
'obj.__defineGetter__',
|
||||
'obj.__defineSetter__',
|
||||
'obj.__lookupGetter__',
|
||||
'obj.__lookupSetter__',
|
||||
'obj.__proto__',
|
||||
'obj.constructor',
|
||||
'obj.hasOwnProperty',
|
||||
'obj.isPrototypeOf',
|
||||
'obj.propertyIsEnumerable',
|
||||
'obj.toLocaleString',
|
||||
'obj.toString',
|
||||
'obj.valueOf',
|
||||
'',
|
||||
'obj.a' ],
|
||||
'obj.' ];
|
||||
putIn.run(['.clear']);
|
||||
putIn.run(['var obj = {1:"a","1a":"b",a:"b"};']);
|
||||
|
||||
testMe.complete('obj.', common.mustCall(function(error, data) {
|
||||
assert.deepEqual(data, obj_elements);
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user