Skip to content

feat(input): add multiline support#200

Merged
kunchenguid merged 4 commits intomainfrom
feat/heredoc
Mar 30, 2026
Merged

feat(input): add multiline support#200
kunchenguid merged 4 commits intomainfrom
feat/heredoc

Conversation

@kunchenguid
Copy link
Copy Markdown
Owner

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.continuationPrompt SDK 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"| sdk
Loading

Key changes made

  • Incomplete input detection — New IsInputComplete() in multiline.go uses mvdan/sh parser to distinguish incomplete input (needs more lines) from complete or errored input (should submit).
  • Enter key behaviorhandleSubmit() now checks completeness before submitting; incomplete input gets a newline inserted. New handleInsertNewline() (Alt+Enter) always inserts a newline.
  • Multi-line renderingrender.go gains renderMultiLine() which renders each line with the correct prompt (main or continuation) and preserves cross-line syntax highlighting via splitHighlightedByNewlines() with ANSI state tracking. Predictions are disabled for multi-line input.
  • gsh.continuationPrompt SDK property — New read/write string property on the gsh object backed by REPLContext.ContinuationPromptValue. Defaults to "> ".
  • Starship integrationstarship.gsh caches starship prompt --continuation at init and applies it via gsh.continuationPrompt.
  • Input sanitizationsanitizeRunes() now preserves \n instead of replacing it with a space, and normalizes \r\n/\r to \n.
  • Renderer refactoring — Existing appendTextWithWrapping and appendTextWithWrappingAndCursor are refactored into appendPreHighlightedWithWrapping and appendPreHighlightedWithCursor variants that accept pre-highlighted text, with a shared consumeANSISequence() helper to eliminate duplication.
  • Tests — 346-line multiline_test.go covers completeness detection, submission behavior, continuation prompts, multi-line rendering, cross-line syntax highlighting, and key bindings.

How was this tested

  • All 24 test packages pass
  • 346 lines of new tests in multiline_test.go covering completeness detection, submission behavior, continuation prompts, multi-line rendering, cross-line syntax highlighting, and key bindings

Copy link
Copy Markdown
Owner Author

@kunchenguid kunchenguid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critique review comments

@kunchenguid kunchenguid merged commit b05973a into main Mar 30, 2026
1 check passed
@kunchenguid kunchenguid deleted the feat/heredoc branch March 30, 2026 23:59
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