fix: emoji column alignment + remove '· exit 0' from success output

- Add unicode-width crate, emoji_cell() pads 1-wide symbols (ℹ, ☀) to 2 cols
- All action/status cells now occupy exactly 2 terminal display columns
- exec success: show only first output line, no trailing '· exit 0'
This commit is contained in:
Helios Agent 2026-03-05 20:10:28 +01:00
parent 8f26d2fbf3
commit b37eec24bc
No known key found for this signature in database
GPG key ID: C8259547CD8309B5
3 changed files with 19 additions and 7 deletions

View file

@ -25,6 +25,7 @@ png = "0.17"
futures-util = "0.3"
colored = "2"
terminal_size = "0.3"
unicode-width = "0.1"
[build-dependencies]
winres = "0.1"

View file

@ -1,10 +1,22 @@
/// Terminal display helpers — table-style command rows with live spinner.
///
/// Layout (no borders, aligned columns):
/// {2 spaces}{action_emoji}{2 spaces}{name:<NAME_W}{2 spaces}{payload:<payload_w}{2 spaces}{status_emoji}{2 spaces}{result}
/// {2 spaces}{action_emoji (2 display cols)}{2 spaces}{name:<NAME_W}{2 spaces}{payload:<payload_w}{2 spaces}{status_emoji}{2 spaces}{result}
use std::io::Write;
use colored::Colorize;
use unicode_width::UnicodeWidthStr;
/// Pad an emoji/symbol string to exactly 2 terminal display columns.
/// Some symbols (, ☀, ⚠ …) render as 1-wide; we add a space so columns align.
fn emoji_cell(s: &str) -> String {
let w = UnicodeWidthStr::width(s);
if w < 2 {
format!("{s} ")
} else {
s.to_string()
}
}
// Fixed column widths (in terminal display columns, ASCII-only content assumed for name/payload/result)
const NAME_W: usize = 14;
@ -52,12 +64,13 @@ fn format_row(action: &str, name: &str, payload: &str, status: &str, result: &st
let (payload_w, result_w) = col_widths();
let p = trunc(payload, payload_w);
let r = trunc(result, result_w);
// emoji_cell ensures every action/status occupies exactly 2 terminal columns
format!(
" {} {:<name_w$} {:<payload_w$} {} {}",
action,
emoji_cell(action),
name,
p,
status,
emoji_cell(status),
r,
name_w = NAME_W,
payload_w = payload_w,

View file

@ -25,7 +25,7 @@ use display::trunc;
fn banner() {
println!();
println!(" {} HELIOS REMOTE ({})", "".yellow().bold(), env!("GIT_COMMIT"));
println!(" {} HELIOS REMOTE ({})", "".yellow().bold(), env!("GIT_COMMIT"));
#[cfg(windows)]
{
let admin = is_admin();
@ -391,10 +391,8 @@ async fn handle_message(
} else {
format!("{first_line} · exit {exit_code}")
}
} else if first_line.is_empty() {
"exit 0".to_string()
} else {
format!("{first_line} · exit 0")
first_line // success: just the output, no "exit 0"
};
display::cmd_done("", "exec", &payload, exit_code == 0, &result);
let _ = stderr;