From eebb45ef07343f4e989f028603afcd2ba13d8f7a Mon Sep 17 00:00:00 2001 From: Jan De Dobbeleer Date: Mon, 20 May 2024 19:59:39 +0200 Subject: [PATCH] fix(iterm): initialize prompt mark correctly for all supported shells --- src/ansi/ansi_writer.go | 1 - src/ansi/iterm.go | 21 ++++++++++++++++++++- src/cli/init.go | 2 ++ src/engine/prompt.go | 2 +- src/shell/init.go | 11 +++++++++++ src/shell/scripts/omp.fish | 10 ++++++++++ 6 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/ansi/ansi_writer.go b/src/ansi/ansi_writer.go index a6b38b56..13522a38 100644 --- a/src/ansi/ansi_writer.go +++ b/src/ansi/ansi_writer.go @@ -181,7 +181,6 @@ func (w *Writer) Init(shellName string) { w.osc99 = "\x1b]9;9;%s\x1b\\" w.osc7 = "\x1b]7;file://%s/%s\x1b\\" w.osc51 = "\x1b]51;A%s@%s:%s\x1b\\" - w.iTermPromptMark = "$(iterm2_prompt_mark)" w.iTermCurrentDir = "\x1b]1337;CurrentDir=%s\x07" w.iTermRemoteHost = "\x1b]1337;RemoteHost=%s@%s\x07" } diff --git a/src/ansi/iterm.go b/src/ansi/iterm.go index 6b013319..d2f692a4 100644 --- a/src/ansi/iterm.go +++ b/src/ansi/iterm.go @@ -2,7 +2,10 @@ package ansi import ( "fmt" + "slices" "strings" + + "github.com/jandedobbeleer/oh-my-posh/src/shell" ) type iTermFeature string @@ -15,11 +18,27 @@ const ( type ITermFeatures []iTermFeature -func (w *Writer) RenderItermFeatures(features ITermFeatures, pwd, user, host string) string { +func (f ITermFeatures) Contains(feature iTermFeature) bool { + for _, item := range f { + if item == feature { + return true + } + } + + return false +} + +func (w *Writer) RenderItermFeatures(features ITermFeatures, sh, pwd, user, host string) string { + supportedShells := []string{shell.BASH, shell.ZSH} + var result strings.Builder for _, feature := range features { switch feature { case PromptMark: + if !slices.Contains(supportedShells, sh) { + continue + } + result.WriteString(w.iTermPromptMark) case CurrentDir: result.WriteString(fmt.Sprintf(w.iTermCurrentDir, pwd)) diff --git a/src/cli/init.go b/src/cli/init.go index 9ff287b1..75689ff0 100644 --- a/src/cli/init.go +++ b/src/cli/init.go @@ -3,6 +3,7 @@ package cli import ( "fmt" + "github.com/jandedobbeleer/oh-my-posh/src/ansi" "github.com/jandedobbeleer/oh-my-posh/src/engine" "github.com/jandedobbeleer/oh-my-posh/src/platform" "github.com/jandedobbeleer/oh-my-posh/src/shell" @@ -71,6 +72,7 @@ func runInit(shellName string) { shell.ErrorLine = cfg.ErrorLine != nil || cfg.ValidLine != nil shell.Tooltips = len(cfg.Tooltips) > 0 shell.ShellIntegration = cfg.ShellIntegration + shell.PromptMark = shellName == shell.FISH && cfg.ITermFeatures != nil && cfg.ITermFeatures.Contains(ansi.PromptMark) for i, block := range cfg.Blocks { // only fetch cursor position when relevant diff --git a/src/engine/prompt.go b/src/engine/prompt.go index 7fdfb406..30e098dd 100644 --- a/src/engine/prompt.go +++ b/src/engine/prompt.go @@ -70,7 +70,7 @@ func (e *Engine) Primary() string { if e.Config.ITermFeatures != nil && e.isIterm() { host, _ := e.Env.Host() - e.write(e.Writer.RenderItermFeatures(e.Config.ITermFeatures, e.Env.Pwd(), e.Env.User(), host)) + e.write(e.Writer.RenderItermFeatures(e.Config.ITermFeatures, e.Env.Shell(), e.Env.Pwd(), e.Env.User(), host)) } if e.Config.ShellIntegration && e.Config.TransientPrompt == nil { diff --git a/src/shell/init.go b/src/shell/init.go index 14bfe60b..df74910e 100644 --- a/src/shell/init.go +++ b/src/shell/init.go @@ -52,6 +52,7 @@ var ( ShellIntegration bool RPrompt bool CursorPositioning bool + PromptMark bool ) func getExecutablePath(env platform.Environment) (string, error) { @@ -207,9 +208,18 @@ func PrintInit(env platform.Environment) string { if env.Flags().Manual { return "false" } + return strconv.FormatBool(setting) } + promptMark := func() string { + if PromptMark { + return "iterm2_prompt_mark" + } + + return "" + } + shell := env.Flags().Shell configFile := env.Flags().Config @@ -273,6 +283,7 @@ func PrintInit(env platform.Environment) string { "::CURSOR::", strconv.FormatBool(CursorPositioning), "::UPGRADE::", strconv.FormatBool(hasNotice), "::UPGRADENOTICE::", notice, + "::PROMPT_MARK::", promptMark(), ).Replace(script) } diff --git a/src/shell/scripts/omp.fish b/src/shell/scripts/omp.fish index 925e304c..6b795fb3 100644 --- a/src/shell/scripts/omp.fish +++ b/src/shell/scripts/omp.fish @@ -23,16 +23,19 @@ function fish_prompt ::OMP:: print transient --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --no-status=$omp_no_exit_code return end + set --global omp_status_cache $omp_status_cache_temp set --global omp_pipestatus_cache $omp_pipestatus_cache_temp set --global omp_stack_count (count $dirstack) set --global omp_duration "$CMD_DURATION$cmd_duration" set --global omp_no_exit_code false + # check if variable set, < 3.2 case if set --query omp_lastcommand; and test "$omp_lastcommand" = "" set omp_duration 0 set omp_no_exit_code true end + # works with fish >=3.2 if set --query omp_last_status_generation; and test "$omp_last_status_generation" = "$status_generation" set omp_duration 0 @@ -41,16 +44,23 @@ function fish_prompt # first execution - $status_generation is 0, $omp_last_status_generation is empty set omp_no_exit_code true end + if set --query status_generation set --global --export omp_last_status_generation $status_generation end + set_poshcontext + # validate if the user cleared the screen set --local omp_cleared false set --local last_command (history search --max 1) + if test "$last_command" = "clear" set omp_cleared true end + + ::PROMPT_MARK:: + ::OMP:: print primary --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --cleared=$omp_cleared --no-status=$omp_no_exit_code end