[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\njobs:\n  build:\n    working_directory: ~/project\n    docker:\n      - image: bkuhlmann/alpine-ruby:latest\n    steps:\n      - checkout\n\n      - restore_cache:\n          name: Gems Restore\n          keys:\n            - gem-cache-{{.Branch}}-{{checksum \"Gemfile\"}}\n            - gem-cache-\n\n      - run:\n          name: Gems Install\n          command: |\n            gem update --system\n            bundle config set path \"vendor/bundle\"\n            bundle install\n\n      - save_cache:\n          name: Gems Store\n          key: gem-cache-{{.Branch}}-{{checksum \"Gemfile\"}}\n          paths:\n            - vendor/bundle\n\n      - run:\n          name: Rake\n          command: bundle exec rake\n"
  },
  {
    "path": ".config/rubocop/config.yml",
    "content": "inherit_gem:\n  caliber: config/all.yml\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [bkuhlmann]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Community\n    url: https://alchemists.io/community\n    about: Please ask questions or discuss specifics here.\n  - name: Security\n    url: https://alchemists.io/policies/security\n    about: Please report security vulnerabilities here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/issue.md",
    "content": "---\nname: Issue\ntitle: \"Add|Update|Fix|Remove|Refactor \"\nabout: Report an issue. Please use only one of the subject prefixes.\n---\n\n<!--\nPlease focus on well written issues. Context: https://alchemists.io/articles/software_issues.\n-->\n\n## Why\n<!-- Required. Describe, briefly, why this issue is important. -->\n\n## How\n<!-- Optional. List exact steps to implement or reproduce behavior. Screen shots/casts are welcome! -->\n\n## Notes\n<!-- Optional. Provide additional details like operating system, software version(s), stack dump, logs, or anything else that would be helpful. -->\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## Overview\n<!-- Required. Describe, briefly, why this is necessary and what the overarching architecture is. -->\n\n## Screenshots/Screencasts\n<!-- Optional. Provide supporting screen shots/casts. -->\n\n## Details\n<!-- Optional. As bullet points, list related issue(s); major highlights; team callouts; and/or other information that is helpful. -->\n"
  },
  {
    "path": ".gitignore",
    "content": "Gemfile.lock\n"
  },
  {
    "path": ".ruby-version",
    "content": "4.0.3\n"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.2.0\nmessage: Please use the following metadata when citing this project in your work.\ntitle: Dotfiles\nabstract: Shell scripts for applying default settings to UNIX-based operating systems.\nversion: 57.0.0\nlicense: Hippocratic-2.1\ndate-released: 2026-04-17\nauthors:\n  - family-names: Kuhlmann\n    given-names: Brooke\n    affiliation: Alchemists\n    orcid: https://orcid.org/0000-0002-5810-6268\nkeywords:\n - bash\n - shell\n - scripts\n - dotfiles\nrepository-code: https://github.com/bkuhlmann/dotfiles\nrepository-artifact: https://alchemists.io/projects/dotfiles\nurl: https://alchemists.io/projects/dotfiles\n"
  },
  {
    "path": "Gemfile",
    "content": "# frozen_string_literal: true\n\nruby file: \".ruby-version\"\n\nsource \"https://rubygems.org\"\n\ngem \"caliber\", \"~> 0.90\"\ngem \"debug\", \"~> 1.11\"\ngem \"git-lint\", \"~> 10.0\"\ngem \"rake\", \"~> 13.4\"\n"
  },
  {
    "path": "LICENSE.adoc",
    "content": "= Hippocratic License\n\nVersion: 2.1.0.\n\nPurpose. The purpose of this License is for the Licensor named above to\npermit the Licensee (as defined below) broad permission, if consistent\nwith Human Rights Laws and Human Rights Principles (as each is defined\nbelow), to use and work with the Software (as defined below) within the\nfull scope of Licensor’s copyright and patent rights, if any, in the\nSoftware, while ensuring attribution and protecting the Licensor from\nliability.\n\nPermission and Conditions. The Licensor grants permission by this\nlicense (\"License\"), free of charge, to the extent of Licensor’s\nrights under applicable copyright and patent law, to any person or\nentity (the \"Licensee\") obtaining a copy of this software and\nassociated documentation files (the \"Software\"), to do everything with\nthe Software that would otherwise infringe (i) the Licensor’s copyright\nin the Software or (ii) any patent claims to the Software that the\nLicensor can license or becomes able to license, subject to all of the\nfollowing terms and conditions:\n\n* Acceptance. This License is automatically offered to every person and\nentity subject to its terms and conditions. Licensee accepts this\nLicense and agrees to its terms and conditions by taking any action with\nthe Software that, absent this License, would infringe any intellectual\nproperty right held by Licensor.\n* Notice. Licensee must ensure that everyone who gets a copy of any part\nof this Software from Licensee, with or without changes, also receives\nthe License and the above copyright notice (and if included by the\nLicensor, patent, trademark and attribution notice). Licensee must cause\nany modified versions of the Software to carry prominent notices stating\nthat Licensee changed the Software. For clarity, although Licensee is\nfree to create modifications of the Software and distribute only the\nmodified portion created by Licensee with additional or different terms,\nthe portion of the Software not modified must be distributed pursuant to\nthis License. If anyone notifies Licensee in writing that Licensee has\nnot complied with this Notice section, Licensee can keep this License by\ntaking all practical steps to comply within 30 days after the notice. If\nLicensee does not do so, Licensee’s License (and all rights licensed\nhereunder) shall end immediately.\n* Compliance with Human Rights Principles and Human Rights Laws.\n[arabic]\n. Human Rights Principles.\n[loweralpha]\n.. Licensee is advised to consult the articles of the United Nations\nUniversal Declaration of Human Rights and the United Nations Global\nCompact that define recognized principles of international human rights\n(the \"Human Rights Principles\"). Licensee shall use the Software in a\nmanner consistent with Human Rights Principles.\n.. Unless the Licensor and Licensee agree otherwise, any dispute,\ncontroversy, or claim arising out of or relating to (i) Section 1(a)\nregarding Human Rights Principles, including the breach of Section 1(a),\ntermination of this License for breach of the Human Rights Principles,\nor invalidity of Section 1(a) or (ii) a determination of whether any Law\nis consistent or in conflict with Human Rights Principles pursuant to\nSection 2, below, shall be settled by arbitration in accordance with the\nHague Rules on Business and Human Rights Arbitration (the \"Rules\");\nprovided, however, that Licensee may elect not to participate in such\narbitration, in which event this License (and all rights licensed\nhereunder) shall end immediately. The number of arbitrators shall be one\nunless the Rules require otherwise.\n+\nUnless both the Licensor and Licensee agree to the contrary: (1) All\ndocuments and information concerning the arbitration shall be public and\nmay be disclosed by any party; (2) The repository referred to under\nArticle 43 of the Rules shall make available to the public in a timely\nmanner all documents concerning the arbitration which are communicated\nto it, including all submissions of the parties, all evidence admitted\ninto the record of the proceedings, all transcripts or other recordings\nof hearings and all orders, decisions and awards of the arbitral\ntribunal, subject only to the arbitral tribunal’s powers to take such\nmeasures as may be necessary to safeguard the integrity of the arbitral\nprocess pursuant to Articles 18, 33, 41 and 42 of the Rules; and (3)\nArticle 26(6) of the Rules shall not apply.\n. Human Rights Laws. The Software shall not be used by any person or\nentity for any systems, activities, or other uses that violate any Human\nRights Laws. \"Human Rights Laws\" means any applicable laws,\nregulations, or rules (collectively, \"Laws\") that protect human,\ncivil, labor, privacy, political, environmental, security, economic, due\nprocess, or similar rights; provided, however, that such Laws are\nconsistent and not in conflict with Human Rights Principles (a dispute\nover the consistency or a conflict between Laws and Human Rights\nPrinciples shall be determined by arbitration as stated above). Where\nthe Human Rights Laws of more than one jurisdiction are applicable or in\nconflict with respect to the use of the Software, the Human Rights Laws\nthat are most protective of the individuals or groups harmed shall\napply.\n. Indemnity. Licensee shall hold harmless and indemnify Licensor (and\nany other contributor) against all losses, damages, liabilities,\ndeficiencies, claims, actions, judgments, settlements, interest, awards,\npenalties, fines, costs, or expenses of whatever kind, including\nLicensor’s reasonable attorneys’ fees, arising out of or relating to\nLicensee’s use of the Software in violation of Human Rights Laws or\nHuman Rights Principles.\n* Failure to Comply. Any failure of Licensee to act according to the\nterms and conditions of this License is both a breach of the License and\nan infringement of the intellectual property rights of the Licensor\n(subject to exceptions under Laws, e.g., fair use). In the event of a\nbreach or infringement, the terms and conditions of this License may be\nenforced by Licensor under the Laws of any jurisdiction to which\nLicensee is subject. Licensee also agrees that the Licensor may enforce\nthe terms and conditions of this License against Licensee through\nspecific performance (or similar remedy under Laws) to the extent\npermitted by Laws. For clarity, except in the event of a breach of this\nLicense, infringement, or as otherwise stated in this License, Licensor\nmay not terminate this License with Licensee.\n* Enforceability and Interpretation. If any term or provision of this\nLicense is determined to be invalid, illegal, or unenforceable by a\ncourt of competent jurisdiction, then such invalidity, illegality, or\nunenforceability shall not affect any other term or provision of this\nLicense or invalidate or render unenforceable such term or provision in\nany other jurisdiction; provided, however, subject to a court\nmodification pursuant to the immediately following sentence, if any term\nor provision of this License pertaining to Human Rights Laws or Human\nRights Principles is deemed invalid, illegal, or unenforceable against\nLicensee by a court of competent jurisdiction, all rights in the\nSoftware granted to Licensee shall be deemed null and void as between\nLicensor and Licensee. Upon a determination that any term or provision\nis invalid, illegal, or unenforceable, to the extent permitted by Laws,\nthe court may modify this License to affect the original purpose that\nthe Software be used in compliance with Human Rights Principles and\nHuman Rights Laws as closely as possible. The language in this License\nshall be interpreted as to its fair meaning and not strictly for or\nagainst any party.\n* Disclaimer. TO THE FULL EXTENT ALLOWED BY LAW, THIS SOFTWARE COMES\n\"AS IS,\" WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED, AND LICENSOR AND\nANY OTHER CONTRIBUTOR SHALL NOT BE LIABLE TO ANYONE FOR ANY DAMAGES OR\nOTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE\nOR THIS LICENSE, UNDER ANY KIND OF LEGAL CLAIM.\n\nThis Hippocratic License is an link:https://ethicalsource.dev[Ethical Source license] and is offered\nfor use by licensors and licensees at their own risk, on an \"AS IS\" basis, and with no warranties\nexpress or implied, to the maximum extent permitted by Laws.\n"
  },
  {
    "path": "README.adoc",
    "content": ":toc: macro\n:toclevels: 5\n:figure-caption!:\n\n= Dotfiles\n\nThese dotfiles are a collection shell scripts for applying default settings to UNIX-based operating\nsystems. They include useful shortcuts, performance augmentation, and advanced practices that --\neven if you don't apply to your own dotfiles -- should be educational for improving your own\npractices.\n\nBy default, these are set to my preferences (namely for macOS) but you can change them to your\nliking by editing any of the `.tt` template files in the `home_files` directory. Read on to learn\nmore.\n\ntoc::[]\n\n== Features\n\n* Configures link:https://github.com/amazing-print/amazing_print[Amazing Print] (`.aprc`).\n* Configures Bash (`.config/bash`, `.bashrc`, `.bash_profile`, and `.inputrc`).\n* Configures link:http://bash-completion.alioth.debian.org[Bash Completion].\n* Configures link:http://ctags.sourceforge.net[CTags] (`.ctags`).\n* Configures link:https://direnv.net[direnv].\n* Configures link:https://www.docker.com[Docker].\n* Configures link:https://eza.rocks[Eza].\n* Configures link:https://github.com/tako8ki/frum[Frum].\n* Configures link:https://git-scm.com[Git] (`.config/git`).\n* Configures link:https://www.gnupg.org[GPG].\n* Configures `.hushlogin`.\n* Configures link:https://nodejs.org[Node.js].\n* Configures link:https://www.npmjs.org[NPM] (`.npmrc`).\n* Configures link:https://www.postgresql.org[PostgreSQL] (`.psqlrc`).\n* Configures link:https://voormedia.github.io/rails-erd[Rails ERD] (`.erdconfig`).\n* Configures link:https://rspec.info[RSpec] (`.rspec`).\n* Configures link:https://www.ruby-lang.org[Ruby] (`.ruby-version` and `.irbrc`).\n* Configures link:https://github.com/bbatsov/rubocop[Rubocop] (`.rubocop.yml`).\n* Configures link:https://www.rust-lang.org[Rust].\n* Configures link:https://github.com/ggreer/the_silver_searcher[Silver Surfer] (`.agignore`).\n* Configures link:https://www.sublimetext.com[Sublime Text].\n* Configures link:https://www.vim.org[Vim] (`.vimrc`).\n* Configures link:https://www.terraform.io[Terraform].\n* Configures link:https://github.com/ajeetdsouza/zoxide[Zoxide].\n\n== Requirements\n\n. link:https://alchemists.io/projects/mac_os-config[macOS Configuration]\n\n== Setup\n\nTo install, run:\n\n[source,bash]\n----\ngit clone https://github.com/bkuhlmann/dotfiles.git\ncd dotfiles\ngit checkout 57.0.0\n----\n\n== Upgrade\n\nWhen upgrading to a new version, run the following:\n\n. Run: `bin/run l`. Links new files. If not using linked files, then run `bin/run d` and `bin/run i`\n  instead.\n. Run: `bin/run c`. Displays file differences, if any. Usually, this will be excluded files.\n. Run: `exec $SHELL`. Updates current shell with the above changes.\n\n== Usage\n\nEdit any of the `.tt` (template) and/or `.command` (command) files in the `home_files` directory as\nyou see fit. Then open a terminal window and execute the following command to install:\n\n[source,bash]\n----\ncd dotfiles\nbin/run\n----\n\nExecuting the `bin/run` script will present the following options:\n\n....\ns: Show managed dotfiles.\ni: Install dotfiles (existing files are skipped).\nl: Link dotfiles to this project (interactive per file, excludes: env.sh and .gitconfig).\nc: Check for differences between $HOME files and this project's files.\nd: Delete dotfiles (interactive per file, excludes: env.sh and .gitconfig).\nq: Quit/Exit.\n....\n\nThe options prompt can be skipped by passing the desired option directly to the `bin/run` script.\nFor example, executing `bin/run s` will show all managed dotfiles by this project.\n\nAfter install, the following files will require manual updating:\n\n* `.bash/env.sh`: Add secret/machine-specific environment settings (if any).\n* `.gitconfig`: Replace all `<redacted>` values for name, email, and signingKey within the `[user]`\n  section with your own credentials.\n\nThe reason the above two files are not managed by this project -- especially via symbolic links --\nis because sensitive data is usually stored in these files and you don't want this information\naccidentally checked into a source code repository or shared via other means.\n\n=== Aliases\n\n==== https://asciidoctor.org:[ASCII Doctor]\n\n....\nad = \"asciidoctor\"\n....\n\n==== https://www.gnu.org/software/bash:[Bash]\n\n....\nbashe = '$EDITOR $HOME/.config/bash/environment.sh'\nbashs = 'exec $SHELL'\n....\n\n==== https://bundler.io:[Bundler]\n\n....\nba = \"bundle add\"\nbb = \"bundle binstubs\"\nbce = '$EDITOR $BUNDLE_USER_CONFIG'\nbch = \"rm -f Gemfile.lock; bundle check\"\nbd = \"bundle doctor\"\nbe = \"bundle exec\"\nbi = \"bundle install\"\nblo = 'bundle list --paths | fzf | xargs $EDITOR'\nbo = \"bundle outdated --only-explicit\"\nbr = \"bundle remove\"\n....\n\n==== https://crystal-lang.org:[Crystal]\n\n....\ncr = \"crystal\"\ncrb = \"crystal build\"\ncrd = \"crystal docs\"\ncrdo = \"open docs/index.html\"\ncrr = \"crystal run\"\ncrs = \"crystal spec\"\n....\n\n==== https://direnv.net:[direnv]\n\n....\ndenva = \"direnv allow\"\ndenvr = \"direnv reload\"\ndenvs = \"direnv status\"\n....\n\n==== https://www.docker.com:[Docker]\n\n....\ndr = \"docker\"\ndrb = \"docker build\"\ndrd = \"docker system prune --force && docker buildx prune --force\"\ndri = \"docker images\"\ndrp = \"docker ps --all\"\ndrt = \"docker tag\"\n....\n\n==== http://duti.org:[duti]\n\n....\ndutia = 'duti $HOME/.config/duti/configuration.duti'\n....\n\n==== https://eza.rocks:[Eza]\n\n....\nx1 = \"eza --oneline --all --group-directories-first\"\nx = \"eza --all --all --long --header --group --group-directories-first --time-style long-iso --git\"\nxt = \"eza --tree --all --group-directories-first --ignore-glob '*.git' --git-ignore\"\nxtv = \"eza --tree --all --group-directories-first --ignore-glob '*.git'\"\n....\n\n==== https://github.com/Schniz/fnm:[Fast Node Manager]\n\n....\njs = \"fnm\"\njsd = \"fnm default\"\njse = \"fnm env\"\njsi = \"fnm install\"\njsl = \"fnm list\"\njss = \"fnm use\"\njsu = \"fnm uninstall\"\n....\n\n==== https://github.com/TaKO8Ki/frum:[Frum]\n\n....\nrb = \"frum\"\nrbd = \"frum global\"\nrbl = \"frum versions\"\nrbs = \"frum local\"\nrbu = \"frum uninstall\"\n....\n\n==== https://github.com/junegunn/fzf:[Fuzzy Finder]\n\n....\nff = \"_fzf_preview_and_select | xargs -0 -o \\$EDITOR\"\n....\n\n==== https://alchemists.io/projects/gemsmith:[Gemsmith]\n\n....\ngsb = \"gemsmith build --name\"\ngsc = \"gemsmith config --edit\"\ngse = \"gemsmith --edit\"\ngsi = \"gemsmith --install\"\ngsp = \"gemsmith --publish\"\ngsq = \"rake quality\"\ngsv = \"gemsmith --view\"\n....\n\n==== General\n\n....\n... = \"cd ../..\"\n.. = \"cd ..\"\nc = \"clear\"\ncat = \"bat --theme DarkNeon\"\ncdb = \"cd -\"\ndu = \"dust\"\nh = \"history\"\nl1 = \"ls -A1 | _copy_and_print '\\n'\"\nl = \"ls -alhT\"\no = \"open\"\np = 'pwd | tr -d \"\\r\\n\" | _copy_and_print'\npss = \"pgrep -i -l -f\"\nrmde = \"find . -type d -empty -not -path '*.git*' -delete\"\n....\n\n==== https://git-scm.com:[Git]\n\n....\ngall = \"git add --all .\"\ngamend = \"git commit --amend\"\ngamenda = \"git commit --amend --all --no-edit\"\ngamendh = \"git commit --amend --no-edit\"\ngap = \"git ls-files --modified | _fzf_preview_and_select | xargs -0 -o -t git add --patch\"\ngatch = \"git commit --patch\"\ngau = \"git add --update\"\ngb = \"git switch\"\ngbb = \"git switch -\"\ngbe = \"git branch --edit-description\"\ngbi = \"git bisect\"\ngbv = 'git config get branch.$(_git_branch_name).description'\ngbib = \"git bisect bad\"\ngbig = \"git bisect good\"\ngbih = \"git bisect help\"\ngbil = \"git bisect log\"\ngbir = \"git bisect reset\"\ngbire = \"git bisect replay\"\ngbis = \"git bisect start\"\ngbisk = \"git bisect skip\"\ngbiv = 'git bisect visualize --reverse --pretty=format:\"$(_git_log_line_format)\"'\ngbm = 'git switch $(_git_branch_default)'\ngbn = \"_git_branch_name | _copy_and_print\"\ngbt = \"git show-branch --topics\"\ngca = \"git commit --all\"\ngcam = \"git commit --all --message\"\ngcd = \"git config list --show-origin --show-scope | fzf\"\ngce = 'cat .git/COMMIT_EDITMSG | pbcopy'\ngcge = \"git config edit --global\"\ngch = \"git checkout\"\ngcl = \"git clone\"\ngcle = \"git config edit --local\"\ngcm = \"git commit --message\"\ngco = \"git commit\"\ngcp = \"git cherry-pick\"\ngcpa = \"git cherry-pick --abort\"\ngcpc = \"git cherry-pick --continue\"\ngcps = \"git cherry-pick --skip\"\ngcs = \"git commit --squash\"\ngd = \"git diff\"\ngdc = \"git diff --cached\"\ngdm = 'git diff origin/$(_git_branch_default)'\ngdo = 'git diff --name-only | uniq | xargs $EDITOR'\ngdt = \"git difftool\"\ngdtc = \"git difftool --cached\"\ngdtm = 'git difftool origin/$(_git_branch_default)'\ngdw = \"git diff --color-words\"\ngel = \"git rm\"\ngelc = \"git rm --cached\"\nges = \"git diff --name-only --cached | _fzf_preview_and_select | xargs -0 -o -t git reset\"\ngf = \"git fetch\"\ngg = \"git grep\"\ngge = \"git config get --global --regexp includeif | fzf | xargs \\$EDITOR\"\ngget = \"git config get\"\ngi = \"git init\"\ngl = 'git log --graph --pretty=format:\"$(_git_log_line_format)\" \"$(_git_branch_range)\"'\ngld = 'git log --stat --pretty=format:\"$(_git_log_details_format)\" \"$(_git_branch_range)\"'\nglame = \"git blame -M -C\"\nglean = \"git clean -d --force\"\nglf = 'git fetch && git log --reverse --no-merges --pretty=format:\"$(_git_log_line_format)\" ..@{upstream}'\nglh = \"_git_sha | _copy_and_print\"\ngna = \"git notes add\"\ngnd = \"git notes remove\"\ngne = \"git notes edit\"\ngnl = \"git notes list\"\ngnp = \"git notes prune\"\ngns = \"git notes show\"\ngp = \"git push\"\ngpf = \"git push --force-with-lease\"\ngpn = \"git push --no-verify\"\ngpu = \"git pull\"\ngpuo = \"git pull origin\"\ngpuom = 'git pull origin $(_git_branch_default)'\ngpuum = 'git pull upstream $(_git_branch_default)'\ngr = \"git ls-files --modified | _fzf_preview_and_select | xargs -0 -o -t git restore\"\ngrba = \"git rebase --abort\"\ngrbc = \"git rebase --continue\"\ngrbd = \"git rebase --show-current-patch\"\ngrbo = \"git rebase --onto\"\ngrbs = \"git rebase --skip\"\ngrbt = \"git rebase --edit-todo\"\ngrev = \"git revert --no-commit\"\ngrl = \"git reflog --relative-date\"\ngrom = 'git fetch --all && git reset --hard origin/$(_git_branch_default)' # Reset local branch to origin/main branch. UNRECOVERABLE!\ngrr = \"git rerere\"\ngset = \"git config set\"\ngst = \"git status --short --branch\"\ngt = \"git tag\"\ngte = 'cat .git/TAG_EDITMSG | pbcopy'\ngtp = \"git push --tags\"\ngtv = \"git tag --verify\"\nguthors = \"git shortlog --numbered --summary --group=author --group=trailer:Co-Authored-By\"\ngwl = \"git worktree list\"\ngwp = \"git worktree prune\"\n....\n\n==== https://alchemists.io/projects/hanamismith:[Hanamismith]\n\n....\nhsb = \"hanamismith build --name\"\nhse = \"hanamismith config --edit\"\nhsh = \"hanamismith --help\"\n....\n\n==== https://brew.sh:[Homebrew]\n\n....\nhb = \"brew\"\nhbd = \"brew doctor\"\nhbi = \"brew install\"\nhbin = \"brew info\"\nhbl = \"brew list --versions | fzf\"\nhblc = \"brew list --casks --versions | fzf\"\nhblf = \"brew list --formulae --versions | fzf\"\nhbp = \"brew pin\"\nhbpu = \"brew unpin\"\nhbr = \"brew reinstall\"\nhbs = \"brew search\"\nhbsu = \"brew update && brew upgrade && brew cleanup\"\nhbu = \"brew uninstall\"\nhbug = \"brew update && brew upgrade\"\n....\n\n==== https://trac.webkit.org/wiki/JSC:[JavaScript Core]\n\n....\njsc = \"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc\"\n....\n\n==== https://jless.io:[jless]\n\n....\njlr = \"jless --mode line\"\n....\n\n==== https://alchemists.io/projects/milestoner:[Milestoner]\n\n....\nms = \"milestoner\"\nmse = \"milestoner config --edit\"\nmsp = \"milestoner --publish\"\n....\n\n==== https://en.wikipedia.org/wiki/Network_Computer:[Network]\n\n....\ndnsi = \"scutil --dns\"\ndnss = \"sudo dscacheutil -statistics\"\nipa = 'curl --silent checkip.dyndns.org | rg --only-matching \"[0-9\\.]+\" | _copy_and_print'\nkey = \"open /Applications/Utilities/Keychain\\ Access.app\"\nping = \"gping\"\nspeed = \"networkQuality\"\nsshe = '$EDITOR $HOME/.ssh/config'\ntop = \"htop\"\n....\n\n==== https://www.npmjs.com:[NPM]\n\n....\nna = \"npm login\"\nnb = \"npm run build\"\nni = \"npm install\"\nnid = \"npm install --save-dev\"\nnl = \"npm ls\"\nno = \"npm outdated\"\nnp = \"npm publish\"\nnq = \"npm run quality\"\nnt = \"npm test\"\nntw = \"npm run test:watch\"\n....\n\n==== https://cocoatech.com:[Path Finder]\n\n....\npfo = 'open -a \"Path Finder.app\" \"$PWD\"'\n....\n\n==== https://github.com/theory/pgenv:[pgenv]\n\n....\npgc = \"pgenv clear\"\npgl = \"pgenv log\"\npgs = \"pgenv use\"\npgsp = \"pgenv stop\"\npgst = \"pgenv start\"\npgu = \"pgenv remove\"\npgv = \"pgenv versions\"\n....\n\n==== https://redis.io:[Redis]\n\n....\nredc = \"redis-cli\"\nreds = 'redis-server $HOMEBREW_PREFIX/etc/redis.conf &'\n....\n\n==== https://github.com/AlexB52/retest[Retest]\n\n....\nrt = \"COVERAGE=no retest\"\n....\n\n==== https://github.com/BurntSushi/ripgrep:[ripgrep]\n\n....\nrgf = \"rg --files --glob\"\n....\n\n==== https://rspec.info:[RSpec]\n\n....\nrsf = \"COVERAGE=no rspec spec --only-failures\"\nrsn = \"COVERAGE=no rspec spec --next-failure\"\nrso = \"COVERAGE=no rspec spec --dry-run --format doc > tmp/rspec-overview.txt && e tmp/rspec-overview.txt\"\nrsr = \"COVERAGE=no rspec\"\nrss = \"rspec\"\nrst = \"COVERAGE=no rspec spec --tag\"\n....\n\n==== https://github.com/bbatsov/rubocop:[Rubocop]\n\n....\ncop = \"rubocop --parallel --display-cop-names --display-style-guide\"\ncopc = \"rubocop --auto-gen-config\"\ncopf = \"rubocop --autocorrect\"\ncopfo = \"rubocop --autocorrect --only\"\ncopo = \"rubocop --display-cop-names --only\"\ncops = \"rubocop --show-cops\"\ncopu = \"rubocop --autocorrect-all\"\n....\n\n==== https://www.ruby-lang.org:[Ruby]\n\n....\nrbbe = '$EDITOR $HOME/Engineering/Misc/benchmark'\nrbbr = '$HOME/Engineering/Misc/benchmark'\nrbde = '$EDITOR $HOME/Engineering/Misc/demo'\nrbdr = '$HOME/Engineering/Misc/demo'\nrbdw = 'viddy $HOME/Engineering/Misc/demo'\n....\n\n==== https://rubyonrails.org:[Ruby on Rails]\n\n....\nrailsb = \"rails console --sandbox\"\nrailse = \"EDITOR = 'sublime --wait' rails credentials:edit\"\n....\n\n==== https://rubygems.org:[RubyGems]\n\n....\ngemc = \"gem cleanup\"\ngemcli = \"rg 'spec\\.executables' --no-messages --max-depth=2 --files-with-matches gemspec . | xargs basename | cut -d. -f1 | sort | _copy_and_print '\\n'\"\ngemcr = '$EDITOR $HOME/.gem/credentials'\ngemb = \"gem build\"\ngeme = \"gem environment\"\ngemi = \"gem install\"\ngeml = \"gem list\"\ngemp = \"gem pristine\"\ngemu = \"gem uninstall\"\ngemuc = \"gem update --system && gem update && gem cleanup\"\n....\n\n==== https://alchemists.io/projects/rubysmith:[Rubysmith]\n\n....\nrbb = \"rubysmith build --name\"\nrbe = \"rubysmith config --edit\"\nrbh = \"rubysmith --help\"\n....\n\n==== https://github.com/colszowka/simplecov:[SimpleCov]\n\n....\ncov = \"open coverage/index.html\"\n....\n\n==== https://www.sublimetext.com:[Sublime Text]\n\n....\ne = \"sublime\"\n....\n\n==== https://www.gnu.org/software/tar/tar.html:[Tar]\n\n....\nbzc = \"tar --use-compress-program=pigz --create --preserve-permissions --bzip2 --verbose --file\"\nbzx = \"tar --extract --bzip2 --verbose --file\"\n....\n\n==== https://www.terraform.io:[Terraform]\n\n....\ntf = \"terraform\"\ntfa = \"noti --title 'Terraform Apply' terraform apply\"\ntfc = \"terraform console\"\ntff = \"terraform fmt -recursive\"\ntfg = \"terraform graph | dot -Tsvg > tmp/graph.svg && open -a 'Firefox.app' tmp/graph.svg\"\ntfi = \"terraform init\"\ntfo = \"terraform output\"\ntfp = \"noti --title 'Terraform Plan' terraform plan\"\ntft = \"terraform taint\"\ntfu = \"terraform untaint\"\ntfup = \"terraform init -upgrade\"\ntfv = \"terraform validate\"\n....\n\n==== http://tmux.sourceforge.net:[tmux]\n\n....\ntsa = \"tmux attach-session -t\"\ntsk = \"tmux kill-session -t\"\ntsl = \"tmux list-sessions\"\ntsr = \"tmux rename-session -t\"\n....\n\n==== https://gitlab.com/procps-ng/procps:[Watch]\n\n....\nwp = \"watch --interval 1 --color --beep --exec\"\n....\n\n=== Functions\n\n==== link:https://asciidoctor.org[ASCII Doctor]\n\n....\nado = ASCII Doctor Open - Transforms ASCII Doc into HTML and opens in default browser.\n....\n\n==== https://bundler.io:[Bundler]\n\n....\nbca = Bundler Clean (all) - Clean projects of gem artifacts.\nbcg = Bundler Config Gem - Configure Bundler to use local gem for development purposes.\nbl = Bundle List - List gem dependencies for project and copy them to clipboard.\nboa = Bundle Outdated (all) - Answer outdated gems for projects in current directory.\nbu = Bundle Update - Update all gems or a single gem in current project.\nbua = Bundle Update (all) - Update gems for projects in current directory.\n....\n\n==== https://alchemists.io/projects/caliber:[Code Quality]\n\n....\ncqa = Code Quality (all) - Run code quality tasks for projects in current directory.\ncqi = Code Quality Issues - List all source files affected by code quality issues.\n....\n\n==== https://curl.se:[curl]\n\n....\ncurld = Curl Diagnostics - Curl with diagnostic information for request.\ncurli = Curl Inspect - Inspect remote file with default editor.\n....\n\n==== https://www.docker.com:[Docker]\n\n....\ndrc = Docker Comppose - Run Docker Comppose for development (default) or production.\ndrcb = Docker Compose Build - Build service for development (default) or production.\ndrcd = Docker Compose Down - Shutdown services for development (default) or production.\ndrce = Docker Compose Execute - Execute command for development (default) or production.\ndrcr = Docker Compose Run - Run oneoff command for development (default) or production.\ndrcu = Docker Compose Up - Startup services for development (default) or production.\n....\n\n==== Dotfiles\n\n....\ndots = Dotfiles - Learn about dotfile aliases, functions, etc.\n....\n\n==== https://github.com/Schniz/fnm:[Fast Node Manager]\n\n....\njsf = JavaScript Force - Installs new Node version as default and removes previous version.\njsua = JavaScript Upgrade (all) - Upgrade JavaScript projects in current directory to new JavaScript version.\n....\n\n==== General\n\n....\ncype = Colorized Type - Identical to \"type\" system command but with Bat support.\neup = Environment Update - Update environment with latest software.\niso = ISO - Builds an ISO image from mounted volume.\nkilp = Kill Process - Kill errant/undesired process.\nt2s = Tab to Space - Convert file from tab to space indentation.\n....\n\n==== https://git-scm.com:[Git]\n\n....\nga = Git Add - Interactively adds modified/untracked files.\ngafe = Git Safe - Marks repository as safe for auto-loading project's `bin` path.\ngalla = Git Add (all) - Apply file changes (including new files) for projects in current directory.\ngash = Git Stash - Creates stash of all changes.\ngasha = Git Stash (all) - Answer stash count for projects in current directory.\ngashc = Git Stash Clear - Clears all stashes.\ngashd = Git Stash Drop - Drop stash or prompt for stash to drop.\ngashi = Git Stash Import - Imports a remote stash.\ngashl = Git Stash List - List stashes.\ngashp = Git Stash Pop - Pop stash or prompt for stash to pop.\ngashs = Git Stash Show - Show stash or prompt for stash to show.\ngasht = Git Stash Stage - Creates stash of staged work.\ngbc = Git Branch Create - Create and switch to branch.\ngbca = Git Branch Create (all) - Create and switch to branch for projects in current directory.\ngbd = Git Branch Delete - Interactively delete local and/or remote branch.\ngbdl = Git Branch Delete (local) - Delete local branch.\ngbdm = Git Branch Delete (merged) - Delete remote and local merged branches.\ngbdr = Git Branch Delete (remote) - Delete remote branch.\ngbf = Git Branch Facsimile - Duplicate current branch with new name and switch to it.\ngbl = Git Branch List - List local and remote branch details.\ngbla = Git Branch List (all) - List current branch for projects in current directory.\ngblo = Git Branch List (owner) - List branches owned by current author or supplied author.\ngbna = Git Branch Number (all) - Answer number of branches for projects in current directory.\ngbr = Git Branch Rename - Rename current branch.\ngbs = Git Branch Switch - Switch between branches.\ngbsa = Git Branch Switch (all) - Switch to given branch for projects in current directory.\ngcaa = Git Commit (all) - Commit changes (unstaged and staged) for projects in current directory.\ngcap = Git Commit and Push (all) - Commit and push changes for projects in current directory.\ngcb = Git Commit Breakpoint - Create a breakpoint (empty) commit to denote related commits in a feature branch.\ngcf = Git Commit Fixup - Create fixup commit with optional amend or reword support.\ngcff = Git Commit Fix (file) - Create commit fix for file (ignores previous fixups).\ngcfi = Git Commit Fix (interactive) - Select which commit to fix within current feature branch.\ngdf = Git Diff Files - List all added/changed files on current branch.\ngday = Git Day - Answer summarized list of current day activity for projects in current directory.\ngesh = Git Reset Hard - Reset to HEAD, destroying all untracked, staged, and unstaged changes. UNRECOVERABLE!\ngesha = Git Reset Hard (all) - Destroy all untracked, staged, and unstaged changes for all projects in current directory. UNRECOVERABLE!\ngess = Git Reset Soft - Resets previous commit (default), resets back to number of commits, or resets to specific commit.\nggeta = Git Get Config Value (all) - Answer key value for projects in current directory.\ngga = Git Guise Add - Adds Git configuration and associated profile.\nggd = Git Guise Delete - Deletes Git configuration and associated profile.\nghow = Git Show - Show commit details with optional diff support.\nghurn = Git Churn - Answer commit churn for project files (sorted highest to lowest).\ngia = Git Init (all) - Initialize/re-initialize repositories in current directory.\ngile = Git File - Show file details for a specific commit (with optional diff support).\ngim = Git Import - Import remote repository commits into current local branch.\ngince = Git Since - Answer summarized list of activity since date/time for projects in current directory.\nginfo = Git Info - Print repository overview information.\ngistory = Git File History - View file commit history (with optional diff support).\nglameh = Git Blame History - View commit history for file and/or lines (with optional diff support).\ngleana = Git Clean (all) - Clean uncommitted files from all projects in current directory.\nglear = Git Clear - Clear repository for packaging/shipping purposes.\nglg = Git Log Grep - Grep Git log by query.\ngli = Git Log (interactive) - List default or feature branch commits with commit show and/or diff support.\ngls = Git Log Search - Search Git log by query.\nglz = Git Log Fuzzy - Fuzzy find commits in the log.\ngm = Git Merge - Interactively select a branch to merge into the current branch and delete after.\ngma = Git Merge (all) - Merges, deletes, and pushes feature branch.\ngmonth = Git Month - Answer summarized list of current month activity for projects in current directory.\ngmpa = Git Amend Push (all) - Amend all changes and force push with lease for projects in current directory.\ngnai = Git Notes Add (interactive) - Select which commit note to add for current feature branch.\ngnei = Git Notes Edit (interactive) - Select which commit note to edit for current feature branch.\ngndi = Git Notes Remove (interactive) - Select which commit note to remove for current feature branch.\ngnri = Git Notes Show (interactive) - Select which commit note to show for current feature branch.\ngount = Git Commit Count - Answer total number of commits for current project.\ngpa = Git Push (all) - Push changes for projects in current directory.\ngpua = Git Pull (all) - Pull new changes from remote branch for projects in current directory.\ngra = Git Remote Add - Add remote repository.\ngrd = Git Remote Delete - Delete local remote.\ngrbi = Git Rebase (interactive) - Rebase commits, interactively.\ngrbq = Git Rebase (quick) - Rebase commits, quickly. Identical to `grbi` function but skips editor.\ngroot = Git Root - Change to repository root directory regardless of current depth.\ngseta = Git Set Config Value (all) - Set key value for projects in current directory.\ngsta = Git Status (all) - Answer status of projects with uncommited/unpushed changes.\ngstats = Git Statistics - Answer statistics for current project.\ngstatsa = Git Statistics (all) - Answer statistics for all projects in current directory.\ngsup = Git Standup - Answer summarized list of activity since yesterday for projects in current directory.\ngtd = Git Tag Delete - Delete local and remote tag (if found).\ngtl = Git Tag List - List tags in tabular form.\ngtr = Git Tag Rebuild - Rebuild a previous tag. WARNING: Use with caution, especially if previously published.\ngtail = Git Tail - Answer commit history since last tag for current project (copies results to clipboard).\ngtaila = Git Tail (all) - Answer commit history count since last tag for projects in current directory.\ngucca = Git Upstream Commit Count (all) - Answer upstream commit count since last pull for projects in current directory.\nguke = Git Nuke - Permanently destroy and erase a file from history. UNRECOVERABLE!\ngarb = Git Garbage Collect - Garbage collect dangling commits for projects in current directory.\ngunseta = Git Unset (all) - Unset key value for projects in current directory.\ngup = Git Update - Fetch commits, prune untracked references, review each commit (optional, with diff), and pull (optional).\nguthorc = Git Author Contributions - Answers total lines added/removed by author for repo (with emphasis on deletion).\nguthorsa = Git Authors (all) - Answer author commit activity per project (ranked highest to lowest).\ngvac = Git Verify and Clean - Verify and clean objects for current project.\ngvaca = Git Verify and Clean (all) - Verify and clean objects for projects in current directory.\ngwa = Git Worktree Add - Add and switch to new worktree.\ngwd = Git Worktree Delete - Deletes current Git worktree.\ngweek = Git Week - Answer summarized list of current week activity for projects in current directory.\ngync = Git Sync - Syncs up remote changes and deletes pruned/merged branches.\n....\n\n==== https://github.com:[GitHub]\n\n....\ngh = GitHub - View GitHub details for current project.\nghpra = GitHub Pull Request (all) - Open pull requests for all projects in current directory (non-default branches only).\n....\n\n==== https://en.wikipedia.org/wiki/Less_(Unix):[less]\n\n....\nlessi = Less Interactive - Inspect file, interactively.\n....\n\n==== https://github.com/pivotal/LicenseFinder:[License Finder]\n\n....\nlicensea = License Finder (add) - Adds library to global list.\nlicensei = License Finder (include) - Include license in global list.\n....\n\n==== https://people.freebsd.org/~abe:[lsof]\n\n....\nport = Port - List file activity on given port.\n....\n\n==== https://marked2app.com:[Marked 2]\n\n....\nmo = Marked Open - Opens Markdown file in Marked.\n....\n\n==== https://alchemists.io/projects/milestoner:[Milestoner]\n\n....\nmsa = Milestoner (ASCII Doc) - Build milestone(s) in ASCII Doc format.\nmsf = Milestoner (feed) - Build milestone(s) in feed (atom) format.\nmsm = Milestoner (Markdown) - Build milestone(s) in Markdown format.\nmss = Milestoner (stream) - Build milestone(s) in stream format.\nmsw = Milestoner (web) - Build milestone(s) in web format.\n....\n\n==== https://jedisct1.github.io/minisign:[Minisign]\n\n....\nsigf = Minisign Sign File - Sign a file.\nsigg = Minisign Generate - Generate private and public key pair.\nsigv = Minisign Verify File - Verify signed file.\n....\n\n==== https://en.wikipedia.org/wiki/Network_Computer:[Network]\n\n....\ndnsf = DNS Flush - Flush DNS cache.\n....\n\n==== https://openssl.org:[OpenSSL]\n\n....\nsslc = SSL Certificate Creation - Create SSL certificate.\n....\n\n==== https://github.com/DarthSim/overmind:[Overmind]\n\n....\nomc = Overmind Connect - Connect to running process.\nomr = Overmind Restart - Restart running process.\noms = Overmind Start - Start processes.\n....\n\n==== https://github.com/theory/pgenv:[pgenv]\n\n....\npgi = PostgreSQL Install - Install (build) specific version.\n....\n\n==== https://www.postgresql.org:[PostgreSQL]\n\n....\npgt = PostgreSQL Template - Edit PostgreSQL template.\npguc = PostgreSQL User Create - Create PostgreSQL user.\npgud = PostgreSQL User Drop - Drop PostgreSQL user.\n....\n\n==== https://github.com/ruby/rake:[Rake]\n\n....\nrakea = Rake (all) - Run default Rake tasks for projects in current directory.\n....\n\n==== https://rspec.info:[RSpec]\n\n....\nrsall = RSpec (all) - Run RSpec for projects in current directory.\nrsb = RSpec Bisect - Debug RSpec failure using bisect to automatically determine the root cause.\nrsd = RSpec Debug - Debug intermittent RSpec failure(s) by running spec(s) until failure is detected.\nrsp = RSpec Profile - Runs RSpec specs with profiling enabled.\n....\n\n==== https://docs.rubocop.org:[Rubocop]\n\n....\ncopa = Rubocop (all) - Run Rubocop for all projects in current directory.\n....\n\n==== https://www.ruby-lang.org:[Ruby]\n\n....\nrbi = Ruby Install - Install a specific version with safe defaults.\nreb = Ruby Web Server - Serve web content via WEBrick.\nrbw = Ruby Which - Locate path to current Ruby program.\nrbua = Ruby Upgrade (all) - Upgrade Ruby projects in current directory to new Ruby version.\nrbva = Ruby Version (all) - Show current Ruby version for all projects in current directory.\n....\n\n==== https://rubygems.org:[Ruby Gems]\n\n....\ngemd = Gem Dependencies - Answers dependencies for a gem.\ngemdep = Gem Dependency Search - Finds a gem defined within a Gemfile or a gemspec.\n....\n\n==== https://rubyonrails.org:[Ruby on Rails]\n\n....\nrailsn = Ruby on Rails New - Create new Rails application from selected option.\n....\n\n==== https://github.com/colszowka/simplecov:[SimpleCov]\n\n....\ncova = RSpec (all) - Run RSpec for projects in current directory.\n....\n\n=== Git Hooks\n\n....\nbrakeman_check = Brakeman Check - Scan Rails project for security vulnerabilities.\nbundler_gemfile_path = Bundler Gemfile Path - Detect gem path statements.\nbundler_audit_check = Bundler Audit Check - Scans gem dependencies for security vulnerabilities.\ncomment_totals = Comment Totals - Print project comment totals.\nctags_rebuild = CTags Rebuild - Rebuild project .tags file.\ndotenv_check = Dotenv Linter - Scan environment files for consistent style and security issues.\ngit_lint_check = Git Lint Check - Enforce consistent Git commits.\ngit_trailer_cleaner = Git Trailer Cleaner - Remove unused/empty Git commit body trailers.\ngit_add_trailers = Git Add Trailers - Dynamically add trailers based on branch description.\njava_script_debugger = JavaScript Debugger - Detect JavaScript debug statements.\njava_script_console = JavaScript Console - Detect JavaScript console statements.\njava_script_alert = JavaScript Alert - Detect JavaScript alert statements.\nlicense_finder_check = License Finder Check - Scan project for valid licenses.\nosv_check = Open Source Vulnerability (OSV) Check - Scan Ruby dependencies for vulnerabilities.\nreek_branch_check = Reek Branch Check - Scan Ruby code -- feature branch only -- for poor style choices.\nreek_stage_check = Reek Stage Check - Scan Ruby code -- staged files only -- for poor style choices.\nrspec_dotfile = RSpec Dotfile - Detect RSpec dotfile.\nrspec_order = RSpec Order - Detect RSpec ordered specs.\nrubocop_branch_check = RuboCop Branch Check - Scan Ruby code -- feature branch only -- for poor style choices.\nrubocop_stage_check = RuboCop Stage Check - Scan Ruby code -- staged files only -- for poor style choices.\n....\n\n== Development\n\nTo contribute, run:\n\n[source,bash]\n----\ngit clone https://github.com/bkuhlmann/dotfiles.git\ncd dotfiles\n----\n\n== link:https://alchemists.io/policies/license[License]\n\n== link:https://alchemists.io/policies/security[Security]\n\n== link:https://alchemists.io/policies/code_of_conduct[Code of Conduct]\n\n== link:https://alchemists.io/policies/contributions[Contributions]\n\n== link:https://alchemists.io/policies/developer_certificate_of_origin[Developer Certificate of Origin]\n\n== link:https://alchemists.io/projects/dotfiles/versions[Versions]\n\n== link:https://alchemists.io/community[Community]\n\n== Credits\n\nEngineered by link:https://alchemists.io/team/brooke_kuhlmann[Brooke Kuhlmann].\n"
  },
  {
    "path": "Rakefile",
    "content": "# frozen_string_literal: true\n\nrequire \"git/lint/rake/register\"\nrequire \"rubocop/rake_task\"\n\nGit::Lint::Rake::Register.call\nRuboCop::RakeTask.new\n\ndesc \"Run code quality checks\"\ntask quality: %i[git_lint rubocop]\n\ntask default: :quality\n"
  },
  {
    "path": "bin/rake",
    "content": "#! /usr/bin/env ruby\n# frozen_string_literal: true\n\nrequire \"bundler/setup\"\n\nload Gem.bin_path \"rake\", \"rake\"\n"
  },
  {
    "path": "bin/run",
    "content": "#! /usr/bin/env bash\n\n# DESCRIPTION\n# Executes the command line interface.\n\n# SETTINGS\nset -o errexit\nset -o pipefail\n\n# LIBRARY\nsource lib/utilities.sh\nsource lib/options.sh\n\n# EXECUTION\nif [[ -d \"$HOME\" ]]; then\n  while true; do\n    if [[ $# == 0 ]]; then\n      printf \"\\n%s\\n\" \"Usage: run OPTION\"\n      printf \"\\n%s\\n\" \"Dotfile Options:\"\n      printf \"  %s\\n\" \"s: Show managed files.\"\n      printf \"  %s\\n\" \"i: Install (existing files are skipped).\"\n      printf \"  %s\\n\" \"l: Link (interactive, excludes: environment.sh and git/configuration).\"\n      printf \"  %s\\n\" \"c: Check for differences between \\$HOME files and this project's files.\"\n      printf \"  %s\\n\" \"d: Delete (interactive, excludes: environment.sh and git/configuration).\"\n      printf \"  %s\\n\\n\" \"q: Quit/Exit.\"\n      read -r -p \"Enter selection: \" response\n      printf \"\\n\"\n      process_option $response\n    else\n      process_option $1\n    fi\n    break\n  done\nelse\n  printf \"%s\\n\" \"ERROR: $HOME does not exist.\"\n  return 1\nfi\n"
  },
  {
    "path": "lib/options.sh",
    "content": "#! /usr/bin/env bash\n\n# DESCRIPTION\n# Defines command line prompt options.\n\n# Process option selection.\n# Parameters:\n# $1 = The option to process.\nprocess_option() {\n  case $1 in\n    's')\n      show_files;;\n    'i')\n      install_files;;\n    'l')\n      link_files;;\n    'c')\n      check_files;;\n    'd')\n      delete_files;;\n    'q');;\n    *)\n      printf \"%s\\n\" \"ERROR: Invalid option.\";;\n  esac\n}\nexport -f process_option\n"
  },
  {
    "path": "lib/templates/.agignore.tt",
    "content": "/log/\n/logs/\n/tmp/\n/.git/\n\n*.tags\n*.tags*\n"
  },
  {
    "path": "lib/templates/.bash_profile.tt",
    "content": "#! /usr/bin/env bash\n\n# Send to .bashrc for all settings.\nif [[ -f $HOME/.bashrc ]]; then\n  . $HOME/.bashrc\nfi\n"
  },
  {
    "path": "lib/templates/.bashrc.tt",
    "content": "#! /usr/bin/env bash\n\nif [[ BASH_VERSINFO[0] < 4 ]]; then\n  printf \"%s\\n\" \"WARNING: Dotfiles requires Bash 4.x.x or higher to work correctly.\"\nfi\n\n# Editors\nexport EDITOR=sublime\nexport VISUAL=vim\n\n# History\nexport HISTFILE=\"$HOME/.config/bash/history.log\"\nexport HISTTIMEFORMAT=\"%F %T \" # Use YYYY-MM-DD HH:MM:SS date/time format.\nexport HISTCONTROL=\"erasedups:ignoreboth\" # Remove duplicate entries.\nexport HISTSIZE=10000 # Keep lengthy command history.\nexport HISTIGNORE=\"#*:..:...:c:h:l:l1:p:pwd:gst:gd:exit:* --help\" # Exclude mundane commands.\n\n# XDG\nexport XDG_CONFIG_HOME=\"$HOME/.config\"\nexport XDG_CACHE_HOME=\"$HOME/.cache\"\nexport PATH=\"$HOME/.local/bin:$PATH\"\n\n# Homebrew\nexport PATH=\"/opt/homebrew/bin:/opt/homebrew/sbin:$PATH\"\nexport HOMEBREW_BAT=1\nexport HOMEBREW_BOOTSNAP=1\nexport HOMEBREW_CURL_RETRIES=3\nexport HOMEBREW_FORCE_BREWED_CA_CERTIFICATES=1\nexport HOMEBREW_FORCE_BREWED_CURL=1\nexport HOMEBREW_FORCE_BREWED_GIT=1\nexport HOMEBREW_NO_ANALYTICS=1\nexport HOMEBREW_NO_AUTO_UPDATE=1\nexport HOMEBREW_NO_INSECURE_REDIRECT=1\nexport HOMEBREW_NO_INSTALL_CLEANUP=1\nexport HOMEBREW_PREFIX=\"$(brew --prefix)\"\n\n# Environment\nsource \"$HOME/.config/bash/environment.sh\"\n\n# Colors\nsource \"$HOME/.config/bash/colors.sh\"\n\n# Aliases\nsource \"$HOME/.config/bash/aliases.sh\"\n\n# Functions\nsource \"$HOME/.config/bash/functions-private.sh\"\nsource \"$HOME/.config/bash/functions-public.sh\"\n\n# Command Prompt (http://jonisalonen.com/2012/your-bash-prompt-needs-this)\nsource \"$HOME/.config/bash/prompt.sh\"\n\n# Bash Completion\nsource \"$HOMEBREW_PREFIX/etc/profile.d/bash_completion.sh\" || :\n\n# OpenSSL\nexport PATH=\"$HOMEBREW_PREFIX/opt/openssl/bin:$PATH\"\n\n# Rust\nexport PATH=\"$HOME/.cargo/bin:$PATH\"\n\n# Docker\nexport DOCKER_CONFIG=$HOME/.config/docker\n\n# GPG\nexport GPG_TTY=$(tty)\n\n# direnv\nif [[ -e \"$HOMEBREW_PREFIX/bin/direnv\" ]]; then\n  eval \"$(direnv hook bash)\"\nfi\n\n# Eza\nexport EZA_STRICT=true\nexport EZA_COLORS=\"da=1;34:di=32:gm=33:gd=31\"\n\n# Ruby\nexport BUNDLE_USER_CACHE=\"$HOME/.cache/bundler\"\nexport BUNDLE_USER_CONFIG=\"$HOME/.config/bundler/configuration.yml\"\nexport BUNDLE_USER_HOME=\"$HOME/.local/share/bundler\"\nexport BUNDLE_USER_PLUGIN=\"$HOME/.local/share/bundler/plugin\"\nexport RUBYOPT=\"-W:deprecated -W:performance -W:strict_unused_block --yjit --debug-frozen-string-literal\"\n\n# Fast Node Manager\nexport FNM_DIR=\"$HOME/.cache/fnm\"\neval \"$(fnm env --use-on-cd)\"\n\n# Frum\nexport FRUM_DIR=\"$HOME/.cache/frum\"\neval \"$(frum init)\"\n\n# Fx\nexport FX_LINE_NUMBERS=true\nexport FX_SHOW_SIZE=true\nexport FX_THEME=8\n\n# FZF\nexport FZF_DEFAULT_COMMAND=\"fd --type file --follow --hidden --color always --exclude .git\"\nexport FZF_DEFAULT_OPTS=\"--multi --ansi\"\n\n# Make\nexport MAKEFLAGS=\"--jobs=$(sysctl -n hw.ncpu)\"\n\n# Node\nexport PATH=\"$PATH:$HOMEBREW_PREFIX/share/npm/bin\"\n\n# Obsidian\nexport PATH=\"$PATH:/Applications/Obsidian.app/Contents/MacOS\"\n\n# OrbStack\nsource \"$HOME/.orbstack/shell/init.bash\" 2>/dev/null || :\n\n# pgenv\nexport PGENV_ROOT=\"$HOME/.cache/pgenv\"\nexport PATH=\"$HOME/.cache/pgenv/bin:$HOME/.cache/pgenv/pgsql/bin:$PATH\"\n\n# Terraform\nexport TF_PLUGIN_CACHE_DIR=\"$HOME/.cache/terraform/plugins\"\n\n# Git\nexport GIT_CONFIG_GLOBAL=\"$HOME/.config/git/configuration\"\nsource \"$HOMEBREW_PREFIX/opt/git/etc/bash_completion.d/git-completion.bash\" || :\nexport PATH=\".git/safe/../../bin:$PATH\"\n\n# Zoxide\nexport _ZO_DATA_DIR=\"$HOME/.cache/zoxide\"\neval \"$(zoxide init bash)\"\n\n# Checks the window size after each command and, if necessary, updates LINES and COLUMNS values.\nshopt -s checkwinsize\n\n# Attempts to save all lines of a multi-line command as a single history entry for easy re-editing.\nshopt -s cmdhist\n\n# Attempts word spelling correction on directory names if directory name supplied does not exist.\nshopt -s dirspell\n\n# Enables extended pattern matching features.\nshopt -s extglob\n\n# Using ** in a pathname expansion context will match all files and zero or more directories and\n# subdirectories. If the pattern is followed by a /, only directories and subdirectories match.\nshopt -s globstar\n\n# The history list is appended (instead of being overwritten) as defined by the HISTFILE variable.\nshopt -s histappend\n\n# Enables history expansion with space (i.e. `!!<space>`).\nbind Space:magic-space\n"
  },
  {
    "path": "lib/templates/.cache/pgenv/config/default.conf.tt",
    "content": "# Enables debug output\n#export PGENV_DEBUG=''\n\n# Enables warning messages\n#export PGENV_WARNINGS=''\n\n###### Build settings #####\n# Make command to use for build\nexport PGENV_MAKE='/usr/bin/make'\n\n# Make flags\ndeclare -a PGENV_MAKE_OPTIONS=([0]=\"-j3\")\nexport PGENV_MAKE_OPTIONS\n\n# Configure PostgreSQL build flags.\nPGENV_CONFIGURE_OPTIONS=(\n  --enable-thread-safety\n  --with-bonjour\n  --with-llvm\n  --with-openssl\n  --with-uuid=e2fs\n  PKG_CONFIG_PATH=$HOMEBREW_PREFIX/opt/icu4c/lib/pkgconfig\n  LLVM_CONFIG=$HOMEBREW_PREFIX/opt/llvm@20/bin/llvm-config\n  CLANG=$HOMEBREW_PREFIX/opt/llvm@20/bin/clang\n  \"CPPFLAGS=-I$HOMEBREW_PREFIX/opt/icu4c/include -I$HOMEBREW_PREFIX/opt/openssl/include -I$HOMEBREW_PREFIX/opt/readline/include\"\n  \"CFLAGS=-I$HOMEBREW_PREFIX/opt/icu4c/include -I$HOMEBREW_PREFIX/opt/openssl/include -I$HOMEBREW_PREFIX/opt/readline/include\"\n  \"LDFLAGS=-L$HOMEBREW_PREFIX/opt/icu4c/lib -L$HOMEBREW_PREFIX/opt/openssl/lib -L$HOMEBREW_PREFIX/opt/readline/lib\"\n)\n\n# A file that lists ordered patches to apply before building starts\n#export PGENV_PATCH_INDEX=''\n\n# Curl command to download source code\nexport PGENV_CURL='/usr/bin/curl'\n\n# Patch command for specific versions\nexport PGENV_PATCH='/usr/bin/patch'\n\n# Sed used to manipulate strings\nexport PGENV_SED='/usr/bin/sed'\n\n##### Runtime options #####\n# Path to the cluster log file (mandatory)\nexport PGENV_LOG=\"$HOME/.cache/pgenv/pgsql/data/server.log\"\n\n# Initdb flags\ndeclare -a PGENV_INITDB_OPTIONS=([0]=\"-U\" [1]=\"postgres\" [2]=\"--locale\" [3]=\"en_US.UTF-8\" [4]=\"--encoding\" [5]=\"UNICODE\")\nexport PGENV_INITDB_OPTIONS\n\n# Stop configuration flags\ndeclare -a PGENV_STOP_OPTIONS=()\nexport PGENV_STOP_OPTIONS\n\n# Start configuration flags\ndeclare -a PGENV_START_OPTIONS=()\nexport PGENV_START_OPTIONS\n\n# Restart configuration flags\ndeclare -a PGENV_RESTART_OPTIONS=()\nexport PGENV_RESTART_OPTIONS\n\n# Script to execute when the build process finishes\n#export PGENV_SCRIPT_POSTINSTALL=''\n\n# Script to execute when initdb finishes (and the server has not started yet)\nexport PGENV_SCRIPT_FIRSTSTART=\"$HOME/.config/pgenv/initialize\"\n\n# Script to execute at the very first start of the instance\n#export PGENV_SCRIPT_FIRSTSTART=''\n\n# Script to execute before the cluster stops\n#export PGENV_SCRIPT_PRESTOP=''\n\n# Script to execute when the cluster has been stopped\n#export PGENV_SCRIPT_POSTSTOP=''\n\n# Script to execute when the cluster has been started\n#export PGENV_SCRIPT_POSTSTART=''\n\n# Script to execute when the cluster has been restarted\n#export PGENV_SCRIPT_POSTRESTART=''\n\n# Ensures configuration is preserved.\nexport PGENV_WRITE_CONFIGURATION_FILE_AUTOMATICALLY=no\n"
  },
  {
    "path": "lib/templates/.config/aprc.tt",
    "content": "AmazingPrint.defaults = {\n  indent: 2,\n  index: false\n}\n"
  },
  {
    "path": "lib/templates/.config/bash/aliases.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Section: https://asciidoctor.org:[ASCII Doctor]\nalias ad=\"asciidoctor\"\n\n# Section: https://www.gnu.org/software/bash:[Bash]\nalias bashe='$EDITOR $HOME/.config/bash/environment.sh'\nalias bashs='exec $SHELL'\n\n# Section: https://bundler.io:[Bundler]\nalias ba=\"bundle add\"\nalias bb=\"bundle binstubs\"\nalias bce='$EDITOR $BUNDLE_USER_CONFIG'\nalias bch=\"rm -f Gemfile.lock; bundle check\"\nalias bd=\"bundle doctor\"\nalias be=\"bundle exec\"\nalias bi=\"bundle install\"\nalias blo='bundle list --paths | fzf | xargs $EDITOR'\nalias bo=\"bundle outdated --only-explicit\"\nalias br=\"bundle remove\"\n\n# Section: https://crystal-lang.org:[Crystal]\nalias cr=\"crystal\"\nalias crb=\"crystal build\"\nalias crd=\"crystal docs\"\nalias crdo=\"open docs/index.html\"\nalias crr=\"crystal run\"\nalias crs=\"crystal spec\"\n\n# Section: https://direnv.net:[direnv]\nalias denva=\"direnv allow\"\nalias denvr=\"direnv reload\"\nalias denvs=\"direnv status\"\n\n# Section: https://www.docker.com:[Docker]\nalias dr=\"docker\"\nalias drb=\"docker build\"\nalias drd=\"docker system prune --force && docker buildx prune --force\"\nalias dri=\"docker images\"\nalias drp=\"docker ps --all\"\nalias drt=\"docker tag\"\n\n# Section: http://duti.org:[duti]\nalias dutia='duti $HOME/.config/duti/configuration.duti'\n\n# Section: https://eza.rocks:[Eza]\nalias x1=\"eza --oneline --all --group-directories-first\"\nalias x=\"eza --all --all --long --header --group --group-directories-first --time-style long-iso --git\"\nalias xt=\"eza --tree --all --group-directories-first --ignore-glob '*.git' --git-ignore\"\nalias xtv=\"eza --tree --all --group-directories-first --ignore-glob '*.git'\"\n\n# Section: https://github.com/Schniz/fnm:[Fast Node Manager]\nalias js=\"fnm\"\nalias jsd=\"fnm default\"\nalias jse=\"fnm env\"\nalias jsi=\"fnm install\"\nalias jsl=\"fnm list\"\nalias jss=\"fnm use\"\nalias jsu=\"fnm uninstall\"\n\n# Section: https://github.com/TaKO8Ki/frum:[Frum]\nalias rb=\"frum\"\nalias rbd=\"frum global\"\nalias rbl=\"frum versions\"\nalias rbs=\"frum local\"\nalias rbu=\"frum uninstall\"\n\n# Section: https://github.com/junegunn/fzf:[Fuzzy Finder]\nalias ff=\"_fzf_preview_and_select | xargs -0 -o \\$EDITOR\"\n\n# Section: https://alchemists.io/projects/gemsmith:[Gemsmith]\nalias gsb=\"gemsmith build --name\"\nalias gsc=\"gemsmith config --edit\"\nalias gse=\"gemsmith --edit\"\nalias gsi=\"gemsmith --install\"\nalias gsp=\"gemsmith --publish\"\nalias gsq=\"rake quality\"\nalias gsv=\"gemsmith --view\"\n\n# Section: General\nalias ...=\"cd ../..\"\nalias ..=\"cd ..\"\nalias c=\"clear\"\nalias cat=\"bat --theme DarkNeon\"\nalias cdb=\"cd -\"\nalias du=\"dust\"\nalias h=\"history\"\nalias l1=\"ls -A1 | _copy_and_print '\\n'\"\nalias l=\"ls -alhT\"\nalias o=\"open\"\nalias p='pwd | tr -d \"\\r\\n\" | _copy_and_print'\nalias pss=\"pgrep -i -l -f\"\nalias rmde=\"find . -type d -empty -not -path '*.git*' -delete\"\n\n# Section: https://ghostty.org:[Ghostty]\nalias ghoste=\"$EDITOR $HOME/.config/ghostty/config.ghostty\"\n\n# Section: https://git-scm.com:[Git]\nalias gall=\"git add --all .\"\nalias gamend=\"git commit --amend\"\nalias gamenda=\"git commit --amend --all --no-edit\"\nalias gamendh=\"git commit --amend --no-edit\"\nalias gap=\"git ls-files --modified | _fzf_preview_and_select | xargs -0 -o -t git add --patch\"\nalias gatch=\"git commit --patch\"\nalias gau=\"git add --update\"\nalias gb=\"git switch\"\nalias gbb=\"git switch -\"\nalias gbe=\"git branch --edit-description\"\nalias gbi=\"git bisect\"\nalias gbv='git config get branch.$(_git_branch_name).description'\nalias gbib=\"git bisect bad\"\nalias gbig=\"git bisect good\"\nalias gbih=\"git bisect help\"\nalias gbil=\"git bisect log\"\nalias gbir=\"git bisect reset\"\nalias gbire=\"git bisect replay\"\nalias gbis=\"git bisect start\"\nalias gbisk=\"git bisect skip\"\nalias gbiv='git bisect visualize --reverse --pretty=format:\"$(_git_log_line_format)\"'\nalias gbm='git switch $(_git_branch_default)'\nalias gbn=\"_git_branch_name | _copy_and_print\"\nalias gbt=\"git show-branch --topics\"\nalias gca=\"git commit --all\"\nalias gcam=\"git commit --all --message\"\nalias gcd=\"git config list --show-origin --show-scope | fzf\"\nalias gce='cat .git/COMMIT_EDITMSG | pbcopy'\nalias gcge=\"git config edit --global\"\nalias gch=\"git checkout\"\nalias gcl=\"git clone\"\nalias gcle=\"git config edit --local\"\nalias gcm=\"git commit --message\"\nalias gco=\"git commit\"\nalias gcp=\"git cherry-pick\"\nalias gcpa=\"git cherry-pick --abort\"\nalias gcpc=\"git cherry-pick --continue\"\nalias gcps=\"git cherry-pick --skip\"\nalias gcs=\"git commit --squash\"\nalias gd=\"git diff\"\nalias gdc=\"git diff --cached\"\nalias gdm='git diff origin/$(_git_branch_default)'\nalias gdo='git diff --name-only | uniq | xargs $EDITOR'\nalias gdt=\"git difftool\"\nalias gdtc=\"git difftool --cached\"\nalias gdtm='git difftool origin/$(_git_branch_default)'\nalias gdw=\"git diff --color-words\"\nalias gel=\"git rm\"\nalias gelc=\"git rm --cached\"\nalias ges=\"git diff --name-only --cached | _fzf_preview_and_select | xargs -0 -o -t git reset\"\nalias gf=\"git fetch\"\nalias gg=\"git grep\"\nalias gge=\"git config get --global --regexp includeif | fzf | xargs \\$EDITOR\"\nalias gget=\"git config get\"\nalias gi=\"git init\"\nalias gl='git log --graph --pretty=format:\"$(_git_log_line_format)\" \"$(_git_branch_range)\"'\nalias gld='git log --stat --pretty=format:\"$(_git_log_details_format)\" \"$(_git_branch_range)\"'\nalias glame=\"git blame -M -C\"\nalias glean=\"git clean -d --force\"\nalias glf='git fetch && git log --reverse --no-merges --pretty=format:\"$(_git_log_line_format)\" ..@{upstream}'\nalias glh=\"_git_sha | _copy_and_print\"\nalias gna=\"git notes add\"\nalias gnd=\"git notes remove\"\nalias gne=\"git notes edit\"\nalias gnl=\"git notes list\"\nalias gnp=\"git notes prune\"\nalias gns=\"git notes show\"\nalias gp=\"git push\"\nalias gpf=\"git push --force-with-lease\"\nalias gpn=\"git push --no-verify\"\nalias gpu=\"git pull\"\nalias gpuo=\"git pull origin\"\nalias gpuom='git pull origin $(_git_branch_default)'\nalias gpuum='git pull upstream $(_git_branch_default)'\nalias gr=\"git ls-files --modified | _fzf_preview_and_select | xargs -0 -o -t git restore\"\nalias grba=\"git rebase --abort\"\nalias grbc=\"git rebase --continue\"\nalias grbd=\"git rebase --show-current-patch\"\nalias grbo=\"git rebase --onto\"\nalias grbs=\"git rebase --skip\"\nalias grbt=\"git rebase --edit-todo\"\nalias grev=\"git revert --no-commit\"\nalias grl=\"git reflog --relative-date\"\nalias grom='git fetch --all && git reset --hard origin/$(_git_branch_default)' # Reset local branch to origin/main branch. UNRECOVERABLE!\nalias grr=\"git rerere\"\nalias gset=\"git config set\"\nalias gst=\"git status --short --branch\"\nalias gt=\"git tag\"\nalias gte='cat .git/TAG_EDITMSG | pbcopy'\nalias gtp=\"git push --tags\"\nalias gtv=\"git tag --verify\"\nalias guthors=\"git shortlog --numbered --summary --group=author --group=trailer:Co-Authored-By\"\nalias gwl=\"git worktree list\"\nalias gwp=\"git worktree prune\"\n\n# Section: https://alchemists.io/projects/hanamismith:[Hanamismith]\nalias hsb=\"hanamismith build --name\"\nalias hse=\"hanamismith config --edit\"\nalias hsh=\"hanamismith --help\"\n\n# Section: https://brew.sh:[Homebrew]\nalias hb=\"brew\"\nalias hbd=\"brew doctor\"\nalias hbi=\"brew install\"\nalias hbin=\"brew info\"\nalias hbl=\"brew list --versions | fzf\"\nalias hblc=\"brew list --casks --versions | fzf\"\nalias hblf=\"brew list --formulae --versions | fzf\"\nalias hbp=\"brew pin\"\nalias hbpu=\"brew unpin\"\nalias hbr=\"brew reinstall\"\nalias hbs=\"brew search\"\nalias hbsu=\"brew update && brew upgrade && brew cleanup\"\nalias hbu=\"brew uninstall\"\nalias hbug=\"brew update && brew upgrade\"\n\n# Section: https://trac.webkit.org/wiki/JSC:[JavaScript Core]\nalias jsc=\"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc\"\n\n# Section: https://jless.io:[jless]\nalias jlr=\"jless --mode line\"\n\n# Section: https://alchemists.io/projects/milestoner:[Milestoner]\nalias ms=\"milestoner\"\nalias mse=\"milestoner config --edit\"\nalias msp=\"milestoner --publish\"\n\n# Section: https://en.wikipedia.org/wiki/Network_Computer:[Network]\nalias dnsi=\"scutil --dns\"\nalias dnss=\"sudo dscacheutil -statistics\"\nalias ipa='curl --silent checkip.dyndns.org | rg --only-matching \"[0-9\\.]+\" | _copy_and_print'\nalias key=\"open /Applications/Utilities/Keychain\\ Access.app\"\nalias ping=\"gping\"\nalias speed=\"networkQuality\"\nalias sshe='$EDITOR $HOME/.ssh/config'\nalias top=\"htop\"\n\n# Section: https://www.npmjs.com:[NPM]\nalias na=\"npm login\"\nalias nb=\"npm run build\"\nalias ni=\"npm install\"\nalias nid=\"npm install --save-dev\"\nalias nl=\"npm ls\"\nalias no=\"npm outdated\"\nalias np=\"npm publish\"\nalias nq=\"npm run quality\"\nalias nt=\"npm test\"\nalias ntw=\"npm run test:watch\"\n\n# Section: https://github.com/theory/pgenv:[pgenv]\nalias pgc=\"pgenv clear\"\nalias pgl=\"pgenv log\"\nalias pgs=\"pgenv use\"\nalias pgsp=\"pgenv stop\"\nalias pgst=\"pgenv start\"\nalias pgu=\"pgenv remove\"\nalias pgv=\"pgenv versions\"\n\n# Section: https://redis.io:[Redis]\nalias redc=\"redis-cli\"\nalias reds='redis-server $HOMEBREW_PREFIX/etc/redis.conf &'\n\n# Section: https://github.com/AlexB52/retest[Retest]\nalias rt=\"COVERAGE=no retest\"\n\n# Section: https://github.com/BurntSushi/ripgrep:[ripgrep]\nalias rgf=\"rg --files --glob\"\n\n# Section: https://rspec.info:[RSpec]\nalias rsf=\"COVERAGE=no rspec spec --only-failures\"\nalias rsn=\"COVERAGE=no rspec spec --next-failure\"\nalias rso=\"COVERAGE=no rspec spec --dry-run --format doc > tmp/rspec-overview.txt && e tmp/rspec-overview.txt\"\nalias rsr=\"COVERAGE=no rspec\"\nalias rss=\"rspec\"\nalias rst=\"COVERAGE=no rspec spec --tag\"\n\n# Section: https://github.com/bbatsov/rubocop:[Rubocop]\nalias cop=\"rubocop --parallel --display-cop-names --display-style-guide\"\nalias copc=\"rubocop --auto-gen-config\"\nalias copf=\"rubocop --autocorrect\"\nalias copfo=\"rubocop --autocorrect --only\"\nalias copo=\"rubocop --display-cop-names --only\"\nalias cops=\"rubocop --show-cops\"\nalias copu=\"rubocop --autocorrect-all\"\n\n# Section: https://www.ruby-lang.org:[Ruby]\nalias rbbe='$EDITOR $HOME/Engineering/Misc/benchmark'\nalias rbbr='$HOME/Engineering/Misc/benchmark'\nalias rbde='$EDITOR $HOME/Engineering/Misc/demo'\nalias rbdr='$HOME/Engineering/Misc/demo'\nalias rbdw='viddy $HOME/Engineering/Misc/demo'\n\n# Section: https://rubyonrails.org:[Ruby on Rails]\nalias railsb=\"rails console --sandbox\"\nalias railse=\"EDITOR='sublime --wait' rails credentials:edit\"\n\n# Section: https://rubygems.org:[RubyGems]\nalias gemc=\"gem cleanup\"\nalias gemcli=\"rg 'spec\\.executables' --no-messages --max-depth=2 --files-with-matches gemspec . | xargs basename | cut -d. -f1 | sort | _copy_and_print '\\n'\"\nalias gemcr='$EDITOR $HOME/.gem/credentials'\nalias gemb=\"gem build\"\nalias geme=\"gem environment\"\nalias gemi=\"gem install\"\nalias geml=\"gem list\"\nalias gemp=\"gem pristine\"\nalias gemu=\"gem uninstall\"\nalias gemuc=\"gem update --system && gem update && gem cleanup\"\n\n# Section: https://alchemists.io/projects/rubysmith:[Rubysmith]\nalias rbb=\"rubysmith build --name\"\nalias rbe=\"rubysmith config --edit\"\nalias rbh=\"rubysmith --help\"\n\n# Section: https://github.com/colszowka/simplecov:[SimpleCov]\nalias cov=\"open coverage/index.html\"\n\n# Section: https://www.sublimetext.com:[Sublime Text]\nalias e=\"sublime\"\n\n# Section: https://www.gnu.org/software/tar/tar.html:[Tar]\nalias bzc=\"tar --use-compress-program=pigz --create --preserve-permissions --bzip2 --verbose --file\"\nalias bzx=\"tar --extract --bzip2 --verbose --file\"\n\n# Section: https://www.terraform.io:[Terraform]\nalias tf=\"terraform\"\nalias tfa=\"noti --title 'Terraform Apply' terraform apply\"\nalias tfc=\"terraform console\"\nalias tff=\"terraform fmt -recursive\"\nalias tfg=\"terraform graph | dot -Tsvg > tmp/graph.svg && open -a 'Firefox.app' tmp/graph.svg\"\nalias tfi=\"terraform init\"\nalias tfo=\"terraform output\"\nalias tfp=\"noti --title 'Terraform Plan' terraform plan\"\nalias tft=\"terraform taint\"\nalias tfu=\"terraform untaint\"\nalias tfup=\"terraform init -upgrade\"\nalias tfv=\"terraform validate\"\n\n# Section: http://tmux.sourceforge.net:[tmux]\nalias tsa=\"tmux attach-session -t\"\nalias tsk=\"tmux kill-session -t\"\nalias tsl=\"tmux list-sessions\"\nalias tsr=\"tmux rename-session -t\"\n"
  },
  {
    "path": "lib/templates/.config/bash/colors.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Terminal Colors\n\n# Color Designators:\n#  a  black\n#  b  red\n#  c  green\n#  d  brown\n#  e  blue\n#  f  magenta\n#  g  cyan\n#  h  light grey\n#  A  bold black, usually shows up as dark grey\n#  B  bold red\n#  C  bold green\n#  D  bold brown, usually shows up as yellow\n#  E  bold blue\n#  F  bold magenta\n#  G  bold cyan\n#  H  bold light grey; looks like bright white\n#  x  default foreground or background\n\n# Attribute Order:\n#  1.   directory\n#  2.   symbolic link\n#  3.   socket\n#  4.   pipe\n#  5.   executable\n#  6.   block special\n#  7.   character special\n#  8.   executable with setuid bit set\n#  9.   executable with setgid bit set\n#  10.  directory writable to others, with sticky bit\n#  11.  directory writable to others, without sticky bit\n\n# Default: \"exfxcxdxbxegedabagacad\"\nexport CLICOLOR=1\nexport LSCOLORS=cxfxcxdxbxegebabagacad\n\n# Bash Colors\nexport BLACK='\\e[0;30m'\nexport GUNMETAL='\\e[1;30m'\nexport GREY='\\e[0;37m'\nexport RED='\\e[0;31m'\nexport LIGHT_RED='\\e[1;31m'\nexport PURPLE='\\e[0;35m'\nexport LIGHT_PURPLE='\\e[1;35m'\nexport BLUE='\\e[0;34m'\nexport LIGHT_BLUE='\\e[1;34m'\nexport GREEN='\\e[0;32m'\nexport LIGHT_GREEN='\\e[1;32m'\nexport CYAN='\\e[0;36m'\nexport LIGHT_CYAN='\\e[1;36m'\nexport GOLD='\\e[0;33m'\nexport YELLOW='\\e[1;33m'\nexport WHITE='\\e[1;37m'\n\nexport BLACK_UNDERLINE='\\e[4;30m'\nexport RED_UNDERLINE='\\e[4;31m'\nexport GREEN_UNDERLINE='\\e[4;32m'\nexport YELLOW_UNDERLINE='\\e[4;33m'\nexport BLUE_UNDERLINE='\\e[4;34m'\nexport PURPLE_UNDERLINE='\\e[4;35m'\nexport CYAN_UNDERLINE='\\e[4;36m'\nexport WHITE_UNDERLINE='\\e[4;37m'\n\nexport BLACK_BACKGROUND='\\e[48;5;0m'\nexport RED_BACKGROUND='\\e[48;5;1m'\nexport GREEN_BACKGROUND='\\e[48;5;2m'\nexport YELLOW_BACKGROUND='\\e[48;5;11m'\nexport SLATE_BACKGROUND='\\e[48;5;23m'\nexport BLUE_BACKGROUND='\\e[48;5;19m'\nexport PURPLE_BACKGROUND='\\e[48;5;5m'\nexport CYAN_BACKGROUND='\\e[48;5;6m'\nexport SILVER_BACKGROUND='\\e[48;5;7m'\nexport WHITE_BACKGROUND='\\e[48;5;255m'\n\nexport NORMAL='\\e[0m'\n"
  },
  {
    "path": "lib/templates/.config/bash/environment.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Add secret/machine specific key/value pairs here.\n# export EXAMPLE=\"An example of a secret/machine-specific key/value.\"\n"
  },
  {
    "path": "lib/templates/.config/bash/functions-private.sh.tt",
    "content": "#! /usr/bin/env bash\n\n#-------------------#\n# Section: Dotfiles #\n#-------------------#\n\n# Label: Find Alias\n# Description: Find and print matching alias.\n# Parameters: $1 (required): The alias to search for.\n_find_alias() {\n  while read -r line; do\n    if [[ \"$line\" == \"alias \"*\"$1\"* ]]; then\n      printf \"    %s \" \"Alias:\"\n      _print_alias \"$line\"\n    fi\n  done < \"$HOME/.config/bash/aliases.sh\"\n}\n\n# Label: Find Command\n# Description: Find and print matching alias or function.\n# Parameters: $1 (required): The alias or function to search for.\n_find_command() {\n  if [[ \"$1\" ]]; then\n    printf \"%s\\n\" \"\\\"$1\\\" Search Results:\"\n\n    _find_alias \"$1\"\n    _find_function \"$1\"\n  else\n    printf \"%s\\n\" \"ERROR: Nothing to search for. Criteria must be supplied.\"\n  fi\n}\n\n# Label: Find Function\n# Description: Find and print matching function.\n# Parameters: $1 (required): The function to search for.\n_find_function() {\n  while read -r line; do\n    _set_function_label \"$line\"\n    _set_function_description \"$line\"\n\n    if [[ \"$line\" == *\"$1\"*\"()\"* ]]; then\n      printf \"    %s \" \"Function:\"\n      _print_function_name \"$line\" \"$label\" \"$description\"\n      unset label\n      unset description\n    fi\n  done < \"$HOME/.config/bash/functions-public.sh\"\n}\n\n# Label: Print Alias\n# Description: Print alias.\n# Parameters: $1 (required): The string from which to parse the alias from.\n_print_alias() {\n  echo \"$1\" | sed 's/alias //' | sed 's/=\"/ = \"/' | sed \"s/='/ = '/\"\n}\n\n# Label: Print Aliases\n# Description: Print aliases.\n_print_aliases() {\n  while read -r line; do\n    _print_section \"$line\"\n\n    if [[ \"$line\" == \"alias\"* ]]; then\n      _print_alias \"$line\"\n    fi\n  done < <(sed '2d' \"$HOME/.config/bash/aliases.sh\")\n\n  printf \"%s\\n\" \"....\"\n}\n\n# Label: Print All\n# Description: Print aliases, functions, and Git hooks.\n_print_all() {\n  printf \"%s\\n\" \"=== Aliases\"\n  _print_aliases\n  printf \"\\n%s\\n\" \"=== Functions\"\n  unset section\n  _print_functions\n  printf \"%s\\n\" \"....\"\n  printf \"\\n%s\\n\\n\" \"=== Git Hooks\"\n  _print_git_hooks\n}\n\n# Label: Print Function Name\n# Description: Print function name.\n# Parameters: $1 (required): The string from which to parse the function name from.\n_print_function_name() {\n  local name=$(printf \"$1\" | sed 's/() {//')\n  printf \"%s\\n\" \"$name = $2 - $3\"\n}\n\n# Label: Print Functions\n# Description: Print functions.\n_print_functions() {\n  local path=\"${1:-$HOME/.config/bash/functions-public.sh}\"\n\n  while read -r line; do\n    _print_section \"$line\"\n    _set_function_label \"$line\"\n    _set_function_description \"$line\"\n\n    if [[ \"$line\" == *\"() {\" && \"$line\" != \"_\"* ]]; then\n      _print_function_name \"$line\" \"$label\" \"$description\"\n      unset label\n      unset description\n    fi\n  done < \"$path\"\n}\n\n# Label: Print Git Hooks\n# Description: Print Git hooks.\n_print_git_hooks() {\n  printf \"%s\\n\" \"....\"\n\n  for file in $(find \"$HOME/.config/git/hooks/extensions\" -type l | sort); do\n    _print_functions \"$file\"\n  done\n\n  printf \"%s\\n\" \"....\"\n}\n\n# Label: Print Section\n# Description: Print section.\n# Parameters: $1 (required): The string from which to parse the section from.\n_print_section() {\n  if [[ \"$1\" == \"# Section:\"* ]]; then\n    if [[ -n \"${section+x}\" ]]; then\n      printf \"%s\\n\" \"....\"\n    fi\n\n    section=$(printf \"$1\" | sed 's/# Section://' | sed 's/^ *//g' | tr -d '#')\n    printf \"\\n%s\\n\\n\" \"==== $section\"\n    printf \"%s\\n\" \"....\"\n  fi\n}\n\n# Label: Process Dotfiles Option\n# Description: Process option for learning about dotfile aliases/functions.\n# Parameters: $1 (optional): The option selection, $2 (optional): The option input.\n_process_dots_option() {\n  case $1 in\n    'a')\n      _print_aliases | more;;\n    'f')\n      _print_functions | more;;\n    'g')\n      _print_git_hooks | more;;\n    'p')\n      _print_all | more;;\n    's')\n      _find_command \"$2\" | more;;\n    'q');;\n    *)\n      printf \"%s\\n\" \"ERROR: Invalid option.\";;\n  esac\n}\n\n# Label: Set Function Description\n# Description: Set function description.\n_set_function_description() {\n  if [[ \"$line\" == \"# Description:\"* ]]; then\n    description=$(printf \"$line\" | sed 's/# Description://' | sed 's/^ *//g')\n  fi\n}\n\n# Label: Set Function Label\n# Description: Set function label.\n# Parameters: $1 (required): The string from which to parse the function label from.\n_set_function_label() {\n  if [[ \"$1\" == \"# Label:\"* ]]; then\n    label=$(printf \"$1\" | sed 's/# Label://' | sed 's/^ *//g')\n  fi\n}\n\n#------------------#\n# Section: General #\n#------------------#\n\n# Label: Clip and Print\n# Description: Copy input to clipboard and print what what was copied (best used with a pipe).\n# Parameters: $1 (optional): Displays \"(copied to cliboard)\" on a new line. Default: false.\n_copy_and_print() {\n  local delimiter=${1:-' '}\n  local message=\"$delimiter(copied to clipboard)\\n\"\n\n  pbcopy && printf \"%s\" \"$(pbpaste)\" && printf \"$message\"\n}\n\n# Label: Print Black on White\n# Description: Print black text on a white background.\n# Parameters: $1 (required): Content to print.\n_print_black_on_white() {\n  local content=\"$1\"\n  printf \"\\e[0;30m\\e[48;5;255m$content\\033[m\"\n}\n\n# Label: Toggle Total Color\n# Description: Format and conditionally color the total.\n# Parameters: $1 (required): The total, $2(required): The label, $3 (required): The color.\n_toggle_total_color() {\n  local total=\"$1\"\n  local label=\"$2\"\n  local color=\"$3\"\n\n  if [[ $total -gt 0 ]]; then\n    printf \"$color$total $label\\033[m\"\n  else\n    printf \"$total $label\"\n  fi\n}\n\n#------------------------------------#\n# Section: https://git-scm.com:[Git] #\n#------------------------------------#\n\n# Label: Git Branch Default\n# Description: Print Git default branch.\n_git_branch_default() {\n  local default=\"$(git config get init.defaultBranch)\"\n  printf \"${default:-main}\"\n}\n\n# Label: Git Branch Name\n# Description: Print Git branch name.\n_git_branch_name() {\n  git branch --show-current | tr -d '\\n'\n}\n\n# Label: Git Branch Parent\n# Description: Answer parent branch of current branch or default branch if default branch.\n_git_branch_parent() {\n  local format=\"\"\n  local name=\"\"\n\n  format=\"%(refname:lstrip=2)%(is-base:$(_git_sha))\"\n\n  if [[ \"$(_git_branch_name)\" == \"$(_git_branch_default)\" ]]; then\n    _git_branch_default\n  else\n    name=\"$(git for-each-ref --format=\"$format\" --count=1 | sed 's/([^)]*)//')\"\n\n    if [[ \"$name\" == \"$(_git_branch_name)\" ]]; then\n      _git_branch_default\n    else\n      printf \"%s\" \"$name\"\n    fi\n  fi\n}\n\n# Label: Git Branch Range\n# Description: Answer branch commit range (i.e. starting and ending reference).\n_git_branch_range() {\n  local range=\"\"\n\n  if [[ \"$(_git_branch_name)\" == \"$(_git_branch_default)\" ]]; then\n    range=\"$(_git_sha)\"\n  else\n    range=\"$(_git_branch_parent)..$(_git_sha)\"\n  fi\n\n  printf \"%s\" \"$range\"\n}\n\n# Label: Git Branch SHAs\n# Description: Answer branch commit SHAs regardless of branch nesting.\n_git_branch_shas() {\n  git log --pretty=format:%h \"$(_git_branch_range)\"\n}\n\n# Label: Git Commit Count Since Last Tag\n# Description: Answer commit count since last tag for project.\n# Parameters: $1 (optional): The output prefix. Default: null, $2 (optional): The output suffix. Default: null.\n_git_commit_count_since_last_tag() {\n  local prefix=\"$1\"\n  local suffix=\"$2\"\n  local count=$(_git_commits_since_last_tag | wc -l | xargs -n 1)\n\n  if [[ -n $count ]]; then\n    # Prefix\n    if [[ -n \"$prefix\" ]]; then\n      printf \"\\033[36m${prefix}\\033[m: \" # Cyan.\n    fi\n\n    # Commit Count\n    if [[ $count -ge 30 ]]; then\n      printf \"\\033[31m$count\\033[m\" # Red.\n    elif [[ $count -ge 20 && $count -le 29 ]]; then\n      printf \"\\033[1;31m$count\\033[m\" # Light red.\n    elif [[ $count -ge 10 && $count -le 19 ]]; then\n      printf \"\\033[33m$count\\033[m\" # Yellow.\n    else\n      printf \"$count\" # White.\n    fi\n\n    # Suffix\n    if [[ -n \"$suffix\" ]]; then\n      printf \"$suffix\"\n    fi\n  fi\n}\n\n# Label: Git Commit Options\n# Description: Print options for interacting with Git commits.\n# Parameters: $1 (required): Commit array.\n_git_commit_options() {\n  local commits=(\"${1}\")\n  local commit_total=${#commits[@]}\n  local option_padding=${#commit_total}\n  local counter=1\n\n  unset response\n\n  if [[ ${#commits[@]} == 0 ]]; then\n    printf \"%s\\n\" \"No commits found.\"\n    return 0\n  fi\n\n  for commit in ${commits[@]}; do\n    option=\"$(printf \"%${option_padding}s\" $counter)\"\n    printf \"%s\\n\" \"$option: $(git log --color --pretty=format:\"$(_git_log_enrich_format)\" -n1 $commit | _git_log_enrich)\"\n    counter=$((counter + 1))\n\n    if [[ \"$response\" == \"q\" ]]; then\n      break\n    fi\n  done\n}\n\n# Label: Git Commit Root\n# Description: Answer root commit of entire repository.\n_git_commit_root() {\n  git rev-list --use-bitmap-index \\\n               --max-parents=0 HEAD \\\n               --pretty=format:%h | \\\n               rg --invert-match \"^commit\"\n}\n\n# Label: Git Commits Since Last Tag\n# Description: Answer commit history since last tag for project.\n_git_commits_since_last_tag() {\n  if [[ $(git tag) ]]; then\n    git log --oneline \"$(_git_tag_last)\"..HEAD\n  else\n    git log --oneline\n  fi\n}\n\n# Label: Git File Commits\n# Description: Print file commit history (with optional diff support).\n# Parameters: $1 (required): The file path.\n_git_file_commits() {\n  local commits=(\"${!1}\")\n  local file=\"$2\"\n  local commit_total=${#commits[@]}\n  local option_padding=${#commit_total}\n  local counter=1\n\n  _git_commit_options \"${commits[*]}\"\n\n  read -r -p \"Enter selection: \" response\n  if [[ \"$response\" == 'q' ]]; then\n    return\n  fi\n\n  printf \"\\n\"\n  local selected_commit=${commits[$((response - 1))]}\n  _git_show_details $selected_commit\n\n  printf \"\\n\"\n  read -p \"View diff (y = yes, n = no)? \" response\n  if [[ \"$response\" == 'y' ]]; then\n    gdt $selected_commit^! -- \"$file\"\n  fi\n}\n\n# Label: Git Log Details Format\n# Description: Prints default log format.\n_git_log_details_format() {\n  printf \"%s\" \"$(_git_log_line_format) %n%n%b%n%N%-%n\"\n}\n\n# Label: Git Log Enrich\n# Description: Enrich log for improved readability.\n_git_log_enrich() {\n  sd \"\\[G\\]\" \"🔒\" \\\n  | sd \"\\[[^G]\\]\" \"🚨\" \\\n  | sd \"\\[major\\]\" \"🔴\" \\\n  | sd \"\\[minor\\]\" \"🔵\" \\\n  | sd \"\\[patch\\]\" \"🟢\" \\\n  | sd \"\\[\\]\" \"⚪️\"\n}\n\n# Label: Git Log Enrich Format\n# Description: Print enriched log line format.\n_git_log_enrich_format() {\n  printf \"%s\" \"%C(yellow)%h%C(reset) [%G?] %C(bold blue)%an%C(reset) [%(trailers:key=Milestone,valueonly=true,separator=)] %s%C(bold cyan)%d%C(reset) %C(green)%cr.%C(reset)\"\n}\n\n# Label: Git Log Line Format\n# Description: Print single line log format.\n_git_log_line_format() {\n  printf \"%s\" \"%C(yellow)%h%C(reset) %G? %C(bold blue)%an%C(reset) %s%C(bold cyan)%d%C(reset) %C(green)%cr.%C(reset)\"\n}\n\n# Label: Git SHA\n# Description: Answer sha for branch, tag, or any kind of valid reference.\n# Parameters: $1 (optional): The reference name, otherwise current branch.\n_git_sha() {\n  local reference=\"${1:-$(_git_branch_name)}\"\n\n  git rev-parse --short \"$reference\"\n}\n\n# Label: Git Show Details\n# Description: Show commit/file change details in a concise format.\n# Parameters: $1 (required): The params to pass to git show.\n_git_show_details() {\n  git show --stat --patch --pretty=format:\"$(_git_log_details_format)\" $@\n}\n\n# Label: Git Stash Count\n# Description: Answer total stash count for current project.\n_git_stash_count() {\n  git stash list | wc -l | xargs -n 1\n}\n\n# Label: Git Stash push\n# Description: Pushes changes to remote.\n_git_stash_push() {\n  local reference=\"refs/stashes/$USER\"\n\n  if [[ -e \".git/$reference\" ]]; then\n    git push --no-verify --force origin \"$reference\"\n  else\n    printf \"%s\\n\" \"Push skipped. Reference doesn't exist: $reference.\"\n  fi\n}\n\n# Label: Git Tag Last\n# Description: Answer last tag or last commit SHA.\n_git_tag_last() {\n  git describe --abbrev=0 --tags --always\n}\n\n# Label: Git Tag Last Info\n# Description: Answer last tag for project (including commits added since tag was created).\n_git_tag_last_info() {\n  printf \"%s\\n\" \"$(git describe --tags --always) ($(_git_commit_count_since_last_tag) commits since)\"\n}\n\n# Label: Git Stash\n# Description: Enhance default git stash behavior by prompting for input (multiple) or using last stash (single).\n# Parameters: $1 (required): The Git stash command to execute, $2 (required): The prompt label (for multiple stashes).\n_process_git_stash() {\n  local stash_command=\"$1\"\n  local stash_index=0\n  local prompt_label=\"$2\"\n  local ifs_original=$IFS\n  IFS=$'\\n'\n\n  # Store existing stashes (if any) as an array. See public, \"gashl\" for details.\n  stashes=($(gashl))\n\n  if [[ ${#stashes[@]} == 0 ]]; then\n    printf \"%s\\n\" \"Git stash is empty. Nothing to do.\"\n    return 0\n  fi\n\n  # Ask which stash to show when multiple stashes are detected, otherwise show the existing stash.\n  if [[ ${#stashes[@]} -gt 1 ]]; then\n    printf \"%s\\n\" \"$prompt_label:\"\n    for ((index = 0; index < ${#stashes[*]}; index++)); do\n      printf \"  %s\\n\" \"$index: ${stashes[$index]}\"\n    done\n    printf \"  %s\\n\\n\" \"q: Quit/Exit.\"\n\n    read -p \"Enter selection: \" response\n\n    local match=\"^[0-9]{1}$\"\n    if [[ \"$response\" =~ $match ]]; then\n      printf \"\\n\"\n      stash_index=\"$response\"\n    else\n      return 0\n    fi\n  fi\n\n  IFS=$ifs_original\n  eval \"$stash_command stash@{$stash_index}\"\n}\n\n#--------------------------------------#\n# Section: https://github.com:[GitHub] #\n#--------------------------------------#\n\n# Label: GitHub URL\n# Description: Answer GitHub URL for current project.\n_gh_url() {\n  printf \"$(git remote -v | rg github.com | rg fetch | head -1 | cut -f2 | cut -d' ' -f1 | sed -e 's/git@/https:\\/\\//' -e 's/com:/com\\//' -e 's/\\.git//')\"\n}\n\n# Label: GitHub Pull Request List\n# Description: List pull requests (local/remote) including subject, author, and relative time.\n# Parameters: $1 (optional): The output format.\n_gh_pr_list() {\n  local format=${1:-\"%(refname) %(color:yellow)%(refname)%(color:reset) %(subject) %(color:blue bold)%(authorname) %(color:green)(%(committerdate:relative))\"}\n\n  git for-each-ref --color \\\n                   --format=\"$format\" \\\n                   refs/remotes/pull_requests \\\n                   | sed 's/refs\\/remotes\\/pull_requests\\///g' \\\n                   | sort --numeric-sort \\\n                   | cut -d' ' -f2-\n}\n\n# Label: Process GitHub Branch Option\n# Description: Process GitHub branch option for remote repository viewing.\n# Parameters: $1 (optional): The option.\n_process_gh_branch_option() {\n  case $1 in\n    'c')\n      open \"$(_gh_url)/tree/$(_git_branch_name)\";;\n    'd')\n      open \"$(_gh_url)/compare/$(_git_branch_name)\";;\n    'r')\n      open \"$(_gh_url)/compare/$(_git_branch_name)?expand=1\";;\n    *)\n      open \"$(_gh_url)/branches\";;\n  esac\n}\n\n# Label: Process GitHub Commit Option\n# Description: Process GitHub commit option for remote repository viewing.\n# Parameters: $1 (optional): The commit hash.\n_process_gh_commit_option() {\n  local commit=\"$1\"\n\n  if [[ \"$commit\" ]]; then\n    open \"$(_gh_url)/commit/$commit\"\n  else\n    open \"$(_gh_url)/commits\"\n  fi\n}\n\n# Label: Process GitHub File Option\n# Description: Process GitHub file option for remote repository viewing.\n# Parameters: $1 (required): The local (relative) file path, $2 (optional): The line numbers.\n_process_gh_file_option() {\n  local path=\"$1\"\n  local lines=\"$2\"\n  local start_index=$(pwd | wc -c)\n  local end_index=$(printf \"$path\" | wc -c)\n  local url=\"$(_gh_url)/blob/$(_git_branch_name)/${path:$start_index:$end_index}\"\n\n  if [[ -n \"$lines\" ]]; then\n    url=\"$url#$lines\"\n  fi\n\n  printf \"$url\" | _copy_and_print\n}\n\n# Label: Process GitHub Option\n# Description: Processes GitHub option for remote repository viewing.\n# Parameters: $1 (optional): The first option, $2 (optional): The second option.\n_process_gh_option() {\n  case $1 in\n    'a')\n      open $(_gh_url)/actions;;\n    'o')\n      open $(_gh_url);;\n    'i')\n      open \"$(_gh_url)/issues\";;\n    'c')\n      _process_gh_commit_option \"$2\";;\n    'f')\n      _process_gh_file_option \"$2\" \"$3\";;\n    'b')\n      _process_gh_branch_option \"$2\";;\n    't')\n      open \"$(_gh_url)/tags\";;\n    'r')\n      _process_gh_pull_request_option \"$2\";;\n    'w')\n      open \"$(_gh_url)/wiki\";;\n    'p')\n      open \"$(_gh_url)/pulse\";;\n    'g')\n      open \"$(_gh_url)/graphs\";;\n    's')\n      open \"$(_gh_url)/settings\";;\n    'u')\n      _process_gh_url_option \"$2\";;\n    'q');;\n    *)\n      printf \"%s\\n\" \"ERROR: Invalid option.\";;\n  esac\n}\n\n# Label: Process GitHub Pull Request Option\n# Description: Process GitHub pull request option for remote repository viewing.\n# Parameters: $1 (optional): The option.\n_process_gh_pull_request_option() {\n  local option=\"$1\"\n  local number_match=\"^[0-9]+$\"\n\n  if [[ \"$option\" =~ $number_match ]]; then\n    open \"$(_gh_url)/pull/$option\"\n  elif [[ \"$option\" == 'l' ]]; then\n    _gh_pr_list\n  else\n    open \"$(_gh_url)/pulls\"\n  fi\n}\n\n# Label: Process GitHub URL Option\n# Description: Processes GitHub URL option for remote repository viewing.\n# Parameters: $1 (optional): The commit/option.\n_process_gh_url_option() {\n  local commit=\"$1\"\n  local commit_match=\"^([0-9a-f]{40}|[0-9a-f]{7})$\"\n\n  if [[ \"$commit\" =~ $commit_match ]]; then\n    printf \"$(_gh_url)/commit/$commit\" | _copy_and_print\n  elif [[ \"$commit\" == 'l' ]]; then\n    printf \"$(_gh_url)/commit/$(_git_sha)\" | _copy_and_print\n  else\n    _gh_url | _copy_and_print\n  fi\n}\n\n#------------------------------------------------#\n# Section: https://github.com/junegunn/fzf:[FZF] #\n#------------------------------------------------#\n\n# Label: FZF Preview and Select\n# Description: Preview and select one ore more files.\n_fzf_preview_and_select() {\n  fzf --preview 'bat --theme DarkNeon --color always {}' --multi --print0\n}\n\n#--------------------------------------------------#\n# Section: https://rubyonrails.org:[Ruby on Rails] #\n#--------------------------------------------------#\n\n# Label: Process Ruby on Rails New Option\n# Description: Process option for constructing new Rails application skeletons with custom build settings.\n# Parameters: $1 (required): Application name, $2 (required): Option.\n_process_rails_new_option() {\n  local flags=\"--skip-git --skip-action-cable --skip-action-text --skip-active-storage --skip-jbuilder --skip-hotwire --skip-test --skip-keeps --asset-pipeline propshaft --database postgresql\"\n\n  case $2 in\n    \"default\")\n      _create_rails_skeleton \"$1\";;\n    \"api\")\n      _create_rails_skeleton \"$1\" \"$flags --api\";;\n    \"slim\")\n      _create_rails_skeleton \"$1\" \"$flags\";;\n    \"static\")\n      _create_rails_skeleton \"$1\" \"$flags --skip-javascript\";;\n    \"dummy\")\n      _create_rails_skeleton \"$1\" \"$flags --skip-bundle --skip-javascript\";;\n    'q');;\n    *)\n      printf \"%s\\n\" \"ERROR: Invalid option.\";;\n  esac\n}\n\n# Label: Create Rails Skeleton\n# Description: Create new Rails application skeleton.\n# Parameters: $1 (required): The application name, $2 (optional): The build options to apply.\n_create_rails_skeleton() {\n  printf \"%s\\n\" \"rails new $1 $2\"\n  rails new $1 $2\n}\n"
  },
  {
    "path": "lib/templates/.config/bash/functions-public.sh.tt",
    "content": "#! /usr/bin/env bash\n\n#-----------------------------------------------------#\n# Section: link:https://asciidoctor.org[ASCII Doctor] #\n#-----------------------------------------------------#\n\n# Label: ASCII Doctor Open\n# Description: Transforms ASCII Doc into HTML and opens in default browser.\n# Parameters: $1 (optional): Path to ASCII Doc file. Default: README.adoc.\nado() {\n  local input=${1:-README.adoc}\n  local output=$(mktemp -t asciidoc -u).html\n\n  asciidoctor --failure-level WARN --out-file \"$output\" \"$input\"\n  open \"$output\"\n  read -p \"Viewing: $output. Use any key to continue. \" response\n  rm -f \"$output\"\n}\n\n#---------------------------------------#\n# Section: https://bundler.io:[Bundler] #\n#---------------------------------------#\n\n# Label: Bundler Clean (all)\n# Description: Clean projects of gem artifacts.\nbca() {\n  while read -r project; do\n    (\n      cd \"$project\"\n      if [[ -f \"Gemfile.lock\" ]]; then\n        printf \"\\033[36m${project}\\033[m\\n\" # Outputs project in cyan color.\n        rm -rf pkg\n        artifacts=(\"$(rg --no-ignore-vcs --files --glob \"*.gem\")\")\n\n        for artifact in ${artifacts[*]}; do\n          printf \"%s\\n\" \" - $artifact\"\n          rm -f \"$artifact\"\n        done\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Bundler Config Gem\n# Description: Configure Bundler to use local gem for development purposes.\n# Parameters: $1 (required): Gem name, $2 (required): Gem path.\nbcg() {\n  local gem_name=$1\n  local gem_path=$2\n\n  if [[ -z \"$gem_name\" ]]; then\n    printf \"%s\\n\" \"ERROR: Gem name must be supplied!\"\n    return 1\n  fi\n\n  if [[ -z \"$gem_path\" ]]; then\n    printf \"%s\\n\" \"ERROR: Gem path must be supplied!\"\n    return 1\n  fi\n\n  bundle config set --global \"local.$gem_name\" \"$gem_path\"\n  printf \"%s\\n\" \"Added: $(tail -n 1 $BUNDLE_USER_CONFIG)\"\n}\n\n# Label: Bundle List\n# Description: List gem dependencies for project and copy them to clipboard.\nbl() {\n  local collection=()\n\n  printf \"%s\\n\" \"Calculating gem dependencies (will be copied to clipboard)...\"\n\n  for gem in $(bundle list --name-only); do\n    collection+=(\"$(bundle info \"$gem\")\")\n  done\n\n  printf \"%s\\n\" \"${collection[@]}\" | pbcopy && pbpaste\n}\n\n# Label: Bundle Outdated (all)\n# Description: Answer outdated gems for projects in current directory.\nboa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -f \"Gemfile.lock\" ]]; then\n        printf \"\\033[36m${project}\\033[m: \" # Outputs project in cyan color.\n\n        # Capture current project status: Search for bullets (*, outdated gems) or missing (not found) gems.\n        local results=$(bundle outdated | rg --only-matching \"(\\*.+|.+not\\sfind.+)\")\n\n        # Print project status if Bundler activity is detected, otherwise a checkmark for passing status.\n        if [[ -n \"$results\" ]]; then\n          printf \"\\n%s\\n\" \"$results\"\n        else\n          printf \"✓\\n\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Bundle Update\n# Description: Update all gems or a single gem in current project.\n# Parameters: $1 (optional): The desired gem. Default: nil.\nbu() {\n  local gem=\"$1\"\n\n  if [[ -n \"$gem\" ]]; then\n    bundle update \"$gem\"\n  else\n    bundle update --all\n  fi\n}\n\n# Label: Bundle Update (all)\n# Description: Update gems for projects in current directory.\nbua() {\n  while read -r project; do\n    (\n      cd \"$project\"\n      if [[ -f \"Gemfile.lock\" ]]; then\n        rm -f Gemfile.lock\n        bundle install --quiet\n\n        # Print project status if Bundler activity is detected, otherwise a checkmark for passing status.\n        printf \"\\033[36m${project}\\033[m: \" # Outputs project in cyan color.\n        if [[ $(git diff | wc -l | tr -d ' ') -gt 0 ]]; then\n          printf \"↑\\n\"\n        else\n          printf \"✓\\n\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n#--------------------------------------------------------------------#\n# Section: https://alchemists.io/projects/caliber:[Code Quality]     #\n#--------------------------------------------------------------------#\n\n# Label: Code Quality (all)\n# Description: Run code quality tasks for projects in current directory.\ncqa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n      if [[ -f \"Gemfile.lock\" && -f \"Rakefile\" ]]; then\n        # Prints project (cyan).\n        printf \"\\033[36m${project}\\033[m:\\n\"\n\n        rake quality\n        printf \"\\n\"\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Code Quality Issues\n# Description: List all source files affected by code quality issues.\ncqi() {\n  local comments=(\n    \"TODO\"\n    \"FIX\"\n    \"DUPLICATE\"\n    \"shellcheck disable\"\n    \":reek:\"\n    \"rubocop:disable\"\n    \"rubocop:todo\"\n    \":nocov:\"\n  )\n\n  for comment in ${comments[*]}; do\n    rg --case-sensitive --iglob '!vendor' --regexp \"^\\s*?(#|--|//) $comment\" .\n  done\n}\n\n#---------------------------------#\n# Section: https://curl.se:[curl] #\n#---------------------------------#\n\n# Label: Curl Diagnostics\n# Description: Curl with diagnostic information for request.\n# Parameters: $1 (required): The URL.\ncurld() {\n  local url=\"$1\"\n\n  printf -v diagnostics \"%s\\n\" \"\\n\" \\\n                               \"HTTP Version:   %{http_version}\" \\\n                               \"HTTP Status:    %{http_code}\" \\\n                               \"Content Type:   %{content_type}\" \\\n                               \"DNS Lookup:     %{time_namelookup} seconds\" \\\n                               \"Connect:        %{time_connect} seconds\" \\\n                               \"App Connect:    %{time_appconnect} seconds\" \\\n                               \"Pre-Transfer:   %{time_pretransfer} seconds\" \\\n                               \"Start Transfer: %{time_starttransfer} seconds\" \\\n                               \"Speed:          %{speed_upload}↑ %{speed_download}↓ bytes/second\" \\\n                               \"Total Time:     %{time_total} seconds\" \\\n                               \"Total Size:     %{size_download} bytes\"\n\n  curl --write-out \"$diagnostics\" --url \"$url\"\n}\n\n# Label: Curl Inspect\n# Description: Inspect remote file with default editor.\n# Parameters: $1 (required): The URL.\ncurli() {\n  if [[ \"$1\" ]]; then\n    local file=$(mktemp -t suspicious_curl_file) || { printf \"%s\\n\" \"ERROR: Unable to create temporary file.\"; return; }\n    curl --location --fail --silent --show-error \"$1\" > $file || { printf \"%s\\n\" \"Failed to curl file.\"; return; }\n    $EDITOR --wait $file || { printf \"Unable to open temporary curl file.\\n\"; return; }\n    rm -f $file;\n  else\n    printf \"%s\\n\" \"ERROR: URL must be supplied.\"\n    return 1\n  fi\n}\n\n#------------------------------------------#\n# Section: https://www.docker.com:[Docker] #\n#------------------------------------------#\n\n# Label: Docker Comppose\n# Description: Run Docker Comppose for development (default) or production.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\ndrc() {\n  local environment=\"$1\"\n\n  shift\n\n  if [[ \"$environment\" == \"p\" ]]; then\n    docker-compose \"$@\"\n  else\n    docker-compose --file \"compose.dev.yml\" \"$@\"\n  fi\n}\n\n# Label: Docker Compose Build\n# Description: Build service for development (default) or production.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\ndrcb() {\n  local environment=\"$1\"\n\n  drc \"$environment\" \"build\"\n}\n\n# Label: Docker Compose Down\n# Description: Shutdown services for development (default) or production.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\ndrcd() {\n  local environment=\"$1\"\n\n  drc \"$environment\" \"down\"\n}\n\n# Label: Docker Compose Execute\n# Description: Execute command for development (default) or production.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\ndrce() {\n  local environment=\"$1\"\n\n  drc \"$environment\" \"exec\"\n}\n\n# Label: Docker Compose Run\n# Description: Run oneoff command for development (default) or production.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\ndrcr() {\n  local environment=\"$1\"\n\n  drc \"$environment\" \"run\" \"--rm\"\n}\n\n# Label: Docker Compose Up\n# Description: Startup services for development (default) or production.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\ndrcu() {\n  local environment=\"$1\"\n\n  drc \"$environment\" \"up\"\n}\n\n#-------------------#\n# Section: Dotfiles #\n#-------------------#\n\n# Label: Dotfiles\n# Description: Learn about dotfile aliases, functions, etc.\n# Parameters: $1 (optional): The option selection, $2 (optional): The option input.\ndots() {\n  while true; do\n    if [[ $# == 0 ]]; then\n      printf \"\\n%s\\n\" \"Usage: dots OPTION\"\n      printf \"\\n%s\\n\" \"Dotfile Options:\"\n      printf \"  %s\\n\" \"a: Print aliases.\"\n      printf \"  %s\\n\" \"f: Print functions.\"\n      printf \"  %s\\n\" \"g: Print Git hooks.\"\n      printf \"  %s\\n\" \"p: Print all.\"\n      printf \"  %s\\n\" \"s: Search for alias/function.\"\n      printf \"  %s\\n\\n\" \"q: Quit/Exit.\"\n      read -r -p \"Enter selection: \" response\n      printf \"\\n\"\n      _process_dots_option $response \"$2\"\n    else\n      _process_dots_option $1 \"$2\"\n    fi\n    break\n  done\n}\n\n#------------------------------------------------------------#\n# Section: https://github.com/Schniz/fnm:[Fast Node Manager] #\n#------------------------------------------------------------#\n\n# Label: JavaScript Force\n# Description: Installs new Node version as default and removes previous version.\n# Parameters: $1 (required): Version.\njsf() {\n  local version=\"$1\"\n  local previous\n\n  previous=\"$(fnm current)\"\n\n  fnm install \"$version\"\n  fnm default \"$version\"\n  fnm uninstall \"$previous\"\n}\n\n# Label: JavaScript Upgrade (all)\n# Description: Upgrade JavaScript projects in current directory to new JavaScript version.\n# Parameters: $1 (required): The new version to upgrade to. Example: 1.2.3.\njsua() {\n  local new_version=\"$1\"\n  local paths=(\".node-version\" \"home_files/.node-version.tt\")\n\n  if [[ \"$new_version\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n        printf \"\\033[36m${project}\\033[m\\n\" # Outputs in cyan color.\n\n        for path in \"${paths[@]}\"; do\n          if [[ -e \"$path\" ]]; then\n            old_version=\"$(head -n 1 \"$path\")\"\n\n            if [[ \"$old_version\" != \"$new_version\" ]]; then\n              printf \"%s\\n\" \"$new_version\" > \"$path\"\n              printf \"%s\\n\" \" $path: $old_version --> $new_version\"\n            fi\n          fi\n        done\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Version must be supplied.\"\n    return 1\n  fi\n}\n\n#------------------#\n# Section: General #\n#------------------#\n\n# Label: Colorized Type\n# Description: Identical to \"type\" system command but with Bat support.\n# Parameters: $1 (required): The alias or function to inspect source code for.\ncype() {\n  local name=\"$1\"\n\n  if [[ -n \"$name\" ]]; then\n    type \"$name\" | cat --language \"bash\"\n  fi\n}\n\n# Label: Environment Update\n# Description: Update environment with latest software.\neup() {\n  local oss_path=\"$HOME/Engineering/OSS\"\n  local alchemists_path=\"$HOME/Engineering/Companies/Alchemists\"\n\n  softwareupdate --all --install --agree-to-license\n  xcode-select --install\n  hbsu\n  rustup update\n  cargo install-update --all\n  tldr --update\n  docker system prune --force\n  docker buildx prune --force\n\n  (\n    cd \"$HOME/.cache/pgenv\"\n    git pull\n  )\n\n  if [[ -d \"$oss_path\" ]]; then\n    (\n      cd \"$oss_path\"\n      gpua\n      gvaca\n      gemuc\n      bca\n      bua\n    )\n  else\n    printf \"%s\\n\" \"Skipped. Unknown path: #oss_path.\"\n  fi\n\n  if [[ -d \"$alchemists_path\" ]]; then\n    (\n      cd \"$alchemists_path\"\n      gpua\n      gvaca\n      bca\n      bua\n    )\n  else\n    printf \"%s\\n\" \"Skipped. Unknown path: #alchemists_path.\"\n  fi\n\n  noti --title \"Environment Update\"\n}\n\n# Label: ISO\n# Description: Builds an ISO image from mounted volume.\n# Parameters: $1 (required): Volume source path. $2 (required): ISO output file path.\niso() {\n  local source_path=\"$1\"\n  local output_path=\"$HOME/Downloads/$2.iso\"\n\n  if [[ ! -d \"$source_path\" ]]; then\n    printf \"%s\\n\" \"Source path must be supplied or doesn't exist: $source_path.\"\n    return 1\n  fi\n\n  if [[ -z \"$2\" ]]; then\n    printf \"%s\\n\" \"ISO file name must be supplied.\"\n    return 1\n  fi\n\n  printf \"%s\\n\" \"Creating $output_path...\"\n  hdiutil makehybrid -iso -joliet -o \"$output_path\" \"$source_path\"\n}\n\n# Label: Kill Process\n# Description: Kill errant/undesired process.\n# Parameters: $1 (required): The search query, $2 (optional): The signal. Default: 15.\nkilp() {\n  local query=\"$1\"\n  local signal=${2:-15}\n\n  pkill -$signal -l -f \"$query\"\n}\n\n# Label: Tab to Space\n# Description: Convert file from tab to space indentation.\n# Parameters: $1 (required): File path, $2 (optional): Number of spaces. Default: 2.\nt2s() {\n  local number_of_spaces=\"${2:-2}\"\n\n  if [[ \"$1\" ]]; then\n    local temp_file=$(mktemp -t tabs_to_spaces) || { printf \"\\n%s\\n\" \"ERROR: Unable to create temporary file.\"; return; }\n    expand -t $number_of_spaces \"$1\" > $temp_file\n    cat $temp_file > \"$1\"\n    printf \"%s\\n\" \"Converted: $1.\"\n    rm -f $temp_file;\n  else\n    printf \"%s\\n\" \"ERROR: File must be supplied.\"\n    return 1\n  fi\n}\n\n#------------------------------------#\n# Section: https://git-scm.com:[Git] #\n#------------------------------------#\n\n# Label: Git Add\n# Description: Interactively adds modified/untracked files.\nga() {\n  git ls-files --modified --other --exclude-standard \\\n  | _fzf_preview_and_select \\\n  | xargs -0 -o -t git add\n}\n\n# Label: Git Safe\n# Description: Marks repository as safe for auto-loading project's `bin` path.\ngafe() {\n  if [[ -d \".git\" ]]; then\n    mkdir -p .git/safe\n    printf \"%s\\n\" \"Repository has been marked safe.\"\n    exec \"$HOMEBREW_PREFIX/bin/bash\"\n  fi\n}\n\n# Label: Git Add (all)\n# Description: Apply file changes (including new files) for projects in current directory.\ngalla() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Apply all changes to Git.\n        local results=$(git add --verbose --all .)\n\n        # Print project name (cyan) and Git activity (white) only if Git activity was detected.\n        if [[ -n \"$results\" ]]; then\n          printf \"\\033[36m${project}\\033[m:\\n$results\\n\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Stash\n# Description: Creates stash of all changes.\n# Parameters: $1 (optional): Label. Default: \"All Work (YYYY-MM-DD HH:MM:SS AM|PM Z).\"\ngash() {\n  local label=${1:-\"All Work ($(date '+%Y-%m-%d %r %Z'))\"}\n  local reference=\"refs/stashes/$USER\"\n\n  git stash push --include-untracked --message \"$label\"\n  git stash export --to-ref \"$reference\"\n  git push --no-verify --force origin \"$reference\"\n}\n\n# Label: Git Stash (all)\n# Description: Answer stash count for projects in current directory.\ngasha() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        local count=$(_git_stash_count)\n\n        if [[ -n $count && $count != 0 ]]; then\n          printf \"\\033[36m${project}\\033[m: $count\\n\" # Outputs in cyan color.\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Stash Clear\n# Description: Clears all stashes.\ngashc() {\n  local reference=\"refs/stashes/$USER\"\n\n  git stash clear\n  git update-ref -d \"$reference\"\n  git push --delete origin \"$reference\"\n}\n\n# Label: Git Stash Drop\n# Description: Drop stash or prompt for stash to drop.\ngashd() {\n  _process_git_stash \"git stash drop\" \"Git Stash Drop Options (select stash to drop)\"\n  _git_stash_push\n}\n\n# Label: Git Stash Import\n# Description: Imports a remote stash.\n# Parameters: $1 (optional): The remote name. Default: $USER.\ngashi() {\n  local name=\"${1:-$USER}\"\n  git stash import \"refs/stashes/$name\"\n}\n\n# Label: Git Stash List\n# Description: List stashes.\ngashl() {\n  git stash list --pretty=format:'%C(magenta)%gd%C(reset) %C(yellow)%h%C(reset) %s %C(green)(%cr)%C(reset)'\n}\n\n# Label: Git Stash Pop\n# Description: Pop stash or prompt for stash to pop.\ngashp() {\n  _process_git_stash \"git stash pop\" \"Git Stash Pop Options (select stash to pop)\"\n  _git_stash_push\n}\n\n# Label: Git Stash Show\n# Description: Show stash or prompt for stash to show.\n# Parameters: $1 (optional): Show git diff. Default: skipped.\ngashs() {\n  local stash=($(git stash list))\n  local diff_option=\"$1\"\n\n  if [[ -n \"$diff_option\" ]]; then\n    case \"$diff_option\" in\n      'd')\n        _process_git_stash \"git stash show\" \"Git Stash Diff Options (select stash to diff)\";;\n      't')\n        _process_git_stash \"git difftool\" \"Git Stash Diff Options (select stash to diff)\";;\n      *)\n        printf \"%s\\n\\n\" \"Usage: gashs OPTION\"\n        printf \"%s\\n\" \"Available options:\"\n        printf \"%s\\n\" \"  d: Git diff.\"\n        printf \"%s\\n\" \"  t: Git difftool.\"\n        return;;\n    esac\n  else\n    _process_git_stash \"_git_show_details\" \"Git Stash Show Options (select stash to show)\"\n  fi\n}\n\n# Label: Git Stash Stage\n# Description: Creates stash of staged work.\n# Parameters: $1 (optional): Label. Default: \"Staged Work (YYYY-MM-DD HH:MM:SS AM|PM Z).\"\ngasht() {\n  local label=${1:-\"Staged Work ($(date '+%Y-%m-%d %r %Z')).\"}\n  git stash push --stage --message \"$label\"\n}\n\n# Label: Git Branch Create\n# Description: Create and switch to branch.\n# Parameters: $1 (required): New branch name.\ngbc() {\n  local name=\"$1\"\n\n  if [[ \"$name\" ]]; then\n    git switch --create \"$name\"\n  else\n    printf \"%s\\n\" \"ERROR: Branch name must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Git Branch Create (all)\n# Description: Create and switch to branch for projects in current directory.\n# Parameters: $1 (required): The branch name.\ngbca() {\n  local branch=\"$1\"\n\n  if [[ -n \"$branch\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n\n        if [[ -d \".git\" ]]; then\n          if [[ \"$(_git_branch_name)\" != \"$branch\" ]]; then\n            git switch --create \"$branch\" --track\n            printf \"\\033[36m${project}\\033[m: $branch\\n\" # Output in cyan and branch in white color.\n          fi\n        fi\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Branch name must be supplied.\"\n  fi\n}\n\n# Label: Git Branch Delete\n# Description: Interactively delete local and/or remote branch.\ngbd() {\n  local branch=\"$(gbl | fzf | awk '{print $1}')\"\n\n  if [[ -n \"$branch\" ]]; then\n    gbdl \"$branch\"\n    gbdr \"$branch\"\n  fi\n}\n\n# Label: Git Branch Delete (local)\n# Description: Delete local branch.\n# Parameters: $1 (required): Branch name.\ngbdl() {\n  local branch=\"$1\"\n\n  if [[ -n \"$(git branch --list $branch)\" ]]; then\n    printf \"\\033[31m\" # Red.\n    read -p \"Delete \\\"$branch\\\" local branch (y/n)?: \" response\n    printf \"\\033[m\" # White.\n\n    if [[ \"$response\" == 'y' ]]; then\n      git branch --delete --force \"$branch\"\n    else\n      printf \"%s\\n\" \"Local branch deletion aborted.\"\n    fi\n  else\n    printf \"%s\\n\" \"Local branch not found.\"\n  fi\n}\n\n# Label: Git Branch Delete (merged)\n# Description: Delete remote and local merged branches.\ngbdm() {\n  if [[ $(_git_branch_name) != \"$(_git_branch_default)\" ]]; then\n    printf \"%s\\n\" \"ERROR: Whoa, switch to default branch first.\"\n    return 1\n  fi\n\n  # Remote\n  git branch --remotes \\\n             --merged \\\n             | rg \"origin\" \\\n             | rg --invert-match \"$(_git_branch_default)\" \\\n             | sed 's/origin\\///' \\\n             | xargs -n 1 git push --delete origin\n\n  # Local\n  git branch --merged | rg --invert-match \"\\* $(_git_branch_default)\" | xargs -n 1 git branch --delete --force\n}\n\n# Label: Git Branch Delete (remote)\n# Description: Delete remote branch.\n# Parameters: $1 (required): Branch name.\ngbdr() {\n  local branch=\"$1\"\n\n  if [[ -n \"$(git branch --remotes --list origin/$branch)\" ]]; then\n    printf \"\\033[31m\" # Red.\n    read -p \"Delete \\\"$branch\\\" remote branch (y/n)?: \" response\n    printf \"\\033[m\" # White.\n\n    if [[ \"$response\" == 'y' ]]; then\n      git push --delete origin \"$branch\"\n    else\n      printf \"%s\\n\" \"Remote branch deletion aborted.\"\n    fi\n  else\n    printf \"%s\\n\" \"Remote branch not found.\"\n  fi\n}\n\n# Label: Git Branch Facsimile\n# Description: Duplicate current branch with new name and switch to it.\n# Parameters: $1 (required): New branch name.\ngbf() {\n  local new=\"$1\"\n  local old=\"$(_git_branch_name)\"\n\n  if [[ \"$new\" ]]; then\n    git switch --create \"$new\" \"$old\" --track\n    git commit --allow-empty --no-verify --message \"----- End of $old work -----\"\n  else\n    printf \"%s\\n\" \"ERROR: Branch name must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Git Branch List\n# Description: List local and remote branch details.\ngbl() {\n  local format=\"%(refname)|%(color:yellow)%(objectname)|%(color:reset)|%(color:blue bold)%(authorname)|%(color:green)|%(committerdate:relative)\"\n\n  git for-each-ref --sort=\"authordate:iso8601\" \\\n                   --sort=\"authorname\" \\\n                   --color \\\n                   --format=\"$format\" \\\n                   refs/heads \\\n                   refs/remotes/origin \\\n                   | sed '/HEAD/d' \\\n                   | sed 's/refs\\/heads\\///g' \\\n                   | sed 's/refs\\/remotes\\/origin\\///g' \\\n                   | uniq \\\n                   | sort \\\n                   | column -s '|' -t\n}\n\n# Label: Git Branch List (all)\n# Description: List current branch for projects in current directory.\ngbla() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        local branch=\"$(_git_branch_name)\"\n        printf \"\\033[36m${project}\\033[m: \" # Output in cyan color.\n\n        if [[ \"$branch\" == \"$(_git_branch_default)\" ]]; then\n          printf \"%s\\n\" \"$branch\"\n        else\n          printf \"\\033[31m$branch\\033[m\\n\" # Output in red color.\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Branch List (owner)\n# Description: List branches owned by current author or supplied author.\n# Parameters: $1 (optional): The author name.\ngblo() {\n  local owner=\"${1:-$(git config get user.name)}\"\n  gbl | rg --color never \"$owner\"\n}\n\n# Label: Git Branch Number (all)\n# Description: Answer number of branches for projects in current directory.\ngbna() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        local current_branch=\"$(_git_branch_name)\"\n        local number=\"$(gbl | rg --invert-match \"$(_git_branch_default)\" | wc -l | tr -d ' ')\"\n\n        if [[ $number -gt 0 ]]; then\n          # Output project in cyan and number in white color.\n          printf \"\\033[36m${project}\\033[m: $number\\n\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Branch Rename\n# Description: Rename current branch.\n# Parameters: $1 (required): Branch name.\ngbr() {\n  local new_branch=\"$1\"\n  local old_branch=\"$(_git_branch_name)\"\n\n  git branch --move \"$new_branch\"\n\n  if [[ -n \"$(git branch --remotes --list origin/$old_branch)\" ]]; then\n    printf \"\\033[31m\" # Red.\n    read -p \"Delete \\\"$old_branch\\\" remote branch and push \\\"$new_branch\\\" branch (y/n)?: \" response\n    printf \"\\033[m\" # White.\n\n    if [[ \"$response\" == 'y' ]]; then\n      git push --delete origin \"$old_branch\"\n      git push --set-upstream origin \"$new_branch\"\n    fi\n  fi\n}\n\n# Label: Git Branch Switch\n# Description: Switch between branches.\ngbs() {\n  gbl | fzf | awk '{print $1}' | xargs git switch\n}\n\n# Label: Git Branch Switch (all)\n# Description: Switch to given branch for projects in current directory.\n# Parameters: $1 (required): The branch name.\ngbsa() {\n  local branch=\"$1\"\n\n  if [[ -n \"$branch\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n\n        if [[ -d \".git\" ]]; then\n          local current_branch=\"$(_git_branch_name)\"\n\n          if [[ $(git rev-parse --quiet --verify \"$branch\") && \"$current_branch\" != \"$branch\" ]]; then\n            git switch --quiet \"$branch\"\n            printf \"\\033[36m${project}\\033[m: $branch\\n\" # Output in cyan and branch in white color.\n          fi\n        fi\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Branch name must be supplied.\"\n  fi\n}\n\n# Label: Git Commit (all)\n# Description: Commit changes (unstaged and staged) for projects in current directory.\ngcaa() {\n  local temp_file=$(mktemp -t git-commit)\n  cp $HOME/.config/git/commit_message.txt $temp_file\n  $EDITOR --wait $temp_file\n\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Only process projects that have changes.\n        if [[ \"$(git status --short)\" ]]; then\n          printf \"\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n          git commit --all --cleanup strip --file $temp_file\n        fi\n      fi\n    )\n  done < <(ls -A1)\n\n  rm -f $temp_file\n}\n\n# Label: Git Commit and Push (all)\n# Description: Commit and push changes for projects in current directory.\ngcap() {\n  local temp_file=$(mktemp -t git-commit)\n  cp $HOME/.config/git/commit_message.txt $temp_file\n  $EDITOR --wait $temp_file\n\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Only process projects that have changes.\n        if [[ \"$(git status --short)\" ]]; then\n          printf \"\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n          git commit --all --cleanup strip --file $temp_file && gp\n        fi\n      fi\n    )\n  done < <(ls -A1)\n\n  rm -f $temp_file\n}\n\n# Label: Git Commit Breakpoint\n# Description: Create a breakpoint (empty) commit to denote related commits in a feature branch.\n# Parameters: $1 (optional): A custom label. Default: \"Breakpoint\"\ngcb() {\n  local label=\"${1:-Breakpoint}\"\n  git commit --allow-empty --no-verify --message \"----- $label -----\"\n}\n\n# Label: Git Commit Fixup\n# Description: Create fixup commit with optional amend or reword support.\n# Parameters: $1 (required): SHA, $2 (optional): (a)mend or (r)eword.\ngcf() {\n  local sha=\"$1\"\n  local kind=\"$2\"\n\n  if [[ -z \"$sha\" ]]; then\n    printf \"%s\\n\" \"ERROR: SHA is missing.\"\n    return\n  fi\n\n  case $kind in\n    'a')\n      git commit --fixup=amend:\"$sha\";;\n    'r')\n      git commit --fixup=reword:\"$sha\";;\n    *)\n      git commit --fixup \"$sha\";;\n  esac\n}\n\n# Label: Git Commit Fix (file)\n# Description: Create commit fix for file (ignores previous fixups).\ngcff() {\n  local file_path\n  local file_sha\n\n  file_path=\"$(git ls-files --modified | _fzf_preview_and_select)\"\n\n  if [[ -a \"$file_path\" ]]; then\n    file_sha=\"$(git log --grep 'fixup!' --invert-grep --pretty=format:%h -1 \"$file_path\")\"\n  else\n    return 0\n  fi\n\n  if [[ \"($(_git_branch_shas))\" == *\"$file_sha\"* ]]; then\n    git add \"$file_path\" && git commit --fixup \"$file_sha\"\n  fi\n}\n\n# Label: Git Commit Fix (interactive)\n# Description: Select which commit to fix within current feature branch.\n# Parameters: $1 (optional): (a)mend or (r)eword.\ngcfi() {\n  local kind=\"$1\"\n\n  selection=$(\n    git log --color --pretty=format:\"$(_git_log_enrich_format)\" \"$(_git_branch_range)\" \\\n    | _git_log_enrich \\\n    | fzf --preview 'git show --color {1}' --preview-window=wrap \\\n    | cut -d ' ' -f 1\n  )\n\n  if [[ -n \"$selection\" ]]; then\n    gcf \"$selection\" \"$kind\"\n  fi\n}\n\n# Label: Git Diff Files\n# Description: List all added/changed files on current branch.\ngdf() {\n  git log --pretty=\"\" --name-only \"$(_git_branch_range)\" \\\n  | sort \\\n  | uniq \\\n  | _fzf_preview_and_select \\\n  | xargs \"$EDITOR\"\n}\n\n# Label: Git Day\n# Description: Answer summarized list of current day activity for projects in current directory.\ngday() {\n  gince \"12am\"\n}\n\n# Label: Git Reset Hard\n# Description: Reset to HEAD, destroying all untracked, staged, and unstaged changes. UNRECOVERABLE!\n# Parameters: $1 (optional): The number of commits to reset or a specific commit SHA.\ngesh() {\n  local value=\"$1\"\n  local number_pattern=\"^[0-9]+$\"\n  local commit_pattern=\"^[a-f0-9]+$\"\n\n  git clean --force --quiet -d\n\n  if [[ \"$value\" =~ $number_pattern ]]; then\n    git reset --hard \"HEAD~${value}\"\n  elif [[ \"$value\" =~ $commit_pattern ]]; then\n    git reset --hard \"${value}\"\n  else\n    git reset --hard HEAD\n  fi\n}\n\n# Label: Git Reset Hard (all)\n# Description: Destroy all untracked, staged, and unstaged changes for all projects in current directory. UNRECOVERABLE!\n# Parameters: $1 (optional): The number of commits to reset or a specific commit SHA.\ngesha() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        printf \"\\n\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n        gesh \"$1\"\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Reset Soft\n# Description: Resets previous commit (default), resets back to number of commits, or resets to specific commit.\n# Parameters: $1 (optional): The number of commits to reset or a specific commit SHA.\ngess() {\n  local value=\"$1\"\n  local number_pattern=\"^[0-9]+$\"\n  local commit_pattern=\"^[a-f0-9]+$\"\n\n  if [[ \"$value\" =~ $number_pattern ]]; then\n    git reset --soft \"HEAD~${value}\"\n  elif [[ \"$value\" =~ $commit_pattern ]]; then\n    git reset --soft \"${value}\"\n  else\n    git reset --soft HEAD^\n  fi\n}\n\n# Label: Git Get Config Value (all)\n# Description: Answer key value for projects in current directory.\n# Parameters: $1 (required): The key name.\nggeta() {\n  if [[ \"$1\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n\n        if [[ -d \".git\" ]]; then\n          # Get Git config value for given key.\n          local result=$(git config get \"$1\")\n\n          # Print project (cyan).\n          printf \"\\033[36m${project}\\033[m: \"\n\n          # Print result.\n          if [[ -n \"$result\" ]]; then\n            printf \"$1 = $result\\n\" # White\n          else\n            printf \"\\033[31mKey not found.\\033[m\\n\" # Red\n          fi\n        fi\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Key must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Git Guise Add\n# Description: Adds Git configuration and associated profile.\n# Parameters: $1 (required): Label.\ngga() {\n  local label=\"$1\"\n  local name=\"${label,,}\"\n  local path=\"$HOME/.config/git/profiles/${name,,}\"\n\n  if [[ -z \"$label\" ]]; then\n    printf \"%s\\n\" \"ERROR: Guise label must be supplied.\"\n    return\n  fi\n\n  git config set --global \\\n  includeIf.\"gitdir:~/Engineering/Companies/$label/\".path \"$HOME/.config/git/profiles/$name\" \\\n  && touch \"$path\" \\\n  && printf \"%s\\n\" \"Created: $path.\"\n}\n\n# Label: Git Guise Delete\n# Description: Deletes Git configuration and associated profile.\n# Parameters: $1 (required): Name.\nggd() {\n  local name=\"$1\"\n  local path=\"$HOME/.config/git/profiles/$name\"\n\n  if [[ -z \"$name\" ]]; then\n    printf \"%s\\n\" \"ERROR: Guise name must be supplied.\"\n    return\n  fi\n\n  rg --no-line-number --ignore-case --regexp \"includeIf.+$name\" \"$GIT_CONFIG_GLOBAL\" \\\n  | sed 's/\\[includeIf \\\"//g' \\\n  | sed 's/\\\"\\]//g' \\\n  | xargs -I {} git config unset --global \"includeIf.{}.path\" \\\n  && rm -f \"$path\" \\\n  && printf \"%s\\n\" \"Deleted: $path.\"\n}\n\n# Label: Git Show\n# Description: Show commit details with optional diff support.\n# Parameters: $1 (optional): The commit to show. Default: <last commit>, $2 (optional): Launch difftool. Default: false.\nghow() {\n  local commit=\"$1\"\n  local difftool=\"$2\"\n\n  if [[ -n \"$commit\" && -n \"$difftool\" ]]; then\n    _git_show_details \"$commit\"\n    git difftool \"$commit^\" \"$commit\"\n  elif [[ -n \"$commit\" && -z \"$difftool\" ]]; then\n    _git_show_details \"$commit\"\n  else\n    _git_show_details\n  fi\n}\n\n# Label: Git Churn\n# Description: Answer commit churn for project files (sorted highest to lowest).\nghurn() {\n  git log --all \\\n          --find-renames \\\n          --find-copies \\\n          --name-only \\\n          --format='format:' \"$@\" \\\n          | sort \\\n          | grep --invert-match '^$' \\\n          | uniq -c \\\n          | sort \\\n          | awk '{print $1 \"\\t\" $2}' \\\n          | sort --general-numeric-sort --reverse \\\n          | more\n}\n\n# Label: Git Init (all)\n# Description: Initialize/re-initialize repositories in current directory.\ngia() {\n  while read -r project; do\n    (\n      cd \"$project\"\n      if [[ -d \".git\" ]]; then\n        printf \"\\033[36m${project}\\033[m: \" # Print project (cyan) and message (white).\n        git init\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git File\n# Description: Show file details for a specific commit (with optional diff support).\n# Parameters: $1 (required): The file, $2 (required): The commit, $3 (optional): Launch difftool. Default: false.\ngile() {\n  local file=\"$1\"\n  local commit=\"$2\"\n  local diff=\"$3\"\n\n  if [[ -z \"$file\" ]]; then\n    printf \"%s\\n\" \"ERROR: File is missing.\"\n    return 1\n  fi\n\n  if [[ -z \"$commit\" ]]; then\n    printf \"%s\\n\" \"ERROR: Commit SHA is missing.\"\n    return 1\n  fi\n\n  git show --stat --pretty=format:\"$(_git_log_details_format)\" \"$commit\" -- \"$file\"\n\n  if [[ -n \"$diff\" ]]; then\n    gdt $commit^! -- \"$file\"\n  fi\n}\n\n# Label: Git Import\n# Description: Import remote repository commits into current local branch.\n# Parameters: $1 (required): URL, $2 (optional): Branch, $3 (optional): Name.\ngim() {\n  local url=\"$1\"\n  local branch=\"${2:-main}\"\n  local name=\"${3:-import}\"\n  local remote=\"$name/$branch\"\n\n  if [[ -z \"$url\" ]]; then\n    printf \"%s\\n\" \"Remote repository URL must be supplied.\"\n    return 1\n  fi\n\n  git remote add \"$name\" \"$url\"\n  git fetch \"$name\"\n  git cherry-pick \"$(git rev-list --max-parents=0 \"$remote\")\"..\"$(git rev-list -1 \"$remote\")\"\n  git remote remove \"$name\"\n}\n\n# Label: Git Since\n# Description: Answer summarized list of activity since date/time for projects in current directory.\n# Parameters: $1 (required): The date/time since value, $2 (optional): The date/time until value, $3 (optional): The commit author.\ngince() {\n  if [[ \"$1\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n\n        if [[ -d \".git\" ]]; then\n          # Capture git log activity.\n          results=$(git log --reverse --color --format=\"$(_git_log_enrich_format)\" --since \"$1\" --until \"$2\" --author \"$3\" | _git_log_enrich)\n          # Print project name (cyan) and Git activity (white) only if Git activity was detected.\n          if [[ -n \"$results\" ]]; then\n            printf \"\\033[36m${project}:\\033[m\\n$results\\n\"\n          fi\n        fi\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Date/time must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Git Info\n# Description: Print repository overview information.\nginfo() {\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Local Configuration (.git/config) ')\"\n  git config list --local\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Stashes ')\"\n  local stashes=\"$(gashl)\"\n  if [[ -n \"$stashes\" ]]; then\n    printf \"%s\\n\" \"$stashes\"\n  else\n    printf \"%s\\n\" \"None.\"\n  fi\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Branches ')\"\n  gbl\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Remote URLs ')\"\n  git remote --verbose\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' File Churn (Top 25) ')\"\n  ghurn | head -n 25\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Commits by Author ')\"\n  guthors\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Total Commits ')\"\n  gount\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Last Tag ')\"\n  _git_tag_last_info\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Last Commit ')\"\n  git show --decorate --stat\n\n  printf \"\\n%s\\n\\n\" \"$(_print_black_on_white ' Current Status ')\"\n  git status --short --branch\n}\n\n# Label: Git File History\n# Description: View file commit history (with optional diff support).\n# Parameters: $1 (required): The file path.\ngistory() {\n  if [[ -z \"$1\" ]]; then\n    printf \"%s\\n\" \"ERROR: File must be supplied.\"\n    return 1\n  fi\n\n  local file=\"$1\"\n  local commits=($(git rev-list --use-bitmap-index --reverse HEAD -- \"$file\"))\n\n  _git_file_commits commits[@] \"$file\"\n}\n\n# Label: Git Blame History\n# Description: View commit history for file and/or lines (with optional diff support).\n# Parameters: $1 (required): The file path, $2 (optional): The file lines (<start>,<end>).\nglameh() {\n  if [[ -z \"$1\" ]]; then\n    printf \"%s\\n\" \"ERROR: File must be supplied.\"\n    return 1\n  fi\n\n  local file=\"$1\"\n  local lines=\"$2\"\n  local commits=(\"$(git blame -s -M -C -L \"$lines\" \"$file\" | awk '{print $1}' | sort -u)\")\n\n  _git_file_commits commits[@] \"$file\"\n}\n\n# Label: Git Clean (all)\n# Description: Clean uncommitted files from all projects in current directory.\ngleana() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Only process projects that have untracked changes.\n        if [[ \"$(git status --untracked-files --short)\" ]]; then\n          printf \"\\n\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n          git clean -d --force\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Clear\n# Description: Clear repository for packaging/shipping purposes.\nglear() {\n  if [[ ! -d .git ]]; then\n    printf \"%s\\n\" \"ERROR: Project is not a Git repository.\"\n    return 1\n  fi\n\n  read -p \"Permanently delete/compact repository files? Continue (y/n)?: \" response\n\n  if [[ \"$response\" == \"y\" ]]; then\n    printf \"%s\\n\\n\" \"Verifying connectivity and validity of the objects in Git repository...\"\n    git fsck\n\n    printf \"%s\\n\\n\" \"Pruning rerere records of older conflicting merges...\"\n    git rerere gc\n\n    printf \"\\n%s\\n\\n\" \"Aggressively pruning repository...\"\n    git gc --aggressive --prune=now\n\n    printf \"\\n%s\\n\" \"Clearing reflog...\"\n    git reflog expire --expire=now --all\n\n    printf \"\\n%s\\n\" \"Clearing commit message file...\"\n    echo > .git/COMMIT_EDITMSG\n\n    printf \"\\n%s\\n\" \"Clearing sample Git Hooks...\"\n    rm -rf .git/hooks/*.sample\n\n    printf \"\\n%s\\n\" \"Deleting code coverage reports...\"\n    rm -rf coverage\n\n    printf \"\\n%s\\n\" \"Deleting Rubocop cache...\"\n    copd\n\n    printf \"\\n%s\\n\" \"Deleting Node modules...\"\n    rm -rf node_modules\n\n    printf \"\\n%s\\n\" \"Deleting temp directory...\"\n    rm -rf tmp\n  else\n    printf \"%s\\n\" \"Git clear aborted.\"\n  fi\n}\n\n# Label: Git Log Grep\n# Description: Grep Git log by query.\n# Parameters: $1 (required): Query.\nglg() {\n  local query=\"$1\"\n\n  if [[ -z \"$query\" ]]; then\n    printf \"%s\\n\" \"ERROR: Grep query is required.\"\n    return 1\n  fi\n\n  selection=$(\n    git log --color --pretty=format:\"$(_git_log_enrich_format)\" --grep \"$query\" \\\n    | _git_log_enrich \\\n    | fzf --preview 'git show --color {1}' --preview-window=wrap \\\n    | cut -d ' ' -f 1\n  )\n\n  if [[ -n \"$selection\" ]]; then\n    ghow \"$selection\"\n  fi\n}\n\n# Label: Git Log (interactive)\n# Description: List default or feature branch commits with commit show and/or diff support.\ngli() {\n  selection=$(\n    git log --color --pretty=format:\"$(_git_log_enrich_format)\" \"$(_git_branch_range)\" \\\n    | _git_log_enrich \\\n    | fzf --preview 'git show --color {1}' --preview-window=wrap \\\n    | cut -d ' ' -f 1\n  )\n\n  if [[ -n \"$selection\" ]]; then\n    ghow \"$selection\"\n  fi\n}\n\n# Label: Git Log Search\n# Description: Search Git log by query.\n# Parameters: $1 (required): Query.\ngls() {\n  local query=\"$1\"\n\n  if [[ -z \"$query\" ]]; then\n    printf \"%s\\n\" \"ERROR: Search query is required.\"\n    return 1\n  fi\n\n  selection=$(\n    git log --color --pretty=format:\"$(_git_log_enrich_format)\" -S \"$query\" \\\n    | _git_log_enrich \\\n    | fzf --preview 'git show --color {1}' --preview-window=wrap \\\n    | cut -d ' ' -f 1\n  )\n\n  if [[ -n \"$selection\" ]]; then\n    ghow \"$selection\"\n  fi\n}\n\n# Label: Git Log Fuzzy\n# Description: Fuzzy find commits in the log.\nglz() {\n  git log --color --pretty=format:\"$(_git_log_line_format)\" \\\n  | fzf --no-sort --reverse --preview 'git show --color {1}' --preview-window=wrap\n}\n\n# Label: Git Merge\n# Description: Interactively select a branch to merge into the current branch and delete after.\n# Parameters: $1 (required): The branch to merge.\ngm() {\n  branch=\"$(gbl | fzf | awk '{print $1}')\"\n\n  git merge \"$branch\" && git branch --delete --force \"$branch\" && git push --delete origin \"$branch\"\n}\n\n# Label: Git Merge (all)\n# Description: Merges, deletes, and pushes feature branch.\n# Parameters: $1 (required): Branch.\ngma() {\n  local branch=\"$1\"\n\n  if [[ -z \"$branch\" ]]; then\n    printf \"%s\\n\" \"ERROR: Branch must be supplied.\"\n    return 1\n  fi\n\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" && \"$(_git_branch_name)\" == \"$branch\" ]]; then\n        printf \"\\033[36m${project}\\033[m: Merging, deleting, and pushing...\\n\"\n\n        git switch \"$(_git_branch_default)\" \\\n        && git merge \"$branch\" \\\n        && git branch --delete --force \"$branch\" \\\n        && git push --delete origin \"$branch\" \\\n        && git push\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Month\n# Description: Answer summarized list of current month activity for projects in current directory.\ngmonth() {\n  gince \"1 month 12am\"\n}\n\n# Label: Git Amend Push (all)\n# Description: Amend all changes and force push with lease for projects in current directory.\ngmpa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Only process projects that have changes.\n        if [[ \"$(git status --short)\" ]]; then\n          printf \"\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n          git commit --amend --all --no-edit && git push --force-with-lease\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Notes Add (interactive)\n# Description: Select which commit note to add for current feature branch.\ngnai() {\n  mapfile -t shas < <(_git_branch_shas)\n\n  _git_commit_options \"${shas[*]}\"\n\n  printf \"\\n\"\n  read -p \"Enter selection or quit (q): \" response\n  if [[ \"$response\" == 'q' ]]; then\n    return\n  fi\n\n  local selection=${shas[$((response - 1))]}\n  printf \"%s\\n\" \"Selected: $selection\"\n  gna \"$selection\"\n}\n\n# Label: Git Notes Edit (interactive)\n# Description: Select which commit note to edit for current feature branch.\ngnei() {\n  mapfile -t shas < <(_git_branch_shas)\n\n  _git_commit_options \"${shas[*]}\"\n\n  printf \"\\n\"\n  read -p \"Enter selection or quit (q): \" response\n  if [[ \"$response\" == 'q' ]]; then\n    return\n  fi\n\n  local selection=${shas[$((response - 1))]}\n  printf \"%s\\n\" \"Selected: $selection\"\n  gne \"$selection\"\n}\n\n# Label: Git Notes Remove (interactive)\n# Description: Select which commit note to remove for current feature branch.\ngndi() {\n  mapfile -t shas < <(_git_branch_shas)\n\n  _git_commit_options \"${shas[*]}\"\n\n  printf \"\\n\"\n  read -p \"Enter selection or quit (q): \" response\n  if [[ \"$response\" == 'q' ]]; then\n    return\n  fi\n\n  local selection=${shas[$((response - 1))]}\n  printf \"%s\\n\" \"Selected: $selection\"\n  gnd \"$selection\"\n}\n\n# Label: Git Notes Show (interactive)\n# Description: Select which commit note to show for current feature branch.\ngnri() {\n  mapfile -t shas < <(_git_branch_shas)\n\n  _git_commit_options \"${shas[*]}\"\n\n  printf \"\\n\"\n  read -p \"Enter selection or quit (q): \" response\n  if [[ \"$response\" == 'q' ]]; then\n    return\n  fi\n\n  local selection=${shas[$((response - 1))]}\n  printf \"%s\\n\" \"Selected: $selection\"\n  gns \"$selection\"\n}\n\n# Label: Git Commit Count\n# Description: Answer total number of commits for current project.\ngount() {\n  printf \"Commits: \"\n  git rev-list --use-bitmap-index --count HEAD\n}\n\n# Label: Git Push (all)\n# Description: Push changes for projects in current directory.\ngpa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Only process projects that have changes.\n        if [[ \"$(git status --short --branch)\" == *\"[ahead\"*\"]\" ]]; then\n          printf \"\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n          gp\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Pull (all)\n# Description: Pull new changes from remote branch for projects in current directory.\ngpua() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Capture current project status.\n        local results=$(git pull | tail -1)\n\n        # Print project name and Git activity only if Git activity was detected.\n        printf \"\\033[36m${project}\\033[m: \" # Outputs in cyan color.\n\n        if [[ -n \"$results\" && \"$results\" != \"Already up-to-date.\" ]]; then\n          printf \"\\n  %s\\n\" \"$results\"\n        else\n          printf \"✓\\n\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Remote Add\n# Description: Add remote repository.\n# Parameters: $1 (required): The repository URL.\ngra() {\n  local url=\"$1\"\n\n  name=$(echo \"$url\" | awk -F/ '{print $4}')\n\n  if [[ -z \"$url\" ]]; then\n    printf \"%s\\n\" \"ERROR: Repository URL must be supplied.\"\n    return 1\n  fi\n\n  git remote add --no-tags \"$name\" \"$url\"\n  git -c fetch.pruneTags=false fetch \"$name\"\n}\n\n# Label: Git Remote Delete\n# Description: Delete local remote.\ngrd() {\n  selection=\"$(git remote | grep -v '^origin$' | fzf)\"\n\n  git remote remove \"$selection\"\n\n  printf \"%s\\n\" \"Removed remote: $selection.\"\n}\n\n# Label: Git Rebase (interactive)\n# Description: Rebase commits, interactively.\n# Parameters: $1 (optional): The number of commits or label (i.e. branch/tag) to rebase to.\ngrbi() {\n  local number_pattern=\"^[0-9]+$\"\n  local label_pattern=\"^[0-9a-zA-Z\\_-]+$\"\n  local parent_sha=$(git log --pretty=format:%h -n 1 \"$(_git_branch_parent)\" 2> /dev/null || :)\n  local value=\"${1:-$parent_sha}\"\n\n  if [[ \"$value\" =~ $number_pattern ]]; then\n    git rebase --keep-empty --interactive \"@~${value}\"\n  elif [[ \"$(_git_branch_name)\" == \"$(_git_branch_default)\" ]]; then\n    git rebase --keep-empty --interactive --root\n  elif [[ \"$value\" =~ $label_pattern ]]; then\n    git rebase --keep-empty --interactive \"$value\"\n  else\n    printf \"%s\\n\" \"Invalid SHA, branch, or tag for rebasing: $value.\"\n    return 1\n  fi\n}\n\n# Label: Git Rebase (quick)\n# Description: Rebase commits, quickly. Identical to `grbi` function but skips editor.\n# Parameters: $1 (optional): The commit number or branch to rebase to. Default: upstream or root.\ngrbq() {\n  GIT_EDITOR=true grbi \"$1\"\n}\n\n# Label: Git Root\n# Description: Change to repository root directory regardless of current depth.\ngroot() {\n  cd \"$(git rev-parse --show-toplevel)\"\n}\n\n# Label: Git Set Config Value (all)\n# Description: Set key value for projects in current directory.\n# Parameters: $1 (required): The key name, $2 (required): The key value.\ngseta() {\n  if [[ \"$1\" && \"$2\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n\n        if [[ -d \".git\" ]]; then\n          # Set key value for current project.\n          git config set \"$1\" \"$2\"\n\n          # Print project (cyan) and email (white).\n          printf \"\\033[36m${project}\\033[m: $1 = $2\\n\"\n        fi\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Key and value must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Git Status (all)\n# Description: Answer status of projects with uncommited/unpushed changes.\ngsta() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Capture current project status info as an array.\n        local results=($(git status --short --branch))\n        local size=${#results[@]}\n\n        # Print Git activity if Git activity detected (white).\n        if [[ $size -gt 2 ]]; then\n          # Remove first and second elements since they contain branch info.\n          results=(\"${results[@]:1}\")\n          results=(\"${results[@]:1}\")\n\n          # Print project (cyan).\n          printf \"\\033[36m${project}\\033[m:\\n\"\n\n          # Print results (white).\n          for line in \"${results[@]}\"; do\n            printf \"%s\" \"$line \"\n            if [[ $newline == 1 ]]; then\n              printf \"\\n\"\n              local newline=0\n            else\n              local newline=1\n            fi\n          done\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Statistics\n# Description: Answer statistics for current project.\ngstats() {\n  if [[ -d \".git\" ]]; then\n    gount\n    printf \"Branches: %s\\n\" \"$(gbl | wc -l | tr -d ' ')\"\n    printf \"Tags: %s\\n\" \"$(git tag | wc -l | tr -d ' ')\"\n    printf \"Stashes: %s\\n\" \"$(_git_stash_count)\"\n    printf \"Size: %s\\n\" \"$(git count-objects --human-readable)\"\n  fi\n}\n\n# Label: Git Statistics (all)\n# Description: Answer statistics for all projects in current directory.\ngstatsa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n      printf \"\\033[36m${project}\\033[m:\\n\" # Print project (cyan) and message (white).\n      gstats\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Standup\n# Description: Answer summarized list of activity since yesterday for projects in current directory.\ngsup() {\n  gince \"yesterday.midnight\" \"midnight\" $(git config get user.name)\n}\n\n# Label: Git Tag Delete\n# Description: Delete local and remote tag (if found).\n# Parameters: $1 (required): The tag name.\ngtd() {\n  if [[ -z \"$1\" ]]; then\n    printf \"%s\\n\" \"ERROR: Tag name must be supplied.\"\n    return 1\n  fi\n\n  read -p \"Delete '$1' tag from local and remote repositories. Continue (y/n)?: \" response\n\n  if [[ \"$response\" == 'y' ]]; then\n    printf \"%s \" \"Local:\"\n    if [[ -n \"$(git tag --list $1)\" ]]; then\n      git tag --delete \"$1\"\n    else\n      printf \"%s\\n\" \"No tag found.\"\n    fi\n\n    printf \"%s \" \"Remote:\"\n    if [[ $(git config get remote.origin.url) && -n \"$(git ls-remote --tags origin | rg $1)\" ]]; then\n      git push --delete origin \"$1\"\n    else\n      printf \"%s\\n\" \"No tag found.\"\n    fi\n  else\n    printf \"%s\\n\" \"Tag deletion aborted.\"\n  fi\n}\n\n# Label: Git Tag List\n# Description: List tags in tabular form.\ngtl() {\n  local format=\"\\\n%(color:yellow)%(refname:short)%(color:reset)|%(taggerdate:short)|\\\n%(color:brightblue)%(taggername)%(color:reset)|\\\n%(color:brightmagenta)%(trailers:key=Commits,separator=)%(color:reset)|\\\n%(color:brightmagenta)%(trailers:key=Files,separator=)%(color:reset)|\\\n%(color:green)%(trailers:key=Deletions,separator=)%(color:reset)|\\\n%(color:red)%(trailers:key=Insertions,separator=)%(color:reset)|\\\n%(color:brightmagenta)%(trailers:key=Duration,separator=)%(color:reset)\"\n\n  git tag --list --sort=taggerdate --color --format=\"$format\" | column -s \"|\" -t\n}\n\n# Label: Git Tag Rebuild\n# Description: Rebuild a previous tag. WARNING: Use with caution, especially if previously published.\n# Parameters: $1 (required): Version, $2 (required): Release notes path, $3 (optional): Creation date/time. Default: current date/time.\ngtr() {\n  local version=\"$1\"\n  local path=\"$2\"\n  local datetime=\"${3:-$(date '+%Y-%m-%d %H:%M:%S')}\"\n\n  GIT_COMMITTER_DATE=\"$datetime\" git tag --force --sign --file \"$path\" \"$version\"\n}\n\n# Label: Git Tail\n# Description: Answer commit history since last tag for current project (copies results to clipboard).\ngtail() {\n  if [[ ! -d \".git\" ]]; then\n    printf \"%s\\n\" \"ERROR: Not a Git repository.\"\n    return 1\n  fi\n\n  if [[ $(git tag) ]]; then\n    git log --reverse \\\n            --color \\\n            --pretty=format:\"$(_git_log_enrich_format)\" \"$(_git_tag_last)..HEAD\" \\\n            | _git_log_enrich\n    printf \"\\n\"\n  else\n    git log --reverse --color --pretty=format:\"$(_git_log_enrich_format)\" | _git_log_enrich\n    printf \"\\n\"\n  fi\n}\n\n# Label: Git Tail (all)\n# Description: Answer commit history count since last tag for projects in current directory.\ngtaila() {\n  # Iterate through root project directories.\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        local info=$(_git_commit_count_since_last_tag \"$project\")\n        if [[ ! \"$info\" == *\": 0\"* ]]; then\n          printf \"%s\\n\" \"$info\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Upstream Commit Count (all)\n# Description: Answer upstream commit count since last pull for projects in current directory.\ngucca() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Capture upstream project commit count.\n        git fetch --quiet\n        local count=$(git log ..@{upstream} --pretty=format:\"%h\" | wc -l | tr -d ' ')\n\n        if [[ $count -gt '0' ]]; then\n          # Print project (cyan) and commit count (white).\n          printf \"\\033[36m${project}\\033[m: $count\\n\"\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Nuke\n# Description: Permanently destroy and erase a file from history. UNRECOVERABLE!\n# Parameters: $1 (optional): The file to destroy.\nguke() {\n  local file=\"$1\"\n\n  if [[ -z \"$file\" ]]; then\n    printf \"%s\\n\" \"ERROR: File to nuke must be supplied.\"\n    return 1\n  fi\n\n  printf \"\\033[31m\" # Switch to red font.\n  read -p \"Permanently delete '$file' from the local repository. Continue (y/n)?: \" response\n  printf \"\\033[m\" # Switch to white font.\n\n  if [[ \"$response\" == 'y' ]]; then\n    git-filter-repo --force --invert-paths --path \"$file\"\n  else\n    printf \"%s\\n\" \"Nuke aborted.\"\n  fi\n}\n\n# Label: Git Garbage Collect\n# Description: Garbage collect dangling commits for projects in current directory.\ngarb() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        printf \"\\033[36m${project}\\033[m\\n\" # Output in cyan and branch in white color.\n        git reflog expire --expire-unreachable=now --all\n        git gc --prune=now\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Unset (all)\n# Description: Unset key value for projects in current directory.\n# Parameters: $1 (required): The key name.\ngunseta() {\n  if [[ \"$1\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n\n        if [[ -d \".git\" ]]; then\n          # Unset key for current project with error output suppressed.\n          git config unset \"$1\" &> /dev/null\n\n          # Print project (cyan).\n          printf \"\\033[36m${project}\\033[m: \\\"$1\\\" key removed.\\n\"\n        fi\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Key must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Git Update\n# Description: Fetch commits, prune untracked references, review each commit (optional, with diff), and pull (optional).\ngup() {\n  git fetch --quiet\n  commits=($(git log --reverse --no-merges --pretty=format:\"%h\" ..@{upstream}))\n\n  if [[ ${#commits[@]} == 0 ]]; then\n    printf \"%s\\n\" \"All is quiet, nothing to update.\"\n    return 0\n  fi\n\n  printf \"%s\\n\" \"Commit Summary:\"\n  hr '-'\n  git log --reverse --no-merges --pretty=format:\"$(_git_log_line_format)\" ..@{upstream}\n  hr '-'\n\n  printf \"%s\\n\" \"Commit Review (↓${#commits[@]}):\"\n\n  local counter=1\n  for commit in \"${commits[@]}\"; do\n    hr '-'\n    printf \"[$counter/${#commits[@]}] \"\n    counter=$((counter + 1))\n\n    _git_show_details $commit\n\n    printf \"\\n\"\n    read -p \"View Diff (y = yes, n = no, q = quit)? \" response\n\n    case $response in\n      'y')\n        git difftool $commit^!;;\n      'n');;\n      'q');;\n      *)\n        printf \"%s\\n\" \"ERROR: Invalid option.\";;\n    esac\n\n    break\n  done\n\n  hr '-'\n  read -p \"Commit Pull (y/n)? \" response\n\n  if [[ \"$response\" == 'y' ]]; then\n    git pull\n  fi\n}\n\n# Label: Git Author Contributions\n# Description: Answers total lines added/removed by author for repo (with emphasis on deletion).\n# Parameters: $1 (optional): Author name. Default: Current user.\nguthorc() {\n  local author=\"${1:-$(git config get user.name)}\"\n\n  if [[ -z \"$author\" ]]; then\n    printf \"%s\\n\" \"ERROR: Author name required.\"\n    return 1\n  fi\n\n  git log --author=\"$author\" \\\n          --pretty=tformat: --numstat \\\n          | awk -v author=\"$author\" \\\n            'BEGIN {\n              initial_pattern = \"\\033[1;34m%s\\033[0m: Added: \\033[0;31m%s\\033[0m, Removed: \\033[0;32m%s\\033[0m, \"\n              positive_pattern = initial_pattern \"Total: \\033[0;32m%s\\033[0m.\\n\";\n              neutral_pattern = initial_pattern \"Total: %s.\\n\";\n              negative_pattern = initial_pattern \"Total: \\033[0;31m%s\\033[0m.\\n\";\n            }\n            {\n              added += $1;\n              removed += $2;\n              total += $1 - $2;\n            }\n            END {\n              if (total > 0)\n                printf negative_pattern, author, added, removed, total\n              else if (total < 0)\n                printf positive_pattern, author, added, removed, total\n              else\n                printf neutral_pattern, author, added, removed, total\n            }'\n}\n\n# Label: Git Authors (all)\n# Description: Answer author commit activity per project (ranked highest to lowest).\nguthorsa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        # Print project (cyan) and message (white).\n        printf \"\\033[36m${project}\\033[m:\\n\"\n        guthors\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Verify and Clean\n# Description: Verify and clean objects for current project.\ngvac() {\n  printf \"%s\\n\\n\" \"Verifying connectivity and validity of the objects in Git repository...\"\n  git fsck\n\n  printf \"%s\\n\" \"Packing unpacked objects into a single pack and removing redundant packs...\"\n  git repack -Ad\n\n  printf \"\\n%s\\n\\n\" \"Cleaning unnecessary files and optimizing local Git repository...\"\n  git maintenance run --task=gc\n\n  printf \"%s\\n\\n\" \"Pruning rerere records of older conflicting merges...\"\n  git rerere gc\n}\n\n# Label: Git Verify and Clean (all)\n# Description: Verify and clean objects for projects in current directory.\ngvaca() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        printf \"\\n\\033[36m${project}\\033[m:\\n\" # Outputs in cyan color.\n        git fsck && git repack -Ad && git maintenance run --task=gc && git rerere gc\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: Git Worktree Add\n# Description: Add and switch to new worktree.\n# Parameters: $1 (required): Worktree/branch name, $2 (required): Option.\ngwa() {\n  local name=\"$1\"\n  local option=\"$2\"\n  local project_name=\"$(basename $(pwd))\"\n  local worktree_path=\"../$project_name-$name\"\n\n  if [[ -z \"$name\" ]]; then\n    printf \"%s\\n\" \"ERROR: Worktree name must be supplied.\"\n    return 1\n  fi\n\n  if [[ \"$option\" != \"d\" && -n $(git branch --list \"$name\") ]]; then\n    printf \"%s\\n\" \"ERROR: Invalid worktree, local branch exists.\"\n    return 1\n  fi\n\n  case $option in\n    'd')\n      git worktree add --detach \"$worktree_path\" HEAD;;\n    'r')\n      git worktree add -b \"$name\" \"$worktree_path\" origin/\"$name\";;\n    'l')\n      git worktree add -b \"$name\" \"$worktree_path\" \"$(_git_branch_default)\";;\n    *)\n      printf \"%s\\n\" \"ERROR: Invalid worktree option: Use: (d)etach, (r)emote, or (l)ocal.\"\n      return 1;;\n  esac\n\n  printf \"%s\\n\" \"Syncing project files...\"\n  git ls-files --others | rsync --links --files-from - \"$(pwd)/\" \"$worktree_path/\"\n  cd \"$worktree_path\"\n}\n\n# Label: Git Worktree Delete\n# Description: Deletes current Git worktree.\ngwd() {\n  local project_name=\"$(basename $(git rev-parse --show-toplevel) | cut -d'-' -f1)\"\n  local worktree_dir=\"$(pwd)\"\n  local branch=\"$(_git_branch_name)\"\n\n  if [[ \"$(git status --short)\" ]]; then\n    printf \"%s\\n\" \"ERROR: Git worktree has uncommitted changes.\"\n    return 1\n  else\n    cd ../$project_name\n    read -p \"Git worktree: $worktree_dir. Delete (y/n)?: \" response\n\n    if [[ \"$response\" == 'y' ]]; then\n      rm -rf $worktree_dir\n      git worktree prune\n      gbdl \"$branch\"\n      git branch --delete --force \"$branch\"\n    fi\n  fi\n}\n\n# Label: Git Week\n# Description: Answer summarized list of current week activity for projects in current directory.\ngweek() {\n  gince \"last Monday 12am\"\n}\n\n# Label: Git Sync\n# Description: Syncs up remote changes and deletes pruned/merged branches.\ngync() {\n  if [[ $(_git_branch_name) != \"$(_git_branch_default)\" ]]; then\n    printf \"%s\\n\" \"ERROR: Whoa, switch to default branch first.\"\n    return 1\n  fi\n\n  git pull && gbdm\n}\n\n#--------------------------------------#\n# Section: https://github.com:[GitHub] #\n#--------------------------------------#\n\n# Label: GitHub\n# Description: View GitHub details for current project.\n# Parameters: $1 (optional): The option selection, $2 (optional): The option input.\ngh() {\n  if [[ -d \".git\" ]]; then\n    while true; do\n      if [[ $# == 0 ]]; then\n        printf \"\\n%s\\n\" \"Usage: gh OPTION\"\n        printf \"\\n%s\\n\" \"GitHub Options (default browser):\"\n        printf \"%s\\n\" \"  a: Open actions.\"\n        printf \"%s\\n\" \"  o: Open repository.\"\n        printf \"%s\\n\" \"  i: Open repository issues.\"\n        printf \"%s\\n\" \"  c: Open repository commits. Options:\"\n        printf \"%s\\n\" \"     HASH: Open commit.\"\n        printf \"%s\\n\" \"  f: Copy repository file URL.\"\n        printf \"%s\\n\" \"  b: Open repository branches. Options:\"\n        printf \"%s\\n\" \"     c: Open current branch.\"\n        printf \"%s\\n\" \"     d: Open diff for current branch.\"\n        printf \"%s\\n\" \"     r: Open pull request for current branch.\"\n        printf \"%s\\n\" \"  t: Open repository tags.\"\n        printf \"%s\\n\" \"  r: Open repository pull requests.\"\n        printf \"%s\\n\" \"     NUMBER: Open pull request.\"\n        printf \"%s\\n\" \"     l: List pull requests.\"\n        printf \"%s\\n\" \"  w: Open repository wiki.\"\n        printf \"%s\\n\" \"  p: Open repository pulse.\"\n        printf \"%s\\n\" \"  g: Open repository graphs.\"\n        printf \"%s\\n\" \"  s: Open repository settings.\"\n        printf \"%s\\n\" \"  u: Print and copy repository URL. Options:\"\n        printf \"%s\\n\" \"     HASH: Print and copy commit URL.\"\n        printf \"%s\\n\" \"     l: Print and copy last commit URL.\"\n        printf \"%s\\n\\n\" \"  q: Quit/Exit.\"\n        read -p \"Enter selection: \" response\n        printf \"\\n\"\n        _process_gh_option $response \"$2\"\n      else\n        _process_gh_option \"$1\" \"$2\" \"$3\"\n      fi\n      break\n    done\n  else\n    printf \"%s\\n\" \"ERROR: Not a Git repository!\"\n    return 1\n  fi\n}\n\n# Label: GitHub Pull Request (all)\n# Description: Open pull requests for all projects in current directory (non-default branches only).\nghpra() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \".git\" ]]; then\n        if [[ \"$(_git_branch_name)\" != \"$(_git_branch_default)\" ]]; then\n          gh b r\n        fi\n      fi\n    )\n  done < <(ls -A1)\n}\n\n#-----------------------------------------------------------#\n# Section: https://en.wikipedia.org/wiki/Less_(Unix):[less] #\n#-----------------------------------------------------------#\n\n# Label: Less Interactive\n# Description: Inspect file, interactively.\n# Parameters: $1 (required): The file path.\nlessi() {\n  if [[ \"$1\" ]]; then\n    less +F --LONG-PROMPT --LINE-NUMBERS --RAW-CONTROL-CHARS --QUIET --quit-if-one-screen -i \"$1\"\n  else\n    printf \"%s\\n\" \"ERROR: File path must be supplied.\"\n    printf \"%s\\n\" \"TIP: Use CONTROL+c to switch to VI mode, SHIFT+f to switch back, and CONTROL+c+q to exit.\"\n  fi\n}\n\n#--------------------------------------------------------------------#\n# Section: https://github.com/pivotal/LicenseFinder:[License Finder] #\n#--------------------------------------------------------------------#\n\n# Label: License Finder (add)\n# Description: Adds library to global list.\n# Parameters: $1 (required): Library, $2 (required): Why.\nlicensea() {\n  local library=\"$1\"\n  local why=\"$2\"\n\n  if [[ -z \"$library\" ]]; then\n    printf \"%s\\n\" \"ERROR: Must supply library.\"\n    return 1\n  fi\n\n  if [[ -z \"$why\" ]]; then\n    printf \"%s\\n\" \"ERROR: Explain why the license is safe.\"\n    return 1\n  fi\n\n  license_finder approval add \"$library\" --who \"$(git config get user.name)\" --why \"$why\"\n}\n\n# Label: License Finder (include)\n# Description: Include license in global list.\n# Parameters: $1 (required): License, $2 (required): Why.\nlicensei() {\n  local license=\"$1\"\n  local why=\"$2\"\n\n  if [[ -z \"$license\" ]]; then\n    printf \"%s\\n\" \"ERROR: Must supply license.\"\n    return 1\n  fi\n\n  if [[ -z \"$why\" ]]; then\n    printf \"%s\\n\" \"ERROR: Explain why the license is safe.\"\n    return 1\n  fi\n\n  license_finder whitelist add \"$license\" --who \"$(git config get user.name)\" --why \"$why\"\n}\n\n#-------------------------------------------------#\n# Section: https://people.freebsd.org/~abe:[lsof] #\n#-------------------------------------------------#\n\n# Label: Port\n# Description: List file activity on given port.\n# Parameters: $1 (required): The port number.\nport() {\n  if [[ \"$1\" ]]; then\n    lsof -i :$1 +c0\n  else\n    printf \"%s\\n\" \"ERROR: Port number must be supplied.\"\n  fi\n}\n\n#--------------------------------------------#\n# Section: https://marked2app.com:[Marked 2] #\n#--------------------------------------------#\n\n# Label: Marked Open\n# Description: Opens Markdown file in Marked.\n# Parameters: $1 (optional): Path to Markdown file. Default: README.md.\nmo() {\n  local path=${1:-README.md}\n  open -a Marked\\ 2 \"$path\"\n}\n\n#-----------------------------------------------------------------#\n# Section: https://alchemists.io/projects/milestoner:[Milestoner] #\n#-----------------------------------------------------------------#\n\n# Label: Milestoner (ASCII Doc)\n# Description: Build milestone(s) in ASCII Doc format.\n# Parameters: $1 (optional): Maximum. Default: 1.\nmsa() {\n  local max=${1:-1}\n  local root=\"tmp/milestones\"\n  local selection=\"\"\n\n  rm -rf tmp/milestones\n  milestoner build --max \"$max\" --format ascii_doc\n\n  read -r selection < <(fd .adoc tmp/milestones | _fzf_preview_and_select)\n\n  if [[ -n \"$selection\" ]]; then\n    ado \"$selection\"\n  fi\n}\n\n# Label: Milestoner (feed)\n# Description: Build milestone(s) in feed (atom) format.\n# Parameters: $1 (optional): Maximum. Default: 10.\nmsf() {\n  local max=${1:-10}\n  local path=\"tmp/milestones/index.xml\"\n\n  rm -rf tmp/milestones\n  milestoner build --max \"$max\" --format feed\n\n  if [[ -f \"$path\" ]]; then\n    open -a \"Vivaldi\" \"tmp/milestones/index.xml\"\n  fi\n}\n\n# Label: Milestoner (Markdown)\n# Description: Build milestone(s) in Markdown format.\n# Parameters: $1 (optional): Maximum. Default: 1.\nmsm() {\n  local max=${1:-1}\n  local path=\"tmp/milestones/index.md\"\n  local selection=\"\"\n\n  rm -rf tmp/milestones\n  milestoner build --max \"$max\" --format markdown\n\n  read -r selection < <(fd .md tmp/milestones | _fzf_preview_and_select)\n\n  if [[ -n \"$selection\" ]]; then\n    mo \"$selection\"\n  fi\n}\n\n# Label: Milestoner (stream)\n# Description: Build milestone(s) in stream format.\n# Parameters: $1 (optional): Maximum. Default: 1.\nmss() {\n  local max=${1:-1}\n  milestoner build --max \"$max\" --format stream\n}\n\n# Label: Milestoner (web)\n# Description: Build milestone(s) in web format.\n# Parameters: $1 (optional): Maximum. Default: 1.\nmsw() {\n  local max=${1:-1}\n  local root=\"tmp/milestones\"\n  local path=\"\"\n\n  rm -rf \"$root\"\n  milestoner build --max \"$max\" --format web\n  path=\"$(eza --oneline --all --only-dirs \"$root\" | tail -n 1)\"\n\n  if [[ -d \"$root\" ]]; then\n    reb \"$root\" 3030 \"$path\"\n  fi\n}\n\n#---------------------------------------------------------#\n# Section: https://jedisct1.github.io/minisign:[Minisign] #\n#---------------------------------------------------------#\n\n# Label: Minisign Sign File\n# Description: Sign a file.\n# Parameters: $1 (required): File path, $2 (optional): Comment.\nsigf() {\n  local path=\"$1\"\n  local comment=\"$2\"\n\n  minisign -S -s \"$HOME/.minisign/alchemists.key\" -m \"$path\" -t \"$comment\"\n}\n\n# Label: Minisign Generate\n# Description: Generate private and public key pair.\n# Parameters: $1 (required): Key pair name.\nsigg() {\n  local name=\"$1\"\n\n  minisign -G -s \"$HOME/.minisign/$name.key\" -p \"$HOME/.minisign/$name.pub\"\n}\n\n# Label: Minisign Verify File\n# Description: Verify signed file.\n# Parameters: $1 (required): File path.\nsigv() {\n  local path=\"$1\"\n\n  minisign -V -p \"$HOME/.minisign/alchemists.pub\" -m \"$path\"\n}\n\n#-------------------------------------------------------------------#\n# Section: https://en.wikipedia.org/wiki/Network_Computer:[Network] #\n#-------------------------------------------------------------------#\n\n# Label: DNS Flush\n# Description: Flush DNS cache.\ndnsf() {\n  sudo killall -HUP mDNSResponder \\\n  && sudo killall mDNSResponderHelper \\\n  && sudo dscacheutil -flushcache \\\n  && printf 'DNS cache cleared.\\n'\n}\n\n#----------------------------------------#\n# Section: https://openssl.org:[OpenSSL] #\n#----------------------------------------#\n\n# Label: SSL Certificate Creation\n# Description: Create SSL certificate.\n# Parameters: $1 (required): The domain name.\nsslc() {\n  local name=\"$1\"\n\n  if [[ -z \"$name\" ]]; then\n    printf \"%s\\n\" \"ERROR: Domain name for SSL certificate must be supplied.\"\n    return 1\n  fi\n\ncat > \"$name.cnf\" <<-EOF\n  [req]\n  distinguished_name = req_distinguished_name\n  x509_extensions = v3_req\n  prompt = no\n  [req_distinguished_name]\n  CN = *.\"$name\"\n  [v3_req]\n  keyUsage = keyEncipherment, dataEncipherment\n  extendedKeyUsage = serverAuth\n  subjectAltName = @alt_names\n  [alt_names]\n  DNS.1 = *.\"$name\"\n  DNS.2 = \"$name\"\nEOF\n\n  openssl req -new \\\n              -newkey rsa:2048 \\\n              -sha256 \\\n              -days 3650 \\\n              -nodes \\\n              -x509 \\\n              -keyout \"$name.key\" \\\n              -out \"$name.crt\" \\\n              -config \"$name.cnf\"\n\n  rm -f \"$name.cnf\"\n}\n\n#----------------------------------------------------------#\n# Section: https://github.com/DarthSim/overmind:[Overmind] #\n#----------------------------------------------------------#\n\n# Label: Overmind Connect\n# Description: Connect to running process.\n# Parameters: $1 (optional): Process. Default: \"web\".\nomc() {\n  local process=\"${1:-web}\"\n  overmind connect \"$process\"\n}\n\n# Label: Overmind Restart\n# Description: Restart running process.\n# Parameters: $1 (optional): Process. Default: \"web\".\nomr() {\n  local process=\"${1:-web}\"\n  overmind restart \"$process\"\n}\n\n# Label: Overmind Start\n# Description: Start processes.\n# Parameters: $1 (optional): Environment. Use: \"p\" for \"production\". Default: \"\".\noms() {\n  local environment=\"$1\"\n\n  if [[ \"$environment\" == \"p\" ]]; then\n    overmind start --port-step 10 --can-die assets,migrate\n  else\n    overmind start --port-step 10 --procfile Procfile.dev --can-die assets,migrate\n  fi\n}\n\n#--------------------------------------------------#\n# Section: https://github.com/theory/pgenv:[pgenv] #\n#--------------------------------------------------#\n\n# Label: PostgreSQL Install\n# Description: Install (build) specific version.\n# Parameters: $1 (required): Version.\npgi() {\n  local version=\"$1\"\n\n  pgenv build \"$version\" && noti --title \"PostgreSQL $version installed!\"\n}\n\n#--------------------------------------------------#\n# Section: https://www.postgresql.org:[PostgreSQL] #\n#--------------------------------------------------#\n\n# Label: PostgreSQL Template\n# Description: Edit PostgreSQL template.\n# Parameters: $1 (required): The username.\npgt() {\n  local user=\"$1\"\n\n  if [[ -n \"$user\" ]]; then\n    psql -U \"$user\" template1\n  else\n    printf \"%s\\n\" \"ERROR: PostgreSQL username must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: PostgreSQL User Create\n# Description: Create PostgreSQL user.\n# Parameters: $1 (required): The username.\npguc() {\n  local user=\"$1\"\n\n  if [[ -n \"$user\" ]]; then\n    createuser --interactive \"$user\" -P\n  else\n    printf \"%s\\n\" \"ERROR: PostgreSQL username must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: PostgreSQL User Drop\n# Description: Drop PostgreSQL user.\n# Parameters: $1 (required): The username.\npgud() {\n  local user=\"$1\"\n\n  if [[ -n \"$user\" ]]; then\n    dropuser --interactive \"$user\"\n  else\n    printf \"%s\\n\" \"ERROR: PostgreSQL username must be supplied.\"\n    return 1\n  fi\n}\n\n#----------------------------------------------#\n# Section: https://github.com/ruby/rake:[Rake] #\n#----------------------------------------------#\n\n# Label: Rake (all)\n# Description: Run default Rake tasks for projects in current directory.\nrakea() {\n  while read -r project; do\n    (\n      cd \"$project\"\n      if [[ -f \"Gemfile.lock\" && -f \"Rakefile\" ]]; then\n        # Prints project (cyan).\n        printf \"\\033[36m${project}\\033[m: \"\n\n        rake > /dev/null\n        printf \"\\n\"\n      fi\n    )\n  done < <(ls -A1)\n}\n\n#-------------------------------------#\n# Section: https://rspec.info:[RSpec] #\n#-------------------------------------#\n\n# Label: RSpec (all)\n# Description: Run RSpec for projects in current directory.\nrsall() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -f \"Gemfile.lock\" && -d \"spec\" ]]; then\n        local json=$(rspec spec --format json)\n        local examples=$(printf \"%s\" \"$json\" | jq \".summary.example_count\" )\n        local failures=$(printf \"%s\" \"$json\" | jq \".summary.failure_count\" )\n        local pending=$(printf \"%s\" \"$json\" | jq \".summary.pending_count\" )\n        local duration=$(printf \"%s\" \"$json\" | jq \".summary.duration\" )\n\n        # Prints project (cyan).\n        printf \"\\033[36m${project}\\033[m: \"\n\n        # Prints total examples (white).\n        printf \"$examples examples, \"\n\n        # Prints total failures (red).\n        _toggle_total_color \"$failures\" \"failures\" \"\\033[31m\"\n        printf \", \"\n\n        # Prints total pending (yellow).\n        _toggle_total_color \"$pending\" \"pending\" \"\\033[33m\"\n        printf \", \"\n\n        # Prints total duration (white).\n        printf \"%s\\n\" \"$duration seconds.\"\n      fi\n    )\n  done < <(ls -A1)\n}\n\n# Label: RSpec Bisect\n# Description: Debug RSpec failure using bisect to automatically determine the root cause.\n# Parameters: $1 (optional):  The seed. Default: 2112, $2 (optional): Debug verbosity. Default: \"normal\".\nrsb() {\n  local seed=${1:-2112}\n  local verbosity=\"${2:-normal}\"\n\n  rspec --seed $seed --bisect=\"$verbosity\" spec\n}\n\n# Label: RSpec Debug\n# Description: Debug intermittent RSpec failure(s) by running spec(s) until failure is detected.\n# Parameters: $1 (optional): The spec to debug. Default: \"spec\".\nrsd() {\n  local subject=${1:-spec}\n\n  while [ $? == 0 ]; do\n    rspec \"$subject\"\n  done\n}\n\n# Label: RSpec Profile\n# Description: Runs RSpec specs with profiling enabled.\n# Parameters: $1 (optional): The number of top specs to profile. Default: 5.\nrsp() {\n  local number=${1:-5}\n  rspec --profile $number spec\n}\n\n#---------------------------------------------#\n# Section: https://docs.rubocop.org:[Rubocop] #\n#---------------------------------------------#\n\n# Label: Rubocop (all)\n# Description: Run Rubocop for all projects in current directory.\ncopa() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -f \".config/rubocop/config.yml\" ]]; then\n        printf \"\\n\\033[36m${project^^}\\033[m\\n\\n\" # Outputs in cyan color.\n        bundle exec rubocop --parallel --format progress\n      fi\n    )\n  done < <(ls -A1)\n}\n\n#-------------------------------------------#\n# Section: https://www.ruby-lang.org:[Ruby] #\n#-------------------------------------------#\n\n# Label: Ruby Install\n# Description: Install a specific version with safe defaults.\n# Parameters: $1 (required): Version.\nrbi() {\n  local version=\"$1\"\n\n  frum install \"$version\" \\\n               --with-openssl-dir=\"$(brew --prefix openssl)\" \\\n               --enable-shared \\\n               --disable-silent-rules\n\n  if [ $? -eq 0 ]; then\n    noti --title \"Ruby $version installed!\"\n  else\n    noti --title \"Ruby $version install failed!\"\n  fi\n}\n\n# Label: Ruby Web Server\n# Description: Serve web content via WEBrick.\n# Parameters: $1 (optional): Root. Default: .\n#             $2 (optional): Port. Default: 3030\n#             $3 (optional): Path. Default: \"\".\nreb() {\n  local root=\"${1:-.}\"\n  local port=${2:-3030}\n  local path=\"${3:-}\"\n\n  ruby -run -e httpd \"$root\" --port \"$port\" &\n\n  while ! nc -z localhost \"$port\"; do\n    sleep 0.1\n  done\n\n  open \"http://localhost:$port/$path\"\n  fg\n}\n\n# Label: Ruby Which\n# Description: Locate path to current Ruby program.\n# Parameters: $1 (required): Program name.\nrbw() {\n  local program=\"$(command -v $1)\"\n\n  printf \"%s\\n\" \"${program//$FRUM_MULTISHELL_PATH/$(readlink $FRUM_MULTISHELL_PATH)}\"\n}\n\n# Label: Ruby Upgrade (all)\n# Description: Upgrade Ruby projects in current directory to new Ruby version.\n# Parameters: $1 (required): The new version to upgrade to. Example: 3.2.0.\nrbua() {\n  local new_version=\"$1\"\n  local paths=(\".ruby-version\" \"home_files/.ruby-version.tt\")\n\n  if [[ \"$new_version\" ]]; then\n    while read -r project; do\n      (\n        cd \"$project\"\n        printf \"\\033[36m${project}\\033[m\\n\" # Outputs in cyan color.\n\n        for path in \"${paths[@]}\"; do\n          if [[ -e \"$path\" ]]; then\n            old_version=\"$(head -n 1 \"$path\")\"\n\n            if [[ \"$old_version\" != \"$new_version\" ]]; then\n              printf \"%s\\n\" \"$new_version\" > \"$path\"\n              printf \"%s\\n\" \" $path: $old_version --> $new_version\"\n            fi\n          fi\n        done\n      )\n    done < <(ls -A1)\n  else\n    printf \"%s\\n\" \"ERROR: Version must be supplied.\"\n    return 1\n  fi\n}\n\n# Label: Ruby Version (all)\n# Description: Show current Ruby version for all projects in current directory.\nrbva() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -e \".ruby-version\" ]]; then\n        local version=$(head -n 1 .ruby-version)\n\n        # Outputs project as cyan and version as white color.\n        printf \"\\033[36m${project}\\033[m: $version\\n\"\n      fi\n    )\n  done < <(ls -A1)\n}\n\n#-------------------------------------------#\n# Section: https://rubygems.org:[Ruby Gems] #\n#-------------------------------------------#\n\n# Label: Gem Dependencies\n# Description: Answers dependencies for a gem.\n# Parameters: $1 (required): The gem name.\ngemd() {\n  local name=\"$1\"\n\n  if [[ -z \"$name\" ]]; then\n    printf \"%s\\n\" \"ERROR: Gem name must be supplied!\"\n    return 1\n  fi\n\n  gem dependency \"$1\" --reverse-dependencies\n}\n\n# Label: Gem Dependency Search\n# Description: Finds a gem defined within a Gemfile or a gemspec.\n# Parameters: $1 (required): The gem name.\ngemdep() {\n  local gem_name=\"$1\"\n\n  if [[ -z \"$gem_name\" ]]; then\n    printf \"%s\\n\" \"ERROR: Gem name must be supplied!\"\n    return 1\n  fi\n\n  rg --sort path \"(add.*dependency \\\"$gem_name\\\"|add.*dependency '$gem_name'|gem \\\"$gem_name\\\"|gem '$gem_name')\" .\n}\n\n#--------------------------------------------------#\n# Section: https://rubyonrails.org:[Ruby on Rails] #\n#--------------------------------------------------#\n\n# Label: Ruby on Rails New\n# Description: Create new Rails application from selected option.\n# Parameters: $1 (required): Application name, $2 (optional): Option.\nrailsn() {\n  if [[ \"$1\" ]]; then\n    while true; do\n      if [[ $2 ]]; then\n        _process_rails_new_option \"$1\" \"$2\"\n      else\n        printf \"%s\\n\" \"\\nUsage: railsn NAME TEMPLATE\"\n        printf \"\\n%s\\n\\n\" \"Select Ruby on Rails generation option:\"\n        printf \"%s\\n\" \"  default: Rails Default\"\n        printf \"%s\\n\" \"      api: Rails API\"\n        printf \"%s\\n\" \"     slim: Rails Slim\"\n        printf \"%s\\n\" \"    dummy: Rails Dummy\"\n        printf \"\\n\"\n        read -p \"Please pick one (or type 'q' to quit): \" response\n        printf \"\\n\"\n        _process_rails_new_option \"$1\" $response\n      fi\n      break\n    done\n  else\n    printf \"%s\\n\" \"ERROR: Rails application name must be supplied.\"\n    return 1\n  fi\n}\n\n#-------------------------------------------------------------#\n# Section: https://github.com/colszowka/simplecov:[SimpleCov] #\n#-------------------------------------------------------------#\n\n# Label: RSpec (all)\n# Description: Run RSpec for projects in current directory.\ncova() {\n  while read -r project; do\n    (\n      cd \"$project\"\n\n      if [[ -d \"coverage\" ]]; then\n        open \"coverage/index.html\"\n      fi\n    )\n  done < <(ls -A1)\n}\n\n"
  },
  {
    "path": "lib/templates/.config/bash/prompt.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# The following was inspired by the original Powerline port by Riobard Zhan (https://github.com/riobard/bash-powerline).\n\n_powerline() {\n  # Unicode symbols\n  readonly OS_DARWIN_SYMBOL=''\n  readonly OS_LINUX_SYMBOL='$'\n  readonly OS_OTHER_SYMBOL='%'\n  readonly GIT_BRANCH_SYMBOL='⑂'\n  readonly GIT_BRANCH_NORMAL_SYMBOL='✓'\n  readonly GIT_BRANCH_CHANGED_SYMBOL='+'\n  readonly GIT_STASH_SYMBOL=\"@\"\n  readonly GIT_PUSH_SYMBOL='↑'\n  readonly GIT_PULL_SYMBOL='↓'\n\n  # Determine OS\n  case \"$(uname)\" in\n    Darwin)\n      readonly OS_SYMBOL=$OS_DARWIN_SYMBOL\n      ;;\n    Linux)\n      readonly OS_SYMBOL=$OS_LINUX_SYMBOL\n      ;;\n    *)\n      readonly OS_SYMBOL=$OS_OTHER_SYMBOL\n  esac\n\n  _update_history() {\n    history -a # Append.\n    history -n # Reload.\n  }\n\n  _update_iterm_label() {\n    printf \"\\033]0;${PWD##*/}\\007\"\n  }\n\n  _git_branch_info() {\n    # Get current branch name or short SHA1 hash for detached head.\n    local branch=\"$(git symbolic-ref --short HEAD 2>/dev/null || git describe --tags --always 2>/dev/null)\"\n    [ -n \"$branch\" ] || return  # Git branch not found.\n\n    local marks=\" $GIT_BRANCH_NORMAL_SYMBOL\"\n\n    # Check if branch is modified.\n    [ -n \"$(git status --porcelain)\" ] && marks=\" $GIT_BRANCH_CHANGED_SYMBOL\"\n\n    # Compute how many commits local branch is ahead/behind of remote branch.\n    local stat=\"$(git status --porcelain --branch | grep '^##' | grep -o '\\[.\\+\\]$')\"\n    local aheadN=\"$(echo $stat | grep -o 'ahead \\d\\+' | grep -o '\\d\\+')\"\n    local behindN=\"$(echo $stat | grep -o 'behind \\d\\+' | grep -o '\\d\\+')\"\n    [ -n \"$aheadN\" ] && marks+=\" $GIT_PUSH_SYMBOL$aheadN\"\n    [ -n \"$behindN\" ] && marks+=\" $GIT_PULL_SYMBOL$behindN\"\n\n    # Print the git branch segment without a trailing newline\n    printf \" $GIT_BRANCH_SYMBOL $branch$marks \"\n  }\n\n  _git_stash_info() {\n    local count=$(git stash list | wc -l | xargs -n 1)\n    count=\"$count\"\n\n    if [[ $count -gt 0 ]]; then\n      printf \"$GIT_STASH_SYMBOL$count \"\n    fi\n  }\n\n  ps1() {\n    # Check the exit code of the previous command and toggle background color accordingly.\n    if [ $? -eq 0 ]; then\n      local BG_EXIT=\"$GREEN_BACKGROUND\"\n    else\n      local BG_EXIT=\"$RED_BACKGROUND\"\n    fi\n\n    PS1=\"\\[$BLACK\\]\\[$WHITE_BACKGROUND\\] \\u@\\h \\[$NORMAL\\]\" # User@host.\n    PS1+=\"\\[$BLACK\\]\\[$CYAN_BACKGROUND\\] ${PWD##*/} \\[$NORMAL\\]\" # Directory.\n\n    if [[ -d .git ]]; then\n      PS1+=\"\\[$SLATE_BACKGROUND\\] $(git config get user.email | egrep --only-matching '[^@]+$') \\[$NORMAL\\]\" # Git Email Domain.\n      PS1+=\"\\[$BLUE_BACKGROUND\\]$(_git_branch_info)\\[$NORMAL\\]\" # Git Branch Info.\n      PS1+=\"\\[$YELLOW\\]\\[$BLUE_BACKGROUND\\]$(_git_stash_info)\\[$NORMAL\\]\" # Git Stash Info.\n    fi\n\n    _update_history\n    _update_iterm_label\n\n    PS1+=\"\\[$BG_EXIT\\] $OS_SYMBOL \\[$NORMAL\\] \"\n  }\n\n  PROMPT_COMMAND=ps1\n}\n\n_powerline\nunset _powerline\n"
  },
  {
    "path": "lib/templates/.config/duti/configuration.duti.tt",
    "content": "# Use `mdls -name kMDItemCFBundleIdentifier -r /Applications/<app>.app` to identify applications.\n\ncom.colliderli.iina .flac all\ncom.colliderli.iina .mkv all\ncom.colliderli.iina .mov all\ncom.colliderli.iina .mp4 all\ncom.colliderli.iina .webm all\ncom.flyingmeat.Acorn8 .arw all\ncom.flyingmeat.Acorn8 .avif all\ncom.flyingmeat.Acorn8 .bmp all\ncom.flyingmeat.Acorn8 .gif all\ncom.flyingmeat.Acorn8 .heic all\ncom.flyingmeat.Acorn8 .jpeg all\ncom.flyingmeat.Acorn8 .jpg all\ncom.flyingmeat.Acorn8 .png all\ncom.flyingmeat.Acorn8 .svg all\ncom.flyingmeat.Acorn8 .tiff all\ncom.flyingmeat.Acorn8 .webp all\ncom.rogueamoeba.Fission .m4a all\ncom.sublimetext.4 .erb all\ncom.sublimetext.4 .rb all\n"
  },
  {
    "path": "lib/templates/.config/git/attributes.tt",
    "content": "*.gemspec diff=ruby\n*.gif diff=exif\n*.ico diff=exif\n*.jpeg diff=exif\n*.jpg diff=exif\n*.mp4 diff=exif\n*.ogg diff=exif\n*.png diff=exif\n*.rake diff=ruby\n*.rb diff=ruby\n*.webm diff=exif\nconfig.ru diff=ruby\nconfig/credentials.yml.enc diff=rails_credentials\nconfig/credentials/*.yml.enc diff=rails_credentials\nGemfile diff=ruby\nGemfile.lock diff=ruby\nGuardfile diff=ruby\nProcfile diff=ruby\nRakefile diff=ruby\n"
  },
  {
    "path": "lib/templates/.config/git/commit_message.txt.tt",
    "content": "\n\nMilestone: ?\n\n# Questions:\n\n# Why is this necessary?\n# Any side effects to be aware of?\n# Any links to add?\n\n# Trailers:\n\n# Co-authored-by: River Tam <river@firefly.com>\n# Format: asciidoc\n# Issue: 123\n# Milestone: patch\n# Reviewer: github\n# Signed-off-by: Malcolm Reynolds <mal@firefly.com>\n# Tracker: linear\n"
  },
  {
    "path": "lib/templates/.config/git/configuration.tt",
    "content": "[advice]\n  detachedHead = false\n[branch]\n  autoSetupRebase = always\n[commit]\n  gpgSign = true\n  template = ~/.config/git/commit_message.txt\n  verbose = true\n[core]\n  abbrev = 12\n  editor = \"$EDITOR --wait\"\n  fsmonitor = false\n  hooksPath = ~/.config/git/hooks\n  pager = delta\n  quotePath = false\n  untrackedCache = true\n  whitespace = fix,-indent-with-non-tab,trailing-space,cr-at-eol\n[color]\n  pager = true\n  ui = true\n[color \"branch\"]\n  current = yellow reverse\n  local = yellow\n  remote = green\n[color \"diff\"]\n  commit = 227 bold\n  frag = magenta bold\n  meta = 227\n  new = green bold\n  old = red bold\n  whitespace = red reverse\n[color \"diff-highlight\"]\n  newHighlight = green bold 22\n  newNormal = green bold\n  oldHighlight = red bold 52\n  oldNormal = red bold\n[color \"status\"]\n  added = yellow\n  changed = green\n  untracked = cyan\n[credential]\n  helper = cache --timeout=3600\n[delta]\n  commit-decoration-style = bold yellow box ul\n  file-style = bold yellow ul\n  hunk-header-decoration-style = yellow box\n  line-numbers = true\n  minus-color = \"#340001\"\n  plus-color = \"#012800\"\n  side-by-side = true\n  whitespace-error-style = 22 reverse\n[diff]\n  algorithm = histogram\n  colorMoved = default\n  dstPrefix = after\n  indentHeuristic = true\n  mnemonicPrefix = true\n  renames = copies\n  srcPrefix = before\n  tool = difftastic\n[diff \"exif\"]\n  textconv = exiftool\n[difftool]\n  prompt = false\n[difftool \"difftastic\"]\n  cmd = difft \"$LOCAL\" \"$REMOTE\"\n[feature]\n  experimental = true\n[fetch]\n  prune = true\n  pruneTags = true\n  writeCommitGraph = true\n[gpg \"ssh\"]\n  allowedSignersFile = ~/.ssh/allowed_signers\n[grep]\n  column = true\n  fullname = true\n  lineNumber = true\n[init]\n  defaultBranch = main\n  templateDir = ~/.config/git/template\n[interactive]\n  diffFilter = delta --color-only\n  singleKey = true\n[maintenance]\n  auto = false\n  strategy = incremental\n[merge]\n  conflictStyle = zdiff3\n  ff = only\n  tool = difftastic\n[mergetool]\n  prompt = false\n[mergetool \"difftastic\"]\n  cmd = difft \"$LOCAL\" \"$REMOTE\"\n  trustExitCode = true\n[notes]\n  rewriteRef = refs/notes/commits\n[pack]\n  useBitmapBoundaryTraversal = true\n[pager]\n  difftool = true\n[pull]\n  rebase = merges\n[push]\n  autoSetupRemote = true\n  default = simple\n  followTags = true\n  useForceIfIncludes = true\n[rebase]\n  abbreviateCommands = true\n  autoSquash = true\n  autoStash = true\n  updateRefs = true\n[remote \"origin\"]\n  fetch = refs/pull/*/head:refs/remotes/pull_requests/*\n  fetch = refs/stashes/*:refs/remote/origin/stashes/*\n[rerere]\n  autoUpdate = true\n  enabled = true\n[revert]\n  reference = true\n[stash]\n  showIncludeUntracked = true\n  showPatch = true\n  showStat = false\n[status]\n  showUntrackedFiles = all\n[tag]\n  gpgSign = true\n  sort = version:refname\n[transfer]\n  fsckObjects = true\n[url \"https://github.com/bkuhlmann/\"]\n  insteadOf = bk:\n[url \"https://github.com/dry-rb/dry-\"]\n  insteadOf = dry:\n[url \"https://github.com/\"]\n  insteadOf = gh:\n[url \"https://github.com/hanami/\"]\n  insteadOf = hanami:\n[url \"https://git.heroku.com\"]\n  insteadOf = heroku:\n[url \"https://github.com/rom-rb/rom-\"]\n  insteadOf = rom:\n[url \"https://github.com/ruby/\"]\n  insteadOf = rb:\n[user]\n  email = <redacted>\n  name = <redacted>\n  signingKey = <redacted>\n  useConfigOnly = true\n[includeIf \"gitdir:~/Engineering/Companies/Example/\"]\n  path = ~/.config/git/profiles/example\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/applypatch-msg.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git apply patch functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/commit-msg.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git commit message functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/git.sh\"\n\ngit_trailer_cleaner \"$1\"\ngit_lint_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/brakeman.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Brakeman Check\n# Description: Scan Rails project for security vulnerabilities.\nbrakeman_check() {\n  if _check_gem_dependencies \"brakeman\"; then\n    printf \"%s\\n\" \"[brakeman]\"\n    bundle exec brakeman --summary --quiet\n  fi\n}\nexport -f brakeman_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/bundler.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Bundler Gemfile Path\n# Description: Detect gem path statements.\nbundler_gemfile_path() {\n  _scan_code \"[bundler]\" \"Gemfile path statement detected\" 'Gemfile' '(path:|:path\\s=>)'\n}\nexport -f bundler_gemfile_path\n\n# Label: Bundler Audit Check\n# Description: Scans gem dependencies for security vulnerabilities.\nbundler_audit_check() {\n  if _check_gem_dependencies \"bundler-audit\"; then\n    printf \"[bundler-audit]: \"\n    bundle exec bundler-audit\n  fi\n}\nexport -f bundler_audit_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/comments.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Comment Total\n# Description: Print project comment total.\n# Parameters: $1 (required): The comment prefix to search for.\n_comment_total() {\n  local prefix=\"$1\"\n  local label=\"[comments]\"\n  local lines=(\"omit:0\") # Ensures array is populated, with omitted total, in case Silver Searcher finds nothing.\n  local total=0\n\n  if ! command -v rg > /dev/null; then\n     printf \"%s\" \"$label: Ripgrep not found. To install, run: brew install ripgrep.\"\n     exit 1\n  fi\n\n  lines+=($(rg --count --case-sensitive --iglob '!vendor' --regexp \"^\\s*?(#|--|//) $prefix\" . || :))\n\n  for line in ${lines[*]}; do\n    total=$((total + ${line#*:}))\n  done\n\n  if [[ $total -gt 0 ]]; then\n    _print_warning \"$label: $total $prefix\"\n  fi\n}\nexport -f _comment_total\n\n# Label: Comment Totals\n# Description: Print project comment totals.\ncomment_totals() {\n  local prefixes=(\n    \"TODO\"\n    \"FIX\"\n    \"DUPLICATE\"\n    \"shellcheck disable\"\n    \":reek:\"\n    \"rubocop:disable\"\n    \"rubocop:todo\"\n    \":nocov:\"\n  )\n\n  for prefix in ${prefixes[*]}; do\n    _comment_total \"$prefix\"\n  done\n}\nexport -f comment_totals\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/ctags.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: CTags Rebuild\n# Description: Rebuild project .tags file.\nctags_rebuild() {\n  local label=\"[ctags]\"\n\n  _build_ctags\n  printf \"%s\\n\" \"$label: CTags rebuilt.\"\n}\nexport -f ctags_rebuild\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/dotenv.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Dotenv Linter\n# Description: Scan environment files for consistent style and security issues.\ndotenv_check() {\n  if command -v dotenv-linter > /dev/null; then\n    printf \"%s\\n\" \"[dotenv-linter]:\"\n    dotenv-linter check .\n  fi\n}\nexport -f dotenv_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/git.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Git Lint Check\n# Description: Enforce consistent Git commits.\ngit_lint_check() {\n  if _check_gem_dependencies \"git-lint\"; then\n    git-lint --hook \"${BASH_ARGV[0]}\"\n  fi\n}\nexport -f git_lint_check\n\n# Label: Git Trailer Cleaner\n# Description: Remove unused/empty Git commit body trailers.\n# Parameters: $1 (required): Commit message file path.\ngit_trailer_cleaner() {\n  local commit_message_path=\"$1\"\n\n  git interpret-trailers --in-place --trim-empty \"$commit_message_path\"\n}\nexport -f git_trailer_cleaner\n\n# Label: Git Add Trailers\n# Description: Dynamically add trailers based on branch description.\n# Parameters: $1 (required): Commit message file path, $2 (required): The kind.\ngit_add_trailers() {\n  local commit_message_path=\"$1\"\n  local kind=\"$2\"\n  local branch=\"\"\n  local trailers=\"\"\n\n  branch=\"$(git branch --show-current | tr -d '\\n')\"\n  trailers=\"$(git config get \"branch.$branch.description\" | git interpret-trailers --parse || :)\"\n\n  case \"$kind\" in\n    message)\n      printf \"\\n\\n%s\" \"$trailers\" >> \"$commit_message_path\";;\n    template)\n      sd --max-replacements 1 \"\\n#\" \"\\n$trailers\\n\\n#\" \"$commit_message_path\";;\n  esac\n}\nexport -f git_add_trailers\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/hadolint.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Haskell Dockerfile Linter\n# Description: Scan Dockerfile for vulnerabilities.\nhadolint_check() {\n  if command -v hadolint > /dev/null && [[ -e \"Dockerfile\" ]]; then\n    printf \"%s\\n\" \"[hadolint]:\"\n    hadolint Dockerfile\n  fi\n}\nexport -f hadolint_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/java_script.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Git Label\n# Description: Print Git label.\n_java_script_label() {\n  printf \"[java_script]\"\n}\nexport -f _java_script_label\n\n# Label: File Pattern\n# Description: Print file regular expression.\n_java_script_file_pattern() {\n  printf '^((?!min).)+.(js|erb|slim)$'\n}\nexport -f _java_script_file_pattern\n\n# Label: JavaScript Debugger\n# Description: Detect JavaScript debug statements.\njava_script_debugger() {\n  local search_pattern='^(?:(?!(.*//.+|.*/\\*.+)).*debugger;)'\n  _scan_code \"$(_java_script_label)\" \"Debug statements detected\" $(_java_script_file_pattern) $search_pattern\n}\nexport -f java_script_debugger\n\n# Label: JavaScript Console\n# Description: Detect JavaScript console statements.\njava_script_console() {\n  local search_pattern='^(?:(?!(.*//.+|.*/\\*.+)).*console.(count|dir|error|group.*|info|log|time.*|table|trace)\\(.+\\);)'\n  _scan_code \"$(_java_script_label)\" \"Console statements detected\" $(_java_script_file_pattern) $search_pattern\n}\nexport -f java_script_console\n\n# Label: JavaScript Alert\n# Description: Detect JavaScript alert statements.\njava_script_alert() {\n  local search_pattern='^(?:(?!(.*//.+|.*/\\*.+)).*alert\\(.+\\);)'\n  _scan_code \"$(_java_script_label)\" \"Alert statements detected\" $(_java_script_file_pattern) $search_pattern\n}\nexport -f java_script_alert\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/license_finder.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: License Finder Check\n# Description: Scan project for valid licenses.\nlicense_finder_check() {\n  if _check_gem_dependencies \"license_finder\"; then\n    printf \"%s\\n\" \"[license_finder]:\"\n    bundle exec license_finder\n  fi\n}\nexport -f license_finder_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/osv.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Open Source Vulnerability (OSV) Check\n# Description: Scan Ruby dependencies for vulnerabilities.\nosv_check() {\n  if command -v osv-scanner > /dev/null && [[ -e \"Gemfile.lock\" ]]; then\n    printf \"%s\\n\" \"[osv]:\"\n    osv-scanner --lockfile Gemfile.lock\n  fi\n}\nexport -f osv_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/reek.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Reek Branch Check\n# Description: Scan Ruby code -- feature branch only -- for poor style choices.\nreek_branch_check() {\n  if _check_gem_dependencies \"reek\"; then\n    printf \"%s\\n\" \"[reek]:\"\n    bundle exec reek \"$(_git_feature_files)\"\n  fi\n}\nexport -f reek_branch_check\n\n# Label: Reek Stage Check\n# Description: Scan Ruby code -- staged files only -- for poor style choices.\nreek_stage_check() {\n  if _check_gem_dependencies \"reek\"; then\n    printf \"%s\\n\" \"[reek]:\"\n    bundle exec reek \"$(_git_staged_files)\"\n  fi\n}\nexport -f reek_stage_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/rspec.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: RSpec Dotfile\n# Description: Detect RSpec dotfile.\nrspec_dotfile() {\n  if command -v rg > /dev/null; then\n    results=(\"$(rg --files --glob .rspec . || :)\")\n\n    if [[ ${#results[@]} -gt 0 && ${results[@]} != '' ]]; then\n      _print_error \"[rspec]: Dotfile detected.\"\n      exit 1\n    fi\n  else\n    _print_error \"[rspec]: Ripgrep not found. To install, run: brew install ripgrep.\"\n     exit 1\n  fi\n}\nexport -f rspec_dotfile\n\n# Label: RSpec Order\n# Description: Detect RSpec ordered specs.\nrspec_order() {\n  _scan_code \"[rspec]\" \"Order detected\" '(_helper.rb$|spec.rb$)' '(order.*\\=.*defined|,\\sorder:.+defined)'\n}\nexport -f rspec_order\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/rubocop.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: RuboCop Branch Check\n# Description: Scan Ruby code -- feature branch only -- for poor style choices.\nrubocop_branch_check() {\n  if _check_gem_dependencies \"caliber\" || _check_gem_dependencies \"rubocop\"; then\n    printf \"%s\\n\" \"[rubocop]:\"\n    _git_feature_files | xargs | _run_rubocop\n  fi\n}\nexport -f rubocop_branch_check\n\n# Label: RuboCop Stage Check\n# Description: Scan Ruby code -- staged files only -- for poor style choices.\nrubocop_stage_check() {\n  if _check_gem_dependencies \"caliber\" || _check_gem_dependencies \"rubocop\"; then\n    printf \"%s\\n\" \"[rubocop]:\"\n    _git_staged_files | xargs | _run_rubocop\n  fi\n}\nexport -f rubocop_stage_check\n\n# Label: Run RuboCop\n# Description: Run RuboCop in a mode compatible for use in Git Hooks.\n_run_rubocop() {\n  bundle exec rubocop --parallel \\\n                      --force-exclusion \\\n                      --display-cop-names \\\n                      --display-style-guide \\\n                      --only-recognized-file-types \\\n                      --format simple\n}\nexport -f _run_rubocop\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/extensions/support.sh.tt",
    "content": "#! /usr/bin/env bash\n\n# Label: Check Gem Dependencies\n# Description: Check Gemfile/gemspec dependencies for specified gem.\n# Parameters: $1 (required): The gem name.\n_check_gem_dependencies() {\n  local gem=\"$1\"\n  rg \"(add.*dependency \\\"$gem\\\"|add.*dependency '$gem'|gem \\\"$gem\\\"|gem '$gem')\" --max-depth 1 . > /dev/null\n}\nexport -f _check_gem_dependencies\n\n# Label: Builds CTags\n# Description: Build/rebuild CTags.\n_build_ctags() {\n  rm -f \".tags\"\n  rm -f \"tags\"\n  ctags\n}\nexport -f _build_ctags\n\n# Label: Git Feature Files\n# Description: Answer feature branch files only.\n_git_feature_files() {\n  git diff \\\n      --diff-filter=d \\\n      \"$(git branch --show-current | tr -d '\\n')\"..\"$(git config get init.defaultBranch)\" \\\n      --name-only\n}\nexport -f _git_feature_files\n\n# Label: Git Staged Files\n# Description: Answer staged files only.\n_git_staged_files() {\n  git diff --diff-filter=d --name-only --cached\n}\n\n# Label: Print Warning.\n# Description: Print yellow warning message.\n# Parameters: $1 (required): Message.\n_print_warning() {\n  local message=\"$1\"\n\n  printf \"\\033[33m\"\n  printf \"%s\\n\" \"$message\"\n  printf \"\\033[m\"\n}\nexport -f _print_warning\n\n# Label: Print Error.\n# Description: Print red error message.\n# Parameters: $1 (required): Message.\n_print_error() {\n  local message=\"$1\"\n\n  printf \"\\033[31m\"\n  printf \"%s\\n\" \"$message\"\n  printf \"\\033[m\"\n}\nexport -f _print_error\n\n# Label: Scan Code\n# Description: Scan for invalid code.\n# Parameters: $1 (required): Label, $2 (required): Message, $3 (required): File regex, $4 (required): Search regex.\n_scan_code() {\n  local label=\"$1\"\n  local message=\"$2\"\n  local file_pattern=$3\n  local search_pattern=$4\n  local ignore_pattern=\"vendor\"\n\n  if command -v ag > /dev/null; then\n    results=(\"$(ag --file-search-regex $file_pattern $search_pattern --ignore $ignore_pattern . || :)\")\n\n    if [[ ${#results[@]} -gt 0 && ${results[@]} != '' ]]; then\n      _print_error \"$label: $message:\"\n\n      for line in ${results[@]}; do\n        _print_error \"  $line\"\n      done\n\n      exit 1\n    fi\n  else\n    _print_error \"$label: Silver Surfer not found. To install, run: brew install the_silver_searcher.\"\n     exit 1\n  fi\n}\nexport -f _scan_code\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/post-applypatch.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git post-apply patch functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/post-checkout.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git post-checkout functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/ctags.sh\"\n\nctags_rebuild\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/post-commit.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git post-commit functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/ctags.sh\"\n\nctags_rebuild\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/post-merge.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git post-merge functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/post-rewrite.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git post-rewrite functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/ctags.sh\"\n\nctags_rebuild\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/pre-applypatch.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git pre-apply patch functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/pre-commit.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git pre-commit functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/java_script.sh\"\nsource \"$HOME/.config/git/hooks/extensions/reek.sh\"\nsource \"$HOME/.config/git/hooks/extensions/rspec.sh\"\nsource \"$HOME/.config/git/hooks/extensions/rubocop.sh\"\n\njava_script_alert\njava_script_console\njava_script_debugger\nreek_stage_check\nrspec_dotfile\nrspec_order\nrubocop_stage_check\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/pre-merge-commit.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git pre-merge commit functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/pre-push.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git pre-push functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/brakeman.sh\"\nsource \"$HOME/.config/git/hooks/extensions/bundler.sh\"\nsource \"$HOME/.config/git/hooks/extensions/comments.sh\"\nsource \"$HOME/.config/git/hooks/extensions/dotenv.sh\"\nsource \"$HOME/.config/git/hooks/extensions/hadolint.sh\"\nsource \"$HOME/.config/git/hooks/extensions/license_finder.sh\"\nsource \"$HOME/.config/git/hooks/extensions/osv.sh\"\nsource \"$HOME/.config/git/hooks/extensions/reek.sh\"\nsource \"$HOME/.config/git/hooks/extensions/rubocop.sh\"\n\npush_command=$(ps -ocommand= -p $PPID)\nzeros=0000000000000000000000000000000000000000\n\n# Ignore remote branch or tag deletes.\nif [[ \"$push_command\" == *\"--delete\"* || \"$push_command\" == *\"--tags\"* ]]; then\n  exit 0\nfi\n\n# Ignore unbuildable commits.\nif [[ $(git log --format=%B -1) == *\"[ci skip]\"* ]]; then\n  exit 0\nfi\n\nwhile read local_ref local_sha remote_ref remote_sha; do\n  if [[ \"$local_sha\" != \"$zeros\" && \"$remote_sha\" != \"$zeros\" ]]; then\n    parallel ::: comment_totals \\\n                 reek_branch_check \\\n                 rubocop_branch_check \\\n                 dotenv_check \\\n                 bundler_gemfile_path \\\n                 bundler_audit_check \\\n                 brakeman_check \\\n                 license_finder_check \\\n                 hadolint_check \\\n                 osv_check\n  fi\ndone\n\nexit 0\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/pre-rebase.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git pre-rebase functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\n"
  },
  {
    "path": "lib/templates/.config/git/hooks/prepare-commit-msg.tt",
    "content": "#! /usr/bin/env bash\n\n# Defines Git prepare commit message functionality.\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\nsource \"$HOME/.config/git/hooks/extensions/support.sh\"\nsource \"$HOME/.config/git/hooks/extensions/git.sh\"\n\ngit_add_trailers \"$1\" \"$2\"\n"
  },
  {
    "path": "lib/templates/.config/git/ignore.tt",
    "content": "# Archives\n*.7z\n*.bzip\n*.dmg\n*.gz\n*.iso\n*.jar\n*.rar\n*.tar\n*.tar.gz\n*.zip\n\n# Bundler\n.bundle\n\n# CTags\n.tags\n.tags_sorted_by_file\n/tags\n\n# Databases\n*.dump\n\n# Docker\ncompose.dev.yml\n\n# Environments\n*.env*\n!*.env*.tt\n\n# Logs\n*.log\n*.log.*\n\n# macOS\n.DS_Store\n\n# SimpleCov\ncoverage\n\n# Processes\nProcfile.dev\n\n# Solargraph\n.solargraph.yml\n\n# Temp Directories\ntmp\n"
  },
  {
    "path": "lib/templates/.config/git/template/mkdir.command",
    "content": "# Special command for creating empty directories.\n# Delete if templates are added.\n"
  },
  {
    "path": "lib/templates/.config/irb/irbrc.tt",
    "content": "#! /usr/bin/env ruby\n# frozen_string_literal: true\n\nrequire \"irb/completion\"\n\nReline::Face.config :completion_dialog do |config|\n  config.define :default, foreground: :white, background: :black\n  config.define :enhanced, foreground: :black, background: :green\n  config.define :scrollbar, foreground: :bright_white, background: :black\nend\n\nbegin\n  require \"amazing_print\"\n\n  AmazingPrint.irb!\nrescue LoadError => error\n  puts \"ERROR: #{error.message.capitalize}.\"\nend\n\nbegin\n  require \"irb/kit\"\n\n  IRB::Kit.register_commands :all\n  IRB::Kit.register_helpers :all\n\n  IRB.conf[:PROMPT] ||= {}\n\n  IRB.conf[:PROMPT][:ALCHEMISTS] = {\n    PROMPT_I: \"[#{IRB::Kit.prompt}]> \",\n    PROMPT_N: \"[#{IRB::Kit.prompt}]| \",\n    PROMPT_C: \"[#{IRB::Kit.prompt}]| \",\n    PROMPT_S: \"[#{IRB::Kit.prompt}]%l \",\n    RETURN: \"=> %s\\n\"\n  }\n\n  IRB.conf[:PROMPT_MODE] = :ALCHEMISTS\nrescue LoadError => error\n  puts \"ERROR: #{error.message.capitalize}.\"\nend\n\nIRB.conf[:EVAL_HISTORY] = 1_000\nIRB.conf[:HISTORY_FILE] = \"#{Dir.home}/.cache/irb/history.log\"\nIRB.conf[:COMPLETOR] = :type\nIRB.conf[:SHOW_BANNER] = false\n\nIRB.conf[:COMMAND_ALIASES]\n   .merge! b: :backtrace,\n           c: :continue,\n           e: :edit,\n           h: :show_cmds,\n           i: :info,\n           l: :ls,\n           n: :next,\n           m: :measure,\n           s: :step,\n           w: :whereami\n"
  },
  {
    "path": "lib/templates/.config/pgenv/initialize.tt",
    "content": "#! /usr/bin/env bash\n\nset -o nounset\nset -o errexit\nset -o pipefail\nIFS=$'\\n\\t'\n\npsql --username postgres \\\n     --command \"CREATE ROLE $USER WITH SUPERUSER CREATEDB CREATEROLE LOGIN PASSWORD '';\"\npsql --username postgres --command \"CREATE DATABASE $USER;\"\n\n(\n  cd \"$HOME/.cache/pgenv/pgsql/data\"\n\n  if [[ ! -e \"server.key\" && ! -e \"server.crt\" ]]; then\n    openssl req -new \\\n                -x509 \\\n                -days 365 \\\n                -nodes \\\n                -text \\\n                -out server.crt \\\n                -keyout server.key \\\n                -subj \"/CN=postgres\"\n\n    chmod 0600 server.key\n  fi\n)\n\npsql -c \"ALTER SYSTEM SET timezone = 'UTC';\"\npsql -c \"ALTER SYSTEM SET ssl = 'on';\"\npsql -c \"ALTER SYSTEM SET ssl_cert_file = 'server.crt';\"\npsql -c \"ALTER SYSTEM SET ssl_key_file = 'server.key';\"\npsql -c \"ALTER SYSTEM SET ssl_min_protocol_version = 'TLSv1.3';\"\n\npgenv restart\n"
  },
  {
    "path": "lib/templates/.config/rubocop/config.yml.tt",
    "content": "inherit_gem:\n  caliber: config/all.yml\n"
  },
  {
    "path": "lib/templates/.ctags.tt",
    "content": "--exclude=*.git*\n--exclude=*.min.js\n--exclude=*coverage*\n--exclude=*node_modules*\n--exclude=*packs*\n--exclude=.DS_Store\n--exclude=log\n--exclude=tmp\n--exclude=vendor\n--fields=+l\n--languages=-sql\n--recurse=yes\n--sort=yes\n--tag-relative=yes\n"
  },
  {
    "path": "lib/templates/.erdconfig.tt",
    "content": "attributes:\n  - primary_keys\n  - foreign_keys\n  - content\n  - inheritance\n  - timestamps\ndisconnected: true\nfilename: tmp/erd\ninheritance: true\nnotation: bachman\n"
  },
  {
    "path": "lib/templates/.hushlogin.tt",
    "content": ""
  },
  {
    "path": "lib/templates/.inputrc.tt",
    "content": "# READLINE SETTINGS (http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC13)\n\n# Sets bell style to visible instead of audible.\nset bell-style visible\n\n# Use VI edit commands instead of Emacs.\nset editing-mode vi\n\n# Use VI key mappings instead of Emacs.\nset keymap vi\n\n# Show all auto-complete results at once.\nset page-completions off\n\n# Use case insensitive tab auto-completion.\nset completion-ignore-case on\n\n# Show all possible auto-completion matches (even when some are ambiguous).\nset show-all-if-ambiguous on\n\n# Show all auto-completion results (by asking) when results are more than current limit.\nset completion-query-items 100\n\n# Use intelligent auto-completion for text after the cursor relative to current command.\nset skip-completed-text on\n\n# Cycles backward through recent history for command completions. Use: ↑\n\"\\e[A\": history-search-backward\n\n# Cycles forward through recent history for command completions. Use: ↓\n\"\\e[B\": history-search-forward\n\n# Ensures backward line movement works. Use: ←\n\"\\e[D\": backward-char\n\n# Ensures forward line movement works. Use: →\n\"\\e[C\": forward-char\n\n# Changes tab completion default menu list to cycle through each matching command. Use: <tab>\n\"\\t\": menu-complete\n"
  },
  {
    "path": "lib/templates/.npmrc.tt",
    "content": "init-author-name=\"Brooke Kuhlmann\"\ninit-license=\"Hippocratic-2.1\"\nprogress=false\nsave-prefix=\"^\"\n"
  },
  {
    "path": "lib/templates/.psqlrc.tt",
    "content": "-- %[...%] = Sets the default prompt bold black color.\n-- %M = The full host name (with domain) of database server, or [local] if the connection is a Unix domain socket.\n-- %n = The database user name.\n-- %/ = The database name.\n-- %x = The transaction state. See legend below:\n--       : Not in transaction.\n--      *: Inside a transaction.\n--      !: Inside a failed transaction and not rolled back.\n--      ?: State is unknown or there is no connection.\n-- %R = The connection info. See legend below:\n--      =: New command.\n--      –: Continuation of multiline query.\n--      ^: In single-line mode.\n--      @: Inside conditional logic branch.\n--      *: Inside unfinished comment block.\n--      ': Inside unfinished single quoted string.\n--      \": Inside unfinished double quoted string.\n--      $: Inside unfinished dollar quoted string.\n--      (: Inside unfinished parenthesis.\n--      !: Disconnected from database.\n-- %[...%] = Resets the color to non-bold black.\n-- %# = '#' if superuser, otherwise '>'.\n\\set PROMPT1 '%[%033[1m%]%M %n@%/%x%R%[%033[0m%]%# '\n\n-- Used when waiting for more input.\n\\set PROMPT2 '[more] %x%R> '\n\n-- Autocomplete keywords (like SELECT) in upper-case, even if you started typing them in lower case.\n\\set COMP_KEYWORD_CASE upper\n\n-- Use a separate history file per-database.\n\\set HISTFILE ~/.cache/psql/:DBNAME.log\n\n-- If a command is run more than once in a row, only store it once in the history.\n\\set HISTCONTROL ignoredups\n\n-- Keep a decently sized history of previously used commands.\n\\set HISTSIZE 1000\n\n-- Enable verbose error reports.\n\\set VERBOSITY verbose\n\n-- Use \"\\q\" instead of CONTROL+D (unless pressed 5 times in a row) to quit.\n\\set IGNOREEOF 5\n\n-- Enables error fixing when entering statements via the prompt without starting over.\n\\set ON_ERROR_ROLLBACK interactive\n\n-- Reduces typing so you can use `:vet` instead of `EXPLAIN ANALYZE` to check query performance.\n\\set vet 'EXPLAIN ANALYZE'\n\n-- By default, NULL is an empty space. This makes NULL values visible.\n\\pset null '[NULL]'\n\n-- Enable display of query execution times.\n\\timing on\n\n-- Use table format (with headers) by default, but switch to expanded table format when there's a lot of data.\n\\x auto\n\n-- Cache Hit\n\\set ch 'SELECT ''index hit rate'' AS name, (sum(idx_blks_hit)) / nullif(sum(idx_blks_hit + idx_blks_read),0) AS ratio FROM pg_statio_user_indexes UNION ALL SELECT ''table hit rate'' AS name, sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read),0) AS ratio FROM pg_statio_user_tables;'\n\n-- Long Running\n\\set lr 'SELECT pid, now() - pg_stat_activity.xact_start AS duration, query, state FROM pg_stat_activity WHERE (now() - pg_stat_activity.xact_start) > interval ''5 minutes'' ORDER by 2 DESC;'\n\n-- Indexes (unused)\n\\set iu 'SELECT schemaname || ''.'' || relname AS table, indexrelname AS index, pg_size_pretty(pg_relation_size(i.indexrelid)) AS index_size, idx_scan as index_scans FROM pg_stat_user_indexes ui JOIN pg_index i ON ui.indexrelid = i.indexrelid WHERE NOT indisunique AND idx_scan < 50 AND pg_relation_size(relid) > 5 * 8192 ORDER BY pg_relation_size(i.indexrelid) / nullif(idx_scan, 0) DESC NULLS FIRST, pg_relation_size(i.indexrelid) DESC;'\n\n-- Table Sizes\n\\set ts 'SELECT c.relname AS name, pg_size_pretty(pg_table_size(c.oid)) AS size FROM pg_class c LEFT JOIN pg_namespace n ON (n.oid = c.relnamespace) WHERE n.nspname NOT IN (''pg_catalog'', ''information_schema'') AND n.nspname !~ ''^pg_toast'' AND c.relkind=''r'' ORDER BY pg_table_size(c.oid) DESC;'\n"
  },
  {
    "path": "lib/templates/.ruby-version.tt",
    "content": "4.0.3\n"
  },
  {
    "path": "lib/templates/.vimrc.tt",
    "content": "\" VIM SETTINGS\n\nset history=1000 \" Keep 1000 lines of history.\nset ruler \" Always show the cursor position.\nset relativenumber \" Show line numbers relative to cursor where cursor number is always zero.\n\nset expandtab \" Use spaces instead of tabs when indenting.\nset smarttab \" Indent instead of tabbing at the beginning of a line.\nset shiftwidth=2 \" Indent by 2 spaces.\nset tabstop=2 \" Hard tab stop.\nset softtabstop=2 \" Soft tab stop.\n\nset incsearch \" Incrementally highlight search pattern as it is updated.\nset hlsearch \" Highlight search matches after entering search pattern.\nset ignorecase \" Use case insensitive search pattern matching by default.\nset smartcase \" Override 'ignorecase' setting if search pattern contains uppercase characters.\n\nset spell \" Enable spell checking.\nset complete+=kspell \" Enables use of CONTROL+N or CONTROL+P within Insert mode to complete words being typed.\n\nset winwidth=120 \" Default window width.\nset winheight=10 \" Default window height.\nset winminheight=10 \" Minimum window height.\nset winheight=1000 \" Reset window height.\n\nset tags=./.tags; \" Use CTags as generated by Sublime Text.\n\nsyntax on \" Enable syntax highlighting.\nfiletype plugin indent on \" Enable file type specific indentation.\n\n\" Leaders\nmap <Leader>i mmgg=G`m\nmap <Leader>cs :nohlsearch<cr>\n\n\" Remappings\nnnoremap <C-K> <C-W><C-K> \" Move up one window.\nnnoremap <C-L> <C-W><C-L> \" Move right one window.\nnnoremap <C-J> <C-W><C-J> \" Move down one window.\nnnoremap <C-H> <C-W><C-H> \" Move left one window.\n\n\" Auto-Commands\nautocmd FileType gitcommit setlocal spell \" Enables spell checking for Git commits.\nautocmd FileType markdown setlocal spell \" Enables spell checking for Markdown files.\n\n\" Extensions\nexecute pathogen#infect()\nruntime macros/matchit.vim\n"
  },
  {
    "path": "lib/utilities.sh",
    "content": "#! /usr/bin/env bash\n\n# DESCRIPTION\n# Defines general utility functions.\n\n# Shows managed files.\nshow_files() {\n  printf \"%s\\n\" \"Managed Dotfiles:\"\n\n  for file in $(home_files); do\n    printf \"  %s\\n\" \"$(base_dest_file $file)\"\n  done\n}\nexport -f show_files\n\n# Installs all files.\ninstall_files() {\n  printf \"%s\\n\" \"Installing dotfiles...\"\n\n  for file in $(home_files); do\n    install_file $file\n  done\n\n  printf \"%s\\n\" \"Dotfiles install complete!\"\n}\nexport -f install_files\n\n# Installs a file.\n# Parameters: $1 (required): The file name.\ninstall_file() {\n  local source_file=\"$1\"\n  local dest_file=\"$HOME/$(base_dest_file $source_file)\"\n  local dest_dir=\"$(dirname $dest_file)\"\n\n  if [[ \"$(basename $source_file)\" == \"mkdir.command\" ]]; then\n    mkdir -p $dest_dir\n    return\n  fi\n\n  if [[ ! -f \"$dest_file\" ]]; then\n    mkdir -p \"$dest_dir\"\n    cp \"$source_file\" \"$dest_file\"\n    printf \"  + %s\\n\" \"$dest_file\"\n  fi\n}\nexport -f install_file\n\n# Links all files.\nlink_files() {\n  printf \"%s\\n\" \"Linking dotfiles...\"\n\n  for file in $(home_files); do\n    link_file $file\n  done\n\n  printf \"%s\\n\" \"Dotfiles link complete!\"\n}\nexport -f link_files\n\n# Links a dotfile to this project.\n# Parameters: $1 (required): The file name.\nlink_file() {\n  local source_file=\"$PWD/$1\"\n  local dest_file=\"$HOME/$(base_dest_file $1)\"\n  local dest_dir=\"$(dirname $dest_file)\"\n  local excludes=\".+(environment.sh.tt|git/configuration.tt)$\"\n\n  if [[ \"$(basename $source_file)\" == \"mkdir.command\" ]]; then\n    mkdir -p $dest_dir\n    return\n  fi\n\n  if [[ ! -h \"$dest_file\" && ! \"$source_file\" =~ $excludes ]]; then\n    read -r -p \"  Link $dest_file -> $source_file (y/n)? \" response\n    if [[ $response == 'y' ]]; then\n      mkdir -p \"$dest_dir\"\n      ln -sf \"$source_file\" \"$dest_file\"\n    fi\n  fi\n}\nexport -f link_file\n\n# Checks all files for changes.\ncheck_files() {\n  printf \"%s\\n\" \"Dotfiles Changes:\"\n\n  for file in $(home_files); do\n    check_file $file\n  done\n\n  printf \"%s\\n\" \"Dotfiles check complete!\"\n}\nexport -f check_files\n\n# Checks a file for changes.\n# Parameters: $1 (required): The file name.\ncheck_file() {\n  local source_file=\"$1\"\n  local dest_file=\"$HOME/$(base_dest_file $1)\"\n  local excludes=\".+command$\"\n\n  if [[ \"$source_file\" =~ $excludes ]]; then\n    return\n  elif [[ -e \"$dest_file\" || -h \"$dest_file\" ]]; then\n    if [[ \"$(diff $dest_file $source_file)\" != '' ]]; then\n      printf \"  * %s\\n\" \"$dest_file\"\n    fi\n  else\n    printf \"  - %s\\n\" \"$dest_file\"\n  fi\n}\nexport -f check_file\n\n# Delete files.\ndelete_files() {\n  printf \"%s\\n\" \"Deleting dotfiles...\"\n\n  for file in $(home_files); do\n    delete_file $file\n  done\n\n  printf \"%s\\n\" \"Dotfiles deletion complete!\"\n}\nexport -f delete_files\n\n# Delete file.\n# Parameters: $1 (required): The file name.\ndelete_file() {\n  local dest_file=\"$HOME/$(base_dest_file $1)\"\n  local excludes=\".+(environment.sh|git/configuration)$\"\n\n  # Proceed only if file exists.\n  if [[ -e \"$dest_file\" || -h \"$dest_file\" ]] && [[ ! \"$dest_file\" =~ $excludes ]]; then\n    read -r -p \"  Delete $dest_file (y/n)? \" response\n    if [[ $response == 'y' ]]; then\n      rm -f \"$dest_file\"\n    fi\n  fi\n}\nexport -f delete_file\n\n# Label: Home Files\n# Description: Enumerate home file templates.\nhome_files() {\n  for file in $(find lib/templates -type f); do\n    printf \"%s\\n\" \"$file\"\n  done\n}\nexport -f home_files\n\n# Label: Base Destination Home File\n# Description: Compute destination file path for source path.\n# Parameters: $1 (required): The source path.\nbase_dest_file() {\n  local source_file=\"$1\"\n  printf \"${source_file%.*}\" | sed 's/lib\\/templates\\///g'\n}\nexport -f base_dest_file\n"
  }
]