Skip to content

feat: fit inbox subjects to row width - #1750

Merged
andrinoff merged 2 commits into
floatpane:masterfrom
mvanhorn:fix/1533-matcha-subject-row-width
Oct 31, 2026
Merged

andrinoff merged 2 commits into
floatpane:masterfrom
mvanhorn:fix/1533-matcha-subject-row-width

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What?

The inbox row is now sized from the list width before anything is drawn, and a zero or negative width draws nothing.

  • The cursor and visual markers are chosen first and counted with the style frame, prefix, icon, and separator.
  • Sender and subject are shortened with an ellipsis by display width.
  • The date is kept only when two extra columns remain, and the styled line is clamped to the list width.
  • Tabs and line breaks are shown as spaces, and the stored title is left unchanged.
  • Row chrome, status icon, and subject text live in small helpers.

go test ./tui/... passed. The tests in tui/inbox_test.go fail without the fix (checked by reverting the source changes).

Fixes #1533

Why?

Long inbox subjects run past the row, so the date no longer sits on the right edge and rows of different lengths stop lining up. On a narrow width the date and the selection marker are carried out with the text, and a tab or line break in the subject or sender splits the row.

The painter kept a floor under every budget: the left side stayed at least 10 columns, the subject at least 4, and the padding at least 1. A narrow list therefore still received a string wider than the row.

The visual-selection marker was prepended after that string was measured, the date was always appended, and the list width was reduced by a hardcoded 2 columns. Truncation cut raw runes, and tabs and newlines in the sender and subject were copied onto the row.

AI was used for assistance.

The row is now sized from the list width before anything is drawn, and a
zero or negative width draws nothing. The cursor and visual markers are
chosen first and counted with the style frame, prefix, icon, and
separator. Sender and subject are shortened with an ellipsis by display
width, the date is kept only when two extra columns remain, and the
styled line is clamped to the list width. Tabs and line breaks are shown
as spaces, the stored title is left unchanged, and row chrome, status
icon, and subject text live in small helpers.

Fixes floatpane#1533
@mvanhorn
mvanhorn requested a review from a team as a code owner October 22, 2026 10:54

@floatpanebot floatpanebot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mvanhorn! Please fix the following issues with your PR:

  • Title: Is too long (42 characters). The PR title must be strictly under 40 characters.

@floatpanebot floatpanebot added bug Something isn't working enhancement New feature or request area/tui Terminal UI / view layer size/L Diff: 201–800 lines and removed bug Something isn't working enhancement New feature or request labels Oct 22, 2026
@floatpanebot

floatpanebot commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Benchmark report — no significant change

Metrics worse: 0 · better: 0 (threshold: ±3%).

benchstat output
goos: linux
goarch: amd64
pkg: github.com/floatpane/matcha/backend
cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                           │    old.txt    │               new.txt               │
                           │    sec/op     │    sec/op      vs base              │
ParseSearchQuery_Simple-4    2.767µ ± 367%   3.026µ ± 171%       ~ (p=0.937 n=6)
ParseSearchQuery_Complex-4   7.716µ ±  46%   8.658µ ±  61%       ~ (p=0.589 n=6)
TokenizeSearchQuery-4        4.288µ ±  24%   4.577µ ±  40%       ~ (p=0.818 n=6)
geomean                      4.507µ          4.931µ         +9.42%

                           │  old.txt   │              new.txt               │
                           │    B/op    │    B/op     vs base                │
ParseSearchQuery_Simple-4    26.00 ± 0%   26.00 ± 0%       ~ (p=1.000 n=6) ¹
ParseSearchQuery_Complex-4   762.0 ± 0%   762.0 ± 0%       ~ (p=1.000 n=6) ¹
TokenizeSearchQuery-4        176.0 ± 0%   176.0 ± 0%       ~ (p=1.000 n=6) ¹
geomean                      151.6        151.6       +0.00%
¹ all samples are equal

                           │  old.txt   │              new.txt               │
                           │ allocs/op  │ allocs/op   vs base                │
ParseSearchQuery_Simple-4    2.000 ± 0%   2.000 ± 0%       ~ (p=1.000 n=6) ¹
ParseSearchQuery_Complex-4   23.00 ± 0%   23.00 ± 0%       ~ (p=1.000 n=6) ¹
TokenizeSearchQuery-4        9.000 ± 0%   9.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                      7.453        7.453       +0.00%
¹ all samples are equal

pkg: github.com/floatpane/matcha/tui
                    │   old.txt    │              new.txt               │
                    │    sec/op    │    sec/op     vs base              │
LogPanelView-4        157.6µ ± 12%   149.3µ ± 14%       ~ (p=0.240 n=6)
SearchOverlayView-4   167.6µ ±  7%   161.7µ ± 10%       ~ (p=0.485 n=6)
InboxConstruction-4   1.011m ± 14%   1.038m ± 17%       ~ (p=0.818 n=6)
geomean               298.9µ         292.6µ        -2.09%

                    │    old.txt    │               new.txt               │
                    │     B/op      │     B/op       vs base              │
LogPanelView-4        44.67Ki ± 51%   44.67Ki ± 51%       ~ (p=1.000 n=6)
SearchOverlayView-4   56.15Ki ± 41%   44.67Ki ± 26%       ~ (p=0.602 n=6)
InboxConstruction-4   874.5Ki ±  0%   874.5Ki ±  0%       ~ (p=1.000 n=6)
geomean               129.9Ki         120.4Ki        -7.34%

                    │   old.txt   │              new.txt              │
                    │  allocs/op  │  allocs/op   vs base              │
LogPanelView-4         714.0 ± 0%    714.0 ± 0%       ~ (p=1.000 n=6)
SearchOverlayView-4    926.0 ± 0%    925.0 ± 0%       ~ (p=0.675 n=6)
InboxConstruction-4   3.483k ± 0%   3.482k ± 0%       ~ (p=0.861 n=6)
geomean               1.321k        1.320k       -0.04%

auto-generated by benchmarks.yml

@mvanhorn mvanhorn changed the title feat: keep inbox subjects within row width feat: fit inbox subjects to row width Oct 22, 2026
@floatpanebot
floatpanebot dismissed their stale review October 22, 2026 15:28

Formatting issues have been resolved. Thank you!

@floatpanebot floatpanebot added bug Something isn't working enhancement New feature or request labels Oct 22, 2026
@mvanhorn

Copy link
Copy Markdown
Contributor Author

govulncheck was red because the branch still built with Go 1.26.9, which carries GO-2026-6809 in crypto/x509. Merged master in f2c5fcd to pick up the 1.26.10 bump from #1749. govulncheck now exits clean locally, and go build ./... and the tui tests pass. The title check is also green after the earlier rename.

@andrinoff andrinoff left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you

@andrinoff
andrinoff added this pull request to the merge queue Oct 31, 2026
Merged via the queue into floatpane:master with commit 8441c76 Oct 31, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tui Terminal UI / view layer bug Something isn't working enhancement New feature or request size/L Diff: 201–800 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FEAT: Wrap/truncate long subject lines cleanly in list

3 participants