2011-10-08 9 views

Odpowiedz

0

Jednym ze sposobów byłoby użyć tput liczyć kolumny swojego terminala, a podścieżka liczbę znaków, które będą drukowane w lewo i prawo, a następnie użyć tej liczby jako liczby spacje między lewym i prawym tekstem. Użyj linii printf, aby skonstruować linię.

krótki przykład:

left="[${status}]\[email protected]\h:\w\$ " 
right="$(git symbolic-ref HEAD) $(date +%T)" 
spaces="$(($(tput cols) - ${#left} - ${#right}))" 
export PS1="$(printf "%s%${spaces}s\n" "$left" "$right")" 
+0

mmm, właśnie widziałem to na line_ _same. Nie sądzę, że^będzie działać. Brzmi bardziej, jakbyś chciał bardziej wsadzić swoje ręce w rzeczy "[n] curses". – c00kiemon5ter

9

Spróbuj wykonać następujące czynności:

PS1='$(printf "%*s\r%s" $((COLUMNS-1)) "[$(git branch 2>/dev/null | grep '^*' | sed s/..//)] $(date +%H:%M:%S)" "[email protected]:$PWD$ ")' 

Należy pamiętać, że nigdy nie będziesz się zachowań, które dokładnie pasuje zsh jedną z tylko bash. W powyższym przypadku, widzę następujące differencies:

  1. prawej części wiersza nie jest czyszczony po uruchomieniu polecenia (accept-line wydarzenie pod względem zsh).
  2. Prawa część zgłoszenia zostanie wyczyszczona, jeśli coś napiszesz, a następnie naciśnij <C-u> lub <BS>.
  3. Prawa część zachęty nie zostanie przywrócona, jeśli coś nad nią wpiszesz, a następnie usuniesz tekst.
  4. Prawa część zachęty nie zniknie, jeśli coś nad nią wpiszesz, ale tekst w tej części zostanie nadpisany.
1

Dzisiaj zbudowałem coś takiego w następujący sposób. Gruntowne badania nie zostały jeszcze wykonane ...

preprompt() { 
    rc=$? 
    c=31 
    [ $rc -eq 0 ] && c=32 

    PS1="\[$(color $c)\]$rc\[$(color 0)\] \t \w \$ " 
    # right "prompt" 
    # We cannot use $COLUMNS here, since in new shells the first prompt 
    # will get garbled then. Seems like the correct value of COLUMNS is 
    # in the shell init. 
    printf "%`tput cols`s`tput cr`" "${USER}@${HOST}" 
} 

PROMPT_COMMAND=preprompt 
1

Poniższy kod tworzy wiersz, który wygląda następująco:

bash prompt with git status on right

To nie błahe to zrobić w bash powodu:

  • Readline mode string takes up characters before the prompt is printed, co oznacza, że ​​rozwiązania printf nie będą działać w niektórych przypadkach.z tego powodu:
  • Usuwanie wszystkich (np kolorów), aby prawidłowo obliczyć długość druku prawostronną stronie szybkiego
  • , która chciałaby skorzystać __git_ps1 do czynienia z git przypadków brzegowych
  • __git_ps1 tylko transmitują kolor w niektórych okolicznościach, tylko wewnątrz $PS1
  • Umożliwienie koloru na wyjściu __git_ps1 podczas usuwania \[ i \] znaków, z którego wyjścia (nie może być zagnieżdżone)
  • Opakowanie cały wiersz RHS w \[ i \], aby zapewnić, że zachęty nie robi dziwne rzeczy podczas przeglądania/edycji/ukończenie polecenia

#!/bin/bash 
# _options=$(shopt -op); set -exu # Save and set shell options for testing 
################## 
# Set the prompt # Sourced from .bashrc 
################## 

# Select git info displayed, see /usr/lib/git-core/git-sh-prompt for more 
export GIT_PS1_SHOWCOLORHINTS=1   # Make pretty colours inside $PS1 
export GIT_PS1_SHOWDIRTYSTATE=1   # '*'=unstaged, '+'=staged 
export GIT_PS1_SHOWSTASHSTATE=1   # '$'=stashed 
export GIT_PS1_SHOWUNTRACKEDFILES=1  # '%'=untracked 
export GIT_PS1_SHOWUPSTREAM="verbose"  # 'u='=no difference, 'u+1'=ahead by 1 commit 
export GIT_PS1_STATESEPARATOR=''   # No space between branch and index status 
export GIT_PS1_DESCRIBE_STYLE="describe" # Detached HEAD style: 
# describe  relative to older annotated tag (v1.6.3.1-13-gdd42c2f) 
# contains  relative to newer annotated tag (v1.6.3.2~35) 
# branch  relative to newer tag or branch (master~4) 
# default  exactly eatching tag 


# Sets prompt like: 
# [email protected]:~/prj/sample_app[exit]$     master*% u= | 30 Apr 22:27 
_set_bash_prompt() { 
    # Set left hand side of the prompt 
    PS1="\[email protected]\h:\w\$ " 

    # 
    # Git status 
    # 

    # Save current state of user shopt settings promptvars and extglob 
    local user_shopt 
    user_shopt=$(shopt -p promptvars extglob) 
    # __git_ps1 usually returns literal text "${__git_ps1_branch_name}" rather 
    # than the contained branch name, eg "master". This prevents calculating 
    # the length of the printable characers in the RHS string (used to move the 
    # cursor that many columns left from the terminal's right edge.) However if 
    # "shopt promptvars" is unset, __git_ps1 it will include the dereferenced 
    # branch name instead. 
    shopt -qu promptvars 
    # extglob is required for the ${variable//@(pattern)/} replacements 
    shopt -qs extglob 

    # Allow disabling git status and no error if __git_ps1 undefined 
    if [[ ! -v _disable_git_prompt && $(type -t __git_ps1 2>/dev/null) == function ]]; then 
    # __git_ps1 will only make pretty colours inside $PS1 
    local old_PS1=$PS1 
    __git_ps1 "" "" "%s" # force colour; no default round bracket (decorations) 

    # Strip "\[" and "\[": non-printable character markers. __git_ps1 outputs 
    # them however the whole of the RHS prompt needs to be included in these 
    # markers, and they can't be nested. 
    git=${PS1//@(\\@(\[|\]))/} 
    PS1=$old_PS1 
    fi 

    # 
    # Right hand side of prompt 
    # 
    local rhs="" # String to be printed on the right hand side of terminal 

    # Create a string like: "25 Apr 13:15" 
    local date_time 
    printf -v date_time "%(%e %b %H:%M)T" -1 # -1 is current time 

    # Format the RHS prompt 
    [[ -n $git ]] && rhs="$git | " #" 
    rhs+="\e[0;1;31m${date_time}" 

    # Strip ANSI CSI commands (eg colours) to enble counting the length of 
    # printable characters, giving offset of cursor from terminal RHS edge (from 
    # https://www.commandlinefu.com/commands/view/12043/remove-color-special-escape-ansi-codes-from-text-with-sed) 
    # Neither bash not sed support lookbehind zero-length assertions, so it's not 
    # possible to ignore "\\e", (ie a literal '\' followed by a literal 'e'), yet 
    # still remove "\e" (ie ESC) 
    local rhs_printable=${rhs//@(\\@(\[|]|[Ee]\[*([0-9;])[a-zA-Z]))/} 
    # or, in using sed (but requires exec): 
    # local rhs_printable=$(sed -e 's,\\[][]\|\\[Ee]\[\([0-9;]\)*[A-Za-z],,g' <<< "$rhs") 

    # Reference: https://en.wikipedia.org/wiki/ANSI_escape_code 
    local Save='\e[s' # Save cursor position 
    local Rest='\e[u' # Restore cursor to save point 

    # Save cursor position, jump to (right hand edge minus N columns) where N is 
    # the length of the printable RHS string. Print the RHS string, then return 
    # to the saved position and print the LHS prompt. 

    # Note: "\[" and "\]" are used so that bash can calculate the number of 
    # printed characters so that the prompt doesn't do strange things when 
    # command line editing/browsing/completion. Ensure that these are not nested. 
    PS1="\[\e[0m${Save}\e[$((COLUMNS - ${#rhs_printable}))G${rhs}${Rest}\]${PS1}" 

    eval "$user_shopt" 
} 

# eval "$_options"; unset _options # Restore previous shell options from line 2 
Powiązane problemy