refactor: separate shell init

This commit is contained in:
Jan De Dobbeleer 2022-03-22 07:41:36 +01:00 committed by Jan De Dobbeleer
parent c1bdd735be
commit 3c0c350564
20 changed files with 82 additions and 74 deletions

View file

@ -10,6 +10,7 @@ import (
"oh-my-posh/console"
"oh-my-posh/engine"
"oh-my-posh/environment"
"oh-my-posh/shell"
"github.com/spf13/cobra"
)
@ -44,7 +45,7 @@ You can tweak the output by using additional flags:
Version: cliVersion,
CmdFlags: &environment.Flags{
Config: config,
Shell: "shell",
Shell: shell.PLAIN,
},
}
env.Init(false)
@ -55,7 +56,7 @@ You can tweak the output by using additional flags:
writerColors := cfg.MakeColors(env)
writer := &color.AnsiWriter{
Ansi: ansi,
TerminalBackground: engine.GetConsoleBackgroundColor(env, cfg.TerminalBackground),
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
AnsiColors: writerColors,
}
consoleTitle := &console.Title{

View file

@ -10,6 +10,7 @@ import (
"oh-my-posh/console"
"oh-my-posh/engine"
"oh-my-posh/environment"
"oh-my-posh/shell"
"github.com/spf13/cobra"
)
@ -34,7 +35,7 @@ var debugCmd = &cobra.Command{
writerColors := cfg.MakeColors(env)
writer := &color.AnsiWriter{
Ansi: ansi,
TerminalBackground: engine.GetConsoleBackgroundColor(env, cfg.TerminalBackground),
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
AnsiColors: writerColors,
}
consoleTitle := &console.Title{

View file

@ -6,8 +6,8 @@ package cli
import (
"fmt"
"oh-my-posh/engine"
"oh-my-posh/environment"
"oh-my-posh/shell"
"github.com/spf13/cobra"
)
@ -41,21 +41,21 @@ func init() { // nolint:gochecknoinits
promptCmd.AddCommand(initCmd)
}
func runInit(shell string) {
func runInit(shellName string) {
env := &environment.ShellEnvironment{
Version: cliVersion,
CmdFlags: &environment.Flags{
Shell: shell,
Shell: shellName,
Config: config,
},
}
env.Init(false)
defer env.Close()
if print {
init := engine.PrintShellInit(env)
init := shell.PrintInit(env)
fmt.Print(init)
return
}
init := engine.InitShell(env)
init := shell.Init(env)
fmt.Print(init)
}

View file

@ -10,6 +10,7 @@ import (
"oh-my-posh/console"
"oh-my-posh/engine"
"oh-my-posh/environment"
"oh-my-posh/shell"
"github.com/spf13/cobra"
)
@ -55,7 +56,7 @@ var printCmd = &cobra.Command{
StackCount: stackCount,
TerminalWidth: terminalWidth,
Eval: eval,
Shell: shell,
Shell: shellName,
},
}
env.Init(false)
@ -70,7 +71,7 @@ var printCmd = &cobra.Command{
writerColors := cfg.MakeColors(env)
writer = &color.AnsiWriter{
Ansi: ansi,
TerminalBackground: engine.GetConsoleBackgroundColor(env, cfg.TerminalBackground),
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
AnsiColors: writerColors,
}
}
@ -113,7 +114,7 @@ var printCmd = &cobra.Command{
func init() { // nolint:gochecknoinits
printCmd.Flags().StringVar(&pwd, "pwd", "", "current working directory")
printCmd.Flags().StringVar(&pswd, "pswd", "", "current working directory (according to pwsh)")
printCmd.Flags().StringVar(&shell, "shell", "", "the shell to print for")
printCmd.Flags().StringVar(&shellName, "shell", "", "the shell to print for")
printCmd.Flags().IntVarP(&exitCode, "error", "e", 0, "last exit code")
printCmd.Flags().Float64Var(&timing, "execution-time", 0, "timing of the last command")
printCmd.Flags().IntVarP(&stackCount, "stack-count", "s", 0, "number of locations on the stack")

View file

@ -23,7 +23,7 @@ experience, regardless of where you are. For a detailed guide
on getting started, have a look at the docs at https://ohmyposh.dev`,
Run: func(cmd *cobra.Command, args []string) {
if initialize {
runInit(shell)
runInit(shellName)
return
}
if displayVersion {
@ -44,7 +44,7 @@ func Execute(version string) {
// Backwards compatibility
var (
shell string
shellName string
initialize bool
)
@ -52,5 +52,5 @@ func init() { // nolint:gochecknoinits
rootCmd.PersistentFlags().StringVarP(&config, "config", "c", "", "config (required)")
rootCmd.Flags().BoolVarP(&initialize, "init", "i", false, "init (deprecated)")
rootCmd.Flags().BoolVar(&displayVersion, "version", false, "version")
rootCmd.Flags().StringVarP(&shell, "shell", "s", "", "shell (deprecated)")
rootCmd.Flags().StringVarP(&shellName, "shell", "s", "", "shell (deprecated)")
}

View file

@ -3,14 +3,11 @@ package color
import (
"fmt"
"oh-my-posh/regex"
"oh-my-posh/shell"
"strings"
)
const (
zsh = "zsh"
bash = "bash"
pwsh = "pwsh"
AnsiRegex = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))"
)
@ -48,10 +45,10 @@ type shellKeyWordReplacement struct {
replacement string
}
func (a *Ansi) Init(shell string) {
a.shell = shell
switch shell {
case zsh:
func (a *Ansi) Init(shellName string) {
a.shell = shellName
switch shellName {
case shell.ZSH:
a.format = "%%{%s%%}"
a.linechange = "%%{\x1b[%d%s%%}"
a.right = "%%{\x1b[%dC%%}"
@ -78,7 +75,7 @@ func (a *Ansi) Init(shell string) {
a.strikethrough = "%%{\x1b[9m%%}%s%%{\x1b[29m%%}"
// escape double quotes and variable expansion
a.shellReservedKeywords = append(a.shellReservedKeywords, shellKeyWordReplacement{"\\", "\\\\"}, shellKeyWordReplacement{"%", "%%"})
case bash:
case shell.BASH:
a.format = "\\[%s\\]"
a.linechange = "\\[\x1b[%d%s\\]"
a.right = "\\[\x1b[%dC\\]"

View file

@ -1,6 +1,7 @@
package color
import (
"oh-my-posh/shell"
"testing"
"github.com/stretchr/testify/assert"
@ -12,9 +13,9 @@ func TestGenerateHyperlinkNoUrl(t *testing.T) {
ShellName string
Expected string
}{
{Text: "sample text with no url", ShellName: zsh, Expected: "sample text with no url"},
{Text: "sample text with no url", ShellName: pwsh, Expected: "sample text with no url"},
{Text: "sample text with no url", ShellName: bash, Expected: "sample text with no url"},
{Text: "sample text with no url", ShellName: shell.ZSH, Expected: "sample text with no url"},
{Text: "sample text with no url", ShellName: shell.PWSH, Expected: "sample text with no url"},
{Text: "sample text with no url", ShellName: shell.BASH, Expected: "sample text with no url"},
}
for _, tc := range cases {
a := Ansi{}
@ -30,9 +31,9 @@ func TestGenerateHyperlinkWithUrl(t *testing.T) {
ShellName string
Expected string
}{
{Text: "[google](http://www.google.be)", ShellName: zsh, Expected: "%{\x1b]8;;http://www.google.be\x1b\\%}google%{\x1b]8;;\x1b\\%}"},
{Text: "[google](http://www.google.be)", ShellName: pwsh, Expected: "\x1b]8;;http://www.google.be\x1b\\google\x1b]8;;\x1b\\"},
{Text: "[google](http://www.google.be)", ShellName: bash, Expected: "\\[\x1b]8;;http://www.google.be\x1b\\\\\\]google\\[\x1b]8;;\x1b\\\\\\]"},
{Text: "[google](http://www.google.be)", ShellName: shell.ZSH, Expected: "%{\x1b]8;;http://www.google.be\x1b\\%}google%{\x1b]8;;\x1b\\%}"},
{Text: "[google](http://www.google.be)", ShellName: shell.PWSH, Expected: "\x1b]8;;http://www.google.be\x1b\\google\x1b]8;;\x1b\\"},
{Text: "[google](http://www.google.be)", ShellName: shell.BASH, Expected: "\\[\x1b]8;;http://www.google.be\x1b\\\\\\]google\\[\x1b]8;;\x1b\\\\\\]"},
}
for _, tc := range cases {
a := Ansi{}
@ -48,9 +49,9 @@ func TestGenerateHyperlinkWithUrlNoName(t *testing.T) {
ShellName string
Expected string
}{
{Text: "[](http://www.google.be)", ShellName: zsh, Expected: "[](http://www.google.be)"},
{Text: "[](http://www.google.be)", ShellName: pwsh, Expected: "[](http://www.google.be)"},
{Text: "[](http://www.google.be)", ShellName: bash, Expected: "[](http://www.google.be)"},
{Text: "[](http://www.google.be)", ShellName: shell.ZSH, Expected: "[](http://www.google.be)"},
{Text: "[](http://www.google.be)", ShellName: shell.PWSH, Expected: "[](http://www.google.be)"},
{Text: "[](http://www.google.be)", ShellName: shell.BASH, Expected: "[](http://www.google.be)"},
}
for _, tc := range cases {
a := Ansi{}

View file

@ -3,6 +3,7 @@ package engine
import (
"oh-my-posh/color"
"oh-my-posh/environment"
"oh-my-posh/shell"
"sync"
"time"
)
@ -51,10 +52,10 @@ func (b *Block) init(env environment.Environment, writer color.Writer, ansi *col
func (b *Block) initPlain(env environment.Environment, config *Config) {
b.ansi = &color.Ansi{}
b.ansi.Init(plain)
b.ansi.Init(shell.PLAIN)
b.writer = &color.AnsiWriter{
Ansi: b.ansi,
TerminalBackground: GetConsoleBackgroundColor(env, config.TerminalBackground),
TerminalBackground: shell.ConsoleBackgroundColor(env, config.TerminalBackground),
AnsiColors: config.MakeColors(env),
}
b.env = env

View file

@ -5,6 +5,7 @@ import (
"oh-my-posh/color"
"oh-my-posh/console"
"oh-my-posh/environment"
"oh-my-posh/shell"
"oh-my-posh/template"
"strings"
"time"
@ -105,7 +106,7 @@ func (e *Engine) shouldFill(block *Block, length int) (string, bool) {
func (e *Engine) renderBlock(block *Block) {
// when in bash, for rprompt blocks we need to write plain
// and wrap in escaped mode or the prompt will not render correctly
if block.Type == RPrompt && e.Env.Shell() == bash {
if block.Type == RPrompt && e.Env.Shell() == shell.BASH {
block.initPlain(e.Env, e.Config)
} else {
block.init(e.Env, e.Writer, e.Ansi)
@ -145,7 +146,7 @@ func (e *Engine) renderBlock(block *Block) {
case RPrompt:
text, length := block.renderSegments()
e.rpromptLength = length
if e.Env.Shell() == bash {
if e.Env.Shell() == shell.BASH {
text = e.Ansi.FormatText(text)
}
e.rprompt = text
@ -154,7 +155,7 @@ func (e *Engine) renderBlock(block *Block) {
// If this doesn't happen, the portion after the prompt gets colored in the background
// color of the line above the new input line. Clearing the line fixes this,
// but can hopefully one day be removed when this is resolved natively.
if e.Env.Shell() == pwsh || e.Env.Shell() == powershell5 {
if e.Env.Shell() == shell.PWSH || e.Env.Shell() == shell.PWSH5 {
e.writeANSI(e.Ansi.ClearAfter())
}
}
@ -205,7 +206,7 @@ func (e *Engine) PrintDebug(version string) string {
func (e *Engine) print() string {
switch e.Env.Shell() {
case zsh:
case shell.ZSH:
if !e.Env.Flags().Eval {
break
}
@ -213,7 +214,7 @@ func (e *Engine) print() string {
prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.string(), "\"", "\"\""))
prompt += fmt.Sprintf("\nRPROMPT=\"%s\"", e.rprompt)
return prompt
case pwsh, powershell5, bash, plain:
case shell.PWSH, shell.PWSH5, shell.BASH, shell.PLAIN:
if e.rprompt == "" || !e.canWriteRPrompt() || e.Plain {
break
}
@ -252,11 +253,11 @@ func (e *Engine) PrintTooltip(tip string) string {
Segments: []*Segment{tooltip},
}
switch e.Env.Shell() {
case zsh, winCMD:
case shell.ZSH, shell.CMD:
block.init(e.Env, e.Writer, e.Ansi)
text, _ := block.renderSegments()
return text
case pwsh, powershell5:
case shell.PWSH, shell.PWSH5:
block.initPlain(e.Env, e.Config)
text, length := block.renderSegments()
e.write(e.Ansi.ClearAfter())
@ -321,7 +322,7 @@ func (e *Engine) PrintExtraPrompt(promptType ExtraPromptType) string {
e.Writer.SetColors(prompt.Background, prompt.Foreground)
e.Writer.Write(prompt.Background, prompt.Foreground, promptText)
switch e.Env.Shell() {
case zsh:
case shell.ZSH:
// escape double quotes contained in the prompt
str, _ := e.Writer.String()
if promptType == Transient {
@ -331,7 +332,7 @@ func (e *Engine) PrintExtraPrompt(promptType ExtraPromptType) string {
return prompt
}
return str
case pwsh, powershell5, winCMD, bash:
case shell.PWSH, shell.PWSH5, shell.CMD, shell.BASH:
str, _ := e.Writer.String()
return str
}

View file

@ -6,6 +6,7 @@ import (
"oh-my-posh/console"
"oh-my-posh/environment"
"oh-my-posh/mock"
"oh-my-posh/shell"
"testing"
"github.com/stretchr/testify/assert"
@ -61,7 +62,7 @@ func engineRender() {
writerColors := cfg.MakeColors(env)
writer := &color.AnsiWriter{
Ansi: ansi,
TerminalBackground: GetConsoleBackgroundColor(env, cfg.TerminalBackground),
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
AnsiColors: writerColors,
}
consoleTitle := &console.Title{

View file

@ -3,6 +3,7 @@ package engine
import (
"io/ioutil"
"oh-my-posh/color"
"oh-my-posh/shell"
"os"
"testing"
@ -17,7 +18,7 @@ func runImageTest(content string) error {
}
defer os.Remove(file.Name())
ansi := &color.Ansi{}
ansi.Init(plain)
ansi.Init(shell.PLAIN)
image := &ImageRenderer{
AnsiString: content,
Ansi: ansi,

View file

@ -246,7 +246,7 @@ func (env *ShellEnvironment) resolveConfigPath() {
}
// Cygwin path always needs the full path as we're on Windows but not really.
// Doing filepath actions will convert it to a Windows path and break the init script.
if env.Platform() == WindowsPlatform && env.Shell() == "bash" {
if env.Platform() == WindowsPlatform && env.Shell() == "constants.BASH" {
return
}
configFile := env.CmdFlags.Config

11
src/shell/constants.go Normal file
View file

@ -0,0 +1,11 @@
package shell
const (
ZSH = "zsh"
BASH = "bash"
PWSH = "pwsh"
FISH = "fish"
PWSH5 = "powershell"
CMD = "cmd"
PLAIN = "shell"
)

View file

@ -1,4 +1,4 @@
package engine
package shell
import (
_ "embed"
@ -10,31 +10,23 @@ import (
"strings"
)
//go:embed init/omp.ps1
//go:embed scripts/omp.ps1
var pwshInit string
//go:embed init/omp.fish
//go:embed scripts/omp.fish
var fishInit string
//go:embed init/omp.bash
//go:embed scripts/omp.bash
var bashInit string
//go:embed init/omp.zsh
//go:embed scripts/omp.zsh
var zshInit string
//go:embed init/omp.lua
//go:embed scripts/omp.lua
var cmdInit string
const (
noExe = "echo \"Unable to find Oh My Posh executable\""
zsh = "zsh"
bash = "bash"
pwsh = "pwsh"
fish = "fish"
powershell5 = "powershell"
winCMD = "cmd"
plain = "shell"
)
func getExecutablePath(env environment.Environment) (string, error) {
@ -47,7 +39,7 @@ func getExecutablePath(env environment.Environment) (string, error) {
// PowerShell knows how to resolve both, so we can swap this without any issue.
executable = strings.ReplaceAll(executable, "\\", "/")
switch env.Flags().Shell {
case bash, zsh:
case BASH, ZSH:
executable = strings.ReplaceAll(executable, " ", "\\ ")
executable = strings.ReplaceAll(executable, "(", "\\(")
executable = strings.ReplaceAll(executable, ")", "\\)")
@ -55,23 +47,23 @@ func getExecutablePath(env environment.Environment) (string, error) {
return executable, nil
}
func InitShell(env environment.Environment) string {
func Init(env environment.Environment) string {
executable, err := getExecutablePath(env)
if err != nil {
return noExe
}
shell := env.Flags().Shell
switch shell {
case pwsh, powershell5:
case PWSH, PWSH5:
return fmt.Sprintf("(@(&\"%s\" prompt init %s --config=\"%s\" --print) -join \"`n\") | Invoke-Expression", executable, shell, env.Flags().Config)
case zsh, bash, fish, winCMD:
return PrintShellInit(env)
case ZSH, BASH, FISH, CMD:
return PrintInit(env)
default:
return fmt.Sprintf("echo \"No initialization script available for %s\"", shell)
}
}
func PrintShellInit(env environment.Environment) string {
func PrintInit(env environment.Environment) string {
executable, err := getExecutablePath(env)
if err != nil {
return noExe
@ -79,15 +71,15 @@ func PrintShellInit(env environment.Environment) string {
shell := env.Flags().Shell
configFile := env.Flags().Config
switch shell {
case pwsh, powershell5:
case PWSH, PWSH5:
return getShellInitScript(executable, configFile, pwshInit)
case zsh:
case ZSH:
return getShellInitScript(executable, configFile, zshInit)
case bash:
case BASH:
return getShellInitScript(executable, configFile, bashInit)
case fish:
case FISH:
return getShellInitScript(executable, configFile, fishInit)
case winCMD:
case CMD:
return getShellInitScript(executable, configFile, cmdInit)
default:
return fmt.Sprintf("echo \"No initialization script available for %s\"", shell)
@ -100,7 +92,7 @@ func getShellInitScript(executable, configFile, script string) string {
return script
}
func GetConsoleBackgroundColor(env environment.Environment, backgroundColorTemplate string) string {
func ConsoleBackgroundColor(env environment.Environment, backgroundColorTemplate string) string {
if len(backgroundColorTemplate) == 0 {
return backgroundColorTemplate
}

View file

@ -1,4 +1,4 @@
package engine
package shell
import (
"oh-my-posh/environment"
@ -25,7 +25,7 @@ func TestConsoleBackgroundColorTemplate(t *testing.T) {
"TERM_PROGRAM": tc.Term,
},
})
color := GetConsoleBackgroundColor(env, "{{ if eq \"vscode\" .Env.TERM_PROGRAM }}#123456{{end}}")
color := ConsoleBackgroundColor(env, "{{ if eq \"vscode\" .Env.TERM_PROGRAM }}#123456{{end}}")
assert.Equal(t, tc.Expected, color, tc.Case)
}
}