editor: Add an option to disable rounded corners for text selection (#36987)

Ivan Trubach created

Closes #19891

Similar to VSCode’s `editor.roundedSelection` option.

#### Before/after

<table>
<tr><th><th>Enabled (default)</th><th>Disabled</th>
<tr><td>Editor-based UIs<td><img width="268" height="58" alt="image"
src="https://github.com/user-attachments/assets/f58c6817-88fc-4cba-b2bc-f7eff58ec6e5"
/>
<img width="146" height="97" alt="image"
src="https://github.com/user-attachments/assets/0cd08afa-8243-4d4e-a5c6-9055f6834ecf"
/><td><img width="272" height="54" alt="image"
src="https://github.com/user-attachments/assets/286c8f53-1973-442e-8446-4f48e3feca30"
/>
<img width="133" height="90" alt="image"
src="https://github.com/user-attachments/assets/4aea2044-403c-47a5-bb6d-a88a0b65814e"
/></td>
<tr><td>Terminal<td><img width="287" height="84" alt="image"
src="https://github.com/user-attachments/assets/b1594f68-2ef6-4bdc-9030-e67d55a5bf99"
/><td><img width="289" height="79" alt="image"
src="https://github.com/user-attachments/assets/6d095d9d-b408-4440-a9f5-6a2af2b84b61"
/></td>
</table>

Release Notes:

- Added setting `rounded_selection` to disable rounded corners for text
selection.

Change summary

assets/settings/default.json                 | 2 ++
crates/editor/src/editor_settings.rs         | 6 ++++++
crates/editor/src/element.rs                 | 9 +++++++--
crates/terminal_view/src/terminal_element.rs | 9 +++++++--
docs/src/configuring-zed.md                  | 6 ++++++
5 files changed, 28 insertions(+), 4 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -223,6 +223,8 @@
   "current_line_highlight": "all",
   // Whether to highlight all occurrences of the selected text in an editor.
   "selection_highlight": true,
+  // Whether the text selection should have rounded corners.
+  "rounded_selection": true,
   // The debounce delay before querying highlights from the language
   // server based on the current cursor location.
   "lsp_highlight_debounce": 75,

crates/editor/src/editor_settings.rs 🔗

@@ -17,6 +17,7 @@ pub struct EditorSettings {
     pub cursor_shape: Option<CursorShape>,
     pub current_line_highlight: CurrentLineHighlight,
     pub selection_highlight: bool,
+    pub rounded_selection: bool,
     pub lsp_highlight_debounce: u64,
     pub hover_popover_enabled: bool,
     pub hover_popover_delay: u64,
@@ -441,6 +442,10 @@ pub struct EditorSettingsContent {
     ///
     /// Default: true
     pub selection_highlight: Option<bool>,
+    /// Whether the text selection should have rounded corners.
+    ///
+    /// Default: true
+    pub rounded_selection: Option<bool>,
     /// The debounce delay before querying highlights from the language
     /// server based on the current cursor location.
     ///
@@ -794,6 +799,7 @@ impl Settings for EditorSettings {
             "editor.selectionHighlight",
             &mut current.selection_highlight,
         );
+        vscode.bool_setting("editor.roundedSelection", &mut current.rounded_selection);
         vscode.bool_setting("editor.hover.enabled", &mut current.hover_popover_enabled);
         vscode.u64_setting("editor.hover.delay", &mut current.hover_popover_delay);
 

crates/editor/src/element.rs 🔗

@@ -6063,7 +6063,7 @@ impl EditorElement {
                 };
 
                 self.paint_lines_background(layout, window, cx);
-                let invisible_display_ranges = self.paint_highlights(layout, window);
+                let invisible_display_ranges = self.paint_highlights(layout, window, cx);
                 self.paint_document_colors(layout, window);
                 self.paint_lines(&invisible_display_ranges, layout, window, cx);
                 self.paint_redactions(layout, window);
@@ -6085,6 +6085,7 @@ impl EditorElement {
         &mut self,
         layout: &mut EditorLayout,
         window: &mut Window,
+        cx: &mut App,
     ) -> SmallVec<[Range<DisplayPoint>; 32]> {
         window.paint_layer(layout.position_map.text_hitbox.bounds, |window| {
             let mut invisible_display_ranges = SmallVec::<[Range<DisplayPoint>; 32]>::new();
@@ -6101,7 +6102,11 @@ impl EditorElement {
                 );
             }
 
-            let corner_radius = 0.15 * layout.position_map.line_height;
+            let corner_radius = if EditorSettings::get_global(cx).rounded_selection {
+                0.15 * layout.position_map.line_height
+            } else {
+                Pixels::ZERO
+            };
 
             for (player_color, selections) in &layout.selections {
                 for selection in selections.iter() {

crates/terminal_view/src/terminal_element.rs 🔗

@@ -1,4 +1,4 @@
-use editor::{CursorLayout, HighlightedRange, HighlightedRangeLine};
+use editor::{CursorLayout, EditorSettings, HighlightedRange, HighlightedRangeLine};
 use gpui::{
     AbsoluteLength, AnyElement, App, AvailableSpace, Bounds, ContentMask, Context, DispatchPhase,
     Element, ElementId, Entity, FocusHandle, Font, FontFeatures, FontStyle, FontWeight,
@@ -1257,12 +1257,17 @@ impl Element for TerminalElement {
                         if let Some((start_y, highlighted_range_lines)) =
                             to_highlighted_range_lines(relative_highlighted_range, layout, origin)
                         {
+                            let corner_radius = if EditorSettings::get_global(cx).rounded_selection {
+                                0.15 * layout.dimensions.line_height
+                            } else {
+                                Pixels::ZERO
+                            };
                             let hr = HighlightedRange {
                                 start_y,
                                 line_height: layout.dimensions.line_height,
                                 lines: highlighted_range_lines,
                                 color: *color,
-                                corner_radius: 0.15 * layout.dimensions.line_height,
+                                corner_radius: corner_radius,
                             };
                             hr.paint(true, bounds, window);
                         }

docs/src/configuring-zed.md 🔗

@@ -685,6 +685,12 @@ List of `string` values
 - Setting: `selection_highlight`
 - Default: `true`
 
+## Rounded Selection
+
+- Description: Whether the text selection should have rounded corners.
+- Setting: `rounded_selection`
+- Default: `true`
+
 ## Cursor Blink
 
 - Description: Whether or not the cursor blinks.