aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/commands/lsp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/commands/lsp.rs')
-rw-r--r--helix-term/src/commands/lsp.rs50
1 files changed, 45 insertions, 5 deletions
diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs
index 810e3adf..8052dcac 100644
--- a/helix-term/src/commands/lsp.rs
+++ b/helix-term/src/commands/lsp.rs
@@ -1,3 +1,4 @@
+use futures_util::FutureExt;
use helix_lsp::{
block_on,
lsp::{self, CodeAction, CodeActionOrCommand, DiagnosticSeverity, NumberOrString},
@@ -14,7 +15,8 @@ use helix_view::{apply_transaction, document::Mode, editor::Action, theme::Style
use crate::{
compositor::{self, Compositor},
ui::{
- self, lsp::SignatureHelp, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent,
+ self, lsp::SignatureHelp, overlay::overlayed, DynamicPicker, FileLocation, FilePicker,
+ Popup, PromptEvent,
},
};
@@ -384,10 +386,48 @@ pub fn workspace_symbol_picker(cx: &mut Context) {
cx.callback(
future,
move |_editor, compositor, response: Option<Vec<lsp::SymbolInformation>>| {
- if let Some(symbols) = response {
- let picker = sym_picker(symbols, current_url, offset_encoding);
- compositor.push(Box::new(overlayed(picker)))
- }
+ let symbols = match response {
+ Some(s) => s,
+ None => return,
+ };
+ let picker = sym_picker(symbols, current_url, offset_encoding);
+ let get_symbols = |query: String, editor: &mut Editor| {
+ let doc = doc!(editor);
+ let language_server = match doc.language_server() {
+ Some(s) => s,
+ None => {
+ // This should not generally happen since the picker will not
+ // even open in the first place if there is no server.
+ return async move { Err(anyhow::anyhow!("LSP not active")) }.boxed();
+ }
+ };
+ let symbol_request = match language_server.workspace_symbols(query) {
+ Some(future) => future,
+ None => {
+ // This should also not happen since the language server must have
+ // supported workspace symbols before to reach this block.
+ return async move {
+ Err(anyhow::anyhow!(
+ "Language server does not support workspace symbols"
+ ))
+ }
+ .boxed();
+ }
+ };
+
+ let future = async move {
+ let json = symbol_request.await?;
+ let response: Option<Vec<lsp::SymbolInformation>> =
+ serde_json::from_value(json)?;
+
+ response.ok_or_else(|| {
+ anyhow::anyhow!("No response for workspace symbols from language server")
+ })
+ };
+ future.boxed()
+ };
+ let dyn_picker = DynamicPicker::new(picker, Box::new(get_symbols));
+ compositor.push(Box::new(overlayed(dyn_picker)))
},
)
}