diff --git a/src/schema-extension-api.ts b/src/schema-extension-api.ts index 9e795bca..c61d17c7 100644 --- a/src/schema-extension-api.ts +++ b/src/schema-extension-api.ts @@ -1,47 +1,49 @@ import { URI } from 'vscode-uri' import { LanguageClient, RequestType } from 'vscode-languageclient'; +import { workspace } from 'vscode'; interface SchemaContributorProvider { - readonly requestSchema: (resource: string) => string; - readonly requestSchemaContent: (uri: string) => string; + readonly requestSchema: (resource: string) => string; + readonly requestSchemaContent: (uri: string) => string; + readonly label?: string; } export enum MODIFICATION_ACTIONS { - 'delete', - 'add' + 'delete', + 'add' } export interface SchemaAdditions { - schema: string, - action: MODIFICATION_ACTIONS.add, - path: string, - key: string, - content: any + schema: string, + action: MODIFICATION_ACTIONS.add, + path: string, + key: string, + content: any } export interface SchemaDeletions { - schema: string, - action: MODIFICATION_ACTIONS.delete, - path: string, - key: string + schema: string, + action: MODIFICATION_ACTIONS.delete, + path: string, + key: string } namespace SchemaModificationNotification { - export const type: RequestType = new RequestType('json/schema/modify'); + export const type: RequestType = new RequestType('json/schema/modify'); } export interface ExtensionAPI { - registerContributor(schema: string, requestSchema: (resource: string) => string, requestSchemaContent: (uri: string) => string): boolean; - modifySchemaContent(schemaModifications: SchemaAdditions | SchemaDeletions): Promise; + registerContributor(schema: string, requestSchema: (resource: string) => string, requestSchemaContent: (uri: string) => string, label?: string): boolean; + modifySchemaContent(schemaModifications: SchemaAdditions | SchemaDeletions): Promise; } class SchemaExtensionAPI implements ExtensionAPI { - private _customSchemaContributors: { [index: string]: SchemaContributorProvider } = {}; - private _yamlClient: LanguageClient; + private _customSchemaContributors: { [index: string]: SchemaContributorProvider } = {}; + private _yamlClient: LanguageClient; - constructor(client: LanguageClient) { - this._yamlClient = client; - } + constructor(client: LanguageClient) { + this._yamlClient = client; + } /** * Register a custom schema provider @@ -49,26 +51,37 @@ class SchemaExtensionAPI implements ExtensionAPI { * @param {string} the provider's name * @param requestSchema the requestSchema function * @param requestSchemaContent the requestSchemaContent function + * @param label the content label, yaml key value pair, like 'apiVersion:some.api/v1' * @returns {boolean} */ - public registerContributor(schema: string, - requestSchema: (resource: string) => string, - requestSchemaContent: (uri: string) => string): boolean { - if (this._customSchemaContributors[schema]) { - return false; - } - - if (!requestSchema) { - throw new Error("Illegal parameter for requestSchema."); - } - - this._customSchemaContributors[schema] = { - requestSchema, - requestSchemaContent - }; - - return true; - } + public registerContributor(schema: string, + requestSchema: (resource: string) => string, + requestSchemaContent: (uri: string) => string, + label?: string): boolean { + if (this._customSchemaContributors[schema]) { + return false; + } + + if (!requestSchema) { + throw new Error("Illegal parameter for requestSchema."); + } + + if (label) { + let [first, second] = label.split(':'); + if (first && second) { + second = second.trim(); + second = second.replace('.', '\\.'); + label = `${first}:[\t ]+${second}`; + } + } + this._customSchemaContributors[schema] = { + requestSchema, + requestSchemaContent, + label + }; + + return true; + } /** * Call requestSchema for each provider and finds all matches. @@ -77,17 +90,30 @@ class SchemaExtensionAPI implements ExtensionAPI { * @returns {string} the schema uri */ public requestCustomSchema(resource: string): string[] { - const matches = []; - for (let customKey of Object.keys(this._customSchemaContributors)) { - const contributor = this._customSchemaContributors[customKey]; - const uri = contributor.requestSchema(resource); - - if (uri) { - matches.push(uri); - } - } - return matches; - } + const matches = []; + for (let customKey of Object.keys(this._customSchemaContributors)) { + const contributor = this._customSchemaContributors[customKey]; + let uri: string; + if (contributor.label && workspace.textDocuments) { + const labelRegexp = new RegExp(contributor.label, 'g'); + for (const doc of workspace.textDocuments) { + if (doc.uri.toString() === resource) { + if (labelRegexp.test(doc.getText())) { + uri = contributor.requestSchema(resource); + return [uri]; + } + } + } + } + + uri = contributor.requestSchema(resource); + + if (uri) { + matches.push(uri); + } + } + return matches; + } /** * Call requestCustomSchemaContent for named provider and get the schema content. @@ -95,24 +121,24 @@ class SchemaExtensionAPI implements ExtensionAPI { * @param {string} uri the schema uri returned from requestSchema. * @returns {string} the schema content */ - public requestCustomSchemaContent(uri: string): string { - if (uri) { - let _uri = URI.parse(uri); - - if (_uri.scheme && this._customSchemaContributors[_uri.scheme] && - this._customSchemaContributors[_uri.scheme].requestSchemaContent) { - return this._customSchemaContributors[_uri.scheme].requestSchemaContent(uri); - } - } - } - - public async modifySchemaContent(schemaModifications: SchemaAdditions | SchemaDeletions) { - return this._yamlClient.sendRequest(SchemaModificationNotification.type, schemaModifications); - } + public requestCustomSchemaContent(uri: string): string { + if (uri) { + let _uri = URI.parse(uri); + + if (_uri.scheme && this._customSchemaContributors[_uri.scheme] && + this._customSchemaContributors[_uri.scheme].requestSchemaContent) { + return this._customSchemaContributors[_uri.scheme].requestSchemaContent(uri); + } + } + } + + public async modifySchemaContent(schemaModifications: SchemaAdditions | SchemaDeletions) { + return this._yamlClient.sendRequest(SchemaModificationNotification.type, schemaModifications); + } } // constants export const CUSTOM_SCHEMA_REQUEST = 'custom/schema/request'; export const CUSTOM_CONTENT_REQUEST = 'custom/schema/content'; -export { SchemaExtensionAPI }; \ No newline at end of file +export { SchemaExtensionAPI };