Skip to content

Commit

Permalink
add option to enable/disable lsp snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalkuthe committed Mar 30, 2023
1 parent 8b3a386 commit ec8cfa4
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 19 deletions.
1 change: 1 addition & 0 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ The following statusline elements can be configured:
| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
| `display-inlay-hints` | Display inlay hints[^2] | `false` |
| `display-signature-help-docs` | Display docs under signature help popup | `true` |
| `enable_snippet` | Enable snippet completions | `true` |

[^1]: By default, a progress spinner is shown in the statusline beside the file path.
[^2]: You may also have to activate them in the LSP config for them to appear, not just in Helix.
Expand Down
4 changes: 2 additions & 2 deletions helix-lsp/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ impl Client {
// General messages
// -------------------------------------------------------------------------------------------

pub(crate) async fn initialize(&self) -> Result<lsp::InitializeResult> {
pub(crate) async fn initialize(&self, enable_snippets: bool) -> Result<lsp::InitializeResult> {
if let Some(config) = &self.config {
log::info!("Using custom LSP config: {}", config);
}
Expand Down Expand Up @@ -459,7 +459,7 @@ impl Client {
text_document: Some(lsp::TextDocumentClientCapabilities {
completion: Some(lsp::CompletionClientCapabilities {
completion_item: Some(lsp::CompletionItemCapability {
snippet_support: Some(true),
snippet_support: Some(enable_snippets),
resolve_support: Some(lsp::CompletionItemCapabilityResolveSupport {
properties: vec![
String::from("documentation"),
Expand Down
33 changes: 28 additions & 5 deletions helix-lsp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,14 @@ pub mod util {
transaction.with_selection(selection)
}

pub fn is_snippet(item: &lsp::CompletionItem) -> bool {
matches!(item.kind, Some(lsp::CompletionItemKind::SNIPPET))
|| matches!(
item.insert_text_format,
Some(lsp::InsertTextFormat::SNIPPET)
)
}

/// Creates a [Transaction] from the [snippet::Snippet] in a completion response.
/// The transaction applies the edit to all cursors.
#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -647,6 +655,7 @@ impl Registry {
language_config: &LanguageConfiguration,
doc_path: Option<&std::path::PathBuf>,
root_dirs: &[PathBuf],
enable_snippets: bool,
) -> Result<Option<Arc<Client>>> {
let config = match &language_config.language_server {
Some(config) => config,
Expand All @@ -661,8 +670,14 @@ impl Registry {
// initialize a new client
let id = self.counter.fetch_add(1, Ordering::Relaxed);

let NewClientResult(client, incoming) =
start_client(id, language_config, config, doc_path, root_dirs)?;
let NewClientResult(client, incoming) = start_client(
id,
language_config,
config,
doc_path,
root_dirs,
enable_snippets,
)?;
self.incoming.push(UnboundedReceiverStream::new(incoming));

let old_clients = entry.insert(vec![(id, client.clone())]);
Expand Down Expand Up @@ -695,6 +710,7 @@ impl Registry {
language_config: &LanguageConfiguration,
doc_path: Option<&std::path::PathBuf>,
root_dirs: &[PathBuf],
enable_snippets: bool,
) -> Result<Option<Arc<Client>>> {
let config = match &language_config.language_server {
Some(config) => config,
Expand All @@ -711,8 +727,14 @@ impl Registry {
// initialize a new client
let id = self.counter.fetch_add(1, Ordering::Relaxed);

let NewClientResult(client, incoming) =
start_client(id, language_config, config, doc_path, root_dirs)?;
let NewClientResult(client, incoming) = start_client(
id,
language_config,
config,
doc_path,
root_dirs,
enable_snippets,
)?;
clients.push((id, client.clone()));
self.incoming.push(UnboundedReceiverStream::new(incoming));
Ok(Some(client))
Expand Down Expand Up @@ -811,6 +833,7 @@ fn start_client(
ls_config: &LanguageServerConfiguration,
doc_path: Option<&std::path::PathBuf>,
root_dirs: &[PathBuf],
enable_snippets: bool,
) -> Result<NewClientResult> {
let (client, incoming, initialize_notify) = Client::start(
&ls_config.command,
Expand All @@ -834,7 +857,7 @@ fn start_client(
.capabilities
.get_or_try_init(|| {
_client
.initialize()
.initialize(enable_snippets)
.map_ok(|response| response.capabilities)
})
.await;
Expand Down
9 changes: 6 additions & 3 deletions helix-term/src/commands/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1378,9 +1378,12 @@ fn lsp_restart(
.context("LSP not defined for the current document")?;

let scope = config.scope.clone();
cx.editor
.language_servers
.restart(config, doc.path(), &editor_config.workspace_lsp_roots)?;
cx.editor.language_servers.restart(
config,
doc.path(),
&editor_config.workspace_lsp_roots,
editor_config.lsp.enable_snippets,
)?;

// This collect is needed because refresh_language_server would need to re-borrow editor.
let document_ids_to_refresh: Vec<DocumentId> = cx
Expand Down
16 changes: 9 additions & 7 deletions helix-term/src/ui/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use helix_view::{graphics::Rect, Document, Editor};
use crate::commands;
use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent};

use helix_lsp::{lsp, util};
use helix_lsp::{
lsp,
util::{self, is_snippet},
};
use lsp::CompletionItem;

impl menu::Item for CompletionItem {
Expand Down Expand Up @@ -107,8 +110,12 @@ impl Completion {
offset_encoding: helix_lsp::OffsetEncoding,
start_offset: usize,
trigger_offset: usize,
show_snippets: bool,
) -> Self {
let replace_mode = editor.config().completion_replace;
if !show_snippets {
items.retain(|completion| !is_snippet(completion))
}
// Sort completion items according to their preselect status (given by the LSP server)
items.sort_by_key(|item| !item.preselect.unwrap_or(false));

Expand Down Expand Up @@ -166,12 +173,7 @@ impl Completion {
(None, new_text)
};

if matches!(item.kind, Some(lsp::CompletionItemKind::SNIPPET))
|| matches!(
item.insert_text_format,
Some(lsp::InsertTextFormat::SNIPPET)
)
{
if is_snippet(item) {
match snippet::parse(&new_text) {
Ok(snippet) => util::generate_transaction_from_snippet(
doc.text(),
Expand Down
1 change: 1 addition & 0 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ impl EditorView {
offset_encoding,
start_offset,
trigger_offset,
editor.config().lsp.enable_snippets,
);

if completion.is_empty() {
Expand Down
13 changes: 11 additions & 2 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ pub struct LspConfig {
pub display_signature_help_docs: bool,
/// Display inlay hints
pub display_inlay_hints: bool,
/// Whether to enable snippet support
pub enable_snippets: bool,
}

impl Default for LspConfig {
Expand All @@ -362,6 +364,7 @@ impl Default for LspConfig {
auto_signature_help: true,
display_signature_help_docs: true,
display_inlay_hints: false,
enable_snippets: true,
}
}
}
Expand Down Expand Up @@ -1092,12 +1095,18 @@ impl Editor {
// if doc doesn't have a URL it's a scratch buffer, ignore it
let doc = self.document(doc_id)?;
let (lang, path) = (doc.language.clone(), doc.path().cloned());
let root_dirs = &doc.config.load().workspace_lsp_roots;
let config = doc.config.load();
let root_dirs = &config.workspace_lsp_roots;

// try to find a language server based on the language name
let language_server = lang.as_ref().and_then(|language| {
self.language_servers
.get(language, path.as_ref(), root_dirs)
.get(
language,
path.as_ref(),
root_dirs,
config.lsp.enable_snippets,
)
.map_err(|e| {
log::error!(
"Failed to initialize the LSP for `{}` {{ {} }}",
Expand Down

0 comments on commit ec8cfa4

Please sign in to comment.