From 7ca96f6087741e928261547725512dfaceae26e6 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Tue, 14 Jul 2026 11:57:12 -0600 Subject: [PATCH] fix(editor): consistent YAML auto-indent on newline The indentNodeProp from @codemirror/lang-yaml computes column-based indents that produce inconsistent and odd-numbered indentation when pressing Enter (e.g. 9 spaces after a nested 'web:' line, 6 after a 4-space 'image:' line). Override it with a line-based indentService: keep the current line's indent, align list-entry keys after the dash marker, and indent one unit deeper after lines opening a block (':', '|', '>'). Fixes #4650 --- .../dokploy/components/shared/code-editor.tsx | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/components/shared/code-editor.tsx b/apps/dokploy/components/shared/code-editor.tsx index f0347da60..7bdb644e3 100644 --- a/apps/dokploy/components/shared/code-editor.tsx +++ b/apps/dokploy/components/shared/code-editor.tsx @@ -7,7 +7,11 @@ import { import { css } from "@codemirror/lang-css"; import { json } from "@codemirror/lang-json"; import { yaml } from "@codemirror/lang-yaml"; -import { StreamLanguage } from "@codemirror/language"; +import { + getIndentUnit, + indentService, + StreamLanguage, +} from "@codemirror/language"; import { properties } from "@codemirror/legacy-modes/mode/properties"; import { shell } from "@codemirror/legacy-modes/mode/shell"; import { search, searchKeymap } from "@codemirror/search"; @@ -98,6 +102,27 @@ const dockerComposeServiceOptions = [ }, })); +// The indentNodeProp shipped with @codemirror/lang-yaml computes wrong +// column-based indents on Enter (odd/inconsistent amounts, see #4650), so +// indentation is resolved line-based here: keep the current indent, align +// list-entry keys after the dash marker, and go one unit deeper after a +// line that opens a block (ending in ":", "|" or ">"). +const yamlIndent = indentService.of((context, pos) => { + const line = context.state.doc.lineAt(pos); + const before = context.state.doc.sliceString(line.from, pos); + const indent = /^ */.exec(before)?.[0].length ?? 0; + const trimmed = before.trim(); + if (!trimmed || trimmed.startsWith("#")) { + return indent; + } + const base = + trimmed.startsWith("- ") && /:\s/.test(trimmed) ? indent + 2 : indent; + if (/[:|>]$/.test(trimmed)) { + return base + getIndentUnit(context.state); + } + return base; +}); + function dockerComposeComplete( context: CompletionContext, ): CompletionResult | null { @@ -160,7 +185,7 @@ export const CodeEditor = ({ search(), keymap.of(searchKeymap), language === "yaml" - ? yaml() + ? [yamlIndent, yaml()] : language === "json" ? json() : language === "css"