Search code examples
shellcshtcsh

Interpreting escape sequences in csh?


I've got a small script to colorize the state of a git repo in the current directory:

#!/usr/bin/env bash

# setup escape codes based on out output format
RD="\e[0;31m"
GN="\e[0;32m"
LG="\e[0;37m"
BL="\e[0;34m"

# return an evil star if git repo is dirty
git_dirty() {
    ERROR="${RD}✘ "
    git diff-files --no-ext-diff --quiet
    if [[ $? -gt 0 ]]; then
        echo -ne "$ERROR"
        return 0
    fi

    git diff-index --no-ext-diff --quiet --cached HEAD
    if [[ $? -gt 0 ]]; then
        echo -ne "$ERROR"
        return 0
    fi

    echo -ne "${GN}✓ "
}

# format current git branch
BRANCH=$(git symbolic-ref -q HEAD 2> /dev/null | sed -e 's|^refs/heads/||')
if [[ -z "${BRANCH// }" ]]; then
    echo -ne ""
else
    echo -ne "${LG}[${BL}$BRANCH`git_dirty`${LG}]"
fi

Which works great when I use it in my prompt in bash:

export PS1="$LG\n[\!] -${LG}bash${LG}- $LG\u$DG@$RD\h $GN\w \$(git_branch)\n$LG └─► $RES"

But when I use it in my prompt in csh:

set prompt = "${LG}\n\[%!\] -${RD}csh${LG}- ${LG}%n${DG}@${RD}%m ${GN}%~ `git_branch`\n${LG} └─► ${RES}"

It prints ^[[0;37m[^[[0;34mmaster^[[0;31m✘ ^[[0;37m] rather than the colorized branch name and status. Though

echo `git_branch` 

Works as expected. How can I make csh/tcsh interpret the escape sequences correctly?


Solution

  • According to https://www.cs.umd.edu/~srhuang/teaching/code_snippets/prompt_color.tcsh.html you should put escape sequences inside %{ } in csh.

    set     red="%{\033[1;31m%}"
    set   green="%{\033[0;32m%}"
    set  yellow="%{\033[1;33m%}"
    set    blue="%{\033[1;34m%}"
    set magenta="%{\033[1;35m%}"
    set    cyan="%{\033[1;36m%}"
    set   white="%{\033[0;37m%}"
    set     end="%{\033[0m%}" # This is needed at the end... :(
    
    set prompt = "${white}\n\[%!\] -${red}csh${white}- ${white}%n${DG}@${red}%m ${green}%~ `git_branch`\n${white} └─► ${RES}${end}"
    

    If you want the GIT branch to update, you need to put the prompt setting in the precmd alias, which is evaluated before each command:

    alias precmd 'set prompt = "${white}\n\[%!\] -${red}csh${white}- ${white}%n${DG}@${red}%m ${green}%~ `git_branch`\n${white} └─► ${RES}${end}"'