1+ use std:: {
2+ env,
3+ path:: { Path , PathBuf } ,
4+ } ;
5+
16use lsp_types:: {
27 InitializeParams , ServerCapabilities , TextDocumentSyncCapability , TextDocumentSyncKind ,
38 TextDocumentSyncOptions ,
49} ;
10+ use tracing:: { error, info} ;
11+
12+ use crate :: workspace:: manifest:: ProjectManifest ;
13+
14+ /// The LSP config.
15+ ///
16+ /// This struct is internal only and should not be serialized or deserialized. Instead, values in
17+ /// this struct are the full view of all merged config sources, such as `initialization_opts`,
18+ /// on-disk config files (e.g. `foundry.toml`).
19+ pub ( crate ) struct Config {
20+ root_path : PathBuf ,
21+ workspace_roots : Vec < PathBuf > ,
22+ discovered_projects : Vec < ProjectManifest > ,
23+ }
24+
25+ impl Config {
26+ pub ( crate ) fn new ( root_path : PathBuf , workspace_roots : Vec < PathBuf > ) -> Self {
27+ Config { root_path, workspace_roots, discovered_projects : Default :: default ( ) }
28+ }
29+
30+ pub ( crate ) fn rediscover_workspaces ( & mut self ) {
31+ let discovered = ProjectManifest :: discover_all ( & self . workspace_roots ) ;
32+ info ! ( "discovered projects: {:?}" , discovered) ;
33+ if discovered. is_empty ( ) {
34+ error ! ( "failed to find any projects in {:?}" , & self . workspace_roots) ;
35+ }
36+ self . discovered_projects = discovered;
37+ }
38+
39+ pub ( crate ) fn root_path ( & self ) -> & Path {
40+ self . root_path . as_path ( )
41+ }
42+ }
43+
44+ pub ( crate ) fn negotiate_capabilities ( params : InitializeParams ) -> ( ServerCapabilities , Config ) {
45+ // todo: make this absolute guaranteed
46+ #[ allow( deprecated) ]
47+ let root_path = match params. root_uri . and_then ( |it| it. to_file_path ( ) . ok ( ) ) {
48+ Some ( it) => it,
49+ None => {
50+ // todo: unwrap
51+ env:: current_dir ( ) . unwrap ( )
52+ }
53+ } ;
554
6- #[ derive( Default ) ]
7- pub ( crate ) struct Config { }
55+ // todo: make this absolute guaranteed
56+ // The latest LSP spec mandates clients report `workspace_folders`, but some might still report
57+ // `root_uri`.
58+ let workspace_roots = params
59+ . workspace_folders
60+ . map ( |workspaces| {
61+ workspaces. into_iter ( ) . filter_map ( |it| it. uri . to_file_path ( ) . ok ( ) ) . collect :: < Vec < _ > > ( )
62+ } )
63+ . filter ( |workspaces| !workspaces. is_empty ( ) )
64+ . unwrap_or_else ( || vec ! [ root_path. clone( ) ] ) ;
865
9- pub ( crate ) fn negotiate_capabilities ( _: InitializeParams ) -> ( ServerCapabilities , Config ) {
1066 (
1167 ServerCapabilities {
1268 text_document_sync : Some ( TextDocumentSyncCapability :: Options (
@@ -20,6 +76,6 @@ pub(crate) fn negotiate_capabilities(_: InitializeParams) -> (ServerCapabilities
2076 ) ) ,
2177 ..Default :: default ( )
2278 } ,
23- Config :: default ( ) ,
79+ Config :: new ( root_path , workspace_roots ) ,
2480 )
2581}
0 commit comments