IntelliTect.PowerShellRestore.psm1



function script:Get-HistoryCsvHeader() {
    $historyHeader = @()
    $historyHeader += '#TYPE Microsoft.PowerShell.Commands.HistoryInfo'
    $historyHeader += '"Id","CommandLine","ExecutionStatus","StartExecutionTime","EndExecutionTime"'
    return $historyHeader.Clone();
}

function script:Get-PowerShellHistoryFileName {
    $currentTabTitle = $null; 
    if(Test-path variable:psise) {
        $currentTabTitle = ".$($psise.CurrentPowerShellTab.DisplayName)"
    }
    return ([io.path]::ChangeExtension( $profile , "$currentTabTitle.CommandHistory.csv"))
}


function Import-PowerShellHistory {
<#
    .SYNOPSIS
        Imports PowerShell history from the given .csv file into the current session.
    .EXAMPLE
        Import-PowerShellHistory
    .PARAMETER HistoryLogFile
        The file to import history from. This file is generated with Export-PowerShellLastCommand. Defaults to a file named after the current tab (ISE) or window name (PowerShell)
    .NOTES
        In PowerShell ISE, this does not import commands to the buffer accessed with the up-arrow key. To access these imported commands, type # and press tab, or run Get-History
#>


    [CmdletBinding()]
    param(
        [string] $historyLogFile = (Get-PowerShellHistoryFileName),
        [switch] $passthru
    )
    # See http://jamesone111.wordpress.com/2012/01/28/adding-persistent-history-to-powershell/ to save history across sessions
    # For more history stuff check out http://orsontyrell.blogspot.ca/2013/11/true-powershell-command-history.html
    Write-Host "PowerShellRestore: Restoring history: $historyLogFile"
    $MaximumHistoryCount = 2048;
    $truncateLogLines = 1000
    if (Test-Path $historyLogFile) {
        #TODO: Change so that Select -Unique excludes the ID number and DateTime stamps which currently makes all items unique.
        $csvImport = Import-Csv $historyLogFile
        if($csvImport -and $csvImport.Count -gt 0) {
            $history = $csvImport[-([math]::Min($csvImport.Length, $truncateLogLines))..-1]
            # $history += $historyLogFileContents[-([math]::Min($historyLogFileContents.Length, $truncateLogLines))..-1] | where {$_ -match '^"\d+"'} | select -Unique
            $history | Add-History -Passthru:$passthru # -errorAction SilentlyContinue
        }
    }
}

Function Export-PowerShellLastCommand {
<#
    .SYNOPSIS
        Appends the last run command in the current session to the given .csv file.
    .EXAMPLE
        Export-PowerShellLastCommand
    .PARAMETER HistoryLogFile
        The file to export history to. This file is consumed by Import-PowerShellHistory. Defaults to a file named after the current tab (ISE) or window name (PowerShell)
#>


    [CmdletBinding()]
    param(
        [string] $historyLogFile = (Get-PowerShellHistoryFileName)
    )

    [int] $id = 0;
    $history = @(get-history -count 2);
    if($history)
    {
        if($history.Count -eq 2) {
            if($history[0].CommandLine -ne $history[1].CommandLine) {
                #Save the last command if it was different from the previous one.
                $history[1] | Export-Csv $historyLogFile -append -confirm:$false
                $id = $history[1].Id+1
            }
        }
        elseif($history.Count -eq 1) {
            $history[0] | Export-Csv $historyLogFile -append -confirm:$false
            $id = $history[0].Id+1
        }
    }
    return $id
}




Function script:Get-WorkingDirectoryLogFileName {
    return ([io.path]::ChangeExtension( $profile , "$($psise.CurrentPowerShellTab.DisplayName).WorkingDirectory.txt"))
}

$script:lastSavedPath = $null
Function Export-PowerShellISEWorkingDirectory {
<#
    .SYNOPSIS
        Saves the given path to the given file if it has changed since last save. Only works in PowerShell ISE.
    .EXAMPLE
        Export-PowerShellISEWorkingDirectory
    .PARAMETER WorkingDirectoryLogFile
        The file to export the working directory to. Defaults to a file named after the current tab.
    .PARAMETER Path
        The path to export to the file. Defaults to $pwd
#>


    [CmdletBinding()]
    param(
        [string] $workingDirectoryLogFile = $null,
        [string] $Path = $pwd.Path
    )
    
    if (Test-Path variable:psise) {
        if ($script:lastSavedPath -ne $Path){
            if (!$workingDirectoryLogFile){
                $workingDirectoryLogFile = Get-WorkingDirectoryLogFileName
            }
            $Path > $workingDirectoryLogFile
            $script:lastSavedPath = $Path
        }
    }
}

Function Import-PowerShellISEWorkingDirectory {
<#
    .SYNOPSIS
        Sets the working directory to the path contained in the given file. Only works in PowerShell ISE.
    .EXAMPLE
        Import-PowerShellISEWorkingDirectory
    .PARAMETER WorkingDirectoryLogFile
        The file to import the working directory from. Defaults to a file named after the current tab.
#>


    [CmdletBinding()]
    param(
        [string] $workingDirectoryLogFile
    )
    
    if (Test-Path variable:psise) {
        if (!$workingDirectoryLogFile){
            $workingDirectoryLogFile = Get-WorkingDirectoryLogFileName
        }
    
        if (Test-Path $workingDirectoryLogFile){
            $path = Get-Content $workingDirectoryLogFile
            Set-Location $path
            $script:lastSavedPath = $path
        }
    }
}


Function Install-PowerShellRestore {
<#
    .SYNOPSIS
        Imports the last saved history and working directory, and injects commands into Prompt to automatically save these for future sessions.
    .EXAMPLE
        Install-PowerShellRestore
    .PARAMETER WorkingDirectoryLogFile
        The file to import the working directory from. Defaults to a file named after the current tab.
    .NOTES
        If you are running this command in your profile, and you have a custom prompt function, make sure to run this after your custom prompt has been defined.
 
        This function adds the following two lines to the top of your prompt:
        Export-PowerShellISEWorkingDirectory
        $historyId = Export-PowerShellLastCommand
#>


    try {
        Import-PowerShellHistory
        Import-PowerShellISEWorkingDirectory 
    }
    catch {
        Write-Error $_
        Write-Host "Error restoring state: $_"
    }


    Invoke-Expression -Command @"
Function global:Prompt {
    Export-PowerShellISEWorkingDirectory
    `$historyId = Export-PowerShellLastCommand
 
    $((Get-Command 'Prompt').Definition)
}
"@


}