PSDirectoryStack.psm1

# Define a global stack variable
if (-not (Get-Variable -Name DirectoryStack -Scope Global -ErrorAction SilentlyContinue)) {
    Set-Variable -Name DirectoryStack -Value @() -Scope Global
}

function Push-Location {
    param(
        [string]$Path
    )

    # Save the current location
    $global:DirectoryStack += (Get-Location)

    if ($Path) {
        Set-Location -Path $Path
    }
}

function Pop-Location {
    if ($global:DirectoryStack.Count -eq 0) {
        Write-Host "Directory stack is empty."
        return
    }

    # Retrieve the last location
    $lastLocation = $global:DirectoryStack[-1]

    # Remove the last location from the stack
    $global:DirectoryStack = $global:DirectoryStack[0..($global:DirectoryStack.Count - 2)]

    # Change to the last location
    Set-Location -Path $lastLocation
}

function Switch-Location {
    if ($global:DirectoryStack.Count -eq 0) {
        Write-Host "Directory stack is empty."
        return
    }

    # Retrieve the last location
    $lastLocation = $global:DirectoryStack[-1]

    # Remove the last location from the stack
    $global:DirectoryStack = $global:DirectoryStack[0..($global:DirectoryStack.Count - 2)]

    # Save the current location
    $global:DirectoryStack += (Get-Location)

    # Change to the last location
    Set-Location -Path $lastLocation
}

function Set-LocationEnhanced {
    param(
        [string]$Path
    )

    if ($Path -eq '-') {
        Switch-Location
        return
    }

    $resolvedPath = Resolve-Path $Path

    try {
        if (Test-Path -Path $Path) {
            if (Test-Path -Path $Path -PathType Leaf) {
                # If it's a file, get the parent directory
                $item = Get-Item -Path $Path -ErrorAction Stop
                Push-Location -Path $item.DirectoryName
            } else {
                # If it's a directory
                Push-Location -Path $Path
            }
        } else {
            throw
        }
    } catch {
        $parentPath = [System.IO.Path]::GetDirectoryName($Path)
        if ($parentPath -and (Test-Path -Path $parentPath)) {
            Push-Location -Path $parentPath
        } else {
            Write-Error "Path '$Path' does not exist."
        }
    }
}

# Create an alias for 'cd' to use Set-LocationEnhanced
Set-Alias -Name cd -Value Set-LocationEnhanced -Option AllScope

# Optional: Create aliases for Push-Location and Pop-Location
Set-Alias -Name pushd -Value Push-Location -Option AllScope
Set-Alias -Name popd -Value Pop-Location -Option AllScope
Set-Alias -Name switchd -Value Switch-Location -Option AllScope

# Example usage:
# cd "C:\path\to\your\file.txt"
# cd "C:\path\to\your\directory"
# cd "-"