@@ -25,6 +25,7 @@ public static class PluginManager
2525 private static readonly string ClassName = nameof ( PluginManager ) ;
2626
2727 private static IEnumerable < PluginPair > _contextMenuPlugins ;
28+ private static IEnumerable < PluginPair > _homePlugins ;
2829
2930 public static List < PluginPair > AllPlugins { get ; private set ; }
3031 public static readonly HashSet < PluginPair > GlobalPlugins = new ( ) ;
@@ -220,13 +221,16 @@ public static async Task InitializePluginsAsync()
220221 {
221222 API . LogException ( ClassName , $ "Fail to Init plugin: { pair . Metadata . Name } ", e ) ;
222223 pair . Metadata . Disabled = true ;
224+ pair . Metadata . HomeDisabled = true ;
223225 failedPlugins . Enqueue ( pair ) ;
224226 }
225227 } ) ) ;
226228
227229 await Task . WhenAll ( InitTasks ) ;
228230
229231 _contextMenuPlugins = GetPluginsForInterface < IContextMenu > ( ) ;
232+ _homePlugins = GetPluginsForInterface < IAsyncHomeQuery > ( ) ;
233+
230234 foreach ( var plugin in AllPlugins )
231235 {
232236 // set distinct on each plugin's action keywords helps only firing global(*) and action keywords once where a plugin
@@ -274,6 +278,11 @@ public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
274278 } ;
275279 }
276280
281+ public static ICollection < PluginPair > ValidPluginsForHomeQuery ( )
282+ {
283+ return _homePlugins . ToList ( ) ;
284+ }
285+
277286 public static async Task < List < Result > > QueryForPluginAsync ( PluginPair pair , Query query , CancellationToken token )
278287 {
279288 var results = new List < Result > ( ) ;
@@ -318,6 +327,36 @@ public static async Task<List<Result>> QueryForPluginAsync(PluginPair pair, Quer
318327 return results ;
319328 }
320329
330+ public static async Task < List < Result > > QueryHomeForPluginAsync ( PluginPair pair , Query query , CancellationToken token )
331+ {
332+ var results = new List < Result > ( ) ;
333+ var metadata = pair . Metadata ;
334+
335+ try
336+ {
337+ var milliseconds = await API . StopwatchLogDebugAsync ( ClassName , $ "Cost for { metadata . Name } ",
338+ async ( ) => results = await ( ( IAsyncHomeQuery ) pair . Plugin ) . HomeQueryAsync ( token ) . ConfigureAwait ( false ) ) ;
339+
340+ token . ThrowIfCancellationRequested ( ) ;
341+ if ( results == null )
342+ return null ;
343+ UpdatePluginMetadata ( results , metadata , query ) ;
344+
345+ token . ThrowIfCancellationRequested ( ) ;
346+ }
347+ catch ( OperationCanceledException )
348+ {
349+ // null will be fine since the results will only be added into queue if the token hasn't been cancelled
350+ return null ;
351+ }
352+ catch ( Exception e )
353+ {
354+ API . LogException ( ClassName , $ "Failed to query home for plugin: { metadata . Name } ", e ) ;
355+ return null ;
356+ }
357+ return results ;
358+ }
359+
321360 public static void UpdatePluginMetadata ( IReadOnlyList < Result > results , PluginMetadata metadata , Query query )
322361 {
323362 foreach ( var r in results )
@@ -378,6 +417,11 @@ public static List<Result> GetContextMenusForPlugin(Result result)
378417 return results ;
379418 }
380419
420+ public static bool IsHomePlugin ( string id )
421+ {
422+ return _homePlugins . Any ( p => p . Metadata . ID == id ) ;
423+ }
424+
381425 public static bool ActionKeywordRegistered ( string actionKeyword )
382426 {
383427 // this method is only checking for action keywords (defined as not '*') registration
0 commit comments