mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-25 19:14:50 -08:00
parent
b103581ed6
commit
a65abd25a5
|
@ -4,8 +4,6 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/shell"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||
)
|
||||
|
||||
// BlockType type of block
|
||||
|
@ -61,15 +59,6 @@ func (b *Block) Init(env runtime.Environment) {
|
|||
b.executeSegmentLogic()
|
||||
}
|
||||
|
||||
func (b *Block) InitPlain(env runtime.Environment, config *Config) {
|
||||
terminal.Init(shell.GENERIC)
|
||||
terminal.BackgroundColor = shell.ConsoleBackgroundColor(env, config.TerminalBackground)
|
||||
terminal.Colors = config.MakeColors()
|
||||
|
||||
b.env = env
|
||||
b.executeSegmentLogic()
|
||||
}
|
||||
|
||||
func (b *Block) Enabled() bool {
|
||||
if b.Type == LineBreak {
|
||||
return true
|
||||
|
|
|
@ -73,17 +73,6 @@ func (e *Engine) canWriteRightBlock(rprompt bool) (int, bool) {
|
|||
return availableSpace, canWrite
|
||||
}
|
||||
|
||||
func (e *Engine) writeRPrompt() {
|
||||
space, OK := e.canWriteRightBlock(true)
|
||||
if !OK {
|
||||
return
|
||||
}
|
||||
e.write(terminal.SaveCursorPosition())
|
||||
e.write(strings.Repeat(" ", space))
|
||||
e.write(e.rprompt)
|
||||
e.write(terminal.RestoreCursorPosition())
|
||||
}
|
||||
|
||||
func (e *Engine) pwd() {
|
||||
// only print when supported
|
||||
sh := e.Env.Shell()
|
||||
|
@ -199,13 +188,7 @@ func (e *Engine) renderBlock(block *config.Block, cancelNewline bool) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// when in bash, for rprompt blocks we need to write plain
|
||||
// and wrap in escaped mode or the prompt will not render correctly
|
||||
if e.Env.Shell() == shell.BASH && block.Type == config.RPrompt {
|
||||
block.InitPlain(e.Env, e.Config)
|
||||
} else {
|
||||
block.Init(e.Env)
|
||||
}
|
||||
block.Init(e.Env)
|
||||
|
||||
if !block.Enabled() {
|
||||
return false
|
||||
|
|
|
@ -30,6 +30,8 @@ func (e *Engine) Primary() string {
|
|||
cycle = &e.Config.Cycle
|
||||
var cancelNewline, didRender bool
|
||||
|
||||
needsPrimaryRPrompt := e.needsPrimaryRPrompt()
|
||||
|
||||
for i, block := range e.Config.Blocks {
|
||||
// do not print a leading newline when we're at the first row and the prompt is cleared
|
||||
if i == 0 {
|
||||
|
@ -42,14 +44,7 @@ func (e *Engine) Primary() string {
|
|||
cancelNewline = !didRender
|
||||
}
|
||||
|
||||
// only render rprompt for shells where we need it from the primary prompt
|
||||
renderRPrompt := true
|
||||
switch e.Env.Shell() {
|
||||
case shell.ELVISH, shell.FISH, shell.NU, shell.XONSH, shell.CMD:
|
||||
renderRPrompt = false
|
||||
}
|
||||
|
||||
if block.Type == config.RPrompt && !renderRPrompt {
|
||||
if block.Type == config.RPrompt && !needsPrimaryRPrompt {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -84,61 +79,48 @@ func (e *Engine) Primary() string {
|
|||
if !e.Env.Flags().Eval {
|
||||
break
|
||||
}
|
||||
|
||||
// Warp doesn't support RPROMPT so we need to write it manually
|
||||
if e.isWarp() {
|
||||
e.writeRPrompt()
|
||||
e.writePrimaryRPrompt()
|
||||
// escape double quotes contained in the prompt
|
||||
prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.string(), `"`, `\"`))
|
||||
return prompt
|
||||
}
|
||||
|
||||
// escape double quotes contained in the prompt
|
||||
prompt := fmt.Sprintf("PS1=\"%s\"", strings.ReplaceAll(e.string(), `"`, `\"`))
|
||||
prompt += fmt.Sprintf("\nRPROMPT=\"%s\"", e.rprompt)
|
||||
|
||||
return prompt
|
||||
case shell.PWSH, shell.PWSH5, shell.GENERIC:
|
||||
e.writeRPrompt()
|
||||
case shell.BASH:
|
||||
space, OK := e.canWriteRightBlock(true)
|
||||
if !OK {
|
||||
default:
|
||||
if !needsPrimaryRPrompt {
|
||||
break
|
||||
}
|
||||
// in bash, the entire rprompt needs to be escaped for the prompt to be interpreted correctly
|
||||
// see https://github.com/jandedobbeleer/oh-my-posh/pull/2398
|
||||
|
||||
terminal.Init(shell.GENERIC)
|
||||
|
||||
prompt := terminal.SaveCursorPosition()
|
||||
prompt += strings.Repeat(" ", space)
|
||||
prompt += e.rprompt
|
||||
prompt += terminal.RestoreCursorPosition()
|
||||
prompt = terminal.EscapeText(prompt)
|
||||
e.write(prompt)
|
||||
e.writePrimaryRPrompt()
|
||||
}
|
||||
|
||||
return e.string()
|
||||
}
|
||||
|
||||
func (e *Engine) RPrompt() string {
|
||||
filterRPromptBlock := func(blocks []*config.Block) *config.Block {
|
||||
for _, block := range blocks {
|
||||
if block.Type == config.RPrompt {
|
||||
return block
|
||||
}
|
||||
}
|
||||
return nil
|
||||
func (e *Engine) needsPrimaryRPrompt() bool {
|
||||
switch e.Env.Shell() {
|
||||
case shell.PWSH, shell.PWSH5, shell.GENERIC, shell.ZSH:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
block := filterRPromptBlock(e.Config.Blocks)
|
||||
if block == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
block.Init(e.Env)
|
||||
if !block.Enabled() {
|
||||
return ""
|
||||
}
|
||||
|
||||
text, length := e.renderBlockSegments(block)
|
||||
e.rpromptLength = length
|
||||
return text
|
||||
}
|
||||
|
||||
func (e *Engine) writePrimaryRPrompt() {
|
||||
space, OK := e.canWriteRightBlock(true)
|
||||
if !OK {
|
||||
return
|
||||
}
|
||||
|
||||
e.write(terminal.SaveCursorPosition())
|
||||
e.write(strings.Repeat(" ", space))
|
||||
e.write(e.rprompt)
|
||||
e.write(terminal.RestoreCursorPosition())
|
||||
}
|
||||
|
|
59
src/prompt/rprompt.go
Normal file
59
src/prompt/rprompt.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package prompt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/config"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/log"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/shell"
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/terminal"
|
||||
)
|
||||
|
||||
func (e *Engine) RPrompt() string {
|
||||
filterRPromptBlock := func(blocks []*config.Block) *config.Block {
|
||||
for _, block := range blocks {
|
||||
if block.Type == config.RPrompt {
|
||||
return block
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
block := filterRPromptBlock(e.Config.Blocks)
|
||||
if block == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if e.Env.Shell() == shell.BASH {
|
||||
terminal.Init(shell.GENERIC)
|
||||
}
|
||||
|
||||
block.Init(e.Env)
|
||||
|
||||
if !block.Enabled() {
|
||||
return ""
|
||||
}
|
||||
|
||||
text, length := e.renderBlockSegments(block)
|
||||
e.rpromptLength = length
|
||||
|
||||
if e.Env.Shell() != shell.BASH {
|
||||
return text
|
||||
}
|
||||
|
||||
width, err := e.Env.TerminalWidth()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
padding := width - e.rpromptLength
|
||||
if padding < 0 {
|
||||
padding = 0
|
||||
}
|
||||
|
||||
text = fmt.Sprintf("%s%s\r", strings.Repeat(" ", padding), text)
|
||||
|
||||
return text
|
||||
}
|
|
@ -45,7 +45,6 @@ func (e *Engine) Tooltip(tip string) string {
|
|||
text, _ := e.renderBlockSegments(block)
|
||||
return text
|
||||
case shell.PWSH, shell.PWSH5:
|
||||
block.InitPlain(e.Env, e.Config)
|
||||
if !block.Enabled() {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ func quotePosixStr(str string) string {
|
|||
if len(str) == 0 {
|
||||
return "''"
|
||||
}
|
||||
|
||||
needQuoting := false
|
||||
var b strings.Builder
|
||||
for _, r := range str {
|
||||
|
@ -166,19 +167,23 @@ func quoteNuStr(str string) string {
|
|||
|
||||
func Init(env runtime.Environment) string {
|
||||
shell := env.Flags().Shell
|
||||
|
||||
switch shell {
|
||||
case PWSH, PWSH5, ELVISH:
|
||||
executable, err := getExecutablePath(env)
|
||||
if err != nil {
|
||||
return noExe
|
||||
}
|
||||
|
||||
var additionalParams string
|
||||
if env.Flags().Strict {
|
||||
additionalParams += " --strict"
|
||||
}
|
||||
|
||||
if env.Flags().Manual {
|
||||
additionalParams += " --manual"
|
||||
}
|
||||
|
||||
var command, config string
|
||||
switch shell {
|
||||
case PWSH, PWSH5:
|
||||
|
@ -189,6 +194,7 @@ func Init(env runtime.Environment) string {
|
|||
command = "eval (%s init %s --config=%s --print%s | slurp)"
|
||||
config = env.Flags().Config
|
||||
}
|
||||
|
||||
return fmt.Sprintf(command, executable, shell, config, additionalParams)
|
||||
case ZSH, BASH, FISH, CMD, TCSH, XONSH:
|
||||
return PrintInit(env)
|
||||
|
|
|
@ -3,7 +3,13 @@ export POSH_SHELL_VERSION=$BASH_VERSION
|
|||
export POWERLINE_COMMAND="oh-my-posh"
|
||||
export POSH_PID=$$
|
||||
export CONDA_PROMPT_MODIFIER=false
|
||||
|
||||
omp_start_time=""
|
||||
omp_stack_count=0
|
||||
omp_elapsed=-1
|
||||
omp_no_exit_code="true"
|
||||
omp_ret=0
|
||||
omp_pipe_status=0
|
||||
|
||||
# start timer on command start
|
||||
PS0='${omp_start_time:0:$((omp_start_time="$(_omp_start_timer)",0))}$(_omp_ftcs_command_start)'
|
||||
|
@ -45,35 +51,42 @@ function set_poshcontext() {
|
|||
return
|
||||
}
|
||||
|
||||
# regular prompt
|
||||
function _omp_hook() {
|
||||
local ret=$? pipeStatus=(${PIPESTATUS[@]})
|
||||
if [[ "${#BP_PIPESTATUS[@]}" -ge "${#pipeStatus[@]}" ]]; then
|
||||
pipeStatus=(${BP_PIPESTATUS[@]})
|
||||
omp_ret=$?
|
||||
omp_pipe_status=(${PIPESTATUS[@]})
|
||||
|
||||
if [[ "${#BP_PIPESTATUS[@]}" -ge "${#omp_pipe_status[@]}" ]]; then
|
||||
omp_pipe_status=(${BP_PIPESTATUS[@]})
|
||||
fi
|
||||
|
||||
local omp_stack_count=$((${#DIRSTACK[@]} - 1))
|
||||
local omp_elapsed=-1
|
||||
local no_exit_code="true"
|
||||
omp_stack_count=$((${#DIRSTACK[@]} - 1))
|
||||
|
||||
if [[ "$omp_start_time" ]]; then
|
||||
local omp_now=$(::OMP:: get millis --shell=bash)
|
||||
omp_elapsed=$((omp_now - omp_start_time))
|
||||
omp_start_time=""
|
||||
no_exit_code="false"
|
||||
omp_no_exit_code="false"
|
||||
fi
|
||||
if [[ "${pipeStatus[-1]}" != "$ret" ]]; then
|
||||
pipeStatus=("$ret")
|
||||
|
||||
if [[ "${omp_pipe_status[-1]}" != "$omp_ret" ]]; then
|
||||
omp_pipe_status=("$omp_ret")
|
||||
fi
|
||||
|
||||
set_poshcontext
|
||||
_set_posh_cursor_position
|
||||
|
||||
PS1="$(::OMP:: print primary --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION" --status="$ret" --pipestatus="${pipeStatus[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --no-status="$no_exit_code" --terminal-width="${COLUMNS-0}" | tr -d '\0')"
|
||||
PS1="$(::OMP:: print primary --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION" --status="$omp_ret" --pipestatus="${omp_pipe_status[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --no-status="$omp_no_exit_code" --terminal-width="${COLUMNS-0}" | tr -d '\0')"
|
||||
return $ret
|
||||
}
|
||||
|
||||
# rprompt
|
||||
_omp_rprompt() {
|
||||
::OMP:: print right --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION" --status="$omp_ret" --pipestatus="${omp_pipe_status[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --no-status="$omp_no_exit_code" --terminal-width="${COLUMNS-0}" | tr -d '\0'
|
||||
}
|
||||
|
||||
if [[ "$TERM" != "linux" ]] && [[ -x "$(command -v ::OMP::)" ]] && ! [[ "$PROMPT_COMMAND" =~ "_omp_hook" ]]; then
|
||||
PROMPT_COMMAND="_omp_hook; $PROMPT_COMMAND"
|
||||
PROMPT_COMMAND="_omp_hook; _omp_rprompt; $PROMPT_COMMAND"
|
||||
fi
|
||||
|
||||
if [[ "::UPGRADE::" == "true" ]]; then
|
||||
|
|
Loading…
Reference in a new issue