Skip to content

Fix pasting in terminals#17603

Merged
colin-grant-work merged 2 commits into
masterfrom
bugfix/paste-in-terminals-17601
Jun 5, 2026
Merged

Fix pasting in terminals#17603
colin-grant-work merged 2 commits into
masterfrom
bugfix/paste-in-terminals-17601

Conversation

@colin-grant-work
Copy link
Copy Markdown
Contributor

What it does

Fixes paste (Cmd+V / Ctrl+V) in the integrated terminal, and along the way restores the documented effect of the terminal.enablePaste and terminal.enableCopy preferences.

Root cause. The global ctrlcmd+v keybinding for CommonCommands.PASTE (see common-frontend-contribution.ts:841, enabled in Electron) intercepts the keystroke at the document level before xterm.js's hidden textarea can fire its native paste event. xterm's own paste pipeline — which would call Terminal.paste() and forward to the PTY, including bracketed-paste sequences — never runs. The same dynamic made terminal.enablePaste / terminal.enableCopy effectively dead, since they were only checked by TerminalWidgetImpl.customKeyHandler, which the global keybinding preempts.

Approach. Follow VSCode's terminal-clipboard pattern, using the keybinding priority mechanism from #16763:

  • Register terminal-specific commands workbench.action.terminal.paste and workbench.action.terminal.copySelection, each with its own ctrlcmd+v / ctrlcmd+c keybinding scoped when: 'terminalFocus'.
  • Each TerminalWidgetImpl declares terminalFocus as a local context key on its own DOM scope (contextKeyService.createScoped(this.node).createKey('terminalFocus', true)). When focus is inside a terminal, KeybindingRegistry.selectBindingByLocalContext prefers the terminal-scoped binding over the unconstrained global CommonCommands.PASTE / CommonCommands.COPY.
  • Paste routes through a new TerminalWidget.paste(text) method that delegates to xterm's Terminal.paste() (preserving bracketed-paste handling). Copy keeps using TerminalCopyOnSelectionHandler.syncCopy().
  • Handlers honor terminal.enablePaste / terminal.enableCopy. When a preference is off, the keybinding's isEnabled returns false and falls through to the global binding — matching the literal reading of the preferences' descriptions.

Outcomes.

  • Cmd+V / Ctrl+V and Cmd+C / Ctrl+C work in the terminal (keystroke, terminal context menu).
  • terminal.enablePaste / terminal.enableCopy regain their effect on the keystroke and context-menu entries; no effect on editor / Command Palette / input-field paste-copy.
  • CommonCommands.PASTE and CommonCommands.COPY are no longer overridden by the terminal package. The registerHandler(CommonCommands.COPY.id, …) from fix(terminal): copy via context menu does not work #17290 is removed; the user-visible fix it landed (context-menu Copy) is preserved by the new structure.

How to test

  1. Open Theia (esp. macOS Electron) and a terminal.
  2. Paste: copy text, then in the terminal use Cmd+V / Ctrl+V and right-click → Paste; both should insert at the prompt.
  3. Bracketed paste: paste a multi-line snippet into bash/zsh/python REPL; lines should not be executed individually or auto-indented.
  4. Copy: select text, use Cmd+C / Ctrl+C and right-click → Copy; verify by pasting elsewhere.
  5. Preferences: with terminal.enablePaste: false (resp. enableCopy: false), the corresponding keystroke and menu entry should no-op in the terminal but still work in editors. Reset and re-verify.
  6. Non-terminal contexts: confirm Cmd+V / Cmd+C are unchanged in editors, Command Palette, dialogs, input fields.
  7. fix(terminal): copy via context menu does not work #17290 regression check: right-click → Copy with a selection still copies.

Follow-ups

  • Electron Edit menu bypasses Theia commands. electron-main-menu-factory.ts:240 deletes menuItem.execute when assigning role: 'paste' / 'copy', so Edit → Paste / Copy runs Electron's native role and skips the new terminal commands (and the terminal.enable* preferences). Paste still lands in xterm's textarea via the synthetic DOM event and reaches the PTY, so it works — but it isn't gated by the preferences. VSCode keeps a click handler alongside the role and re-dispatches through the renderer's keybinding service so a focused terminal resolves the correct command; aligning Theia's Electron menu factory with that pattern is tracked as a follow-up.
  • customKeyHandler Cmd+V / Cmd+C branches are now mostly dead with the renderer-level keybindings handling both. Worth removing or scoping to browser-only modes in a follow-up.

Breaking changes

  • This PR introduces breaking changes and requires careful review.

Note: TerminalWidget gains a new abstract method paste(text: string). Downstream subclasses will need to implement it. Consistent with getSelection() / hasSelection() added in #17290.

Attribution

Review checklist

Reminder for reviewers

@github-project-automation github-project-automation Bot moved this to Waiting on reviewers in PR Backlog Jun 1, 2026
@ndoschek ndoschek linked an issue Jun 3, 2026 that may be closed by this pull request
@ndoschek ndoschek requested a review from cdamus June 3, 2026 15:21
Copy link
Copy Markdown
Contributor

@cdamus cdamus left a comment

Choose a reason for hiding this comment

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

Very clean! Nice fix and it all works as advertised and (perhaps more importantly) as I expect as a user.

I think, though, that adding an abstract method to a class that is meant to be subclassed is a breaking API change, so that should be called out in the changelog.

The two nits are optional.

Comment thread packages/terminal/src/browser/terminal-frontend-contribution.ts Outdated
Comment thread packages/terminal/src/browser/terminal-frontend-contribution.ts Outdated
@colin-grant-work colin-grant-work force-pushed the bugfix/paste-in-terminals-17601 branch from a6aec5d to 5c4cbe2 Compare June 4, 2026 14:32
Copy link
Copy Markdown
Contributor

@cdamus cdamus left a comment

Choose a reason for hiding this comment

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

Thanks for the changes! 🚀

@github-project-automation github-project-automation Bot moved this from Waiting on reviewers to Needs merge in PR Backlog Jun 4, 2026
@colin-grant-work colin-grant-work merged commit 76e8885 into master Jun 5, 2026
16 of 17 checks passed
@colin-grant-work colin-grant-work deleted the bugfix/paste-in-terminals-17601 branch June 5, 2026 15:06
@github-project-automation github-project-automation Bot moved this from Needs merge to Done in PR Backlog Jun 5, 2026
@github-actions github-actions Bot added this to the 1.73.0 milestone Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Unable to paste in terminals on MacOS

2 participants