1
0
Эх сурвалжийг харах

Add `DiagnosticsOptions.onlyVisible` to limit computing diagnostics to only the visible text models

Alex Dima 4 жил өмнө
parent
commit
22e7676a8c

+ 5 - 0
monaco.d.ts

@@ -143,6 +143,11 @@ declare namespace monaco.languages.typescript {
 		noSemanticValidation?: boolean;
 		noSyntaxValidation?: boolean;
 		noSuggestionDiagnostics?: boolean;
+		/**
+		 * Limit diagnostic computation to only visible files.
+		 * Defaults to false.
+		 */
+		onlyVisible?: boolean;
 		diagnosticCodesToIgnore?: number[];
 	}
 	export interface WorkerOptions {

+ 43 - 7
src/languageFeatures.ts

@@ -163,6 +163,15 @@ enum DiagnosticCategory {
 	Message = 3
 }
 
+/**
+ * temporary interface until the editor API exposes
+ * `IModel.isAttachedToEditor` and `IModel.onDidChangeAttached`
+ */
+interface IInternalEditorModel extends editor.IModel {
+	onDidChangeAttached(listener: () => void): IDisposable;
+	isAttachedToEditor(): boolean;
+}
+
 export class DiagnosticsAdapter extends Adapter {
 	private _disposables: IDisposable[] = [];
 	private _listener: { [uri: string]: IDisposable } = Object.create(null);
@@ -175,25 +184,52 @@ export class DiagnosticsAdapter extends Adapter {
 	) {
 		super(worker);
 
-		const onModelAdd = (model: editor.IModel): void => {
+		const onModelAdd = (model: IInternalEditorModel): void => {
 			if (model.getModeId() !== _selector) {
 				return;
 			}
 
+			const maybeValidate = () => {
+				const { onlyVisible } = this._defaults.getDiagnosticsOptions();
+				if (onlyVisible) {
+					if (model.isAttachedToEditor()) {
+						this._doValidate(model);
+					}
+				} else {
+					this._doValidate(model);
+				}
+			};
+
 			let handle: number;
 			const changeSubscription = model.onDidChangeContent(() => {
 				clearTimeout(handle);
-				handle = setTimeout(() => this._doValidate(model), 500);
+				handle = setTimeout(maybeValidate, 500);
+			});
+
+			const visibleSubscription = model.onDidChangeAttached(() => {
+				const { onlyVisible } = this._defaults.getDiagnosticsOptions();
+				if (onlyVisible) {
+					if (model.isAttachedToEditor()) {
+						// this model is now attached to an editor
+						// => compute diagnostics
+						maybeValidate();
+					} else {
+						// this model is no longer attached to an editor
+						// => clear existing diagnostics
+						editor.setModelMarkers(model, this._selector, []);
+					}
+				}
 			});
 
 			this._listener[model.uri.toString()] = {
 				dispose() {
 					changeSubscription.dispose();
+					visibleSubscription.dispose();
 					clearTimeout(handle);
 				}
 			};
 
-			this._doValidate(model);
+			maybeValidate();
 		};
 
 		const onModelRemoved = (model: editor.IModel): void => {
@@ -205,12 +241,12 @@ export class DiagnosticsAdapter extends Adapter {
 			}
 		};
 
-		this._disposables.push(editor.onDidCreateModel(onModelAdd));
+		this._disposables.push(editor.onDidCreateModel((model) => onModelAdd(<IInternalEditorModel>model)));
 		this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
 		this._disposables.push(
 			editor.onDidChangeModelLanguage((event) => {
 				onModelRemoved(event.model);
-				onModelAdd(event.model);
+				onModelAdd(<IInternalEditorModel>event.model);
 			})
 		);
 
@@ -226,13 +262,13 @@ export class DiagnosticsAdapter extends Adapter {
 			// redo diagnostics when options change
 			for (const model of editor.getModels()) {
 				onModelRemoved(model);
-				onModelAdd(model);
+				onModelAdd(<IInternalEditorModel>model);
 			}
 		};
 		this._disposables.push(this._defaults.onDidChange(recomputeDiagostics));
 		this._disposables.push(this._defaults.onDidExtraLibsChange(recomputeDiagostics));
 
-		editor.getModels().forEach(onModelAdd);
+		editor.getModels().forEach((model) => onModelAdd(<IInternalEditorModel>model));
 	}
 
 	public dispose(): void {

+ 3 - 2
src/monaco.contribution.ts

@@ -156,6 +156,7 @@ export interface DiagnosticsOptions {
 	noSemanticValidation?: boolean;
 	noSyntaxValidation?: boolean;
 	noSuggestionDiagnostics?: boolean;
+	onlyVisible?: boolean;
 	diagnosticCodesToIgnore?: number[];
 }
 
@@ -616,13 +617,13 @@ export const typescriptVersion: string = tsversion;
 
 export const typescriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
 	{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
-	{ noSemanticValidation: false, noSyntaxValidation: false },
+	{ noSemanticValidation: false, noSyntaxValidation: false, onlyVisible: false },
 	{}
 );
 
 export const javascriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
 	{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
-	{ noSemanticValidation: true, noSyntaxValidation: false },
+	{ noSemanticValidation: true, noSyntaxValidation: false, onlyVisible: false },
 	{}
 );