From a1b2b8d67bfba3090b2f423e56441962b90e0541 Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Tue, 22 Dec 2020 19:31:20 +0100 Subject: [PATCH] feat: initialize pwsh starship style --- .github/workflows/code.yml | 4 ++ .github/workflows/release.yml | 4 ++ .gitignore | 4 +- README.md | 2 + docs/docs/contributing-segment.md | 9 +++ init/pwsh.ps1 | 66 +++++++++++++++++++ main.go | 63 ++++++++++++++++++ .../powershell/oh-my-posh/oh-my-posh.psm1 | 2 +- 8 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 init/pwsh.ps1 diff --git a/.github/workflows/code.yml b/.github/workflows/code.yml index d3bce487..45ca3d66 100644 --- a/.github/workflows/code.yml +++ b/.github/workflows/code.yml @@ -26,6 +26,10 @@ jobs: go-version: 1.15.x - name: Checkout code uses: actions/checkout@v2 + - name: Bundle init scripts + run: | + go get -u github.com/kevinburke/go-bindata/... + go-bindata -o init.go init/ - name: Golang CI uses: golangci/golangci-lint-action@v2 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 88bb73ad..bbdee0bf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,6 +66,10 @@ jobs: go-version: 1.15.x - name: Checkout code uses: actions/checkout@v2 + - name: Bundle init scripts + run: | + go get -u github.com/kevinburke/go-bindata/... + go-bindata -o init.go init/ - name: Build id: build run: go build -o ${{ matrix.ARTIFACT }} -ldflags="-X 'main.Version=${{ needs.release.outputs.version }}'" diff --git a/.gitignore b/.gitignore index a373526b..67caab3c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ *.dll *.so *.dylib +# Initialization scripts generated by https://github.com/kevinburke/go-bindata +init.go # Test binary, built with `go test -c` *.test @@ -147,4 +149,4 @@ dist # End of https://www.toptal.com/developers/gitignore/api/node,go,visualstudiocode # linux binary -/oh-my-posh3 \ No newline at end of file +/oh-my-posh3 diff --git a/README.md b/README.md index 2e07f14a..8aa6d978 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ a modern and more efficient tool was needed to suit my personal needs. * [Robby Russel][oh-my-zsh] for creating oh-my-zsh, without him this would probably not be here * [Janne Mareike Koschinski][justjanne] for providing information on how to get certain information using Go (and the amazing [README][powerline-go]) +* [Starship][starship] for creating an amazing way to initialize the prompt [release-status]: https://github.com/jandedobbeleer/oh-my-posh3/workflows/Release/badge.svg [psgallery-badge]: https://img.shields.io/powershellgallery/dt/oh-my-posh.svg @@ -69,3 +70,4 @@ using Go (and the amazing [README][powerline-go]) [oh-my-zsh]: https://github.com/robbyrussell/oh-my-zsh [justjanne]: https://github.com/justjanne [powerline-go]: https://github.com/justjanne/powerline-go +[starship]: https://github.com/starship/starship/blob/master/src/init/mod.rs diff --git a/docs/docs/contributing-segment.md b/docs/docs/contributing-segment.md index fd3b59ce..d05c1a38 100644 --- a/docs/docs/contributing-segment.md +++ b/docs/docs/contributing-segment.md @@ -70,6 +70,15 @@ New: &new{}, Even with unit tests, it's a good idea to build and validate the changes. +First, we need to package the init scripts: + +```shell +go get -u github.com/kevinburke/go-bindata/... +go-bindata -o init.go init/ +``` + +Next, build the app and validate the changes: + ```shell go build -o $GOPATH/bin/oh-my-posh ``` diff --git a/init/pwsh.ps1 b/init/pwsh.ps1 new file mode 100644 index 00000000..8debaf15 --- /dev/null +++ b/init/pwsh.ps1 @@ -0,0 +1,66 @@ +$global:PoshSettings = New-Object -TypeName PSObject -Property @{ + Theme = ""; + ShowDebug = $false +} + +if (Test-Path "::CONFIG::") { + $global:PoshSettings.Theme = Resolve-Path -Path "::CONFIG::" +} +function Set-PoshContext {} + +function Set-GitStatus { + if (Get-Command -Name "Get-GitStatus" -ErrorAction SilentlyContinue) { + $Global:GitStatus = Get-GitStatus + } +} + +[ScriptBlock]$Prompt = { + #store if the last command was successfull + $lastCommandSuccess = $? + #store the last exit code for restore + $realLASTEXITCODE = $global:LASTEXITCODE + $errorCode = 0 + Set-PoshContext + if ($lastCommandSuccess -eq $false) { + #native app exit code + if ($realLASTEXITCODE -is [int] -and $realLASTEXITCODE -gt 0) { + $errorCode = $realLASTEXITCODE + } + else { + $errorCode = 1 + } + } + + $executionTime = -1 + $history = Get-History -ErrorAction Ignore -Count 1 + if ($null -ne $history -and $null -ne $history.EndExecutionTime -and $null -ne $history.StartExecutionTime) { + $executionTime = ($history.EndExecutionTime - $history.StartExecutionTime).TotalMilliseconds + } + + $startInfo = New-Object System.Diagnostics.ProcessStartInfo + $startInfo.FileName = "::OMP::" + $config = $global:PoshSettings.Theme + $showDebug = $global:PoshSettings.ShowDebug + $cleanPWD = $PWD.ProviderPath.TrimEnd("\") + $startInfo.Arguments = "--debug=""$showDebug"" --config=""$config"" --error=$errorCode --pwd=""$cleanPWD"" --execution-time=$executionTime" + $startInfo.Environment["TERM"] = "xterm-256color" + $startInfo.CreateNoWindow = $true + $startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8 + $startInfo.RedirectStandardOutput = $true + $startInfo.UseShellExecute = $false + if ($PWD.Provider.Name -eq 'FileSystem') { + $startInfo.WorkingDirectory = $PWD.ProviderPath + } + $process = New-Object System.Diagnostics.Process + $process.StartInfo = $startInfo + $process.Start() | Out-Null + $standardOut = $process.StandardOutput.ReadToEnd() + $process.WaitForExit() + $standardOut + $global:LASTEXITCODE = $realLASTEXITCODE + #remove temp variables + Remove-Variable realLASTEXITCODE -Confirm:$false + Remove-Variable lastCommandSuccess -Confirm:$false + Set-GitStatus +} +Set-Item -Path Function:prompt -Value $Prompt -Force diff --git a/main.go b/main.go index d481a12a..a9cb6412 100644 --- a/main.go +++ b/main.go @@ -5,12 +5,18 @@ import ( "encoding/json" "flag" "fmt" + "os" + "strings" "time" ) // Version number of oh-my-posh var Version = "development" +const ( + noExe = "echo \"Unable to find Oh my Posh executable\"" +) + type args struct { ErrorCode *int PrintConfig *bool @@ -23,6 +29,8 @@ type args struct { ExecutionTime *float64 Millis *bool Eval *bool + Init *bool + PrintInit *bool } func main() { @@ -71,6 +79,14 @@ func main() { "eval", false, "Run in eval mode"), + Init: flag.Bool( + "init", + false, + "Initialize the shell"), + PrintInit: flag.Bool( + "print-init", + false, + "Print the shell initialization script"), } flag.Parse() env := &environment{ @@ -80,6 +96,16 @@ func main() { fmt.Print(time.Now().UnixNano() / 1000000) return } + if *args.Init { + init := initShell(*args.Shell, *args.Config) + fmt.Print(init) + return + } + if *args.PrintInit { + init := printShellInit(*args.Shell, *args.Config) + fmt.Print(init) + return + } settings := GetSettings(env) if *args.PrintConfig { theme, _ := json.MarshalIndent(settings, "", " ") @@ -114,3 +140,40 @@ func main() { } engine.render() } + +func initShell(shell, config string) string { + executable, err := os.Executable() + if err != nil { + return noExe + } + switch shell { + case pwsh: + return fmt.Sprintf("Invoke-Expression (@(&\"%s\" --print-init --shell pwsh --config %s) -join \"`n\")", executable, config) + default: + return fmt.Sprintf("echo \"No initialization script available for %s\"", shell) + } +} + +func printShellInit(shell, config string) string { + executable, err := os.Executable() + if err != nil { + return noExe + } + switch shell { + case pwsh: + return getShellInitScript(executable, config, "init/pwsh.ps1") + default: + return fmt.Sprintf("echo \"No initialization script available for %s\"", shell) + } +} + +func getShellInitScript(executable, config, script string) string { + data, err := Asset(script) + if err != nil { + return fmt.Sprintf("echo \"Unable to find initialization script %s\"", script) + } + init := string(data) + init = strings.ReplaceAll(init, "::OMP::", executable) + init = strings.ReplaceAll(init, "::CONFIG::", config) + return init +} diff --git a/packages/powershell/oh-my-posh/oh-my-posh.psm1 b/packages/powershell/oh-my-posh/oh-my-posh.psm1 index 0a2930fd..a212a842 100644 --- a/packages/powershell/oh-my-posh/oh-my-posh.psm1 +++ b/packages/powershell/oh-my-posh/oh-my-posh.psm1 @@ -83,7 +83,7 @@ function Set-PoshPrompt { $config = $global:PoshSettings.Theme $showDebug = $global:PoshSettings.ShowDebug $cleanPWD = $PWD.ProviderPath.TrimEnd("\") - $startInfo.Arguments = "-debug=""$showDebug"" -config=""$config"" -error=$errorCode -pwd=""$cleanPWD"" -execution-time=$executionTime" + $startInfo.Arguments = "--debug=""$showDebug"" --config=""$config"" --error=$errorCode --pwd=""$cleanPWD"" --execution-time=$executionTime" $startInfo.Environment["TERM"] = "xterm-256color" $startInfo.CreateNoWindow = $true $startInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8