-
-
Notifications
You must be signed in to change notification settings - Fork 455
[FEATURE] Folder and File Action Keywords #4093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
|
🥷 Code experts: Jack251970, VictoriousRaptor Jack251970, VictoriousRaptor have most 👩💻 activity in the files. See details
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame:
Activity based on git-commit:
Knowledge based on git-blame: ✨ Comment |
|
Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX. |
|
Note Other AI code review bot(s) detectedCodeRabbit 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. 📝 WalkthroughWalkthroughAdds folder/file action keywords and an ExcludeQuickAccessFromActionKeywords setting, updates English localization and settings UI, and refactors SearchManager to use GetActiveActionKeyword with centralized branching, result filtering (ShouldSkip) and quick-access merging. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as UI / Query
participant Settings as Settings.GetActiveActionKeyword
participant SearchMgr as SearchManager
participant PathSearch as PathSearchAsync
participant ContentSearch as Content/Index Search
participant QuickAccess as QuickAccessLookup
UI->>SearchMgr: Submit Query
SearchMgr->>Settings: GetActiveActionKeyword(query.ActionKeywordStr)
Settings-->>SearchMgr: activeActionKeyword (nullable)
alt no active keyword & not path search
SearchMgr-->>UI: return empty results
else active keyword is QuickAccessActionKeyword
SearchMgr->>QuickAccess: Find matches
QuickAccess-->>SearchMgr: quick access results
SearchMgr-->>UI: return quick access results
else active keyword is PathSearchActionKeyword
SearchMgr->>PathSearch: PathSearchAsync(query)
PathSearch-->>SearchMgr: path results
SearchMgr->>SearchMgr: MergeQuickAccessInResultsIfQueryMatch(...)
SearchMgr->>SearchMgr: filter with ShouldSkip(...)
SearchMgr-->>UI: return filtered results
else
SearchMgr->>ContentSearch: Content/index search (FileContent handled specially)
ContentSearch-->>SearchMgr: content results
SearchMgr->>SearchMgr: MergeQuickAccessInResultsIfQueryMatch(...)
SearchMgr->>SearchMgr: filter with ShouldSkip(...)
SearchMgr-->>UI: return filtered results
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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
📒 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.csPlugins/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.csPlugins/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.csPlugins/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.csPlugins/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.csPlugins/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.csPlugins/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.csPlugins/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.csPlugins/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.xamlPlugins/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
There was a problem hiding this 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.
Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml
Outdated
Show resolved
Hide resolved
Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this 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
♻️ Duplicate comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (1)
281-289: Quick Access results bypass folder/file action keyword filters.When
ExcludeQuickAccessFromActionKeywordsisfalse(the default),MergeQuickAccessInResultsIfQueryMatchmerges all matched Quick Access entries regardless of their type. This means:
FolderSearchActionKeywordwill show Quick Access filesFileSearchActionKeywordwill show Quick Access foldersThis contradicts the PR's goal of respecting action keyword constraints.
Apply this diff to filter Quick Access results by type:
private void MergeQuickAccessInResultsIfQueryMatch(HashSet<Result> results, Query query, ActionKeyword? activeActionKeyword) { if (activeActionKeyword != null && activeActionKeyword != ActionKeyword.QuickAccessActionKeyword && Settings.ExcludeQuickAccessFromActionKeywords) return; - var quickAccessMatched = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); + + IEnumerable<AccessLink> quickAccessLinks = Settings.QuickAccessLinks; + + if (activeActionKeyword == ActionKeyword.FolderSearchActionKeyword) + quickAccessLinks = quickAccessLinks.Where(link => link.Type != ResultType.File); + else if (activeActionKeyword == ActionKeyword.FileSearchActionKeyword) + quickAccessLinks = quickAccessLinks.Where(link => link.Type == ResultType.File); + + var quickAccessMatched = QuickAccess.AccessLinkListMatched(query, quickAccessLinks); if (quickAccessMatched != null && quickAccessMatched.Count > 0) results.UnionWith(quickAccessMatched); }
🧹 Nitpick comments (1)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (1)
80-104: Consider simplifying the switch pattern.The
switchon a boolean with pattern matching works but is non-idiomatic. Anif/else ifchain would be more readable.Apply this diff for clearer logic flow:
- switch (activeActionKeyword!.Equals(ActionKeyword.PathSearchActionKeyword)) + if (activeActionKeyword!.Equals(ActionKeyword.PathSearchActionKeyword)) { - case true: - results.UnionWith(await PathSearchAsync(query, token).ConfigureAwait(false)); - return results.ToList(); - case false - // Intentionally require enabling of Everything's content search due to its slowness - when activeActionKeyword.Equals(ActionKeyword.FileContentSearchActionKeyword): - if (Settings.ContentIndexProvider is EverythingSearchManager && !Settings.EnableEverythingContentSearch) - return EverythingContentSearchResult(query); - - searchResults = Settings.ContentIndexProvider.ContentSearchAsync("", query.Search, token); - engineName = Enum.GetName(Settings.ContentSearchEngine); - break; - - case false - when activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword): - return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); - - - default: - searchResults = Settings.IndexProvider.SearchAsync(query.Search, token); - engineName = Enum.GetName(Settings.IndexSearchEngine); - break; + results.UnionWith(await PathSearchAsync(query, token).ConfigureAwait(false)); + return results.ToList(); + } + else if (activeActionKeyword.Equals(ActionKeyword.FileContentSearchActionKeyword)) + { + // Intentionally require enabling of Everything's content search due to its slowness + if (Settings.ContentIndexProvider is EverythingSearchManager && !Settings.EnableEverythingContentSearch) + return EverythingContentSearchResult(query); + + searchResults = Settings.ContentIndexProvider.ContentSearchAsync("", query.Search, token); + engineName = Enum.GetName(Settings.ContentSearchEngine); + } + else if (activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword)) + { + return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); + } + else + { + searchResults = Settings.IndexProvider.SearchAsync(query.Search, token); + engineName = Enum.GetName(Settings.IndexSearchEngine); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs(5 hunks)Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs(1 hunks)Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml(2 hunks)
🧰 Additional context used
🧠 Learnings (11)
📚 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
📚 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: 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: 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-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-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-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-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
📚 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
🧬 Code graph analysis (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (3)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (2)
Settings(14-241)ActionKeyword(228-239)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-241)ActionKeyword(228-239)
🪛 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). (3)
- GitHub Check: gitStream.cm
- GitHub Check: gitStream.cm
- GitHub Check: build
🔇 Additional comments (7)
Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs (1)
282-286: LGTM!The new action keyword entries follow the established pattern and are properly integrated with the underlying Settings API.
Plugins/Flow.Launcher.Plugin.Explorer/Views/ExplorerSettings.xaml (2)
677-677: LGTM!The new checkbox for excluding Quick Access from action keywords is properly bound and follows the established UI patterns.
Also applies to: 684-691
693-705: LGTM!The grid layout updates correctly accommodate the new checkbox row, and the ListView wrapping maintains proper visual hierarchy.
Also applies to: 708-708
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs (4)
54-66: LGTM!The active keyword detection and path search inference logic is well-structured and handles edge cases appropriately.
70-74: LGTM!Returning all Quick Access links for empty searches with the QuickAccess action keyword provides intuitive user experience.
107-107: LGTM!The result filtering logic properly applies the
ShouldSkipcheck to exclude results that don't match the active action keyword.Also applies to: 112-118
261-279: LGTM!The
ShouldSkipmethod correctly filters results based on the active action keyword, handling both excluded file types and keyword-specific type constraints.
Jack251970
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution! LGTM.
There was a problem hiding this 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)
283-294: Quick Access entries still bypass folder/file filtersThis helper adds every Quick Access hit even when
activeActionKeywordisFolderSearchActionKeywordorFileSearchActionKeyword, so folders leak into file-only queries and vice versa. That defeats the new per-type filtering and matches the earlier unresolved feedback. Please run each Quick Access result through the sameShouldSkiplogic (or pre-filter the collection) before unioning so action keywords remain authoritative.You can reuse
ShouldSkip:- var quickAccessMatched = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); - if (quickAccessMatched != null && quickAccessMatched.Count > 0) results.UnionWith(quickAccessMatched); + var quickAccessMatched = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); + if (quickAccessMatched is { Count: > 0 }) + { + foreach (var qa in quickAccessMatched.Where(r => + !ShouldSkip(activeActionKeyword!.Value, (SearchResult)r.ContextData))) + { + results.Add(qa); + } + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs(10 hunks)Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs(7 hunks)
🧰 Additional context used
🧠 Learnings (10)
📚 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.csPlugins/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.csPlugins/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.csPlugins/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.csPlugins/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
📚 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.csPlugins/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/Settings.csPlugins/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.csPlugins/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 (5)
Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs (2)
Settings(14-240)ActionKeyword(228-239)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)
QuickAccess(7-41)List(11-28)List(30-40)Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs (8)
ResultManager(16-412)Result(62-72)Result(95-173)Result(175-178)Result(180-183)Result(185-227)Result(257-283)Result(285-343)Plugins/Flow.Launcher.Plugin.Explorer/Main.cs (2)
List(54-57)Main(18-131)
⏰ 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
| // If no action keyword matched but the query is a path search, set active action keyword to path search. | ||
| if (activeActionKeyword == null && isPathSearch) activeActionKeyword = ActionKeyword.PathSearchActionKeyword; | ||
|
|
||
| // This allows the user to type the below action keywords and see/search the list of quick folder links | ||
| if (string.IsNullOrEmpty(query.Search) | ||
| && activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword)) | ||
| { | ||
| // No action keyword matched- plugin should not handle this query, return empty results. | ||
| return new List<Result>(); | ||
| return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks); | ||
| } | ||
|
|
||
| IAsyncEnumerable<SearchResult> searchResults; | ||
|
|
||
| bool isPathSearch = query.Search.IsLocationPathString() | ||
| || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) | ||
| || EnvironmentVariables.HasEnvironmentVar(query.Search); | ||
|
|
||
| string engineName; | ||
|
|
||
| switch (isPathSearch) | ||
| switch (activeActionKeyword.Equals(ActionKeyword.PathSearchActionKeyword)) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path search regression when wildcard keyword is active
Because GetActiveActionKeyword returns ActionKeyword.SearchActionKeyword for the default *, Line 66 never flips activeActionKeyword to PathSearchActionKeyword for plain path queries (e.g., typing C:\ or %appdata%). The path branch is therefore skipped and we fall into the index-search path, which no longer enumerates drives/folders or expands environment variables — a blocking regression of core Explorer behavior. Please force the active keyword over to path search whenever the query is classified as a path (while still allowing explicit non-search keywords to win).
Apply this diff to restore the path-search flow:
- if (activeActionKeyword == null && isPathSearch) activeActionKeyword = ActionKeyword.PathSearchActionKeyword;
+ if (isPathSearch && (activeActionKeyword is null || activeActionKeyword == ActionKeyword.SearchActionKeyword))
+ {
+ activeActionKeyword = ActionKeyword.PathSearchActionKeyword;
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // If no action keyword matched but the query is a path search, set active action keyword to path search. | |
| if (activeActionKeyword == null && isPathSearch) activeActionKeyword = ActionKeyword.PathSearchActionKeyword; | |
| // This allows the user to type the below action keywords and see/search the list of quick folder links | |
| if (string.IsNullOrEmpty(query.Search) | |
| && activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword)) | |
| { | |
| // No action keyword matched- plugin should not handle this query, return empty results. | |
| return new List<Result>(); | |
| return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks); | |
| } | |
| IAsyncEnumerable<SearchResult> searchResults; | |
| bool isPathSearch = query.Search.IsLocationPathString() | |
| || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) | |
| || EnvironmentVariables.HasEnvironmentVar(query.Search); | |
| string engineName; | |
| switch (isPathSearch) | |
| switch (activeActionKeyword.Equals(ActionKeyword.PathSearchActionKeyword)) | |
| { | |
| // If no action keyword matched but the query is a path search, set active action keyword to path search. | |
| if (isPathSearch && (activeActionKeyword is null || activeActionKeyword == ActionKeyword.SearchActionKeyword)) | |
| { | |
| activeActionKeyword = ActionKeyword.PathSearchActionKeyword; | |
| } | |
| // This allows the user to type the below action keywords and see/search the list of quick folder links | |
| if (string.IsNullOrEmpty(query.Search) | |
| && activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword)) | |
| { | |
| return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks); | |
| } | |
| IAsyncEnumerable<SearchResult> searchResults; | |
| string engineName; | |
| switch (activeActionKeyword.Equals(ActionKeyword.PathSearchActionKeyword)) | |
| { |
🤖 Prompt for AI Agents
In Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs around lines 65
to 80, the code only switches activeActionKeyword to PathSearchActionKeyword
when activeActionKeyword is null, which misses the case where
GetActiveActionKeyword returns the default SearchActionKeyword (wildcard '*')
for plain path queries; change the condition so that if isPathSearch is true and
activeActionKeyword is either null or equals ActionKeyword.SearchActionKeyword,
set activeActionKeyword = ActionKeyword.PathSearchActionKeyword, leaving any
other explicit non-search keywords untouched.
|
@jjw24 It works well for me generally. But I am not particularly sure about the refactoring within the |
|
Yeah no worries I will take a look too. |

CHANGES
Details
Exclude Quick Access
Quick Access items currently don’t respect the action keyword result filters.
For example, the Folder Search action should only display folders, but if there’s a
.txtfile in Quick Access, it still appears in the results.My idea introduces a new option to include or exclude Quick Access items when an action keyword is used.
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.