1+ """
2+ This module provides utilities for text editing operations, particularly focused on
3+ working with markers, segments, and range specifications in source code.
4+
5+ It includes functions for file I/O, marker and segment processing, and range
6+ manipulations, which are useful for tasks such as code analysis and transformation.
7+ """
8+
19from collections .abc import Sequence
210from typing import Protocol , runtime_checkable
311from os import PathLike
715
816
917def read_file (file_path : str | PathLike ) -> str :
18+ """
19+ Read the contents of a file.
20+
21+ Args:
22+ file_path (str | PathLike): The path to the file to be read.
23+
24+ Returns:
25+ str: The contents of the file as a string.
26+ """
1027 with open (file_path , 'r' ) as file :
1128 return file .read ()
1229
1330
1431def write_file (file_path : str | PathLike , lines : Sequence [str ]):
32+ """
33+ Write a sequence of lines to a file.
34+
35+ Args:
36+ file_path (str | PathLike): The path to the file to be written.
37+ lines (Sequence[str]): The lines to be written to the file.
38+ """
1539 with open (file_path , 'w' ) as file :
1640 file .writelines ([line + '\n ' for line in lines ])
1741
@@ -20,6 +44,19 @@ def write_file(file_path: str | PathLike, lines: Sequence[str]):
2044# return len(line) - len(line.lstrip(char))
2145
2246def bow_to_search_range (bow : BodyOrWhole , searh_range : IdentifierBoundaries | RangeSpec | None = None ) -> RangeSpec :
47+ """
48+ Convert a BodyOrWhole specification to a search range.
49+
50+ Args:
51+ bow (BodyOrWhole): The BodyOrWhole specification.
52+ searh_range (IdentifierBoundaries | RangeSpec | None, optional): The search range to use. Defaults to None.
53+
54+ Returns:
55+ RangeSpec: The resulting search range.
56+
57+ Raises:
58+ ValueError: If an invalid search range is provided.
59+ """
2360 match searh_range :
2461
2562 case RangeSpec () | None :
@@ -41,11 +78,29 @@ def bow_to_search_range(bow: BodyOrWhole, searh_range: IdentifierBoundaries | Ra
4178
4279@runtime_checkable
4380class MarkerOrSegmentProtocol (Protocol ):
81+ """
82+ A protocol for objects that can be converted to an index range.
83+
84+ This protocol defines the interface for objects that can be converted
85+ to a RangeSpec based on a sequence of lines and search indices.
86+ """
87+
4488 def marker_or_segment_to_index_range (
4589 self ,
4690 lines : Sequence [str ],
4791 search_start_index : int = 0 , search_end_index : int = - 1
4892 ) -> RangeSpec :
93+ """
94+ Convert the object to an index range.
95+
96+ Args:
97+ lines (Sequence[str]): The lines to search in.
98+ search_start_index (int, optional): The start index for the search. Defaults to 0.
99+ search_end_index (int, optional): The end index for the search. Defaults to -1.
100+
101+ Returns:
102+ RangeSpec: The resulting index range.
103+ """
49104 ...
50105
51106
@@ -54,6 +109,22 @@ def marker_or_segment_to_search_range_impl(
54109 lines : Sequence [str ],
55110 search_range : RangeSpec = RangeSpec .EMPTY
56111) -> RangeSpec | None :
112+ """
113+ Implementation of the marker or segment to search range conversion.
114+
115+ This function is used to convert a Marker or Segment object to a RangeSpec.
116+
117+ Args:
118+ self: The Marker or Segment object.
119+ lines (Sequence[str]): The lines to search in.
120+ search_range (RangeSpec, optional): The initial search range. Defaults to RangeSpec.EMPTY.
121+
122+ Returns:
123+ RangeSpec | None: The resulting search range, or None if not found.
124+
125+ Raises:
126+ ValueError: If an unexpected type is encountered.
127+ """
57128 match self :
58129 case Marker (type = MarkerType .LINE ):
59130 result = RangeSpec .from_line_marker (lines , self , search_range )
@@ -79,6 +150,24 @@ def segment_to_search_range(
79150 start_relpos : RelativeMarker , end_relpos : RelativeMarker ,
80151 search_range : RangeSpec = RangeSpec .EMPTY
81152) -> RangeSpec :
153+ """
154+ Convert a segment defined by start and end relative markers to a search range.
155+
156+ This function takes a segment defined by start and end relative markers and
157+ converts it to a RangeSpec that can be used for searching within the given lines.
158+
159+ Args:
160+ lines (Sequence[str]): The lines to search in.
161+ start_relpos (RelativeMarker): The relative marker for the start of the segment.
162+ end_relpos (RelativeMarker): The relative marker for the end of the segment.
163+ search_range (RangeSpec, optional): The initial search range. Defaults to RangeSpec.EMPTY.
164+
165+ Returns:
166+ RangeSpec: The resulting search range.
167+
168+ Raises:
169+ AssertionError: If the lines are empty or if the start or end markers cannot be found.
170+ """
82171 assert len (lines ), "`lines` is empty"
83172
84173 start_match_result = RangeSpec .from_line_marker (lines , start_relpos , search_range )
0 commit comments