Functions/GenXdev.Coding.PowerShell.Modules/Search-GenXdevCmdlet.cs
// ################################################################################
// Part of PowerShell module : GenXdev.Coding.PowerShell.Modules // Original cmdlet filename : Search-GenXdevCmdlet.cs // Original author : René Vaessen / GenXdev // Version : 1.302.2025 // ################################################################################ // Copyright (c) René Vaessen / GenXdev // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ################################################################################ using System; using System.Collections; using System.Management.Automation; using System.Threading; namespace GenXdev.Coding.PowerShell.Modules { /// <summary> /// <para type="synopsis"> /// Searches for a GenXdev cmdlet and optionally opens it in an IDE for editing. /// </para> /// /// <para type="description"> /// This function searches for GenXdev cmdlets using a pattern and optionally opens /// the found cmdlet's source file in Visual Studio Code or Visual Studio for /// editing. It retrieves cmdlet information and provides keyboard shortcuts to /// quickly navigate to the function definition. /// </para> /// /// <para type="description"> /// PARAMETERS /// </para> /// /// <para type="description"> /// -CmdletName <string><br/> /// Search pattern to filter cmdlets. Supports wildcards. Default is '*' to show all cmdlets.<br/> /// - <b>Aliases</b>: Filter, CmdLet, Cmd, FunctionName, Name<br/> /// - <b>Position</b>: 0<br/> /// - <b>Default</b>: null<br/> /// </para> /// /// <para type="description"> /// -ModuleName <string[]><br/> /// GenXdev module names to search. Must match pattern starting with 'GenXdev'.<br/> /// - <b>Aliases</b>: Module, BaseModuleName, SubModuleName<br/> /// - <b>Position</b>: 1<br/> /// - <b>Default</b>: null<br/> /// </para> /// /// <para type="description"> /// -NoLocal <SwitchParameter><br/> /// Skip searching in local module paths when finding cmdlets.<br/> /// - <b>Position</b>: Named<br/> /// - <b>Default</b>: false<br/> /// </para> /// /// <para type="description"> /// -OnlyPublished <SwitchParameter><br/> /// Limit search to published module paths only.<br/> /// - <b>Position</b>: Named<br/> /// - <b>Default</b>: false<br/> /// </para> /// /// <para type="description"> /// -FromScripts <SwitchParameter><br/> /// Search in script files instead of module files.<br/> /// - <b>Position</b>: Named<br/> /// - <b>Default</b>: false<br/> /// </para> /// /// <para type="description"> /// -Code <SwitchParameter><br/> /// Open the found cmdlet in Visual Studio Code.<br/> /// - <b>Aliases</b>: c<br/> /// - <b>Position</b>: Named<br/> /// - <b>Default</b>: false<br/> /// </para> /// /// <para type="description"> /// -VisualStudio <SwitchParameter><br/> /// Open the found cmdlet in Visual Studio.<br/> /// - <b>Aliases</b>: vs<br/> /// - <b>Position</b>: Named<br/> /// - <b>Default</b>: false<br/> /// </para> /// /// <para type="description"> /// -EditCmdlet <SwitchParameter><br/> /// Also opens the file in the editor after finding the cmdlet.<br/> /// - <b>Position</b>: Named<br/> /// - <b>Default</b>: false<br/> /// </para> /// /// <example> /// <para>Example 1: Opens first matching cmdlet starting with "Get-" in Visual Studio Code</para> /// <para>Detailed explanation of the example.</para> /// <code> /// Search-GenXdevCmdlet -CmdletName "Get-*" -Code /// </code> /// </example> /// /// <example> /// <para>Example 2: Searches for Set-GitConfig cmdlet and opens it for editing</para> /// <para>Detailed explanation of the example.</para> /// <code> /// searchcmdlet "Set-GitConfig" -EditCmdlet /// </code> /// </example> /// </summary> [Cmdlet(VerbsCommon.Search, "GenXdevCmdlet")] [Alias("searchcmdlet")] [OutputType(typeof(void))] public class SearchGenXdevCmdletCommand : PSGenXdevCmdlet { /// <summary> /// Search pattern to filter cmdlets /// </summary> [Parameter( Mandatory = false, Position = 0, ValueFromRemainingArguments = false, HelpMessage = "Search pattern to filter cmdlets")] [Alias("Filter", "CmdLet", "Cmd", "FunctionName", "Name")] [SupportsWildcards()] public string CmdletName { get; set; } /// <summary> /// GenXdev module names to search /// </summary> [Parameter( Mandatory = false, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, Position = 1, HelpMessage = "GenXdev module names to search")] [ValidateNotNullOrEmpty()] [Alias("Module", "BaseModuleName", "SubModuleName")] [ValidatePattern(@"^(GenXdev|GenXde[v]\*|GenXdev(\.[\w*\[\]\?]*)+)+$")] [SupportsWildcards()] public string[] ModuleName { get; set; } /// <summary> /// Skip searching in local module paths /// </summary> [Parameter( Mandatory = false, HelpMessage = "Skip searching in local module paths")] public SwitchParameter NoLocal { get; set; } /// <summary> /// Limit search to published module paths only /// </summary> [Parameter( Mandatory = false, HelpMessage = "Limit search to published module paths only")] public SwitchParameter OnlyPublished { get; set; } /// <summary> /// Search in script files instead of module files /// </summary> [Parameter( Mandatory = false, HelpMessage = "Search in script files instead of module files")] public SwitchParameter FromScripts { get; set; } /// <summary> /// Open the found cmdlet in Visual Studio Code /// </summary> [Parameter( Mandatory = false, HelpMessage = "Open the found cmdlet in Visual Studio Code")] [Alias("c")] public SwitchParameter Code { get; set; } /// <summary> /// Open the found cmdlet in Visual Studio /// </summary> [Parameter( Mandatory = false, HelpMessage = "Open the found cmdlet in Visual Studio")] [Alias("vs")] public SwitchParameter VisualStudio { get; set; } /// <summary> /// Also opens the file in the editor after finding /// </summary> [Parameter( Mandatory = false, HelpMessage = "Also opens the file in the editor after finding")] public SwitchParameter EditCmdlet { get; set; } private PSObject cmdletInfo; private string previousClipboard; /// <summary> /// Begin processing - initialization logic /// </summary> protected override void BeginProcessing() { // Retrieve and validate the target cmdlet exists var invocationParams = CopyIdenticalParamValues("GenXdev.Helpers\\Get-GenXDevCmdlet"); invocationParams["ExactMatch"] = true; var getCmdletScript = ScriptBlock.Create("param($params) GenXdev.Helpers\\Get-GenXDevCmdlet @params | Microsoft.PowerShell.Utility\\Select-Object -First 1"); var result = getCmdletScript.Invoke(invocationParams); cmdletInfo = (PSObject)result[0]; if (cmdletInfo == null) { ThrowTerminatingError(new ErrorRecord( new Exception($"Could not find GenXdev cmdlet {CmdletName}"), "CmdletNotFound", ErrorCategory.ObjectNotFound, CmdletName)); } // Initialize core variables for processing CmdletName = (string)cmdletInfo.Properties["Name"].Value; var getClipboardScript = ScriptBlock.Create("Microsoft.PowerShell.Management\\Get-Clipboard"); var clipResult = getClipboardScript.Invoke(); previousClipboard = clipResult[0]?.ToString(); var setClipboardScript = ScriptBlock.Create("param($value) Microsoft.PowerShell.Management\\Set-Clipboard -Value $value"); setClipboardScript.Invoke(CmdletName); WriteVerbose($"Processing cmdlet: {CmdletName}"); } /// <summary> /// Process record - main cmdlet logic /// </summary> protected override void ProcessRecord() { // Open cmdlet in ide and insert prompt with keyboard shortcuts var invocationParams = CopyIdenticalParamValues("GenXdev.Coding\\Open-SourceFileInIde"); invocationParams["KeysToSend"] = new object[] { "^+f", "^a", "{DELETE}", "^v", "{ENTER}", "^{ENTER}", "^``" }; invocationParams["Path"] = cmdletInfo.Properties["ScriptFilePath"].Value; invocationParams["LineNo"] = cmdletInfo.Properties["LineNo"].Value; var openScript = ScriptBlock.Create("param($params) GenXdev.Coding\\Open-SourceFileInIde @params"); foreach (var line in openScript.Invoke(invocationParams)) { Console.WriteLine(line.ToString().Trim()); } } /// <summary> /// End processing - cleanup logic /// </summary> protected override void EndProcessing() { // Wait for ide operations to complete Thread.Sleep(3000); // Restore original clipboard content var setClipboardScript = ScriptBlock.Create("param($value) Microsoft.PowerShell.Management\\Set-Clipboard -Value $value"); setClipboardScript.Invoke(previousClipboard); if (EditCmdlet.ToBool()) { // Copy parameters for editing cmdlet function var invocationParams = CopyIdenticalParamValues("GenXdev.Coding\\Show-GenXdevCmdLetInIde"); var showScript = ScriptBlock.Create("param($params) GenXdev.Coding\\Show-GenXdevCmdLetInIde @params"); foreach (var line in showScript.Invoke(invocationParams)) { Console.WriteLine(line.ToString().Trim()); } } } } } |