WIP

Nathan Sobo created

Change summary

crates/project_panel/src/project_panel.rs  |  2 
crates/settings/src/settings.rs            | 50 +++++++++++++++++++++++
crates/terminal_view/src/terminal_panel.rs | 30 ++++++++++++-
crates/workspace/src/dock.rs               | 10 ++++
crates/workspace/src/item.rs               |  4 
crates/zed/src/zed.rs                      | 13 +----
6 files changed, 92 insertions(+), 17 deletions(-)

Detailed changes

crates/project_panel/src/project_panel.rs 🔗

@@ -1329,7 +1329,7 @@ impl Entity for ProjectPanel {
 
 impl workspace::dock::Panel for ProjectPanel {
     fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
-        todo!()
+        cx.global::<Settings>().project_panel_overrides.dock.into()
     }
 
     fn position_is_valid(&self, position: DockPosition) -> bool {

crates/settings/src/settings.rs 🔗

@@ -44,6 +44,8 @@ pub struct Settings {
     pub show_call_status_icon: bool,
     pub vim_mode: bool,
     pub autosave: Autosave,
+    pub project_panel_defaults: ProjectPanelSettings,
+    pub project_panel_overrides: ProjectPanelSettings,
     pub editor_defaults: EditorSettings,
     pub editor_overrides: EditorSettings,
     pub git: GitSettings,
@@ -129,6 +131,14 @@ impl TelemetrySettings {
     }
 }
 
+#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema)]
+#[serde(rename_all="lowercase")]
+pub enum DockPosition {
+    Left,
+    Right,
+    Bottom,
+}
+
 #[derive(Clone, Debug, Default)]
 pub struct CopilotSettings {
     pub disabled_globs: Vec<glob::Pattern>,
@@ -156,6 +166,19 @@ pub enum GitGutter {
 
 pub struct GitGutterConfig {}
 
+#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
+pub struct ProjectPanelSettings {
+    pub dock: DockPosition
+}
+
+impl Default for ProjectPanelSettings {
+    fn default() -> Self {
+        Self {
+            dock: DockPosition::Left
+        }
+    }
+}
+
 #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
 pub struct EditorSettings {
     pub tab_size: Option<NonZeroU32>,
@@ -237,7 +260,7 @@ impl Default for HourFormat {
     }
 }
 
-#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
+#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
 pub struct TerminalSettings {
     pub shell: Option<Shell>,
     pub working_directory: Option<WorkingDirectory>,
@@ -250,8 +273,29 @@ pub struct TerminalSettings {
     pub alternate_scroll: Option<AlternateScroll>,
     pub option_as_meta: Option<bool>,
     pub copy_on_select: Option<bool>,
+    pub dock: DockPosition,
+}
+
+impl Default for TerminalSettings {
+    fn default() -> Self {
+        Self {
+            shell:Default::default(),
+            working_directory:Default::default(),
+            font_size:Default::default(),
+            font_family:Default::default(),
+            line_height:Default::default(),
+            font_features:Default::default(),
+            env:Default::default(),
+            blinking:Default::default(),
+            alternate_scroll:Default::default(),
+            option_as_meta:Default::default(),
+            copy_on_select:Default::default(),
+            dock: DockPosition::Bottom,
+        }
+    }
 }
 
+
 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
 #[serde(rename_all = "snake_case")]
 pub enum TerminalLineHeight {
@@ -457,6 +501,8 @@ impl Settings {
             show_call_status_icon: defaults.show_call_status_icon.unwrap(),
             vim_mode: defaults.vim_mode.unwrap(),
             autosave: defaults.autosave.unwrap(),
+            project_panel_defaults: Default::default(),
+            project_panel_overrides: Default::default(),
             editor_defaults: EditorSettings {
                 tab_size: required(defaults.editor.tab_size),
                 hard_tabs: required(defaults.editor.hard_tabs),
@@ -750,6 +796,8 @@ impl Settings {
             show_call_status_icon: true,
             vim_mode: false,
             autosave: Autosave::Off,
+            project_panel_defaults: Default::default(),
+            project_panel_overrides: Default::default(),
             editor_defaults: EditorSettings {
                 tab_size: Some(4.try_into().unwrap()),
                 hard_tabs: Some(false),

crates/terminal_view/src/terminal_panel.rs 🔗

@@ -6,7 +6,7 @@ use gpui::{
 use project::Project;
 use settings::{Settings, WorkingDirectory};
 use util::ResultExt;
-use workspace::{dock::Panel, pane, DraggedItem, Pane, Workspace};
+use workspace::{dock::{Panel, DockPosition}, pane, DraggedItem, Pane, Workspace};
 
 pub fn init(cx: &mut AppContext) {
     cx.add_action(TerminalPanel::add_terminal);
@@ -135,8 +135,20 @@ impl View for TerminalPanel {
 }
 
 impl Panel for TerminalPanel {
-    fn should_close_on_event(&self, event: &Event, _: &AppContext) -> bool {
-        matches!(event, Event::Close)
+    fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
+        cx.global::<Settings>().terminal_overrides.dock.into()
+    }
+
+    fn position_is_valid(&self, _: DockPosition) -> bool {
+        true
+    }
+
+    fn icon_path(&self) -> &'static str {
+        "icons/terminal_12.svg"
+    }
+
+    fn icon_tooltip(&self) -> String {
+        "Terminals".to_string()
     }
 
     fn icon_label(&self, cx: &AppContext) -> Option<String> {
@@ -147,4 +159,16 @@ impl Panel for TerminalPanel {
             Some(count.to_string())
         }
     }
+
+    fn should_change_position_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+        todo!()
+    }
+
+    fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool {
+        todo!()
+    }
+
+    fn should_close_on_event(&self, event: &Event, _: &AppContext) -> bool {
+        matches!(event, Event::Close)
+    }
 }

crates/workspace/src/dock.rs 🔗

@@ -92,6 +92,16 @@ pub enum DockPosition {
     Right,
 }
 
+impl From<settings::DockPosition> for DockPosition {
+    fn from(value: settings::DockPosition) -> Self {
+        match value {
+            settings::DockPosition::Left => Self::Left,
+            settings::DockPosition::Bottom => Self::Bottom,
+            settings::DockPosition::Right => Self::Right,
+        }
+    }
+}
+
 impl DockPosition {
     fn to_resizable_side(self) -> Side {
         match self {

crates/workspace/src/item.rs 🔗

@@ -1061,11 +1061,11 @@ pub(crate) mod test {
     }
 
     impl Panel for TestItem {
-        fn position(&self, cx: &gpui::WindowContext) -> crate::dock::DockPosition {
+        fn position(&self, _cx: &gpui::WindowContext) -> crate::dock::DockPosition {
             unimplemented!()
         }
 
-        fn position_is_valid(&self, position: crate::dock::DockPosition) -> bool {
+        fn position_is_valid(&self, _position: crate::dock::DockPosition) -> bool {
             unimplemented!()
         }
 

crates/zed/src/zed.rs 🔗

@@ -311,18 +311,11 @@ pub fn initialize_workspace(
         cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
     workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
 
-    let project_panel = cx.add_view(|cx| ProjectPanel::new(workspace, cx));
-    workspace.add_panel(panel, cx);
+    let project_panel = ProjectPanel::new(workspace, cx);
+    workspace.add_panel(project_panel, cx);
 
     let terminal_panel = cx.add_view(|cx| TerminalPanel::new(workspace, cx));
-    workspace.bottom_dock().update(cx, |dock, cx| {
-        dock.add_panel(
-            "icons/terminal_12.svg",
-            "Terminals".to_string(),
-            terminal_panel,
-            cx,
-        );
-    });
+    workspace.add_panel(terminal_panel, cx);
 
     let copilot = cx.add_view(|cx| copilot_button::CopilotButton::new(cx));
     let diagnostic_summary =