mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-07 12:25:32 +03:00
Make tests less noisy (#12463)
When running the tests for linux, I found a lot of benign errors getting logged. This PR cuts down some of the noise from unnecessary workspace serialization and SVG renders Release Notes: - N/A
This commit is contained in:
parent
bdf627ce07
commit
5a149b970c
@ -16,9 +16,9 @@ use rust_embed::RustEmbed;
|
||||
pub struct Assets;
|
||||
|
||||
impl AssetSource for Assets {
|
||||
fn load(&self, path: &str) -> Result<std::borrow::Cow<'static, [u8]>> {
|
||||
fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
|
||||
Self::get(path)
|
||||
.map(|f| f.data)
|
||||
.map(|f| Some(f.data))
|
||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||
}
|
||||
|
||||
@ -42,7 +42,10 @@ impl Assets {
|
||||
let mut embedded_fonts = Vec::new();
|
||||
for font_path in font_paths {
|
||||
if font_path.ends_with(".ttf") {
|
||||
let font_bytes = cx.asset_source().load(&font_path)?;
|
||||
let font_bytes = cx
|
||||
.asset_source()
|
||||
.load(&font_path)?
|
||||
.expect("Assets should never return None");
|
||||
embedded_fonts.push(font_bytes);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,12 @@ impl SoundRegistry {
|
||||
}
|
||||
|
||||
let path = format!("sounds/{}.wav", name);
|
||||
let bytes = self.assets.load(&path)?.into_owned();
|
||||
let bytes = self
|
||||
.assets
|
||||
.load(&path)?
|
||||
.map(|asset| Ok(asset))
|
||||
.unwrap_or_else(|| Err(anyhow::anyhow!("No such asset available")))?
|
||||
.into_owned();
|
||||
let cursor = Cursor::new(bytes);
|
||||
let source = Decoder::new(cursor)?.convert_samples::<f32>().buffered();
|
||||
|
||||
|
@ -42,7 +42,7 @@ use std::{
|
||||
},
|
||||
};
|
||||
use text::Point;
|
||||
use workspace::{Workspace, WorkspaceId};
|
||||
use workspace::Workspace;
|
||||
|
||||
#[gpui::test(iterations = 10)]
|
||||
async fn test_host_disconnect(
|
||||
@ -85,14 +85,8 @@ async fn test_host_disconnect(
|
||||
|
||||
assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
|
||||
|
||||
let workspace_b = cx_b.add_window(|cx| {
|
||||
Workspace::new(
|
||||
WorkspaceId::default(),
|
||||
project_b.clone(),
|
||||
client_b.app_state.clone(),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
let workspace_b = cx_b
|
||||
.add_window(|cx| Workspace::new(None, project_b.clone(), client_b.app_state.clone(), cx));
|
||||
let cx_b = &mut VisualTestContext::from_window(*workspace_b, cx_b);
|
||||
let workspace_b_view = workspace_b.root_view(cx_b).unwrap();
|
||||
|
||||
|
@ -42,7 +42,7 @@ use std::{
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
use workspace::{Workspace, WorkspaceId, WorkspaceStore};
|
||||
use workspace::{Workspace, WorkspaceStore};
|
||||
|
||||
pub struct TestServer {
|
||||
pub app_state: Arc<AppState>,
|
||||
@ -906,12 +906,7 @@ impl TestClient {
|
||||
) -> (View<Workspace>, &'a mut VisualTestContext) {
|
||||
cx.add_window_view(|cx| {
|
||||
cx.activate_window();
|
||||
Workspace::new(
|
||||
WorkspaceId::default(),
|
||||
project.clone(),
|
||||
self.app_state.clone(),
|
||||
cx,
|
||||
)
|
||||
Workspace::new(None, project.clone(), self.app_state.clone(), cx)
|
||||
})
|
||||
}
|
||||
|
||||
@ -922,12 +917,7 @@ impl TestClient {
|
||||
let project = self.build_test_project(cx).await;
|
||||
cx.add_window_view(|cx| {
|
||||
cx.activate_window();
|
||||
Workspace::new(
|
||||
WorkspaceId::default(),
|
||||
project.clone(),
|
||||
self.app_state.clone(),
|
||||
cx,
|
||||
)
|
||||
Workspace::new(None, project.clone(), self.app_state.clone(), cx)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,11 @@ impl Item for ChannelView {
|
||||
None
|
||||
}
|
||||
|
||||
fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext<Self>) -> Option<View<Self>> {
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>> {
|
||||
Some(cx.new_view(|cx| {
|
||||
Self::new(
|
||||
self.project.clone(),
|
||||
|
@ -704,7 +704,7 @@ impl Item for ProjectDiagnosticsEditor {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: workspace::WorkspaceId,
|
||||
_workspace_id: Option<workspace::WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
|
@ -484,7 +484,7 @@ pub struct Editor {
|
||||
current_line_highlight: CurrentLineHighlight,
|
||||
collapse_matches: bool,
|
||||
autoindent_mode: Option<AutoindentMode>,
|
||||
workspace: Option<(WeakView<Workspace>, WorkspaceId)>,
|
||||
workspace: Option<(WeakView<Workspace>, Option<WorkspaceId>)>,
|
||||
keymap_context_layers: BTreeMap<TypeId, KeyContext>,
|
||||
input_enabled: bool,
|
||||
use_modal_editing: bool,
|
||||
|
@ -657,7 +657,7 @@ impl Item for Editor {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Editor>>
|
||||
where
|
||||
@ -846,9 +846,12 @@ impl Item for Editor {
|
||||
}
|
||||
|
||||
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
||||
let workspace_id = workspace.database_id();
|
||||
let item_id = cx.view().item_id().as_u64() as ItemId;
|
||||
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
||||
let Some(workspace_id) = workspace.database_id() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let item_id = cx.view().item_id().as_u64() as ItemId;
|
||||
|
||||
fn serialize(
|
||||
buffer: Model<Buffer>,
|
||||
@ -873,7 +876,7 @@ impl Item for Editor {
|
||||
serialize(buffer.clone(), workspace_id, item_id, cx);
|
||||
|
||||
cx.subscribe(&buffer, |this, buffer, event, cx| {
|
||||
if let Some((_, workspace_id)) = this.workspace.as_ref() {
|
||||
if let Some((_, Some(workspace_id))) = this.workspace.as_ref() {
|
||||
if let language::Event::FileHandleChanged = event {
|
||||
serialize(
|
||||
buffer,
|
||||
|
@ -389,7 +389,8 @@ impl Editor {
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
hide_hover(self, cx);
|
||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
||||
let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1);
|
||||
|
||||
self.scroll_manager.set_scroll_position(
|
||||
scroll_position,
|
||||
&display_map,
|
||||
@ -409,7 +410,7 @@ impl Editor {
|
||||
|
||||
pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext<Self>) {
|
||||
hide_hover(self, cx);
|
||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
||||
let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1);
|
||||
let top_row = scroll_anchor
|
||||
.anchor
|
||||
.to_point(&self.buffer().read(cx).snapshot(cx))
|
||||
@ -424,7 +425,7 @@ impl Editor {
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
hide_hover(self, cx);
|
||||
let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1);
|
||||
let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1);
|
||||
let snapshot = &self.buffer().read(cx).snapshot(cx);
|
||||
if !scroll_anchor.anchor.is_valid(snapshot) {
|
||||
log::warn!("Invalid scroll anchor: {:?}", scroll_anchor);
|
||||
|
@ -992,7 +992,7 @@ impl Item for ExtensionsPage {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
_: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>> {
|
||||
None
|
||||
|
@ -38,11 +38,10 @@ impl FileIcons {
|
||||
pub fn new(assets: impl AssetSource) -> Self {
|
||||
assets
|
||||
.load("icons/file_icons/file_types.json")
|
||||
.and_then(|file| {
|
||||
serde_json::from_str::<FileIcons>(str::from_utf8(&file).unwrap())
|
||||
.map_err(Into::into)
|
||||
})
|
||||
.unwrap_or_else(|_| FileIcons {
|
||||
.ok()
|
||||
.flatten()
|
||||
.and_then(|file| serde_json::from_str::<FileIcons>(str::from_utf8(&file).unwrap()).ok())
|
||||
.unwrap_or_else(|| FileIcons {
|
||||
stems: HashMap::default(),
|
||||
suffixes: HashMap::default(),
|
||||
types: HashMap::default(),
|
||||
|
@ -5,8 +5,11 @@ use gpui::*;
|
||||
struct Assets {}
|
||||
|
||||
impl AssetSource for Assets {
|
||||
fn load(&self, path: &str) -> Result<std::borrow::Cow<'static, [u8]>> {
|
||||
std::fs::read(path).map(Into::into).map_err(Into::into)
|
||||
fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
|
||||
std::fs::read(path)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
.map(|result| Some(result))
|
||||
}
|
||||
|
||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{size, DevicePixels, Result, SharedString, Size};
|
||||
use anyhow::anyhow;
|
||||
|
||||
use image::{Bgra, ImageBuffer};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
@ -11,18 +11,15 @@ use std::{
|
||||
/// A source of assets for this app to use.
|
||||
pub trait AssetSource: 'static + Send + Sync {
|
||||
/// Load the given asset from the source path.
|
||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>>;
|
||||
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>>;
|
||||
|
||||
/// List the assets at the given path.
|
||||
fn list(&self, path: &str) -> Result<Vec<SharedString>>;
|
||||
}
|
||||
|
||||
impl AssetSource for () {
|
||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>> {
|
||||
Err(anyhow!(
|
||||
"load called on empty asset provider with \"{}\"",
|
||||
path
|
||||
))
|
||||
fn load(&self, _path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn list(&self, _path: &str) -> Result<Vec<SharedString>> {
|
||||
|
@ -344,8 +344,8 @@ pub(crate) trait PlatformAtlas: Send + Sync {
|
||||
fn get_or_insert_with<'a>(
|
||||
&self,
|
||||
key: &AtlasKey,
|
||||
build: &mut dyn FnMut() -> Result<(Size<DevicePixels>, Cow<'a, [u8]>)>,
|
||||
) -> Result<AtlasTile>;
|
||||
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
|
||||
) -> Result<Option<AtlasTile>>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -114,18 +114,20 @@ impl PlatformAtlas for BladeAtlas {
|
||||
fn get_or_insert_with<'a>(
|
||||
&self,
|
||||
key: &AtlasKey,
|
||||
build: &mut dyn FnMut() -> Result<(Size<DevicePixels>, Cow<'a, [u8]>)>,
|
||||
) -> Result<AtlasTile> {
|
||||
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
|
||||
) -> Result<Option<AtlasTile>> {
|
||||
let mut lock = self.0.lock();
|
||||
if let Some(tile) = lock.tiles_by_key.get(key) {
|
||||
Ok(tile.clone())
|
||||
Ok(Some(tile.clone()))
|
||||
} else {
|
||||
profiling::scope!("new tile");
|
||||
let (size, bytes) = build()?;
|
||||
let Some((size, bytes)) = build()? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let tile = lock.allocate(size, key.texture_kind());
|
||||
lock.upload_texture(tile.texture_id, tile.bounds, &bytes);
|
||||
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
||||
Ok(tile)
|
||||
Ok(Some(tile))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,20 +60,22 @@ impl PlatformAtlas for MetalAtlas {
|
||||
fn get_or_insert_with<'a>(
|
||||
&self,
|
||||
key: &AtlasKey,
|
||||
build: &mut dyn FnMut() -> Result<(Size<DevicePixels>, Cow<'a, [u8]>)>,
|
||||
) -> Result<AtlasTile> {
|
||||
build: &mut dyn FnMut() -> Result<Option<(Size<DevicePixels>, Cow<'a, [u8]>)>>,
|
||||
) -> Result<Option<AtlasTile>> {
|
||||
let mut lock = self.0.lock();
|
||||
if let Some(tile) = lock.tiles_by_key.get(key) {
|
||||
Ok(tile.clone())
|
||||
Ok(Some(tile.clone()))
|
||||
} else {
|
||||
let (size, bytes) = build()?;
|
||||
let Some((size, bytes)) = build()? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let tile = lock
|
||||
.allocate(size, key.texture_kind())
|
||||
.ok_or_else(|| anyhow!("failed to allocate"))?;
|
||||
let texture = lock.texture(tile.texture_id);
|
||||
texture.upload(tile.bounds, &bytes);
|
||||
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
||||
Ok(tile)
|
||||
Ok(Some(tile))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,25 +291,26 @@ impl PlatformAtlas for TestAtlas {
|
||||
fn get_or_insert_with<'a>(
|
||||
&self,
|
||||
key: &crate::AtlasKey,
|
||||
build: &mut dyn FnMut() -> anyhow::Result<(
|
||||
Size<crate::DevicePixels>,
|
||||
std::borrow::Cow<'a, [u8]>,
|
||||
)>,
|
||||
) -> anyhow::Result<crate::AtlasTile> {
|
||||
build: &mut dyn FnMut() -> anyhow::Result<
|
||||
Option<(Size<crate::DevicePixels>, std::borrow::Cow<'a, [u8]>)>,
|
||||
>,
|
||||
) -> anyhow::Result<Option<crate::AtlasTile>> {
|
||||
let mut state = self.0.lock();
|
||||
if let Some(tile) = state.tiles.get(key) {
|
||||
return Ok(tile.clone());
|
||||
return Ok(Some(tile.clone()));
|
||||
}
|
||||
drop(state);
|
||||
|
||||
let Some((size, _)) = build()? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let mut state = self.0.lock();
|
||||
state.next_id += 1;
|
||||
let texture_id = state.next_id;
|
||||
state.next_id += 1;
|
||||
let tile_id = state.next_id;
|
||||
|
||||
drop(state);
|
||||
let (size, _) = build()?;
|
||||
let mut state = self.0.lock();
|
||||
|
||||
state.tiles.insert(
|
||||
key.clone(),
|
||||
crate::AtlasTile {
|
||||
@ -326,6 +327,6 @@ impl PlatformAtlas for TestAtlas {
|
||||
},
|
||||
);
|
||||
|
||||
Ok(state.tiles[key].clone())
|
||||
Ok(Some(state.tiles[key].clone()))
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,15 @@ impl SvgRenderer {
|
||||
Self { asset_source }
|
||||
}
|
||||
|
||||
pub fn render(&self, params: &RenderSvgParams) -> Result<Vec<u8>> {
|
||||
pub fn render(&self, params: &RenderSvgParams) -> Result<Option<Vec<u8>>> {
|
||||
if params.size.is_zero() {
|
||||
return Err(anyhow!("can't render at a zero size"));
|
||||
}
|
||||
|
||||
// Load the tree.
|
||||
let bytes = self.asset_source.load(¶ms.path)?;
|
||||
let Some(bytes) = self.asset_source.load(¶ms.path)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let pixmap = self.render_pixmap(&bytes, SvgSize::Size(params.size))?;
|
||||
|
||||
@ -40,7 +42,7 @@ impl SvgRenderer {
|
||||
.iter()
|
||||
.map(|p| p.alpha())
|
||||
.collect::<Vec<_>>();
|
||||
Ok(alpha_mask)
|
||||
Ok(Some(alpha_mask))
|
||||
}
|
||||
|
||||
pub fn render_pixmap(&self, bytes: &[u8], size: SvgSize) -> Result<Pixmap, usvg::Error> {
|
||||
|
@ -2347,13 +2347,14 @@ impl<'a> WindowContext<'a> {
|
||||
|
||||
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
|
||||
if !raster_bounds.is_zero() {
|
||||
let tile =
|
||||
self.window
|
||||
let tile = self
|
||||
.window
|
||||
.sprite_atlas
|
||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||
let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
|
||||
Ok((size, Cow::Owned(bytes)))
|
||||
})?;
|
||||
Ok(Some((size, Cow::Owned(bytes))))
|
||||
})?
|
||||
.expect("Callback above only errors or returns Some");
|
||||
let bounds = Bounds {
|
||||
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
||||
size: tile.bounds.size.map(Into::into),
|
||||
@ -2410,13 +2411,15 @@ impl<'a> WindowContext<'a> {
|
||||
|
||||
let raster_bounds = self.text_system().raster_bounds(¶ms)?;
|
||||
if !raster_bounds.is_zero() {
|
||||
let tile =
|
||||
self.window
|
||||
let tile = self
|
||||
.window
|
||||
.sprite_atlas
|
||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||
let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
|
||||
Ok((size, Cow::Owned(bytes)))
|
||||
})?;
|
||||
Ok(Some((size, Cow::Owned(bytes))))
|
||||
})?
|
||||
.expect("Callback above only errors or returns Some");
|
||||
|
||||
let bounds = Bounds {
|
||||
origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
|
||||
size: tile.bounds.size.map(Into::into),
|
||||
@ -2464,13 +2467,18 @@ impl<'a> WindowContext<'a> {
|
||||
.map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
|
||||
};
|
||||
|
||||
let tile =
|
||||
let Some(tile) =
|
||||
self.window
|
||||
.sprite_atlas
|
||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||
let bytes = self.svg_renderer.render(¶ms)?;
|
||||
Ok((params.size, Cow::Owned(bytes)))
|
||||
})?;
|
||||
let Some(bytes) = self.svg_renderer.render(¶ms)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
Ok(Some((params.size, Cow::Owned(bytes))))
|
||||
})?
|
||||
else {
|
||||
return Ok(());
|
||||
};
|
||||
let content_mask = self.content_mask().scale(scale_factor);
|
||||
|
||||
self.window
|
||||
@ -2513,8 +2521,9 @@ impl<'a> WindowContext<'a> {
|
||||
.window
|
||||
.sprite_atlas
|
||||
.get_or_insert_with(¶ms.clone().into(), &mut || {
|
||||
Ok((data.size(), Cow::Borrowed(data.as_bytes())))
|
||||
})?;
|
||||
Ok(Some((data.size(), Cow::Borrowed(data.as_bytes()))))
|
||||
})?
|
||||
.expect("Callback above only returns Some");
|
||||
let content_mask = self.content_mask().scale(scale_factor);
|
||||
let corner_radii = corner_radii.scale(scale_factor);
|
||||
|
||||
|
@ -95,6 +95,7 @@ impl Item for ImageView {
|
||||
let workspace_id = workspace.database_id();
|
||||
let image_path = self.path.clone();
|
||||
|
||||
if let Some(workspace_id) = workspace_id {
|
||||
cx.background_executor()
|
||||
.spawn({
|
||||
let image_path = image_path.clone();
|
||||
@ -107,6 +108,7 @@ impl Item for ImageView {
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
|
||||
fn serialized_item_kind() -> Option<&'static str> {
|
||||
Some(IMAGE_VIEWER_KIND)
|
||||
@ -133,7 +135,7 @@ impl Item for ImageView {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
|
@ -407,7 +407,7 @@ impl Item for SyntaxTreeView {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_: workspace::WorkspaceId,
|
||||
_: Option<workspace::WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
|
@ -287,7 +287,7 @@ impl PickerDelegate for RecentProjectsDelegate {
|
||||
};
|
||||
workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
if workspace.database_id() == *candidate_workspace_id {
|
||||
if workspace.database_id() == Some(*candidate_workspace_id) {
|
||||
Task::ready(Ok(()))
|
||||
} else {
|
||||
match candidate_workspace_location {
|
||||
@ -675,7 +675,7 @@ impl RecentProjectsDelegate {
|
||||
) -> bool {
|
||||
if let Some(workspace) = self.workspace.upgrade() {
|
||||
let workspace = workspace.read(cx);
|
||||
if workspace_id == workspace.database_id() {
|
||||
if Some(workspace_id) == workspace.database_id() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ impl Item for ProjectSearchView {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
|
@ -283,7 +283,7 @@ impl Item for ProjectIndexDebugView {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_: workspace::WorkspaceId,
|
||||
_: Option<workspace::WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
|
@ -15,10 +15,11 @@ use rust_embed::RustEmbed;
|
||||
pub struct Assets;
|
||||
|
||||
impl AssetSource for Assets {
|
||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>> {
|
||||
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
||||
Self::get(path)
|
||||
.map(|f| f.data)
|
||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||
.map(|data| Some(data))
|
||||
}
|
||||
|
||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||
|
@ -128,7 +128,10 @@ fn load_embedded_fonts(cx: &AppContext) -> gpui::Result<()> {
|
||||
let mut embedded_fonts = Vec::new();
|
||||
for font_path in font_paths {
|
||||
if font_path.ends_with(".ttf") {
|
||||
let font_bytes = cx.asset_source().load(&font_path)?;
|
||||
let font_bytes = cx
|
||||
.asset_source()
|
||||
.load(&font_path)?
|
||||
.expect("Should never be None in the storybook");
|
||||
embedded_fonts.push(font_bytes);
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +221,9 @@ impl TerminalPanel {
|
||||
|
||||
let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| {
|
||||
let panel = cx.new_view(|cx| TerminalPanel::new(workspace, cx));
|
||||
let items = if let Some(serialized_panel) = serialized_panel.as_ref() {
|
||||
let items = if let Some((serialized_panel, database_id)) =
|
||||
serialized_panel.as_ref().zip(workspace.database_id())
|
||||
{
|
||||
panel.update(cx, |panel, cx| {
|
||||
cx.notify();
|
||||
panel.height = serialized_panel.height.map(|h| h.round());
|
||||
@ -234,7 +236,7 @@ impl TerminalPanel {
|
||||
TerminalView::deserialize(
|
||||
workspace.project().clone(),
|
||||
workspace.weak_handle(),
|
||||
workspace.database_id(),
|
||||
database_id,
|
||||
*item_id,
|
||||
cx,
|
||||
)
|
||||
|
@ -91,7 +91,7 @@ pub struct TerminalView {
|
||||
blinking_paused: bool,
|
||||
blink_epoch: usize,
|
||||
can_navigate_to_selected_word: bool,
|
||||
workspace_id: WorkspaceId,
|
||||
workspace_id: Option<WorkspaceId>,
|
||||
show_title: bool,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
_terminal_subscriptions: Vec<Subscription>,
|
||||
@ -142,7 +142,7 @@ impl TerminalView {
|
||||
pub fn new(
|
||||
terminal: Model<Terminal>,
|
||||
workspace: WeakView<Workspace>,
|
||||
workspace_id: WorkspaceId,
|
||||
workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let workspace_handle = workspace.clone();
|
||||
@ -458,7 +458,7 @@ fn subscribe_for_terminal_events(
|
||||
if terminal.task().is_none() {
|
||||
if let Some(cwd) = terminal.get_cwd() {
|
||||
let item_id = cx.entity_id();
|
||||
let workspace_id = this.workspace_id;
|
||||
if let Some(workspace_id) = this.workspace_id {
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
TERMINAL_DB
|
||||
@ -470,6 +470,7 @@ fn subscribe_for_terminal_events(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Event::NewNavigationTarget(maybe_navigation_target) => {
|
||||
this.can_navigate_to_selected_word = match maybe_navigation_target {
|
||||
@ -853,7 +854,7 @@ impl Item for TerminalView {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
_cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>> {
|
||||
//From what I can tell, there's no way to tell the current working
|
||||
@ -941,20 +942,18 @@ impl Item for TerminalView {
|
||||
project.create_terminal(cwd, None, window, cx)
|
||||
})??;
|
||||
pane.update(&mut cx, |_, cx| {
|
||||
cx.new_view(|cx| TerminalView::new(terminal, workspace, workspace_id, cx))
|
||||
cx.new_view(|cx| TerminalView::new(terminal, workspace, Some(workspace_id), cx))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext<Self>) {
|
||||
if self.terminal().read(cx).task().is_none() {
|
||||
if let Some((new_id, old_id)) = workspace.database_id().zip(self.workspace_id) {
|
||||
cx.background_executor()
|
||||
.spawn(TERMINAL_DB.update_workspace_id(
|
||||
workspace.database_id(),
|
||||
self.workspace_id,
|
||||
cx.entity_id().as_u64(),
|
||||
))
|
||||
.spawn(TERMINAL_DB.update_workspace_id(new_id, old_id, cx.entity_id().as_u64()))
|
||||
.detach();
|
||||
}
|
||||
self.workspace_id = workspace.database_id();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::{fmt::Debug, path::Path};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use collections::HashMap;
|
||||
@ -226,7 +226,7 @@ impl ThemeRegistry {
|
||||
.filter(|path| path.ends_with(".json"));
|
||||
|
||||
for path in theme_paths {
|
||||
let Some(theme) = self.assets.load(&path).log_err() else {
|
||||
let Some(theme) = self.assets.load(&path).log_err().flatten() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
@ -11,10 +11,11 @@ use rust_embed::RustEmbed;
|
||||
pub struct Assets;
|
||||
|
||||
impl AssetSource for Assets {
|
||||
fn load(&self, path: &str) -> Result<Cow<'static, [u8]>> {
|
||||
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
||||
Self::get(path)
|
||||
.map(|f| f.data)
|
||||
.ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
|
||||
.map(|result| Some(result))
|
||||
}
|
||||
|
||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||
|
@ -313,7 +313,7 @@ impl Item for WelcomePage {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>> {
|
||||
Some(cx.new_view(|cx| WelcomePage {
|
||||
|
@ -172,7 +172,7 @@ pub trait Item: FocusableView + EventEmitter<Self::Event> {
|
||||
fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext<Self>) {}
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
_: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
@ -287,7 +287,7 @@ pub trait ItemHandle: 'static + Send {
|
||||
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
workspace_id: WorkspaceId,
|
||||
workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Option<Box<dyn ItemHandle>>;
|
||||
fn added_to_pane(
|
||||
@ -437,7 +437,7 @@ impl<T: Item> ItemHandle for View<T> {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
workspace_id: WorkspaceId,
|
||||
workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut WindowContext,
|
||||
) -> Option<Box<dyn ItemHandle>> {
|
||||
self.update(cx, |item, cx| item.clone_on_split(workspace_id, cx))
|
||||
@ -528,7 +528,6 @@ impl<T: Item> ItemHandle for View<T> {
|
||||
{
|
||||
pane
|
||||
} else {
|
||||
log::error!("unexpected item event after pane was dropped");
|
||||
return;
|
||||
};
|
||||
|
||||
@ -883,7 +882,7 @@ pub mod test {
|
||||
}
|
||||
|
||||
pub struct TestItem {
|
||||
pub workspace_id: WorkspaceId,
|
||||
pub workspace_id: Option<WorkspaceId>,
|
||||
pub state: String,
|
||||
pub label: String,
|
||||
pub save_count: usize,
|
||||
@ -964,7 +963,7 @@ pub mod test {
|
||||
|
||||
pub fn new_deserialized(id: WorkspaceId, cx: &mut ViewContext<Self>) -> Self {
|
||||
let mut this = Self::new(cx);
|
||||
this.workspace_id = id;
|
||||
this.workspace_id = Some(id);
|
||||
this
|
||||
}
|
||||
|
||||
@ -1081,7 +1080,7 @@ pub mod test {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>>
|
||||
where
|
||||
|
@ -119,7 +119,7 @@ impl Item for SharedScreen {
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: WorkspaceId,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<View<Self>> {
|
||||
let track = self.track.upgrade()?;
|
||||
|
@ -588,7 +588,7 @@ pub struct Workspace {
|
||||
window_edited: bool,
|
||||
active_call: Option<(Model<ActiveCall>, Vec<Subscription>)>,
|
||||
leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
|
||||
database_id: WorkspaceId,
|
||||
database_id: Option<WorkspaceId>,
|
||||
app_state: Arc<AppState>,
|
||||
dispatching_keystrokes: Rc<RefCell<Vec<Keystroke>>>,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
@ -622,7 +622,7 @@ impl Workspace {
|
||||
const MAX_PADDING: f32 = 0.4;
|
||||
|
||||
pub fn new(
|
||||
workspace_id: WorkspaceId,
|
||||
workspace_id: Option<WorkspaceId>,
|
||||
project: Model<Project>,
|
||||
app_state: Arc<AppState>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
@ -795,15 +795,17 @@ impl Workspace {
|
||||
if let Some(display) = cx.display() {
|
||||
if let Some(display_uuid) = display.uuid().log_err() {
|
||||
let window_bounds = cx.window_bounds();
|
||||
if let Some(database_id) = workspace_id {
|
||||
cx.background_executor()
|
||||
.spawn(DB.set_window_open_status(
|
||||
workspace_id,
|
||||
database_id,
|
||||
SerializedWindowBounds(window_bounds),
|
||||
display_uuid,
|
||||
))
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.bounds_save_task_queued.take();
|
||||
})
|
||||
.ok();
|
||||
@ -956,7 +958,12 @@ impl Workspace {
|
||||
let window = if let Some(window) = requesting_window {
|
||||
cx.update_window(window.into(), |_, cx| {
|
||||
cx.replace_root_view(|cx| {
|
||||
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
|
||||
Workspace::new(
|
||||
Some(workspace_id),
|
||||
project_handle.clone(),
|
||||
app_state.clone(),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
})?;
|
||||
window
|
||||
@ -994,7 +1001,7 @@ impl Workspace {
|
||||
move |cx| {
|
||||
cx.new_view(|cx| {
|
||||
let mut workspace =
|
||||
Workspace::new(workspace_id, project_handle, app_state, cx);
|
||||
Workspace::new(Some(workspace_id), project_handle, app_state, cx);
|
||||
workspace.centered_layout = centered_layout;
|
||||
workspace
|
||||
})
|
||||
@ -3464,9 +3471,12 @@ impl Workspace {
|
||||
pub fn on_window_activation_changed(&mut self, cx: &mut ViewContext<Self>) {
|
||||
if cx.is_window_active() {
|
||||
self.update_active_view_for_followers(cx);
|
||||
|
||||
if let Some(database_id) = self.database_id {
|
||||
cx.background_executor()
|
||||
.spawn(persistence::DB.update_timestamp(self.database_id()))
|
||||
.spawn(persistence::DB.update_timestamp(database_id))
|
||||
.detach();
|
||||
}
|
||||
} else {
|
||||
for pane in &self.panes {
|
||||
pane.update(cx, |pane, cx| {
|
||||
@ -3506,7 +3516,7 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn database_id(&self) -> WorkspaceId {
|
||||
pub fn database_id(&self) -> Option<WorkspaceId> {
|
||||
self.database_id
|
||||
}
|
||||
|
||||
@ -3566,6 +3576,10 @@ impl Workspace {
|
||||
}
|
||||
|
||||
fn serialize_workspace_internal(&self, cx: &mut WindowContext) -> Task<()> {
|
||||
let Some(database_id) = self.database_id() else {
|
||||
return Task::ready(());
|
||||
};
|
||||
|
||||
fn serialize_pane_handle(pane_handle: &View<Pane>, cx: &WindowContext) -> SerializedPane {
|
||||
let (items, active) = {
|
||||
let pane = pane_handle.read(cx);
|
||||
@ -3701,7 +3715,7 @@ impl Workspace {
|
||||
let docks = build_serialized_docks(self, cx);
|
||||
let window_bounds = Some(SerializedWindowBounds(cx.window_bounds()));
|
||||
let serialized_workspace = SerializedWorkspace {
|
||||
id: self.database_id,
|
||||
id: database_id,
|
||||
location,
|
||||
center_group,
|
||||
window_bounds,
|
||||
@ -3944,9 +3958,11 @@ impl Workspace {
|
||||
|
||||
pub fn toggle_centered_layout(&mut self, _: &ToggleCenteredLayout, cx: &mut ViewContext<Self>) {
|
||||
self.centered_layout = !self.centered_layout;
|
||||
if let Some(database_id) = self.database_id() {
|
||||
cx.background_executor()
|
||||
.spawn(DB.set_centered_layout(self.database_id, self.centered_layout))
|
||||
.spawn(DB.set_centered_layout(database_id, self.centered_layout))
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
|
@ -832,7 +832,7 @@ fn load_embedded_fonts(cx: &AppContext) {
|
||||
}
|
||||
|
||||
scope.spawn(async {
|
||||
let font_bytes = asset_source.load(font_path).unwrap();
|
||||
let font_bytes = asset_source.load(font_path).unwrap().unwrap();
|
||||
embedded_fonts.lock().push(font_bytes);
|
||||
});
|
||||
}
|
||||
|
@ -3043,8 +3043,14 @@ mod tests {
|
||||
fn test_bundled_settings_and_themes(cx: &mut AppContext) {
|
||||
cx.text_system()
|
||||
.add_fonts(vec![
|
||||
Assets.load("fonts/zed-sans/zed-sans-extended.ttf").unwrap(),
|
||||
Assets.load("fonts/zed-mono/zed-mono-extended.ttf").unwrap(),
|
||||
Assets
|
||||
.load("fonts/zed-sans/zed-sans-extended.ttf")
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
Assets
|
||||
.load("fonts/zed-mono/zed-mono-extended.ttf")
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
])
|
||||
.unwrap();
|
||||
let themes = ThemeRegistry::default();
|
||||
|
Loading…
Reference in New Issue
Block a user