UNPKG

@jupyter-lsp/jupyterlab-lsp

Version:

Language Server Protocol integration for JupyterLab

143 lines 8.72 kB
import { FormComponent } from '@jupyterlab/ui-components'; import validatorAjv8 from '@rjsf/validator-ajv8'; import React, { useState } from 'react'; import { ServerLinksList } from './utils'; export const renderCollapseConflicts = (props) => { const conflicts = Object.entries(props.conflicts).map(([server, serverConflicts]) => { if (Object.keys(serverConflicts).length === 0) { return null; } const listing = Object.entries(serverConflicts).map(([key, values]) => (React.createElement("li", { key: 'lsp-server-setting-conflict-' + key }, React.createElement("code", null, key), ": ", React.createElement("code", null, JSON.stringify(values))))); return (React.createElement("div", { key: 'lsp-server-setting-conflict-' + server }, React.createElement("h4", null, server), React.createElement("ul", null, listing))); }); return (React.createElement("div", null, props.trans.__('Multiple distinct values detected for:'), conflicts, props.trans.__('Retaining the last value for each of the settings. Please remove the additional values in JSON Settings Editor.'))); }; export const renderLanguageServerSettings = (props) => { return React.createElement(LanguageServerSettings, { ...props }); }; export class LanguageServerSettings extends React.Component { constructor(props) { super(props); this.state = { ...props.formData }; this._objectTemplate = TabbedObjectTemplateFactory({ baseTemplate: this.props.registry.templates.ObjectFieldTemplate, objectSelector: props => { return (props.title === this.props.schema.title && props.description === this.props.schema.description); }, trans: this.props.trans, languageServerManager: this.props.languageServerManager }); } render() { this.props.schema.description = undefined; // hide the boilerplate title/description from schema definitions for (const serverSchema of Object.values(this.props.schema.properties)) { // note: have to be strings. serverSchema.title = ''; serverSchema.description = ''; } const validationErrors = this.props.validationErrors.map(error => (React.createElement("li", { key: 'lsp-validation-error-' + error.instancePath }, React.createElement("b", null, error.keyword), ": ", error.message, " in", ' ', React.createElement("code", null, error.instancePath), error.params && 'allowedValues' in error.params ? this.props.trans.__('allowed values: %1', JSON.stringify(error.params.allowedValues)) : null))); const templates = { ...this.props.registry.templates, ObjectFieldTemplate: this._objectTemplate }; // remove self field to avoid infinite recursion const fields = Object.fromEntries(Object.entries(this.props.registry.fields).filter(f => f[0] != 'language_servers')); return (React.createElement("div", { className: "lsp-ServerSettings" }, React.createElement("h3", { className: "lsp-ServerSettings-title" }, this.props.trans.__('Language servers')), validationErrors.length > 0 ? (React.createElement("div", { className: "lsp-ServerSettings-validationError" }, React.createElement("h4", null, this.props.trans.__('Validation of user settings for language server failed')), React.createElement("p", null, this.props.trans.__('Your language server settings do not follow current schema. The LSP configuration graphical interface will run in schema-free mode to enable you to continue using the current settings as-is (in case if the schema is outdated). If this is however an earlier configuration mistake (settings were not validated in earlier versions of jupyterlab-lsp), please correct the following validation errors in JSON Settings Editor, save, and reload application:')), React.createElement("ul", null, validationErrors))) : null, React.createElement(FormComponent, { schema: this.props.schema, formData: this.state, validator: validatorAjv8, // note: default JupyterLab `FieldTemplate` cannot correctly distinguish fields // modified relative to programatically populated (transformed) schema >of objects<; // the issue is in lines: https://github.com/jupyterlab/jupyterlab/blob/c2907074e58725942946a73a823fc60e1795da39/packages/settingeditor/src/SettingsFormEditor.tsx#L254-L272 // this is because 1) the schemaIds does not include the object key // 2) the code assumes all objects on the same have the same defaults // Probably the solution is to perform modification check on the level of ObjectFieldTemplate instead; this should be implemented upstream in JupyterLab. // TODO templates: templates, uiSchema: this.props.uiSchema, fields: fields, formContext: this.props.formContext, liveValidate: true, idPrefix: this.props.idPrefix + '_language_servers', onChange: this._onChange.bind(this) }))); } _onChange(event) { if (event.errors.length) { console.error('Errors in form validation:', event.errors); } this.setState(event.formData, () => this.props.onChange(this.state)); } } /** * Template for tabbed interface. */ const TabbedObjectTemplateFactory = (options) => { const factory = (props) => { if (!options.objectSelector(props)) { const BaseTemplate = options.baseTemplate; return React.createElement(BaseTemplate, { ...props }); } const [tab, setTab] = useState(props.properties.length > 0 ? props.properties[0].name : null); const renderServerLabels = (options) => { const retained = options.properties.filter(property => options.filter(property.name)); if (retained.length == 0) { return null; } return (React.createElement(React.Fragment, null, React.createElement("h4", { className: 'lsp-ServerSettings-list-group' }, options.title), React.createElement("ul", null, retained.map(property => { return (React.createElement("li", { onClick: () => setTab(property.name), key: 'tab-' + property.name, "data-tab": property.name, className: property.name === tab ? 'lsp-selected' : undefined }, property.name)); })))); }; const renderServerMetadata = (spec) => { const workspaceConfig = spec.workspace_configuration; return (React.createElement("div", null, React.createElement("h4", { className: 'lsp-ServerSettings-content-name' }, spec.display_name), React.createElement(ServerLinksList, { specification: spec }), workspaceConfig ? (React.createElement("p", { className: 'lsp-ServerSettings-content-specOverrides' }, trans.__('Default values set programatically for: ') + Object.keys(workspaceConfig).join(', '))) : null)); }; const manager = options.languageServerManager; const trans = options.trans; // TODO: expose `specs` upstream return (React.createElement("fieldset", { id: props.idSchema.$id }, React.createElement("div", { className: 'lsp-ServerSettings-tabs' }, React.createElement("div", { className: 'lsp-ServerSettings-list' }, renderServerLabels({ properties: props.properties, filter: name => manager.sessions.has(name), title: trans.__('Available') }), renderServerLabels({ properties: props.properties, filter: name => !manager.sessions.has(name), title: trans.__('Not installed') })), React.createElement("div", { className: 'lsp-ServerSettings-content' }, manager.specs.has(tab) ? renderServerMetadata(manager.specs.get(tab)) : null, props.properties .filter(property => property.name === tab) .map(property => property.content))))); }; factory.displayName = 'TabbedObjectTemplate'; return factory; }; //# sourceMappingURL=serverSettings.js.map