Skip to content

Commit

Permalink
feat(lsp): add codeActionKinds (#3731)
Browse files Browse the repository at this point in the history
  • Loading branch information
suxin2017 committed Aug 29, 2024
1 parent 33040d7 commit 7120d53
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 4 deletions.
20 changes: 17 additions & 3 deletions crates/biome_lsp/src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::converters::{negotiated_encoding, PositionEncoding, WideEncoding};
use tower_lsp::lsp_types::{
ClientCapabilities, CodeActionProviderCapability, DocumentOnTypeFormattingOptions, OneOf,
PositionEncodingKind, ServerCapabilities, TextDocumentSyncCapability, TextDocumentSyncKind,
ClientCapabilities, CodeActionKind, CodeActionOptions, CodeActionProviderCapability,
DocumentOnTypeFormattingOptions, OneOf, PositionEncodingKind, ServerCapabilities,
TextDocumentSyncCapability, TextDocumentSyncKind,
};

/// The capabilities to send from server as part of [`InitializeResult`]
Expand Down Expand Up @@ -50,6 +51,19 @@ pub(crate) fn server_capabilities(capabilities: &ClientCapabilities) -> ServerCa
}
});

let code_action_provider = capabilities
.text_document
.as_ref()
.and_then(|text_document| text_document.code_action.as_ref())
.and_then(|code_action| code_action.code_action_literal_support.as_ref())
.map(|_| {
CodeActionProviderCapability::Options(CodeActionOptions {
code_action_kinds: Some(vec![CodeActionKind::new("source.fixAll.biome")]),
..Default::default()
})
})
.or(Some(CodeActionProviderCapability::Simple(true)));

ServerCapabilities {
position_encoding: Some(match negotiated_encoding(capabilities) {
PositionEncoding::Utf8 => PositionEncodingKind::UTF8,
Expand All @@ -64,7 +78,7 @@ pub(crate) fn server_capabilities(capabilities: &ClientCapabilities) -> ServerCa
document_formatting_provider: supports_formatter_dynamic_registration,
document_range_formatting_provider: supports_range_formatter_dynamic_registration,
document_on_type_formatting_provider: supports_on_type_formatter_dynamic_registration,
code_action_provider: Some(CodeActionProviderCapability::Simple(true)),
code_action_provider,
rename_provider: None,
..Default::default()
}
Expand Down
106 changes: 105 additions & 1 deletion crates/biome_lsp/tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ use tower::{Service, ServiceExt};
use tower_lsp::jsonrpc;
use tower_lsp::jsonrpc::Response;
use tower_lsp::lsp_types as lsp;
use tower_lsp::lsp_types::CodeActionClientCapabilities;
use tower_lsp::lsp_types::CodeActionKind;
use tower_lsp::lsp_types::CodeActionKindLiteralSupport;
use tower_lsp::lsp_types::CodeActionLiteralSupport;
use tower_lsp::lsp_types::CodeActionOptions;
use tower_lsp::lsp_types::CodeActionProviderCapability;
use tower_lsp::lsp_types::DidOpenTextDocumentParams;
use tower_lsp::lsp_types::DocumentFormattingParams;
use tower_lsp::lsp_types::FormattingOptions;
Expand All @@ -36,6 +42,7 @@ use tower_lsp::lsp_types::InitializedParams;
use tower_lsp::lsp_types::Position;
use tower_lsp::lsp_types::PublishDiagnosticsParams;
use tower_lsp::lsp_types::Range;
use tower_lsp::lsp_types::TextDocumentClientCapabilities;
use tower_lsp::lsp_types::TextDocumentContentChangeEvent;
use tower_lsp::lsp_types::TextDocumentIdentifier;
use tower_lsp::lsp_types::TextDocumentItem;
Expand Down Expand Up @@ -183,7 +190,6 @@ impl Server {
)
.await?
.context("initialize returned None")?;

Ok(())
}

Expand Down Expand Up @@ -405,6 +411,104 @@ where
Ok(())
}

#[allow(deprecated)]
#[tokio::test]
async fn server_capabilities_fix_all_code_action_kinds() -> Result<()> {
let factory = ServerFactory::default();
let (service, client) = factory.create(None).into_inner();
let (stream, sink) = client.split();
let mut server = Server::new(service);

let (sender, _) = channel(CHANNEL_BUFFER_SIZE);
let reader = tokio::spawn(client_handler(stream, sink, sender));
let expect_code_action_provider =
Some(CodeActionProviderCapability::Options(CodeActionOptions {
code_action_kinds: Some(vec![CodeActionKind::new("source.fixAll.biome")]),
..Default::default()
}));
let res: InitializeResult = server
.request(
"initialize",
"_init",
InitializeParams {
process_id: None,
root_path: None,
root_uri: Some(url!("")),
initialization_options: None,
capabilities: ClientCapabilities {
text_document: Some(TextDocumentClientCapabilities {
code_action: Some(CodeActionClientCapabilities {
code_action_literal_support: Some(CodeActionLiteralSupport {
code_action_kind: CodeActionKindLiteralSupport {
value_set: Vec::new(),
},
}),
..CodeActionClientCapabilities::default()
}),

..TextDocumentClientCapabilities::default()
}),

..ClientCapabilities::default()
},
trace: None,
workspace_folders: None,
client_info: None,
locale: None,
},
)
.await?
.context("initialize returned None")?;

assert_eq!(
res.capabilities.code_action_provider,
expect_code_action_provider
);
server.shutdown().await?;
reader.abort();

Ok(())
}

#[allow(deprecated)]
#[tokio::test]
async fn server_capabilities_default_code_action_kinds() -> Result<()> {
let factory = ServerFactory::default();
let (service, client) = factory.create(None).into_inner();
let (stream, sink) = client.split();
let mut server = Server::new(service);

let (sender, _) = channel(CHANNEL_BUFFER_SIZE);
let reader = tokio::spawn(client_handler(stream, sink, sender));
let expect_code_action_provider = Some(CodeActionProviderCapability::Simple(true));
let res: InitializeResult = server
.request(
"initialize",
"_init",
InitializeParams {
process_id: None,
root_path: None,
root_uri: Some(url!("")),
initialization_options: None,
capabilities: ClientCapabilities::default(),
trace: None,
workspace_folders: None,
client_info: None,
locale: None,
},
)
.await?
.context("initialize returned None")?;
assert_eq!(
res.capabilities.code_action_provider,
expect_code_action_provider
);
server.shutdown().await?;
reader.abort();

Ok(())
}

#[tokio::test]
async fn basic_lifecycle() -> Result<()> {
let factory = ServerFactory::default();
Expand Down

0 comments on commit 7120d53

Please sign in to comment.