DidChangeWatchedFiles 通知

当客户端检测到语言客户端监视的文件和文件夹的更改时,此通知将从客户端发送到服务器(注意,尽管名称表明仅发送文件事件,但它与文件系统事件有关,其中也包括文件夹)。建议服务器使用注册机制注册这些文件系统事件。在以前的实现中,客户端在没有服务器主动请求的情况下推送文件事件。

允许服务器运行自己的文件系统监视机制,而不依赖客户端提供文件系统事件。但是,由于以下原因,不建议这样做:

  • 根据我们的经验,在磁盘上正确监视文件系统是具有挑战性的,特别是如果它需要跨多个操作系统支持。

  • 文件系统监视不是免费的,特别是如果实现使用某种轮询并将文件系统树保留在内存中以比较时间戳(例如,某些节点模块这样做)

  • 一个客户端通常会启动多个服务器。如果每个服务器都运行自己的文件系统,监视它可能会成为 CPU 或内存问题。

  • 通常,服务器实现多于客户端实现。所以这个问题最好在客户端解决。

客户端能力(Client capability):

  • 属性路径: workspace.didChangeWatchedFiles
  • 属性类型: DidChangeWatchedFilesClientCapabilities, 定义如下:
export interface DidChangeWatchedFilesClientCapabilities {
	/**
	 * Did change watched files notification supports dynamic registration.
	 * Please note that the current protocol doesn't support static
	 * configuration for file changes from the server side.
	 */
	dynamicRegistration?: boolean;

	/**
	 * Whether the client has support for relative patterns
	 * or not.
	 *
	 * @since 3.17.0
	 */
	relativePatternSupport?: boolean;
}

注册选项(Registration Options): DidChangeWatchedFilesRegistrationOptions, 定义如下:

/**
 * Describe options to be used when registering for file system change events.
 */
export interface DidChangeWatchedFilesRegistrationOptions {
	/**
	 * The watchers to register.
	 */
	watchers: FileSystemWatcher[];
}
/**
 * The glob pattern to watch relative to the base path. Glob patterns can have
 * the following syntax:
 * - `*` to match one or more characters in a path segment
 * - `?` to match on one character in a path segment
 * - `**` to match any number of path segments, including none
 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript
 *   and JavaScript files)
 * - `[]` to declare a range of characters to match in a path segment
 *   (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
 * - `[!...]` to negate a range of characters to match in a path segment
 *   (e.g., `example.[!0-9]` to match on `example.a`, `example.b`,
 *   but not `example.0`)
 *
 * @since 3.17.0
 */
export type Pattern = string;
/**
 * A relative pattern is a helper to construct glob patterns that are matched
 * relatively to a base URI. The common value for a `baseUri` is a workspace
 * folder root, but it can be another absolute URI as well.
 *
 * @since 3.17.0
 */
export interface RelativePattern {
	/**
	 * A workspace folder or a base URI to which this pattern will be matched
	 * against relatively.
	 */
	baseUri: WorkspaceFolder | URI;

	/**
	 * The actual glob pattern;
	 */
	pattern: Pattern;
}
/**
 * The glob pattern. Either a string pattern or a relative pattern.
 *
 * @since 3.17.0
 */
export type GlobPattern = Pattern | RelativePattern;
export interface FileSystemWatcher {
	/**
	 * The glob pattern to watch. See {@link GlobPattern glob pattern}
	 * for more detail.
	 *
 	 * @since 3.17.0 support for relative patterns.
	 */
	globPattern: GlobPattern;

	/**
	 * The kind of events of interest. If omitted it defaults
	 * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
	 * which is 7.
	 */
	kind?: WatchKind;
}
export namespace WatchKind {
	/**
	 * Interested in create events.
	 */
	export const Create = 1;

	/**
	 * Interested in change events
	 */
	export const Change = 2;

	/**
	 * Interested in delete events
	 */
	export const Delete = 4;
}
export type WatchKind = uinteger;

通知(Notification):

  • method: "workspace/didChangeWatchedFiles"
  • params: DidChangeWatchedFilesParams, 定义如下:
interface DidChangeWatchedFilesParams {
	/**
	 * The actual file events.
	 */
	changes: FileEvent[];
}
/**
 * An event describing a file change.
 */
interface FileEvent {
	/**
	 * The file's URI.
	 */
	uri: DocumentUri;
	/**
	 * The change type.
	 */
	type: FileChangeType;
}
/**
 * The file event type.
 */
export namespace FileChangeType {
	/**
	 * The file got created.
	 */
	export const Created = 1;
	/**
	 * The file got changed.
	 */
	export const Changed = 2;
	/**
	 * The file got deleted.
	 */
	export const Deleted = 3;
}

export type FileChangeType = 1 | 2 | 3;