@myuon/refactor-mcp
Version:
MCP server for refactoring tools
97 lines • 4.21 kB
JavaScript
import { existsSync } from 'fs';
import { searchFiles, readFileContent } from '../utils/file-utils.js';
import { groupConsecutiveLines } from '../utils/line-utils.js';
export async function performSearch(options) {
const files = await searchFiles(options.filePattern);
const results = [];
const searchRegex = new RegExp(options.searchPattern, 'gm');
const contextRegex = options.contextPattern
? new RegExp(options.contextPattern, 'gm')
: null;
for (const filePath of files) {
if (!existsSync(filePath))
continue;
const content = readFileContent(filePath);
const lines = content.split('\n');
const matches = [...content.matchAll(searchRegex)];
const validMatches = [];
for (const match of matches) {
if (match.index !== undefined) {
const beforeMatch = content.substring(0, match.index);
const lineNumber = beforeMatch.split('\n').length;
// Extract capture groups if any
const captureGroups = match
.slice(1)
.filter(group => group !== undefined);
// Extract the full matched text
const matchedText = match[0];
if (contextRegex) {
const beforeMatchLines = beforeMatch.split('\n').slice(-5).join('\n');
const afterMatchIndex = match.index + match[0].length;
const afterMatch = content.substring(afterMatchIndex);
const afterMatchLines = afterMatch.split('\n').slice(0, 5).join('\n');
const contextArea = beforeMatchLines + match[0] + afterMatchLines;
if (contextRegex.test(contextArea)) {
validMatches.push({
line: lineNumber,
content: lines[lineNumber - 1],
captureGroups: captureGroups.length > 0 ? captureGroups : undefined,
matchedText,
});
}
}
else {
validMatches.push({
line: lineNumber,
content: lines[lineNumber - 1],
captureGroups: captureGroups.length > 0 ? captureGroups : undefined,
matchedText,
});
}
}
}
if (validMatches.length > 0) {
const uniqueLineNumbers = [...new Set(validMatches.map(m => m.line))];
const lineNumbers = uniqueLineNumbers.sort((a, b) => a - b);
const groupedLines = groupConsecutiveLines(lineNumbers);
results.push({
filePath,
matches: validMatches,
lineNumbers,
groupedLines,
});
}
}
return results;
}
export function formatSearchResults(results, options) {
if (results.length === 0) {
return 'No matches found for the given pattern';
}
if (options?.includeCaptureGroups || options?.includeMatchedText) {
return formatDetailedSearchResults(results, options);
}
const formattedResults = results.map(result => `${result.filePath} (${result.groupedLines.join(', ')})`);
return `Search results:\n${formattedResults.join('\n')}`;
}
function formatDetailedSearchResults(results, options) {
const output = ['Search results:'];
for (const result of results) {
output.push(`\n${result.filePath}:`);
for (const match of result.matches) {
if (options.includeMatchedText) {
output.push(` Line ${match.line}: ${match.matchedText}`);
}
else {
output.push(` Line ${match.line}: ${match.content}`);
}
if (options.includeCaptureGroups &&
match.captureGroups &&
match.captureGroups.length > 0) {
output.push(` └─ Captured: [${match.captureGroups.join(', ')}]`);
}
}
}
return output.join('\n');
}
//# sourceMappingURL=search-tool.js.map