33//! Of particular interest is the `feature_flags` hash map: while other fields
44//! configure the server itself, feature flags are passed into analysis, and
55//! tweak things like automatic insertion of `()` in completions.
6- use std:: { fmt, iter, ops:: Not , sync:: OnceLock } ;
6+ use std:: {
7+ env, fmt, iter,
8+ ops:: Not ,
9+ sync:: { LazyLock , OnceLock } ,
10+ } ;
711
812use cfg:: { CfgAtom , CfgDiff } ;
9- use dirs:: config_dir;
1013use hir:: Symbol ;
1114use ide:: {
1215 AssistConfig , CallableSnippets , CompletionConfig , DiagnosticsConfig , ExprFillDefaultMode ,
@@ -735,7 +738,6 @@ pub enum RatomlFileKind {
735738}
736739
737740#[ derive( Debug , Clone ) ]
738- // FIXME @alibektas : Seems like a clippy warning of this sort should tell that combining different ConfigInputs into one enum was not a good idea.
739741#[ allow( clippy:: large_enum_variant) ]
740742enum RatomlFile {
741743 Workspace ( GlobalLocalConfigInput ) ,
@@ -757,16 +759,6 @@ pub struct Config {
757759 /// by receiving a `lsp_types::notification::DidChangeConfiguration`.
758760 client_config : ( FullConfigInput , ConfigErrors ) ,
759761
760- /// Path to the root configuration file. This can be seen as a generic way to define what would be `$XDG_CONFIG_HOME/rust-analyzer/rust-analyzer.toml` in Linux.
761- /// If not specified by init of a `Config` object this value defaults to :
762- ///
763- /// |Platform | Value | Example |
764- /// | ------- | ------------------------------------- | ---------------------------------------- |
765- /// | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config |
766- /// | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support |
767- /// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
768- user_config_path : VfsPath ,
769-
770762 /// Config node whose values apply to **every** Rust project.
771763 user_config : Option < ( GlobalLocalConfigInput , ConfigErrors ) > ,
772764
@@ -794,8 +786,25 @@ impl std::ops::Deref for Config {
794786}
795787
796788impl Config {
797- pub fn user_config_path ( & self ) -> & VfsPath {
798- & self . user_config_path
789+ /// Path to the root configuration file. This can be seen as a generic way to define what would be `$XDG_CONFIG_HOME/rust-analyzer/rust-analyzer.toml` in Linux.
790+ /// This path is equal to:
791+ ///
792+ /// |Platform | Value | Example |
793+ /// | ------- | ------------------------------------- | ---------------------------------------- |
794+ /// | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config |
795+ /// | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support |
796+ /// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
797+ pub fn user_config_path ( ) -> Option < & ' static AbsPath > {
798+ static USER_CONFIG_PATH : LazyLock < Option < AbsPathBuf > > = LazyLock :: new ( || {
799+ let user_config_path = if let Some ( path) = env:: var_os ( "__TEST_RA_USER_CONFIG_DIR" ) {
800+ std:: path:: PathBuf :: from ( path)
801+ } else {
802+ dirs:: config_dir ( ) ?. join ( "rust-analyzer" )
803+ }
804+ . join ( "rust-analyzer.toml" ) ;
805+ Some ( AbsPathBuf :: assert_utf8 ( user_config_path) )
806+ } ) ;
807+ USER_CONFIG_PATH . as_deref ( )
799808 }
800809
801810 pub fn same_source_root_parent_map (
@@ -1315,24 +1324,8 @@ impl Config {
13151324 caps : lsp_types:: ClientCapabilities ,
13161325 workspace_roots : Vec < AbsPathBuf > ,
13171326 visual_studio_code_version : Option < Version > ,
1318- user_config_path : Option < Utf8PathBuf > ,
13191327 ) -> Self {
13201328 static DEFAULT_CONFIG_DATA : OnceLock < & ' static DefaultConfigData > = OnceLock :: new ( ) ;
1321- let user_config_path = if let Some ( user_config_path) = user_config_path {
1322- user_config_path. join ( "rust-analyzer" ) . join ( "rust-analyzer.toml" )
1323- } else {
1324- let p = config_dir ( )
1325- . expect ( "A config dir is expected to existed on all platforms ra supports." )
1326- . join ( "rust-analyzer" )
1327- . join ( "rust-analyzer.toml" ) ;
1328- Utf8PathBuf :: from_path_buf ( p) . expect ( "Config dir expected to be abs." )
1329- } ;
1330-
1331- // A user config cannot be a virtual path as rust-analyzer cannot support watching changes in virtual paths.
1332- // See `GlobalState::process_changes` to get more info.
1333- // FIXME @alibektas : Temporary solution. I don't think this is right as at some point we may allow users to specify
1334- // custom USER_CONFIG_PATHs which may also be relative.
1335- let user_config_path = VfsPath :: from ( AbsPathBuf :: assert ( user_config_path) ) ;
13361329
13371330 Config {
13381331 caps : ClientCapabilities :: new ( caps) ,
@@ -1345,7 +1338,6 @@ impl Config {
13451338 default_config : DEFAULT_CONFIG_DATA . get_or_init ( || Box :: leak ( Box :: default ( ) ) ) ,
13461339 source_root_parent_map : Arc :: new ( FxHashMap :: default ( ) ) ,
13471340 user_config : None ,
1348- user_config_path,
13491341 detached_files : Default :: default ( ) ,
13501342 validation_errors : Default :: default ( ) ,
13511343 ratoml_file : Default :: default ( ) ,
@@ -3417,7 +3409,7 @@ mod tests {
34173409 #[ test]
34183410 fn proc_macro_srv_null ( ) {
34193411 let mut config =
3420- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3412+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
34213413
34223414 let mut change = ConfigChange :: default ( ) ;
34233415 change. change_client_config ( serde_json:: json!( {
@@ -3432,7 +3424,7 @@ mod tests {
34323424 #[ test]
34333425 fn proc_macro_srv_abs ( ) {
34343426 let mut config =
3435- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3427+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
34363428 let mut change = ConfigChange :: default ( ) ;
34373429 change. change_client_config ( serde_json:: json!( {
34383430 "procMacro" : {
@@ -3446,7 +3438,7 @@ mod tests {
34463438 #[ test]
34473439 fn proc_macro_srv_rel ( ) {
34483440 let mut config =
3449- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3441+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
34503442
34513443 let mut change = ConfigChange :: default ( ) ;
34523444
@@ -3466,7 +3458,7 @@ mod tests {
34663458 #[ test]
34673459 fn cargo_target_dir_unset ( ) {
34683460 let mut config =
3469- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3461+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
34703462
34713463 let mut change = ConfigChange :: default ( ) ;
34723464
@@ -3484,7 +3476,7 @@ mod tests {
34843476 #[ test]
34853477 fn cargo_target_dir_subdir ( ) {
34863478 let mut config =
3487- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3479+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
34883480
34893481 let mut change = ConfigChange :: default ( ) ;
34903482 change. change_client_config ( serde_json:: json!( {
@@ -3502,7 +3494,7 @@ mod tests {
35023494 #[ test]
35033495 fn cargo_target_dir_relative_dir ( ) {
35043496 let mut config =
3505- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3497+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
35063498
35073499 let mut change = ConfigChange :: default ( ) ;
35083500 change. change_client_config ( serde_json:: json!( {
@@ -3523,7 +3515,7 @@ mod tests {
35233515 #[ test]
35243516 fn toml_unknown_key ( ) {
35253517 let config =
3526- Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None , None ) ;
3518+ Config :: new ( AbsPathBuf :: assert ( project_root ( ) ) , Default :: default ( ) , vec ! [ ] , None ) ;
35273519
35283520 let mut change = ConfigChange :: default ( ) ;
35293521
0 commit comments