Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expanded Shell Integration Example #143

Open
Aliervo opened this issue Feb 22, 2023 · 2 comments
Open

Expanded Shell Integration Example #143

Aliervo opened this issue Feb 22, 2023 · 2 comments

Comments

@Aliervo
Copy link

Aliervo commented Feb 22, 2023

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!

@facundoolano
Copy link
Owner

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.

@octoshrimpy
Copy link

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"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants