Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide option to completely disable LSP #4425

Merged
merged 3 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ The following statusline elements can be configured:

| Key | Description | Default |
| --- | ----------- | ------- |
| `enable` | Enables LSP integration. Setting to false will completely disable language servers regardless of language settings.| `true` |
| `display-messages` | Display LSP progress messages below statusline[^1] | `false` |
| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
| `display-signature-help-docs` | Display docs under signature help popup | `true` |
Expand Down
2 changes: 1 addition & 1 deletion helix-term/tests/test/auto_indent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ async fn auto_indent_c() -> anyhow::Result<()> {
files: vec![(PathBuf::from("foo.c"), Position::default())],
..Default::default()
},
Config::default(),
helpers::test_config(),
helpers::test_syntax_conf(None),
// switches to append mode?
(
Expand Down
43 changes: 20 additions & 23 deletions helix-term/tests/test/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use std::{
use anyhow::bail;
use crossterm::event::{Event, KeyEvent};
use helix_core::{diagnostic::Severity, test, Selection, Transaction};
use helix_term::{application::Application, args::Args, config::Config};
use helix_view::{doc, input::parse_macro, Editor};
use helix_term::{application::Application, args::Args, config::Config, keymap::merge_keys};
use helix_view::{doc, editor::LspConfig, input::parse_macro, Editor};
use tempfile::NamedTempFile;
use tokio_stream::wrappers::UnboundedReceiverStream;

Expand Down Expand Up @@ -118,7 +118,7 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(
let test_case = test_case.into();
let mut app = match app {
Some(app) => app,
None => Application::new(Args::default(), Config::default(), test_syntax_conf(None))?,
None => Application::new(Args::default(), test_config(), test_syntax_conf(None))?,
};

let (view, doc) = helix_view::current!(app.editor);
Expand All @@ -143,27 +143,9 @@ pub async fn test_key_sequence_with_input_text<T: Into<TestCase>>(

/// Generates language configs that merge in overrides, like a user language
/// config. The argument string must be a raw TOML document.
///
/// By default, language server configuration is dropped from the languages.toml
/// document. If a language-server is necessary for a test, it must be explicitly
/// added in `overrides`.
pub fn test_syntax_conf(overrides: Option<String>) -> helix_core::syntax::Configuration {
let mut lang = helix_loader::config::default_lang_config();

for lang_config in lang
.as_table_mut()
.expect("Expected languages.toml to be a table")
.get_mut("language")
.expect("Expected languages.toml to have \"language\" keys")
.as_array_mut()
.expect("Expected an array of language configurations")
{
lang_config
.as_table_mut()
.expect("Expected language config to be a TOML table")
.remove("language-server");
}

if let Some(overrides) = overrides {
let override_toml = toml::from_str(&overrides).unwrap();
lang = helix_loader::merge_toml_values(lang, override_toml, 3);
Expand All @@ -177,11 +159,12 @@ pub fn test_syntax_conf(overrides: Option<String>) -> helix_core::syntax::Config
/// want to verify the resulting document and selection.
pub async fn test_with_config<T: Into<TestCase>>(
args: Args,
config: Config,
mut config: Config,
syn_conf: helix_core::syntax::Configuration,
test_case: T,
) -> anyhow::Result<()> {
let test_case = test_case.into();
config = helix_term::keymap::merge_keys(config);
let app = Application::new(args, config, syn_conf)?;

test_key_sequence_with_input_text(
Expand All @@ -205,7 +188,7 @@ pub async fn test_with_config<T: Into<TestCase>>(
pub async fn test<T: Into<TestCase>>(test_case: T) -> anyhow::Result<()> {
test_with_config(
Args::default(),
Config::default(),
test_config(),
test_syntax_conf(None),
test_case,
)
Expand All @@ -226,6 +209,20 @@ pub fn temp_file_with_contents<S: AsRef<str>>(
Ok(temp_file)
}

/// Generates a config with defaults more suitable for integration tests
pub fn test_config() -> Config {
merge_keys(Config {
editor: helix_view::editor::Config {
lsp: LspConfig {
enable: false,
..Default::default()
},
..Default::default()
},
..Default::default()
})
}

/// Replaces all LF chars with the system's appropriate line feed
/// character, and if one doesn't exist already, appends the system's
/// appropriate line ending to the end of a string.
Expand Down
4 changes: 2 additions & 2 deletions helix-view/src/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ macro_rules! command_provider {
primary_paste => $pr_get_prg:literal $( , $pr_get_arg:literal )* ;
primary_copy => $pr_set_prg:literal $( , $pr_set_arg:literal )* ;
) => {{
log::info!(
log::debug!(
"Using {} to interact with the system and selection (primary) clipboard",
if $set_prg != $get_prg { format!("{}+{}", $set_prg, $get_prg)} else { $set_prg.to_string() }
);
Expand Down Expand Up @@ -381,7 +381,7 @@ mod provider {

impl ClipboardProvider for WindowsProvider {
fn name(&self) -> Cow<str> {
log::info!("Using clipboard-win to interact with the system clipboard");
log::debug!("Using clipboard-win to interact with the system clipboard");
Cow::Borrowed("clipboard-win")
}

Expand Down
33 changes: 25 additions & 8 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ pub fn get_terminal_provider() -> Option<TerminalConfig> {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
pub struct LspConfig {
/// Enables LSP
pub enable: bool,
/// Display LSP progress messages below statusline
pub display_messages: bool,
/// Enable automatic pop up of signature help (parameter hints)
Expand All @@ -377,6 +379,7 @@ pub struct LspConfig {
impl Default for LspConfig {
fn default() -> Self {
Self {
enable: true,
display_messages: false,
auto_signature_help: true,
display_signature_help_docs: true,
Expand Down Expand Up @@ -1074,18 +1077,25 @@ impl Editor {

/// Refreshes the language server for a given document
pub fn refresh_language_server(&mut self, doc_id: DocumentId) -> Option<()> {
let doc = self.documents.get_mut(&doc_id)?;
Self::launch_language_server(&mut self.language_servers, doc)
self.launch_language_server(doc_id)
}

/// Launch a language server for a given document
fn launch_language_server(ls: &mut helix_lsp::Registry, doc: &mut Document) -> Option<()> {
fn launch_language_server(&mut self, doc_id: DocumentId) -> Option<()> {
if !self.config().lsp.enable {
return None;
}

// if doc doesn't have a URL it's a scratch buffer, ignore it
let doc_url = doc.url()?;
let (lang, path) = {
let doc = self.document(doc_id)?;
(doc.language.clone(), doc.path().cloned())
};

// try to find a language server based on the language name
let language_server = doc.language.as_ref().and_then(|language| {
ls.get(language, doc.path())
let language_server = lang.as_ref().and_then(|language| {
self.language_servers
.get(language, path.as_ref())
.map_err(|e| {
log::error!(
"Failed to initialize the LSP for `{}` {{ {} }}",
Expand All @@ -1096,6 +1106,10 @@ impl Editor {
.ok()
.flatten()
});

let doc = self.document_mut(doc_id)?;
let doc_url = doc.url()?;

if let Some(language_server) = language_server {
// only spawn a new lang server if the servers aren't the same
if Some(language_server.id()) != doc.language_server().map(|server| server.id()) {
Expand Down Expand Up @@ -1285,11 +1299,14 @@ impl Editor {
self.config.clone(),
)?;

let _ = Self::launch_language_server(&mut self.language_servers, &mut doc);
if let Some(diff_base) = self.diff_providers.get_diff_base(&path) {
doc.set_diff_base(diff_base, self.redraw_handle.clone());
}
self.new_document(doc)

let id = self.new_document(doc);
let _ = self.launch_language_server(id);

id
};

self.switch(id, action);
Expand Down