multiline_input

Crates.iomultiline_input
lib.rsmultiline_input
version0.2.0
created_at2025-11-15 12:28:48.555103+00
updated_at2026-01-21 06:18:20.355279+00
descriptionTerminal multiline input with rich editing (ENTER to submit, CTRL+ENTER for newline)
homepage
repositoryhttps://github.com/Wandalen/wTools
max_upload_size
id1934302
size182,958
Wandalen (Wandalen)

documentation

README

multiline_input

Terminal multiline input with rich editing capabilities

Crates.io Documentation License: MIT

Scope

Responsibility:

  • Terminal multiline input widget with rich editing capabilities
  • ENTER to submit, CTRL+ENTER for newlines (optimized for AI assistants)
  • Raw terminal mode with visual feedback and validation
  • Cross-platform support (Linux, macOS, Windows)

In Scope:

  • Multiline text input widget
  • Line editing (cursor movement, backspace, delete)
  • Terminal manipulation (raw mode, key event capture)
  • Visual feedback (line numbers, status line, colors)
  • Validation (min/max length, custom validators)
  • Builder API for configuration
  • Pre-filled text editing
  • Key bindings (ENTER, CTRL+ENTER, ESC, arrows, Home, End)
  • Cross-platform terminal support

Out of Scope:

  • ❌ Wizard framework → delegated to terminal_wizard crate
  • ❌ CLI applications → individual binaries use this as library
  • ❌ Scrolling for large texts → future work
  • ❌ Undo/redo → future work
  • ❌ Clipboard integration → future work

Features

  • ENTER to submit input
  • CTRL+ENTER to insert newline (multiline support)
  • Rich line editing (cursor movement, backspace, delete)
  • Visual feedback (line numbers, status line, colors)
  • Validation (min/max length, custom validators)
  • Cross-platform (Linux, macOS, Windows)
  • Zero-config defaults

Quick Start

use multiline_input::collect;

fn main() {
  match collect("Enter your message:") {
    Ok(Some(text)) => println!("You entered:\n{}", text),
    Ok(None) => println!("Cancelled"),
    Err(e) => eprintln!("Error: {}", e),
  }
}

Key Bindings

Key Action
ENTER Submit input and return
CTRL+ENTER Insert newline
ESC Cancel (returns None)
CTRL+C Cancel (returns None)
CTRL+D Submit (alternative to ENTER)
Backspace Delete character before cursor
Delete Delete character at cursor
←/→ Move cursor left/right
↑/↓ Move cursor up/down (between lines)
Home Move to start of current line
End Move to end of current line
CTRL+Home Move to start of text
CTRL+End Move to end of text

Advanced Usage

With Builder Pattern

use multiline_input::Builder;

let editor = Builder::new()
  .prompt("Enter commit message:")
  .min_length(10)
  .max_length(500)
  .show_line_numbers(true)
  .show_status(true)
  .color(true)
  .build();

match editor.collect() {
  Ok(Some(msg)) => println!("Commit:\n{}", msg),
  Ok(None) => println!("Cancelled"),
  Err(e) => eprintln!("Error: {}", e),
}

With Validation

use multiline_input::Builder;

let editor = Builder::new()
  .prompt("Enter message:")
  .validator(|text| {
    if text.contains("spam") {
      Err("Message contains prohibited content".to_string())
    } else {
      Ok(())
    }
  })
  .build();

match editor.collect() {
  Ok(Some(text)) => println!("Valid: {}", text),
  Ok(None) => println!("Cancelled"),
  Err(e) => eprintln!("Error: {}", e),
}

Pre-filled Text

use multiline_input::Builder;

let editor = Builder::new()
  .prompt("Edit TODO:")
  .initial_text("- Task 1\n- Task 2\n- Task 3")
  .show_line_numbers(true)
  .build();

match editor.collect() {
  Ok(Some(text)) => println!("Updated:\n{}", text),
  Ok(None) => println!("Cancelled"),
  Err(e) => eprintln!("Error: {}", e),
}

Configuration Options

Option Type Default Description
prompt &str "" Prompt message to display
allow_empty bool true Allow empty input
min_length Option<usize> None Minimum text length
max_length Option<usize> None Maximum text length
validator Fn(&str) -> Result<(), String> None Custom validation function
initial_text Option<String> None Pre-filled text
placeholder Option<String> None Placeholder text when empty
show_line_numbers bool false Display line numbers
show_status bool false Display status line (line/col/chars)
show_char_count bool false Display character count
color bool true Enable colored output

Examples

See examples/ directory for more usage examples:

  • basic_usage.rs - Simple input collection
  • with_validation.rs - Custom validation
  • with_config.rs - Full configuration demo
  • pre_filled.rs - Edit existing text

Run examples:

cargo run --example basic_usage

How It Works

  1. Enters raw terminal mode to capture individual key events
  2. Parses key combinations (ENTER, CTRL+ENTER, arrows, etc.)
  3. Updates text buffer with insertions/deletions
  4. Renders to screen with visual feedback
  5. Returns collected text on ENTER or None on ESC/CTRL+C

Platform Support

  • Linux: Full support (all terminals)
  • macOS: Full support (Terminal.app, iTerm2)
  • ⚠️ Windows:
    • Windows Terminal: Full support
    • cmd.exe: Limited (CTRL+ENTER may not work)
    • ConEmu: Full support

Implementation Status

  • Core input collection
  • Key event handling (ENTER, CTRL+ENTER, ESC, arrows)
  • Text buffer with cursor management
  • Basic rendering
  • Builder API
  • Validation (min/max, custom)
  • Visual enhancements (line numbers, status, colors)
  • Scrolling for large texts
  • Undo/redo
  • Clipboard integration

Documentation

For complete specification and implementation details, see spec.md.

For API documentation: cargo doc --open

Testing

# Run tests
cargo test

# Run with coverage
cargo tarpaulin --out Html

Contributing

Contributions welcome! Please:

  1. Read spec.md for architecture details
  2. Write tests for new features
  3. Follow existing code style
  4. Update documentation

License

MIT License - see LICENSE for details

Related Projects

Difference: multiline_input focuses specifically on multiline text collection with ENTER to submit and CTRL+ENTER for newlines, optimized for AI assistant integration and commit message editing.

Commit count: 999

cargo fmt