1 use std::{
2 cell::RefCell,
3 fmt,
4 io::{self, stdout, Write},
5 ops::Deref,
6 print,
7 rc::Rc,
8 };
9
10 use colored::Colorize;
11
12 use crate::env::EnvManager;
13
14 pub struct Printer {
15 /// 提示语
16 pub prompt: Prompt,
17 /// 缓存区,记录当前显示的内容
18 pub buf: Rc<RefCell<Vec<u8>>>,
19 /// 光标位置(不包括提示语)
20 pub cursor: usize,
21 }
22
23 impl Printer {
new(bytes: &Rc<RefCell<Vec<u8>>>) -> Self24 pub fn new(bytes: &Rc<RefCell<Vec<u8>>>) -> Self {
25 Printer {
26 prompt: Prompt {
27 computer_name: "DragonOS".to_string(),
28 user_name: "root".to_string(),
29 path: EnvManager::current_dir(),
30 },
31 buf: Rc::clone(bytes),
32 cursor: 0,
33 }
34 }
35
36 /// 读取输入前初始化信息
init_before_readline(&mut self)37 pub fn init_before_readline(&mut self) {
38 self.buf = Rc::new(RefCell::new(Vec::new()));
39 self.prompt.update_path();
40 self.print_prompt();
41 self.cursor = 0;
42 }
43
print_prompt(&self)44 pub fn print_prompt(&self) {
45 print!("{}", self.prompt);
46 stdout().flush().unwrap();
47 }
48
49 /// 在光标处插入字符串
insert(&mut self, bytes: &[u8])50 pub fn insert(&mut self, bytes: &[u8]) {
51 // 记录光标距离末尾的长度,用于后续光标复位
52 let len_to_end = self.buf.deref().borrow().len() - self.cursor;
53
54 // 在buf中插入内容
55 let mut buf = self.buf.deref().borrow_mut();
56 buf.splice(self.cursor..self.cursor, bytes.iter().cloned());
57
58 // 打印cursor后面的内容,此时屏幕光标在末尾
59 print!(
60 "{}",
61 String::from_utf8(buf[self.cursor..].to_vec()).unwrap()
62 );
63
64 // 移回光标
65 if len_to_end > 0 {
66 crossterm::execute!(
67 io::stdout(),
68 crossterm::cursor::MoveLeft(len_to_end.try_into().unwrap())
69 )
70 .unwrap();
71 }
72 self.cursor += bytes.len();
73
74 stdout().flush().unwrap();
75 }
76
77 /// 删除下标为[cursor,cursor + len)的字符,光标位置不变
delete(&mut self, len: usize)78 pub fn delete(&mut self, len: usize) {
79 let cursor = self.cursor;
80 let buf_len = self.buf.deref().borrow().len();
81
82 // 判断最大下标是否越界
83 if cursor + len - 1 < buf_len {
84 // 在buf中删除内容
85 self.buf.deref().borrow_mut().drain(cursor..cursor + len);
86
87 // 直接打印删除范围之后的内容
88 print!(
89 "{}",
90 String::from_utf8(self.buf.deref().borrow()[self.cursor..].to_vec()).unwrap()
91 );
92
93 // 打印len个空格覆盖遗留的内容,此时屏幕光标下标恰好为原buf长度
94 print!("{}", " ".repeat(len));
95
96 // 屏幕光标移回原位
97 crossterm::execute!(
98 io::stdout(),
99 crossterm::cursor::MoveLeft((buf_len - cursor).try_into().unwrap())
100 )
101 .unwrap();
102 stdout().flush().unwrap();
103 }
104 }
105
backspace(&mut self)106 pub fn backspace(&mut self) {
107 if self.cursor > 0 {
108 self.cursor_left(1);
109 self.delete(1);
110 }
111 }
112
cursor_left(&mut self, len: usize)113 pub fn cursor_left(&mut self, len: usize) {
114 if self.cursor > 0 {
115 crossterm::execute!(
116 io::stdout(),
117 crossterm::cursor::MoveLeft(len.try_into().unwrap())
118 )
119 .unwrap();
120 self.cursor -= len;
121 }
122 }
123
cursor_right(&mut self, len: usize)124 pub fn cursor_right(&mut self, len: usize) {
125 let buf = self.buf.deref().borrow();
126 if self.cursor < buf.len() {
127 crossterm::execute!(
128 io::stdout(),
129 crossterm::cursor::MoveRight(len.try_into().unwrap())
130 )
131 .unwrap();
132 self.cursor += len;
133 }
134 }
135
home(&mut self)136 pub fn home(&mut self) {
137 self.cursor_left(self.cursor);
138 }
139
end(&mut self)140 pub fn end(&mut self) {
141 let buf_len = self.buf.deref().borrow().len();
142 self.cursor_right(buf_len - self.cursor);
143 }
144
145 /// 将命令行的内容修改为新的内容
change_line(&mut self, new_buf: &Rc<RefCell<Vec<u8>>>)146 pub fn change_line(&mut self, new_buf: &Rc<RefCell<Vec<u8>>>) {
147 // 移动到开头
148 self.home();
149
150 // 打印新的字符串
151 print!(
152 "{}",
153 String::from_utf8(new_buf.deref().borrow()[..].to_vec()).unwrap()
154 );
155
156 // 如果新字符串长度比旧的短,后面会有残留,用空格覆盖
157 let old_buf_len = self.buf.deref().borrow().len();
158 let new_buf_len = new_buf.deref().borrow().len();
159 if new_buf_len < old_buf_len {
160 let remain_len = old_buf_len - new_buf_len;
161 print!("{}", " ".repeat(remain_len));
162 crossterm::execute!(
163 io::stdout(),
164 crossterm::cursor::MoveLeft(remain_len.try_into().unwrap())
165 )
166 .unwrap();
167 }
168
169 self.cursor = new_buf_len;
170 self.buf = Rc::clone(new_buf);
171 stdout().flush().unwrap();
172 }
173 }
174
175 pub struct Prompt {
176 user_name: String,
177 computer_name: String,
178 path: String,
179 }
180
181 impl Prompt {
len(&self) -> usize182 pub fn len(&self) -> usize {
183 format!("{}@{}:{}$ ", self.user_name, self.computer_name, self.path).len()
184 }
185
update_path(&mut self)186 pub fn update_path(&mut self) {
187 self.path = EnvManager::current_dir()
188 }
189 }
190
191 impl fmt::Display for Prompt {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 write!(
194 f,
195 "{}:{}$ ",
196 format!("{}@{}", self.user_name, self.computer_name).bright_green(),
197 self.path.bright_cyan()
198 )
199 }
200 }
201
202 // 测试终端颜色显示效果
203 #[allow(dead_code)]
_print_color_example()204 pub fn _print_color_example() {
205 let example = "abcdefghijklmnopqrstuvwxyz";
206 println!("{}", example.bright_black());
207 println!("{}", example.bright_blue());
208 println!("{}", example.bright_cyan());
209 println!("{}", example.bright_green());
210 println!("{}", example.bright_magenta());
211 println!("{}", example.bright_purple());
212 println!("{}", example.bright_red());
213 println!("{}", example.bright_white());
214 println!("{}", example.bright_yellow());
215 println!("{}", example.black());
216 println!("{}", example.blue());
217 println!("{}", example.cyan());
218 println!("{}", example.green());
219 println!("{}", example.magenta());
220 println!("{}", example.purple());
221 println!("{}", example.red());
222 println!("{}", example.white());
223 println!("{}", example.yellow());
224 }
225