Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fixup! repl: simplify repl autocompletion
Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information
BridgeAR committed May 18, 2020
commit 0dc59285c9cb836b9cafa0dd5a428db6f99d1b34
56 changes: 29 additions & 27 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,24 @@ function gracefulReaddir(...args) {
} catch {}
}

function completeFSFunctions(line) {
let baseName = '';
let filePath = line.match(fsAutoCompleteRE)[1];
let fileList = gracefulReaddir(filePath, { withFileTypes: true });

if (!fileList) {
baseName = path.basename(filePath);
filePath = path.dirname(filePath);
fileList = gracefulReaddir(filePath, { withFileTypes: true }) || [];
}

const completions = fileList
.filter((dirent) => dirent.name.startsWith(baseName))
.map((d) => d.name);

return [[completions], baseName];
}

// Provide a list of completions for the given leading text. This is
// given to the readline interface for handling tab completion.
//
Expand Down Expand Up @@ -1202,21 +1220,7 @@ function complete(line, callback) {
completionGroups.push(_builtinLibs);
}
} else if (fsAutoCompleteRE.test(line)) {
let baseName = '';
let filePath = line.match(fsAutoCompleteRE)[1];
let fileList = gracefulReaddir(filePath, { withFileTypes: true });

if (!fileList) {
baseName = path.basename(filePath);
filePath = path.dirname(filePath);
fileList = gracefulReaddir(filePath, { withFileTypes: true }) || [];
}

const filteredValue = fileList
.filter((dirent) => dirent.name.startsWith(baseName))
.map((d) => d.name);
completionGroups.push(filteredValue);
completeOn = baseName;
[completionGroups, completeOn] = completeFSFunctions(line);
// Handle variable member lookup.
// We support simple chained expressions like the following (no function
// calls, etc.). That is for simplicity and also because we *eval* that
Expand All @@ -1228,25 +1232,22 @@ function complete(line, callback) {
// foo<|> # all scope vars with filter 'foo'
// foo.<|> # completions for 'foo' with filter ''
} else if (line.length === 0 || /\w|\.|\$/.test(line[line.length - 1])) {
const match = simpleExpressionRE.exec(line);
const [match] = simpleExpressionRE.exec(line) || [''];
if (line.length !== 0 && !match) {
completionGroupsLoaded();
return;
}
let expr;
completeOn = (match ? match[0] : '');
if (line.length === 0) {
expr = '';
} else if (line[line.length - 1] === '.') {
expr = match[0].slice(0, match[0].length - 1);
} else {
const bits = match[0].split('.');
let expr = '';
completeOn = match;
if (line.endsWith('.')) {
expr = match.slice(0, -1);
} else if (line.length !== 0) {
const bits = match.split('.');
filter = bits.pop();
expr = bits.join('.');
}

// Resolve expr and get its completions.
const memberGroups = [];
if (!expr) {
// Get global vars synchronously
completionGroups.push(getGlobalLexicalScopeNames(this[kContextId]));
Expand All @@ -1267,11 +1268,12 @@ function complete(line, callback) {
}

let chaining = '.';
if (expr[expr.length - 1] === '?') {
if (expr.endsWith('?')) {
expr = expr.slice(0, -1);
chaining = '?.';
}

const memberGroups = [];
const evalExpr = `try { ${expr} } catch {}`;
this.eval(evalExpr, this.context, 'repl', (e, obj) => {
try {
Expand Down Expand Up @@ -1320,7 +1322,7 @@ function complete(line, callback) {
if (completionGroups.length && filter) {
const newCompletionGroups = [];
for (const group of completionGroups) {
const filteredGroup = group.filter((e) => e.indexOf(filter) === 0);
const filteredGroup = group.filter((str) => str.startsWith(filter));
if (filteredGroup.length) {
newCompletionGroups.push(filteredGroup);
}
Expand Down