zsh-users
 help / color / mirror / code / Atom feed
* zle reset-prompt with prompt that is COLUMNS wide eats line above prompt’s first line
@ 2010-12-10 10:40 Nikolai Weibull
  2010-12-11  7:57 ` zle reset-prompt with prompt that is COLUMNS wide eats line above prompt's " Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Nikolai Weibull @ 2010-12-10 10:40 UTC (permalink / raw)
  To: Zsh Users

Hi!

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

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?


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: zle reset-prompt with prompt that is COLUMNS wide eats line above prompt's first line
  2010-12-10 10:40 zle reset-prompt with prompt that is COLUMNS wide eats line above prompt’s first line Nikolai Weibull
@ 2010-12-11  7:57 ` Bart Schaefer
  2011-01-25 13:23   ` Nikolai Weibull
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2010-12-11  7:57 UTC (permalink / raw)
  To: Zsh Users

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.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* 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

end of thread, other threads:[~2011-01-25 13:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-10 10:40 zle reset-prompt with prompt that is COLUMNS wide eats line above prompt’s first line 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

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).