ripgrepFileSearch.ts 2.7 KB
Newer Older
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as cp from 'child_process';
import { rgPath } from 'vscode-ripgrep';

9
import { isMacintosh as isMac } from 'vs/base/common/platform';
10
import * as glob from 'vs/base/common/glob';
C
Christof Marti 已提交
11
import { normalizeNFD, startsWith } from 'vs/base/common/strings';
12

13
import { IFolderSearch, IRawSearch } from './search';
14 15
import { foldersToIncludeGlobs, foldersToRgExcludeGlobs } from './ripgrepTextSearch';

16 17 18
// If vscode-ripgrep is in an .asar file, then the binary is unpacked.
const rgDiskPath = rgPath.replace(/\bnode_modules\.asar\b/, 'node_modules.asar.unpacked');

19 20
export function spawnRipgrepCmd(config: IRawSearch, folderQuery: IFolderSearch, includePattern: glob.IExpression, excludePattern: glob.IExpression) {
	const rgArgs = getRgArgs(config, folderQuery, includePattern, excludePattern);
21
	const cwd = folderQuery.folder;
22
	return {
23
		cmd: cp.spawn(rgDiskPath, rgArgs.args, { cwd }),
24 25 26
		siblingClauses: rgArgs.siblingClauses,
		rgArgs,
		cwd
27 28 29
	};
}

30
function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePattern: glob.IExpression, excludePattern: glob.IExpression) {
31 32 33 34
	const args = ['--files', '--hidden', '--case-sensitive'];

	// includePattern can't have siblingClauses
	foldersToIncludeGlobs([folderQuery], includePattern, false).forEach(globArg => {
35 36 37 38 39 40 41 42
		const inclusion = anchor(globArg);
		args.push('-g', inclusion);
		if (isMac) {
			const normalized = normalizeNFD(inclusion);
			if (normalized !== inclusion) {
				args.push('-g', normalized);
			}
		}
43 44 45 46 47
	});

	let siblingClauses: glob.IExpression;

	const rgGlobs = foldersToRgExcludeGlobs([folderQuery], excludePattern, undefined, false);
48 49 50 51 52 53 54 55 56 57
	rgGlobs.globArgs.forEach(globArg => {
		const exclusion = `!${anchor(globArg)}`;
		args.push('-g', exclusion);
		if (isMac) {
			const normalized = normalizeNFD(exclusion);
			if (normalized !== exclusion) {
				args.push('-g', normalized);
			}
		}
	});
58 59
	siblingClauses = rgGlobs.siblingClauses;

60
	if (folderQuery.disregardIgnoreFiles !== false) {
61 62
		// Don't use .gitignore or .ignore
		args.push('--no-ignore');
R
Rob Lourens 已提交
63 64
	} else {
		args.push('--no-ignore-parent');
65
	}
66 67

	// Follow symlinks
68 69 70
	if (!config.ignoreSymlinks) {
		args.push('--follow');
	}
71

72 73 74 75
	if (config.exists) {
		args.push('--quiet');
	}

76 77 78 79 80
	// Folder to search
	args.push('--');

	args.push('.');

81
	return { args, siblingClauses };
82
}
C
Christof Marti 已提交
83 84 85 86

function anchor(glob: string) {
	return startsWith(glob, '**') || startsWith(glob, '/') ? glob : `/${glob}`;
}