Skip to content

feat(hm-common): add string utils (ellipsis, align, escape)#174

Merged
markovejnovic merged 4 commits into
mainfrom
feat/hm-common-string-utils
Jul 26, 2026
Merged

feat(hm-common): add string utils (ellipsis, align, escape)#174
markovejnovic merged 4 commits into
mainfrom
feat/hm-common-string-utils

Conversation

@markovejnovic

Copy link
Copy Markdown
Contributor

Generated by an AI agent.

Port budget-aware, display-width/grapheme-correct string helpers from
atuin (crates/atuin-common/src/string/, MIT) into a new hm_common::string
module:

- ellipsis: EllipsizeExt (ellipsize/pad_ellipsize), Indicator, Pos, Measure
- align:    AlignExt::pad_to, Alignment
- escape:   EscapeNonPrintablePosixExt (cat -v control-char escaping)

Always compiled here (upstream gates align/ellipsis behind a `unicode`
feature). Tests ported and adapted to repo conventions: rstest over bare
#[test], std assert_eq in place of pretty_assertions. Adds unicode-width
and unicode-segmentation workspace deps.

Also point CLAUDE.md's shared-utilities crate at hm-common as the source
of truth.
Use the new hm_common::string helpers where the codebase hand-rolled the
same logic, fixing latent width/escaping bugs in the process:

- scheduler: derive a step's display_name via EllipsizeExt instead of
  chars().take(39) + "…" — now budgets by display columns and cuts on
  grapheme boundaries.
- progress summary: pad the step-name column with AlignExt::pad_to over a
  unicode-width budget instead of byte-length {:<n$}, so multibyte/wide
  names line up.
- human + progress renderers: escape raw StepLog subprocess output with
  EscapeNonPrintablePosixExt before writing it to the terminal, so build
  logs can't drive the terminal (cursor moves, screen clears, …).

Adds hm-common dep to hm-exec and unicode-width dep to hm-render.
Regression tests for the escaping and wide-glyph alignment.
@markovejnovic
markovejnovic marked this pull request as ready for review July 26, 2026 02:49
@markovejnovic
markovejnovic merged commit f43d8f8 into main Jul 26, 2026
15 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant