|
|
@@ -1,8 +1,8 @@
|
|
|
import { fileExistsAtPath } from "@utils/fs"
|
|
|
+import chokidar, { FSWatcher } from "chokidar"
|
|
|
import fs from "fs/promises"
|
|
|
import ignore, { Ignore } from "ignore"
|
|
|
import path from "path"
|
|
|
-import * as vscode from "vscode"
|
|
|
|
|
|
export const LOCK_TEXT_SYMBOL = "\u{1F512}"
|
|
|
|
|
|
@@ -14,22 +14,22 @@ export const LOCK_TEXT_SYMBOL = "\u{1F512}"
|
|
|
export class ClineIgnoreController {
|
|
|
private cwd: string
|
|
|
private ignoreInstance: Ignore
|
|
|
- private disposables: vscode.Disposable[] = []
|
|
|
+ private fileWatcher?: FSWatcher
|
|
|
clineIgnoreContent: string | undefined
|
|
|
|
|
|
constructor(cwd: string) {
|
|
|
this.cwd = cwd
|
|
|
this.ignoreInstance = ignore()
|
|
|
this.clineIgnoreContent = undefined
|
|
|
- // Set up file watcher for .clineignore
|
|
|
- this.setupFileWatcher()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Initialize the controller by loading custom patterns
|
|
|
+ * Initialize the controller by loading custom patterns and setting up file watcher
|
|
|
* Must be called after construction and before using the controller
|
|
|
*/
|
|
|
async initialize(): Promise<void> {
|
|
|
+ // Set up file watcher for .clineignore
|
|
|
+ this.setupFileWatcher()
|
|
|
await this.loadClineIgnore()
|
|
|
}
|
|
|
|
|
|
@@ -37,24 +37,35 @@ export class ClineIgnoreController {
|
|
|
* Set up the file watcher for .clineignore changes
|
|
|
*/
|
|
|
private setupFileWatcher(): void {
|
|
|
- const clineignorePattern = new vscode.RelativePattern(this.cwd, ".clineignore")
|
|
|
- const fileWatcher = vscode.workspace.createFileSystemWatcher(clineignorePattern)
|
|
|
-
|
|
|
- // Watch for changes and updates
|
|
|
- this.disposables.push(
|
|
|
- fileWatcher.onDidChange(() => {
|
|
|
- this.loadClineIgnore()
|
|
|
- }),
|
|
|
- fileWatcher.onDidCreate(() => {
|
|
|
- this.loadClineIgnore()
|
|
|
- }),
|
|
|
- fileWatcher.onDidDelete(() => {
|
|
|
- this.loadClineIgnore()
|
|
|
- }),
|
|
|
- )
|
|
|
-
|
|
|
- // Add fileWatcher itself to disposables
|
|
|
- this.disposables.push(fileWatcher)
|
|
|
+ const ignorePath = path.join(this.cwd, ".clineignore")
|
|
|
+
|
|
|
+ this.fileWatcher = chokidar.watch(ignorePath, {
|
|
|
+ persistent: true, // Keep the process running as long as files are being watched
|
|
|
+ ignoreInitial: true, // Don't fire 'add' events when discovering the file initially
|
|
|
+ awaitWriteFinish: {
|
|
|
+ // Wait for writes to finish before emitting events (handles chunked writes)
|
|
|
+ stabilityThreshold: 100, // Wait 100ms for file size to remain constant
|
|
|
+ pollInterval: 100, // Check file size every 100ms while waiting for stability
|
|
|
+ },
|
|
|
+ atomic: true, // Handle atomic writes where editors write to a temp file then rename
|
|
|
+ })
|
|
|
+
|
|
|
+ // Watch for file changes, creation, and deletion
|
|
|
+ this.fileWatcher.on("change", () => {
|
|
|
+ this.loadClineIgnore()
|
|
|
+ })
|
|
|
+
|
|
|
+ this.fileWatcher.on("add", () => {
|
|
|
+ this.loadClineIgnore()
|
|
|
+ })
|
|
|
+
|
|
|
+ this.fileWatcher.on("unlink", () => {
|
|
|
+ this.loadClineIgnore()
|
|
|
+ })
|
|
|
+
|
|
|
+ this.fileWatcher.on("error", (error) => {
|
|
|
+ console.error("Error watching .clineignore file:", error)
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -238,8 +249,10 @@ export class ClineIgnoreController {
|
|
|
/**
|
|
|
* Clean up resources when the controller is no longer needed
|
|
|
*/
|
|
|
- dispose(): void {
|
|
|
- this.disposables.forEach((d) => d.dispose())
|
|
|
- this.disposables = []
|
|
|
+ async dispose(): Promise<void> {
|
|
|
+ if (this.fileWatcher) {
|
|
|
+ await this.fileWatcher.close()
|
|
|
+ this.fileWatcher = undefined
|
|
|
+ }
|
|
|
}
|
|
|
}
|