Cargo.lock 🔗
@@ -10340,7 +10340,6 @@ dependencies = [
"futures 0.3.31",
"fuzzy",
"gpui",
- "itertools 0.13.0",
"language",
"log",
"markdown",
Jason Lee created
Close #13595
Release Notes:
- Fixed empty title in Recent Projects.
---
| Before | After |
| --- | --- |
| <img width="695" alt="SCR-20241213-nzxr"
src="https://github.com/user-attachments/assets/f19a0bad-d542-44cd-85c1-89386d396f27"
/> | <img width="625" alt="image"
src="https://github.com/user-attachments/assets/0d2afef7-4cd2-43eb-9046-c169df2eb8a0"
/> |
This is because the `LocalPathsOrder` get empty list.
```
[crates/recent_projects/src/recent_projects.rs:385:9] &location = Local(
LocalPaths(
[
"/Users/jason/Library/Application Support/Zed/prettier/node_modules",
],
),
LocalPathsOrder(
[],
),
)
[crates/recent_projects/src/recent_projects.rs:386:9] &paths = [
"~/Library/Application Support/Zed/prettier/node_modules",
]
[crates/recent_projects/src/recent_projects.rs:385:9] &location = Local(
LocalPaths(
[
"/Users/jason/github/tree-sitter-csv",
],
),
LocalPathsOrder(
[],
),
)
[crates/recent_projects/src/recent_projects.rs:386:9] &paths = [
"~/github/tree-sitter-csv",
]
[crates/recent_projects/src/recent_projects.rs:385:9] &location = Local(
LocalPaths(
[
"/Users/jason/work/autocorrect/autocorrect-website/dist",
],
),
LocalPathsOrder(
[],
),
)
```
Cargo.lock | 1
crates/recent_projects/Cargo.toml | 1
crates/recent_projects/src/recent_projects.rs | 39 ++-------
crates/workspace/src/persistence/model.rs | 81 +++++++++++++++++++++
crates/workspace/src/workspace.rs | 14 --
5 files changed, 93 insertions(+), 43 deletions(-)
@@ -10340,7 +10340,6 @@ dependencies = [
"futures 0.3.31",
"fuzzy",
"gpui",
- "itertools 0.13.0",
"language",
"log",
"markdown",
@@ -22,7 +22,6 @@ file_finder.workspace = true
futures.workspace = true
fuzzy.workspace = true
gpui.workspace = true
-itertools.workspace = true
log.workspace = true
language.workspace = true
markdown.workspace = true
@@ -9,7 +9,6 @@ use gpui::{
Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
Subscription, Task, View, ViewContext, WeakView,
};
-use itertools::Itertools;
use ordered_float::OrderedFloat;
use picker::{
highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
@@ -211,22 +210,12 @@ impl PickerDelegate for RecentProjectsDelegate {
.enumerate()
.filter(|(_, (id, _))| !self.is_current_workspace(*id, cx))
.map(|(id, (_, location))| {
- let combined_string = match location {
- SerializedWorkspaceLocation::Local(paths, order) => order
- .order()
- .iter()
- .zip(paths.paths().iter())
- .sorted_by_key(|(i, _)| *i)
- .map(|(_, path)| path.compact().to_string_lossy().into_owned())
- .collect::<Vec<_>>()
- .join(""),
- SerializedWorkspaceLocation::Ssh(ssh_project) => ssh_project
- .ssh_urls()
- .iter()
- .map(|path| path.to_string_lossy().to_string())
- .collect::<Vec<_>>()
- .join(""),
- };
+ let combined_string = location
+ .sorted_paths()
+ .iter()
+ .map(|path| path.compact().to_string_lossy().into_owned())
+ .collect::<Vec<_>>()
+ .join("");
StringMatchCandidate::new(id, &combined_string)
})
@@ -364,21 +353,11 @@ impl PickerDelegate for RecentProjectsDelegate {
let (_, location) = self.workspaces.get(hit.candidate_id)?;
let mut path_start_offset = 0;
- let paths = match location {
- SerializedWorkspaceLocation::Local(paths, order) => Arc::new(
- order
- .order()
- .iter()
- .zip(paths.paths().iter())
- .sorted_by_key(|(i, _)| **i)
- .map(|(_, path)| path.compact())
- .collect(),
- ),
- SerializedWorkspaceLocation::Ssh(ssh_project) => Arc::new(ssh_project.ssh_urls()),
- };
- let (match_labels, paths): (Vec<_>, Vec<_>) = paths
+ let (match_labels, paths): (Vec<_>, Vec<_>) = location
+ .sorted_paths()
.iter()
+ .map(|p| p.compact())
.map(|path| {
let highlighted_text =
highlights_for_path(path.as_ref(), &hit.positions, path_start_offset);
@@ -9,6 +9,7 @@ use db::sqlez::{
statement::Statement,
};
use gpui::{AsyncWindowContext, Model, View, WeakView};
+use itertools::Itertools as _;
use project::Project;
use remote::ssh_session::SshProjectId;
use serde::{Deserialize, Serialize};
@@ -228,6 +229,28 @@ impl SerializedWorkspaceLocation {
Self::Local(LocalPaths::new(sorted_paths), LocalPathsOrder::new(order))
}
+
+ /// Get sorted paths
+ pub fn sorted_paths(&self) -> Arc<Vec<PathBuf>> {
+ match self {
+ SerializedWorkspaceLocation::Local(paths, order) => {
+ if order.order().len() == 0 {
+ paths.paths().clone()
+ } else {
+ Arc::new(
+ order
+ .order()
+ .iter()
+ .zip(paths.paths().iter())
+ .sorted_by_key(|(i, _)| **i)
+ .map(|(_, p)| p.clone())
+ .collect(),
+ )
+ }
+ }
+ SerializedWorkspaceLocation::Ssh(ssh_project) => Arc::new(ssh_project.ssh_urls()),
+ }
+ }
}
#[derive(Debug, PartialEq, Clone)]
@@ -564,4 +587,62 @@ mod tests {
)
);
}
+
+ #[test]
+ fn test_sorted_paths() {
+ let paths = vec!["b", "a", "c"];
+ let serialized = SerializedWorkspaceLocation::from_local_paths(paths);
+ assert_eq!(
+ serialized.sorted_paths(),
+ Arc::new(vec![
+ PathBuf::from("b"),
+ PathBuf::from("a"),
+ PathBuf::from("c"),
+ ])
+ );
+
+ let paths = Arc::new(vec![
+ PathBuf::from("a"),
+ PathBuf::from("b"),
+ PathBuf::from("c"),
+ ]);
+ let order = vec![2, 0, 1];
+ let serialized =
+ SerializedWorkspaceLocation::Local(LocalPaths(paths.clone()), LocalPathsOrder(order));
+ assert_eq!(
+ serialized.sorted_paths(),
+ Arc::new(vec![
+ PathBuf::from("b"),
+ PathBuf::from("c"),
+ PathBuf::from("a"),
+ ])
+ );
+
+ let paths = Arc::new(vec![
+ PathBuf::from("a"),
+ PathBuf::from("b"),
+ PathBuf::from("c"),
+ ]);
+ let order = vec![];
+ let serialized =
+ SerializedWorkspaceLocation::Local(LocalPaths(paths.clone()), LocalPathsOrder(order));
+ assert_eq!(serialized.sorted_paths(), paths);
+
+ let urls = ["/a", "/b", "/c"];
+ let serialized = SerializedWorkspaceLocation::Ssh(SerializedSshProject {
+ id: SshProjectId(0),
+ host: "host".to_string(),
+ port: Some(22),
+ paths: urls.iter().map(|s| s.to_string()).collect(),
+ user: Some("user".to_string()),
+ });
+ assert_eq!(
+ serialized.sorted_paths(),
+ Arc::new(
+ urls.iter()
+ .map(|p| PathBuf::from(format!("user@host:22{}", p)))
+ .collect()
+ )
+ );
+ }
}
@@ -1127,22 +1127,14 @@ impl Workspace {
.as_ref()
.map(|ws| &ws.location)
.and_then(|loc| match loc {
- SerializedWorkspaceLocation::Local(paths, order) => {
- Some((paths.paths(), order.order()))
+ SerializedWorkspaceLocation::Local(_, order) => {
+ Some((loc.sorted_paths(), order.order()))
}
_ => None,
});
if let Some((paths, order)) = workspace_location {
- // todo: should probably move this logic to a method on the SerializedWorkspaceLocation
- // it's only valid for Local and would be more clear there and be able to be tested
- // and reused elsewhere
- paths_to_open = order
- .iter()
- .zip(paths.iter())
- .sorted_by_key(|(i, _)| *i)
- .map(|(_, path)| path.clone())
- .collect();
+ paths_to_open = paths.iter().cloned().collect();
if order.iter().enumerate().any(|(i, &j)| i != j) {
project_handle