@@ -45,6 +45,9 @@ import { Script, createContext, runInContext } from 'vm';
45
45
46
46
declare const __non_webpack_require__ : any ;
47
47
48
+ // eslint-disable-next-line no-control-regex
49
+ const CONTROL_CHAR_REGEXP = / [ \x00 - \x1F \x7F - \x9F ] / g;
50
+
48
51
/**
49
52
* All CLI flags that are useful for {@link MongoshNodeRepl}.
50
53
*/
@@ -388,52 +391,64 @@ class MongoshNodeRepl implements EvaluationListener {
388
391
null ,
389
392
instanceState . getAutocompleteParameters ( )
390
393
) ;
391
- ( repl as Mutable < typeof repl > ) . completer = callbackify (
394
+ const innerCompleter = async (
395
+ text : string
396
+ ) : Promise < [ string [ ] , string ] > => {
397
+ // Merge the results from the repl completer and the mongosh completer.
398
+ const [
399
+ [ replResults , replOrig ] ,
400
+ [ mongoshResults , , mongoshResultsExclusive ] ,
401
+ ] = await Promise . all ( [
402
+ ( async ( ) => ( await origReplCompleter ( text ) ) || [ [ ] ] ) ( ) ,
403
+ ( async ( ) => await mongoshCompleter ( text ) ) ( ) ,
404
+ ] ) ;
405
+ this . bus . emit ( 'mongosh:autocompletion-complete' ) ; // For testing.
406
+
407
+ // Sometimes the mongosh completion knows that what it is doing is right,
408
+ // and that autocompletion based on inspecting the actual objects that
409
+ // are being accessed will not be helpful, e.g. in `use a<tab>`, we know
410
+ // that we want *only* database names and not e.g. `assert`.
411
+ if ( mongoshResultsExclusive ) {
412
+ return [ mongoshResults , text ] ;
413
+ }
414
+
415
+ // The REPL completer may not complete the entire string; for example,
416
+ // when completing ".ed" to ".editor", it reports as having completed
417
+ // only the last piece ("ed"), or when completing "{ $g", it completes
418
+ // only "$g" and not the entire result.
419
+ // The mongosh completer always completes on the entire string.
420
+ // In order to align them, we always extend the REPL results to include
421
+ // the full string prefix.
422
+ const replResultPrefix = replOrig
423
+ ? text . substr ( 0 , text . lastIndexOf ( replOrig ) )
424
+ : '' ;
425
+ const longReplResults = replResults . map (
426
+ ( result : string ) => replResultPrefix + result
427
+ ) ;
428
+
429
+ // Remove duplicates, because shell API methods might otherwise show
430
+ // up in both completions.
431
+ const deduped = [ ...new Set ( [ ...longReplResults , ...mongoshResults ] ) ] ;
432
+
433
+ return [ deduped , text ] ;
434
+ } ;
435
+
436
+ const nodeReplCompleter = callbackify (
392
437
async ( text : string ) : Promise < [ string [ ] , string ] > => {
393
438
this . insideAutoCompleteOrGetPrompt = true ;
394
439
try {
395
- // Merge the results from the repl completer and the mongosh completer.
396
- const [
397
- [ replResults , replOrig ] ,
398
- [ mongoshResults , , mongoshResultsExclusive ] ,
399
- ] = await Promise . all ( [
400
- ( async ( ) => ( await origReplCompleter ( text ) ) || [ [ ] ] ) ( ) ,
401
- ( async ( ) => await mongoshCompleter ( text ) ) ( ) ,
402
- ] ) ;
403
- this . bus . emit ( 'mongosh:autocompletion-complete' ) ; // For testing.
404
-
405
- // Sometimes the mongosh completion knows that what it is doing is right,
406
- // and that autocompletion based on inspecting the actual objects that
407
- // are being accessed will not be helpful, e.g. in `use a<tab>`, we know
408
- // that we want *only* database names and not e.g. `assert`.
409
- if ( mongoshResultsExclusive ) {
410
- return [ mongoshResults , text ] ;
411
- }
412
-
413
- // The REPL completer may not complete the entire string; for example,
414
- // when completing ".ed" to ".editor", it reports as having completed
415
- // only the last piece ("ed"), or when completing "{ $g", it completes
416
- // only "$g" and not the entire result.
417
- // The mongosh completer always completes on the entire string.
418
- // In order to align them, we always extend the REPL results to include
419
- // the full string prefix.
420
- const replResultPrefix = replOrig
421
- ? text . substr ( 0 , text . lastIndexOf ( replOrig ) )
422
- : '' ;
423
- const longReplResults = replResults . map (
424
- ( result : string ) => replResultPrefix + result
440
+ // eslint-disable-next-line prefer-const
441
+ let [ results , completeOn ] = await innerCompleter ( text ) ;
442
+ results = results . filter (
443
+ ( result ) => ! CONTROL_CHAR_REGEXP . test ( result )
425
444
) ;
426
-
427
- // Remove duplicates, because shell API methods might otherwise show
428
- // up in both completions.
429
- const deduped = [ ...new Set ( [ ...longReplResults , ...mongoshResults ] ) ] ;
430
-
431
- return [ deduped , text ] ;
445
+ return [ results , completeOn ] ;
432
446
} finally {
433
447
this . insideAutoCompleteOrGetPrompt = false ;
434
448
}
435
449
}
436
450
) ;
451
+ ( repl as Mutable < typeof repl > ) . completer = nodeReplCompleter ;
437
452
438
453
// This is used below for multiline history manipulation.
439
454
let originalHistory : string [ ] | null = null ;
0 commit comments