Skip to content

Commit

Permalink
use bat as formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
pythops committed Oct 26, 2023
1 parent e36f8ae commit 1849fd7
Show file tree
Hide file tree
Showing 8 changed files with 1,026 additions and 369 deletions.
1,223 changes: 928 additions & 295 deletions Cargo.lock

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ homepage = "https://github.com/pythops/tenere"
repository = "https://github.com/pythops/tenere"

[dependencies]
crossterm = "0.26.1"
tui = { package = "ratatui", version = "0.22.0", features = ["all-widgets"] }
unicode-width = "0.1.10"
crossterm = "0.26"
tui = { package = "ratatui", version = "0.24", features = ["all-widgets"] }
unicode-width = "0.1"
reqwest = { version = "0.11", default-features = false, features = [
"blocking",
"json",
"rustls-tls",
] }
serde_json = "1.0"
termimad = "0.20"
ansi-to-tui = "3.1.0"
serde_json = "1"
ansi-to-tui = "3"

clap = { version = "4", features = ["derive", "cargo"] }
toml = { version = "0.7" }
serde = { version = "1.0", features = ["derive"] }
dirs = "5.0.1"
regex = "1.9.3"
colored = "2.0.4"
bat = "0.24.0"
serde = { version = "1", features = ["derive"] }
dirs = "5"
regex = "1"
colored = "2"
bat = "0.24"
syntect = "5"
16 changes: 9 additions & 7 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use std::collections::HashMap;
use std::sync::atomic::AtomicBool;

use crate::config::Config;
use crate::formatter::Formatter;
use crate::notification::Notification;
use crate::spinner::Spinner;
use crossterm::event::KeyCode;
use tui::widgets::scrollbar::ScrollbarState;
use tui::widgets::ScrollbarState;

use std::sync::Arc;

Expand All @@ -26,13 +27,12 @@ pub enum FocusedBlock {
Preview,
}

#[derive(Debug)]
pub struct App {
pub struct App<'a> {
pub prompt: String,
pub mode: Mode,
pub running: bool,
pub chat: Vec<String>,
pub scroll: u16,
pub scroll: usize,
pub previous_key: KeyCode,
pub focused_block: FocusedBlock,
pub show_help_popup: bool,
Expand All @@ -46,11 +46,12 @@ pub struct App {
pub spinner: Spinner,
pub terminate_response_signal: Arc<AtomicBool>,
pub chat_scroll_state: ScrollbarState,
pub chat_scroll: u16,
pub chat_scroll: usize,
pub formatter: Formatter<'a>,
}

impl App {
pub fn new(config: Arc<Config>) -> Self {
impl<'a> App<'a> {
pub fn new(config: Arc<Config>, formatter: Formatter<'a>) -> Self {
Self {
running: true,
prompt: String::from(">_ "),
Expand All @@ -71,6 +72,7 @@ impl App {
terminate_response_signal: Arc::new(AtomicBool::new(false)),
chat_scroll_state: ScrollbarState::default(),
chat_scroll: 0,
formatter,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl Config {
.join("tenere")
.join("config.toml");

let config = std::fs::read_to_string(conf_path).unwrap_or(String::new());
let config = std::fs::read_to_string(conf_path).unwrap_or_default();
let app_config: Config = toml::from_str(&config).unwrap();
app_config
}
Expand Down
23 changes: 23 additions & 0 deletions src/formatter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use ansi_to_tui::IntoText;

use bat::{assets::HighlightingAssets, config::Config, controller::Controller, Input};
use tui::text::Text;

pub struct Formatter<'a> {
controller: Controller<'a>,
}

impl<'a> Formatter<'a> {
pub fn new(config: &'a Config, assets: &'a HighlightingAssets) -> Self {
let controller = Controller::new(config, assets);
Self { controller }
}
pub fn format(&self, input: &str) -> Text<'static> {
let mut buffer = String::new();
let input = Input::from_bytes(input.as_bytes()).name("text.md");
self.controller
.run(vec![input.into()], Some(&mut buffer))
.unwrap();
buffer.into_text().unwrap_or(Text::from(buffer))
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ pub mod notification;
pub mod llm;

pub mod spinner;

pub mod formatter;
13 changes: 12 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use tenere::app::{App, AppResult};
use tenere::cli;
use tenere::config::Config;
use tenere::event::{Event, EventHandler};
use tenere::formatter::Formatter;
use tenere::handler::handle_key_events;
use tenere::llm::LLMAnswer;
use tenere::tui::Tui;
Expand All @@ -20,7 +21,17 @@ fn main() -> AppResult<()> {
cli::cli().version(crate_version!()).get_matches();

let config = Arc::new(Config::load());
let mut app = App::new(config.clone());

let formatter_config = bat::config::Config {
colored_output: true,
..Default::default()
};
let formatter_assets = bat::assets::HighlightingAssets::from_binary();

let formatter = Formatter::new(&formatter_config, &formatter_assets);

let mut app = App::new(config.clone(), formatter);

let llm = Arc::new(LLMModel::init(LLMBackend::ChatGPT, config));

let backend = CrosstermBackend::new(io::stderr());
Expand Down
94 changes: 40 additions & 54 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std;

use crate::app::{App, FocusedBlock, Mode};
use tui::{
backend::Backend,
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Style},
text::{Line, Span, Text},
Expand Down Expand Up @@ -97,7 +96,7 @@ pub fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
.split(popup_layout[1])[1]
}

pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
pub fn render(app: &mut App, frame: &mut Frame) {
// Layout
let frame_size = frame.size();

Expand Down Expand Up @@ -146,8 +145,8 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
if diff < 0 {
app.scroll = 0;
} else {
app.scroll = diff as u16;
scroll = app.scroll;
app.scroll = diff as usize;
scroll = app.scroll as u16;
}
}

Expand Down Expand Up @@ -199,15 +198,13 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
let mut messages: String = app.chat.iter().map(|m| m.to_string()).collect();
messages.push_str(app.answer.as_str());

let nb_lines = termimad::term_text(messages.as_str()).lines.len() + 3;
let messages_height = termimad::term_text(messages.as_str())
.lines
.iter()
.fold(nb_lines, |acc, line| {
acc + line.visible_length() / frame_size.width as usize
});
let text = app.formatter.format(&messages);
let nb_lines = text.lines.len() + 3;
let messages_height = text.lines.iter().fold(nb_lines, |acc, line| {
acc + line.width() / frame_size.width as usize
});

messages_height as u16
messages_height
};

let chat_paragraph = {
Expand All @@ -222,16 +219,16 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
if diff > 0 {
let diff = diff as u16;

if app.scroll >= diff {
app.scroll = diff;
if app.scroll >= diff.into() {
app.scroll = diff.into();
app.chat_scroll_state.last()
} else {
scroll = app.scroll;
scroll = app.scroll as u16;
app.chat_scroll_state.position(app.scroll);
}
}
} else {
app.chat_scroll = diff as u16;
app.chat_scroll = diff as usize;
app.chat_scroll_state.last();
}

Expand All @@ -243,17 +240,11 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
};
let assets = HighlightingAssets::from_binary();
let controller = Controller::new(&config, &assets);
let input = Input::from_bytes(messages.as_bytes())
.name("chat.md")
.kind("file")
.title("Chat");
let input = Input::from_bytes(messages.as_bytes()).name("Readme.markdown");
controller
.run(vec![input.into()], Some(&mut buffer))
.unwrap();
termimad::term_text(&buffer)
.to_string()
.into_text()
.unwrap_or(Text::from(messages))
buffer.into_text().unwrap_or(Text::from(buffer))
})
.scroll((scroll, 0))
.wrap(Wrap { trim: false })
Expand Down Expand Up @@ -281,7 +272,7 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {

frame.render_widget(chat_paragraph, chat_block);

if chat_messages_height > chat_block.height {
if chat_messages_height > chat_block.height.into() {
frame.render_stateful_widget(
Scrollbar::default()
.orientation(ScrollbarOrientation::VerticalRight)
Expand Down Expand Up @@ -360,20 +351,21 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {

if height_diff > 0 {
if let FocusedBlock::Preview = app.focused_block {
if app.scroll > height_diff as u16 {
app.scroll = height_diff as u16;
scroll = app.scroll;
if app.scroll > height_diff as usize {
app.scroll = height_diff as usize;
scroll = app.scroll as u16;
}
}
}
scroll
};

let preview = Paragraph::new({
termimad::term_text(preview_chat.as_str())
.to_string()
.into_text()
.unwrap_or(Text::from(preview_chat))
if !preview_chat.is_empty() {
app.formatter.format(preview_chat.as_str())
} else {
Text::from("")
}
})
.wrap(Wrap { trim: false })
.scroll((preview_scroll, 0))
Expand Down Expand Up @@ -414,22 +406,17 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
app.config.archive_file_name
);

let block = Paragraph::new(
termimad::term_text(help.as_str())
.to_string()
.into_text()
.unwrap_or(Text::from(help)),
)
.wrap(Wrap { trim: false })
.block(
Block::default()
.title(" Help ")
.title_alignment(tui::layout::Alignment::Center)
.borders(Borders::ALL)
.style(Style::default())
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(Color::Yellow)),
);
let block = Paragraph::new(app.formatter.format(help.as_str()))
.wrap(Wrap { trim: false })
.block(
Block::default()
.title(" Help ")
.title_alignment(tui::layout::Alignment::Center)
.borders(Borders::ALL)
.style(Style::default())
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(Color::Yellow)),
);
let area = help_rect(frame_size);
frame.render_widget(Clear, area);
frame.render_widget(block, area);
Expand All @@ -442,12 +429,11 @@ pub fn render<B: Backend>(app: &mut App, frame: &mut Frame<'_, B>) {
NotificationLevel::Error => Color::Red,
};

let block = Paragraph::new(
termimad::term_text(n.message.clone().as_str())
.to_string()
.into_text()
.unwrap_or(Text::from(n.message.clone())),
)
let block = Paragraph::new(if !n.message.is_empty() {
app.formatter.format(n.message.as_str())
} else {
Text::from("")
})
.wrap(Wrap { trim: false })
.alignment(tui::layout::Alignment::Center)
.block(
Expand Down

0 comments on commit 1849fd7

Please sign in to comment.