only advertise range formatting support if enabled
This commit is contained in:
@@ -158,7 +158,24 @@ fn run_server() -> Result<()> {
|
|||||||
let initialize_params =
|
let initialize_params =
|
||||||
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
|
from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
|
||||||
|
|
||||||
let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);
|
let root_path = match initialize_params
|
||||||
|
.root_uri
|
||||||
|
.and_then(|it| it.to_file_path().ok())
|
||||||
|
.and_then(|it| AbsPathBuf::try_from(it).ok())
|
||||||
|
{
|
||||||
|
Some(it) => it,
|
||||||
|
None => {
|
||||||
|
let cwd = env::current_dir()?;
|
||||||
|
AbsPathBuf::assert(cwd)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut config = Config::new(root_path, initialize_params.capabilities);
|
||||||
|
if let Some(json) = initialize_params.initialization_options {
|
||||||
|
config.update(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
let server_capabilities = rust_analyzer::server_capabilities(&config);
|
||||||
|
|
||||||
let initialize_result = lsp_types::InitializeResult {
|
let initialize_result = lsp_types::InitializeResult {
|
||||||
capabilities: server_capabilities,
|
capabilities: server_capabilities,
|
||||||
@@ -166,11 +183,7 @@ fn run_server() -> Result<()> {
|
|||||||
name: String::from("rust-analyzer"),
|
name: String::from("rust-analyzer"),
|
||||||
version: Some(String::from(env!("REV"))),
|
version: Some(String::from(env!("REV"))),
|
||||||
}),
|
}),
|
||||||
offset_encoding: if supports_utf8(&initialize_params.capabilities) {
|
offset_encoding: if supports_utf8(&config.caps) { Some("utf-8".to_string()) } else { None },
|
||||||
Some("utf-8".to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let initialize_result = serde_json::to_value(initialize_result).unwrap();
|
let initialize_result = serde_json::to_value(initialize_result).unwrap();
|
||||||
@@ -181,47 +194,26 @@ fn run_server() -> Result<()> {
|
|||||||
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
|
log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = {
|
if config.linked_projects().is_empty() && config.detached_files().is_empty() {
|
||||||
let root_path = match initialize_params
|
let workspace_roots = initialize_params
|
||||||
.root_uri
|
.workspace_folders
|
||||||
.and_then(|it| it.to_file_path().ok())
|
.map(|workspaces| {
|
||||||
.and_then(|it| AbsPathBuf::try_from(it).ok())
|
workspaces
|
||||||
{
|
.into_iter()
|
||||||
Some(it) => it,
|
.filter_map(|it| it.uri.to_file_path().ok())
|
||||||
None => {
|
.filter_map(|it| AbsPathBuf::try_from(it).ok())
|
||||||
let cwd = env::current_dir()?;
|
.collect::<Vec<_>>()
|
||||||
AbsPathBuf::assert(cwd)
|
})
|
||||||
}
|
.filter(|workspaces| !workspaces.is_empty())
|
||||||
};
|
.unwrap_or_else(|| vec![config.root_path.clone()]);
|
||||||
|
|
||||||
let mut config = Config::new(root_path, initialize_params.capabilities);
|
let discovered = ProjectManifest::discover_all(&workspace_roots);
|
||||||
if let Some(json) = initialize_params.initialization_options {
|
log::info!("discovered projects: {:?}", discovered);
|
||||||
config.update(json);
|
if discovered.is_empty() {
|
||||||
|
log::error!("failed to find any projects in {:?}", workspace_roots);
|
||||||
}
|
}
|
||||||
|
config.discovered_projects = Some(discovered);
|
||||||
if config.linked_projects().is_empty() && config.detached_files().is_empty() {
|
}
|
||||||
let workspace_roots = initialize_params
|
|
||||||
.workspace_folders
|
|
||||||
.map(|workspaces| {
|
|
||||||
workspaces
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|it| it.uri.to_file_path().ok())
|
|
||||||
.filter_map(|it| AbsPathBuf::try_from(it).ok())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
})
|
|
||||||
.filter(|workspaces| !workspaces.is_empty())
|
|
||||||
.unwrap_or_else(|| vec![config.root_path.clone()]);
|
|
||||||
|
|
||||||
let discovered = ProjectManifest::discover_all(&workspace_roots);
|
|
||||||
log::info!("discovered projects: {:?}", discovered);
|
|
||||||
if discovered.is_empty() {
|
|
||||||
log::error!("failed to find any projects in {:?}", workspace_roots);
|
|
||||||
}
|
|
||||||
config.discovered_projects = Some(discovered);
|
|
||||||
}
|
|
||||||
|
|
||||||
config
|
|
||||||
};
|
|
||||||
|
|
||||||
rust_analyzer::main_loop(config, connection)?;
|
rust_analyzer::main_loop(config, connection)?;
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ use lsp_types::{
|
|||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::config::{Config, RustfmtConfig};
|
||||||
use crate::semantic_tokens;
|
use crate::semantic_tokens;
|
||||||
|
|
||||||
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
|
pub fn server_capabilities(config: &Config) -> ServerCapabilities {
|
||||||
ServerCapabilities {
|
ServerCapabilities {
|
||||||
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
|
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
|
||||||
open_close: Some(true),
|
open_close: Some(true),
|
||||||
@@ -32,7 +33,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
|
|||||||
})),
|
})),
|
||||||
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
||||||
completion_provider: Some(CompletionOptions {
|
completion_provider: Some(CompletionOptions {
|
||||||
resolve_provider: completions_resolve_provider(client_caps),
|
resolve_provider: completions_resolve_provider(&config.caps),
|
||||||
trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]),
|
trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]),
|
||||||
all_commit_characters: None,
|
all_commit_characters: None,
|
||||||
completion_item: None,
|
completion_item: None,
|
||||||
@@ -51,10 +52,13 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
|
|||||||
document_highlight_provider: Some(OneOf::Left(true)),
|
document_highlight_provider: Some(OneOf::Left(true)),
|
||||||
document_symbol_provider: Some(OneOf::Left(true)),
|
document_symbol_provider: Some(OneOf::Left(true)),
|
||||||
workspace_symbol_provider: Some(OneOf::Left(true)),
|
workspace_symbol_provider: Some(OneOf::Left(true)),
|
||||||
code_action_provider: Some(code_action_capabilities(client_caps)),
|
code_action_provider: Some(code_action_capabilities(&config.caps)),
|
||||||
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
|
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
|
||||||
document_formatting_provider: Some(OneOf::Left(true)),
|
document_formatting_provider: Some(OneOf::Left(true)),
|
||||||
document_range_formatting_provider: Some(OneOf::Left(true)),
|
document_range_formatting_provider: match config.rustfmt() {
|
||||||
|
RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
|
||||||
|
_ => Some(OneOf::Left(false)),
|
||||||
|
},
|
||||||
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
|
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
|
||||||
first_trigger_character: "=".to_string(),
|
first_trigger_character: "=".to_string(),
|
||||||
more_trigger_character: Some(vec![".".to_string(), ">".to_string(), "{".to_string()]),
|
more_trigger_character: Some(vec![".".to_string(), ">".to_string(), "{".to_string()]),
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ impl Default for ConfigData {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
caps: lsp_types::ClientCapabilities,
|
pub caps: lsp_types::ClientCapabilities,
|
||||||
data: ConfigData,
|
data: ConfigData,
|
||||||
detached_files: Vec<AbsPathBuf>,
|
detached_files: Vec<AbsPathBuf>,
|
||||||
pub discovered_projects: Option<Vec<ProjectManifest>>,
|
pub discovered_projects: Option<Vec<ProjectManifest>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user