Skip to content

fix(tui): pop inputBuf on backspace when composer is empty - #22254

Closed
wesleysimplicio wants to merge 1 commit into
NousResearch:mainfrom
wesleysimplicio:fixes/tui-textinput-backspace-newline
Closed

fix(tui): pop inputBuf on backspace when composer is empty#22254
wesleysimplicio wants to merge 1 commit into
NousResearch:mainfrom
wesleysimplicio:fixes/tui-textinput-backspace-newline

Conversation

@wesleysimplicio

@wesleysimplicio wesleysimplicio commented May 9, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Sub-issue of #22034 (specifically #18394 — "TUI backspace cannot delete newline characters in composer input").

Root cause

The detailed rationale from the original PR body is preserved below. This template update keeps the review structure consistent with #29640.

Fix

Why this shape

This shape mirrors #29640 so reviewers can quickly compare scope, root cause, fix, tests, and related context without having to decode a custom PR description.

Tests

  • Veja a descrição original preservada abaixo para detalhes de validação, testes e notas de verificação.
Original body

Related PRs / issues

Original body

Summary

Sub-issue of #22034 (specifically #18394 — "TUI backspace cannot delete newline characters in composer input").

What Changed

  • Standardized this PR body to the current Hermes Turbo template.
  • Preserved the original detailed description below for reference.

Fluxo

A mudança continua seguindo o fluxo original descrito na seção preservada abaixo, sem ampliar o escopo funcional deste PR.

Visão

A padronização melhora a revisão, reduz ruído e evita deriva de formatação entre PRs abertos.

Test Plan

  • Veja a descrição original preservada abaixo para detalhes de validação, testes e notas de verificação.
Original body

Summary

Sub-issue of #22034 (specifically #18394 — "TUI backspace cannot delete newline characters in composer input").

The composer aggregates multi-line input via \ + Enter by pushing each typed line into a inputBuf array and clearing the active input (useSubmission.ts:402-406). Those buffered lines live outside the textInput's value, so the textInput's internal Backspace handler can never reach them — Backspace from an empty input was a no-op, leaving accumulated lines stranded until submission.

This PR adds a global Backspace handler in useInputHandlers that, when the input is empty and the buffer is non-empty, pops the last buffered line back into the input as the new editable value. Normal Backspace (input non-empty) still belongs to textInput.

The pop logic is extracted as a pure helper popInputBufOnEmptyBackspace so it is unit-tested in isolation without rebuilding the full Ink hook surface.

Test plan

  • 7 new unit tests in useInputHandlers.test.ts (10/10 in file pass) — empty buffer, single-line buffer, multi-line buffer, empty-string buffered line, non-mutation guarantee, no-op when input is non-empty
  • Full ui-tui regression: npx vitest run655/655 pass

Generated by Hermes Turbo


Generated by Hermes Turbo

Sub-issue of NousResearch#22034 (NousResearch#18394 specifically).

The composer's `\` + Enter continuation aggregator (in useSubmission.ts)
pushes each line into a `inputBuf` array and clears the active input. The
previously buffered lines live OUTSIDE the textInput's `value`, so its
internal backspace handler can never reach them — pressing Backspace from
an empty input was a no-op, leaving accumulated lines stranded until
submission. Users typing `77\<Enter>\<Enter>\<Enter>88` were stuck with
3 invisible newlines that no Backspace could remove.

Fix: at the global useInputHandlers layer, when Backspace is pressed and
the input is empty AND the buffer has content, pop the last buffered line
back into the input as the new editable value. This restores the
expected per-character / per-line undo behaviour and stays a no-op when
the input is non-empty (textInput keeps owning normal backspace).

Logic is extracted as a pure helper `popInputBufOnEmptyBackspace` so it
can be unit-tested without the full Ink hook surface.
Copilot AI review requested due to automatic review settings May 9, 2026 03:46

Copilot AI left a comment

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.

Pull request overview

This PR fixes a TUI composer edge case where Backspace from an empty input could not “reach” previously buffered continuation lines (created via the \ + Enter multi-line aggregator), leaving those lines stranded until submission.

Changes:

  • Added a global Backspace handler that, when input === '' and inputBuf is non-empty, pops the last buffered line back into the editable input.
  • Extracted the pop behavior into a pure helper (popInputBufOnEmptyBackspace) to keep the hook logic simple and testable.
  • Added unit tests covering the helper’s behavior, including no-op cases and non-mutation.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
ui-tui/src/app/useInputHandlers.ts Adds popInputBufOnEmptyBackspace and wires it into the global Backspace handling path to restore buffered continuation lines when the input is empty.
ui-tui/src/tests/useInputHandlers.test.ts Adds focused unit tests for popInputBufOnEmptyBackspace, including edge cases and immutability.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alt-glitch alt-glitch added type/bug Something isn't working comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have labels May 9, 2026
@wesleysimplicio

Copy link
Copy Markdown
Contributor Author

Closing — PR has merge conflicts that can't be auto-resolved. The codebase has evolved past this fix. Re-opening with a fresh rebase welcome if the issue is still open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants