errors
This commit is contained in:
parent
d8e445b5f7
commit
4a7817a239
4 changed files with 82 additions and 8 deletions
|
|
@ -1,20 +1,20 @@
|
|||
use ratatui_themes::{Theme, ThemeName};
|
||||
use regex::bytes::Regex;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fs::{self, DirEntry},
|
||||
io,
|
||||
ops::ControlFlow,
|
||||
path::{Path, PathBuf},
|
||||
process::exit,
|
||||
rc::Rc,
|
||||
time::Instant,
|
||||
};
|
||||
use tui_widget_list::{ListBuilder, ListView};
|
||||
|
||||
use crate::tui::{
|
||||
filter::FilterKind,
|
||||
log_viewer::{InputState, InputTarget, LogViewer},
|
||||
model::pretty_print_value,
|
||||
widgets::{hyperlink::Hyperlink, items::Items, line_text::Highlighted},
|
||||
widgets::{hyperlink::Hyperlink, items::Items, last_error::LastError},
|
||||
};
|
||||
use crate::tui::{
|
||||
filter::{Filter, Matcher},
|
||||
|
|
@ -27,7 +27,7 @@ use ratatui::{
|
|||
buffer::Buffer,
|
||||
crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers},
|
||||
layout::{Constraint, HorizontalAlignment, Layout, Rect},
|
||||
style::Style,
|
||||
style::{self, Style},
|
||||
text::Line,
|
||||
widgets::{
|
||||
Block, Clear, List, ListItem, ListState, Padding, Paragraph, StatefulWidget, Widget, Wrap,
|
||||
|
|
@ -116,6 +116,8 @@ struct App {
|
|||
compiler_root: Option<PathBuf>,
|
||||
current_file: Option<LogfileReader>,
|
||||
theme: Theme,
|
||||
|
||||
last_error: LastError,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
|
@ -126,6 +128,7 @@ impl App {
|
|||
logs_dir,
|
||||
compiler_root,
|
||||
theme,
|
||||
last_error: LastError::new(),
|
||||
};
|
||||
res.replace_tab(res.choose_file());
|
||||
res
|
||||
|
|
@ -356,6 +359,8 @@ impl App {
|
|||
|
||||
fn run(mut self, mut terminal: DefaultTerminal) -> io::Result<()> {
|
||||
loop {
|
||||
self.last_error.check_expired();
|
||||
|
||||
terminal.draw(|frame| frame.render_widget(&mut self, frame.area()))?;
|
||||
|
||||
if let Event::Key(key) = event::read()? {
|
||||
|
|
@ -376,12 +381,14 @@ impl App {
|
|||
let highlighted = Style::new().fg(palette.accent).bg(palette.selection);
|
||||
let border = Style::new().fg(palette.fg).bg(palette.bg);
|
||||
let border_highlighted = Style::new().fg(palette.secondary).bg(palette.bg);
|
||||
let error = Style::new().fg(palette.error).bg(palette.bg);
|
||||
|
||||
Styles {
|
||||
default,
|
||||
highlighted,
|
||||
border,
|
||||
border_highlighted,
|
||||
error,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,11 +407,12 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
struct Styles {
|
||||
pub struct Styles {
|
||||
default: Style,
|
||||
highlighted: Style,
|
||||
border: Style,
|
||||
border_highlighted: Style,
|
||||
error: Style,
|
||||
}
|
||||
|
||||
impl Widget for &mut App {
|
||||
|
|
@ -471,6 +479,8 @@ impl Widget for &mut App {
|
|||
.style(styles.default)
|
||||
.render(middle, buf);
|
||||
|
||||
let [right, error] =
|
||||
Layout::vertical([Constraint::Length(1), Constraint::Length(1)]).areas(right);
|
||||
Paragraph::new("").style(styles.default).render(right, buf);
|
||||
|
||||
for tab in &mut self.tabs {
|
||||
|
|
@ -533,6 +543,7 @@ impl Widget for &mut App {
|
|||
.get(idx)
|
||||
.map(|(a, b)| (a.clone(), b.clone()))
|
||||
}),
|
||||
self.last_error.clone(),
|
||||
)
|
||||
.styled_ref(&styles)
|
||||
.render(main_area, buf);
|
||||
|
|
@ -575,6 +586,8 @@ impl Widget for &mut App {
|
|||
Paragraph::new(HELP_TEXT).render(popup_area, buf);
|
||||
}
|
||||
}
|
||||
|
||||
self.last_error.clone().styled(&styles).render(error, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::rc::Rc;
|
||||
use std::{cell::OnceCell, rc::Rc};
|
||||
|
||||
use itertools::Itertools;
|
||||
use ratatui::widgets::{List, ListItem, Widget};
|
||||
|
|
@ -8,6 +8,7 @@ use crate::tui::{
|
|||
log_viewer::{FieldMatcher, InputState, InputTarget},
|
||||
model::LogEntry,
|
||||
widgets::{
|
||||
last_error::LastError,
|
||||
line_text::Highlighted,
|
||||
styled::{IntoStyled, Styled},
|
||||
},
|
||||
|
|
@ -92,6 +93,7 @@ pub struct Items<'a> {
|
|||
input_state: &'a InputState,
|
||||
|
||||
selected_footer_field: Option<(String, String)>,
|
||||
last_error: LastError,
|
||||
}
|
||||
|
||||
impl<'a> Items<'a> {
|
||||
|
|
@ -100,12 +102,14 @@ impl<'a> Items<'a> {
|
|||
selected_offset: usize,
|
||||
input_state: &'a InputState,
|
||||
selected_footer_field: Option<(String, String)>,
|
||||
last_error: LastError,
|
||||
) -> Self {
|
||||
Self {
|
||||
items,
|
||||
selected_offset,
|
||||
input_state,
|
||||
selected_footer_field,
|
||||
last_error,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,6 +124,7 @@ impl Widget for Styled<'_, &Items<'_>> {
|
|||
Self: Sized,
|
||||
{
|
||||
let ts = TreeState::from_items(&self.items);
|
||||
let regex_cache = OnceCell::new();
|
||||
|
||||
let list = List::new(
|
||||
self.inner
|
||||
|
|
@ -161,8 +166,13 @@ impl Widget for Styled<'_, &Items<'_>> {
|
|||
}
|
||||
}
|
||||
FieldMatcher::Regex(r) => {
|
||||
if let Ok(regex) = Regex::new(r)
|
||||
&& let Some(start_offset) = line.message.find(msg)
|
||||
if let Ok(regex) = regex_cache.get_or_init(|| {
|
||||
let regex = Regex::new(r);
|
||||
if let Err(e) = ®ex {
|
||||
self.last_error.set(format!("{e}"));
|
||||
}
|
||||
regex
|
||||
}) && let Some(start_offset) = line.message.find(msg)
|
||||
&& let Some(m) = regex.find(msg)
|
||||
{
|
||||
let from = start_offset + m.start();
|
||||
|
|
|
|||
50
src/tui/widgets/last_error.rs
Normal file
50
src/tui/widgets/last_error.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use std::{cell::RefCell, rc::Rc, time::Instant};
|
||||
|
||||
use ratatui::widgets::{Paragraph, Widget};
|
||||
|
||||
use crate::tui::widgets::styled::Styled;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LastError {
|
||||
inner: Rc<RefCell<Option<(String, Instant)>>>,
|
||||
}
|
||||
|
||||
impl LastError {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: Rc::new(RefCell::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&self, s: String) {
|
||||
*self.inner.borrow_mut() = Some((s, Instant::now()));
|
||||
}
|
||||
|
||||
pub fn check_expired(&self) {
|
||||
let inner = self.inner.borrow();
|
||||
if let Some((_, time)) = *inner {
|
||||
if Instant::now().duration_since(time).as_secs_f64() > 1.0 {
|
||||
drop(inner);
|
||||
*self.inner.borrow_mut() = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Styled<'_, LastError> {
|
||||
fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Paragraph::new(
|
||||
self.inner
|
||||
.inner
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|i| i.0.replace("\n", ""))
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.style(self.styles.error)
|
||||
.render(area, buf);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
pub mod hyperlink;
|
||||
pub mod items;
|
||||
pub mod last_error;
|
||||
pub mod line_text;
|
||||
pub mod styled;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue