feat: ctrl-c handling

This commit is contained in:
Lukas Wölfer
2026-01-23 23:37:36 +01:00
parent 40167f0f23
commit e8e68682d8

View File

@@ -9,7 +9,7 @@ use crossterm::terminal::{
use ratatui::Terminal; use ratatui::Terminal;
use ratatui::backend::CrosstermBackend; use ratatui::backend::CrosstermBackend;
use ratatui::layout::{Constraint, Direction, Layout}; use ratatui::layout::{Constraint, Direction, Layout};
use ratatui::style::{Color, Modifier, Style}; use ratatui::style::Style;
use ratatui::widgets::{Block, Borders, List, ListItem, ListState}; use ratatui::widgets::{Block, Borders, List, ListItem, ListState};
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -58,48 +58,62 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.borders(Borders::ALL) .borders(Borders::ALL)
.title("Lines (space to mark, q to quit)"), .title("Lines (space to mark, q to quit)"),
) )
.highlight_style( .highlight_style(Style::default().bold().yellow().on_dark_gray());
Style::default()
.fg(Color::White)
.bg(Color::Blue)
.add_modifier(Modifier::BOLD),
);
f.render_stateful_widget(list, chunks[0], &mut state); f.render_stateful_widget(list, chunks[0], &mut state);
})?; })?;
// Event handling // Event handling
if event::poll(Duration::from_millis(100))? if event::poll(Duration::from_millis(100))? {
&& let Event::Key(key) = event::read()? match event::read()? {
{ Event::Key(key) => {
match key.code { match key.code {
KeyCode::Char('q') => break, KeyCode::Char('q') => break,
KeyCode::Up => { KeyCode::Up => {
if let Some(i) = state.selected() if let Some(i) = state.selected()
&& i > 0 && i > 0
{ {
state.select(Some(i - 1)); state.select(Some(i - 1));
}
}
KeyCode::Down => {
if let Some(i) = state.selected()
&& i + 1 < lines.len()
{
state.select(Some(i + 1));
}
}
KeyCode::Char(' ') => {
if let Some(i) = state.selected()
&& i < marked.len()
{
assert!(i < marked.len());
if marked[i] {
marked[i] = false;
} else {
marked[i] = true;
// move cursor down
let next = lines.len().min(i + 1);
state.select(Some(next));
}
}
}
KeyCode::Char('c')
if key.modifiers.contains(event::KeyModifiers::CONTROL) =>
{
break;
}
_ => {}
} }
} }
KeyCode::Down => { Event::Mouse(s) => {
if let Some(i) = state.selected() if let event::MouseEventKind::Down(event::MouseButton::Left) = s.kind {
&& i + 1 < lines.len() let area = terminal.size()?;
{ if s.row > area.height && s.row < area.height + area.height {
state.select(Some(i + 1)); let idx = (s.row - area.height - 1) as usize;
} if idx < lines.len() {
} state.select(Some(idx));
KeyCode::Char(' ') => { }
if let Some(i) = state.selected()
&& i < marked.len()
{
assert!(i < marked.len());
if marked[i] {
marked[i] = false;
} else {
marked[i] = true;
// move cursor down
let next = lines.len().min(i + 1);
state.select(Some(next));
} }
} }
} }