feat: Add mouse capture functionality to terminal and enhance markdown rendering with table support
This commit is contained in:
@@ -119,6 +119,7 @@ fn run_single_process() -> Result<()> {
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
execute!(stdout, crossterm::event::EnableBracketedPaste)?;
|
||||
execute!(stdout, crossterm::event::EnableMouseCapture)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
terminal.clear()?;
|
||||
@@ -127,6 +128,7 @@ fn run_single_process() -> Result<()> {
|
||||
|
||||
let mut restore_stdout = io::stdout();
|
||||
let _ = execute!(restore_stdout, crossterm::event::DisableBracketedPaste);
|
||||
let _ = execute!(restore_stdout, crossterm::event::DisableMouseCapture);
|
||||
let _ = execute!(restore_stdout, LeaveAlternateScreen);
|
||||
let _ = disable_raw_mode();
|
||||
|
||||
@@ -500,6 +502,7 @@ fn run_attach(session_id: &str) -> Result<()> {
|
||||
let mut stdout = io::stdout();
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
execute!(stdout, crossterm::event::EnableBracketedPaste)?;
|
||||
execute!(stdout, crossterm::event::EnableMouseCapture)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
terminal.clear()?;
|
||||
@@ -591,6 +594,7 @@ fn run_attach(session_id: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
let _ = execute!(io::stdout(), crossterm::event::DisableBracketedPaste);
|
||||
let _ = execute!(io::stdout(), crossterm::event::DisableMouseCapture);
|
||||
let _ = execute!(io::stdout(), LeaveAlternateScreen);
|
||||
let _ = disable_raw_mode();
|
||||
|
||||
@@ -617,6 +621,7 @@ fn run_loop(
|
||||
|
||||
let _ = disable_raw_mode();
|
||||
let _ = execute!(io::stdout(), crossterm::event::DisableBracketedPaste);
|
||||
let _ = execute!(io::stdout(), crossterm::event::DisableMouseCapture);
|
||||
let _ = execute!(io::stdout(), LeaveAlternateScreen);
|
||||
}
|
||||
result
|
||||
|
||||
+75
-4
@@ -30,11 +30,19 @@ use super::theme::Theme;
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn render_markdown(text: &str, width: u16) -> Vec<Span<'static>> {
|
||||
let mut spans = Vec::new();
|
||||
let parser = pulldown_cmark::Parser::new(text);
|
||||
let mut options = pulldown_cmark::Options::empty();
|
||||
options.insert(pulldown_cmark::Options::ENABLE_TABLES);
|
||||
let parser = pulldown_cmark::Parser::new_ext(text, options);
|
||||
let mut in_code_block = false;
|
||||
let mut in_heading = false;
|
||||
let mut heading_level = 0;
|
||||
|
||||
let mut in_table = false;
|
||||
let mut in_table_cell = false;
|
||||
let mut table_rows: Vec<Vec<Vec<Span<'static>>>> = Vec::new();
|
||||
let mut current_row: Vec<Vec<Span<'static>>> = Vec::new();
|
||||
let mut current_cell: Vec<Span<'static>> = Vec::new();
|
||||
|
||||
for event in parser {
|
||||
match event {
|
||||
pulldown_cmark::Event::Start(tag) => {
|
||||
@@ -90,6 +98,17 @@ pub fn render_markdown(text: &str, width: u16) -> Vec<Span<'static>> {
|
||||
Style::default().fg(Theme::BLOCKQUOTE_BAR),
|
||||
));
|
||||
}
|
||||
pulldown_cmark::Tag::Table(_) => {
|
||||
in_table = true;
|
||||
table_rows.clear();
|
||||
}
|
||||
pulldown_cmark::Tag::TableHead | pulldown_cmark::Tag::TableRow => {
|
||||
current_row.clear();
|
||||
}
|
||||
pulldown_cmark::Tag::TableCell => {
|
||||
in_table_cell = true;
|
||||
current_cell.clear();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -114,6 +133,52 @@ pub fn render_markdown(text: &str, width: u16) -> Vec<Span<'static>> {
|
||||
pulldown_cmark::TagEnd::Item | pulldown_cmark::TagEnd::BlockQuote(_) => {
|
||||
spans.push(Span::raw("\n"));
|
||||
}
|
||||
pulldown_cmark::TagEnd::TableCell => {
|
||||
in_table_cell = false;
|
||||
current_row.push(std::mem::take(&mut current_cell));
|
||||
}
|
||||
pulldown_cmark::TagEnd::TableHead | pulldown_cmark::TagEnd::TableRow => {
|
||||
table_rows.push(std::mem::take(&mut current_row));
|
||||
}
|
||||
pulldown_cmark::TagEnd::Table => {
|
||||
in_table = false;
|
||||
|
||||
let mut col_widths = Vec::new();
|
||||
for row in &table_rows {
|
||||
for (i, cell) in row.iter().enumerate() {
|
||||
let width: usize = cell.iter().map(|s| s.content.chars().count()).sum();
|
||||
if i >= col_widths.len() {
|
||||
col_widths.push(width);
|
||||
} else if width > col_widths[i] {
|
||||
col_widths[i] = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spans.push(Span::raw("\n"));
|
||||
for (r, row) in table_rows.iter().enumerate() {
|
||||
spans.push(Span::styled(" | ", Style::default().fg(Theme::BORDER)));
|
||||
for (i, cell) in row.iter().enumerate() {
|
||||
let width: usize = cell.iter().map(|s| s.content.chars().count()).sum();
|
||||
let pad = col_widths.get(i).copied().unwrap_or(0).saturating_sub(width);
|
||||
for span in cell {
|
||||
spans.push(span.clone());
|
||||
}
|
||||
spans.push(Span::raw(" ".repeat(pad)));
|
||||
spans.push(Span::styled(" | ", Style::default().fg(Theme::BORDER)));
|
||||
}
|
||||
spans.push(Span::raw("\n"));
|
||||
|
||||
if r == 0 {
|
||||
spans.push(Span::styled(" |", Style::default().fg(Theme::BORDER)));
|
||||
for width in &col_widths {
|
||||
spans.push(Span::styled(format!("{}-|", "-".repeat(*width + 2)), Style::default().fg(Theme::BORDER)));
|
||||
}
|
||||
spans.push(Span::raw("\n"));
|
||||
}
|
||||
}
|
||||
spans.push(Span::raw("\n"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -136,19 +201,25 @@ pub fn render_markdown(text: &str, width: u16) -> Vec<Span<'static>> {
|
||||
s,
|
||||
Style::default().fg(color).add_modifier(Modifier::BOLD),
|
||||
));
|
||||
} else if in_table_cell {
|
||||
current_cell.push(Span::raw(s));
|
||||
} else {
|
||||
spans.push(Span::raw(s));
|
||||
}
|
||||
}
|
||||
pulldown_cmark::Event::Code(text) => {
|
||||
// Inline code with background
|
||||
spans.push(Span::styled(
|
||||
let span = Span::styled(
|
||||
format!(" {text} "),
|
||||
Style::default()
|
||||
.fg(Theme::ACCENT_TEAL)
|
||||
.bg(Theme::CODE_BAR)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
));
|
||||
);
|
||||
if in_table_cell {
|
||||
current_cell.push(span);
|
||||
} else {
|
||||
spans.push(span);
|
||||
}
|
||||
}
|
||||
pulldown_cmark::Event::SoftBreak => {
|
||||
spans.push(Span::raw(" "));
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
use crossterm::event::{EnableMouseCapture, EnableMouseScrollCapture};
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user