ISearchApplication
ISearchApplication is the entrypoint for a C# Search App plugin.
Typical namespace: Blast.Core.Interfaces
Typical related types: SearchApplicationInfo, SearchRequest, ISearchResult, IHandleResult
Implementations typically:
- Describe the app via
SearchApplicationInfo. - Return results from
SearchAsync. - Perform actions in
HandleSearchResultwhen the user selects an operation.
Minimal skeleton
Below is a “shape correct” skeleton that matches how plugins are commonly structured. Names/signatures can vary slightly by version, but the flow is stable.
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Blast.Core.Interfaces;
using Blast.Core.Objects;
using Blast.Core.Results;
public sealed class MySearchApp : ISearchApplication
{
private readonly SearchApplicationInfo _info;
public MySearchApp()
{
_info = new SearchApplicationInfo(
name: "MyApp",
description: "Does something useful",
supportedOperations: new List<ISearchOperation>());
}
public SearchApplicationInfo GetApplicationInfo() => _info;
public ValueTask LoadSearchApplicationAsync() => ValueTask.CompletedTask;
public async IAsyncEnumerable<ISearchResult> SearchAsync(
SearchRequest request,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
yield break;
// Many plugins also early-exit for process-search passes
// if (request.SearchType == SearchType.SearchProcess) yield break;
var searchedText = request.SearchedText;
if (string.IsNullOrWhiteSpace(searchedText))
yield break;
// yield return new MySearchResult(...);
await Task.CompletedTask;
}
public ValueTask<IHandleResult> HandleSearchResult(ISearchResult searchResult)
{
// Inspect searchResult.SelectedOperation and act
return new ValueTask<IHandleResult>(new HandleResult(success: true, searchAgain: false));
}
// Signature differs by version: some builds use object, some use string.
public ValueTask<ISearchResult> GetSearchResultForId(object searchObjectId)
{
// Rebuild a result for custom tags / pinned results.
return new ValueTask<ISearchResult>();
}
}
Key members
SearchApplicationInfo GetApplicationInfo()
Returns static metadata about your app (name, icon, supported operations, default search tags, settings page, etc.).
ValueTask LoadSearchApplicationAsync()
Runs once on Fluent Search startup.
Use it to:
- Load settings-dependent state after settings are available.
- Warm caches (carefully) or load external metadata.
Tip: Keep this fast. Slow startup impacts the whole app.
💡 Developer tip: if you rely on settings values, initialize anything settings-dependent here (some plugins intentionally avoid reading settings in the constructor).
IAsyncEnumerable<ISearchResult> SearchAsync(SearchRequest request, CancellationToken token)
Generates results for the current query.
Common patterns seen in community plugins:
- Ignore process search: return nothing when
request.SearchType == SearchType.SearchProcess. - Filter by tag: only handle your tag(s) and return
yield breakfor others. - Stream results as you compute them (good UX) rather than building huge lists.
See: SearchRequest and SearchResultBase
Cancellation and responsiveness
- Check
token.IsCancellationRequestedearly and often. - Prefer streaming results (
yield returnas soon as you have something) over collecting everything in memory. - Avoid throwing exceptions for “no results”; just
yield break.
ValueTask<IHandleResult> HandleSearchResult(ISearchResult result)
Called when the user executes an operation (right-side action panel or operation hotkey).
Typical responsibilities:
- Detect the selected operation (often by type checks on
result.SelectedOperation). - Perform the action (copy to clipboard, open URL, start a process, etc.).
- Optionally ask Fluent Search to re-run the search.
See: HandleResult
Operation dispatch
Most plugins dispatch by operation type:
var op = result.SelectedOperation;
if (op is CopySearchOperation) { ... }
else if (op is MyCustomOperation myOp) { ... }
This is more robust than matching strings (operation names can change).
ValueTask<ISearchResult> GetSearchResultForId(object searchObjectId)
Used for “custom tag” / pinned result scenarios where Fluent Search needs to rebuild a result after restart.
Common approach:
- Store a stable
SearchObjectIdon the result (string/id or a serializable object). - Recreate a fresh
ISearchResultwhen this method is called.
See: SearchResultBase
Version note
Some community plugins show GetSearchResultForId(string serializedSearchObjectId) while others use object.
Treat this as version-dependent and follow the interface in your referenced Blast.API/Fluent Search version.
Practical tips
- Prefer strict early exits (wrong tag, empty input, cancellation requested) to reduce work.
- Avoid throwing exceptions on normal “no result” flows; just return no results.