Skip to content

Commit 55c2e11

Browse files
committed
feat(editor): add oxc.fmt.experimental flag (#13923)
Support the new server option `fmt.experimental` with an own VSCode option `oxc.fmt.experimental`. This option can be set for each Workspace individually. Added a Test to check if changing the settings, will tell the server and then the file can be formatted.
1 parent a21ff54 commit 55c2e11

File tree

6 files changed

+71
-1
lines changed

6 files changed

+71
-1
lines changed

editors/vscode/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ This is the linter for Oxc. The currently supported features are listed below.
2121
to automatically apply fixes when saving the file.
2222
- Support for multi root workspaces
2323

24+
## Oxfmt
25+
26+
This is the formatter for Oxc. The currently supported features are listed below.
27+
28+
- Experimental formatting with `oxc.fmt.experimental`
29+
30+
To enable it, use a VSCode `settings.json` like:
31+
32+
```json
33+
{
34+
"oxc.fmt.experimental": true,
35+
"editor.defaultFormatter": "oxc.oxc-vscode"
36+
// Or enable it for specific files:
37+
// "[javascript]": {
38+
// "editor.defaultFormatter": "oxc.oxc-vscode"
39+
// },
40+
}
41+
```
42+
2443
## Configuration
2544

2645
### Window Configuration
@@ -46,6 +65,7 @@ Following configuration are supported via `settings.json` and can be changed for
4665
| `oxc.unusedDisableDirectives` | `allow` | `allow` \| `warn` \| `deny` | Define how directive comments like `// oxlint-disable-line` should be reported, when no errors would have been reported on that line anyway. |
4766
| `oxc.typeAware` | `false` | `false` \| `true` | Enable type aware linting. |
4867
| `oxc.flags` | - | `Record<string, string>` | Custom flags passed to the language server. |
68+
| `oxc.fmt.experimental` | `false` | `false` \| `true` | Enable experimental formatting support. This feature is experimental and might not work as expected. |
4969

5070
#### Flags
5171

editors/vscode/client/WorkspaceConfig.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ export interface WorkspaceConfigInterface {
6161
* @default {}
6262
*/
6363
flags: Record<string, string>;
64+
65+
/**
66+
* Enable formatting experiment
67+
* `oxc.fmt.experimental`
68+
*
69+
* @default false
70+
*/
71+
['fmt.experimental']: boolean;
6472
}
6573

6674
export class WorkspaceConfig {
@@ -70,6 +78,7 @@ export class WorkspaceConfig {
7078
private _unusedDisableDirectives: UnusedDisableDirectives = 'allow';
7179
private _typeAware: boolean = false;
7280
private _flags: Record<string, string> = {};
81+
private _formattingExperimental: boolean = false;
7382

7483
constructor(private readonly workspace: WorkspaceFolder) {
7584
this.refresh();
@@ -91,6 +100,7 @@ export class WorkspaceConfig {
91100
'allow';
92101
this._typeAware = this.configuration.get<boolean>('typeAware') ?? false;
93102
this._flags = flags;
103+
this._formattingExperimental = this.configuration.get<boolean>('fmt.experimental') ?? false;
94104
}
95105

96106
public effectsConfigChange(event: ConfigurationChangeEvent): boolean {
@@ -112,6 +122,9 @@ export class WorkspaceConfig {
112122
if (event.affectsConfiguration(`${ConfigService.namespace}.flags`, this.workspace)) {
113123
return true;
114124
}
125+
if (event.affectsConfiguration(`${ConfigService.namespace}.fmt.experimental`, this.workspace)) {
126+
return true;
127+
}
115128
return false;
116129
}
117130

@@ -173,6 +186,15 @@ export class WorkspaceConfig {
173186
return this.configuration.update('flags', value, ConfigurationTarget.WorkspaceFolder);
174187
}
175188

189+
get formattingExperimental(): boolean {
190+
return this._formattingExperimental;
191+
}
192+
193+
updateFormattingExperimental(value: boolean): PromiseLike<void> {
194+
this._formattingExperimental = value;
195+
return this.configuration.update('fmt.experimental', value, ConfigurationTarget.WorkspaceFolder);
196+
}
197+
176198
public toLanguageServerConfig(): WorkspaceConfigInterface {
177199
return {
178200
run: this.runTrigger,
@@ -181,6 +203,7 @@ export class WorkspaceConfig {
181203
unusedDisableDirectives: this.unusedDisableDirectives,
182204
typeAware: this.typeAware,
183205
flags: this.flags,
206+
['fmt.experimental']: this.formattingExperimental,
184207
};
185208
}
186209
}
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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@
152152
"scope": "resource",
153153
"default": {},
154154
"description": "Specific Oxlint flags to pass to the language server."
155+
},
156+
"oxc.fmt.experimental": {
157+
"type": "boolean",
158+
"scope": "resource",
159+
"default": false,
160+
"description": "Enable experimental formatting support. This feature is experimental and might not work as expected."
155161
}
156162
}
157163
},

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'];
6+
const keys = ['lint.run', 'configPath', 'tsConfigPath', 'flags', 'unusedDisableDirectives', 'typeAware', 'fmt.experimental'];
77

88
suite('WorkspaceConfig', () => {
99
setup(async () => {
@@ -35,6 +35,7 @@ suite('WorkspaceConfig', () => {
3535
strictEqual(config.unusedDisableDirectives, 'allow');
3636
strictEqual(config.typeAware, false);
3737
deepStrictEqual(config.flags, {});
38+
strictEqual(config.formattingExperimental, false);
3839
});
3940

4041
test('configPath defaults to null when using nested configs and configPath is empty', async () => {
@@ -69,6 +70,7 @@ suite('WorkspaceConfig', () => {
6970
config.updateUnusedDisableDirectives('deny'),
7071
config.updateTypeAware(true),
7172
config.updateFlags({ test: 'value' }),
73+
config.updateFormattingExperimental(true),
7274
]);
7375

7476
const wsConfig = workspace.getConfiguration('oxc', WORKSPACE_FOLDER);
@@ -79,5 +81,6 @@ suite('WorkspaceConfig', () => {
7981
strictEqual(wsConfig.get('unusedDisableDirectives'), 'deny');
8082
strictEqual(wsConfig.get('typeAware'), true);
8183
deepStrictEqual(wsConfig.get('flags'), { test: 'value' });
84+
strictEqual(wsConfig.get('fmt.experimental'), true);
8285
});
8386
});

editors/vscode/tests/e2e_server.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ teardown(async () => {
3535
await workspace.getConfiguration('oxc').update('flags', undefined);
3636
await workspace.getConfiguration('oxc').update('tsConfigPath', undefined);
3737
await workspace.getConfiguration('oxc').update('typeAware', undefined);
38+
await workspace.getConfiguration('oxc').update('fmt.experimental', undefined);
39+
await workspace.getConfiguration('editor').update('defaultFormatter', undefined);
3840
await workspace.saveAll();
3941
});
4042

@@ -321,4 +323,19 @@ suite('E2E Diagnostics', () => {
321323
strictEqual(diagnostics[0].range.end.line, 1);
322324
strictEqual(diagnostics[0].range.end.character, 30);
323325
});
326+
327+
test('formats code with `oxc.fmt.experimental`', async () => {
328+
await workspace.getConfiguration('oxc').update('fmt.experimental', true);
329+
await workspace.getConfiguration('editor').update('defaultFormatter', 'oxc.oxc-vscode');
330+
await loadFixture('formatting');
331+
const fileUri = Uri.joinPath(fixturesWorkspaceUri(), 'fixtures', 'formatting.ts');
332+
333+
const document = await workspace.openTextDocument(fileUri);
334+
await window.showTextDocument(document);
335+
await commands.executeCommand('editor.action.formatDocument');
336+
await workspace.saveAll();
337+
const content = await workspace.fs.readFile(fileUri);
338+
339+
strictEqual(content.toString(), "class X {\n foo() {\n return 42;\n }\n}\n");
340+
});
324341
});

0 commit comments

Comments
 (0)