Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions crates/languages/src/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,13 +568,14 @@ impl LspAdapter for RustLspAdapter {
language: &Arc<Language>,
) -> Option<CodeLabel> {
let (prefix, suffix) = match kind {
lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => ("fn ", " () {}"),
lsp::SymbolKind::STRUCT => ("struct ", " {}"),
lsp::SymbolKind::ENUM => ("enum ", " {}"),
lsp::SymbolKind::INTERFACE => ("trait ", " {}"),
lsp::SymbolKind::CONSTANT => ("const ", ": () = ();"),
lsp::SymbolKind::MODULE => ("mod ", " {}"),
lsp::SymbolKind::TYPE_PARAMETER => ("type ", " {}"),
lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => ("fn ", "();"),
lsp::SymbolKind::STRUCT => ("struct ", ";"),
lsp::SymbolKind::ENUM => ("enum ", "{}"),
lsp::SymbolKind::INTERFACE => ("trait ", "{}"),
lsp::SymbolKind::CONSTANT => ("const ", ":()=();"),
lsp::SymbolKind::MODULE => ("mod ", ";"),
lsp::SymbolKind::PACKAGE => ("extern crate ", ";"),
lsp::SymbolKind::TYPE_PARAMETER => ("type ", "=();"),
_ => return None,
};

Expand Down Expand Up @@ -1824,6 +1825,17 @@ mod tests {
vec![(0..4, highlight_keyword), (5..10, highlight_type)],
))
);

assert_eq!(
adapter
.label_for_symbol("zed", lsp::SymbolKind::PACKAGE, &language)
.await,
Some(CodeLabel::new(
"extern crate zed".to_string(),
13..16,
vec![(0..6, highlight_keyword), (7..12, highlight_keyword),],
))
);
}

#[gpui::test]
Expand Down
82 changes: 49 additions & 33 deletions crates/project/src/lsp_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7810,46 +7810,62 @@ impl LspStore {
let worktree_handle = worktree_handle.clone();
let server_id = server.server_id();
requests.push(
server
.request::<lsp::request::WorkspaceSymbolRequest>(
lsp::WorkspaceSymbolParams {
query: query.to_string(),
..Default::default()
},
)
.map(move |response| {
let lsp_symbols = response.into_response()
.context("workspace symbols request")
.log_err()
.flatten()
.map(|symbol_response| match symbol_response {
lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
flat_responses.into_iter().map(|lsp_symbol| {
(lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
}).collect::<Vec<_>>()
}
lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
nested_responses.into_iter().filter_map(|lsp_symbol| {
server
.request::<lsp::request::WorkspaceSymbolRequest>(
lsp::WorkspaceSymbolParams {
query: query.to_string(),
..Default::default()
},
)
.map(move |response| {
let lsp_symbols = response
.into_response()
.context("workspace symbols request")
.log_err()
.flatten()
.map(|symbol_response| match symbol_response {
lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
flat_responses
.into_iter()
.map(|lsp_symbol| {
(
lsp_symbol.name,
lsp_symbol.kind,
lsp_symbol.location,
)
})
.collect::<Vec<_>>()
}
lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
nested_responses
.into_iter()
.filter_map(|lsp_symbol| {
let location = match lsp_symbol.location {
OneOf::Left(location) => location,
OneOf::Right(_) => {
log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
return None
log::error!(
"Unexpected: client capabilities \
forbid symbol resolutions in \
workspace.symbol.resolveSupport"
);
return None;
}
};
Some((lsp_symbol.name, lsp_symbol.kind, location))
}).collect::<Vec<_>>()
}
}).unwrap_or_default();
})
.collect::<Vec<_>>()
}
})
.unwrap_or_default();

WorkspaceSymbolsResult {
server_id,
lsp_adapter,
worktree: worktree_handle.downgrade(),
lsp_symbols,
}
}),
);
WorkspaceSymbolsResult {
server_id,
lsp_adapter,
worktree: worktree_handle.downgrade(),
lsp_symbols,
}
}),
);
}

cx.spawn(async move |this, cx| {
Expand Down
33 changes: 29 additions & 4 deletions crates/project_symbols/src/project_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,15 @@ impl PickerDelegate for ProjectSymbolsDelegate {
window: &mut Window,
cx: &mut Context<Picker<Self>>,
) -> Task<()> {
self.filter(&query, window, cx);
// Try to support rust-analyzer's path based symbols feature which
// allows to search by rust path syntax, in that case we only want to
// filter names by the last segment
// Ideally this was a first class LSP feature (rich queries)
let query_filter = query
.rsplit_once("::")
.map_or(&*query, |(_, suffix)| suffix)
.to_owned();
self.filter(&query_filter, window, cx);
self.show_worktree_root_name = self.project.read(cx).visible_worktrees(cx).count() > 1;
let symbols = self
.project
Expand Down Expand Up @@ -208,7 +216,7 @@ impl PickerDelegate for ProjectSymbolsDelegate {
delegate.visible_match_candidates = visible_match_candidates;
delegate.external_match_candidates = external_match_candidates;
delegate.symbols = symbols;
delegate.filter(&query, window, cx);
delegate.filter(&query_filter, window, cx);
})
.log_err();
}
Expand Down Expand Up @@ -354,17 +362,24 @@ mod tests {
let executor = cx.background_executor().clone();
let fake_symbols = fake_symbols.clone();
async move {
let (query, prefixed) = match params.query.strip_prefix("dir::") {
Some(query) => (query, true),
None => (&*params.query, false),
};
let candidates = fake_symbols
.iter()
.enumerate()
.filter(|(_, symbol)| {
!prefixed || symbol.location.uri.path().contains("dir")
})
.map(|(id, symbol)| StringMatchCandidate::new(id, &symbol.name))
.collect::<Vec<_>>();
let matches = if params.query.is_empty() {
let matches = if query.is_empty() {
Vec::new()
} else {
fuzzy::match_strings(
&candidates,
&params.query,
&query,
true,
true,
100,
Expand Down Expand Up @@ -434,6 +449,16 @@ mod tests {
symbols.read_with(cx, |symbols, _| {
assert_eq!(symbols.delegate.matches.len(), 0);
});

// Check that rust-analyzer path style symbols work
symbols.update_in(cx, |p, window, cx| {
p.update_matches("dir::to".to_string(), window, cx);
});

cx.run_until_parked();
symbols.read_with(cx, |symbols, _| {
assert_eq!(symbols.delegate.matches.len(), 1);
});
}

fn init_test(cx: &mut TestAppContext) {
Expand Down