Merge pull request #1659 from zed-industries/terminal-selections

Mikayla Maki created

Terminal Touch ups

Change summary

Cargo.lock                              |  1 
assets/keymaps/default.json             | 44 ++++++++++++++---
crates/terminal/Cargo.toml              |  2 
crates/terminal/src/terminal.rs         | 15 +----
crates/terminal/src/terminal_element.rs | 11 ----
crates/terminal/src/terminal_view.rs    | 69 +++++++++++---------------
6 files changed, 72 insertions(+), 70 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -5489,6 +5489,7 @@ dependencies = [
  "procinfo",
  "project",
  "rand 0.8.5",
+ "serde",
  "settings",
  "shellexpand",
  "smallvec",

assets/keymaps/default.json 🔗

@@ -428,17 +428,45 @@
     {
         "context": "Terminal",
         "bindings": {
-            // Overrides for global bindings, remove at your own risk:
-            "up": "terminal::Up",
-            "down": "terminal::Down",
-            "escape": "terminal::Escape",
-            "enter": "terminal::Enter",
-            "ctrl-c": "terminal::CtrlC",
-            // Useful terminal actions:
             "ctrl-cmd-space": "terminal::ShowCharacterPalette",
             "cmd-c": "terminal::Copy",
             "cmd-v": "terminal::Paste",
-            "cmd-k": "terminal::Clear"
+            "cmd-k": "terminal::Clear",
+            // Some nice conveniences
+            "cmd-backspace": [
+                "terminal::SendText",
+                "\u0015"
+            ],
+            "cmd-right": [
+                "terminal::SendText",
+                "\u0005"
+            ],
+            "cmd-left": [
+                "terminal::SendText",
+                "\u0001"
+            ],
+            // There are conflicting bindings for these keys in the global context.
+            // these bindings override them, remove at your own risk:
+            "up": [
+                "terminal::SendKeystroke",
+                "up"
+            ],
+            "down": [
+                "terminal::SendKeystroke",
+                "down"
+            ],
+            "escape": [
+                "terminal::SendKeystroke",
+                "escape"
+            ],
+            "enter": [
+                "terminal::SendKeystroke",
+                "enter"
+            ],
+            "ctrl-c": [
+                "terminal::SendKeystroke",
+                "ctrl-c"
+            ]
         }
     }
 ]

crates/terminal/Cargo.toml 🔗

@@ -30,6 +30,8 @@ libc = "0.2"
 anyhow = "1"
 thiserror = "1.0"
 lazy_static = "1.4.0"
+serde = { version = "1.0", features = ["derive"] }
+
 
 
 

crates/terminal/src/terminal.rs 🔗

@@ -53,9 +53,7 @@ use thiserror::Error;
 use gpui::{
     geometry::vector::{vec2f, Vector2F},
     keymap::Keystroke,
-    scene::{
-        ClickRegionEvent, DownRegionEvent, DragRegionEvent, ScrollWheelRegionEvent, UpRegionEvent,
-    },
+    scene::{DownRegionEvent, DragRegionEvent, ScrollWheelRegionEvent, UpRegionEvent},
     ClipboardItem, Entity, ModelContext, MouseButton, MouseMovedEvent, MutableAppContext, Task,
 };
 
@@ -969,8 +967,6 @@ impl Terminal {
 
                 self.events
                     .push_back(InternalEvent::Scroll(AlacScroll::Delta(scroll_lines)));
-                self.events
-                    .push_back(InternalEvent::UpdateSelection(position))
             }
         }
     }
@@ -996,21 +992,18 @@ impl Terminal {
             self.last_content.size,
             self.last_content.display_offset,
         );
-        let side = mouse_side(position, self.last_content.size);
+        // let side = mouse_side(position, self.last_content.size);
 
         if self.mouse_mode(e.shift) {
             if let Some(bytes) = mouse_button_report(point, e, true, self.last_content.mode) {
                 self.pty_tx.notify(bytes);
             }
         } else if e.button == MouseButton::Left {
-            self.events.push_back(InternalEvent::SetSelection(Some((
-                Selection::new(SelectionType::Simple, point, side),
-                point,
-            ))));
+            self.left_click(e, origin)
         }
     }
 
-    pub fn left_click(&mut self, e: &ClickRegionEvent, origin: Vector2F) {
+    pub fn left_click(&mut self, e: &DownRegionEvent, origin: Vector2F) {
         let position = e.position.sub(origin);
         if !self.mouse_mode(e.shift) {
             //Hyperlinks

crates/terminal/src/terminal_element.rs 🔗

@@ -429,17 +429,6 @@ impl TerminalElement {
                     },
                 ),
             )
-            // Handle click based selections
-            .on_click(
-                MouseButton::Left,
-                TerminalElement::generic_button_handler(
-                    connection,
-                    origin,
-                    move |terminal, origin, e, _cx| {
-                        terminal.left_click(&e, origin);
-                    },
-                ),
-            )
             // Context menu
             .on_click(MouseButton::Right, move |e, cx| {
                 let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx.app) {

crates/terminal/src/terminal_view.rs 🔗

@@ -6,13 +6,15 @@ use gpui::{
     actions,
     elements::{AnchorCorner, ChildView, ParentElement, Stack},
     geometry::vector::Vector2F,
-    impl_internal_actions,
+    impl_actions, impl_internal_actions,
     keymap::Keystroke,
     AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext, Task,
     View, ViewContext, ViewHandle,
 };
+use serde::Deserialize;
 use settings::{Settings, TerminalBlink};
 use smol::Timer;
+use util::ResultExt;
 use workspace::pane;
 
 use crate::{terminal_element::TerminalElement, Event, Terminal};
@@ -28,6 +30,12 @@ pub struct DeployContextMenu {
     pub position: Vector2F,
 }
 
+#[derive(Clone, Default, Deserialize, PartialEq)]
+pub struct SendText(String);
+
+#[derive(Clone, Default, Deserialize, PartialEq)]
+pub struct SendKeystroke(String);
+
 actions!(
     terminal,
     [
@@ -43,16 +51,15 @@ actions!(
         SearchTest
     ]
 );
+
+impl_actions!(terminal, [SendText, SendKeystroke]);
+
 impl_internal_actions!(project_panel, [DeployContextMenu]);
 
 pub fn init(cx: &mut MutableAppContext) {
-    //Global binding overrrides
-    cx.add_action(TerminalView::ctrl_c);
-    cx.add_action(TerminalView::up);
-    cx.add_action(TerminalView::down);
-    cx.add_action(TerminalView::escape);
-    cx.add_action(TerminalView::enter);
     //Useful terminal views
+    cx.add_action(TerminalView::send_text);
+    cx.add_action(TerminalView::send_keystroke);
     cx.add_action(TerminalView::deploy_context_menu);
     cx.add_action(TerminalView::copy);
     cx.add_action(TerminalView::paste);
@@ -283,44 +290,26 @@ impl TerminalView {
         }
     }
 
-    ///Synthesize the keyboard event corresponding to 'up'
-    fn up(&mut self, _: &Up, cx: &mut ViewContext<Self>) {
-        self.clear_bel(cx);
-        self.terminal.update(cx, |term, _| {
-            term.try_keystroke(&Keystroke::parse("up").unwrap(), false)
-        });
-    }
-
-    ///Synthesize the keyboard event corresponding to 'down'
-    fn down(&mut self, _: &Down, cx: &mut ViewContext<Self>) {
-        self.clear_bel(cx);
-        self.terminal.update(cx, |term, _| {
-            term.try_keystroke(&Keystroke::parse("down").unwrap(), false)
-        });
-    }
-
-    ///Synthesize the keyboard event corresponding to 'ctrl-c'
-    fn ctrl_c(&mut self, _: &CtrlC, cx: &mut ViewContext<Self>) {
-        self.clear_bel(cx);
-        self.terminal.update(cx, |term, _| {
-            term.try_keystroke(&Keystroke::parse("ctrl-c").unwrap(), false)
-        });
-    }
-
-    ///Synthesize the keyboard event corresponding to 'escape'
-    fn escape(&mut self, _: &Escape, cx: &mut ViewContext<Self>) {
+    fn send_text(&mut self, text: &SendText, cx: &mut ViewContext<Self>) {
         self.clear_bel(cx);
         self.terminal.update(cx, |term, _| {
-            term.try_keystroke(&Keystroke::parse("escape").unwrap(), false)
+            term.input(text.0.to_string());
         });
     }
 
-    ///Synthesize the keyboard event corresponding to 'enter'
-    fn enter(&mut self, _: &Enter, cx: &mut ViewContext<Self>) {
-        self.clear_bel(cx);
-        self.terminal.update(cx, |term, _| {
-            term.try_keystroke(&Keystroke::parse("enter").unwrap(), false)
-        });
+    fn send_keystroke(&mut self, text: &SendKeystroke, cx: &mut ViewContext<Self>) {
+        if let Some(keystroke) = Keystroke::parse(&text.0).log_err() {
+            self.clear_bel(cx);
+            self.terminal.update(cx, |term, cx| {
+                term.try_keystroke(
+                    &keystroke,
+                    cx.global::<Settings>()
+                        .terminal_overrides
+                        .option_as_meta
+                        .unwrap_or(false),
+                );
+            });
+        }
     }
 }