CmdPal: Add history to the new run page (#40427)

_⚠️ targets #39955_

This adds history support to the new run page.

* It'll initialize the history with the history from the run dialog, if
there is any.
* Any new commands that are run, or files/dirs that are opened will also
get added to the history
* history will persist across reboots
This commit is contained in:
Mike Griese
2025-07-23 06:51:30 -05:00
committed by GitHub
parent b5584eee76
commit 3b3df5b74f
24 changed files with 483 additions and 43 deletions

View File

@@ -7,7 +7,9 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Shell.Commands;
using Microsoft.CmdPal.Ext.Shell.Pages;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Shell.Helpers;
@@ -94,4 +96,80 @@ public class ShellListPageHelpers
}
}
}
internal static ListItem? ListItemForCommandString(string query, Action<string>? addToHistory)
{
var li = new ListItem();
var searchText = query.Trim();
var expanded = Environment.ExpandEnvironmentVariables(searchText);
searchText = expanded;
if (string.IsNullOrEmpty(searchText) || string.IsNullOrWhiteSpace(searchText))
{
return null;
}
ShellListPage.ParseExecutableAndArgs(searchText, out var exe, out var args);
var exeExists = false;
var pathIsDir = false;
var fullExePath = string.Empty;
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(200));
// Use Task.Run with timeout - this will actually timeout even if the sync operations don't respond to cancellation
var pathResolutionTask = Task.Run(
() =>
{
// Don't check cancellation token here - let the Task timeout handle it
exeExists = ShellListPageHelpers.FileExistInPath(exe, out fullExePath);
pathIsDir = Directory.Exists(expanded);
},
CancellationToken.None); // Use None here since we're handling timeout differently
// Wait for either completion or timeout
pathResolutionTask.Wait(cts.Token);
}
catch (OperationCanceledException)
{
}
if (exeExists)
{
// TODO we need to probably get rid of the settings for this provider entirely
var exeItem = ShellListPage.CreateExeItem(exe, args, fullExePath, addToHistory);
li.Command = exeItem.Command;
li.Title = exeItem.Title;
li.Subtitle = exeItem.Subtitle;
li.Icon = exeItem.Icon;
li.MoreCommands = exeItem.MoreCommands;
}
else if (pathIsDir)
{
var pathItem = new PathListItem(exe, query, addToHistory);
li.Command = pathItem.Command;
li.Title = pathItem.Title;
li.Subtitle = pathItem.Subtitle;
li.Icon = pathItem.Icon;
li.MoreCommands = pathItem.MoreCommands;
}
else if (System.Uri.TryCreate(searchText, UriKind.Absolute, out var uri))
{
li.Command = new OpenUrlWithHistoryCommand(searchText) { Result = CommandResult.Dismiss() };
li.Title = searchText;
}
else
{
return null;
}
if (li != null)
{
li.TextToSuggest = searchText;
}
return li;
}
}