zsh在ps1中右對齊


轉到接受的答案


我想要一個帶有右斜線部分的多行zsh提示符,它看起來像這樣:

 [email protected]:/current/dir                                               16:00
->
 

我知道zsh中的RPROMPT,但是它的右對齊提示與您的普通提示相反,普通提示與您鍵入的文字在同一行。

有沒有辦法使多行命令提示符的第一行右對齊?我正在尋找PS1變量中的指令“現在正確對齊”,或者尋找PS1變量,即RPROMPT對PROMPT。

謝謝!


21





2011-11-14




回覆數: 4


您將在此處找到詳細的答案和示例。這個想法是使用 precmd 回調,use $COLUMNS 和一點數學函數在PS1之前寫一行,以計算文本在屏幕右側的位置。轉義序列的知識也將幫助您確定光標的位置和顏色。

另一個解決方案是使用Oh My ZSH中的主題。


13


2011-11-14

我也一直在尋找。對我而言, precmd() 繪製的線條不會在調整大小時或在 ^L 清除屏幕時重新繪製,這一事實一直困擾著我。我現在正在使用ANSI轉義序列來將光標移動一點。儘管我懷疑有一種更優雅的發行方式,但是這對我有用:

 _newline=$'\n'
_lineup=$'\e[1A'
_linedown=$'\e[1B'

PROMPT=...whatever...${_newline}...whatever...
RPROMPT=%{${_lineup}%}...whatever...%{${_linedown}%}
 

請記住,zsh手冊指出%{...%}用於不移動光標的原義轉義序列。即便如此,我仍在使用它們,因為它們允許忽略其內容的長度(雖然無法弄清楚如何發出使用它們移動光標的轉義符)


10


2014-04-03

這就是我剛才配置此東西的方式。這種方法不需要任何轉義序列操作,但是會使您在主提示中具有兩個不同的變量: PS1 帶顏色和 NPS1 不帶顏色。

 # Here NPS1 stands for "naked PS1" and isn't a built-in shell variable. I've
# defined it myself for PS1-PS2 alignment to operate properly.
PS1='%S%F{red}[%l]%f%s %F{green}%[email protected]%m%f %B%#%b '
NPS1='[%l] %[email protected]%m # '
RPS1='%B%F{green}(%~)%f%b'

# Hook function which gets executed right before shell prints prompt.
function precmd() {
    local expandedPrompt="$(print -P "$NPS1")"
    local promptLength="${#expandedPrompt}"
    PS2="> "
    PS2="$(printf "%${promptLength}s" "$PS2")"
}
 

請注意 print -P 用於快速擴展, ${#variable} 獲取存儲在變量中的字符串的長度以及 printf "%Nd" 用於 N 空格的左側填充的用法。這兩個 printprintf 是內置命令,所以應該沒有性能損失。


3


2014-11-03

讓我們用這種佈局定義提示:

 top_left              top_right
bottom_left        bottom_right
 

為此,我們需要一個函數來告訴我們給定字符串在打印時需要多少個字符。

 # Usage: prompt-length TEXT [COLUMNS]
#
# If you run `print -P TEXT`, how many characters will be printed
# on the last line?
#
# Or, equivalently, if you set PROMPT=TEXT with prompt_subst
# option unset, on which column will the cursor be?
#
# The second argument specifies terminal width. Defaults to the
# real terminal width.
#
# Assumes that `%{%}` and `%G` don't lie.
#
# Examples:
#
#   prompt-length ''            => 0
#   prompt-length 'abc'         => 3
#   prompt-length $'abc\nxy'    => 2
#   prompt-length '❎'          => 2
#   prompt-length $'\t'         => 8
#   prompt-length $'\u274E'     => 2
#   prompt-length '%F{red}abc'  => 3
#   prompt-length $'%{a\b%Gb%}' => 1
#   prompt-length '%D'          => 8
#   prompt-length '%1(l..ab)'   => 2
#   prompt-length '%(!.a.)'     => 1 if root, 0 if not
function prompt-length() {
  emulate -L zsh
  local COLUMNS=${2:-$COLUMNS}
  local -i x y=$#1 m
  if (( y )); then
    while (( ${${(%):-$1%$y(l.1.0)}[-1]} )); do
      x=y
      (( y *= 2 ));
    done
    local xy
    while (( y > x + 1 )); do
      m=$(( x + (y - x) / 2 ))
      typeset ${${(%):-$1%$m(l.x.y)}[-1]}=$m
    done
  fi
  echo $x
}
 

我們需要另一個函數,該函數需要兩個參數,並在屏幕的相對側上完全打印這些參數。

 # Usage: fill-line LEFT RIGHT
#
# Prints LEFT<spaces>RIGHT with enough spaces in the middle
# to fill a terminal line.
function fill-line() {
  emulate -L zsh
  local left_len=$(prompt-length $1)
  local right_len=$(prompt-length $2 9999)
  local pad_len=$((COLUMNS - left_len - right_len - ${ZLE_RPROMPT_INDENT:-1}))
  if (( pad_len < 1 )); then
    # Not enough space for the right part. Drop it.
    echo -E - ${1}
  else
    local pad=${(pl.$pad_len.. .)}  # pad_len spaces
    echo -E - ${1}${pad}${2}
  fi
}
 

最後,我們可以定義一個函數來設置 PROMPTRPROMPT ,指示ZSH在每個提示之前調用它,並設置適當的提示擴展選項:

 # Sets PROMPT and RPROMPT.
#
# Requires: prompt_percent and no_prompt_subst.
function set-prompt() {
  emulate -L zsh
  local git_branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
  git_branch=${${git_branch//\%/%%}/\\/\\\\\\}  # escape '%' and '\'

  local top_left='%F{blue}%~%f'
  local top_right="%F{green}${git_branch}%f"
  local bottom_left='%B%F{%(?.green.red)}%#%f%b '
  local bottom_right='%F{yellow}%T%f'

  PROMPT="$(fill-line "$top_left" "$top_right")"$'\n'$bottom_left
  RPROMPT=$bottom_right
}

autoload -Uz add-zsh-hook
add-zsh-hook precmd set-prompt
setopt noprompt{bang,subst} prompt{cr,percent,sp}
 

這將產生以下提示:

 ~/foo/bar                     master
% █                            10:51
 
  • 左上方:藍色當前目錄。
  • 右上方:Green Git分支。
  • 左下: # 如果是root, % 則不是;綠色表示成功,紅色表示錯誤。
  • 右下:黃色當前時間。

您可以在“ 多行提示”中找到更多詳細信息本要點中缺少的成分和完整的代碼。


1


2019-07-22