mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Fix JSON schema configuration in multi root workspaces (#173169)
[json] add folderUri to SchemaAssociation and schema setting
This commit is contained in:
parent
262ab0e7bf
commit
bd9ac7a089
|
@ -70,6 +70,7 @@ export type JSONSchemaSettings = {
|
|||
fileMatch?: string[];
|
||||
url?: string;
|
||||
schema?: any;
|
||||
folderUri?: string;
|
||||
};
|
||||
|
||||
export namespace SettingIds {
|
||||
|
@ -472,6 +473,8 @@ function getSettings(): Settings {
|
|||
jsonFoldingLimit = normalizeLimit(workspace.getConfiguration(SettingIds.editorSection, { languageId: 'json' }).get(SettingIds.foldingMaximumRegions));
|
||||
jsoncFoldingLimit = normalizeLimit(workspace.getConfiguration(SettingIds.editorSection, { languageId: 'jsonc' }).get(SettingIds.foldingMaximumRegions));
|
||||
|
||||
const schemas: JSONSchemaSettings[] = [];
|
||||
|
||||
const settings: Settings = {
|
||||
http: {
|
||||
proxy: httpSettings.get('proxy'),
|
||||
|
@ -481,85 +484,34 @@ function getSettings(): Settings {
|
|||
validate: { enable: configuration.get(SettingIds.enableValidation) },
|
||||
format: { enable: configuration.get(SettingIds.enableFormatter) },
|
||||
keepLines: { enable: configuration.get(SettingIds.enableKeepLines) },
|
||||
schemas: [],
|
||||
schemas,
|
||||
resultLimit: resultLimit + 1, // ask for one more so we can detect if the limit has been exceeded
|
||||
jsonFoldingLimit: jsonFoldingLimit + 1,
|
||||
jsoncFoldingLimit: jsoncFoldingLimit + 1
|
||||
}
|
||||
};
|
||||
const schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null);
|
||||
const collectSchemaSettings = (schemaSettings: JSONSchemaSettings[], folderUri?: Uri, isMultiRoot?: boolean) => {
|
||||
|
||||
let fileMatchPrefix = undefined;
|
||||
if (folderUri && isMultiRoot) {
|
||||
fileMatchPrefix = folderUri.toString();
|
||||
if (fileMatchPrefix[fileMatchPrefix.length - 1] === '/') {
|
||||
fileMatchPrefix = fileMatchPrefix.substr(0, fileMatchPrefix.length - 1);
|
||||
}
|
||||
}
|
||||
const collectSchemaSettings = (schemaSettings: JSONSchemaSettings[], folderUri?: Uri) => {
|
||||
for (const setting of schemaSettings) {
|
||||
const url = getSchemaId(setting, folderUri);
|
||||
if (!url) {
|
||||
continue;
|
||||
}
|
||||
let schemaSetting = schemaSettingsById[url];
|
||||
if (!schemaSetting) {
|
||||
schemaSetting = schemaSettingsById[url] = { url, fileMatch: [] };
|
||||
settings.json!.schemas!.push(schemaSetting);
|
||||
}
|
||||
const fileMatches = setting.fileMatch;
|
||||
if (Array.isArray(fileMatches)) {
|
||||
const resultingFileMatches = schemaSetting.fileMatch || [];
|
||||
schemaSetting.fileMatch = resultingFileMatches;
|
||||
const addMatch = (pattern: string) => { // filter duplicates
|
||||
if (resultingFileMatches.indexOf(pattern) === -1) {
|
||||
resultingFileMatches.push(pattern);
|
||||
}
|
||||
};
|
||||
for (const fileMatch of fileMatches) {
|
||||
if (fileMatchPrefix) {
|
||||
if (fileMatch[0] === '/') {
|
||||
addMatch(fileMatchPrefix + fileMatch);
|
||||
addMatch(fileMatchPrefix + '/*' + fileMatch);
|
||||
} else {
|
||||
addMatch(fileMatchPrefix + '/' + fileMatch);
|
||||
addMatch(fileMatchPrefix + '/*/' + fileMatch);
|
||||
}
|
||||
} else {
|
||||
addMatch(fileMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (setting.schema && !schemaSetting.schema) {
|
||||
schemaSetting.schema = setting.schema;
|
||||
if (url) {
|
||||
const schemaSetting: JSONSchemaSettings = { url, fileMatch: setting.fileMatch, folderUri: folderUri?.toString(false), schema: setting.schema };
|
||||
schemas.push(schemaSetting);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const folders = workspace.workspaceFolders;
|
||||
|
||||
// merge global and folder settings. Qualify all file matches with the folder path.
|
||||
const globalSettings = workspace.getConfiguration('json', null).get<JSONSchemaSettings[]>('schemas');
|
||||
if (Array.isArray(globalSettings)) {
|
||||
if (!folders) {
|
||||
collectSchemaSettings(globalSettings);
|
||||
}
|
||||
collectSchemaSettings(globalSettings);
|
||||
}
|
||||
const folders = workspace.workspaceFolders;
|
||||
if (folders) {
|
||||
const isMultiRoot = folders.length > 1;
|
||||
for (const folder of folders) {
|
||||
const folderUri = folder.uri;
|
||||
|
||||
const schemaConfigInfo = workspace.getConfiguration('json', folderUri).inspect<JSONSchemaSettings[]>('schemas');
|
||||
|
||||
const folderSchemas = schemaConfigInfo!.workspaceFolderValue;
|
||||
if (Array.isArray(folderSchemas)) {
|
||||
collectSchemaSettings(folderSchemas, folderUri, isMultiRoot);
|
||||
const schemaConfigInfo = workspace.getConfiguration('json', folder.uri).inspect<JSONSchemaSettings[]>('schemas');
|
||||
if (schemaConfigInfo && Array.isArray(schemaConfigInfo.workspaceFolderValue)) {
|
||||
collectSchemaSettings(schemaConfigInfo.workspaceFolderValue, folder.uri);
|
||||
}
|
||||
if (Array.isArray(globalSettings)) {
|
||||
collectSchemaSettings(globalSettings, folderUri, isMultiRoot);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
|
@ -572,7 +524,7 @@ function getSchemaId(schema: JSONSchemaSettings, folderUri?: Uri): string | unde
|
|||
url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`;
|
||||
}
|
||||
} else if (folderUri && (url[0] === '.' || url[0] === '/')) {
|
||||
url = Uri.joinPath(folderUri, url).toString();
|
||||
url = Uri.joinPath(folderUri, url).toString(false);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,8 @@ The server supports the following settings:
|
|||
- `schemas`: Configures association of file names to schema URL or schemas and/or associations of schema URL to schema content.
|
||||
- `fileMatch`: an array of file names or paths (separated by `/`). `*` can be used as a wildcard. Exclusion patterns can also be defined and start with '!'. A file matches when there is at least one matching pattern and the last matching pattern is not an exclusion pattern.
|
||||
- `url`: The URL of the schema, optional when also a schema is provided.
|
||||
- `schema`: The schema content.
|
||||
- `schema`: The schema content, optional
|
||||
- `folderUri`: If provided, the association is only used if the document is located in the given folder (directly or indirectly)
|
||||
- `resultLimit`: The max number of color decorators and outline symbols to be computed (for performance reasons)
|
||||
- `jsonFoldingLimit`: The max number of folding ranges to be computed for json documents (for performance reasons)
|
||||
- `jsoncFoldingLimit`: The max number of folding ranges to be computed for jsonc documents (for performance reasons)
|
||||
|
@ -170,6 +171,10 @@ interface ISchemaAssociation {
|
|||
* A match succeeds when there is at least one pattern matching and last matching pattern does not start with '!'.
|
||||
*/
|
||||
fileMatch: string[];
|
||||
/**
|
||||
* If provided, the association is only used if the validated document is located in the given folder (directly or indirectly)
|
||||
*/
|
||||
folderUri?: string;
|
||||
/*
|
||||
* The schema for the given URI.
|
||||
* If no schema is provided, the schema will be fetched with the schema request service (if available).
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
},
|
||||
"main": "./out/node/jsonServerMain",
|
||||
"dependencies": {
|
||||
"@vscode/l10n": "^0.0.11",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"request-light": "^0.7.0",
|
||||
"vscode-json-languageservice": "^5.1.4",
|
||||
"vscode-json-languageservice": "^5.2.0",
|
||||
"vscode-languageserver": "^8.1.0-next.6",
|
||||
"vscode-uri": "^3.0.7",
|
||||
"@vscode/l10n": "^0.0.11"
|
||||
"vscode-uri": "^3.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^9.1.1",
|
||||
|
|
|
@ -201,6 +201,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
|||
fileMatch?: string[];
|
||||
url?: string;
|
||||
schema?: JSONSchema;
|
||||
folderUri?: string;
|
||||
}
|
||||
|
||||
|
||||
|
@ -313,7 +314,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
|||
uri = schema.schema.id || `vscode://schemas/custom/${index}`;
|
||||
}
|
||||
if (uri) {
|
||||
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema });
|
||||
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema, folderUri: schema.folderUri });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ request-light@^0.7.0:
|
|||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a"
|
||||
integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==
|
||||
|
||||
vscode-json-languageservice@^5.1.4:
|
||||
version "5.1.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.1.4.tgz#cbdb447f281dcd107705e7fe8fbfc0b71db7610d"
|
||||
integrity sha512-ROZ1ezYQUbq9b/07xYpHtZSyyhoUk3oTTGVAEr6bU1DKr8ELaz9fsDoHno34tKtHj/Tf3deQqfjQNGKdbRuvTw==
|
||||
vscode-json-languageservice@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.2.0.tgz#884b7f108be4310e3332167c3ea60ab17f03418c"
|
||||
integrity sha512-q8Rdhu2HEddRxvlhVqwh0cWmKK+OtyMB2xRhtqXEQ7cjb0iZ14madb90iJe9fCHPjoj9CGBrq6QzuOp8OE6XWg==
|
||||
dependencies:
|
||||
"@vscode/l10n" "^0.0.11"
|
||||
jsonc-parser "^3.2.0"
|
||||
|
|
Loading…
Reference in a new issue