feat: Copy Mode for OpenCode #1808

Open
opened 2026-02-16 17:32:42 -05:00 by yindo · 6 comments
Owner

Originally created by @thuanpham582002 on GitHub (Sep 24, 2025).

Originally assigned to: @adamdotdevin on GitHub.

Summary

OpenCode currently lacks a proper copy mode, making it difficult for users to selectively copy text from chat
messages, code blocks, and other content displayed in the viewport. While basic message copying exists (ctrl+x y), users need vim/tmux-like copy mode for precise text selection and copying.

Problem Statement

Current Limitations

  1. No Keyboard-based Text Selection: Users cannot select text using keyboard only
  2. Limited Copy Functionality: Only entire message copying is available (ctrl+x y)
  3. Incompatible with tmux Copy Mode: OpenCode runs as a TUI application but doesn't integrate with tmux's copy
    mode
  4. Poor UX for Code Review: Cannot selectively copy code snippets, error messages, or specific parts of
    responses
  5. Mouse Dependency: Users must rely on mouse for text selection, which is inefficient in terminal
    environments

User Impact

  • Developers: Cannot quickly copy code snippets from AI responses
  • Power Users: Keyboard-driven workflow is broken when needing to copy text
  • Terminal Enthusiasts: Expect vim/tmux-like navigation and selection
  • Accessibility: Mouse-dependent selection is not accessible to all users

Why Copy Mode is Essential

1. Terminal Workflow Compatibility

OpenCode is a TUI (Terminal User Interface) application that runs in terminal emulators. Terminal users expect:

  • Vim-like navigation and selection
  • Keyboard-driven text manipulation
  • Integration with existing terminal tools

2. tmux Integration Problem

When OpenCode runs inside tmux:

  • tmux's copy mode (prefix+[) doesn't work properly, it only can select and copy one page that currently visible of opencode.

3. Pager-like Applications Need Copy Mode

OpenCode functions as a pager for chat messages and code:

  • Similar to less, more, or vim
  • All major pagers have copy/select functionality
  • Users expect to be able to select and copy content

4. Developer Productivity

Developers using OpenCode need to:

  • Copy code snippets from AI responses
  • Select error messages for debugging
  • Extract specific parts of long responses
  • Maintain keyboard-driven workflow

What Already Exists ()

  1. Selection System:
    type selection struct {
        startX int
        endX   int
        startY int
        endY   int
    }
    
• Mouse-based selection is implemented
• Coordinate tracking works correctly

2. Highlight System:
```go
type highlightInfo struct {
    lineStart, lineEnd int
    lines map[int][2]int
}

• Viewport has robust highlighting
• Multi-line highlighting supported
• SetHighlights(), HighlightNext(), HighlightPrevious() available
3. Navigation Keymap:

type KeyMap struct {
    PageDown, PageUp key.Binding
    HalfPageUp, HalfPageDown key.Binding
    Down, Up key.Binding
    Left, Right key.Binding
}

• Vim-like keys already implemented: j/k, h/l, f/b, d/u
• Navigation system is mature
4. Clipboard Integration:
• cmds = append(cmds, app.SetClipboard(lastTextPart.Text))
• app.SetClipboard() function exists
• Toast notification system available

Originally created by @thuanpham582002 on GitHub (Sep 24, 2025). Originally assigned to: @adamdotdevin on GitHub. ## Summary OpenCode currently lacks a proper copy mode, making it difficult for users to selectively copy text from chat messages, code blocks, and other content displayed in the viewport. While basic message copying exists (`ctrl+x y`), users need vim/tmux-like copy mode for precise text selection and copying. ## Problem Statement ### Current Limitations 1. **No Keyboard-based Text Selection**: Users cannot select text using keyboard only 2. **Limited Copy Functionality**: Only entire message copying is available (`ctrl+x y`) 3. **Incompatible with tmux Copy Mode**: OpenCode runs as a TUI application but doesn't integrate with tmux's copy mode 4. **Poor UX for Code Review**: Cannot selectively copy code snippets, error messages, or specific parts of responses 5. **Mouse Dependency**: Users must rely on mouse for text selection, which is inefficient in terminal environments ### User Impact - **Developers**: Cannot quickly copy code snippets from AI responses - **Power Users**: Keyboard-driven workflow is broken when needing to copy text - **Terminal Enthusiasts**: Expect vim/tmux-like navigation and selection - **Accessibility**: Mouse-dependent selection is not accessible to all users ## Why Copy Mode is Essential ### 1. **Terminal Workflow Compatibility** OpenCode is a TUI (Terminal User Interface) application that runs in terminal emulators. Terminal users expect: - Vim-like navigation and selection - Keyboard-driven text manipulation - Integration with existing terminal tools ### 2. **tmux Integration Problem** When OpenCode runs inside tmux: - tmux's copy mode (`prefix+[`) doesn't work properly, it only can select and copy one page that currently visible of opencode. ### 3. **Pager-like Applications Need Copy Mode** OpenCode functions as a pager for chat messages and code: - Similar to `less`, `more`, or `vim` - All major pagers have copy/select functionality - Users expect to be able to select and copy content ### 4. **Developer Productivity** Developers using OpenCode need to: - Copy code snippets from AI responses - Select error messages for debugging - Extract specific parts of long responses - Maintain keyboard-driven workflow ### What Already Exists (✅) 1. **Selection System**: ```go type selection struct { startX int endX int startY int endY int } ``` • Mouse-based selection is implemented • Coordinate tracking works correctly 2. Highlight System: ```go type highlightInfo struct { lineStart, lineEnd int lines map[int][2]int } ``` • Viewport has robust highlighting • Multi-line highlighting supported • SetHighlights(), HighlightNext(), HighlightPrevious() available 3. Navigation Keymap: ```go type KeyMap struct { PageDown, PageUp key.Binding HalfPageUp, HalfPageDown key.Binding Down, Up key.Binding Left, Right key.Binding } ``` • Vim-like keys already implemented: j/k, h/l, f/b, d/u • Navigation system is mature 4. Clipboard Integration: • cmds = append(cmds, app.SetClipboard(lastTextPart.Text)) • app.SetClipboard() function exists • Toast notification system available
Author
Owner

@github-actions[bot] commented on GitHub (Sep 24, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #2114: Directly addresses the core problem - no way to select or copy text from output messages
  • #2118: Requests a /copy command and better text selection with scrolling capabilities
  • #1210: Addresses mouse text selection issues and specifically mentions wanting vim/tmux-like behavior
  • #862: Requested keyboard shortcuts for scrolling (Ctrl+d, Ctrl+u) and mentions tmux usage
  • #2649: Requests improved keyboard navigation (Home/End, ctrl+left/right keys)

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Sep 24, 2025): This issue might be a duplicate of existing issues. Please check: - #2114: Directly addresses the core problem - no way to select or copy text from output messages - #2118: Requests a /copy command and better text selection with scrolling capabilities - #1210: Addresses mouse text selection issues and specifically mentions wanting vim/tmux-like behavior - #862: Requested keyboard shortcuts for scrolling (Ctrl+d, Ctrl+u) and mentions tmux usage - #2649: Requests improved keyboard navigation (Home/End, ctrl+left/right keys) Feel free to ignore if none of these address your specific case.
Author
Owner

@rekram1-node commented on GitHub (Sep 24, 2025):

yeah copying could be better, tui is being rewritten currently so features like this can best be addressed after the fact.

Ultimately all ux goes through @adamdotdevin

@rekram1-node commented on GitHub (Sep 24, 2025): yeah copying could be better, tui is being rewritten currently so features like this can best be addressed after the fact. Ultimately all ux goes through @adamdotdevin
Author
Owner

@jonahbenton commented on GitHub (Nov 18, 2025):

Voting +1. Would also like selection by mouse and keyboard navigation.

@jonahbenton commented on GitHub (Nov 18, 2025): Voting +1. Would also like selection by mouse and keyboard navigation.
Author
Owner

@itse4elhaam commented on GitHub (Dec 10, 2025):

+1

Incompatible with tmux Copy Mode: OpenCode runs as a TUI application but doesn't integrate with tmux's copy
mode

This is one of the painpoints.

@itse4elhaam commented on GitHub (Dec 10, 2025): +1 > Incompatible with tmux Copy Mode: OpenCode runs as a TUI application but doesn't integrate with tmux's copy mode This is one of the painpoints.
Author
Owner

@jkirkpatrick commented on GitHub (Jan 25, 2026):

+1

The "Copied to Clipboard" notification is a lie - not an error or omission.

It should be removed (and gated behind a feature flag) until tested and confirmed working.

@jkirkpatrick commented on GitHub (Jan 25, 2026): +1 The "Copied to Clipboard" notification is a lie - not an error or omission. It should be removed (and gated behind a feature flag) until tested and confirmed working.
Author
Owner

@fadedlamp42 commented on GitHub (Feb 5, 2026):

A decent workaround, for now, is to:

  1. Use ^x x to "Export session transcript"
  2. Hold ^w to clear out the default filename and replace with /tmp/s[croll] (or whatever you prefer)
  3. Upon submitting, a child $EDITOR /tmp/s opens (nvim for me) which provides access to the full conversation. A simple G and you can pretend you're in tmux scroll mode

EDIT: These make things not as bad, too

    "messages_page_up": "pageup,ctrl+alt+b",
    "messages_page_down": "pagedown,ctrl+alt+f",
    "messages_line_up": "ctrl+alt+y",
    "messages_line_down": "ctrl+alt+e",
    "messages_half_page_up": "ctrl+alt+u",
    "messages_half_page_down": "ctrl+alt+d",
    "messages_first": "ctrl+g,home",
    "messages_last": "ctrl+alt+g,end",
@fadedlamp42 commented on GitHub (Feb 5, 2026): A decent workaround, for now, is to: 1. Use `^x x` to "Export session transcript" 2. Hold `^w` to clear out the default filename and replace with `/tmp/s`[croll] (or whatever you prefer) 3. Upon submitting, a child `$EDITOR /tmp/s` opens (`nvim` for me) which provides access to the full conversation. A simple `G` and you can pretend you're in `tmux` scroll mode EDIT: [These](https://opencode.ai/docs/keybinds) make things not as bad, too ``` "messages_page_up": "pageup,ctrl+alt+b", "messages_page_down": "pagedown,ctrl+alt+f", "messages_line_up": "ctrl+alt+y", "messages_line_down": "ctrl+alt+e", "messages_half_page_up": "ctrl+alt+u", "messages_half_page_down": "ctrl+alt+d", "messages_first": "ctrl+g,home", "messages_last": "ctrl+alt+g,end", ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1808