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
9 changes: 4 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Changelog

## 2026-11-07 — banner-text 0.1.1
## 2026-11-07 — banner-text 0.1.2

- `banner-text` 0.1.1: add invisible zero-width padding after wide characters
so the current box layouts keep the right border aligned. It is a
compatibility shim for the character-count width calculation; the rendered
text is unchanged.
- Reverted the zero-width padding added in 0.1.1: it rendered as tofu squares
on terminals or fonts without a U+200B glyph. The plugin emits the text
unchanged again; the box border alignment remains a core layout issue.

## 2026-11-06 — SDK 0.3.1 migration

Expand Down
3 changes: 1 addition & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion index.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
{
"name": "banner-text",
"description": "Xfetch info plugin that emits text lines from a file or literal argument",
"version": "0.1.1",
"version": "0.1.2",
"kind": "info_provider",
"runtime": "native",
"path": "plugins/banner-text",
Expand Down
3 changes: 1 addition & 2 deletions plugins/banner-text/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
[package]
name = "xfetch-plugin-banner-text"
version = "0.1.1"
version = "0.1.2"
edition = "2024"
license = "MIT"
description = "Xfetch info plugin that emits text lines from a file or literal argument"

[dependencies]
console = "0.16.6"
serde = { version = "1", features = ["derive"] }
xfetch-plugin-api = { workspace = true }
4 changes: 0 additions & 4 deletions plugins/banner-text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ Each line is emitted separately. Trailing whitespace is removed and leading or
trailing empty lines are discarded. Leading spaces on non-empty lines are
preserved.

Wide characters (CJK, emoji) are followed by invisible zero-width spaces so the
current box layouts, which count characters instead of terminal columns, keep
the right border aligned. The rendered text is unchanged.

## Output

Given a file containing `永遠は朽ち、儚さが記憶を刻む`, the plugin returns:
Expand Down
36 changes: 2 additions & 34 deletions plugins/banner-text/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn resolve_text(args: &PluginArgs) -> String {
fn normalize_lines(raw: &str, blank_line: bool) -> Vec<String> {
let mut lines: Vec<String> = raw
.lines()
.map(|line| compensate_wide_chars(line.trim_end()))
.map(|line| line.trim_end().to_string())
.collect();
while lines.first().is_some_and(|line| line.is_empty()) {
lines.remove(0);
Expand All @@ -69,25 +69,6 @@ fn normalize_lines(raw: &str, blank_line: bool) -> Vec<String> {
lines
}

/// Adds zero-width spaces after wide characters.
///
/// The current box layouts measure each row with `chars().count()`, so a CJK
/// character counts as one column even though terminals render it as two. The
/// invisible padding makes that character count match the visible width, which
/// keeps the right border aligned. It is harmless once the core measures the
/// display width instead.
fn compensate_wide_chars(line: &str) -> String {
let mut out = String::with_capacity(line.len());
for ch in line.chars() {
out.push(ch);
let width = console::measure_text_width(&ch.to_string());
for _ in 1..width {
out.push('\u{200b}');
}
}
out
}

fn expand_path(path: &str) -> PathBuf {
if path == "~" {
return home_dir().unwrap_or_else(|| PathBuf::from(path));
Expand All @@ -110,7 +91,7 @@ fn home_dir() -> Option<PathBuf> {

#[cfg(test)]
mod tests {
use super::{compensate_wide_chars, normalize_lines};
use super::normalize_lines;

#[test]
fn trims_trailing_whitespace_and_edge_blank_lines() {
Expand All @@ -128,17 +109,4 @@ mod tests {
fn empty_text_returns_no_lines() {
assert!(normalize_lines(" \n\t\n", true).is_empty());
}

#[test]
fn wide_characters_get_zero_width_padding() {
let line = compensate_wide_chars("秘密の距離");
assert_eq!(line.chars().count(), 10);
assert_eq!(line.matches('\u{200b}').count(), 5);
assert_eq!(console::measure_text_width(&line), 10);
}

#[test]
fn ascii_is_not_padded() {
assert_eq!(compensate_wide_chars("banner"), "banner");
}
}
Loading