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