mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Auto merge of #17735 - alibektas:ratoml_workspaces, r=Veykril
feat: Introduce workspace `rust-analyzer.toml`s In order to globally configure a project it was, prior to this PR, possible to have a `ratoml` at the root path of a project. This is not the case anymore. Instead we now let ratoml files that are placed at the root of any workspace have a new scope called `workspace`. Although there is not a difference between a `workspace` scope and and a `global` scope, future PRs will change that.
This commit is contained in:
commit
412c915139
6 changed files with 338 additions and 277 deletions
|
@ -67,7 +67,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
|
||||||
code_action_provider: Some(config.caps().code_action_capabilities()),
|
code_action_provider: Some(config.caps().code_action_capabilities()),
|
||||||
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: match config.rustfmt() {
|
document_range_formatting_provider: match config.rustfmt(None) {
|
||||||
RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
|
RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
|
||||||
_ => Some(OneOf::Left(false)),
|
_ => Some(OneOf::Left(false)),
|
||||||
},
|
},
|
||||||
|
|
|
@ -751,6 +751,20 @@ config_data! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum RatomlFileKind {
|
||||||
|
Workspace,
|
||||||
|
Crate,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
// FIXME @alibektas : Seems like a clippy warning of this sort should tell that combining different ConfigInputs into one enum was not a good idea.
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
enum RatomlFile {
|
||||||
|
Workspace(GlobalLocalConfigInput),
|
||||||
|
Crate(LocalConfigInput),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
discovered_projects: Vec<ProjectManifest>,
|
discovered_projects: Vec<ProjectManifest>,
|
||||||
|
@ -779,14 +793,7 @@ pub struct Config {
|
||||||
/// Config node whose values apply to **every** Rust project.
|
/// Config node whose values apply to **every** Rust project.
|
||||||
user_config: Option<(GlobalLocalConfigInput, ConfigErrors)>,
|
user_config: Option<(GlobalLocalConfigInput, ConfigErrors)>,
|
||||||
|
|
||||||
/// A special file for this session whose path is set to `self.root_path.join("rust-analyzer.toml")`
|
ratoml_file: FxHashMap<SourceRootId, (RatomlFile, ConfigErrors)>,
|
||||||
root_ratoml_path: VfsPath,
|
|
||||||
|
|
||||||
/// This file can be used to make global changes while having only a workspace-wide scope.
|
|
||||||
root_ratoml: Option<(GlobalLocalConfigInput, ConfigErrors)>,
|
|
||||||
|
|
||||||
/// For every `SourceRoot` there can be at most one RATOML file.
|
|
||||||
ratoml_files: FxHashMap<SourceRootId, (LocalConfigInput, ConfigErrors)>,
|
|
||||||
|
|
||||||
/// Clone of the value that is stored inside a `GlobalState`.
|
/// Clone of the value that is stored inside a `GlobalState`.
|
||||||
source_root_parent_map: Arc<FxHashMap<SourceRootId, SourceRootId>>,
|
source_root_parent_map: Arc<FxHashMap<SourceRootId, SourceRootId>>,
|
||||||
|
@ -917,84 +924,95 @@ impl Config {
|
||||||
should_update = true;
|
should_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(change) = change.root_ratoml_change {
|
|
||||||
tracing::info!("updating root ra-toml config: {:#}", change);
|
|
||||||
#[allow(clippy::single_match)]
|
|
||||||
match toml::from_str(&change) {
|
|
||||||
Ok(table) => {
|
|
||||||
let mut toml_errors = vec![];
|
|
||||||
validate_toml_table(
|
|
||||||
GlobalLocalConfigInput::FIELDS,
|
|
||||||
&table,
|
|
||||||
&mut String::new(),
|
|
||||||
&mut toml_errors,
|
|
||||||
);
|
|
||||||
config.root_ratoml = Some((
|
|
||||||
GlobalLocalConfigInput::from_toml(table, &mut toml_errors),
|
|
||||||
ConfigErrors(
|
|
||||||
toml_errors
|
|
||||||
.into_iter()
|
|
||||||
.map(|(a, b)| ConfigErrorInner::Toml { config_key: a, error: b })
|
|
||||||
.map(Arc::new)
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
should_update = true;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
config.root_ratoml = Some((
|
|
||||||
GlobalLocalConfigInput::from_toml(toml::map::Map::default(), &mut vec![]),
|
|
||||||
ConfigErrors(vec![ConfigErrorInner::ParseError {
|
|
||||||
reason: e.message().to_owned(),
|
|
||||||
}
|
|
||||||
.into()]),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(change) = change.ratoml_file_change {
|
if let Some(change) = change.ratoml_file_change {
|
||||||
for (source_root_id, (_, text)) in change {
|
for (source_root_id, (kind, _, text)) in change {
|
||||||
if let Some(text) = text {
|
match kind {
|
||||||
let mut toml_errors = vec![];
|
RatomlFileKind::Crate => {
|
||||||
tracing::info!("updating ra-toml config: {:#}", text);
|
if let Some(text) = text {
|
||||||
#[allow(clippy::single_match)]
|
let mut toml_errors = vec![];
|
||||||
match toml::from_str(&text) {
|
tracing::info!("updating ra-toml config: {:#}", text);
|
||||||
Ok(table) => {
|
match toml::from_str(&text) {
|
||||||
validate_toml_table(
|
Ok(table) => {
|
||||||
&[LocalConfigInput::FIELDS],
|
validate_toml_table(
|
||||||
&table,
|
&[LocalConfigInput::FIELDS],
|
||||||
&mut String::new(),
|
&table,
|
||||||
&mut toml_errors,
|
&mut String::new(),
|
||||||
);
|
&mut toml_errors,
|
||||||
config.ratoml_files.insert(
|
);
|
||||||
source_root_id,
|
config.ratoml_file.insert(
|
||||||
(
|
source_root_id,
|
||||||
LocalConfigInput::from_toml(&table, &mut toml_errors),
|
(
|
||||||
ConfigErrors(
|
RatomlFile::Crate(LocalConfigInput::from_toml(
|
||||||
toml_errors
|
&table,
|
||||||
.into_iter()
|
&mut toml_errors,
|
||||||
.map(|(a, b)| ConfigErrorInner::Toml {
|
)),
|
||||||
config_key: a,
|
ConfigErrors(
|
||||||
error: b,
|
toml_errors
|
||||||
})
|
.into_iter()
|
||||||
.map(Arc::new)
|
.map(|(a, b)| ConfigErrorInner::Toml {
|
||||||
.collect(),
|
config_key: a,
|
||||||
),
|
error: b,
|
||||||
),
|
})
|
||||||
);
|
.map(Arc::new)
|
||||||
}
|
.collect(),
|
||||||
Err(e) => {
|
),
|
||||||
config.root_ratoml = Some((
|
),
|
||||||
GlobalLocalConfigInput::from_toml(
|
);
|
||||||
toml::map::Map::default(),
|
|
||||||
&mut vec![],
|
|
||||||
),
|
|
||||||
ConfigErrors(vec![ConfigErrorInner::ParseError {
|
|
||||||
reason: e.message().to_owned(),
|
|
||||||
}
|
}
|
||||||
.into()]),
|
Err(e) => {
|
||||||
));
|
config.validation_errors.0.push(
|
||||||
|
ConfigErrorInner::ParseError {
|
||||||
|
reason: e.message().to_owned(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RatomlFileKind::Workspace => {
|
||||||
|
if let Some(text) = text {
|
||||||
|
let mut toml_errors = vec![];
|
||||||
|
match toml::from_str(&text) {
|
||||||
|
Ok(table) => {
|
||||||
|
validate_toml_table(
|
||||||
|
GlobalLocalConfigInput::FIELDS,
|
||||||
|
&table,
|
||||||
|
&mut String::new(),
|
||||||
|
&mut toml_errors,
|
||||||
|
);
|
||||||
|
config.ratoml_file.insert(
|
||||||
|
source_root_id,
|
||||||
|
(
|
||||||
|
RatomlFile::Workspace(
|
||||||
|
GlobalLocalConfigInput::from_toml(
|
||||||
|
table,
|
||||||
|
&mut toml_errors,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ConfigErrors(
|
||||||
|
toml_errors
|
||||||
|
.into_iter()
|
||||||
|
.map(|(a, b)| ConfigErrorInner::Toml {
|
||||||
|
config_key: a,
|
||||||
|
error: b,
|
||||||
|
})
|
||||||
|
.map(Arc::new)
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
should_update = true;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
config.validation_errors.0.push(
|
||||||
|
ConfigErrorInner::ParseError {
|
||||||
|
reason: e.message().to_owned(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +1023,7 @@ impl Config {
|
||||||
config.source_root_parent_map = source_root_map;
|
config.source_root_parent_map = source_root_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.check_command().is_empty() {
|
if config.check_command(None).is_empty() {
|
||||||
config.validation_errors.0.push(Arc::new(ConfigErrorInner::Json {
|
config.validation_errors.0.push(Arc::new(ConfigErrorInner::Json {
|
||||||
config_key: "/check/command".to_owned(),
|
config_key: "/check/command".to_owned(),
|
||||||
error: serde_json::Error::custom("expected a non-empty string"),
|
error: serde_json::Error::custom("expected a non-empty string"),
|
||||||
|
@ -1026,9 +1044,8 @@ impl Config {
|
||||||
.1
|
.1
|
||||||
.0
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.chain(config.root_ratoml.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
|
|
||||||
.chain(config.user_config.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
|
.chain(config.user_config.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
|
||||||
.chain(config.ratoml_files.values().flat_map(|it| it.1 .0.iter()))
|
.chain(config.ratoml_file.values().flat_map(|it| it.1 .0.iter()))
|
||||||
.chain(config.validation_errors.0.iter())
|
.chain(config.validation_errors.0.iter())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -1055,9 +1072,9 @@ impl Config {
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct ConfigChange {
|
pub struct ConfigChange {
|
||||||
user_config_change: Option<Arc<str>>,
|
user_config_change: Option<Arc<str>>,
|
||||||
root_ratoml_change: Option<Arc<str>>,
|
|
||||||
client_config_change: Option<serde_json::Value>,
|
client_config_change: Option<serde_json::Value>,
|
||||||
ratoml_file_change: Option<FxHashMap<SourceRootId, (VfsPath, Option<Arc<str>>)>>,
|
ratoml_file_change:
|
||||||
|
Option<FxHashMap<SourceRootId, (RatomlFileKind, VfsPath, Option<Arc<str>>)>>,
|
||||||
source_map_change: Option<Arc<FxHashMap<SourceRootId, SourceRootId>>>,
|
source_map_change: Option<Arc<FxHashMap<SourceRootId, SourceRootId>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,10 +1084,10 @@ impl ConfigChange {
|
||||||
source_root: SourceRootId,
|
source_root: SourceRootId,
|
||||||
vfs_path: VfsPath,
|
vfs_path: VfsPath,
|
||||||
content: Option<Arc<str>>,
|
content: Option<Arc<str>>,
|
||||||
) -> Option<(VfsPath, Option<Arc<str>>)> {
|
) -> Option<(RatomlFileKind, VfsPath, Option<Arc<str>>)> {
|
||||||
self.ratoml_file_change
|
self.ratoml_file_change
|
||||||
.get_or_insert_with(Default::default)
|
.get_or_insert_with(Default::default)
|
||||||
.insert(source_root, (vfs_path, content))
|
.insert(source_root, (RatomlFileKind::Crate, vfs_path, content))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_user_config(&mut self, content: Option<Arc<str>>) {
|
pub fn change_user_config(&mut self, content: Option<Arc<str>>) {
|
||||||
|
@ -1078,9 +1095,15 @@ impl ConfigChange {
|
||||||
self.user_config_change = content;
|
self.user_config_change = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_root_ratoml(&mut self, content: Option<Arc<str>>) {
|
pub fn change_workspace_ratoml(
|
||||||
assert!(self.root_ratoml_change.is_none()); // Otherwise it is a double write.
|
&mut self,
|
||||||
self.root_ratoml_change = content;
|
source_root: SourceRootId,
|
||||||
|
vfs_path: VfsPath,
|
||||||
|
content: Option<Arc<str>>,
|
||||||
|
) -> Option<(RatomlFileKind, VfsPath, Option<Arc<str>>)> {
|
||||||
|
self.ratoml_file_change
|
||||||
|
.get_or_insert_with(Default::default)
|
||||||
|
.insert(source_root, (RatomlFileKind::Workspace, vfs_path, content))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_client_config(&mut self, change: serde_json::Value) {
|
pub fn change_client_config(&mut self, change: serde_json::Value) {
|
||||||
|
@ -1333,11 +1356,6 @@ impl Config {
|
||||||
// FIXME @alibektas : Temporary solution. I don't think this is right as at some point we may allow users to specify
|
// FIXME @alibektas : Temporary solution. I don't think this is right as at some point we may allow users to specify
|
||||||
// custom USER_CONFIG_PATHs which may also be relative.
|
// custom USER_CONFIG_PATHs which may also be relative.
|
||||||
let user_config_path = VfsPath::from(AbsPathBuf::assert(user_config_path));
|
let user_config_path = VfsPath::from(AbsPathBuf::assert(user_config_path));
|
||||||
let root_ratoml_path = {
|
|
||||||
let mut p = root_path.clone();
|
|
||||||
p.push("rust-analyzer.toml");
|
|
||||||
VfsPath::new_real_path(p.to_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
caps: ClientCapabilities::new(caps),
|
caps: ClientCapabilities::new(caps),
|
||||||
|
@ -1347,15 +1365,13 @@ impl Config {
|
||||||
workspace_roots,
|
workspace_roots,
|
||||||
visual_studio_code_version,
|
visual_studio_code_version,
|
||||||
client_config: (FullConfigInput::default(), ConfigErrors(vec![])),
|
client_config: (FullConfigInput::default(), ConfigErrors(vec![])),
|
||||||
ratoml_files: FxHashMap::default(),
|
|
||||||
default_config: DEFAULT_CONFIG_DATA.get_or_init(|| Box::leak(Box::default())),
|
default_config: DEFAULT_CONFIG_DATA.get_or_init(|| Box::leak(Box::default())),
|
||||||
source_root_parent_map: Arc::new(FxHashMap::default()),
|
source_root_parent_map: Arc::new(FxHashMap::default()),
|
||||||
user_config: None,
|
user_config: None,
|
||||||
user_config_path,
|
user_config_path,
|
||||||
root_ratoml: None,
|
|
||||||
root_ratoml_path,
|
|
||||||
detached_files: Default::default(),
|
detached_files: Default::default(),
|
||||||
validation_errors: Default::default(),
|
validation_errors: Default::default(),
|
||||||
|
ratoml_file: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,10 +1414,6 @@ impl Config {
|
||||||
&self.root_path
|
&self.root_path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_ratoml_path(&self) -> &VfsPath {
|
|
||||||
&self.root_ratoml_path
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn caps(&self) -> &ClientCapabilities {
|
pub fn caps(&self) -> &ClientCapabilities {
|
||||||
&self.caps
|
&self.caps
|
||||||
}
|
}
|
||||||
|
@ -1455,11 +1467,11 @@ impl Config {
|
||||||
|
|
||||||
pub fn diagnostics(&self, source_root: Option<SourceRootId>) -> DiagnosticsConfig {
|
pub fn diagnostics(&self, source_root: Option<SourceRootId>) -> DiagnosticsConfig {
|
||||||
DiagnosticsConfig {
|
DiagnosticsConfig {
|
||||||
enabled: *self.diagnostics_enable(),
|
enabled: *self.diagnostics_enable(source_root),
|
||||||
proc_attr_macros_enabled: self.expand_proc_attr_macros(),
|
proc_attr_macros_enabled: self.expand_proc_attr_macros(),
|
||||||
proc_macros_enabled: *self.procMacro_enable(),
|
proc_macros_enabled: *self.procMacro_enable(),
|
||||||
disable_experimental: !self.diagnostics_experimental_enable(),
|
disable_experimental: !self.diagnostics_experimental_enable(source_root),
|
||||||
disabled: self.diagnostics_disabled().clone(),
|
disabled: self.diagnostics_disabled(source_root).clone(),
|
||||||
expr_fill_default: match self.assist_expressionFillDefault(source_root) {
|
expr_fill_default: match self.assist_expressionFillDefault(source_root) {
|
||||||
ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
|
ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
|
||||||
ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
|
ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
|
||||||
|
@ -1469,7 +1481,7 @@ impl Config {
|
||||||
prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
|
prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
|
||||||
prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
|
prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
|
||||||
prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
|
prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
|
||||||
style_lints: self.diagnostics_styleLints_enable().to_owned(),
|
style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(),
|
||||||
term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
|
term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
|
||||||
term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
|
term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
|
||||||
}
|
}
|
||||||
|
@ -1662,11 +1674,11 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_linked_projects(&self) -> bool {
|
pub fn has_linked_projects(&self) -> bool {
|
||||||
!self.linkedProjects().is_empty()
|
!self.linkedProjects(None).is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn linked_manifests(&self) -> impl Iterator<Item = &AbsPath> + '_ {
|
pub fn linked_manifests(&self) -> impl Iterator<Item = &AbsPath> + '_ {
|
||||||
self.linkedProjects().iter().filter_map(|it| match it {
|
self.linkedProjects(None).iter().filter_map(|it| match it {
|
||||||
ManifestOrProjectJson::Manifest(p) => Some(&**p),
|
ManifestOrProjectJson::Manifest(p) => Some(&**p),
|
||||||
// despite having a buildfile, using this variant as a manifest
|
// despite having a buildfile, using this variant as a manifest
|
||||||
// will fail.
|
// will fail.
|
||||||
|
@ -1676,20 +1688,20 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_linked_project_jsons(&self) -> bool {
|
pub fn has_linked_project_jsons(&self) -> bool {
|
||||||
self.linkedProjects()
|
self.linkedProjects(None)
|
||||||
.iter()
|
.iter()
|
||||||
.any(|it| matches!(it, ManifestOrProjectJson::ProjectJson { .. }))
|
.any(|it| matches!(it, ManifestOrProjectJson::ProjectJson { .. }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn discover_workspace_config(&self) -> Option<&DiscoverWorkspaceConfig> {
|
pub fn discover_workspace_config(&self) -> Option<&DiscoverWorkspaceConfig> {
|
||||||
self.workspace_discoverConfig().as_ref()
|
self.workspace_discoverConfig(None).as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn linked_or_discovered_projects(&self) -> Vec<LinkedProject> {
|
pub fn linked_or_discovered_projects(&self) -> Vec<LinkedProject> {
|
||||||
match self.linkedProjects().as_slice() {
|
match self.linkedProjects(None).as_slice() {
|
||||||
[] => {
|
[] => {
|
||||||
let exclude_dirs: Vec<_> =
|
let exclude_dirs: Vec<_> =
|
||||||
self.files_excludeDirs().iter().map(|p| self.root_path.join(p)).collect();
|
self.files_excludeDirs(None).iter().map(|p| self.root_path.join(p)).collect();
|
||||||
self.discovered_projects
|
self.discovered_projects
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|project| {
|
.filter(|project| {
|
||||||
|
@ -1724,48 +1736,48 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prefill_caches(&self) -> bool {
|
pub fn prefill_caches(&self) -> bool {
|
||||||
self.cachePriming_enable().to_owned()
|
self.cachePriming_enable(None).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn publish_diagnostics(&self) -> bool {
|
pub fn publish_diagnostics(&self) -> bool {
|
||||||
self.diagnostics_enable().to_owned()
|
self.diagnostics_enable(None).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics_map(&self) -> DiagnosticsMapConfig {
|
pub fn diagnostics_map(&self) -> DiagnosticsMapConfig {
|
||||||
DiagnosticsMapConfig {
|
DiagnosticsMapConfig {
|
||||||
remap_prefix: self.diagnostics_remapPrefix().clone(),
|
remap_prefix: self.diagnostics_remapPrefix(None).clone(),
|
||||||
warnings_as_info: self.diagnostics_warningsAsInfo().clone(),
|
warnings_as_info: self.diagnostics_warningsAsInfo(None).clone(),
|
||||||
warnings_as_hint: self.diagnostics_warningsAsHint().clone(),
|
warnings_as_hint: self.diagnostics_warningsAsHint(None).clone(),
|
||||||
check_ignore: self.check_ignore().clone(),
|
check_ignore: self.check_ignore(None).clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extra_args(&self) -> &Vec<String> {
|
pub fn extra_args(&self) -> &Vec<String> {
|
||||||
self.cargo_extraArgs()
|
self.cargo_extraArgs(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extra_env(&self) -> &FxHashMap<String, String> {
|
pub fn extra_env(&self) -> &FxHashMap<String, String> {
|
||||||
self.cargo_extraEnv()
|
self.cargo_extraEnv(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_extra_args(&self) -> Vec<String> {
|
pub fn check_extra_args(&self) -> Vec<String> {
|
||||||
let mut extra_args = self.extra_args().clone();
|
let mut extra_args = self.extra_args().clone();
|
||||||
extra_args.extend_from_slice(self.check_extraArgs());
|
extra_args.extend_from_slice(self.check_extraArgs(None));
|
||||||
extra_args
|
extra_args
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_extra_env(&self) -> FxHashMap<String, String> {
|
pub fn check_extra_env(&self) -> FxHashMap<String, String> {
|
||||||
let mut extra_env = self.cargo_extraEnv().clone();
|
let mut extra_env = self.cargo_extraEnv(None).clone();
|
||||||
extra_env.extend(self.check_extraEnv().clone());
|
extra_env.extend(self.check_extraEnv(None).clone());
|
||||||
extra_env
|
extra_env
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lru_parse_query_capacity(&self) -> Option<u16> {
|
pub fn lru_parse_query_capacity(&self) -> Option<u16> {
|
||||||
self.lru_capacity().to_owned()
|
self.lru_capacity(None).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lru_query_capacities_config(&self) -> Option<&FxHashMap<Box<str>, u16>> {
|
pub fn lru_query_capacities_config(&self) -> Option<&FxHashMap<Box<str>, u16>> {
|
||||||
self.lru_query_capacities().is_empty().not().then(|| self.lru_query_capacities())
|
self.lru_query_capacities(None).is_empty().not().then(|| self.lru_query_capacities(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn proc_macro_srv(&self) -> Option<AbsPathBuf> {
|
pub fn proc_macro_srv(&self) -> Option<AbsPathBuf> {
|
||||||
|
@ -1774,7 +1786,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ignored_proc_macros(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
|
pub fn ignored_proc_macros(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
|
||||||
self.procMacro_ignored()
|
self.procMacro_ignored(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_proc_macros(&self) -> bool {
|
pub fn expand_proc_macros(&self) -> bool {
|
||||||
|
@ -1789,7 +1801,11 @@ impl Config {
|
||||||
}
|
}
|
||||||
_ => FilesWatcher::Server,
|
_ => FilesWatcher::Server,
|
||||||
},
|
},
|
||||||
exclude: self.files_excludeDirs().iter().map(|it| self.root_path.join(it)).collect(),
|
exclude: self
|
||||||
|
.files_excludeDirs(None)
|
||||||
|
.iter()
|
||||||
|
.map(|it| self.root_path.join(it))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1800,22 +1816,22 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cargo_autoreload_config(&self) -> bool {
|
pub fn cargo_autoreload_config(&self) -> bool {
|
||||||
self.cargo_autoreload().to_owned()
|
self.cargo_autoreload(None).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_build_scripts(&self) -> bool {
|
pub fn run_build_scripts(&self) -> bool {
|
||||||
self.cargo_buildScripts_enable().to_owned() || self.procMacro_enable().to_owned()
|
self.cargo_buildScripts_enable(None).to_owned() || self.procMacro_enable().to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cargo(&self) -> CargoConfig {
|
pub fn cargo(&self) -> CargoConfig {
|
||||||
let rustc_source = self.rustc_source().as_ref().map(|rustc_src| {
|
let rustc_source = self.rustc_source(None).as_ref().map(|rustc_src| {
|
||||||
if rustc_src == "discover" {
|
if rustc_src == "discover" {
|
||||||
RustLibSource::Discover
|
RustLibSource::Discover
|
||||||
} else {
|
} else {
|
||||||
RustLibSource::Path(self.root_path.join(rustc_src))
|
RustLibSource::Path(self.root_path.join(rustc_src))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let sysroot = self.cargo_sysroot().as_ref().map(|sysroot| {
|
let sysroot = self.cargo_sysroot(None).as_ref().map(|sysroot| {
|
||||||
if sysroot == "discover" {
|
if sysroot == "discover" {
|
||||||
RustLibSource::Discover
|
RustLibSource::Discover
|
||||||
} else {
|
} else {
|
||||||
|
@ -1823,26 +1839,26 @@ impl Config {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let sysroot_src =
|
let sysroot_src =
|
||||||
self.cargo_sysrootSrc().as_ref().map(|sysroot| self.root_path.join(sysroot));
|
self.cargo_sysrootSrc(None).as_ref().map(|sysroot| self.root_path.join(sysroot));
|
||||||
let sysroot_query_metadata = self.cargo_sysrootQueryMetadata();
|
let sysroot_query_metadata = self.cargo_sysrootQueryMetadata(None);
|
||||||
|
|
||||||
CargoConfig {
|
CargoConfig {
|
||||||
all_targets: *self.cargo_allTargets(),
|
all_targets: *self.cargo_allTargets(None),
|
||||||
features: match &self.cargo_features() {
|
features: match &self.cargo_features(None) {
|
||||||
CargoFeaturesDef::All => CargoFeatures::All,
|
CargoFeaturesDef::All => CargoFeatures::All,
|
||||||
CargoFeaturesDef::Selected(features) => CargoFeatures::Selected {
|
CargoFeaturesDef::Selected(features) => CargoFeatures::Selected {
|
||||||
features: features.clone(),
|
features: features.clone(),
|
||||||
no_default_features: self.cargo_noDefaultFeatures().to_owned(),
|
no_default_features: self.cargo_noDefaultFeatures(None).to_owned(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
target: self.cargo_target().clone(),
|
target: self.cargo_target(None).clone(),
|
||||||
sysroot,
|
sysroot,
|
||||||
sysroot_query_metadata: *sysroot_query_metadata,
|
sysroot_query_metadata: *sysroot_query_metadata,
|
||||||
sysroot_src,
|
sysroot_src,
|
||||||
rustc_source,
|
rustc_source,
|
||||||
cfg_overrides: project_model::CfgOverrides {
|
cfg_overrides: project_model::CfgOverrides {
|
||||||
global: CfgDiff::new(
|
global: CfgDiff::new(
|
||||||
self.cargo_cfgs()
|
self.cargo_cfgs(None)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, val)| match val {
|
.map(|(key, val)| match val {
|
||||||
Some(val) => CfgAtom::KeyValue {
|
Some(val) => CfgAtom::KeyValue {
|
||||||
|
@ -1857,49 +1873,49 @@ impl Config {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
selective: Default::default(),
|
selective: Default::default(),
|
||||||
},
|
},
|
||||||
wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(),
|
wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(None),
|
||||||
invocation_strategy: match self.cargo_buildScripts_invocationStrategy() {
|
invocation_strategy: match self.cargo_buildScripts_invocationStrategy(None) {
|
||||||
InvocationStrategy::Once => project_model::InvocationStrategy::Once,
|
InvocationStrategy::Once => project_model::InvocationStrategy::Once,
|
||||||
InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace,
|
InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace,
|
||||||
},
|
},
|
||||||
invocation_location: match self.cargo_buildScripts_invocationLocation() {
|
invocation_location: match self.cargo_buildScripts_invocationLocation(None) {
|
||||||
InvocationLocation::Root => {
|
InvocationLocation::Root => {
|
||||||
project_model::InvocationLocation::Root(self.root_path.clone())
|
project_model::InvocationLocation::Root(self.root_path.clone())
|
||||||
}
|
}
|
||||||
InvocationLocation::Workspace => project_model::InvocationLocation::Workspace,
|
InvocationLocation::Workspace => project_model::InvocationLocation::Workspace,
|
||||||
},
|
},
|
||||||
run_build_script_command: self.cargo_buildScripts_overrideCommand().clone(),
|
run_build_script_command: self.cargo_buildScripts_overrideCommand(None).clone(),
|
||||||
extra_args: self.cargo_extraArgs().clone(),
|
extra_args: self.cargo_extraArgs(None).clone(),
|
||||||
extra_env: self.cargo_extraEnv().clone(),
|
extra_env: self.cargo_extraEnv(None).clone(),
|
||||||
target_dir: self.target_dir_from_config(),
|
target_dir: self.target_dir_from_config(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rustfmt(&self) -> RustfmtConfig {
|
pub fn rustfmt(&self, source_root_id: Option<SourceRootId>) -> RustfmtConfig {
|
||||||
match &self.rustfmt_overrideCommand() {
|
match &self.rustfmt_overrideCommand(source_root_id) {
|
||||||
Some(args) if !args.is_empty() => {
|
Some(args) if !args.is_empty() => {
|
||||||
let mut args = args.clone();
|
let mut args = args.clone();
|
||||||
let command = args.remove(0);
|
let command = args.remove(0);
|
||||||
RustfmtConfig::CustomCommand { command, args }
|
RustfmtConfig::CustomCommand { command, args }
|
||||||
}
|
}
|
||||||
Some(_) | None => RustfmtConfig::Rustfmt {
|
Some(_) | None => RustfmtConfig::Rustfmt {
|
||||||
extra_args: self.rustfmt_extraArgs().clone(),
|
extra_args: self.rustfmt_extraArgs(source_root_id).clone(),
|
||||||
enable_range_formatting: *self.rustfmt_rangeFormatting_enable(),
|
enable_range_formatting: *self.rustfmt_rangeFormatting_enable(source_root_id),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flycheck_workspace(&self) -> bool {
|
pub fn flycheck_workspace(&self) -> bool {
|
||||||
*self.check_workspace()
|
*self.check_workspace(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cargo_test_options(&self) -> CargoOptions {
|
pub fn cargo_test_options(&self) -> CargoOptions {
|
||||||
CargoOptions {
|
CargoOptions {
|
||||||
target_triples: self.cargo_target().clone().into_iter().collect(),
|
target_triples: self.cargo_target(None).clone().into_iter().collect(),
|
||||||
all_targets: false,
|
all_targets: false,
|
||||||
no_default_features: *self.cargo_noDefaultFeatures(),
|
no_default_features: *self.cargo_noDefaultFeatures(None),
|
||||||
all_features: matches!(self.cargo_features(), CargoFeaturesDef::All),
|
all_features: matches!(self.cargo_features(None), CargoFeaturesDef::All),
|
||||||
features: match self.cargo_features().clone() {
|
features: match self.cargo_features(None).clone() {
|
||||||
CargoFeaturesDef::All => vec![],
|
CargoFeaturesDef::All => vec![],
|
||||||
CargoFeaturesDef::Selected(it) => it,
|
CargoFeaturesDef::Selected(it) => it,
|
||||||
},
|
},
|
||||||
|
@ -1910,7 +1926,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn flycheck(&self) -> FlycheckConfig {
|
pub fn flycheck(&self) -> FlycheckConfig {
|
||||||
match &self.check_overrideCommand() {
|
match &self.check_overrideCommand(None) {
|
||||||
Some(args) if !args.is_empty() => {
|
Some(args) if !args.is_empty() => {
|
||||||
let mut args = args.clone();
|
let mut args = args.clone();
|
||||||
let command = args.remove(0);
|
let command = args.remove(0);
|
||||||
|
@ -1918,13 +1934,13 @@ impl Config {
|
||||||
command,
|
command,
|
||||||
args,
|
args,
|
||||||
extra_env: self.check_extra_env(),
|
extra_env: self.check_extra_env(),
|
||||||
invocation_strategy: match self.check_invocationStrategy() {
|
invocation_strategy: match self.check_invocationStrategy(None) {
|
||||||
InvocationStrategy::Once => flycheck::InvocationStrategy::Once,
|
InvocationStrategy::Once => flycheck::InvocationStrategy::Once,
|
||||||
InvocationStrategy::PerWorkspace => {
|
InvocationStrategy::PerWorkspace => {
|
||||||
flycheck::InvocationStrategy::PerWorkspace
|
flycheck::InvocationStrategy::PerWorkspace
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
invocation_location: match self.check_invocationLocation() {
|
invocation_location: match self.check_invocationLocation(None) {
|
||||||
InvocationLocation::Root => {
|
InvocationLocation::Root => {
|
||||||
flycheck::InvocationLocation::Root(self.root_path.clone())
|
flycheck::InvocationLocation::Root(self.root_path.clone())
|
||||||
}
|
}
|
||||||
|
@ -1933,28 +1949,30 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) | None => FlycheckConfig::CargoCommand {
|
Some(_) | None => FlycheckConfig::CargoCommand {
|
||||||
command: self.check_command().clone(),
|
command: self.check_command(None).clone(),
|
||||||
options: CargoOptions {
|
options: CargoOptions {
|
||||||
target_triples: self
|
target_triples: self
|
||||||
.check_targets()
|
.check_targets(None)
|
||||||
.clone()
|
.clone()
|
||||||
.and_then(|targets| match &targets.0[..] {
|
.and_then(|targets| match &targets.0[..] {
|
||||||
[] => None,
|
[] => None,
|
||||||
targets => Some(targets.into()),
|
targets => Some(targets.into()),
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| self.cargo_target().clone().into_iter().collect()),
|
.unwrap_or_else(|| self.cargo_target(None).clone().into_iter().collect()),
|
||||||
all_targets: self.check_allTargets().unwrap_or(*self.cargo_allTargets()),
|
all_targets: self
|
||||||
|
.check_allTargets(None)
|
||||||
|
.unwrap_or(*self.cargo_allTargets(None)),
|
||||||
no_default_features: self
|
no_default_features: self
|
||||||
.check_noDefaultFeatures()
|
.check_noDefaultFeatures(None)
|
||||||
.unwrap_or(*self.cargo_noDefaultFeatures()),
|
.unwrap_or(*self.cargo_noDefaultFeatures(None)),
|
||||||
all_features: matches!(
|
all_features: matches!(
|
||||||
self.check_features().as_ref().unwrap_or(self.cargo_features()),
|
self.check_features(None).as_ref().unwrap_or(self.cargo_features(None)),
|
||||||
CargoFeaturesDef::All
|
CargoFeaturesDef::All
|
||||||
),
|
),
|
||||||
features: match self
|
features: match self
|
||||||
.check_features()
|
.check_features(None)
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| self.cargo_features().clone())
|
.unwrap_or_else(|| self.cargo_features(None).clone())
|
||||||
{
|
{
|
||||||
CargoFeaturesDef::All => vec![],
|
CargoFeaturesDef::All => vec![],
|
||||||
CargoFeaturesDef::Selected(it) => it,
|
CargoFeaturesDef::Selected(it) => it,
|
||||||
|
@ -1969,7 +1987,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn target_dir_from_config(&self) -> Option<Utf8PathBuf> {
|
fn target_dir_from_config(&self) -> Option<Utf8PathBuf> {
|
||||||
self.cargo_targetDir().as_ref().and_then(|target_dir| match target_dir {
|
self.cargo_targetDir(None).as_ref().and_then(|target_dir| match target_dir {
|
||||||
TargetDirectory::UseSubdirectory(true) => {
|
TargetDirectory::UseSubdirectory(true) => {
|
||||||
Some(Utf8PathBuf::from("target/rust-analyzer"))
|
Some(Utf8PathBuf::from("target/rust-analyzer"))
|
||||||
}
|
}
|
||||||
|
@ -1980,18 +1998,18 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_on_save(&self) -> bool {
|
pub fn check_on_save(&self) -> bool {
|
||||||
*self.checkOnSave()
|
*self.checkOnSave(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn script_rebuild_on_save(&self) -> bool {
|
pub fn script_rebuild_on_save(&self) -> bool {
|
||||||
*self.cargo_buildScripts_rebuildOnSave()
|
*self.cargo_buildScripts_rebuildOnSave(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn runnables(&self) -> RunnablesConfig {
|
pub fn runnables(&self) -> RunnablesConfig {
|
||||||
RunnablesConfig {
|
RunnablesConfig {
|
||||||
override_cargo: self.runnables_command().clone(),
|
override_cargo: self.runnables_command(None).clone(),
|
||||||
cargo_extra_args: self.runnables_extraArgs().clone(),
|
cargo_extra_args: self.runnables_extraArgs(None).clone(),
|
||||||
extra_test_binary_args: self.runnables_extraTestBinaryArgs().clone(),
|
extra_test_binary_args: self.runnables_extraTestBinaryArgs(None).clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2062,7 +2080,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prime_caches_num_threads(&self) -> usize {
|
pub fn prime_caches_num_threads(&self) -> usize {
|
||||||
match self.cachePriming_numThreads() {
|
match self.cachePriming_numThreads(None) {
|
||||||
NumThreads::Concrete(0) | NumThreads::Physical => num_cpus::get_physical(),
|
NumThreads::Concrete(0) | NumThreads::Physical => num_cpus::get_physical(),
|
||||||
&NumThreads::Concrete(n) => n,
|
&NumThreads::Concrete(n) => n,
|
||||||
NumThreads::Logical => num_cpus::get(),
|
NumThreads::Logical => num_cpus::get(),
|
||||||
|
@ -2536,20 +2554,23 @@ macro_rules! _impl_for_config_data {
|
||||||
$($doc)*
|
$($doc)*
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
$vis fn $field(&self, source_root: Option<SourceRootId>) -> &$ty {
|
$vis fn $field(&self, source_root: Option<SourceRootId>) -> &$ty {
|
||||||
let mut par: Option<SourceRootId> = source_root;
|
let mut source_root = source_root.as_ref();
|
||||||
while let Some(source_root_id) = par {
|
while let Some(sr) = source_root {
|
||||||
par = self.source_root_parent_map.get(&source_root_id).copied();
|
if let Some((file, _)) = self.ratoml_file.get(&sr) {
|
||||||
if let Some((config, _)) = self.ratoml_files.get(&source_root_id) {
|
match file {
|
||||||
if let Some(value) = config.$field.as_ref() {
|
RatomlFile::Workspace(config) => {
|
||||||
return value;
|
if let Some(v) = config.local.$field.as_ref() {
|
||||||
|
return &v;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RatomlFile::Crate(config) => {
|
||||||
|
if let Some(value) = config.$field.as_ref() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
source_root = self.source_root_parent_map.get(&sr);
|
||||||
|
|
||||||
if let Some((root_path_ratoml, _)) = self.root_ratoml.as_ref() {
|
|
||||||
if let Some(v) = root_path_ratoml.local.$field.as_ref() {
|
|
||||||
return &v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(v) = self.client_config.0.local.$field.as_ref() {
|
if let Some(v) = self.client_config.0.local.$field.as_ref() {
|
||||||
|
@ -2576,12 +2597,16 @@ macro_rules! _impl_for_config_data {
|
||||||
$(
|
$(
|
||||||
$($doc)*
|
$($doc)*
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
$vis fn $field(&self) -> &$ty {
|
$vis fn $field(&self, source_root : Option<SourceRootId>) -> &$ty {
|
||||||
|
let mut source_root = source_root.as_ref();
|
||||||
if let Some((root_path_ratoml, _)) = self.root_ratoml.as_ref() {
|
while let Some(sr) = source_root {
|
||||||
if let Some(v) = root_path_ratoml.global.$field.as_ref() {
|
if let Some((RatomlFile::Workspace(config), _)) = self.ratoml_file.get(&sr) {
|
||||||
return &v;
|
if let Some(v) = config.global.$field.as_ref() {
|
||||||
|
return &v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source_root = self.source_root_parent_map.get(&sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(v) = self.client_config.0.global.$field.as_ref() {
|
if let Some(v) = self.client_config.0.global.$field.as_ref() {
|
||||||
|
@ -3524,7 +3549,7 @@ mod tests {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
(config, _, _) = config.apply_change(change);
|
(config, _, _) = config.apply_change(change);
|
||||||
assert_eq!(config.cargo_targetDir(), &None);
|
assert_eq!(config.cargo_targetDir(None), &None);
|
||||||
assert!(
|
assert!(
|
||||||
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none())
|
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none())
|
||||||
);
|
);
|
||||||
|
@ -3547,7 +3572,7 @@ mod tests {
|
||||||
|
|
||||||
(config, _, _) = config.apply_change(change);
|
(config, _, _) = config.apply_change(change);
|
||||||
|
|
||||||
assert_eq!(config.cargo_targetDir(), &Some(TargetDirectory::UseSubdirectory(true)));
|
assert_eq!(config.cargo_targetDir(None), &Some(TargetDirectory::UseSubdirectory(true)));
|
||||||
assert!(
|
assert!(
|
||||||
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer")))
|
matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer")))
|
||||||
);
|
);
|
||||||
|
@ -3571,7 +3596,7 @@ mod tests {
|
||||||
(config, _, _) = config.apply_change(change);
|
(config, _, _) = config.apply_change(change);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.cargo_targetDir(),
|
config.cargo_targetDir(None),
|
||||||
&Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder")))
|
&Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder")))
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -3591,7 +3616,7 @@ mod tests {
|
||||||
|
|
||||||
let mut change = ConfigChange::default();
|
let mut change = ConfigChange::default();
|
||||||
|
|
||||||
change.change_root_ratoml(Some(
|
change.change_user_config(Some(
|
||||||
toml::toml! {
|
toml::toml! {
|
||||||
[cargo.cfgs]
|
[cargo.cfgs]
|
||||||
these = "these"
|
these = "these"
|
||||||
|
@ -3650,21 +3675,7 @@ mod tests {
|
||||||
let (_, e, _) = config.apply_change(change);
|
let (_, e, _) = config.apply_change(change);
|
||||||
expect_test::expect![[r#"
|
expect_test::expect![[r#"
|
||||||
ConfigErrors(
|
ConfigErrors(
|
||||||
[
|
[],
|
||||||
Toml {
|
|
||||||
config_key: "invalid/config/err",
|
|
||||||
error: Error {
|
|
||||||
inner: Error {
|
|
||||||
inner: TomlError {
|
|
||||||
message: "unexpected field",
|
|
||||||
raw: None,
|
|
||||||
keys: [],
|
|
||||||
span: None,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
"#]]
|
"#]]
|
||||||
.assert_debug_eq(&e);
|
.assert_debug_eq(&e);
|
||||||
|
|
|
@ -10,6 +10,7 @@ use flycheck::{project_json, FlycheckHandle};
|
||||||
use hir::ChangeWithProcMacros;
|
use hir::ChangeWithProcMacros;
|
||||||
use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
|
use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
|
||||||
use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabaseExt};
|
use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabaseExt};
|
||||||
|
use itertools::Itertools;
|
||||||
use load_cargo::SourceRootConfig;
|
use load_cargo::SourceRootConfig;
|
||||||
use lsp_types::{SemanticTokens, Url};
|
use lsp_types::{SemanticTokens, Url};
|
||||||
use nohash_hasher::IntMap;
|
use nohash_hasher::IntMap;
|
||||||
|
@ -22,16 +23,13 @@ use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, Worksp
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use tracing::{span, trace, Level};
|
use tracing::{span, trace, Level};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs};
|
use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs, VfsPath};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, ConfigChange, ConfigErrors},
|
config::{Config, ConfigChange, ConfigErrors, RatomlFileKind},
|
||||||
diagnostics::{CheckFixes, DiagnosticCollection},
|
diagnostics::{CheckFixes, DiagnosticCollection},
|
||||||
line_index::{LineEndings, LineIndex},
|
line_index::{LineEndings, LineIndex},
|
||||||
lsp::{
|
lsp::{from_proto, to_proto::url_from_abs_path},
|
||||||
from_proto::{self},
|
|
||||||
to_proto::url_from_abs_path,
|
|
||||||
},
|
|
||||||
lsp_ext,
|
lsp_ext,
|
||||||
main_loop::Task,
|
main_loop::Task,
|
||||||
mem_docs::MemDocs,
|
mem_docs::MemDocs,
|
||||||
|
@ -382,37 +380,62 @@ impl GlobalState {
|
||||||
{
|
{
|
||||||
let config_change = {
|
let config_change = {
|
||||||
let user_config_path = self.config.user_config_path();
|
let user_config_path = self.config.user_config_path();
|
||||||
let root_ratoml_path = self.config.root_ratoml_path();
|
|
||||||
let mut change = ConfigChange::default();
|
let mut change = ConfigChange::default();
|
||||||
let db = self.analysis_host.raw_database();
|
let db = self.analysis_host.raw_database();
|
||||||
|
|
||||||
|
// FIXME @alibektas : This is silly. There is no reason to use VfsPaths when there is SourceRoots. But how
|
||||||
|
// do I resolve a "workspace_root" to its corresponding id without having to rely on a cargo.toml's ( or project json etc.) file id?
|
||||||
|
let workspace_ratoml_paths = self
|
||||||
|
.workspaces
|
||||||
|
.iter()
|
||||||
|
.map(|ws| {
|
||||||
|
VfsPath::from({
|
||||||
|
let mut p = ws.workspace_root().to_owned();
|
||||||
|
p.push("rust-analyzer.toml");
|
||||||
|
p
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files {
|
for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files {
|
||||||
if vfs_path == *user_config_path {
|
if vfs_path == *user_config_path {
|
||||||
change.change_user_config(Some(db.file_text(file_id)));
|
change.change_user_config(Some(db.file_text(file_id)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if vfs_path == *root_ratoml_path {
|
|
||||||
change.change_root_ratoml(Some(db.file_text(file_id)));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If change has been made to a ratoml file that
|
// If change has been made to a ratoml file that
|
||||||
// belongs to a non-local source root, we will ignore it.
|
// belongs to a non-local source root, we will ignore it.
|
||||||
// As it doesn't make sense a users to use external config files.
|
|
||||||
let sr_id = db.file_source_root(file_id);
|
let sr_id = db.file_source_root(file_id);
|
||||||
let sr = db.source_root(sr_id);
|
let sr = db.source_root(sr_id);
|
||||||
|
|
||||||
if !sr.is_library {
|
if !sr.is_library {
|
||||||
if let Some((old_path, old_text)) = change.change_ratoml(
|
let entry = if workspace_ratoml_paths.contains(&vfs_path) {
|
||||||
sr_id,
|
change.change_workspace_ratoml(
|
||||||
vfs_path.clone(),
|
sr_id,
|
||||||
Some(db.file_text(file_id)),
|
vfs_path.clone(),
|
||||||
) {
|
Some(db.file_text(file_id)),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
change.change_ratoml(
|
||||||
|
sr_id,
|
||||||
|
vfs_path.clone(),
|
||||||
|
Some(db.file_text(file_id)),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some((kind, old_path, old_text)) = entry {
|
||||||
// SourceRoot has more than 1 RATOML files. In this case lexicographically smaller wins.
|
// SourceRoot has more than 1 RATOML files. In this case lexicographically smaller wins.
|
||||||
if old_path < vfs_path {
|
if old_path < vfs_path {
|
||||||
span!(Level::ERROR, "Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect.");
|
span!(Level::ERROR, "Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect.");
|
||||||
// Put the old one back in.
|
// Put the old one back in.
|
||||||
change.change_ratoml(sr_id, old_path, old_text);
|
match kind {
|
||||||
|
RatomlFileKind::Crate => {
|
||||||
|
change.change_ratoml(sr_id, old_path, old_text);
|
||||||
|
}
|
||||||
|
RatomlFileKind::Workspace => {
|
||||||
|
change.change_workspace_ratoml(sr_id, old_path, old_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -430,7 +453,7 @@ impl GlobalState {
|
||||||
if should_update {
|
if should_update {
|
||||||
self.update_configuration(config);
|
self.update_configuration(config);
|
||||||
} else {
|
} else {
|
||||||
// No global or client level config was changed. So we can just naively replace config.
|
// No global or client level config was changed. So we can naively replace config.
|
||||||
self.config = Arc::new(config);
|
self.config = Arc::new(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2110,8 +2110,9 @@ fn run_rustfmt(
|
||||||
let edition = editions.iter().copied().max();
|
let edition = editions.iter().copied().max();
|
||||||
|
|
||||||
let line_index = snap.file_line_index(file_id)?;
|
let line_index = snap.file_line_index(file_id)?;
|
||||||
|
let sr = snap.analysis.source_root_id(file_id)?;
|
||||||
|
|
||||||
let mut command = match snap.config.rustfmt() {
|
let mut command = match snap.config.rustfmt(Some(sr)) {
|
||||||
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
|
RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
|
||||||
// FIXME: Set RUSTUP_TOOLCHAIN
|
// FIXME: Set RUSTUP_TOOLCHAIN
|
||||||
let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path());
|
let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path());
|
||||||
|
@ -2300,7 +2301,7 @@ pub(crate) fn internal_testing_fetch_config(
|
||||||
serde_json::to_value(match &*params.config {
|
serde_json::to_value(match &*params.config {
|
||||||
"local" => state.config.assist(source_root).assist_emit_must_use,
|
"local" => state.config.assist(source_root).assist_emit_must_use,
|
||||||
"global" => matches!(
|
"global" => matches!(
|
||||||
state.config.rustfmt(),
|
state.config.rustfmt(source_root),
|
||||||
RustfmtConfig::Rustfmt { enable_range_formatting: true, .. }
|
RustfmtConfig::Rustfmt { enable_range_formatting: true, .. }
|
||||||
),
|
),
|
||||||
_ => return Err(anyhow::anyhow!("Unknown test config key: {}", params.config)),
|
_ => return Err(anyhow::anyhow!("Unknown test config key: {}", params.config)),
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl GlobalState {
|
||||||
};
|
};
|
||||||
let mut message = String::new();
|
let mut message = String::new();
|
||||||
|
|
||||||
if !self.config.cargo_autoreload()
|
if !self.config.cargo_autoreload(None)
|
||||||
&& self.is_quiescent()
|
&& self.is_quiescent()
|
||||||
&& self.fetch_workspaces_queue.op_requested()
|
&& self.fetch_workspaces_queue.op_requested()
|
||||||
&& self.config.discover_workspace_config().is_none()
|
&& self.config.discover_workspace_config().is_none()
|
||||||
|
@ -541,7 +541,6 @@ impl GlobalState {
|
||||||
|
|
||||||
watchers.extend(
|
watchers.extend(
|
||||||
iter::once(self.config.user_config_path().as_path())
|
iter::once(self.config.user_config_path().as_path())
|
||||||
.chain(iter::once(self.config.root_ratoml_path().as_path()))
|
|
||||||
.chain(self.workspaces.iter().map(|ws| ws.manifest().map(ManifestPath::as_ref)))
|
.chain(self.workspaces.iter().map(|ws| ws.manifest().map(ManifestPath::as_ref)))
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|glob_pattern| lsp_types::FileSystemWatcher {
|
.map(|glob_pattern| lsp_types::FileSystemWatcher {
|
||||||
|
|
|
@ -10,6 +10,7 @@ use paths::Utf8PathBuf;
|
||||||
|
|
||||||
use rust_analyzer::lsp::ext::{InternalTestingFetchConfig, InternalTestingFetchConfigParams};
|
use rust_analyzer::lsp::ext::{InternalTestingFetchConfig, InternalTestingFetchConfigParams};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use test_utils::skip_slow_tests;
|
||||||
|
|
||||||
enum QueryType {
|
enum QueryType {
|
||||||
Local,
|
Local,
|
||||||
|
@ -182,6 +183,10 @@ impl RatomlTest {
|
||||||
/// the client config.
|
/// the client config.
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_client_config_basic() {
|
fn ratoml_client_config_basic() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
let server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -283,6 +288,10 @@ enum Value {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
||||||
fn ratoml_user_config_detected() {
|
fn ratoml_user_config_detected() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
let server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -312,6 +321,10 @@ enum Value {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
||||||
fn ratoml_create_user_config() {
|
fn ratoml_create_user_config() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -343,6 +356,10 @@ enum Value {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
||||||
fn ratoml_modify_user_config() {
|
fn ratoml_modify_user_config() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -373,6 +390,10 @@ assist.emitMustUse = true"#,
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
#[ignore = "the user config is currently not being watched on startup, fix this"]
|
||||||
fn ratoml_delete_user_config() {
|
fn ratoml_delete_user_config() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -402,6 +423,10 @@ assist.emitMustUse = true"#,
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_inherit_config_from_ws_root() {
|
fn ratoml_inherit_config_from_ws_root() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
let server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -445,6 +470,10 @@ pub fn add(left: usize, right: usize) -> usize {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_modify_ratoml_at_ws_root() {
|
fn ratoml_modify_ratoml_at_ws_root() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -490,6 +519,10 @@ pub fn add(left: usize, right: usize) -> usize {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_delete_ratoml_at_ws_root() {
|
fn ratoml_delete_ratoml_at_ws_root() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -535,6 +568,10 @@ pub fn add(left: usize, right: usize) -> usize {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_add_immediate_child_to_ws_root() {
|
fn ratoml_add_immediate_child_to_ws_root() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -581,6 +618,10 @@ pub fn add(left: usize, right: usize) -> usize {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "Root ratomls are not being looked for on startup. Fix this."]
|
#[ignore = "Root ratomls are not being looked for on startup. Fix this."]
|
||||||
fn ratoml_rm_ws_root_ratoml_child_has_client_as_parent_now() {
|
fn ratoml_rm_ws_root_ratoml_child_has_client_as_parent_now() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -626,6 +667,10 @@ pub fn add(left: usize, right: usize) -> usize {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_crates_both_roots() {
|
fn ratoml_crates_both_roots() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
let server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -670,6 +715,10 @@ enum Value {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ratoml_multiple_ratoml_in_single_source_root() {
|
fn ratoml_multiple_ratoml_in_single_source_root() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
let server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -700,37 +749,6 @@ fn ratoml_multiple_ratoml_in_single_source_root() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(server.query(QueryType::Local, 3));
|
assert!(server.query(QueryType::Local, 3));
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
|
||||||
vec![
|
|
||||||
r#"
|
|
||||||
//- /p1/Cargo.toml
|
|
||||||
[package]
|
|
||||||
name = "p1"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
"#,
|
|
||||||
r#"
|
|
||||||
//- /p1/src/rust-analyzer.toml
|
|
||||||
assist.emitMustUse = false
|
|
||||||
"#,
|
|
||||||
r#"
|
|
||||||
//- /p1/rust-analyzer.toml
|
|
||||||
assist.emitMustUse = true
|
|
||||||
"#,
|
|
||||||
r#"
|
|
||||||
//- /p1/src/lib.rs
|
|
||||||
enum Value {
|
|
||||||
Number(i32),
|
|
||||||
Text(String),
|
|
||||||
}
|
|
||||||
"#,
|
|
||||||
],
|
|
||||||
vec!["p1"],
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(server.query(QueryType::Local, 3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If a root is non-local, so we cannot find what its parent is
|
/// If a root is non-local, so we cannot find what its parent is
|
||||||
|
@ -808,8 +826,11 @@ enum Value {
|
||||||
/// Having a ratoml file at the root of a project enables
|
/// Having a ratoml file at the root of a project enables
|
||||||
/// configuring global level configurations as well.
|
/// configuring global level configurations as well.
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "Root ratomls are not being looked for on startup. Fix this."]
|
|
||||||
fn ratoml_in_root_is_global() {
|
fn ratoml_in_root_is_global() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let server = RatomlTest::new(
|
let server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -820,7 +841,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
//- /rust-analyzer.toml
|
//- /p1/rust-analyzer.toml
|
||||||
rustfmt.rangeFormatting.enable = true
|
rustfmt.rangeFormatting.enable = true
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
|
@ -829,7 +850,7 @@ fn main() {
|
||||||
todo!()
|
todo!()
|
||||||
}"#,
|
}"#,
|
||||||
],
|
],
|
||||||
vec![],
|
vec!["p1"],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -837,8 +858,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "Root ratomls are not being looked for on startup. Fix this."]
|
|
||||||
fn ratoml_root_is_updateable() {
|
fn ratoml_root_is_updateable() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -849,7 +873,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
//- /rust-analyzer.toml
|
//- /p1/rust-analyzer.toml
|
||||||
rustfmt.rangeFormatting.enable = true
|
rustfmt.rangeFormatting.enable = true
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
|
@ -858,7 +882,7 @@ fn main() {
|
||||||
todo!()
|
todo!()
|
||||||
}"#,
|
}"#,
|
||||||
],
|
],
|
||||||
vec![],
|
vec!["p1"],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -868,8 +892,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "Root ratomls are not being looked for on startup. Fix this."]
|
|
||||||
fn ratoml_root_is_deletable() {
|
fn ratoml_root_is_deletable() {
|
||||||
|
if skip_slow_tests() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut server = RatomlTest::new(
|
let mut server = RatomlTest::new(
|
||||||
vec![
|
vec![
|
||||||
r#"
|
r#"
|
||||||
|
@ -880,7 +907,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
//- /rust-analyzer.toml
|
//- /p1/rust-analyzer.toml
|
||||||
rustfmt.rangeFormatting.enable = true
|
rustfmt.rangeFormatting.enable = true
|
||||||
"#,
|
"#,
|
||||||
r#"
|
r#"
|
||||||
|
@ -889,7 +916,7 @@ fn main() {
|
||||||
todo!()
|
todo!()
|
||||||
}"#,
|
}"#,
|
||||||
],
|
],
|
||||||
vec![],
|
vec!["p1"],
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue