xref: /Held/src/utils/ui/uicore.rs (revision fcc6ced0d18453415ce4b88b047a4e8e424fc693)
1984a200eSGnoCiYeH use std::{
2984a200eSGnoCiYeH     io,
3984a200eSGnoCiYeH     sync::{atomic::AtomicU16, Arc, Mutex, MutexGuard, Once, RwLock, Weak},
4984a200eSGnoCiYeH };
5984a200eSGnoCiYeH 
6984a200eSGnoCiYeH use crossterm::{
7984a200eSGnoCiYeH     style::Color,
8984a200eSGnoCiYeH     terminal::{self},
9984a200eSGnoCiYeH };
10984a200eSGnoCiYeH use lazy_static::lazy_static;
11984a200eSGnoCiYeH 
12984a200eSGnoCiYeH use crate::{
13984a200eSGnoCiYeH     config::appconfig::AppSetting,
14984a200eSGnoCiYeH     utils::{
15984a200eSGnoCiYeH         buffer::EditBuffer, cursor::CursorCrtl, style::StyleManager, terminal::TermManager,
16984a200eSGnoCiYeH         ui::InfoLevel,
17984a200eSGnoCiYeH     },
18984a200eSGnoCiYeH };
19984a200eSGnoCiYeH 
20984a200eSGnoCiYeH #[cfg(feature = "dragonos")]
21984a200eSGnoCiYeH use crate::utils::input::Input;
22984a200eSGnoCiYeH 
23984a200eSGnoCiYeH use super::{
24984a200eSGnoCiYeH     mode::mode::{Command, InputMode, Insert, LastLine, ModeType},
25*fcc6ced0SZ YS     mode::normal::Normal,
26984a200eSGnoCiYeH     AppInfo,
27984a200eSGnoCiYeH };
28984a200eSGnoCiYeH 
29984a200eSGnoCiYeH lazy_static! {
30984a200eSGnoCiYeH     static ref COMMAND: Arc<Command> = Arc::new(Command);
31984a200eSGnoCiYeH     static ref INSERT: Arc<Insert> = Arc::new(Insert);
32984a200eSGnoCiYeH     static ref LASTLINE: Arc<LastLine> = Arc::new(LastLine::new());
33*fcc6ced0SZ YS     static ref NORMAL: Arc<Normal> = Arc::new(Normal::new());
34984a200eSGnoCiYeH     pub static ref APP_INFO: Mutex<AppInfo> = Mutex::new(AppInfo {
35984a200eSGnoCiYeH         level: InfoLevel::Info,
36984a200eSGnoCiYeH         info: String::new()
37984a200eSGnoCiYeH     });
38984a200eSGnoCiYeH }
39984a200eSGnoCiYeH 
40984a200eSGnoCiYeH pub static TAB_SIZE: AtomicU16 = AtomicU16::new(4);
41984a200eSGnoCiYeH 
42984a200eSGnoCiYeH #[derive(Debug, Clone, Copy)]
43984a200eSGnoCiYeH pub struct WinSize {
44984a200eSGnoCiYeH     pub cols: u16,
45984a200eSGnoCiYeH     pub rows: u16,
46984a200eSGnoCiYeH }
47984a200eSGnoCiYeH 
48984a200eSGnoCiYeH #[derive(Debug)]
49984a200eSGnoCiYeH pub struct UiCore {
50984a200eSGnoCiYeH     pub buffer: Arc<EditBuffer>,
51984a200eSGnoCiYeH     pub cursor: CursorCrtl,
52984a200eSGnoCiYeH 
53984a200eSGnoCiYeH     #[allow(dead_code)]
54984a200eSGnoCiYeH     setting: AppSetting,
55984a200eSGnoCiYeH     container: Weak<Ui>,
56984a200eSGnoCiYeH 
57984a200eSGnoCiYeH     edited: bool,
58984a200eSGnoCiYeH     edited_once: Once,
59984a200eSGnoCiYeH }
60984a200eSGnoCiYeH 
61984a200eSGnoCiYeH impl UiCore {
new(buf: Arc<EditBuffer>, cursor: CursorCrtl, setting: AppSetting) -> Self62984a200eSGnoCiYeH     pub fn new(buf: Arc<EditBuffer>, cursor: CursorCrtl, setting: AppSetting) -> Self {
63984a200eSGnoCiYeH         Self {
64984a200eSGnoCiYeH             buffer: buf,
65984a200eSGnoCiYeH             cursor,
66984a200eSGnoCiYeH             container: Weak::new(),
67984a200eSGnoCiYeH             setting,
68984a200eSGnoCiYeH             edited: false,
69984a200eSGnoCiYeH             edited_once: Once::new(),
70984a200eSGnoCiYeH         }
71984a200eSGnoCiYeH     }
72984a200eSGnoCiYeH 
edited(&self) -> bool73984a200eSGnoCiYeH     pub fn edited(&self) -> bool {
74984a200eSGnoCiYeH         self.edited
75984a200eSGnoCiYeH     }
76984a200eSGnoCiYeH 
set_edited(&mut self)77984a200eSGnoCiYeH     pub fn set_edited(&mut self) {
78984a200eSGnoCiYeH         self.edited_once.call_once(|| self.edited = true)
79984a200eSGnoCiYeH     }
80984a200eSGnoCiYeH 
update_bottom_state_bar(&mut self) -> io::Result<()>81984a200eSGnoCiYeH     pub fn update_bottom_state_bar(&mut self) -> io::Result<()> {
82984a200eSGnoCiYeH         let container = self.container.upgrade().unwrap();
83984a200eSGnoCiYeH         let mode = container.mode.read().unwrap().mode_type();
84984a200eSGnoCiYeH         if mode == ModeType::LastLine {
85984a200eSGnoCiYeH             return Ok(());
86984a200eSGnoCiYeH         }
87984a200eSGnoCiYeH 
88984a200eSGnoCiYeH         let size = *WINSIZE.read().unwrap();
89984a200eSGnoCiYeH 
90984a200eSGnoCiYeH         let store_x = self.cursor.x();
91984a200eSGnoCiYeH         let store_y = self.cursor.y();
92984a200eSGnoCiYeH 
93984a200eSGnoCiYeH         self.cursor.set_prefix_mode(false);
94984a200eSGnoCiYeH 
95984a200eSGnoCiYeH         DEF_STYLE.read().unwrap().set_cmd_style()?;
96984a200eSGnoCiYeH         let cmd_y = size.rows - 1;
97984a200eSGnoCiYeH         self.cursor.move_to_row(cmd_y)?;
98984a200eSGnoCiYeH         self.cursor.clear_current_line()?;
99984a200eSGnoCiYeH         self.cursor
100984a200eSGnoCiYeH             .write_with_pos(format!("{mode:?}"), 0, cmd_y, false)?;
101984a200eSGnoCiYeH 
102984a200eSGnoCiYeH         let (buf_x, buf_y) = (store_x, store_y + 1 + self.buffer.offset() as u16);
103984a200eSGnoCiYeH         let index_info = format!("row:{buf_y} col:{buf_x}");
104984a200eSGnoCiYeH         let len = index_info.len() as u16;
105984a200eSGnoCiYeH         self.cursor
106984a200eSGnoCiYeH             .write_with_pos(index_info, size.cols - len, cmd_y, false)?;
107984a200eSGnoCiYeH 
108984a200eSGnoCiYeH         self.cursor.set_prefix_mode(true);
109984a200eSGnoCiYeH         self.cursor.move_to(store_x, store_y)?;
110984a200eSGnoCiYeH 
111984a200eSGnoCiYeH         let mut info = APP_INFO.lock().unwrap();
112984a200eSGnoCiYeH         info.level.set_style()?;
113984a200eSGnoCiYeH         self.cursor
114984a200eSGnoCiYeH             .write_with_pos(&info.info, size.cols / 3, cmd_y, false)?;
115984a200eSGnoCiYeH 
116984a200eSGnoCiYeH         info.reset();
117984a200eSGnoCiYeH         self.cursor.move_to(store_x, store_y)?;
118984a200eSGnoCiYeH 
119984a200eSGnoCiYeH         StyleManager::reset_color()?;
120984a200eSGnoCiYeH 
121984a200eSGnoCiYeH         Ok(())
122984a200eSGnoCiYeH     }
123984a200eSGnoCiYeH 
124984a200eSGnoCiYeH     /// 渲染部分文件内容,从y行开始渲染count行
125984a200eSGnoCiYeH     /// 返回实际渲染行数
render_content(&mut self, mut y: u16, mut count: usize) -> io::Result<usize>126984a200eSGnoCiYeH     pub fn render_content(&mut self, mut y: u16, mut count: usize) -> io::Result<usize> {
127984a200eSGnoCiYeH         y += UI_HEAD_OFFSET;
128984a200eSGnoCiYeH         let content_winsize = *CONTENT_WINSIZE.read().unwrap();
129984a200eSGnoCiYeH 
130984a200eSGnoCiYeH         // 超出正文范围
131984a200eSGnoCiYeH         if y + count as u16 > content_winsize.rows {
132984a200eSGnoCiYeH             count = (content_winsize.rows - y) as usize;
133984a200eSGnoCiYeH         }
134984a200eSGnoCiYeH 
135984a200eSGnoCiYeH         let def_style = *DEF_STYLE.read().unwrap();
136984a200eSGnoCiYeH 
137984a200eSGnoCiYeH         let content = self.buffer.get_content(y as usize, count);
138984a200eSGnoCiYeH 
139984a200eSGnoCiYeH         if content.is_none() {
140984a200eSGnoCiYeH             return Ok(0);
141984a200eSGnoCiYeH         }
142984a200eSGnoCiYeH         let content = content.unwrap();
143984a200eSGnoCiYeH 
144984a200eSGnoCiYeH         // 保存光标
145984a200eSGnoCiYeH         let pos = self.cursor.store_tmp_pos();
146984a200eSGnoCiYeH 
147984a200eSGnoCiYeH         let tmp = y;
148984a200eSGnoCiYeH 
149984a200eSGnoCiYeH         let num_len = (tmp + content_winsize.rows).to_string().len();
150984a200eSGnoCiYeH 
151984a200eSGnoCiYeH         self.cursor.set_prefix_mode(false);
152984a200eSGnoCiYeH         for line in content.iter() {
153984a200eSGnoCiYeH             let str = String::from_utf8_lossy(&line.data).to_string();
154984a200eSGnoCiYeH             def_style.set_content_style()?;
155984a200eSGnoCiYeH 
156984a200eSGnoCiYeH             // 移动
157984a200eSGnoCiYeH             self.cursor
158984a200eSGnoCiYeH                 .move_to(num_len as u16 + 2 + CursorCrtl::PREFIX_COL, y)?;
159984a200eSGnoCiYeH             self.cursor.clear_current_line()?;
160984a200eSGnoCiYeH             self.cursor.write(str)?;
161984a200eSGnoCiYeH             y += 1;
162984a200eSGnoCiYeH             StyleManager::reset_color()?;
163984a200eSGnoCiYeH         }
164984a200eSGnoCiYeH 
165984a200eSGnoCiYeH         self.cursor.update_line_prefix(&content, tmp, num_len)?;
166984a200eSGnoCiYeH         self.cursor.set_prefix_mode(true);
167984a200eSGnoCiYeH 
168984a200eSGnoCiYeH         self.cursor.restore_tmp_pos(pos)?;
169984a200eSGnoCiYeH 
170984a200eSGnoCiYeH         self.cursor.highlight(None)?;
171984a200eSGnoCiYeH 
172984a200eSGnoCiYeH         Ok(content.len())
173984a200eSGnoCiYeH     }
174984a200eSGnoCiYeH 
175984a200eSGnoCiYeH     // 将正文向上滚动count行
scroll_up(&mut self, mut count: u16) -> io::Result<()>176984a200eSGnoCiYeH     pub fn scroll_up(&mut self, mut count: u16) -> io::Result<()> {
177984a200eSGnoCiYeH         let winsize = *CONTENT_WINSIZE.read().unwrap();
178984a200eSGnoCiYeH 
179984a200eSGnoCiYeH         let pos = self.cursor.store_tmp_pos();
180984a200eSGnoCiYeH 
181984a200eSGnoCiYeH         // 计算最多还能滚动多少行
182984a200eSGnoCiYeH         let offset = self.buffer.offset();
183984a200eSGnoCiYeH 
184984a200eSGnoCiYeH         // 最多出两行
185984a200eSGnoCiYeH         let linecount = self.buffer.line_count();
186984a200eSGnoCiYeH         if offset + winsize.rows as usize + count as usize >= linecount {
187984a200eSGnoCiYeH             count = linecount as u16 - offset as u16 - winsize.rows;
188984a200eSGnoCiYeH         }
189984a200eSGnoCiYeH         self.buffer.set_offset(offset + count as usize);
190984a200eSGnoCiYeH         // 将光标移动到滚动后的位置
191984a200eSGnoCiYeH         self.cursor.move_to_row(winsize.rows - count)?;
192984a200eSGnoCiYeH 
193984a200eSGnoCiYeH         // 执行滚动
194984a200eSGnoCiYeH         TermManager::scroll_up(count)?;
195984a200eSGnoCiYeH 
196984a200eSGnoCiYeH         // 清除光标以下的内容
197984a200eSGnoCiYeH         TermManager::clear_under_cursor()?;
198984a200eSGnoCiYeH 
199984a200eSGnoCiYeH         // 渲染count行数据
200984a200eSGnoCiYeH         self.render_content(self.cursor.y(), count as usize)?;
201984a200eSGnoCiYeH 
202984a200eSGnoCiYeH         self.cursor.restore_tmp_pos(pos)?;
203984a200eSGnoCiYeH 
204984a200eSGnoCiYeH         self.cursor.highlight(Some(self.cursor.y() - count))?;
205984a200eSGnoCiYeH         Ok(())
206984a200eSGnoCiYeH     }
207984a200eSGnoCiYeH 
scroll_down(&mut self, mut count: u16) -> io::Result<()>208984a200eSGnoCiYeH     pub fn scroll_down(&mut self, mut count: u16) -> io::Result<()> {
209984a200eSGnoCiYeH         let pos = self.cursor.store_tmp_pos();
210984a200eSGnoCiYeH 
211984a200eSGnoCiYeH         // 计算最多还能滚动多少行
212984a200eSGnoCiYeH         let offset = self.buffer.offset();
213984a200eSGnoCiYeH         if offset < count as usize {
214984a200eSGnoCiYeH             count = offset as u16;
215984a200eSGnoCiYeH         }
216984a200eSGnoCiYeH 
217984a200eSGnoCiYeH         self.buffer.set_offset(offset - count as usize);
218984a200eSGnoCiYeH 
219984a200eSGnoCiYeH         // 执行滚动
220984a200eSGnoCiYeH         TermManager::scroll_down(count)?;
221984a200eSGnoCiYeH 
222ec52bc29SZ YS         // 将光标移动第count行
223984a200eSGnoCiYeH         self.cursor.move_to_row(count - 1)?;
224984a200eSGnoCiYeH         // 清除光标以上的内容
225984a200eSGnoCiYeH         TermManager::clear_up_cursor()?;
226984a200eSGnoCiYeH 
227984a200eSGnoCiYeH         // 渲染count行数据
228984a200eSGnoCiYeH         self.render_content(0, count as usize)?;
229984a200eSGnoCiYeH 
230984a200eSGnoCiYeH         self.cursor.restore_tmp_pos(pos)?;
231984a200eSGnoCiYeH 
232984a200eSGnoCiYeH         self.cursor.highlight(Some(self.cursor.y() + count))?;
233984a200eSGnoCiYeH 
234984a200eSGnoCiYeH         Ok(())
235984a200eSGnoCiYeH     }
236984a200eSGnoCiYeH }
237984a200eSGnoCiYeH 
238984a200eSGnoCiYeH #[derive(Debug)]
239984a200eSGnoCiYeH pub struct Ui {
240984a200eSGnoCiYeH     pub core: Arc<Mutex<UiCore>>,
241984a200eSGnoCiYeH     pub mode: RwLock<Arc<dyn InputMode>>,
242984a200eSGnoCiYeH }
243984a200eSGnoCiYeH 
244984a200eSGnoCiYeH lazy_static! {
245984a200eSGnoCiYeH     pub static ref WINSIZE: RwLock<WinSize> = {
246984a200eSGnoCiYeH         let size = terminal::size().unwrap();
247984a200eSGnoCiYeH         RwLock::new(WinSize {
248984a200eSGnoCiYeH             cols: size.0,
249984a200eSGnoCiYeH             rows: size.1,
250984a200eSGnoCiYeH         })
251984a200eSGnoCiYeH     };
252984a200eSGnoCiYeH     pub static ref CONTENT_WINSIZE: RwLock<WinSize> = {
253984a200eSGnoCiYeH         let size = *WINSIZE.read().unwrap();
254984a200eSGnoCiYeH         RwLock::new(WinSize {
255984a200eSGnoCiYeH             cols: size.cols,
256984a200eSGnoCiYeH             rows: size.rows - UI_CMD_HEIGHT - UI_HEAD_OFFSET,
257984a200eSGnoCiYeH         })
258984a200eSGnoCiYeH     };
259984a200eSGnoCiYeH     pub static ref DEF_STYLE: RwLock<UiStyle> = {
260984a200eSGnoCiYeH         let style = UiStyle {
261984a200eSGnoCiYeH             content_fg: Some(Color::White),
262984a200eSGnoCiYeH             content_bg: None,
263984a200eSGnoCiYeH             cmd_line_fg: Some(Color::White),
264984a200eSGnoCiYeH             cmd_line_bg: Some(Color::DarkCyan),
265984a200eSGnoCiYeH         };
266984a200eSGnoCiYeH 
267984a200eSGnoCiYeH         RwLock::new(style)
268984a200eSGnoCiYeH     };
269984a200eSGnoCiYeH }
270984a200eSGnoCiYeH 
271984a200eSGnoCiYeH pub static UI_HEAD_OFFSET: u16 = 0;
272984a200eSGnoCiYeH pub const UI_CMD_HEIGHT: u16 = 1;
273984a200eSGnoCiYeH 
274984a200eSGnoCiYeH impl Ui {
new(buf: Arc<EditBuffer>, setting: AppSetting) -> Arc<Self>275984a200eSGnoCiYeH     pub fn new(buf: Arc<EditBuffer>, setting: AppSetting) -> Arc<Self> {
276984a200eSGnoCiYeH         let mut cursor = CursorCrtl::new(buf.clone(), setting.line);
277984a200eSGnoCiYeH         cursor.move_to(0, 0).unwrap();
278984a200eSGnoCiYeH 
279984a200eSGnoCiYeH         let core = Arc::new(Mutex::new(UiCore::new(buf, cursor, setting)));
280984a200eSGnoCiYeH         let ret = Arc::new(Self {
281984a200eSGnoCiYeH             mode: RwLock::new(Arc::new(Command)),
282984a200eSGnoCiYeH             core: core.clone(),
283984a200eSGnoCiYeH         });
284984a200eSGnoCiYeH 
285984a200eSGnoCiYeH         core.lock().unwrap().container = Arc::downgrade(&ret);
286984a200eSGnoCiYeH 
287984a200eSGnoCiYeH         ret
288984a200eSGnoCiYeH     }
init_ui() -> io::Result<()>289984a200eSGnoCiYeH     pub fn init_ui() -> io::Result<()> {
290984a200eSGnoCiYeH         TermManager::init_term()?;
291984a200eSGnoCiYeH         Ok(())
292984a200eSGnoCiYeH     }
293984a200eSGnoCiYeH 
start_page_ui(&self) -> io::Result<()>294984a200eSGnoCiYeH     pub fn start_page_ui(&self) -> io::Result<()> {
295984a200eSGnoCiYeH         StyleManager::set_foreground_color(Color::Cyan)?;
296984a200eSGnoCiYeH         let mut core = self.core.lock().unwrap();
297984a200eSGnoCiYeH         core.cursor
298984a200eSGnoCiYeH             .write_with_pos("Held - DragonOS/Linux Term Editor\n", 5, 0, false)?;
299984a200eSGnoCiYeH         StyleManager::set_foreground_color(Color::Green)?;
300984a200eSGnoCiYeH         core.cursor
301984a200eSGnoCiYeH             .write_with_pos("Author: heyicong@dragonos.org\n", 7, 1, false)?;
302984a200eSGnoCiYeH         StyleManager::set_foreground_color(Color::DarkMagenta)?;
303984a200eSGnoCiYeH         core.cursor
304984a200eSGnoCiYeH             .write_with_pos("Type any key to continue ><\n", 8, 2, false)?;
305984a200eSGnoCiYeH         StyleManager::reset_color()?;
306984a200eSGnoCiYeH 
307984a200eSGnoCiYeH         core.cursor.move_to(0, 0)?;
308984a200eSGnoCiYeH 
309984a200eSGnoCiYeH         #[cfg(feature = "dragonos")]
310984a200eSGnoCiYeH         let _ = Input::wait_keydown();
311984a200eSGnoCiYeH 
312984a200eSGnoCiYeH         #[cfg(not(feature = "dragonos"))]
313984a200eSGnoCiYeH         loop {
314984a200eSGnoCiYeH             let ev = crossterm::event::read()?;
315984a200eSGnoCiYeH             if let crossterm::event::Event::Key(_) = ev {
316984a200eSGnoCiYeH                 break;
317984a200eSGnoCiYeH             }
318984a200eSGnoCiYeH         }
319984a200eSGnoCiYeH 
320984a200eSGnoCiYeH         TermManager::clear_all()?;
321984a200eSGnoCiYeH 
322984a200eSGnoCiYeH         Ok(())
323984a200eSGnoCiYeH     }
324984a200eSGnoCiYeH 
ui_loop(&self) -> io::Result<bool>325984a200eSGnoCiYeH     pub fn ui_loop(&self) -> io::Result<bool> {
326984a200eSGnoCiYeH         let mut core = self.core.lock().unwrap();
327984a200eSGnoCiYeH         core.render_content(0, CONTENT_WINSIZE.read().unwrap().rows as usize)?;
328984a200eSGnoCiYeH         core.update_bottom_state_bar()?;
329984a200eSGnoCiYeH         core.cursor.move_to(0, 0)?;
330984a200eSGnoCiYeH         core.cursor.highlight(None)?;
331984a200eSGnoCiYeH         loop {
332984a200eSGnoCiYeH             #[cfg(feature = "dragonos")]
333984a200eSGnoCiYeH             let callback = {
334984a200eSGnoCiYeH                 let key = Input::wait_keydown()?;
335984a200eSGnoCiYeH                 self.mode.read().unwrap().key_event_route(&mut core, key)?
336984a200eSGnoCiYeH             };
337984a200eSGnoCiYeH 
338984a200eSGnoCiYeH             #[cfg(not(feature = "dragonos"))]
339984a200eSGnoCiYeH             let callback = {
340984a200eSGnoCiYeH                 let ev = crossterm::event::read()?;
341984a200eSGnoCiYeH                 self.mode.read().unwrap().event_route(&mut core, ev)?
342984a200eSGnoCiYeH             };
343984a200eSGnoCiYeH 
344984a200eSGnoCiYeH             match callback {
345984a200eSGnoCiYeH                 super::event::WarpUiCallBackType::ChangMode(mode) => {
346984a200eSGnoCiYeH                     self.set_mode(mode, &mut core)?
347984a200eSGnoCiYeH                 }
348984a200eSGnoCiYeH                 super::event::WarpUiCallBackType::None => {}
349984a200eSGnoCiYeH                 super::event::WarpUiCallBackType::Exit(store) => {
350984a200eSGnoCiYeH                     self.ui_exit();
351984a200eSGnoCiYeH                     return Ok(store);
352984a200eSGnoCiYeH                 }
353984a200eSGnoCiYeH             }
354984a200eSGnoCiYeH 
355984a200eSGnoCiYeH             if self.mode.read().unwrap().mode_type() != ModeType::LastLine {
356984a200eSGnoCiYeH                 core.update_bottom_state_bar()?;
357984a200eSGnoCiYeH             }
358984a200eSGnoCiYeH         }
359984a200eSGnoCiYeH     }
360984a200eSGnoCiYeH 
set_mode(&self, mode: ModeType, ui: &mut MutexGuard<UiCore>) -> io::Result<()>361984a200eSGnoCiYeH     fn set_mode(&self, mode: ModeType, ui: &mut MutexGuard<UiCore>) -> io::Result<()> {
362984a200eSGnoCiYeH         if mode != ModeType::LastLine {
363984a200eSGnoCiYeH             ui.cursor.set_prefix_mode(true);
364984a200eSGnoCiYeH 
365984a200eSGnoCiYeH             ui.render_content(0, CONTENT_WINSIZE.read().unwrap().rows as usize)?;
366984a200eSGnoCiYeH         }
367984a200eSGnoCiYeH         match mode {
368984a200eSGnoCiYeH             ModeType::Command => *self.mode.write().unwrap() = COMMAND.clone(),
369984a200eSGnoCiYeH             ModeType::LastLine => {
370984a200eSGnoCiYeH                 ui.cursor.set_prefix_mode(false);
371984a200eSGnoCiYeH                 let lastline = LASTLINE.clone();
372984a200eSGnoCiYeH                 lastline.reset();
373984a200eSGnoCiYeH                 *self.mode.write().unwrap() = lastline;
374984a200eSGnoCiYeH 
375984a200eSGnoCiYeH                 ui.cursor.move_to(0, u16::MAX - 1)?;
376984a200eSGnoCiYeH                 DEF_STYLE.read().unwrap().set_cmd_style()?;
377984a200eSGnoCiYeH                 // 写一个空行
378984a200eSGnoCiYeH                 ui.cursor.clear_current_line()?;
379984a200eSGnoCiYeH                 ui.cursor.move_to_columu(0)?;
380984a200eSGnoCiYeH                 ui.cursor.write(':')?;
381984a200eSGnoCiYeH             }
382984a200eSGnoCiYeH             ModeType::Insert => *self.mode.write().unwrap() = INSERT.clone(),
383*fcc6ced0SZ YS             ModeType::Normal => *self.mode.write().unwrap() = NORMAL.clone(),
384984a200eSGnoCiYeH         }
385984a200eSGnoCiYeH 
386984a200eSGnoCiYeH         Ok(())
387984a200eSGnoCiYeH     }
388984a200eSGnoCiYeH 
ui_exit(&self)389984a200eSGnoCiYeH     fn ui_exit(&self) {
390984a200eSGnoCiYeH         // 处理未保存退出时的提醒
391c775ed96Ssparkzky 
392c775ed96Ssparkzky         // 解决退出程序后颜色没改变的问题
393c775ed96Ssparkzky         StyleManager::reset_color().unwrap();
394984a200eSGnoCiYeH     }
395984a200eSGnoCiYeH }
396984a200eSGnoCiYeH 
397984a200eSGnoCiYeH #[derive(Debug, Clone, Copy)]
398984a200eSGnoCiYeH pub struct UiStyle {
399984a200eSGnoCiYeH     pub content_fg: Option<Color>,
400984a200eSGnoCiYeH     pub content_bg: Option<Color>,
401984a200eSGnoCiYeH     pub cmd_line_fg: Option<Color>,
402984a200eSGnoCiYeH     pub cmd_line_bg: Option<Color>,
403984a200eSGnoCiYeH }
404984a200eSGnoCiYeH 
405984a200eSGnoCiYeH impl UiStyle {
set_cmd_style(&self) -> io::Result<()>406984a200eSGnoCiYeH     pub fn set_cmd_style(&self) -> io::Result<()> {
407984a200eSGnoCiYeH         StyleManager::reset_color()?;
408984a200eSGnoCiYeH         if self.cmd_line_bg.is_some() {
409984a200eSGnoCiYeH             StyleManager::set_background_color(self.cmd_line_bg.unwrap())?;
410984a200eSGnoCiYeH         }
411984a200eSGnoCiYeH         if self.cmd_line_fg.is_some() {
412984a200eSGnoCiYeH             StyleManager::set_foreground_color(self.cmd_line_fg.unwrap())?;
413984a200eSGnoCiYeH         }
414984a200eSGnoCiYeH 
415984a200eSGnoCiYeH         Ok(())
416984a200eSGnoCiYeH     }
417984a200eSGnoCiYeH 
set_content_style(&self) -> io::Result<()>418984a200eSGnoCiYeH     pub fn set_content_style(&self) -> io::Result<()> {
419984a200eSGnoCiYeH         StyleManager::reset_color()?;
420984a200eSGnoCiYeH         if self.content_bg.is_some() {
421984a200eSGnoCiYeH             StyleManager::set_background_color(self.content_bg.unwrap())?;
422984a200eSGnoCiYeH         }
423984a200eSGnoCiYeH         if self.content_fg.is_some() {
424984a200eSGnoCiYeH             StyleManager::set_foreground_color(self.content_fg.unwrap())?;
425984a200eSGnoCiYeH         }
426984a200eSGnoCiYeH 
427984a200eSGnoCiYeH         Ok(())
428984a200eSGnoCiYeH     }
429984a200eSGnoCiYeH }
430