Fix empty title in Recent Projects (#21952)
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( [], ), ) ```
This commit is contained in:
parent
e08eba8129
commit
dc0075b8e6
5 changed files with 93 additions and 43 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -10340,7 +10340,6 @@ dependencies = [
|
||||||
"futures 0.3.31",
|
"futures 0.3.31",
|
||||||
"fuzzy",
|
"fuzzy",
|
||||||
"gpui",
|
"gpui",
|
||||||
"itertools 0.13.0",
|
|
||||||
"language",
|
"language",
|
||||||
"log",
|
"log",
|
||||||
"markdown",
|
"markdown",
|
||||||
|
|
|
@ -22,7 +22,6 @@ file_finder.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
fuzzy.workspace = true
|
fuzzy.workspace = true
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
itertools.workspace = true
|
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
language.workspace = true
|
language.workspace = true
|
||||||
markdown.workspace = true
|
markdown.workspace = true
|
||||||
|
|
|
@ -9,7 +9,6 @@ use gpui::{
|
||||||
Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
|
Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle, FocusableView,
|
||||||
Subscription, Task, View, ViewContext, WeakView,
|
Subscription, Task, View, ViewContext, WeakView,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use picker::{
|
use picker::{
|
||||||
highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
|
highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
|
||||||
|
@ -211,22 +210,12 @@ impl PickerDelegate for RecentProjectsDelegate {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, (id, _))| !self.is_current_workspace(*id, cx))
|
.filter(|(_, (id, _))| !self.is_current_workspace(*id, cx))
|
||||||
.map(|(id, (_, location))| {
|
.map(|(id, (_, location))| {
|
||||||
let combined_string = match location {
|
let combined_string = location
|
||||||
SerializedWorkspaceLocation::Local(paths, order) => order
|
.sorted_paths()
|
||||||
.order()
|
.iter()
|
||||||
.iter()
|
.map(|path| path.compact().to_string_lossy().into_owned())
|
||||||
.zip(paths.paths().iter())
|
.collect::<Vec<_>>()
|
||||||
.sorted_by_key(|(i, _)| *i)
|
.join("");
|
||||||
.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(""),
|
|
||||||
};
|
|
||||||
|
|
||||||
StringMatchCandidate::new(id, &combined_string)
|
StringMatchCandidate::new(id, &combined_string)
|
||||||
})
|
})
|
||||||
|
@ -364,21 +353,11 @@ impl PickerDelegate for RecentProjectsDelegate {
|
||||||
let (_, location) = self.workspaces.get(hit.candidate_id)?;
|
let (_, location) = self.workspaces.get(hit.candidate_id)?;
|
||||||
|
|
||||||
let mut path_start_offset = 0;
|
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()
|
.iter()
|
||||||
|
.map(|p| p.compact())
|
||||||
.map(|path| {
|
.map(|path| {
|
||||||
let highlighted_text =
|
let highlighted_text =
|
||||||
highlights_for_path(path.as_ref(), &hit.positions, path_start_offset);
|
highlights_for_path(path.as_ref(), &hit.positions, path_start_offset);
|
||||||
|
|
|
@ -9,6 +9,7 @@ use db::sqlez::{
|
||||||
statement::Statement,
|
statement::Statement,
|
||||||
};
|
};
|
||||||
use gpui::{AsyncWindowContext, Model, View, WeakView};
|
use gpui::{AsyncWindowContext, Model, View, WeakView};
|
||||||
|
use itertools::Itertools as _;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use remote::ssh_session::SshProjectId;
|
use remote::ssh_session::SshProjectId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -228,6 +229,28 @@ impl SerializedWorkspaceLocation {
|
||||||
|
|
||||||
Self::Local(LocalPaths::new(sorted_paths), LocalPathsOrder::new(order))
|
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)]
|
#[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()
|
.as_ref()
|
||||||
.map(|ws| &ws.location)
|
.map(|ws| &ws.location)
|
||||||
.and_then(|loc| match loc {
|
.and_then(|loc| match loc {
|
||||||
SerializedWorkspaceLocation::Local(paths, order) => {
|
SerializedWorkspaceLocation::Local(_, order) => {
|
||||||
Some((paths.paths(), order.order()))
|
Some((loc.sorted_paths(), order.order()))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((paths, order)) = workspace_location {
|
if let Some((paths, order)) = workspace_location {
|
||||||
// todo: should probably move this logic to a method on the SerializedWorkspaceLocation
|
paths_to_open = paths.iter().cloned().collect();
|
||||||
// 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();
|
|
||||||
|
|
||||||
if order.iter().enumerate().any(|(i, &j)| i != j) {
|
if order.iter().enumerate().any(|(i, &j)| i != j) {
|
||||||
project_handle
|
project_handle
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue