1use neophyte_ui_event::{CmdlineShow, CmdlineSpecialChar, Content};
2
3#[derive(Debug, Clone, Default)]
4pub struct Cmdline {
5 pub mode: Option<Mode>,
6}
7
8impl Cmdline {
9 pub fn show(&mut self, event: CmdlineShow) {
10 let i = event.level as usize;
11 let level = event.into();
12 match &mut self.mode {
13 Some(Mode::Normal { levels }) => {
14 if i > levels.len() {
15 levels.push(level);
16 } else {
17 levels[i - 1] = level;
18 }
19 }
20 Some(Mode::Block {
21 previous_lines: _,
22 current_line,
23 }) => {
24 *current_line = level;
25 }
26 None => {
27 self.mode = Some(Mode::Normal {
28 levels: vec![level],
29 })
30 }
31 }
32 }
33
34 pub fn hide(&mut self) {
35 if let Some(Mode::Normal { levels }) = &mut self.mode {
36 match levels.len() {
37 0 | 1 => {
38 self.mode = None;
39 }
40 _ => {
41 levels.pop();
42 }
43 }
44 }
45 }
46
47 pub fn hide_block(&mut self) {
48 self.mode = None;
49 }
50
51 pub fn show_block(&mut self, lines: Vec<Content>) {
52 self.mode = Some(Mode::Block {
53 previous_lines: lines,
54 current_line: Default::default(),
56 });
57 }
58
59 pub fn append_block(&mut self, line: Content) {
60 if let Some(Mode::Block {
61 previous_lines,
62 current_line,
63 }) = &mut self.mode
64 {
65 previous_lines.push(line);
66 *current_line = Default::default();
68 }
69 }
70
71 pub fn set_cursor_pos(&mut self, pos: u32) {
72 match &mut self.mode {
73 Some(Mode::Normal { levels }) => {
74 if let Some(level) = levels.last_mut() {
75 level.cursor_pos = pos;
76 }
77 }
78 Some(Mode::Block {
79 previous_lines: _,
80 current_line,
81 }) => {
82 current_line.cursor_pos = pos;
83 }
84 None => {}
85 }
86 }
87
88 pub fn special(&mut self, event: CmdlineSpecialChar) {
89 let special = Some(Special::new(event.c, event.shift));
90 match &mut self.mode {
91 Some(Mode::Normal { levels }) => {
92 if let Some(level) = levels.last_mut() {
93 level.special = special;
94 }
95 }
96 Some(Mode::Block {
97 previous_lines: _,
98 current_line,
99 }) => {
100 current_line.special = special;
101 }
102 None => {}
103 }
104 }
105}
106
107#[derive(Debug, Clone)]
108pub enum Mode {
109 Normal {
110 levels: Vec<Prompt>,
111 },
112 Block {
113 previous_lines: Vec<Content>,
114 current_line: Prompt,
115 },
116}
117
118#[derive(Debug, Clone, Default)]
119pub struct Prompt {
120 pub content_lines: Vec<Content>,
121 pub cursor_pos: u32,
122 pub first_char: Option<char>,
123 pub prompt: String,
124 pub special: Option<Special>,
125 #[allow(unused)]
126 pub indent: u32,
127}
128
129impl From<CmdlineShow> for Prompt {
130 fn from(value: CmdlineShow) -> Self {
131 Self {
132 content_lines: vec![value.content],
133 cursor_pos: value.pos,
134 first_char: value.firstc.chars().next(),
135 prompt: value.prompt,
136 special: None,
137 indent: value.indent,
138 }
139 }
140}
141
142#[derive(Debug, Clone)]
143pub struct Special {
144 #[allow(unused)]
145 pub c: char,
146 #[allow(unused)]
147 pub shift: bool,
148}
149
150impl Special {
151 pub fn new(c: char, shift: bool) -> Self {
152 Self { c, shift }
153 }
154}