on master help sign in
add option to enable/disable lsp snippets
9fe3adcPascal Kuthe
book/src/configuration.md+1
@@ -127,6 +127,7 @@ The following statusline elements can be configured:
127| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
127| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
128| `display-inlay-hints` | Display inlay hints[^2] | `false` |
128| `display-inlay-hints` | Display inlay hints[^2] | `false` |
129| `display-signature-help-docs` | Display docs under signature help popup | `true` |
129| `display-signature-help-docs` | Display docs under signature help popup | `true` |
130+| `snippets` | Enables snippet completions. Requires a server restart (`:lsp-restart`) to take effect after `:config-reload`/`:set`. | `true` |
130
131
131[^1]: By default, a progress spinner is shown in the statusline beside the file path.
132[^1]: By default, a progress spinner is shown in the statusline beside the file path.
132[^2]: You may also have to activate them in the LSP config for them to appear, not just in Helix.
133[^2]: You may also have to activate them in the LSP config for them to appear, not just in Helix.
helix-lsp/src/client.rs+2−2
@@ -411,7 +411,7 @@ impl Client {
411 // General messages
411 // General messages
412 // -------------------------------------------------------------------------------------------
412 // -------------------------------------------------------------------------------------------
413
413
414− pub(crate) async fn initialize(&self) -> Result<lsp::InitializeResult> {
414+ pub(crate) async fn initialize(&self, enable_snippets: bool) -> Result<lsp::InitializeResult> {
415 if let Some(config) = &self.config {
415 if let Some(config) = &self.config {
416 log::info!("Using custom LSP config: {}", config);
416 log::info!("Using custom LSP config: {}", config);
417 }
417 }
@@ -459,7 +459,7 @@ impl Client {
459 text_document: Some(lsp::TextDocumentClientCapabilities {
459 text_document: Some(lsp::TextDocumentClientCapabilities {
460 completion: Some(lsp::CompletionClientCapabilities {
460 completion: Some(lsp::CompletionClientCapabilities {
461 completion_item: Some(lsp::CompletionItemCapability {
461 completion_item: Some(lsp::CompletionItemCapability {
462− snippet_support: Some(true),
462+ snippet_support: Some(enable_snippets),
463 resolve_support: Some(lsp::CompletionItemCapabilityResolveSupport {
463 resolve_support: Some(lsp::CompletionItemCapabilityResolveSupport {
464 properties: vec![
464 properties: vec![
465 String::from("documentation"),
465 String::from("documentation"),
helix-lsp/src/lib.rs+20−5
@@ -647,6 +647,7 @@ impl Registry {
647 language_config: &LanguageConfiguration,
647 language_config: &LanguageConfiguration,
648 doc_path: Option<&std::path::PathBuf>,
648 doc_path: Option<&std::path::PathBuf>,
649 root_dirs: &[PathBuf],
649 root_dirs: &[PathBuf],
650+ enable_snippets: bool,
650 ) -> Result<Option<Arc<Client>>> {
651 ) -> Result<Option<Arc<Client>>> {
651 let config = match &language_config.language_server {
652 let config = match &language_config.language_server {
652 Some(config) => config,
653 Some(config) => config,
@@ -661,8 +662,14 @@ impl Registry {
661 // initialize a new client
662 // initialize a new client
662 let id = self.counter.fetch_add(1, Ordering::Relaxed);
663 let id = self.counter.fetch_add(1, Ordering::Relaxed);
663
664
664− let NewClientResult(client, incoming) =
665+ let NewClientResult(client, incoming) = start_client(
666+ id,
665− start_client(id, language_config, config, doc_path, root_dirs)?;
667+ language_config,
668+ config,
669+ doc_path,
670+ root_dirs,
671+ enable_snippets,
672+ )?;
666 self.incoming.push(UnboundedReceiverStream::new(incoming));
673 self.incoming.push(UnboundedReceiverStream::new(incoming));
667
674
668 let old_clients = entry.insert(vec![(id, client.clone())]);
675 let old_clients = entry.insert(vec![(id, client.clone())]);
@@ -695,6 +702,7 @@ impl Registry {
695 language_config: &LanguageConfiguration,
702 language_config: &LanguageConfiguration,
696 doc_path: Option<&std::path::PathBuf>,
703 doc_path: Option<&std::path::PathBuf>,
697 root_dirs: &[PathBuf],
704 root_dirs: &[PathBuf],
705+ enable_snippets: bool,
698 ) -> Result<Option<Arc<Client>>> {
706 ) -> Result<Option<Arc<Client>>> {
699 let config = match &language_config.language_server {
707 let config = match &language_config.language_server {
700 Some(config) => config,
708 Some(config) => config,
@@ -711,8 +719,14 @@ impl Registry {
711 // initialize a new client
719 // initialize a new client
712 let id = self.counter.fetch_add(1, Ordering::Relaxed);
720 let id = self.counter.fetch_add(1, Ordering::Relaxed);
713
721
714− let NewClientResult(client, incoming) =
722+ let NewClientResult(client, incoming) = start_client(
723+ id,
715− start_client(id, language_config, config, doc_path, root_dirs)?;
724+ language_config,
725+ config,
726+ doc_path,
727+ root_dirs,
728+ enable_snippets,
729+ )?;
716 clients.push((id, client.clone()));
730 clients.push((id, client.clone()));
717 self.incoming.push(UnboundedReceiverStream::new(incoming));
731 self.incoming.push(UnboundedReceiverStream::new(incoming));
718 Ok(Some(client))
732 Ok(Some(client))
@@ -811,6 +825,7 @@ fn start_client(
811 ls_config: &LanguageServerConfiguration,
825 ls_config: &LanguageServerConfiguration,
812 doc_path: Option<&std::path::PathBuf>,
826 doc_path: Option<&std::path::PathBuf>,
813 root_dirs: &[PathBuf],
827 root_dirs: &[PathBuf],
828+ enable_snippets: bool,
814) -> Result<NewClientResult> {
829) -> Result<NewClientResult> {
815 let (client, incoming, initialize_notify) = Client::start(
830 let (client, incoming, initialize_notify) = Client::start(
816 &ls_config.command,
831 &ls_config.command,
@@ -834,7 +849,7 @@ fn start_client(
834 .capabilities
849 .capabilities
835 .get_or_try_init(|| {
850 .get_or_try_init(|| {
836 _client
851 _client
837− .initialize()
852+ .initialize(enable_snippets)
838 .map_ok(|response| response.capabilities)
853 .map_ok(|response| response.capabilities)
839 })
854 })
840 .await;
855 .await;
helix-term/src/commands/typed.rs+6−3
@@ -1378,9 +1378,12 @@ fn lsp_restart(
1378 .context("LSP not defined for the current document")?;
1378 .context("LSP not defined for the current document")?;
1379
1379
1380 let scope = config.scope.clone();
1380 let scope = config.scope.clone();
1381− cx.editor
1382− .language_servers
1381+ cx.editor.language_servers.restart(
1382+ config,
1383+ doc.path(),
1383− .restart(config, doc.path(), &editor_config.workspace_lsp_roots)?;
1384+ &editor_config.workspace_lsp_roots,
1385+ editor_config.lsp.snippets,
1386+ )?;
1384
1387
1385 // This collect is needed because refresh_language_server would need to re-borrow editor.
1388 // This collect is needed because refresh_language_server would need to re-borrow editor.
1386 let document_ids_to_refresh: Vec<DocumentId> = cx
1389 let document_ids_to_refresh: Vec<DocumentId> = cx
helix-view/src/editor.rs+6−2
@@ -352,6 +352,8 @@ pub struct LspConfig {
352 pub display_signature_help_docs: bool,
352 pub display_signature_help_docs: bool,
353 /// Display inlay hints
353 /// Display inlay hints
354 pub display_inlay_hints: bool,
354 pub display_inlay_hints: bool,
355+ /// Whether to enable snippet support
356+ pub snippets: bool,
355}
357}
356
358
357impl Default for LspConfig {
359impl Default for LspConfig {
@@ -362,6 +364,7 @@ impl Default for LspConfig {
362 auto_signature_help: true,
364 auto_signature_help: true,
363 display_signature_help_docs: true,
365 display_signature_help_docs: true,
364 display_inlay_hints: false,
366 display_inlay_hints: false,
367+ snippets: true,
365 }
368 }
366 }
369 }
367}
370}
@@ -1092,12 +1095,13 @@ impl Editor {
1092 // if doc doesn't have a URL it's a scratch buffer, ignore it
1095 // if doc doesn't have a URL it's a scratch buffer, ignore it
1093 let doc = self.document(doc_id)?;
1096 let doc = self.document(doc_id)?;
1094 let (lang, path) = (doc.language.clone(), doc.path().cloned());
1097 let (lang, path) = (doc.language.clone(), doc.path().cloned());
1095− let root_dirs = &doc.config.load().workspace_lsp_roots;
1098+ let config = doc.config.load();
1099+ let root_dirs = &config.workspace_lsp_roots;
1096
1100
1097 // try to find a language server based on the language name
1101 // try to find a language server based on the language name
1098 let language_server = lang.as_ref().and_then(|language| {
1102 let language_server = lang.as_ref().and_then(|language| {
1099 self.language_servers
1103 self.language_servers
1100− .get(language, path.as_ref(), root_dirs)
1104+ .get(language, path.as_ref(), root_dirs, config.lsp.snippets)
1101 .map_err(|e| {
1105 .map_err(|e| {
1102 log::error!(
1106 log::error!(
1103 "Failed to initialize the LSP for `{}` {{ {} }}",
1107 "Failed to initialize the LSP for `{}` {{ {} }}",