load formatOptons by document uri

Closes #81
This commit is contained in:
chemzqm 2019-11-23 13:31:43 +08:00
parent d48cc4a312
commit f59086837e
3 changed files with 33 additions and 26 deletions

View file

@ -232,8 +232,9 @@
}, },
"typescript.preferences.quoteStyle": { "typescript.preferences.quoteStyle": {
"type": "string", "type": "string",
"default": "single", "default": "auto",
"enum": [ "enum": [
"auto",
"single", "single",
"double" "double"
] ]
@ -354,8 +355,9 @@
}, },
"javascript.preferences.quoteStyle": { "javascript.preferences.quoteStyle": {
"type": "string", "type": "string",
"default": "single", "default": "auto",
"enum": [ "enum": [
"auto",
"single", "single",
"double" "double"
] ]

View file

@ -2,12 +2,11 @@
* Copyright (c) Microsoft Corporation. All rights reserved. * Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { TextDocument, CancellationToken } from 'vscode-languageserver-protocol' import { workspace, WorkspaceConfiguration } from 'coc.nvim'
import { WorkspaceConfiguration, workspace } from 'coc.nvim' import { CancellationToken, TextDocument } from 'vscode-languageserver-protocol'
import Proto from '../protocol' import Proto from '../protocol'
import { ITypeScriptServiceClient } from '../typescriptService' import { ITypeScriptServiceClient } from '../typescriptService'
import API from '../utils/api' import API from '../utils/api'
import * as languageIds from '../utils/languageModeIds'
function objAreEqual<T>(a: T, b: T): boolean { function objAreEqual<T>(a: T, b: T): boolean {
let keys = Object.keys(a) let keys = Object.keys(a)
@ -39,34 +38,36 @@ export interface SuggestOptions {
} }
export default class FileConfigurationManager { export default class FileConfigurationManager {
private cachedOption = null private cachedOption: FileConfiguration = null
private requesting = false private requesting = false
public constructor(private readonly client: ITypeScriptServiceClient) { public constructor(private readonly client: ITypeScriptServiceClient) {
} }
public async ensureConfigurationOptions(languageId: string, insertSpaces: boolean, tabSize: number): Promise<void> { public async ensureConfigurationOptions(document: TextDocument, insertSpaces: boolean, tabSize: number): Promise<void> {
let { requesting } = this let { requesting } = this
let options: FormatOptions = { let options: FormatOptions = {
tabSize, tabSize,
insertSpaces insertSpaces
} }
if (requesting || (this.cachedOption && objAreEqual(this.cachedOption, options))) return const currentOptions = this.getFileOptions(options, document)
const currentOptions = this.getFileOptions(options, languageId) if (requesting || (this.cachedOption
&& objAreEqual(this.cachedOption.formatOptions, currentOptions.formatOptions)
&& objAreEqual(this.cachedOption.preferences, currentOptions.preferences))) return
this.requesting = true this.requesting = true
const args = { const args = {
hostInfo: 'nvim-coc', hostInfo: 'nvim-coc',
...currentOptions ...currentOptions
} as Proto.ConfigureRequestArguments } as Proto.ConfigureRequestArguments
await this.client.execute('configure', args, CancellationToken.None) await this.client.execute('configure', args, CancellationToken.None)
this.cachedOption = options this.cachedOption = currentOptions
this.requesting = false this.requesting = false
} }
public async ensureConfigurationForDocument(document: TextDocument): Promise<void> { public async ensureConfigurationForDocument(document: TextDocument): Promise<void> {
let opts = await workspace.getFormatOptions(document.uri) let opts = await workspace.getFormatOptions(document.uri)
if (!this.client.bufferSyncSupport.has(document.uri)) return if (!this.client.bufferSyncSupport.has(document.uri)) return
return this.ensureConfigurationOptions(document.languageId, opts.insertSpaces, opts.tabSize) return this.ensureConfigurationOptions(document, opts.insertSpaces, opts.tabSize)
} }
public reset(): void { public reset(): void {
@ -78,8 +79,7 @@ export default class FileConfigurationManager {
} }
public isTypeScriptDocument(languageId: string): boolean { public isTypeScriptDocument(languageId: string): boolean {
return languageId === languageIds.typescript || languageId === languageIds.typescriptreact || return languageId.startsWith('typescript')
languageId === languageIds.typescripttsx || languageId === languageIds.typescriptjsx
} }
public enableJavascript(): boolean { public enableJavascript(): boolean {
@ -87,16 +87,16 @@ export default class FileConfigurationManager {
return !!config.get<boolean>('enableJavascript') return !!config.get<boolean>('enableJavascript')
} }
private getFileOptions(options: FormatOptions, languageId: string): FileConfiguration { private getFileOptions(options: FormatOptions, document: TextDocument): FileConfiguration {
const lang = this.isTypeScriptDocument(languageId) ? 'typescript' : 'javascript' const lang = this.isTypeScriptDocument(document.languageId) ? 'typescript' : 'javascript'
return { return {
formatOptions: this.getFormatOptions(options, lang), formatOptions: this.getFormatOptions(options, lang, document.uri),
preferences: this.getPreferences(lang) preferences: this.getPreferences(lang, document.uri)
} }
} }
private getFormatOptions(options: FormatOptions, language: string): Proto.FormatCodeSettings { private getFormatOptions(options: FormatOptions, language: string, uri: string): Proto.FormatCodeSettings {
const config = workspace.getConfiguration(`${language}.format`) const config = workspace.getConfiguration(`${language}.format`, uri)
return { return {
tabSize: options.tabSize, tabSize: options.tabSize,
@ -134,21 +134,26 @@ export default class FileConfigurationManager {
} }
} }
public getPreferences(language: string): Proto.UserPreferences { public getPreferences(language: string, uri: string): Proto.UserPreferences {
if (!this.client.apiVersion.gte(API.v290)) { if (this.client.apiVersion.lt(API.v290)) {
return {} return {}
} }
const config = workspace.getConfiguration(`${language}`) const config = workspace.getConfiguration(language, uri)
const defaultQuote = this.client.apiVersion.gte(API.v333) ? 'auto' : undefined
return { return {
disableSuggestions: !config.get<boolean>('suggest.enabled', true), disableSuggestions: !config.get<boolean>('suggest.enabled', true),
importModuleSpecifierPreference: getImportModuleSpecifier(config) as any, importModuleSpecifierPreference: getImportModuleSpecifier(config) as any,
quotePreference: config.get<'single' | 'double' | 'auto'>('preferences.quoteStyle', defaultQuote), quotePreference: this.getQuoteStyle(config),
allowRenameOfImportPath: true, allowRenameOfImportPath: true,
allowTextChangesInNewFiles: true, allowTextChangesInNewFiles: true,
providePrefixAndSuffixTextForRename: true, providePrefixAndSuffixTextForRename: true,
} }
} }
private getQuoteStyle(config: WorkspaceConfiguration): 'auto' | 'double' | 'single' {
let quoteStyle = config.get<'single' | 'double' | 'auto'>('preferences.quoteStyle', 'auto')
if (this.client.apiVersion.gte(API.v333) || quoteStyle != 'auto') return quoteStyle
return 'single'
}
} }
type ModuleImportType = 'relative' | 'non-relative' | 'auto' type ModuleImportType = 'relative' | 'non-relative' | 'auto'

View file

@ -27,7 +27,7 @@ export default class TypeScriptFormattingProvider
token?: CancellationToken token?: CancellationToken
): Promise<TextEdit[]> { ): Promise<TextEdit[]> {
await this.formattingOptionsManager.ensureConfigurationOptions( await this.formattingOptionsManager.ensureConfigurationOptions(
document.languageId, document,
options.insertSpaces, options.insertSpaces,
options.tabSize options.tabSize
) )
@ -94,7 +94,7 @@ export default class TypeScriptFormattingProvider
} }
await this.formattingOptionsManager.ensureConfigurationOptions( await this.formattingOptionsManager.ensureConfigurationOptions(
document.languageId, document,
options.insertSpaces, options.insertSpaces,
options.tabSize options.tabSize
) )