Show symbols located in visible paths before ones located externally
This commit is contained in:
parent
f775cb2947
commit
8552ba15dc
5 changed files with 103 additions and 74 deletions
|
@ -2589,7 +2589,7 @@ async fn test_project_symbols(cx_a: &mut TestAppContext, cx_b: &mut TestAppConte
|
||||||
|
|
||||||
// Attempt to craft a symbol and violate host's privacy by opening an arbitrary file.
|
// Attempt to craft a symbol and violate host's privacy by opening an arbitrary file.
|
||||||
let mut fake_symbol = symbols[0].clone();
|
let mut fake_symbol = symbols[0].clone();
|
||||||
fake_symbol.path = Path::new("/code/secrets").into();
|
fake_symbol.path.path = Path::new("/code/secrets").into();
|
||||||
let error = project_b
|
let error = project_b
|
||||||
.update(cx_b, |project, cx| {
|
.update(cx_b, |project, cx| {
|
||||||
project.open_buffer_for_symbol(&fake_symbol, cx)
|
project.open_buffer_for_symbol(&fake_symbol, cx)
|
||||||
|
|
|
@ -181,7 +181,7 @@ pub async fn match_strings(
|
||||||
cancel_flag: &AtomicBool,
|
cancel_flag: &AtomicBool,
|
||||||
background: Arc<executor::Background>,
|
background: Arc<executor::Background>,
|
||||||
) -> Vec<StringMatch> {
|
) -> Vec<StringMatch> {
|
||||||
if candidates.is_empty() {
|
if candidates.is_empty() || max_results == 0 {
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,10 +254,9 @@ pub struct DocumentHighlight {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Symbol {
|
pub struct Symbol {
|
||||||
pub source_worktree_id: WorktreeId,
|
|
||||||
pub worktree_id: WorktreeId,
|
|
||||||
pub language_server_name: LanguageServerName,
|
pub language_server_name: LanguageServerName,
|
||||||
pub path: PathBuf,
|
pub source_worktree_id: WorktreeId,
|
||||||
|
pub path: ProjectPath,
|
||||||
pub label: CodeLabel,
|
pub label: CodeLabel,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub kind: lsp::SymbolKind,
|
pub kind: lsp::SymbolKind,
|
||||||
|
@ -3324,16 +3323,19 @@ impl Project {
|
||||||
if let Some((worktree, rel_path)) =
|
if let Some((worktree, rel_path)) =
|
||||||
this.find_local_worktree(&abs_path, cx)
|
this.find_local_worktree(&abs_path, cx)
|
||||||
{
|
{
|
||||||
worktree_id = worktree.read(cx).id();
|
worktree_id = (&worktree.read(cx)).id();
|
||||||
path = rel_path;
|
path = rel_path;
|
||||||
} else {
|
} else {
|
||||||
path = relativize_path(&worktree_abs_path, &abs_path);
|
path = relativize_path(&worktree_abs_path, &abs_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
let signature = this.symbol_signature(worktree_id, &path);
|
let project_path = ProjectPath {
|
||||||
let language = this.languages.select_language(&path);
|
worktree_id,
|
||||||
|
path: path.into(),
|
||||||
|
};
|
||||||
|
let signature = this.symbol_signature(&project_path);
|
||||||
|
let language = this.languages.select_language(&project_path.path);
|
||||||
let language_server_name = adapter.name.clone();
|
let language_server_name = adapter.name.clone();
|
||||||
|
|
||||||
Some(async move {
|
Some(async move {
|
||||||
let label = if let Some(language) = language {
|
let label = if let Some(language) = language {
|
||||||
language
|
language
|
||||||
|
@ -3344,15 +3346,14 @@ impl Project {
|
||||||
};
|
};
|
||||||
|
|
||||||
Symbol {
|
Symbol {
|
||||||
source_worktree_id,
|
|
||||||
worktree_id,
|
|
||||||
language_server_name,
|
language_server_name,
|
||||||
|
source_worktree_id,
|
||||||
|
path: project_path,
|
||||||
label: label.unwrap_or_else(|| {
|
label: label.unwrap_or_else(|| {
|
||||||
CodeLabel::plain(lsp_symbol.name.clone(), None)
|
CodeLabel::plain(lsp_symbol.name.clone(), None)
|
||||||
}),
|
}),
|
||||||
kind: lsp_symbol.kind,
|
kind: lsp_symbol.kind,
|
||||||
name: lsp_symbol.name,
|
name: lsp_symbol.name,
|
||||||
path,
|
|
||||||
range: range_from_lsp(lsp_symbol.location.range),
|
range: range_from_lsp(lsp_symbol.location.range),
|
||||||
signature,
|
signature,
|
||||||
}
|
}
|
||||||
|
@ -3410,7 +3411,7 @@ impl Project {
|
||||||
};
|
};
|
||||||
|
|
||||||
let worktree_abs_path = if let Some(worktree_abs_path) = self
|
let worktree_abs_path = if let Some(worktree_abs_path) = self
|
||||||
.worktree_for_id(symbol.worktree_id, cx)
|
.worktree_for_id(symbol.path.worktree_id, cx)
|
||||||
.and_then(|worktree| worktree.read(cx).as_local())
|
.and_then(|worktree| worktree.read(cx).as_local())
|
||||||
.map(|local_worktree| local_worktree.abs_path())
|
.map(|local_worktree| local_worktree.abs_path())
|
||||||
{
|
{
|
||||||
|
@ -3418,7 +3419,7 @@ impl Project {
|
||||||
} else {
|
} else {
|
||||||
return Task::ready(Err(anyhow!("worktree not found for symbol")));
|
return Task::ready(Err(anyhow!("worktree not found for symbol")));
|
||||||
};
|
};
|
||||||
let symbol_abs_path = worktree_abs_path.join(&symbol.path);
|
let symbol_abs_path = worktree_abs_path.join(&symbol.path.path);
|
||||||
let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
|
let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
|
||||||
uri
|
uri
|
||||||
} else {
|
} else {
|
||||||
|
@ -4622,11 +4623,11 @@ impl Project {
|
||||||
self.active_entry
|
self.active_entry
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn entry_for_path(&self, path: &ProjectPath, cx: &AppContext) -> Option<ProjectEntryId> {
|
pub fn entry_for_path(&self, path: &ProjectPath, cx: &AppContext) -> Option<Entry> {
|
||||||
self.worktree_for_id(path.worktree_id, cx)?
|
self.worktree_for_id(path.worktree_id, cx)?
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.entry_for_path(&path.path)
|
.entry_for_path(&path.path)
|
||||||
.map(|entry| entry.id)
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path_for_entry(&self, entry_id: ProjectEntryId, cx: &AppContext) -> Option<ProjectPath> {
|
pub fn path_for_entry(&self, entry_id: ProjectEntryId, cx: &AppContext) -> Option<ProjectPath> {
|
||||||
|
@ -5436,7 +5437,7 @@ impl Project {
|
||||||
.read_with(&cx, |this, _| this.deserialize_symbol(symbol))
|
.read_with(&cx, |this, _| this.deserialize_symbol(symbol))
|
||||||
.await?;
|
.await?;
|
||||||
let symbol = this.read_with(&cx, |this, _| {
|
let symbol = this.read_with(&cx, |this, _| {
|
||||||
let signature = this.symbol_signature(symbol.worktree_id, &symbol.path);
|
let signature = this.symbol_signature(&symbol.path);
|
||||||
if signature == symbol.signature {
|
if signature == symbol.signature {
|
||||||
Ok(symbol)
|
Ok(symbol)
|
||||||
} else {
|
} else {
|
||||||
|
@ -5454,10 +5455,10 @@ impl Project {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_signature(&self, worktree_id: WorktreeId, path: &Path) -> [u8; 32] {
|
fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(worktree_id.to_proto().to_be_bytes());
|
hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
|
||||||
hasher.update(path.to_string_lossy().as_bytes());
|
hasher.update(project_path.path.to_string_lossy().as_bytes());
|
||||||
hasher.update(self.nonce.to_be_bytes());
|
hasher.update(self.nonce.to_be_bytes());
|
||||||
hasher.finalize().as_slice().try_into().unwrap()
|
hasher.finalize().as_slice().try_into().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -5655,14 +5656,17 @@ impl Project {
|
||||||
.end
|
.end
|
||||||
.ok_or_else(|| anyhow!("invalid end"))?;
|
.ok_or_else(|| anyhow!("invalid end"))?;
|
||||||
let kind = unsafe { mem::transmute(serialized_symbol.kind) };
|
let kind = unsafe { mem::transmute(serialized_symbol.kind) };
|
||||||
let path = PathBuf::from(serialized_symbol.path);
|
let path = ProjectPath {
|
||||||
let language = languages.select_language(&path);
|
|
||||||
Ok(Symbol {
|
|
||||||
source_worktree_id,
|
|
||||||
worktree_id,
|
worktree_id,
|
||||||
|
path: PathBuf::from(serialized_symbol.path).into(),
|
||||||
|
};
|
||||||
|
let language = languages.select_language(&path.path);
|
||||||
|
Ok(Symbol {
|
||||||
language_server_name: LanguageServerName(
|
language_server_name: LanguageServerName(
|
||||||
serialized_symbol.language_server_name.into(),
|
serialized_symbol.language_server_name.into(),
|
||||||
),
|
),
|
||||||
|
source_worktree_id,
|
||||||
|
path,
|
||||||
label: {
|
label: {
|
||||||
match language {
|
match language {
|
||||||
Some(language) => {
|
Some(language) => {
|
||||||
|
@ -5676,7 +5680,6 @@ impl Project {
|
||||||
},
|
},
|
||||||
|
|
||||||
name: serialized_symbol.name,
|
name: serialized_symbol.name,
|
||||||
path,
|
|
||||||
range: PointUtf16::new(start.row, start.column)
|
range: PointUtf16::new(start.row, start.column)
|
||||||
..PointUtf16::new(end.row, end.column),
|
..PointUtf16::new(end.row, end.column),
|
||||||
kind,
|
kind,
|
||||||
|
@ -6142,12 +6145,12 @@ impl From<lsp::DeleteFileOptions> for fs::RemoveOptions {
|
||||||
|
|
||||||
fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
|
fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
|
||||||
proto::Symbol {
|
proto::Symbol {
|
||||||
source_worktree_id: symbol.source_worktree_id.to_proto(),
|
|
||||||
worktree_id: symbol.worktree_id.to_proto(),
|
|
||||||
language_server_name: symbol.language_server_name.0.to_string(),
|
language_server_name: symbol.language_server_name.0.to_string(),
|
||||||
|
source_worktree_id: symbol.source_worktree_id.to_proto(),
|
||||||
|
worktree_id: symbol.path.worktree_id.to_proto(),
|
||||||
|
path: symbol.path.path.to_string_lossy().to_string(),
|
||||||
name: symbol.name.clone(),
|
name: symbol.name.clone(),
|
||||||
kind: unsafe { mem::transmute(symbol.kind) },
|
kind: unsafe { mem::transmute(symbol.kind) },
|
||||||
path: symbol.path.to_string_lossy().to_string(),
|
|
||||||
start: Some(proto::Point {
|
start: Some(proto::Point {
|
||||||
row: symbol.range.start.row,
|
row: symbol.range.start.row,
|
||||||
column: symbol.range.start.column,
|
column: symbol.range.start.column,
|
||||||
|
|
|
@ -26,7 +26,8 @@ pub struct ProjectSymbolsView {
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
selected_match_index: usize,
|
selected_match_index: usize,
|
||||||
symbols: Vec<Symbol>,
|
symbols: Vec<Symbol>,
|
||||||
match_candidates: Vec<StringMatchCandidate>,
|
visible_match_candidates: Vec<StringMatchCandidate>,
|
||||||
|
external_match_candidates: Vec<StringMatchCandidate>,
|
||||||
show_worktree_root_name: bool,
|
show_worktree_root_name: bool,
|
||||||
pending_update: Task<()>,
|
pending_update: Task<()>,
|
||||||
matches: Vec<StringMatch>,
|
matches: Vec<StringMatch>,
|
||||||
|
@ -63,7 +64,8 @@ impl ProjectSymbolsView {
|
||||||
picker: cx.add_view(|cx| Picker::new(handle, cx)),
|
picker: cx.add_view(|cx| Picker::new(handle, cx)),
|
||||||
selected_match_index: 0,
|
selected_match_index: 0,
|
||||||
symbols: Default::default(),
|
symbols: Default::default(),
|
||||||
match_candidates: Default::default(),
|
visible_match_candidates: Default::default(),
|
||||||
|
external_match_candidates: Default::default(),
|
||||||
matches: Default::default(),
|
matches: Default::default(),
|
||||||
show_worktree_root_name: false,
|
show_worktree_root_name: false,
|
||||||
pending_update: Task::ready(()),
|
pending_update: Task::ready(()),
|
||||||
|
@ -80,38 +82,39 @@ impl ProjectSymbolsView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter(&mut self, query: &str, cx: &mut ViewContext<Self>) {
|
fn filter(&mut self, query: &str, cx: &mut ViewContext<Self>) {
|
||||||
let mut matches = if query.is_empty() {
|
const MAX_MATCHES: usize = 100;
|
||||||
self.match_candidates
|
let mut visible_matches = cx.background_executor().block(fuzzy::match_strings(
|
||||||
.iter()
|
&self.visible_match_candidates,
|
||||||
.enumerate()
|
|
||||||
.map(|(candidate_id, candidate)| StringMatch {
|
|
||||||
candidate_id,
|
|
||||||
score: Default::default(),
|
|
||||||
positions: Default::default(),
|
|
||||||
string: candidate.string.clone(),
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
cx.background_executor().block(fuzzy::match_strings(
|
|
||||||
&self.match_candidates,
|
|
||||||
query,
|
query,
|
||||||
false,
|
false,
|
||||||
100,
|
MAX_MATCHES,
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
cx.background().clone(),
|
cx.background().clone(),
|
||||||
))
|
));
|
||||||
};
|
let mut external_matches = cx.background_executor().block(fuzzy::match_strings(
|
||||||
|
&self.external_match_candidates,
|
||||||
matches.sort_unstable_by_key(|mat| {
|
query,
|
||||||
let label = &self.symbols[mat.candidate_id].label;
|
false,
|
||||||
|
MAX_MATCHES - visible_matches.len(),
|
||||||
|
&Default::default(),
|
||||||
|
cx.background().clone(),
|
||||||
|
));
|
||||||
|
let sort_key_for_match = |mat: &StringMatch| {
|
||||||
|
let symbol = &self.symbols[mat.candidate_id];
|
||||||
(
|
(
|
||||||
Reverse(OrderedFloat(mat.score)),
|
Reverse(OrderedFloat(mat.score)),
|
||||||
&label.text[label.filter_range.clone()],
|
&symbol.label.text[symbol.label.filter_range.clone()],
|
||||||
)
|
)
|
||||||
});
|
};
|
||||||
|
|
||||||
|
visible_matches.sort_unstable_by_key(sort_key_for_match);
|
||||||
|
external_matches.sort_unstable_by_key(sort_key_for_match);
|
||||||
|
let mut matches = visible_matches;
|
||||||
|
matches.append(&mut external_matches);
|
||||||
|
|
||||||
for mat in &mut matches {
|
for mat in &mut matches {
|
||||||
let filter_start = self.symbols[mat.candidate_id].label.filter_range.start;
|
let symbol = &self.symbols[mat.candidate_id];
|
||||||
|
let filter_start = symbol.label.filter_range.start;
|
||||||
for position in &mut mat.positions {
|
for position in &mut mat.positions {
|
||||||
*position += filter_start;
|
*position += filter_start;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +201,8 @@ impl PickerDelegate for ProjectSymbolsView {
|
||||||
if let Some(this) = this.upgrade(&cx) {
|
if let Some(this) = this.upgrade(&cx) {
|
||||||
if let Some(symbols) = symbols {
|
if let Some(symbols) = symbols {
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.match_candidates = symbols
|
let project = this.project.read(cx);
|
||||||
|
let (visible_match_candidates, external_match_candidates) = symbols
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(id, symbol)| {
|
.map(|(id, symbol)| {
|
||||||
|
@ -208,7 +212,14 @@ impl PickerDelegate for ProjectSymbolsView {
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.partition(|candidate| {
|
||||||
|
project
|
||||||
|
.entry_for_path(&symbols[candidate.id].path, cx)
|
||||||
|
.map_or(false, |e| !e.is_ignored)
|
||||||
|
});
|
||||||
|
|
||||||
|
this.visible_match_candidates = visible_match_candidates;
|
||||||
|
this.external_match_candidates = external_match_candidates;
|
||||||
this.symbols = symbols;
|
this.symbols = symbols;
|
||||||
this.filter(&query, cx);
|
this.filter(&query, cx);
|
||||||
});
|
});
|
||||||
|
@ -232,10 +243,10 @@ impl PickerDelegate for ProjectSymbolsView {
|
||||||
let symbol = &self.symbols[string_match.candidate_id];
|
let symbol = &self.symbols[string_match.candidate_id];
|
||||||
let syntax_runs = styled_runs_for_code_label(&symbol.label, &settings.theme.editor.syntax);
|
let syntax_runs = styled_runs_for_code_label(&symbol.label, &settings.theme.editor.syntax);
|
||||||
|
|
||||||
let mut path = symbol.path.to_string_lossy();
|
let mut path = symbol.path.path.to_string_lossy();
|
||||||
if self.show_worktree_root_name {
|
if self.show_worktree_root_name {
|
||||||
let project = self.project.read(cx);
|
let project = self.project.read(cx);
|
||||||
if let Some(worktree) = project.worktree_for_id(symbol.worktree_id, cx) {
|
if let Some(worktree) = project.worktree_for_id(symbol.path.worktree_id, cx) {
|
||||||
path = Cow::Owned(format!(
|
path = Cow::Owned(format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
worktree.read(cx).root_name(),
|
worktree.read(cx).root_name(),
|
||||||
|
@ -275,7 +286,7 @@ mod tests {
|
||||||
use gpui::{serde_json::json, TestAppContext};
|
use gpui::{serde_json::json, TestAppContext};
|
||||||
use language::{FakeLspAdapter, Language, LanguageConfig};
|
use language::{FakeLspAdapter, Language, LanguageConfig};
|
||||||
use project::FakeFs;
|
use project::FakeFs;
|
||||||
use std::sync::Arc;
|
use std::{path::Path, sync::Arc};
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_project_symbols(cx: &mut TestAppContext) {
|
async fn test_project_symbols(cx: &mut TestAppContext) {
|
||||||
|
@ -309,15 +320,21 @@ mod tests {
|
||||||
|
|
||||||
// Set up fake langauge server to return fuzzy matches against
|
// Set up fake langauge server to return fuzzy matches against
|
||||||
// a fixed set of symbol names.
|
// a fixed set of symbol names.
|
||||||
let fake_symbol_names = ["one", "ton", "uno"];
|
let fake_symbols = [
|
||||||
|
symbol("one", "/external"),
|
||||||
|
symbol("ton", "/dir/test.rs"),
|
||||||
|
symbol("uno", "/dir/test.rs"),
|
||||||
|
];
|
||||||
let fake_server = fake_servers.next().await.unwrap();
|
let fake_server = fake_servers.next().await.unwrap();
|
||||||
fake_server.handle_request::<lsp::request::WorkspaceSymbol, _, _>(
|
fake_server.handle_request::<lsp::request::WorkspaceSymbol, _, _>(
|
||||||
move |params: lsp::WorkspaceSymbolParams, cx| {
|
move |params: lsp::WorkspaceSymbolParams, cx| {
|
||||||
let executor = cx.background();
|
let executor = cx.background();
|
||||||
|
let fake_symbols = fake_symbols.clone();
|
||||||
async move {
|
async move {
|
||||||
let candidates = fake_symbol_names
|
let candidates = fake_symbols
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|name| StringMatchCandidate::new(0, name.into()))
|
.enumerate()
|
||||||
|
.map(|(id, symbol)| StringMatchCandidate::new(id, symbol.name.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let matches = if params.query.is_empty() {
|
let matches = if params.query.is_empty() {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
|
@ -334,7 +351,10 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
matches.into_iter().map(|mat| symbol(&mat.string)).collect(),
|
matches
|
||||||
|
.into_iter()
|
||||||
|
.map(|mat| fake_symbols[mat.candidate_id].clone())
|
||||||
|
.collect(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -367,8 +387,8 @@ mod tests {
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
symbols_view.read_with(cx, |symbols_view, _| {
|
symbols_view.read_with(cx, |symbols_view, _| {
|
||||||
assert_eq!(symbols_view.matches.len(), 2);
|
assert_eq!(symbols_view.matches.len(), 2);
|
||||||
assert_eq!(symbols_view.matches[0].string, "one");
|
assert_eq!(symbols_view.matches[0].string, "ton");
|
||||||
assert_eq!(symbols_view.matches[1].string, "ton");
|
assert_eq!(symbols_view.matches[1].string, "one");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Spawn more updates such that in the end, there are again no matches.
|
// Spawn more updates such that in the end, there are again no matches.
|
||||||
|
@ -383,7 +403,7 @@ mod tests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol(name: &str) -> lsp::SymbolInformation {
|
fn symbol(name: &str, path: impl AsRef<Path>) -> lsp::SymbolInformation {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
lsp::SymbolInformation {
|
lsp::SymbolInformation {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
@ -392,7 +412,7 @@ mod tests {
|
||||||
deprecated: None,
|
deprecated: None,
|
||||||
container_name: None,
|
container_name: None,
|
||||||
location: lsp::Location::new(
|
location: lsp::Location::new(
|
||||||
lsp::Url::from_file_path("/a/b").unwrap(),
|
lsp::Url::from_file_path(path.as_ref()).unwrap(),
|
||||||
lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 0)),
|
lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 0)),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2821,7 +2821,9 @@ mod tests {
|
||||||
project.read_with(cx, |project, cx| {
|
project.read_with(cx, |project, cx| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
project.active_entry(),
|
project.active_entry(),
|
||||||
project.entry_for_path(&(worktree_id, "one.txt").into(), cx)
|
project
|
||||||
|
.entry_for_path(&(worktree_id, "one.txt").into(), cx)
|
||||||
|
.map(|e| e.id)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -2838,7 +2840,9 @@ mod tests {
|
||||||
project.read_with(cx, |project, cx| {
|
project.read_with(cx, |project, cx| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
project.active_entry(),
|
project.active_entry(),
|
||||||
project.entry_for_path(&(worktree_id, "two.txt").into(), cx)
|
project
|
||||||
|
.entry_for_path(&(worktree_id, "two.txt").into(), cx)
|
||||||
|
.map(|e| e.id)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2856,7 +2860,9 @@ mod tests {
|
||||||
project.read_with(cx, |project, cx| {
|
project.read_with(cx, |project, cx| {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
project.active_entry(),
|
project.active_entry(),
|
||||||
project.entry_for_path(&(worktree_id, "one.txt").into(), cx)
|
project
|
||||||
|
.entry_for_path(&(worktree_id, "one.txt").into(), cx)
|
||||||
|
.map(|e| e.id)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue