2011-10-08 18 views

Respuesta

0

Una forma sería utilizar tput para contar los columnas de su terminal, y Subtrack el número de caracteres que se van a imprimir a la izquierda y la derecha, a continuación, utilizar ese número como el número de espacios entre el texto izquierdo y derecho. Use printf para construir la línea.

ejemplo rápido:

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, acabo de ver esto es en la line_ _same. No creo que^vaya a funcionar. Suena más como si necesitaras poner tus manos más en cosas de '[n] maldiciones'. – c00kiemon5ter

9

Pruebe lo siguiente:

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

Tenga en cuenta que no se consigue un comportamiento que coincide exactamente un zsh sólo con bash. En el caso anterior Veo las siguientes differencies:

  1. parte derecha de la línea de no se borra cuando se ejecuta un comando (accept-line evento en términos de zsh).
  2. La parte derecha del aviso se borrará si escribe algo y luego presiona <C-u> o <BS>.
  3. La parte derecha de la solicitud no se restaurará si escribe algo encima y luego elimina el texto.
  4. La parte derecha del aviso no desaparecerá si escribe algo encima, aunque el texto de esta parte se sobrescribirá.
1

Hoy construí algo así de la siguiente manera. pruebas exhaustivas no se ha hecho todavía ...

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

El código de abajo creará un indicador de que se parece a:

bash prompt with git status on right

Es no trivial de hacer esto en bash debido a:

  • Readline mode string takes up characters before the prompt is printed, lo que significa que las soluciones printf no funcionarán en algunos casos.Debido a esto:
  • Eliminación de la lista (por ejemplo, los colores) para calcular correctamente la longitud de la mano del lado derecho imprimible pronta
  • necesidad de utilizar __git_ps1 para hacer frente a git casos extremos
  • __git_ps1 sólo en la salida de color en cierta circunstancias, y sólo en el interior $PS1
  • Permitir que el color de la salida __git_ps1 mientras se quita los \[ y \] personajes de su producción (que no se pueden anidar)
  • envolver toda la línea de RHS en \[ y \] para asegurarse de que el indicador no hace cosas extrañas cuando la navegación/edición/completar comandos

#!/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 
Cuestiones relacionadas