Skip to content

Replace survey/v2 with huh-based prompter to fix terminal scrolling#82

Draft
skarim wants to merge 2 commits intomainfrom
skarim/prompter-refactor
Draft

Replace survey/v2 with huh-based prompter to fix terminal scrolling#82
skarim wants to merge 2 commits intomainfrom
skarim/prompter-refactor

Conversation

@skarim
Copy link
Copy Markdown
Collaborator

@skarim skarim commented May 7, 2026

Problem

When using certain modern terminals, interactive prompts that require text input (e.g., entering a branch name for gh stack add, setting a prefix for gh stack init) cause the terminal to scroll unexpectedly, pushing all previous output to the top of the screen. The prompt line jumps and hides the user's history.

Root Cause

We currently use github.com/cli/go-gh/v2/pkg/prompter, which wraps AlecAivazis/survey/v2. To detect terminal dimensions, survey emits the ANSI escape sequence \x1b[999;999f (HVP — Horizontal Vertical Position: move cursor to row 999, column 999) and then reads back the actual cursor position. Traditional xterm-compatible terminals clamp this to the viewport boundary — a 24×80 terminal moves the cursor to row 24, column 80 with no side effects.

However, this behavior is not universal. Terminals with non-standard renderers (custom terminal frameworks) may interpret the sequence literally, extending the scrollback buffer or scrolling the viewport down hundreds of lines instead of clamping. The ANSI standard is ambiguous on what should happen when a position beyond the screen boundary is requested, so terminal behavior varies.

Since survey/v2 was archived in April 2024, no fix is possible upstream. The go-gh/v2/pkg/prompter package has not been updated to use an alternative.

Solution

Created a new internal/prompter package that replaces go-gh/v2/pkg/prompter with prompt implementations that avoid the problematic ANSI escape sequences:

  • Select — Uses charm.land/huh/v2 (the same library the GitHub CLI uses in its own internal/prompter/huh_prompter.go, merged in cli/cli#12859). The cursor.Size() call was only triggered by survey's Select/MultiSelect prompts, so huh eliminates the problematic escape sequences entirely.

  • Input — Also uses charm.land/huh/v2 with Inline(true) for single-line rendering that matches the old survey look. survey's Input prompt also triggered cursor manipulation sequences that could cause issues in non-standard terminals.

  • Confirm — Uses a simple bufio.Reader-based line prompt. Survey's Confirm prompt did not use cursor.Size() or other problematic escape sequences (it just reads y/n from stdin), so a plain stdin reader preserves the exact same ? Question (Y/n) format without needing any TUI library.

Visual Style

A custom surveyTheme ensures prompts visually match the old survey/v2 style:

Prompt Type Before (survey/v2) After
Input ? Enter a name for the new branch bar ? Enter a name for the new branch bar
Confirm ? Enable git rerere? (Y/n) ? Enable git rerere? (Y/n)
Select ? Which stack? + > option list ? Which stack? + > option list
  • No box borders (removed huh's default left border)
  • Cyan ? prefix on all prompts
  • Inline layout for Input (title + cursor on the same line)
  • (Y/n) / (y/N) hint format for Confirm
  • Cyan > selector for Select options
  • No help text footer ("enter submit")

Interrupt Handling

  • On Ctrl+C, huh returns huh.ErrUserAborted, which is mapped to a local prompter.ErrInterrupt sentinel error
  • After huh exits, printResult() re-prints the prompt line so it stays visible in terminal history (huh's bubbletea renderer clears its rendering area on exit)
  • For Select prompts, residual option lines are cleared with ANSI cursor movement before re-printing the clean result
  • errInterrupt is now handled in Execute() to exit silently (previously it fell through and printed "interrupt" to stderr)

Dependency Changes

Added

  • charm.land/huh/v2 v2.0.3 — same version used by cli/cli
  • charm.land/lipgloss/v2, charm.land/bubbles/v2, charm.land/bubbletea/v2 — transitive deps of huh/v2

Removed

  • github.com/AlecAivazis/survey/v2 — archived, source of the problematic escape sequences
  • github.com/kballard/go-shellquote — was a transitive dep of survey

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