WIP termial implementation. need some way of getting the currently valid workspace ID

Mikayla Maki created

Change summary

crates/db/Cargo.toml                           |  1 
crates/sqlez/src/lib.rs                        |  2 
crates/sqlez/src/typed_statements.rs           | 54 ++++++++++++++++++++
crates/terminal/src/persistence.rs             | 46 +++++-----------
crates/terminal/src/terminal.rs                | 26 +++------
crates/terminal/src/terminal_container_view.rs | 10 +--
6 files changed, 84 insertions(+), 55 deletions(-)

Detailed changes

crates/db/Cargo.toml 🔗

@@ -23,7 +23,6 @@ log = { version = "0.4.16", features = ["kv_unstable_serde"] }
 parking_lot = "0.11.1"
 serde = { version = "1.0", features = ["derive"] }
 
-
 [dev-dependencies]
 gpui = { path = "../gpui", features = ["test-support"] }
 tempdir = { version = "0.3.7" }

crates/sqlez/src/typed_statements.rs 🔗

@@ -52,3 +52,57 @@ impl Connection {
         Ok(move |bindings| statement.with_bindings(bindings)?.maybe_row::<C>())
     }
 }
+
+#[macro_export]
+macro_rules! exec_method {
+    ($id:ident(): $sql:literal) => {
+         pub fn $id(&self) -> $crate::anyhow::Result<()> {
+             iife!({
+                 self.exec($sql)?()
+             })
+         }
+    };
+    ($id:ident($($arg:ident: $arg_type:ty),+): $sql:literal) => {
+         pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<()> {
+             iife!({
+                 self.exec_bound::<($($arg_type),+)>($sql)?(($($arg),+))
+             })
+         }
+    };
+}
+
+#[macro_export]
+macro_rules! select_method {
+    ($id:ident() ->  $return_type:ty: $sql:literal) => {
+         pub fn $id(&self) -> $crate::anyhow::Result<Vec<$return_type>> {
+             iife!({
+                 self.select::<$return_type>($sql)?(())
+             })
+         }
+    };
+    ($id:ident($($arg:ident: $arg_type:ty),+) -> $return_type:ty: $sql:literal) => {
+         pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<Vec<$return_type>> {
+             iife!({
+                 self.exec_bound::<($($arg_type),+), $return_type>($sql)?(($($arg),+))
+             })
+         }
+    };
+}
+
+#[macro_export]
+macro_rules! select_row_method {
+    ($id:ident() ->  $return_type:ty: $sql:literal) => {
+         pub fn $id(&self) -> $crate::anyhow::Result<Option<$return_type>> {
+             iife!({
+                 self.select_row::<$return_type>($sql)?(())
+             })
+         }
+    };
+    ($id:ident($($arg:ident: $arg_type:ty),+) ->  $return_type:ty: $sql:literal) => {
+         pub fn $id(&self, $($arg: $arg_type),+) -> $crate::anyhow::Result<Option<$return_type>>  {
+             iife!({
+                 self.select_row_bound::<($($arg_type),+), $return_type>($sql)?(($($arg),+))
+             })
+         }
+    };
+}

crates/terminal/src/persistence.rs 🔗

@@ -1,7 +1,10 @@
 use std::path::{Path, PathBuf};
 
-use db::{connection, indoc, sqlez::domain::Domain};
-use util::{iife, ResultExt};
+use db::{
+    connection, indoc,
+    sqlez::{domain::Domain, exec_method, select_row_method},
+};
+use util::iife;
 use workspace::{ItemId, Workspace, WorkspaceId};
 
 use crate::Terminal;
@@ -29,33 +32,16 @@ impl Domain for Terminal {
 }
 
 impl TerminalDb {
-    pub fn save_working_directory(
-        &self,
-        item_id: ItemId,
-        workspace_id: &WorkspaceId,
-        working_directory: &Path,
-    ) {
-        iife!({
-            self.exec_bound::<(ItemId, &WorkspaceId, &Path)>(indoc! {"
-                INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory) 
-                VALUES (?, ?, ?)  
-            "})?((item_id, workspace_id, working_directory))
-        })
-        .log_err();
-    }
+    exec_method!(
+        save_working_directory(item_id: ItemId, workspace_id: &WorkspaceId, working_directory: &Path):
+            "INSERT OR REPLACE INTO terminals(item_id, workspace_id, working_directory)
+             VALUES (?, ?, ?)"
+    );
 
-    pub fn get_working_directory(
-        &self,
-        item_id: ItemId,
-        workspace_id: &WorkspaceId,
-    ) -> Option<PathBuf> {
-        iife!({
-            self.select_row_bound::<(ItemId, &WorkspaceId), PathBuf>(indoc! {"
-            SELECT working_directory 
-            FROM terminals 
-            WHERE item_id = ? workspace_id = ?"})?((item_id, workspace_id))
-        })
-        .log_err()
-        .flatten()
-    }
+    select_row_method!(
+        get_working_directory(item_id: ItemId, workspace_id: &WorkspaceId) -> PathBuf:
+            "SELECT working_directory
+             FROM terminals 
+             WHERE item_id = ? workspace_id = ?"
+    );
 }

crates/terminal/src/terminal.rs 🔗

@@ -33,11 +33,9 @@ use mappings::mouse::{
     alt_scroll, grid_point, mouse_button_report, mouse_moved_report, mouse_side, scroll_report,
 };
 
-use persistence::TERMINAL_CONNECTION;
 use procinfo::LocalProcessInfo;
 use settings::{AlternateScroll, Settings, Shell, TerminalBlink};
 use util::ResultExt;
-use workspace::{ItemId, WorkspaceId};
 
 use std::{
     cmp::min,
@@ -284,8 +282,6 @@ impl TerminalBuilder {
         blink_settings: Option<TerminalBlink>,
         alternate_scroll: &AlternateScroll,
         window_id: usize,
-        item_id: ItemId,
-        workspace_id: WorkspaceId,
     ) -> Result<TerminalBuilder> {
         let pty_config = {
             let alac_shell = shell.clone().and_then(|shell| match shell {
@@ -390,8 +386,6 @@ impl TerminalBuilder {
             last_mouse_position: None,
             next_link_id: 0,
             selection_phase: SelectionPhase::Ended,
-            workspace_id,
-            item_id,
         };
 
         Ok(TerminalBuilder {
@@ -535,8 +529,6 @@ pub struct Terminal {
     scroll_px: f32,
     next_link_id: usize,
     selection_phase: SelectionPhase,
-    item_id: ItemId,
-    workspace_id: WorkspaceId,
 }
 
 impl Terminal {
@@ -578,15 +570,15 @@ impl Terminal {
                 if self.update_process_info() {
                     cx.emit(Event::TitleChanged);
 
-                    if let Some(foreground_info) = self.foreground_process_info {
-                        cx.background().spawn(async move {
-                            TERMINAL_CONNECTION.save_working_directory(
-                                self.item_id,
-                                &self.workspace_id,
-                                &foreground_info.cwd,
-                            );
-                        });
-                    }
+                    // if let Some(foreground_info) = self.foreground_process_info {
+                    // cx.background().spawn(async move {
+                    //     TERMINAL_CONNECTION.save_working_directory(
+                    //         self.item_id,
+                    //         &self.workspace_id,
+                    //         &foreground_info.cwd,
+                    //     );
+                    // });
+                    // }
                 }
             }
             AlacTermEvent::ColorRequest(idx, fun_ptr) => {

crates/terminal/src/terminal_container_view.rs 🔗

@@ -8,13 +8,13 @@ use gpui::{
     actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MutableAppContext, Task,
     View, ViewContext, ViewHandle, WeakViewHandle,
 };
-use util::truncate_and_trailoff;
+use util::{truncate_and_trailoff, ResultExt};
 use workspace::searchable::{SearchEvent, SearchOptions, SearchableItem, SearchableItemHandle};
 use workspace::{
     item::{Item, ItemEvent},
     ToolbarItemLocation, Workspace,
 };
-use workspace::{register_deserializable_item, ItemId, Pane, WorkspaceId};
+use workspace::{register_deserializable_item, Pane};
 
 use project::{LocalWorktree, Project, ProjectPath};
 use settings::{AlternateScroll, Settings, WorkingDirectory};
@@ -90,8 +90,6 @@ impl TerminalContainer {
     pub fn new(
         working_directory: Option<PathBuf>,
         modal: bool,
-        item_id: ItemId,
-        workspace_id: WorkspaceId,
         cx: &mut ViewContext<Self>,
     ) -> Self {
         let settings = cx.global::<Settings>();
@@ -118,8 +116,6 @@ impl TerminalContainer {
             settings.terminal_overrides.blinking.clone(),
             scroll,
             cx.window_id(),
-            item_id,
-            workspace_id,
         ) {
             Ok(terminal) => {
                 let terminal = cx.add_model(|cx| terminal.subscribe(cx));
@@ -397,7 +393,7 @@ impl Item for TerminalContainer {
     ) -> Task<anyhow::Result<ViewHandle<Self>>> {
         let working_directory = TERMINAL_CONNECTION.get_working_directory(item_id, &workspace_id);
         Task::ready(Ok(cx.add_view(|cx| {
-            TerminalContainer::new(working_directory, false, cx)
+            TerminalContainer::new(working_directory.log_err().flatten(), false, cx)
         })))
     }
 }