Files
oak-gpui/crates/project_core/src/project_settings.rs
T
Thorsten Ball a52177fd39 Allow users to configure ESLint codeActionOnSave settings (#8537)
This fixes #8533 by allowing users to specify the settings that are
passed to ESLint on workspace initialization.

Example Zed `settings.json` to enable `fixAll` for eslint when
saving/formatting, but only for the `import/order` rule:

```json
{
  "languages": {
    "JavaScript": {
      "code_actions_on_format": {
        "source.fixAll.eslint": true
      }
    }
  },
  "lsp": {
    "eslint": {
      "settings": {
        "codeActionOnSave": {
          "rules": ["import/order"]
        }
      }
    },
  }
}
```

The possible settings are described in the README of `vscode-eslint`
here:
https://github.com/Microsoft/vscode-eslint?tab=readme-ov-file#settings-options

- `eslint.codeActionsOnSave.enable` (default: `true`, config key in Zed:
`lsp.eslint.settings.codeActionOnSave.enable`)
- `eslint.codeActionsOnSave.mode` (default: not set by Zed, config key
in Zed: `lsp.eslint.settings.codeActionOnSave.mode`)
- `eslint.codeActionsOnSave.rules` (default: `[]`, config key in Zed:
`lsp.eslint.settings.codeActionOnSave.rules`)

Yes, in the readme it's plural: `codeActionsOnSave`, but since
`eslint-vscode` we're using this old release:


https://github.com/microsoft/vscode-eslint/releases/tag/release%2F2.2.20-Insider

We use the singular version:
https://github.com/microsoft/vscode-eslint/blob/release/2.2.20-Insider/server/src/eslintServer.ts#L461

Our schema looks like this:

```json
{
  "lsp": {
    "eslint": {
      "settings": {
        "codeActionOnSave": {
          "enable": true,
          "rules": ["import/order"],
          "mode": "all"
        }
      }
    },
  }
}
```

We should probably fix this and upgrade to the newest version of ESLint.

Release Notes:

- Added ability for users to configure settings for ESLint's
`codeActionOnSave`, e.g. specifying `rules` that should be respected
when also using `"code_actions_on_format": {"source.fixAll.eslint":
true}`. These settings can be passed to ESLint as part of the `"lsp"`
part of the Zed settings. Example: `{"lsp": {"eslint": {"settings":
{"codeActionOnSave": { "rules": ["import/order"] }}}}}`
([#8533](https://github.com/zed-industries/zed/issues/8533)).

Demo:


https://github.com/zed-industries/zed/assets/1185253/5c0cf900-9acb-4a70-b89d-49b6eeb6f0e4
2024-02-28 17:04:36 +01:00

83 lines
2.3 KiB
Rust

use collections::HashMap;
use gpui::AppContext;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::Settings;
use std::sync::Arc;
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct ProjectSettings {
/// Configuration for language servers.
///
/// The following settings can be overridden for specific language servers:
/// - initialization_options
/// To override settings for a language, add an entry for that language server's
/// name to the lsp value.
/// Default: null
#[serde(default)]
pub lsp: HashMap<Arc<str>, LspSettings>,
/// Configuration for Git-related features
#[serde(default)]
pub git: GitSettings,
/// Completely ignore files matching globs from `file_scan_exclusions`
///
/// Default: [
/// "**/.git",
/// "**/.svn",
/// "**/.hg",
/// "**/CVS",
/// "**/.DS_Store",
/// "**/Thumbs.db",
/// "**/.classpath",
/// "**/.settings"
/// ]
#[serde(default)]
pub file_scan_exclusions: Option<Vec<String>>,
/// Treat the files matching these globs as `.env` files.
/// Default: [ "**/.env*" ]
pub private_files: Option<Vec<String>>,
}
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct GitSettings {
/// Whether or not to show the git gutter.
///
/// Default: tracked_files
pub git_gutter: Option<GitGutterSetting>,
pub gutter_debounce: Option<u64>,
}
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum GitGutterSetting {
/// Show git gutter in tracked files.
#[default]
TrackedFiles,
/// Hide git gutter
Hide,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct LspSettings {
pub initialization_options: Option<serde_json::Value>,
pub settings: Option<serde_json::Value>,
}
impl Settings for ProjectSettings {
const KEY: Option<&'static str> = None;
type FileContent = Self;
fn load(
default_value: &Self::FileContent,
user_values: &[&Self::FileContent],
_: &mut AppContext,
) -> anyhow::Result<Self> {
Self::load_via_json_merge(default_value, user_values)
}
}