diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 136c99776..8e910173b 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -140,7 +140,7 @@ class DiagnosticsProvider extends AbstractSupport { // Go ahead and check for diagnostics in the currently visible editors. for (let editor of vscode.window.visibleTextEditors) { let document = editor.document; - if (document.languageId === 'csharp' && document.uri.scheme === 'file') { + if (document.languageId === 'csharp') { this._validateDocument(document); } } @@ -172,7 +172,7 @@ class DiagnosticsProvider extends AbstractSupport { } private _onDocumentAddOrChange(document: vscode.TextDocument): void { - if (document.languageId === 'csharp' && document.uri.scheme === 'file') { + if (document.languageId === 'csharp') { this._validateDocument(document); this._validateProject(); } diff --git a/src/features/virtualDocumentTracker.ts b/src/features/virtualDocumentTracker.ts new file mode 100644 index 000000000..e91b6ebdb --- /dev/null +++ b/src/features/virtualDocumentTracker.ts @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import {workspace, TextDocument} from 'vscode'; +import {OmniSharpServer} from '../omnisharp/server'; +import * as serverUtils from '../omnisharp/utils'; +import { FileChangeType } from '../omnisharp/protocol'; +import { IDisposable } from '../Disposable'; +import CompositeDisposable from '../CompositeDisposable'; + +function trackCurrentVirtualDocuments(server: OmniSharpServer) { + let registration = server.onProjectAdded(() => { + for (let i = 0; i < workspace.textDocuments.length; i++) { + let document = workspace.textDocuments[i]; + + if (!shouldIgnoreDocument(document, server)) { + openVirtualDocument(document, server); + } + } + + registration.dispose(); + }); +} + +function trackFutureVirtualDocuments(server: OmniSharpServer): IDisposable { + let onTextDocumentOpen = workspace.onDidOpenTextDocument(document => { + if (shouldIgnoreDocument(document, server)) { + return; + } + + openVirtualDocument(document, server); + }); + + let onTextDocumentClose = workspace.onDidCloseTextDocument(document => { + if (shouldIgnoreDocument(document, server)) { + return; + } + + closeVirtualDocument(document, server); + }); + + // We already track text document changes for virtual documents in our change forwarder. + return new CompositeDisposable( + onTextDocumentOpen, + onTextDocumentClose); +} + +function shouldIgnoreDocument(document: TextDocument, server: OmniSharpServer): boolean { + if (document.uri.scheme === 'file' || document.languageId !== 'csharp') { + // We're only interested in non-physical CSharp documents. + return true; + } + + if (!server.isRunning()) { + return true; + } + + return false; +} + +function openVirtualDocument(document: TextDocument, server: OmniSharpServer) { + let req = { FileName: document.uri.path, changeType: FileChangeType.Create }; + serverUtils.filesChanged(server, [req]) + .catch(err => { + console.warn(`[o] failed to forward virtual document change event for ${document.uri.path}`, err); + return err; + }); + + serverUtils.updateBuffer(server, { Buffer: document.getText(), FileName: document.fileName }) + .catch(err => { + console.warn(`[o] failed to forward virtual document change event for ${document.uri.path}`, err); + return err; + }); +} + +function closeVirtualDocument(document: TextDocument, server: OmniSharpServer) { + let req = { FileName: document.uri.path, changeType: FileChangeType.Delete }; + serverUtils.filesChanged(server, [req]).catch(err => { + console.warn(`[o] failed to forward virtual document change event for ${document.uri.path}`, err); + return err; + }); +} + +export default function trackVirtualDocuments(server: OmniSharpServer): IDisposable { + trackCurrentVirtualDocuments(server); + let disposable = trackFutureVirtualDocuments(server); + + return disposable; +} diff --git a/src/omnisharp/extension.ts b/src/omnisharp/extension.ts index d434514c0..7adfa6bb9 100644 --- a/src/omnisharp/extension.ts +++ b/src/omnisharp/extension.ts @@ -34,6 +34,7 @@ import { NetworkSettingsProvider } from '../NetworkSettings'; import CompositeDisposable from '../CompositeDisposable'; import Disposable from '../Disposable'; import OptionProvider from '../observers/OptionProvider'; +import trackVirtualDocuments from '../features/virtualDocumentTracker'; import { StructureProvider } from '../features/structureProvider'; export let omnisharp: OmniSharpServer; @@ -41,7 +42,6 @@ export let omnisharp: OmniSharpServer; export async function activate(context: vscode.ExtensionContext, packageJSON: any, platformInfo: PlatformInformation, provider: NetworkSettingsProvider, eventStream: EventStream, optionProvider: OptionProvider, extensionPath: string) { const documentSelector: vscode.DocumentSelector = { language: 'csharp', - scheme: 'file' // only files from disk }; const options = optionProvider.GetLatestOptions(); @@ -81,6 +81,7 @@ export async function activate(context: vscode.ExtensionContext, packageJSON: an localDisposables.add(vscode.languages.registerCodeActionsProvider(documentSelector, codeActionProvider)); localDisposables.add(reportDiagnostics(server, advisor)); localDisposables.add(forwardChanges(server)); + localDisposables.add(trackVirtualDocuments(server)); localDisposables.add(vscode.languages.registerFoldingRangeProvider(documentSelector, new StructureProvider(server))); }));