Scan trivia for doc-block comments and groups of consecutive single-line comments, emitting `FoldingRange` entries with `FoldingRangeKind::Comment`.
(
trivia: &sequence::Sequence<'_, Trivia<'_>>,
content: &str,
ranges: &mut Vec<FoldingRange>,
)
| 788 | /// Scan trivia for doc-block comments and groups of consecutive single-line |
| 789 | /// comments, emitting `FoldingRange` entries with `FoldingRangeKind::Comment`. |
| 790 | fn collect_comment_ranges( |
| 791 | trivia: &sequence::Sequence<'_, Trivia<'_>>, |
| 792 | content: &str, |
| 793 | ranges: &mut Vec<FoldingRange>, |
| 794 | ) { |
| 795 | // ── Doc-block and multi-line comments ── |
| 796 | for t in trivia.iter() { |
| 797 | if matches!( |
| 798 | t.kind, |
| 799 | TriviaKind::DocBlockComment | TriviaKind::MultiLineComment |
| 800 | ) { |
| 801 | let start_pos = offset_to_position(content, t.span.start.offset as usize); |
| 802 | let end_pos = offset_to_position(content, t.span.end.offset as usize); |
| 803 | if start_pos.line < end_pos.line { |
| 804 | ranges.push(FoldingRange { |
| 805 | start_line: start_pos.line, |
| 806 | start_character: Some(start_pos.character), |
| 807 | end_line: end_pos.line, |
| 808 | end_character: Some(end_pos.character), |
| 809 | kind: Some(FoldingRangeKind::Comment), |
| 810 | collapsed_text: None, |
| 811 | }); |
| 812 | } |
| 813 | } |
| 814 | } |
| 815 | |
| 816 | // ── Consecutive single-line comments (`//` or `#`) ── |
| 817 | // Group adjacent single-line comment trivia whose lines differ by |
| 818 | // exactly 1 (allowing interleaved whitespace trivia). |
| 819 | let single_line_comments: Vec<&Trivia<'_>> = trivia |
| 820 | .iter() |
| 821 | .filter(|t| t.kind.is_single_line_comment()) |
| 822 | .collect(); |
| 823 | |
| 824 | if single_line_comments.is_empty() { |
| 825 | return; |
| 826 | } |
| 827 | |
| 828 | let mut group_start_offset = single_line_comments[0].span.start.offset; |
| 829 | let mut group_end_offset = single_line_comments[0].span.end.offset; |
| 830 | let mut group_start_line = offset_to_position(content, group_start_offset as usize).line; |
| 831 | let mut group_end_line = offset_to_position(content, group_end_offset as usize).line; |
| 832 | |
| 833 | for t in single_line_comments.iter().skip(1) { |
| 834 | let cur_line = offset_to_position(content, t.span.start.offset as usize).line; |
| 835 | if cur_line == group_end_line + 1 { |
| 836 | // Extend the current group. |
| 837 | group_end_offset = t.span.end.offset; |
| 838 | group_end_line = offset_to_position(content, group_end_offset as usize).line; |
| 839 | } else { |
| 840 | // Flush the previous group if it spans multiple lines. |
| 841 | if group_start_line < group_end_line { |
| 842 | let start_char = offset_to_position(content, group_start_offset as usize).character; |
| 843 | let end_char = offset_to_position(content, group_end_offset as usize).character; |
| 844 | ranges.push(FoldingRange { |
| 845 | start_line: group_start_line, |
| 846 | start_character: Some(start_char), |
| 847 | end_line: group_end_line, |
no test coverage detected