Bring back support for truncation with ellipsis

timeout_old
Jakub Jirutka 2 years ago
parent 053becd176
commit befb2aa7d3
  1. 12
      NEWS.md
  2. 12
      README.md
  3. 22
      src/rtfmt.rs
  4. 32
      src/tree.rs

@ -4,10 +4,14 @@ swayr v0.13.0
- The placeholders `{id}`, `{app_name}`, `{name}`/`{title}`, `{output_name}`,
`{workspace_name}`, and `{marks}` may optionally provide a format string as
specified by [Rust's std::fmt](https://doc.rust-lang.org/std/fmt/). The
syntax is `{<placeholder>:<fmt_str>}`. For example, `{app_name:{:>10.10}}`
would mean that the application name is printed with exactly 10 characters.
If it's shorter, it will be right-aligned (the `>`) and padded with spaces,
if it's longer, it'll be cut after the 10th character.
syntax is `{<placeholder>:<fmt_str>}` or `{<placeholder>:<fmt_str>…}`. For
example, `{app_name:{:>10.10}}` would mean that the application name is
printed with exactly 10 characters. If it's shorter, it will be
right-aligned (the `>`) and padded with spaces, if it's longer, it'll be cut
after the 10th character. Another example, `{app_name:{:.10}…}` would mean
that the application name is truncated at 10 characters. If it's shorter, it
will be printed as-is (no padding), if it's longer, it'll be cut after the
9th character and the ellipsis (…) character will be added after it.
swayr v0.12.0
=============

@ -327,10 +327,14 @@ right now.
The placeholders `{id}`, `{app_name}`, `{name}`/`{title}`, `{output_name}`,
`{workspace_name}`, and `{marks}` may optionally provide a format string as
specified by [Rust's std::fmt](https://doc.rust-lang.org/std/fmt/). The syntax
is `{<placeholder>:<fmt_str>}`. For example, `{app_name:{:>10.10}}` would mean
that the application name is printed with exactly 10 characters. If it's
shorter, it will be right-aligned (the `>`) and padded with spaces, if it's
longer, it'll be cut after the 10th character.
is `{<placeholder>:<fmt_str>}` or `{<placeholder>:<fmt_str>…}`. For example,
`{app_name:{:>10.10}}` would mean that the application name is printed with
exactly 10 characters. If it's shorter, it will be right-aligned (the `>`) and
padded with spaces, if it's longer, it'll be cut after the 10th character.
Another example, `{app_name:{:.10}…}` would mean that the application name is
truncated at 10 characters. If it's shorter, it will be printed as-is (no
padding), if it's longer, it'll be cut after the 9th character and the ellipsis
(…) character will be added after it.
It is crucial that during selection (using wofi or some other menu program)
each window has a different display string. Therefore, it is highly

@ -73,11 +73,29 @@ impl<'a> std::convert::TryInto<usize> for &FmtArg<'a> {
}
}
pub fn format(fmt: &str, arg: &str) -> String {
pub fn format(fmt: &str, arg: &str, ellipsis: bool) -> String {
let args = &[FmtArg::Str(arg)];
if let Ok(pf) = ParsedFormat::parse(fmt, args, &NoNamedArguments) {
format!("{}", pf)
let mut s = format!("{}", pf);
if ellipsis && !s.contains(arg) {
s.pop();
s.push('…');
}
s
} else {
format!("Invalid format string: {}", fmt)
}
}
#[test]
fn test_format() {
assert_eq!(format("{:.10}", "sway", false), "sway");
assert_eq!(format("{:.10}", "sway", true), "sway");
assert_eq!(format("{:.4}", "𝔰𝔴𝔞𝔶", true), "𝔰𝔴𝔞𝔶");
assert_eq!(format("{:.3}", "sway", false), "swa");
assert_eq!(format("{:.3}", "sway", true), "sw…");
assert_eq!(format("{:.3}", "𝔰𝔴𝔞𝔶", true), "𝔰𝔴…");
}

@ -428,9 +428,10 @@ pub fn get_tree<'a>(
lazy_static! {
static ref APP_NAME_AND_VERSION_RX: regex::Regex =
regex::Regex::new("(.+)(-[0-9.]+)").unwrap();
static ref PLACEHOLDER_RX: regex::Regex =
regex::Regex::new(r"\{(?P<name>[^}:]+)(?::(?P<fmtstr>\{[^}]*\}))?\}")
.unwrap();
static ref PLACEHOLDER_RX: regex::Regex = regex::Regex::new(
r"\{(?P<name>[^}:]+)(?::(?P<fmtstr>\{[^}]*\})(?P<ellipsis>…)?)?\}"
)
.unwrap();
}
fn maybe_html_escape(do_it: bool, text: String) -> String {
@ -530,7 +531,12 @@ impl DisplayFormat for DisplayNode<'_> {
_ => caps[0].to_string(),
};
let fmt_str = caps.name("fmtstr").map_or("{}", |m| m.as_str());
maybe_html_escape(html_escape, rtfmt::format(fmt_str, &value))
let ellipsis = caps.name("ellipsis").is_some();
maybe_html_escape(
html_escape,
rtfmt::format(fmt_str, &value, ellipsis),
)
})
.into()
}
@ -561,3 +567,21 @@ impl DisplayFormat for DisplayNode<'_> {
}
}
}
#[test]
fn test_placeholder_rx() {
let caps = PLACEHOLDER_RX.captures("Hello, {place}!").unwrap();
assert_eq!(caps.name("name").unwrap().as_str(), "place");
assert_eq!(caps.name("fmtstr"), None);
assert_eq!(caps.name("ellipsis"), None);
let caps = PLACEHOLDER_RX.captures("Hi, {place:{:>10.10}}!").unwrap();
assert_eq!(caps.name("name").unwrap().as_str(), "place");
assert_eq!(caps.name("fmtstr").unwrap().as_str(), "{:>10.10}");
assert_eq!(caps.name("ellipsis"), None);
let caps = PLACEHOLDER_RX.captures("Hello, {place:{:.5}…}!").unwrap();
assert_eq!(caps.name("name").unwrap().as_str(), "place");
assert_eq!(caps.name("fmtstr").unwrap().as_str(), "{:.5}");
assert_eq!(caps.name("ellipsis").unwrap().as_str(), "…");
}

Loading…
Cancel
Save