mecanismo de búsqueda de documentos vscode

La velocidad de búsqueda global de vscode es muy rápida, ¿cuál es el secreto?

A menudo necesitamos buscar una cadena en una gran cantidad de archivos de texto, y podemos usar el integrado Linuxa continuación grep, pero la línea de comando de grep todavía es un poco difícil de recordar. ripgrepEs una herramienta de código abierto, Rustescrita en uso y compatible con todas las plataformas. Parece mucho más poderoso que grep. Si lo usa VS Code, entonces debe haber usado esta herramienta indirectamente, porque la función Buscar en archivos de VS Code se llama directamente ripgrep.

La dirección de github de ripgrep: https://github.com/BurntSushi/ripgrep

inserte la descripción de la imagen aquí
ripgrepes una herramienta de búsqueda orientada a líneas que busca recursivamente patrones de expresiones regulares en el directorio actual. De forma predeterminada, las reglas ripgrepse respetan Gitignore y los archivos/directorios ocultos y los archivos binarios se omiten automáticamente. ripgrepHay soporte de primera clase en Windows, macOSy Linux, con descargas binarias disponibles para cada versión. ripgrep es similar a otras herramientas de búsqueda populares como Silver Searcher, ACK y Grep.

Hay un gran dios que resolvió un documento chino: https://gitcode.gitcode.host/docs-cn/ripgrep-docs-cn/index.html

Para facilitar el uso en el proyecto, vscode está empaquetado en un módulo npmvscode-regexpp

Dirección de Npm: https://www.npmjs.com/package/@vscode/ripgrep

ejemplo:

const {
    
     rgPath } = require('vscode-ripgrep');

// child_process.spawn(rgPath, ...)

repositorio de github: https://github.com/microsoft/vscode-ripgrep

Veamos como se llama, el siguiente es el paquete npm, de hecho también es un archivo ejecutable
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
que se ejecuta al final.rg

src/vs/workbench/services/search/node/ripgrepTextSearchEngine.ts

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

// 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');

export class RipgrepTextSearchEngine {
    
    

	constructor(private outputChannel: IOutputChannel) {
    
     }

	provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): Promise<TextSearchComplete> {
    
    
		this.outputChannel.appendLine(`provideTextSearchResults ${
      
      query.pattern}, ${
      
      JSON.stringify({
      
      
			...options,
			...{
      
      
				folder: options.folder.toString()
			}
		})}`);
		return new Promise((resolve, reject) => {
    
    
			token.onCancellationRequested(() => cancel());

			const rgArgs = getRgArgs(query, options);

			const cwd = options.folder.fsPath;

			const escapedArgs = rgArgs
				.map(arg => arg.match(/^-/) ? arg : `'${
      
      arg}'`)
				.join(' ');
			this.outputChannel.appendLine(`${
      
      rgDiskPath} ${
      
      escapedArgs}\n - cwd: ${
      
      cwd}`);
			// console.log('999999999999', rgDiskPath); // /Users/liuchongyang/site/vscode/node_modules/@vscode/ripgrep/bin/rg
			let rgProc: Maybe<cp.ChildProcess> = cp.spawn(rgDiskPath, rgArgs, {
    
     cwd });
			rgProc.on('error', e => {
    
    
				console.error(e);
				this.outputChannel.appendLine('Error: ' + (e && e.message));
				reject(serializeSearchError(new SearchError(e && e.message, SearchErrorCode.rgProcessError)));
			});

			let gotResult = false;
			const ripgrepParser = new RipgrepParser(options.maxResults, cwd, options.previewOptions);
			ripgrepParser.on('result', (match: TextSearchResult) => {
    
    
				console.log('match-->', match); //匹配的结果
				gotResult = true;
				dataWithoutResult = '';
				progress.report(match);
			});

			let isDone = false;
			const cancel = () => {
    
    
				isDone = true;

				if (rgProc) {
    
    
					rgProc.kill();
				}

				if (ripgrepParser) {
    
    
					ripgrepParser.cancel();
				}
			};

			let limitHit = false;
			ripgrepParser.on('hitLimit', () => {
    
    
				limitHit = true;
				cancel();
			});

			let dataWithoutResult = '';
			rgProc.stdout!.on('data', data => {
    
    
				console.log('data->', data);
				ripgrepParser.handleData(data);
				if (!gotResult) {
    
    
					dataWithoutResult += data;
				}
			});

			let gotData = false;
			rgProc.stdout!.once('data', () => gotData = true);

			let stderr = '';
			rgProc.stderr!.on('data', data => {
    
    
				const message = data.toString();
				this.outputChannel.appendLine(message);
				stderr += message;
			});

			rgProc.on('close', () => {
    
    
				this.outputChannel.appendLine(gotData ? 'Got data from stdout' : 'No data from stdout');
				this.outputChannel.appendLine(gotResult ? 'Got result from parser' : 'No result from parser');
				if (dataWithoutResult) {
    
    
					this.outputChannel.appendLine(`Got data without result: ${
      
      dataWithoutResult}`);
				}

				this.outputChannel.appendLine('');

				if (isDone) {
    
    
					resolve({
    
     limitHit });
				} else {
    
    
					// Trigger last result
					ripgrepParser.flush();
					rgProc = null;
					let searchError: Maybe<SearchError>;
					if (stderr && !gotData && (searchError = rgErrorMsgForDisplay(stderr))) {
    
    
						reject(serializeSearchError(new SearchError(searchError.message, searchError.code)));
					} else {
    
    
						resolve({
    
     limitHit });
					}
				}
			});
		});
	}
}

Imprimir datos Los datos originales devuelven la matriz de búfer, que
inserte la descripción de la imagen aquí
se vuelve así después de ser procesada por vscode,
inserte la descripción de la imagen aquí
lo cual es muy claro y podemos entenderlo.

range es un objeto javascript que representa un fragmento de documento que contiene nodos y partes de nodos de texto. Se utiliza para el procesamiento de documentos.
https://developer.mozilla.org/en-US/docs/Web/API/Range

Vscode es un rango simulado que encapsula un rango adecuado para sus propios escenarios de uso.

Supongo que te gusta

Origin blog.csdn.net/woyebuzhidao321/article/details/131495844
Recomendado
Clasificación