From 1e82deb73d965e0de159436322b93aeb393c3afd Mon Sep 17 00:00:00 2001 From: nimamasl114514 Date: Mon, 3 Aug 2026 18:15:44 +0800 Subject: [PATCH] fix #20078: nimpretty --indent applies to keepIndents regions (#25985) ## Summary - nimpretty with non-default \--indent\ (e.g. 3 or 10) produced invalid indentation in if/block/try expression regions because layouter kept the original column when \keepIndents > 0\ and ignored \indWidth\. - Rebase the column onto \indWidth\ using the relative offset from the enclosing block baseline (\indentStack[^1]\). ## Root cause \parser.nim\'s \ imprettyDontTouch\ template sets \keepIndents\ for if/block/try expressions. layouter in the \keepIndents > 0\ branch used \ ok.indent\ (source column) directly as \indentLevel\ without scaling by \indWidth\, so lines in these regions kept the original column and misaligned with the rest of the file when \--indent\ differed from source indent width. ## Fix \\\ im em.indentLevel = em.indentStack.high * em.indWidth + (tok.indent - em.indentStack[^1]) \\\ Keeps the relative offset from the enclosing block baseline but rebases onto \indWidth\. At default \--indent:2\ the offset equals \indWidth\, so output is unchanged (backwards compatible). ## Testing - 12 custom cases x 3 indent values (2/3/10) = 36/36 pass - nimpretty self-test suite 7/7 pass (no regression at default indent) - 5 keepIndents scenarios (if/block/try expression continuation alignment) that failed at indent:3/10 now pass Fixes #20078. --- compiler/layouter.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/layouter.nim b/compiler/layouter.nim index 0121b11858..d2eb613ca3 100644 --- a/compiler/layouter.nim +++ b/compiler/layouter.nim @@ -451,7 +451,13 @@ proc emitTok*(em: var Emitter; L: Lexer; tok: Token) = elif tok.indent >= 0: var newlineKind = ltCrucialNewline if em.keepIndents > 0: - em.indentLevel = tok.indent + # Apply the requested --indent width to "don't touch" regions (if/block + # expressions) too: keep the relative offset from the enclosing block + # baseline, but rebase it onto indWidth. Otherwise a non-default + # --indent would leave these lines at the original column and inject + # invalid indentation (see #20078). + em.indentLevel = em.indentStack.high * em.indWidth + + (tok.indent - em.indentStack[^1]) elif (em.lastTok in (splitters + oprSet) and tok.tokType notin (closedPars - {tkBracketDotRi})): if tok.tokType in openPars and tok.indent > em.indentStack[^1]: