1 use std::io::Read; 2 use std::sync::atomic::Ordering; 3 use std::sync::{Mutex, MutexGuard}; 4 use std::{fmt::Debug, io}; 5 6 use crate::config::lastline_cmd::LastLineCommand; 7 use crate::utils::buffer::LineState; 8 #[cfg(feature = "dragonos")] 9 use crate::utils::input::KeyEventType; 10 11 use crate::utils::terminal::TermManager; 12 13 use crate::utils::ui::uicore::{UiCore, APP_INFO, TAB_SIZE}; 14 use crate::utils::ui::{ 15 event::KeyEventCallback, 16 uicore::{CONTENT_WINSIZE, DEF_STYLE}, 17 }; 18 19 use crate::utils::ui::event::WarpUiCallBackType; 20 21 pub trait InputMode: KeyEventCallback + Debug { 22 fn mode_type(&self) -> ModeType; 23 24 #[cfg(not(feature = "dragonos"))] 25 fn event_route( 26 &self, 27 ui: &mut MutexGuard<UiCore>, 28 event: crossterm::event::Event, 29 ) -> io::Result<WarpUiCallBackType> { 30 match event { 31 crossterm::event::Event::FocusGained => todo!(), 32 crossterm::event::Event::FocusLost => todo!(), 33 crossterm::event::Event::Key(key) => self.key_event_route(ui, key), 34 crossterm::event::Event::Mouse(_) => todo!(), 35 crossterm::event::Event::Paste(_) => todo!(), 36 crossterm::event::Event::Resize(_, _) => todo!(), 37 } 38 } 39 40 #[cfg(not(feature = "dragonos"))] 41 fn key_event_route( 42 &self, 43 ui: &mut MutexGuard<UiCore>, 44 keyev: crossterm::event::KeyEvent, 45 ) -> io::Result<WarpUiCallBackType> { 46 let callback = match keyev.code { 47 crossterm::event::KeyCode::Backspace => self.backspace(ui)?, 48 crossterm::event::KeyCode::Enter => self.enter(ui)?, 49 crossterm::event::KeyCode::Left => self.left(ui)?, 50 crossterm::event::KeyCode::Right => self.right(ui)?, 51 crossterm::event::KeyCode::Up => self.up(ui)?, 52 crossterm::event::KeyCode::Down => self.down(ui)?, 53 crossterm::event::KeyCode::Home => todo!(), 54 crossterm::event::KeyCode::End => todo!(), 55 crossterm::event::KeyCode::PageUp => todo!(), 56 crossterm::event::KeyCode::PageDown => todo!(), 57 crossterm::event::KeyCode::Tab => self.tab(ui)?, 58 crossterm::event::KeyCode::BackTab => todo!(), 59 crossterm::event::KeyCode::Delete => todo!(), 60 crossterm::event::KeyCode::Insert => todo!(), 61 crossterm::event::KeyCode::F(_) => todo!(), 62 crossterm::event::KeyCode::Char(c) => self.input_data(ui, &[c as u8])?, 63 crossterm::event::KeyCode::Null => todo!(), 64 crossterm::event::KeyCode::Esc => self.esc(ui)?, 65 crossterm::event::KeyCode::CapsLock => todo!(), 66 crossterm::event::KeyCode::ScrollLock => todo!(), 67 crossterm::event::KeyCode::NumLock => todo!(), 68 crossterm::event::KeyCode::PrintScreen => todo!(), 69 crossterm::event::KeyCode::Pause => todo!(), 70 crossterm::event::KeyCode::Menu => todo!(), 71 crossterm::event::KeyCode::KeypadBegin => todo!(), 72 crossterm::event::KeyCode::Media(_) => todo!(), 73 crossterm::event::KeyCode::Modifier(_) => todo!(), 74 }; 75 76 Ok(callback) 77 } 78 79 #[cfg(feature = "dragonos")] 80 fn key_event_route( 81 &self, 82 ui: &mut MutexGuard<UiCore>, 83 key: KeyEventType, 84 ) -> io::Result<WarpUiCallBackType> { 85 match key { 86 KeyEventType::Common(c) => self.input_data(ui, &[c]), 87 KeyEventType::Up => self.up(ui), 88 KeyEventType::Down => self.down(ui), 89 KeyEventType::Right => self.right(ui), 90 KeyEventType::Left => self.left(ui), 91 KeyEventType::Enter => self.enter(ui), 92 KeyEventType::Tab => self.tab(ui), 93 KeyEventType::Backspace => self.backspace(ui), 94 KeyEventType::Esc => self.esc(ui), 95 KeyEventType::Unknown(_) => { 96 ui.update_bottom_state_bar()?; 97 Ok(WarpUiCallBackType::None) 98 } 99 } 100 } 101 } 102 103 #[derive(Debug, PartialEq, Clone, Copy)] 104 pub enum ModeType { 105 Command, 106 LastLine, 107 Insert, 108 } 109 110 impl InputMode for Command { 111 fn mode_type(&self) -> ModeType { 112 ModeType::Command 113 } 114 } 115 impl InputMode for LastLine { 116 fn mode_type(&self) -> ModeType { 117 ModeType::LastLine 118 } 119 } 120 impl InputMode for Insert { 121 fn mode_type(&self) -> ModeType { 122 ModeType::Insert 123 } 124 } 125 126 #[derive(Debug)] 127 pub struct Command; 128 129 impl Command { 130 pub fn jump_to_next_flag( 131 &self, 132 ui: &mut MutexGuard<UiCore>, 133 flags: LineState, 134 ) -> io::Result<()> { 135 let offset = ui.buffer.offset(); 136 let y = ui.cursor.y() as usize; 137 138 let start_line_number = offset + y + 1; 139 if start_line_number >= ui.buffer.line_count() { 140 return Ok(()); 141 } 142 143 let content = &ui.buffer.all_buffer()[start_line_number..]; 144 145 // 下一个flaged位置 146 let idx = content.iter().position(|x| x.flags.contains(flags)); 147 148 if idx.is_some() { 149 // y + idx 150 let line_number = start_line_number + idx.unwrap(); 151 let new_y = ui.buffer.goto_line(line_number); 152 ui.render_content(0, CONTENT_WINSIZE.read().unwrap().rows as usize)?; 153 ui.cursor.move_to_row(new_y)?; 154 ui.cursor.highlight(Some(y as u16))?; 155 } 156 157 Ok(()) 158 } 159 160 pub fn jump_to_previous_flag( 161 &self, 162 ui: &mut MutexGuard<UiCore>, 163 flags: LineState, 164 ) -> io::Result<()> { 165 let offset = ui.buffer.offset(); 166 let y = ui.cursor.y() as usize; 167 if offset == 0 && y == 0 { 168 return Ok(()); 169 } 170 let end_linenumber = offset + y - 1; 171 172 let content = &ui.buffer.all_buffer()[0..end_linenumber]; 173 174 // 下一个flaged位置 175 let idx = content.iter().rposition(|x| x.flags.contains(flags)); 176 177 if idx.is_some() { 178 // y + idx 179 let new_y = ui.buffer.goto_line(idx.unwrap()); 180 ui.render_content(0, CONTENT_WINSIZE.read().unwrap().rows as usize)?; 181 ui.cursor.move_to_row(new_y)?; 182 ui.cursor.highlight(Some(y as u16))?; 183 } 184 185 Ok(()) 186 } 187 188 fn jump_to_first_char(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 189 // 移动到行第一个单词的首字母 190 let first_char = { 191 let line = ui.buffer.get_line(ui.cursor.y()).data; 192 let mut idx = 0; 193 for char in line { 194 if char == b" "[0] { 195 idx += 1; 196 } else if char == b"\t"[0] { 197 idx += 4; 198 } 199 } 200 idx 201 }; 202 ui.cursor.move_to_columu(first_char)?; 203 return Ok(WarpUiCallBackType::None); 204 } 205 206 fn do_delete_on_d_clicked( 207 &self, 208 ui: &mut MutexGuard<UiCore>, 209 ) -> io::Result<WarpUiCallBackType> { 210 let buf: &mut [u8] = &mut [0; 8]; 211 let _ = io::stdin().read(buf)?; 212 213 match buf[0] { 214 b'd' => { 215 TermManager::clear_current_line()?; 216 TermManager::clear_under_cursor()?; 217 let y = ui.cursor.y() as usize; 218 let old_line_count = ui.buffer.line_count(); 219 220 let count = old_line_count - y as usize; 221 ui.buffer.delete_line(y); 222 ui.render_content(y as u16, count.max(1))?; 223 224 if y == old_line_count - 1 { 225 self.up(ui)?; 226 } 227 228 if old_line_count == 1 { 229 ui.cursor.move_to_columu(0)?; 230 ui.buffer.insert_char('\n' as u8, 0, 0); 231 ui.render_content(0, 1)?; 232 } 233 } 234 b'0' => { 235 let x = ui.cursor.x() as usize; 236 let y = ui.cursor.y() as usize; 237 match ui.buffer.delete_until_line_beg(x, y) { 238 Some(..) => { 239 // 文本变动重新渲染 240 ui.cursor.move_to_columu(0)?; 241 ui.render_content(y as u16, 1)?; 242 } 243 None => {} 244 }; 245 } 246 b'$' => { 247 let x = ui.cursor.x() as usize; 248 let y = ui.cursor.y() as usize; 249 match ui.buffer.delete_until_endl(x, y) { 250 Some(..) => { 251 ui.cursor.move_left(1)?; 252 ui.render_content(y as u16, 1)?; 253 } 254 None => {} 255 } 256 } 257 258 b'w' | b'e' => { 259 let x = ui.cursor.x(); 260 let y = ui.cursor.y(); 261 let next_word_pos = ui.buffer.search_nextw_begin(x, y); 262 let linesize = ui.buffer.get_linesize(y); 263 264 // 如果下一个单词在当前行,则删除当前单词 265 if next_word_pos < linesize.into() { 266 ui.buffer.remove_str(x, y, next_word_pos - x as usize); 267 } else { 268 // 如果下一个单词在下一行,则删除当前行剩余部分 269 self.left(ui)?; 270 ui.buffer.delete_until_endl(x.into(), y.into()); 271 } 272 ui.render_content(y, 1)?; 273 } 274 275 b'b' => { 276 let old_x = ui.cursor.x(); 277 let old_y = ui.cursor.y(); 278 279 self.jump_to_prevw_beg(ui)?; 280 281 let x = ui.cursor.x(); 282 let y = ui.cursor.y(); 283 if old_y == y { 284 ui.buffer.remove_str(x, y, old_x as usize - x as usize); 285 ui.render_content(y, 1)?; 286 } else { 287 ui.buffer.delete_until_endl(x as usize, y as usize); 288 ui.buffer 289 .delete_until_line_beg(old_x as usize, old_y as usize); 290 ui.buffer.merge_line(old_y); 291 let linecount = ui.buffer.line_count(); 292 TermManager::clear_under_cursor()?; 293 ui.render_content(y, linecount - y as usize - 1)?; 294 } 295 } 296 _ => {} 297 } 298 return Ok(WarpUiCallBackType::None); 299 } 300 301 fn jump_to_next_word(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 302 let x = ui.cursor.x(); 303 let y = ui.cursor.y(); 304 let pos = ui.buffer.search_nextw_begin(x, y); 305 let linesize = ui.buffer.get_linesize(y); 306 307 if pos < linesize as usize { 308 // 如果下一个单词在当前行,则移动光标到该单词的起始位置 309 ui.cursor.move_to_columu(pos as u16)?; 310 } else if y + 1 < ui.buffer.line_count() as u16 { 311 // 如果当前行不是最后一行,则移动到下一行的开头 312 self.down(ui)?; 313 ui.cursor.move_to_columu(0)?; 314 } else { 315 // 如果当前行是最后一行,则移动到当前行的末尾 316 ui.cursor.move_to_columu(linesize as u16 - 1)?; 317 } 318 return Ok(WarpUiCallBackType::None); 319 } 320 321 fn jump_to_nextw_ending(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 322 let x = ui.cursor.x(); 323 let y = ui.cursor.y(); 324 let linesize = ui.buffer.get_linesize(y) as usize; 325 326 // 如果光标已经在当前行的末尾或最后一个字符,则尝试移动到下一行的末尾或单词末尾 327 let final_char_pos = linesize - 2; 328 if x as usize >= final_char_pos { 329 if y < ui.buffer.line_count() as u16 - 1 { 330 let next_end_pos = ui.buffer.search_nextw_end(0, y + 1) as u16; 331 ui.cursor.move_to(next_end_pos, y + 1)?; 332 ui.cursor.highlight(Some(y))?; 333 } else { 334 // 如果已经是最后一行,则保持光标在当前行的末尾 335 ui.cursor.move_to_columu(linesize as u16 - 1)?; 336 } 337 return Ok(WarpUiCallBackType::None); 338 } 339 340 let next_end_pos = ui.buffer.search_nextw_end(x, y) as u16; 341 // 如果下一个单词的末尾在当前行,则移动光标到该单词的末尾 342 ui.cursor 343 .move_to_columu(next_end_pos.min(linesize as u16 - 2))?; 344 return Ok(WarpUiCallBackType::None); 345 } 346 347 fn jump_to_prevw_beg(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 348 let x = ui.cursor.x(); 349 let y = ui.cursor.y(); 350 351 // 如果光标已在行首,则尝试移动到上一行的单词首字母 352 if x == 0 { 353 if y > 0 { 354 let end_of_prev_line = ui.buffer.get_linesize(y - 1) - 1; 355 let prev_word_pos = match ui.buffer.search_prevw_begin(end_of_prev_line, y - 1) { 356 Some(pos) => pos, 357 None => 0, 358 }; 359 ui.cursor.move_to(prev_word_pos as u16, y - 1)?; 360 ui.cursor.highlight(Some(y))?; 361 } else { 362 // 如果已经是第一行,则保持光标在当前行的起始位置 363 ui.cursor.move_to_columu(0)?; 364 } 365 return Ok(WarpUiCallBackType::None); 366 } 367 368 let prev_word_pos = match ui.buffer.search_prevw_begin(x, y) { 369 Some(pos) => pos, 370 None => 0, 371 }; 372 373 ui.cursor.move_to(prev_word_pos as u16, y)?; 374 return Ok(WarpUiCallBackType::None); 375 } 376 } 377 378 impl KeyEventCallback for Command { 379 fn backspace(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 380 Ok(WarpUiCallBackType::None) 381 } 382 fn enter(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 383 Ok(WarpUiCallBackType::None) 384 } 385 386 fn tab(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 387 Ok(WarpUiCallBackType::None) 388 } 389 390 fn esc(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 391 Ok(WarpUiCallBackType::None) 392 } 393 394 fn input_data( 395 &self, 396 ui: &mut MutexGuard<UiCore>, 397 data: &[u8], 398 ) -> io::Result<WarpUiCallBackType> { 399 match data { 400 b":" => { 401 // 保存位置 402 ui.cursor.store_pos(); 403 return Ok(WarpUiCallBackType::ChangMode(ModeType::LastLine)); 404 } 405 406 b"i" | b"I" => { 407 // 切换Insert模式 408 return Ok(WarpUiCallBackType::ChangMode(ModeType::Insert)); 409 } 410 411 // hjkl 与 Vim 的效果一致 412 b"h" => self.left(ui), 413 414 // 向下 415 b"j" => self.down(ui), 416 417 // 向上 418 b"k" => self.up(ui), 419 420 // 向右 421 b"l" => self.right(ui), 422 423 b"L" => { 424 // 设置当前行lock 425 let flag = ui.buffer.line_flags(ui.cursor.y()); 426 let offset = ui.buffer.offset(); 427 if flag.contains(LineState::LOCKED) { 428 ui.buffer 429 .remove_line_flags(offset + ui.cursor.y() as usize, LineState::LOCKED); 430 } else { 431 ui.buffer 432 .add_line_flags(offset + ui.cursor.y() as usize, LineState::LOCKED); 433 } 434 let y = ui.cursor.y(); 435 ui.render_content(y, 1)?; 436 return Ok(WarpUiCallBackType::None); 437 } 438 439 b"f" | b"F" => { 440 // 设置当前行flag 441 let flag = ui.buffer.line_flags(ui.cursor.y()); 442 let offset = ui.buffer.offset(); 443 if flag.contains(LineState::FLAGED) { 444 ui.buffer 445 .remove_line_flags(offset + ui.cursor.y() as usize, LineState::FLAGED); 446 } else { 447 ui.buffer 448 .add_line_flags(offset + ui.cursor.y() as usize, LineState::FLAGED); 449 } 450 451 let y = ui.cursor.y(); 452 ui.render_content(y, 1)?; 453 return Ok(WarpUiCallBackType::None); 454 } 455 456 b"q" | b"Q" => { 457 // 跳转到上一个flag行 458 self.jump_to_previous_flag(ui, LineState::FLAGED)?; 459 return Ok(WarpUiCallBackType::None); 460 } 461 462 b"w" => self.jump_to_next_word(ui), 463 464 b"e" => self.jump_to_nextw_ending(ui), 465 466 b"b" => self.jump_to_prevw_beg(ui), 467 468 b"W" => { 469 // 跳转到下一个flag行 470 self.jump_to_next_flag(ui, LineState::FLAGED)?; 471 return Ok(WarpUiCallBackType::None); 472 } 473 474 b"a" | b"A" => { 475 self.jump_to_previous_flag(ui, LineState::LOCKED)?; 476 return Ok(WarpUiCallBackType::None); 477 } 478 479 b"s" | b"S" => { 480 self.jump_to_next_flag(ui, LineState::LOCKED)?; 481 return Ok(WarpUiCallBackType::None); 482 } 483 484 b"0" => { 485 // 移动到行首 486 ui.cursor.move_to_columu(0)?; 487 return Ok(WarpUiCallBackType::None); 488 } 489 490 b"^" => self.jump_to_first_char(ui), 491 492 b"$" => { 493 // 移动到行末 494 let line_end = ui.buffer.get_linesize(ui.cursor.y()) - 1; 495 ui.cursor.move_to_columu(line_end)?; 496 return Ok(WarpUiCallBackType::None); 497 } 498 499 b"d" => self.do_delete_on_d_clicked(ui), 500 501 b"x" => { 502 let y = ui.cursor.y(); 503 let x = ui.cursor.x(); 504 if x < ui.buffer.get_linesize(y) - 1 { 505 ui.buffer.remove_char(x, y); 506 ui.render_content(y, 1)?; 507 } 508 return Ok(WarpUiCallBackType::None); 509 } 510 511 b"G" => { 512 // 移动到最后一行 513 let line_count = ui.buffer.line_count() as u16; 514 let y = ui.cursor.y(); 515 let new_y = ui.buffer.goto_line(line_count as usize - 1); 516 ui.render_content(0, CONTENT_WINSIZE.read().unwrap().rows as usize)?; 517 ui.cursor.move_to_row(new_y)?; 518 ui.cursor.highlight(Some(y))?; 519 return Ok(WarpUiCallBackType::None); 520 } 521 522 _ => { 523 return Ok(WarpUiCallBackType::None); 524 } 525 } 526 } 527 } 528 529 #[derive(Debug)] 530 pub struct Insert; 531 impl KeyEventCallback for Insert { 532 fn enter(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 533 let line_idx = ui.cursor.y(); 534 let col = ui.cursor.x(); 535 536 let line = ui.buffer.get_line(line_idx); 537 if line.flags.contains(LineState::LOCKED) { 538 APP_INFO.lock().unwrap().info = "Row is locked".to_string(); 539 return Ok(WarpUiCallBackType::None); 540 } 541 ui.buffer.input_enter(col, line_idx); 542 543 DEF_STYLE.read().unwrap().set_content_style()?; 544 // 清空改行光标后的内容 545 TermManager::clear_until_new_line()?; 546 547 // 执行渲染后续文本 548 ui.cursor.move_to_nextline(1)?; 549 ui.cursor.clear_current_line()?; 550 551 let ret = ui.render_content( 552 line_idx + 1, 553 (CONTENT_WINSIZE.read().unwrap().rows - line_idx) as usize, 554 )?; 555 556 if ret == 0 { 557 ui.scroll_up(1)?; 558 ui.render_content( 559 line_idx + 1, 560 (CONTENT_WINSIZE.read().unwrap().rows - line_idx) as usize, 561 )?; 562 563 ui.cursor.move_up(1)?; 564 } 565 566 let last = ui.cursor.y() - 1; 567 ui.cursor.highlight(Some(last))?; 568 ui.set_edited(); 569 Ok(WarpUiCallBackType::None) 570 } 571 572 fn tab(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 573 ui.set_edited(); 574 let x = ui.cursor.x(); 575 576 let tab_size = TAB_SIZE.load(Ordering::SeqCst); 577 let space_size = tab_size - (x % tab_size); 578 579 for _ in 0..space_size { 580 ui.buffer 581 .insert_char(' ' as u8, ui.cursor.x(), ui.cursor.y()); 582 } 583 584 let y = ui.cursor.y(); 585 ui.render_content(y, 1)?; 586 587 ui.cursor.move_right(space_size)?; 588 589 Ok(WarpUiCallBackType::None) 590 } 591 592 fn esc(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 593 Ok(WarpUiCallBackType::ChangMode(ModeType::Command)) 594 } 595 596 fn input_data( 597 &self, 598 ui: &mut MutexGuard<UiCore>, 599 data: &[u8], 600 ) -> io::Result<WarpUiCallBackType> { 601 let x = ui.cursor.x(); 602 let y = ui.cursor.y(); 603 604 let line = ui.buffer.get_line(y); 605 if line.flags.contains(LineState::LOCKED) { 606 APP_INFO.lock().unwrap().info = "Row is locked".to_string(); 607 return Ok(WarpUiCallBackType::None); 608 } 609 610 for (idx, ch) in data.iter().enumerate() { 611 ui.buffer.insert_char(*ch, x + idx as u16, y); 612 } 613 614 let line_data = ui.buffer.get_line(y); 615 616 // 考虑长度包含\n,所以要减1 617 ui.cursor.write(String::from_utf8_lossy( 618 &line_data.data[x as usize..(line_data.size() - 1)], 619 ))?; 620 621 ui.cursor.move_to_columu(x + data.len() as u16)?; 622 ui.set_edited(); 623 ui.cursor.highlight(None)?; 624 Ok(WarpUiCallBackType::None) 625 } 626 } 627 628 #[derive(Debug)] 629 pub struct LastLine { 630 buf: Mutex<Vec<u8>>, 631 } 632 633 impl LastLine { 634 pub fn new() -> Self { 635 Self { 636 buf: Mutex::new(vec![':' as u8]), 637 } 638 } 639 640 pub fn reset(&self) { 641 self.buf.lock().unwrap().resize(1, ':' as u8); 642 } 643 } 644 645 impl KeyEventCallback for LastLine { 646 fn enter(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 647 let mut buf = self.buf.lock().unwrap(); 648 let cmd = String::from_utf8_lossy(&buf).to_string(); 649 650 let ret = LastLineCommand::process(ui, cmd); 651 652 ui.cursor.move_to(1, u16::MAX - 1)?; 653 // ui.cursor.move_to_columu(1)?; 654 TermManager::clear_until_new_line()?; 655 ui.cursor.move_to(1, u16::MAX - 1)?; 656 657 buf.resize(1, 0); 658 if ret == WarpUiCallBackType::None { 659 ui.cursor.restore_pos()?; 660 return Ok(WarpUiCallBackType::ChangMode(ModeType::Command)); 661 } 662 663 Ok(ret) 664 } 665 666 fn tab(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 667 Ok(WarpUiCallBackType::None) 668 } 669 670 fn backspace(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 671 if ui.cursor.x() == 1 { 672 return Ok(WarpUiCallBackType::None); 673 } 674 675 self.left(ui)?; 676 self.buf.lock().unwrap().remove(ui.cursor.x() as usize); 677 678 ui.cursor.write(' ')?; 679 self.left(ui)?; 680 681 Ok(WarpUiCallBackType::None) 682 } 683 684 fn up(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 685 Ok(WarpUiCallBackType::None) 686 } 687 688 fn down(&self, _ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 689 Ok(WarpUiCallBackType::None) 690 } 691 692 fn esc(&self, ui: &mut MutexGuard<UiCore>) -> io::Result<WarpUiCallBackType> { 693 ui.cursor.restore_pos()?; 694 Ok(WarpUiCallBackType::ChangMode(ModeType::Command)) 695 } 696 697 fn input_data( 698 &self, 699 ui: &mut MutexGuard<UiCore>, 700 data: &[u8], 701 ) -> io::Result<WarpUiCallBackType> { 702 let mut buf = self.buf.lock().unwrap(); 703 704 if ui.cursor.x() == buf.len() as u16 { 705 buf.extend(data); 706 } else { 707 let index = ui.cursor.x() as usize; 708 for (i, &item) in data.iter().enumerate() { 709 buf.insert(index + i, item); 710 } 711 } 712 713 ui.cursor.write(String::from_utf8_lossy(&data))?; 714 715 Ok(WarpUiCallBackType::None) 716 } 717 } 718