Cool.psm1
|
# Cool.psm1 # This is the main module file for the Cool PowerShell module. # set UTF-8 encoding for input and output to ensure proper handling of Unicode characters, # which is essential for the color and icon features of the module. $OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::OutputEncoding = [Text.Encoding]::UTF8 [Console]::InputEncoding = [Text.Encoding]::UTF8 $PSDefaultParameterValues['Get-Content:Encoding'] = 'UTF8' # Import the HotKeys script first to ensure that any hotkey-related functionality is available # before loading the rest of the module's features. . (Join-Path $PSScriptRoot "HotKeys.ps1") Set-Alias -Name 'ls' -Value 'l' -Option AllScope -Force -Scope Global Set-Alias -Name 'cd' -Value 'Set-CurrentDirectory' -Option AllScope -Force -Scope Global Export-ModuleMember -Alias 'ls', 'cd' # Initialize a variable to track whether the module has been fully loaded. # This can be used to prevent certain actions from being performed before the module is ready. $script:Cool_IsLoaded = $false $script:Cool_LoadLock = [object]::new() $script:ExportedMap = @{} # To ensure that the module's command not found handler is properly chained with any existing handlers, # we store the original CommandNotFoundAction and set up a cleanup action to restore it when the module is removed. if (-not $global:Cool_Module_IsImported) { $global:Cool_OriginalCommandNotFoundAction = $ExecutionContext.InvokeCommand.CommandNotFoundAction $global:Cool_Module_IsImported = $true $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { $ExecutionContext.InvokeCommand.CommandNotFoundAction = $global:Cool_OriginalCommandNotFoundAction $global:Cool_Module_IsImported = $false } } $ExecutionContext.InvokeCommand.CommandNotFoundAction = { param($commandName, $commandEventArgs) # Ensure the module is fully loaded before handling any commands, # to avoid issues with commands being invoked before their definitions are available. if (-not $script:Cool_IsLoaded) { [System.Threading.Monitor]::Enter($script:Cool_LoadLock) try { if (-not $script:Cool_IsLoaded) { # Load all necessary components of the Cool module. . (Join-Path $PSScriptRoot "Private/Localization.ps1") . (Join-Path $PSScriptRoot "Private/Cache.ps1") . (Join-Path $PSScriptRoot "Private/ColorAndIcon.ps1") . (Join-Path $PSScriptRoot "Private/VisualWidth.ps1") . (Join-Path $PSScriptRoot "Private/Profile.ps1") . (Join-Path $PSScriptRoot "Private/Core.ps1") . (Join-Path $PSScriptRoot "Functions/ls.ps1") . (Join-Path $PSScriptRoot "Functions/cool.ps1") . (Join-Path $PSScriptRoot "Functions/cd.ps1") # Mark the module as fully loaded to prevent reinitialization. $manifestPath = Join-Path $PSScriptRoot "Cool.psd1" $manifest = Import-PowerShellDataFile -Path $manifestPath foreach ($name in ($manifest.FunctionsToExport + $manifest.AliasesToExport)) { if ($name -and $name -ne '*') { $script:ExportedMap[[string]$name] = $true } } $script:Cool_IsLoaded = $true } } finally { [System.Threading.Monitor]::Exit($script:Cool_LoadLock) } } $fullInput = Get-InputFromPSReadLine # Check if the command matches an exported function or alias from this module. # If it does, we create a script block to invoke that command and set it as the action for this event, # effectively handling the command not found scenario for commands that are actually part of this module. if ($script:ExportedMap.ContainsKey($commandName)) { $commandEventArgs.CommandScriptBlock = [scriptblock]::Create($fullInput) $commandEventArgs.StopSearch = $true } # Check if the command name corresponds to an existing directory. If it does, change to that directory. elseif (Test-Path -LiteralPath $fullInput -PathType Container) { $commandEventArgs.CommandScriptBlock = [scriptblock]::Create("Set-CurrentDirectory -LiteralPath '$fullInput'") $commandEventArgs.StopSearch = $true } elseif ($null -ne $global:Cool_OriginalCommandNotFoundAction -and -not $commandEventArgs.PSObject.Properties['Cool_Handled']) { # If the command was not handled by Cool Module, and there is an original CommandNotFoundAction # from another module or default, we call it to allow for chaining of command not found handlers. # We also add a check to prevent infinite loops in case the original handler tries to invoke a # command that also triggers Cool Module's handler. # By marking the event args with a custom property, we can detect if we've already handled this # event and avoid calling the original handler again. $commandEventArgs | Add-Member -NotePropertyName "Cool_Handled" -NotePropertyValue $true $global:Cool_OriginalCommandNotFoundAction.Invoke($commandName, $commandEventArgs) } } |