Merged
Conversation
kunchenguid
commented
Mar 30, 2026
Owner
Author
kunchenguid
left a comment
There was a problem hiding this comment.
Critique review comments
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
Adds multiline input editing to the gsh REPL. When the user presses Enter on incomplete input (unclosed quotes, heredocs, trailing pipes, control structures), a newline is inserted and a continuation prompt is shown instead of submitting. Alt+Enter force-inserts a newline regardless of completeness. A new
gsh.continuationPromptSDK property allows customization, with Starship integration out of the box.Risk Assessment: 🟢 Low — Well-tested multiline input feature scoped to the REPL input subsystem with minor critique warnings and no test failures.
Architecture
flowchart TD keymap["KeyMap / ActionInsertNewline (updated)"] handlers["handlers.go (updated)"] multiline["IsInputComplete (added)"] input_model["input.Model (updated)"] renderer["Renderer (updated)"] highlight["renderStyled / splitHighlightedByNewlines (added)"] prediction["onTextChanged (updated)"] repl["REPL.Run / getContinuationPrompt (updated)"] sdk["gsh.continuationPrompt (added)"] repl_context["REPLContext.ContinuationPromptValue (added)"] starship["starship.gsh (updated)"] docs["gsh-object docs (updated)"] sh_parser["mvdan/sh syntax.Parser (unchanged)"] subgraph input_pkg["internal/repl/input"] direction TB keymap -->|"Alt+Enter maps to"| input_model input_model -->|"Enter delegates to"| handlers handlers -->|"checks completeness via"| multiline multiline -->|"parses with"| sh_parser handlers -->|"inserts newline into"| input_model input_model -->|"renders via"| renderer renderer -->|"splits highlighted text via"| highlight input_model -->|"disables predictions via"| prediction end subgraph repl_pkg["internal/repl"] direction TB repl -->|"reads continuation prompt from"| repl_context repl -->|"passes ContinuationPrompt to"| input_model end subgraph sdk_pkg["internal/script/interpreter"] direction TB sdk -->|"backed by"| repl_context end subgraph defaults_pkg["cmd/gsh/defaults"] direction TB starship -->|"sets"| sdk end docs -.->|"documents"| sdkKey changes made
IsInputComplete()inmultiline.gousesmvdan/shparser to distinguish incomplete input (needs more lines) from complete or errored input (should submit).handleSubmit()now checks completeness before submitting; incomplete input gets a newline inserted. NewhandleInsertNewline()(Alt+Enter) always inserts a newline.render.gogainsrenderMultiLine()which renders each line with the correct prompt (main or continuation) and preserves cross-line syntax highlighting viasplitHighlightedByNewlines()with ANSI state tracking. Predictions are disabled for multi-line input.gsh.continuationPromptSDK property — New read/write string property on thegshobject backed byREPLContext.ContinuationPromptValue. Defaults to"> ".starship.gshcachesstarship prompt --continuationat init and applies it viagsh.continuationPrompt.sanitizeRunes()now preserves\ninstead of replacing it with a space, and normalizes\r\n/\rto\n.appendTextWithWrappingandappendTextWithWrappingAndCursorare refactored intoappendPreHighlightedWithWrappingandappendPreHighlightedWithCursorvariants that accept pre-highlighted text, with a sharedconsumeANSISequence()helper to eliminate duplication.multiline_test.gocovers completeness detection, submission behavior, continuation prompts, multi-line rendering, cross-line syntax highlighting, and key bindings.How was this tested
multiline_test.gocovering completeness detection, submission behavior, continuation prompts, multi-line rendering, cross-line syntax highlighting, and key bindings