Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion packages/language-server/src/ls-config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { merge, get } from 'lodash';
import { get, merge } from 'lodash';
import { UserPreferences } from 'typescript';
import { VSCodeEmmetConfig } from 'vscode-emmet-helper';
import { returnObjectIfHasKeys } from './utils';

/**
* Default config for the language server.
Expand Down Expand Up @@ -340,6 +341,29 @@ export class LSConfigManager {
return this.prettierConfig;
}

/**
* Returns a merged Prettier config following these rules:
* - If `prettierFromFileConfig` exists, that one is returned
* - Else the Svelte extension's Prettier config is used as a starting point,
* and overridden by a possible Prettier config from the Prettier extension,
* or, if that doesn't exist, a possible fallback override.
*/
getMergedPrettierConfig(
prettierFromFileConfig: any,
overridesWhenNoPrettierConfig: any = {}
): any {
return (
returnObjectIfHasKeys(prettierFromFileConfig) ||
merge(
{}, // merge into empty obj to not manipulate own config
this.get('svelte.format.config'),
returnObjectIfHasKeys(this.getPrettierConfig()) ||
overridesWhenNoPrettierConfig ||
{}
)
);
}

updateTsJsUserPreferences(config: Record<TsUserConfigLang, TSUserConfig>): void {
(['typescript', 'javascript'] as const).forEach((lang) => {
if (config[lang]) {
Expand Down
42 changes: 15 additions & 27 deletions packages/language-server/src/plugins/svelte/SveltePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import {
CancellationToken,
CodeAction,
CodeActionContext,
CompletionContext,
CompletionList,
Diagnostic,
FormattingOptions,
Hover,
Position,
Range,
TextEdit,
WorkspaceEdit,
SelectionRange,
CancellationToken,
CompletionContext
TextEdit,
WorkspaceEdit
} from 'vscode-languageserver';
import { getPackageInfo, importPrettier } from '../../importPackage';
import { Document } from '../../lib/documents';
import { Logger } from '../../logger';
import { LSConfigManager, LSSvelteConfig } from '../../ls-config';
import { getPackageInfo, importPrettier } from '../../importPackage';
import {
CodeActionsProvider,
CompletionsProvider,
Expand All @@ -28,10 +29,8 @@ import { executeCommand, getCodeActions } from './features/getCodeActions';
import { getCompletions } from './features/getCompletions';
import { getDiagnostics } from './features/getDiagnostics';
import { getHoverInfo } from './features/getHoverInfo';
import { SvelteCompileResult, SvelteDocument } from './SvelteDocument';
import { Logger } from '../../logger';
import { getSelectionRange } from './features/getSelectionRanges';
import { merge } from 'lodash';
import { SvelteCompileResult, SvelteDocument } from './SvelteDocument';

export class SveltePlugin
implements
Expand Down Expand Up @@ -75,19 +74,14 @@ export class SveltePlugin
const filePath = document.getFilePath()!;
const prettier = importPrettier(filePath);
// Try resolving the config through prettier and fall back to possible editor config
const config =
returnObjectIfHasKeys(await prettier.resolveConfig(filePath, { editorconfig: true })) ||
merge(
{}, // merge into empty obj to not manipulate own config
this.configManager.get('svelte.format.config'),
returnObjectIfHasKeys(this.configManager.getPrettierConfig()) ||
// Be defensive here because IDEs other than VSCode might not have these settings
(options && {
tabWidth: options.tabSize,
useTabs: !options.insertSpaces
}) ||
{}
);
const config = this.configManager.getMergedPrettierConfig(
await prettier.resolveConfig(filePath, { editorconfig: true }),
// Be defensive here because IDEs other than VSCode might not have these settings
options && {
tabWidth: options.tabSize,
useTabs: !options.insertSpaces
}
);
// If user has prettier-plugin-svelte 1.x, then remove `options` from the sort
// order or else it will throw a config error (`options` was not present back then).
if (
Expand Down Expand Up @@ -137,12 +131,6 @@ export class SveltePlugin
.languages.some((l) => l.name === 'svelte');
return hasPluginLoadedAlready ? [] : [require.resolve('prettier-plugin-svelte')];
}

function returnObjectIfHasKeys<T>(obj: T | undefined): T | undefined {
if (Object.keys(obj || {}).length > 0) {
return obj;
}
}
}

async getCompletions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ export class TypeScriptPlugin
this.completionProvider = new CompletionsProviderImpl(this.lsAndTsDocResolver);
this.codeActionsProvider = new CodeActionsProviderImpl(
this.lsAndTsDocResolver,
this.completionProvider
this.completionProvider,
configManager
);
this.updateImportsProvider = new UpdateImportsProviderImpl(this.lsAndTsDocResolver);
this.diagnosticsProvider = new DiagnosticsProviderImpl(this.lsAndTsDocResolver);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import {
TextEdit,
WorkspaceEdit
} from 'vscode-languageserver';
import { importPrettier } from '../../../importPackage';
import {
Document,
getLineAtPosition,
isAtEndOfLine,
isRangeInTag,
mapRangeToOriginal
} from '../../../lib/documents';
import { LSConfigManager } from '../../../ls-config';
import { flatten, getIndent, isNotNullOrUndefined, modifyLines, pathToUrl } from '../../../utils';
import { CodeActionsProvider } from '../../interfaces';
import { SnapshotFragment, SvelteSnapshotFragment } from '../DocumentSnapshot';
Expand All @@ -35,7 +37,8 @@ interface RefactorArgs {
export class CodeActionsProviderImpl implements CodeActionsProvider {
constructor(
private readonly lsAndTsDocResolver: LSAndTSDocResolver,
private readonly completionProvider: CompletionsProviderImpl
private readonly completionProvider: CompletionsProviderImpl,
private readonly configManager: LSConfigManager
) {}

async getCodeActions(
Expand Down Expand Up @@ -77,12 +80,25 @@ export class CodeActionsProviderImpl implements CodeActionsProvider {
return [];
}

const useSemicolons =
this.configManager.getMergedPrettierConfig(
await importPrettier(document.getFilePath()!).resolveConfig(
document.getFilePath()!,
{
editorconfig: true
}
)
).semi ?? true;
const changes = lang.organizeImports(
{
fileName: tsDoc.filePath,
type: 'file'
},
{},
{
semicolons: useSemicolons
? ts.SemicolonPreference.Insert
: ts.SemicolonPreference.Remove
},
userPreferences
);

Expand Down
13 changes: 11 additions & 2 deletions packages/language-server/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { URI } from 'vscode-uri';
import { Position, Range } from 'vscode-languageserver';
import { Node } from 'vscode-html-languageservice';
import { Position, Range } from 'vscode-languageserver';
import { URI } from 'vscode-uri';

export function clamp(num: number, min: number, max: number): number {
return Math.max(min, Math.min(max, num));
Expand Down Expand Up @@ -240,3 +240,12 @@ export function getIndent(text: string) {
export function possiblyComponent(node: Node): boolean {
return !!node.tag?.[0].match(/[A-Z]/);
}

/**
* If the object if it has entries, else undefined
*/
export function returnObjectIfHasKeys<T>(obj: T | undefined): T | undefined {
if (Object.keys(obj || {}).length > 0) {
return obj;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { DocumentManager, Document } from '../../../../src/lib/documents';
import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver';
import { CodeActionsProviderImpl } from '../../../../src/plugins/typescript/features/CodeActionsProvider';
import { pathToUrl } from '../../../../src/utils';
import ts from 'typescript';
import * as path from 'path';
import * as assert from 'assert';
import * as path from 'path';
import ts from 'typescript';
import {
Range,
Position,
CodeActionKind,
TextDocumentEdit,
CancellationTokenSource,
CodeAction,
CancellationTokenSource
CodeActionKind,
Position,
Range,
TextDocumentEdit
} from 'vscode-languageserver';
import { CompletionsProviderImpl } from '../../../../src/plugins/typescript/features/CompletionProvider';
import { Document, DocumentManager } from '../../../../src/lib/documents';
import { LSConfigManager } from '../../../../src/ls-config';
import { CodeActionsProviderImpl } from '../../../../src/plugins/typescript/features/CodeActionsProvider';
import { CompletionsProviderImpl } from '../../../../src/plugins/typescript/features/CompletionProvider';
import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver';
import { pathToUrl } from '../../../../src/utils';

const testDir = path.join(__dirname, '..');

Expand All @@ -41,7 +41,11 @@ describe('CodeActionsProvider', () => {
new LSConfigManager()
);
const completionProvider = new CompletionsProviderImpl(lsAndTsDocResolver);
const provider = new CodeActionsProviderImpl(lsAndTsDocResolver, completionProvider);
const provider = new CodeActionsProviderImpl(
lsAndTsDocResolver,
completionProvider,
new LSConfigManager()
);
const filePath = getFullPath(filename);
const document = docManager.openDocument(<any>{
uri: pathToUrl(filePath),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ts from 'typescript';
import assert from 'assert';
import { join } from 'path';

import ts from 'typescript';
import {
CodeActionContext,
Diagnostic,
Expand All @@ -11,11 +10,11 @@ import {
TextDocumentEdit
} from 'vscode-languageserver';
import { Document, DocumentManager } from '../../../../src/lib/documents';
import { LSConfigManager, TSUserConfig } from '../../../../src/ls-config';
import { CodeActionsProviderImpl } from '../../../../src/plugins/typescript/features/CodeActionsProvider';
import { CompletionsProviderImpl } from '../../../../src/plugins/typescript/features/CompletionProvider';
import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver';
import { pathToUrl } from '../../../../src/utils';
import { CodeActionsProviderImpl } from '../../../../src/plugins/typescript/features/CodeActionsProvider';
import { LSConfigManager, TSUserConfig } from '../../../../src/ls-config';

const testFilesDir = join(__dirname, '..', 'testfiles', 'preferences');

Expand Down Expand Up @@ -88,7 +87,8 @@ describe('ts user preferences', () => {
const completionProvider = new CompletionsProviderImpl(lsAndTsDocResolver);
const codeActionProvider = new CodeActionsProviderImpl(
lsAndTsDocResolver,
completionProvider
completionProvider,
new LSConfigManager()
);

const codeAction = await codeActionProvider.getCodeActions(document, range, context);
Expand Down Expand Up @@ -188,7 +188,8 @@ describe('ts user preferences', () => {
const completionProvider = new CompletionsProviderImpl(lsAndTsDocResolver);
const codeActionProvider = new CodeActionsProviderImpl(
lsAndTsDocResolver,
completionProvider
completionProvider,
new LSConfigManager()
);

const codeAction = await codeActionProvider.getCodeActions(document, range, {
Expand Down