Skip to content

feat: implement text selection in terminal pane #95

@TechDufus

Description

@TechDufus

Summary

The terminal pane lacks scrollback and text selection capabilities. Users cannot scroll through terminal history or select/copy text in the embedded terminal view.

Background

Discovered while fixing mouse event leak bugs (#92, #96, #98). Deep investigation revealed the root cause.

Root Cause Analysis

Why Scrolling Doesn't Work

Component Limitation
vt10x No scrollback buffer - terminal history is discarded when it scrolls off screen
bubbletea Uses alternate screen mode (WithAltScreen) which has no native scrollback
Mouse capture Bubbletea captures all mouse events - they can't fall through to host terminal

The Paradox Explained

When Claude Code runs directly in a terminal:

  • Host terminal (iTerm, etc.) maintains scrollback buffer
  • Mouse wheel scrolls the terminal's buffer
  • Works because the terminal handles it, not the app

When Claude Code runs inside OpenKanban:

  • OpenKanban's terminal pane (vt10x) has no scrollback
  • Alternate screen mode disables host terminal scrollback
  • Mouse events captured by bubbletea can't reach host terminal
  • No scrollback buffer exists anywhere in the chain

Current Behavior

Mouse Action Behavior
Click Blocked (prevents garbage)
Scroll wheel Blocked (no scrollback to scroll)
Click-drag Nothing (no selection infrastructure)
Motion Blocked (prevents garbage)

Solution Options

Option A: Implement Scrollback in Pane (Recommended)

Add scrollback buffer to the Pane struct:

  • Maintain history buffer (vt10x doesn't support this)
  • Intercept scroll-up before lines are discarded
  • Track viewport offset
  • Render from scrollback when scrolled up
  • Handle scroll wheel to adjust viewport

Option B: Migrate to bubbleterm

Replace vt10x with bubbleterm:

  • Built-in scrollback support ✅
  • Designed for bubbletea integration ✅
  • Handles mouse events properly ✅
  • More significant refactor

Option C: Hybrid Approach

  1. Use bubbleterm for terminal emulation
  2. Keep existing pane management
  3. Leverage bubbleterm's scrollback and mouse handling

Implementation Requirements (Option A)

1. Scrollback Buffer

type Pane struct {
    // ... existing fields
    scrollbackBuffer [][]vt10x.Glyph  // historical lines
    scrollbackMax    int               // max lines to keep (e.g., 10000)
    viewportOffset   int               // 0 = bottom (live), >0 = scrolled up
}

2. Line Capture

Intercept when vt10x scrolls content off the top of the screen and save to buffer.

3. Scroll Handling

func (p *Pane) HandleScroll(direction int) {
    if direction < 0 { // scroll up
        p.viewportOffset = min(p.viewportOffset + 3, len(p.scrollbackBuffer))
    } else { // scroll down
        p.viewportOffset = max(p.viewportOffset - 3, 0)
    }
}

4. Render Modification

When viewportOffset > 0, render from scrollback buffer instead of live vt10x screen.

Text Selection (Separate but Related)

Once scrollback exists, selection becomes feasible:

  • Track selection start/end coordinates
  • Render selected text with inverted colors
  • Copy to clipboard on release

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions