UNPKG

typescript-language-server

Version:

Language Server Protocol (LSP) implementation for TypeScript using tsserver

125 lines 5.36 kB
import deepmerge from 'deepmerge'; import path from 'node:path'; import API from './utils/api.js'; const DEFAULT_TSSERVER_PREFERENCES = { allowIncompleteCompletions: true, allowRenameOfImportPath: true, allowTextChangesInNewFiles: true, autoImportFileExcludePatterns: [], disableSuggestions: false, displayPartsForJSDoc: true, generateReturnInDocTemplate: true, importModuleSpecifierEnding: 'auto', importModuleSpecifierPreference: 'shortest', includeAutomaticOptionalChainCompletions: true, includeCompletionsForImportStatements: true, includeCompletionsForModuleExports: true, includeCompletionsWithClassMemberSnippets: true, includeCompletionsWithInsertText: true, includeCompletionsWithObjectLiteralMethodSnippets: true, includeCompletionsWithSnippetText: true, includeInlayEnumMemberValueHints: false, includeInlayFunctionLikeReturnTypeHints: false, includeInlayFunctionParameterTypeHints: false, includeInlayParameterNameHints: 'none', includeInlayParameterNameHintsWhenArgumentMatchesName: false, includeInlayPropertyDeclarationTypeHints: false, includeInlayVariableTypeHints: false, includeInlayVariableTypeHintsWhenTypeMatchesName: false, includePackageJsonAutoImports: 'auto', jsxAttributeCompletionStyle: 'auto', lazyConfiguredProjectsFromExternalProject: false, providePrefixAndSuffixTextForRename: true, provideRefactorNotApplicableReason: true, quotePreference: 'auto', useLabelDetailsInCompletionEntries: true, }; export class ConfigurationManager { constructor(documents) { this.documents = documents; this.tsPreferences = deepmerge({}, DEFAULT_TSSERVER_PREFERENCES); this.workspaceConfiguration = {}; this.tspClient = null; } mergeTsPreferences(preferences) { this.tsPreferences = deepmerge(this.tsPreferences, preferences); } setWorkspaceConfiguration(configuration) { this.workspaceConfiguration = configuration; } async setAndConfigureTspClient(workspaceFolder, client, hostInfo) { this.tspClient = client; const formatOptions = { // We can use \n here since the editor should normalize later on to its line endings. newLineCharacter: '\n', }; const args = { ...hostInfo ? { hostInfo } : {}, formatOptions, preferences: { ...this.tsPreferences, autoImportFileExcludePatterns: this.getAutoImportFileExcludePatternsPreference(workspaceFolder), }, }; await this.tspClient?.request("configure" /* CommandTypes.Configure */, args); } async configureGloballyFromDocument(filename, formattingOptions) { const args = { formatOptions: this.getFormattingOptions(filename, formattingOptions), preferences: this.getPreferences(filename), }; await this.tspClient?.request("configure" /* CommandTypes.Configure */, args); } getPreferences(filename) { if (this.tspClient?.apiVersion.lt(API.v290)) { return {}; } const workspacePreferences = this.getWorkspacePreferencesForFile(filename); const preferences = Object.assign({}, this.tsPreferences, workspacePreferences?.inlayHints || {}); return { ...preferences, quotePreference: this.getQuoteStylePreference(preferences), }; } getFormattingOptions(filename, formattingOptions) { const workspacePreferences = this.getWorkspacePreferencesForFile(filename); const opts = { ...workspacePreferences?.format, ...formattingOptions, }; if (opts.convertTabsToSpaces === undefined) { opts.convertTabsToSpaces = formattingOptions?.insertSpaces; } if (opts.indentSize === undefined) { opts.indentSize = formattingOptions?.tabSize; } return opts; } getQuoteStylePreference(preferences) { switch (preferences.quotePreference) { case 'single': return 'single'; case 'double': return 'double'; default: return this.tspClient?.apiVersion.gte(API.v333) ? 'auto' : undefined; } } getWorkspacePreferencesForFile(filename) { const document = this.documents.get(filename); const languageId = document?.languageId.startsWith('typescript') ? 'typescript' : 'javascript'; return this.workspaceConfiguration[languageId] || {}; } getAutoImportFileExcludePatternsPreference(workspaceFolder) { if (!workspaceFolder || this.tsPreferences.autoImportFileExcludePatterns.length === 0) { return; } return this.tsPreferences.autoImportFileExcludePatterns.map(p => { // Normalization rules: https://github.com/microsoft/TypeScript/pull/49578 const slashNormalized = p.replace(/\\/g, '/'); const isRelative = /^\.\.?($|\/)/.test(slashNormalized); return path.posix.isAbsolute(p) ? p : p.startsWith('*') ? '/' + slashNormalized : isRelative ? path.posix.join(workspaceFolder, p) : '/**/' + slashNormalized; }); } } //# sourceMappingURL=configuration-manager.js.map