Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/jp_cli/src/render/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ fn formatter_from_config(
Formatter::with_width(wrap_width(config, terminal_width))
.terminal_width(terminal_width.map_or(0, usize::from))
.table_max_column_width(config.markdown.table_max_column_width)
.table_continuation_edge(config.markdown.table_continuation_edge)
.theme(theme_name)
.pretty_hr(pretty && config.markdown.hr_style.is_line())
.inline_code_bg(
Expand Down
41 changes: 40 additions & 1 deletion crates/jp_cli/src/render/chat_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ fn test_table_is_fitted_to_the_printers_terminal_width() {
renderer.printer.flush();

let rendered = strip_ansi(&out.lock());
let rows: Vec<&str> = rendered.lines().filter(|l| l.starts_with('|')).collect();
// Wrapped rows continue on a line opening with `┆` rather than `|`.
let rows: Vec<&str> = rendered
.lines()
.filter(|l| l.starts_with('|') || l.starts_with('┆'))
.collect();
assert!(rows.len() > 3, "expected wrapped rows:\n{rendered}");
for row in rows {
assert_eq!(
Expand All @@ -161,6 +165,41 @@ fn test_table_is_fitted_to_the_printers_terminal_width() {
}
}

/// The continuation edge is configurable, so the rendered table has to follow
/// `style.markdown.table_continuation_edge` rather than a hardcoded default.
#[test]
fn test_table_continuation_edge_follows_the_config() {
let mut config = AppConfig::new_test();
config.style.markdown.wrap_width = 80;
config.style.markdown.table_max_column_width = 40;
config.style.markdown.table_continuation_edge = false;

let (printer, out, _err) = Printer::memory(OutputFormat::Text);
let mut renderer = ChatRenderer::new(
Arc::new(printer.with_output_width(OutputWidth::Terminal(30))),
config.style,
);

renderer.render_response(&ChatResponse::Message {
message: "| Alpha heading | Beta heading |\n| --- | --- |\n| first cell content | second \
cell content |\n\n"
.into(),
});
renderer.flush();
renderer.printer.flush();

// The fourth line means the data row wrapped, so there is a continuation
// line for the setting to act on.
let rendered = strip_ansi(&out.lock());
let rows: Vec<&str> = rendered.lines().filter(|l| l.contains('|')).collect();
assert_eq!(rows, vec![
"| Alpha headi… | Beta headi… |",
"|--------------|-------------|",
"| first cell | second cell |",
"| content | content |",
]);
}

#[test]
fn test_renders_message() {
let (mut renderer, out, _err) = create_renderer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ expression: "AppConfig::fields()"
"style.reasoning.extend_across_tool_calls",
"style.reasoning.summary_model",
"style.markdown.hr_style",
"style.markdown.table_continuation_edge",
"style.markdown.table_max_column_width",
"style.markdown.theme",
"style.markdown.wrap_width",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ PartialAppConfig {
markdown: PartialMarkdownConfig {
wrap_width: None,
table_max_column_width: None,
table_continuation_edge: None,
theme: None,
hr_style: None,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ Ok(
table_max_column_width: Some(
40,
),
table_continuation_edge: Some(
true,
),
theme: Some(
"gruvbox-dark",
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ PartialAppConfig {
markdown: PartialMarkdownConfig {
wrap_width: None,
table_max_column_width: None,
table_continuation_edge: None,
theme: None,
hr_style: None,
},
Expand Down
35 changes: 34 additions & 1 deletion crates/jp_config/src/style/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ pub struct MarkdownConfig {
/// Defaults to `40`.
/// Set to `0` to leave columns as wide as their content.
///
/// Cells exceeding their column's width are wrapped over multiple lines.
/// Body cells exceeding their column's width are wrapped over multiple
/// lines.
/// A line continuing the row above opens with `┆` instead of `|`, so a
/// wrapped row reads as one row rather than several.
/// A header cell is cut short with `…` rather than wrapped, so the row of
/// dashes stays directly beneath the header and the table survives being
/// copied out of the terminal into a markdown document.
/// A column can end up narrower than this: a table wider than the terminal
/// has its widest columns narrowed until it fits, so the terminal does not
/// break the rows apart.
Expand All @@ -64,6 +70,19 @@ pub struct MarkdownConfig {
#[setting(default = 40)]
pub table_max_column_width: usize,

/// Whether the continuation lines of a wrapped table row open with `┆`.
///
/// Defaults to `true`.
/// Set to `false` to open every line with `|`.
///
/// A cell wrapped over several lines otherwise reads as several one-line
/// rows, since nothing distinguishes the start of a row from the middle of
/// one.
/// Only the line's opening delimiter changes, so a table copied out of the
/// terminal into a markdown document still splits into the right columns.
#[setting(default = true)]
pub table_continuation_edge: bool,

/// Syntax highlighting theme for code blocks.
///
/// Uses `bat` / `syntect` theme names (e.g. `"Monokai Extended"`,
Expand All @@ -88,6 +107,9 @@ impl AssignKeyValue for PartialMarkdownConfig {
"table_max_column_width" => {
self.table_max_column_width = kv.try_some_from_str()?;
}
"table_continuation_edge" => {
self.table_continuation_edge = kv.try_some_from_str()?;
}
"theme" => self.theme = kv.try_some_from_str()?,
"hr_style" => self.hr_style = kv.try_some_from_str()?,
_ => return missing_key(&kv),
Expand All @@ -105,6 +127,10 @@ impl PartialConfigDelta for PartialMarkdownConfig {
self.table_max_column_width.as_ref(),
next.table_max_column_width,
),
table_continuation_edge: delta_opt(
self.table_continuation_edge.as_ref(),
next.table_continuation_edge,
),
theme: delta_opt(self.theme.as_ref(), next.theme),
hr_style: delta_opt(self.hr_style.as_ref(), next.hr_style),
}
Expand All @@ -118,6 +144,9 @@ impl FillDefaults for PartialMarkdownConfig {
table_max_column_width: self
.table_max_column_width
.or(defaults.table_max_column_width),
table_continuation_edge: self
.table_continuation_edge
.or(defaults.table_continuation_edge),
theme: self.theme.or(defaults.theme),
hr_style: self.hr_style.or(defaults.hr_style),
}
Expand All @@ -134,6 +163,10 @@ impl ToPartial for MarkdownConfig {
&self.table_max_column_width,
defaults.table_max_column_width,
),
table_continuation_edge: partial_opt(
&self.table_continuation_edge,
defaults.table_continuation_edge,
),
theme: partial_opts(self.theme.as_ref(), defaults.theme),
hr_style: partial_opt(&self.hr_style, defaults.hr_style),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ expression: v
"markdown": {
"wrap_width": 80,
"table_max_column_width": 40,
"table_continuation_edge": true,
"theme": "gruvbox-dark",
"hr_style": "line"
},
Expand Down
Loading
Loading