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 pub fn remove_str(&self, x: u16, y: u16, n: usize) { 171 let mut buf = self.buf.write().unwrap(); 172 let line = buf.get_mut(self.offset.load(Ordering::SeqCst) + y as usize); 173 if line.is_none() { 174 return; 175 } 176 let x = x as usize; 177 line.unwrap().data.drain(x..x + n); 178 } 179 180 /// 获取一份对应行的拷贝 181 pub fn get_line(&self, line: u16) -> LineBuffer { 182 let buf = self.buf.read().unwrap(); 183 let line = buf.get(self.offset.load(Ordering::SeqCst) + line as usize); 184 if line.is_none() { 185 LineBuffer::default() 186 } else { 187 line.unwrap().clone() 188 } 189 } 190 191 /// 将某行数据与上一行合并 192 /// 返回合并是否成功,以及被合并行之前的长度 193 pub fn merge_line(&self, line: u16) -> (bool, usize) { 194 let line = self.offset.load(Ordering::SeqCst) + line as usize; 195 if line == 0 { 196 // 没有上一行 197 return (false, 0); 198 } 199 200 let mut buf = self.buf.write().unwrap(); 201 let cur_line = buf.get(line as usize).unwrap().clone(); 202 203 let previous_line = buf.get_mut(line - 1).unwrap(); 204 205 if previous_line.flags.contains(LineState::LOCKED) 206 || cur_line.flags.contains(LineState::LOCKED) 207 { 208 APP_INFO.lock().unwrap().info = "Row is locked".to_string(); 209 return (false, 0); 210 } 211 212 let p_len = previous_line.size(); 213 // 移除最后的\n 214 previous_line.remove(p_len - 1); 215 previous_line.extend(cur_line); 216 217 buf.remove(line as usize); 218 219 return (true, p_len - 1); 220 } 221 222 /// 屏幕坐标 223 #[inline] 224 pub fn insert_char(&self, ch: u8, x: u16, y: u16) { 225 let mut buf = self.buf.write().unwrap(); 226 let line = buf.get_mut(self.offset() + y as usize); 227 match line { 228 Some(line) => line.insert(x as usize, ch), 229 None => { 230 let newline = vec!['\n' as u8]; 231 buf.push(LineBuffer::new(newline)); 232 } 233 } 234 } 235 236 #[inline] 237 pub fn all_buffer(&self) -> Vec<LineBuffer> { 238 self.buf.read().unwrap().clone() 239 } 240 241 /// 输入enter时buf的更新操作 242 pub fn input_enter(&self, x: u16, y: u16) { 243 let y = self.offset.load(Ordering::SeqCst) + y as usize; 244 245 let mut buf = self.buf.write().unwrap(); 246 let linesize = buf.get(y).unwrap().size(); 247 if x as usize == linesize { 248 buf.insert(y, LineBuffer::new(vec!['\n' as u8])); 249 } 250 251 let oldline = buf.get_mut(y).unwrap(); 252 let mut newline = Vec::new(); 253 newline.extend_from_slice(&oldline.data[x as usize..]); 254 255 oldline.data.resize(x as usize, 0); 256 oldline.data.push('\n' as u8); 257 258 buf.insert(y + 1, LineBuffer::new(newline)); 259 } 260 261 pub fn add_line_flags(&self, line_index: usize, flags: LineState) { 262 let mut buf = self.buf.write().unwrap(); 263 264 let line = buf.get_mut(line_index); 265 266 if line.is_none() { 267 return; 268 } 269 270 let line = line.unwrap(); 271 272 line.flags.insert(flags); 273 274 let mut flag_map = self.flag_lines.write().unwrap(); 275 if flags.contains(LineState::FLAGED) { 276 flag_map.insert(line.id, line_index); 277 } 278 279 let mut locked_map = self.locked_lines.write().unwrap(); 280 if flags.contains(LineState::LOCKED) { 281 locked_map.insert(line.id, line_index); 282 } 283 } 284 285 pub fn remove_line_flags(&self, line_index: usize, flags: LineState) { 286 let mut buf = self.buf.write().unwrap(); 287 288 let line = buf.get_mut(line_index); 289 290 if line.is_none() { 291 return; 292 } 293 294 let line = line.unwrap(); 295 296 line.flags.remove(flags); 297 298 let mut flag_map = self.flag_lines.write().unwrap(); 299 if flags.contains(LineState::FLAGED) { 300 flag_map.remove(&line.id); 301 } 302 303 let mut locked_map = self.locked_lines.write().unwrap(); 304 if flags.contains(LineState::LOCKED) { 305 locked_map.remove(&line.id); 306 } 307 } 308 309 #[inline] 310 pub fn line_flags(&self, line: u16) -> LineState { 311 self.get_line(line).flags 312 } 313 314 // 定位到指定行数,返回在正文窗口中的y坐标 315 pub fn goto_line(&self, mut line_idx: usize) -> u16 { 316 let max_line = self.line_count(); 317 318 if line_idx > max_line - 1 { 319 line_idx = max_line - 1 320 } 321 322 let size = *CONTENT_WINSIZE.read().unwrap(); 323 324 // 先将其坐标定位在正文中央 325 let win_rows = size.rows as usize; 326 let mut y = win_rows / 2; 327 328 if line_idx < y { 329 self.set_offset(0); 330 return line_idx as u16; 331 } 332 333 let mut offset = line_idx - y; 334 335 if offset + win_rows > max_line { 336 // 最底下无数据,则调整 337 let adapt_offset = max_line - win_rows; 338 339 y += offset - adapt_offset; 340 offset = adapt_offset; 341 } 342 343 self.set_offset(offset); 344 345 y as u16 346 } 347 348 /// 删除行,不会删除锁定行,返回删除成功的行数 349 pub fn delete_lines(&self, start: usize, mut end: usize) -> usize { 350 let max = self.line_count(); 351 if start >= max { 352 return 0; 353 } 354 355 end = end.min(max); 356 let mut index = start; 357 let mut count = 0; 358 let mut buffer = self.buf.write().unwrap(); 359 360 for _ in start..=end { 361 let line = buffer.get(index).unwrap(); 362 if line.flags.contains(LineState::LOCKED) { 363 index += 1; 364 } else { 365 buffer.remove(index); 366 count += 1; 367 } 368 } 369 370 count 371 } 372 373 pub fn delete_line(&self, y: usize) { 374 let mut buffer = self.buf.write().unwrap(); 375 let line = buffer.get(y).unwrap(); 376 if line.data.is_empty() { 377 return; 378 } 379 380 if !line.flags.contains(LineState::LOCKED) { 381 buffer.remove(y); 382 } 383 } 384 385 pub fn delete_until_line_beg(&self, x: usize, y: usize) -> Option<usize> { 386 let mut buffer = self.buf.write().unwrap(); 387 let line = buffer.get_mut(y).unwrap(); 388 389 if line.data.len() < 2 { 390 return None; 391 } 392 line.data.drain(0..x); 393 return Some(x - 1); 394 } 395 396 pub fn delete_until_endl(&self, x: usize, y: usize) -> Option<usize> { 397 let mut buffer = self.buf.write().unwrap(); 398 let line = buffer.get_mut(y).unwrap(); 399 let len = line.data.len(); 400 if len < 2 { 401 return None; 402 } 403 line.data.drain(x..len - 1); 404 return Some(x); 405 } 406 407 /// 返回下一个单词的起始位置 408 /// 如果为该行最后一单词,返回该行长度 409 pub fn search_nextw_begin(&self, x: u16, y: u16) -> usize { 410 let mut left = x as usize; 411 let mut right = left; 412 let linesize = self.get_linesize(y) as usize; 413 let buf = self.buf.read().unwrap(); 414 let line = buf 415 .get(self.offset.load(Ordering::SeqCst) + y as usize) 416 .unwrap(); 417 418 while left <= right && right < linesize { 419 let lchar = line[left] as char; 420 let rchar = line[right] as char; 421 if !(lchar == ' ' || lchar == '\t') { 422 left += 1; 423 right += 1; 424 continue; 425 } 426 if rchar != ' ' && rchar != '\t' { 427 break; 428 } 429 right += 1; 430 } 431 432 return right; 433 } 434 435 /// 搜索下一个单词的末尾 436 /// 如果为该行最后一单词,返回该行长度 437 pub fn search_nextw_end(&self, x: u16, y: u16) -> usize { 438 let mut left = x as usize; 439 let mut right = left; 440 let linesize = self.get_linesize(y) as usize; 441 let buf = self.buf.read().unwrap(); 442 let line = buf 443 .get(self.offset.load(Ordering::SeqCst) + y as usize) 444 .unwrap(); 445 446 while left <= right && right < linesize { 447 let lchar = line[left] as char; 448 let rchar = line[right] as char; 449 if lchar == ' ' || lchar == '\t' { 450 left += 1; 451 right += 1; 452 continue; 453 } 454 if rchar == ' ' || rchar == '\t' { 455 if right == x as usize + 1 { 456 left = right; 457 continue; 458 } 459 right -= 1; 460 break; 461 } 462 right += 1; 463 } 464 465 return right; 466 } 467 468 /// 返回前一单词首字母位置,如果是当前行首单词,返回 None 469 pub fn search_prevw_begin(&self, x: u16, y: u16) -> Option<usize> { 470 let mut left = x as i32; 471 let mut right = left; 472 let buf = self.buf.read().unwrap(); 473 let line = buf 474 .get(self.offset.load(Ordering::SeqCst) + y as usize) 475 .unwrap(); 476 477 while left <= right && left >= 0 { 478 let lchar = line[left as usize] as char; 479 let rchar = line[right as usize] as char; 480 481 if rchar == ' ' || rchar == '\t' { 482 left -= 1; 483 right -= 1; 484 continue; 485 } 486 487 if lchar == ' ' || lchar == '\t' { 488 if left + 1 == x.into() { 489 right = left; 490 continue; 491 } 492 return Some(left as usize + 1); 493 } 494 495 left -= 1; 496 } 497 return None; 498 } 499 } 500 501 bitflags! { 502 #[derive(Debug, Default, Clone,Copy)] 503 pub struct LineState: u32 { 504 /// 该行被标记 505 const FLAGED = 1 << 1; 506 /// 锁定该行不能被更改 507 const LOCKED = 1 << 2; 508 } 509 } 510 511 impl LineState { 512 pub fn set_style(&self) -> io::Result<()> { 513 if self.contains(Self::FLAGED) { 514 StyleManager::set_background_color(Color::Cyan)?; 515 } 516 517 if self.contains(Self::LOCKED) { 518 StyleManager::set_background_color(Color::DarkRed)?; 519 } 520 521 Ok(()) 522 } 523 } 524