workspace: Add restore_on_startup setting that allows always opening an empty Zed instance (#10366)

Piotr Osiewicz created

Fixes #7694
The new setting accepts "last_workspace" (default) and "none" as
options.

In a follow-up PR I'll add a new option that re-launches all of the Zed
windows and not just the last one.

Release Notes:

- Added `restore_on_startup` option, accepting `last_workspace`
(default) and `none` options. With `none`, new Zed instances will not
restore workspaces that were open last.

Change summary

assets/settings/default.json               |  2 ++
crates/workspace/src/workspace.rs          |  4 +++-
crates/workspace/src/workspace_settings.rs | 15 +++++++++++++++
crates/zed/src/main.rs                     | 12 ++++++++++--
4 files changed, 30 insertions(+), 3 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -58,6 +58,8 @@
   "hover_popover_enabled": true,
   // Whether to confirm before quitting Zed.
   "confirm_quit": false,
+  // Whether to restore last closed project when fresh Zed instance is opened.
+  "restore_on_startup": "last_workspace",
   // Whether the cursor blinks in the editor.
   "cursor_blink": true,
   // Whether to pop the completions menu while typing in an editor without

crates/workspace/src/workspace.rs 🔗

@@ -81,7 +81,9 @@ use ui::{
 };
 use util::ResultExt;
 use uuid::Uuid;
-pub use workspace_settings::{AutosaveSetting, TabBarSettings, WorkspaceSettings};
+pub use workspace_settings::{
+    AutosaveSetting, RestoreOnStartupBehaviour, TabBarSettings, WorkspaceSettings,
+};
 
 use crate::notifications::NotificationId;
 use crate::persistence::{

crates/workspace/src/workspace_settings.rs 🔗

@@ -10,6 +10,17 @@ pub struct WorkspaceSettings {
     pub confirm_quit: bool,
     pub show_call_status_icon: bool,
     pub autosave: AutosaveSetting,
+    pub restore_on_startup: RestoreOnStartupBehaviour,
+}
+
+#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema)]
+#[serde(rename_all = "snake_case")]
+pub enum RestoreOnStartupBehaviour {
+    /// Always start with an empty editor
+    None,
+    /// Restore the workspace that was closed last.
+    #[default]
+    LastWorkspace,
 }
 
 #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
@@ -32,6 +43,10 @@ pub struct WorkspaceSettingsContent {
     ///
     /// Default: off
     pub autosave: Option<AutosaveSetting>,
+    /// Controls previous session restoration in freshly launched Zed instance.
+    /// Values: none, last_workspace
+    /// Default: last_workspace
+    pub restore_on_startup: Option<RestoreOnStartupBehaviour>,
 }
 
 #[derive(Deserialize)]

crates/zed/src/main.rs 🔗

@@ -62,7 +62,7 @@ use util::{
 };
 use uuid::Uuid;
 use welcome::{show_welcome_view, BaseKeymap, FIRST_OPEN};
-use workspace::{AppState, WorkspaceStore};
+use workspace::{AppState, WorkspaceSettings, WorkspaceStore};
 use zed::{
     app_menus, build_window_options, ensure_only_instance, handle_cli_connection,
     handle_keymap_file_changes, initialize_workspace, open_paths_with_positions, IsOnlyInstance,
@@ -504,7 +504,15 @@ async fn installation_id() -> Result<(String, bool)> {
 
 async fn restore_or_create_workspace(app_state: Arc<AppState>, cx: AsyncAppContext) {
     maybe!(async {
-        if let Some(location) = workspace::last_opened_workspace_paths().await {
+        let restore_behaviour =
+            cx.update(|cx| WorkspaceSettings::get(None, cx).restore_on_startup)?;
+        let location = match restore_behaviour {
+            workspace::RestoreOnStartupBehaviour::LastWorkspace => {
+                workspace::last_opened_workspace_paths().await
+            }
+            _ => None,
+        };
+        if let Some(location) = location {
             cx.update(|cx| {
                 workspace::open_paths(
                     location.paths().as_ref(),