Skip to main content

merman_editor_core/
snapshot.rs

1use crate::types::{DocumentKind, DocumentUri, Position};
2use merman_analysis::{
3    FenceDelimiter, FenceTextIndex, SharedTextSlice, SourceDescriptor, SourceMap,
4};
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
8pub struct DocumentSnapshot {
9    pub uri: DocumentUri,
10    pub version: i32,
11    pub kind: DocumentKind,
12    pub source: SourceDescriptor,
13    pub text: Arc<str>,
14    pub source_map: SourceMap,
15    pub fences: Vec<FenceSnapshot>,
16}
17
18#[derive(Debug, Clone)]
19pub struct FenceSnapshot {
20    pub source_id: String,
21    pub index: usize,
22    pub source: SourceDescriptor,
23    pub start: usize,
24    pub body_start: usize,
25    pub body_end: usize,
26    pub end: usize,
27    pub text: SharedTextSlice,
28    pub fence_delimiter: Option<FenceDelimiter>,
29    pub diagram_type: Option<String>,
30    pub text_index: FenceTextIndex,
31}
32
33impl DocumentSnapshot {
34    pub fn byte_offset_for_position(&self, position: Position) -> Option<usize> {
35        self.source_map
36            .byte_offset_for_utf16_position(merman_analysis::Utf16Position {
37                line: position.line,
38                character: position.character,
39            })
40    }
41
42    pub fn fence_at_position(&self, position: Position) -> Option<&FenceSnapshot> {
43        let offset = self.byte_offset_for_position(position)?;
44
45        self.fences
46            .iter()
47            .find(|fence| fence.includes_document_offset(offset))
48    }
49}
50
51impl FenceSnapshot {
52    fn includes_document_offset(&self, offset: usize) -> bool {
53        if offset < self.start {
54            return false;
55        }
56        offset < self.end || (offset == self.end && self.includes_end_offset())
57    }
58
59    fn includes_end_offset(&self) -> bool {
60        self.fence_delimiter.is_none() || self.end == self.body_end
61    }
62}