Skip to main content

lutra_compiler/codespan/
edit.rs

1pub struct TextEdit {
2    pub span: crate::Span,
3    pub new_text: String,
4}
5
6/// Apply edits to the source code
7pub fn apply_text_edits(text: &str, edits: &[TextEdit]) -> String {
8    let mut out = String::new();
9    let mut current_offset: usize = 0;
10
11    for edit in edits {
12        assert!(
13            current_offset <= edit.span.start as usize,
14            "[TextEdit]s are not ordered"
15        );
16
17        let start = (edit.span.start as usize).min(text.len());
18        let end = (edit.span.end() as usize).min(text.len());
19
20        out += &text[current_offset..start];
21        out += &edit.new_text;
22        current_offset = end;
23    }
24    out += &text[current_offset..];
25    out
26}
27
28/// Drop text edits that do not change the source.
29pub fn minimize_text_edits(text: &str, edits: Vec<TextEdit>) -> Vec<TextEdit> {
30    edits
31        .into_iter()
32        .filter(|e| {
33            let old_text = e.span.get_slice(text);
34            old_text != e.new_text
35        })
36        .collect()
37}
38
39/// Apply an offset to span of each edit
40pub fn offset_text_edits(edits: Vec<TextEdit>, offset: i32) -> Vec<TextEdit> {
41    edits
42        .into_iter()
43        .map(|mut e| {
44            e.span.start = if 0 <= offset {
45                e.span.start.saturating_add(offset as u32)
46            } else {
47                e.span.start.saturating_sub((-offset) as u32)
48            };
49            e
50        })
51        .collect()
52}