Skip to content

Commit e99b7ca

Browse files
committed
sdjifodjio
1 parent 4b7ccbf commit e99b7ca

File tree

3 files changed

+13
-192
lines changed

3 files changed

+13
-192
lines changed

crates/chat-cli/src/cli/chat/mod.rs

Lines changed: 9 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ mod message;
99
mod parse;
1010
mod parser;
1111
mod prompt;
12-
mod shared_writer;
1312
#[cfg(unix)]
1413
mod skim_integration;
1514
mod token_counter;
@@ -55,7 +54,6 @@ use crossterm::style::{
5554
Color,
5655
Stylize,
5756
};
58-
use crossterm::terminal::ClearType;
5957
use crossterm::{
6058
cursor,
6159
execute,
@@ -82,8 +80,9 @@ use rand::distr::{
8280
Alphanumeric,
8381
SampleString,
8482
};
85-
use shared_writer::SharedWriter;
8683
use tokio::signal::ctrl_c;
84+
use util::shared_writer::SharedWriter;
85+
use util::ui::draw_box;
8786

8887
use crate::fig_api_client::StreamingClient;
8988
use crate::fig_api_client::clients::SendMessageOutput;
@@ -676,100 +675,6 @@ impl ChatContext {
676675
Ok(content.trim().to_string())
677676
}
678677

679-
fn draw_tip_box(&mut self, text: &str) -> Result<()> {
680-
let box_width = GREETING_BREAK_POINT;
681-
let inner_width = box_width - 4; // account for │ and padding
682-
683-
// wrap the single line into multiple lines respecting inner width
684-
// Manually wrap the text by splitting at word boundaries
685-
let mut wrapped_lines = Vec::new();
686-
let mut line = String::new();
687-
688-
for word in text.split_whitespace() {
689-
if line.len() + word.len() < inner_width {
690-
if !line.is_empty() {
691-
line.push(' ');
692-
}
693-
line.push_str(word);
694-
} else {
695-
// Here we need to account for words that are too long as well
696-
if word.len() >= inner_width {
697-
let mut start = 0_usize;
698-
for (i, _) in word.chars().enumerate() {
699-
if i - start >= inner_width {
700-
wrapped_lines.push(word[start..i].to_string());
701-
start = i;
702-
}
703-
}
704-
wrapped_lines.push(word[start..].to_string());
705-
line = String::new();
706-
} else {
707-
wrapped_lines.push(line);
708-
line = word.to_string();
709-
}
710-
}
711-
}
712-
713-
if !line.is_empty() {
714-
wrapped_lines.push(line);
715-
}
716-
717-
// ───── Did you know? ─────
718-
let label = " Did you know? ";
719-
let side_len = (box_width.saturating_sub(label.len())) / 2;
720-
let top_border = format!(
721-
"╭{}{}{}╮",
722-
"─".repeat(side_len - 1),
723-
label,
724-
"─".repeat(box_width - side_len - label.len() - 1)
725-
);
726-
727-
// Build output
728-
execute!(
729-
self.output,
730-
terminal::Clear(ClearType::CurrentLine),
731-
cursor::MoveToColumn(0),
732-
style::Print(format!("{top_border}\n")),
733-
)?;
734-
735-
// Top vertical padding
736-
execute!(
737-
self.output,
738-
style::Print(format!("│{: <width$}│\n", "", width = box_width - 2))
739-
)?;
740-
741-
// Centered wrapped content
742-
for line in wrapped_lines {
743-
let visible_line_len = strip_ansi_escapes::strip(&line).len();
744-
let left_pad = box_width.saturating_sub(4).saturating_sub(visible_line_len) / 2;
745-
746-
let content = format!(
747-
"│ {: <pad$}{}{: <rem$} │",
748-
"",
749-
line,
750-
"",
751-
pad = left_pad,
752-
rem = box_width
753-
.saturating_sub(4)
754-
.saturating_sub(left_pad)
755-
.saturating_sub(visible_line_len),
756-
);
757-
execute!(self.output, style::Print(format!("{}\n", content)))?;
758-
}
759-
760-
// Bottom vertical padding
761-
execute!(
762-
self.output,
763-
style::Print(format!("│{: <width$}│\n", "", width = box_width - 2))
764-
)?;
765-
766-
// Bottom rounded corner line: ╰────────────╯
767-
let bottom = format!("╰{}╯", "─".repeat(box_width - 2));
768-
execute!(self.output, style::Print(format!("{}\n", bottom)))?;
769-
770-
Ok(())
771-
}
772-
773678
async fn try_chat(&mut self) -> Result<()> {
774679
let is_small_screen = self.terminal_width() < GREETING_BREAK_POINT;
775680
if self.interactive && self.settings.get_bool_or("chat.greeting.enabled", true) {
@@ -796,7 +701,13 @@ impl ChatContext {
796701
style::Print("\n")
797702
)?;
798703
} else {
799-
self.draw_tip_box(tip)?;
704+
draw_box(
705+
self.output.clone(),
706+
"Did you know?",
707+
tip,
708+
GREETING_BREAK_POINT,
709+
Color::DarkGrey,
710+
)?;
800711
}
801712

802713
execute!(
@@ -3469,9 +3380,6 @@ fn create_stream(model_responses: serde_json::Value) -> StreamingClient {
34693380

34703381
#[cfg(test)]
34713382
mod tests {
3472-
use bstr::ByteSlice;
3473-
use shared_writer::TestWriterWithSink;
3474-
34753383
use super::*;
34763384

34773385
#[tokio::test]
@@ -3854,86 +3762,4 @@ mod tests {
38543762
assert_eq!(processed, expected.trim().to_string(), "Failed for input: {}", input);
38553763
}
38563764
}
3857-
3858-
#[tokio::test]
3859-
async fn test_draw_tip_box() {
3860-
let ctx = Context::builder().with_test_home().await.unwrap().build_fake();
3861-
let buf = Arc::new(std::sync::Mutex::new(Vec::<u8>::new()));
3862-
let test_writer = TestWriterWithSink { sink: buf.clone() };
3863-
let output = SharedWriter::new(test_writer.clone());
3864-
let tool_manager = ToolManager::default();
3865-
let tool_config = serde_json::from_str::<HashMap<String, ToolSpec>>(include_str!("tools/tool_index.json"))
3866-
.expect("Tools failed to load");
3867-
let test_client = create_stream(serde_json::json!([]));
3868-
3869-
let mut chat_context = ChatContext::new(
3870-
Arc::clone(&ctx),
3871-
"fake_conv_id",
3872-
Settings::new(),
3873-
State::new(),
3874-
output,
3875-
None,
3876-
InputSource::new_mock(vec![]),
3877-
true,
3878-
test_client,
3879-
|| Some(80),
3880-
tool_manager,
3881-
None,
3882-
tool_config,
3883-
ToolPermissions::new(0),
3884-
)
3885-
.await
3886-
.unwrap();
3887-
3888-
// Test with a short tip
3889-
let short_tip = "This is a short tip";
3890-
chat_context.draw_tip_box(short_tip).expect("Failed to draw tip box");
3891-
3892-
// Test with a longer tip that should wrap
3893-
let long_tip = "This is a much longer tip that should wrap to multiple lines because it exceeds the inner width of the tip box which is calculated based on the GREETING_BREAK_POINT constant";
3894-
chat_context.draw_tip_box(long_tip).expect("Failed to draw tip box");
3895-
3896-
// Test with a long tip with two long words that should wrap
3897-
let long_tip_with_one_long_word = {
3898-
let mut s = "a".repeat(200);
3899-
s.push(' ');
3900-
s.push_str(&"a".repeat(200));
3901-
s
3902-
};
3903-
chat_context
3904-
.draw_tip_box(long_tip_with_one_long_word.as_str())
3905-
.expect("Failed to draw tip box");
3906-
3907-
// Test with a long tip with two long words that should wrap
3908-
let long_tip_with_two_long_words = "a".repeat(200);
3909-
chat_context
3910-
.draw_tip_box(long_tip_with_two_long_words.as_str())
3911-
.expect("Failed to draw tip box");
3912-
3913-
// Get the output and verify it contains expected formatting elements
3914-
let content = test_writer.get_content();
3915-
let output_str = content.to_str_lossy();
3916-
3917-
// Check for box drawing characters
3918-
assert!(output_str.contains("╭"), "Output should contain top-left corner");
3919-
assert!(output_str.contains("╮"), "Output should contain top-right corner");
3920-
assert!(output_str.contains("│"), "Output should contain vertical lines");
3921-
assert!(output_str.contains("╰"), "Output should contain bottom-left corner");
3922-
assert!(output_str.contains("╯"), "Output should contain bottom-right corner");
3923-
3924-
// Check for the label
3925-
assert!(
3926-
output_str.contains("Did you know?"),
3927-
"Output should contain the 'Did you know?' label"
3928-
);
3929-
3930-
// Check that both tips are present
3931-
assert!(output_str.contains(short_tip), "Output should contain the short tip");
3932-
3933-
// For the long tip, we check for substrings since it will be wrapped
3934-
let long_tip_parts: Vec<&str> = long_tip.split_whitespace().collect();
3935-
for part in long_tip_parts.iter().take(3) {
3936-
assert!(output_str.contains(part), "Output should contain parts of the long tip");
3937-
}
3938-
}
39393765
}

crates/chat-cli/src/cli/chat/util/ui.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,10 @@ mod tests {
120120

121121
use bstr::ByteSlice;
122122
use crossterm::style::Color;
123-
use shared_writer::TestWriterWithSink;
124-
125-
use crate::GREETING_BREAK_POINT;
126-
use crate::chat::util::shared_writer::{
127-
self,
128-
SharedWriter,
129-
};
130-
use crate::util::ui::draw_box;
123+
124+
use super::*;
125+
use crate::cli::chat::GREETING_BREAK_POINT;
126+
use crate::cli::chat::util::shared_writer::TestWriterWithSink;
131127

132128
#[tokio::test]
133129
async fn test_draw_tip_box() {

crates/chat-cli/src/fig_settings/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
pub mod error;
2-
pub mod keys;
32
pub mod settings;
43
pub mod sqlite;
54
pub mod state;

0 commit comments

Comments
 (0)