@@ -5,8 +5,11 @@ use std::{
55} ;
66use tracing:: info;
77
8+ use async_lsp:: lsp_types:: ProgressParamsValue ;
89use async_lsp:: lsp_types:: { CompletionItem , CompletionItemKind , PublishDiagnosticsParams , Url } ;
10+ use std:: sync:: mpsc:: Sender ;
911use tree_sitter:: Node ;
12+ use walkdir:: WalkDir ;
1013
1114use crate :: {
1215 nodekind:: NodeKind ,
@@ -17,6 +20,7 @@ pub struct ProtoLanguageState {
1720 documents : Arc < RwLock < HashMap < Url , String > > > ,
1821 trees : Arc < RwLock < HashMap < Url , ParsedTree > > > ,
1922 parser : Arc < Mutex < ProtoParser > > ,
23+ parsed_workspaces : Arc < RwLock < HashSet < String > > > ,
2024}
2125
2226impl ProtoLanguageState {
@@ -25,6 +29,7 @@ impl ProtoLanguageState {
2529 documents : Default :: default ( ) ,
2630 trees : Default :: default ( ) ,
2731 parser : Arc :: new ( Mutex :: new ( ProtoParser :: new ( ) ) ) ,
32+ parsed_workspaces : Arc :: new ( RwLock :: new ( HashSet :: new ( ) ) ) ,
2833 }
2934 }
3035
@@ -146,83 +151,65 @@ impl ProtoLanguageState {
146151 . collect ( )
147152 }
148153
149- // #[allow(unused)]
150- // pub fn add_workspace_folder_async(
151- // &mut self,
152- // workspace: WorkspaceFolder,
153- // tx: Sender<ProgressParamsValue>,
154- // ) {
155- // let parser = self.parser.clone();
156- // let tree = self.trees.clone();
157- // let docs = self.documents.clone();
158- //
159- // let begin = ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(WorkDoneProgressBegin {
160- // title: String::from("indexing"),
161- // cancellable: Some(false),
162- // percentage: Some(0),
163- // ..Default::default()
164- // }));
165- //
166- // if let Err(e) = tx.send(begin) {
167- // error!(error=%e, "failed to send work begin progress");
168- // }
169- //
170- // thread::spawn(move || {
171- // let files: Vec<_> = WalkDir::new(workspace.uri.path())
172- // .into_iter()
173- // .filter_map(|e| e.ok())
174- // .filter(|e| e.path().extension().is_some())
175- // .filter(|e| e.path().extension().unwrap() == "proto")
176- // .collect();
177- //
178- // let total_files = files.len();
179- // let mut current = 0;
180- //
181- // for file in files.into_iter() {
182- // let path = file.path();
183- // if path.is_absolute() && path.is_file() {
184- // let Ok(content) = read_to_string(path) else {
185- // continue;
186- // };
187- //
188- // let Ok(uri) = Url::from_file_path(path) else {
189- // continue;
190- // };
191- //
192- // Self::upsert_content_impl(
193- // parser.lock().expect("poison"),
194- // &uri,
195- // content,
196- // docs.write().expect("poison"),
197- // tree.write().expect("poison"),
198- // );
199- //
200- // current += 1;
201- //
202- // let report = ProgressParamsValue::WorkDone(WorkDoneProgress::Report(
203- // WorkDoneProgressReport {
204- // cancellable: Some(false),
205- // message: Some(path.display().to_string()),
206- // percentage: Some((current * 100 / total_files) as u32),
207- // },
208- // ));
209- //
210- // if let Err(e) = tx.send(report) {
211- // error!(error=%e, "failed to send work report progress");
212- // }
213- // }
214- // }
215- // let report =
216- // ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
217- // message: Some(String::from("completed")),
218- // }));
219- //
220- // info!(len = total_files, "workspace file parsing completed");
221- // if let Err(e) = tx.send(report) {
222- // error!(error=%e, "failed to send work completed result");
223- // }
224- // });
225- // }
154+ pub fn parse_all_from_workspace (
155+ & mut self ,
156+ workspace : PathBuf ,
157+ progress_sender : Option < Sender < ProgressParamsValue > > ,
158+ ) {
159+ if self
160+ . parsed_workspaces
161+ . read ( )
162+ . expect ( "poison" )
163+ . contains ( workspace. to_str ( ) . unwrap_or_default ( ) )
164+ {
165+ return ;
166+ }
167+
168+ let files: Vec < _ > = WalkDir :: new ( workspace. to_str ( ) . unwrap_or_default ( ) )
169+ . into_iter ( )
170+ . filter_map ( |e| e. ok ( ) )
171+ . filter ( |e| e. path ( ) . extension ( ) . is_some ( ) )
172+ . filter ( |e| e. path ( ) . extension ( ) . unwrap ( ) == "proto" )
173+ . collect ( ) ;
174+
175+ let total_files = files. len ( ) ;
176+
177+ for ( idx, file) in files. into_iter ( ) . enumerate ( ) {
178+ let path = file. path ( ) ;
179+ if path. is_absolute ( ) && path. is_file ( ) {
180+ if let Ok ( content) = std:: fs:: read_to_string ( path) {
181+ if let Ok ( uri) = Url :: from_file_path ( path) {
182+ if self . documents . read ( ) . expect ( "poison" ) . contains_key ( & uri) {
183+ continue ;
184+ }
185+ self . upsert_content ( & uri, content, & [ ] , 1 ) ;
186+
187+ if let Some ( sender) = & progress_sender {
188+ let percentage = ( ( idx + 1 ) as f64 / total_files as f64 * 100.0 ) as u32 ;
189+ let _ = sender. send ( ProgressParamsValue :: WorkDone (
190+ async_lsp:: lsp_types:: WorkDoneProgress :: Report (
191+ async_lsp:: lsp_types:: WorkDoneProgressReport {
192+ cancellable : None ,
193+ message : Some ( format ! (
194+ "Parsing file {} of {}" ,
195+ idx + 1 ,
196+ total_files
197+ ) ) ,
198+ percentage : Some ( percentage) ,
199+ } ,
200+ ) ,
201+ ) ) ;
202+ }
203+ }
204+ }
205+ }
206+ }
207+
208+ self . parsed_workspaces
209+ . write ( )
210+ . expect ( "poison" )
211+ . insert ( workspace. to_str ( ) . unwrap_or_default ( ) . to_string ( ) ) ;
212+ }
226213
227214 pub fn upsert_file (
228215 & mut self ,
0 commit comments