diff --git a/extensions/html-language-features/server/src/htmlServer.ts b/extensions/html-language-features/server/src/htmlServer.ts
index 29aa041746c..22ab2e18076 100644
--- a/extensions/html-language-features/server/src/htmlServer.ts
+++ b/extensions/html-language-features/server/src/htmlServer.ts
@@ -7,11 +7,12 @@ import {
Connection, TextDocuments, InitializeParams, InitializeResult, RequestType,
DocumentRangeFormattingRequest, Disposable, ServerCapabilities,
ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification,
- DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind, NotificationType, RequestType0, DocumentFormattingRequest, FormattingOptions, TextEdit
+ DocumentColorRequest, ColorPresentationRequest, TextDocumentSyncKind, NotificationType, RequestType0, DocumentFormattingRequest, FormattingOptions, TextEdit,
+ TextDocumentContentRequest
} from 'vscode-languageserver';
import {
getLanguageModes, LanguageModes, Settings, TextDocument, Position, Diagnostic, WorkspaceFolder, ColorInformation,
- Range, DocumentLink, SymbolInformation, TextDocumentIdentifier, isCompletionItemData
+ Range, DocumentLink, SymbolInformation, TextDocumentIdentifier, isCompletionItemData, FILE_PROTOCOL
} from './modes/languageModes';
import { format } from './modes/formatting';
@@ -213,6 +214,9 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
documentSelector: null,
interFileDependencies: false,
workspaceDiagnostics: false
+ },
+ workspace: {
+ textDocumentContent: { schemes: [FILE_PROTOCOL] }
}
};
return { capabilities };
@@ -584,6 +588,18 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
});
});
+ connection.onRequest(TextDocumentContentRequest.type, (params, token) => {
+ return runSafe(runtime, async () => {
+ for (const languageMode of languageModes.getAllModes()) {
+ const content = await languageMode.getTextDocumentContent?.(params.uri);
+ if (content) {
+ return { text: content };
+ }
+ }
+ return null;
+ }, null, `Error while computing text document content for ${params.uri}`, token);
+ });
+
// Listen on the connection
connection.listen();
}
diff --git a/extensions/html-language-features/server/src/modes/javascriptMode.ts b/extensions/html-language-features/server/src/modes/javascriptMode.ts
index d820810c920..aafb54a64b5 100644
--- a/extensions/html-language-features/server/src/modes/javascriptMode.ts
+++ b/extensions/html-language-features/server/src/modes/javascriptMode.ts
@@ -8,7 +8,7 @@ import {
SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation,
Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover,
DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions, FoldingRange, FoldingRangeKind, SelectionRange,
- LanguageMode, Settings, SemanticTokenData, Workspace, DocumentContext, CompletionItemData, isCompletionItemData
+ LanguageMode, Settings, SemanticTokenData, Workspace, DocumentContext, CompletionItemData, isCompletionItemData, FILE_PROTOCOL, DocumentUri
} from './languageModes';
import { getWordAtText, isWhitespaceOnly, repeat } from '../utils/strings';
import { HTMLDocumentRegions } from './embeddedSupport';
@@ -77,18 +77,24 @@ function getLanguageServiceHost(scriptKind: ts.ScriptKind) {
}
};
- return ts.createLanguageService(host);
+ return {
+ service: ts.createLanguageService(host),
+ loadLibrary: libs.loadLibrary,
+ };
});
return {
async getLanguageService(jsDocument: TextDocument): Promise {
currentTextDocument = jsDocument;
- return jsLanguageService;
+ return (await jsLanguageService).service;
},
getCompilationSettings() {
return compilerOptions;
},
+ async loadLibrary(fileName: string) {
+ return (await jsLanguageService).loadLibrary(fileName);
+ },
dispose() {
- jsLanguageService.then(s => s.dispose());
+ jsLanguageService.then(s => s.service.dispose());
}
};
}
@@ -104,6 +110,8 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache d.fileName === jsDocument.uri).map(d => {
- return {
- uri: document.uri,
- range: convertRange(jsDocument, d.textSpan)
- };
- });
+ return (await Promise.all(definition.map(async d => {
+ if (d.fileName === jsDocument.uri) {
+ return {
+ uri: document.uri,
+ range: convertRange(jsDocument, d.textSpan)
+ };
+ } else {
+ const libUri = libParentUri + d.fileName;
+ const content = await host.loadLibrary(d.fileName);
+ if (!content) {
+ return undefined;
+ }
+ const libDocument = TextDocument.create(libUri, languageId, 1, content);
+ return {
+ uri: libUri,
+ range: convertRange(libDocument, d.textSpan)
+ };
+ }
+ }))).filter(d => !!d);
}
return null;
},
@@ -402,6 +423,12 @@ export function getJavaScriptMode(documentRegions: LanguageModelCache {
+ if (documentUri.startsWith(libParentUri)) {
+ return host.loadLibrary(documentUri.substring(libParentUri.length));
+ }
+ return undefined;
+ },
dispose() {
host.dispose();
jsDocuments.dispose();
diff --git a/extensions/html-language-features/server/src/modes/languageModes.ts b/extensions/html-language-features/server/src/modes/languageModes.ts
index 803fa6c1c87..45d0b8fabe7 100644
--- a/extensions/html-language-features/server/src/modes/languageModes.ts
+++ b/extensions/html-language-features/server/src/modes/languageModes.ts
@@ -14,7 +14,7 @@ import {
Color, ColorInformation, ColorPresentation, WorkspaceEdit,
WorkspaceFolder
} from 'vscode-languageserver';
-import { TextDocument } from 'vscode-languageserver-textdocument';
+import { DocumentUri, TextDocument } from 'vscode-languageserver-textdocument';
import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache';
import { getCSSMode } from './cssMode';
@@ -34,7 +34,7 @@ export {
export { ClientCapabilities, DocumentContext, LanguageService, HTMLDocument, HTMLFormatConfiguration, TokenType } from 'vscode-html-languageservice';
-export { TextDocument } from 'vscode-languageserver-textdocument';
+export { TextDocument, DocumentUri } from 'vscode-languageserver-textdocument';
export interface Settings {
readonly css?: any;
@@ -89,6 +89,7 @@ export interface LanguageMode {
onDocumentRemoved(document: TextDocument): void;
getSemanticTokens?(document: TextDocument): Promise;
getSemanticTokenLegend?(): { types: string[]; modifiers: string[] };
+ getTextDocumentContent?(uri: DocumentUri): Promise;
dispose(): void;
}
@@ -108,6 +109,8 @@ export interface LanguageModeRange extends Range {
attributeValue?: boolean;
}
+export const FILE_PROTOCOL = 'html-server';
+
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean }, workspace: Workspace, clientCapabilities: ClientCapabilities, requestService: FileSystemProvider): LanguageModes {
const htmlLanguageService = getHTMLLanguageService({ clientCapabilities, fileSystemProvider: requestService });
const cssLanguageService = getCSSLanguageService({ clientCapabilities, fileSystemProvider: requestService });