-
-
Notifications
You must be signed in to change notification settings - Fork 477
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(editor/vscode)!: unify configuration logic (#6630)
> Closes https://github.com/oxc-project/backlog/issues/132 Unify configuration logic into `ConfigService`. This allows for type-checked config settings. It also lets us make sure config values are synced with what the user has set in their vscode settings. This PR is a breaking change since it also unifies config key prefixes (`oxc` and `oxc_language_server` -> `oxc` only)
- Loading branch information
Showing
4 changed files
with
185 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { ConfigurationChangeEvent, workspace, WorkspaceConfiguration } from 'vscode'; | ||
import { IDisposable } from './types'; | ||
|
||
export class ConfigService implements Config, IDisposable { | ||
private static readonly _namespace = 'oxc'; | ||
private readonly _disposables: IDisposable[] = []; | ||
private _inner: WorkspaceConfiguration; | ||
private _runTrigger: 'onSave' | 'onType'; | ||
private _enable: boolean; | ||
private _trace: 'off' | 'messages' | 'verbose'; | ||
private _configPath: string; | ||
private _binPath: string | undefined; | ||
|
||
public onConfigChange: | ||
| ((this: ConfigService, config: ConfigurationChangeEvent) => void) | ||
| undefined; | ||
|
||
constructor() { | ||
this._inner = workspace.getConfiguration(ConfigService._namespace); | ||
this._runTrigger = this._inner.get<Trigger>('lint.run') || 'onType'; | ||
this._enable = this._inner.get<boolean>('enable') ?? true; | ||
this._trace = this._inner.get<TraceLevel>('trace.server') || 'off'; | ||
this._configPath = this._inner.get<string>('configPath') || '.eslintrc'; | ||
this._binPath = this._inner.get<string>('path.server'); | ||
this.onConfigChange = undefined; | ||
|
||
const disposeChangeListener = workspace.onDidChangeConfiguration( | ||
this.onVscodeConfigChange.bind(this), | ||
); | ||
this._disposables.push(disposeChangeListener); | ||
} | ||
|
||
get rawConfig(): WorkspaceConfiguration { | ||
return this._inner; | ||
} | ||
|
||
get runTrigger(): Trigger { | ||
return this._runTrigger; | ||
} | ||
|
||
set runTrigger(value: Trigger) { | ||
this._runTrigger = value; | ||
workspace | ||
.getConfiguration(ConfigService._namespace) | ||
.update('lint.run', value); | ||
} | ||
|
||
get enable(): boolean { | ||
return this._enable; | ||
} | ||
|
||
set enable(value: boolean) { | ||
this._enable = value; | ||
workspace | ||
.getConfiguration(ConfigService._namespace) | ||
.update('enable', value); | ||
} | ||
|
||
get trace(): TraceLevel { | ||
return this._trace; | ||
} | ||
|
||
set trace(value: TraceLevel) { | ||
this._trace = value; | ||
workspace | ||
.getConfiguration(ConfigService._namespace) | ||
.update('trace.server', value); | ||
} | ||
|
||
get configPath(): string { | ||
return this._configPath; | ||
} | ||
|
||
set configPath(value: string) { | ||
this._configPath = value; | ||
workspace | ||
.getConfiguration(ConfigService._namespace) | ||
.update('configPath', value); | ||
} | ||
|
||
get binPath(): string | undefined { | ||
return this._binPath; | ||
} | ||
|
||
set binPath(value: string | undefined) { | ||
this._binPath = value; | ||
workspace | ||
.getConfiguration(ConfigService._namespace) | ||
.update('path.server', value); | ||
} | ||
|
||
private onVscodeConfigChange(event: ConfigurationChangeEvent): void { | ||
if (event.affectsConfiguration(ConfigService._namespace)) { | ||
this._runTrigger = this._inner.get<Trigger>('lint.run') || 'onType'; | ||
this._enable = this._inner.get<boolean>('enable') ?? true; | ||
this._trace = this._inner.get<TraceLevel>('trace.server') || 'off'; | ||
this._configPath = this._inner.get<string>('configPath') || '.eslintrc'; | ||
this._binPath = this._inner.get<string>('path.server'); | ||
this.onConfigChange?.call(this, event); | ||
} | ||
} | ||
|
||
dispose() { | ||
for (const disposable of this._disposables) { | ||
disposable.dispose(); | ||
} | ||
} | ||
|
||
public toJSON(): Config { | ||
return { | ||
runTrigger: this.runTrigger, | ||
enable: this.enable, | ||
trace: this.trace, | ||
configPath: this.configPath, | ||
binPath: this.binPath, | ||
}; | ||
} | ||
} | ||
|
||
type Trigger = 'onSave' | 'onType'; | ||
type TraceLevel = 'off' | 'messages' | 'verbose'; | ||
|
||
/** | ||
* See `"contributes.configuration"` in `package.json` | ||
*/ | ||
interface Config { | ||
/** | ||
* When to run the linter and generate diagnostics | ||
* `oxc.lint.run` | ||
* | ||
* @default 'onType' | ||
*/ | ||
runTrigger: Trigger; | ||
/** | ||
* `oxc.enable` | ||
* | ||
* @default true | ||
*/ | ||
enable: boolean; | ||
/** | ||
* Trace VSCode <-> Oxc Language Server communication | ||
* `oxc.trace.server` | ||
* | ||
* @default 'off' | ||
*/ | ||
trace: TraceLevel; | ||
/** | ||
* oxlint config path | ||
* | ||
* `oxc.configPath` | ||
* | ||
* @default ".eslintrc" | ||
*/ | ||
configPath: string; | ||
/** | ||
* Path to LSP binary | ||
* `oxc.path.server` | ||
* @default undefined | ||
*/ | ||
binPath: string | undefined; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* A type with a destructor for releasing resources when de-registered by an LSP client. | ||
* | ||
* There's a newer {@link Disposable} interface that works with `using`, but | ||
* VSCode uses this in its APIs. | ||
*/ | ||
export interface IDisposable { | ||
dispose(): void | Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Does the scope of configPath here consider machine-overridable ?