[html] Follow Link in Multi Root Workspace. Fixes #38469

This commit is contained in:
Martin Aeschlimann 2017-11-20 13:36:45 +01:00
parent e1eeccd55c
commit ce11eb88b3
3 changed files with 60 additions and 5 deletions

View file

@ -12,7 +12,6 @@ import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
import { activateTagClosing } from './tagClosing';
import TelemetryReporter from 'vscode-extension-telemetry';
import { ConfigurationFeature } from 'vscode-languageclient/lib/configuration.proposed';
import { DocumentColorRequest, DocumentColorParams, ColorPresentationRequest, ColorPresentationParams } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
import * as nls from 'vscode-nls';
@ -65,7 +64,7 @@ export function activate(context: ExtensionContext) {
// Create the language client and start the client.
let client = new LanguageClient('html', localize('htmlserver.name', 'HTML Language Server'), serverOptions, clientOptions);
client.registerFeature(new ConfigurationFeature(client));
client.registerProposedFeatures();
let disposable = client.start();
toDispose.push(disposable);

View file

@ -11,9 +11,11 @@ import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes
import { ConfigurationRequest, ConfigurationParams } from 'vscode-languageserver-protocol/lib/protocol.configuration.proposed';
import { DocumentColorRequest, ServerCapabilities as CPServerCapabilities, ColorInformation, ColorPresentationRequest } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
import { DidChangeWorkspaceFoldersNotification, WorkspaceFolder } from 'vscode-languageserver-protocol/lib/protocol.workspaceFolders.proposed';
import { format } from './modes/formatting';
import { pushAll } from './utils/arrays';
import { endsWith, startsWith } from './utils/strings';
import * as url from 'url';
import * as path from 'path';
@ -40,11 +42,14 @@ let documents: TextDocuments = new TextDocuments();
documents.listen(connection);
let workspacePath: string | undefined | null;
let workspaceFolders: WorkspaceFolder[] | undefined;
var languageModes: LanguageModes;
let clientSnippetSupport = false;
let clientDynamicRegisterSupport = false;
let scopedSettingsSupport = false;
let workspaceFoldersSupport = false;
var globalSettings: Settings = {};
let documentSettings: { [key: string]: Thenable<Settings> } = {};
@ -73,6 +78,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
let initializationOptions = params.initializationOptions;
workspacePath = params.rootPath;
workspaceFolders = (<any>params).workspaceFolders;
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true });
documents.onDidClose(e => {
@ -93,6 +99,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
clientSnippetSupport = hasClientCapability('textDocument', 'completion', 'completionItem', 'snippetSupport');
clientDynamicRegisterSupport = hasClientCapability('workspace', 'symbol', 'dynamicRegistration');
scopedSettingsSupport = hasClientCapability('workspace', 'configuration');
workspaceFoldersSupport = hasClientCapability('workspace', 'workspaceFolders');
let capabilities: ServerCapabilities & CPServerCapabilities = {
// Tell the client that the server works in FULL text document sync mode
textDocumentSync: documents.syncKind,
@ -107,10 +114,29 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
referencesProvider: true,
colorProvider: true
};
return { capabilities };
});
connection.onInitialized((p) => {
if (workspaceFoldersSupport) {
connection.client.register(DidChangeWorkspaceFoldersNotification.type);
connection.onNotification(DidChangeWorkspaceFoldersNotification.type, e => {
let toAdd = e.event.added;
let toRemove = e.event.removed;
let updatedFolders = [];
if (workspaceFolders) {
for (let folder of workspaceFolders) {
if (!toRemove.some(r => r.uri === folder.uri) && !toAdd.some(r => r.uri === folder.uri)) {
updatedFolders.push(folder);
}
}
}
workspaceFolders = updatedFolders.concat(toAdd);
});
}
});
let formatterRegistration: Thenable<Disposable> | null = null;
// The settings have changed. Is send on server activation as well.
@ -284,8 +310,11 @@ connection.onDocumentLinks(documentLinkParam => {
if (base) {
ref = url.resolve(base, ref);
}
if (workspacePath && ref[0] === '/') {
return uri.file(path.join(workspacePath, ref)).toString();
if (ref[0] === '/') {
let root = getRootFolder(document.uri);
if (root) {
return uri.file(path.join(root, ref)).toString();
}
}
return url.resolve(document.uri, ref);
},
@ -300,6 +329,22 @@ connection.onDocumentLinks(documentLinkParam => {
return links;
});
function getRootFolder(docUri: string): string | undefined | null {
if (workspaceFolders) {
for (let folder of workspaceFolders) {
let folderURI = folder.uri;
if (!endsWith(folderURI, '/')) {
folderURI = folderURI + '/';
}
if (startsWith(docUri, folderURI)) {
return folderURI;
}
}
return void 0;
}
return workspacePath;
}
connection.onDocumentSymbol(documentSymbolParms => {
let document = documents.get(documentSymbolParms.textDocument.uri);
let symbols: SymbolInformation[] = [];

View file

@ -41,6 +41,17 @@ export function startsWith(haystack: string, needle: string): boolean {
return true;
}
export function endsWith(haystack: string, needle: string): boolean {
let diff = haystack.length - needle.length;
if (diff > 0) {
return haystack.indexOf(needle, diff) === diff;
} else if (diff === 0) {
return haystack === needle;
} else {
return false;
}
}
export function repeat(value: string, count: number) {
var s = '';
while (count > 0) {