Skip to content

Commit 77a1ed0

Browse files
fix: chat output styling (#657)
* fix: chat output styling * Update crates/q_cli/src/cli/chat/conversation_state.rs Co-authored-by: Chay Nabors <[email protected]> --------- Co-authored-by: Chay Nabors <[email protected]>
1 parent 539da87 commit 77a1ed0

File tree

7 files changed

+251
-53
lines changed

7 files changed

+251
-53
lines changed

crates/q_cli/src/cli/chat/conversation_state.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ use fig_settings::history::{
2929
};
3030
use fig_util::Shell;
3131
use regex::Regex;
32-
use tracing::warn;
32+
use tracing::{
33+
error,
34+
warn,
35+
};
3336

3437
use crate::cli::chat::ToolConfiguration;
3538
use crate::cli::chat::tools::{
@@ -282,9 +285,14 @@ fn build_env_state(modifiers: Option<&ContextModifiers>) -> EnvState {
282285
..Default::default()
283286
};
284287

285-
if let Ok(current_dir) = env::current_dir() {
286-
env_state.current_working_directory =
287-
Some(truncate_safe(&current_dir.to_string_lossy(), MAX_CURRENT_WORKING_DIRECTORY_LEN).into());
288+
match env::current_dir() {
289+
Ok(current_dir) => {
290+
env_state.current_working_directory =
291+
Some(truncate_safe(&current_dir.to_string_lossy(), MAX_CURRENT_WORKING_DIRECTORY_LEN).into());
292+
},
293+
Err(err) => {
294+
error!(?err, "Attempted to fetch the CWD but it did not exist.");
295+
},
288296
}
289297

290298
if modifiers.is_some_and(|c| c.env) {

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -509,18 +509,16 @@ Hi, I'm <g>Amazon Q</g>. Ask me anything.
509509
bail!("Exceeded max tool use recursion limit: {}", MAX_TOOL_USE_RECURSIONS);
510510
}
511511
for (_, tool) in &queued_tools {
512-
queue!(self.output, style::Print(format!("{}\n", "─".repeat(terminal_width))))?;
513-
queue!(self.output, cursor::MoveToPreviousLine(1))?;
514-
queue!(self.output, cursor::MoveToColumn(2))?;
515-
queue!(self.output, style::Print(format!(" {} ", tool.display_name())))?;
516-
queue!(self.output, cursor::MoveToNextLine(1))?;
512+
queue!(self.output, style::Print(format!("{}\n", "▔".repeat(terminal_width))))?;
513+
queue!(self.output, style::SetAttribute(Attribute::Bold))?;
514+
queue!(self.output, style::Print(format!("{}\n", tool.display_name())))?;
517515
queue!(self.output, style::SetAttribute(Attribute::NormalIntensity))?;
516+
queue!(self.output, style::Print(format!("{}\n\n", "▁".repeat(terminal_width))))?;
518517
tool.queue_description(&self.ctx, self.output)?;
519518
queue!(self.output, style::Print("\n"))?;
520-
queue!(self.output, cursor::MoveToNextLine(1))?;
521519
}
522-
queue!(self.output, style::Print("".repeat(terminal_width)))?;
523-
queue!(self.output, style::Print("\n"))?;
520+
queue!(self.output, style::Print("".repeat(terminal_width)))?;
521+
queue!(self.output, style::Print("\n\n"))?;
524522
execute!(
525523
self.output,
526524
style::Print("Enter "),

crates/q_cli/src/cli/chat/tools/fs_read.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use tracing::warn;
2121
use super::{
2222
InvokeOutput,
2323
OutputKind,
24-
relative_path,
24+
format_path,
2525
};
2626

2727
#[derive(Debug, Deserialize)]
@@ -49,11 +49,10 @@ impl FsRead {
4949
// we need to pass it through the Context first.
5050
let path = ctx.fs().chroot_path_str(&self.path);
5151
let is_file = ctx.fs().symlink_metadata(&self.path).await?.is_file();
52+
let cwd = ctx.env().current_dir()?;
5253

5354
if is_file {
54-
// TODO(bskiser): improve pathing display
55-
// let relative_path = relative_path(ctx.env().current_dir()?, &path);
56-
let relative_path = &path;
55+
let relative_path = format_path(&cwd, &path);
5756
if let Some((start, Some(end))) = self.read_range()? {
5857
// TODO: file size limit?
5958
// TODO: don't read entire file in memory
@@ -115,7 +114,7 @@ impl FsRead {
115114
if depth > max_depth {
116115
break;
117116
}
118-
let relative_path = relative_path(&cwd, &path);
117+
let relative_path = format_path(&cwd, &path);
119118
queue!(
120119
updates,
121120
style::SetForegroundColor(Color::Green),
@@ -218,7 +217,8 @@ impl FsRead {
218217
style::Print("Reading directory: "),
219218
style::SetForegroundColor(Color::Green),
220219
style::Print(&self.path),
221-
style::ResetColor
220+
style::ResetColor,
221+
style::Print(" "),
222222
)?;
223223

224224
let depth = if let Some(ref depth) = self.read_range {

crates/q_cli/src/cli/chat/tools/fs_write.rs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ use syntect::util::{
2929
use tokio::io::AsyncWriteExt;
3030
use tracing::error;
3131

32-
use super::InvokeOutput;
33-
use crate::cli::chat::tools::absolute_to_relative;
32+
use super::{
33+
InvokeOutput,
34+
format_path,
35+
};
3436

3537
static SYNTAX_SET: LazyLock<SyntaxSet> = LazyLock::new(SyntaxSet::load_defaults_newlines);
3638
static THEME_SET: LazyLock<ThemeSet> = LazyLock::new(ThemeSet::load_defaults);
@@ -138,9 +140,10 @@ impl FsWrite {
138140
style::SetForegroundColor(Color::Green),
139141
style::Print(path),
140142
style::ResetColor,
141-
style::Print("\n\n"),
143+
style::Print("\n\nContents:\n"),
144+
style::Print(file),
145+
style::ResetColor,
142146
)?;
143-
queue!(updates, style::Print(file), style::ResetColor)?;
144147
Ok(())
145148
},
146149
FsWrite::Insert {
@@ -156,9 +159,10 @@ impl FsWrite {
156159
style::SetForegroundColor(Color::Green),
157160
style::Print(path),
158161
style::ResetColor,
159-
style::Print("\n\n"),
162+
style::Print("\n\nContents:\n"),
163+
style::Print(file),
164+
style::ResetColor,
160165
)?;
161-
queue!(updates, style::Print(file), style::ResetColor)?;
162166
Ok(())
163167
},
164168
FsWrite::StrReplace { path, old_str, new_str } => {
@@ -178,22 +182,18 @@ impl FsWrite {
178182
style::Print(path),
179183
style::ResetColor,
180184
style::Print("\n\n"),
181-
)?;
182-
queue!(
183-
updates,
184-
style::SetAttribute(style::Attribute::Bold),
185+
// style::SetAttribute(style::Attribute::Bold),
185186
style::Print("Replacing:\n"),
186-
style::SetAttribute(style::Attribute::Reset),
187-
)?;
188-
queue!(updates, style::Print(old_str), style::ResetColor)?;
189-
queue!(updates, style::Print("\n\n"))?;
190-
queue!(
191-
updates,
192-
style::SetAttribute(style::Attribute::Bold),
187+
// style::SetAttribute(style::Attribute::Reset),
188+
style::Print(old_str),
189+
style::ResetColor,
190+
style::Print("\n\n"),
191+
// style::SetAttribute(style::Attribute::Bold),
193192
style::Print("With:\n"),
194-
style::SetAttribute(style::Attribute::Reset),
193+
// style::SetAttribute(style::Attribute::Reset),
194+
style::Print(new_str),
195+
style::ResetColor
195196
)?;
196-
queue!(updates, style::Print(new_str), style::ResetColor)?;
197197
Ok(())
198198
},
199199
}
@@ -217,13 +217,6 @@ impl FsWrite {
217217
}
218218
}
219219

220-
/// Small helper for formatting the path in [FsWrite] output.
221-
fn format_path(cwd: impl AsRef<Path>, path: impl AsRef<Path>) -> String {
222-
absolute_to_relative(cwd, path.as_ref())
223-
.map(|p| p.to_string_lossy().to_string())
224-
.unwrap_or(path.as_ref().to_string_lossy().to_string())
225-
}
226-
227220
/// Limits the passed str to `max_len`.
228221
///
229222
/// If the str exceeds `max_len`, then the first `max_len` characters are returned with a suffix of
@@ -317,6 +310,8 @@ fn stylized_file(
317310
};
318311

319312
let mut file = String::new();
313+
// We need to append newlines here for some reason, otherwise the highlighting ends at the end
314+
// of the content for the first line.
320315
file.push_str(&as_24_bit_terminal_escaped(&[(gutter_linenum_style, "\n\n")], true));
321316
for (i, line) in file_text.enumerate() {
322317
let i = (i + starting_line).to_string();
@@ -329,6 +324,9 @@ fn stylized_file(
329324
let escaped_line = as_24_bit_terminal_escaped(&ranges[..], true);
330325
file.push_str(&escaped_line);
331326
}
327+
if !file.ends_with("\n") {
328+
file.push('\n');
329+
}
332330

333331
Ok(file)
334332
}

crates/q_cli/src/cli/chat/tools/mod.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,6 @@ pub fn serde_value_to_document(value: serde_json::Value) -> Document {
166166
}
167167
}
168168

169-
/// Returns a display-friendly [String] of `path` relative to `cwd`, returning `path` if either
170-
/// `cwd` or `path` is invalid UTF-8, or `path` is not prefixed by `cwd`.
171-
fn relative_path(cwd: impl AsRef<Path>, path: impl AsRef<Path>) -> String {
172-
match (cwd.as_ref().to_str(), path.as_ref().to_str()) {
173-
(Some(cwd), Some(path)) => path.strip_prefix(cwd).unwrap_or_default().to_string(),
174-
_ => path.as_ref().to_string_lossy().to_string(),
175-
}
176-
}
177-
178169
/// Converts `path` to a relative path according to the current working directory `cwd`.
179170
fn absolute_to_relative(cwd: impl AsRef<Path>, path: impl AsRef<Path>) -> Result<PathBuf> {
180171
let cwd = cwd.as_ref().canonicalize()?;
@@ -201,3 +192,10 @@ fn absolute_to_relative(cwd: impl AsRef<Path>, path: impl AsRef<Path>) -> Result
201192

202193
Ok(relative)
203194
}
195+
196+
/// Small helper for formatting the path as a relative path, if able.
197+
fn format_path(cwd: impl AsRef<Path>, path: impl AsRef<Path>) -> String {
198+
absolute_to_relative(cwd, path.as_ref())
199+
.map(|p| p.to_string_lossy().to_string())
200+
.unwrap_or(path.as_ref().to_string_lossy().to_string())
201+
}

0 commit comments

Comments
 (0)