Skip to content

Commit 20cc8ec

Browse files
addaleaxtargos
authored andcommitted
readline: allow completer to rewrite existing input
Sometimes, it makes sense for a completer to change the existing input, e.g. by adjusting the casing (imagine a completer that corrects `Number.isNan` to `Number.IsNaN`, for example). This commit allows that in the readline implemention. PR-URL: #39178 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
1 parent 63f8702 commit 20cc8ec

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

‎lib/readline.js‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,9 +705,21 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab){
705705
// If there is a common prefix to all matches, then apply that portion.
706706
constprefix=commonPrefix(ArrayPrototypeFilter(completions,
707707
(e)=>e!==''));
708-
if(prefix.length>completeOn.length){
708+
if(StringPrototypeStartsWith(prefix,completeOn)&&
709+
prefix.length>completeOn.length){
709710
this._insertString(StringPrototypeSlice(prefix,completeOn.length));
710711
return;
712+
}elseif(!StringPrototypeStartsWith(completeOn,prefix)){
713+
this.line=StringPrototypeSlice(this.line,
714+
0,
715+
this.cursor-completeOn.length)+
716+
prefix+
717+
StringPrototypeSlice(this.line,
718+
this.cursor,
719+
this.line.length);
720+
this.cursor=this.cursor-completeOn.length+prefix.length;
721+
this._refreshLine();
722+
return;
711723
}
712724

713725
if(!lastKeypressWasTab){

‎test/parallel/test-readline-tab-complete.js‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,39 @@ common.skipIfDumbTerminal();
100100
});
101101
rli.close();
102102
}
103+
104+
{
105+
letoutput='';
106+
classFakeInputextendsEventEmitter{
107+
columns=80
108+
109+
write=common.mustCall((data)=>{
110+
output+=data;
111+
},9)
112+
113+
resume(){}
114+
pause(){}
115+
end(){}
116+
}
117+
118+
constfi=newFakeInput();
119+
constrli=newreadline.Interface({
120+
input: fi,
121+
output: fi,
122+
terminal: true,
123+
completer: common.mustCall((input,cb)=>{
124+
cb(null,[[input[0].toUpperCase()+input.slice(1)],input]);
125+
}),
126+
});
127+
128+
rli.on('line',common.mustNotCall());
129+
fi.emit('data','input');
130+
queueMicrotask(()=>{
131+
fi.emit('data','\t');
132+
queueMicrotask(()=>{
133+
assert.match(output,/>Input/);
134+
output='';
135+
rli.close();
136+
});
137+
});
138+
}

0 commit comments

Comments
(0)