mirror of
https://github.com/microsoft/PowerToys
synced 2025-08-22 01:58:04 +00:00
[CmdPal] Search PATH starting with ~ / \ (#40887)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Love that we have now environment variables expanding! 🚀 Porting also few small features I implemented in Run Folder plugin a long time ago and I love: - https://github.com/microsoft/PowerToys/pull/7711 - https://github.com/microsoft/PowerToys/pull/9579 Threat `/` and `\` as root of system drive (typically `C:\`) Threat `~` as user home directory `%USERPROFILE%` <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [ ] Closes: #xxx - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <img width="591" height="356" alt="image" src="https://github.com/user-attachments/assets/9c1f196a-bd4d-428c-a4e6-af9f269acd1f" /> <img width="591" height="356" alt="image" src="https://github.com/user-attachments/assets/4295ebca-f12b-43b0-b3d0-c130b6faf419" /> <img width="591" height="356" alt="image" src="https://github.com/user-attachments/assets/87748864-e250-4141-b366-29b45d58edcf" /> <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested search starting with `~` `/` `\` - Tested UNC network path starting with `\\...` and `//...`
This commit is contained in:
parent
911989bac1
commit
ab76dd1255
@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CmdPal.Ext.Shell.Helpers;
|
||||
@ -15,6 +16,8 @@ namespace Microsoft.CmdPal.Ext.Shell;
|
||||
|
||||
internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDisposable
|
||||
{
|
||||
private static readonly char[] _systemDirectoryRoots = ['\\', '/'];
|
||||
|
||||
private readonly Action<string>? _addToHistory;
|
||||
private CancellationTokenSource? _cancellationTokenSource;
|
||||
private Task? _currentUpdateTask;
|
||||
@ -80,8 +83,8 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var searchText = query.Trim();
|
||||
var expanded = Environment.ExpandEnvironmentVariables(searchText);
|
||||
searchText = expanded;
|
||||
Expand(ref searchText);
|
||||
|
||||
if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText))
|
||||
{
|
||||
Command = null;
|
||||
@ -184,8 +187,8 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
|
||||
internal static bool SuppressFileFallbackIf(string query)
|
||||
{
|
||||
var searchText = query.Trim();
|
||||
var expanded = Environment.ExpandEnvironmentVariables(searchText);
|
||||
searchText = expanded;
|
||||
Expand(ref searchText);
|
||||
|
||||
if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText))
|
||||
{
|
||||
return false;
|
||||
@ -197,4 +200,57 @@ internal sealed partial class FallbackExecuteItem : FallbackCommandItem, IDispos
|
||||
|
||||
return exeExists || pathIsDir;
|
||||
}
|
||||
|
||||
private static void Expand(ref string searchText)
|
||||
{
|
||||
if (searchText.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var singleCharQuery = searchText.Length == 1;
|
||||
|
||||
searchText = Environment.ExpandEnvironmentVariables(searchText);
|
||||
|
||||
if (!TryExpandHome(ref searchText))
|
||||
{
|
||||
TryExpandRoot(ref searchText);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryExpandHome(ref string searchText)
|
||||
{
|
||||
if (searchText[0] == '~')
|
||||
{
|
||||
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
|
||||
if (searchText.Length == 1)
|
||||
{
|
||||
searchText = home;
|
||||
}
|
||||
else if (_systemDirectoryRoots.Contains(searchText[1]))
|
||||
{
|
||||
searchText = Path.Combine(home, searchText[2..]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryExpandRoot(ref string searchText)
|
||||
{
|
||||
if (_systemDirectoryRoots.Contains(searchText[0]) && (searchText.Length == 1 || !_systemDirectoryRoots.Contains(searchText[1])))
|
||||
{
|
||||
var root = Path.GetPathRoot(Environment.SystemDirectory);
|
||||
if (root != null)
|
||||
{
|
||||
searchText = searchText.Length == 1 ? root : Path.Combine(root, searchText[1..]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user