Replace survey/v2 with huh-based prompter to fix terminal scrolling#82
Draft
Replace survey/v2 with huh-based prompter to fix terminal scrolling#82
Conversation
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.
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 forgh 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 wrapsAlecAivazis/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/v2was archived in April 2024, no fix is possible upstream. Thego-gh/v2/pkg/prompterpackage has not been updated to use an alternative.Solution
Created a new
internal/prompterpackage that replacesgo-gh/v2/pkg/prompterwith prompt implementations that avoid the problematic ANSI escape sequences:Select — Uses
charm.land/huh/v2(the same library the GitHub CLI uses in its owninternal/prompter/huh_prompter.go, merged in cli/cli#12859). Thecursor.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/v2withInline(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 usecursor.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
surveyThemeensures prompts visually match the old survey/v2 style:? Enter a name for the new branch bar? Enter a name for the new branch bar? Enable git rerere? (Y/n)? Enable git rerere? (Y/n)? Which stack?+> optionlist? Which stack?+> optionlist┃left border)?prefix on all prompts(Y/n)/(y/N)hint format for Confirm>selector for Select optionsInterrupt Handling
huh.ErrUserAborted, which is mapped to a localprompter.ErrInterruptsentinel errorprintResult()re-prints the prompt line so it stays visible in terminal history (huh's bubbletea renderer clears its rendering area on exit)errInterruptis now handled inExecute()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 bycli/clicharm.land/lipgloss/v2,charm.land/bubbles/v2,charm.land/bubbletea/v2— transitive deps of huh/v2Removed
github.com/AlecAivazis/survey/v2— archived, source of the problematic escape sequencesgithub.com/kballard/go-shellquote— was a transitive dep of survey