strop_engine/editor/trace/
mod.rs1pub mod drive;
4#[cfg(test)]
5pub(crate) mod model;
6pub mod seed;
7pub mod services;
8mod snapshot;
9
10#[cfg(test)]
11mod generated;
12#[cfg(test)]
13mod tests;
14
15use super::{Editor, Key};
16use serde::Serialize;
17use std::cell::Cell;
18use strop_trace::{enabled, record, EventKind};
19thread_local! { static INPUT_DEPTH: Cell<usize> = const { Cell::new(0) }; }
20
21pub struct InputScope;
22impl InputScope {
23 pub fn enter(editor: &Editor, key: Key) -> Option<Self> {
24 if !enabled() {
25 return None;
26 }
27 let depth = INPUT_DEPTH.with(|value| {
28 let depth = value.get();
29 value.set(depth + 1);
30 depth
31 });
32 #[derive(Serialize)]
33 struct Input {
34 action: &'static str,
35 source: InputSource,
36 key: Key,
37 replay: String,
38 }
39 let source = if editor.macro_depth > 0 {
40 InputSource::Macro
41 } else if depth > 0 {
42 InputSource::Synthetic
43 } else {
44 InputSource::External
45 };
46 record(
47 EventKind::Input,
48 &Input {
49 action: "key",
50 source,
51 key,
52 replay: replay_token(key),
53 },
54 );
55 Some(Self)
56 }
57}
58impl Drop for InputScope {
59 fn drop(&mut self) {
60 INPUT_DEPTH.with(|value| value.set(value.get().saturating_sub(1)));
61 }
62}
63#[derive(Serialize)]
64#[serde(rename_all = "snake_case")]
65enum InputSource {
66 External,
67 Synthetic,
68 Macro,
69}
70
71pub fn replay_token(key: Key) -> String {
72 match key {
73 Key::Char('<') => "<lt>".into(),
74 Key::Char('>') => "<gt>".into(),
75 Key::Char(c) => c.to_string(),
76 Key::Esc => "<esc>".into(),
77 Key::CtrlSpace => "<c-space>".into(),
78 Key::Enter => "<cr>".into(),
79 Key::Backspace => "<bs>".into(),
80 Key::Up => "<up>".into(),
81 Key::Down => "<down>".into(),
82 Key::Left => "<left>".into(),
83 Key::Right => "<right>".into(),
84 Key::Tab => "<tab>".into(),
85 Key::Backtab => "<s-tab>".into(),
86 Key::CtrlD => "<c-d>".into(),
87 Key::CtrlR => "<c-r>".into(),
88 Key::CtrlO => "<c-o>".into(),
89 Key::CtrlW => "<c-w>".into(),
90 Key::CtrlX => "<c-x>".into(),
91 Key::CtrlU => "<c-u>".into(),
92 Key::CtrlF => "<c-f>".into(),
93 Key::CtrlB => "<c-b>".into(),
94 Key::CtrlCaret => "<c-^>".into(),
95 Key::CtrlV => "<c-v>".into(),
96 Key::CtrlL => "<c-l>".into(),
97 }
98}