* Re: zle reset-prompt with prompt that is COLUMNS wide eats line above prompt's first line
2010-12-11 7:57 ` zle reset-prompt with prompt that is COLUMNS wide eats line above prompt's " Bart Schaefer
@ 2011-01-25 13:23 ` Nikolai Weibull
0 siblings, 0 replies; 3+ messages in thread
From: Nikolai Weibull @ 2011-01-25 13:23 UTC (permalink / raw)
To: Bart Schaefer; +Cc: Zsh Users
[-- Attachment #1: Type: text/plain, Size: 2431 bytes --]
On Sat, Dec 11, 2010 at 08:57, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Dec 10, 11:40am, Nikolai Weibull wrote:
> }
> } Running zle reset-prompt with a prompt that is COLUMNS wide eats the
> } line above prompt's first line. Here's a set-up to try it with:
> }
> } PS1=${(l:COLUMNS:)}$'\n'
> } bindkey '^^' reset-prompt
>
> The problem here isn't the width of the prompt, it's the newline.
> (OK, it's sort of the combination of the two, but more the latter.)
>
> } Each time you press CTRL-^ you'll be eating the line above the first
> } line of the prompt. If you change PS1 to ${(l:COLUMNS-1)}$'\n' this
> } doesn't happen.
> }
> } Would it be possible to have prompt that is COLUMNS wide and have this
> } not happen?
>
> This is a problem with terminals and terminfo or termcap descriptions.
> Some terminals silently discard a newline when one is output at the
> right margin, others don't, and still others discard it only when it
> is output at the right margin of the very last line of the screen.
> Some terminals cause the cursor to wrap onto the next line right
> away when the right margin is reached, others leave the cursor on
> top of the last character that was output until at least one more
> character appears.
>
> Terminal description databases aren't very good at differentiating
> these cases. ZLE decides in this case that the terminal both wraps
> the line and does not discard the newline, so it believes it needs
> to move up one line before redrawing the prompt. Your terminal
> wraps at the margin but does discard the newline, so ZLE's internal
> idea of what the screen looks like does not match reality.
>
> You can get around this by replacing $'\n' with $'%1(l.\n.)' which
> means to emit the newline only if ZLE believes that at least one
> character has been output since the last (implicit) newline. If
> the line is exactly $COLUMNS wide, ZLE will think that the terminal
> has wrapped and that zero characters have been output since, so it
> won't fool itself by emitting a newline that the terminal discards.
>
> On a different terminal, though, you might need to go back to $'\n'
> unconditionally.
It seems that there is some other complication. I’ve attached my
prompt definition, if anyone wants to take a look. I’m currently
running through screen inside PuTTY and iTerm, in which this trick
didn’t work.
[-- Attachment #2: prompt_now_setup --]
[-- Type: application/octet-stream, Size: 3087 bytes --]
prompt_now_help () {
emulate -L zsh
cat <<EOH
Nothing to see here.
EOH
}
integer PSCOL=-1
PSZERO='%([BSUbfksu]|[0-9]#[FK]({[^}]##}|))'
prompt_now_precmd () {
emulate -L zsh
setopt extendedglob
psvar[8]=$?
(( psvar[8] )) || psvar[8]=
(( ${+functions[vcs_info]} )) && vcs_info
prompt_now_adjust_width || return
local -A cs
prompt_now_chars
local host=
[[ -n $SSH_CONNECTION ]] && host=' %m'
local -ah ps1
ps1=(
'%249K'
"%$COLUMNS<$cs[…]<"
'%~'
'%8(V. [%9F%8v%f].)'
\$vcs_info_msg_0_
'%9v'
$host
'%<<'
'%k'
$'\n'
)
PS1=${(j::)ps1}
local listprompt='More%R page: %p'
integer fill
(( fill = COLUMNS - ${#${${listprompt//\%R}//\%p/Top}} - 2 ))
zstyle ':completion:*:default' list-prompt \
"%K{white}${listprompt%\%R*}${(l:fill:)}${listprompt##*%R}%k"
}
prompt_now_winch () {
prompt_now_adjust_width && zle && zle reset-prompt
}
prompt_now_adjust_width () {
emulate -L zsh
setopt extendedglob
local saved_vcs_info_msg_0_=$vcs_info_msg_0_
integer width
psvar[9]=""
vcs_info_msg_0_=${vcs_info_msg_0_//$~PSZERO}
(( width = COLUMNS - ${#${(f)${(%%)${PS1//$~PSZERO}}}[1]} ))
vcs_info_msg_0_=$saved_vcs_info_msg_0_
psvar[9]=${(l:width:)}
(( COLUMNS == PSCOL )) && return 1
(( PSCOL = COLUMNS ))
}
prompt_now_chars () {
case $TERM in
(xterm-256color|screen-256color) cs=('…' '…' '“' '“' '”' '”') ;;
(*) cs=('…' '...' '“' '"' '”' '"') ;;
esac
}
prompt_now_setup () {
emulate -L zsh
setopt extendedglob nolocaltraps
prompt_opts=(cr percent subst)
zstyle ':vcs_info:*' stagedstr '%F{green}+'
zstyle ':vcs_info:*' unstagedstr '%F{red}!'
zstyle ':vcs_info:*' formats ' [%b%c%u%f]'
zstyle ':vcs_info:*' actionformats ' [%a: %b%c%u%f]'
prompt_now_teardown
prompt_now_precmd
local -A cs
prompt_now_chars
PS2='${(l|$((2 * ${(w)#${(%%):-%_}}))|)}'
PS3='Your selection: '
PS4='%F{yellow}+%F{blue}%N%f:%i: '
SPROMPT="zsh: correct $cs[“]%9F%R%f$cs[”] to $cs[“]%10F%r%f$cs[”]? "
TIMEFMT=%J$'\n''real: %*E user: %*U system: %*S (%P)'
WATCHFMT='%(a.logon.logoff): %n (%M) tty: %l time: %T (%D)'
(( $#mailpath > 0 )) && mailpath=(${^mailpath%\?*}'?new: $_')
zstyle ':completion:*:descriptions' format '%K{white}%d%k'
zstyle ':completion:*:messages' format '%F{green}%d%f'
zstyle ':completion:*:warnings' format '%F{red}no matches for %d%f'
zstyle ':completion:*:corrections' format '%K{white}%d (errors: %9F%e%f)%k'
zstyle ':completion:*:options' auto-description "specify $cs[“]%d$cs[”]"
add-zsh-hook precmd prompt_now_precmd
add-zsh-hook chpwd prompt_now_adjust_width
functions[TRAPWINCH]="${functions[TRAPWINCH]//$'\n' prompt_now_winch}
prompt_now_winch"
}
prompt_now_teardown () {
emulate -L zsh
add-zsh-hook -D precmd prompt_now_precmd
functions[TRAPWINCH]="${functions[TRAPWINCH]//$'\n' prompt_now_winch}"
}
prompt_now_preview () {
local +h PS1='%# '
prompt_preview_theme now "$@"
}
[[ -o kshautoload ]] || prompt_now_setup "$@"
^ permalink raw reply [flat|nested] 3+ messages in thread