LINUX.ORG.RU

Добавить имя branch в prompt

 


1

1
PS1="\[\033[0;37m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo '\[\033[0;31m\]\h'; else echo '\[\033[0;33m\]\u\[\033[0;37m\]@\[\033[0;96m\]\h'; fi)\[\033[0;37m\]]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]"

Как добавить в этот PS1 вот это?

$(__git_ps1 '(%s)')

Что-то я растерялся из-за обилия [

┌─[user@debian-home]─[~/media/source_project/dj/work/some/auth]
└──╼

Надо сделать

┌─[user@debian-home]─[git_branch_name]-[~/media/source_project/dj/work/some/auth]
└──╼

А то неудобно, иногда сабмодули перескакивают на HEAD-some с мастера, нужно видеть в каком бренче нахожусь

★★★★

Последнее исправление: bryak (всего исправлений: 2)

┌─[user@debian-home]─[~/media/source_project/dj/work/some/auth]
└──╼

Какой ужас. o_O У меня всё проще.

Для bash:

source $HOME/bin/git-prompt.sh
export GIT_PS1_SHOWDIRTYSTATE=true
export GIT_PS1_SHOWCOLORHINTS=true
export PROMPT_COMMAND='__git_ps1 "\W" " \$ "'

Для zsh:

source $HOME/bin/git-prompt.sh
export GIT_PS1_SHOWDIRTYSTATE=true
export GIT_PS1_SHOWCOLORHINTS=true
precmd () { __git_ps1 "%1~" " %# " " (%s)" }

Сам git-prompt.sh ванильный.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)

__git_ps1 ‘(%s)’

и получишь тормоза на больших git-директориях

anonymous
()
Ответ на: комментарий от bhfq

виртуалки позволяют онанировать с разными девчебрутивами

bryak ★★★★
() автор топика

Вот так

PS1="\[\033[0;37m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo '\[\033[0;31m\]\h'; else echo '\[\033[0;33m\]\u\[\033[0;37m\]@\[\033[0;96m\]\h'; fi)\[\033[0;37m\]]\342\224\200[$(/usr/bin/git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]"

И так

PS1="\[\033[0;37m\]\342\224\214\342\224\200\$([[ \$? != 0 ]] && echo \"[\[\033[0;31m\]\342\234\227\[\033[0;37m\]]\342\224\200\")[$(if [[ ${EUID} == 0 ]]; then echo '\[\033[0;31m\]\h'; else echo '\[\033[0;33m\]\u\[\033[0;37m\]@\[\033[0;96m\]\h'; fi)\[\033[0;37m\]]\342\224\200[$(__git_ps1 '%s')]\342\224\200[\[\033[0;32m\]\w\[\033[0;37m\]]\n\[\033[0;37m\]\342\224\224\342\224\200\342\224\200\342\225\274 \[\033[0m\]"

не получается

bryak ★★★★
() автор топика
Ответ на: комментарий от bryak

Что за ад на главной? (комментарий)

# подставь свой путь к git-prompt.sh
. /usr/share/git/git-prompt.sh

# https://en.wikipedia.org/wiki/ANSI_escape_code
  reset='\e[0m'

   bold='\e[1m'
 normal='\e[22m'

  black='\e[30m'
    red='\e[31m'
  green='\e[32m'
 yellow='\e[33m'
   blue='\e[34m'
magenta='\e[35m'
   cyan='\e[36m'
  white='\e[37m'

# escape non-printing
e(){ printf "\[%s\]" "$1"; }

# собираем код возврата
exitcode(){
	printf "%s" "\$([[ \$? != 0 ]] && printf \""
	printf "%s" "$(e $white)[$(e $red)x$(e $white)]"
	printf "%s" "\")"
}

# дальше сам
user_host(){
	printf "%s" "[\u@\h]"
}
workdir(){
	printf "%s" "[\w]"
}
git_branch(){
	printf "%s" "\$(__git_ps1 \"─[%s]\")"
}

# наглядно и редактируемо собираем PS1
PS1=
PS1+="$(e $white)┌─$(exitcode)─$(user_host)─$(workdir)$(git_branch)\n"
PS1+="$(e $white)└──╼ $(e $reset)"
anonymous
()
Ответ на: комментарий от anonymous

Огромное огромное огромное спасибо!

bryak ★★★★
() автор топика
Ответ на: комментарий от anonymous

Немного не получается. Посмотри как оно по факту

# # подставь свой путь к git-prompt.sh
# . /usr/share/git/git-prompt.sh

# https://en.wikipedia.org/wiki/ANSI_escape_code
reset='\e[0m'
bold='\e[1m'
normal='\e[22m'
black='\e[30m'
red='\e[31m'
green='\e[32m'
yellow='\e[33m'
blue='\e[34m'
magenta='\e[35m'
cyan='\e[36m'
white='\e[37m'

# escape non-printing
e() {
    printf "\[%s\]" "$1"
}

# собираем код возврата
exitcode(){
	printf "%s" "\$([[ \$? != 0 ]] && printf \""
	printf "%s" "$(e $white)[$(e $red)x$(e $white)]"
	printf "%s" "\")"
}

user() {
    printf "%s" "\u$1"
}

host() {
    printf "%s" "\h$1"
}

workdir(){
	printf "%s" "[\w]" "$1"
}

git_branch(){
	printf "%s" "\$(__git_ps1 \"─[%s]\")"
}

# наглядно и редактируемо собираем PS1
PS1=
PS1+="$(e $white)┌─$(exitcode)─[$(user $blue)@$(host $red)]─$(workdir $cyan)$(git_branch $yellow)\n"
PS1+="$(e $white)└──╼ $(e $reset)"
bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 2)
Ответ на: комментарий от bryak

$(e $asci_esc_code)

Это отдельная конструкция - вызов фукции e c эскейп-кодом, которая вставляет цвет для последующего текста.

Не проверял, где-то так:

user() {
    # $1 - цвет
    # устанавливаем его вызовом "$(e $1)"
    printf "%s" "$(e $1)\u"
}

host() {
    # $1 - цвет
    printf "%s" "$(e $1)\h"
}
# Кстати, задумайся над засорением окружения этими функциями
# можешь переименовать, добавив префикс "__", или другой уникальный

git_branch(){
	# можно по другому.
	# дергаем НОРМАЛЬНУЮ bash-функцию prompt_git_branch
	printf "%s" "\$(prompt_git_branch)"
}

# и в этой функции пишем логику
# НОРМАЛЬНО без изварщений с обратной косой
prompt_git_branch(){
	# вариант без использования __git_ps1 и git-prompt.sh
	# сами дергаем git
	local branch=$(git branch --show-current 2>/dev/null)

	# тут используем цвета без экранирования, который нужен в PS1
	# в общем, еще проще

	# внимание, printf "%b"
	# %b - чтобы понимал экранирование \e,
	# иначe %s выводило бы как есть с обратной косой
	[[ "$branch" ]] && printf "%b" "-(${cyan}${branch}${white})"
}
anonymous
()
Ответ на: комментарий от anonymous

Пока получилось так. Но не получается вот это сделать:

git_branch() {
    local zzz="\$(git branch 2>/dev/null | grep '^*' | colrm 1 2)"
    
    if [[ ! -z "$zzz" ]];then 
        printf "%s" "$1${zzz}${Color_Off}"
    else
        printf "%s" "$1---${Color_Off}"
    fi
}
# Reset
Color_Off="\[\033[0m\]"       # Text Reset

# Regular Colors
Black="\[\033[0;30m\]"        # Black
Red="\[\033[0;31m\]"          # Red
Green="\[\033[0;32m\]"        # Green
Yellow="\[\033[0;33m\]"       # Yellow
Blue="\[\033[0;34m\]"         # Blue
Purple="\[\033[0;35m\]"       # Purple
Cyan="\[\033[0;36m\]"         # Cyan
White="\[\033[0;37m\]"        # White

# Bold
BBlack="\[\033[1;30m\]"       # Black
BRed="\[\033[1;31m\]"         # Red
BGreen="\[\033[1;32m\]"       # Green
BYellow="\[\033[1;33m\]"      # Yellow
BBlue="\[\033[1;34m\]"        # Blue
BPurple="\[\033[1;35m\]"      # Purple
BCyan="\[\033[1;36m\]"        # Cyan
BWhite="\[\033[1;37m\]"       # White

# Underline
UBlack="\[\033[4;30m\]"       # Black
URed="\[\033[4;31m\]"         # Red
UGreen="\[\033[4;32m\]"       # Green
UYellow="\[\033[4;33m\]"      # Yellow
UBlue="\[\033[4;34m\]"        # Blue
UPurple="\[\033[4;35m\]"      # Purple
UCyan="\[\033[4;36m\]"        # Cyan
UWhite="\[\033[4;37m\]"       # White

# Background
On_Black="\[\033[40m\]"       # Black
On_Red="\[\033[41m\]"         # Red
On_Green="\[\033[42m\]"       # Green
On_Yellow="\[\033[43m\]"      # Yellow
On_Blue="\[\033[44m\]"        # Blue
On_Purple="\[\033[45m\]"      # Purple
On_Cyan="\[\033[46m\]"        # Cyan
On_White="\[\033[47m\]"       # White

# High Intensty
IBlack="\[\033[0;90m\]"       # Black
IRed="\[\033[0;91m\]"         # Red
IGreen="\[\033[0;92m\]"       # Green
IYellow="\[\033[0;93m\]"      # Yellow
IBlue="\[\033[0;94m\]"        # Blue
IPurple="\[\033[0;95m\]"      # Purple
ICyan="\[\033[0;96m\]"        # Cyan
IWhite="\[\033[0;97m\]"       # White

# Bold High Intensty
BIBlack="\[\033[1;90m\]"      # Black
BIRed="\[\033[1;91m\]"        # Red
BIGreen="\[\033[1;92m\]"      # Green
BIYellow="\[\033[1;93m\]"     # Yellow
BIBlue="\[\033[1;94m\]"       # Blue
BIPurple="\[\033[1;95m\]"     # Purple
BICyan="\[\033[1;96m\]"       # Cyan
BIWhite="\[\033[1;97m\]"      # White

# High Intensty backgrounds
On_IBlack="\[\033[0;100m\]"   # Black
On_IRed="\[\033[0;101m\]"     # Red
On_IGreen="\[\033[0;102m\]"   # Green
On_IYellow="\[\033[0;103m\]"  # Yellow
On_IBlue="\[\033[0;104m\]"    # Blue
On_IPurple="\[\033[10;95m\]"  # Purple
On_ICyan="\[\033[0;106m\]"    # Cyan
On_IWhite="\[\033[0;107m\]"   # White

# # https://en.wikipedia.org/wiki/ANSI_escape_code
reset='\e[0m'
bold='\e[1m'
normal='\e[22m'
black='\e[30m'
red='\e[31m'
green='\e[32m'
yellow='\e[33m'
blue='\e[34m'
magenta='\e[35m'
cyan='\e[36m'
white='\e[37m'
escape='\e[37m'

# escape non-printing
e() {
    printf "\[%s\]" "$1"
}

# собираем код возврата
exitcode(){
	printf "%s" "\$([[ \$? != 0 ]] && printf \""
	printf "%s" "$(e $white)[$(e $red)x$(e $white)]"
	printf "%s" "\")"
}

user() {
    printf "%s" "$1\u$Color_Off"
}

host() {
    printf "%s" "$1\h$Color_Off"
}

workdir(){
	printf "%s" "$1[\w]$Color_Off"
}

git_branch() {
    local zzz="\$(git branch 2>/dev/null | grep '^*' | colrm 1 2)"
    
    if [[ ! -z "$zzz" ]];then 
        printf "%s" "$1${zzz}${Color_Off}"
    else
        printf "%s" "$1---${Color_Off}"
    fi
}


PS1=
PS1+="$(e $white)┌─$(exitcode)─[$(user $Yellow)@$(host $IRed)]─[$(git_branch $Yellow)]─$(workdir $IBlue)\n"
PS1+="$(e $white)└──╼ $(e $reset)"
bryak ★★★★
() автор топика
Ответ на: комментарий от bryak

Ты слишком сильно упоролся в цвета. Забей на цвета, сделай, чтобы работало без раскраски. Разберись с bash: как дергать свои функции/переменные, чтобы красиво собрать PS1, и как дергаются свои функции из собранного PS1.

git branch 2>/dev/null | grep '^*' | colrm 1 2

Будь проще git branch --show-current 2>/dev/null

anonymous
()
Ответ на: комментарий от anonymous

Вот так не работает(ничего не отдает)

git branch --show-current 2>/dev/null

вот так работает

git rev-parse --abbrev-ref HEAD 2>/dev/null

Только вопрос в кондишен print

git_branch() {
    local zzz="\$(git branch 2>/dev/null | grep '^*' | colrm 1 2)"
    
    if [[ ! -z "$zzz" ]];then 
        printf "%s" "$1${zzz}${Color_Off}"
    else
        printf "%s" "$1---${Color_Off}"
    fi
}

Например вот это - работает, а то, что я писал ранее - нет

euid() {
    if [[ ${EUID} == 0 ]];then
        user "$On_IRed"
    else
        user "$IYellow"
    fi
}
bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 7)
Ответ на: комментарий от bryak

Вот так не работает git branch --show-current

Должно работать начиная с git-2.22

вот так работает git rev-parse --abbrev-ref HEAD

Да, это более надежный способ.

Только вопрос в кондишен print

Все эксперименты (тесты) можно делать отдельно от PS1.

Написал скриптик с нужными функциями и переменными. Тупо подгрузил прямо в командной строке с

$ source ./my-test-function.sh

и дергай нужную функцию с нужными аргументами

$ git_branch $MyBestColorEscCode

В общем, я не хочу опускаться до разжевывания базы, которую нужно знать, чтобы что-то сделать. Если не знаешь, то сперва изучи bash на базовом уровне, только потом лезь в тонкости с PS1. Или тупо бери уже готовое.

anonymous
()
Ответ на: комментарий от anonymous
  1. Я не пойму, при каждой смене директории выполняются эти все функции или один раз?

  2. Почему вот это не работает без начального слеша? Может он и есть причина того, что условие [[ -z некорректно проверяется?

git_branch() {
    # local zzz="\$(git branch 2>/dev/null | grep '^*' | colrm 1 2)"
    local zzz="\$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
    printf "%s" "$1${zzz}$Color_Off"
    # printf "%s" "$1${zzz}${Color_Off}"
    # if [[ ! -z ${zzz} ]];then 
    #     printf "%s" "$1${zzz}${Color_Off}"
    # else
    #     printf "%s" "$1---${Color_Off}"
    # fi
}

Т.е, если сделать не

local zzz="\$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"

а

local zzz="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"

то ничего не выводит

printf "%s" "$1${zzz}${Color_Off}"
bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 1)
Ответ на: комментарий от bryak

Ты не знаешь основу. Читай маны.

Строка в PS1 выполняется каждый раз, когда выводится строка приглашения. Упрощенно, каждый раз выполняется eval "$PS1", если упустить парсинг спец. кодов \u, \h, \w и тд. Читай маны.

Ты можешь посмотреть текущий собранный echo $PS1. В скрипте при создании-сборке PS1, если доллар не экранирован, то сразу подставляется результат переменной или вызывается команда $(my_command args ...). Если экранирован \$, обратная косая перед долларом, то эта строка попадет как есть, и подстановка переменной или функции будет происходить во время показа строки приглашения.

Краткие итоги: неэкранированные - для красивой наглядной сборки PS1, экранированные - для вызова по месту и времени показа строки приглашения.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.