From 6afdd783a51a2345920ead9322edb38bafd992a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=AE=B6?= Date: Fri, 13 Mar 2026 19:57:29 +0800 Subject: [PATCH 1/5] feat(cli): add Zed editor support for project creation --- packages/cli/src/utils/editor.ts | 120 +++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/packages/cli/src/utils/editor.ts b/packages/cli/src/utils/editor.ts index 297dc82b21..9a5615fcbe 100644 --- a/packages/cli/src/utils/editor.ts +++ b/packages/cli/src/utils/editor.ts @@ -21,6 +21,118 @@ const VSCODE_EXTENSIONS = { recommendations: ['VoidZero.vite-plus-extension-pack'], } as const; +const ZED_SETTINGS = { + lsp: { + oxlint: { + initialization_options: { + settings: { + configPath: './oxlintrc.json', + run: 'onType', + disableNestedConfig: false, + fixKind: 'safe_fix', + typeAware: true, + unusedDisableDirectives: 'deny', + }, + }, + }, + oxfmt: { + initialization_options: { + settings: { + configPath: './oxfmtrc.jsonc', + }, + }, + }, + }, + languages: { + CSS: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + GraphQL: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + Handlebars: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + HTML: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + JavaScript: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + code_action: 'source.fixAll.oxc', + }, + JSX: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + JSON: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + JSON5: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + JSONC: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + Less: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + Markdown: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + MDX: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + SCSS: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + TypeScript: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + TSX: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + Vue: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + YAML: { + format_on_save: 'on', + prettier: { allowed: false }, + formatter: [{ language_server: { name: 'oxfmt' } }], + }, + }, +} as const; + export const EDITORS = [ { id: 'vscode', @@ -31,6 +143,14 @@ export const EDITORS = [ 'extensions.json': VSCODE_EXTENSIONS as Record, }, }, + { + id: 'zed', + label: 'Zed', + targetDir: '.zed', + files: { + 'settings.json': ZED_SETTINGS as Record, + }, + }, ] as const; export type EditorId = (typeof EDITORS)[number]['id']; From 409a2e63b15f92b1694a39a83c6b75d95cfb30bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=AE=B6?= Date: Fri, 13 Mar 2026 20:08:15 +0800 Subject: [PATCH 2/5] feat(cli): add onSave to zed oxfmt config --- packages/cli/src/utils/editor.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/utils/editor.ts b/packages/cli/src/utils/editor.ts index 9a5615fcbe..f22794b709 100644 --- a/packages/cli/src/utils/editor.ts +++ b/packages/cli/src/utils/editor.ts @@ -39,6 +39,7 @@ const ZED_SETTINGS = { initialization_options: { settings: { configPath: './oxfmtrc.jsonc', + run: 'onSave', }, }, }, From 1757033b6974fd5a89fbfdb5ea5ccdf9cb3ef46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=AE=B6?= Date: Fri, 13 Mar 2026 21:23:07 +0800 Subject: [PATCH 3/5] Potential fix for pull request finding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: 王兴家 --- packages/cli/src/utils/editor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/utils/editor.ts b/packages/cli/src/utils/editor.ts index f22794b709..7ebd23a930 100644 --- a/packages/cli/src/utils/editor.ts +++ b/packages/cli/src/utils/editor.ts @@ -26,7 +26,7 @@ const ZED_SETTINGS = { oxlint: { initialization_options: { settings: { - configPath: './oxlintrc.json', + configPath: './.oxlintrc.json', run: 'onType', disableNestedConfig: false, fixKind: 'safe_fix', @@ -38,7 +38,7 @@ const ZED_SETTINGS = { oxfmt: { initialization_options: { settings: { - configPath: './oxfmtrc.jsonc', + configPath: './.oxfmtrc.jsonc', run: 'onSave', }, }, From acb6cfc97980d7a8664922adcd80e8ef06731828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=AE=B6?= Date: Fri, 13 Mar 2026 21:28:41 +0800 Subject: [PATCH 4/5] fix(cli): use recursive deep merge for editor configs --- packages/cli/src/utils/editor.ts | 45 ++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/packages/cli/src/utils/editor.ts b/packages/cli/src/utils/editor.ts index 7ebd23a930..8d97e4fd31 100644 --- a/packages/cli/src/utils/editor.ts +++ b/packages/cli/src/utils/editor.ts @@ -368,28 +368,33 @@ function mergeEditorConfigs( }; } - // settings.json: 2-level deep merge, preserving existing keys - const result = { ...existing }; - for (const [key, value] of Object.entries(incoming)) { - if (!(key in result)) { - result[key] = value; - } else if ( - typeof result[key] === 'object' && - result[key] !== null && - !Array.isArray(result[key]) && - typeof value === 'object' && - value !== null && - !Array.isArray(value) - ) { - // Nested object: merge preserving existing keys - result[key] = { - ...(value as Record), - ...(result[key] as Record), - }; + // settings.json: recursive deep merge, preserving existing keys + function deepMerge( + target: Record, + source: Record, + ): Record { + const result = { ...target }; + for (const [key, value] of Object.entries(source)) { + if (!(key in result)) { + result[key] = value; + } else if ( + typeof result[key] === 'object' && + result[key] !== null && + !Array.isArray(result[key]) && + typeof value === 'object' && + value !== null && + !Array.isArray(value) + ) { + result[key] = deepMerge( + result[key] as Record, + value as Record, + ); + } } - // else: existing key is preserved as-is + return result; } - return result; + + return deepMerge(existing, incoming); } function resolveEditorId(editor: string): EditorId | undefined { From e0dcda8a2286fee8d2d80a42918f007af03a9b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=AE=B6?= Date: Fri, 13 Mar 2026 21:39:49 +0800 Subject: [PATCH 5/5] fix(cli): move deepMerge outside to satisfy oxlint --- packages/cli/src/utils/editor.ts | 49 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/packages/cli/src/utils/editor.ts b/packages/cli/src/utils/editor.ts index 8d97e4fd31..ce25c25043 100644 --- a/packages/cli/src/utils/editor.ts +++ b/packages/cli/src/utils/editor.ts @@ -368,33 +368,32 @@ function mergeEditorConfigs( }; } - // settings.json: recursive deep merge, preserving existing keys - function deepMerge( - target: Record, - source: Record, - ): Record { - const result = { ...target }; - for (const [key, value] of Object.entries(source)) { - if (!(key in result)) { - result[key] = value; - } else if ( - typeof result[key] === 'object' && - result[key] !== null && - !Array.isArray(result[key]) && - typeof value === 'object' && - value !== null && - !Array.isArray(value) - ) { - result[key] = deepMerge( - result[key] as Record, - value as Record, - ); - } + return deepMerge(existing, incoming); +} + +function deepMerge( + target: Record, + source: Record, +): Record { + const result = { ...target }; + for (const [key, value] of Object.entries(source)) { + if (!(key in result)) { + result[key] = value; + } else if ( + typeof result[key] === 'object' && + result[key] !== null && + !Array.isArray(result[key]) && + typeof value === 'object' && + value !== null && + !Array.isArray(value) + ) { + result[key] = deepMerge( + result[key] as Record, + value as Record, + ); } - return result; } - - return deepMerge(existing, incoming); + return result; } function resolveEditorId(editor: string): EditorId | undefined {