fix(shell): do not fetch cursor position using ANSI

resolves #3434
This commit is contained in:
Jan De Dobbeleer 2023-02-01 09:59:50 +01:00 committed by Jan De Dobbeleer
parent db557e4b31
commit bc21ba3aef
7 changed files with 32 additions and 45 deletions

View file

@ -20,7 +20,6 @@ type Engine struct {
Env platform.Environment Env platform.Environment
Writer *ansi.Writer Writer *ansi.Writer
Plain bool Plain bool
PromptCount int
console strings.Builder console strings.Builder
currentLineLength int currentLineLength int
@ -64,9 +63,13 @@ func (e *Engine) canWriteRightBlock(rprompt bool) bool {
func (e *Engine) PrintPrimary() string { func (e *Engine) PrintPrimary() string {
// cache a pointer to the color cycle // cache a pointer to the color cycle
cycle = &e.Config.Cycle cycle = &e.Config.Cycle
firstLine := e.Env.Getenv("POSH_CURSOR_LINE") == "1"
for i, block := range e.Config.Blocks { for i, block := range e.Config.Blocks {
e.renderBlock(block, (i == 0 && (e.PromptCount == 1 || firstLine))) var cancelNewline bool
if i == 0 {
row, _ := e.Env.CursorPosition()
cancelNewline = e.Env.Flags().PromptCount == 1 || row == 1
}
e.renderBlock(block, cancelNewline)
} }
if len(e.Config.ConsoleTitleTemplate) > 0 { if len(e.Config.ConsoleTitleTemplate) > 0 {
title := e.getTitleTemplateText() title := e.getTitleTemplateText()

View file

@ -29,7 +29,6 @@ func New(flags *platform.Flags) *Engine {
Env: env, Env: env,
Writer: ansiWriter, Writer: ansiWriter,
Plain: flags.Plain, Plain: flags.Plain,
PromptCount: env.CmdFlags.PromptCount,
} }
return eng return eng

View file

@ -268,3 +268,8 @@ func (env *MockedEnvironment) DirIsWritable(path string) bool {
func (env *MockedEnvironment) SetPromptCount() { func (env *MockedEnvironment) SetPromptCount() {
_ = env.Called() _ = env.Called()
} }
func (env *MockedEnvironment) CursorPosition() (int, int) {
args := env.Called()
return args.Int(0), args.Int(1)
}

View file

@ -216,6 +216,7 @@ type Environment interface {
TemplateCache() *TemplateCache TemplateCache() *TemplateCache
LoadTemplateCache() LoadTemplateCache()
SetPromptCount() SetPromptCount()
CursorPosition() (row, col int)
Debug(message string) Debug(message string)
Error(err error) Error(err error)
Trace(start time.Time, args ...string) Trace(start time.Time, args ...string)
@ -831,6 +832,16 @@ func (env *Shell) SetPromptCount() {
env.CmdFlags.PromptCount = count env.CmdFlags.PromptCount = count
} }
func (env *Shell) CursorPosition() (row, col int) {
if number, err := strconv.Atoi(env.Getenv("POSH_CURSOR_LINE")); err == nil {
row = number
}
if number, err := strconv.Atoi(env.Getenv("POSH_CURSOR_COLUMN")); err != nil {
col = number
}
return
}
func IsPathSeparator(env Environment, c uint8) bool { func IsPathSeparator(env Environment, c uint8) bool {
if c == '/' { if c == '/' {
return true return true

View file

@ -9,20 +9,6 @@ PS0='${omp_start_time:0:$((omp_start_time="$(_omp_start_timer)",0))}'
# set secondary prompt # set secondary prompt
PS2="$(::OMP:: print secondary --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION")" PS2="$(::OMP:: print secondary --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION")"
function _set_posh_cursor_position() {
# not supported in Midnight Commander
# see https://github.com/JanDeDobbeleer/oh-my-posh/issues/3415
if [[ -v MC_SID ]] || [[ $TERM_PROGRAM == "WarpTerminal" ]]; then
return
fi
local pos
echo -ne "\033[6n" # ask the terminal for the position
read -s -d\[ garbage # discard the first part of the response
read -s -d R pos # store the position in bash variable 'pos'
export POSH_CURSOR_LINE=${pos%;*}
export POSH_CURSOR_COLUMN=${pos#*;}
}
function _omp_start_timer() { function _omp_start_timer() {
::OMP:: get millis ::OMP:: get millis
} }
@ -42,7 +28,6 @@ function _omp_hook() {
omp_start_time="" omp_start_time=""
fi fi
set_poshcontext set_poshcontext
_set_posh_cursor_position
PS1="$(::OMP:: print primary --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION" --error="$ret" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" | tr -d '\0')" PS1="$(::OMP:: print primary --config="$POSH_THEME" --shell=bash --shell-version="$BASH_VERSION" --error="$ret" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" | tr -d '\0')"
return $ret return $ret
} }

View file

@ -7,20 +7,6 @@ export POSH_PROMPT_COUNT=0
# set secondary prompt # set secondary prompt
PS2="$(::OMP:: print secondary --config="$POSH_THEME" --shell=zsh)" PS2="$(::OMP:: print secondary --config="$POSH_THEME" --shell=zsh)"
function _set_posh_cursor_position() {
# not supported in Midnight Commander
# see https://github.com/JanDeDobbeleer/oh-my-posh/issues/3415
if [[ -v MC_SID ]] || [[ $TERM_PROGRAM == "WarpTerminal" ]]; then
return
fi
local pos
echo -ne "\033[6n" # ask the terminal for the position
read -s -d\[ garbage # discard the first part of the response
read -s -d R pos # store the position in bash variable 'pos'
export POSH_CURSOR_LINE=${pos%;*}
export POSH_CURSOR_COLUMN=${pos#*;}
}
# template function for context loading # template function for context loading
function set_poshcontext() { function set_poshcontext() {
return return
@ -41,7 +27,6 @@ function prompt_ohmyposh_precmd() {
count=$((POSH_PROMPT_COUNT+1)) count=$((POSH_PROMPT_COUNT+1))
export POSH_PROMPT_COUNT=$count export POSH_PROMPT_COUNT=$count
set_poshcontext set_poshcontext
_set_posh_cursor_position
eval "$(::OMP:: print primary --config="$POSH_THEME" --error="$omp_last_error" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --eval --shell=zsh --shell-version="$ZSH_VERSION")" eval "$(::OMP:: print primary --config="$POSH_THEME" --error="$omp_last_error" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --eval --shell=zsh --shell-version="$ZSH_VERSION")"
unset omp_start_time unset omp_start_time
} }

View file

@ -86,9 +86,8 @@ Tells the engine what to do with the block. There are two options:
### Newline ### Newline
Start the block on a new line - defaults to `false`. For `zsh`, `bash`, `pwsh` this will not print a newline that's Start the block on a new line - defaults to `false`. For `pwsh` and `cmd` this will not print a newline that's defined
defined on the first block when the prompt is on the first line (when using clear), or when the shell session starts on the first block when the prompt is on the first line (when using clear), or when the shell session starts (1st prompt).
(1st prompt).
### Alignment ### Alignment