Skip to content

Conversation

@01Dri
Copy link
Contributor

@01Dri 01Dri commented Nov 5, 2025

CHANGES

  • Added new File and Folder action keywords
  • Implemented action keyword–based result filtering
  • Refactored the Search Manager for better maintainability

Details

Note

The Search Manager in Explorer was refactored to simplify the addition of new action keywords.
Previously, each new keyword required code changes in multiple places.
Now, the logic for action keywords and filters is much easier to understand and extend.

The quick access results is filtered action keyword based

@github-actions github-actions bot added this to the 2.1.0 milestone Nov 5, 2025
@gitstream-cm
Copy link

gitstream-cm bot commented Nov 5, 2025

🥷 Code experts: Jack251970, VictoriousRaptor

Jack251970, VictoriousRaptor have most 👩‍💻 activity in the files.
Jack251970, jjw24 have most 🧠 knowledge in the files.

See details

Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml

Activity based on git-commit:

Jack251970 VictoriousRaptor
NOV
OCT
SEP 1 additions & 0 deletions
AUG
JUL 7 additions & 0 deletions 28 additions & 15 deletions
JUN 7 additions & 0 deletions

Knowledge based on git-blame:
jjw24: 20%
Jack251970: 12%

Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs

Activity based on git-commit:

Jack251970 VictoriousRaptor
NOV
OCT
SEP 2 additions & 2 deletions
AUG
JUL
JUN 12 additions & 0 deletions

Knowledge based on git-blame:
jjw24: 18%
Jack251970: 6%

Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs

Activity based on git-commit:

Jack251970 VictoriousRaptor
NOV
OCT
SEP 3 additions & 6 deletions
AUG
JUL 2 additions & 6 deletions
JUN 2 additions & 0 deletions

Knowledge based on git-blame:
jjw24: 8%
Jack251970: 2%

Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs

Activity based on git-commit:

Jack251970 VictoriousRaptor
NOV
OCT
SEP 9 additions & 9 deletions
AUG
JUL 17 additions & 13 deletions 33 additions & 6 deletions
JUN 51 additions & 27 deletions

Knowledge based on git-blame:
Jack251970: 13%
jjw24: 5%

Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml

Activity based on git-commit:

Jack251970 VictoriousRaptor
NOV
OCT 7 additions & 8 deletions
SEP
AUG
JUL 6 additions & 15 deletions
JUN 867 additions & 821 deletions

Knowledge based on git-blame:
Jack251970: 83%
jjw24: 1%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

@gitstream-cm
Copy link

gitstream-cm bot commented Nov 5, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@coderabbitai coderabbitai bot added the enhancement New feature or request label Nov 5, 2025
@01Dri
Copy link
Contributor Author

01Dri commented Nov 5, 2025

image

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 5, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds folder- and file-search action keywords to the Explorer plugin: new English localization strings, Settings API additions (new action keywords, enable flags, GetActiveActionKeywords), SettingsViewModel UI entries, and SearchManager refactor to route and filter searches by active action keywords.

Changes

Cohort / File(s) Summary
Localization strings
Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
Added two new resource strings: plugin_explorer_actionkeywordview_foldersearch ("Folder Search:") and plugin_explorer_actionkeywordview_filesearch ("File Search:").
Settings API & model
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
Added FolderSearchActionKeyword and FileSearchActionKeyword properties with enable flags; extended ActionKeyword enum with FolderSearchActionKeyword and FileSearchActionKeyword; added GetActiveActionKeywords(string) to return enabled/matching action keywords.
Search routing & filtering
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
Introduced _typesToFilterByActionKeyword mapping and keyword-driven routing/filtering: compute active action keywords, detect path-like queries, conditional PathSearchAsync insertion, integrate QuickAccess via GetQuickAccessResultsFilteredByActionKeyword, replace earlier ActionKeywordMatch guards with helper methods (IsResultTypeFilteredByActionKeyword, CanUseIndexSearchByActionKeywords, CanUsePatchSearchByActionKeywords), and consolidate result/error/cancellation handling.
SettingsViewModel UI updates
Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
Added FolderSearchActionKeyword and FileSearchActionKeyword entries to ActionKeywordsModels initialization referencing the new localization keys.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant VM as SettingsViewModel
    participant Settings
    participant SM as SearchManager
    participant QA as QuickAccessEngine
    participant SE as SearchEngines
    participant UI as ResultsDisplay

    User->>VM: Update folder/file action keywords & toggles
    VM->>Settings: Set keywords & enabled flags
    Settings->>Settings: Persist config

    User->>SM: Submit query
    SM->>Settings: GetActiveActionKeywords(query)
    Settings-->>SM: activeActionKeywords

    SM->>SM: Determine routing (path-like, file, index) using activeActionKeywords
    alt Path-like & path search active
        SM->>SE: Run path-oriented search
        SE-->>SM: pathResults
    else File-search active
        SM->>SE: Run file/content searches
        SE-->>SM: fileResults
    else Index/QuickAccess fallback
        SM->>SE: Run index/default searches
        SE-->>SM: indexResults
    end
    SM->>QA: GetQuickAccessResultsFilteredByActionKeyword(activeActionKeywords)
    QA-->>SM: qaResults
    SM->>SM: Merge qaResults + filtered search results
    SM->>UI: Return final filtered/merged results
    UI-->>User: Display results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus areas:
    • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs — control-flow refactor, new helper methods, QuickAccess merge, path-detection and cancellation semantics.
    • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs — new enum members, wildcard matching and GetActiveActionKeywords logic.
    • Localization and ViewModel — key consistency between en.xaml and SettingsViewModel.cs.

Possibly related PRs

Suggested reviewers

  • jjw24
  • Jack251970
  • taooceros

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main feature addition: introducing new Folder and File action keywords for the Explorer plugin.
Description check ✅ Passed The description is directly related to the changeset, explaining the new File and Folder action keywords, action keyword-based filtering, and the Search Manager refactor for maintainability.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2ac321 and 4e5378b.

📒 Files selected for processing (5)
  • Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml (2 hunks)
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (4 hunks)
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (7 hunks)
  • Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs (2 hunks)
  • Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml (2 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.
📚 Learning: 2025-09-05T11:56:27.267Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Flow.Launcher/HotkeyControlDialog.xaml:6-6
Timestamp: 2025-09-05T11:56:27.267Z
Learning: In Flow.Launcher's migration to iNKORE.UI.WPF.Modern UI framework, dialog resource keys like PopuBGColor, PopupButtonAreaBGColor, PopupButtonAreaBorderColor, and PopupTextColor are provided by the iNKORE.UI.WPF.Modern framework itself, not defined locally in the codebase theme files.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml
📚 Learning: 2025-07-01T05:46:13.251Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-09-04T11:52:29.096Z
Learnt from: jjw24
Repo: Flow-Launcher/Flow.Launcher PR: 3932
File: Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs:48-55
Timestamp: 2025-09-04T11:52:29.096Z
Learning: In Flow Launcher's PluginsManifest.cs, when dealing with version parsing for the MinimumAppVersion feature, maintainer jjw24 prefers to keep the solution simple rather than implementing comprehensive helper methods for SemVer parsing normalization.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-09-13T06:04:26.977Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs:143-165
Timestamp: 2025-09-13T06:04:26.977Z
Learning: In Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml, the ListView_SizeChanged handler in the C# file assumes 5 GridViewColumns but the XAML may have more columns. The user Jack251970 indicated this mismatch doesn't need to be fixed when pointed out during PR #3593 review.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
  • Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
📚 Learning: 2025-09-11T08:30:29.487Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml:0-0
Timestamp: 2025-09-11T08:30:29.487Z
Learning: In Flow.Launcher's SettingsPaneTheme.xaml theme editor panel, the inner ui:ScrollViewerEx within the Border (Grid.Column="1") is intentionally kept because its height cannot be expanded to the whole page due to layout constraints. This serves a different scrolling purpose than the outer ScrollViewerEx and is necessary for the theme editor panel functionality.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
📚 Learning: 2025-03-28T21:20:54.978Z
Learnt from: onesounds
Repo: Flow-Launcher/Flow.Launcher PR: 3394
File: Flow.Launcher/Themes/Darker Glass.xaml:134-141
Timestamp: 2025-03-28T21:20:54.978Z
Learning: In WPF applications like Flow.Launcher, Border elements cannot directly display text content and require a child element like TextBlock to handle text rendering. This separation of concerns (Border for visual container styling, TextBlock for text display) follows WPF best practices and provides greater styling flexibility.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
📚 Learning: 2025-07-06T12:21:37.947Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
🧬 Code graph analysis (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (4)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (2)
  • Settings (14-242)
  • ActionKeyword (229-240)
Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs (1)
  • IsLocationPathString (246-265)
Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs (3)
  • EnvironmentVariables (10-109)
  • IsEnvironmentVariableSearch (25-31)
  • HasEnvironmentVar (33-41)
Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs (3)
  • List (11-28)
  • List (30-40)
  • QuickAccess (7-41)
Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs (1)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (2)
  • Settings (14-242)
  • ActionKeyword (229-240)
🪛 GitHub Check: Check Spelling
Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml

[warning] 690-690:
quickaccess is not a recognized word. (unrecognized-spelling)

Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs

[warning] 282-282:
actionkeywordview is not a recognized word. (unrecognized-spelling)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

@Jack251970 Jack251970 requested a review from Copilot November 6, 2025 07:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds two new action keywords for folder-only and file-only search functionality, along with an option to exclude Quick Access results from appearing when other action keywords are used. The changes enable more targeted search experiences within the Explorer plugin.

Key changes:

  • Added FolderSearchActionKeyword and FileSearchActionKeyword to the ActionKeyword enum with associated settings
  • Implemented filtering logic in SearchManager to skip results based on active action keyword type
  • Added UI checkbox to control Quick Access result merging behavior

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Settings.cs Adds new action keyword properties and enum values for folder/file search, implements GetActiveActionKeyword method, reorganizes using statements
SearchManager.cs Refactors search logic to use GetActiveActionKeyword, adds filtering for folder/file-only searches, reorganizes using statements
SettingsViewModel.cs Adds new action keywords to UI model initialization, has trailing whitespace on one line
ExplorerSettings.xaml Adds checkbox for Quick Access exclusion option, adjusts grid layout with improper indentation
en.xaml Adds localization strings for new action keywords and checkbox

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (1)

226-242: GetActiveActionKeywords implementation is sound; consider avoiding null returns

The method correctly:

  • Ignores keywords that are null/empty.
  • Filters by exact match on the provided actionKeywordStr.
  • Only includes entries whose enabled flag is true.
  • Supports multiple active actions for the same keyword (e.g., wildcard scenarios) via the dictionary.

One minor API suggestion: returning null for an empty actionKeywordStr can be slightly awkward for callers compared to always returning a dictionary (possibly empty). Returning the preallocated result instead of null would keep the API non-nullable and reduce the chance of missed null checks, if you don’t rely on null as a special sentinel elsewhere.

Example tweak:

-            var result = new Dictionary<ActionKeyword, string>();
-            if (string.IsNullOrEmpty(actionKeywordStr)) return null;
+            var result = new Dictionary<ActionKeyword, string>();
+            if (string.IsNullOrEmpty(actionKeywordStr)) return result;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b7cbf7 and 438e709.

📒 Files selected for processing (1)
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (7 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-09-04T11:52:29.096Z
Learnt from: jjw24
Repo: Flow-Launcher/Flow.Launcher PR: 3932
File: Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs:48-55
Timestamp: 2025-09-04T11:52:29.096Z
Learning: In Flow Launcher's PluginsManifest.cs, when dealing with version parsing for the MinimumAppVersion feature, maintainer jjw24 prefers to keep the solution simple rather than implementing comprehensive helper methods for SemVer parsing normalization.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-06T12:21:37.947Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-01T05:46:13.251Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (3)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (3)

1-11: Imports for new search managers look correct

The added using directives for the Explorer search managers and providers are coherent with the types referenced later in the file; no issues here.


62-69: New folder/file keyword settings align with existing pattern

FolderSearchActionKeyword / FileSearchActionKeyword and their ...Enabled flags follow the same pattern as Path/Index/QuickAccess keywords (defaulting to GlobalPluginWildcardSign with disabled flags). This keeps configuration behavior consistent and avoids accidentally enabling new behaviors by default.


167-224: Enum and switch extensions are consistent and exhaustive

Extending ActionKeyword with FolderSearchActionKeyword and FileSearchActionKeyword and wiring them through all four helpers (GetActionKeyword, SetActionKeyword, GetActionKeywordEnabled, SetActionKeywordEnabled) keeps the enum and switch expressions in sync; there are no missing cases, and error paths remain unchanged.

@01Dri
Copy link
Contributor Author

01Dri commented Nov 29, 2025

@jjw24 Can you test again? Thanks!

@jjw24 jjw24 added the review in progress Indicates that a review is in progress for this PR label Dec 3, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (1)

319-336: Simplify the control flow for better readability.

The loop stores ContainsKey in a variable, skips if false, then returns the same variable if true. This can be simplified to directly return true when a match is found.

Apply this diff to streamline the logic:

 private bool CanUseIndexSearchByActionKeywords(Dictionary<ActionKeyword, string> actions)
 {
     List<ActionKeyword> keysToUseSearch =
     [
         ActionKeyword.FileSearchActionKeyword,
         ActionKeyword.FolderSearchActionKeyword,
         ActionKeyword.IndexSearchActionKeyword,
         ActionKeyword.SearchActionKeyword
     ];
     foreach (var key in keysToUseSearch)
     {
-        var contains = actions.ContainsKey(key);
-        if (!contains) continue;
-        return contains;
+        if (actions.ContainsKey(key))
+            return true;
     }
 
     return false;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 438e709 and 8e34897.

📒 Files selected for processing (2)
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (11 hunks)
  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (7 hunks)
🧰 Additional context used
🧠 Learnings (11)
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-04T11:52:29.096Z
Learnt from: jjw24
Repo: Flow-Launcher/Flow.Launcher PR: 3932
File: Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs:48-55
Timestamp: 2025-09-04T11:52:29.096Z
Learning: In Flow Launcher's PluginsManifest.cs, when dealing with version parsing for the MinimumAppVersion feature, maintainer jjw24 prefers to keep the solution simple rather than implementing comprehensive helper methods for SemVer parsing normalization.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-06T12:21:37.947Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3572
File: Flow.Launcher/App.xaml.cs:214-216
Timestamp: 2025-07-06T12:21:37.947Z
Learning: In Flow Launcher, the UpdatePluginManifestAsync method in PluginsManifest.cs already has comprehensive internal try-catch handling that logs exceptions and returns false on failure rather than throwing, making external try-catch wrappers unnecessary.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-07-01T05:46:13.251Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3791
File: Flow.Launcher.Core/Plugin/PluginManager.cs:293-295
Timestamp: 2025-07-01T05:46:13.251Z
Learning: In Flow.Launcher.Core/Plugin/PluginManager.cs, when checking if a plugin is modified within the PluginManager class itself, prefer using the internal static PluginModified(string id) method directly rather than going through API.PluginModified() for better performance and architectural design.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-13T06:04:26.977Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs:143-165
Timestamp: 2025-09-13T06:04:26.977Z
Learning: In Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml, the ListView_SizeChanged handler in the C# file assumes 5 GridViewColumns but the XAML may have more columns. The user Jack251970 indicated this mismatch doesn't need to be fixed when pointed out during PR #3593 review.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-11-06T12:57:11.574Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 4072
File: Plugins/Flow.Launcher.Plugin.Program/Main.cs:100-111
Timestamp: 2025-11-06T12:57:11.574Z
Learning: In Flow Launcher's Program plugin Main.cs QueryAsync method, the semaphore pattern where WaitAsync(token) is inside a try-catch that only catches OperationCanceledException, followed by an explicit Release() call after the try-catch block, is safe and doesn't cause semaphore leaks. When WaitAsync throws OperationCanceledException, the semaphore is not acquired, so no release is needed. When WaitAsync succeeds, the Release() call after the try-catch executes normally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (6)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (3)

63-69: LGTM! New action keyword properties follow existing patterns.

The new FolderSearchActionKeyword and FileSearchActionKeyword properties (along with their corresponding enabled flags) are consistent with the existing action keyword properties in the file. The default values (wildcard and disabled) are appropriate.


173-176: LGTM! Enum and switch expressions updated consistently.

The new ActionKeyword enum values are correctly integrated into all four switch expressions (GetActionKeyword, SetActionKeyword, GetActionKeywordEnabled, SetActionKeywordEnabled), maintaining consistency across the API.

Also applies to: 185-223


226-242: LGTM! Dictionary-based approach simplifies multi-keyword handling.

The GetActiveActionKeywords method correctly handles wildcard matching and provides O(1) lookup for enabled action keywords. The null return for empty input is safe given the caller's guarantee (line 59 in SearchManager.cs ensures non-empty input via wildcard fallback).

Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (3)

23-27: LGTM! Dictionary-based filtering simplifies maintenance.

The _typesToFilterByActionKeyword mapping centralizes filter configuration, making it easy to add new action keywords without scattered conditional logic. This directly addresses the PR objective of simplifying keyword additions.


59-90: LGTM! Active keyword logic handles empty queries and path searches correctly.

The early-return logic for empty queries (lines 72-82) correctly implements the PR requirement: Quick Access returns all items, while Folder/File search returns empty results. The path search handling (lines 86-90) appropriately adds PathSearchActionKeyword when needed while preventing unwanted drive listings during file searches.


282-305: LGTM! Filtering methods correctly align Quick Access with active keywords.

The ShouldSkipResultByTypeAndActionKeyword and GetQuickAccessResultsFilteredByActionKeyword methods properly filter results based on the active action keyword, addressing the past concern that Quick Access results ignored folder/file action filters.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (2)

6-6: Unused import?

System.Windows.Documents doesn't appear to be used anywhere in this file. Consider removing it to keep imports clean.


321-338: Simplify the loop logic.

Lines 333-334 can be simplified. The current if (!contains) continue; return contains; pattern is unnecessarily verbose.

Apply this diff to streamline the logic:

         foreach (var key in keysToUseSearch)
         {
             var contains = actions.ContainsKey(key);
-            if (!contains) continue;
-            return contains;
+            if (contains) return true;
         }

Alternatively, use LINQ for even more conciseness:

-        foreach (var key in keysToUseSearch)
-        {
-            var contains = actions.ContainsKey(key);
-            if (!contains) continue;
-            return contains;
-        }
-
-        return false;
+        return keysToUseSearch.Any(actions.ContainsKey);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e34897 and 1f2f474.

📒 Files selected for processing (1)
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (11 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-13T06:04:26.977Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs:143-165
Timestamp: 2025-09-13T06:04:26.977Z
Learning: In Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml, the ListView_SizeChanged handler in the C# file assumes 5 GridViewColumns but the XAML may have more columns. The user Jack251970 indicated this mismatch doesn't need to be fixed when pointed out during PR #3593 review.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-04T11:52:29.096Z
Learnt from: jjw24
Repo: Flow-Launcher/Flow.Launcher PR: 3932
File: Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs:48-55
Timestamp: 2025-09-04T11:52:29.096Z
Learning: In Flow Launcher's PluginsManifest.cs, when dealing with version parsing for the MinimumAppVersion feature, maintainer jjw24 prefers to keep the solution simple rather than implementing comprehensive helper methods for SemVer parsing normalization.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-11-06T12:57:11.574Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 4072
File: Plugins/Flow.Launcher.Plugin.Program/Main.cs:100-111
Timestamp: 2025-11-06T12:57:11.574Z
Learning: In Flow Launcher's Program plugin Main.cs QueryAsync method, the semaphore pattern where WaitAsync(token) is inside a try-catch that only catches OperationCanceledException, followed by an explicit Release() call after the try-catch block, is safe and doesn't cause semaphore leaks. When WaitAsync throws OperationCanceledException, the semaphore is not acquired, so no release is needed. When WaitAsync succeeds, the Release() call after the try-catch executes normally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (6)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (6)

23-28: LGTM!

The filtering dictionary is well-structured and clearly maps action keywords to the result types that should be excluded. The logic correctly excludes folders/volumes for file search and files for folder search.


60-92: LGTM!

The action keyword detection and early-return logic correctly implements the PR requirements:

  • Returns empty results when file/folder keywords are used with no query text.
  • Properly detects path searches and conditionally adds PathSearchActionKeyword.
  • Prevents path search when FileSearchActionKeyword is active.

98-161: LGTM!

The search routing logic correctly handles different search types and integrates the new action keyword filtering. The Quick Access merge at line 132 now properly filters by active keywords, addressing the previous review concern.


284-293: LGTM!

The filtering logic correctly combines file type exclusions with action keyword-based type filtering.


295-307: LGTM!

This method correctly filters Quick Access results to respect the active action keywords, addressing the previous review concern. Files won't appear in folder searches and folders won't appear in file searches.


308-319: LGTM!

The filtering check correctly determines whether a result type should be excluded based on the active action keywords.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (2)

277-293: Avoid re-splitting ExcludedFileTypes on every result (performance nit)

IsExcludedFile splits Settings.ExcludedFileTypes on every call:

string[] excludedFileTypes = Settings.ExcludedFileTypes.Split([','], StringSplitOptions.RemoveEmptyEntries);
...
return excludedFileTypes.Contains(fileExtension, StringComparer.OrdinalIgnoreCase);

Because ShouldSkipResultByTypeAndActionKeyword is invoked for each SearchResult, this repeated split and array scan can be unnecessarily expensive on large result sets.

Consider caching a normalized HashSet<string> of extensions on the settings object (or on SearchManager) and updating it when ExcludedFileTypes changes, e.g.:

-        private bool IsExcludedFile(SearchResult result)
-        {
-            string[] excludedFileTypes = Settings.ExcludedFileTypes.Split([','], StringSplitOptions.RemoveEmptyEntries);
-            string fileExtension = Path.GetExtension(result.FullPath).TrimStart('.');
-
-            return excludedFileTypes.Contains(fileExtension, StringComparer.OrdinalIgnoreCase);
-        }
+        private bool IsExcludedFile(SearchResult result)
+        {
+            // Pseudocode: assume Settings.ExcludedFileTypesSet is a cached, case‑insensitive HashSet<string>
+            var fileExtension = Path.GetExtension(result.FullPath).TrimStart('.');
+            return Settings.ExcludedFileTypesSet.Contains(fileExtension);
+        }

If introducing a cached set is too much for this PR, at least consider hoisting the split out of the per‑result path (e.g., compute once at the start of SearchAsync and pass it down).


23-27: New action-keyword type filter mapping looks good and centralizes behavior

The _typesToFilterByActionKeyword map plus IsResultTypeFilteredByActionKeyword and CanUseIndexSearchByActionKeywords nicely centralize the per‑keyword filtering and routing rules:

  • File search suppresses folders/volumes, folder search suppresses files.
  • The mapping is easy to extend if more scoped action keywords or result types are added later.
  • ShouldSkipResultByTypeAndActionKeyword combines excluded extensions with type‑based filtering cleanly.

Once the path-search branch and Quick Access concerns are addressed, this structure should make future evolution of action keywords relatively low‑touch.

If you want to tighten it further, you could rewrite IsResultTypeFilteredByActionKeyword and CanUseIndexSearchByActionKeywords with LINQ (Any) to make the intent more explicit, but that’s purely stylistic.

Also applies to: 285-339

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f2f474 and bb490c0.

📒 Files selected for processing (1)
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (11 hunks)
🧰 Additional context used
🧠 Learnings (9)
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-13T06:04:26.977Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs:143-165
Timestamp: 2025-09-13T06:04:26.977Z
Learning: In Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml, the ListView_SizeChanged handler in the C# file assumes 5 GridViewColumns but the XAML may have more columns. The user Jack251970 indicated this mismatch doesn't need to be fixed when pointed out during PR #3593 review.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-04T11:52:29.096Z
Learnt from: jjw24
Repo: Flow-Launcher/Flow.Launcher PR: 3932
File: Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs:48-55
Timestamp: 2025-09-04T11:52:29.096Z
Learning: In Flow Launcher's PluginsManifest.cs, when dealing with version parsing for the MinimumAppVersion feature, maintainer jjw24 prefers to keep the solution simple rather than implementing comprehensive helper methods for SemVer parsing normalization.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-11-06T12:57:11.574Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 4072
File: Plugins/Flow.Launcher.Plugin.Program/Main.cs:100-111
Timestamp: 2025-11-06T12:57:11.574Z
Learning: In Flow Launcher's Program plugin Main.cs QueryAsync method, the semaphore pattern where WaitAsync(token) is inside a try-catch that only catches OperationCanceledException, followed by an explicit Release() call after the try-catch block, is safe and doesn't cause semaphore leaks. When WaitAsync throws OperationCanceledException, the semaphore is not acquired, so no release is needed. When WaitAsync succeeds, the Release() call after the try-catch executes normally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (2)

69-107: Path-like queries with FileSearchActionKeyword return no results, and folder path results aren't type-filtered

The review identifies two potential behavioral issues in the action-keyword routing logic:

  1. When FileSearchActionKeyword is active and query.Search resembles a path, isPathSearch evaluates to true, but the condition on lines 89–93 explicitly excludes FileSearchActionKeyword from triggering PathSearchActionKeyword addition. If the subsequent switch statement falls through to a default case without running index search, no results are returned.

  2. When FolderSearchActionKeyword is active with a path-like query, PathSearchAsync is invoked but the results are not filtered by type before being returned, potentially surfacing files when only folders should appear.

The proposed fix addresses both by:

  • Treating path-like input under file search as normal text search (preserving index search)
  • Applying type-filtering to PathSearchAsync results when file/folder keywords are active

To confirm these issues, verify the complete switch statement behavior (especially the default case) and whether PathSearchAsync results bypass type-filtering logic.


132-308: Quick Access merge ignores ExcludeQuickAccessFromActionKeywords and assumes ContextData is SearchResult

Two related concerns in GetQuickAccessResultsFilteredByActionKeyword and how it is used:

  1. ExcludeQuickAccessFromActionKeywords may be ignored

The visible code unconditionally merges Quick Access results via:

results.UnionWith(GetQuickAccessResultsFilteredByActionKeyword(query, activeActionKeywords));

GetQuickAccessResultsFilteredByActionKeyword does not check Settings.ExcludeQuickAccessFromActionKeywords, only filtering by action-keyword type. If this setting should gate Quick Access merging for non-QuickAccess keyword searches, a guard is needed:

-            //Merge Quick Access Link results for non-path searches.
-            results.UnionWith(GetQuickAccessResultsFilteredByActionKeyword(query, activeActionKeywords));
+            // Merge Quick Access Link results for non-path searches, unless explicitly disabled.
+            if (!Settings.ExcludeQuickAccessFromActionKeywords
+                || activeActionKeywords.ContainsKey(ActionKeyword.QuickAccessActionKeyword))
+            {
+                results.UnionWith(GetQuickAccessResultsFilteredByActionKeyword(query, activeActionKeywords));
+            }
  1. Filtering relies on Result.ContextData being a SearchResult

GetQuickAccessResultsFilteredByActionKeyword filters with:

return results
    .Where(r => r.ContextData is SearchResult result
           && !IsResultTypeFilteredByActionKeyword(result.Type, actions))
    .ToList();

This assumes all Quick Access results have ContextData set to a SearchResult. If QuickAccess.AccessLinkListMatched stores a different type or leaves ContextData null, this filter silently removes all merged Quick Access results.

Verify that QuickAccess.AccessLinkListMatched creates Result objects with ContextData as SearchResult; otherwise, the type filtering will not apply and all Quick Access items will be excluded.


var queryIsEmpty = string.IsNullOrEmpty(query.Search);

if (queryIsEmpty && activeActionKeywords.ContainsKey(ActionKeyword.QuickAccessActionKeyword))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there. Index search is giving the error without any query:

Image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, strange, it works fine for me.

Screenshot 2025-12-07 133406

Copy link
Member

@jjw24 jjw24 Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's still running the query and the error is specific to my environment, but we should have it returned empty list if no query input with the action keyword.

Copy link
Member

@jjw24 jjw24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to make the folder search behaviour consistent- it should either allow path search for when there is a hotkey or global, or not allow at all:

With global hotkey:

Image

With action keyword:

Image

@01Dri
Copy link
Contributor Author

01Dri commented Dec 7, 2025

I think we also need to make the folder search behaviour consistent- it should either allow path search for when there is a hotkey or global, or not allow at all:

With global hotkey:

Image With action keyword: Image

I think Folder and Search should not allow global hotkey assignment, similar to Quick Access.

@jjw24
Copy link
Member

jjw24 commented Dec 9, 2025

Pretty sure Quick Access allows global action keyword, only one doesn't is content search which is due to significant search time/load.

I don't see why we shouldn't allow global action keyword for Folder and Search. What's the reasoning?

@01Dri
Copy link
Contributor Author

01Dri commented Dec 11, 2025

Pretty sure Quick Access allows global action keyword, only one doesn't is content search which is due to significant search time/load.

I don't see why we shouldn't allow global action keyword for Folder and Search. What's the reasoning?

When both file and folder use the global keyword, which one should the search manager prioritize?
The results are filtered based on the action keyword, but for example, if I type “User” and both file and folder actions are active with the global keyword, which results should the search manager show, folders or files?

I think allowing global keywords for both actions can make the results confusing. What do you think?

Either way, I’ve applied the requested fixes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (1)

59-90: Path-search elevation currently overrides explicit non-path action keywords

Because we always add PathSearchActionKeyword whenever isPathSearch is true (lines 84‑88), CanUsePatchSearchByActionKeywords(activeActionKeywords) will succeed for any path-like query, even when the query was triggered with an explicit non-path action keyword (e.g. QuickAccess, FileContent, FileSearch, IndexSearch). That sends those queries down the path-search branch and bypasses their dedicated behaviors, which goes against the earlier intent that explicit non-search keywords should “win” over automatic path detection when conflicts arise.

Consider tightening the condition so we only elevate to path search when we’re on keywords that are meant to support it (e.g. default search / explicit path / folder search), and not when Quick Access or content-search actions are active. For example:

-            // If no action keyword for path search is specified but the query is a path search, add it.
-            if (!activeActionKeywords.ContainsKey(ActionKeyword.PathSearchActionKeyword) && isPathSearch)
-            {
-                activeActionKeywords.Add(ActionKeyword.PathSearchActionKeyword, keyword);
-            }
+            // Elevate to path search only when using keywords that are intended to support it,
+            // so explicit non-path actions (QuickAccess, FileContent, FileSearch, IndexSearch) still win.
+            if (isPathSearch
+                && activeActionKeywords.ContainsKey(ActionKeyword.SearchActionKeyword)
+                && !activeActionKeywords.ContainsKey(ActionKeyword.PathSearchActionKeyword))
+            {
+                activeActionKeywords.Add(ActionKeyword.PathSearchActionKeyword, keyword);
+            }

This keeps the “plain path query with *” behavior fixed while avoiding surprising overrides for dedicated actions like Quick Access.

🧹 Nitpick comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (1)

94-127: Quick Access merge now respects file/folder filters, but may ignore the exclusion setting

The new switch and GetQuickAccessResultsFilteredByActionKeyword wiring does a good job of:

  • Routing Quick Access–only queries via the QuickAccessActionKeyword cases.
  • Merging Quick Access into index/content results and then filtering out types inconsistent with the active file/folder action keywords.

One thing to double‑check: GetQuickAccessResultsFilteredByActionKeyword is always called for non-path index/content flows, and it doesn’t currently look at Settings.ExcludeQuickAccessFromActionKeywords. If that setting previously controlled whether Quick Access items should be merged when any action keyword is active, this behavior may have been lost.

If the setting is still expected to be honored here, you could gate the merge like:

-            //Merge Quick Access Link results for non-path searches.
-            results.UnionWith(GetQuickAccessResultsFilteredByActionKeyword(query, activeActionKeywords));
+            // Merge Quick Access Link results for non-path searches, unless explicitly excluded.
+            if (!Settings.ExcludeQuickAccessFromActionKeywords
+                || activeActionKeywords.ContainsKey(ActionKeyword.QuickAccessActionKeyword))
+            {
+                results.UnionWith(GetQuickAccessResultsFilteredByActionKeyword(query, activeActionKeywords));
+            }

and, if desired, add a similar guard inside GetQuickAccessResultsFilteredByActionKeyword. This keeps the new type-based filtering while preserving the legacy opt-out toggle for users who don’t want Quick Access mixed into typed searches.

Also applies to: 130-145, 149-149, 163-163, 287-299

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb490c0 and 336afe8.

📒 Files selected for processing (1)
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (10 hunks)
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-13T06:04:26.977Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs:143-165
Timestamp: 2025-09-13T06:04:26.977Z
Learning: In Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml, the ListView_SizeChanged handler in the C# file assumes 5 GridViewColumns but the XAML may have more columns. The user Jack251970 indicated this mismatch doesn't need to be fixed when pointed out during PR #3593 review.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-11-06T12:57:11.574Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 4072
File: Plugins/Flow.Launcher.Plugin.Program/Main.cs:100-111
Timestamp: 2025-11-06T12:57:11.574Z
Learning: In Flow Launcher's Program plugin Main.cs QueryAsync method, the semaphore pattern where WaitAsync(token) is inside a try-catch that only catches OperationCanceledException, followed by an explicit Release() call after the try-catch block, is safe and doesn't cause semaphore leaks. When WaitAsync throws OperationCanceledException, the semaphore is not acquired, so no release is needed. When WaitAsync succeeds, the Release() call after the try-catch executes normally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
🧬 Code graph analysis (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (3)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (2)
  • Settings (14-243)
  • Dictionary (230-242)
Plugins/Flow.Launcher.Plugin.Explorer/Search/QuickAccessLinks/QuickAccess.cs (3)
  • QuickAccess (7-41)
  • List (11-28)
  • List (30-40)
Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs (3)
  • EnvironmentVariables (10-109)
  • IsEnvironmentVariableSearch (25-31)
  • HasEnvironmentVar (33-41)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (2)

1-26: Centralized type-filter map for action keywords looks good

The _typesToFilterByActionKeyword map is a nice way to centralize which result types should be excluded for file/folder searches, and the new imports are consistent with the rest of the file. No issues here.


168-183: Modernization of returns and helpers looks correct

The small refactors using list spread ([.. results]) in SearchAsync and PathSearchAsync, the list expression in EverythingContentSearchResult, the pattern-based check in UseIndexSearch, and the updated Split call in IsExcludedFile all preserve behavior and improve clarity/readability. No further changes needed here.

Also applies to: 203-253, 259-259, 281-281

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (1)

330-346: Typo in method name: "Patch" should be "Path".

The method name CanUsePatchSearchByActionKeywords and its comment have a typo—"Patch" should be "Path" to match the PathSearchActionKeyword it checks.

-        // Action keywords that supports patch search in results.
-        private bool CanUsePatchSearchByActionKeywords(Dictionary<ActionKeyword, string> actions)
+        // Action keywords that support path search in results.
+        private bool CanUsePathSearchByActionKeywords(Dictionary<ActionKeyword, string> actions)

Also update the call site at line 97:

-                    when CanUsePatchSearchByActionKeywords(activeActionKeywords):
+                    when CanUsePathSearchByActionKeywords(activeActionKeywords):
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 336afe8 and 7b22fd8.

📒 Files selected for processing (1)
  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (10 hunks)
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2025-10-16T09:29:19.653Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:519-523
Timestamp: 2025-10-16T09:29:19.653Z
Learning: In Flow Launcher's PluginManager.cs QueryDialogJumpForPluginAsync method, when a DialogJump plugin is still initializing, returning null is intentional behavior. This allows the query to fall through to the default Explorer plugin, which serves as a fallback handler. This is different from QueryForPluginAsync and QueryHomeForPluginAsync, which show "still initializing" messages because they don't have fallback mechanisms.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:19.012Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher.Core/Plugin/PluginManager.cs:280-292
Timestamp: 2025-07-21T09:19:19.012Z
Learning: In Flow Launcher's PluginManager.cs, the post-initialization operations (RegisterResultsUpdatedEvent, UpdatePluginMetadataTranslation, RegisterPluginActionKeywords, DialogJump.InitializeDialogJumpPlugin, and AddPluginToLists) are designed to be exception-safe and do not require additional try-catch error handling according to the maintainer Jack251970.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-09-13T06:04:26.977Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3593
File: Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs:143-165
Timestamp: 2025-09-13T06:04:26.977Z
Learning: In Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml, the ListView_SizeChanged handler in the C# file assumes 5 GridViewColumns but the XAML may have more columns. The user Jack251970 indicated this mismatch doesn't need to be fixed when pointed out during PR #3593 review.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-10-16T10:48:30.573Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:252-275
Timestamp: 2025-10-16T10:48:30.573Z
Learning: In Flow Launcher's App.xaml.cs, the plugin initialization block (lines 252-275) that includes PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, _mainVM.QueryResults(), and API.SaveAppAllSettings() does not require additional Task.Run wrappers or Dispatcher.InvokeAsync calls according to maintainer Jack251970, as the threading model is already safe as designed.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-07-21T09:19:49.684Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 3854
File: Flow.Launcher/App.xaml.cs:246-262
Timestamp: 2025-07-21T09:19:49.684Z
Learning: In Flow Launcher's App.xaml.cs, the asynchronous plugin initialization task (containing AbstractPluginEnvironment.PreStartPluginExecutablePathUpdate, PluginManager.LoadPlugins, PluginManager.InitializePluginsAsync, and AutoPluginUpdates) does not require additional try-catch error handling according to maintainer Jack251970, as these operations are designed to handle exceptions internally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-06-24T19:06:48.344Z
Learnt from: Koisu-unavailable
Repo: Flow-Launcher/Flow.Launcher PR: 3770
File: Flow.Launcher/ViewModel/MainViewModel.cs:0-0
Timestamp: 2025-06-24T19:06:48.344Z
Learning: In Flow.Launcher's Explorer plugin results, the SubTitle property always contains the directory containing the file. For file results, Title contains the filename and SubTitle contains the parent directory. For directory results, SubTitle contains the directory path itself.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2024-11-03T07:40:11.014Z
Learnt from: Yusyuriv
Repo: Flow-Launcher/Flow.Launcher PR: 3057
File: Flow.Launcher.Core/Plugin/JsonRPCPluginSettings.cs:0-0
Timestamp: 2024-11-03T07:40:11.014Z
Learning: In Flow Launcher, when using Windows Forms dialogs (e.g., in `JsonRPCPluginSettings.cs`), path validation is enabled by default in `OpenFileDialog` and `FolderBrowserDialog`, preventing users from selecting invalid paths, but it's possible to opt out of this validation on individual dialogs.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
📚 Learning: 2025-11-06T12:57:11.574Z
Learnt from: Jack251970
Repo: Flow-Launcher/Flow.Launcher PR: 4072
File: Plugins/Flow.Launcher.Plugin.Program/Main.cs:100-111
Timestamp: 2025-11-06T12:57:11.574Z
Learning: In Flow Launcher's Program plugin Main.cs QueryAsync method, the semaphore pattern where WaitAsync(token) is inside a try-catch that only catches OperationCanceledException, followed by an explicit Release() call after the try-catch block, is safe and doesn't cause semaphore leaks. When WaitAsync throws OperationCanceledException, the semaphore is not acquired, so no release is needed. When WaitAsync succeeds, the Release() call after the try-catch executes normally.

Applied to files:

  • Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (7)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (7)

22-27: LGTM!

The filtering dictionary correctly maps action keywords to result types that should be excluded. FileSearchActionKeyword excludes folders/volumes (showing only files), and FolderSearchActionKeyword excludes files (showing only folders).


68-77: LGTM!

The empty query handling correctly addresses the PR requirement—returning empty results when only the file/folder action keyword is typed without additional query text. QuickAccess is handled as a special case with its own behavior.


84-88: LGTM!

Auto-adding PathSearchActionKeyword when the query is a path search preserves the expected path navigation behavior regardless of which action keyword is currently active. This correctly addresses the previously flagged path search regression.


111-113: LGTM!

When QuickAccessActionKeyword is explicitly active, returning all matching Quick Access results without file/folder filtering is correct—the user specifically requested Quick Access search, so all matching items should be shown.


126-140: Quick Access filtering is now correctly applied.

The previous review flagged that Quick Access results were ignoring folder/file action filters. This is now addressed by calling GetQuickAccessResultsFilteredByActionKeyword at line 127, which filters Quick Access items based on the active action keywords before merging them into results.


300-312: LGTM!

The implementation correctly iterates through all active action keywords to determine if a result type should be filtered. The edge case where both file and folder search share the same keyword (resulting in everything being excluded) is a configuration issue flagged in PR discussion—this is acceptable given the feature design.


295-298: The filter condition is correct. All Quick Access results are created by ResultManager methods (CreateDriveSpaceDisplayResult, CreateFolderResult, CreateFileResult), which consistently set ContextData to a SearchResult instance. The exhaustive switch statement in QuickAccess.AccessLinkListMatched ensures no result can bypass this. The Where condition will never exclude valid items because all Quick Access results will have SearchResult context data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

10 min review Code Refactor enhancement New feature or request review in progress Indicates that a review is in progress for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants