Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/commands/typed.rs')
-rw-r--r--helix-term/src/commands/typed.rs70
1 files changed, 50 insertions, 20 deletions
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index 4a2546d7..8a335674 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -1476,9 +1476,34 @@ fn lsp_workspace_command(
Ok(())
}
+/// Returns all language servers used by the current document if no servers are supplied
+/// If servers are supplied, do a check to make sure that all of the servers exist
+fn valid_lang_servers(doc: &Document, servers: &[Cow<str>]) -> anyhow::Result<Vec<String>> {
+ let valid_ls_names = doc
+ .language_servers()
+ .map(|ls| ls.name().to_string())
+ .collect();
+
+ if servers.is_empty() {
+ Ok(valid_ls_names)
+ } else {
+ let (valid, invalid): (Vec<_>, Vec<_>) = servers
+ .iter()
+ .map(|m| m.to_string())
+ .partition(|ls| valid_ls_names.contains(ls));
+
+ if !invalid.is_empty() {
+ let s = if invalid.len() == 1 { "" } else { "s" };
+ bail!("Unknown language server{s}: {}", invalid.join(", "));
+ };
+
+ Ok(valid)
+ }
+}
+
fn lsp_restart(
cx: &mut compositor::Context,
- _args: &[Cow<str>],
+ args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
@@ -1486,17 +1511,25 @@ fn lsp_restart(
}
let editor_config = cx.editor.config.load();
- let (_view, doc) = current!(cx.editor);
+ let doc = doc!(cx.editor);
let config = doc
.language_config()
.context("LSP not defined for the current document")?;
- cx.editor.language_servers.restart(
- config,
- doc.path(),
- &editor_config.workspace_lsp_roots,
- editor_config.lsp.snippets,
- )?;
+ let ls_restart_names = valid_lang_servers(doc, args)?;
+
+ for server in ls_restart_names.iter() {
+ cx.editor
+ .language_servers
+ .restart_server(
+ server,
+ config,
+ doc.path(),
+ &editor_config.workspace_lsp_roots,
+ editor_config.lsp.snippets,
+ )
+ .transpose()?;
+ }
// This collect is needed because refresh_language_server would need to re-borrow editor.
let document_ids_to_refresh: Vec<DocumentId> = cx
@@ -1505,10 +1538,9 @@ fn lsp_restart(
.filter_map(|doc| match doc.language_config() {
Some(config)
if config.language_servers.iter().any(|ls| {
- config
- .language_servers
+ ls_restart_names
.iter()
- .any(|restarted_ls| restarted_ls.name == ls.name)
+ .any(|restarted_ls| restarted_ls == &ls.name)
}) =>
{
Some(doc.id())
@@ -1526,17 +1558,15 @@ fn lsp_restart(
fn lsp_stop(
cx: &mut compositor::Context,
- _args: &[Cow<str>],
+ args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
+ let doc = doc!(cx.editor);
- let ls_shutdown_names = doc!(cx.editor)
- .language_servers()
- .map(|ls| ls.name().to_string())
- .collect::<Vec<_>>();
+ let ls_shutdown_names = valid_lang_servers(doc, args)?;
for ls_name in &ls_shutdown_names {
cx.editor.language_servers.stop(ls_name);
@@ -2910,16 +2940,16 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand {
name: "lsp-restart",
aliases: &[],
- doc: "Restarts the language servers used by the current doc",
+ doc: "Restarts the given language servers, or all language servers that are used by the current file if no arguments are supplied",
fun: lsp_restart,
- signature: CommandSignature::none(),
+ signature: CommandSignature::all(completers::language_servers),
},
TypableCommand {
name: "lsp-stop",
aliases: &[],
- doc: "Stops the language servers that are used by the current doc",
+ doc: "Stops the given language servers, or all language servers that are used by the current file if no arguments are supplied",
fun: lsp_stop,
- signature: CommandSignature::none(),
+ signature: CommandSignature::all(completers::language_servers),
},
TypableCommand {
name: "tree-sitter-scopes",