Skip to content

Commit

Permalink
feat: improve file marking logic and better handle single file select…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
codybrom committed Jan 8, 2025
1 parent 435c2c8 commit 38bc115
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 13 deletions.
63 changes: 52 additions & 11 deletions src/commands/markFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const markFile = {
action: () => void,
message: string,
markedFilesProvider: MarkedFilesProvider,
) {
): Promise<void> {
action();
showMessage.info(message);
await markedFilesProvider.refresh();
Expand Down Expand Up @@ -61,30 +61,43 @@ export const markFile = {
return;
}

if (markedFiles.has(filePath)) {
this.unmarkFile(filePath, markedFilesProvider);
} else {
await this.handleSingleFile(filePath, workspacePath, markedFilesProvider);
}
},

async handleSingleFile(
filePath: string,
workspacePath: string,
markedFilesProvider: MarkedFilesProvider,
): Promise<boolean> {
const relPath = getRelativePath(workspacePath, filePath);

if (isIgnored(relPath)) {
showMessage.warning(
`Cannot mark "${getBasename(filePath)}": File is excluded\nThis file matches patterns in your ignore files (.gitignore, .dockerignore, etc.)\nPath: ${relPath}`,
`Note: "${getBasename(filePath)}" matches patterns in your ignore files but will be marked anyway since it was specifically selected.`,
);
return;
}

if (!this.isFileTypeSupported(filePath)) {
showMessage.warning(
`Cannot mark "${getBasename(filePath)}": Unsupported file type (.${getExtension(filePath)})\nSupported types: ${getConfig().detectedFileExtensions.join(', ')}\nYou can add more file types in Settings > LLM Context Generator > Detected File Extensions`,
);
return;
return false;
}

if (markedFiles.has(filePath)) {
this.unmarkFile(filePath, markedFilesProvider);
} else {
if (!markedFiles.has(filePath)) {
this.updateMarkedFiles(
() => markedFiles.add(filePath),
`Marked: ${getBasename(filePath)}`,
markedFilesProvider,
);
} else {
showMessage.info('Selected file is already marked.');
}
return true;
},

async unmarkFromTreeView(
Expand Down Expand Up @@ -113,6 +126,16 @@ export const markFile = {
return;
}

// Special case: single non-directory file selected
if (uris.length === 1 && !isDirectory(uris[0].fsPath)) {
await this.handleSingleFile(
uris[0].fsPath,
workspacePath,
markedFilesProvider,
);
return;
}

const newFiles = new Set<string>();
const ignoredFiles = new Set<string>();
const unsupportedFiles = new Set<string>();
Expand All @@ -131,7 +154,13 @@ export const markFile = {
return;
}
}
await this.processPath(filePath, newFiles, workspacePath);
await this.processPath(
filePath,
newFiles,
ignoredFiles,
unsupportedFiles,
workspacePath,
);
}),
);

Expand Down Expand Up @@ -175,15 +204,20 @@ export const markFile = {
async processPath(
path: string,
newFiles: Set<string>,
ignoredFiles: Set<string>,
unsupportedFiles: Set<string>,
workspacePath: string,
): Promise<void> {
if (!isDirectory(path)) {
const relPath = getRelativePath(workspacePath, path);
// Only check ignore status for files that are part of bulk operations
if (isIgnored(relPath)) {
return; // Skip warning as it's handled at higher level
ignoredFiles.add(path);
return;
}
if (!this.isFileTypeSupported(path)) {
return; // Skip warning as it's handled at higher level
unsupportedFiles.add(path);
return;
}
if (!markedFiles.has(path)) {
newFiles.add(path);
Expand All @@ -199,10 +233,17 @@ export const markFile = {
const relPath = getRelativePath(workspacePath, filePath);

if (isIgnored(relPath)) {
ignoredFiles.add(filePath);
return;
}

await this.processPath(filePath, newFiles, workspacePath);
await this.processPath(
filePath,
newFiles,
ignoredFiles,
unsupportedFiles,
workspacePath,
);
}),
);
} catch (error) {
Expand Down
32 changes: 30 additions & 2 deletions src/generators/contextGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getExtension,
resolvePath,
getDirname,
getBasename,
} from '../utils/fileUtils';
import { formatFileComment } from '../utils/markdownUtils';
import { estimateTokenCount } from '../utils/tokenUtils';
Expand Down Expand Up @@ -94,12 +95,28 @@ export class ContextGenerator {
};
}

private async handleSingleFile(
filePath: string,
relPath: string,
contextParts: string[],
): Promise<void> {
if (isIgnored(relPath)) {
showMessage.warning(
`Note: "${getBasename(filePath)}" matches patterns in your ignore files but will be included anyway since it was specifically selected.`,
);
}

if (!isDirectory(filePath)) {
await this.processFile(filePath, relPath, contextParts);
}
}

private async processOpenFile(
filePath: string,
contextParts: string[],
): Promise<void> {
const relPath = getRelativePath(this.workspacePath, filePath);
await this.processFile(filePath, relPath, contextParts);
await this.handleSingleFile(filePath, relPath, contextParts);

const content = readFileContent(filePath);
await this.processImports(filePath, content, contextParts);
Expand All @@ -115,6 +132,7 @@ export class ContextGenerator {
const resolvedPath = resolvePath(getDirname(filePath), importPath);
const relPath = getRelativePath(this.workspacePath, resolvedPath);

// For imports, we do respect ignore patterns
if (isIgnored(relPath)) {
continue;
}
Expand Down Expand Up @@ -156,6 +174,7 @@ export class ContextGenerator {
const filePath = resolvePath(dir, file);
const relPath = getRelativePath(this.workspacePath, filePath);

// For workspace-wide scanning, respect ignore patterns
if (isIgnored(relPath)) {
continue;
}
Expand All @@ -172,9 +191,18 @@ export class ContextGenerator {
files: string[],
contextParts: string[],
): Promise<void> {
// Special case for single marked file
if (files.length === 1) {
const filePath = files[0];
const relPath = getRelativePath(this.workspacePath, filePath);
await this.handleSingleFile(filePath, relPath, contextParts);
return;
}

// For multiple files, trust the marking process's decisions
for (const filePath of files) {
const relPath = getRelativePath(this.workspacePath, filePath);
if (!isIgnored(relPath) && !isDirectory(filePath)) {
if (!isDirectory(filePath)) {
await this.processFile(filePath, relPath, contextParts);
}
}
Expand Down

0 comments on commit 38bc115

Please sign in to comment.