terminal: Expose selection in context and add keep_selection_on_copy setting (#33491)

Closes #21262

Introduces a new setting `keep_selection_on_copy`, which controls
whether the current text selection is preserved after copying in the
terminal. The default behavior remains the same (`true`), but setting it
to `false` will clear the selection after the copy operation, matching
VSCode's behavior.

Additionally, the terminal context now exposes a `selection` flag
whenever text is selected.

This allows users to match VSCode and other terminal's smart copy
behavior.

Release Notes:

- Expose `selection` to terminal context when there is text selected in
the terminal
- Add `keep_selection_on_copy` terminal setting. Can be set to false to
clear the text selection when copying text.

**VSCode Behavior Example:**

**settings.json:**
```json
  "terminal": {
    "keep_selection_on_copy": false
  },
```
**keymap.json:**
```json
  {
    "context": "Terminal && selection",
    "bindings": {
      "ctrl-c": "terminal::Copy"
    }
  }
```
This commit is contained in:
chico ferreira 2025-07-03 07:37:27 +01:00 committed by GitHub
parent 2a8121fbfc
commit 5c88e9c66b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 40 additions and 1 deletions

View file

@ -1292,6 +1292,8 @@
// Whether or not selecting text in the terminal will automatically
// copy to the system clipboard.
"copy_on_select": false,
// Whether to keep the text selection after copying it to the clipboard
"keep_selection_on_copy": false,
// Whether to show the terminal button in the status bar
"button": true,
// Any key-value pairs added to this list will be added to the terminal's

View file

@ -898,7 +898,13 @@ impl Terminal {
InternalEvent::Copy => {
if let Some(txt) = term.selection_to_string() {
cx.write_to_clipboard(ClipboardItem::new_string(txt))
cx.write_to_clipboard(ClipboardItem::new_string(txt));
let settings = TerminalSettings::get_global(cx);
if !settings.keep_selection_on_copy {
self.events.push_back(InternalEvent::SetSelection(None));
}
}
}
InternalEvent::ScrollToAlacPoint(point) => {

View file

@ -40,6 +40,7 @@ pub struct TerminalSettings {
pub alternate_scroll: AlternateScroll,
pub option_as_meta: bool,
pub copy_on_select: bool,
pub keep_selection_on_copy: bool,
pub button: bool,
pub dock: TerminalDockPosition,
pub default_width: Pixels,
@ -193,6 +194,10 @@ pub struct TerminalSettingsContent {
///
/// Default: false
pub copy_on_select: Option<bool>,
/// Whether to keep the text selection after copying it to the clipboard.
///
/// Default: false
pub keep_selection_on_copy: Option<bool>,
/// Whether to show the terminal button in the status bar.
///
/// Default: true

View file

@ -823,6 +823,11 @@ impl TerminalView {
};
dispatch_context.set("mouse_format", format);
};
if self.terminal.read(cx).last_content.selection.is_some() {
dispatch_context.add("selection");
}
dispatch_context
}

View file

@ -2564,6 +2564,7 @@ List of `integer` column numbers
"alternate_scroll": "off",
"blinking": "terminal_controlled",
"copy_on_select": false,
"keep_selection_on_copy": false,
"dock": "bottom",
"default_width": 640,
"default_height": 320,
@ -2688,6 +2689,26 @@ List of `integer` column numbers
}
```
### Terminal: Keep Selection On Copy
- Description: Whether or not to keep the selection in the terminal after copying text.
- Setting: `keep_selection_on_copy`
- Default: `false`
**Options**
`boolean` values
**Example**
```json
{
"terminal": {
"keep_selection_on_copy": true
}
}
```
### Terminal: Env
- Description: Any key-value pairs added to this object will be added to the terminal's environment. Keys must be unique, use `:` to separate multiple values in a single variable