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