@@ -175,6 +175,10 @@ export class ServeD extends EventEmitter implements vscode.TreeDataProvider<DubD
175175 return this . client . sendRequest ( "served/getActiveDubConfig" ) ;
176176 }
177177
178+ forceLoadProjects ( roots : string [ ] ) : Thenable < boolean [ ] > {
179+ return this . client . sendRequest ( "served/forceLoadProjects" , roots ) ;
180+ }
181+
178182 private static taskGroups : vscode . TaskGroup [ ] = [
179183 vscode . TaskGroup . Build ,
180184 vscode . TaskGroup . Clean ,
@@ -193,6 +197,7 @@ async function startClient(context: vscode.ExtensionContext) {
193197 "--provide" , "context-snippets" ,
194198 "--provide" , "default-snippets" ,
195199 "--provide" , "tasks-current" ,
200+ "--provide" , "async-ask-load" ,
196201 ] ;
197202
198203 let executable : ServerOptions = {
@@ -273,6 +278,128 @@ async function startClient(context: vscode.ExtensionContext) {
273278 served . refreshDependencies ( ) ;
274279 } ) ;
275280
281+ client . onNotification ( "coded/skippedLoads" , async function ( roots : string [ ] ) {
282+ if ( typeof ( roots ) === "object" && ! Array . isArray ( roots ) )
283+ roots = ( < any > roots ) . roots ;
284+
285+ if ( typeof ( roots ) === "string" )
286+ roots = < string [ ] > [ roots ] ;
287+ else if ( ! Array . isArray ( roots ) )
288+ throw new Error ( "Unexpected roots with coded/skippedLoads: " + JSON . stringify ( roots ) ) ;
289+
290+ var allowList = config ( null ) . get < string [ ] > ( "manyProjectsAllowList" ) || [ ] ;
291+ var denyList = config ( null ) . get < string [ ] > ( "manyProjectsDenyList" ) || [ ] ;
292+ var decisions = new Array ( roots . length ) ;
293+ let decidedNum = 0 ;
294+ for ( let i = 0 ; i < roots . length ; i ++ ) {
295+ const root = roots [ i ] ;
296+ if ( allowList . includes ( root ) )
297+ decisions [ i ] = true ;
298+ else if ( denyList . includes ( root ) )
299+ decisions [ i ] = false ;
300+ else
301+ continue ;
302+ decidedNum ++ ;
303+ }
304+
305+ console . log ( "Asking for late init for projects " , roots , " (allowlist: " , allowList , ", denylist: " , denyList , ")" ) ;
306+
307+ let btnLoadAll = decidedNum > 0
308+ ? "Load Remaining (" + ( roots . length - decidedNum ) + ")"
309+ : roots . length == 1
310+ ? "Load"
311+ : "Load All (" + roots . length + ")" ;
312+ let btnSkipAll = decidedNum > 0
313+ ? "Skip Remaining"
314+ : roots . length == 1
315+ ? "Skip"
316+ : "Skip All" ;
317+ let btnInteractive = "More Options..." ;
318+ let msg = "There are too many subprojects in this project according to d.manyProjectsThreshold. Load "
319+ + ( roots . length == 1 ? "1 extra project?" : roots . length + " extra projects?" )
320+ + ( decidedNum > 0 ? ( "\n" + ( decidedNum == 1 ? "1 project has" : decidedNum + " projects have" )
321+ + " been decided on based on d.manyProjects{Allow/Deny}List already." ) : "" ) ;
322+ let result = await vscode . window . showInformationMessage ( msg ,
323+ btnLoadAll , btnSkipAll , btnInteractive ) ;
324+
325+ function setRemaining ( b : boolean ) {
326+ for ( let i = 0 ; i < decisions . length ; i ++ )
327+ if ( decisions [ i ] === undefined )
328+ decisions [ i ] = b ;
329+ }
330+
331+ switch ( result )
332+ {
333+ case btnLoadAll :
334+ setRemaining ( true ) ;
335+ break ;
336+ case btnInteractive :
337+ let result = await vscode . window . showQuickPick < vscode . QuickPickItem > ( roots . map ( ( r , i ) => < vscode . QuickPickItem > {
338+ _root : r ,
339+ _id : i ,
340+ label : r ,
341+ picked : decisions [ i ] ,
342+ } ) . concat ( [
343+ {
344+ kind : vscode . QuickPickItemKind . Separator ,
345+ label : "Options" ,
346+ alwaysShow : true ,
347+ } ,
348+ < any > {
349+ _id : "remember" ,
350+ label : "Remember Selection (workspace settings)" ,
351+ alwaysShow : true
352+ }
353+ ] ) , {
354+ canPickMany : true ,
355+ ignoreFocusOut : true ,
356+ title : "Select projects to load"
357+ } ) ;
358+
359+ result ?. forEach ( r => {
360+ let root = < string > ( < any > r ) . _root ;
361+ let id = < number > ( < any > r ) . _id ;
362+ if ( ! root )
363+ return ;
364+
365+ if ( ! allowList . includes ( root ) )
366+ allowList . push ( root ) ;
367+ let denyIndex = denyList . indexOf ( root ) ;
368+ if ( denyIndex != - 1 )
369+ denyList . splice ( denyIndex , 1 ) ;
370+
371+ decisions [ id ] = true ;
372+ } ) ;
373+
374+ for ( let i = 0 ; i < decisions . length ; i ++ ) {
375+ if ( decisions [ i ] === undefined ) {
376+ let root = roots [ i ] ;
377+ if ( ! denyList . includes ( root ) )
378+ denyList . push ( root ) ;
379+ let allowIndex = allowList . indexOf ( root ) ;
380+ if ( allowIndex != - 1 )
381+ allowList . splice ( allowIndex , 1 ) ;
382+ decisions [ i ] = false ;
383+ }
384+ }
385+
386+ let save = ( result ?. findIndex ( r => ( < any > r ) . _id == "remember" ) ?? - 1 ) >= 0 ;
387+ if ( save )
388+ {
389+ config ( null ) . update ( "manyProjectsAllowList" , allowList , vscode . ConfigurationTarget . Workspace ) ;
390+ config ( null ) . update ( "manyProjectsDenyList" , denyList , vscode . ConfigurationTarget . Workspace ) ;
391+ }
392+ return ;
393+ case btnSkipAll :
394+ default :
395+ setRemaining ( false ) ;
396+ break ;
397+ }
398+
399+ let toLoad = roots . filter ( ( _ , i ) => decisions [ i ] === true ) ;
400+ served . forceLoadProjects ( toLoad ) ;
401+ } ) ;
402+
276403 const startupProgress = new statusbar . StartupProgress ( ) ;
277404 client . onNotification ( "window/logMessage" , function ( info : { type : MessageType , message : string } ) {
278405 if ( info . type == MessageType . Log && info . message . startsWith ( "[progress]" ) ) {
@@ -913,6 +1040,20 @@ function shortenPath(p: string) {
9131040 return short ;
9141041}
9151042
1043+ function getOwnerWorkspace ( p : string ) : vscode . WorkspaceFolder | null {
1044+ if ( p . endsWith ( "serve-d-dummy-workspace" ) )
1045+ return null ;
1046+ let best : vscode . WorkspaceFolder | null = null ;
1047+ if ( vscode . workspace . workspaceFolders )
1048+ vscode . workspace . workspaceFolders . forEach ( element => {
1049+ const dir = element . uri . fsPath ;
1050+ if ( dir . length >= ( best ?. uri ?. fsPath ?. length ?? 0 ) && dir . startsWith ( p ) ) {
1051+ best = element ;
1052+ }
1053+ } ) ;
1054+ return best ;
1055+ }
1056+
9161057/**
9171058 * Watches for config updates that need a vscode window reload to be effective
9181059 * and shows a hint to the user in these cases.
0 commit comments