From 2b3c899a0aa20074ed0e582c5965b359fe57bb77 Mon Sep 17 00:00:00 2001 From: honhimW Date: Tue, 17 Dec 2024 18:43:54 +0800 Subject: [PATCH] feat: CLi support raw data highlight & automatically scroll to end on commit --- src/components/console_output.rs | 22 +++++++++++++++++----- src/components/hash_table.rs | 2 +- src/components/highlight_value.rs | 8 ++++++++ src/components/list_table.rs | 2 +- src/components/raw_paragraph.rs | 2 +- src/components/raw_value.rs | 7 ++++--- src/components/set_table.rs | 2 +- src/components/stream_view.rs | 2 +- src/components/zset_table.rs | 2 +- src/tabs/cli.rs | 13 +++++++++---- src/utils.rs | 3 ++- 11 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/components/console_output.rs b/src/components/console_output.rs index 4aa468f..8dd5047 100644 --- a/src/components/console_output.rs +++ b/src/components/console_output.rs @@ -1,12 +1,13 @@ -use crate::components::console_output::OutputKind::{ERR, STD}; +use std::borrow::Cow; use ratatui::layout::{Position, Rect}; use ratatui::prelude::Text; -use ratatui::style::{Style}; +use ratatui::style::{Style, Stylize}; use ratatui::widgets::{Paragraph, Wrap}; use ratatui_macros::{line, span}; use std::cmp; use strum::Display; -use OutputKind::{Else, CMD}; +use OutputKind::{ERR, STD, CMD, Else, Raw}; +use crate::components::raw_value::raw_value_to_highlight_text; use crate::theme::get_color; pub struct ConsoleData<'a> { @@ -24,7 +25,8 @@ pub enum OutputKind { CMD, STD, ERR, - Else(Style) + Else(Style), + Raw, } impl ConsoleData<'_> { @@ -44,13 +46,23 @@ impl ConsoleData<'_> { let mut text = Text::default(); for (kind, l) in self.lines.iter() { let new_line = match kind { - CMD => line![span!(Style::default().fg(get_color(|t| &t.tab.cli.console.cmd)); l.clone())], STD => line![span!(Style::default().fg(get_color(|t| &t.tab.cli.console.out)); l.clone())], ERR => line![span!(Style::default().fg(get_color(|t| &t.tab.cli.console.err)); l.clone())], Else(style) => line![span!(*style; l.clone())], + Raw => line![], }; text.push_line(new_line); + if matches!(kind, Raw) { + let (highlight_text, content_type) = raw_value_to_highlight_text(Cow::from(l.clone()), true); + let ct = content_type.map(|ct| ct.to_string()).unwrap_or_default(); + text.push_line(line![span!(Style::default().dim(); format!("```{ct}"))]); + for x in highlight_text.lines { + text.push_line(x) + } + text.push_line(line![span!(Style::default().dim(); "```")]) + } + } let mut paragraph = Paragraph::new(text).wrap(Wrap { trim: false }); paragraph = paragraph.scroll((self.position.y, self.position.x)); diff --git a/src/components/hash_table.rs b/src/components/hash_table.rs index 53554d7..a2f6d23 100644 --- a/src/components/hash_table.rs +++ b/src/components/hash_table.rs @@ -165,7 +165,7 @@ impl HashValue { .map(|content| { let mut text = Text::default(); text.push_line(Line::default()); - let highlight_text = raw_value_to_highlight_text(Cow::from(content), false); + let (highlight_text, _) = raw_value_to_highlight_text(Cow::from(content), false); for line in highlight_text.lines { text.push_line(line); } diff --git a/src/components/highlight_value.rs b/src/components/highlight_value.rs index e737f5d..02f2edd 100644 --- a/src/components/highlight_value.rs +++ b/src/components/highlight_value.rs @@ -106,23 +106,31 @@ impl HighlightProcessor { } let is_json = self.process_json()?; if is_json { + self.content_type = Some(ContentType::Json); return Ok(()); } let is_xml = self.process_xml()?; if is_xml { + self.content_type = Some(ContentType::Xml); return Ok(()); } let is_ron = self.process_ron()?; if is_ron { + self.content_type = Some(ContentType::Ron); return Ok(()); } let is_plain = self.process_plain()?; if is_plain { + self.content_type = Some(ContentType::String); return Ok(()); } Ok(()) } + pub fn get_content_type(&self) -> Option { + self.content_type.clone() + } + #[allow(unused)] pub fn get_cursor_path(&self, row: usize, column: usize) -> Result { if let Some(tree) = &self.tree { diff --git a/src/components/list_table.rs b/src/components/list_table.rs index 560af2f..f85f5ba 100644 --- a/src/components/list_table.rs +++ b/src/components/list_table.rs @@ -160,7 +160,7 @@ impl ListValue { .map(|content| { let mut text = Text::default(); text.push_line(Line::default()); - let highlight_text = raw_value_to_highlight_text(Cow::from(content), false); + let (highlight_text, _) = raw_value_to_highlight_text(Cow::from(content), false); for line in highlight_text.lines { text.push_line(line); } diff --git a/src/components/raw_paragraph.rs b/src/components/raw_paragraph.rs index f09be9d..d7b0f8c 100644 --- a/src/components/raw_paragraph.rs +++ b/src/components/raw_paragraph.rs @@ -20,7 +20,7 @@ pub struct RawParagraph<'a> { impl<'a> RawParagraph<'a> { pub fn new(raw: String, content_type: Option, format: bool) -> Self { - let text = raw_value_to_highlight_text_with_content_type(Cow::from(raw.clone()), content_type.clone(), format); + let (text, _) = raw_value_to_highlight_text_with_content_type(Cow::from(raw.clone()), content_type.clone(), format); let paragraph = Paragraph::new(text).wrap(Wrap { trim: false }); Self { raw, diff --git a/src/components/raw_value.rs b/src/components/raw_value.rs index 5e17852..01759c6 100644 --- a/src/components/raw_value.rs +++ b/src/components/raw_value.rs @@ -6,11 +6,11 @@ use crate::theme::get_color; use crate::utils::ContentType; use crate::components::highlight_value::{HighlightKind, HighlightProcessor, HighlightText}; -pub fn raw_value_to_highlight_text(value: Cow, format: bool) -> Text { +pub fn raw_value_to_highlight_text(value: Cow, format: bool) -> (Text, Option) { raw_value_to_highlight_text_with_content_type(value, None, format) } -pub fn raw_value_to_highlight_text_with_content_type(value: Cow, content_type: Option, format: bool) -> Text { +pub fn raw_value_to_highlight_text_with_content_type(value: Cow, content_type: Option, format: bool) -> (Text, Option) { let mut processor = HighlightProcessor::new(value.to_string(), content_type); if !format { processor.disable_formatting(); @@ -58,5 +58,6 @@ pub fn raw_value_to_highlight_text_with_content_type(value: Cow, content_ty } } } - text + + (text, processor.get_content_type()) } diff --git a/src/components/set_table.rs b/src/components/set_table.rs index 4aca785..6a0d515 100644 --- a/src/components/set_table.rs +++ b/src/components/set_table.rs @@ -160,7 +160,7 @@ impl SetValue { .map(|content| { let mut text = Text::default(); text.push_line(Line::default()); - let highlight_text = raw_value_to_highlight_text(Cow::from(content), false); + let (highlight_text, _) = raw_value_to_highlight_text(Cow::from(content), false); for line in highlight_text.lines { text.push_line(line); } diff --git a/src/components/stream_view.rs b/src/components/stream_view.rs index 20ad81d..926e7e0 100644 --- a/src/components/stream_view.rs +++ b/src/components/stream_view.rs @@ -293,7 +293,7 @@ impl SteamView { .map(|content| { let mut text = Text::default(); text.push_line(Line::default()); - let highlight_text = raw_value_to_highlight_text(Cow::from(content), false); + let (highlight_text, _) = raw_value_to_highlight_text(Cow::from(content), false); for line in highlight_text.lines { text.push_line(line); } diff --git a/src/components/zset_table.rs b/src/components/zset_table.rs index ebb2b5f..3bebeae 100644 --- a/src/components/zset_table.rs +++ b/src/components/zset_table.rs @@ -169,7 +169,7 @@ impl ZSetValue { .map(|content| { let mut text = Text::default(); text.push_line(Line::default()); - let highlight_text = raw_value_to_highlight_text(Cow::from(content), false); + let (highlight_text, _) = raw_value_to_highlight_text(Cow::from(content), false); for line in highlight_text.lines { text.push_line(line); } diff --git a/src/tabs/cli.rs b/src/tabs/cli.rs index 10e0d51..d30a0e2 100644 --- a/src/tabs/cli.rs +++ b/src/tabs/cli.rs @@ -265,6 +265,7 @@ impl CliTab { self.lock_input = true; self.lock_at = Some(Instant::now()); self.console_data.push(OutputKind::CMD, format!(">_ {}", command)); + self.scroll_end(); self.console_data.build_paragraph(); if command.is_empty() { self.lock_input = false; @@ -466,10 +467,14 @@ fn value_to_lines(value: &Value, pad: u16) -> Vec<(OutputKind, String)> { } Value::BulkString(bulk_string) => { let bulk_string = bytes_to_string(bulk_string.clone()).unwrap_or_else(|e| e.to_string()); - let bulk_string = bulk_string.replace("\t", "\\t"); - // let bulk_string = format!("\"{}\"", bulk_string); - let lines = bulk_string.lines(); - lines.map(|line| format(line)).collect_vec() + if pad == 0 { + vec![(OutputKind::Raw, bulk_string)] + } else { + let bulk_string = bulk_string.replace("\t", "\\t"); + // let bulk_string = format!("\"{}\"", bulk_string); + let lines = bulk_string.lines(); + lines.map(|line| format(line)).collect_vec() + } } Value::Array(array) => { let mut lines = vec![]; diff --git a/src/utils.rs b/src/utils.rs index 5391119..56b9c7e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -8,9 +8,10 @@ use ron::ser::PrettyConfig; use serde::Serialize; use tui_textarea::TextArea; use jaded::Parser; +use strum::Display; #[allow(unused)] -#[derive(Default, Clone)] +#[derive(Default, Clone, Display)] pub enum ContentType { String, #[default]