textarea: guard wordLeft against empty buffer so alt+left doesn't hang#959
Open
SAY-5 wants to merge 11 commits intocharmbracelet:masterfrom
Open
textarea: guard wordLeft against empty buffer so alt+left doesn't hang#959SAY-5 wants to merge 11 commits intocharmbracelet:masterfrom
SAY-5 wants to merge 11 commits intocharmbracelet:masterfrom
Conversation
Bumps the all group with 2 updates: [charm.land/bubbletea/v2](https://github.com/charmbracelet/bubbletea) and [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth). Updates `charm.land/bubbletea/v2` from 2.0.0 to 2.0.1 - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Commits](charmbracelet/bubbletea@v2.0.0...v2.0.1) Updates `github.com/mattn/go-runewidth` from 0.0.20 to 0.0.21 - [Commits](mattn/go-runewidth@v0.0.20...v0.0.21) --- updated-dependencies: - dependency-name: charm.land/bubbletea/v2 dependency-version: 2.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: github.com/mattn/go-runewidth dependency-version: 0.0.21 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the all group with 2 updates: [charm.land/bubbletea/v2](https://github.com/charmbracelet/bubbletea) and [charm.land/lipgloss/v2](https://github.com/charmbracelet/lipgloss). Updates `charm.land/bubbletea/v2` from 2.0.1 to 2.0.2 - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Commits](charmbracelet/bubbletea@v2.0.1...v2.0.2) Updates `charm.land/lipgloss/v2` from 2.0.0 to 2.0.2 - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Commits](charmbracelet/lipgloss@v2.0.0...v2.0.2) --- updated-dependencies: - dependency-name: charm.land/bubbletea/v2 dependency-version: 2.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: charm.land/lipgloss/v2 dependency-version: 2.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andrey Nering <andreynering@users.noreply.github.com>
Co-authored-by: rohan436 <rohan.santhoshkumar@googlemail.com>
…rmbracelet#945) Bumps the all group with 1 update: [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth). Updates `github.com/mattn/go-runewidth` from 0.0.21 to 0.0.22 - [Commits](mattn/go-runewidth@v0.0.21...v0.0.22) --- updated-dependencies: - dependency-name: github.com/mattn/go-runewidth dependency-version: 0.0.22 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…oup (charmbracelet#953) Bumps the all group with 1 update: [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata). Updates `dependabot/fetch-metadata` from 2 to 3 - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](dependabot/fetch-metadata@v2...v3) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major dependency-group: all ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…rmbracelet#952) Bumps the all group with 1 update: [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth). Updates `github.com/mattn/go-runewidth` from 0.0.22 to 0.0.23 - [Commits](mattn/go-runewidth@v0.0.22...v0.0.23) --- updated-dependencies: - dependency-name: github.com/mattn/go-runewidth dependency-version: 0.0.23 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the all group with 3 updates: [charm.land/bubbletea/v2](https://github.com/charmbracelet/bubbletea), [charm.land/lipgloss/v2](https://github.com/charmbracelet/lipgloss) and [github.com/charmbracelet/x/ansi](https://github.com/charmbracelet/x). Updates `charm.land/bubbletea/v2` from 2.0.2 to 2.0.6 - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Commits](charmbracelet/bubbletea@v2.0.2...v2.0.6) Updates `charm.land/lipgloss/v2` from 2.0.2 to 2.0.3 - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Commits](charmbracelet/lipgloss@v2.0.2...v2.0.3) Updates `github.com/charmbracelet/x/ansi` from 0.11.6 to 0.11.7 - [Commits](charmbracelet/x@ansi/v0.11.6...ansi/v0.11.7) --- updated-dependencies: - dependency-name: charm.land/bubbletea/v2 dependency-version: 2.0.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: charm.land/lipgloss/v2 dependency-version: 2.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all - dependency-name: github.com/charmbracelet/x/ansi dependency-version: 0.11.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
wordLeft() ran an unconditional for {} loop whose only exit was
finding a non-space rune under the cursor. On an empty textarea
(m.value == [][]rune{{}}, cursor at row=0/col=0), characterLeft() is
a no-op and the break condition 'col < len(value[row]) &&
!unicode.IsSpace' evaluates to '0 < 0' — so the loop spun forever and
froze the entire Bubble Tea event loop the first time the user hit
alt+b or alt+left on an empty input (charmbracelet/bubbletea#1652).
doWordRight() already has an analogous end-of-text guard. Add the
mirror: bail at (row 0, col 0) before stepping left so there is no
loop with no exit.
Adds TestWordLeftEmptyDoesNotHang which runs Update with alt+left on
a freshly-created textarea in a goroutine and fails if the goroutine
doesn't return within 2s. Confirmed: fails on master (hang), passes
with the fix.
Fixes charmbracelet/bubbletea#1652
Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes charmbracelet/bubbletea#1652.
wordLeft()ran an unconditionalfor {}loop whose only exit was finding a non-space rune under the cursor. On an empty textarea (m.value == [][]rune{{}}, cursor atrow=0/col=0),characterLeft()is a no-op and the break conditioncol < len(value[row]) && !unicode.IsSpace(...)evaluates to0 < 0— so the loop spins forever and freezes the entire Bubble Tea event loop the first time the user hitsalt+boralt+lefton an empty input.doWordRight()already has an analogous end-of-text guard. Mirror it: bail at(row 0, col 0)before stepping left so there is no loop with no exit.Tests
TestWordLeftEmptyDoesNotHang— runsUpdatewithalt+lefton a freshly-created textarea inside a goroutine and fails if it doesn't return within 2s. On master it hangs; with this fix it returns instantly.go test ./textarea/...,go vet,go buildall clean.