j_cli/command/help/
mod.rs1pub mod app;
2pub mod ui;
3
4use crossterm::{
5 event::{self, Event, KeyCode, KeyModifiers},
6 execute,
7 terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
8};
9use ratatui::{Terminal, backend::CrosstermBackend};
10use std::io;
11
12use app::HelpApp;
13use ui::draw_help_ui;
14
15pub fn handle_help() {
17 match run_help_tui() {
18 Ok(_) => {}
19 Err(e) => {
20 eprintln!("TUI 启动失败: {}", e);
21 }
22 }
23}
24
25fn run_help_tui() -> io::Result<()> {
26 terminal::enable_raw_mode()?;
27 let mut stdout = io::stdout();
28 execute!(stdout, EnterAlternateScreen)?;
29
30 let backend = CrosstermBackend::new(stdout);
31 let mut terminal = Terminal::new(backend)?;
32
33 let mut app = HelpApp::new();
34
35 loop {
36 terminal.draw(|f| draw_help_ui(f, &mut app))?;
37
38 if event::poll(std::time::Duration::from_millis(100))? {
39 match event::read()? {
40 Event::Key(key) => {
41 match key.code {
42 KeyCode::Char('q') | KeyCode::Esc => break,
44 KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
45 break;
46 }
47
48 KeyCode::Right | KeyCode::Char('l') => app.next_tab(),
50 KeyCode::Left | KeyCode::Char('h') => app.prev_tab(),
51 KeyCode::Tab => {
52 if key.modifiers.contains(KeyModifiers::SHIFT) {
53 app.prev_tab();
54 } else {
55 app.next_tab();
56 }
57 }
58 KeyCode::BackTab => app.prev_tab(),
59
60 KeyCode::Char(c @ '1'..='9') => {
62 let idx = (c as usize) - ('1' as usize);
63 app.goto_tab(idx);
64 }
65 KeyCode::Char('0') => app.goto_tab(9),
66
67 KeyCode::Down | KeyCode::Char('j') => app.scroll_down(1),
69 KeyCode::Up | KeyCode::Char('k') => app.scroll_up(1),
70 KeyCode::PageDown => app.scroll_down(10),
71 KeyCode::PageUp => app.scroll_up(10),
72 KeyCode::Home => app.scroll_to_top(),
73 KeyCode::End => app.scroll_to_bottom(),
74
75 _ => {}
76 }
77 }
78 Event::Resize(_, _) => {
79 app.invalidate_cache();
80 }
81 _ => {}
82 }
83 }
84 }
85
86 terminal::disable_raw_mode()?;
87 execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
88
89 Ok(())
90}