Skip to content

Commit dc3e899

Browse files
committed
rewrite autocomplete
1 parent d181071 commit dc3e899

2 files changed

Lines changed: 72 additions & 92 deletions

File tree

src/io.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ class IO {
263263
await this.autocomplete();
264264
}
265265
} catch {} // eslint-disable-line no-empty
266+
return;
266267
}
268+
await this.flip();
267269
}
268270

269271
async setPrefix(s = '') {

src/repl.js

Lines changed: 70 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const util = require('util');
4-
const acorn = require('acorn');
4+
const { parse_dammit: parseDammit } = require('acorn/dist/acorn_loose');
55
const IO = require('./io');
66
const highlight = require('./highlight');
77
const { processTopLevelAwait } = require('./await');
@@ -47,14 +47,6 @@ function wrapObjectLiteralExpressionIfNeeded(code) {
4747
}
4848
}
4949

50-
function isCallExpression(code) {
51-
try {
52-
return acorn.parse(code).body[0].expression.type === 'CallExpression';
53-
} catch {
54-
return false;
55-
}
56-
}
57-
5850
async function collectGlobalNames() {
5951
const keys = Object.getOwnPropertyNames(global);
6052
try {
@@ -170,115 +162,101 @@ Prototype REPL - https://github.com/nodejs/repl`,
170162
}
171163

172164
async onAutocomplete(buffer) {
165+
if (buffer.length === 0) {
166+
return collectGlobalNames();
167+
}
168+
169+
const inlineEval = async (source) => {
170+
const { result, exceptionDetails } =
171+
await this.eval(wrapObjectLiteralExpressionIfNeeded(source), false, true);
172+
if (exceptionDetails) {
173+
return undefined;
174+
}
175+
return ` // ${await oneLineInspect(result)}`;
176+
};
177+
178+
const statement = parseDammit(buffer).body[0];
179+
if (statement.type !== 'ExpressionStatement') {
180+
return undefined;
181+
}
182+
const { expression } = statement;
183+
173184
let keys;
174185
let filter;
175-
if (buffer.length === 0) {
186+
if (expression.type === 'Identifier') {
176187
keys = await collectGlobalNames();
177-
} else {
178-
let expr;
179-
let computed = false;
180-
let leadingQuote = false;
188+
filter = expression.name;
181189

182-
let index = buffer.lastIndexOf('.');
183-
if (index !== -1) {
184-
expr = buffer.slice(0, index);
185-
filter = buffer.slice(index + 1, buffer.length).trim();
190+
if (keys.includes(filter)) {
191+
return inlineEval(buffer);
186192
}
193+
}
187194

188-
if (!expr) {
189-
index = buffer.lastIndexOf('[\'');
190-
if (index !== -1) {
191-
expr = buffer.slice(0, index);
192-
filter = buffer.slice(index + 2, buffer.length);
193-
computed = true;
194-
leadingQuote = true;
195-
}
195+
if (expression.type === 'MemberExpression') {
196+
const expr = buffer.slice(expression.object.start, expression.object.end);
197+
let leadingQuote = false;
198+
if (expression.computed && expression.property.type === 'Literal') {
199+
filter = expression.property.value;
200+
leadingQuote = expression.property.raw.startsWith('\'');
201+
} else if (!expression.computed && expression.property.type === 'Identifier') {
202+
filter = expression.property.name === '✖' ? undefined : expression.property.name;
196203
}
197204

198-
if (!expr) {
199-
index = buffer.lastIndexOf('[');
200-
if (index !== -1) {
201-
expr = buffer.slice(0, index);
202-
filter = buffer.slice(index + 1, buffer.length);
203-
computed = true;
204-
}
205+
const evaluateResult = await this.eval(expr, false, true);
206+
if (evaluateResult.exceptionDetails) {
207+
return undefined;
205208
}
206209

207-
if (isCallExpression(filter)) {
208-
expr = undefined;
209-
filter = undefined;
210+
const own = [];
211+
const inherited = [];
212+
(await Runtime.getProperties({
213+
objectId: evaluateResult.result.objectId,
214+
generatePreview: true,
215+
}))
216+
.result
217+
.filter(({ symbol }) => !symbol)
218+
.forEach(({ isOwn, name }) => {
219+
if (isOwn) {
220+
own.push(name);
221+
} else {
222+
inherited.push(name);
223+
}
224+
});
225+
226+
keys = [...own, ...inherited];
227+
228+
if (keys.includes(filter)) {
229+
return inlineEval(buffer);
210230
}
211231

212-
if (expr) {
213-
const evaluateResult = await this.eval(expr, false, true);
214-
if (evaluateResult.exceptionDetails) {
215-
return undefined;
216-
}
217-
218-
const own = [];
219-
const inherited = [];
220-
221-
(await Runtime.getProperties({
222-
objectId: evaluateResult.result.objectId,
223-
generatePreview: true,
224-
}))
225-
.result
226-
.filter(({ symbol }) => !symbol)
227-
.forEach(({ isOwn, name }) => {
228-
if (isOwn) {
229-
own.push(name);
230-
} else {
231-
inherited.push(name);
232-
}
233-
});
234-
const k = [...own, ...inherited];
235-
236-
if (computed) {
237-
keys = k.map((key) => {
238-
let r;
239-
if (!leadingQuote && `${+key}` === key) {
240-
r = `${key}]`;
241-
} else {
242-
r = `${strEscape(key)}]`;
243-
}
232+
if (expression.computed) {
233+
keys = keys.map((key) => {
234+
let r;
235+
if (!leadingQuote && `${+key}` === key) {
236+
r = key;
237+
} else {
238+
r = strEscape(key);
244239
if (leadingQuote) {
245-
return r.slice(1);
240+
r = r.slice(1);
246241
}
247-
return r;
248-
});
249-
} else {
250-
keys = k.filter(isIdentifier);
251-
}
242+
}
243+
return `${r}]`;
244+
});
252245
} else {
253-
const evaluateResult = await this.eval(
254-
wrapObjectLiteralExpressionIfNeeded(buffer), false, true,
255-
);
256-
if (evaluateResult.exceptionDetails) {
257-
return undefined;
258-
}
259-
return ` // ${await oneLineInspect(evaluateResult.result)}`;
246+
keys = keys.filter(isIdentifier);
260247
}
261248
}
262249

263250
if (keys) {
264251
if (filter) {
265-
if (keys.includes(filter)) {
266-
const evaluateResult = await this.eval(
267-
wrapObjectLiteralExpressionIfNeeded(buffer), false, true,
268-
);
269-
if (evaluateResult.exceptionDetails) {
270-
return undefined;
271-
}
272-
return ` // ${await oneLineInspect(evaluateResult.result)}`;
273-
}
274-
275252
return keys
276253
.filter((k) => k.startsWith(filter))
277254
.map((k) => k.slice(filter.length));
278255
}
279256
return keys;
280257
}
281-
return undefined;
258+
259+
return inlineEval(buffer);
282260
}
283261
}
284262

0 commit comments

Comments
 (0)