dracula theme tweaks
This commit is contained in:
@@ -249,6 +249,150 @@ impl TerminalState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse markdown and convert to styled lines
|
||||||
|
fn parse_markdown_line(&self, line: &str) -> Line {
|
||||||
|
let mut spans = Vec::new();
|
||||||
|
let mut chars = line.chars().peekable();
|
||||||
|
let mut current_text = String::new();
|
||||||
|
|
||||||
|
// Check for headers first
|
||||||
|
if line.starts_with("### ") {
|
||||||
|
return Line::from(Span::styled(
|
||||||
|
format!(" {}", &line[4..]),
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_cyan.to_color())
|
||||||
|
.add_modifier(Modifier::BOLD | Modifier::UNDERLINED),
|
||||||
|
));
|
||||||
|
} else if line.starts_with("## ") {
|
||||||
|
return Line::from(Span::styled(
|
||||||
|
format!(" {}", &line[3..]),
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_amber.to_color())
|
||||||
|
.add_modifier(Modifier::BOLD),
|
||||||
|
));
|
||||||
|
} else if line.starts_with("# ") {
|
||||||
|
return Line::from(Span::styled(
|
||||||
|
format!(" {}", &line[2..]),
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_green.to_color())
|
||||||
|
.add_modifier(Modifier::BOLD),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for code block markers
|
||||||
|
if line.starts_with("```") {
|
||||||
|
return Line::from(Span::styled(
|
||||||
|
format!(" {}", line),
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_dim_green.to_color())
|
||||||
|
.bg(Color::Rgb(40, 42, 54)), // Dark background for code blocks
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add leading space
|
||||||
|
spans.push(Span::raw(" "));
|
||||||
|
|
||||||
|
// Parse inline formatting
|
||||||
|
while let Some(ch) = chars.next() {
|
||||||
|
if ch == '*' {
|
||||||
|
// Check for bold (**) or italic (*)
|
||||||
|
if chars.peek() == Some(&'*') {
|
||||||
|
chars.next(); // consume second *
|
||||||
|
// Save current text
|
||||||
|
if !current_text.is_empty() {
|
||||||
|
spans.push(Span::styled(
|
||||||
|
current_text.clone(),
|
||||||
|
Style::default().fg(self.theme.terminal_green.to_color()),
|
||||||
|
));
|
||||||
|
current_text.clear();
|
||||||
|
}
|
||||||
|
// Find closing **
|
||||||
|
let mut bold_text = String::new();
|
||||||
|
while let Some(ch) = chars.next() {
|
||||||
|
if ch == '*' && chars.peek() == Some(&'*') {
|
||||||
|
chars.next(); // consume second *
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bold_text.push(ch);
|
||||||
|
}
|
||||||
|
spans.push(Span::styled(
|
||||||
|
bold_text,
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_amber.to_color())
|
||||||
|
.add_modifier(Modifier::BOLD),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// Handle italic (*)
|
||||||
|
if !current_text.is_empty() {
|
||||||
|
spans.push(Span::styled(
|
||||||
|
current_text.clone(),
|
||||||
|
Style::default().fg(self.theme.terminal_green.to_color()),
|
||||||
|
));
|
||||||
|
current_text.clear();
|
||||||
|
}
|
||||||
|
// Find closing *
|
||||||
|
let mut italic_text = String::new();
|
||||||
|
while let Some(ch) = chars.next() {
|
||||||
|
if ch == '*' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
italic_text.push(ch);
|
||||||
|
}
|
||||||
|
spans.push(Span::styled(
|
||||||
|
italic_text,
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_cyan.to_color())
|
||||||
|
.add_modifier(Modifier::ITALIC),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else if ch == '`' {
|
||||||
|
// Handle inline code
|
||||||
|
if !current_text.is_empty() {
|
||||||
|
spans.push(Span::styled(
|
||||||
|
current_text.clone(),
|
||||||
|
Style::default().fg(self.theme.terminal_green.to_color()),
|
||||||
|
));
|
||||||
|
current_text.clear();
|
||||||
|
}
|
||||||
|
// Find closing `
|
||||||
|
let mut code_text = String::new();
|
||||||
|
while let Some(ch) = chars.next() {
|
||||||
|
if ch == '`' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code_text.push(ch);
|
||||||
|
}
|
||||||
|
spans.push(Span::styled(
|
||||||
|
code_text,
|
||||||
|
Style::default()
|
||||||
|
.fg(self.theme.terminal_cyan.to_color())
|
||||||
|
.bg(Color::Rgb(40, 42, 54)),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
current_text.push(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any remaining text
|
||||||
|
if !current_text.is_empty() {
|
||||||
|
spans.push(Span::styled(
|
||||||
|
current_text,
|
||||||
|
Style::default().fg(self.theme.terminal_green.to_color()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the line with all spans
|
||||||
|
if spans.len() > 1 { // More than just the leading space
|
||||||
|
Line::from(spans)
|
||||||
|
} else {
|
||||||
|
// Fallback to plain text if no formatting found
|
||||||
|
Line::from(Span::styled(
|
||||||
|
format!(" {}", line),
|
||||||
|
Style::default().fg(self.theme.terminal_green.to_color()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add text to output history
|
/// Add text to output history
|
||||||
fn add_output(&mut self, text: &str) {
|
fn add_output(&mut self, text: &str) {
|
||||||
let mut lines = text.lines();
|
let mut lines = text.lines();
|
||||||
@@ -574,7 +718,7 @@ impl RetroTui {
|
|||||||
Self::draw_input_area(f, chunks[0], &state.input_buffer, state.cursor_position, state.cursor_blink, state.is_processing, &state.theme);
|
Self::draw_input_area(f, chunks[0], &state.input_buffer, state.cursor_position, state.cursor_blink, state.is_processing, &state.theme);
|
||||||
|
|
||||||
// Draw main output area
|
// Draw main output area
|
||||||
Self::draw_output_area(f, chunks[1], &state.output_history, state.scroll_offset, &state.theme);
|
Self::draw_output_area(f, chunks[1], state, &state.output_history, state.scroll_offset, &state.theme);
|
||||||
|
|
||||||
// Draw activity area only if it's visible (during animation or when shown)
|
// Draw activity area only if it's visible (during animation or when shown)
|
||||||
if activity_height > 0 {
|
if activity_height > 0 {
|
||||||
@@ -678,6 +822,7 @@ impl RetroTui {
|
|||||||
fn draw_output_area(
|
fn draw_output_area(
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
area: Rect,
|
area: Rect,
|
||||||
|
state: &TerminalState,
|
||||||
output_history: &[String],
|
output_history: &[String],
|
||||||
scroll_offset: usize,
|
scroll_offset: usize,
|
||||||
theme: &ColorTheme,
|
theme: &ColorTheme,
|
||||||
@@ -703,6 +848,8 @@ impl RetroTui {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut in_code_block = false;
|
||||||
|
|
||||||
// Get visible lines
|
// Get visible lines
|
||||||
let visible_lines: Vec<Line> = output_history
|
let visible_lines: Vec<Line> = output_history
|
||||||
.iter()
|
.iter()
|
||||||
@@ -745,6 +892,21 @@ impl RetroTui {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for code block boundaries
|
||||||
|
if line.starts_with("```") {
|
||||||
|
in_code_block = !in_code_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're in a code block, style it appropriately
|
||||||
|
if in_code_block && !line.starts_with("```") {
|
||||||
|
return Line::from(Span::styled(
|
||||||
|
format!(" {}", line),
|
||||||
|
Style::default()
|
||||||
|
.fg(theme.terminal_cyan.to_color())
|
||||||
|
.bg(Color::Rgb(40, 42, 54)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// Check if this is a box border line
|
// Check if this is a box border line
|
||||||
if line.starts_with("┌")
|
if line.starts_with("┌")
|
||||||
|| line.starts_with("└")
|
|| line.starts_with("└")
|
||||||
@@ -756,7 +918,14 @@ impl RetroTui {
|
|||||||
Style::default().fg(theme.terminal_dim_green.to_color()),
|
Style::default().fg(theme.terminal_dim_green.to_color()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// Apply different colors based on content
|
|
||||||
|
// Check if line contains markdown formatting
|
||||||
|
if line.contains("**") || line.contains('`') || line.starts_with('#') {
|
||||||
|
// Use the markdown parser
|
||||||
|
return state.parse_markdown_line(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply different colors based on content (existing logic)
|
||||||
let style = if line.starts_with("ERROR:") {
|
let style = if line.starts_with("ERROR:") {
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(theme.terminal_red.to_color())
|
.fg(theme.terminal_red.to_color())
|
||||||
|
|||||||
Reference in New Issue
Block a user