mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-03 07:04:53 +00:00
Add supported commands in server capabilities (#11850)
## Summary This PR updates the server capabilities to include the commands that Ruff supports. This is similar to how there's a list of possible code actions supported by the server. I noticed this when I was trying to find whether Helix supported workspace commands or not based on Jane's comment (https://github.com/astral-sh/ruff/pull/11831#discussion_r1634984921) and I found the `:lsp-workspace-command` in the editor but it didn't show up anything in the picker. So, I looked at the implementation in Helix (9c479e6d2d/helix-term/src/commands/typed.rs (L1372-L1384)
) which made me realize that Ruff doesn't provide this in its capabilities. Currently, this does require `ruff` to be first in the list of language servers in the user config but that should be resolved by https://github.com/helix-editor/helix/pull/10176. So, the following config should work: ```toml [[language]] name = "python" # Ruff should come first until https://github.com/helix-editor/helix/pull/10176 is released language-servers = ["ruff", "pyright"] ``` ## Test Plan 1. Neovim's server capabilities output should include the supported commands: ``` executeCommandProvider = { commands = { "ruff.applyFormat", "ruff.applyAutofix", "ruff.applyOrganizeImports", "ruff.printDebugInformation" }, workDoneProgress = false }, ``` 2. Helix should now display the commands to pick from when `:lsp-workspace-command` is invoked: <img width="832" alt="Screenshot 2024-06-13 at 08 47 14" src="09048ecd
-c974-4e09-ab56-9482ff3d780b">
This commit is contained in:
parent
bcbddac21c
commit
9dc226be97
2 changed files with 70 additions and 41 deletions
|
@ -1,6 +1,7 @@
|
||||||
//! Scheduling, I/O, and API endpoints.
|
//! Scheduling, I/O, and API endpoints.
|
||||||
|
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use lsp_server as lsp;
|
use lsp_server as lsp;
|
||||||
use lsp_types as types;
|
use lsp_types as types;
|
||||||
|
@ -276,6 +277,14 @@ impl Server {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
execute_command_provider: Some(types::ExecuteCommandOptions {
|
||||||
|
commands: SupportedCommand::all()
|
||||||
|
.map(|command| command.identifier().to_string())
|
||||||
|
.to_vec(),
|
||||||
|
work_done_progress_options: WorkDoneProgressOptions {
|
||||||
|
work_done_progress: Some(false),
|
||||||
|
},
|
||||||
|
}),
|
||||||
hover_provider: Some(types::HoverProviderCapability::Simple(true)),
|
hover_provider: Some(types::HoverProviderCapability::Simple(true)),
|
||||||
notebook_document_sync: Some(types::OneOf::Left(NotebookDocumentSyncOptions {
|
notebook_document_sync: Some(types::OneOf::Left(NotebookDocumentSyncOptions {
|
||||||
save: Some(false),
|
save: Some(false),
|
||||||
|
@ -354,3 +363,56 @@ impl SupportedCodeAction {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub(crate) enum SupportedCommand {
|
||||||
|
Debug,
|
||||||
|
Format,
|
||||||
|
FixAll,
|
||||||
|
OrganizeImports,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SupportedCommand {
|
||||||
|
const fn label(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::FixAll => "Fix all auto-fixable problems",
|
||||||
|
Self::Format => "Format document",
|
||||||
|
Self::OrganizeImports => "Format imports",
|
||||||
|
Self::Debug => "Print debug information",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the identifier of the command.
|
||||||
|
const fn identifier(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
SupportedCommand::Format => "ruff.applyFormat",
|
||||||
|
SupportedCommand::FixAll => "ruff.applyAutofix",
|
||||||
|
SupportedCommand::OrganizeImports => "ruff.applyOrganizeImports",
|
||||||
|
SupportedCommand::Debug => "ruff.printDebugInformation",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns all the commands that the server currently supports.
|
||||||
|
const fn all() -> [SupportedCommand; 4] {
|
||||||
|
[
|
||||||
|
SupportedCommand::Format,
|
||||||
|
SupportedCommand::FixAll,
|
||||||
|
SupportedCommand::OrganizeImports,
|
||||||
|
SupportedCommand::Debug,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for SupportedCommand {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(name: &str) -> anyhow::Result<Self, Self::Err> {
|
||||||
|
Ok(match name {
|
||||||
|
"ruff.applyAutofix" => Self::FixAll,
|
||||||
|
"ruff.applyFormat" => Self::Format,
|
||||||
|
"ruff.applyOrganizeImports" => Self::OrganizeImports,
|
||||||
|
"ruff.printDebugInformation" => Self::Debug,
|
||||||
|
_ => return Err(anyhow::anyhow!("Invalid command `{name}`")),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use crate::edit::WorkspaceEditTracker;
|
use crate::edit::WorkspaceEditTracker;
|
||||||
use crate::server::api::LSPResult;
|
use crate::server::api::LSPResult;
|
||||||
use crate::server::client;
|
|
||||||
use crate::server::schedule::Task;
|
use crate::server::schedule::Task;
|
||||||
|
use crate::server::{client, SupportedCommand};
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::DIAGNOSTIC_NAME;
|
use crate::DIAGNOSTIC_NAME;
|
||||||
use crate::{edit::DocumentVersion, server};
|
use crate::{edit::DocumentVersion, server};
|
||||||
|
@ -11,14 +11,6 @@ use lsp_server::ErrorCode;
|
||||||
use lsp_types::{self as types, request as req};
|
use lsp_types::{self as types, request as req};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
enum Command {
|
|
||||||
Debug,
|
|
||||||
Format,
|
|
||||||
FixAll,
|
|
||||||
OrganizeImports,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct ExecuteCommand;
|
pub(crate) struct ExecuteCommand;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -38,10 +30,10 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
||||||
requester: &mut client::Requester,
|
requester: &mut client::Requester,
|
||||||
params: types::ExecuteCommandParams,
|
params: types::ExecuteCommandParams,
|
||||||
) -> server::Result<Option<serde_json::Value>> {
|
) -> server::Result<Option<serde_json::Value>> {
|
||||||
let command =
|
let command = SupportedCommand::from_str(¶ms.command)
|
||||||
Command::from_str(¶ms.command).with_failure_code(ErrorCode::InvalidParams)?;
|
.with_failure_code(ErrorCode::InvalidParams)?;
|
||||||
|
|
||||||
if command == Command::Debug {
|
if command == SupportedCommand::Debug {
|
||||||
let output = debug_information(session);
|
let output = debug_information(session);
|
||||||
notifier
|
notifier
|
||||||
.notify::<types::notification::LogMessage>(types::LogMessageParams {
|
.notify::<types::notification::LogMessage>(types::LogMessageParams {
|
||||||
|
@ -74,7 +66,7 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
match command {
|
match command {
|
||||||
Command::FixAll => {
|
SupportedCommand::FixAll => {
|
||||||
let fixes = super::code_action_resolve::fix_all_edit(
|
let fixes = super::code_action_resolve::fix_all_edit(
|
||||||
snapshot.query(),
|
snapshot.query(),
|
||||||
snapshot.encoding(),
|
snapshot.encoding(),
|
||||||
|
@ -84,13 +76,13 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
||||||
.set_fixes_for_document(fixes, snapshot.query().version())
|
.set_fixes_for_document(fixes, snapshot.query().version())
|
||||||
.with_failure_code(ErrorCode::InternalError)?;
|
.with_failure_code(ErrorCode::InternalError)?;
|
||||||
}
|
}
|
||||||
Command::Format => {
|
SupportedCommand::Format => {
|
||||||
let fixes = super::format::format_full_document(&snapshot)?;
|
let fixes = super::format::format_full_document(&snapshot)?;
|
||||||
edit_tracker
|
edit_tracker
|
||||||
.set_fixes_for_document(fixes, version)
|
.set_fixes_for_document(fixes, version)
|
||||||
.with_failure_code(ErrorCode::InternalError)?;
|
.with_failure_code(ErrorCode::InternalError)?;
|
||||||
}
|
}
|
||||||
Command::OrganizeImports => {
|
SupportedCommand::OrganizeImports => {
|
||||||
let fixes = super::code_action_resolve::organize_imports_edit(
|
let fixes = super::code_action_resolve::organize_imports_edit(
|
||||||
snapshot.query(),
|
snapshot.query(),
|
||||||
snapshot.encoding(),
|
snapshot.encoding(),
|
||||||
|
@ -100,7 +92,7 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
||||||
.set_fixes_for_document(fixes, snapshot.query().version())
|
.set_fixes_for_document(fixes, snapshot.query().version())
|
||||||
.with_failure_code(ErrorCode::InternalError)?;
|
.with_failure_code(ErrorCode::InternalError)?;
|
||||||
}
|
}
|
||||||
Command::Debug => {
|
SupportedCommand::Debug => {
|
||||||
unreachable!("The debug command should have already been handled")
|
unreachable!("The debug command should have already been handled")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,31 +111,6 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
|
||||||
fn label(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
Self::FixAll => "Fix all auto-fixable problems",
|
|
||||||
Self::Format => "Format document",
|
|
||||||
Self::OrganizeImports => "Format imports",
|
|
||||||
Self::Debug => "Print debug information",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Command {
|
|
||||||
type Err = anyhow::Error;
|
|
||||||
|
|
||||||
fn from_str(name: &str) -> Result<Self, Self::Err> {
|
|
||||||
Ok(match name {
|
|
||||||
"ruff.applyAutofix" => Self::FixAll,
|
|
||||||
"ruff.applyFormat" => Self::Format,
|
|
||||||
"ruff.applyOrganizeImports" => Self::OrganizeImports,
|
|
||||||
"ruff.printDebugInformation" => Self::Debug,
|
|
||||||
_ => return Err(anyhow::anyhow!("Invalid command `{name}`")),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_edit(
|
fn apply_edit(
|
||||||
requester: &mut client::Requester,
|
requester: &mut client::Requester,
|
||||||
label: &str,
|
label: &str,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue