mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-01 04:28:57 +00:00
Define workspace settings in workspace crate
This commit is contained in:
parent
cbd4771f10
commit
6403bb86e1
22 changed files with 253 additions and 243 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -8676,6 +8676,7 @@ dependencies = [
|
|||
"parking_lot 0.11.2",
|
||||
"postage",
|
||||
"project",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
|
|
|
@ -6,7 +6,7 @@ use gpui::{
|
|||
platform::{Appearance, MouseButton},
|
||||
AnyElement, AppContext, Element, Entity, View, ViewContext,
|
||||
};
|
||||
use settings::Settings;
|
||||
use workspace::WorkspaceSettings;
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
let active_call = ActiveCall::global(cx);
|
||||
|
@ -15,7 +15,9 @@ pub fn init(cx: &mut AppContext) {
|
|||
cx.observe(&active_call, move |call, cx| {
|
||||
if let Some(room) = call.read(cx).room() {
|
||||
if room.read(cx).is_screen_sharing() {
|
||||
if status_indicator.is_none() && cx.global::<Settings>().show_call_status_icon {
|
||||
if status_indicator.is_none()
|
||||
&& settings::get_setting::<WorkspaceSettings>(None, cx).show_call_status_icon
|
||||
{
|
||||
status_indicator = Some(cx.add_status_bar_item(|_| SharingStatusIndicator));
|
||||
}
|
||||
} else if let Some((window_id, _)) = status_indicator.take() {
|
||||
|
|
|
@ -1499,6 +1499,7 @@ mod tests {
|
|||
cx.set_global(Settings::test(cx));
|
||||
cx.set_global(SettingsStore::test(cx));
|
||||
language::init(cx);
|
||||
workspace::init_settings(cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6685,6 +6685,7 @@ pub(crate) fn init_test(cx: &mut TestAppContext, f: fn(&mut AllLanguageSettingsC
|
|||
language::init(cx);
|
||||
crate::init(cx);
|
||||
Project::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
});
|
||||
|
||||
update_test_settings(cx, f);
|
||||
|
|
|
@ -40,7 +40,7 @@ use language::{
|
|||
Selection,
|
||||
};
|
||||
use project::ProjectPath;
|
||||
use settings::{GitGutter, Settings};
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
|
@ -50,7 +50,7 @@ use std::{
|
|||
ops::Range,
|
||||
sync::Arc,
|
||||
};
|
||||
use workspace::item::Item;
|
||||
use workspace::{item::Item, GitGutterSetting, WorkspaceSettings};
|
||||
|
||||
enum FoldMarkers {}
|
||||
|
||||
|
@ -550,11 +550,11 @@ impl EditorElement {
|
|||
let scroll_top = scroll_position.y() * line_height;
|
||||
|
||||
let show_gutter = matches!(
|
||||
&cx.global::<Settings>()
|
||||
.git_overrides
|
||||
settings::get_setting::<WorkspaceSettings>(None, cx)
|
||||
.git
|
||||
.git_gutter
|
||||
.unwrap_or_default(),
|
||||
GitGutter::TrackedFiles
|
||||
GitGutterSetting::TrackedFiles
|
||||
);
|
||||
|
||||
if show_gutter {
|
||||
|
|
|
@ -41,6 +41,7 @@ impl<'a> EditorLspTestContext<'a> {
|
|||
crate::init(cx);
|
||||
pane::init(cx);
|
||||
Project::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
});
|
||||
|
||||
let file_name = format!(
|
||||
|
|
|
@ -658,6 +658,7 @@ mod tests {
|
|||
language::init(cx);
|
||||
super::init(cx);
|
||||
editor::init(cx);
|
||||
workspace::init_settings(cx);
|
||||
state
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1936,6 +1936,7 @@ mod tests {
|
|||
cx.set_global(SettingsStore::test(cx));
|
||||
language::init(cx);
|
||||
editor::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -375,6 +375,7 @@ mod tests {
|
|||
cx.set_global(SettingsStore::test(cx));
|
||||
language::init(cx);
|
||||
Project::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1288,6 +1288,7 @@ pub mod tests {
|
|||
|
||||
language::init(cx);
|
||||
editor::init_settings(cx);
|
||||
workspace::init_settings(cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ mod keymap_file;
|
|||
mod settings_file;
|
||||
mod settings_store;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::Result;
|
||||
use gpui::{
|
||||
font_cache::{FamilyId, FontCache},
|
||||
fonts, AppContext, AssetSource,
|
||||
|
@ -15,10 +15,6 @@ use schemars::{
|
|||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use sqlez::{
|
||||
bindable::{Bind, Column, StaticColumnCount},
|
||||
statement::Statement,
|
||||
};
|
||||
use std::{borrow::Cow, str, sync::Arc};
|
||||
use theme::{Theme, ThemeRegistry};
|
||||
use util::ResultExt as _;
|
||||
|
@ -37,13 +33,6 @@ pub struct Settings {
|
|||
pub buffer_font_features: fonts::Features,
|
||||
pub buffer_font_family: FamilyId,
|
||||
pub buffer_font_size: f32,
|
||||
pub active_pane_magnification: f32,
|
||||
pub confirm_quit: bool,
|
||||
pub show_call_status_icon: bool,
|
||||
pub autosave: Autosave,
|
||||
pub default_dock_anchor: DockAnchor,
|
||||
pub git: GitSettings,
|
||||
pub git_overrides: GitSettings,
|
||||
pub theme: Arc<Theme>,
|
||||
pub base_keymap: BaseKeymap,
|
||||
}
|
||||
|
@ -72,13 +61,6 @@ impl Setting for Settings {
|
|||
buffer_font_family_name: defaults.buffer_font_family.clone().unwrap(),
|
||||
buffer_font_features,
|
||||
buffer_font_size: defaults.buffer_font_size.unwrap(),
|
||||
active_pane_magnification: defaults.active_pane_magnification.unwrap(),
|
||||
confirm_quit: defaults.confirm_quit.unwrap(),
|
||||
show_call_status_icon: defaults.show_call_status_icon.unwrap(),
|
||||
autosave: defaults.autosave.unwrap(),
|
||||
default_dock_anchor: defaults.default_dock_anchor.unwrap(),
|
||||
git: defaults.git.unwrap(),
|
||||
git_overrides: Default::default(),
|
||||
theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(),
|
||||
base_keymap: Default::default(),
|
||||
};
|
||||
|
@ -201,65 +183,6 @@ impl BaseKeymap {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct GitSettings {
|
||||
pub git_gutter: Option<GitGutter>,
|
||||
pub gutter_debounce: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitGutter {
|
||||
#[default]
|
||||
TrackedFiles,
|
||||
Hide,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Autosave {
|
||||
Off,
|
||||
AfterDelay { milliseconds: u64 },
|
||||
OnFocusChange,
|
||||
OnWindowChange,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DockAnchor {
|
||||
#[default]
|
||||
Bottom,
|
||||
Right,
|
||||
Expanded,
|
||||
}
|
||||
|
||||
impl StaticColumnCount for DockAnchor {}
|
||||
impl Bind for DockAnchor {
|
||||
fn bind(&self, statement: &Statement, start_index: i32) -> anyhow::Result<i32> {
|
||||
match self {
|
||||
DockAnchor::Bottom => "Bottom",
|
||||
DockAnchor::Right => "Right",
|
||||
DockAnchor::Expanded => "Expanded",
|
||||
}
|
||||
.bind(statement, start_index)
|
||||
}
|
||||
}
|
||||
|
||||
impl Column for DockAnchor {
|
||||
fn column(statement: &mut Statement, start_index: i32) -> anyhow::Result<(Self, i32)> {
|
||||
String::column(statement, start_index).and_then(|(anchor_text, next_index)| {
|
||||
Ok((
|
||||
match anchor_text.as_ref() {
|
||||
"Bottom" => DockAnchor::Bottom,
|
||||
"Right" => DockAnchor::Right,
|
||||
"Expanded" => DockAnchor::Expanded,
|
||||
_ => bail!("Stored dock anchor is incorrect"),
|
||||
},
|
||||
next_index,
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct SettingsFileContent {
|
||||
|
@ -270,24 +193,6 @@ pub struct SettingsFileContent {
|
|||
#[serde(default)]
|
||||
pub buffer_font_features: Option<fonts::Features>,
|
||||
#[serde(default)]
|
||||
pub active_pane_magnification: Option<f32>,
|
||||
#[serde(default)]
|
||||
pub cursor_blink: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub confirm_quit: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub hover_popover_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub show_completions_on_input: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub show_call_status_icon: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub autosave: Option<Autosave>,
|
||||
#[serde(default)]
|
||||
pub default_dock_anchor: Option<DockAnchor>,
|
||||
#[serde(default)]
|
||||
pub git: Option<GitSettings>,
|
||||
#[serde(default)]
|
||||
pub theme: Option<String>,
|
||||
#[serde(default)]
|
||||
pub base_keymap: Option<BaseKeymap>,
|
||||
|
@ -323,13 +228,6 @@ impl Settings {
|
|||
buffer_font_family_name: defaults.buffer_font_family.unwrap(),
|
||||
buffer_font_features,
|
||||
buffer_font_size: defaults.buffer_font_size.unwrap(),
|
||||
active_pane_magnification: defaults.active_pane_magnification.unwrap(),
|
||||
confirm_quit: defaults.confirm_quit.unwrap(),
|
||||
show_call_status_icon: defaults.show_call_status_icon.unwrap(),
|
||||
autosave: defaults.autosave.unwrap(),
|
||||
default_dock_anchor: defaults.default_dock_anchor.unwrap(),
|
||||
git: defaults.git.unwrap(),
|
||||
git_overrides: Default::default(),
|
||||
theme: themes.get(&defaults.theme.unwrap()).unwrap(),
|
||||
base_keymap: Default::default(),
|
||||
}
|
||||
|
@ -367,24 +265,7 @@ impl Settings {
|
|||
}
|
||||
|
||||
merge(&mut self.buffer_font_size, data.buffer_font_size);
|
||||
merge(
|
||||
&mut self.active_pane_magnification,
|
||||
data.active_pane_magnification,
|
||||
);
|
||||
merge(&mut self.confirm_quit, data.confirm_quit);
|
||||
merge(&mut self.autosave, data.autosave);
|
||||
merge(&mut self.default_dock_anchor, data.default_dock_anchor);
|
||||
merge(&mut self.base_keymap, data.base_keymap);
|
||||
|
||||
self.git_overrides = data.git.unwrap_or_default();
|
||||
}
|
||||
|
||||
pub fn git_gutter(&self) -> GitGutter {
|
||||
self.git_overrides.git_gutter.unwrap_or_else(|| {
|
||||
self.git
|
||||
.git_gutter
|
||||
.expect("git_gutter should be some by setting setup")
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
@ -397,13 +278,6 @@ impl Settings {
|
|||
.load_family(&["Monaco"], &Default::default())
|
||||
.unwrap(),
|
||||
buffer_font_size: 14.,
|
||||
active_pane_magnification: 1.,
|
||||
confirm_quit: false,
|
||||
show_call_status_icon: true,
|
||||
autosave: Autosave::Off,
|
||||
default_dock_anchor: DockAnchor::Bottom,
|
||||
git: Default::default(),
|
||||
git_overrides: Default::default(),
|
||||
theme: gpui::fonts::with_font_cache(cx.font_cache().clone(), Default::default),
|
||||
base_keymap: Default::default(),
|
||||
}
|
||||
|
|
|
@ -787,22 +787,18 @@ fn get_path_from_wt(wt: &LocalWorktree) -> Option<PathBuf> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use gpui::TestAppContext;
|
||||
use project::{Entry, Project, ProjectPath, Worktree};
|
||||
use std::path::Path;
|
||||
use workspace::AppState;
|
||||
|
||||
use std::path::Path;
|
||||
// Working directory calculation tests
|
||||
|
||||
///Working directory calculation tests
|
||||
|
||||
///No Worktrees in project -> home_dir()
|
||||
// No Worktrees in project -> home_dir()
|
||||
#[gpui::test]
|
||||
async fn no_worktree(cx: &mut TestAppContext) {
|
||||
//Setup variables
|
||||
let (project, workspace) = blank_workspace(cx).await;
|
||||
//Test
|
||||
let (project, workspace) = init_test(cx).await;
|
||||
cx.read(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
let active_entry = project.read(cx).active_entry();
|
||||
|
@ -818,14 +814,12 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
///No active entry, but a worktree, worktree is a file -> home_dir()
|
||||
// No active entry, but a worktree, worktree is a file -> home_dir()
|
||||
#[gpui::test]
|
||||
async fn no_active_entry_worktree_is_file(cx: &mut TestAppContext) {
|
||||
//Setup variables
|
||||
let (project, workspace) = init_test(cx).await;
|
||||
|
||||
let (project, workspace) = blank_workspace(cx).await;
|
||||
create_file_wt(project.clone(), "/root.txt", cx).await;
|
||||
|
||||
cx.read(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
let active_entry = project.read(cx).active_entry();
|
||||
|
@ -841,14 +835,12 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
//No active entry, but a worktree, worktree is a folder -> worktree_folder
|
||||
// No active entry, but a worktree, worktree is a folder -> worktree_folder
|
||||
#[gpui::test]
|
||||
async fn no_active_entry_worktree_is_dir(cx: &mut TestAppContext) {
|
||||
//Setup variables
|
||||
let (project, workspace) = blank_workspace(cx).await;
|
||||
let (_wt, _entry) = create_folder_wt(project.clone(), "/root/", cx).await;
|
||||
let (project, workspace) = init_test(cx).await;
|
||||
|
||||
//Test
|
||||
let (_wt, _entry) = create_folder_wt(project.clone(), "/root/", cx).await;
|
||||
cx.update(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
let active_entry = project.read(cx).active_entry();
|
||||
|
@ -863,17 +855,15 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
//Active entry with a work tree, worktree is a file -> home_dir()
|
||||
// Active entry with a work tree, worktree is a file -> home_dir()
|
||||
#[gpui::test]
|
||||
async fn active_entry_worktree_is_file(cx: &mut TestAppContext) {
|
||||
//Setup variables
|
||||
let (project, workspace) = init_test(cx).await;
|
||||
|
||||
let (project, workspace) = blank_workspace(cx).await;
|
||||
let (_wt, _entry) = create_folder_wt(project.clone(), "/root1/", cx).await;
|
||||
let (wt2, entry2) = create_file_wt(project.clone(), "/root2.txt", cx).await;
|
||||
insert_active_entry_for(wt2, entry2, project.clone(), cx);
|
||||
|
||||
//Test
|
||||
cx.update(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
let active_entry = project.read(cx).active_entry();
|
||||
|
@ -887,16 +877,15 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
//Active entry, with a worktree, worktree is a folder -> worktree_folder
|
||||
// Active entry, with a worktree, worktree is a folder -> worktree_folder
|
||||
#[gpui::test]
|
||||
async fn active_entry_worktree_is_dir(cx: &mut TestAppContext) {
|
||||
//Setup variables
|
||||
let (project, workspace) = blank_workspace(cx).await;
|
||||
let (project, workspace) = init_test(cx).await;
|
||||
|
||||
let (_wt, _entry) = create_folder_wt(project.clone(), "/root1/", cx).await;
|
||||
let (wt2, entry2) = create_folder_wt(project.clone(), "/root2/", cx).await;
|
||||
insert_active_entry_for(wt2, entry2, project.clone(), cx);
|
||||
|
||||
//Test
|
||||
cx.update(|cx| {
|
||||
let workspace = workspace.read(cx);
|
||||
let active_entry = project.read(cx).active_entry();
|
||||
|
@ -910,8 +899,8 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
///Creates a worktree with 1 file: /root.txt
|
||||
pub async fn blank_workspace(
|
||||
/// Creates a worktree with 1 file: /root.txt
|
||||
pub async fn init_test(
|
||||
cx: &mut TestAppContext,
|
||||
) -> (ModelHandle<Project>, ViewHandle<Workspace>) {
|
||||
let params = cx.update(AppState::test);
|
||||
|
@ -922,7 +911,7 @@ mod tests {
|
|||
(project, workspace)
|
||||
}
|
||||
|
||||
///Creates a worktree with 1 folder: /root{suffix}/
|
||||
/// Creates a worktree with 1 folder: /root{suffix}/
|
||||
async fn create_folder_wt(
|
||||
project: ModelHandle<Project>,
|
||||
path: impl AsRef<Path>,
|
||||
|
@ -931,7 +920,7 @@ mod tests {
|
|||
create_wt(project, true, path, cx).await
|
||||
}
|
||||
|
||||
///Creates a worktree with 1 file: /root{suffix}.txt
|
||||
/// Creates a worktree with 1 file: /root{suffix}.txt
|
||||
async fn create_file_wt(
|
||||
project: ModelHandle<Project>,
|
||||
path: impl AsRef<Path>,
|
||||
|
|
|
@ -45,6 +45,7 @@ lazy_static.workspace = true
|
|||
log.workspace = true
|
||||
parking_lot.workspace = true
|
||||
postage.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
mod toggle_dock_button;
|
||||
|
||||
use crate::{
|
||||
sidebar::SidebarSide, BackgroundActions, DockAnchor, ItemHandle, Pane, Workspace,
|
||||
WorkspaceSettings,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use gpui::{
|
||||
actions,
|
||||
|
@ -8,10 +12,7 @@ use gpui::{
|
|||
platform::{CursorStyle, MouseButton},
|
||||
AnyElement, AppContext, Border, Element, SizeConstraint, ViewContext, ViewHandle,
|
||||
};
|
||||
use settings::{DockAnchor, Settings};
|
||||
use theme::Theme;
|
||||
|
||||
use crate::{sidebar::SidebarSide, BackgroundActions, ItemHandle, Pane, Workspace};
|
||||
pub use toggle_dock_button::ToggleDockButton;
|
||||
|
||||
actions!(
|
||||
|
@ -171,7 +172,9 @@ impl Dock {
|
|||
background_actions: BackgroundActions,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Self {
|
||||
let position = DockPosition::Hidden(cx.global::<Settings>().default_dock_anchor);
|
||||
let position = DockPosition::Hidden(
|
||||
settings::get_setting::<WorkspaceSettings>(None, cx).default_dock_anchor,
|
||||
);
|
||||
let workspace = cx.weak_handle();
|
||||
let pane =
|
||||
cx.add_view(|cx| Pane::new(workspace, Some(position.anchor()), background_actions, cx));
|
||||
|
@ -405,7 +408,6 @@ mod tests {
|
|||
|
||||
use gpui::{AppContext, BorrowWindowContext, TestAppContext, ViewContext, WindowContext};
|
||||
use project::{FakeFs, Project};
|
||||
use settings::Settings;
|
||||
use theme::ThemeRegistry;
|
||||
|
||||
use super::*;
|
||||
|
@ -417,6 +419,7 @@ mod tests {
|
|||
},
|
||||
register_deserializable_item,
|
||||
sidebar::Sidebar,
|
||||
tests::init_test,
|
||||
AppState, ItemHandle, Workspace,
|
||||
};
|
||||
|
||||
|
@ -429,8 +432,7 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_dock_workspace_infinite_loop(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
|
||||
cx.update(|cx| {
|
||||
register_deserializable_item::<item::test::TestItem>(cx);
|
||||
|
@ -598,7 +600,7 @@ mod tests {
|
|||
|
||||
impl<'a> DockTestContext<'a> {
|
||||
pub async fn new(cx: &'a mut TestAppContext) -> DockTestContext<'a> {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
cx.update(|cx| init(cx));
|
||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
|||
FollowableItemBuilders, ItemNavHistory, Pane, ToolbarItemLocation, ViewId, Workspace,
|
||||
WorkspaceId,
|
||||
};
|
||||
use crate::{AutosaveSetting, WorkspaceSettings};
|
||||
use anyhow::Result;
|
||||
use client::{proto, Client};
|
||||
use gpui::{
|
||||
|
@ -10,7 +11,6 @@ use gpui::{
|
|||
ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
||||
};
|
||||
use project::{Project, ProjectEntryId, ProjectPath};
|
||||
use settings::{Autosave, Settings};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
|
@ -450,8 +450,11 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
|||
}
|
||||
|
||||
ItemEvent::Edit => {
|
||||
if let Autosave::AfterDelay { milliseconds } =
|
||||
cx.global::<Settings>().autosave
|
||||
let settings = settings::get_setting::<WorkspaceSettings>(None, cx);
|
||||
let debounce_delay = settings.git.gutter_debounce;
|
||||
|
||||
if let AutosaveSetting::AfterDelay { milliseconds } =
|
||||
settings.autosave
|
||||
{
|
||||
let delay = Duration::from_millis(milliseconds);
|
||||
let item = item.clone();
|
||||
|
@ -460,9 +463,6 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
|||
});
|
||||
}
|
||||
|
||||
let settings = cx.global::<Settings>();
|
||||
let debounce_delay = settings.git_overrides.gutter_debounce;
|
||||
|
||||
let item = item.clone();
|
||||
|
||||
if let Some(delay) = debounce_delay {
|
||||
|
@ -500,7 +500,10 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
|||
}));
|
||||
|
||||
cx.observe_focus(self, move |workspace, item, focused, cx| {
|
||||
if !focused && cx.global::<Settings>().autosave == Autosave::OnFocusChange {
|
||||
if !focused
|
||||
&& settings::get_setting::<WorkspaceSettings>(None, cx).autosave
|
||||
== AutosaveSetting::OnFocusChange
|
||||
{
|
||||
Pane::autosave_item(&item, workspace.project.clone(), cx)
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@ use crate::{
|
|||
dock::{icon_for_dock_anchor, AnchorDockBottom, AnchorDockRight, Dock, ExpandDock},
|
||||
item::WeakItemHandle,
|
||||
toolbar::Toolbar,
|
||||
Item, NewFile, NewSearch, NewTerminal, Workspace,
|
||||
AutosaveSetting, DockAnchor, Item, NewFile, NewSearch, NewTerminal, Workspace,
|
||||
WorkspaceSettings,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
|
@ -29,7 +30,7 @@ use gpui::{
|
|||
};
|
||||
use project::{Project, ProjectEntryId, ProjectPath};
|
||||
use serde::Deserialize;
|
||||
use settings::{Autosave, DockAnchor, Settings};
|
||||
use settings::Settings;
|
||||
use std::{any::Any, cell::RefCell, cmp, mem, path::Path, rc::Rc};
|
||||
use theme::Theme;
|
||||
use util::ResultExt;
|
||||
|
@ -1024,8 +1025,8 @@ impl Pane {
|
|||
} else if is_dirty && (can_save || is_singleton) {
|
||||
let will_autosave = cx.read(|cx| {
|
||||
matches!(
|
||||
cx.global::<Settings>().autosave,
|
||||
Autosave::OnFocusChange | Autosave::OnWindowChange
|
||||
settings::get_setting::<WorkspaceSettings>(None, cx).autosave,
|
||||
AutosaveSetting::OnFocusChange | AutosaveSetting::OnWindowChange
|
||||
) && Self::can_autosave_item(&*item, cx)
|
||||
});
|
||||
let should_save = if should_prompt_for_save && !will_autosave {
|
||||
|
@ -2087,10 +2088,11 @@ mod tests {
|
|||
use crate::item::test::{TestItem, TestProjectItem};
|
||||
use gpui::{executor::Deterministic, TestAppContext};
|
||||
use project::FakeFs;
|
||||
use settings::SettingsStore;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_remove_active_empty(cx: &mut TestAppContext) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2104,7 +2106,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
async fn test_add_item_with_new_item(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2192,7 +2194,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
async fn test_add_item_with_existing_item(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2268,7 +2270,7 @@ mod tests {
|
|||
#[gpui::test]
|
||||
async fn test_add_item_with_same_project_entries(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2377,7 +2379,7 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_remove_item_ordering(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2424,7 +2426,7 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_close_inactive_items(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2443,7 +2445,7 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_close_clean_items(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2470,7 +2472,7 @@ mod tests {
|
|||
deterministic: Arc<Deterministic>,
|
||||
cx: &mut TestAppContext,
|
||||
) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2492,7 +2494,7 @@ mod tests {
|
|||
deterministic: Arc<Deterministic>,
|
||||
cx: &mut TestAppContext,
|
||||
) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2511,7 +2513,7 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_close_all_items(deterministic: Arc<Deterministic>, cx: &mut TestAppContext) {
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -2531,6 +2533,14 @@ mod tests {
|
|||
assert_item_labels(&pane, [], cx);
|
||||
}
|
||||
|
||||
fn init_test(cx: &mut TestAppContext) {
|
||||
cx.update(|cx| {
|
||||
cx.set_global(SettingsStore::test(cx));
|
||||
cx.set_global(settings::Settings::test(cx));
|
||||
crate::init_settings(cx);
|
||||
});
|
||||
}
|
||||
|
||||
fn add_labeled_item(
|
||||
workspace: &ViewHandle<Workspace>,
|
||||
pane: &ViewHandle<Pane>,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{AppState, FollowerStatesByLeader, Pane, Workspace};
|
||||
use crate::{AppState, FollowerStatesByLeader, Pane, Workspace, WorkspaceSettings};
|
||||
use anyhow::{anyhow, Result};
|
||||
use call::{ActiveCall, ParticipantLocation};
|
||||
use gpui::{
|
||||
|
@ -11,7 +11,6 @@ use gpui::{
|
|||
};
|
||||
use project::Project;
|
||||
use serde::Deserialize;
|
||||
use settings::Settings;
|
||||
use theme::Theme;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -380,7 +379,8 @@ impl PaneAxis {
|
|||
.with_children(self.members.iter().enumerate().map(|(ix, member)| {
|
||||
let mut flex = 1.0;
|
||||
if member.contains(active_pane) {
|
||||
flex = cx.global::<Settings>().active_pane_magnification;
|
||||
flex = settings::get_setting::<WorkspaceSettings>(None, cx)
|
||||
.active_pane_magnification;
|
||||
}
|
||||
|
||||
let mut member = member.render(
|
||||
|
|
|
@ -497,13 +497,10 @@ impl WorkspaceDb {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use db::open_test_db;
|
||||
use settings::DockAnchor;
|
||||
|
||||
use super::*;
|
||||
use crate::DockAnchor;
|
||||
use db::open_test_db;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_next_id_stability() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{
|
||||
dock::DockPosition, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId,
|
||||
dock::DockPosition, DockAnchor, ItemDeserializers, Member, Pane, PaneAxis, Workspace,
|
||||
WorkspaceId,
|
||||
};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_recursion::async_recursion;
|
||||
|
@ -11,7 +12,6 @@ use gpui::{
|
|||
platform::WindowBounds, AsyncAppContext, Axis, ModelHandle, Task, ViewHandle, WeakViewHandle,
|
||||
};
|
||||
use project::Project;
|
||||
use settings::DockAnchor;
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
|
@ -305,10 +305,9 @@ impl Column for DockPosition {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use db::sqlez::connection::Connection;
|
||||
use settings::DockAnchor;
|
||||
|
||||
use super::WorkspaceLocation;
|
||||
use crate::DockAnchor;
|
||||
use db::sqlez::connection::Connection;
|
||||
|
||||
#[test]
|
||||
fn test_workspace_round_trips() {
|
||||
|
|
|
@ -13,6 +13,7 @@ pub mod shared_screen;
|
|||
pub mod sidebar;
|
||||
mod status_bar;
|
||||
mod toolbar;
|
||||
mod workspace_settings;
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use assets::Assets;
|
||||
|
@ -75,7 +76,7 @@ pub use persistence::{
|
|||
use postage::prelude::Stream;
|
||||
use project::{Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId};
|
||||
use serde::Deserialize;
|
||||
use settings::{Autosave, DockAnchor, Settings};
|
||||
use settings::Settings;
|
||||
use shared_screen::SharedScreen;
|
||||
use sidebar::{Sidebar, SidebarButtons, SidebarSide, ToggleSidebarItem};
|
||||
use status_bar::StatusBar;
|
||||
|
@ -83,6 +84,7 @@ pub use status_bar::StatusItemView;
|
|||
use theme::{Theme, ThemeRegistry};
|
||||
pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
||||
use util::{paths, ResultExt};
|
||||
pub use workspace_settings::{AutosaveSetting, DockAnchor, GitGutterSetting, WorkspaceSettings};
|
||||
|
||||
lazy_static! {
|
||||
static ref ZED_WINDOW_SIZE: Option<Vector2F> = env::var("ZED_WINDOW_SIZE")
|
||||
|
@ -183,7 +185,12 @@ pub type WorkspaceId = i64;
|
|||
|
||||
impl_actions!(workspace, [ActivatePane]);
|
||||
|
||||
pub fn init_settings(cx: &mut AppContext) {
|
||||
settings::register_setting::<WorkspaceSettings>(cx);
|
||||
}
|
||||
|
||||
pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
||||
init_settings(cx);
|
||||
pane::init(cx);
|
||||
dock::init(cx);
|
||||
notifications::init(cx);
|
||||
|
@ -384,6 +391,7 @@ impl AppState {
|
|||
let themes = ThemeRegistry::new((), cx.font_cache().clone());
|
||||
|
||||
client::init(&client, cx);
|
||||
crate::init_settings(cx);
|
||||
|
||||
Arc::new(Self {
|
||||
client,
|
||||
|
@ -672,7 +680,9 @@ impl Workspace {
|
|||
Self::load_from_serialized_workspace(weak_handle, serialized_workspace, cx)
|
||||
});
|
||||
} else if project.read(cx).is_local() {
|
||||
if cx.global::<Settings>().default_dock_anchor != DockAnchor::Expanded {
|
||||
if settings::get_setting::<WorkspaceSettings>(None, cx).default_dock_anchor
|
||||
!= DockAnchor::Expanded
|
||||
{
|
||||
Dock::show(&mut this, false, cx);
|
||||
}
|
||||
}
|
||||
|
@ -2406,8 +2416,8 @@ impl Workspace {
|
|||
item.workspace_deactivated(cx);
|
||||
}
|
||||
if matches!(
|
||||
cx.global::<Settings>().autosave,
|
||||
Autosave::OnWindowChange | Autosave::OnFocusChange
|
||||
settings::get_setting::<WorkspaceSettings>(None, cx).autosave,
|
||||
AutosaveSetting::OnWindowChange | AutosaveSetting::OnFocusChange
|
||||
) {
|
||||
for item in pane.items() {
|
||||
Pane::autosave_item(item.as_ref(), self.project.clone(), cx)
|
||||
|
@ -3067,7 +3077,7 @@ pub fn join_remote_project(
|
|||
}
|
||||
|
||||
pub fn restart(_: &Restart, cx: &mut AppContext) {
|
||||
let should_confirm = cx.global::<Settings>().confirm_quit;
|
||||
let should_confirm = settings::get_setting::<WorkspaceSettings>(None, cx).confirm_quit;
|
||||
cx.spawn(|mut cx| async move {
|
||||
let mut workspaces = cx
|
||||
.window_ids()
|
||||
|
@ -3128,20 +3138,18 @@ fn parse_pixel_position_env_var(value: &str) -> Option<Vector2F> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::item::test::{TestItem, TestItemEvent, TestProjectItem};
|
||||
|
||||
use super::*;
|
||||
use crate::item::test::{TestItem, TestItemEvent, TestProjectItem};
|
||||
use fs::FakeFs;
|
||||
use gpui::{executor::Deterministic, TestAppContext};
|
||||
use project::{Project, ProjectEntryId};
|
||||
use serde_json::json;
|
||||
use settings::SettingsStore;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_tab_disambiguation(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
|
@ -3189,8 +3197,8 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_tracking_active_path(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
fs.insert_tree(
|
||||
"/root1",
|
||||
|
@ -3293,8 +3301,8 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_close_window(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
fs.insert_tree("/root", json!({ "one": "" })).await;
|
||||
|
||||
|
@ -3329,8 +3337,8 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_close_pane_items(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, None, cx).await;
|
||||
|
@ -3436,8 +3444,8 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_prompting_to_save_only_on_last_item_for_entry(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
|
@ -3542,9 +3550,8 @@ mod tests {
|
|||
|
||||
#[gpui::test]
|
||||
async fn test_autosave(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppContext) {
|
||||
deterministic.forbid_parking();
|
||||
init_test(cx);
|
||||
|
||||
Settings::test_async(cx);
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
|
@ -3560,8 +3567,10 @@ mod tests {
|
|||
|
||||
// Autosave on window change.
|
||||
item.update(cx, |item, cx| {
|
||||
cx.update_global(|settings: &mut Settings, _| {
|
||||
settings.autosave = Autosave::OnWindowChange;
|
||||
cx.update_global(|settings: &mut SettingsStore, cx| {
|
||||
settings.update_user_settings::<WorkspaceSettings>(cx, |settings| {
|
||||
settings.autosave = Some(AutosaveSetting::OnWindowChange);
|
||||
})
|
||||
});
|
||||
item.is_dirty = true;
|
||||
});
|
||||
|
@ -3574,8 +3583,10 @@ mod tests {
|
|||
// Autosave on focus change.
|
||||
item.update(cx, |item, cx| {
|
||||
cx.focus_self();
|
||||
cx.update_global(|settings: &mut Settings, _| {
|
||||
settings.autosave = Autosave::OnFocusChange;
|
||||
cx.update_global(|settings: &mut SettingsStore, cx| {
|
||||
settings.update_user_settings::<WorkspaceSettings>(cx, |settings| {
|
||||
settings.autosave = Some(AutosaveSetting::OnFocusChange);
|
||||
})
|
||||
});
|
||||
item.is_dirty = true;
|
||||
});
|
||||
|
@ -3598,8 +3609,10 @@ mod tests {
|
|||
|
||||
// Autosave after delay.
|
||||
item.update(cx, |item, cx| {
|
||||
cx.update_global(|settings: &mut Settings, _| {
|
||||
settings.autosave = Autosave::AfterDelay { milliseconds: 500 };
|
||||
cx.update_global(|settings: &mut SettingsStore, cx| {
|
||||
settings.update_user_settings::<WorkspaceSettings>(cx, |settings| {
|
||||
settings.autosave = Some(AutosaveSetting::AfterDelay { milliseconds: 500 });
|
||||
})
|
||||
});
|
||||
item.is_dirty = true;
|
||||
cx.emit(TestItemEvent::Edit);
|
||||
|
@ -3615,8 +3628,10 @@ mod tests {
|
|||
|
||||
// Autosave on focus change, ensuring closing the tab counts as such.
|
||||
item.update(cx, |item, cx| {
|
||||
cx.update_global(|settings: &mut Settings, _| {
|
||||
settings.autosave = Autosave::OnFocusChange;
|
||||
cx.update_global(|settings: &mut SettingsStore, cx| {
|
||||
settings.update_user_settings::<WorkspaceSettings>(cx, |settings| {
|
||||
settings.autosave = Some(AutosaveSetting::OnFocusChange);
|
||||
})
|
||||
});
|
||||
item.is_dirty = true;
|
||||
});
|
||||
|
@ -3656,12 +3671,9 @@ mod tests {
|
|||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_pane_navigation(
|
||||
deterministic: Arc<Deterministic>,
|
||||
cx: &mut gpui::TestAppContext,
|
||||
) {
|
||||
deterministic.forbid_parking();
|
||||
Settings::test_async(cx);
|
||||
async fn test_pane_navigation(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
|
@ -3713,4 +3725,14 @@ mod tests {
|
|||
assert!(pane.can_navigate_forward());
|
||||
});
|
||||
}
|
||||
|
||||
pub fn init_test(cx: &mut TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
cx.update(|cx| {
|
||||
cx.set_global(SettingsStore::test(cx));
|
||||
cx.set_global(Settings::test(cx));
|
||||
language::init(cx);
|
||||
crate::init_settings(cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
103
crates/workspace/src/workspace_settings.rs
Normal file
103
crates/workspace/src/workspace_settings.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
use anyhow::bail;
|
||||
use db::sqlez::{
|
||||
bindable::{Bind, Column, StaticColumnCount},
|
||||
statement::Statement,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::Setting;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct WorkspaceSettings {
|
||||
pub active_pane_magnification: f32,
|
||||
pub confirm_quit: bool,
|
||||
pub show_call_status_icon: bool,
|
||||
pub autosave: AutosaveSetting,
|
||||
pub default_dock_anchor: DockAnchor,
|
||||
pub git: GitSettings,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct WorkspaceSettingsContent {
|
||||
pub active_pane_magnification: Option<f32>,
|
||||
pub confirm_quit: Option<bool>,
|
||||
pub show_call_status_icon: Option<bool>,
|
||||
pub autosave: Option<AutosaveSetting>,
|
||||
pub default_dock_anchor: Option<DockAnchor>,
|
||||
pub git: Option<GitSettings>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AutosaveSetting {
|
||||
Off,
|
||||
AfterDelay { milliseconds: u64 },
|
||||
OnFocusChange,
|
||||
OnWindowChange,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Default, Copy, Clone, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DockAnchor {
|
||||
#[default]
|
||||
Bottom,
|
||||
Right,
|
||||
Expanded,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct GitSettings {
|
||||
pub git_gutter: Option<GitGutterSetting>,
|
||||
pub gutter_debounce: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitGutterSetting {
|
||||
#[default]
|
||||
TrackedFiles,
|
||||
Hide,
|
||||
}
|
||||
|
||||
impl StaticColumnCount for DockAnchor {}
|
||||
|
||||
impl Bind for DockAnchor {
|
||||
fn bind(&self, statement: &Statement, start_index: i32) -> anyhow::Result<i32> {
|
||||
match self {
|
||||
DockAnchor::Bottom => "Bottom",
|
||||
DockAnchor::Right => "Right",
|
||||
DockAnchor::Expanded => "Expanded",
|
||||
}
|
||||
.bind(statement, start_index)
|
||||
}
|
||||
}
|
||||
|
||||
impl Column for DockAnchor {
|
||||
fn column(statement: &mut Statement, start_index: i32) -> anyhow::Result<(Self, i32)> {
|
||||
String::column(statement, start_index).and_then(|(anchor_text, next_index)| {
|
||||
Ok((
|
||||
match anchor_text.as_ref() {
|
||||
"Bottom" => DockAnchor::Bottom,
|
||||
"Right" => DockAnchor::Right,
|
||||
"Expanded" => DockAnchor::Expanded,
|
||||
_ => bail!("Stored dock anchor is incorrect"),
|
||||
},
|
||||
next_index,
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Setting for WorkspaceSettings {
|
||||
const KEY: Option<&'static str> = None;
|
||||
|
||||
type FileContent = WorkspaceSettingsContent;
|
||||
|
||||
fn load(
|
||||
default_value: &Self::FileContent,
|
||||
user_values: &[&Self::FileContent],
|
||||
_: &gpui::AppContext,
|
||||
) -> anyhow::Result<Self> {
|
||||
Self::load_via_json_merge(default_value, user_values)
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ use uuid::Uuid;
|
|||
pub use workspace;
|
||||
use workspace::{
|
||||
create_and_open_local_file, open_new, sidebar::SidebarSide, AppState, NewFile, NewWindow,
|
||||
Workspace,
|
||||
Workspace, WorkspaceSettings,
|
||||
};
|
||||
|
||||
#[derive(Deserialize, Clone, PartialEq)]
|
||||
|
@ -367,7 +367,7 @@ pub fn build_window_options(
|
|||
}
|
||||
|
||||
fn quit(_: &Quit, cx: &mut gpui::AppContext) {
|
||||
let should_confirm = cx.global::<Settings>().confirm_quit;
|
||||
let should_confirm = settings::get_setting::<WorkspaceSettings>(None, cx).confirm_quit;
|
||||
cx.spawn(|mut cx| async move {
|
||||
let mut workspaces = cx
|
||||
.window_ids()
|
||||
|
|
Loading…
Reference in a new issue