Skip to content

Add Custom Template shell option to Shell plugin - #4580

Open
DavidGBrett wants to merge 3 commits into
devfrom
use-any-shell
Open

Add Custom Template shell option to Shell plugin #4580
DavidGBrett wants to merge 3 commits into
devfrom
use-any-shell

Conversation

@DavidGBrett

@DavidGBrett DavidGBrett commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Adds a "Custom Template" entry to the shell selection dropdown.

Should resolve #187 (The most upvoted feature request) - users can fully control shell configuration with this.

Users can provide any executable path and an arguments template using {command} as a placeholder.
Browse button calls OpenFileDialog for executable file path.

Shows error message when command ran with no executable path is set, though empty arguments templates are accepted for full user control.

Leave Shell Open, Close After Press, and Use Windows Terminal settings are disabled for Custom Template - the user has to manually implement those.

Use Windows Terminal is also now correctly disabled for RunCommand, which never supported it.


Summary by cubic

Adds a Custom Template shell so you can run commands with any executable using a simple {command} placeholder. If no executable is set, we show an error and do not run.

  • Summary of changes

    • Changed
      • Disabled “Use Windows Terminal” for RunCommand and CustomTemplate.
      • Disabled “Leave Shell Open” and “Close After Press” for CustomTemplate.
      • Settings panel shows Custom Template fields only when selected; Windows Terminal toggle now respects a view-model flag.
      • Execution stops with a clear error if the executable path is empty.
    • Added
      • New Shell.CustomTemplate and Settings.CustomTemplateShellConfig with example defaults: ExecutablePath "cmd.exe", ArgumentsTemplate /k "{command}".
      • Process creation for Custom Template: expands env vars in path and template, trims and strips quotes from the path, replaces {command}, and allows empty templates.
      • Browse button for the executable path plus matching localization strings and tooltips.
    • Removed
      • Silent fallback to RunCommand/default template when no executable was set.
    • Memory
      • Minimal: one small settings object and two UI rows.
    • Security
      • Same as RunCommand: users can target any executable; no new elevation paths beyond existing “Run as Admin”.
    • Unit tests
      • Added coverage for placeholder replacement, empty template support, null/empty config leaving FileName empty, trim and quote stripping, env var expansion (path, template, and command), working directory, UseShellExecute, and admin verb.
  • Release Note
    Choose any app to run your commands with a simple {command} template, with a clear error if no app is set.

Written for commit 62d3edb. Summary will update on new commits.

Review in cubic

@github-actions github-actions Bot added this to the 2.2.0 milestone Jul 18, 2026
@DavidGBrett DavidGBrett added the enhancement New feature or request label Jul 18, 2026
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Shell.CustomTemplate mode with configurable executable and argument templates, settings UI and localization, process-start construction, shell-state handling, and expanded tests.

Changes

Custom template shell

Layer / File(s) Summary
Shell mode and configuration contract
Plugins/Flow.Launcher.Plugin.Shell/Settings.cs, Plugins/Flow.Launcher.Plugin.Shell/ViewModels/ShellSettingViewModel.cs
Adds the CustomTemplate shell option, configuration properties, and computed UI-state properties with change notifications.
Custom template process construction
Plugins/Flow.Launcher.Plugin.Shell/Main.cs, Plugins/Flow.Launcher.Plugin.Shell/Converters/*
Passes custom configuration into process creation, applies executable and argument templates, validates the executable path, and excludes CustomTemplate from the shell-open decision.
Custom template settings interface
Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml, Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml, Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml.cs
Adds localized labels, conditional executable and argument inputs, executable browsing, and Windows Terminal enablement rules.
Execution coverage
Flow.Launcher.Test/Plugins/ShellPluginTest.cs
Tests default and custom templates, command substitution, environment expansion, path normalization, and null or empty configuration behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ShellSetting
  participant Settings
  participant Main
  participant ProcessStartInfo
  User->>ShellSetting: select CustomTemplate and configure fields
  ShellSetting->>Settings: store executable path and argument template
  Settings->>Main: provide CustomTemplateShellConfig
  Main->>ProcessStartInfo: set expanded executable and substituted arguments
Loading

Possibly related PRs

Suggested reviewers: jjw24, victoriousraptor

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR fulfills #187 by letting users configure any executable and command template for Shell executions.
Out of Scope Changes check ✅ Passed The changes are focused on the Custom Template shell feature, its UI, settings, tests, and related behavior.
Title check ✅ Passed The title clearly summarizes the main change: adding a Custom Template shell option to the Shell plugin.
Description check ✅ Passed The description matches the changeset by describing the new Custom Template shell behavior and related UI/settings changes.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch use-any-shell

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
Flow.Launcher.Test/Plugins/ShellPluginTest.cs (1)

308-356: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Shell.CustomTemplate to common test cases.

To ensure the new custom template behavior is fully validated against standard shell baselines (like setting the correct working directory and UseShellExecute flag), consider adding [TestCase(Shell.CustomTemplate)] to the shared common tests.

💡 Proposed change
         [TestCase(Shell.Cmd)]
         [TestCase(Shell.Powershell)]
         [TestCase(Shell.Pwsh)]
         [TestCase(Shell.RunCommand)]
+        [TestCase(Shell.CustomTemplate)]
         public void SetsWorkingDirectory(Shell shell)
         {
             var info = Create(shell: shell);
 
             var expected = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
             Assert.That(info.WorkingDirectory, Is.EqualTo(expected));
         }
 
         [TestCase(Shell.Cmd)]
         [TestCase(Shell.Powershell)]
         [TestCase(Shell.Pwsh)]
         [TestCase(Shell.RunCommand)]
+        [TestCase(Shell.CustomTemplate)]
         public void SetsUseShellExecute(Shell shell)
         {
             var info = Create(shell: shell);
 
             Assert.That(info.UseShellExecute, Is.True);
         }
 
         [TestCase(Shell.Cmd)]
         [TestCase(Shell.Powershell)]
         [TestCase(Shell.Pwsh)]
         [TestCase(Shell.RunCommand)]
+        [TestCase(Shell.CustomTemplate)]
         public void ExpandsEnvironmentVariables(Shell shell)
         {
             var info = Create(
                 command: "%USERPROFILE%\\test",
                 shell: shell);
 
             var expandedPath = Environment.ExpandEnvironmentVariables("%USERPROFILE%\\test");
 
             switch (shell)
             {
                 case Shell.Cmd:
                     Assert.That(info.Arguments, Is.EqualTo($"/c {expandedPath}"));
                     break;
                 case Shell.Powershell:
                 case Shell.Pwsh:
                     Assert.That(info.ArgumentList, Does.Contain(expandedPath + ";"));
                     break;
                 case Shell.RunCommand:
+                case Shell.CustomTemplate:
                     Assert.That(info.FileName, Is.EqualTo(expandedPath));
                     break;
             }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Flow.Launcher.Test/Plugins/ShellPluginTest.cs` around lines 308 - 356, Add
[TestCase(Shell.CustomTemplate)] to the shared SetsWorkingDirectory,
SetsUseShellExecute, and ExpandsEnvironmentVariables tests so the custom
template follows the same baseline assertions as the other shell values.
Preserve the existing test setup and assertions.
Plugins/Flow.Launcher.Plugin.Shell/Main.cs (1)

450-456: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Expand environment variables for custom paths and templates.

Users often rely on environment variables like %LOCALAPPDATA% or %ProgramFiles% to define executable paths, especially for apps installed in user directories or portable setups. To provide feature parity with how commands are treated elsewhere in the plugin, consider expanding environment variables in the configuration strings.

💡 Proposed change
-            info.FileName = config.ExecutablePath;
+            info.FileName = Environment.ExpandEnvironmentVariables(config.ExecutablePath);
 
             var template = string.IsNullOrEmpty(config.ArgumentsTemplate)
                 ? "{command}"
-                : config.ArgumentsTemplate;
+                : Environment.ExpandEnvironmentVariables(config.ArgumentsTemplate);
 
             info.Arguments = template.Replace("{command}", command);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Plugins/Flow.Launcher.Plugin.Shell/Main.cs` around lines 450 - 456, Expand
environment variables in the configured executable path and arguments template
before assigning them in the command setup flow. Update the logic around
config.ExecutablePath, config.ArgumentsTemplate, and template so both custom
configuration strings support variables such as %LOCALAPPDATA% while preserving
the existing default "{command}" behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Plugins/Flow.Launcher.Plugin.Shell/Settings.cs`:
- Around line 145-150: Update CustomTemplateShellConfig to inherit BaseModel and
make ExecutablePath and ArgumentsTemplate observable by raising
OnPropertyChanged in their setters, so programmatic changes such as
BrowseExecutablePath_Click refresh the bound UI controls.

---

Nitpick comments:
In `@Flow.Launcher.Test/Plugins/ShellPluginTest.cs`:
- Around line 308-356: Add [TestCase(Shell.CustomTemplate)] to the shared
SetsWorkingDirectory, SetsUseShellExecute, and ExpandsEnvironmentVariables tests
so the custom template follows the same baseline assertions as the other shell
values. Preserve the existing test setup and assertions.

In `@Plugins/Flow.Launcher.Plugin.Shell/Main.cs`:
- Around line 450-456: Expand environment variables in the configured executable
path and arguments template before assigning them in the command setup flow.
Update the logic around config.ExecutablePath, config.ArgumentsTemplate, and
template so both custom configuration strings support variables such as
%LOCALAPPDATA% while preserving the existing default "{command}" behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aae87e58-bdb7-47ab-8a99-4dc1f541b199

📥 Commits

Reviewing files that changed from the base of the PR and between 07a958d and a34f902.

📒 Files selected for processing (8)
  • Flow.Launcher.Test/Plugins/ShellPluginTest.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Converters/LeaveShellOpenOrCloseShellAfterPressEnabledConverter.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
  • Plugins/Flow.Launcher.Plugin.Shell/Main.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Shell/ViewModels/ShellSettingViewModel.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml
  • Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml.cs

Comment thread Plugins/Flow.Launcher.Plugin.Shell/Settings.cs Outdated
@DavidGBrett
DavidGBrett marked this pull request as draft July 18, 2026 19:55

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
Comment thread Plugins/Flow.Launcher.Plugin.Shell/Main.cs Outdated
@DavidGBrett
DavidGBrett marked this pull request as ready for review July 19, 2026 07:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Plugins/Flow.Launcher.Plugin.Shell/Main.cs`:
- Around line 450-456: Update the custom configuration handling near the
ProcessStartInfo assignments to expand environment variables in
config.ExecutablePath and config.ArgumentsTemplate, then trim the executable
path and remove surrounding quotes before assigning info.FileName. Apply the
same variable expansion to the arguments template before replacing {command},
preserving the existing default template behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 563c3bb9-9fff-4584-81c2-fba14fed6c24

📥 Commits

Reviewing files that changed from the base of the PR and between a34f902 and 393aa16.

📒 Files selected for processing (8)
  • Flow.Launcher.Test/Plugins/ShellPluginTest.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Converters/LeaveShellOpenOrCloseShellAfterPressEnabledConverter.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
  • Plugins/Flow.Launcher.Plugin.Shell/Main.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Shell/ViewModels/ShellSettingViewModel.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml
  • Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml.cs
🚧 Files skipped from review as they are similar to previous changes (6)
  • Plugins/Flow.Launcher.Plugin.Shell/Converters/LeaveShellOpenOrCloseShellAfterPressEnabledConverter.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml
  • Plugins/Flow.Launcher.Plugin.Shell/Settings.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml.cs
  • Plugins/Flow.Launcher.Plugin.Shell/ViewModels/ShellSettingViewModel.cs
  • Plugins/Flow.Launcher.Plugin.Shell/Views/ShellSetting.xaml

Comment thread Plugins/Flow.Launcher.Plugin.Shell/Main.cs Outdated
@DavidGBrett
DavidGBrett marked this pull request as draft July 19, 2026 07:52

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Plugins/Flow.Launcher.Plugin.Shell/Main.cs Outdated
Adds a "Custom Template" entry to the shell selection dropdown. Users can provide any executable path and an arguments template using {command} as a placeholder. Falls back to RunCommand behavior when no executable path is configured.

Leave Shell Open, Close After Press, and Use Windows Terminal checkboxes are disabled for Custom Template - the user has to manually implement those

Use Windows Terminal is also now correctly disabled for RunCommand, which never supported it.
@DavidGBrett
DavidGBrett marked this pull request as ready for review July 19, 2026 09:34

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Plugins/Flow.Launcher.Plugin.Shell/Main.cs Outdated
Comment thread Plugins/Flow.Launcher.Plugin.Shell/Main.cs Outdated
@DavidGBrett
DavidGBrett marked this pull request as draft July 19, 2026 09:39
@DavidGBrett
DavidGBrett marked this pull request as ready for review July 23, 2026 20:16
@DavidGBrett
DavidGBrett marked this pull request as draft July 23, 2026 20:16

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 8 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Plugins/Flow.Launcher.Plugin.Shell/Main.cs
Comment thread Plugins/Flow.Launcher.Plugin.Shell/Languages/en.xaml Outdated
@DavidGBrett
DavidGBrett marked this pull request as ready for review July 24, 2026 08:17

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 8 files

Re-trigger cubic

@DavidGBrett
DavidGBrett enabled auto-merge July 24, 2026 08:22
… default template

Now catches empty filename in Execute instead of trying to do a run
command.

Adjusted defaults for executable path and arguement template to be an
example to the user and made tooltips match

Empty argument templates are now accepted to give full control to the
user
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow using any shell with Shell plugin

1 participant