Skip to content

Commit 595867a

Browse files
committed
feat(oxlint): Generate markdownDescription fields for oxlint JSON schema. (#15959)
This allows VS Code and other editors to display better descriptions in hover tooltips when editing oxlintrc.json files. Before: <img width="676" height="179" alt="Screenshot 2025-11-21 at 9 24 52 PM" src="https://github.com/user-attachments/assets/775cbf62-19cb-44f4-ad48-2a9e3b867900" /> After: <img width="926" height="164" alt="Screenshot 2025-11-21 at 9 24 41 PM" src="https://github.com/user-attachments/assets/d2e668b2-88a9-4765-9f18-122185fdeb8e" /> This can probably be made more efficient, as I wrote it using GitHub Copilot + Claude Sonnet 4.5. But it's not really ever used outside developers regenerating the schema occasionally, so 🤷. Based heavily on https://github.com/moonrepo/schematic/blob/d3a9422cead2802b940c96f8ab8b188c86ab281f/crates/schematic/src/schema/renderers/json_schema.rs#L84, with permission (via discord). Part of #15247.
1 parent 0b18005 commit 595867a

File tree

3 files changed

+199
-82
lines changed

3 files changed

+199
-82
lines changed

crates/oxc_linter/src/config/oxlintrc.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ impl Oxlintrc {
204204
/// Panics if the schema generation fails.
205205
pub fn generate_schema_json() -> String {
206206
let mut schema = schema_for!(Oxlintrc);
207+
207208
// Allow comments and trailing commas for vscode-json-languageservice
208209
// NOTE: This is NOT part of standard JSON Schema specification
209210
// https://github.com/microsoft/vscode-json-languageservice/blob/fb83547762901f32d8449d57e24666573016b10c/src/jsonLanguageTypes.ts#L151-L159
@@ -212,7 +213,43 @@ impl Oxlintrc {
212213
.schema
213214
.extensions
214215
.insert("allowTrailingCommas".to_string(), serde_json::Value::Bool(true));
215-
serde_json::to_string_pretty(&schema).unwrap()
216+
217+
// Inject markdownDescription fields for better editor support (e.g., VS Code)
218+
let mut json = serde_json::to_value(&schema).unwrap();
219+
Self::inject_markdown_descriptions(&mut json);
220+
221+
serde_json::to_string_pretty(&json).unwrap()
222+
}
223+
224+
/// Recursively inject `markdownDescription` fields into the JSON schema.
225+
/// This is a non-standard field that some editors (like VS Code) use to render
226+
/// markdown in hover tooltips.
227+
fn inject_markdown_descriptions(value: &mut serde_json::Value) {
228+
match value {
229+
serde_json::Value::Object(map) => {
230+
// If this object has a `description` field, copy it to `markdownDescription`
231+
if let Some(serde_json::Value::String(desc_str)) = map.get("description") {
232+
map.insert(
233+
"markdownDescription".to_string(),
234+
serde_json::Value::String(desc_str.clone()),
235+
);
236+
}
237+
238+
// Recursively process all values in the object
239+
for value in map.values_mut() {
240+
Self::inject_markdown_descriptions(value);
241+
}
242+
}
243+
serde_json::Value::Array(items) => {
244+
// Recursively process all items in the array
245+
for item in items {
246+
Self::inject_markdown_descriptions(item);
247+
}
248+
}
249+
_ => {
250+
// Primitive values don't need processing
251+
}
252+
}
216253
}
217254

218255
/// Merges two [Oxlintrc] files together

0 commit comments

Comments
 (0)