@@ -1,6 +1,6 @@
use std::cell::RefCell;
use std::ops::Range;
-use std::path::{Path, PathBuf};
+use std::path::Path;
use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
@@ -70,18 +70,18 @@ impl ContextPickerCompletionProvider {
.filter_map(|entry| match entry {
super::RecentEntry::File {
project_path,
- path_prefix: _,
- } => Self::completion_for_path(
+ path_prefix,
+ } => Some(Self::completion_for_path(
project_path.clone(),
+ path_prefix,
true,
false,
excerpt_id,
source_range.clone(),
editor.clone(),
context_store.clone(),
- workspace.clone(),
cx,
- ),
+ )),
super::RecentEntry::Thread(thread_context_entry) => {
let thread_store = thread_store
.as_ref()
@@ -120,56 +120,24 @@ impl ContextPickerCompletionProvider {
completions
}
- fn full_path_for_entry(
- worktree_id: WorktreeId,
- path: &Path,
- workspace: Entity<Workspace>,
- cx: &App,
- ) -> Option<PathBuf> {
- let worktree = workspace
- .read(cx)
- .project()
- .read(cx)
- .worktree_for_id(worktree_id, cx)?
- .read(cx);
-
- let mut full_path = PathBuf::from(worktree.root_name());
- full_path.push(path);
- Some(full_path)
- }
-
fn build_code_label_for_full_path(
- worktree_id: WorktreeId,
- path: &Path,
- workspace: Entity<Workspace>,
+ file_name: &str,
+ directory: Option<&str>,
cx: &App,
- ) -> Option<CodeLabel> {
+ ) -> CodeLabel {
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
let mut label = CodeLabel::default();
- let worktree = workspace
- .read(cx)
- .project()
- .read(cx)
- .worktree_for_id(worktree_id, cx)?;
-
- let entry = worktree.read(cx).entry_for_path(&path)?;
- let file_name = path.file_name()?.to_string_lossy();
+
label.push_str(&file_name, None);
- if entry.is_dir() {
- label.push_str("/ ", None);
- } else {
- label.push_str(" ", None);
- };
+ label.push_str(" ", None);
- let mut path_hint = PathBuf::from(worktree.read(cx).root_name());
- if let Some(path_to_entry) = path.parent() {
- path_hint.push(path_to_entry);
+ if let Some(directory) = directory {
+ label.push_str(&directory, comment_id);
}
- label.push_str(&path_hint.to_string_lossy(), comment_id);
label.filter_range = 0..label.text().len();
- Some(label)
+ label
}
fn completion_for_thread(
@@ -274,32 +242,36 @@ impl ContextPickerCompletionProvider {
fn completion_for_path(
project_path: ProjectPath,
+ path_prefix: &str,
is_recent: bool,
is_directory: bool,
excerpt_id: ExcerptId,
source_range: Range<Anchor>,
editor: Entity<Editor>,
context_store: Entity<ContextStore>,
- workspace: Entity<Workspace>,
cx: &App,
- ) -> Option<Completion> {
- let label = Self::build_code_label_for_full_path(
- project_path.worktree_id,
- &project_path.path,
- workspace.clone(),
- cx,
- )?;
- let full_path = Self::full_path_for_entry(
- project_path.worktree_id,
+ ) -> Completion {
+ let (file_name, directory) = super::file_context_picker::extract_file_name_and_directory(
&project_path.path,
- workspace.clone(),
+ path_prefix,
+ );
+
+ let label = Self::build_code_label_for_full_path(
+ &file_name,
+ directory.as_ref().map(|s| s.as_ref()),
cx,
- )?;
+ );
+ let full_path = if let Some(directory) = directory {
+ format!("{}{}", directory, file_name)
+ } else {
+ file_name.to_string()
+ };
let crease_icon_path = if is_directory {
FileIcons::get_folder_icon(false, cx).unwrap_or_else(|| IconName::Folder.path().into())
} else {
- FileIcons::get_icon(&full_path, cx).unwrap_or_else(|| IconName::File.path().into())
+ FileIcons::get_icon(Path::new(&full_path), cx)
+ .unwrap_or_else(|| IconName::File.path().into())
};
let completion_icon_path = if is_recent {
IconName::HistoryRerun.path().into()
@@ -307,15 +279,9 @@ impl ContextPickerCompletionProvider {
crease_icon_path.clone()
};
- let crease_name = project_path
- .path
- .file_name()
- .map(|file_name| file_name.to_string_lossy().to_string())
- .unwrap_or_else(|| "untitled".to_string());
-
- let new_text = format!("@file {}", full_path.to_string_lossy());
+ let new_text = format!("@file {}", full_path);
let new_text_len = new_text.len();
- Some(Completion {
+ Completion {
old_range: source_range.clone(),
new_text,
label,
@@ -324,7 +290,7 @@ impl ContextPickerCompletionProvider {
icon_path: Some(completion_icon_path),
confirm: Some(confirm_completion_callback(
crease_icon_path,
- crease_name.into(),
+ file_name,
excerpt_id,
source_range.start,
new_text_len,
@@ -340,7 +306,7 @@ impl ContextPickerCompletionProvider {
})
},
)),
- })
+ }
}
}
@@ -397,33 +363,34 @@ impl CompletionProvider for ContextPickerCompletionProvider {
.update(|cx| {
super::file_context_picker::search_paths(
query,
- Arc::new(AtomicBool::default()),
+ Arc::<AtomicBool>::default(),
&workspace,
cx,
)
})?
.await;
- completions.reserve(path_matches.len());
- cx.update(|cx| {
- completions.extend(path_matches.iter().filter_map(|mat| {
- let editor = editor.upgrade()?;
- Self::completion_for_path(
- ProjectPath {
- worktree_id: WorktreeId::from_usize(mat.worktree_id),
- path: mat.path.clone(),
- },
- false,
- mat.is_dir,
- excerpt_id,
- source_range.clone(),
- editor.clone(),
- context_store.clone(),
- workspace.clone(),
- cx,
- )
- }));
- })?;
+ if let Some(editor) = editor.upgrade() {
+ completions.reserve(path_matches.len());
+ cx.update(|cx| {
+ completions.extend(path_matches.iter().map(|mat| {
+ Self::completion_for_path(
+ ProjectPath {
+ worktree_id: WorktreeId::from_usize(mat.worktree_id),
+ path: mat.path.clone(),
+ },
+ &mat.path_prefix,
+ false,
+ mat.is_dir,
+ excerpt_id,
+ source_range.clone(),
+ editor.clone(),
+ context_store.clone(),
+ cx,
+ )
+ }));
+ })?;
+ }
}
Some(ContextPickerMode::Fetch) => {
if let Some(editor) = editor.upgrade() {
@@ -771,7 +738,6 @@ mod tests {
.unwrap();
}
- //TODO: Construct the editor without an actual buffer that points to a file
let item = workspace
.update_in(&mut cx, |workspace, window, cx| {
workspace.open_path(
@@ -821,10 +787,10 @@ mod tests {
assert_eq!(
current_completion_labels(editor),
&[
- format!("seven.txt {}", separator!("dir/b")).as_str(),
- format!("six.txt {}", separator!("dir/b")).as_str(),
- format!("five.txt {}", separator!("dir/b")).as_str(),
- format!("four.txt {}", separator!("dir/a")).as_str(),
+ "seven.txt dir/b/",
+ "six.txt dir/b/",
+ "five.txt dir/b/",
+ "four.txt dir/a/",
"Files & Directories",
"Fetch"
]
@@ -853,10 +819,7 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(editor.text(cx), "Lorem @file one");
assert!(editor.has_visible_completions_menu());
- assert_eq!(
- current_completion_labels(editor),
- vec![format!("one.txt {}", separator!("dir/a")).as_str(),]
- );
+ assert_eq!(current_completion_labels(editor), vec!["one.txt dir/a/"]);
});
editor.update_in(&mut cx, |editor, window, cx| {
@@ -865,10 +828,7 @@ mod tests {
});
editor.update(&mut cx, |editor, cx| {
- assert_eq!(
- editor.text(cx),
- format!("Lorem @file {}", separator!("dir/a/one.txt"))
- );
+ assert_eq!(editor.text(cx), "Lorem @file dir/a/one.txt",);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
crease_ranges(editor, cx),
@@ -879,10 +839,7 @@ mod tests {
cx.simulate_input(" ");
editor.update(&mut cx, |editor, cx| {
- assert_eq!(
- editor.text(cx),
- format!("Lorem @file {} ", separator!("dir/a/one.txt"))
- );
+ assert_eq!(editor.text(cx), "Lorem @file dir/a/one.txt ",);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
crease_ranges(editor, cx),
@@ -893,10 +850,7 @@ mod tests {
cx.simulate_input("Ipsum ");
editor.update(&mut cx, |editor, cx| {
- assert_eq!(
- editor.text(cx),
- format!("Lorem @file {} Ipsum ", separator!("dir/a/one.txt"))
- );
+ assert_eq!(editor.text(cx), "Lorem @file dir/a/one.txt Ipsum ",);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
crease_ranges(editor, cx),
@@ -907,10 +861,7 @@ mod tests {
cx.simulate_input("@file ");
editor.update(&mut cx, |editor, cx| {
- assert_eq!(
- editor.text(cx),
- format!("Lorem @file {} Ipsum @file ", separator!("dir/a/one.txt"))
- );
+ assert_eq!(editor.text(cx), "Lorem @file dir/a/one.txt Ipsum @file ",);
assert!(editor.has_visible_completions_menu());
assert_eq!(
crease_ranges(editor, cx),
@@ -927,11 +878,7 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
- format!(
- "Lorem @file {} Ipsum @file {}",
- separator!("dir/a/one.txt"),
- separator!("dir/b/seven.txt")
- )
+ "Lorem @file dir/a/one.txt Ipsum @file dir/b/seven.txt"
);
assert!(!editor.has_visible_completions_menu());
assert_eq!(
@@ -948,11 +895,7 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
- format!(
- "Lorem @file {} Ipsum @file {}\n@",
- separator!("dir/a/one.txt"),
- separator!("dir/b/seven.txt")
- )
+ "Lorem @file dir/a/one.txt Ipsum @file dir/b/seven.txt\n@"
);
assert!(editor.has_visible_completions_menu());
assert_eq!(
@@ -973,12 +916,7 @@ mod tests {
editor.update(&mut cx, |editor, cx| {
assert_eq!(
editor.text(cx),
- format!(
- "Lorem @file {} Ipsum @file {}\n@file {}",
- separator!("dir/a/one.txt"),
- separator!("dir/b/seven.txt"),
- separator!("dir/b/six.txt"),
- )
+ "Lorem @file dir/a/one.txt Ipsum @file dir/b/seven.txt\n@file dir/b/six.txt"
);
assert!(!editor.has_visible_completions_menu());
assert_eq!(