Skip to content

Commit d0aba11

Browse files
committed
feat(editor): support oxc.fmt.configPath configuration
1 parent be35392 commit d0aba11

File tree

7 files changed

+59
-1
lines changed

7 files changed

+59
-1
lines changed

editors/vscode/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Following configuration are supported via `settings.json` and can be changed for
6666
| `oxc.typeAware` | `false` | `false` \| `true` | Enable type aware linting. |
6767
| `oxc.flags` | - | `Record<string, string>` | Custom flags passed to the language server. |
6868
| `oxc.fmt.experimental` | `false` | `false` \| `true` | Enable experimental formatting support. This feature is experimental and might not work as expected. |
69+
| `oxc.fmt.configPath` | `null` | `<string>` \| `null` | Path to a oxfmt configuration file, when `null` is passed, the server will use `.oxfmtrc.json` and the workspace root |
6970

7071
#### Flags
7172

editors/vscode/client/WorkspaceConfig.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ export interface WorkspaceConfigInterface {
6969
* @default false
7070
*/
7171
['fmt.experimental']: boolean;
72+
73+
/**
74+
* Path to a oxfmt configuration file
75+
* `oxc.fmt.configPath`
76+
*/
77+
['fmt.configPath']?: string | null;
7278
}
7379

7480
export class WorkspaceConfig {
@@ -79,6 +85,7 @@ export class WorkspaceConfig {
7985
private _typeAware: boolean = false;
8086
private _flags: Record<string, string> = {};
8187
private _formattingExperimental: boolean = false;
88+
private _formattingConfigPath: string | null = null;
8289

8390
constructor(private readonly workspace: WorkspaceFolder) {
8491
this.refresh();
@@ -101,6 +108,7 @@ export class WorkspaceConfig {
101108
this._typeAware = this.configuration.get<boolean>('typeAware') ?? false;
102109
this._flags = flags;
103110
this._formattingExperimental = this.configuration.get<boolean>('fmt.experimental') ?? false;
111+
this._formattingConfigPath = this.configuration.get<string | null>('fmt.configPath') ?? null;
104112
}
105113

106114
public effectsConfigChange(event: ConfigurationChangeEvent): boolean {
@@ -125,6 +133,9 @@ export class WorkspaceConfig {
125133
if (event.affectsConfiguration(`${ConfigService.namespace}.fmt.experimental`, this.workspace)) {
126134
return true;
127135
}
136+
if (event.affectsConfiguration(`${ConfigService.namespace}.fmt.configPath`, this.workspace)) {
137+
return true;
138+
}
128139
return false;
129140
}
130141

@@ -195,6 +206,15 @@ export class WorkspaceConfig {
195206
return this.configuration.update('fmt.experimental', value, ConfigurationTarget.WorkspaceFolder);
196207
}
197208

209+
get formattingConfigPath(): string | null {
210+
return this._formattingConfigPath;
211+
}
212+
213+
updateFormattingConfigPath(value: string | null): PromiseLike<void> {
214+
this._formattingConfigPath = value;
215+
return this.configuration.update('fmt.configPath', value, ConfigurationTarget.WorkspaceFolder);
216+
}
217+
198218
public toLanguageServerConfig(): WorkspaceConfigInterface {
199219
return {
200220
run: this.runTrigger,
@@ -204,6 +224,7 @@ export class WorkspaceConfig {
204224
typeAware: this.typeAware,
205225
flags: this.flags,
206226
['fmt.experimental']: this.formattingExperimental,
227+
['fmt.configPath']: this.formattingConfigPath ?? null,
207228
};
208229
}
209230
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"semicolons": "as-needed"
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
class X { foo() { return 42; } }

editors/vscode/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@
158158
"scope": "resource",
159159
"default": false,
160160
"description": "Enable experimental formatting support. This feature is experimental and might not work as expected."
161+
},
162+
"oxc.fmt.configPath": {
163+
"type": [
164+
"string",
165+
"null"
166+
],
167+
"scope": "resource",
168+
"default": null,
169+
"description": "Path to a oxfmt configuration file"
161170
}
162171
}
163172
},

editors/vscode/tests/WorkspaceConfig.spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ConfigurationTarget, workspace } from 'vscode';
33
import { WorkspaceConfig } from '../client/WorkspaceConfig.js';
44
import { WORKSPACE_FOLDER } from './test-helpers.js';
55

6-
const keys = ['lint.run', 'configPath', 'tsConfigPath', 'flags', 'unusedDisableDirectives', 'typeAware', 'fmt.experimental'];
6+
const keys = ['lint.run', 'configPath', 'tsConfigPath', 'flags', 'unusedDisableDirectives', 'typeAware', 'fmt.experimental', 'fmt.configPath'];
77

88
suite('WorkspaceConfig', () => {
99
setup(async () => {
@@ -36,6 +36,7 @@ suite('WorkspaceConfig', () => {
3636
strictEqual(config.typeAware, false);
3737
deepStrictEqual(config.flags, {});
3838
strictEqual(config.formattingExperimental, false);
39+
strictEqual(config.formattingConfigPath, null);
3940
});
4041

4142
test('configPath defaults to null when using nested configs and configPath is empty', async () => {
@@ -71,6 +72,7 @@ suite('WorkspaceConfig', () => {
7172
config.updateTypeAware(true),
7273
config.updateFlags({ test: 'value' }),
7374
config.updateFormattingExperimental(true),
75+
config.updateFormattingConfigPath('./oxfmt.json'),
7476
]);
7577

7678
const wsConfig = workspace.getConfiguration('oxc', WORKSPACE_FOLDER);
@@ -82,5 +84,6 @@ suite('WorkspaceConfig', () => {
8284
strictEqual(wsConfig.get('typeAware'), true);
8385
deepStrictEqual(wsConfig.get('flags'), { test: 'value' });
8486
strictEqual(wsConfig.get('fmt.experimental'), true);
87+
strictEqual(wsConfig.get('fmt.configPath'), './oxfmt.json');
8588
});
8689
});

editors/vscode/tests/e2e_server.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ teardown(async () => {
3636
await workspace.getConfiguration('oxc').update('tsConfigPath', undefined);
3737
await workspace.getConfiguration('oxc').update('typeAware', undefined);
3838
await workspace.getConfiguration('oxc').update('fmt.experimental', undefined);
39+
await workspace.getConfiguration('oxc').update('fmt.configPath', undefined);
3940
await workspace.getConfiguration('editor').update('defaultFormatter', undefined);
4041
await workspace.saveAll();
4142
});
@@ -288,4 +289,23 @@ suite('E2E Diagnostics', () => {
288289

289290
strictEqual(content.toString(), "class X {\n foo() {\n return 42;\n }\n}\n");
290291
});
292+
293+
test('formats code with `oxc.fmt.configPath`', async () => {
294+
await loadFixture('formatting_with_config');
295+
296+
await workspace.getConfiguration('oxc').update('fmt.experimental', true);
297+
await workspace.getConfiguration('oxc').update('fmt.configPath', './fixtures/formatter.json');
298+
await workspace.getConfiguration('editor').update('defaultFormatter', 'oxc.oxc-vscode');
299+
300+
await sleep(500); // wait for the server to pick up the new config
301+
const fileUri = Uri.joinPath(fixturesWorkspaceUri(), 'fixtures', 'formatting.ts');
302+
303+
const document = await workspace.openTextDocument(fileUri);
304+
await window.showTextDocument(document);
305+
await commands.executeCommand('editor.action.formatDocument');
306+
await workspace.saveAll();
307+
const content = await workspace.fs.readFile(fileUri);
308+
309+
strictEqual(content.toString(), "class X {\n foo() {\n return 42\n }\n}\n");
310+
});
291311
});

0 commit comments

Comments
 (0)