Skip to content

Commit 371bc3d

Browse files
committed
rewrite autocomplete
1 parent d181071 commit 371bc3d

File tree

2 files changed

+68
-91
lines changed

2 files changed

+68
-91
lines changed

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: 66 additions & 91 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,98 @@ 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 statement = parseDammit(buffer).body[0];
170+
if (statement.type !== 'ExpressionStatement') {
171+
return undefined;
172+
}
173+
const { expression } = statement;
174+
173175
let keys;
174176
let filter;
175-
if (buffer.length === 0) {
177+
if (expression.type === 'Identifier') {
176178
keys = await collectGlobalNames();
177-
} else {
178-
let expr;
179-
let computed = false;
180-
let leadingQuote = false;
179+
filter = expression.name;
180+
}
181181

182-
let index = buffer.lastIndexOf('.');
183-
if (index !== -1) {
184-
expr = buffer.slice(0, index);
185-
filter = buffer.slice(index + 1, buffer.length).trim();
182+
if (expression.type === 'MemberExpression') {
183+
const expr = buffer.slice(expression.object.start, expression.object.end);
184+
let leadingQuote = false;
185+
if (expression.computed && expression.property.type === 'Literal') {
186+
filter = expression.property.value;
187+
leadingQuote = expression.property.raw.startsWith('\'');
188+
} else if (!expression.computed && expression.property.type === 'Identifier') {
189+
filter = expression.property.name === '✖' ? undefined : expression.property.name;
186190
}
187191

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-
}
192+
const evaluateResult = await this.eval(expr, false, true);
193+
if (evaluateResult.exceptionDetails) {
194+
return undefined;
196195
}
197196

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-
}
197+
const own = [];
198+
const inherited = [];
199+
(await Runtime.getProperties({
200+
objectId: evaluateResult.result.objectId,
201+
generatePreview: true,
202+
}))
203+
.result
204+
.filter(({ symbol }) => !symbol)
205+
.forEach(({ isOwn, name }) => {
206+
if (isOwn) {
207+
own.push(name);
208+
} else {
209+
inherited.push(name);
210+
}
211+
});
206212

207-
if (isCallExpression(filter)) {
208-
expr = undefined;
209-
filter = undefined;
210-
}
213+
keys = [...own, ...inherited];
211214

212-
if (expr) {
213-
const evaluateResult = await this.eval(expr, false, true);
214-
if (evaluateResult.exceptionDetails) {
215+
if (keys.includes(filter)) {
216+
const { result, exceptionDetails } =
217+
await this.eval(wrapObjectLiteralExpressionIfNeeded(buffer), false, true);
218+
if (exceptionDetails) {
215219
return undefined;
216220
}
221+
return ` // ${await oneLineInspect(result)}`;
222+
}
217223

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-
}
224+
if (expression.computed) {
225+
keys = keys.map((key) => {
226+
let r;
227+
if (!leadingQuote && `${+key}` === key) {
228+
r = key;
229+
} else {
230+
r = strEscape(key);
244231
if (leadingQuote) {
245-
return r.slice(1);
232+
r = r.slice(1);
246233
}
247-
return r;
248-
});
249-
} else {
250-
keys = k.filter(isIdentifier);
251-
}
234+
}
235+
return `${r}]`;
236+
});
252237
} 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)}`;
238+
keys = keys.filter(isIdentifier);
260239
}
261240
}
262241

263242
if (keys) {
264243
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-
275244
return keys
276245
.filter((k) => k.startsWith(filter))
277246
.map((k) => k.slice(filter.length));
278247
}
279248
return keys;
280249
}
281-
return undefined;
250+
251+
const { result, exceptionDetails } =
252+
await this.eval(wrapObjectLiteralExpressionIfNeeded(buffer), false, true);
253+
if (exceptionDetails) {
254+
return undefined;
255+
}
256+
return ` // ${await oneLineInspect(result)}`;
282257
}
283258
}
284259

0 commit comments

Comments
 (0)