Skip to content

Commit 22a4c60

Browse files
dario-piotrowiczaduh95
authored andcommitted
repl: fix tab completion not working with computer string properties
PR-URL: #58709 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent db648b9 commit 22a4c60

2 files changed

Lines changed: 131 additions & 1 deletion

File tree

‎lib/repl.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ const importRE = /\bimport\s*\(\s*['"`](([\w@./:-]+\/)?(?:[\w@./:-]*))(?![^'"`])
12071207
constrequireRE=/\brequire\s*\(\s*['"`](([\w@./:-]+\/)?(?:[\w@./:-]*))(?![^'"`])$/;
12081208
constfsAutoCompleteRE=/fs(?:\.promises)?\.\s*[a-z][a-zA-Z]+\(\s*["'](.*)/;
12091209
constsimpleExpressionRE=
1210-
/(?:[\w$'"`[{(](?:\w|\$|['"`\]})])*\??\.)*[a-zA-Z_$](?:\w|\$)*\??\.?$/;
1210+
/(?:[\w$'"`[{(](?:(\w||\t)*?['"`]|\$|['"`\]})])*\??(?:\.|])?)*?(?:[a-zA-Z_$])?(?:\w|\$)*\??\.?$/;
12111211
constversionedFileNamesRe=/-\d+\.\d+/;
12121212

12131213
functionisIdentifier(str){
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constArrayStream=require('../common/arraystream');
5+
const{ describe, it, before, after }=require('node:test');
6+
constassert=require('assert');
7+
8+
constrepl=require('repl');
9+
10+
functionprepareREPL(){
11+
constinput=newArrayStream();
12+
constreplServer=repl.start({
13+
prompt: '',
14+
input,
15+
output: process.stdout,
16+
allowBlockingCompletions: true,
17+
});
18+
19+
// Some errors are passed to the domain, but do not callback
20+
replServer._domain.on('error',assert.ifError);
21+
22+
return{ replServer, input };
23+
}
24+
25+
functiontestCompletion(replServer,{ input, expectedCompletions }){
26+
replServer.complete(
27+
input,
28+
common.mustCall((_error,data)=>{
29+
assert.deepStrictEqual(data,[expectedCompletions,input]);
30+
}),
31+
);
32+
};
33+
34+
describe('REPL tab object completion on computed properties',()=>{
35+
describe('simple string cases',()=>{
36+
letreplServer;
37+
38+
before(()=>{
39+
const{replServer: server, input }=prepareREPL();
40+
replServer=server;
41+
42+
input.run([
43+
`
44+
const obj = {
45+
one: 1,
46+
innerObj: { two: 2 },
47+
'inner object': { three: 3 },
48+
};
49+
50+
const oneStr = 'one';
51+
`,
52+
]);
53+
});
54+
55+
after(()=>{
56+
replServer.close();
57+
});
58+
59+
it('works with double quoted strings',()=>testCompletion(replServer,{
60+
input: 'obj["one"].toFi',
61+
expectedCompletions: ['obj["one"].toFixed'],
62+
}));
63+
64+
it('works with single quoted strings',()=>testCompletion(replServer,{
65+
input: "obj['one'].toFi",
66+
expectedCompletions: ["obj['one'].toFixed"],
67+
}));
68+
69+
it('works with template strings',()=>testCompletion(replServer,{
70+
input: 'obj[`one`].toFi',
71+
expectedCompletions: ['obj[`one`].toFixed'],
72+
}));
73+
74+
it('works with nested objects',()=>{
75+
testCompletion(replServer,{
76+
input: 'obj["innerObj"].tw',
77+
expectedCompletions: ['obj["innerObj"].two'],
78+
});
79+
testCompletion(replServer,{
80+
input: 'obj["innerObj"].two.tofi',
81+
expectedCompletions: ['obj["innerObj"].two.toFixed'],
82+
});
83+
});
84+
85+
it('works with nested objects combining different type of strings',()=>testCompletion(replServer,{
86+
input: 'obj["innerObj"][`two`].tofi',
87+
expectedCompletions: ['obj["innerObj"][`two`].toFixed'],
88+
}));
89+
90+
it('works with strings with spaces',()=>testCompletion(replServer,{
91+
input: 'obj["inner object"].th',
92+
expectedCompletions: ['obj["inner object"].three'],
93+
}));
94+
});
95+
96+
describe('variables as indexes',()=>{
97+
letreplServer;
98+
99+
before(()=>{
100+
const{replServer: server, input }=prepareREPL();
101+
replServer=server;
102+
103+
input.run([
104+
`
105+
const oneStr = 'One';
106+
const helloWorldStr = 'Hello' + ' ' + 'World';
107+
108+
const obj = {
109+
[oneStr]: 1,
110+
['Hello World']: 'hello world!',
111+
};
112+
`,
113+
]);
114+
});
115+
116+
after(()=>{
117+
replServer.close();
118+
});
119+
120+
it('works with a simple variable',()=>testCompletion(replServer,{
121+
input: 'obj[oneStr].toFi',
122+
expectedCompletions: ['obj[oneStr].toFixed'],
123+
}));
124+
125+
it('works with a computed variable',()=>testCompletion(replServer,{
126+
input: 'obj[helloWorldStr].tolocaleup',
127+
expectedCompletions: ['obj[helloWorldStr].toLocaleUpperCase'],
128+
}));
129+
});
130+
});

0 commit comments

Comments
 (0)