1 use std::{ 2 collections::HashMap, 3 io, 4 ops::Deref, 5 sync::{ 6 atomic::{AtomicUsize, Ordering}, 7 RwLock, 8 }, 9 }; 10 11 use bitflags::bitflags; 12 use crossterm::style::Color; 13 14 use super::{ 15 style::StyleManager, 16 ui::uicore::{APP_INFO, CONTENT_WINSIZE}, 17 }; 18 19 #[derive(Debug, Default, Clone)] 20 pub struct LineBuffer { 21 id: usize, 22 23 pub data: Vec<u8>, 24 25 // 是否被标记 26 pub flags: LineState, 27 } 28 29 impl Deref for LineBuffer { 30 type Target = Vec<u8>; 31 32 fn deref(&self) -> &Self::Target { 33 &self.data 34 } 35 } 36 37 impl LineBuffer { 38 pub fn new(data: Vec<u8>) -> Self { 39 static LINE_ID_ALLOCTOR: AtomicUsize = AtomicUsize::new(0); 40 Self { 41 id: LINE_ID_ALLOCTOR.fetch_add(1, Ordering::SeqCst), 42 data, 43 flags: LineState::empty(), 44 } 45 } 46 47 #[inline] 48 pub fn remove(&mut self, idx: usize) { 49 self.data.remove(idx); 50 } 51 52 #[inline] 53 pub fn size(&self) -> usize { 54 self.data.len() 55 } 56 57 #[inline] 58 pub fn extend(&mut self, other: LineBuffer) { 59 self.data.extend(other.data) 60 } 61 62 #[inline] 63 pub fn insert(&mut self, idx: usize, data: u8) { 64 self.data.insert(idx, data) 65 } 66 } 67 68 #[derive(Debug, Default)] 69 pub struct EditBuffer { 70 buf: RwLock<Vec<LineBuffer>>, 71 72 // 记录当前页第一行对应buf中的index 73 offset: AtomicUsize, 74 75 // 记录被标记的行,行ID -> 行index 76 flag_lines: RwLock<HashMap<usize, usize>>, 77 78 // 记录锁定行 79 locked_lines: RwLock<HashMap<usize, usize>>, 80 } 81 82 impl EditBuffer { 83 pub fn new(buf: Vec<u8>) -> Self { 84 let mut lines = buf 85 .split_inclusive(|x| *x == '\n' as u8) 86 .map(|slice| slice.to_vec()) 87 .collect::<Vec<Vec<_>>>(); 88 89 let last = lines.last(); 90 if last.is_none() { 91 lines.push(vec!['\n' as u8]) 92 } else { 93 let last = last.unwrap(); 94 if !last.ends_with(&['\n' as u8]) { 95 lines.last_mut().unwrap().push('\n' as u8) 96 } 97 } 98 99 let mut buf = Vec::new(); 100 for v in lines { 101 buf.push(LineBuffer::new(v)); 102 } 103 104 Self { 105 buf: RwLock::new(buf), 106 offset: AtomicUsize::new(0), 107 flag_lines: RwLock::new(HashMap::new()), 108 locked_lines: RwLock::new(HashMap::new()), 109 } 110 } 111 112 #[inline] 113 pub fn set_offset(&self, mut offset: usize) { 114 offset = offset.min(self.buf.read().unwrap().len() - 1); 115 self.offset.store(offset, Ordering::SeqCst); 116 } 117 118 #[inline] 119 pub fn offset(&self) -> usize { 120 self.offset.load(Ordering::SeqCst) 121 } 122 123 pub fn line_count(&self) -> usize { 124 self.buf.read().unwrap().len() 125 } 126 127 /// 获取一部分上下文 128 pub fn get_content( 129 &self, 130 mut start_y: usize, 131 mut line_count: usize, 132 ) -> Option<Vec<LineBuffer>> { 133 start_y += self.offset.load(Ordering::SeqCst); 134 line_count = line_count.min(self.line_count() - start_y); 135 let buf = self.buf.read().unwrap(); 136 if start_y > buf.len() { 137 return None; 138 } 139 let end = buf.len().min(start_y + line_count); 140 141 let mut ret = Vec::with_capacity(end - start_y); 142 ret.resize(end - start_y, LineBuffer::default()); 143 ret[..].clone_from_slice(&buf[start_y..end]); 144 Some(ret) 145 } 146 147 pub fn get_linesize(&self, line: u16) -> u16 { 148 let buf = self.buf.read().unwrap(); 149 let line = buf.get(self.offset.load(Ordering::SeqCst) + line as usize); 150 if line.is_none() { 151 return 0; 152 } 153 154 let line = line.unwrap(); 155 156 line.data.len() as u16 157 } 158 159 /// 外部接口,本结构体内部方法不应该使用,因为涉及offset计算 160 pub fn remove_char(&self, x: u16, y: u16) { 161 let mut buf = self.buf.write().unwrap(); 162 let line = buf.get_mut(self.offset.load(Ordering::SeqCst) + y as usize); 163 if line.is_none() { 164 return; 165 } 166 167 line.unwrap().remove(x as usize); 168 } 169 170 /// 获取一份对应行的拷贝 171 pub fn get_line(&self, line: u16) -> LineBuffer { 172 let buf = self.buf.read().unwrap(); 173 let line = buf.get(self.offset.load(Ordering::SeqCst) + line as usize); 174 if line.is_none() { 175 LineBuffer::default() 176 } else { 177 line.unwrap().clone() 178 } 179 } 180 181 /// 将某行数据与上一行合并 182 /// 返回合并是否成功,以及被合并行之前的长度 183 pub fn merge_line(&self, line: u16) -> (bool, usize) { 184 let line = self.offset.load(Ordering::SeqCst) + line as usize; 185 if line == 0 { 186 // 没有上一行 187 return (false, 0); 188 } 189 190 let mut buf = self.buf.write().unwrap(); 191 let cur_line = buf.get(line as usize).unwrap().clone(); 192 193 let previous_line = buf.get_mut(line - 1).unwrap(); 194 195 if previous_line.flags.contains(LineState::LOCKED) 196 || cur_line.flags.contains(LineState::LOCKED) 197 { 198 APP_INFO.lock().unwrap().info = "Row is locked".to_string(); 199 return (false, 0); 200 } 201 202 let p_len = previous_line.size(); 203 // 移除最后的\n 204 previous_line.remove(p_len - 1); 205 previous_line.extend(cur_line); 206 207 buf.remove(line as usize); 208 209 return (true, p_len - 1); 210 } 211 212 /// 屏幕坐标 213 #[inline] 214 pub fn insert_char(&self, ch: u8, x: u16, y: u16) { 215 let mut buf = self.buf.write().unwrap(); 216 let line = buf.get_mut(self.offset() + y as usize).unwrap(); 217 line.insert(x as usize, ch); 218 } 219 220 #[inline] 221 pub fn all_buffer(&self) -> Vec<LineBuffer> { 222 self.buf.read().unwrap().clone() 223 } 224 225 /// 输入enter时buf的更新操作 226 pub fn input_enter(&self, x: u16, y: u16) { 227 let y = self.offset.load(Ordering::SeqCst) + y as usize; 228 229 let mut buf = self.buf.write().unwrap(); 230 let linesize = buf.get(y).unwrap().size(); 231 if x as usize == linesize { 232 buf.insert(y, LineBuffer::new(vec!['\n' as u8])); 233 } 234 235 let oldline = buf.get_mut(y).unwrap(); 236 let mut newline = Vec::new(); 237 newline.extend_from_slice(&oldline.data[x as usize..]); 238 239 oldline.data.resize(x as usize, 0); 240 oldline.data.push('\n' as u8); 241 242 buf.insert(y + 1, LineBuffer::new(newline)); 243 } 244 245 pub fn add_line_flags(&self, line_index: usize, flags: LineState) { 246 let mut buf = self.buf.write().unwrap(); 247 248 let line = buf.get_mut(line_index); 249 250 if line.is_none() { 251 return; 252 } 253 254 let line = line.unwrap(); 255 256 line.flags.insert(flags); 257 258 let mut flag_map = self.flag_lines.write().unwrap(); 259 if flags.contains(LineState::FLAGED) { 260 flag_map.insert(line.id, line_index); 261 } 262 263 let mut locked_map = self.locked_lines.write().unwrap(); 264 if flags.contains(LineState::LOCKED) { 265 locked_map.insert(line.id, line_index); 266 } 267 } 268 269 pub fn remove_line_flags(&self, line_index: usize, flags: LineState) { 270 let mut buf = self.buf.write().unwrap(); 271 272 let line = buf.get_mut(line_index); 273 274 if line.is_none() { 275 return; 276 } 277 278 let line = line.unwrap(); 279 280 line.flags.remove(flags); 281 282 let mut flag_map = self.flag_lines.write().unwrap(); 283 if flags.contains(LineState::FLAGED) { 284 flag_map.remove(&line.id); 285 } 286 287 let mut locked_map = self.locked_lines.write().unwrap(); 288 if flags.contains(LineState::LOCKED) { 289 locked_map.remove(&line.id); 290 } 291 } 292 293 #[inline] 294 pub fn line_flags(&self, line: u16) -> LineState { 295 self.get_line(line).flags 296 } 297 298 // 定位到指定行数,返回在正文窗口中的y坐标 299 pub fn goto_line(&self, mut line_idx: usize) -> u16 { 300 let max_line = self.line_count(); 301 302 if line_idx > max_line - 1 { 303 line_idx = max_line - 1 304 } 305 306 let size = *CONTENT_WINSIZE.read().unwrap(); 307 308 // 先将其坐标定位在正文中央 309 let win_rows = size.rows as usize; 310 let mut y = win_rows / 2; 311 312 if line_idx < y { 313 self.set_offset(0); 314 return line_idx as u16; 315 } 316 317 let mut offset = line_idx - y; 318 319 if offset + win_rows > max_line { 320 // 最底下无数据,则调整 321 let adapt_offset = max_line - win_rows; 322 323 y += offset - adapt_offset; 324 offset = adapt_offset; 325 } 326 327 self.set_offset(offset); 328 329 y as u16 330 } 331 332 /// 删除行,不会删除锁定行,返回删除成功的行数 333 pub fn delete_lines(&self, start: usize, mut end: usize) -> usize { 334 let max = self.line_count(); 335 if start >= max { 336 return 0; 337 } 338 339 end = end.min(max); 340 let mut index = start; 341 let mut count = 0; 342 let mut buffer = self.buf.write().unwrap(); 343 344 for _ in start..=end { 345 let line = buffer.get(index).unwrap(); 346 if line.flags.contains(LineState::LOCKED) { 347 index += 1; 348 } else { 349 buffer.remove(index); 350 count += 1; 351 } 352 } 353 354 count 355 } 356 } 357 358 bitflags! { 359 #[derive(Debug, Default, Clone,Copy)] 360 pub struct LineState: u32 { 361 /// 该行被标记 362 const FLAGED = 1 << 1; 363 /// 锁定该行不能被更改 364 const LOCKED = 1 << 2; 365 } 366 } 367 368 impl LineState { 369 pub fn set_style(&self) -> io::Result<()> { 370 if self.contains(Self::FLAGED) { 371 StyleManager::set_background_color(Color::Cyan)?; 372 } 373 374 if self.contains(Self::LOCKED) { 375 StyleManager::set_background_color(Color::DarkRed)?; 376 } 377 378 Ok(()) 379 } 380 } 381