|
5 | 5 | //
|
6 | 6 | //
|
7 | 7 |
|
| 8 | +use std::borrow::Cow; |
8 | 9 | use std::cmp::Ordering;
|
9 | 10 | use std::sync::LazyLock;
|
10 | 11 |
|
@@ -81,15 +82,18 @@ fn parse_ts_node(
|
81 | 82 | }
|
82 | 83 |
|
83 | 84 | // Nested comment section handling
|
84 |
| - let comment_line = get_line_text(document, start.row, None, None); |
85 |
| - |
86 |
| - if let Err(err) = |
87 |
| - nested_processor(comment_stack, folding_ranges, start.row, &comment_line) |
88 |
| - { |
89 |
| - lsp::log_error!("Can't process comment: {err:?}"); |
| 85 | + if let Some(comment_line) = document.contents.get_line(start.row) { |
| 86 | + // O(n) if comment overlaps rope chunks, O(1) otherwise |
| 87 | + let comment_line: Cow<'_, str> = comment_line.into(); |
| 88 | + |
| 89 | + if let Err(err) = |
| 90 | + nested_processor(comment_stack, folding_ranges, start.row, &comment_line) |
| 91 | + { |
| 92 | + lsp::log_error!("Can't process comment: {err:?}"); |
| 93 | + }; |
| 94 | + region_processor(folding_ranges, region_marker, start.row, &comment_line); |
| 95 | + cell_processor(folding_ranges, cell_marker, start.row, &comment_line); |
90 | 96 | };
|
91 |
| - region_processor(folding_ranges, region_marker, start.row, &comment_line); |
92 |
| - cell_processor(folding_ranges, cell_marker, start.row, &comment_line); |
93 | 97 | },
|
94 | 98 | _ => (),
|
95 | 99 | }
|
@@ -168,42 +172,13 @@ fn comment_range(start_line: usize, end_line: usize) -> FoldingRange {
|
168 | 172 | }
|
169 | 173 | }
|
170 | 174 |
|
171 |
| -fn get_line_text( |
172 |
| - document: &Document, |
173 |
| - line_num: usize, |
174 |
| - start_char: Option<usize>, |
175 |
| - end_char: Option<usize>, |
176 |
| -) -> String { |
177 |
| - let text = &document.contents; |
178 |
| - // Split the text into lines |
179 |
| - let lines: Vec<&str> = text.lines().filter_map(|line| line.as_str()).collect(); |
180 |
| - |
181 |
| - // Ensure the start_line is within bounds |
182 |
| - if line_num >= lines.len() { |
183 |
| - return String::new(); // Return an empty string if out of bounds |
184 |
| - } |
185 |
| - |
186 |
| - // Get the line corresponding to start_line |
187 |
| - let line = lines[line_num]; |
188 |
| - |
189 |
| - // Determine the start and end character indices |
190 |
| - let start_idx = start_char.unwrap_or(0); // Default to 0 if None |
191 |
| - let end_idx = end_char.unwrap_or(line.len()); // Default to the line's length if None |
192 |
| - |
193 |
| - // Ensure indices are within bounds for the line |
194 |
| - let start_idx = start_idx.min(line.len()); |
195 |
| - let end_idx = end_idx.min(line.len()); |
196 |
| - |
197 |
| - // Extract the substring and return it |
198 |
| - line[start_idx..end_idx].to_string() |
199 |
| -} |
200 |
| - |
201 | 175 | fn count_leading_whitespaces(document: &Document, line_num: usize) -> usize {
|
202 |
| - let line_text = get_line_text(document, line_num, None, None); |
203 |
| - line_text |
204 |
| - .as_bytes() |
205 |
| - .iter() |
206 |
| - .take_while(|&&b| b == b' ' || b == b'\t') |
| 176 | + let Some(line) = document.contents.get_line(line_num) else { |
| 177 | + return 0; |
| 178 | + }; |
| 179 | + |
| 180 | + line.bytes() |
| 181 | + .take_while(|&b| b == b' ' || b == b'\t') |
207 | 182 | .count()
|
208 | 183 | }
|
209 | 184 |
|
|
0 commit comments