Apply TextEdits to content (edits are assumed to be non-overlapping and will be applied from bottom to top to preserve positions).
(content: &str, edits: &[TextEdit])
| 848 | /// Apply TextEdits to content (edits are assumed to be non-overlapping |
| 849 | /// and will be applied from bottom to top to preserve positions). |
| 850 | fn apply_edits(content: &str, edits: &[TextEdit]) -> String { |
| 851 | let mut result = content.to_string(); |
| 852 | // Sort edits in reverse document order so earlier edits don't |
| 853 | // shift positions of later ones. |
| 854 | let mut sorted: Vec<&TextEdit> = edits.iter().collect(); |
| 855 | sorted.sort_by(|a, b| { |
| 856 | b.range |
| 857 | .start |
| 858 | .line |
| 859 | .cmp(&a.range.start.line) |
| 860 | .then(b.range.start.character.cmp(&a.range.start.character)) |
| 861 | }); |
| 862 | for edit in sorted { |
| 863 | let start = position_to_byte_offset(&result, edit.range.start); |
| 864 | let end = position_to_byte_offset(&result, edit.range.end); |
| 865 | result.replace_range(start..end, &edit.new_text); |
| 866 | } |
| 867 | result |
| 868 | } |
| 869 | |
| 870 | // ── Basic inline ──────────────────────────────────────────────── |
| 871 |