reovim_kernel/api/
debug.rs1use crate::{
16 core::{MarkBank, ModeStack, RegisterBank, SpecialMark, YankType},
17 mm::{BufferId, Position},
18};
19
20use super::context::KernelContext;
21
22#[derive(Debug, Clone)]
28pub struct KernelStateSnapshot {
29 pub buffer_count: usize,
31 pub buffer_ids: Vec<BufferId>,
33 pub event_handlers: usize,
35 pub event_queue_len: usize,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum YankTypeSnapshot {
42 Characterwise,
44 Linewise,
46}
47
48impl From<YankType> for YankTypeSnapshot {
49 fn from(yt: YankType) -> Self {
50 match yt {
51 YankType::Characterwise => Self::Characterwise,
52 YankType::Linewise => Self::Linewise,
53 }
54 }
55}
56
57#[derive(Debug, Clone)]
59pub struct RegisterSnapshot {
60 pub name: char,
62 pub text: String,
64 pub yank_type: YankTypeSnapshot,
66}
67
68#[derive(Debug, Clone)]
70pub struct RegistersSnapshot {
71 pub unnamed: RegisterSnapshot,
73 pub named: Vec<RegisterSnapshot>,
75}
76
77#[derive(Debug, Clone)]
79pub struct MarkSnapshot {
80 pub name: String,
82 pub position: Position,
84 pub buffer_id: Option<BufferId>,
86}
87
88#[derive(Debug, Clone)]
90pub struct MarksSnapshot {
91 pub local: Vec<MarkSnapshot>,
93 pub global: Vec<MarkSnapshot>,
95 pub special: Vec<MarkSnapshot>,
97}
98
99#[derive(Debug, Clone)]
101pub struct ModeStackSnapshot {
102 pub current: String,
104 pub stack: Vec<String>,
106 pub depth: usize,
108}
109
110#[must_use]
116pub fn snapshot_kernel_state(ctx: &KernelContext) -> KernelStateSnapshot {
117 let buffer_ids = ctx.buffers.list();
118 let buffer_count = buffer_ids.len();
119
120 KernelStateSnapshot {
121 buffer_count,
122 buffer_ids,
123 event_handlers: ctx.event_bus.total_handler_count(),
124 event_queue_len: ctx.event_bus.queue_len(),
125 }
126}
127
128#[must_use]
130#[cfg_attr(coverage_nightly, coverage(off))]
131pub fn snapshot_registers(bank: &RegisterBank) -> RegistersSnapshot {
132 let unnamed_content = bank.get();
134 let unnamed = RegisterSnapshot {
135 name: '"',
136 text: unnamed_content.text.clone(),
137 yank_type: unnamed_content.yank_type.into(),
138 };
139
140 let mut named = Vec::new();
142 for c in 'a'..='z' {
143 if let Some(content) = bank.get_named(c)
144 && !content.text.is_empty()
145 {
146 named.push(RegisterSnapshot {
147 name: c,
148 text: content.text.clone(),
149 yank_type: content.yank_type.into(),
150 });
151 }
152 }
153
154 RegistersSnapshot { unnamed, named }
155}
156
157#[must_use]
159pub fn snapshot_marks(bank: &MarkBank) -> MarksSnapshot {
160 let local: Vec<MarkSnapshot> = bank
162 .list_local()
163 .into_iter()
164 .map(|(name, pos)| MarkSnapshot {
165 name: name.to_string(),
166 position: pos,
167 buffer_id: None,
168 })
169 .collect();
170
171 let global: Vec<MarkSnapshot> = bank
173 .list_global()
174 .into_iter()
175 .map(|(name, mark)| MarkSnapshot {
176 name: name.to_string(),
177 position: mark.position,
178 buffer_id: Some(mark.buffer_id),
179 })
180 .collect();
181
182 let special_marks = [
184 (SpecialMark::LastJump, "'"),
185 (SpecialMark::LastEdit, "."),
186 (SpecialMark::LastInsert, "^"),
187 (SpecialMark::VisualStart, "<"),
188 (SpecialMark::VisualEnd, ">"),
189 (SpecialMark::LastExitInsert, "]"),
190 ];
191
192 let special: Vec<MarkSnapshot> = special_marks
193 .iter()
194 .filter_map(|(mark_type, name)| {
195 bank.get_special(*mark_type).map(|mark| MarkSnapshot {
196 name: (*name).to_string(),
197 position: mark.position,
198 buffer_id: Some(mark.buffer_id),
199 })
200 })
201 .collect();
202
203 MarksSnapshot {
204 local,
205 global,
206 special,
207 }
208}
209
210#[must_use]
212pub fn snapshot_mode_stack(stack: &ModeStack) -> ModeStackSnapshot {
213 let current = stack.current().to_string();
214 let depth = stack.depth();
215
216 let stack_vec: Vec<String> = stack.as_slice().iter().map(ToString::to_string).collect();
218
219 ModeStackSnapshot {
220 current,
221 stack: stack_vec,
222 depth,
223 }
224}