domingo, 8 de enero de 2017

Personalizar prompt en Bash/Visual Studio Code

Ahora que la consola mola y he adoptado como animal de compañía a Visual Studio Code, me pasa que estoy más tiempo del previsto en el panel de la terminal integrada.

La verdad es que funciona muy bien y raramente abro ya el terminal como aplicación independiente, pero lo cierto es que en ambas versiones le falta color... y eso es una buena excusa para indagar un poco sobre cómo funciona bash y como personalizarlo

Como básicamente no tengo ningún background linuxero y llevo con Mac 6 meses, lo mismo digo algo por lo que merezco la hoguera, pero yo sólo quería cambiar el prompt y agregar color a la consola, avisado estás.

Para personalizar el prompt tenemos que modificar la variable de entorno PS1, en Bash Shell PS1: 10 Examples to Make Your Linux Prompt like Angelina Jolie está muy bien explicado, pero después de hacer algunas pruebas y desesperado por la sintaxis del color, encontré EzPromptEasy Bash PS1 Generator que permite gráficamente construir un prompt nivel 100.

Screen Shot 2017-01-08 at 20.07.04

Solucionado ya el tema del prompt, ahora queda ver como agregar color al comando ls

Lo primero es establecer la variable CLICOLOR a 1 y después en la variable LSCOLORS establecer qué colores queremos según qué elementos (directorios, ejecutables, etc.). Lógicamente y después de haber encontrado el anterior generador pensé que quizás debía haber uno para este tema y… ¡voilà! allí estaba LSCOLORS Generator

Finalmente quedaría un fichero .bash_profile como el siguiente:.

# get current branch in git repo
function parse_git_branch() {
 BRANCH=`git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
 if [ ! "${BRANCH}" == "" ]
 then
  STAT=`parse_git_dirty`
  echo "[${BRANCH}${STAT}]"
 else
  echo ""
 fi
}

# get current status of git repo
function parse_git_dirty {
 status=`git status 2>&1 | tee`
 dirty=`echo -n "${status}" 2> /dev/null | grep "modified:" &> /dev/null; echo "$?"`
 untracked=`echo -n "${status}" 2> /dev/null | grep "Untracked files" &> /dev/null; echo "$?"`
 ahead=`echo -n "${status}" 2> /dev/null | grep "Your branch is ahead of" &> /dev/null; echo "$?"`
 newfile=`echo -n "${status}" 2> /dev/null | grep "new file:" &> /dev/null; echo "$?"`
 renamed=`echo -n "${status}" 2> /dev/null | grep "renamed:" &> /dev/null; echo "$?"`
 deleted=`echo -n "${status}" 2> /dev/null | grep "deleted:" &> /dev/null; echo "$?"`
 bits=''
 if [ "${renamed}" == "0" ]; then
  bits=">${bits}"
 fi
 if [ "${ahead}" == "0" ]; then
  bits="*${bits}"
 fi
 if [ "${newfile}" == "0" ]; then
  bits="+${bits}"
 fi
 if [ "${untracked}" == "0" ]; then
  bits="?${bits}"
 fi
 if [ "${deleted}" == "0" ]; then
  bits="x${bits}"
 fi
 if [ "${dirty}" == "0" ]; then
  bits="!${bits}"
 fi
 if [ ! "${bits}" == "" ]; then
  echo " ${bits}"
 else
  echo ""
 fi
}

export PS1="\[\e[32m\]\u\[\e[m\]@\[\e[32m\]\h\[\e[m\]:\[\e[35m\]\w\[\e[m\]\[\e[34m\]\`parse_git_branch\`\[\e[m\]\[\e[32m\]\\$\[\e[m\] "
export CLICOLOR=1
export LSCOLORS=exfxcxdxbxegedabagacad
alias ls='ls -GFh'
alias showFiles='defaults write com.apple.finder AppleShowAllFiles YES; killall Finder /System/Library/CoreServices/Finder.app'
alias hideFiles='defaults write com.apple.finder AppleShowAllFiles NO; killall Finder /System/Library/CoreServices/Finder.app'

La terminal de Mac funciona perfecto con este fichero.

Screen Shot 2017-01-08 at 20.19.47

Sin embargo Visual Studio Code no se entera, ¿Por qué? Porque .bash_profile es una cosa y .bashrc es otra completamente distinta

.bash_profile se carga cuando la sesión del terminal se hace bajo un login (cosa que siempre ocurre en Mac cuando abrimos el terminal), mientras que .bashrc se carga cuando el terminal es ejecutado sin un login, y resulta que Visual Studio Code carga la terminal integrada con un non-login shell, Allow integrated terminal to run as login shell #7263, luego no ejecuta .bash_profile y sí .bashrc (entiendo que esto cambiará en alguna update venidera). ¿Solución? Mover el código de .bash_profile a .bashrc y en .bash_profile incluir código para chequear si existe .bashrc y cargarlo (dándonos así igual si la sesión del terminal es con login o sin login).

if [ -f ~/.bashrc ]; then
   source ~/.bashrc
fi

Ahora sí, el terminal integrado de Visual Studio Code muestra nuestra personalización.

Screen Shot 2017-01-08 at 20.16.27

Un saludo!