rpg-cli icon indicating copy to clipboard operation
rpg-cli copied to clipboard

Expanded Shell Integration Example

Open Aliervo opened this issue 2 years ago • 2 comments

I took some of your shell examples and combined/expanded them into a full zsh plugin. It might also be source-able from bash, but I have not tested it this way.

We could link it in the README as an additional example, if you were so inclined.

Thanks for making such a cool game!

Aliervo avatar Feb 22 '23 15:02 Aliervo

This look nice, thanks!

This would definitely be a nice a addition to the shell integration guide. If you want you could send a PR adding your plugin as example.zsh as already done for bash and fish or, if you prefer to keep it as a separate repo, feel free to link it in the shell guide.

facundoolano avatar Feb 22 '23 15:02 facundoolano

I've gone a bit more in-depth than that and built shell integration in bash, including an auto-battler:


# =============================
# PS1 builder

# my custom prompt
ps1_text="$USER in $PWD"
rpg_text=$(rpg-cli -q | sed 's/@.*//' | sed 'y/-x/╌━/')
length=$(( ${#ps1_text} - ${#rpg_text} ))

# pretty-print rpg-cli -q
format_rpg_text() {
  counter=0
  output_parts=""
  rpg -q | sed 's/@.*//; s/]\[/\n/g; s/x/═/g ; s/-/╌/g' \
  | while IFS= read -r part; do
    ((counter++))
    if [ "$counter" -eq 2 ]; then
      # Colorize '═' in green for Part 2
      colored_part=$(echo "$part" | sed 's/═/\'$(tput setaf 2)'&\'$(tput sgr0)'/g')
      colored_part=$(echo "$colored_part" | sed 's/╌/\'$(tput setaf 0)'&\'$(tput sgr0)'/g')
      colored_part+="]["
    elif [ "$counter" -eq 3 ]; then
      # Colorize '═' in blue for Part 3
      colored_part=$(echo "$part" | sed 's/═/\'$(tput setaf 4)'&\'$(tput sgr0)'/g')
      colored_part=$(echo "$colored_part" | sed 's/╌/\'$(tput setaf 0)'&\'$(tput sgr0)'/g')
      colored_part+="]["

    elif [ "$counter" -eq 4 ]; then
      # Colorize '═' in orange for Part 4
      colored_part=$(echo "$part" | sed 's/═/\'$(tput setaf 3)'&\'$(tput sgr0)'/g')
      colored_part=$(echo "$colored_part" | sed 's/╌/\'$(tput setaf 0)'&\'$(tput sgr0)'/g')

    else
      colored_part=$(echo "$part")
      colored_part+="]["
    fi

    # last minute color replace 
    colored_part=$(echo "$colored_part" | awk '
    BEGIN {
      gray_code="\033[90m";
      reset_code="\033[0m";
    }

    {
      len = length($0);
      in_escape = 0;
      for (i = 1; i <= len; ++i) {
        char = substr($0, i, 1);
        if (in_escape) {
          if (char == "m") {
            in_escape = 0;
          }
        } else {
          if (char == "\033") {
            in_escape = 1;
          }
        }
        
        if (in_escape || (char != "[" && char != "]")) {
          printf "%s", char;
        } else {
          printf "%s%s%s", gray_code, char, reset_code;
        }
      }
      printf "\n";
    }')
    printf '%s' "$colored_part"
  done
}

# ignore ansi codes on charcount - not working correctly?
count_printable_chars() {
  local str="$1"
  local clean_str=$(echo -n "$str" | sed 's/\x1b\[[^a-zA-Z]*[a-zA-Z]//g')
  echo ${#clean_str}
}

# for right-align text
calc_space() {
  FORMATTED_RPG=$(format_rpg_text)
  FORMATTED_RPG_LEN=$(count_printable_chars $FORMATTED_RPG)
  length=$(( $COLUMNS - $FORMATTED_RPG_LEN + 10))
  PS1_SPACES=$(printf '%*s' $length "")
}

# runs before prompt is printed
PROMPT_COMMAND="calc_space"

# the prompt
PS1="\$PS1_SPACES"
PS1+="\$FORMATTED_RPG"
PS1+="\n╭ "
PS1+="\[\e[35m\]\[\e[95m\]\u"
PS1+="\[\e[35m\]\[\e[90m\] in "

# replace home dir with ~
PS1+="\[\e[92;1;3m\]\$(echo \$PWD | awk -v home=\$HOME 'BEGIN{FS=home;OFS=\"~\"} {if (\$1 == \"\") \$1=\"\"; print \$0}')/ "

# you can ignore this line if you don't have git_ps1 installed 
PS1+="\[\e[0;36m\]\$(__git_ps1) "

PS1+="\n\[\e[0m\]└❱ "


# =============================
# helpers

# prompts for path creation if cd'd path does not exist
__mkcd() {
  \cd "$@" 2>/dev/null
  if [ $? -ne 0 ]; then
    read -p "Folder does not exist. Create it? (Y/n): " choice
    case "$choice" in
      Y|y|"") mkdir -p "$1" && \cd "$1";;
      *) echo "Not changing directory.";;
    esac
  fi
}



# =============================
# rpg-cli

rpg () {
    rpg-cli "$@"
    sync_rpg
}

# casual rpg cd
__cd () {
    __mkcd "$@"
    rpg-cli cd -f .
    rpg-cli battle
}

# full rpg cd override
# Try to move the hero to the given destination, and cd match the shell pwd
# to that of the hero's location:
# - the one supplied as parameter, if there weren't any battles
# - the one where the battle took place, if the hero wins
# - the home dir, if the hero dies
#
# cd () {
#     rpg-cli cd "$@"
#     builtin cd "$(rpg-cli pwd)"
# }

# look for loot
__ls () {
    command ls --color=auto "$@"
    if [ $# -eq 0 ] ; then
        rpg cd -f .
        rpg ls
    fi
}

alias cd=__cd
alias ls=__ls
alias l=ls

# auto-explore for battles and items
dn () {
    current=$(basename $PWD)
    number_re='^[0-9]+$'

    if [[ $current =~ $number_re ]]; then
        next=$(($current + 1))
        command mkdir -p $next && cd $next && rpg ls
    elif [[ -d 1 ]] ; then
        cd 1 && rpg ls
    else
        command mkdir -p dungeon/1 && cd dungeon/1 && rpg ls
    fi
}

# This helper is used to make the pwd match the tracked internally by the game
sync_rpg () {
    builtin cd "$($RPG pwd)"
}

# auto-battler
# look for fights, look for loot, go home, heal, repeat
rpg-battle () {
  clear
  while true; do
    rpg battle
    echo -e ""
    echo $(format_rpg_text)
    echo -e "\n"
    sleep 2
    __cd ~
    echo -e ""
    rpg ls
    echo $(format_rpg_text)
    echo -e "\n"
    sleep 2
    __cd -
    echo -e ""
    rpg ls
    echo $(format_rpg_text)
    echo -e "\n"
    sleep 2
    clear
  done
}

# only modify files if battle succeeds
alias rm="rpg-battle && rm"
alias rmdir="rpg-battle && rmdir"
alias mkdir="rpg-battle && mkdir"
alias touch="rpg-battle && touch"
alias mv="rpg-battle && mv"
alias cp="rpg-battle && cp"
alias chown="rpg-battle && chown"
alias chmod="rpg-battle && chmod"

octoshrimpy avatar Sep 26 '23 17:09 octoshrimpy