浏览代码

move clineignore filewatcher to chokidar (#5676)

celestial-vault 4 月之前
父节点
当前提交
714bcf92cf
共有 1 个文件被更改,包括 39 次插入26 次删除
  1. 39 26
      src/core/ignore/ClineIgnoreController.ts

+ 39 - 26
src/core/ignore/ClineIgnoreController.ts

@@ -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
+		}
 	}
 }