What if the run page had the same typeahead that Rundlg had?

This commit is contained in:
Mike Griese
2025-04-29 17:01:49 -05:00
parent 9cb99be4e9
commit a7cb535515
4 changed files with 175 additions and 1 deletions

View File

@@ -9,4 +9,6 @@ namespace Microsoft.CmdPal.Ext.Shell;
internal sealed class Icons
{
internal static IconInfo RunV2 { get; } = IconHelpers.FromRelativePath("Assets\\Run.svg");
internal static IconInfo Folder { get; } = new("📁");
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell;
internal sealed partial class PathListItem : ListItem
{
private readonly Lazy<IconInfo> _icon;
private readonly bool _isDirectory;
public override IIconInfo? Icon { get => _icon.Value; set => base.Icon = value; }
public PathListItem(string path)
: base(new OpenUrlCommand(path))
{
var fileName = Path.GetFileName(path);
_isDirectory = Directory.Exists(path);
if (_isDirectory)
{
path = path + "\\";
fileName = fileName + "\\";
}
Title = fileName;
Subtitle = path;
TextToSuggest = path;
MoreCommands = [
new CommandContextItem(new CopyTextCommand(path))
];
_icon = new Lazy<IconInfo>(() =>
{
var iconStream = ThumbnailHelper.GetThumbnail(path).Result;
var icon = iconStream != null ? IconInfo.FromStream(iconStream) :
_isDirectory ? Icons.Folder : Icons.RunV2;
return icon;
});
}
}

View File

@@ -0,0 +1,117 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell;
internal sealed partial class RunMainPage : DynamicListPage
{
private readonly List<ListItem> _pathItems = new();
public RunMainPage()
{
Name = "Open"; // LOC!
Title = "Run commands"; // LOC!
Icon = Icons.RunV2;
EmptyContent = new CommandItem()
{
Title = "Run commands",
Icon = Icons.RunV2,
};
}
public override void UpdateSearchText(string oldSearch, string newSearch)
{
// If the search text is the start of a path to a file (it might be a unc path), then we want to list all the files that start with that text:
// 1. Check if the search text is a valid path
// 2. If it is, then list all the files that start with that text
var searchText = newSearch.Trim();
if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText))
{
_pathItems.Clear();
RaiseItemsChanged();
return;
}
// Check if the search text is a valid path
if (Path.IsPathRooted(searchText) && Path.GetDirectoryName(searchText) is string directoryName)
{
// Check if the directory exists
if (Directory.Exists(directoryName))
{
// Get all the files in the directory that start with the search text
var files = Directory.GetFileSystemEntries(directoryName, $"{Path.GetFileName(searchText)}*");
// Create a list of commands for each file
var commands = files.Select(PathToListItem).ToList();
// Add the commands to the list
ListHelpers.InPlaceUpdateList(_pathItems, commands);
}
}
// we should also handle just drive roots, ala c:\ or d:\
else if (searchText.Length == 2 && searchText[1] == ':')
{
// Check if the drive exists
if (Directory.Exists(searchText + "\\"))
{
// Get all the files in the directory that start with the search text
var files = Directory.GetFileSystemEntries(searchText + "\\", "*");
// Create a list of commands for each file
var commands = files.Select(PathToListItem).ToList();
// Add the commands to the list
ListHelpers.InPlaceUpdateList(_pathItems, commands);
}
}
// Check if the search text is a valid UNC path
else if (searchText.StartsWith(@"\\", System.StringComparison.CurrentCultureIgnoreCase) && searchText.Contains(@"\\"))
{
// Check if the directory exists
if (Directory.Exists(searchText))
{
// Get all the files in the directory that start with the search text
var files = Directory.GetFileSystemEntries(searchText, "*");
// Create a list of commands for each file
var commands = files.Select(PathToListItem).ToList();
// Add the commands to the list
ListHelpers.InPlaceUpdateList(_pathItems, commands);
}
}
RaiseItemsChanged();
}
private ListItem PathToListItem(string path)
{
// var iconStream = ThumbnailHelper.GetThumbnail(path).Result;
// var icon = iconStream != null ? IconInfo.FromStream(iconStream) : Icons.RunV2;
// var fileName = Path.GetFileName(path);
// var isDirectory = Directory.Exists(path);
// if (isDirectory)
// {
// path = path + "\\";
// fileName = fileName + "\\";
// icon = Icons.Folder;
// }
return new PathListItem(path);
}
public override IListItem[] GetItems()
{
return _pathItems.ToArray();
}
}

View File

@@ -13,6 +13,7 @@ namespace Microsoft.CmdPal.Ext.Shell;
public partial class ShellCommandsProvider : CommandProvider
{
private readonly CommandItem _shellPageItem;
private readonly CommandItem _runMainPageItem;
private readonly SettingsManager _settingsManager = new();
private readonly FallbackCommandItem _fallbackItem;
@@ -34,9 +35,18 @@ public partial class ShellCommandsProvider : CommandProvider
new CommandContextItem(Settings.SettingsPage),
],
};
_runMainPageItem = new CommandItem(new RunMainPage())
{
Icon = Icons.RunV2,
Title = "Run 2 electric boogaloo", // LOC!
Subtitle = Resources.cmd_plugin_description,
MoreCommands = [
new CommandContextItem(Settings.SettingsPage),
],
};
}
public override ICommandItem[] TopLevelCommands() => [_shellPageItem];
public override ICommandItem[] TopLevelCommands() => [_shellPageItem, _runMainPageItem];
public override IFallbackCommandItem[]? FallbackCommands() => [_fallbackItem];
}