[
  {
    "path": ".github/FUNDING.yml",
    "content": "ko_fi: sudofox\n"
  },
  {
    "path": "README.md",
    "content": "# sudofox/shell-mommy\n\nInspired by [Gankra/cargo-mommy](https://github.com/Gankra/cargo-mommy)\n\nThis is a shell script that provides a `mommy` function which emulates a nurturing and supportive figure. The `mommy` function can be used to offer praise and encouraging responses to a user's actions, depending on the exit status of the command that is passed to it.\n\nBy default, the text will be output in a light pink to stderr. You can change this to a light blue if you find that more encouraging.\n\n<img src=\"preview.png\" alt=\"Example\" ></a>\n\n\nI hope this will serve to improve the efficiency of your workflow and general mental health. Please use responsibly.\n\n## Installation\n\nTo use the `mommy` function, you can source the `shell-mommy.sh` script in your current shell or add it to your `~/.bashrc` file to have it available every time you open a new terminal.\n\n```\n. /path/to/shell-mommy.sh\n```\n\nIf you'd like it to always show a message after each command, you can define a custom `PROMPT_COMMAND` like so:\n\n```\nexport PROMPT_COMMAND=\"mommy \\\\$\\\\(exit \\$?\\\\); $PROMPT_COMMAND\"\n```\n\nif that doesn't work for you, try:\n```\nexport PS1=\"\\$(mommy \\$\\(exit \\$?\\))$PS1\"\n```\n\n## Configuration\n\nThe `mommy` function has several customizable options that can be set using environment variables:\n\n- `SHELL_MOMMYS_LITTLE`: Sets the affectionate term that `mommy` will use to refer to the user. The default value is \"girl\".\n- `SHELL_MOMMYS_PRONOUNS`: Sets the pronouns that `mommy` will use to refer to itself. The default value is \"her\".\n- `SHELL_MOMMYS_ROLES`: Sets the role that `mommy` will have. The default value is \"mommy\".\n- `SHELL_MOMMYS_COLOR`: Sets the color of the text output by `mommy`. The default value is a light pink color.\n- `SHELL_MOMMYS_ONLY_NEGATIVE`: If set to `true`, `mommy` will provide encouragement (on non-zero exit status) but not praise. This will keep clutter down if you intend to use `mommy` as a `PROMPT_COMMAND`.\n- `SHELL_MOMMYS_NEGATIVE_RESPONSES`/`SHELL_MOMMYS_POSITIVE_RESPONSES`: Sets the possible responses that `mommy` will use. This should be in the form of a bash array and will override the default responses. Want Samuel L. Jackson to chastise or compliment you? [Now you can!](https://github.com/sudofox/shell-mommy/issues/5#issuecomment-1381029744)\n\nTo add multiple possible values, separate them with a forward slash, for example:\n\n```sh\nexport SHELL_MOMMYS_LITTLE=\"child/girl/boy\"\n# ...\n$ mommy ls\nREADME.md  shell-mommy.sh\nawe, what a good boy~\nmommy knew you could do it~ ❤️\n$ mommy ls\nREADME.md  shell-mommy.sh\ngood girl~\nmommy's so proud of you~ ❤️\n$ mommy ls\nREADME.md  shell-mommy.sh\nmommy thinks her little child earned a big hug~ ❤️\n```\n\n## Usage\n\nTo use the `mommy` function, simply pass a command as an argument and `mommy` will provide a supportive response based on the exit status of the command. Depending on the exit status, `mommy` will provide a response of praise or encouragement.\n\n```sh\nmommy ls\n# Output: Good girl! mommy's so proud of you! ❤️\n\nmommy this-command-does-not-exist\n# Output: Just a little further, sweetie~ ❤️\n```\n\n## Example\n\n```\n# Set custom affectionate term and pronouns\nexport SHELL_MOMMYS_LITTLE=\"kiddo\"\nexport SHELL_MOMMYS_PRONOUNS=\"them\"\n\n# Use the mommy function to run a command\nmommy ls\n\n# Output:\n# That's a good kiddo~ ❤️\n```\n"
  },
  {
    "path": "shell-mommy.sh",
    "content": "# sudofox/shell-mommy.sh\n\nmommy() (\n\n  # SHELL_MOMMYS_LITTLE - what to call you~ (default: \"girl\")\n  # SHELL_MOMMYS_PRONOUNS - what pronouns mommy will use for themself~ (default: \"her\")\n  # SHELL_MOMMYS_ROLES - what role mommy will have~ (default \"mommy\")\n\n  COLORS_LIGHT_PINK='\\033[38;5;217m'  #\\e[38;5;217m\n  COLORS_LIGHT_BLUE='\\033[38;5;117m'  #'\\e[38;5;117m\n  COLORS_FAINT='\\033[2m'              #'\\e[2m\n  COLORS_RESET='\\033[0m'              #'\\e[0m\n\n  DEF_WORDS_LITTLE=\"girl\"\n  DEF_WORDS_PRONOUNS=\"her\"\n  DEF_WORDS_ROLES=\"mommy\"\n  DEF_MOMMY_COLOR=\"${COLORS_LIGHT_PINK}\"\n  DEF_ONLY_NEGATIVE=\"false\"\n\n  NEGATIVE_RESPONSES=\"do you need MOMMYS_ROLE's help~? ❤️\nDon't give up, my love~ ❤️\nDon't worry, MOMMYS_ROLE is here to help you~ ❤️\nI believe in you, my sweet AFFECTIONATE_TERM~ ❤️\nIt's okay to make mistakes, my dear~ ❤️\njust a little further, sweetie~ ❤️\nLet's try again together, okay~? ❤️\nMOMMYS_ROLE believes in you, and knows you can overcome this~ ❤️\nMOMMYS_ROLE believes in you~ ❤️\nMOMMYS_ROLE is always here for you, no matter what~ ❤️\nMOMMYS_ROLE is here to help you through it~ ❤️\nMOMMYS_ROLE is proud of you for trying, no matter what the outcome~ ❤️\nMOMMYS_ROLE knows it's tough, but you can do it~ ❤️\nMOMMYS_ROLE knows MOMMYS_PRONOUN little AFFECTIONATE_TERM can do better~ ❤️\nMOMMYS_ROLE knows you can do it, even if it's tough~ ❤️\nMOMMYS_ROLE knows you're feeling down, but you'll get through it~ ❤️\nMOMMYS_ROLE knows you're trying your best~ ❤️\nMOMMYS_ROLE loves you, and is here to support you~ ❤️\nMOMMYS_ROLE still loves you no matter what~ ❤️\nYou're doing your best, and that's all that matters to MOMMYS_ROLE~ ❤️\nMOMMYS_ROLE is always here to encourage you~ ❤️\"\n\n  POSITIVE_RESPONSES=\"*pets your head*\nawe, what a good AFFECTIONATE_TERM~\\nMOMMYS_ROLE knew you could do it~ ❤️\ngood AFFECTIONATE_TERM~\\nMOMMYS_ROLE's so proud of you~ ❤️\nKeep up the good work, my love~ ❤️\nMOMMYS_ROLE is proud of the progress you've made~ ❤️\nMOMMYS_ROLE is so grateful to have you as MOMMYS_PRONOUN little AFFECTIONATE_TERM~ ❤️\nI'm so proud of you, my love~ ❤️\nMOMMYS_ROLE is so proud of you~ ❤️\nMOMMYS_ROLE loves seeing MOMMYS_PRONOUN little AFFECTIONATE_TERM succeed~ ❤️\nMOMMYS_ROLE thinks MOMMYS_PRONOUN little AFFECTIONATE_TERM earned a big hug~ ❤️\nthat's a good AFFECTIONATE_TERM~ ❤️\nyou did an amazing job, my dear~ ❤️\nyou're such a smart cookie~ ❤️\"\n\n  # allow for overriding of default words (IF ANY SET)\n\n  if [ -n \"$SHELL_MOMMYS_LITTLE\" ]; then\n    DEF_WORDS_LITTLE=\"${SHELL_MOMMYS_LITTLE}\"\n  fi\n  if [ -n \"$SHELL_MOMMYS_PRONOUNS\" ]; then\n    DEF_WORDS_PRONOUNS=\"${SHELL_MOMMYS_PRONOUNS}\"\n  fi\n  if [ -n \"$SHELL_MOMMYS_ROLES\" ]; then\n    DEF_WORDS_ROLES=\"${SHELL_MOMMYS_ROLES}\"\n  fi\n  if [ -n \"$SHELL_MOMMYS_COLOR\" ]; then\n    DEF_MOMMY_COLOR=\"${SHELL_MOMMYS_COLOR}\"\n  fi\n  # allow overriding to true\n  if [ \"$SHELL_MOMMYS_ONLY_NEGATIVE\" = \"true\" ]; then\n    DEF_ONLY_NEGATIVE=\"true\"\n  fi\n  # if the variable is set for positive/negative responses, overwrite it\n  if [ -n \"$SHELL_MOMMYS_POSITIVE_RESPONSES\" ]; then\n    POSITIVE_RESPONSES=\"$SHELL_MOMMYS_POSITIVE_RESPONSES\"\n  fi\n  if [ -n \"$SHELL_MOMMYS_NEGATIVE_RESPONSES\" ]; then\n    NEGATIVE_RESPONSES=\"$SHELL_MOMMYS_NEGATIVE_RESPONSES\"\n  fi\n\n  # split a string on forward slashes and return a random element\n  pick_word() {\n    echo \"$1\" | tr '/' '\\n' | shuf | sed 1q\n  }\n\n  pick_response() { # given a response type, pick an entry from the list\n\n    if [ \"$1\" = \"positive\" ]; then\n      element=$(echo \"$POSITIVE_RESPONSES\" | shuf | sed 1q)\n    elif [ \"$1\" = \"negative\" ]; then\n      element=$(echo \"$NEGATIVE_RESPONSES\" | shuf | sed 1q)\n    else\n      echo \"Invalid response type: $1\"\n      exit 1\n    fi\n\n    # Return the selected response\n    echo \"$element\"\n\n  }\n\n  sub_terms() { # given a response, sub in the appropriate terms\n    response=\"$1\"\n    # pick_word for each term\n    affectionate_term=\"$(pick_word \"${DEF_WORDS_LITTLE}\")\"\n    pronoun=\"$(pick_word \"${DEF_WORDS_PRONOUNS}\")\"\n    role=\"$(pick_word \"${DEF_WORDS_ROLES}\")\"\n    # sub in the terms, store in variable\n    response=\"$(echo \"$response\" | sed \"s/AFFECTIONATE_TERM/$affectionate_term/g\")\"\n    response=\"$(echo \"$response\" | sed \"s/MOMMYS_PRONOUN/$pronoun/g\")\"\n    response=\"$(echo \"$response\" | sed \"s/MOMMYS_ROLE/$role/g\")\"\n    # we have string literal newlines in the response, so we need to printf it out\n    # print faint and colorcode\n    printf \"${DEF_MOMMY_COLOR}$response${COLORS_RESET}\\n\"\n  }\n\n  success() {\n    (\n      # if we're only supposed to show negative responses, return\n      if [ \"$DEF_ONLY_NEGATIVE\" = \"true\" ]; then\n        return 0\n      fi\n      # pick_response for the response type\n      response=\"$(pick_response \"positive\")\"\n      sub_terms \"$response\" >&2\n    )\n    return 0\n  }\n  failure() {\n    rc=$?\n    (\n      response=\"$(pick_response \"negative\")\"\n      sub_terms \"$response\" >&2\n    )\n    return $rc\n  }\n  # eval is used here to allow for alias resolution\n\n  # TODO: add a way to check if we're running from PROMPT_COMMAND to use the previous exit code instead of doing things this way\n  eval \"$@\" && success || failure\n  return $?\n)\n"
  }
]