feat: allow control over displaying hidden/dotfiles and .gitignore matches (#179)

* feat: add chat setting to toggle hidden files (dotfiles)

* feat: add toggle to show/hide gitignored files in file browser

* refactor: don't reuse visibility setting for dotfiles toggle

* fix: honor hidden/gitignored toggles across runtimes

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
syntext
2026-01-20 15:20:17 +02:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent 6544b12e78
commit 2de0d9d3dd
19 changed files with 639 additions and 157 deletions
+24 -6
View File
@@ -15,14 +15,25 @@ interface FileSearchStoreState {
cache: Record<string, FileSearchCacheEntry>;
cacheKeys: string[];
inFlight: Record<string, Promise<ProjectFileSearchHit[]>>;
searchFiles: (directory: string, query: string, limit?: number) => Promise<ProjectFileSearchHit[]>;
searchFiles: (
directory: string,
query: string,
limit?: number,
options?: { includeHidden?: boolean; respectGitignore?: boolean }
) => Promise<ProjectFileSearchHit[]>;
invalidateDirectory: (directory?: string | null) => void;
}
const buildCacheKey = (directory: string, query: string, limit: number) => {
const buildCacheKey = (
directory: string,
query: string,
limit: number,
includeHidden: boolean,
respectGitignore: boolean
) => {
const normalizedDirectory = directory.trim();
const normalizedQuery = query.trim().toLowerCase();
return `${normalizedDirectory}::${normalizedQuery}::${limit}`;
return `${normalizedDirectory}::${normalizedQuery}::${limit}::${includeHidden ? '1' : '0'}::${respectGitignore ? '1' : '0'}`;
};
export const useFileSearchStore = create<FileSearchStoreState>()(
@@ -31,14 +42,16 @@ export const useFileSearchStore = create<FileSearchStoreState>()(
cache: {},
cacheKeys: [],
inFlight: {},
async searchFiles(directory, query, limit = DEFAULT_SEARCH_LIMIT) {
async searchFiles(directory, query, limit = DEFAULT_SEARCH_LIMIT, options) {
if (!directory || directory.trim().length === 0) {
return [];
}
const normalizedDirectory = directory.trim();
const normalizedQuery = typeof query === 'string' ? query.trim() : '';
const key = buildCacheKey(normalizedDirectory, normalizedQuery, limit);
const includeHidden = Boolean(options?.includeHidden);
const respectGitignore = options?.respectGitignore ?? true;
const key = buildCacheKey(normalizedDirectory, normalizedQuery, limit, includeHidden, respectGitignore);
const now = Date.now();
const cached = get().cache[key];
@@ -52,7 +65,12 @@ export const useFileSearchStore = create<FileSearchStoreState>()(
}
const searchPromise = opencodeClient
.searchFiles(normalizedQuery, { directory: normalizedDirectory, limit })
.searchFiles(normalizedQuery, {
directory: normalizedDirectory,
limit,
includeHidden,
respectGitignore,
})
.then((files) => {
set((state) => {
const nextCache = { ...state.cache, [key]: { files, timestamp: Date.now() } };