From: Nikolai Weibull <now@bitwi.se>
To: Bart Schaefer <schaefer@brasslantern.com>
Cc: Zsh Users <zsh-users@zsh.org>
Subject: Re: zle reset-prompt with prompt that is COLUMNS wide eats line above prompt's first line
Date: Tue, 25 Jan 2011 14:23:47 +0100 [thread overview]
Message-ID: <AANLkTi=3XBAg_LTZDPSm5vCKytQohb6sCoekGLEPDA5e@mail.gmail.com> (raw)
In-Reply-To: <101210235748.ZM11748@torch.brasslantern.com>
[-- 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 "$@"
prev parent reply other threads:[~2011-01-25 13:45 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-10 10:40 zle reset-prompt with prompt that is COLUMNS wide eats line above prompt’s " Nikolai Weibull
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 [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='AANLkTi=3XBAg_LTZDPSm5vCKytQohb6sCoekGLEPDA5e@mail.gmail.com' \
--to=now@bitwi.se \
--cc=schaefer@brasslantern.com \
--cc=zsh-users@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).