@@ -25,7 +25,6 @@ import com.itsaky.androidide.editor.schemes.IDEColorScheme
2525import com.itsaky.androidide.editor.schemes.LanguageScheme
2626import com.itsaky.androidide.editor.schemes.LanguageSpecProvider.getLanguageSpec
2727import com.itsaky.androidide.editor.schemes.LocalCaptureSpecProvider.newLocalCaptureSpec
28- import com.itsaky.androidide.editor.utils.isNonBlankLine
2928import com.itsaky.androidide.treesitter.TSLanguage
3029import com.itsaky.androidide.treesitter.TreeSitter
3130import com.itsaky.androidide.utils.IntPair
@@ -78,7 +77,10 @@ abstract class TreeSitterLanguage(
7877
7978 private val log = LoggerFactory .getLogger(TreeSitterLanguage ::class .java)
8079 private const val DEF_IDENT_ADV = 0
81- private const val MAX_INDENT_ADVANCE = 4096
80+ // A real indentation delta is at most a handful of columns. Anything beyond this
81+ // signals the computation went wrong (e.g. a pathological ERROR tree), in which
82+ // case we discard the value and fall back to the previous line's indentation.
83+ private const val MAX_INDENT_ADVANCE = 256
8284 }
8385
8486 fun setupWith (scheme : IDEColorScheme ? ) {
@@ -146,13 +148,18 @@ abstract class TreeSitterLanguage(
146148 return DEF_IDENT_ADV
147149 }
148150
149- var linesToReq = LongArray (1 )
150- linesToReq[0 ] = IntPair .pack(line, column)
151-
152- if (content.reference.isNonBlankLine(line + 1 )) {
153- // consider the indentation of the next line only if it is non-blank
154- linesToReq + = IntPair .pack(line + 1 , 0 )
155- }
151+ // Always compute the indentation of both the current line and the next line and use
152+ // their difference (see the size == 2 branch below). Using the next line's indent even
153+ // when it is blank keeps the computation relative: the two absolute indents are both
154+ // expressed in units of the editor's indent size, so any mismatch between that size and
155+ // the file's actual indentation width cancels out. Relying on the current line's
156+ // absolute indent alone (the size == 1 branch) would instead force the new line toward
157+ // the editor's indent width, producing a wrong indent (e.g. doubling) on files whose
158+ // indentation width differs from the configured indent size.
159+ val linesToReq = longArrayOf(
160+ IntPair .pack(line, column),
161+ IntPair .pack(line + 1 , 0 )
162+ )
156163
157164 val indents = this .indentProvider.getIndentsForLines(
158165 content = content.reference,
@@ -167,8 +174,9 @@ abstract class TreeSitterLanguage(
167174 return DEF_IDENT_ADV
168175 }
169176
170- return (indent - (spaceCountOnLine + (tabCountOnLine * getTabSize())))
171- .coerceIn(- MAX_INDENT_ADVANCE , MAX_INDENT_ADVANCE )
177+ val advance = indent - (spaceCountOnLine + (tabCountOnLine * getTabSize()))
178+ return advance.takeIf { it in - MAX_INDENT_ADVANCE .. MAX_INDENT_ADVANCE }
179+ ? : DEF_IDENT_ADV
172180 }
173181
174182 val (indentLine, indentNxtLine) = indents
@@ -184,7 +192,9 @@ abstract class TreeSitterLanguage(
184192 return DEF_IDENT_ADV
185193 }
186194
187- return (indentNxtLine - indentLine).coerceIn(- MAX_INDENT_ADVANCE , MAX_INDENT_ADVANCE )
195+ val advance = indentNxtLine - indentLine
196+ return advance.takeIf { it in - MAX_INDENT_ADVANCE .. MAX_INDENT_ADVANCE }
197+ ? : DEF_IDENT_ADV
188198 } catch (e: Exception ) {
189199 log.error(
190200 " An error occurred computing indentation at line:column::{}:{}" ,
0 commit comments