jumperless-boardboard-v5/RP23V50firmware/CodeDocs/REPL_Multiline_Editing_Improvements.md

7.1 KiB

REPL Multiline Editing Improvements

Overview

Completely revamped multiline editing in the Jumperless MicroPython REPL using a full buffer synchronization approach. This eliminates all display inconsistencies and ensures perfect synchronization between the internal buffer and what's displayed on screen.

Problems Fixed

1. Line Content Disappearing During Edit

  • Issue: When editing a line in multiline mode, the line would clear but not show the updated content properly
  • Cause: Partial screen updates getting out of sync with terminal state
  • Solution: Complete buffer redraw on every keystroke ensures perfect synchronization

2. Inconsistent Display Updates

  • Issue: What was typed would be executed correctly but not always displayed on screen
  • Cause: Race conditions between incremental display updates and terminal control sequences
  • Solution: Full buffer approach eliminates race conditions by always showing the complete current state

3. Cursor Positioning Issues

  • Issue: Cursor would end up in wrong position after editing multiline content
  • Cause: Accumulating errors from incremental cursor movement commands
  • Solution: Precise cursor positioning calculation based on actual buffer content and cursor position

Technical Changes

New Full Buffer Approach

Core Philosophy

  • Complete Redraw: Every keystroke triggers a full redraw of the entire input buffer
  • Buffer Synchronization: Internal buffer state is always perfectly reflected on screen
  • Precise Positioning: Cursor position calculated based on actual buffer content, not incremental movements
  • Accurate Line Tracking: Fixed line clearing logic to prevent screen scrolling issues

Modified Functions in src/Python_Proper.cpp

redrawFullInput() (Enhanced)

  • Now used for ALL display updates, not just specific cases
  • Added positionCursorAtCurrentPos() for precise cursor positioning
  • Completely clears display area and redraws entire buffer with proper prompts
  • Handles multiline syntax highlighting correctly

positionCursorAtCurrentPos() (New)

  • Calculates exact line and column position based on cursor_pos in buffer
  • Accounts for prompt lengths (">>>" vs "...")
  • Moves cursor to precise location using terminal control sequences
  • Handles multiline navigation correctly

Input Handling Logic (Completely Revised)

  • All Operations: Character input, backspace, tab, arrow keys ALL use full redraw
  • Eliminated Incremental Updates: No more partial screen updates or character echoing
  • Perfect Consistency: What you see is exactly what's in the buffer, always

Line Clearing Fix (Critical Bug Fix)

  • Issue: Going up a line was erasing one extra line, causing screen scrolling
  • Root Cause: last_displayed_lines was tracking newline count instead of actual cursor movement needed
  • Solution: Now tracks lines_printed which represents lines moved down from first line
  • Result: Perfect line clearing without unwanted screen scrolling

Testing

Basic Testing

  1. Enter multiline mode by typing code that requires multiple lines:
def test_function():
    print("line 1")
    print("line 2")
    return "done"
  1. Use arrow keys to navigate to the middle of any line
  2. Edit the content (add/remove characters)
  3. Verify the line displays correctly and stays visible

Advanced Testing

Use the comprehensive test scripts:

# Basic functionality test
exec(open('/path/to/test_multiline_editing.py').read())

# Full buffer synchronization test
exec(open('/path/to/test_full_buffer_multiline.py').read())

# Line clearing fix verification test
exec(open('/path/to/test_line_clearing_fix.py').read())

Expected Behavior

  • Perfect Synchronization: Buffer content always matches display exactly
  • Reliable Cursor Position: Cursor always positioned correctly, never out of sync
  • Complete Redraw: Every keystroke shows immediate, complete result
  • Multiline Navigation: Arrow keys work perfectly in complex multiline structures
  • No Display Artifacts: No leftover characters or partial line updates
  • Syntax Highlighting: Works correctly across all multiline content
  • Edit Anywhere: Can edit any character in any line without display issues

Memory Usage

The full buffer approach uses slightly more resources but ensures reliability:

  • Complete buffer redraw on each keystroke (acceptable performance impact)
  • Enhanced cursor position calculation
  • Eliminated incremental update complexity
  • Overall more reliable and maintainable code

Backward Compatibility

All changes are fully backward compatible:

  • Existing REPL functionality unchanged
  • All keyboard shortcuts and commands work as before
  • History navigation still works perfectly
  • File operations and special commands unchanged

Performance Impact

  • Multiline editing: Small increase in redraw time, but perfect reliability
  • Single-line editing: Same full redraw approach, consistent experience
  • Terminal responsiveness: Improved due to elimination of synchronization issues
  • Visual feedback: Immediate and always accurate display updates

Future Improvements

  • Optional performance optimization: Only redraw when buffer actually changes
  • Add configurable redraw modes (full vs. smart) for different terminal capabilities
  • Implement line wrapping for extremely long lines (>terminal width)
  • Add visual indicators for multiline mode status
  • Consider terminal size detection for adaptive display

Technical Architecture

Buffer Management

  • Single Source of Truth: current_input string contains entire buffer
  • Cursor Tracking: cursor_pos integer tracks character position in buffer
  • Display Synchronization: redrawFullInput() ensures screen matches buffer exactly

Terminal Control Flow

  1. Input Received → Update buffer (current_input) and cursor position (cursor_pos)
  2. Full Redraw → Clear display area, redraw entire buffer with syntax highlighting
  3. Cursor Positioning → Calculate exact screen position and move cursor there
  4. Flush → Ensure all terminal commands are processed

Key Benefits

  • Eliminates State Drift: No accumulation of display/buffer mismatches
  • Predictable Behavior: Every keystroke produces same result regardless of history
  • Easier Debugging: Single redraw function handles all display logic
  • Robust Navigation: Arrow keys work correctly in any multiline scenario
  • src/Python_Proper.cpp - Main REPL implementation with full buffer logic
  • src/Python_Proper.h - REPL editor structure definitions
  • CodeDocs/examples/test_multiline_editing.py - Basic functionality testing
  • CodeDocs/examples/test_full_buffer_multiline.py - Comprehensive buffer sync testing
  • CodeDocs/examples/test_line_clearing_fix.py - Line clearing fix verification

Memory References

  • memory:2792014 - C++ serial output requires \r\n for proper cursor positioning
  • memory:240128 - MicroPython REPL with proper multiline state tracking
  • memory:240161 - Complete REPL implementation with edge case handling