oh-my-posh/src/main.go

217 lines
4.6 KiB
Go
Raw Normal View History

2019-03-13 04:14:30 -07:00
package main
import (
2021-02-27 07:41:50 -08:00
_ "embed"
2019-03-13 04:14:30 -07:00
"encoding/json"
"flag"
"fmt"
2020-12-22 10:31:20 -08:00
"os"
"strings"
"time"
2019-03-13 04:14:30 -07:00
)
2020-11-22 06:02:50 -08:00
// Version number of oh-my-posh
var Version = "development"
2020-11-19 16:53:09 -08:00
2021-02-27 07:41:50 -08:00
//go:embed init/omp.ps1
var pwshInit string
//go:embed init/omp.fish
var fishInit string
//go:embed init/omp.bash
var bashInit string
//go:embed init/omp.zsh
var zshInit string
2020-12-22 10:31:20 -08:00
const (
2020-12-23 04:48:14 -08:00
noExe = "echo \"Unable to find Oh my Posh executable\""
zsh = "zsh"
bash = "bash"
pwsh = "pwsh"
fish = "fish"
powershell5 = "powershell"
2020-12-22 10:31:20 -08:00
)
2019-03-13 04:14:30 -07:00
type args struct {
2020-12-06 13:03:40 -08:00
ErrorCode *int
PrintConfig *bool
PrintShell *bool
Config *string
Shell *string
PWD *string
PSWD *string
2020-12-06 13:03:40 -08:00
Version *bool
Debug *bool
ExecutionTime *float64
Millis *bool
2020-12-17 23:59:45 -08:00
Eval *bool
2020-12-22 10:31:20 -08:00
Init *bool
PrintInit *bool
2019-03-13 04:14:30 -07:00
}
func main() {
args := &args{
ErrorCode: flag.Int(
"error",
0,
"Error code of previously executed command"),
PrintConfig: flag.Bool(
"print-config",
false,
2020-11-03 06:07:58 -08:00
"Print the current config in json format"),
PrintShell: flag.Bool(
"print-shell",
false,
"Print the current shell name"),
2019-03-13 04:14:30 -07:00
Config: flag.String(
"config",
"",
"Add the path to a configuration you wish to load"),
Shell: flag.String(
"shell",
"",
"Override the shell you are working in"),
PWD: flag.String(
"pwd",
"",
"the path you are working in"),
PSWD: flag.String(
"pswd",
"",
"the powershell path you are working in, useful when working with drives"),
2020-11-19 16:53:09 -08:00
Version: flag.Bool(
"version",
false,
"Print the current version of the binary"),
Debug: flag.Bool(
"debug",
false,
"Print debug information"),
2020-12-06 13:03:40 -08:00
ExecutionTime: flag.Float64(
"execution-time",
0,
"Execution time of the previously executed command"),
Millis: flag.Bool(
"millis",
false,
"Get the current time in milliseconds"),
2020-12-17 23:59:45 -08:00
Eval: flag.Bool(
"eval",
false,
"Run in eval mode"),
2020-12-22 10:31:20 -08:00
Init: flag.Bool(
"init",
false,
"Initialize the shell"),
PrintInit: flag.Bool(
"print-init",
false,
"Print the shell initialization script"),
2019-03-13 04:14:30 -07:00
}
flag.Parse()
env := &environment{}
env.init(args)
if *args.Millis {
fmt.Print(time.Now().UnixNano() / 1000000)
return
}
2020-12-22 10:31:20 -08:00
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
}
2019-03-13 04:14:30 -07:00
settings := GetSettings(env)
if *args.PrintConfig {
theme, _ := json.MarshalIndent(settings, "", " ")
fmt.Println(string(theme))
return
}
2020-11-03 06:07:58 -08:00
if *args.PrintShell {
fmt.Println(env.getShellName())
return
}
2020-11-19 16:53:09 -08:00
if *args.Version {
fmt.Println(Version)
2020-11-19 16:53:09 -08:00
return
}
2020-12-26 10:51:21 -08:00
formats := &ansiFormats{}
2020-12-27 05:59:40 -08:00
formats.init(env.getShellName())
2020-12-17 23:59:45 -08:00
renderer := &AnsiRenderer{
2020-12-26 10:51:21 -08:00
formats: formats,
2020-12-17 23:59:45 -08:00
}
colorer := &AnsiColor{
formats: formats,
terminalBackground: settings.TerminalBackground,
2020-12-17 23:59:45 -08:00
}
2020-12-26 10:51:21 -08:00
title := &consoleTitle{
2019-03-13 04:14:30 -07:00
env: env,
2020-12-26 10:51:21 -08:00
settings: settings,
formats: formats,
}
engine := &engine{
settings: settings,
env: env,
color: colorer,
renderer: renderer,
consoleTitle: title,
2019-03-13 04:14:30 -07:00
}
if *args.Debug {
engine.debug()
2020-12-29 00:13:56 -08:00
return
}
2020-12-29 00:13:56 -08:00
engine.render()
2019-03-13 04:14:30 -07:00
}
2020-12-22 10:31:20 -08:00
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)
2020-12-23 04:48:14 -08:00
case zsh, bash, fish:
2020-12-23 04:00:50 -08:00
return printShellInit(shell, config)
2020-12-22 10:31:20 -08:00
default:
return fmt.Sprintf("echo \"No initialization script available for %s\"", shell)
}
}
func printShellInit(shell, config string) string {
executable, err := os.Executable()
2020-12-29 10:54:04 -08:00
// On Windows, it fails when the excutable is called in MSYS2 for example
// which uses unix style paths to resolve the executable's location.
// PowerShell knows how to resolve both, so we can swap this without any issue.
executable = strings.ReplaceAll(executable, "\\", "/")
2020-12-22 10:31:20 -08:00
if err != nil {
return noExe
}
switch shell {
case pwsh:
2021-02-27 07:41:50 -08:00
return getShellInitScript(executable, config, pwshInit)
2020-12-23 04:00:50 -08:00
case zsh:
2021-02-27 07:41:50 -08:00
return getShellInitScript(executable, config, zshInit)
2020-12-23 04:12:10 -08:00
case bash:
2021-02-27 07:41:50 -08:00
return getShellInitScript(executable, config, bashInit)
2020-12-23 04:48:14 -08:00
case fish:
2021-02-27 07:41:50 -08:00
return getShellInitScript(executable, config, fishInit)
2020-12-22 10:31:20 -08:00
default:
return fmt.Sprintf("echo \"No initialization script available for %s\"", shell)
}
}
func getShellInitScript(executable, config, script string) string {
2021-02-27 07:41:50 -08:00
script = strings.ReplaceAll(script, "::OMP::", executable)
script = strings.ReplaceAll(script, "::CONFIG::", config)
return script
2020-12-22 10:31:20 -08:00
}