@@ -1,3 +1,4 @@
1+use futures_util::FutureExt;
1use helix_lsp::{
2use helix_lsp::{
3 lsp::{self, CodeAction, CodeActionOrCommand, DiagnosticSeverity, NumberOrString},
4 lsp::{self, CodeAction, CodeActionOrCommand, DiagnosticSeverity, NumberOrString},
@@ -14,7 +15,8 @@ use helix_view::{apply_transaction, document::Mode, editor::Action, theme::Style
14use crate::{
15use crate::{
15 compositor::{self, Compositor},
16 compositor::{self, Compositor},
17− self, lsp::SignatureHelp, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent,
18+ self, lsp::SignatureHelp, overlay::overlayed, DynamicPicker, FileLocation, FilePicker,
@@ -384,10 +386,48 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
384 cx.callback(
386 cx.callback(
386 move |_editor, compositor, response: Option<Vec<lsp::SymbolInformation>>| {
388 move |_editor, compositor, response: Option<Vec<lsp::SymbolInformation>>| {
387− if let Some(symbols) = response {
389+ let symbols = match response {
388− let picker = sym_picker(symbols, current_url, offset_encoding);
393+ let picker = sym_picker(symbols, current_url, offset_encoding);
394+ let get_symbols = |query: String, editor: &mut Editor| {
395+ let doc = doc!(editor);
396+ let language_server = match doc.language_server() {
399+ // This should not generally happen since the picker will not
400+ // even open in the first place if there is no server.
401+ return async move { Err(anyhow::anyhow!("LSP not active")) }.boxed();
404+ let symbol_request = match language_server.workspace_symbols(query) {
405+ Some(future) => future,
407+ // This should also not happen since the language server must have
408+ // supported workspace symbols before to reach this block.
410+ Err(anyhow::anyhow!(
411+ "Language server does not support workspace symbols"
418+ let future = async move {
419+ let json = symbol_request.await?;
420+ let response: Option<Vec<lsp::SymbolInformation>> =
421+ serde_json::from_value(json)?;
423+ response.ok_or_else(|| {
424+ anyhow::anyhow!("No response for workspace symbols from language server")
429+ let dyn_picker = DynamicPicker::new(picker, Box::new(get_symbols));
389− compositor.push(Box::new(overlayed(picker)))
430+ compositor.push(Box::new(overlayed(dyn_picker)))