on master help sign in
Re-request workspace symbols on keypress in picker
d1f717eGokul Soumya
helix-term/src/commands/lsp.rs+45−5
@@ -1,3 +1,4 @@
1+use futures_util::FutureExt;
1use helix_lsp::{
2use helix_lsp::{
2 block_on,
3 block_on,
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},
16 ui::{
17 ui::{
17− self, lsp::SignatureHelp, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent,
18+ self, lsp::SignatureHelp, overlay::overlayed, DynamicPicker, FileLocation, FilePicker,
19+ Popup, PromptEvent,
18 },
20 },
19};
21};
20
22
@@ -384,10 +386,48 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
384 cx.callback(
386 cx.callback(
385 future,
387 future,
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 {
390+ Some(s) => s,
391+ None => return,
392+ };
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() {
397+ Some(s) => s,
398+ None => {
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();
402+ }
403+ };
404+ let symbol_request = match language_server.workspace_symbols(query) {
405+ Some(future) => future,
406+ None => {
407+ // This should also not happen since the language server must have
408+ // supported workspace symbols before to reach this block.
409+ return async move {
410+ Err(anyhow::anyhow!(
411+ "Language server does not support workspace symbols"
412+ ))
413+ }
414+ .boxed();
415+ }
416+ };
417+
418+ let future = async move {
419+ let json = symbol_request.await?;
420+ let response: Option<Vec<lsp::SymbolInformation>> =
421+ serde_json::from_value(json)?;
422+
423+ response.ok_or_else(|| {
424+ anyhow::anyhow!("No response for workspace symbols from language server")
425+ })
426+ };
427+ future.boxed()
428+ };
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)))
390− }
391 },
431 },
392 )
432 )
393}
433}