18
18
from collections .abc import Sequence
19
19
from math import gcd
20
20
from typing import NamedTuple
21
+ import re
21
22
22
23
from .cst_kit import IdentifierFinder
23
24
24
25
from .line_kit import get_line_indent_count , extract_indentation
25
26
27
+ relative_indent_prefix = re .compile (r'^\s*@(-?\d+):(.*)' )
28
+
29
+
26
30
class IndentationInfo (NamedTuple ):
27
31
"""
28
32
A class to represent and manage indentation information.
@@ -276,9 +280,9 @@ def adjust_line(line: str) -> str:
276
280
return new_indent + line .lstrip ()
277
281
return adjust_line
278
282
279
- def apply_relative_indents (self , content : str | Sequence [str ], context_indent_count : int = 0 ) -> list [str ]:
283
+ def apply_relative_indents (self , content : str | Sequence [str ], reference_indent_count : int = 0 ) -> list [str ]:
280
284
"""
281
- Apply relative indentation based on annotations in the content.
285
+ Apply relative indentation based on optional annotations in the content.
282
286
283
287
This method processes the input content, interpreting special annotations
284
288
to apply relative indentation. It uses '@' followed by a number to indicate
@@ -287,7 +291,7 @@ def apply_relative_indents(self, content: str | Sequence[str], context_indent_co
287
291
Args:
288
292
content (str | Sequence[str]): The content to process. Can be a string
289
293
or a sequence of strings.
290
- context_indent_count (int, optional): The base indentation count of the
294
+ reference_indent_count (int, optional): The base indentation count of the
291
295
context. Defaults to 0.
292
296
293
297
Returns:
@@ -312,23 +316,23 @@ def apply_relative_indents(self, content: str | Sequence[str], context_indent_co
312
316
[' def example():', ' print('Hello')', ' if True:', ' print('World')']
313
317
"""
314
318
# TODO Always send str?
315
- lines = [l .lstrip () for l in content .splitlines () if l .strip ()] if isinstance (content , str ) else content
316
-
317
- context_indent_level = self .char_count_to_level (context_indent_count )
319
+ lines = [l for l in content .strip ('\n ' ).splitlines ()] if isinstance (content , str ) else content
320
+ reference_indent_level = self .char_count_to_level (reference_indent_count )
318
321
for i in range (len (lines )):
319
322
line = lines [i ]
320
- parts = line .split (':' , 1 )
321
- if len (parts ) == 2 and parts [0 ].startswith ('@' ):
322
- relative_indent_level = int (parts [0 ][1 :])
323
- absolute_indent_level = context_indent_level + relative_indent_level
324
- assert absolute_indent_level >= 0 , (
325
- f"Final indentation for line `{ line .strip ()} ` cannot be negative "
326
- f"({ absolute_indent_level } )"
327
- )
328
- lines [i ] = self .level_to_chars (absolute_indent_level ) + parts [1 ].lstrip ()
329
- else :
330
- absolute_indent_level = context_indent_level
331
- lines [i ] = self .level_to_chars (absolute_indent_level ) + line .lstrip ()
323
+ match relative_indent_prefix .match (line ):
324
+ case re .Match () as m :
325
+ relative_indent_level , line = m .groups ()
326
+ relative_indent_level = int (relative_indent_level )
327
+ line = line .lstrip ()
328
+ case _:
329
+ relative_indent_level = self .char_count_to_level (get_line_indent_count (line ))
330
+ absolute_indent_level = reference_indent_level + relative_indent_level
331
+ assert absolute_indent_level >= 0 , (
332
+ f"Final indent level for line `{ line .strip ()} ` cannot be negative "
333
+ f"({ absolute_indent_level } )"
334
+ )
335
+ lines [i ] = self .level_to_chars (absolute_indent_level ) + line .lstrip ()
332
336
333
337
return lines
334
338
0 commit comments