workspace: Add trailing /
to directories on completion when using OpenPathPrompt
(#25430)
Closes #25045 With the setting `"use_system_path_prompts": false`, previously, if the completion target was a directory, no separator would be added after it, requiring us to manually append a `/` or `\`. Now, if the completion target is a directory, a `/` or `\` will be automatically added. On Windows, both `/` and `\` are considered valid path separators. https://github.com/user-attachments/assets/0594ce27-9693-4a49-ae0e-3ed29f62526a Release Notes: - N/A
This commit is contained in:
parent
8c4da9fba0
commit
11b79d0ab9
8 changed files with 472 additions and 41 deletions
|
@ -524,6 +524,12 @@ enum EntitySubscription {
|
|||
SettingsObserver(PendingEntitySubscription<SettingsObserver>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DirectoryItem {
|
||||
pub path: PathBuf,
|
||||
pub is_dir: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DirectoryLister {
|
||||
Project(Entity<Project>),
|
||||
|
@ -552,10 +558,10 @@ impl DirectoryLister {
|
|||
return worktree.read(cx).abs_path().to_string_lossy().to_string();
|
||||
}
|
||||
};
|
||||
"~/".to_string()
|
||||
format!("~{}", std::path::MAIN_SEPARATOR_STR)
|
||||
}
|
||||
|
||||
pub fn list_directory(&self, path: String, cx: &mut App) -> Task<Result<Vec<PathBuf>>> {
|
||||
pub fn list_directory(&self, path: String, cx: &mut App) -> Task<Result<Vec<DirectoryItem>>> {
|
||||
match self {
|
||||
DirectoryLister::Project(project) => {
|
||||
project.update(cx, |project, cx| project.list_directory(path, cx))
|
||||
|
@ -568,8 +574,12 @@ impl DirectoryLister {
|
|||
let query = Path::new(expanded.as_ref());
|
||||
let mut response = fs.read_dir(query).await?;
|
||||
while let Some(path) = response.next().await {
|
||||
if let Some(file_name) = path?.file_name() {
|
||||
results.push(PathBuf::from(file_name.to_os_string()));
|
||||
let path = path?;
|
||||
if let Some(file_name) = path.file_name() {
|
||||
results.push(DirectoryItem {
|
||||
path: PathBuf::from(file_name.to_os_string()),
|
||||
is_dir: fs.is_dir(&path).await,
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(results)
|
||||
|
@ -3491,7 +3501,7 @@ impl Project {
|
|||
&self,
|
||||
query: String,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Vec<PathBuf>>> {
|
||||
) -> Task<Result<Vec<DirectoryItem>>> {
|
||||
if self.is_local() {
|
||||
DirectoryLister::Local(self.fs.clone()).list_directory(query, cx)
|
||||
} else if let Some(session) = self.ssh_client.as_ref() {
|
||||
|
@ -3499,12 +3509,23 @@ impl Project {
|
|||
let request = proto::ListRemoteDirectory {
|
||||
dev_server_id: SSH_PROJECT_ID,
|
||||
path: path_buf.to_proto(),
|
||||
config: Some(proto::ListRemoteDirectoryConfig { is_dir: true }),
|
||||
};
|
||||
|
||||
let response = session.read(cx).proto_client().request(request);
|
||||
cx.background_spawn(async move {
|
||||
let response = response.await?;
|
||||
Ok(response.entries.into_iter().map(PathBuf::from).collect())
|
||||
let proto::ListRemoteDirectoryResponse {
|
||||
entries,
|
||||
entry_info,
|
||||
} = response.await?;
|
||||
Ok(entries
|
||||
.into_iter()
|
||||
.zip(entry_info)
|
||||
.map(|(entry, info)| DirectoryItem {
|
||||
path: PathBuf::from(entry),
|
||||
is_dir: info.is_dir,
|
||||
})
|
||||
.collect())
|
||||
})
|
||||
} else {
|
||||
Task::ready(Err(anyhow!("cannot list directory in remote project")))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue