405
// exported for testing
406
export function getRgArgs(query: TextSearchQuery2, options: RipgrepTextSearchOptions): string[] {
408
>
args.push(query.isCaseSensitive ? '--case-sensitive' : '--ignore-case');
409
>
410
>
if (options.folderOptions.ignoreGlobCase) {
411
args.push('--glob-case-insensitive');
412
args.push('--ignore-file-case-insensitive');
413
}
415
>
const { doubleStarIncludes, otherIncludes } = groupBy(
416
>
options.folderOptions.includes,
417
>
(include: string) => include.startsWith('**') ? 'doubleStarIncludes' : 'otherIncludes');
418
>
419
>
if (otherIncludes && otherIncludes.length) {
420
>
const uniqueOthers = new Set<string>();
421
>
otherIncludes.forEach(other => { uniqueOthers.add(other); });
422
>
423
>
args.push('-g', '!*');
424
>
uniqueOthers
425
>
.forEach(otherIncude => {
426
>
spreadGlobComponents(otherIncude)
427
>
.map(anchorGlob)
428
>
.forEach(globArg => {
429
>
args.push('-g', globArg);
430
>
});
431
>
});
432
>
}
433
>
434
>
if (doubleStarIncludes && doubleStarIncludes.length) {
435
>
doubleStarIncludes.forEach(globArg => {
436
>
args.push('-g', globArg);
437
>
});
438
>
}
439
>
440
>
options.folderOptions.excludes.map(e => typeof (e) === 'string' ? e : e.pattern)
441
>
.map(anchorGlob)
442
>
.forEach(rgGlob => args.push('-g', `!${rgGlob}`));
443
>
444
>
if (options.maxFileSize) {
445
args.push('--max-filesize', options.maxFileSize + '');
446
}
448
>
if (options.folderOptions.useIgnoreFiles.local) {
449
if (!options.folderOptions.useIgnoreFiles.parent) {
450
args.push('--no-ignore-parent');
451
}
453
>
// Don't use .gitignore or .ignore
454
>
args.push('--no-ignore');
455
>
}
456
>
457
>
if (options.folderOptions.followSymlinks) {
458
args.push('--follow');
459
}
461
>
if (options.folderOptions.encoding && options.folderOptions.encoding !== 'utf8') {
462
args.push('--encoding', options.folderOptions.encoding);
463
}
465
>
if (options.numThreads) {
466
args.push('--threads', `${options.numThreads}`);
467
}
469
>
// Ripgrep handles -- as a -- arg separator. Only --.
470
>
// - is ok, --- is ok, --some-flag is also ok. Need to special case.
471
>
if (query.pattern === '--') {
472
query.isRegExp = true;
473
query.pattern = '\\-\\-';
474
}
476
>
if (query.isMultiline && !query.isRegExp) {
477
query.pattern = escapeRegExpCharacters(query.pattern);
478
query.isRegExp = true;
479
}
481
>
// Allow $ to match /r/n
482
>
args.push('--crlf');
483
>
484
>
if (query.isRegExp) {
485
query.pattern = unicodeEscapesToPCRE2(query.pattern);
486
args.push('--engine', 'auto');
487
}
489
>
let searchPatternAfterDoubleDashes: Maybe<string>;
490
>
if (query.isWordMatch) {
491
const regexp = createRegExp(query.pattern, !!query.isRegExp, { wholeWord: query.isWordMatch });
492
const regexpStr = regexp.source.replace(/\\\//g, '/'); // RegExp.source arbitrarily returns escaped slashes. Search and destroy.
493
args.push('--regexp', regexpStr);
495
let fixedRegexpQuery = fixRegexNewline(query.pattern);
496
fixedRegexpQuery = fixNewline(fixedRegexpQuery);
497
args.push('--regexp', fixedRegexpQuery);
499
>
searchPatternAfterDoubleDashes = query.pattern;
500
>
args.push('--fixed-strings');
501
>
}
502
>
503
>
args.push('--no-config');
504
>
if (!options.folderOptions.useIgnoreFiles.global) {
505
>
args.push('--no-ignore-global');
506
>
}
507
>
508
>
args.push('--json');
509
>
510
>
if (query.isMultiline) {
511
args.push('--multiline');
512
}
514
>
if (options.surroundingContext) {
515
args.push('--before-context', options.surroundingContext + '');
516
args.push('--after-context', options.surroundingContext + '');
517
}
519
>
// Folder to search
520
>
args.push('--');
521
>
522
>
if (searchPatternAfterDoubleDashes) {
523
>
// Put the query after --, in case the query starts with a dash
524
>
args.push(searchPatternAfterDoubleDashes);
525
>
}
526
>
527
>
args.push('.');
528
>
529
>
return args;
530
>
}
531
532
/**
533
* `"foo/*bar/something"` -> `["foo", "foo/*bar", "foo/*bar/something", "foo/*bar/something/**"]`
534
*/
536
>
const globComponentWithBraceExpansion = performBraceExpansionForRipgrep(globComponent);
537
>
538
>
return globComponentWithBraceExpansion.flatMap((globArg) => {
539
>
const components = splitGlobAware(globArg, '/');
540
>
return components.map((_, i) => components.slice(0, i + 1).join('/'));
541
>
});
542
>
543
>
}
544
545
export function unicodeEscapesToPCRE2(pattern: string): string {