Skip to content

fix(textinput): resolve placeholder truncation on initial render#816

Open
sebastianhuus wants to merge 3 commits intocharmbracelet:masterfrom
sebastianhuus:fix-placeholder-rendering
Open

fix(textinput): resolve placeholder truncation on initial render#816
sebastianhuus wants to merge 3 commits intocharmbracelet:masterfrom
sebastianhuus:fix-placeholder-rendering

Conversation

@sebastianhuus
Copy link
Copy Markdown

Summary

  • Fixes placeholder text being truncated to first character on initial render
  • Resolves issue where placeholder displays correctly only after width is calculated

Problem

The placeholderView function in textinput.go was creating a rune slice with size m.Width+1. When m.Width is 0 during initial render, this created a slice of length 1, truncating multi-character placeholders to just their first character.

Solution

  • Changed slice allocation from m.Width+1 to max(len(m.Placeholder), m.Width+1) to ensure it can always hold the full placeholder
  • Updated early return condition to check len(m.Placeholder) instead of len(p)

Test plan

  • Verified fix resolves the truncation issue with gum input commands
  • Tested with long placeholder: "Enter your full name and email address here"
  • Tested with medium placeholder: "Your message here"
  • Tested with short placeholder: "Name"
  • Confirmed existing functionality remains intact

All tests show full placeholder text immediately on render, no more truncation.

Fixes #779

@sebastianhuus
Copy link
Copy Markdown
Author

I also tested some various length placeholders. They all rendered properly with the caret highlighted on the first character and allowing input without a duplicate placeholder line.

Pre fix behavior:

pre fix old short placeholder old medium placeholder 2 old long placeholder

Post fix behavior:

post fix short placeholder medium placeholder long placeholder

@kwlzn
Copy link
Copy Markdown

kwlzn commented Jan 25, 2026

@sebastianhuus @meowgorithm can we get this landed?

@sebastianhuus
Copy link
Copy Markdown
Author

@kwlzn currently ill but I can take a look during the week and update my fork.

While looking at other similar PRs and their Discord, I got the impression that changes like this weren't prioritized because they're working on shipping v2 of bubbles. I haven't followed the space since then so I'm not sure if that's still a concern. From what I understood V2 contains extra terminal-specific features and support for a lot more terminals.

@sebastianhuus
Copy link
Copy Markdown
Author

sebastianhuus commented Jan 30, 2026

@kwlzn I see #768 (merged October 2025) includes a refactor that also addresses this bug. It was shipped to v2.0.0-rc.1 (November 2025), but Gum uses Bubbles v0.21 (April 2025).

meowgorithm If you could ship this fix before v2, then I suggest to release a intermediary patch v0.21.1 or v0.22 is released for Bubbles and Gum's dependency is updated respectively.

I tested Master branch of Bubbles as dependency for gum and the bug is fixed for me.

Screen.Recording.2026-01-30.at.22.13.43.mov

Edit 25 April 2026: I see I suggested Bubbles v0.21.1 but I have to admit I didn't dig that deep into it – it has been released in February 3

@marksalpeter
Copy link
Copy Markdown

So is this being addressed? Gum is unusable.

@andreynering
Copy link
Copy Markdown
Member

@marksalpeter Which version of Gum and/or Bubbles are you using?

It seems to be working on v2 for me.

@marksalpeter
Copy link
Copy Markdown

marksalpeter commented Apr 6, 2026

I'm using zsh and starship on OSX 26.3.1. Normal terminal app. Gum is installed via the latest homebrew release.

❯ gum --version
gum version 0.17.0

❯ gum input
> Type something...                                                            
> Type something...                                                             
enter submit      
Screenshot 2026-04-06 at 11 22 58 PM

@marksalpeter
Copy link
Copy Markdown

marksalpeter commented Apr 12, 2026

@andreynering please ack that the latest release of gum is broken on osx.

Comment thread textinput/textinput.go Outdated
)

p := make([]rune, m.Width+1)
p := make([]rune, max(len(m.Placeholder), m.Width+1))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

len here would give incorrect placeholder cell/grapheme width

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ok thanks for the review Ayman. I'll update the branch and take a look

The placeholderView function incorrectly sized the rune slice using
m.Width+1, which created a slice of length 1 when Width was 0 during
initial render. This truncated multi-character placeholders to just
their first character.

Fixed by ensuring the slice is always large enough to hold the entire
placeholder text and updated the early return condition to check the
actual placeholder length.

Fixes charmbracelet#779

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@sebastianhuus sebastianhuus force-pushed the fix-placeholder-rendering branch from 8722eb6 to 9edc16c Compare April 14, 2026 10:18
Fix calculation of the placeholder rune slice length by converting the
placeholder string to a rune slice before taking its length. Ensures multi-byte characters are measured correctly and prevents
improper sizing of the placeholder buffer when the placeholder contains
non-ASCII characters.
@sebastianhuus
Copy link
Copy Markdown
Author

Right. While updating my fork git reminded me that the bug is already fixed in Bubbles but Gum is still using the old Bubbles version.

See my post above

I see #768 (merged October 2025) includes a refactor that also addresses this bug. It was shipped to v2.0.0-rc.1 (November 2025), but Gum uses Bubbles v0.21 (April 2025).I see #768 (merged October 2025) includes a refactor that also addresses this bug. It was shipped to v2.0.0-rc.1 (November 2025), but Gum uses Bubbles v0.21 (April 2025).

That's a gum release/dependency issue, not something this PR should solve.

@sebastianhuus
Copy link
Copy Markdown
Author

@aymanbagabas Any info if a new Gum release is planned with updated dependencies?

@sebastianhuus
Copy link
Copy Markdown
Author

For any interested users, maybe it is more appropriate to keep the discussion in the Gum repo, since it has not been updated since 2025. Then this PR can be closed without merge while we ask for a new gum release with the fix applied?

Particularly this issue is where I initially started when I had this issue.

@marksalpeter
Copy link
Copy Markdown

@sebastianhuus I see an abandoned branch in gum that attempted to version bump everything to v2. Maybe it was too ambitious. If this patches the prior version, a minor version bump will be much easier to merge than a major one.

@sebastianhuus
Copy link
Copy Markdown
Author

@sebastianhuus I see an abandoned branch in gum that attempted to version bump everything to v2. Maybe it was too ambitious. If this patches the prior version, a minor version bump will be much easier to merge than a major one.

Interesting, can be worth a shot. I think its better to salvage the new fix from v2 and patch that into a PR that can become a minor patch – I found it a bit more pragmatic.

@sebastianhuus
Copy link
Copy Markdown
Author

sebastianhuus commented Apr 25, 2026

Found a nicer fix actually – than making some PR patch.

Tracking the fix in the other PR, the fix was released to Bubbles 0.21.1 3rd February.

I forked Gum again, checked out the 0.17.0 version and bumped Bubbles 0.21.0 -> 0.21.1.

Screen.Recording.2026-04-25.at.20.34.40.mov

I hopped on the Charm discord and asked if they'd be kind enough to just bump the dependency in Gum and release it as a patch – no PR needed. I guess its in the works but doesn't hurt to ask again :)

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.

textinput: Initial letter only shown in placeholder

5 participants