]> src.twobees.de Git - dotfiles.git/commitdiff
initial
authorTobias Sachs <git-pngdhxpf-ts@twobees.de>
Sun, 6 Nov 2022 10:59:38 +0000 (11:59 +0100)
committerTobias Sachs <git-pngdhxpf-ts@twobees.de>
Sun, 6 Nov 2022 10:59:38 +0000 (11:59 +0100)
978 files changed:
.gitignore [new file with mode: 0644]
.gitmodules [new file with mode: 0644]
.stow-local-ignore [new file with mode: 0644]
README.md [new file with mode: 0644]
install/basic [new file with mode: 0644]
install/init_win.ps1 [new file with mode: 0644]
install/ui [new file with mode: 0644]
stow/bin/.bin/i3status.sh [new file with mode: 0755]
stow/bin/.bin/touchpad.sh [new file with mode: 0755]
stow/i3/.config/i3/config [new file with mode: 0644]
stow/nvim/.config/nvim/init.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/cmp-settings.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/csharp.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/lspsetup.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/mappings.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/perl.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/plugin_mgr.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/set.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/theme.lua [new file with mode: 0644]
stow/nvim/.config/nvim/lua/treesitter.lua [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.editorconfig [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/CODEOWNERS [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/FUNDING.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/bug_report.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/bug_report_omz.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/config.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/feature_request.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/PULL_REQUEST_TEMPLATE.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/workflows/main.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.github/workflows/project.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.gitignore [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.gitpod.Dockerfile [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/.gitpod.yml [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/CODE_OF_CONDUCT.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/CONTRIBUTING.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/LICENSE.txt [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/SECURITY.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/bzr.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/cli.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/clipboard.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/compfix.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/completion.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/correction.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/diagnostics.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/directories.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/functions.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/git.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/grep.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/history.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/key-bindings.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/misc.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/nvm.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/prompt_info_functions.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/spectrum.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/termsupport.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/theme-and-appearance.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/lib/vcs_info.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/oh-my-zsh.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/1password/1password.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/1password/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/1password/_opswd [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/1password/opswd [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/adb/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/adb/_adb [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ag/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ag/_ag [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/alias-finder/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/alias-finder/alias-finder.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/.gitignore [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/aliases.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/cheatsheet.py [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/termcolor.py [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ansible/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ansible/ansible.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ant/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ant/_ant [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ant/ant.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/apache2-macports/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/apache2-macports/apache2-macports.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/arcanist/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/arcanist/arcanist.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/archlinux/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/archlinux/archlinux.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/asdf/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/asdf/asdf.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/autoenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/autoenv/autoenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/autojump/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/autojump/autojump.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/autopep8/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/autopep8/_autopep8 [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aws/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/aws/aws.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/battery/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/battery/battery.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bazel/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bazel/_bazel [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bbedit/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bbedit/bbedit.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bedtools/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bedtools/_bedtools [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bgnotify/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bgnotify/bgnotify.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bower/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bower/_bower [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bower/bower.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/branch/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/branch/branch.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/brew/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/brew/brew.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/_bundler [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/bundler.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cabal/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cabal/cabal.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cake/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cake/cake.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cakephp3/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cakephp3/cakephp3.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/_capistrano [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/capistrano.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cask/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cask/cask.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/catimg.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/catimg.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/colors.png [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/celery/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/celery/_celery [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/charm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/charm/charm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/chruby/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/chruby/chruby.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/.gitignore [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/chucknorris.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/fortunes/chucknorris [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cloudfoundry/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cloudfoundry/cloudfoundry.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/codeclimate/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/codeclimate/_codeclimate [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/_coffee [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/coffee.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/.gitignore [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/colemak-less [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/colemak.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/nroff [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/colorize/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/colorize/colorize.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/command-not-found/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/command-not-found/command-not-found.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/common-aliases/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/common-aliases/common-aliases.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/compleat/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/compleat/compleat.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/composer/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/composer/composer.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/copybuffer/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/copybuffer/copybuffer.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/copyfile/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/copyfile/copyfile.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/copypath/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/copypath/copypath.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cp/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cp/cp.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cpanm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/cpanm/_cpanm [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dash/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dash/dash.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/debian/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/debian/debian.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/deno/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/deno/deno.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dircycle/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dircycle/dircycle.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/direnv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/direnv/direnv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/dirhistory.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dirpersist/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dirpersist/dirpersist.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dnf/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dnf/dnf.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dnote/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dnote/_dnote [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/_docker-compose [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/docker-compose.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/_docker-machine [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/docker-machine.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker/_docker [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/docker/docker.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/doctl/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/doctl/doctl.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dotenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dotenv/dotenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dotnet/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/dotnet/dotnet.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/droplr/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/droplr/droplr.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/drush/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/drush/drush.complete.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/drush/drush.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/eecms/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/eecms/eecms.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/emacs.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/emacsclient.sh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/_ember-cli [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/ember-cli.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji-clock/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji-clock/emoji-clock.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji-char-definitions.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji-data.txt [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/gemoji_db.json [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/update_emoji.py [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_emoji_set.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_floral_set.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_love_set.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_nature_set.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_stellar_set.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_zodiac_set.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/encode64/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/encode64/encode64.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/extract/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/extract/_extract [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/extract/extract.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/_fab [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/fabric.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fancy-ctrl-z/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fancy-ctrl-z/fancy-ctrl-z.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fasd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fasd/fasd.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fastfile/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fastfile/fastfile.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fbterm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fbterm/fbterm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fd/_fd [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fig/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fig/fig.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/firewalld/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/firewalld/firewalld.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/flutter/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/flutter/flutter.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fnm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fnm/fnm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/forklift/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/forklift/forklift.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/_fossil [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/fossil.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/_frontend [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/frontend-search.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fzf/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/fzf/fzf.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gas/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gas/_gas [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gatsby/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gatsby/_gatsby [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gcloud/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gcloud/gcloud.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/_geeknote [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/geeknote.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gem/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gem/_gem [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gem/gem.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-apple [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-monkey [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-xkcd [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gh/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gh/gh.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-auto-fetch/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/git-escape-magic [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/git-escape-magic.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-extras/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-extras/git-extras.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow-avh/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow-avh/git-flow-avh.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/_git-flow [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/git-flow.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-hubflow/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-hubflow/git-hubflow.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-lfs/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-lfs/git-lfs.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/git-prompt.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/gitstatus.py [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/git/git.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/_git [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/git-completion.bash [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/git-prompt.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/gitfast.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/update [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/github/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/github/_hub [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/github/github.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitignore/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gitignore/gitignore.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/_asadmin [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/glassfish.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/globalias/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/globalias/globalias.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gnu-utils/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gnu-utils/gnu-utils.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/golang/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/golang/_golang [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/golang/golang.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/golang/templates/package.txt [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/golang/templates/search.txt [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gpg-agent/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gpg-agent/gpg-agent.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/_gradle [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/gradle.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/grails/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/grails/grails.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/grc/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/grc/grc.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/grunt/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/grunt/grunt.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gulp/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/gulp/gulp.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hanami/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hanami/hanami.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/helm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/helm/helm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/heroku/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/heroku/heroku.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/history-substring-search.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/history-substring-search.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/update-from-upstream.zsh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/history/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/history/history.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/.gitignore [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/fortunes/hitchhiker [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/hitchhiker.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hitokoto/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/hitokoto/hitokoto.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/homestead/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/homestead/homestead.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/httpie/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/httpie/_httpie [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/invoke/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/invoke/invoke.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ionic/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ionic/ionic.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/LICENSE [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/_ipfs [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/isodate/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/isodate/isodate.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/istioctl/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/istioctl/istioctl.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/iterm2/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/iterm2/iterm2.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jake-node/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jake-node/jake-node.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jenv/jenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jfrog/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jfrog/jfrog.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jhbuild/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jhbuild/jhbuild.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jira/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jira/_jira [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jira/jira.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jruby/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jruby/jruby.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jsontools/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jsontools/jsontools.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/juju/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/juju/juju.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jump/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/jump/jump.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kate/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kate/kate.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/keychain/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/keychain/keychain.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kitchen/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kitchen/_kitchen [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kn/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kn/kn.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/knife/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/knife/_knife [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/knife_ssh/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/knife_ssh/knife_ssh.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kops/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kops/kops.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kube-ps1/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kube-ps1/kube-ps1.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kubectl/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kubectl/kubectl.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/kubectx.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/prod.png [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/stage.png [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lando/LICENSE [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lando/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lando/lando.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/_artisan [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/laravel.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel4/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel4/laravel4.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel5/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/laravel5/laravel5.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/last-working-dir/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/last-working-dir/last-working-dir.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lein/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lein/_lein [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lighthouse/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lighthouse/lighthouse.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lol/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lol/lol.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lpass/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lpass/_lpass [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lxd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/lxd/lxd.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macos/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macos/_security [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macos/macos.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macos/music [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macos/spotify [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macports/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macports/_port [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/macports/macports.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/magic-enter/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/magic-enter/magic-enter.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/man/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/man/man.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/marked2/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/marked2/marked2.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mercurial/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mercurial/mercurial.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/_meteor [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/meteor.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/microk8s/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/microk8s/microk8s.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/minikube/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/minikube/minikube.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mix-fast/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mix-fast/mix-fast.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mix/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mix/_mix [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mongocli/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mongocli/mongocli.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mosh/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mosh/mosh.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/_multipass [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/multipass.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mvn/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mvn/mvn.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mysql-macports/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/mysql-macports/mysql-macports.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/n98-magerun/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/n98-magerun/n98-magerun.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/_nanoc [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/nanoc.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ng/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ng/_ng [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nmap/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nmap/nmap.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/node/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/node/node.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nomad/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nomad/_nomad [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/npm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/npm/npm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/_nvm [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/nvm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/oc/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/oc/oc.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/octozen/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/octozen/octozen.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/operator-sdk/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/operator-sdk/operator-sdk.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/otp/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/otp/otp.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pass/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pass/_pass [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/paver/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/paver/paver.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pep8/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pep8/_pep8 [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/per-directory-history.plugin.zsh [new symlink]
stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/per-directory-history.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/percol/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/percol/percol.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/perl/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/perl/perl.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/perms/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/perms/perms.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/phing/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/phing/phing.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pip/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pip/_pip [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pip/pip.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pipenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pipenv/pipenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pj/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pj/pj.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/please/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/please/please.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/_pm2 [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/pm2.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pod/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pod/_pod [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/poetry/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/poetry/poetry.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/postgres/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/postgres/postgres.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pow/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pow/pow.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/powder/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/powder/_powder [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/powify/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/powify/_powify [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/profiles/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/profiles/profiles.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pyenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pyenv/pyenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/_pylint [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/pylint.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/python/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/python/python.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rails/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rails/_rails [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rails/rails.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rake-fast/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rake-fast/rake-fast.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rake/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rake/rake.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rand-quote/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rand-quote/rand-quote.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rbenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rbenv/rbenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rbfu/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rbfu/rbfu.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rbw/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rbw/rbw.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/_react-native [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/react-native.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rebar/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rebar/_rebar [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/redis-cli/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/redis-cli/_redis-cli [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/repo/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/repo/_repo [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/repo/repo.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ripgrep/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ripgrep/_ripgrep [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ros/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ros/_ros [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rsync/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rsync/rsync.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ruby/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ruby/ruby.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rust/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rust/_rustc [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rust/rust.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rvm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/rvm/rvm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/safe-paste/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/safe-paste/safe-paste.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/salt/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/salt/_salt [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/samtools/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/samtools/_samtools [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/_sbt [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/sbt.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scala/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scala/_scala [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scd/_scd [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scd/scd [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/scd/scd.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/screen/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/screen/screen.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scw/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/scw/_scw [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sdk/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sdk/sdk.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sfdx/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sfdx/_sfdx [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sfffe/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sfffe/sfffe.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/.editorconfig [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/proxy.py [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/ssh-agent.py [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/ssh-proxy.py [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/shrink-path/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/shrink-path/shrink-path.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/singlechar/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/singlechar/singlechar.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/spring/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/spring/_spring [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sprunge/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sprunge/sprunge.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ssh-agent/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ssh-agent/ssh-agent.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/stack/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/stack/stack.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sublime-merge/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sublime-merge/sublime-merge.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sublime/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sublime/sublime.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sudo/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/sudo/sudo.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/_supervisorctl [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/_supervisord [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/supervisor.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/suse/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/suse/suse.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/svcat/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/svcat/svcat.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/svn-fast-info/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/svn-fast-info/svn-fast-info.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/svn/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/svn/svn.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/_swift [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/swiftpm.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/symfony/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/symfony/symfony.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/symfony2/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/symfony2/symfony2.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/systemadmin/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/systemadmin/systemadmin.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/systemd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/systemd/systemd.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/_task [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/taskwarrior.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/term_tab/README [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/term_tab/term_tab.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/terminitor/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/terminitor/_terminitor [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/_terraform [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/terraform.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/textastic/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/textastic/textastic.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/textmate/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/textmate/textmate.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/thefuck/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/thefuck/thefuck.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/themes/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/themes/themes.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/thor/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/thor/_thor [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tig/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tig/tig.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/timer/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/timer/timer.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmux-cssh/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmux-cssh/_tmux-cssh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.extra.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.only.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/_tmuxinator [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/tmuxinator.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/toolbox/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/toolbox/toolbox.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/torrent/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/torrent/torrent.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/transfer/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/transfer/transfer.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tugboat/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/tugboat/_tugboat [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ubuntu/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ubuntu/ubuntu.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ufw/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/ufw/_ufw [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/_universalarchive [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/universalarchive.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/urltools/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/urltools/urltools.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant-prompt/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/_vagrant [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/vagrant.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vault/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vault/_vault [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vi-mode/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vi-mode/vi-mode.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vim-interaction/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vim-interaction/vim-interaction.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenv/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenv/virtualenv.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenvwrapper/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/volta/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/volta/volta.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vscode/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vscode/vscode.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vundle/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/vundle/vundle.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/_wake [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/wakeonlan.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wd/LICENSE [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wd/_wd.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wd/wd.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wd/wd.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/web-search/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/web-search/web-search.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wp-cli/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/wp-cli/wp-cli.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/_xcselv [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/xcode.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/_yarn [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/yarn.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yii/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yii/yii.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yii2/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yii2/yii2.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yum/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/yum/yum.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/z/LICENSE [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/z/MANUAL.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/z/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/z/_z [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/z/z.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zbell/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zbell/zbell.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/_zeus [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/zeus.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zoxide/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zoxide/zoxide.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-interactive-cd/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-aliases.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-cd.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-env.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-functions.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-history.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-kill.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-list.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-options.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-panelize.conf [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/LICENSE [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/Makefile [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/NEWS [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/README.md [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/_n-kill [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/generate_single_file [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/img/n-history2.png [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/install.sh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/n-preview [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/znt-tmux.zsh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-aliases [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-cd [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-env [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-functions [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-help [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-history [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-kill [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list-draw [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list-input [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-options [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-panelize [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-cd-widget [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-history-widget [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-kill-widget [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-usetty-wrapper [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/zsh-navigation-tools.plugin.zsh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/templates/zshrc.zsh-template [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/3den.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/Soliah.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/adben.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/af-magic.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/afowler.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/agnoster.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/alanpeabody.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/amuse.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/apple.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/arrow.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/aussiegeek.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/avit.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/awesomepanda.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/bira.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/blinks.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/bureau.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/candy-kingdom.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/candy.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/clean.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/cloud.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/crcandy.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/crunch.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/cypher.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/dallas.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/darkblood.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/daveverwer.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/dieter.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/dogenpunk.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/dpoggi.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/dst.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/dstufft.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/duellj.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/eastwood.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/edvardm.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/emotty.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/essembeh.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/evan.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/fino-time.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/fino.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/fishy.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/flazz.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/fletcherm.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/fox.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/frisk.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/frontcube.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/funky.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/fwalch.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/gallifrey.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/gallois.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/garyblessington.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/gentoo.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/geoffgarside.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/gianu.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/gnzh.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/gozilla.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/half-life.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/humza.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/imajes.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/intheloop.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/itchy.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jaischeema.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jbergantine.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jispwoso.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jnrowe.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jonathan.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/josh.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jreese.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/jtriley.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/juanghurtado.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/junkfood.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/kafeitu.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/kardan.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/kennethreitz.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/kiwi.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/kolo.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/kphoen.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/lambda.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/linuxonly.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/lukerandall.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/macovsky-ruby.zsh-theme [new symlink]
stow/oh-my-zsh/.oh-my-zsh/themes/macovsky.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/maran.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mgutz.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mh.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/michelebologna.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mikeh.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/miloshadzic.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/minimal.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mira.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mlh.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mortalscumbag.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/mrtazz.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/murilasso.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/muse.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/nanotech.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/nebirhos.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/nicoulaj.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/norm.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/obraun.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/peepcode.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/philips.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/pmcgee.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/pygmalion-virtualenv.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/pygmalion.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/random.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/re5et.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/refined.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/rgm.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/risto.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/rixius.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/rkj-repos.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/rkj.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/robbyrussell.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/sammy.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/simonoff.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/simple.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/skaro.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/smt.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/sonicradish.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/sorin.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/sporty_256.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/steeef.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/strug.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/sunaku.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/sunrise.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/superjarin.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/suvash.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/takashiyoshida.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/terminalparty.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/theunraveler.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/tjkirch.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/tjkirch_mod.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/tonotdo.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/trapd00r.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/wedisagree.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/wezm+.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/wezm.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/wuffers.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/xiong-chiamiov-plus.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/xiong-chiamiov.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/ys.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/themes/zhann.zsh-theme [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/tools/changelog.sh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/tools/check_for_upgrade.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/tools/install.sh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/tools/require_tool.sh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/tools/theme_chooser.sh [new file with mode: 0755]
stow/oh-my-zsh/.oh-my-zsh/tools/uninstall.sh [new file with mode: 0644]
stow/oh-my-zsh/.oh-my-zsh/tools/upgrade.sh [new file with mode: 0755]
stow/tmux/.tmux.conf [new file with mode: 0755]
stow/vim/.vim/README.md [new file with mode: 0644]
stow/vim/.vim/filetype.vim [new file with mode: 0644]
stow/vim/.vim/ftplugin/go.vim [new file with mode: 0644]
stow/vim/.vim/ftplugin/hub.vim [new file with mode: 0644]
stow/vim/.vim/ftplugin/perl.vim [new file with mode: 0644]
stow/vim/.vim/init.sh [new file with mode: 0755]
stow/vim/.vim/plugins.vundel.vim [new file with mode: 0644]
stow/vim/.vim/syntax/hub.vim [new file with mode: 0644]
stow/vim/.vim/syntax/iptables.vim [new file with mode: 0644]
stow/vim/.vim/vimrc [new file with mode: 0644]
stow/vsvim/_vsvimrc [new file with mode: 0644]
stow/zsh/.zshrc [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..3ba4099
--- /dev/null
@@ -0,0 +1,6 @@
+stow/vim/.vim/spell/
+stow/vim/.vim/bundle/
+stow/vim/.vim/tmp/
+stow/vim/.vim/tmpnvim/
+*~
+stow/nvim/.config/nvim/plugin/packer_compiled.lua
diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..3445db8
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "oh-my-zsh/.oh-my-zsh"]
+       path = stow/oh-my-zsh/.oh-my-zsh
+       url = https://github.com/ohmyzsh/ohmyzsh.git
diff --git a/.stow-local-ignore b/.stow-local-ignore
new file mode 100644 (file)
index 0000000..728619e
--- /dev/null
@@ -0,0 +1,2 @@
+\.git
+\.gitignore
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..5ccd901
--- /dev/null
+++ b/README.md
@@ -0,0 +1,24 @@
+# Get started:
+
+    git clone https://src.twobees.de/git/dotfiles ~/dotfiles
+
+## install stuff on debian:
+
+    cd ~/dotfiles/install
+    sudo apt-get install `cat basic` `cat ui`
+
+or without ui stuff
+
+    sudo apt-get install `cat basic`
+
+## setup dotfiles:
+linux:
+
+    cd ~/dotfiles/stow
+    stow -v -t ~/ */
+
+windows:
+
+    cd ~/dotfiles/install/
+    init_win.ps1
+
diff --git a/install/basic b/install/basic
new file mode 100644 (file)
index 0000000..da5c5d9
--- /dev/null
@@ -0,0 +1,7 @@
+screen
+tmux
+zsh
+git
+fzf
+neovim
+stow
diff --git a/install/init_win.ps1 b/install/init_win.ps1
new file mode 100644 (file)
index 0000000..3382845
--- /dev/null
@@ -0,0 +1,19 @@
+$localData = Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\' -Name 'Local AppData' `
+                | Select-Object -ExpandProperty 'Local AppData'
+
+# nvim config
+$nvmConfigDir = $localData + "\nvim\"
+$dotfilesDir = $HOME + "\dotfiles\stow"
+
+echo "linking nvim config dir"
+echo $nvmConfigDir
+New-Item -Force -ItemType SymbolicLink -Path "$nvmConfigDir" -Target "$dotfilesDir\nvim\.config\nvim\"
+
+# vsvim studio plugin
+$vsvimConfigHome = $HOME + "\_vsvimrc"
+$vsvimConfigDotfiles = $HOME + "\dotfiles\vsvim\_vsvimrc"
+
+echo "linking nvim config dir"
+echo $nvmConfigDir
+New-Item -Force -ItemType SymbolicLink -Path "$vsvimConfigHome" -Target "$vsvimConfigDotfiles"
+
diff --git a/install/ui b/install/ui
new file mode 100644 (file)
index 0000000..538db7c
--- /dev/null
@@ -0,0 +1,6 @@
+dmenu
+i3
+network-manager-gnome
+pasystray
+xfce4-power-manager
+xserver-xorg-input-synaptics
diff --git a/stow/bin/.bin/i3status.sh b/stow/bin/.bin/i3status.sh
new file mode 100755 (executable)
index 0000000..a33d670
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+i3status | while :
+do
+    read line
+    LG=$(setxkbmap -query | awk '/layout/{print $2}')
+    if [ $LG == "br" ]
+    then
+        dat="[{ \"full_text\": \"LANG: $LG\", \"color\":\"#009E00\" },"
+    else
+        dat="[{ \"full_text\": \"LANG: $LG\", \"color\":\"#C60101\" },"
+    fi
+    echo "${line/[/$dat}" || exit 1
+done
diff --git a/stow/bin/.bin/touchpad.sh b/stow/bin/.bin/touchpad.sh
new file mode 100755 (executable)
index 0000000..370a604
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+#xinput list-props 'Elan Touchpad'
+# only for the old eeebook...
+xinput set-prop 'Elan Touchpad' 'libinput Tapping Enabled' 1
+xinput set-prop 'Elan Touchpad' 'libinput Middle Emulation Enabled' 1
+xinput set-prop 'Elan Touchpad' 'libinput Natural Scrolling Enabled' 1
+xinput set-prop 'Elan Touchpad' 'libinput Disable While Typing Enabled' 1
+
+# swift 3:
+# invert scrolling, like on a touchscreen
+synclient VertScrollDelta=-28
+# 3 finger touch = middle mouse:
+synclient TapButton3=2
diff --git a/stow/i3/.config/i3/config b/stow/i3/.config/i3/config
new file mode 100644 (file)
index 0000000..4dc7ecd
--- /dev/null
@@ -0,0 +1,207 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see https://i3wm.org/docs/userguide.html for a complete reference!
+
+set $mod Mod4
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+font pango:monospace 8
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# The combination of xss-lock, nm-applet and pactl is a popular choice, so
+# they are included here as an example. Modify as you see fit.
+
+# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
+# screen before suspend. Use loginctl lock-session to lock your screen.
+exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
+
+# NetworkManager is the most popular way to manage wireless networks on Linux,
+# and nm-applet is a desktop environment-independent system tray GUI for it.
+exec dunst
+exec --no-startup-id nm-applet
+exec --no-startup-id /usr/bin/pasystray
+exec --no-startup-id ~/.bin/touchpad.sh
+exec --no-startup-id /usr/bin/xfce4-power-manager
+exec --no-startup-id /usr/bin/firefox
+# exec --no-startup-id /usr/bin/x2goclient
+exec --no-startup-id "sleep 10; /usr/bin/nextcloud"
+exec --no-startup-id "sleep 12; /usr/bin/pass git pull"
+exec --no-startup-id nitrogen --restore
+exec --no-startup-id "/usr/bin/setxkbmap -layout us,de"
+exec --no-startup-id "/usr/bin/setxkbmap -option 'grp:alt_shift_toggle'"
+
+
+
+
+
+# Use pactl to adjust volume in PulseAudio.
+set $refresh_i3status killall -SIGUSR1 /usr/bin/i3status
+bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
+bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
+bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
+bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+bindsym $mod+Return exec /usr/bin/i3-sensible-terminal
+# start a terminal
+# use default and hope for the best. ... # bindsym $mod+Return exec /usr/bin/gnome-terminal
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+# start dmenu (a program launcher)
+# bindsym $mod+d exec --no-startup-id dmenu_run
+# A more modern dmenu replacement is rofi:
+# bindcode $mod+40 exec rofi -modi drun,run -show drun
+# There also is i3-dmenu-desktop which only displays applications shipping a
+# .desktop file. It is a wrapper around dmenu, so you need that installed.
+bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
+
+# change focus
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+bindsym Control+space focus right
+bindsym Control+Shift+space focus left
+bindsym Mod1+Tab focus right
+bindsym Mod1+Shift+Tab focus left
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+h move left
+bindsym $mod+Shift+j move down
+bindsym $mod+Shift+k move up
+bindsym $mod+Shift+l move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+b split h
+
+# split in vertical orientation
+bindsym $mod+v split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+
+# Define names for default workspaces for which we configure key bindings later on.
+# We use variables to avoid repeating the names in multiple places.
+workspace_layout tabbed
+set $ws1 "1"
+set $ws2 "2"
+set $ws3 "3"
+set $ws4 "4"
+set $ws5 "5"
+set $ws6 "6"
+set $ws7 "7"
+set $ws8 "8"
+set $ws9 "9"
+set $ws10 "10"
+
+# switch to workspace
+bindsym $mod+1 workspace number $ws1
+bindsym $mod+2 workspace number $ws2
+bindsym $mod+3 workspace number $ws3
+bindsym $mod+4 workspace number $ws4
+bindsym $mod+5 workspace number $ws5
+bindsym $mod+6 workspace number $ws6
+bindsym $mod+7 workspace number $ws7
+bindsym $mod+8 workspace number $ws8
+bindsym $mod+9 workspace number $ws9
+bindsym $mod+0 workspace number $ws10
+
+# move focused container to workspace
+bindsym $mod+Shift+1 move container to workspace number $ws1
+bindsym $mod+Shift+2 move container to workspace number $ws2
+bindsym $mod+Shift+3 move container to workspace number $ws3
+bindsym $mod+Shift+4 move container to workspace number $ws4
+bindsym $mod+Shift+5 move container to workspace number $ws5
+bindsym $mod+Shift+6 move container to workspace number $ws6
+bindsym $mod+Shift+7 move container to workspace number $ws7
+bindsym $mod+Shift+8 move container to workspace number $ws8
+bindsym $mod+Shift+9 move container to workspace number $ws9
+bindsym $mod+Shift+0 move container to workspace number $ws10
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
+bindsym $mod+Shift+F1 exec "shutdown -h now"
+
+
+
+mode "resize" {
+        # These bindings trigger as soon as you enter the resize mode
+
+        # Pressing left will shrink the window’s width.
+        # Pressing right will grow the window’s width.
+        # Pressing up will shrink the window’s height.
+        # Pressing down will grow the window’s height.
+        bindsym j resize shrink width 10 px or 10 ppt
+        bindsym k resize grow height 10 px or 10 ppt
+        bindsym l resize shrink height 10 px or 10 ppt
+        bindsym semicolon resize grow width 10 px or 10 ppt
+
+        # same bindings, but for the arrow keys
+        bindsym Left resize shrink width 10 px or 10 ppt
+        bindsym Down resize grow height 10 px or 10 ppt
+        bindsym Up resize shrink height 10 px or 10 ppt
+        bindsym Right resize grow width 10 px or 10 ppt
+
+        # back to normal: Enter or Escape or $mod+r
+        bindsym Return mode "default"
+        bindsym Escape mode "default"
+        bindsym $mod+r mode "default"
+}
+
+bindsym $mod+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+bar {
+        status_command ~/.bin/i3status.sh
+#        status_command i3status
+}
+
diff --git a/stow/nvim/.config/nvim/init.lua b/stow/nvim/.config/nvim/init.lua
new file mode 100644 (file)
index 0000000..d0876a8
--- /dev/null
@@ -0,0 +1,27 @@
+
+local data_path = vim.fn.stdpath('data')
+vim.o.backupdir = data_path .. "/backup//"
+require 'plugin_mgr'
+require 'set'
+require 'lspsetup'
+require 'mappings'
+require 'treesitter'
+pcall (require 'perl')
+pcall (require 'theme')
+pcall (require 'cmp-settings')
+
+-- found in ThePrimagen dotfiles:
+local augroup = vim.api.nvim_create_augroup
+local yank_group = augroup('HighlightYank', {})
+local autocmd = vim.api.nvim_create_autocmd
+
+autocmd('TextYankPost', {
+    group = yank_group,
+    pattern = '*',
+    callback = function()
+        vim.highlight.on_yank({
+            higroup = 'IncSearch',
+            timeout = 40,
+        })
+    end,
+})
diff --git a/stow/nvim/.config/nvim/lua/cmp-settings.lua b/stow/nvim/.config/nvim/lua/cmp-settings.lua
new file mode 100644 (file)
index 0000000..517fc9d
--- /dev/null
@@ -0,0 +1,122 @@
+
+-- mostly got this stuff from here: https://raw.githubusercontent.com/tjdevries/config_manager/master/xdg_config/nvim/after/plugin/completion.lua
+vim.opt.completeopt = { "menu", "menuone", "noselect" }
+
+-- Don't show the dumb matching stuff.
+vim.opt.shortmess:append "c"
+
+
+local ok, lspkind = pcall(require, "lspkind")
+if not ok then
+  return
+end
+
+lspkind.init()
+
+local cmp = require "cmp"
+
+cmp.setup {
+  mapping = {
+    ["<C-n>"] = cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Insert },
+    ["<C-p>"] = cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Insert },
+    ["<C-d>"] = cmp.mapping.scroll_docs(-4),
+    ["<C-f>"] = cmp.mapping.scroll_docs(4),
+    ["<C-e>"] = cmp.mapping.abort(),
+    ["<c-y>"] = cmp.mapping(
+      cmp.mapping.confirm {
+        behavior = cmp.ConfirmBehavior.Insert,
+        select = true,
+      },
+      { "i", "c" }
+    ),
+
+    ["<c-space>"] = cmp.mapping {
+      i = cmp.mapping.complete(),
+      c = function(
+        _ --[[fallback]]
+      )
+        if cmp.visible() then
+          if not cmp.confirm { select = true } then
+            return
+          end
+        else
+          cmp.complete()
+        end
+      end,
+    },
+
+    -- ["<tab>"] = false,
+    ["<tab>"] = cmp.config.disable,
+
+    -- Testing
+    ["<c-q>"] = cmp.mapping.confirm {
+      behavior = cmp.ConfirmBehavior.Replace,
+      select = true,
+    },
+
+  },
+
+  sources = {
+
+    -- Youtube: Could enable this only for lua, but nvim_lua handles that already.
+    { name = "nvim_lua" },
+    { name = "nvim_lsp" },
+    { name = "path" },
+    { name = "buffer", keyword_length = 3 },
+  },
+
+  sorting = {
+    -- TODO: Would be cool to add stuff like "See variable names before method names" in rust, or something like that.
+    comparators = {
+      cmp.config.compare.offset,
+      cmp.config.compare.exact,
+      cmp.config.compare.score,
+
+      -- copied from cmp-under, but I don't think I need the plugin for this.
+      -- I might add some more of my own.
+      function(entry1, entry2)
+        local _, entry1_under = entry1.completion_item.label:find "^_+"
+        local _, entry2_under = entry2.completion_item.label:find "^_+"
+        entry1_under = entry1_under or 0
+        entry2_under = entry2_under or 0
+        if entry1_under > entry2_under then
+          return false
+        elseif entry1_under < entry2_under then
+          return true
+        end
+      end,
+
+      cmp.config.compare.kind,
+      cmp.config.compare.sort_text,
+      cmp.config.compare.length,
+      cmp.config.compare.order,
+    },
+  },
+
+  -- do i want luasnip?
+  -- snippet = {
+  --   expand = function(args)
+  --     require("luasnip").lsp_expand(args.body)
+  --   end,
+  -- },
+
+  formatting = {
+    -- Youtube: How to set up nice formatting for your sources.
+    format = lspkind.cmp_format {
+      with_text = true,
+      menu = {
+        buffer = "[buf]",
+        nvim_lsp = "[LSP]",
+        nvim_lua = "[api]",
+        path = "[path]",
+        luasnip = "[snip]",
+        gh_issues = "[issues]",
+        tn = "[TabNine]",
+      },
+    },
+  },
+
+  experimental = {
+    native_menu = false,
+  },
+}
diff --git a/stow/nvim/.config/nvim/lua/csharp.lua b/stow/nvim/.config/nvim/lua/csharp.lua
new file mode 100644 (file)
index 0000000..0ad4a5d
--- /dev/null
@@ -0,0 +1,13 @@
+require'lspconfig'.csharp_ls.setup({ -- install server: 'dotnet tool install --global csharp-ls'
+--        cmd = {"~\\.dotnet\\tools\\csharp-ls.exe"},
+    on_attach = function ()
+        vim.keymap.set ("n", "K", vim.lsp.buf.hover, { buffer=0}) -- buffer=0 -> only in current buffer
+        vim.keymap.set ("n", "gd", vim.lsp.buf.definition, { buffer=0}) -- goto definition
+        vim.keymap.set ("n", "gT", vim.lsp.buf.type_definition, { buffer=0}) -- goto typedefinition
+        vim.keymap.set ("n", "gi", vim.lsp.buf.implementation, { buffer=0}) -- goto implementation
+        vim.keymap.set ("n", "dj", vim.diagnostic.goto_next, { buffer=0}) -- goto dignostic next
+        vim.keymap.set ("n", "dk", vim.diagnostic.goto_prev, { buffer=0}) -- goto diognostic prev
+        vim.keymap.set ("n", "dl", "<cmd>Telescope diagnostic", { buffer=0}) -- goto list failure
+        vim.keymap.set ("n", "<leader>r", vim.lsp.buf.rename, { buffer=0})
+    end
+})
diff --git a/stow/nvim/.config/nvim/lua/lspsetup.lua b/stow/nvim/.config/nvim/lua/lspsetup.lua
new file mode 100644 (file)
index 0000000..2701515
--- /dev/null
@@ -0,0 +1,52 @@
+vim.api.nvim_create_autocmd('LspAttach', {
+    callback = function()
+        vim.keymap.set ("n", "K", vim.lsp.buf.hover, { buffer=0}) -- buffer=0 -> only in current buffer
+        vim.keymap.set ("n", "gd", vim.lsp.buf.definition, { buffer=0}) -- goto definition
+        vim.keymap.set ("n", "gT", vim.lsp.buf.type_definition, { buffer=0}) -- goto typedefinition
+        vim.keymap.set ("n", "gi", vim.lsp.buf.implementation, { buffer=0}) -- goto implementation
+        vim.keymap.set ("n", "dj", vim.diagnostic.goto_next, { buffer=0}) -- goto dignostic next
+        vim.keymap.set ("n", "dk", vim.diagnostic.goto_prev, { buffer=0}) -- goto diognostic prev
+        vim.keymap.set ("n", "dl", "<cmd>Telescope diagnostic", { buffer=0}) -- goto list failure
+        vim.keymap.set ("n", "<leader>r", vim.lsp.buf.rename, { buffer=0})
+    end,
+})
+require("mason").setup()
+
+require'lspconfig'.csharp_ls.setup({})
+
+require'lspconfig'.perlls.setup{
+    settings = {
+        perl = {
+            fileFilter = { ".pm", ".pl" },
+            ignoreDirs = ".git",
+            perlCmd = "perl",
+            perlInc = " "
+        }
+    },
+    single_file_support = true
+}
+
+
+require'lspconfig'.sumneko_lua.setup {
+    filetypes = { "lua"},
+    settings = {
+        Lua = {
+            runtime = {
+                -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
+                version = 'LuaJIT',
+            },
+            diagnostics = {
+                -- Get the language server to recognize the `vim` global
+                globals = {'vim'},
+            },
+            workspace = {
+                -- Make the server aware of Neovim runtime files
+                library = vim.api.nvim_get_runtime_file("", true),
+            },
+            -- Do not send telemetry data containing a randomized but unique identifier
+            telemetry = {
+                enable = false,
+            },
+        },
+    },
+}
diff --git a/stow/nvim/.config/nvim/lua/mappings.lua b/stow/nvim/.config/nvim/lua/mappings.lua
new file mode 100644 (file)
index 0000000..8911c61
--- /dev/null
@@ -0,0 +1,70 @@
+function map(mode, shortcut, command)
+    vim.api.nvim_set_keymap(mode, shortcut, command, { noremap = true, silent = true })
+end
+
+function nmap(shortcut, command)
+    map('n', shortcut, command)
+end
+
+function imap(shortcut, command)
+    map('i', shortcut, command)
+end
+
+function vmap(shortcut, command)
+    map('v', shortcut, command)
+end
+
+vim.g.mapleader = " "
+nmap("<F8>", "]s")
+nmap("<S-F8>", "[s")
+nmap("Z", "Y")
+nmap("<leader>-", "i•")
+nmap("<C-k>", "<C-W>k")
+nmap("<C-j>", "<C-W>j")
+nmap("<C-h>", "<C-W>h")
+nmap("<C-l>", "<C-W>l")
+nmap("<Leader>i", "a'\" <<  << \"' <Esc>6hi")
+nmap("<Leader>a", "a'{}' <Esc>2hi")
+nmap("<Leader>A", "a'\"+  +\"' <Esc>4hi")
+nmap("<F2>", "msgg=G`s")
+imap("kj", "<Esc>")
+nmap("<leader>j", ":bprev<CR>")
+nmap("<leader>k", ":bnext<CR>")
+nmap("<C-l>", "<C-W>l")
+vmap("<leader>c", "\"*y")
+nmap("<leader>v", "\"*p")
+nmap("<S-Up>", ":m .-2<CR>==")
+vmap("<S-Up>", ":m '<-2<CR>gv=gv")
+nmap("<S-Down>", ":m .+1<CR>==")
+vmap("<S-Down>", ":m '>+1<CR>gv=gv")
+nmap("<S-Right>", ">>")
+vmap("<S-Right>", ":><CR>gv")
+vmap("<S-Left>", " :<<CR>gv")
+nmap("<S-Left>", "<<")
+nmap("<leader>w", ":w<CR>")
+nmap("<leader>wj", ":wa<CR>")
+nmap("<leader>wk", ":xall<CR>")
+vmap(".", ":normal.<CR>")
+-- vmap("<leader>tt", ":Tabular /^[^-+=]*\zs\S*=/l1l1<cr>")
+-- vmap("<leader>t,", ":Tabular /,\zs/l1l1<cr>")
+-- vmap("<leader>t<space>", " :Tabular /\s\+\zs/l1l0<cr>")
+-- vmap("<leader>t:", "       :Tabular /:\zs/l1l0<cr>")
+-- vmap("<leader>t(", " :Tabular /(/l1l0<cr>")
+nmap("<Leader>s", "yiw/<C-R>/\\|<C-R>\"<cr>")
+vmap("<Leader>s", "y/<C-R>/\\|<C-R>\"<cr>")
+nmap("<Leader>ll", "iprint_log(\"\");<Esc>V=0f(la")
+nmap("<leader><tab>", ":Files<cr>")
+imap("<F4>", "<Esc>:Explore<CR>")
+nmap("<F4>", ":Explore<CR>")
+
+nmap("<Leader>r", ":Reload<CR>:echom 'config relaoded!'<CR>")
+nmap("<leader>e", ":tabedit $MYVIMRC<CR>:lcd %:p:h<cr>")
+
+vim.keymap.set('n', "<Leader>r", function ()
+    for k in pairs(package.loaded) do
+        package.loaded[k] = nil
+    end
+    vim.cmd [[ :source $MYVIMRC ]]
+    print ('config reloaded!')
+end
+)
diff --git a/stow/nvim/.config/nvim/lua/perl.lua b/stow/nvim/.config/nvim/lua/perl.lua
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/stow/nvim/.config/nvim/lua/plugin_mgr.lua b/stow/nvim/.config/nvim/lua/plugin_mgr.lua
new file mode 100644 (file)
index 0000000..319fda1
--- /dev/null
@@ -0,0 +1,39 @@
+local ensure_packer = function()
+    local fn = vim.fn
+    local install_path = fn.stdpath('data')..'/site/pack/packer/start/packer.nvim'
+    if fn.empty(fn.glob(install_path)) > 0 then
+        fn.system({'git', 'clone', '--depth', '1', 'https://github.com/wbthomason/packer.nvim', install_path})
+        vim.cmd [[packadd packer.nvim]]
+        return true
+    end
+    return false
+end
+
+local packer_bootstrap = ensure_packer()
+
+return require('packer').startup(function(use)
+    use { 'wbthomason/packer.nvim' }
+    use { 'catppuccin/nvim', as = 'catppuccin' }
+    use { 'folke/tokyonight.nvim' }
+    use { 'unblevable/quick-scope'}
+    use { 'neovim/nvim-lspconfig' }
+    use { 'onsails/lspkind.nvim' }
+    use { "williamboman/mason.nvim" } -- lsp installer
+    use
+    {
+        'nvim-treesitter/nvim-treesitter',
+        run = ':TSUpdate'
+    }
+
+    -- complition stuff
+    use { 'hrsh7th/cmp-nvim-lsp' }
+    use { 'hrsh7th/cmp-buffer' }
+    use { 'hrsh7th/cmp-path' }
+    use { 'hrsh7th/cmp-cmdline' }
+    use { 'hrsh7th/nvim-cmp' }
+
+    -- Automatically set up configuration after cloning packer.nvim
+    if packer_bootstrap then
+        require('packer').sync()
+    end
+end)
diff --git a/stow/nvim/.config/nvim/lua/set.lua b/stow/nvim/.config/nvim/lua/set.lua
new file mode 100644 (file)
index 0000000..e2142bd
--- /dev/null
@@ -0,0 +1,52 @@
+vim.opt.backspace = "indent,eol,start"
+vim.opt.lazyredraw = true
+vim.opt.number = true
+vim.opt.relativenumber = true
+vim.opt.scrolloff = 8
+vim.opt.showmatch = true
+vim.opt.expandtab = true
+vim.opt.tabstop = 4
+vim.opt.softtabstop = 4 -- <BS> deletes 4 spacesj
+vim.opt.shiftwidth = 4
+vim.opt.pastetoggle = "<F3>"
+vim.opt.termguicolors = true
+vim.opt.encoding = "utf-8"
+vim.opt.modeline = true
+vim.opt.history = 50
+vim.opt.errorbells = false
+vim.opt.visualbell  = false
+vim.opt.hidden = true
+vim.opt.joinspaces = false
+vim.opt.nrformats = ""
+vim.opt.mouse = "a"
+vim.opt.undofile = true
+vim.opt.wildmode = "longest:full"
+vim.opt.wildmenu = true
+vim.opt.wildignore = "*.pdf,*.fo,"
+vim.opt.title = true
+vim.opt.ruler = true
+vim.opt.showmode = true
+vim.opt.showcmd = true
+vim.opt.laststatus = 2
+vim.opt.hlsearch = true
+vim.opt.incsearch = true
+vim.opt.ignorecase = true
+vim.opt.smartcase = true
+vim.opt.background = "dark"
+vim.opt.autoindent = true
+vim.opt.listchars.tab = "→\\ "
+vim.opt.listchars.trail = "·"
+vim.opt.cursorline = true
+
+vim.opt.signcolumn = "yes"
+vim.opt.colorcolumn = "80"
+
+
+vim.cmd [[
+let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']
+augroup qs_colors
+    autocmd!
+    autocmd ColorScheme * highlight QuickScopePrimary guifg='#afff5f' gui=underline ctermfg=155 cterm=underline
+    autocmd ColorScheme * highlight QuickScopeSecondary guifg='#5fffff' gui=underline ctermfg=81 cterm=underline
+augroup END
+]]
diff --git a/stow/nvim/.config/nvim/lua/theme.lua b/stow/nvim/.config/nvim/lua/theme.lua
new file mode 100644 (file)
index 0000000..3a779d6
--- /dev/null
@@ -0,0 +1,3 @@
+vim.g.catppuccin_flavour = "frappe" -- latte, frappe, macchiato, mocha
+require("catppuccin").setup()
+vim.cmd [[colorscheme catppuccin]]
diff --git a/stow/nvim/.config/nvim/lua/treesitter.lua b/stow/nvim/.config/nvim/lua/treesitter.lua
new file mode 100644 (file)
index 0000000..7c83727
--- /dev/null
@@ -0,0 +1,11 @@
+
+require'nvim-treesitter.configs'.setup {
+--    ensure_installed = "all",
+    sync_install = false,
+
+    highlight = {
+        enable = true,
+        additional_vim_regex_highlighting = false,
+    },
+    indent = { enable = true, },
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.editorconfig b/stow/oh-my-zsh/.oh-my-zsh/.editorconfig
new file mode 100644 (file)
index 0000000..b5321de
--- /dev/null
@@ -0,0 +1,8 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+indent_size = 2
+indent_style = space
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/CODEOWNERS b/stow/oh-my-zsh/.oh-my-zsh/.github/CODEOWNERS
new file mode 100644 (file)
index 0000000..c6b3e8c
--- /dev/null
@@ -0,0 +1,12 @@
+# Plugin owners
+plugins/archlinux/                  @ratijas
+plugins/aws/                        @maksyms
+plugins/genpass/                    @atoponce
+plugins/git-lfs/                    @hellovietduc
+plugins/gitfast/                    @felipec
+plugins/react-native                @esthor
+plugins/sdk/                        @rgoldberg
+plugins/shell-proxy/                @septs
+plugins/universalarchive/           @Konfekt
+plugins/wp-cli/                     @joshmedeski
+plugins/zoxide/                     @ajeetdsouza
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/FUNDING.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/FUNDING.yml
new file mode 100644 (file)
index 0000000..6c86ac4
--- /dev/null
@@ -0,0 +1,2 @@
+github: [ohmyzsh, robbyrussell, mcornella, larson-carter, carlosala]
+open_collective: ohmyzsh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/bug_report.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644 (file)
index 0000000..98f66b1
--- /dev/null
@@ -0,0 +1,68 @@
+name: Report a bug
+description: Report a bug that isn't caused by Oh My Zsh. If unsure, use this form
+body:
+  - type: markdown
+    attributes:
+      value: |
+        ## Self Check
+        - Look for similar errors in existing [GitHub Issues](https://github.com/ohmyzsh/ohmyzsh/issues?q=is%3Aissue) (open or closed).
+        - Try reaching out on the [Discord server](https://discord.gg/ohmyzsh) for help.
+  - type: textarea
+    validations:
+      required: true
+    attributes:
+      label: Describe the bug
+      description: A clear description of what the bug is.
+  - type: textarea
+    validations:
+      required: true
+    attributes:
+      label: Steps to reproduce
+      description: |
+        Steps to reproduce the problem.
+      placeholder: |
+        For example:
+        1. Enable plugin '...'
+        2. Run command '...' or try to complete command '...'
+        3. See error
+  - type: textarea
+    validations:
+      required: true
+    attributes:
+      label: Expected behavior
+      description: A brief description of what should happen.
+  - type: textarea
+    attributes:
+      label: Screenshots and recordings
+      description: |
+        If applicable, add screenshots to help explain your problem. You can also record an asciinema session: https://asciinema.org/
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: OS / Linux distribution
+      placeholder: Windows 10, Ubuntu 20.04, Arch Linux, macOS 10.15...
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: Zsh version
+      description: Run `echo $ZSH_VERSION` to check.
+      placeholder: "5.6"
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: Terminal emulator
+      placeholder: iTerm2, GNOME Terminal, Terminal.app...
+  - type: dropdown
+    attributes:
+      label: If using WSL on Windows, which version of WSL
+      description: Run `wsl -l -v` to check.
+      options:
+        - WSL1
+        - WSL2
+  - type: textarea
+    attributes:
+      label: Additional context
+      description: Add any other context about the problem here. This can be themes, plugins, custom settings...
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/bug_report_omz.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/bug_report_omz.yml
new file mode 100644 (file)
index 0000000..96f5ad9
--- /dev/null
@@ -0,0 +1,77 @@
+name: Report a bug in Oh My Zsh
+description: Create a report to help us improve Oh My Zsh
+labels: ['Bug']
+body:
+  - type: markdown
+    attributes:
+      value: |
+        ## Self Check
+        - **Make sure this bug only happens with Oh My Zsh enabled**.
+        - Look for similar errors in existing [GitHub Issues](https://github.com/ohmyzsh/ohmyzsh/issues?q=is%3Aissue) (open or closed).
+        - Try reaching out on the [Discord server](https://discord.gg/ohmyzsh) for help.
+  - type: textarea
+    validations:
+      required: true
+    attributes:
+      label: Describe the bug
+      description: A clear description of what the bug is.
+  - type: textarea
+    validations:
+      required: true
+    attributes:
+      label: Steps to reproduce
+      description: |
+        Steps to reproduce the problem.
+      placeholder: |
+        For example:
+        1. Enable plugin '...'
+        2. Run command '...' or try to complete command '...'
+        3. See error
+  - type: textarea
+    validations:
+      required: true
+    attributes:
+      label: Expected behavior
+      description: A brief description of what should happen.
+  - type: textarea
+    attributes:
+      label: Screenshots and recordings
+      description: |
+        If applicable, add screenshots to help explain your problem. You can also record an asciinema session: https://asciinema.org/
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: OS / Linux distribution
+      placeholder: Windows 10, Ubuntu 20.04, Arch Linux, macOS 10.15...
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: Zsh version
+      description: Run `echo $ZSH_VERSION` to check.
+      placeholder: "5.6"
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: Oh My Zsh version
+      description: Run `omz version` to check.
+      placeholder: master (bf303965)
+  - type: input
+    validations:
+      required: true
+    attributes:
+      label: Terminal emulator
+      placeholder: iTerm2, GNOME Terminal, Terminal.app...
+  - type: dropdown
+    attributes:
+      label: If using WSL on Windows, which version of WSL
+      description: Run `wsl -l -v` to check.
+      options:
+        - WSL1
+        - WSL2
+  - type: textarea
+    attributes:
+      label: Additional context
+      description: Add any other context about the problem here. This can be themes, plugins, custom settings...
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/config.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644 (file)
index 0000000..3ddd72a
--- /dev/null
@@ -0,0 +1,8 @@
+blank_issues_enabled: true
+contact_links:
+  - name: Support
+    url: https://github.com/ohmyzsh/ohmyzsh/discussions
+    about: Ask the community for support
+  - name: Get help on Discord
+    url: https://discord.gg/ohmyzsh
+    about: Have a quick question? Join the Discord server and ask on the appropriate channel.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/feature_request.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644 (file)
index 0000000..ac966df
--- /dev/null
@@ -0,0 +1,37 @@
+name: Feature request
+description: Suggest a feature for Oh My Zsh
+labels: ["Feature"]
+body:
+  - type: markdown
+    attributes:
+      value: |
+        ## Self Check
+        - Look for similar features in existing [GitHub Issues](https://github.com/ohmyzsh/ohmyzsh/issues?q=is%3Aissue) (open or closed).
+  - type: input
+    attributes:
+      label: If the feature request is for a plugin or theme, specify it here.
+      description: The name of the plugin or theme that you would like us to improve.
+      placeholder: e.g. Git plugin, Agnoster theme
+  - type: textarea
+    attributes:
+      label: If the feature solves a problem you have, specify it here.
+      description: A description of what the problem is. 
+      placeholder: Ex. I'm always frustrated when...
+  - type: textarea
+    attributes:
+      label: Describe the proposed feature.
+      description: A description of what you want to happen. Be as specific as possible.
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: Describe alternatives you've considered
+      description: A description of any alternative solutions or features you've considered. This can also include other plugins or themes.
+  - type: textarea
+    attributes:
+      label: Additional context
+      description: Add any other context, screenshots or Discord conversations about the feature request here. Also if you have any PRs related to this issue that are already open that you would like us to look at.
+  - type: textarea
+    attributes:
+      label: Related Issues
+      description: Is there any open or closed issues that is related to this feature request? If so please link them below!
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/PULL_REQUEST_TEMPLATE.md b/stow/oh-my-zsh/.oh-my-zsh/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644 (file)
index 0000000..5c94cae
--- /dev/null
@@ -0,0 +1,20 @@
+## Standards checklist:
+
+<!-- Fill with an x the ones that apply. Example: [x] -->
+
+- [ ] The PR title is descriptive.
+- [ ] The PR doesn't replicate another PR which is already open.
+- [ ] I have read the contribution guide and followed all the instructions.
+- [ ] The code follows the code style guide detailed in the wiki.
+- [ ] The code is mine or it's from somewhere with an MIT-compatible license.
+- [ ] The code is efficient, to the best of my ability, and does not waste computer resources.
+- [ ] The code is stable and I have tested it myself, to the best of my abilities.
+- [ ] If the code introduces new aliases, I provide a valid use case for all plugin users down below.
+
+## Changes:
+
+- [...]
+
+## Other comments:
+
+...
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/workflows/main.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/workflows/main.yml
new file mode 100644 (file)
index 0000000..57a1e38
--- /dev/null
@@ -0,0 +1,44 @@
+name: CI
+on:
+  pull_request:
+    types:
+      - opened
+      - synchronize
+    branches:
+      - master
+  push:
+    branches: 
+      - master
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
+
+permissions:
+  contents: read # to fetch code (actions/checkout)
+
+jobs:
+  tests:
+    name: Run tests
+    runs-on: ${{ matrix.os }}
+    if: github.repository == 'ohmyzsh/ohmyzsh'
+    strategy:
+      matrix:
+        os: [ubuntu-latest, macos-latest]
+    steps:
+      - name: Set up git repository
+        uses: actions/checkout@v2
+      - name: Install zsh
+        if: runner.os == 'Linux'
+        run: sudo apt-get update; sudo apt-get install zsh
+      - name: Test installer
+        run: sh ./tools/install.sh
+      - name: Check syntax
+        run: |
+          for file in ./oh-my-zsh.sh \
+                      ./lib/*.zsh \
+                      ./plugins/*/*.plugin.zsh \
+                      ./plugins/*/_* \
+                      ./themes/*.zsh-theme; do
+            zsh -n "$file" || return 1
+          done
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.github/workflows/project.yml b/stow/oh-my-zsh/.oh-my-zsh/.github/workflows/project.yml
new file mode 100644 (file)
index 0000000..999cc08
--- /dev/null
@@ -0,0 +1,136 @@
+name: Project tracking
+on:
+  issues:
+    types: [opened, reopened]
+  pull_request_target:
+    types: [opened, reopened, synchronize]
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+  cancel-in-progress: true
+
+permissions: {}
+jobs:
+  add-to-project:
+    name: Add to project
+    runs-on: ubuntu-latest
+    if: github.repository == 'ohmyzsh/ohmyzsh'
+    env:
+      GITHUB_TOKEN: ${{ secrets.PROJECT_TOKEN }}
+    steps:
+      - name: Read project data
+        env:
+          ORGANIZATION: ohmyzsh
+          PROJECT_NUMBER: "1"
+        run: |
+          # Get Project data
+          gh api graphql -f query='
+            query($org: String!, $number: Int!) {
+              organization(login: $org){
+                projectNext(number: $number) {
+                  id
+                  fields(first:20) {
+                    nodes {
+                      id
+                      name
+                    }
+                  }
+                }
+              }
+            }
+          ' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json
+
+          # Parse project data
+          cat >> $GITHUB_ENV <<EOF
+          PROJECT_ID=$(jq '.data.organization.projectNext.id' project_data.json)
+          PLUGIN_FIELD_ID=$(jq '.data.organization.projectNext.fields.nodes[] | select(.name == "Plugin") | .id' project_data.json)
+          THEME_FIELD_ID=$(jq '.data.organization.projectNext.fields.nodes[] | select(.name == "Theme") | .id' project_data.json)
+          EOF
+
+      - name: Add to project
+        env:
+          ISSUE_OR_PR_ID: ${{ github.event.issue.node_id || github.event.pull_request.node_id }}
+        run: |
+          item_id="$(gh api graphql -f query='
+            mutation($project: ID!, $content: ID!) {
+              addProjectNextItem(input: {projectId: $project, contentId: $content}) {
+                projectNextItem {
+                  id
+                }
+              }
+            }
+          ' -f project=$PROJECT_ID -f content=$ISSUE_OR_PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
+
+          echo "ITEM_ID=$item_id" >> $GITHUB_ENV
+
+      - name: Classify Pull Request
+        if: github.event_name == 'pull_request_target'
+        run: |
+          touch plugins.list themes.list
+
+          gh pr view ${{ github.event.pull_request.number }} \
+            --repo ${{ github.repository }} \
+            --json files --jq '.files.[].path' | awk -F/ '
+            /^plugins\// {
+              plugins[$2] = 1
+            }
+            /^themes\// {
+              gsub(/\.zsh-theme$/, "", $2)
+              themes[$2] = 1
+            }
+            END {
+              for (plugin in plugins) {
+                print plugin >> "plugins.list"
+              }
+              for (theme in themes) {
+                print theme >> "themes.list"
+              }
+            }
+          '
+          # If only one plugin is modified, add it to the plugin field
+          if [[ $(wc -l < plugins.list) = 1 ]]; then
+            echo "PLUGIN=$(cat plugins.list)" >> $GITHUB_ENV
+          fi
+          # If only one theme is modified, add it to the theme field
+          if [[ $(wc -l < themes.list) = 1 ]]; then
+            echo "THEME=$(cat themes.list)" >> $GITHUB_ENV
+          fi
+
+      - name: Fill Pull Request fields in project
+        if: github.event_name == 'pull_request_target'
+        run: |
+          gh api graphql -f query='
+            mutation (
+              $project: ID!
+              $item: ID!
+              $plugin_field: ID!
+              $plugin_value: String!
+              $theme_field: ID!
+              $theme_value: String!
+            ) {
+              set_plugin: updateProjectNextItemField(input: {
+                projectId: $project
+                itemId: $item
+                fieldId: $plugin_field
+                value: $plugin_value
+              }) {
+                projectNextItem {
+                  id
+                }
+              }
+              set_theme: updateProjectNextItemField(input: {
+                projectId: $project
+                itemId: $item
+                fieldId: $theme_field
+                value: $theme_value
+              }) {
+                projectNextItem {
+                  id
+                }
+              }
+            }
+          ' -f project=$PROJECT_ID -f item=$ITEM_ID \
+            -f plugin_field=$PLUGIN_FIELD_ID -f plugin_value=$PLUGIN \
+            -f theme_field=$THEME_FIELD_ID -f theme_value=$THEME \
+            --silent
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.gitignore b/stow/oh-my-zsh/.oh-my-zsh/.gitignore
new file mode 100644 (file)
index 0000000..71ae444
--- /dev/null
@@ -0,0 +1,11 @@
+# custom files
+custom/
+
+# temp files directories
+cache/
+log/
+*.swp
+.DS_Store
+
+# editor configs
+.vscode
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.gitpod.Dockerfile b/stow/oh-my-zsh/.oh-my-zsh/.gitpod.Dockerfile
new file mode 100644 (file)
index 0000000..b35c80d
--- /dev/null
@@ -0,0 +1,5 @@
+FROM gitpod/workspace-full
+
+RUN sudo apt-get update && \
+    sudo apt-get install -y zsh && \
+    sudo rm -rf /var/lib/apt/lists/*
diff --git a/stow/oh-my-zsh/.oh-my-zsh/.gitpod.yml b/stow/oh-my-zsh/.oh-my-zsh/.gitpod.yml
new file mode 100644 (file)
index 0000000..ccc5724
--- /dev/null
@@ -0,0 +1,9 @@
+image:
+  file: .gitpod.Dockerfile
+
+tasks:
+  - init: |
+      export EDITOR="command gp open -w" VISUAL="command gp open -w"
+      cp -f /workspace/ohmyzsh/templates/zshrc.zsh-template ~/.zshrc
+      ln -sf /workspace/ohmyzsh ~/.oh-my-zsh
+    command: exec zsh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/CODE_OF_CONDUCT.md b/stow/oh-my-zsh/.oh-my-zsh/CODE_OF_CONDUCT.md
new file mode 100644 (file)
index 0000000..20ad1cc
--- /dev/null
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+  advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+  address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies within all project spaces, and it also applies when
+an individual is representing the project or its community in public spaces.
+Examples of representing a project or community include using an official
+project e-mail address, posting via an official social media account, or acting
+as an appointed representative at an online or offline event. Representation of
+a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at ohmyzsh@planetargon.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/stow/oh-my-zsh/.oh-my-zsh/CONTRIBUTING.md b/stow/oh-my-zsh/.oh-my-zsh/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..e78bd81
--- /dev/null
@@ -0,0 +1,245 @@
+# CONTRIBUTING GUIDELINES
+
+Oh-My-Zsh is a community-driven project. Contribution is welcome, encouraged, and appreciated.
+It is also essential for the development of the project.
+
+First, please take a moment to review our [code of conduct](CODE_OF_CONDUCT.md).
+
+These guidelines are an attempt at better addressing the huge amount of pending
+issues and pull requests. Please read them closely.
+
+Foremost, be so kind as to [search](#use-the-search-luke). This ensures any contribution
+you would make is not already covered.
+
+<!-- TOC updateonsave:true depthfrom:2 -->
+
+- [Reporting Issues](#reporting-issues)
+  - [You have a problem](#you-have-a-problem)
+  - [You have a suggestion](#you-have-a-suggestion)
+- [Submitting Pull Requests](#submitting-pull-requests)
+  - [Getting started](#getting-started)
+  - [You have a solution](#you-have-a-solution)
+  - [You have an addition](#you-have-an-addition)
+- [Use the Search, Luke](#use-the-search-luke)
+- [Commit Guidelines](#commit-guidelines)
+  - [Format](#format)
+  - [Style](#style)
+- [Volunteer](#volunteer)
+
+<!-- /TOC -->
+
+## Reporting Issues
+
+### You have a problem
+
+Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
+your problem.
+
+If you find one, comment on it so we can know there are more people experiencing it.
+
+If not, look at the [Troubleshooting](https://github.com/ohmyzsh/ohmyzsh/wiki/Troubleshooting)
+page for instructions on how to gather data to better debug your problem.
+
+Then, you can go ahead and create an issue with as much detail as you can provide.
+It should include the data gathered as indicated above, along with:
+
+1. How to reproduce the problem
+2. What the correct behavior should be
+3. What the actual behavior is
+
+Please copy to anyone relevant (e.g. plugin maintainers) by mentioning their GitHub handle
+(starting with `@`) in your message.
+
+We will do our very best to help you.
+
+### You have a suggestion
+
+Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
+your suggestion.
+
+If you find one, comment on it so we can know there are more people supporting it.
+
+If not, you can go ahead and create an issue. Please copy to anyone relevant (e.g. plugin
+maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
+
+## Submitting Pull Requests
+
+### Getting started
+
+You should be familiar with the basics of
+[contributing on GitHub](https://help.github.com/articles/using-pull-requests) and have a fork
+[properly set up](https://github.com/ohmyzsh/ohmyzsh/wiki/Contribution-Technical-Practices).
+
+You MUST always create PRs with _a dedicated branch_ based on the latest upstream tree.
+
+If you create your own PR, please make sure you do it right. Also be so kind as to reference
+any issue that would be solved in the PR description body,
+[for instance](https://help.github.com/articles/closing-issues-via-commit-messages/)
+_"Fixes #XXXX"_ for issue number XXXX.
+
+### You have a solution
+
+Please be so kind as to [search](#use-the-search-luke) for any open issue already covering
+your [problem](#you-have-a-problem), and any pending/merged/rejected PR covering your solution.
+
+If the solution is already reported, try it out and +1 the pull request if the
+solution works ok. On the other hand, if you think your solution is better, post
+it with a reference to the other one so we can have both solutions to compare.
+
+If not, then go ahead and submit a PR. Please copy to anyone relevant (e.g. plugin
+maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
+
+### You have an addition
+
+Please [do not](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#dont-send-us-your-theme-for-now)
+send themes for now.
+
+Please be so kind as to [search](#use-the-search-luke) for any pending, merged or rejected Pull Requests
+covering or related to what you want to add.
+
+If you find one, try it out and work with the author on a common solution.
+
+If not, then go ahead and submit a PR. Please copy to anyone relevant (e.g. plugin
+maintainers) by mentioning their GitHub handle (starting with `@`) in your message.
+
+For any extensive change, such as a new plugin, you will have to find testers to +1 your PR.
+
+### New plugin aliases
+
+We acknowledge that aliases are a core part of Oh My Zsh. There are plugins that have +100 aliases!
+
+This has become an issue for two opposing reasons:
+
+- Some users want to have their personal aliases in Oh My Zsh.
+- Some users don't want any aliases at all and feel that there are too many.
+
+Because of this, from now on we're requiring that new aliases follow these conditions:
+
+1. They will be used by many people, not just a few.
+2. The aliases will be used many times and for common tasks.
+3. Prefer one generic alias over many specific ones.
+4. When justifying the need for an alias, talk about workflows where you'll use it,
+   preferably in combination with other aliases.
+5. If there exists a command with the same name, look for a different alias name.
+
+This list is not exhaustive! Please remember that your alias will be in the machines of many people,
+so it should be justified why they should have it.
+
+----
+
+## Use the Search, Luke
+
+_May the Force (of past experiences) be with you_
+
+GitHub offers [many search features](https://help.github.com/articles/searching-github/)
+to help you check whether a similar contribution to yours already exists. Please search
+before making any contribution, it avoids duplicates and eases maintenance. Trust me,
+that works 90% of the time.
+
+You can also take a look at the [FAQ](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ)
+to be sure your contribution has not already come up.
+
+If all fails, your thing has probably not been reported yet, so you can go ahead
+and [create an issue](#reporting-issues) or [submit a PR](#submitting-pull-requests).
+
+----
+
+## Commit Guidelines
+
+Oh My Zsh uses the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
+specification. The automatic changelog tool uses these to automatically generate
+a changelog based on the commit messages. Here's a guide to writing a commit message
+to allow this:
+
+### Format
+
+```
+type(scope)!: subject
+```
+
+- `type`: the type of the commit is one of the following:
+
+  - `feat`: new features.
+  - `fix`: bug fixes.
+  - `docs`: documentation changes.
+  - `refactor`: refactor of a particular code section without introducing
+    new features or bug fixes.
+  - `style`: code style improvements.
+  - `perf`: performance improvements.
+  - `test`: changes to the test suite.
+  - `ci`: changes to the CI system.
+  - `build`: changes to the build system (we don't yet have one so this shouldn't apply).
+  - `chore`: for other changes that don't match previous types. This doesn't appear
+    in the changelog.
+
+- `scope`: section of the codebase that the commit makes changes to. If it makes changes to
+  many sections, or if no section in particular is modified, leave blank without the parentheses.
+  Examples:
+
+  - Commit that changes the `git` plugin:
+  ```
+  feat(git): add alias for `git commit`
+  ```
+
+  - Commit that changes many plugins:
+  ```
+  style: fix inline declaration of arrays
+  ```
+
+  For changes to plugins or themes, the scope should be the plugin or theme name:
+
+  - ✅ `fix(agnoster): commit subject`
+  - ❌ `fix(theme/agnoster): commit subject`
+
+- `!`: this goes after the `scope` (or the `type` if scope is empty), to indicate that the commit
+  introduces breaking changes.
+
+  Optionally, you can specify a message that the changelog tool will display to the user to indicate
+  what's changed and what they can do to deal with it. You can use multiple lines to type this message;
+  the changelog parser will keep reading until the end of the commit message or until it finds an empty
+  line.
+
+  Example (made up):
+
+  ```
+  style(agnoster)!: change dirty git repo glyph
+
+  BREAKING CHANGE: the glyph to indicate when a git repository is dirty has
+  changed from a Powerline character to a standard UTF-8 emoji. You can
+  change it back by setting `ZSH_THEME_DIRTY_GLYPH`.
+
+  Fixes #420
+
+  Co-authored-by: Username <email>
+  ```
+
+- `subject`: a brief description of the changes. This will be displayed in the changelog. If you need
+  to specify other details you can use the commit body but it won't be visible.
+
+  Formatting tricks: the commit subject may contain:
+
+  - Links to related issues or PRs by writing `#issue`. This will be highlighted by the changelog tool:
+    ```
+    feat(archlinux): add support for aura AUR helper (#9467)
+    ```
+
+  - Formatted inline code by using backticks: the text between backticks will also be highlighted by
+    the changelog tool:
+    ```
+    feat(shell-proxy): enable unexported `DEFAULT_PROXY` setting (#9774)
+    ```
+
+### Style
+
+Try to keep the first commit line short. This is harder to do using this commit style but try to be
+concise and if you need more space, you can use the commit body. Try to make sure that the commit
+subject is clear and precise enough that users will know what changed by just looking at the changelog.
+
+----
+
+## Volunteer
+
+Very nice!! :)
+
+Please have a look at the [Volunteer](https://github.com/ohmyzsh/ohmyzsh/wiki/Volunteers)
+page for instructions on where to start and more.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/LICENSE.txt b/stow/oh-my-zsh/.oh-my-zsh/LICENSE.txt
new file mode 100644 (file)
index 0000000..2d7ca6f
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2009-2022 Robby Russell and contributors (https://github.com/ohmyzsh/ohmyzsh/contributors)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/README.md b/stow/oh-my-zsh/.oh-my-zsh/README.md
new file mode 100644 (file)
index 0000000..1e4b7ff
--- /dev/null
@@ -0,0 +1,367 @@
+<p align="center"><img src="https://ohmyzsh.s3.amazonaws.com/omz-ansi-github.png" alt="Oh My Zsh"></p>
+
+Oh My Zsh is an open source, community-driven framework for managing your [zsh](https://www.zsh.org/) configuration.
+
+Sounds boring. Let's try again.
+
+**Oh My Zsh will not make you a 10x developer...but you may feel like one.**
+
+Once installed, your terminal shell will become the talk of the town _or your money back!_ With each keystroke in your command prompt, you'll take advantage of the hundreds of powerful plugins and beautiful themes. Strangers will come up to you in cafés and ask you, _"that is amazing! are you some sort of genius?"_
+
+Finally, you'll begin to get the sort of attention that you have always felt you deserved. ...or maybe you'll use the time that you're saving to start flossing more often. 😬
+
+To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://twitter.com/ohmyzsh) on Twitter, and join us on [Discord](https://discord.gg/ohmyzsh).
+
+[![CI](https://github.com/ohmyzsh/ohmyzsh/workflows/CI/badge.svg)](https://github.com/ohmyzsh/ohmyzsh/actions?query=workflow%3ACI)
+[![Follow @ohmyzsh](https://img.shields.io/twitter/follow/ohmyzsh?label=Follow+@ohmyzsh&style=flat)](https://twitter.com/intent/follow?screen_name=ohmyzsh)
+[![Discord server](https://img.shields.io/discord/642496866407284746)](https://discord.gg/ohmyzsh)
+[![Gitpod ready](https://img.shields.io/badge/Gitpod-ready-blue?logo=gitpod)](https://gitpod.io/#https://github.com/ohmyzsh/ohmyzsh)
+[![huntr.dev](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev/bounties/disclose/?utm_campaign=ohmyzsh%2Fohmyzsh&utm_medium=social&utm_source=github&target=https%3A%2F%2Fgithub.com%2Fohmyzsh%2Fohmyzsh)
+
+<details>
+<summary>Table of Contents</summary>
+
+- [Getting Started](#getting-started)
+  - [Prerequisites](#prerequisites)
+  - [Basic Installation](#basic-installation)
+    - [Manual inspection](#manual-inspection)
+- [Using Oh My Zsh](#using-oh-my-zsh)
+  - [Plugins](#plugins)
+    - [Enabling Plugins](#enabling-plugins)
+    - [Using Plugins](#using-plugins)
+  - [Themes](#themes)
+    - [Selecting a Theme](#selecting-a-theme)
+  - [FAQ](#faq)
+- [Advanced Topics](#advanced-topics)
+  - [Advanced Installation](#advanced-installation)
+    - [Custom Directory](#custom-directory)
+    - [Unattended install](#unattended-install)
+    - [Installing from a forked repository](#installing-from-a-forked-repository)
+    - [Manual Installation](#manual-installation)
+  - [Installation Problems](#installation-problems)
+  - [Custom Plugins and Themes](#custom-plugins-and-themes)
+- [Getting Updates](#getting-updates)
+  - [Manual Updates](#manual-updates)
+- [Uninstalling Oh My Zsh](#uninstalling-oh-my-zsh)
+- [How do I contribute to Oh My Zsh?](#how-do-i-contribute-to-oh-my-zsh)
+  - [Do NOT send us themes](#do-not-send-us-themes)
+- [Contributors](#contributors)
+- [Follow Us](#follow-us)
+- [Merchandise](#merchandise)
+- [License](#license)
+- [About Planet Argon](#about-planet-argon)
+
+</details>
+
+## Getting Started
+
+### Prerequisites
+
+- A Unix-like operating system: macOS, Linux, BSD. On Windows: WSL2 is preferred, but cygwin or msys also mostly work.
+- [Zsh](https://www.zsh.org) should be installed (v4.3.9 or more recent is fine but we prefer 5.0.8 and newer). If not pre-installed (run `zsh --version` to confirm), check the following wiki instructions here: [Installing ZSH](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)
+- `curl` or `wget` should be installed
+- `git` should be installed (recommended v2.4.11 or higher)
+
+### Basic Installation
+
+Oh My Zsh is installed by running one of the following commands in your terminal. You can install this via the command-line with either `curl`, `wget` or another similar tool.
+
+| Method    | Command                                                                                           |
+| :-------- | :------------------------------------------------------------------------------------------------ |
+| **curl**  | `sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
+| **wget**  | `sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"`   |
+| **fetch** | `sh -c "$(fetch -o - https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
+
+_Note that any previous `.zshrc` will be renamed to `.zshrc.pre-oh-my-zsh`. After installation, you can move the configuration you want to preserve into the new `.zshrc`._
+
+#### Manual inspection
+
+It's a good idea to inspect the install script from projects you don't yet know. You can do
+that by downloading the install script first, looking through it so everything looks normal,
+then running it:
+
+```sh
+wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
+sh install.sh
+```
+
+## Using Oh My Zsh
+
+### Plugins
+
+Oh My Zsh comes with a shitload of plugins for you to take advantage of. You can take a look in the [plugins](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins) directory and/or the [wiki](https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins) to see what's currently available.
+
+#### Enabling Plugins
+
+Once you spot a plugin (or several) that you'd like to use with Oh My Zsh, you'll need to enable them in the `.zshrc` file. You'll find the zshrc file in your `$HOME` directory. Open it with your favorite text editor and you'll see a spot to list all the plugins you want to load.
+
+```sh
+vi ~/.zshrc
+```
+
+For example, this might begin to look like this:
+
+```sh
+plugins=(
+  git
+  bundler
+  dotenv
+  macos
+  rake
+  rbenv
+  ruby
+)
+```
+
+_Note that the plugins are separated by whitespace (spaces, tabs, new lines...). **Do not** use commas between them or it will break._
+
+#### Using Plugins
+
+Each built-in plugin includes a **README**, documenting it. This README should show the aliases (if the plugin adds any) and extra goodies that are included in that particular plugin.
+
+### Themes
+
+We'll admit it. Early in the Oh My Zsh world, we may have gotten a bit too theme happy. We have over one hundred and fifty themes now bundled. Most of them have [screenshots](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes) on the wiki (We are working on updating this!). Check them out!
+
+#### Selecting a Theme
+
+_Robby's theme is the default one. It's not the fanciest one. It's not the simplest one. It's just the right one (for him)._
+
+Once you find a theme that you'd like to use, you will need to edit the `~/.zshrc` file. You'll see an environment variable (all caps) in there that looks like:
+
+```sh
+ZSH_THEME="robbyrussell"
+```
+
+To use a different theme, simply change the value to match the name of your desired theme. For example:
+
+```sh
+ZSH_THEME="agnoster" # (this is one of the fancy ones)
+# see https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#agnoster
+```
+
+_Note: many themes require installing a [Powerline Font](https://github.com/powerline/fonts) or a [Nerd Font](https://github.com/ryanoasis/nerd-fonts) in order to render properly. Without them, these themes will render [weird prompt symbols](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#i-have-a-weird-character-in-my-prompt)_
+
+Open up a new terminal window and your prompt should look something like this:
+
+![Agnoster theme](https://cloud.githubusercontent.com/assets/2618447/6316862/70f58fb6-ba03-11e4-82c9-c083bf9a6574.png)
+
+In case you did not find a suitable theme for your needs, please have a look at the wiki for [more of them](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes).
+
+If you're feeling feisty, you can let the computer select one randomly for you each time you open a new terminal window.
+
+```sh
+ZSH_THEME="random" # (...please let it be pie... please be some pie..)
+```
+
+And if you want to pick random theme from a list of your favorite themes:
+
+```sh
+ZSH_THEME_RANDOM_CANDIDATES=(
+  "robbyrussell"
+  "agnoster"
+)
+```
+
+If you only know which themes you don't like, you can add them similarly to an ignored list:
+
+```sh
+ZSH_THEME_RANDOM_IGNORED=(pygmalion tjkirch_mod)
+```
+
+### FAQ
+
+If you have some more questions or issues, you might find a solution in our [FAQ](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ).
+
+## Advanced Topics
+
+If you're the type that likes to get their hands dirty, these sections might resonate.
+
+### Advanced Installation
+
+Some users may want to manually install Oh My Zsh, or change the default path or other settings that
+the installer accepts (these settings are also documented at the top of the install script).
+
+#### Custom Directory
+
+The default location is `~/.oh-my-zsh` (hidden in your home directory, you can access it with `cd ~/.oh-my-zsh`)
+
+If you'd like to change the install directory with the `ZSH` environment variable, either by running
+`export ZSH=/your/path` before installing, or by setting it before the end of the install pipeline
+like this:
+
+```sh
+ZSH="$HOME/.dotfiles/oh-my-zsh" sh install.sh
+```
+
+#### Unattended install
+
+If you're running the Oh My Zsh install script as part of an automated install, you can pass the `--unattended`
+flag to the `install.sh` script. This will have the effect of not trying to change
+the default shell, and it also won't run `zsh` when the installation has finished.
+
+```sh
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
+```
+
+#### Installing from a forked repository
+
+The install script also accepts these variables to allow installation of a different repository:
+
+- `REPO` (default: `ohmyzsh/ohmyzsh`): this takes the form of `owner/repository`. If you set
+  this variable, the installer will look for a repository at `https://github.com/{owner}/{repository}`.
+
+- `REMOTE` (default: `https://github.com/${REPO}.git`): this is the full URL of the git repository
+  clone. You can use this setting if you want to install from a fork that is not on GitHub (GitLab,
+  Bitbucket...) or if you want to clone with SSH instead of HTTPS (`git@github.com:user/project.git`).
+
+  _NOTE: it's incompatible with setting the `REPO` variable. This setting will take precedence._
+
+- `BRANCH` (default: `master`): you can use this setting if you want to change the default branch to be
+  checked out when cloning the repository. This might be useful for testing a Pull Request, or if you
+  want to use a branch other than `master`.
+
+For example:
+
+```sh
+REPO=apjanke/oh-my-zsh BRANCH=edge sh install.sh
+```
+
+#### Manual Installation
+
+##### 1. Clone the repository <!-- omit in toc -->
+
+```sh
+git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh
+```
+
+##### 2. _Optionally_, backup your existing `~/.zshrc` file <!-- omit in toc -->
+
+```sh
+cp ~/.zshrc ~/.zshrc.orig
+```
+
+##### 3. Create a new zsh configuration file <!-- omit in toc -->
+
+You can create a new zsh config file by copying the template that we have included for you.
+
+```sh
+cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
+```
+
+##### 4. Change your default shell <!-- omit in toc -->
+
+```sh
+chsh -s $(which zsh)
+```
+
+You must log out from your user session and log back in to see this change.
+
+##### 5. Initialize your new zsh configuration <!-- omit in toc -->
+
+Once you open up a new terminal window, it should load zsh with Oh My Zsh's configuration.
+
+### Installation Problems
+
+If you have any hiccups installing, here are a few common fixes.
+
+- You _might_ need to modify your `PATH` in `~/.zshrc` if you're not able to find some commands after switching to `oh-my-zsh`.
+- If you installed manually or changed the install location, check the `ZSH` environment variable in `~/.zshrc`.
+
+### Custom Plugins and Themes
+
+If you want to override any of the default behaviors, just add a new file (ending in `.zsh`) in the `custom/` directory.
+
+If you have many functions that go well together, you can put them as a `XYZ.plugin.zsh` file in the `custom/plugins/` directory and then enable this plugin.
+
+If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
+
+## Getting Updates
+
+By default, you will be prompted to check for updates every 2 weeks. You can choose other update modes by adding a line to your `~/.zshrc` file, **before Oh My Zsh is loaded**:
+
+1. Automatic update without confirmation prompt:
+
+   ```sh
+   zstyle ':omz:update' mode auto
+   ```
+
+2. Just offer a reminder every few days, if there are updates available:
+
+   ```sh
+   zstyle ':omz:update' mode reminder
+   ```
+
+3. To disable automatic updates entirely:
+
+   ```sh
+   zstyle ':omz:update' mode disabled
+   ```
+
+NOTE: you can control how often Oh My Zsh checks for updates with the following setting:
+
+```sh
+# This will check for updates every 7 days
+zstyle ':omz:update' frequency 7
+# This will check for updates every time you open the terminal (not recommended)
+zstyle ':omz:update' frequency 0
+```
+
+### Manual Updates
+
+If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to wait a week?) you just need to run:
+
+```sh
+omz update
+```
+
+Magic! 🎉
+
+## Uninstalling Oh My Zsh
+
+Oh My Zsh isn't for everyone. We'll miss you, but we want to make this an easy breakup.
+
+If you want to uninstall `oh-my-zsh`, just run `uninstall_oh_my_zsh` from the command-line. It will remove itself and revert your previous `bash` or `zsh` configuration.
+
+## How do I contribute to Oh My Zsh?
+
+Before you participate in our delightful community, please read the [code of conduct](CODE_OF_CONDUCT.md).
+
+I'm far from being a [Zsh](https://www.zsh.org/) expert and suspect there are many ways to improve – if you have ideas on how to make the configuration easier to maintain (and faster), don't hesitate to fork and send pull requests!
+
+We also need people to test out pull requests. So take a look through [the open issues](https://github.com/ohmyzsh/ohmyzsh/issues) and help where you can.
+
+See [Contributing](CONTRIBUTING.md) for more details.
+
+### Do NOT send us themes
+
+We have (more than) enough themes for the time being. Please add your theme to the [external themes](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes) wiki page.
+
+## Contributors
+
+Oh My Zsh has a vibrant community of happy users and delightful contributors. Without all the time and help from our contributors, it wouldn't be so awesome.
+
+Thank you so much!
+
+## Follow Us
+
+We're on social media:
+
+- [@ohmyzsh](https://twitter.com/ohmyzsh) on Twitter. You should follow it.
+- [Facebook](https://www.facebook.com/Oh-My-Zsh-296616263819290/) poke us.
+- [Instagram](https://www.instagram.com/_ohmyzsh/) tag us in your post showing Oh My Zsh!
+- [Discord](https://discord.gg/ohmyzsh) to chat with us!
+
+## Merchandise
+
+We have [stickers, shirts, and coffee mugs available](https://shop.planetargon.com/collections/oh-my-zsh?utm_source=github) for you to show off your love of Oh My Zsh. Again, you will become the talk of the town!
+
+## License
+
+Oh My Zsh is released under the [MIT license](LICENSE.txt).
+
+## About Planet Argon
+
+![Planet Argon](https://pa-github-assets.s3.amazonaws.com/PARGON_logo_digital_COL-small.jpg)
+
+Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a [Ruby on Rails development agency](https://www.planetargon.com/skills/ruby-on-rails-development?utm_source=github). Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/SECURITY.md b/stow/oh-my-zsh/.oh-my-zsh/SECURITY.md
new file mode 100644 (file)
index 0000000..7e5c8ee
--- /dev/null
@@ -0,0 +1,24 @@
+# Security Policy
+
+## Supported Versions
+
+At the moment Oh My Zsh only considers the very latest commit to be supported.
+We combine that with our fast response to incidents and the automated updates
+to minimize the time between vulnerability publication and patch release.
+
+| Version        | Supported          |
+|:-------------- |:------------------ |
+| master         | :white_check_mark: |
+| other commits  | :x:                |
+
+In the near future we will introduce versioning, so expect this section to change.
+
+## Reporting a Vulnerability
+
+**Do not submit an issue or pull request**: this might reveal the vulnerability.
+
+Instead, you should email the maintainers directly at: [**security@ohmyz.sh**](mailto:security@ohmyz.sh).
+
+We will deal with the vulnerability privately and submit a patch as soon as possible.
+
+You can also submit your vulnerability report to [huntr.dev](https://huntr.dev/bounties/disclose/?utm_campaign=ohmyzsh%2Fohmyzsh&utm_medium=social&utm_source=github&target=https%3A%2F%2Fgithub.com%2Fohmyzsh%2Fohmyzsh) and see if you can get a bounty reward.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/bzr.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/bzr.zsh
new file mode 100644 (file)
index 0000000..005a165
--- /dev/null
@@ -0,0 +1,10 @@
+## Bazaar integration
+## Just works with the GIT integration just add $(bzr_prompt_info) to the PROMPT
+function bzr_prompt_info() {
+       BZR_CB=`bzr nick 2> /dev/null | grep -v "ERROR" | cut -d ":" -f2 | awk -F / '{print "bzr::"$1}'`
+       if [ -n "$BZR_CB" ]; then
+               BZR_DIRTY=""
+               [[ -n `bzr status` ]] && BZR_DIRTY=" %{$fg[red]%} * %{$fg[green]%}"
+               echo "$ZSH_THEME_SCM_PROMPT_PREFIX$BZR_CB$BZR_DIRTY$ZSH_THEME_GIT_PROMPT_SUFFIX"
+       fi
+}
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/cli.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/cli.zsh
new file mode 100644 (file)
index 0000000..fed00d2
--- /dev/null
@@ -0,0 +1,820 @@
+#!/usr/bin/env zsh
+
+function omz {
+  [[ $# -gt 0 ]] || {
+    _omz::help
+    return 1
+  }
+
+  local command="$1"
+  shift
+
+  # Subcommand functions start with _ so that they don't
+  # appear as completion entries when looking for `omz`
+  (( $+functions[_omz::$command] )) || {
+    _omz::help
+    return 1
+  }
+
+  _omz::$command "$@"
+}
+
+function _omz {
+  local -a cmds subcmds
+  cmds=(
+    'changelog:Print the changelog'
+    'help:Usage information'
+    'plugin:Manage plugins'
+    'pr:Manage Oh My Zsh Pull Requests'
+    'reload:Reload the current zsh session'
+    'theme:Manage themes'
+    'update:Update Oh My Zsh'
+    'version:Show the version'
+  )
+
+  if (( CURRENT == 2 )); then
+    _describe 'command' cmds
+  elif (( CURRENT == 3 )); then
+    case "$words[2]" in
+      changelog) local -a refs
+        refs=("${(@f)$(builtin cd -q "$ZSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}")
+        _describe 'command' refs ;;
+      plugin) subcmds=(
+        'disable:Disable plugin(s)'
+        'enable:Enable plugin(s)'
+        'info:Get plugin information'
+        'list:List plugins'
+        'load:Load plugin(s)'
+      )
+        _describe 'command' subcmds ;;
+      pr) subcmds=('clean:Delete all Pull Request branches' 'test:Test a Pull Request')
+        _describe 'command' subcmds ;;
+      theme) subcmds=('list:List themes' 'set:Set a theme in your .zshrc file' 'use:Load a theme')
+        _describe 'command' subcmds ;;
+    esac
+  elif (( CURRENT == 4 )); then
+    case "${words[2]}::${words[3]}" in
+      plugin::(disable|enable|load))
+        local -aU valid_plugins
+
+        if [[ "${words[3]}" = disable ]]; then
+          # if command is "disable", only offer already enabled plugins
+          valid_plugins=($plugins)
+        else
+          valid_plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t))
+          # if command is "enable", remove already enabled plugins
+          [[ "${words[3]}" = enable ]] && valid_plugins=(${valid_plugins:|plugins})
+        fi
+
+        _describe 'plugin' valid_plugins ;;
+      plugin::info)
+        local -aU plugins
+        plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t))
+        _describe 'plugin' plugins ;;
+      theme::(set|use))
+        local -aU themes
+        themes=("$ZSH"/themes/*.zsh-theme(-.N:t:r) "$ZSH_CUSTOM"/**/*.zsh-theme(-.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::))
+        _describe 'theme' themes ;;
+    esac
+  elif (( CURRENT > 4 )); then
+    case "${words[2]}::${words[3]}" in
+      plugin::(enable|disable|load))
+        local -aU valid_plugins
+
+        if [[ "${words[3]}" = disable ]]; then
+          # if command is "disable", only offer already enabled plugins
+          valid_plugins=($plugins)
+        else
+          valid_plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t))
+          # if command is "enable", remove already enabled plugins
+          [[ "${words[3]}" = enable ]] && valid_plugins=(${valid_plugins:|plugins})
+        fi
+
+        # Remove plugins already passed as arguments
+        # NOTE: $(( CURRENT - 1 )) is the last plugin argument completely passed, i.e. that which
+        # has a space after them. This is to avoid removing plugins partially passed, which makes
+        # the completion not add a space after the completed plugin.
+        local -a args
+        args=(${words[4,$(( CURRENT - 1))]})
+        valid_plugins=(${valid_plugins:|args})
+
+        _describe 'plugin' valid_plugins ;;
+    esac
+  fi
+
+  return 0
+}
+
+# If run from a script, do not set the completion function
+if (( ${+functions[compdef]} )); then
+  compdef _omz omz
+fi
+
+## Utility functions
+
+function _omz::confirm {
+  # If question supplied, ask it before reading the answer
+  # NOTE: uses the logname of the caller function
+  if [[ -n "$1" ]]; then
+    _omz::log prompt "$1" "${${functrace[1]#_}%:*}"
+  fi
+
+  # Read one character
+  read -r -k 1
+
+  # If no newline entered, add a newline
+  if [[ "$REPLY" != $'\n' ]]; then
+    echo
+  fi
+}
+
+function _omz::log {
+  # if promptsubst is set, a message with `` or $()
+  # will be run even if quoted due to `print -P`
+  setopt localoptions nopromptsubst
+
+  # $1 = info|warn|error|debug
+  # $2 = text
+  # $3 = (optional) name of the logger
+
+  local logtype=$1
+  local logname=${3:-${${functrace[1]#_}%:*}}
+
+  # Don't print anything if debug is not active
+  if [[ $logtype = debug && -z $_OMZ_DEBUG ]]; then
+    return
+  fi
+
+  # Choose coloring based on log type
+  case "$logtype" in
+    prompt) print -Pn "%S%F{blue}$logname%f%s: $2" ;;
+    debug) print -P "%F{white}$logname%f: $2" ;;
+    info) print -P "%F{green}$logname%f: $2" ;;
+    warn) print -P "%S%F{yellow}$logname%f%s: $2" ;;
+    error) print -P "%S%F{red}$logname%f%s: $2" ;;
+  esac >&2
+}
+
+## User-facing commands
+
+function _omz::help {
+  cat >&2 <<EOF
+Usage: omz <command> [options]
+
+Available commands:
+
+  help                Print this help message
+  changelog           Print the changelog
+  plugin <command>    Manage plugins
+  pr     <command>    Manage Oh My Zsh Pull Requests
+  reload              Reload the current zsh session
+  theme  <command>    Manage themes
+  update              Update Oh My Zsh
+  version             Show the version
+
+EOF
+}
+
+function _omz::changelog {
+  local version=${1:-HEAD} format=${3:-"--text"}
+
+  if (
+    builtin cd -q "$ZSH"
+    ! command git show-ref --verify refs/heads/$version && \
+    ! command git show-ref --verify refs/tags/$version && \
+    ! command git rev-parse --verify "${version}^{commit}"
+  ) &>/dev/null; then
+    cat >&2 <<EOF
+Usage: ${(j: :)${(s.::.)0#_}} [version]
+
+NOTE: <version> must be a valid branch, tag or commit.
+EOF
+    return 1
+  fi
+
+  "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
+}
+
+function _omz::plugin {
+  (( $# > 0 && $+functions[$0::$1] )) || {
+    cat >&2 <<EOF
+Usage: ${(j: :)${(s.::.)0#_}} <command> [options]
+
+Available commands:
+
+  disable <plugin> Disable plugin(s)
+  enable <plugin>  Enable plugin(s)
+  info <plugin>    Get information of a plugin
+  list             List all available Oh My Zsh plugins
+  load <plugin>    Load plugin(s)
+
+EOF
+    return 1
+  }
+
+  local command="$1"
+  shift
+
+  $0::$command "$@"
+}
+
+function _omz::plugin::disable {
+  if [[ -z "$1" ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <plugin> [...]"
+    return 1
+  fi
+
+  # Check that plugin is in $plugins
+  local -a dis_plugins
+  for plugin in "$@"; do
+    if [[ ${plugins[(Ie)$plugin]} -eq 0 ]]; then
+      _omz::log warn "plugin '$plugin' is not enabled."
+      continue
+    fi
+    dis_plugins+=("$plugin")
+  done
+
+  # Exit if there are no enabled plugins to disable
+  if [[ ${#dis_plugins} -eq 0 ]]; then
+    return 1
+  fi
+
+  # Remove plugins substitution awk script
+  local awk_subst_plugins="\
+  gsub(/[ \t]+(${(j:|:)dis_plugins})/, \"\") # with spaces before
+  gsub(/(${(j:|:)dis_plugins})[ \t]+/, \"\") # with spaces after
+  gsub(/\((${(j:|:)dis_plugins})\)/, \"\") # without spaces (only plugin)
+"
+  # Disable plugins awk script
+  local awk_script="
+# if plugins=() is in oneline form, substitute disabled plugins and go to next line
+/^[ \t]*plugins=\([^#]+\).*\$/ {
+  $awk_subst_plugins
+  print \$0
+  next
+}
+
+# if plugins=() is in multiline form, enable multi flag and disable plugins if they're there
+/^[ \t]*plugins=\(/ {
+  multi=1
+  $awk_subst_plugins
+  print \$0
+  next
+}
+
+# if multi flag is enabled and we find a valid closing parenthesis, remove plugins and disable multi flag
+multi == 1 && /^[^#]*\)/ {
+  multi=0
+  $awk_subst_plugins
+  print \$0
+  next
+}
+
+multi == 1 && length(\$0) > 0 {
+  $awk_subst_plugins
+  if (length(\$0) > 0) print \$0
+  next
+}
+
+{ print \$0 }
+"
+
+  local zdot="${ZDOTDIR:-$HOME}"
+  local zshrc="${${:-"${zdot}/.zshrc"}:A}"
+  awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \
+  && command cp -f "$zshrc" "$zdot/.zshrc.bck" \
+  && command mv -f "$zdot/.zshrc.new" "$zshrc"
+
+  # Exit if the new .zshrc file wasn't created correctly
+  [[ $? -eq 0 ]] || {
+    local ret=$?
+    _omz::log error "error disabling plugins."
+    return $ret
+  }
+
+  # Exit if the new .zshrc file has syntax errors
+  if ! command zsh -n "$zdot/.zshrc"; then
+    _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
+    command mv -f "$zdot/.zshrc.bck" "$zshrc"
+    return 1
+  fi
+
+  # Restart the zsh session if there were no errors
+  _omz::log info "plugins disabled: ${(j:, :)dis_plugins}."
+
+  # Only reload zsh if run in an interactive session
+  [[ ! -o interactive ]] || _omz::reload
+}
+
+function _omz::plugin::enable {
+  if [[ -z "$1" ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <plugin> [...]"
+    return 1
+  fi
+
+  # Check that plugin is not in $plugins
+  local -a add_plugins
+  for plugin in "$@"; do
+    if [[ ${plugins[(Ie)$plugin]} -ne 0 ]]; then
+      _omz::log warn "plugin '$plugin' is already enabled."
+      continue
+    fi
+    add_plugins+=("$plugin")
+  done
+
+  # Exit if there are no plugins to enable
+  if [[ ${#add_plugins} -eq 0 ]]; then
+    return 1
+  fi
+
+  # Enable plugins awk script
+  local awk_script="
+# if plugins=() is in oneline form, substitute ) with new plugins and go to the next line
+/^[ \t]*plugins=\([^#]+\).*\$/ {
+  sub(/\)/, \" $add_plugins&\")
+  print \$0
+  next
+}
+
+# if plugins=() is in multiline form, enable multi flag
+/^[ \t]*plugins=\(/ {
+  multi=1
+}
+
+# if multi flag is enabled and we find a valid closing parenthesis,
+# add new plugins and disable multi flag
+multi == 1 && /^[^#]*\)/ {
+  multi=0
+  sub(/\)/, \" $add_plugins&\")
+  print \$0
+  next
+}
+
+{ print \$0 }
+"
+
+  local zdot="${ZDOTDIR:-$HOME}"
+  local zshrc="${${:-"${zdot}/.zshrc"}:A}"
+  awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \
+  && command cp -f "$zshrc" "$zdot/.zshrc.bck" \
+  && command mv -f "$zdot/.zshrc.new" "$zshrc"
+
+  # Exit if the new .zshrc file wasn't created correctly
+  [[ $? -eq 0 ]] || {
+    local ret=$?
+    _omz::log error "error enabling plugins."
+    return $ret
+  }
+
+  # Exit if the new .zshrc file has syntax errors
+  if ! command zsh -n "$zdot/.zshrc"; then
+    _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
+    command mv -f "$zdot/.zshrc.bck" "$zshrc"
+    return 1
+  fi
+
+  # Restart the zsh session if there were no errors
+  _omz::log info "plugins enabled: ${(j:, :)add_plugins}."
+
+  # Only reload zsh if run in an interactive session
+  [[ ! -o interactive ]] || _omz::reload
+}
+
+function _omz::plugin::info {
+  if [[ -z "$1" ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <plugin>"
+    return 1
+  fi
+
+  local readme
+  for readme in "$ZSH_CUSTOM/plugins/$1/README.md" "$ZSH/plugins/$1/README.md"; do
+    if [[ -f "$readme" ]]; then
+      (( ${+commands[less]} )) && less "$readme" || cat "$readme"
+      return 0
+    fi
+  done
+
+  if [[ -d "$ZSH_CUSTOM/plugins/$1" || -d "$ZSH/plugins/$1" ]]; then
+    _omz::log error "the '$1' plugin doesn't have a README file"
+  else
+    _omz::log error "'$1' plugin not found"
+  fi
+
+  return 1
+}
+
+function _omz::plugin::list {
+  local -a custom_plugins builtin_plugins
+  custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t))
+  builtin_plugins=("$ZSH"/plugins/*(-/N:t))
+
+  # If the command is being piped, print all found line by line
+  if [[ ! -t 1 ]]; then
+    print -l ${(q-)custom_plugins} ${(q-)builtin_plugins}
+    return
+  fi
+
+  if (( ${#custom_plugins} )); then
+    print -P "%U%BCustom plugins%b%u:"
+    print -lac ${(q-)custom_plugins}
+  fi
+
+  if (( ${#builtin_plugins} )); then
+    (( ${#custom_plugins} )) && echo # add a line of separation
+
+    print -P "%U%BBuilt-in plugins%b%u:"
+    print -lac ${(q-)builtin_plugins}
+  fi
+}
+
+function _omz::plugin::load {
+  if [[ -z "$1" ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <plugin> [...]"
+    return 1
+  fi
+
+  local plugin base has_completion=0
+  for plugin in "$@"; do
+    if [[ -d "$ZSH_CUSTOM/plugins/$plugin" ]]; then
+      base="$ZSH_CUSTOM/plugins/$plugin"
+    elif [[ -d "$ZSH/plugins/$plugin" ]]; then
+      base="$ZSH/plugins/$plugin"
+    else
+      _omz::log warn "plugin '$plugin' not found"
+      continue
+    fi
+
+    # Check if its a valid plugin
+    if [[ ! -f "$base/_$plugin" && ! -f "$base/$plugin.plugin.zsh" ]]; then
+      _omz::log warn "'$plugin' is not a valid plugin"
+      continue
+    # It it is a valid plugin, add its directory to $fpath unless it is already there
+    elif (( ! ${fpath[(Ie)$base]} )); then
+      fpath=("$base" $fpath)
+    fi
+
+    # Check if it has completion to reload compinit
+    local -a comp_files
+    comp_files=($base/_*(N))
+    has_completion=$(( $#comp_files > 0 ))
+
+    # Load the plugin
+    if [[ -f "$base/$plugin.plugin.zsh" ]]; then
+      source "$base/$plugin.plugin.zsh"
+    fi
+  done
+
+  # If we have completion, we need to reload the completion
+  # We pass -D to avoid generating a new dump file, which would overwrite our
+  # current one for the next session (and we don't want that because we're not
+  # actually enabling the plugins for the next session).
+  # Note that we still have to pass -d "$_comp_dumpfile", so that compinit
+  # doesn't use the default zcompdump location (${ZDOTDIR:-$HOME}/.zcompdump).
+  if (( has_completion )); then
+    compinit -D -d "$_comp_dumpfile"
+  fi
+}
+
+function _omz::pr {
+  (( $# > 0 && $+functions[$0::$1] )) || {
+    cat >&2 <<EOF
+Usage: ${(j: :)${(s.::.)0#_}} <command> [options]
+
+Available commands:
+
+  clean                       Delete all PR branches (ohmyzsh/pull-*)
+  test <PR_number_or_URL>     Fetch PR #NUMBER and rebase against master
+
+EOF
+    return 1
+  }
+
+  local command="$1"
+  shift
+
+  $0::$command "$@"
+}
+
+function _omz::pr::clean {
+  (
+    set -e
+    builtin cd -q "$ZSH"
+
+    # Check if there are PR branches
+    local fmt branches
+    fmt="%(color:bold blue)%(align:18,right)%(refname:short)%(end)%(color:reset) %(color:dim bold red)%(objectname:short)%(color:reset) %(color:yellow)%(contents:subject)"
+    branches="$(command git for-each-ref --sort=-committerdate --color --format="$fmt" "refs/heads/ohmyzsh/pull-*")"
+
+    # Exit if there are no PR branches
+    if [[ -z "$branches" ]]; then
+      _omz::log info "there are no Pull Request branches to remove."
+      return
+    fi
+
+    # Print found PR branches
+    echo "$branches\n"
+    # Confirm before removing the branches
+    _omz::confirm "do you want remove these Pull Request branches? [Y/n] "
+    # Only proceed if the answer is a valid yes option
+    [[ "$REPLY" != [yY$'\n'] ]] && return
+
+    _omz::log info "removing all Oh My Zsh Pull Request branches..."
+    command git branch --list 'ohmyzsh/pull-*' | while read branch; do
+      command git branch -D "$branch"
+    done
+  )
+}
+
+function _omz::pr::test {
+  # Allow $1 to be a URL to the pull request
+  if [[ "$1" = https://* ]]; then
+    1="${1:t}"
+  fi
+
+  # Check the input
+  if ! [[ -n "$1" && "$1" =~ ^[[:digit:]]+$ ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <PR_NUMBER_or_URL>"
+    return 1
+  fi
+
+  # Save current git HEAD
+  local branch
+  branch=$(builtin cd -q "$ZSH"; git symbolic-ref --short HEAD) || {
+    _omz::log error "error when getting the current git branch. Aborting..."
+    return 1
+  }
+
+
+  # Fetch PR onto ohmyzsh/pull-<PR_NUMBER> branch and rebase against master
+  # If any of these operations fail, undo the changes made
+  (
+    set -e
+    builtin cd -q "$ZSH"
+
+    # Get the ohmyzsh git remote
+    command git remote -v | while read remote url _; do
+      case "$url" in
+      https://github.com/ohmyzsh/ohmyzsh(|.git)) found=1; break ;;
+      git@github.com:ohmyzsh/ohmyzsh(|.git)) found=1; break ;;
+      esac
+    done
+
+    (( $found )) || {
+      _omz::log error "could not found the ohmyzsh git remote. Aborting..."
+      return 1
+    }
+
+    # Fetch pull request head
+    _omz::log info "fetching PR #$1 to ohmyzsh/pull-$1..."
+    command git fetch -f "$remote" refs/pull/$1/head:ohmyzsh/pull-$1 || {
+      _omz::log error "error when trying to fetch PR #$1."
+      return 1
+    }
+
+    # Rebase pull request branch against the current master
+    _omz::log info "rebasing PR #$1..."
+    local ret gpgsign
+    {
+      # Back up commit.gpgsign setting: use --local to get the current repository
+      # setting, not the global one. If --local is not a known option, it will
+      # exit with a 129 status code.
+      gpgsign=$(command git config --local commit.gpgsign 2>/dev/null) || ret=$?
+      [[ $ret -ne 129 ]] || gpgsign=$(command git config commit.gpgsign 2>/dev/null)
+      command git config commit.gpgsign false
+
+      command git rebase master ohmyzsh/pull-$1 || {
+        command git rebase --abort &>/dev/null
+        _omz::log warn "could not rebase PR #$1 on top of master."
+        _omz::log warn "you might not see the latest stable changes."
+        _omz::log info "run \`zsh\` to test the changes."
+        return 1
+      }
+    } always {
+      case "$gpgsign" in
+      "") command git config --unset commit.gpgsign ;;
+      *) command git config commit.gpgsign "$gpgsign" ;;
+      esac
+    }
+
+    _omz::log info "fetch of PR #${1} successful."
+  )
+
+  # If there was an error, abort running zsh to test the PR
+  [[ $? -eq 0 ]] || return 1
+
+  # Run zsh to test the changes
+  _omz::log info "running \`zsh\` to test the changes. Run \`exit\` to go back."
+  command zsh -l
+
+  # After testing, go back to the previous HEAD if the user wants
+  _omz::confirm "do you want to go back to the previous branch? [Y/n] "
+  # Only proceed if the answer is a valid yes option
+  [[ "$REPLY" != [yY$'\n'] ]] && return
+
+  (
+    set -e
+    builtin cd -q "$ZSH"
+
+    command git checkout "$branch" -- || {
+      _omz::log error "could not go back to the previous branch ('$branch')."
+      return 1
+    }
+  )
+}
+
+function _omz::reload {
+  # Delete current completion cache
+  command rm -f $_comp_dumpfile $ZSH_COMPDUMP
+
+  # Old zsh versions don't have ZSH_ARGZERO
+  local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}"
+  # Check whether to run a login shell
+  [[ "$zsh" = -* || -o login ]] && exec -l "${zsh#-}" || exec "$zsh"
+}
+
+function _omz::theme {
+  (( $# > 0 && $+functions[$0::$1] )) || {
+    cat >&2 <<EOF
+Usage: ${(j: :)${(s.::.)0#_}} <command> [options]
+
+Available commands:
+
+  list            List all available Oh My Zsh themes
+  set <theme>     Set a theme in your .zshrc file
+  use <theme>     Load a theme
+
+EOF
+    return 1
+  }
+
+  local command="$1"
+  shift
+
+  $0::$command "$@"
+}
+
+function _omz::theme::list {
+  local -a custom_themes builtin_themes
+  custom_themes=("$ZSH_CUSTOM"/**/*.zsh-theme(-.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::))
+  builtin_themes=("$ZSH"/themes/*.zsh-theme(-.N:t:r))
+
+  # If the command is being piped, print all found line by line
+  if [[ ! -t 1 ]]; then
+    print -l ${(q-)custom_themes} ${(q-)builtin_themes}
+    return
+  fi
+
+  # Print theme in use
+  if [[ -n "$ZSH_THEME" ]]; then
+    print -Pn "%U%BCurrent theme%b%u: "
+    [[ $ZSH_THEME = random ]] && echo "$RANDOM_THEME (via random)" || echo "$ZSH_THEME"
+    echo
+  fi
+
+  # Print custom themes if there are any
+  if (( ${#custom_themes} )); then
+    print -P "%U%BCustom themes%b%u:"
+    print -lac ${(q-)custom_themes}
+    echo
+  fi
+
+  # Print built-in themes
+  print -P "%U%BBuilt-in themes%b%u:"
+  print -lac ${(q-)builtin_themes}
+}
+
+function _omz::theme::set {
+  if [[ -z "$1" ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <theme>"
+    return 1
+  fi
+
+  # Check that theme exists
+  if [[ ! -f "$ZSH_CUSTOM/$1.zsh-theme" ]] \
+    && [[ ! -f "$ZSH_CUSTOM/themes/$1.zsh-theme" ]] \
+    && [[ ! -f "$ZSH/themes/$1.zsh-theme" ]]; then
+    _omz::log error "%B$1%b theme not found"
+    return 1
+  fi
+
+  # Enable theme in .zshrc
+  local awk_script='
+!set && /^[ \t]*ZSH_THEME=[^#]+.*$/ {
+  set=1
+  sub(/^[ \t]*ZSH_THEME=[^#]+.*$/, "ZSH_THEME=\"'$1'\" # set by `omz`")
+  print $0
+  next
+}
+
+{ print $0 }
+
+END {
+  # If no ZSH_THEME= line was found, return an error
+  if (!set) exit 1
+}
+'
+
+  local zdot="${ZDOTDIR:-$HOME}"
+  local zshrc="${${:-"${zdot}/.zshrc"}:A}"
+  awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \
+  || {
+    # Prepend ZSH_THEME= line to .zshrc if it doesn't exist
+    cat <<EOF
+ZSH_THEME="$1" # set by \`omz\`
+
+EOF
+    cat "$zdot/.zshrc"
+  } > "$zdot/.zshrc.new" \
+  && command cp -f "$zshrc" "$zdot/.zshrc.bck" \
+  && command mv -f "$zdot/.zshrc.new" "$zshrc"
+
+  # Exit if the new .zshrc file wasn't created correctly
+  [[ $? -eq 0 ]] || {
+    local ret=$?
+    _omz::log error "error setting theme."
+    return $ret
+  }
+
+  # Exit if the new .zshrc file has syntax errors
+  if ! command zsh -n "$zdot/.zshrc"; then
+    _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..."
+    command mv -f "$zdot/.zshrc.bck" "$zshrc"
+    return 1
+  fi
+
+  # Restart the zsh session if there were no errors
+  _omz::log info "'$1' theme set correctly."
+
+  # Only reload zsh if run in an interactive session
+  [[ ! -o interactive ]] || _omz::reload
+}
+
+function _omz::theme::use {
+  if [[ -z "$1" ]]; then
+    echo >&2 "Usage: ${(j: :)${(s.::.)0#_}} <theme>"
+    return 1
+  fi
+
+  # Respect compatibility with old lookup order
+  if [[ -f "$ZSH_CUSTOM/$1.zsh-theme" ]]; then
+    source "$ZSH_CUSTOM/$1.zsh-theme"
+  elif [[ -f "$ZSH_CUSTOM/themes/$1.zsh-theme" ]]; then
+    source "$ZSH_CUSTOM/themes/$1.zsh-theme"
+  elif [[ -f "$ZSH/themes/$1.zsh-theme" ]]; then
+    source "$ZSH/themes/$1.zsh-theme"
+  else
+    _omz::log error "%B$1%b theme not found"
+    return 1
+  fi
+
+  # Update theme settings
+  ZSH_THEME="$1"
+  [[ $1 = random ]] || unset RANDOM_THEME
+}
+
+function _omz::update {
+  local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD)
+
+  # Run update script
+  if [[ "$1" != --unattended ]]; then
+    ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" --interactive || return $?
+  else
+    ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" || return $?
+  fi
+
+  # Update last updated file
+  zmodload zsh/datetime
+  echo "LAST_EPOCH=$(( EPOCHSECONDS / 60 / 60 / 24 ))" >! "${ZSH_CACHE_DIR}/.zsh-update"
+  # Remove update lock if it exists
+  command rm -rf "$ZSH/log/update.lock"
+
+  # Restart the zsh session if there were changes
+  if [[ "$1" != --unattended && "$(builtin cd -q "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then
+    # Old zsh versions don't have ZSH_ARGZERO
+    local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}"
+    # Check whether to run a login shell
+    [[ "$zsh" = -* || -o login ]] && exec -l "${zsh#-}" || exec "$zsh"
+  fi
+}
+
+function _omz::version {
+  (
+    builtin cd -q "$ZSH"
+
+    # Get the version name:
+    # 1) try tag-like version
+    # 2) try branch name
+    # 3) try name-rev (tag~<rev> or branch~<rev>)
+    local version
+    version=$(command git describe --tags HEAD 2>/dev/null) \
+    || version=$(command git symbolic-ref --quiet --short HEAD 2>/dev/null) \
+    || version=$(command git name-rev --no-undefined --name-only --exclude="remotes/*" HEAD 2>/dev/null) \
+    || version="<detached>"
+
+    # Get short hash for the current HEAD
+    local commit=$(command git rev-parse --short HEAD 2>/dev/null)
+
+    # Show version and commit hash
+    printf "%s (%s)\n" "$version" "$commit"
+  )
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/clipboard.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/clipboard.zsh
new file mode 100644 (file)
index 0000000..ad83fc4
--- /dev/null
@@ -0,0 +1,107 @@
+# System clipboard integration
+#
+# This file has support for doing system clipboard copy and paste operations
+# from the command line in a generic cross-platform fashion.
+#
+# This is uses essentially the same heuristic as neovim, with the additional
+# special support for Cygwin.
+# See: https://github.com/neovim/neovim/blob/e682d799fa3cf2e80a02d00c6ea874599d58f0e7/runtime/autoload/provider/clipboard.vim#L55-L121
+#
+# - pbcopy, pbpaste (macOS)
+# - cygwin (Windows running Cygwin)
+# - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
+# - xsel (if $DISPLAY is set)
+# - xclip (if $DISPLAY is set)
+# - lemonade (for SSH) https://github.com/pocke/lemonade
+# - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
+# - win32yank (Windows)
+# - tmux (if $TMUX is set)
+#
+# Defines two functions, clipcopy and clippaste, based on the detected platform.
+##
+#
+# clipcopy - Copy data to clipboard
+#
+# Usage:
+#
+#  <command> | clipcopy    - copies stdin to clipboard
+#
+#  clipcopy <file>         - copies a file's contents to clipboard
+#
+##
+#
+# clippaste - "Paste" data from clipboard to stdout
+#
+# Usage:
+#
+#   clippaste   - writes clipboard's contents to stdout
+#
+#   clippaste | <command>    - pastes contents and pipes it to another process
+#
+#   clippaste > <file>      - paste contents to a file
+#
+# Examples:
+#
+#   # Pipe to another process
+#   clippaste | grep foo
+#
+#   # Paste to a file
+#   clippaste > file.txt
+#
+function detect-clipboard() {
+  emulate -L zsh
+
+  if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | pbcopy; }
+    function clippaste() { pbpaste; }
+  elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then
+    function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; }
+    function clippaste() { cat /dev/clipboard; }
+  elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | wl-copy &>/dev/null &|; }
+    function clippaste() { wl-paste; }
+  elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | xsel --clipboard --input; }
+    function clippaste() { xsel --clipboard --output; }
+  elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | xclip -selection clipboard -in &>/dev/null &|; }
+    function clippaste() { xclip -out -selection clipboard; }
+  elif (( ${+commands[lemonade]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | lemonade copy; }
+    function clippaste() { lemonade paste; }
+  elif (( ${+commands[doitclient]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | doitclient wclip; }
+    function clippaste() { doitclient wclip -r; }
+  elif (( ${+commands[win32yank]} )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | win32yank -i; }
+    function clippaste() { win32yank -o; }
+  elif [[ $OSTYPE == linux-android* ]] && (( $+commands[termux-clipboard-set] )); then
+    function clipcopy() { cat "${1:-/dev/stdin}" | termux-clipboard-set; }
+    function clippaste() { termux-clipboard-get; }
+  elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then
+    function clipcopy() { tmux load-buffer "${1:--}"; }
+    function clippaste() { tmux save-buffer -; }
+  elif [[ $(uname -r) = *icrosoft* ]]; then
+    function clipcopy() { cat "${1:-/dev/stdin}" | clip.exe; }
+    function clippaste() { powershell.exe -noprofile -command Get-Clipboard; }
+  else
+    function _retry_clipboard_detection_or_fail() {
+      local clipcmd="${1}"; shift
+      if detect-clipboard; then
+        "${clipcmd}" "$@"
+      else
+        print "${clipcmd}: Platform $OSTYPE not supported or xclip/xsel not installed" >&2
+        return 1
+      fi
+    }
+    function clipcopy() { _retry_clipboard_detection_or_fail clipcopy "$@"; }
+    function clippaste() { _retry_clipboard_detection_or_fail clippaste "$@"; }
+    return 1
+  fi
+}
+
+# Detect at startup. A non-zero exit here indicates that the dummy clipboards were set,
+# which is not really an error. If the user calls them, they will attempt to redetect
+# (for example, perhaps the user has now installed xclip) and then either print an error
+# or proceed successfully.
+detect-clipboard || true
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/compfix.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/compfix.zsh
new file mode 100644 (file)
index 0000000..b09b283
--- /dev/null
@@ -0,0 +1,44 @@
+# Handle completions insecurities (i.e., completion-dependent directories with
+# insecure ownership or permissions) by:
+#
+# * Human-readably notifying the user of these insecurities.
+function handle_completion_insecurities() {
+  # List of the absolute paths of all unique insecure directories, split on
+  # newline from compaudit()'s output resembling:
+  #
+  #     There are insecure directories:
+  #     /usr/share/zsh/site-functions
+  #     /usr/share/zsh/5.0.6/functions
+  #     /usr/share/zsh
+  #     /usr/share/zsh/5.0.6
+  #
+  # Since the ignorable first line is printed to stderr and thus not captured,
+  # stderr is squelched to prevent this output from leaking to the user. 
+  local -aU insecure_dirs
+  insecure_dirs=( ${(f@):-"$(compaudit 2>/dev/null)"} )
+
+  # If no such directories exist, get us out of here.
+  [[ -z "${insecure_dirs}" ]] && return
+
+  # List ownership and permissions of all insecure directories.
+  print "[oh-my-zsh] Insecure completion-dependent directories detected:"
+  ls -ld "${(@)insecure_dirs}"
+
+  cat <<EOD
+
+[oh-my-zsh] For safety, we will not load completions from these directories until
+[oh-my-zsh] you fix their permissions and ownership and restart zsh.
+[oh-my-zsh] See the above list for directories with group or other writability.
+
+[oh-my-zsh] To fix your permissions you can do so by disabling
+[oh-my-zsh] the write permission of "group" and "others" and making sure that the
+[oh-my-zsh] owner of these directories is either root or your current user.
+[oh-my-zsh] The following command may help:
+[oh-my-zsh]     compaudit | xargs chmod g-w,o-w
+
+[oh-my-zsh] If the above didn't help or you want to skip the verification of
+[oh-my-zsh] insecure directories you can set the variable ZSH_DISABLE_COMPFIX to
+[oh-my-zsh] "true" before oh-my-zsh is sourced in your zshrc file.
+
+EOD
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/completion.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/completion.zsh
new file mode 100644 (file)
index 0000000..2c56954
--- /dev/null
@@ -0,0 +1,78 @@
+# fixme - the load process here seems a bit bizarre
+zmodload -i zsh/complist
+
+WORDCHARS=''
+
+unsetopt menu_complete   # do not autoselect the first completion entry
+unsetopt flowcontrol
+setopt auto_menu         # show completion menu on successive tab press
+setopt complete_in_word
+setopt always_to_end
+
+# should this be in keybindings?
+bindkey -M menuselect '^o' accept-and-infer-next-history
+zstyle ':completion:*:*:*:*:*' menu select
+
+# case insensitive (all), partial-word and substring completion
+if [[ "$CASE_SENSITIVE" = true ]]; then
+  zstyle ':completion:*' matcher-list 'r:|=*' 'l:|=* r:|=*'
+else
+  if [[ "$HYPHEN_INSENSITIVE" = true ]]; then
+    zstyle ':completion:*' matcher-list 'm:{a-zA-Z-_}={A-Za-z_-}' 'r:|=*' 'l:|=* r:|=*'
+  else
+    zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'
+  fi
+fi
+unset CASE_SENSITIVE HYPHEN_INSENSITIVE
+
+# Complete . and .. special directories
+zstyle ':completion:*' special-dirs true
+
+zstyle ':completion:*' list-colors ''
+zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'
+
+if [[ "$OSTYPE" = solaris* ]]; then
+  zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm"
+else
+  zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm -w -w"
+fi
+
+# disable named-directories autocompletion
+zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories
+
+# Use caching so that commands like apt and dpkg complete are useable
+zstyle ':completion:*' use-cache yes
+zstyle ':completion:*' cache-path $ZSH_CACHE_DIR
+
+# Don't complete uninteresting users
+zstyle ':completion:*:*:*:users' ignored-patterns \
+        adm amanda apache at avahi avahi-autoipd beaglidx bin cacti canna \
+        clamav daemon dbus distcache dnsmasq dovecot fax ftp games gdm \
+        gkrellmd gopher hacluster haldaemon halt hsqldb ident junkbust kdm \
+        ldap lp mail mailman mailnull man messagebus  mldonkey mysql nagios \
+        named netdump news nfsnobody nobody nscd ntp nut nx obsrun openvpn \
+        operator pcap polkitd postfix postgres privoxy pulse pvm quagga radvd \
+        rpc rpcuser rpm rtkit scard shutdown squid sshd statd svn sync tftp \
+        usbmux uucp vcsa wwwrun xfs '_*'
+
+# ... unless we really want to.
+zstyle '*' single-ignored show
+
+if [[ ${COMPLETION_WAITING_DOTS:-false} != false ]]; then
+  expand-or-complete-with-dots() {
+    # use $COMPLETION_WAITING_DOTS either as toggle or as the sequence to show
+    [[ $COMPLETION_WAITING_DOTS = true ]] && COMPLETION_WAITING_DOTS="%F{red}…%f"
+    # turn off line wrapping and print prompt-expanded "dot" sequence
+    printf '\e[?7l%s\e[?7h' "${(%)COMPLETION_WAITING_DOTS}"
+    zle expand-or-complete
+    zle redisplay
+  }
+  zle -N expand-or-complete-with-dots
+  # Set the function as the default tab completion widget
+  bindkey -M emacs "^I" expand-or-complete-with-dots
+  bindkey -M viins "^I" expand-or-complete-with-dots
+  bindkey -M vicmd "^I" expand-or-complete-with-dots
+fi
+
+# automatically load bash completion functions
+autoload -U +X bashcompinit && bashcompinit
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/correction.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/correction.zsh
new file mode 100644 (file)
index 0000000..4259d34
--- /dev/null
@@ -0,0 +1,15 @@
+if [[ "$ENABLE_CORRECTION" == "true" ]]; then
+  alias cp='nocorrect cp'
+  alias ebuild='nocorrect ebuild'
+  alias gist='nocorrect gist'
+  alias heroku='nocorrect heroku'
+  alias hpodder='nocorrect hpodder'
+  alias man='nocorrect man'
+  alias mkdir='nocorrect mkdir'
+  alias mv='nocorrect mv'
+  alias mysql='nocorrect mysql'
+  alias sudo='nocorrect sudo'
+  alias su='nocorrect su'
+
+  setopt correct_all
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/diagnostics.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/diagnostics.zsh
new file mode 100644 (file)
index 0000000..eaeba7d
--- /dev/null
@@ -0,0 +1,353 @@
+# diagnostics.zsh
+#
+# Diagnostic and debugging support for oh-my-zsh
+
+# omz_diagnostic_dump()
+#
+# Author: Andrew Janke <andrew@apjanke.net>
+#
+# Usage:
+#
+# omz_diagnostic_dump [-v] [-V] [file]
+#
+# NOTE: This is a work in progress. Its interface and behavior are going to change,
+# and probably in non-back-compatible ways.
+#
+# Outputs a bunch of information about the state and configuration of
+# oh-my-zsh, zsh, and the user's system. This is intended to provide a
+# bunch of context for diagnosing your own or a third party's problems, and to
+# be suitable for posting to public bug reports.
+#
+# The output is human-readable and its format may change over time. It is not
+# suitable for parsing. All the output is in one single file so it can be posted
+# as a gist or bug comment on GitHub. GitHub doesn't support attaching tarballs
+# or other files to bugs; otherwise, this would probably have an option to produce
+# tarballs that contain copies of the config and customization files instead of
+# catting them all in to one file.
+#
+# This is intended to be widely portable, and run anywhere that oh-my-zsh does.
+# Feel free to report any portability issues as bugs.
+#
+# This is written in a defensive style so it still works (and can detect) cases when
+# basic functionality like echo and which have been redefined. In particular, almost
+# everything is invoked with "builtin" or "command", to work in the face of user 
+# redefinitions.
+#
+# OPTIONS
+#
+# [file]   Specifies the output file. If not given, a file in the current directory
+#        is selected automatically.
+#
+# -v    Increase the verbosity of the dump output. May be specified multiple times.
+#       Verbosity levels:
+#        0 - Basic info, shell state, omz configuration, git state
+#        1 - (default) Adds key binding info and configuration file contents
+#        2 - Adds zcompdump file contents
+#
+# -V    Reduce the verbosity of the dump output. May be specified multiple times.
+#
+# TODO:
+# * Multi-file capture
+# * Add automatic gist uploading
+# * Consider whether to move default output file location to TMPDIR. More robust
+#     but less user friendly.
+#
+
+autoload -Uz is-at-least
+
+function omz_diagnostic_dump() {
+  emulate -L zsh
+
+  builtin echo "Generating diagnostic dump; please be patient..."
+  
+  local thisfcn=omz_diagnostic_dump
+  local -A opts
+  local opt_verbose opt_noverbose opt_outfile
+  local timestamp=$(date +%Y%m%d-%H%M%S)
+  local outfile=omz_diagdump_$timestamp.txt
+  builtin zparseopts -A opts -D -- "v+=opt_verbose" "V+=opt_noverbose"
+  local verbose n_verbose=${#opt_verbose} n_noverbose=${#opt_noverbose}
+  (( verbose = 1 + n_verbose - n_noverbose ))
+
+  if [[ ${#*} > 0 ]]; then
+    opt_outfile=$1
+  fi
+  if [[ ${#*} > 1 ]]; then
+    builtin echo "$thisfcn: error: too many arguments" >&2
+    return 1
+  fi
+  if [[ -n "$opt_outfile" ]]; then
+    outfile="$opt_outfile"
+  fi
+
+  # Always write directly to a file so terminal escape sequences are
+  # captured cleanly
+  _omz_diag_dump_one_big_text &> "$outfile"
+  if [[ $? != 0 ]]; then
+    builtin echo "$thisfcn: error while creating diagnostic dump; see $outfile for details"
+  fi
+
+  builtin echo
+  builtin echo Diagnostic dump file created at: "$outfile"
+  builtin echo
+  builtin echo To share this with OMZ developers, post it as a gist on GitHub 
+  builtin echo at "https://gist.github.com" and share the link to the gist.
+  builtin echo
+  builtin echo "WARNING: This dump file contains all your zsh and omz configuration files,"
+  builtin echo "so don't share it publicly if there's sensitive information in them."
+  builtin echo
+
+}
+
+function _omz_diag_dump_one_big_text() {
+  local program programs progfile md5
+
+  builtin echo oh-my-zsh diagnostic dump
+  builtin echo
+  builtin echo $outfile
+  builtin echo 
+  
+  # Basic system and zsh information
+  command date
+  command uname -a
+  builtin echo OSTYPE=$OSTYPE
+  builtin echo ZSH_VERSION=$ZSH_VERSION
+  builtin echo User: $USERNAME
+  builtin echo umask: $(umask)
+  builtin echo
+  _omz_diag_dump_os_specific_version
+  builtin echo
+
+  # Installed programs
+  programs=(sh zsh ksh bash sed cat grep ls find git posh)
+  local progfile="" extra_str="" sha_str=""
+  for program in $programs; do
+    extra_str="" sha_str=""
+    progfile=$(builtin which $program)
+    if [[ $? == 0 ]]; then
+      if [[ -e $progfile ]]; then
+        if builtin whence shasum &>/dev/null; then
+          sha_str=($(command shasum $progfile))
+          sha_str=$sha_str[1]
+          extra_str+=" SHA $sha_str"
+        fi
+        if [[ -h "$progfile" ]]; then
+          extra_str+=" ( -> ${progfile:A} )"
+        fi
+      fi
+      builtin printf '%-9s %-20s %s\n' "$program is" "$progfile" "$extra_str"
+    else
+      builtin echo "$program: not found"
+    fi
+  done
+  builtin echo
+  builtin echo Command Versions:
+  builtin echo "zsh: $(zsh --version)"
+  builtin echo "this zsh session: $ZSH_VERSION"
+  builtin echo "bash: $(bash --version | command grep bash)"
+  builtin echo "git: $(git --version)"
+  builtin echo "grep: $(grep --version)"
+  builtin echo
+
+  # Core command definitions
+  _omz_diag_dump_check_core_commands || return 1
+  builtin echo  
+
+  # ZSH Process state
+  builtin echo Process state:
+  builtin echo pwd: $PWD
+  if builtin whence pstree &>/dev/null; then
+    builtin echo Process tree for this shell:
+    pstree -p $$
+  else
+    ps -fT
+  fi
+  builtin set | command grep -a '^\(ZSH\|plugins\|TERM\|LC_\|LANG\|precmd\|chpwd\|preexec\|FPATH\|TTY\|DISPLAY\|PATH\)\|OMZ'
+  builtin echo
+  #TODO: Should this include `env` instead of or in addition to `export`?
+  builtin echo Exported:
+  builtin echo $(builtin export | command sed 's/=.*//')
+  builtin echo 
+  builtin echo Locale:
+  command locale
+  builtin echo
+
+  # Zsh installation and configuration
+  builtin echo Zsh configuration:
+  builtin echo setopt: $(builtin setopt)
+  builtin echo
+  builtin echo zstyle:
+  builtin zstyle
+  builtin echo
+  builtin echo 'compaudit output:'
+  compaudit
+  builtin echo 
+  builtin echo '$fpath directories:'
+  command ls -lad $fpath
+  builtin echo
+
+  # Oh-my-zsh installation
+  builtin echo oh-my-zsh installation:
+  command ls -ld ~/.z*
+  command ls -ld ~/.oh*
+  builtin echo
+  builtin echo oh-my-zsh git state:
+  (builtin cd $ZSH && builtin echo "HEAD: $(git rev-parse HEAD)" && git remote -v && git status | command grep "[^[:space:]]")
+  if [[ $verbose -ge 1 ]]; then
+    (builtin cd $ZSH && git reflog --date=default | command grep pull)
+  fi
+  builtin echo
+  if [[ -e $ZSH_CUSTOM ]]; then
+    local custom_dir=$ZSH_CUSTOM
+    if [[ -h $custom_dir ]]; then
+      custom_dir=$(builtin cd $custom_dir && pwd -P)
+    fi
+    builtin echo "oh-my-zsh custom dir:"
+    builtin echo "   $ZSH_CUSTOM ($custom_dir)"
+    (builtin cd ${custom_dir:h} && command find ${custom_dir:t} -name .git -prune -o -print)
+    builtin echo
+  fi
+
+  # Key binding and terminal info
+  if [[ $verbose -ge 1 ]]; then
+    builtin echo "bindkey:"
+    builtin bindkey
+    builtin echo
+    builtin echo "infocmp:"
+    command infocmp -L
+    builtin echo
+  fi
+
+  # Configuration file info
+  local zdotdir=${ZDOTDIR:-$HOME}
+  builtin echo "Zsh configuration files:"
+  local cfgfile cfgfiles
+  # Some files for bash that zsh does not use are intentionally included
+  # to help with diagnosing behavior differences between bash and zsh
+  cfgfiles=( /etc/zshenv /etc/zprofile /etc/zshrc /etc/zlogin /etc/zlogout 
+    $zdotdir/.zshenv $zdotdir/.zprofile $zdotdir/.zshrc $zdotdir/.zlogin $zdotdir/.zlogout
+    ~/.zsh.pre-oh-my-zsh
+    /etc/bashrc /etc/profile ~/.bashrc ~/.profile ~/.bash_profile ~/.bash_logout )
+  command ls -lad $cfgfiles 2>&1
+  builtin echo
+  if [[ $verbose -ge 1 ]]; then
+    for cfgfile in $cfgfiles; do
+      _omz_diag_dump_echo_file_w_header $cfgfile
+    done
+  fi
+  builtin echo
+  builtin echo "Zsh compdump files:"
+  local dumpfile dumpfiles
+  command ls -lad $zdotdir/.zcompdump*
+  dumpfiles=( $zdotdir/.zcompdump*(N) )
+  if [[ $verbose -ge 2 ]]; then
+    for dumpfile in $dumpfiles; do
+      _omz_diag_dump_echo_file_w_header $dumpfile
+    done
+  fi
+
+}
+
+function _omz_diag_dump_check_core_commands() {
+  builtin echo "Core command check:"
+  local redefined name builtins externals reserved_words
+  redefined=()
+  # All the zsh non-module builtin commands
+  # These are taken from the zsh reference manual for 5.0.2
+  # Commands from modules should not be included.
+  # (For back-compatibility, if any of these are newish, they should be removed,
+  # or at least made conditional on the version of the current running zsh.)
+  # "history" is also excluded because OMZ is known to redefine that
+  reserved_words=( do done esac then elif else fi for case if while function 
+    repeat time until select coproc nocorrect foreach end '!' '[[' '{' '}' 
+    )
+  builtins=( alias autoload bg bindkey break builtin bye cd chdir command
+    comparguments compcall compctl compdescribe compfiles compgroups compquote comptags
+    comptry compvalues continue dirs disable disown echo echotc echoti emulate
+    enable eval exec exit false fc fg functions getln getopts hash
+    jobs kill let limit log logout noglob popd print printf
+    pushd pushln pwd r read rehash return sched set setopt shift
+    source suspend test times trap true ttyctl type ulimit umask unalias
+    unfunction unhash unlimit unset unsetopt vared wait whence where which zcompile
+    zle zmodload zparseopts zregexparse zstyle )
+  if is-at-least 5.1; then
+    reserved_word+=( declare export integer float local readonly typeset )
+  else
+    builtins+=( declare export integer float local readonly typeset )
+  fi
+  builtins_fatal=( builtin command local )
+  externals=( zsh )
+  for name in $reserved_words; do
+    if [[ $(builtin whence -w $name) != "$name: reserved" ]]; then
+      builtin echo "reserved word '$name' has been redefined"
+      builtin which $name
+      redefined+=$name
+    fi
+  done
+  for name in $builtins; do
+    if [[ $(builtin whence -w $name) != "$name: builtin" ]]; then
+      builtin echo "builtin '$name' has been redefined"
+      builtin which $name
+      redefined+=$name
+    fi
+  done
+  for name in $externals; do
+    if [[ $(builtin whence -w $name) != "$name: command" ]]; then
+      builtin echo "command '$name' has been redefined"
+      builtin which $name
+      redefined+=$name
+    fi
+  done
+
+  if [[ -n "$redefined" ]]; then
+    builtin echo "SOME CORE COMMANDS HAVE BEEN REDEFINED: $redefined"
+  else
+    builtin echo "All core commands are defined normally"
+  fi
+
+}
+
+function _omz_diag_dump_echo_file_w_header() {
+  local file=$1
+  if [[ ( -f $file || -h $file ) ]]; then
+    builtin echo "========== $file =========="
+    if [[ -h $file ]]; then
+      builtin echo "==========    ( => ${file:A} )   =========="
+    fi
+    command cat $file
+    builtin echo "========== end $file =========="
+    builtin echo
+  elif [[ -d $file ]]; then
+    builtin echo "File '$file' is a directory"
+  elif [[ ! -e $file ]]; then
+    builtin echo "File '$file' does not exist"
+  else
+    command ls -lad "$file"
+  fi
+}
+
+function _omz_diag_dump_os_specific_version() {
+  local osname osver version_file version_files
+  case "$OSTYPE" in
+    darwin*)
+      osname=$(command sw_vers -productName)
+      osver=$(command sw_vers -productVersion)      
+      builtin echo "OS Version: $osname $osver build $(sw_vers -buildVersion)"
+      ;;
+    cygwin)
+      command systeminfo | command head -n 4 | command tail -n 2
+      ;;
+  esac
+
+  if builtin which lsb_release >/dev/null; then
+    builtin echo "OS Release: $(command lsb_release -s -d)"
+  fi
+
+  version_files=( /etc/*-release(N) /etc/*-version(N) /etc/*_version(N) )
+  for version_file in $version_files; do
+    builtin echo "$version_file:"
+    command cat "$version_file"
+    builtin echo
+  done
+}
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/directories.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/directories.zsh
new file mode 100644 (file)
index 0000000..c62f564
--- /dev/null
@@ -0,0 +1,38 @@
+# Changing/making/removing directory
+setopt auto_pushd
+setopt pushd_ignore_dups
+setopt pushdminus
+
+alias -g ...='../..'
+alias -g ....='../../..'
+alias -g .....='../../../..'
+alias -g ......='../../../../..'
+
+alias -- -='cd -'
+alias 1='cd -1'
+alias 2='cd -2'
+alias 3='cd -3'
+alias 4='cd -4'
+alias 5='cd -5'
+alias 6='cd -6'
+alias 7='cd -7'
+alias 8='cd -8'
+alias 9='cd -9'
+
+alias md='mkdir -p'
+alias rd=rmdir
+
+function d () {
+  if [[ -n $1 ]]; then
+    dirs "$@"
+  else
+    dirs -v | head -n 10
+  fi
+}
+compdef _dirs d
+
+# List directory contents
+alias lsa='ls -lah'
+alias l='ls -lah'
+alias ll='ls -lh'
+alias la='ls -lAh'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/functions.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/functions.zsh
new file mode 100644 (file)
index 0000000..dfcc4d9
--- /dev/null
@@ -0,0 +1,255 @@
+function zsh_stats() {
+  fc -l 1 \
+    | awk '{ CMD[$2]++; count++; } END { for (a in CMD) print CMD[a] " " CMD[a]*100/count "% " a }' \
+    | grep -v "./" | sort -nr | head -n 20 | column -c3 -s " " -t | nl
+}
+
+function uninstall_oh_my_zsh() {
+  env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh"
+}
+
+function upgrade_oh_my_zsh() {
+  echo >&2 "${fg[yellow]}Note: \`$0\` is deprecated. Use \`omz update\` instead.$reset_color"
+  omz update
+}
+
+function open_command() {
+  local open_cmd
+
+  # define the open command
+  case "$OSTYPE" in
+    darwin*)  open_cmd='open' ;;
+    cygwin*)  open_cmd='cygstart' ;;
+    linux*)   [[ "$(uname -r)" != *icrosoft* ]] && open_cmd='nohup xdg-open' || {
+                open_cmd='cmd.exe /c start ""'
+                [[ -e "$1" ]] && { 1="$(wslpath -w "${1:a}")" || return 1 }
+              } ;;
+    msys*)    open_cmd='start ""' ;;
+    *)        echo "Platform $OSTYPE not supported"
+              return 1
+              ;;
+  esac
+
+  ${=open_cmd} "$@" &>/dev/null
+}
+
+# take functions
+
+# mkcd is equivalent to takedir
+function mkcd takedir() {
+  mkdir -p $@ && cd ${@:$#}
+}
+
+function takeurl() {
+  local data thedir
+  data="$(mktemp)"
+  curl -L "$1" > "$data"
+  tar xf "$data"
+  thedir="$(tar tf "$data" | head -n 1)"
+  rm "$data"
+  cd "$thedir"
+}
+
+function takegit() {
+  git clone "$1"
+  cd "$(basename ${1%%.git})"
+}
+
+function take() {
+  if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]; then
+    takeurl "$1"
+  elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then
+    takegit "$1"
+  else
+    takedir "$@"
+  fi
+}
+
+#
+# Get the value of an alias.
+#
+# Arguments:
+#    1. alias - The alias to get its value from
+# STDOUT:
+#    The value of alias $1 (if it has one).
+# Return value:
+#    0 if the alias was found,
+#    1 if it does not exist
+#
+function alias_value() {
+    (( $+aliases[$1] )) && echo $aliases[$1]
+}
+
+#
+# Try to get the value of an alias,
+# otherwise return the input.
+#
+# Arguments:
+#    1. alias - The alias to get its value from
+# STDOUT:
+#    The value of alias $1, or $1 if there is no alias $1.
+# Return value:
+#    Always 0
+#
+function try_alias_value() {
+    alias_value "$1" || echo "$1"
+}
+
+#
+# Set variable "$1" to default value "$2" if "$1" is not yet defined.
+#
+# Arguments:
+#    1. name - The variable to set
+#    2. val  - The default value
+# Return value:
+#    0 if the variable exists, 3 if it was set
+#
+function default() {
+    (( $+parameters[$1] )) && return 0
+    typeset -g "$1"="$2"   && return 3
+}
+
+#
+# Set environment variable "$1" to default value "$2" if "$1" is not yet defined.
+#
+# Arguments:
+#    1. name - The env variable to set
+#    2. val  - The default value
+# Return value:
+#    0 if the env variable exists, 3 if it was set
+#
+function env_default() {
+    [[ ${parameters[$1]} = *-export* ]] && return 0
+    export "$1=$2" && return 3
+}
+
+
+# Required for $langinfo
+zmodload zsh/langinfo
+
+# URL-encode a string
+#
+# Encodes a string using RFC 2396 URL-encoding (%-escaped).
+# See: https://www.ietf.org/rfc/rfc2396.txt
+#
+# By default, reserved characters and unreserved "mark" characters are
+# not escaped by this function. This allows the common usage of passing
+# an entire URL in, and encoding just special characters in it, with
+# the expectation that reserved and mark characters are used appropriately.
+# The -r and -m options turn on escaping of the reserved and mark characters,
+# respectively, which allows arbitrary strings to be fully escaped for
+# embedding inside URLs, where reserved characters might be misinterpreted.
+#
+# Prints the encoded string on stdout.
+# Returns nonzero if encoding failed.
+#
+# Usage:
+#  omz_urlencode [-r] [-m] [-P] <string> [<string> ...]
+#
+#    -r causes reserved characters (;/?:@&=+$,) to be escaped
+#
+#    -m causes "mark" characters (_.!~*''()-) to be escaped
+#
+#    -P causes spaces to be encoded as '%20' instead of '+'
+function omz_urlencode() {
+  emulate -L zsh
+  local -a opts
+  zparseopts -D -E -a opts r m P
+
+  local in_str="$@"
+  local url_str=""
+  local spaces_as_plus
+  if [[ -z $opts[(r)-P] ]]; then spaces_as_plus=1; fi
+  local str="$in_str"
+
+  # URLs must use UTF-8 encoding; convert str to UTF-8 if required
+  local encoding=$langinfo[CODESET]
+  local safe_encodings
+  safe_encodings=(UTF-8 utf8 US-ASCII)
+  if [[ -z ${safe_encodings[(r)$encoding]} ]]; then
+    str=$(echo -E "$str" | iconv -f $encoding -t UTF-8)
+    if [[ $? != 0 ]]; then
+      echo "Error converting string from $encoding to UTF-8" >&2
+      return 1
+    fi
+  fi
+
+  # Use LC_CTYPE=C to process text byte-by-byte
+  local i byte ord LC_ALL=C
+  export LC_ALL
+  local reserved=';/?:@&=+$,'
+  local mark='_.!~*''()-'
+  local dont_escape="[A-Za-z0-9"
+  if [[ -z $opts[(r)-r] ]]; then
+    dont_escape+=$reserved
+  fi
+  # $mark must be last because of the "-"
+  if [[ -z $opts[(r)-m] ]]; then
+    dont_escape+=$mark
+  fi
+  dont_escape+="]"
+
+  # Implemented to use a single printf call and avoid subshells in the loop,
+  # for performance (primarily on Windows).
+  local url_str=""
+  for (( i = 1; i <= ${#str}; ++i )); do
+    byte="$str[i]"
+    if [[ "$byte" =~ "$dont_escape" ]]; then
+      url_str+="$byte"
+    else
+      if [[ "$byte" == " " && -n $spaces_as_plus ]]; then
+        url_str+="+"
+      else
+        ord=$(( [##16] #byte ))
+        url_str+="%$ord"
+      fi
+    fi
+  done
+  echo -E "$url_str"
+}
+
+# URL-decode a string
+#
+# Decodes a RFC 2396 URL-encoded (%-escaped) string.
+# This decodes the '+' and '%' escapes in the input string, and leaves
+# other characters unchanged. Does not enforce that the input is a
+# valid URL-encoded string. This is a convenience to allow callers to
+# pass in a full URL or similar strings and decode them for human
+# presentation.
+#
+# Outputs the encoded string on stdout.
+# Returns nonzero if encoding failed.
+#
+# Usage:
+#   omz_urldecode <urlstring>  - prints decoded string followed by a newline
+function omz_urldecode {
+  emulate -L zsh
+  local encoded_url=$1
+
+  # Work bytewise, since URLs escape UTF-8 octets
+  local caller_encoding=$langinfo[CODESET]
+  local LC_ALL=C
+  export LC_ALL
+
+  # Change + back to ' '
+  local tmp=${encoded_url:gs/+/ /}
+  # Protect other escapes to pass through the printf unchanged
+  tmp=${tmp:gs/\\/\\\\/}
+  # Handle %-escapes by turning them into `\xXX` printf escapes
+  tmp=${tmp:gs/%/\\x/}
+  local decoded="$(printf -- "$tmp")"
+
+  # Now we have a UTF-8 encoded string in the variable. We need to re-encode
+  # it if caller is in a non-UTF-8 locale.
+  local -a safe_encodings
+  safe_encodings=(UTF-8 utf8 US-ASCII)
+  if [[ -z ${safe_encodings[(r)$caller_encoding]} ]]; then
+    decoded=$(echo -E "$decoded" | iconv -f UTF-8 -t $caller_encoding)
+    if [[ $? != 0 ]]; then
+      echo "Error converting string from UTF-8 to $caller_encoding" >&2
+      return 1
+    fi
+  fi
+
+  echo -E "$decoded"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/git.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/git.zsh
new file mode 100644 (file)
index 0000000..be9fa7e
--- /dev/null
@@ -0,0 +1,281 @@
+# The git prompt's git commands are read-only and should not interfere with
+# other processes. This environment variable is equivalent to running with `git
+# --no-optional-locks`, but falls back gracefully for older versions of git.
+# See git(1) for and git-status(1) for a description of that flag.
+#
+# We wrap in a local function instead of exporting the variable directly in
+# order to avoid interfering with manually-run git commands by the user.
+function __git_prompt_git() {
+  GIT_OPTIONAL_LOCKS=0 command git "$@"
+}
+
+function git_prompt_info() {
+  # If we are on a folder not tracked by git, get out.
+  # Otherwise, check for hide-info at global and local repository level
+  if ! __git_prompt_git rev-parse --git-dir &> /dev/null \
+     || [[ "$(__git_prompt_git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then
+    return 0
+  fi
+
+  local ref
+  ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \
+  || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \
+  || return 0
+
+  # Use global ZSH_THEME_GIT_SHOW_UPSTREAM=1 for including upstream remote info
+  local upstream
+  if (( ${+ZSH_THEME_GIT_SHOW_UPSTREAM} )); then
+    upstream=$(__git_prompt_git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) \
+    && upstream=" -> ${upstream}"
+  fi
+
+  echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
+}
+
+# Checks if working tree is dirty
+function parse_git_dirty() {
+  local STATUS
+  local -a FLAGS
+  FLAGS=('--porcelain')
+  if [[ "$(__git_prompt_git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
+    if [[ "${DISABLE_UNTRACKED_FILES_DIRTY:-}" == "true" ]]; then
+      FLAGS+='--untracked-files=no'
+    fi
+    case "${GIT_STATUS_IGNORE_SUBMODULES:-}" in
+      git)
+        # let git decide (this respects per-repo config in .gitmodules)
+        ;;
+      *)
+        # if unset: ignore dirty submodules
+        # other values are passed to --ignore-submodules
+        FLAGS+="--ignore-submodules=${GIT_STATUS_IGNORE_SUBMODULES:-dirty}"
+        ;;
+    esac
+    STATUS=$(__git_prompt_git status ${FLAGS} 2> /dev/null | tail -n 1)
+  fi
+  if [[ -n $STATUS ]]; then
+    echo "$ZSH_THEME_GIT_PROMPT_DIRTY"
+  else
+    echo "$ZSH_THEME_GIT_PROMPT_CLEAN"
+  fi
+}
+
+# Gets the difference between the local and remote branches
+function git_remote_status() {
+    local remote ahead behind git_remote_status git_remote_status_detailed
+    remote=${$(__git_prompt_git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/}
+    if [[ -n ${remote} ]]; then
+        ahead=$(__git_prompt_git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l)
+        behind=$(__git_prompt_git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)
+
+        if [[ $ahead -eq 0 ]] && [[ $behind -eq 0 ]]; then
+            git_remote_status="$ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE"
+        elif [[ $ahead -gt 0 ]] && [[ $behind -eq 0 ]]; then
+            git_remote_status="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE"
+            git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}"
+        elif [[ $behind -gt 0 ]] && [[ $ahead -eq 0 ]]; then
+            git_remote_status="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE"
+            git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
+        elif [[ $ahead -gt 0 ]] && [[ $behind -gt 0 ]]; then
+            git_remote_status="$ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE"
+            git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
+        fi
+
+        if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then
+            git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote:gs/%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
+        fi
+
+        echo $git_remote_status
+    fi
+}
+
+# Outputs the name of the current branch
+# Usage example: git pull origin $(git_current_branch)
+# Using '--quiet' with 'symbolic-ref' will not cause a fatal error (128) if
+# it's not a symbolic ref, but in a Git repo.
+function git_current_branch() {
+  local ref
+  ref=$(__git_prompt_git symbolic-ref --quiet HEAD 2> /dev/null)
+  local ret=$?
+  if [[ $ret != 0 ]]; then
+    [[ $ret == 128 ]] && return  # no git repo.
+    ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) || return
+  fi
+  echo ${ref#refs/heads/}
+}
+
+
+# Gets the number of commits ahead from remote
+function git_commits_ahead() {
+  if __git_prompt_git rev-parse --git-dir &>/dev/null; then
+    local commits="$(__git_prompt_git rev-list --count @{upstream}..HEAD 2>/dev/null)"
+    if [[ -n "$commits" && "$commits" != 0 ]]; then
+      echo "$ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX$commits$ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX"
+    fi
+  fi
+}
+
+# Gets the number of commits behind remote
+function git_commits_behind() {
+  if __git_prompt_git rev-parse --git-dir &>/dev/null; then
+    local commits="$(__git_prompt_git rev-list --count HEAD..@{upstream} 2>/dev/null)"
+    if [[ -n "$commits" && "$commits" != 0 ]]; then
+      echo "$ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX$commits$ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX"
+    fi
+  fi
+}
+
+# Outputs if current branch is ahead of remote
+function git_prompt_ahead() {
+  if [[ -n "$(__git_prompt_git rev-list origin/$(git_current_branch)..HEAD 2> /dev/null)" ]]; then
+    echo "$ZSH_THEME_GIT_PROMPT_AHEAD"
+  fi
+}
+
+# Outputs if current branch is behind remote
+function git_prompt_behind() {
+  if [[ -n "$(__git_prompt_git rev-list HEAD..origin/$(git_current_branch) 2> /dev/null)" ]]; then
+    echo "$ZSH_THEME_GIT_PROMPT_BEHIND"
+  fi
+}
+
+# Outputs if current branch exists on remote or not
+function git_prompt_remote() {
+  if [[ -n "$(__git_prompt_git show-ref origin/$(git_current_branch) 2> /dev/null)" ]]; then
+    echo "$ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS"
+  else
+    echo "$ZSH_THEME_GIT_PROMPT_REMOTE_MISSING"
+  fi
+}
+
+# Formats prompt string for current git commit short SHA
+function git_prompt_short_sha() {
+  local SHA
+  SHA=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
+}
+
+# Formats prompt string for current git commit long SHA
+function git_prompt_long_sha() {
+  local SHA
+  SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
+}
+
+function git_prompt_status() {
+  [[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
+
+  # Maps a git status prefix to an internal constant
+  # This cannot use the prompt constants, as they may be empty
+  local -A prefix_constant_map
+  prefix_constant_map=(
+    '\?\? '     'UNTRACKED'
+    'A  '       'ADDED'
+    'M  '       'ADDED'
+    'MM '       'MODIFIED'
+    ' M '       'MODIFIED'
+    'AM '       'MODIFIED'
+    ' T '       'MODIFIED'
+    'R  '       'RENAMED'
+    ' D '       'DELETED'
+    'D  '       'DELETED'
+    'UU '       'UNMERGED'
+    'ahead'     'AHEAD'
+    'behind'    'BEHIND'
+    'diverged'  'DIVERGED'
+    'stashed'   'STASHED'
+  )
+
+  # Maps the internal constant to the prompt theme
+  local -A constant_prompt_map
+  constant_prompt_map=(
+    'UNTRACKED' "$ZSH_THEME_GIT_PROMPT_UNTRACKED"
+    'ADDED'     "$ZSH_THEME_GIT_PROMPT_ADDED"
+    'MODIFIED'  "$ZSH_THEME_GIT_PROMPT_MODIFIED"
+    'RENAMED'   "$ZSH_THEME_GIT_PROMPT_RENAMED"
+    'DELETED'   "$ZSH_THEME_GIT_PROMPT_DELETED"
+    'UNMERGED'  "$ZSH_THEME_GIT_PROMPT_UNMERGED"
+    'AHEAD'     "$ZSH_THEME_GIT_PROMPT_AHEAD"
+    'BEHIND'    "$ZSH_THEME_GIT_PROMPT_BEHIND"
+    'DIVERGED'  "$ZSH_THEME_GIT_PROMPT_DIVERGED"
+    'STASHED'   "$ZSH_THEME_GIT_PROMPT_STASHED"
+  )
+
+  # The order that the prompt displays should be added to the prompt
+  local status_constants
+  status_constants=(
+    UNTRACKED ADDED MODIFIED RENAMED DELETED
+    STASHED UNMERGED AHEAD BEHIND DIVERGED
+  )
+
+  local status_text
+  status_text="$(__git_prompt_git status --porcelain -b 2> /dev/null)"
+
+  # Don't continue on a catastrophic failure
+  if [[ $? -eq 128 ]]; then
+    return 1
+  fi
+
+  # A lookup table of each git status encountered
+  local -A statuses_seen
+
+  if __git_prompt_git rev-parse --verify refs/stash &>/dev/null; then
+    statuses_seen[STASHED]=1
+  fi
+
+  local status_lines
+  status_lines=("${(@f)${status_text}}")
+
+  # If the tracking line exists, get and parse it
+  if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then
+    local branch_statuses
+    branch_statuses=("${(@s/,/)match}")
+    for branch_status in $branch_statuses; do
+      if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then
+        continue
+      fi
+      local last_parsed_status=$prefix_constant_map[$match[1]]
+      statuses_seen[$last_parsed_status]=$match[2]
+    done
+  fi
+
+  # For each status prefix, do a regex comparison
+  for status_prefix in ${(k)prefix_constant_map}; do
+    local status_constant="${prefix_constant_map[$status_prefix]}"
+    local status_regex=$'(^|\n)'"$status_prefix"
+
+    if [[ "$status_text" =~ $status_regex ]]; then
+      statuses_seen[$status_constant]=1
+    fi
+  done
+
+  # Display the seen statuses in the order specified
+  local status_prompt
+  for status_constant in $status_constants; do
+    if (( ${+statuses_seen[$status_constant]} )); then
+      local next_display=$constant_prompt_map[$status_constant]
+      status_prompt="$next_display$status_prompt"
+    fi
+  done
+
+  echo $status_prompt
+}
+
+# Outputs the name of the current user
+# Usage example: $(git_current_user_name)
+function git_current_user_name() {
+  __git_prompt_git config user.name 2>/dev/null
+}
+
+# Outputs the email of the current user
+# Usage example: $(git_current_user_email)
+function git_current_user_email() {
+  __git_prompt_git config user.email 2>/dev/null
+}
+
+# Output the name of the root directory of the git repository
+# Usage example: $(git_repo_name)
+function git_repo_name() {
+  local repo_path
+  if repo_path="$(__git_prompt_git rev-parse --show-toplevel 2>/dev/null)" && [[ -n "$repo_path" ]]; then
+    echo ${repo_path:t}
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/grep.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/grep.zsh
new file mode 100644 (file)
index 0000000..54e0f69
--- /dev/null
@@ -0,0 +1,41 @@
+__GREP_CACHE_FILE="$ZSH_CACHE_DIR"/grep-alias
+
+# See if there's a cache file modified in the last day
+__GREP_ALIAS_CACHES=("$__GREP_CACHE_FILE"(Nm-1))
+if [[ -n "$__GREP_ALIAS_CACHES" ]]; then
+    source "$__GREP_CACHE_FILE"
+else
+    grep-flags-available() {
+        command grep "$@" "" &>/dev/null <<< ""
+    }
+
+    # Ignore these folders (if the necessary grep flags are available)
+    EXC_FOLDERS="{.bzr,CVS,.git,.hg,.svn,.idea,.tox}"
+
+    # Check for --exclude-dir, otherwise check for --exclude. If --exclude
+    # isn't available, --color won't be either (they were released at the same
+    # time (v2.5): https://git.savannah.gnu.org/cgit/grep.git/tree/NEWS?id=1236f007
+    if grep-flags-available --color=auto --exclude-dir=.cvs; then
+        GREP_OPTIONS="--color=auto --exclude-dir=$EXC_FOLDERS"
+    elif grep-flags-available --color=auto --exclude=.cvs; then
+        GREP_OPTIONS="--color=auto --exclude=$EXC_FOLDERS"
+    fi
+
+    if [[ -n "$GREP_OPTIONS" ]]; then
+        # export grep, egrep and fgrep settings
+        alias grep="grep $GREP_OPTIONS"
+        alias egrep="grep -E $GREP_OPTIONS"
+        alias fgrep="grep -F $GREP_OPTIONS"
+
+        # write to cache file if cache directory is writable
+        if [[ -w "$ZSH_CACHE_DIR" ]]; then
+            alias -L grep egrep fgrep >| "$__GREP_CACHE_FILE"
+        fi
+    fi
+
+    # Clean up
+    unset GREP_OPTIONS EXC_FOLDERS
+    unfunction grep-flags-available
+fi
+
+unset __GREP_CACHE_FILE __GREP_ALIAS_CACHES
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/history.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/history.zsh
new file mode 100644 (file)
index 0000000..7940769
--- /dev/null
@@ -0,0 +1,40 @@
+## History wrapper
+function omz_history {
+  local clear list
+  zparseopts -E c=clear l=list
+
+  if [[ -n "$clear" ]]; then
+    # if -c provided, clobber the history file
+    echo -n >| "$HISTFILE"
+    fc -p "$HISTFILE"
+    echo >&2 History file deleted.
+  elif [[ -n "$list" ]]; then
+    # if -l provided, run as if calling `fc' directly
+    builtin fc "$@"
+  else
+    # unless a number is provided, show all history events (starting from 1)
+    [[ ${@[-1]-} = *[0-9]* ]] && builtin fc -l "$@" || builtin fc -l "$@" 1
+  fi
+}
+
+# Timestamp format
+case ${HIST_STAMPS-} in
+  "mm/dd/yyyy") alias history='omz_history -f' ;;
+  "dd.mm.yyyy") alias history='omz_history -E' ;;
+  "yyyy-mm-dd") alias history='omz_history -i' ;;
+  "") alias history='omz_history' ;;
+  *) alias history="omz_history -t '$HIST_STAMPS'" ;;
+esac
+
+## History file configuration
+[ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history"
+[ "$HISTSIZE" -lt 50000 ] && HISTSIZE=50000
+[ "$SAVEHIST" -lt 10000 ] && SAVEHIST=10000
+
+## History command configuration
+setopt extended_history       # record timestamp of command in HISTFILE
+setopt hist_expire_dups_first # delete duplicates first when HISTFILE size exceeds HISTSIZE
+setopt hist_ignore_dups       # ignore duplicated commands history list
+setopt hist_ignore_space      # ignore commands that start with space
+setopt hist_verify            # show command with history expansion to user before running it
+setopt share_history          # share command history data
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/key-bindings.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/key-bindings.zsh
new file mode 100644 (file)
index 0000000..aaa7304
--- /dev/null
@@ -0,0 +1,138 @@
+# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html
+# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Builtins
+# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Standard-Widgets
+
+# Make sure that the terminal is in application mode when zle is active, since
+# only then values from $terminfo are valid
+if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
+  function zle-line-init() {
+    echoti smkx
+  }
+  function zle-line-finish() {
+    echoti rmkx
+  }
+  zle -N zle-line-init
+  zle -N zle-line-finish
+fi
+
+# Use emacs key bindings
+bindkey -e
+
+# [PageUp] - Up a line of history
+if [[ -n "${terminfo[kpp]}" ]]; then
+  bindkey -M emacs "${terminfo[kpp]}" up-line-or-history
+  bindkey -M viins "${terminfo[kpp]}" up-line-or-history
+  bindkey -M vicmd "${terminfo[kpp]}" up-line-or-history
+fi
+# [PageDown] - Down a line of history
+if [[ -n "${terminfo[knp]}" ]]; then
+  bindkey -M emacs "${terminfo[knp]}" down-line-or-history
+  bindkey -M viins "${terminfo[knp]}" down-line-or-history
+  bindkey -M vicmd "${terminfo[knp]}" down-line-or-history
+fi
+
+# Start typing + [Up-Arrow] - fuzzy find history forward
+if [[ -n "${terminfo[kcuu1]}" ]]; then
+  autoload -U up-line-or-beginning-search
+  zle -N up-line-or-beginning-search
+
+  bindkey -M emacs "${terminfo[kcuu1]}" up-line-or-beginning-search
+  bindkey -M viins "${terminfo[kcuu1]}" up-line-or-beginning-search
+  bindkey -M vicmd "${terminfo[kcuu1]}" up-line-or-beginning-search
+fi
+# Start typing + [Down-Arrow] - fuzzy find history backward
+if [[ -n "${terminfo[kcud1]}" ]]; then
+  autoload -U down-line-or-beginning-search
+  zle -N down-line-or-beginning-search
+
+  bindkey -M emacs "${terminfo[kcud1]}" down-line-or-beginning-search
+  bindkey -M viins "${terminfo[kcud1]}" down-line-or-beginning-search
+  bindkey -M vicmd "${terminfo[kcud1]}" down-line-or-beginning-search
+fi
+
+# [Home] - Go to beginning of line
+if [[ -n "${terminfo[khome]}" ]]; then
+  bindkey -M emacs "${terminfo[khome]}" beginning-of-line
+  bindkey -M viins "${terminfo[khome]}" beginning-of-line
+  bindkey -M vicmd "${terminfo[khome]}" beginning-of-line
+fi
+# [End] - Go to end of line
+if [[ -n "${terminfo[kend]}" ]]; then
+  bindkey -M emacs "${terminfo[kend]}"  end-of-line
+  bindkey -M viins "${terminfo[kend]}"  end-of-line
+  bindkey -M vicmd "${terminfo[kend]}"  end-of-line
+fi
+
+# [Shift-Tab] - move through the completion menu backwards
+if [[ -n "${terminfo[kcbt]}" ]]; then
+  bindkey -M emacs "${terminfo[kcbt]}" reverse-menu-complete
+  bindkey -M viins "${terminfo[kcbt]}" reverse-menu-complete
+  bindkey -M vicmd "${terminfo[kcbt]}" reverse-menu-complete
+fi
+
+# [Backspace] - delete backward
+bindkey -M emacs '^?' backward-delete-char
+bindkey -M viins '^?' backward-delete-char
+bindkey -M vicmd '^?' backward-delete-char
+# [Delete] - delete forward
+if [[ -n "${terminfo[kdch1]}" ]]; then
+  bindkey -M emacs "${terminfo[kdch1]}" delete-char
+  bindkey -M viins "${terminfo[kdch1]}" delete-char
+  bindkey -M vicmd "${terminfo[kdch1]}" delete-char
+else
+  bindkey -M emacs "^[[3~" delete-char
+  bindkey -M viins "^[[3~" delete-char
+  bindkey -M vicmd "^[[3~" delete-char
+
+  bindkey -M emacs "^[3;5~" delete-char
+  bindkey -M viins "^[3;5~" delete-char
+  bindkey -M vicmd "^[3;5~" delete-char
+fi
+
+# [Ctrl-Delete] - delete whole forward-word
+bindkey -M emacs '^[[3;5~' kill-word
+bindkey -M viins '^[[3;5~' kill-word
+bindkey -M vicmd '^[[3;5~' kill-word
+
+# [Ctrl-RightArrow] - move forward one word
+bindkey -M emacs '^[[1;5C' forward-word
+bindkey -M viins '^[[1;5C' forward-word
+bindkey -M vicmd '^[[1;5C' forward-word
+# [Ctrl-LeftArrow] - move backward one word
+bindkey -M emacs '^[[1;5D' backward-word
+bindkey -M viins '^[[1;5D' backward-word
+bindkey -M vicmd '^[[1;5D' backward-word
+
+
+bindkey '\ew' kill-region                             # [Esc-w] - Kill from the cursor to the mark
+bindkey -s '\el' 'ls\n'                               # [Esc-l] - run command: ls
+bindkey '^r' history-incremental-search-backward      # [Ctrl-r] - Search backward incrementally for a specified string. The string may begin with ^ to anchor the search to the beginning of the line.
+bindkey ' ' magic-space                               # [Space] - don't do history expansion
+
+
+# Edit the current command line in $EDITOR
+autoload -U edit-command-line
+zle -N edit-command-line
+bindkey '\C-x\C-e' edit-command-line
+
+# file rename magick
+bindkey "^[m" copy-prev-shell-word
+
+# consider emacs keybindings:
+
+#bindkey -e  ## emacs key bindings
+#
+#bindkey '^[[A' up-line-or-search
+#bindkey '^[[B' down-line-or-search
+#bindkey '^[^[[C' emacs-forward-word
+#bindkey '^[^[[D' emacs-backward-word
+#
+#bindkey -s '^X^Z' '%-^M'
+#bindkey '^[e' expand-cmd-path
+#bindkey '^[^I' reverse-menu-complete
+#bindkey '^X^N' accept-and-infer-next-history
+#bindkey '^W' kill-region
+#bindkey '^I' complete-word
+## Fix weird sequence that rxvt produces
+#bindkey -s '^[[Z' '\t'
+#
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/misc.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/misc.zsh
new file mode 100644 (file)
index 0000000..1f63708
--- /dev/null
@@ -0,0 +1,35 @@
+autoload -Uz is-at-least
+
+# *-magic is known buggy in some versions; disable if so
+if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then
+  for d in $fpath; do
+    if [[ -e "$d/url-quote-magic" ]]; then
+      if is-at-least 5.1; then
+        autoload -Uz bracketed-paste-magic
+        zle -N bracketed-paste bracketed-paste-magic
+      fi
+      autoload -Uz url-quote-magic
+      zle -N self-insert url-quote-magic
+    break
+    fi
+  done
+fi
+
+## jobs
+setopt long_list_jobs
+
+env_default 'PAGER' 'less'
+env_default 'LESS' '-R'
+
+## super user alias
+alias _='sudo '
+
+## more intelligent acking for ubuntu users and no alias for users without ack
+if (( $+commands[ack-grep] )); then
+  alias afind='ack-grep -il'
+elif (( $+commands[ack] )); then
+  alias afind='ack -il'
+fi
+
+# recognize comments
+setopt interactivecomments
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/nvm.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/nvm.zsh
new file mode 100644 (file)
index 0000000..a8989f9
--- /dev/null
@@ -0,0 +1,6 @@
+# get the nvm-controlled node.js version
+function nvm_prompt_info() {
+  which nvm &>/dev/null || return
+  local nvm_prompt=${$(nvm current)#v}
+  echo "${ZSH_THEME_NVM_PROMPT_PREFIX}${nvm_prompt:gs/%/%%}${ZSH_THEME_NVM_PROMPT_SUFFIX}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/prompt_info_functions.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/prompt_info_functions.zsh
new file mode 100644 (file)
index 0000000..e553584
--- /dev/null
@@ -0,0 +1,43 @@
+# *_prompt_info functions for usage in your prompt
+#
+# Plugin creators, please add your *_prompt_info function to the list
+# of dummy implementations to help theme creators not receiving errors
+# without the need of implementing conditional clauses.
+#
+# See also lib/bzr.zsh, lib/git.zsh and lib/nvm.zsh for
+# git_prompt_info, bzr_prompt_info and nvm_prompt_info
+
+# Dummy implementations that return false to prevent command_not_found
+# errors with themes, that implement these functions
+# Real implementations will be used when the respective plugins are loaded
+function chruby_prompt_info \
+  rbenv_prompt_info \
+  hg_prompt_info \
+  pyenv_prompt_info \
+  svn_prompt_info \
+  vi_mode_prompt_info \
+  virtualenv_prompt_info \
+  jenv_prompt_info \
+  tf_prompt_info \
+{
+  return 1
+}
+
+# oh-my-zsh supports an rvm prompt by default
+# get the name of the rvm ruby version
+function rvm_prompt_info() {
+  [ -f $HOME/.rvm/bin/rvm-prompt ] || return 1
+  local rvm_prompt
+  rvm_prompt=$($HOME/.rvm/bin/rvm-prompt ${=ZSH_THEME_RVM_PROMPT_OPTIONS} 2>/dev/null)
+  [[ -z "${rvm_prompt}" ]] && return 1
+  echo "${ZSH_THEME_RUBY_PROMPT_PREFIX}${rvm_prompt:gs/%/%%}${ZSH_THEME_RUBY_PROMPT_SUFFIX}"
+}
+
+ZSH_THEME_RVM_PROMPT_OPTIONS="i v g"
+
+
+# use this to enable users to see their ruby version, no matter which
+# version management system they use
+function ruby_prompt_info() {
+  echo $(rvm_prompt_info || rbenv_prompt_info || chruby_prompt_info)
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/spectrum.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/spectrum.zsh
new file mode 100644 (file)
index 0000000..97f5c36
--- /dev/null
@@ -0,0 +1,37 @@
+# A script to make using 256 colors in zsh less painful.
+# P.C. Shyamshankar <sykora@lucentbeing.com>
+# Copied from https://github.com/sykora/etc/blob/master/zsh/functions/spectrum/
+
+typeset -AHg FX FG BG
+
+FX=(
+  reset     "%{\e[00m%}"
+  bold      "%{\e[01m%}" no-bold      "%{\e[22m%}"
+  italic    "%{\e[03m%}" no-italic    "%{\e[23m%}"
+  underline "%{\e[04m%}" no-underline "%{\e[24m%}"
+  blink     "%{\e[05m%}" no-blink     "%{\e[25m%}"
+  reverse   "%{\e[07m%}" no-reverse   "%{\e[27m%}"
+)
+
+for color in {000..255}; do
+  FG[$color]="%{\e[38;5;${color}m%}"
+  BG[$color]="%{\e[48;5;${color}m%}"
+done
+
+# Show all 256 colors with color number
+function spectrum_ls() {
+  setopt localoptions nopromptsubst
+  local ZSH_SPECTRUM_TEXT=${ZSH_SPECTRUM_TEXT:-Arma virumque cano Troiae qui primus ab oris}
+  for code in {000..255}; do
+    print -P -- "$code: ${FG[$code]}${ZSH_SPECTRUM_TEXT}%{$reset_color%}"
+  done
+}
+
+# Show all 256 colors where the background is set to specific color
+function spectrum_bls() {
+  setopt localoptions nopromptsubst
+  local ZSH_SPECTRUM_TEXT=${ZSH_SPECTRUM_TEXT:-Arma virumque cano Troiae qui primus ab oris}
+  for code in {000..255}; do
+    print -P -- "$code: ${BG[$code]}${ZSH_SPECTRUM_TEXT}%{$reset_color%}"
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/termsupport.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/termsupport.zsh
new file mode 100644 (file)
index 0000000..80ca7ef
--- /dev/null
@@ -0,0 +1,136 @@
+# Set terminal window and tab/icon title
+#
+# usage: title short_tab_title [long_window_title]
+#
+# See: http://www.faqs.org/docs/Linux-mini/Xterm-Title.html#ss3.1
+# Fully supports screen, iterm, and probably most modern xterm and rxvt
+# (In screen, only short_tab_title is used)
+# Limited support for Apple Terminal (Terminal can't set window and tab separately)
+function title {
+  setopt localoptions nopromptsubst
+
+  # Don't set the title if inside emacs, unless using vterm
+  [[ -n "${INSIDE_EMACS:-}" && "$INSIDE_EMACS" != vterm ]] && return
+
+  # if $2 is unset use $1 as default
+  # if it is set and empty, leave it as is
+  : ${2=$1}
+
+  case "$TERM" in
+    cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty|st*|foot)
+      print -Pn "\e]2;${2:q}\a" # set window name
+      print -Pn "\e]1;${1:q}\a" # set tab name
+      ;;
+    screen*|tmux*)
+      print -Pn "\ek${1:q}\e\\" # set screen hardstatus
+      ;;
+    *)
+      if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then
+        print -Pn "\e]2;${2:q}\a" # set window name
+        print -Pn "\e]1;${1:q}\a" # set tab name
+      else
+        # Try to use terminfo to set the title if the feature is available
+        if (( ${+terminfo[fsl]} && ${+terminfo[tsl]} )); then
+          print -Pn "${terminfo[tsl]}$1${terminfo[fsl]}"
+        fi
+      fi
+      ;;
+  esac
+}
+
+ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<" #15 char left truncated PWD
+ZSH_THEME_TERM_TITLE_IDLE="%n@%m:%~"
+# Avoid duplication of directory in terminals with independent dir display
+if [[ "$TERM_PROGRAM" == Apple_Terminal ]]; then
+  ZSH_THEME_TERM_TITLE_IDLE="%n@%m"
+fi
+
+# Runs before showing the prompt
+function omz_termsupport_precmd {
+  [[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return
+  title "$ZSH_THEME_TERM_TAB_TITLE_IDLE" "$ZSH_THEME_TERM_TITLE_IDLE"
+}
+
+# Runs before executing the command
+function omz_termsupport_preexec {
+  [[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return
+
+  emulate -L zsh
+  setopt extended_glob
+
+  # split command into array of arguments
+  local -a cmdargs
+  cmdargs=("${(z)2}")
+  # if running fg, extract the command from the job description
+  if [[ "${cmdargs[1]}" = fg ]]; then
+    # get the job id from the first argument passed to the fg command
+    local job_id jobspec="${cmdargs[2]#%}"
+    # logic based on jobs arguments:
+    # http://zsh.sourceforge.net/Doc/Release/Jobs-_0026-Signals.html#Jobs
+    # https://www.zsh.org/mla/users/2007/msg00704.html
+    case "$jobspec" in
+      <->) # %number argument:
+        # use the same <number> passed as an argument
+        job_id=${jobspec} ;;
+      ""|%|+) # empty, %% or %+ argument:
+        # use the current job, which appears with a + in $jobstates:
+        # suspended:+:5071=suspended (tty output)
+        job_id=${(k)jobstates[(r)*:+:*]} ;;
+      -) # %- argument:
+        # use the previous job, which appears with a - in $jobstates:
+        # suspended:-:6493=suspended (signal)
+        job_id=${(k)jobstates[(r)*:-:*]} ;;
+      [?]*) # %?string argument:
+        # use $jobtexts to match for a job whose command *contains* <string>
+        job_id=${(k)jobtexts[(r)*${(Q)jobspec}*]} ;;
+      *) # %string argument:
+        # use $jobtexts to match for a job whose command *starts with* <string>
+        job_id=${(k)jobtexts[(r)${(Q)jobspec}*]} ;;
+    esac
+
+    # override preexec function arguments with job command
+    if [[ -n "${jobtexts[$job_id]}" ]]; then
+      1="${jobtexts[$job_id]}"
+      2="${jobtexts[$job_id]}"
+    fi
+  fi
+
+  # cmd name only, or if this is sudo or ssh, the next cmd
+  local CMD="${1[(wr)^(*=*|sudo|ssh|mosh|rake|-*)]:gs/%/%%}"
+  local LINE="${2:gs/%/%%}"
+
+  title "$CMD" "%100>...>${LINE}%<<"
+}
+
+autoload -Uz add-zsh-hook
+
+if [[ -z "$INSIDE_EMACS" || "$INSIDE_EMACS" = vterm ]]; then
+  add-zsh-hook precmd omz_termsupport_precmd
+  add-zsh-hook preexec omz_termsupport_preexec
+fi
+
+# Keep Apple Terminal.app's current working directory updated
+# Based on this answer: https://superuser.com/a/315029
+# With extra fixes to handle multibyte chars and non-UTF-8 locales
+
+if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then
+  # Emits the control sequence to notify Terminal.app of the cwd
+  # Identifies the directory using a file: URI scheme, including
+  # the host name to disambiguate local vs. remote paths.
+  function update_terminalapp_cwd() {
+    emulate -L zsh
+
+    # Percent-encode the host and path names.
+    local URL_HOST URL_PATH
+    URL_HOST="$(omz_urlencode -P $HOST)" || return 1
+    URL_PATH="$(omz_urlencode -P $PWD)" || return 1
+
+    # Undocumented Terminal.app-specific control sequence
+    printf '\e]7;%s\a' "file://$URL_HOST$URL_PATH"
+  }
+
+  # Use a precmd hook instead of a chpwd hook to avoid contaminating output
+  add-zsh-hook precmd update_terminalapp_cwd
+  # Run once to get initial cwd set
+  update_terminalapp_cwd
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/theme-and-appearance.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/theme-and-appearance.zsh
new file mode 100644 (file)
index 0000000..00947f7
--- /dev/null
@@ -0,0 +1,59 @@
+# ls colors
+autoload -U colors && colors
+
+# Enable ls colors
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
+
+# TODO organise this chaotic logic
+
+if [[ "$DISABLE_LS_COLORS" != "true" ]]; then
+  # Find the option for using colors in ls, depending on the version
+  if [[ "$OSTYPE" == netbsd* ]]; then
+    # On NetBSD, test if "gls" (GNU ls) is installed (this one supports colors);
+    # otherwise, leave ls as is, because NetBSD's ls doesn't support -G
+    gls --color -d . &>/dev/null && alias ls='gls --color=tty'
+  elif [[ "$OSTYPE" == openbsd* ]]; then
+    # On OpenBSD, "gls" (ls from GNU coreutils) and "colorls" (ls from base,
+    # with color and multibyte support) are available from ports.  "colorls"
+    # will be installed on purpose and can't be pulled in by installing
+    # coreutils, so prefer it to "gls".
+    gls --color -d . &>/dev/null && alias ls='gls --color=tty'
+    colorls -G -d . &>/dev/null && alias ls='colorls -G'
+  elif [[ "$OSTYPE" == (darwin|freebsd)* ]]; then
+    # this is a good alias, it works by default just using $LSCOLORS
+    ls -G . &>/dev/null && alias ls='ls -G'
+
+    # only use coreutils ls if there is a dircolors customization present ($LS_COLORS or .dircolors file)
+    # otherwise, gls will use the default color scheme which is ugly af
+    [[ -n "$LS_COLORS" || -f "$HOME/.dircolors" ]] && gls --color -d . &>/dev/null && alias ls='gls --color=tty'
+  else
+    # For GNU ls, we use the default ls color theme. They can later be overwritten by themes.
+    if [[ -z "$LS_COLORS" ]]; then
+      (( $+commands[dircolors] )) && eval "$(dircolors -b)"
+    fi
+
+    ls --color -d . &>/dev/null && alias ls='ls --color=tty' || { ls -G . &>/dev/null && alias ls='ls -G' }
+
+    # Take advantage of $LS_COLORS for completion as well.
+    zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
+  fi
+fi
+
+# enable diff color if possible.
+if command diff --color /dev/null /dev/null &>/dev/null; then
+  alias diff='diff --color'
+fi
+
+setopt auto_cd
+setopt multios
+setopt prompt_subst
+
+[[ -n "$WINDOW" ]] && SCREEN_NO="%B$WINDOW%b " || SCREEN_NO=""
+
+# git theming default: Variables for theming the git info prompt
+ZSH_THEME_GIT_PROMPT_PREFIX="git:("         # Prefix at the very beginning of the prompt, before the branch name
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"             # At the very end of the prompt
+ZSH_THEME_GIT_PROMPT_DIRTY="*"              # Text to display if the branch is dirty
+ZSH_THEME_GIT_PROMPT_CLEAN=""               # Text to display if the branch is clean
+ZSH_THEME_RUBY_PROMPT_PREFIX="("
+ZSH_THEME_RUBY_PROMPT_SUFFIX=")"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/lib/vcs_info.zsh b/stow/oh-my-zsh/.oh-my-zsh/lib/vcs_info.zsh
new file mode 100644 (file)
index 0000000..e60938c
--- /dev/null
@@ -0,0 +1,53 @@
+# Don't skip this file until a Zsh release does the necessary quoting.
+# This is because even though 5.8.1 undid recursive prompt_subst inside
+# prompt sequences, % characters in relevant fields will still be rendered
+# incorrectly in vcs_info, on all Zsh releases up to writing this.
+#
+# There is no release yet that does this right, since it requires changing
+# how what vcs_info hooks expect to receive. Even so, I'd rather be correct
+# and break custom vcs_info hooks than have a broken prompt.
+
+# Quote necessary $hook_com[<field>] items just before they are used
+# in the line "VCS_INFO_hook 'post-backend'" of the VCS_INFO_formats
+# function, where <field> is:
+#
+#   base:       the full path of the repository's root directory.
+#   base-name:  the name of the repository's root directory.
+#   branch:     the name of the currently checked out branch.
+#   misc:       a string that may contain anything the vcs_info backend wants.
+#   revision:   an identifier of the currently checked out revision.
+#   subdir:     the path of the current directory relative to the
+#               repository's root directory.
+#
+# This patch %-quotes these fields previous to their use in vcs_info hooks and
+# the zformat call and, eventually, when they get expanded in the prompt.
+# It's important to quote these here, and not later after hooks have modified the
+# fields, because then we could be quoting % characters from valid prompt sequences,
+# like %F{color}, %B, etc.
+#
+#  32   │ hook_com[subdir]="$(VCS_INFO_reposub ${hook_com[base]})"
+#  33   │ hook_com[subdir_orig]="${hook_com[subdir]}"
+#  34   │
+#  35 + │ for tmp in base base-name branch misc revision subdir; do
+#  36 + │     hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"
+#  37 + │ done
+#  38 + │
+#  39   │ VCS_INFO_hook 'post-backend'
+#
+# This is especially important so that no command substitution is performed
+# due to malicious input as a consequence of CVE-2021-45444, which affects
+# zsh versions from 5.0.3 to 5.8.
+#
+autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return
+
+# We use $tmp here because it's already a local variable in VCS_INFO_formats
+typeset PATCH='for tmp (base base-name branch misc revision subdir) hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"'
+# Unique string to avoid reapplying the patch if this code gets called twice
+typeset PATCH_ID=vcs_info-patch-9b9840f2-91e5-4471-af84-9e9a0dc68c1b
+# Only patch the VCS_INFO_formats function if not already patched
+if [[ "$functions[VCS_INFO_formats]" != *$PATCH_ID* ]]; then
+  regexp-replace 'functions[VCS_INFO_formats]' \
+    "VCS_INFO_hook 'post-backend'" \
+    ': ${PATCH_ID}; ${PATCH}; ${MATCH}'
+fi
+unset PATCH PATCH_ID
diff --git a/stow/oh-my-zsh/.oh-my-zsh/oh-my-zsh.sh b/stow/oh-my-zsh/.oh-my-zsh/oh-my-zsh.sh
new file mode 100644 (file)
index 0000000..29d39ca
--- /dev/null
@@ -0,0 +1,190 @@
+# Protect against non-zsh execution of Oh My Zsh (use POSIX syntax here)
+[ -n "$ZSH_VERSION" ] || {
+  # ANSI formatting function (\033[<code>m)
+  # 0: reset, 1: bold, 4: underline, 22: no bold, 24: no underline, 31: red, 33: yellow
+  omz_f() {
+    [ $# -gt 0 ] || return
+    IFS=";" printf "\033[%sm" $*
+  }
+  # If stdout is not a terminal ignore all formatting
+  [ -t 1 ] || omz_f() { :; }
+
+  omz_ptree() {
+    # Get process tree of the current process
+    pid=$$; pids="$pid"
+    while [ ${pid-0} -ne 1 ] && ppid=$(ps -e -o pid,ppid | awk "\$1 == $pid { print \$2 }"); do
+      pids="$pids $pid"; pid=$ppid
+    done
+
+    # Show process tree
+    case "$(uname)" in
+    Linux) ps -o ppid,pid,command -f -p $pids 2>/dev/null ;;
+    Darwin|*) ps -o ppid,pid,command -p $pids 2>/dev/null ;;
+    esac
+
+    # If ps command failed, try Busybox ps
+    [ $? -eq 0 ] || ps -o ppid,pid,comm | awk "NR == 1 || index(\"$pids\", \$2) != 0"
+  }
+
+  {
+    shell=$(ps -o pid,comm | awk "\$1 == $$ { print \$2 }")
+    printf "$(omz_f 1 31)Error:$(omz_f 22) Oh My Zsh can't be loaded from: $(omz_f 1)${shell}$(omz_f 22). "
+    printf "You need to run $(omz_f 1)zsh$(omz_f 22) instead.$(omz_f 0)\n"
+    printf "$(omz_f 33)Here's the process tree:$(omz_f 22)\n\n"
+    omz_ptree
+    printf "$(omz_f 0)\n"
+  } >&2
+
+  return 1
+}
+
+# If ZSH is not defined, use the current script's directory.
+[[ -z "$ZSH" ]] && export ZSH="${${(%):-%x}:a:h}"
+
+# Set ZSH_CACHE_DIR to the path where cache files should be created
+# or else we will use the default cache/
+if [[ -z "$ZSH_CACHE_DIR" ]]; then
+  ZSH_CACHE_DIR="$ZSH/cache"
+fi
+
+# Make sure $ZSH_CACHE_DIR is writable, otherwise use a directory in $HOME
+if [[ ! -w "$ZSH_CACHE_DIR" ]]; then
+  ZSH_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh"
+fi
+
+# Create cache and completions dir and add to $fpath
+mkdir -p "$ZSH_CACHE_DIR/completions"
+(( ${fpath[(Ie)"$ZSH_CACHE_DIR/completions"]} )) || fpath=("$ZSH_CACHE_DIR/completions" $fpath)
+
+# Check for updates on initial load...
+if [[ "$DISABLE_AUTO_UPDATE" != true ]]; then
+  source "$ZSH/tools/check_for_upgrade.sh"
+fi
+
+# Initializes Oh My Zsh
+
+# add a function path
+fpath=("$ZSH/functions" "$ZSH/completions" $fpath)
+
+# Load all stock functions (from $fpath files) called below.
+autoload -U compaudit compinit zrecompile
+
+# Set ZSH_CUSTOM to the path where your custom config files
+# and plugins exists, or else we will use the default custom/
+if [[ -z "$ZSH_CUSTOM" ]]; then
+    ZSH_CUSTOM="$ZSH/custom"
+fi
+
+is_plugin() {
+  local base_dir=$1
+  local name=$2
+  builtin test -f $base_dir/plugins/$name/$name.plugin.zsh \
+    || builtin test -f $base_dir/plugins/$name/_$name
+}
+
+# Add all defined plugins to fpath. This must be done
+# before running compinit.
+for plugin ($plugins); do
+  if is_plugin "$ZSH_CUSTOM" "$plugin"; then
+    fpath=("$ZSH_CUSTOM/plugins/$plugin" $fpath)
+  elif is_plugin "$ZSH" "$plugin"; then
+    fpath=("$ZSH/plugins/$plugin" $fpath)
+  else
+    echo "[oh-my-zsh] plugin '$plugin' not found"
+  fi
+done
+
+# Figure out the SHORT hostname
+if [[ "$OSTYPE" = darwin* ]]; then
+  # macOS's $HOST changes with dhcp, etc. Use ComputerName if possible.
+  SHORT_HOST=$(scutil --get ComputerName 2>/dev/null) || SHORT_HOST="${HOST/.*/}"
+else
+  SHORT_HOST="${HOST/.*/}"
+fi
+
+# Save the location of the current completion dump file.
+if [[ -z "$ZSH_COMPDUMP" ]]; then
+  ZSH_COMPDUMP="${ZDOTDIR:-$HOME}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"
+fi
+
+# Construct zcompdump OMZ metadata
+zcompdump_revision="#omz revision: $(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)"
+zcompdump_fpath="#omz fpath: $fpath"
+
+# Delete the zcompdump file if OMZ zcompdump metadata changed
+if ! command grep -q -Fx "$zcompdump_revision" "$ZSH_COMPDUMP" 2>/dev/null \
+   || ! command grep -q -Fx "$zcompdump_fpath" "$ZSH_COMPDUMP" 2>/dev/null; then
+  command rm -f "$ZSH_COMPDUMP"
+  zcompdump_refresh=1
+fi
+
+if [[ "$ZSH_DISABLE_COMPFIX" != true ]]; then
+  source "$ZSH/lib/compfix.zsh"
+  # Load only from secure directories
+  compinit -i -d "$ZSH_COMPDUMP"
+  # If completion insecurities exist, warn the user
+  handle_completion_insecurities &|
+else
+  # If the user wants it, load from all found directories
+  compinit -u -d "$ZSH_COMPDUMP"
+fi
+
+# Append zcompdump metadata if missing
+if (( $zcompdump_refresh )) \
+  || ! command grep -q -Fx "$zcompdump_revision" "$ZSH_COMPDUMP" 2>/dev/null; then
+  # Use `tee` in case the $ZSH_COMPDUMP filename is invalid, to silence the error
+  # See https://github.com/ohmyzsh/ohmyzsh/commit/dd1a7269#commitcomment-39003489
+  tee -a "$ZSH_COMPDUMP" &>/dev/null <<EOF
+
+$zcompdump_revision
+$zcompdump_fpath
+EOF
+fi
+unset zcompdump_revision zcompdump_fpath zcompdump_refresh
+
+# zcompile the completion dump file if the .zwc is older or missing.
+zrecompile -q -p "$ZSH_COMPDUMP" && command rm -f "$ZSH_COMPDUMP.zwc.old"
+
+# Load all of the config files in ~/oh-my-zsh that end in .zsh
+# TIP: Add files you don't want in git to .gitignore
+for config_file ("$ZSH"/lib/*.zsh); do
+  custom_config_file="$ZSH_CUSTOM/lib/${config_file:t}"
+  [[ -f "$custom_config_file" ]] && config_file="$custom_config_file"
+  source "$config_file"
+done
+unset custom_config_file
+
+# Load all of the plugins that were defined in ~/.zshrc
+for plugin ($plugins); do
+  if [[ -f "$ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh" ]]; then
+    source "$ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh"
+  elif [[ -f "$ZSH/plugins/$plugin/$plugin.plugin.zsh" ]]; then
+    source "$ZSH/plugins/$plugin/$plugin.plugin.zsh"
+  fi
+done
+unset plugin
+
+# Load all of your custom configurations from custom/
+for config_file ("$ZSH_CUSTOM"/*.zsh(N)); do
+  source "$config_file"
+done
+unset config_file
+
+# Load the theme
+is_theme() {
+  local base_dir=$1
+  local name=$2
+  builtin test -f $base_dir/$name.zsh-theme
+}
+
+if [[ -n "$ZSH_THEME" ]]; then
+  if is_theme "$ZSH_CUSTOM" "$ZSH_THEME"; then
+    source "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme"
+  elif is_theme "$ZSH_CUSTOM/themes" "$ZSH_THEME"; then
+    source "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme"
+  elif is_theme "$ZSH/themes" "$ZSH_THEME"; then
+    source "$ZSH/themes/$ZSH_THEME.zsh-theme"
+  else
+    echo "[oh-my-zsh] theme '$ZSH_THEME' not found"
+  fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/1password.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/1password.plugin.zsh
new file mode 100644 (file)
index 0000000..941523c
--- /dev/null
@@ -0,0 +1,9 @@
+# Do nothing if op is not installed
+(( ${+commands[op]} )) || return
+
+# Load op completion
+eval "$(op completion zsh)"
+compdef _op op
+
+# Load opswd function
+autoload -Uz opswd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/README.md
new file mode 100644 (file)
index 0000000..f6854da
--- /dev/null
@@ -0,0 +1,38 @@
+# 1Password
+
+This plugin adds 1Password functionality to oh-my-zsh.
+
+To use, add `1password` to the list of plugins in your `.zshrc` file:
+
+```zsh
+plugins=(... 1password)
+```
+
+Then, you can use the command `opswd` to copy passwords for services into your
+clipboard.
+
+## `opswd`
+
+The `opswd` command is a wrapper around the `op` command. It takes a service
+name as an argument and copies the password for that service to the clipboard.
+
+If the service also contains a TOTP, it is copied to the clipboard after 10 seconds.
+Finally, after 20 seconds, the clipboard is cleared.
+
+The function has completion support, so you can use tab completion to select
+which service you want to get.
+
+For example, `opswd github.com` will put your GitHub password into your clipboard, and if
+a TOTP is available, it will be copied to the clipboard after 10 seconds.
+
+> NOTE: you need to be signed in for `opswd` to work. If you are using biometric unlock,
+> 1Password CLI will automatically prompt you to sign in. See:
+>
+> - [Get started with 1Password CLI 2: Sign in](https://developer.1password.com/docs/cli/get-started#sign-in)
+> - [Sign in to your 1Password account manually](https://developer.1password.com/docs/cli/sign-in-manually)
+
+## Requirements
+
+- [1Password CLI 2](https://developer.1password.com/docs/cli/get-started#install)
+
+  > NOTE: if you're using 1Password CLI 1, [see how to upgrade to CLI 2](https://developer.1password.com/docs/cli/upgrade).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/_opswd b/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/_opswd
new file mode 100644 (file)
index 0000000..dbc094f
--- /dev/null
@@ -0,0 +1,19 @@
+#compdef opswd
+
+function _opswd() {
+  local -a services
+  services=("${(@f)$(op item list --categories Login --cache 2>/dev/null | awk 'NR != 1 { print $2 }')}")
+  [[ -z "$services" ]] || compadd -a -- services
+}
+
+# TODO: 2022-03-26: Remove support for op CLI 1
+autoload -Uz is-at-least
+is-at-least 2.0.0 $(op --version) || {
+  function _opswd() {
+    local -a services
+    services=("${(@f)$(op list items --categories Login 2>/dev/null | op get item - --fields title 2>/dev/null)}")
+    [[ -z "$services" ]] || compadd -a -- services
+  }
+}
+
+_opswd "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/opswd b/stow/oh-my-zsh/.oh-my-zsh/plugins/1password/opswd
new file mode 100644 (file)
index 0000000..5767280
--- /dev/null
@@ -0,0 +1,78 @@
+#autoload
+
+# opswd puts the password of the named service into the clipboard. If there's a
+# one time password, it will be copied into the clipboard after 10 seconds. The
+# clipboard is cleared after another 20 seconds.
+function opswd() {
+  if [[ $# -lt 1 ]]; then
+    echo "Usage: opswd <service>"
+    return 1
+  fi
+
+  local service=$1
+
+  # If not logged in, print error and return
+  op user list > /dev/null || return
+
+  local password
+  # Copy the password to the clipboard
+  if ! password=$(op item get "$service" --fields password 2>/dev/null); then
+    echo "error: could not obtain password for $service"
+    return 1
+  fi
+
+  echo -n "$password" | clipcopy
+  echo "✔ password for $service copied to clipboard"
+
+  # If there's a one time password, copy it to the clipboard after 10 seconds
+  local totp
+  if totp=$(op item get --otp "$service" 2>/dev/null) && [[ -n "$totp" ]]; then
+    sleep 10 && echo -n "$totp" | clipcopy
+    echo "✔ TOTP for $service copied to clipboard"
+  fi
+
+  (sleep 20 && clipcopy </dev/null 2>/dev/null) &!
+}
+
+# TODO: 2022-03-26: Remove support for op CLI 1
+autoload -Uz is-at-least
+is-at-least 2.0.0 $(op --version) || {
+  print -ru2 ${(%):-"%F{yellow}opswd: usage with op version $(op --version) is deprecated. Upgrade to CLI 2 and reload zsh.
+For instructions, see https://developer.1password.com/docs/cli/upgrade.%f"}
+
+  # opswd puts the password of the named service into the clipboard. If there's a
+  # one time password, it will be copied into the clipboard after 10 seconds. The
+  # clipboard is cleared after another 20 seconds.
+  function opswd() {
+    if [[ $# -lt 1 ]]; then
+      echo "Usage: opswd <service>"
+      return 1
+    fi
+
+    local service=$1
+
+    # If not logged in, print error and return
+    op list users > /dev/null || return
+
+    local password
+    # Copy the password to the clipboard
+    if ! password=$(op get item "$service" --fields password 2>/dev/null); then
+      echo "error: could not obtain password for $service"
+      return 1
+    fi
+
+    echo -n "$password" | clipcopy
+    echo "✔ password for $service copied to clipboard"
+
+    # If there's a one time password, copy it to the clipboard after 5 seconds
+    local totp
+    if totp=$(op get totp "$service" 2>/dev/null) && [[ -n "$totp" ]]; then
+      sleep 10 && echo -n "$totp" | clipcopy
+      echo "✔ TOTP for $service copied to clipboard"
+    fi
+
+    (sleep 20 && clipcopy </dev/null 2>/dev/null) &!
+  }
+}
+
+opswd "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/adb/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/adb/README.md
new file mode 100644 (file)
index 0000000..83dcc72
--- /dev/null
@@ -0,0 +1,8 @@
+# adb autocomplete plugin
+
+* Adds autocomplete options for all adb commands.
+* Add autocomplete for `adb -s`
+
+## Requirements
+
+In order to make this work, you will need to have the Android adb tools set up in your path.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/adb/_adb b/stow/oh-my-zsh/.oh-my-zsh/plugins/adb/_adb
new file mode 100644 (file)
index 0000000..78c4577
--- /dev/null
@@ -0,0 +1,67 @@
+#compdef adb
+#autoload
+
+# in order to make this work, you will need to have the android adb tools
+
+# adb zsh completion, based on homebrew completion
+
+local -a _1st_arguments
+_1st_arguments=(
+'bugreport:return all information from the device that should be included in a bug report.'
+'connect:connect to a device via TCP/IP Port 5555 is default.'
+'devices:list all connected devices'
+'disconnect:disconnect from a TCP/IP device. Port 5555 is default.'
+'emu:run emulator console command'
+'forward:forward socket connections'
+'get-devpath:print the device path'
+'get-serialno:print the serial number of the device'
+'get-state:print the current state of the device: offline | bootloader | device'
+'help:show the help message'
+'install:push this package file to the device and install it'
+'jdwp:list PIDs of processes hosting a JDWP transport'
+'keygen:generate adb public/private key'
+'kill-server:kill the server if it is running'
+'logcat:view device log'
+'pull:copy file/dir from device'
+'push:copy file/dir to device'
+'reboot:reboots the device, optionally into the bootloader or recovery program'
+'reboot-bootloader:reboots the device into the bootloader'
+'remount:remounts the partitions on the device read-write'
+'root:restarts the adbd daemon with root permissions'
+'sideload:push a ZIP to device and install it'
+'shell:run remote shell interactively'
+'sync:copy host->device only if changed (-l means list but dont copy)'
+'start-server:ensure that there is a server running'
+'tcpip:restart host adb in tcpip mode'
+'uninstall:remove this app package from the device'
+'usb:restart the adbd daemon listing on USB'
+'version:show version num'
+'wait-for-device:block until device is online'
+)
+
+local expl
+local -a pkgs installed_pkgs
+
+_arguments \
+       '-s[devices]:specify device:->specify_device' \
+       '*:: :->subcmds' && return 0
+
+case "$state" in
+       specify_device)
+       _values -C 'devices' ${$(adb devices -l|awk 'NR>1&& $1 \
+               {sub(/ +/," ",$0); \
+               gsub(":","\\:",$1); \
+               for(i=1;i<=NF;i++) {
+                       if($i ~ /model:/) { split($i,m,":") } \
+                       else if($i ~ /product:/) { split($i,p,":") } } \
+               printf "%s[%s(%s)] ",$1, p[2], m[2]}'):-""}
+       return
+       ;;
+esac
+
+if (( CURRENT == 1 )); then
+       _describe -t commands "adb subcommand" _1st_arguments
+       return
+fi
+
+_files
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ag/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ag/README.md
new file mode 100644 (file)
index 0000000..1983aaa
--- /dev/null
@@ -0,0 +1,13 @@
+# The Silver Searcher
+
+This plugin provides completion support for [`ag`](https://github.com/ggreer/the_silver_searcher).
+
+To use it, add ag to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... ag)
+```
+
+## INSTALLATION NOTES
+
+Besides oh-my-zsh, `ag` needs to be installed by following these steps: https://github.com/ggreer/the_silver_searcher#installing.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ag/_ag b/stow/oh-my-zsh/.oh-my-zsh/plugins/ag/_ag
new file mode 100644 (file)
index 0000000..25b0c27
--- /dev/null
@@ -0,0 +1,66 @@
+#compdef ag
+#autoload
+
+typeset -A opt_args
+
+# Took the liberty of not listing every option… specially aliases and -D
+_ag () {
+  local -a _1st_arguments
+  _1st_arguments=(
+    '--ackmate:Print results in AckMate-parseable format'
+    {'-A','--after'}':[LINES] Print lines after match (Default: 2)'
+    {'-B','--before'}':[LINES] Print lines before match (Default: 2)'
+    '--break:Print newlines between matches in different files'
+    '--nobreak:Do not print newlines between matches in different files'
+    {'-c','--count'}':Only print the number of matches in each file'
+    '--color:Print color codes in results (Default: On)'
+    '--nocolor:Do not print color codes in results'
+    '--color-line-number:Color codes for line numbers (Default: 1;33)'
+    '--color-match:Color codes for result match numbers (Default: 30;43)'
+    '--color-path:Color codes for path names (Default: 1;32)'
+    '--column:Print column numbers in results'
+    {'-H','--heading'}':Print file names (On unless searching a single file)'
+    '--noheading:Do not print file names (On unless searching a single file)'
+    '--line-numbers:Print line numbers even for streams'
+    {'-C','--context'}':[LINES] Print lines before and after matches (Default: 2)'
+    '-g:[PATTERN] Print filenames matching PATTERN'
+    {'-l','--files-with-matches'}':Only print filenames that contain matches'
+    {'-L','--files-without-matches'}':Only print filenames that do not contain matches'
+    '--no-numbers:Do not print line numbers'
+    {'-o','--only-matching'}':Prints only the matching part of the lines'
+    '--print-long-lines:Print matches on very long lines (Default: 2k characters)'
+    '--passthrough:When searching a stream, print all lines even if they do not match'
+    '--silent:Suppress all log messages, including errors'
+    '--stats:Print stats (files scanned, time taken, etc.)'
+    '--vimgrep:Print results like vim :vimgrep /pattern/g would'
+    {'-0','--null'}':Separate filenames with null (for "xargs -0")'
+
+    {'-a','--all-types'}':Search all files (does not include hidden files / .gitignore)'
+    '--depth:[NUM] Search up to NUM directories deep (Default: 25)'
+    {'-f','--follow'}':Follow symlinks'
+    {'-G','--file-search-regex'}':[PATTERN] Limit search to filenames matching PATTERN'
+    '--hidden:Search hidden files (obeys .*ignore files)'
+    {'-i','--ignore-case'}':Match case insensitively'
+    '--ignore:[PATTERN] Ignore files/directories matching PATTERN'
+    {'-m','--max-count'}':[NUM] Skip the rest of a file after NUM matches (Default: 10k)'
+    {'-p','--path-to-agignore'}':[PATH] Use .agignore file at PATH'
+    {'-Q','--literal'}':Do not parse PATTERN as a regular expression'
+    {'-s','--case-sensitive'}':Match case'
+    {'-S','--smart-case'}':Insensitive match unless PATTERN has uppercase (Default: On)'
+    '--search-binary:Search binary files for matches'
+    {'-t','--all-text'}':Search all text files (Hidden files not included)'
+    {'-u','--unrestricted'}':Search all files (ignore .agignore and _all_)'
+    {'-U','--skip-vcs-ignores'}':Ignore VCS files (stil obey .agignore)'
+    {'-v','--invert-match'}':Invert match'
+    {'-w','--word-regexp'}':Only match whole words'
+    {'-z','--search-zip'}':Search contents of compressed (e.g., gzip) files'
+
+    '--list-file-types:list of supported file types'
+  )
+
+  if [[ $words[-1] =~ "^-" ]]; then
+    _describe -t commands "ag options" _1st_arguments && ret=0
+  else
+    _files && ret=0
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/alias-finder/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/alias-finder/README.md
new file mode 100644 (file)
index 0000000..409f4b6
--- /dev/null
@@ -0,0 +1,46 @@
+# alias-finder plugin
+
+This plugin searches the defined aliases and outputs any that match the command inputted. This makes learning new aliases easier.
+
+To use it, add `alias-finder` to the `plugins` array of your zshrc file:
+```
+plugins=(... alias-finder)
+```
+
+## Usage
+To see if there is an alias defined for the command, pass it as an argument to `alias-finder`. This can also run automatically before each command you input - add `ZSH_ALIAS_FINDER_AUTOMATIC=true` to your zshrc if you want this.
+
+## Options
+
+- Use `--longer` or `-l` to allow the aliases to be longer than the input (match aliases if they contain the input).
+- Use `--exact` or `-e` to avoid matching aliases that are shorter than the input.
+
+## Examples
+```
+$ alias-finder "git pull"
+gl='git pull'
+g=git
+```
+```
+$ alias-finder "web_search google oh my zsh"
+google='web_search google'
+```
+```
+$ alias-finder "git commit -v"
+gc="git commit -v"
+g=git
+```
+```
+$ alias-finder -e "git commit -v"
+gc='git commit -v'
+```
+```
+$ alias-finder -l "git commit -v"
+gc='git commit -v'
+'gc!'='git commit -v --amend'
+gca='git commit -v -a'
+'gca!'='git commit -v -a --amend'
+'gcan!'='git commit -v -a --no-edit --amend'
+'gcans!'='git commit -v -a -s --no-edit --amend'
+'gcn!'='git commit -v --no-edit --amend'
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/alias-finder/alias-finder.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/alias-finder/alias-finder.plugin.zsh
new file mode 100644 (file)
index 0000000..caee9b5
--- /dev/null
@@ -0,0 +1,47 @@
+alias-finder() {
+  local cmd="" exact="" longer="" wordStart="" wordEnd="" multiWordEnd=""
+  for i in $@; do
+    case $i in
+      -e|--exact) exact=true;;
+      -l|--longer) longer=true;;
+      *)
+        if [[ -z $cmd ]]; then
+          cmd=$i
+        else
+          cmd="$cmd $i"
+        fi
+        ;;
+    esac
+  done
+  cmd=$(sed 's/[].\|$(){}?+*^[]/\\&/g' <<< $cmd) # adds escaping for grep
+  if (( $(wc -l <<< $cmd) == 1 )); then
+    while [[ $cmd != "" ]]; do
+      if [[ $longer = true ]]; then
+        wordStart="'{0,1}"
+      else
+        wordEnd="$"
+        multiWordEnd="'$"
+      fi
+      if [[ $cmd == *" "* ]]; then
+        local finder="'$cmd$multiWordEnd"
+      else
+        local finder=$wordStart$cmd$wordEnd
+      fi
+      alias | grep -E "=$finder"
+      if [[ $exact = true || $longer = true ]]; then
+        break
+      else
+        cmd=$(sed -E 's/ {0,1}[^ ]*$//' <<< $cmd) # removes last word
+      fi
+    done
+  fi
+}
+
+preexec_alias-finder() {
+  if [[ $ZSH_ALIAS_FINDER_AUTOMATIC = true ]]; then
+    alias-finder $1
+  fi
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook preexec preexec_alias-finder
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/.gitignore b/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/.gitignore
new file mode 100644 (file)
index 0000000..bee8a64
--- /dev/null
@@ -0,0 +1 @@
+__pycache__
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/README.md
new file mode 100644 (file)
index 0000000..66fd845
--- /dev/null
@@ -0,0 +1,28 @@
+# Aliases cheatsheet
+
+**Maintainer:** [@hqingyi](https://github.com/hqingyi)
+
+With lots of 3rd-party amazing aliases installed, this plugin helps list the shortcuts
+that are currently available based on the plugins you have enabled.
+
+To use it, add `aliases` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(aliases)
+```
+
+Requirements: Python needs to be installed.
+
+## Usage
+
+- `acs`: show all aliases by group.
+
+- `acs -h/--help`: print help mesage.
+
+- `acs <keyword>`: filter aliases by `<keyword>` and highlight.
+
+- `acs -g <group>/--group <group`: show only aliases for group `<group>`. Multiple uses of the flag show all groups,
+
+- `acs --groups-only`: show only group names
+
+  ![screenshot](https://cloud.githubusercontent.com/assets/3602957/11581913/cb54fb8a-9a82-11e5-846b-5a67f67ad9ad.png)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/aliases.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/aliases.plugin.zsh
new file mode 100644 (file)
index 0000000..9864de9
--- /dev/null
@@ -0,0 +1,14 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+eval '
+  function acs(){
+    (( $+commands[python3] )) || {
+      echo "[error] No python executable detected"
+      return
+    }
+    alias | python3 "'"${0:h}"'/cheatsheet.py" "$@"
+  }
+'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/cheatsheet.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/cheatsheet.py
new file mode 100644 (file)
index 0000000..3362a6a
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+import sys
+import itertools
+import termcolor
+import argparse
+
+def parse(line):
+    left = line[0:line.find('=')].strip()
+    right = line[line.find('=')+1:].strip('\'"\n ')
+    try:
+        cmd = next(part for part in right.split() if len([char for char in '=<>' if char in part])==0)
+    except StopIteration:
+        cmd = right
+    return (left, right, cmd)
+
+def cheatsheet(lines):
+    exps = [ parse(line) for line in lines ]
+    cheatsheet = {'_default': []}
+    for key, group in itertools.groupby(exps, lambda exp:exp[2]):
+        group_list = [ item for item in group ]
+        if len(group_list)==1:
+            target_aliases = cheatsheet['_default']
+        else:
+            if key not in cheatsheet:
+                cheatsheet[key] = []
+            target_aliases = cheatsheet[key]
+        target_aliases.extend(group_list)
+    return cheatsheet
+
+def pretty_print_group(key, aliases, highlight=None, only_groupname=False):
+    if len(aliases) == 0:
+        return
+    group_hl_formatter = lambda g, hl: termcolor.colored(hl, 'yellow').join([termcolor.colored(part, 'red') for part in ('[%s]' % g).split(hl)])
+    alias_hl_formatter = lambda alias, hl: termcolor.colored(hl, 'yellow').join([termcolor.colored(part, 'green') for part in ('\t%s = %s' % alias[0:2]).split(hl)])
+    group_formatter = lambda g: termcolor.colored('[%s]' % g, 'red')
+    alias_formatter = lambda alias: termcolor.colored('\t%s = %s' % alias[0:2], 'green')
+    if highlight and len(highlight)>0:
+        print (group_hl_formatter(key, highlight))
+        if not only_groupname:
+            print ('\n'.join([alias_hl_formatter(alias, highlight) for alias in aliases]))
+    else:
+        print (group_formatter(key))
+        if not only_groupname:
+            print ('\n'.join([alias_formatter(alias) for alias in aliases]))
+    print ('')
+
+def pretty_print(cheatsheet, wfilter, group_list=None, groups_only=False):
+    sorted_key = sorted(cheatsheet.keys())
+    for key in sorted_key:
+        if group_list and key not in group_list:
+            continue
+        aliases = cheatsheet.get(key)
+        if not wfilter:
+            pretty_print_group(key, aliases, wfilter, groups_only)
+        else:
+            pretty_print_group(key, [ alias for alias in aliases if alias[0].find(wfilter)>-1 or alias[1].find(wfilter)>-1], wfilter)
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="Pretty print aliases.")
+    parser.add_argument('filter', nargs="*", help="search aliases matching string")
+    parser.add_argument('-g', '--group', dest="group_list", action='append', help="only print aliases in given groups")
+    parser.add_argument('--groups', dest='groups_only', action='store_true', help="only print alias groups")
+    args = parser.parse_args()
+
+    lines = sys.stdin.readlines()
+    group_list = args.group_list or None
+    wfilter = " ".join(args.filter) or None
+    pretty_print(cheatsheet(lines), wfilter, group_list, args.groups_only)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/termcolor.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/aliases/termcolor.py
new file mode 100644 (file)
index 0000000..bb725e9
--- /dev/null
@@ -0,0 +1,168 @@
+# coding: utf-8
+# Copyright (c) 2008-2011 Volvox Development Team
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# Author: Konstantin Lepa <konstantin.lepa@gmail.com>
+
+"""ANSI Color formatting for output in terminal."""
+
+from __future__ import print_function
+import os
+
+
+__ALL__ = [ 'colored', 'cprint' ]
+
+VERSION = (1, 1, 0)
+
+ATTRIBUTES = dict(
+        list(zip([
+            'bold',
+            'dark',
+            '',
+            'underline',
+            'blink',
+            '',
+            'reverse',
+            'concealed'
+            ],
+            list(range(1, 9))
+            ))
+        )
+del ATTRIBUTES['']
+
+
+HIGHLIGHTS = dict(
+        list(zip([
+            'on_grey',
+            'on_red',
+            'on_green',
+            'on_yellow',
+            'on_blue',
+            'on_magenta',
+            'on_cyan',
+            'on_white'
+            ],
+            list(range(40, 48))
+            ))
+        )
+
+
+COLORS = dict(
+        list(zip([
+            'grey',
+            'red',
+            'green',
+            'yellow',
+            'blue',
+            'magenta',
+            'cyan',
+            'white',
+            ],
+            list(range(30, 38))
+            ))
+        )
+
+
+RESET = '\033[0m'
+
+
+def colored(text, color=None, on_color=None, attrs=None):
+    """Colorize text.
+
+    Available text colors:
+        red, green, yellow, blue, magenta, cyan, white.
+
+    Available text highlights:
+        on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white.
+
+    Available attributes:
+        bold, dark, underline, blink, reverse, concealed.
+
+    Example:
+        colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink'])
+        colored('Hello, World!', 'green')
+    """
+    if os.getenv('ANSI_COLORS_DISABLED') is None:
+        fmt_str = '\033[%dm%s'
+        if color is not None:
+            text = fmt_str % (COLORS[color], text)
+
+        if on_color is not None:
+            text = fmt_str % (HIGHLIGHTS[on_color], text)
+
+        if attrs is not None:
+            for attr in attrs:
+                text = fmt_str % (ATTRIBUTES[attr], text)
+
+        text += RESET
+    return text
+
+
+def cprint(text, color=None, on_color=None, attrs=None, **kwargs):
+    """Print colorize text.
+
+    It accepts arguments of print function.
+    """
+
+    print((colored(text, color, on_color, attrs)), **kwargs)
+
+
+if __name__ == '__main__':
+    print('Current terminal type: %s' % os.getenv('TERM'))
+    print('Test basic colors:')
+    cprint('Grey color', 'grey')
+    cprint('Red color', 'red')
+    cprint('Green color', 'green')
+    cprint('Yellow color', 'yellow')
+    cprint('Blue color', 'blue')
+    cprint('Magenta color', 'magenta')
+    cprint('Cyan color', 'cyan')
+    cprint('White color', 'white')
+    print(('-' * 78))
+
+    print('Test highlights:')
+    cprint('On grey color', on_color='on_grey')
+    cprint('On red color', on_color='on_red')
+    cprint('On green color', on_color='on_green')
+    cprint('On yellow color', on_color='on_yellow')
+    cprint('On blue color', on_color='on_blue')
+    cprint('On magenta color', on_color='on_magenta')
+    cprint('On cyan color', on_color='on_cyan')
+    cprint('On white color', color='grey', on_color='on_white')
+    print('-' * 78)
+
+    print('Test attributes:')
+    cprint('Bold grey color', 'grey', attrs=['bold'])
+    cprint('Dark red color', 'red', attrs=['dark'])
+    cprint('Underline green color', 'green', attrs=['underline'])
+    cprint('Blink yellow color', 'yellow', attrs=['blink'])
+    cprint('Reversed blue color', 'blue', attrs=['reverse'])
+    cprint('Concealed Magenta color', 'magenta', attrs=['concealed'])
+    cprint('Bold underline reverse cyan color', 'cyan',
+            attrs=['bold', 'underline', 'reverse'])
+    cprint('Dark blink concealed white color', 'white',
+            attrs=['dark', 'blink', 'concealed'])
+    print(('-' * 78))
+
+    print('Test mixing:')
+    cprint('Underline red on grey color', 'red', 'on_grey',
+            ['underline'])
+    cprint('Reversed green on red color', 'green', 'on_red', ['reverse'])
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ansible/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ansible/README.md
new file mode 100644 (file)
index 0000000..e0e6a19
--- /dev/null
@@ -0,0 +1,34 @@
+# ansible plugin
+
+## Introduction
+
+The `ansible plugin` adds several aliases for useful [ansible](https://docs.ansible.com/ansible/latest/index.html) commands and [aliases](#aliases).
+
+To use it, add `ansible` to the plugins array of your zshrc file:
+
+```
+plugins=(... ansible)
+```
+
+## Aliases
+
+| Command                                    | Description                                                         |
+|:-------------------------------------------|:--------------------------------------------------------------------|
+| `ansible-version` / `aver`                 | Show the version on ansible installed in this host                  |
+| `ansible-role-init <role name>` / `arinit` | Creates the Ansible Role as per Ansible Galaxy standard             |
+| `a`                                        | command `ansible`                                                   |
+| `aconf`                                    | command `ansible-config`                                            |
+| `acon`                                     | command `ansible-console`                                           |
+| `ainv`                                     | command `ansible-inventory`                                         |
+| `aplaybook`                                | command `ansible-playbook`                                          |
+| `ainv`                                     | command `ansible-inventory`                                         |
+| `adoc`                                     | command `ansible-doc`                                               |
+| `agal`                                     | command `ansible-galaxy`                                            |
+| `apull`                                    | command `ansible-pull`                                              |
+| `aval`                                     | command `ansible-vault`                                             |
+
+## Maintainer
+
+### [Deepankumar](https://github.com/deepan10) 
+
+[https://github.com/deepan10/oh-my-zsh/tree/features/ansible-plugin](https://github.com/deepan10/oh-my-zsh/tree/features/ansible-plugin)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ansible/ansible.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ansible/ansible.plugin.zsh
new file mode 100644 (file)
index 0000000..75393b7
--- /dev/null
@@ -0,0 +1,28 @@
+# Functions
+function ansible-version(){
+    ansible --version
+}
+
+function ansible-role-init(){
+    if ! [ -z $1 ] ; then
+        echo "Ansible Role : $1 Creating...."
+        ansible-galaxy init $1
+        tree $1
+    else
+        echo "Usage : ansible-role-init <role name>"
+        echo "Example : ansible-role-init role1"
+    fi
+}
+
+# Alias
+alias a='ansible '
+alias aconf='ansible-config '
+alias acon='ansible-console '
+alias aver='ansible-version'
+alias arinit='ansible-role-init'
+alias aplaybook='ansible-playbook '
+alias ainv='ansible-inventory '
+alias adoc='ansible-doc '
+alias agal='ansible-galaxy '
+alias apull='ansible-pull '
+alias aval='ansible-vault'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ant/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ant/README.md
new file mode 100644 (file)
index 0000000..5712372
--- /dev/null
@@ -0,0 +1,12 @@
+# Ant
+
+This plugin provides completion for [Ant](https://ant.apache.org/).
+
+To use it, add `ant` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ant)
+```
+
+It caches ant targets in a file named `.ant_targets`, you might want to add that to
+your `.gitignore` file.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ant/_ant b/stow/oh-my-zsh/.oh-my-zsh/plugins/ant/_ant
new file mode 100644 (file)
index 0000000..24a8e36
--- /dev/null
@@ -0,0 +1,22 @@
+#compdef ant
+
+_ant_does_target_list_need_generating () {
+  [[ ! -f .ant_targets ]] && return 0
+  [[ build.xml -nt .ant_targets ]] && return 0
+  return 1
+}
+
+_ant () {
+  if [[ ! -f build.xml ]]; then
+    return
+  fi
+
+  if ! _ant_does_target_list_need_generating; then
+    return
+  fi
+
+  ant -p | awk -F " " 'NR > 5 { print lastTarget } { lastTarget = $1 }' >| .ant_targets
+  compadd -- "$(cat .ant_targets)"
+}
+
+_ant "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ant/ant.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ant/ant.plugin.zsh
new file mode 100644 (file)
index 0000000..5f63825
--- /dev/null
@@ -0,0 +1,2 @@
+# Default to colored output
+export ANT_ARGS='-logger org.apache.tools.ant.listener.AnsiColorLogger'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/apache2-macports/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/apache2-macports/README.md
new file mode 100644 (file)
index 0000000..dbf2e89
--- /dev/null
@@ -0,0 +1,21 @@
+# apache2-macports plugin
+
+Enables aliases to control a local Apache2 installed via [MacPorts](https://www.macports.org/).
+
+To use it, add `apache2-macports` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... apache2-macports)
+```
+
+## Aliases
+
+| Alias          | Function                                | Description           |
+|----------------|-----------------------------------------|-----------------------|
+| apache2restart | `sudo /path/to/apache2.wrapper restart` | Restart apache daemon |
+| apache2start   | `sudo /path/to/apache2.wrapper start`   | Start apache daemon   |
+| apache2stop    | `sudo /path/to/apache2.wrapper stop`    | Stop apache daemon    |
+
+## Contributors
+
+- Alexander Rinass (alex@rinass.net)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/apache2-macports/apache2-macports.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/apache2-macports/apache2-macports.plugin.zsh
new file mode 100644 (file)
index 0000000..1caa4cf
--- /dev/null
@@ -0,0 +1,6 @@
+# commands to control local apache2 server installation
+# paths are for osx installation via macports
+
+alias apache2start='sudo /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper start'
+alias apache2stop='sudo /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper stop'
+alias apache2restart='sudo /opt/local/etc/LaunchDaemons/org.macports.apache2/apache2.wrapper restart'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/arcanist/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/arcanist/README.md
new file mode 100644 (file)
index 0000000..07e7669
--- /dev/null
@@ -0,0 +1,43 @@
+## arcanist
+
+This plugin adds many useful aliases for [arcanist](https://github.com/phacility/arcanist).
+
+To use it, add `arcanist` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... arcanist)
+```
+
+## Aliases
+
+| Alias   | Command                            |
+| ------- | ---------------------------------- |
+| ara     | `arc amend`                        |
+| arb     | `arc branch`                       |
+| arbl    | `arc bland`                        |
+| arco    | `arc cover`                        |
+| arci    | `arc commit`                       |
+| ard     | `arc diff`                         |
+| ardc    | `arc diff --create`                |
+| ardp    | `arc diff --preview`               |
+| ardnu   | `arc diff --nounit`                |
+| ardnupc | `arc diff --nounit --plan-changes` |
+| ardpc   | `arc diff --plan-changes`          |
+| are     | `arc export`                       |
+| arh     | `arc help`                         |
+| arho    | `arc hotfix`                       |
+| arl     | `arc land`                         |
+| arli    | `arc lint`                         |
+| arls    | `arc list`                         |
+| arpa    | `arc patch`                        |
+
+## Functions
+
+The following functions make copy pasting revision ids from the URL bar of your browser
+easier, as they allow for copy pasting the whole URL. For example: `ardu` accepts
+both `https://arcanist-url.com/<REVISION>` as well as `<REVISION>`.
+
+| Function                  | Command                           |
+| ------------------------- | --------------------------------- |
+| ardu [URL or revision_id] | `arc diff --update` [revision_id] |
+| arpa [URL or revision_id] | `arc patch` [revision_id]         |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/arcanist/arcanist.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/arcanist/arcanist.plugin.zsh
new file mode 100644 (file)
index 0000000..380eede
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Aliases
+# (sorted alphabetically)
+#
+
+alias ara='arc amend'
+alias arb='arc branch'
+alias arbl='arc bland'
+alias arco='arc cover'
+alias arci='arc commit'
+
+alias ard='arc diff'
+alias ardc='arc diff --create'
+alias ardnu='arc diff --nounit'
+alias ardnupc='arc diff --nounit --plan-changes'
+alias ardpc='arc diff --plan-changes'
+alias ardp='arc diff --preview' # creates a new diff in the phab interface
+
+alias are='arc export'
+alias arh='arc help'
+alias arho='arc hotfix'
+alias arl='arc land'
+alias arli='arc lint'
+alias arls='arc list'
+
+#
+# Functions
+# (sorted alphabetically)
+#
+
+ardu() {
+  # Both `ardu https://arcanist-url.com/<REVISION>`, and `ardu <REVISION>` work.
+  arc diff --update "${1:t}"
+}
+
+arpa() {
+  # Both `arpa https://arcanist-url.com/<REVISION>`, and `arpa <REVISION>` work.
+  arc patch "${1:t}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/archlinux/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/archlinux/README.md
new file mode 100644 (file)
index 0000000..fd772c6
--- /dev/null
@@ -0,0 +1,183 @@
+# Arch Linux plugin
+
+This plugin adds some aliases and functions to work with Arch Linux.
+
+To use it, add `archlinux` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... archlinux)
+```
+
+## Features
+
+### Pacman
+
+| Alias        | Command                                | Description                                                      |
+|--------------|----------------------------------------|------------------------------------------------------------------|
+| pacin        | `sudo pacman -S`                       | Install packages from the repositories                           |
+| pacins       | `sudo pacman -U`                       | Install a package from a local file                              |
+| pacinsd      | `sudo pacman -S --asdeps`              | Install packages as dependencies of another package              |
+| paclean      | `sudo pacman -Sc`                      | Clean out old and unused caches and packages                     |
+| pacloc       | `pacman -Qi`                           | Display information about a package in the local database        |
+| paclocs      | `pacman -Qs`                           | Search for packages in the local database                        |
+| paclr        | `sudo pacman -Scc`                     | Remove all files from the cache                                  |
+| paclsorphans | `sudo pacman -Qdt`                     | List all orphaned packages                                       |
+| pacmir       | `sudo pacman -Syy`                     | Force refresh of all package lists after updating mirrorlist     |
+| pacre        | `sudo pacman -R`                       | Remove packages, keeping its settings and dependencies           |
+| pacrem       | `sudo pacman -Rns`                     | Remove packages, including its settings and dependencies         |
+| pacrep       | `pacman -Si`                           | Display information about a package in the repositories          |
+| pacreps      | `pacman -Ss`                           | Search for packages in the repositories                          |
+| pacrmorphans | `sudo pacman -Rs $(pacman -Qtdq)`      | Delete all orphaned packages                                     |
+| pacupd       | `sudo pacman -Sy`                      | Update and refresh local package, ABS and AUR databases          |
+| pacupg       | `sudo pacman -Syu`                     | Sync with repositories before upgrading packages                 |
+| pacfileupg   | `sudo pacman -Fy`                      | Download fresh package databases from the server                 |
+| pacfiles     | `pacman -F`                            | Search package file names for matching strings                   |
+| pacls        | `pacman -Ql`                           | List files in a package                                          |
+| pacown       | `pacman -Qo`                           | Show which package owns a file                                   |
+| upgrade[¹](#f1) | `sudo pacman -Syu`                  | Sync with repositories before upgrading packages                 |
+
+| Function       | Description                                               |
+|----------------|-----------------------------------------------------------|
+| pacdisowned    | List all disowned files in your system                    |
+| paclist        | List all explicitly installed packages with a description |
+| pacmanallkeys  | Get all keys for developers and trusted users             |
+| pacmansignkeys | Locally trust all keys passed as parameters               |
+| pacweb         | Open the website of an ArchLinux package                  |
+
+Note: paclist used to print packages with a description which are (1) explicitly installed
+and (2) available for upgrade. Due to flawed scripting, it also printed all packages if no
+upgrades were available. Use `pacman -Que` instead.
+
+### AUR helpers
+
+#### Aura
+
+| Alias   | Command                                         | Description                                                             |
+|---------|-------------------------------------------------|-------------------------------------------------------------------------|
+| auclean | `sudo aura -Sc`                                 | Clean out old and unused caches and packages                            |
+| auclr   | `sudo aura -Scc`                                | Remove all files from the cache                                         |
+| auin    | `sudo aura -S`                                  | Install packages from the repositories                                  |
+| aurin   | `sudo aura -A`                                  | Install packages from the repositories                                  |
+| auins   | `sudo aura -U`                                  | Install a package from a local file                                     |
+| auinsd  | `sudo aura -S --asdeps`                         | Install packages as dependencies of another package (repositories only) |
+| aurinsd | `sudo aura -A --asdeps`                         | Install packages as dependencies of another package (AUR only)          |
+| auloc   | `aura -Qi`                                      | Display information about a package in the local database               |
+| aulocs  | `aura -Qs`                                      | Search for packages in the local database                               |
+| auls    | `aura -Qql`                                     | List all files owned by a given package                                 |
+| aulst   | `aura -Qe`                                      | List installed packages including from AUR (tagged as "local")          |
+| aumir   | `sudo aura -Syy`                                | Force refresh of all package lists after updating mirrorlist            |
+| aurph   | `sudo aura -Oj`                                 | Remove orphans using aura                                               |
+| auown   | `aura -Qqo`                                     | Search for packages that own the specified file(s)                      |
+| aure    | `sudo aura -R`                                  | Remove packages, keeping its settings and dependencies                  |
+| aurem   | `sudo aura -Rns`                                | Remove packages, including its settings and unneeded dependencies       |
+| aurep   | `aura -Si`                                      | Display information about a package in the repositories                 |
+| aurrep  | `aura -Ai`                                      | Display information about a package from AUR                            |
+| aureps  | `aura -As --both`                               | Search for packages in the repositories and AUR                         |
+| auras   | `aura -As --both`                               | Same as above                                                           |
+| auupd   | `sudo aura -Sy`                                 | Update and refresh local package, ABS and AUR databases                 |
+| auupg   | `sudo sh -c "aura -Syu              && aura -Au"` | Sync with repositories before upgrading all packages (from AUR too)   |
+| ausu    | `sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"` | Same as `auupg`, but without confirmation                |
+| upgrade[¹](#f1) | `sudo aura -Syu`                        | Sync with repositories before upgrading packages                        |
+
+| Function        | Description                                                         |
+|-----------------|---------------------------------------------------------------------|
+| auownloc _file_ | Display information about a package that owns the specified file(s) |
+| auownls  _file_ | List all files owned by a package that owns the specified file(s)   |
+
+#### Pacaur
+
+| Alias   | Command                           | Description                                                         |
+|---------|-----------------------------------|---------------------------------------------------------------------|
+| pacclean| `pacaur -Sc`                      | Clean out old and unused caches and packages                        |
+| pacclr  | `pacaur -Scc`                     | Remove all files from the cache                                     |
+| pain    | `pacaur -S`                       | Install packages from the repositories                              |
+| pains   | `pacaur -U`                       | Install a package from a local file                                 |
+| painsd  | `pacaur -S --asdeps`              | Install packages as dependencies of another package                 |
+| paloc   | `pacaur -Qi`                      | Display information about a package in the local database           |
+| palocs  | `pacaur -Qs`                      | Search for packages in the local database                           |
+| palst   | `pacaur -Qe`                      | List installed packages including from AUR (tagged as "local")      |
+| pamir   | `pacaur -Syy`                     | Force refresh of all package lists after updating mirrorlist        |
+| paorph  | `pacaur -Qtd`                     | Remove orphans using pacaur                                         |
+| pare    | `pacaur -R`                       | Remove packages, keeping its settings and dependencies              |
+| parem   | `pacaur -Rns`                     | Remove packages, including its settings and unneeded dependencies   |
+| parep   | `pacaur -Si`                      | Display information about a package in the repositories             |
+| pareps  | `pacaur -Ss`                      | Search for packages in the repositories                             |
+| paupd   | `pacaur -Sy`                      | Update and refresh local package, ABS and AUR databases             |
+| paupg   | `pacaur -Syua`                    | Sync with repositories before upgrading all packages (from AUR too) |
+| pasu    | `pacaur -Syua --no-confirm`       | Same as `paupg`, but without confirmation                           |
+| upgrade[¹](#f1) | `pacaur -Syu`             | Sync with repositories before upgrading packages                    |
+
+#### Trizen
+
+| Alias   | Command                           | Description                                                         |
+|---------|-----------------------------------|---------------------------------------------------------------------|
+| trconf  | `trizen -C`                       | Fix all configuration files with vimdiff                            |
+| trclean | `trizen -Sc`                      | Clean out old and unused caches and packages                        |
+| trclr   | `trizen -Scc`                     | Remove all files from the cache                                     |
+| trin    | `trizen -S`                       | Install packages from the repositories                              |
+| trins   | `trizen -U`                       | Install a package from a local file                                 |
+| trinsd  | `trizen -S --asdeps`              | Install packages as dependencies of another package                 |
+| trloc   | `trizen -Qi`                      | Display information about a package in the local database           |
+| trlocs  | `trizen -Qs`                      | Search for packages in the local database                           |
+| trlst   | `trizen -Qe`                      | List installed packages including from AUR (tagged as "local")      |
+| trmir   | `trizen -Syy`                     | Force refresh of all package lists after updating mirrorlist        |
+| trorph  | `trizen -Qtd`                     | Remove orphans using yaourt                                         |
+| trre    | `trizen -R`                       | Remove packages, keeping its settings and dependencies              |
+| trrem   | `trizen -Rns`                     | Remove packages, including its settings and unneeded dependencies   |
+| trrep   | `trizen -Si`                      | Display information about a package in the repositories             |
+| trreps  | `trizen -Ss`                      | Search for packages in the repositories                             |
+| trupd   | `trizen -Sy`                      | Update and refresh local package, ABS and AUR databases             |
+| trupg   | `trizen -Syua`                    | Sync with repositories before upgrading all packages (from AUR too) |
+| trsu    | `trizen -Syua --no-confirm`       | Same as `trupg`, but without confirmation                           |
+| upgrade[¹](#f1) | `trizen -Syu`             | Sync with repositories before upgrading packages                    |
+
+#### Yay
+
+| Alias   | Command                        | Description                                                       |
+|---------|--------------------------------|-------------------------------------------------------------------|
+| yaconf  | `yay -Pg`                      | Print current configuration                                       |
+| yaclean | `yay -Sc`                      | Clean out old and unused caches and packages                      |
+| yaclr   | `yay -Scc`                     | Remove all files from the cache                                   |
+| yain    | `yay -S`                       | Install packages from the repositories                            |
+| yains   | `yay -U`                       | Install a package from a local file                               |
+| yainsd  | `yay -S --asdeps`              | Install packages as dependencies of another package               |
+| yaloc   | `yay -Qi`                      | Display information about a package in the local database         |
+| yalocs  | `yay -Qs`                      | Search for packages in the local database                         |
+| yalst   | `yay -Qe`                      | List installed packages including from AUR (tagged as "local")    |
+| yamir   | `yay -Syy`                     | Force refresh of all package lists after updating mirrorlist      |
+| yaorph  | `yay -Qtd`                     | Remove orphans using yay                                          |
+| yare    | `yay -R`                       | Remove packages, keeping its settings and dependencies            |
+| yarem   | `yay -Rns`                     | Remove packages, including its settings and unneeded dependencies |
+| yarep   | `yay -Si`                      | Display information about a package in the repositories           |
+| yareps  | `yay -Ss`                      | Search for packages in the repositories                           |
+| yaupd   | `yay -Sy`                      | Update and refresh local package, ABS and AUR databases           |
+| yaupg   | `yay -Syu`                     | Sync with repositories before upgrading packages                  |
+| yasu    | `yay -Syu --no-confirm`        | Same as `yaupg`, but without confirmation                         |
+| upgrade[¹](#f1) | `yay -Syu`             | Sync with repositories before upgrading packages                  |
+
+---
+
+<span id="f1">¹</span>
+The `upgrade` alias is set for all package managers. Its value will depend on
+whether the package manager is installed, checked in the following order:
+
+1. `yay`
+2. `trizen`
+3. `pacaur`
+4. `aura`
+5. `pacman`
+
+## Contributors
+
+- Benjamin Boudreau - dreurmail@gmail.com
+- Celso Miranda - contacto@celsomiranda.net
+- ratijas (ivan tkachenko) - me@ratijas.tk
+- Juraj Fiala - doctorjellyface@riseup.net
+- KhasMek - Boushh@gmail.com
+- Majora320 (Moses Miller) - Majora320@gmail.com
+- Martin Putniorz - mputniorz@gmail.com
+- MatthR3D - matthr3d@gmail.com
+- ornicar - thibault.duplessis@gmail.com
+- Ybalrid (Arthur Brainville) - ybalrid@ybalrid.info
+- Jeff M. Hubbard - jeffmhubbard@gmail.com
+- K. Harishankar(harishnkr) - hari2menon1234@gmail.com
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/archlinux/archlinux.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/archlinux/archlinux.plugin.zsh
new file mode 100644 (file)
index 0000000..4f13647
--- /dev/null
@@ -0,0 +1,184 @@
+#######################################
+#               Pacman                #
+#######################################
+
+# Pacman - https://wiki.archlinux.org/index.php/Pacman_Tips
+alias pacupg='sudo pacman -Syu'
+alias pacin='sudo pacman -S'
+alias paclean='sudo pacman -Sc'
+alias pacins='sudo pacman -U'
+alias paclr='sudo pacman -Scc'
+alias pacre='sudo pacman -R'
+alias pacrem='sudo pacman -Rns'
+alias pacrep='pacman -Si'
+alias pacreps='pacman -Ss'
+alias pacloc='pacman -Qi'
+alias paclocs='pacman -Qs'
+alias pacinsd='sudo pacman -S --asdeps'
+alias pacmir='sudo pacman -Syy'
+alias paclsorphans='sudo pacman -Qdt'
+alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)'
+alias pacfileupg='sudo pacman -Fy'
+alias pacfiles='pacman -F'
+alias pacls='pacman -Ql'
+alias pacown='pacman -Qo'
+alias pacupd="sudo pacman -Sy"
+alias upgrade='sudo pacman -Syu'
+
+function paclist() {
+  # Based on https://bbs.archlinux.org/viewtopic.php?id=93683
+  pacman -Qqe | \
+    xargs -I '{}' \
+      expac "${bold_color}% 20n ${fg_no_bold[white]}%d${reset_color}" '{}'
+}
+
+function pacdisowned() {
+  local tmp db fs
+  tmp=${TMPDIR-/tmp}/pacman-disowned-$UID-$$
+  db=$tmp/db
+  fs=$tmp/fs
+
+  mkdir "$tmp"
+  trap 'rm -rf "$tmp"' EXIT
+
+  pacman -Qlq | sort -u > "$db"
+
+  find /bin /etc /lib /sbin /usr ! -name lost+found \
+    \( -type d -printf '%p/\n' -o -print \) | sort > "$fs"
+
+  comm -23 "$fs" "$db"
+}
+
+alias pacmanallkeys='sudo pacman-key --refresh-keys'
+
+function pacmansignkeys() {
+  local key
+  for key in $@; do
+    sudo pacman-key --recv-keys $key
+    sudo pacman-key --lsign-key $key
+    printf 'trust\n3\n' | sudo gpg --homedir /etc/pacman.d/gnupg \
+      --no-permission-warning --command-fd 0 --edit-key $key
+  done
+}
+
+if (( $+commands[xdg-open] )); then
+  function pacweb() {
+    if [[ $# = 0 || "$1" =~ '--help|-h' ]]; then
+      local underline_color="\e[${color[underline]}m"
+      echo "$0 - open the website of an ArchLinux package"
+      echo
+      echo "Usage:"
+      echo "    $bold_color$0$reset_color ${underline_color}target${reset_color}"
+      return 1
+    fi
+
+    local pkg="$1"
+    local infos="$(LANG=C pacman -Si "$pkg")"
+    if [[ -z "$infos" ]]; then
+      return
+    fi
+    local repo="$(grep -m 1 '^Repo' <<< "$infos" | grep -oP '[^ ]+$')"
+    local arch="$(grep -m 1 '^Arch' <<< "$infos" | grep -oP '[^ ]+$')"
+    xdg-open "https://www.archlinux.org/packages/$repo/$arch/$pkg/" &>/dev/null
+  }
+fi
+
+#######################################
+#             AUR helpers             #
+#######################################
+
+if (( $+commands[aura] )); then
+  alias auin='sudo aura -S'
+  alias aurin='sudo aura -A'
+  alias auclean='sudo aura -Sc'
+  alias auclr='sudo aura -Scc'
+  alias auins='sudo aura -U'
+  alias auinsd='sudo aura -S --asdeps'
+  alias aurinsd='sudo aura -A --asdeps'
+  alias auloc='aura -Qi'
+  alias aulocs='aura -Qs'
+  alias aulst='aura -Qe'
+  alias aumir='sudo aura -Syy'
+  alias aurph='sudo aura -Oj'
+  alias aure='sudo aura -R'
+  alias aurem='sudo aura -Rns'
+  alias aurep='aura -Si'
+  alias aurrep='aura -Ai'
+  alias aureps='aura -As --both'
+  alias auras='aura -As --both'
+  alias auupd="sudo aura -Sy"
+  alias auupg='sudo sh -c "aura -Syu              && aura -Au"'
+  alias ausu='sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"'
+  alias upgrade='sudo aura -Syu'
+
+  # extra bonus specially for aura
+  alias auown="aura -Qqo"
+  alias auls="aura -Qql"
+  function auownloc() { aura -Qi  $(aura -Qqo $@); }
+  function auownls () { aura -Qql $(aura -Qqo $@); }
+fi
+
+if (( $+commands[pacaur] )); then
+  alias pacclean='pacaur -Sc'
+  alias pacclr='pacaur -Scc'
+  alias paupg='pacaur -Syu'
+  alias pasu='pacaur -Syu --noconfirm'
+  alias pain='pacaur -S'
+  alias pains='pacaur -U'
+  alias pare='pacaur -R'
+  alias parem='pacaur -Rns'
+  alias parep='pacaur -Si'
+  alias pareps='pacaur -Ss'
+  alias paloc='pacaur -Qi'
+  alias palocs='pacaur -Qs'
+  alias palst='pacaur -Qe'
+  alias paorph='pacaur -Qtd'
+  alias painsd='pacaur -S --asdeps'
+  alias pamir='pacaur -Syy'
+  alias paupd="pacaur -Sy"
+  alias upgrade='pacaur -Syu'
+fi
+
+if (( $+commands[trizen] )); then
+  alias trconf='trizen -C'
+  alias trupg='trizen -Syua'
+  alias trsu='trizen -Syua --noconfirm'
+  alias trin='trizen -S'
+  alias trclean='trizen -Sc'
+  alias trclr='trizen -Scc'
+  alias trins='trizen -U'
+  alias trre='trizen -R'
+  alias trrem='trizen -Rns'
+  alias trrep='trizen -Si'
+  alias trreps='trizen -Ss'
+  alias trloc='trizen -Qi'
+  alias trlocs='trizen -Qs'
+  alias trlst='trizen -Qe'
+  alias trorph='trizen -Qtd'
+  alias trinsd='trizen -S --asdeps'
+  alias trmir='trizen -Syy'
+  alias trupd="trizen -Sy"
+  alias upgrade='trizen -Syu'
+fi
+
+if (( $+commands[yay] )); then
+  alias yaconf='yay -Pg'
+  alias yaclean='yay -Sc'
+  alias yaclr='yay -Scc'
+  alias yaupg='yay -Syu'
+  alias yasu='yay -Syu --noconfirm'
+  alias yain='yay -S'
+  alias yains='yay -U'
+  alias yare='yay -R'
+  alias yarem='yay -Rns'
+  alias yarep='yay -Si'
+  alias yareps='yay -Ss'
+  alias yaloc='yay -Qi'
+  alias yalocs='yay -Qs'
+  alias yalst='yay -Qe'
+  alias yaorph='yay -Qtd'
+  alias yainsd='yay -S --asdeps'
+  alias yamir='yay -Syy'
+  alias yaupd="yay -Sy"
+  alias upgrade='yay -Syu'
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/asdf/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/asdf/README.md
new file mode 100644 (file)
index 0000000..f047860
--- /dev/null
@@ -0,0 +1,30 @@
+## asdf
+
+**Maintainer:** [@RobLoach](https://github.com/RobLoach)
+
+Adds integration with [asdf](https://github.com/asdf-vm/asdf), the extendable version manager, with support for Ruby, Node.js, Elixir, Erlang and more.
+
+### Installation
+
+1. [Download asdf](https://asdf-vm.com/guide/getting-started.html#_2-download-asdf) by running the following:
+
+  ```
+  git clone https://github.com/asdf-vm/asdf.git ~/.asdf
+  ```
+
+2. [Enable asdf](https://asdf-vm.com/guide/getting-started.html#_3-install-asdf) by adding it to your `plugins` definition in `~/.zshrc`.
+
+  ```
+  plugins=(asdf)
+  ```
+
+### Usage
+
+See the [asdf documentation](https://asdf-vm.com/guide/getting-started.html#_4-install-a-plugin) for information on how to use asdf:
+
+```
+asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
+asdf install nodejs latest
+asdf global nodejs latest
+asdf local nodejs latest
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/asdf/asdf.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/asdf/asdf.plugin.zsh
new file mode 100644 (file)
index 0000000..3016282
--- /dev/null
@@ -0,0 +1,27 @@
+# Find where asdf should be installed
+ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
+ASDF_COMPLETIONS="$ASDF_DIR/completions"
+
+# If not found, check for archlinux/AUR package (/opt/asdf-vm/)
+if [[ ! -f "$ASDF_DIR/asdf.sh" || ! -f "$ASDF_COMPLETIONS/asdf.bash" ]] && [[ -f "/opt/asdf-vm/asdf.sh" ]]; then
+  ASDF_DIR="/opt/asdf-vm"
+  ASDF_COMPLETIONS="$ASDF_DIR"
+fi
+
+# If not found, check for Homebrew package
+if [[ ! -f "$ASDF_DIR/asdf.sh" || ! -f "$ASDF_COMPLETIONS/asdf.bash" ]] && (( $+commands[brew] )); then
+  brew_prefix="$(brew --prefix asdf)"
+  ASDF_DIR="${brew_prefix}/libexec"
+  ASDF_COMPLETIONS="${brew_prefix}/etc/bash_completion.d"
+  unset brew_prefix
+fi
+
+# Load command
+if [[ -f "$ASDF_DIR/asdf.sh" ]]; then
+  . "$ASDF_DIR/asdf.sh"
+
+  # Load completions
+  if [[ -f "$ASDF_COMPLETIONS/asdf.bash" ]]; then
+    . "$ASDF_COMPLETIONS/asdf.bash"
+  fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/autoenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/autoenv/README.md
new file mode 100644 (file)
index 0000000..5dfb5fb
--- /dev/null
@@ -0,0 +1,20 @@
+# Autoenv plugin
+
+This plugin loads the [Autoenv](https://github.com/inishchith/autoenv).
+
+To use it, add `autoenv` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... autoenv)
+```
+
+## Functions
+
+* `use_env()`: creates and/or activates a virtualenv. For use in `.env` files.
+  See the source code for details.
+
+## Requirements
+
+In order to make this work, you will need to have the autoenv installed.
+
+More info on the usage and install at [the project's homepage](https://github.com/inishchith/autoenv).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/autoenv/autoenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/autoenv/autoenv.plugin.zsh
new file mode 100644 (file)
index 0000000..229a8a8
--- /dev/null
@@ -0,0 +1,72 @@
+# Initialization: activate autoenv or report its absence
+() {
+local d autoenv_dir install_locations
+if ! type autoenv_init >/dev/null; then
+  # Check if activate.sh is in $PATH
+  if (( $+commands[activate.sh] )); then
+    autoenv_dir="${commands[activate.sh]:h}"
+  fi
+
+  # Locate autoenv installation
+  if [[ -z $autoenv_dir ]]; then
+    install_locations=(
+      ~/.autoenv
+      ~/.local/bin
+      /usr/local/opt/autoenv
+      /opt/homebrew/opt/autoenv
+      /usr/local/bin
+      /usr/share/autoenv-git
+      ~/Library/Python/bin
+    )
+    for d ( $install_locations ); do
+      if [[ -e $d/activate.sh ]]; then
+        autoenv_dir=$d
+        break
+      fi
+    done
+  fi
+
+  # Look for Homebrew path as a last resort
+  if [[ -z "$autoenv_dir" ]] && (( $+commands[brew] )); then
+    d=$(brew --prefix)/opt/autoenv
+    if [[ -e $d/activate.sh ]]; then
+      autoenv_dir=$d
+    fi
+  fi
+
+  # Complain if autoenv is not installed
+  if [[ -z $autoenv_dir ]]; then 
+    cat <<END >&2
+-------- AUTOENV ---------
+Could not locate autoenv installation.
+Please check if autoenv is correctly installed.
+In the meantime the autoenv plugin is DISABLED.
+--------------------------
+END
+    return 1
+  fi
+  # Load autoenv
+  source $autoenv_dir/activate.sh
+fi
+}
+[[ $? != 0 ]] && return $?
+
+# The use_env call below is a reusable command to activate/create a new Python
+# virtualenv, requiring only a single declarative line of code in your .env files.
+# It only performs an action if the requested virtualenv is not the current one.
+
+use_env() {
+  local venv
+  venv="$1"
+  if [[ "${VIRTUAL_ENV:t}" != "$venv" ]]; then
+    if workon | grep -q "$venv"; then
+      workon "$venv"
+    else
+      echo -n "Create virtualenv $venv now? (Yn) "
+      read answer
+      if [[ "$answer" == "Y" ]]; then
+        mkvirtualenv "$venv"
+      fi
+    fi
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/autojump/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/autojump/README.md
new file mode 100644 (file)
index 0000000..750ff56
--- /dev/null
@@ -0,0 +1,11 @@
+# Autojump plugin
+
+This plugin loads the [autojump navigation tool](https://github.com/wting/autojump).
+
+To use it, add `autojump` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... autojump)
+```
+
+**Note:** you have to [install autojump](https://github.com/wting/autojump#installation) first.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/autojump/autojump.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/autojump/autojump.plugin.zsh
new file mode 100644 (file)
index 0000000..e11f231
--- /dev/null
@@ -0,0 +1,37 @@
+declare -a autojump_paths
+autojump_paths=(
+  $HOME/.autojump/etc/profile.d/autojump.zsh         # manual installation
+  $HOME/.autojump/share/autojump/autojump.zsh        # manual installation
+  $HOME/.nix-profile/etc/profile.d/autojump.sh       # NixOS installation
+  /run/current-system/sw/share/autojump/autojump.zsh # NixOS installation
+  /usr/share/autojump/autojump.zsh                   # Debian and Ubuntu package
+  /etc/profile.d/autojump.zsh                        # manual installation
+  /etc/profile.d/autojump.sh                         # Gentoo installation
+  /usr/local/share/autojump/autojump.zsh             # FreeBSD installation
+  /usr/pkg/share/autojump/autojump.zsh               # NetBSD installation
+  /opt/local/etc/profile.d/autojump.sh               # macOS with MacPorts
+  /usr/local/etc/profile.d/autojump.sh               # macOS with Homebrew (default)
+  /opt/homebrew/etc/profile.d/autojump.sh            # macOS with Homebrew (default on M1 macs)
+  /etc/profiles/per-user/$USER/bin/autojump          # macOS Nix, Home Manager and flakes
+)
+
+for file in $autojump_paths; do
+  if [[ -f "$file" ]]; then
+    source "$file"
+    found=1
+    break
+  fi
+done
+
+# if no path found, try Homebrew
+if (( ! found && $+commands[brew] )); then
+  file=$(brew --prefix)/etc/profile.d/autojump.sh
+  if [[ -f "$file" ]]; then
+    source "$file"
+    found=1
+  fi
+fi
+
+(( ! found )) && echo '[oh-my-zsh] autojump not found. Please install it first.'
+
+unset autojump_paths file found
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/autopep8/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/autopep8/README.md
new file mode 100644 (file)
index 0000000..02bbb9a
--- /dev/null
@@ -0,0 +1,8 @@
+# autopep8 plugin
+
+This plugin adds completion for [autopep8](https://pypi.org/project/autopep8/), a tool that automatically formats Python code to conform to the [PEP 8](http://www.python.org/dev/peps/pep-0008/) style guide.
+
+To use it, add autopep8 to the plugins array of your zshrc file:
+```
+plugins=(... autopep8)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/autopep8/_autopep8 b/stow/oh-my-zsh/.oh-my-zsh/plugins/autopep8/_autopep8
new file mode 100644 (file)
index 0000000..c14d06d
--- /dev/null
@@ -0,0 +1,32 @@
+#compdef autopep8
+#
+# this is zsh completion function file.
+# generated by genzshcomp(ver: 0.5.1)
+#
+
+typeset -A opt_args
+local context state line
+
+_arguments -s -S \
+  "--help[show this help message and exit]:" \
+  "-h[show this help message and exit]:" \
+  "--version[show program's version number and exit]:" \
+  "--verbose[print verbose messages; multiple -v result in more verbose messages]" \
+  "-v[print verbose messages; multiple -v result in more verbose messages]" \
+  "--diff[print the diff for the fixed source]" \
+  "-d[print the diff for the fixed source]" \
+  "--in-place[make changes to files in place]" \
+  "-i[make changes to files in place]" \
+  "--recursive[run recursively; must be used with --in-place or --diff]" \
+  "-r[run recursively; must be used with --in-place or --diff]" \
+  "--jobs[number of parallel jobs; match CPU count if value is less than 1]::n        number of parallel jobs; match CPU count if value is:_files" \
+  "-j[number of parallel jobs; match CPU count if value is less than 1]::n        number of parallel jobs; match CPU count if value is:_files" \
+  "--pep8-passes[maximum number of additional pep8 passes (default: 100)]::n:_files" \
+  "-p[maximum number of additional pep8 passes (default: 100)]::n:_files" \
+  "-a[-a result in more aggressive changes]::result:_files" \
+  "--exclude[exclude files/directories that match these comma- separated globs]::globs:_files" \
+  "--list-fixes[list codes for fixes; used by --ignore and --select]" \
+  "--ignore[do not fix these errors/warnings (default E226,E24)]::errors:_files" \
+  "--select[fix only these errors/warnings (e.g. E4,W)]::errors:_files" \
+  "--max-line-length[set maximum allowed line length (default: 79)]::n:_files" \
+  "*::args:_files"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aws/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/aws/README.md
new file mode 100644 (file)
index 0000000..d6f4f46
--- /dev/null
@@ -0,0 +1,76 @@
+# aws
+
+This plugin provides completion support for [awscli](https://docs.aws.amazon.com/cli/latest/reference/index.html)
+and a few utilities to manage AWS profiles and display them in the prompt.
+
+To use it, add `aws` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... aws)
+```
+
+## Plugin commands
+
+* `asp [<profile>]`: sets `$AWS_PROFILE` and `$AWS_DEFAULT_PROFILE` (legacy) to `<profile>`.
+  It also sets `$AWS_EB_PROFILE` to `<profile>` for the Elastic Beanstalk CLI.
+  Run `asp` without arguments to clear the profile.
+* `asp [<profile>] login`: If AWS SSO has been configured in your aws profile, it will run the `aws sso login` command following profile selection. 
+
+* `acp [<profile>] [<mfa_token>]`: in addition to `asp` functionality, it actually changes
+   the profile by assuming the role specified in the `<profile>` configuration. It supports
+   MFA and sets `$AWS_ACCESS_KEY_ID`, `$AWS_SECRET_ACCESS_KEY` and `$AWS_SESSION_TOKEN`, if
+   obtained. It requires the roles to be configured as per the
+   [official guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html).
+   Run `acp` without arguments to clear the profile.
+
+* `agp`: gets the current value of `$AWS_PROFILE`.
+
+* `aws_change_access_key`: changes the AWS access key of a profile.
+
+* `aws_profiles`: lists the available profiles in the  `$AWS_CONFIG_FILE` (default: `~/.aws/config`).
+  Used to provide completion for the `asp` function.
+
+## Plugin options
+
+* Set `SHOW_AWS_PROMPT=false` in your zshrc file if you want to prevent the plugin from modifying your RPROMPT.
+  Some themes might overwrite the value of RPROMPT instead of appending to it, so they'll need to be fixed to
+  see the AWS profile prompt.
+
+## Theme
+
+The plugin creates an `aws_prompt_info` function that you can use in your theme, which displays
+the current `$AWS_PROFILE`. It uses two variables to control how that is shown:
+
+* ZSH_THEME_AWS_PREFIX: sets the prefix of the AWS_PROFILE. Defaults to `<aws:`.
+
+* ZSH_THEME_AWS_SUFFIX: sets the suffix of the AWS_PROFILE. Defaults to `>`.
+
+## Configuration
+
+[Configuration and credential file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) by AWS
+
+### Scenario: IAM roles with a source profile and MFA authentication
+
+Source profile credentials in `~/.aws/credentials`:
+
+```
+[source-profile-name]
+aws_access_key_id = ...
+aws_secret_access_key = ...
+```
+
+Role configuration in `~/.aws/config`:
+
+```
+[profile source-profile-name]
+mfa_serial = arn:aws:iam::111111111111:mfa/myuser
+region = us-east-1
+output = json
+
+[profile profile-with-role]
+role_arn = arn:aws:iam::9999999999999:role/myrole
+mfa_serial = arn:aws:iam::111111111111:mfa/myuser
+source_profile = source-profile-name
+region = us-east-1
+output = json
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/aws/aws.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/aws/aws.plugin.zsh
new file mode 100644 (file)
index 0000000..2167f55
--- /dev/null
@@ -0,0 +1,212 @@
+function agp() {
+  echo $AWS_PROFILE
+}
+
+# AWS profile selection
+function asp() {
+  if [[ -z "$1" ]]; then
+    unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
+    echo AWS profile cleared.
+    return
+  fi
+
+  local -a available_profiles
+  available_profiles=($(aws_profiles))
+  if [[ -z "${available_profiles[(r)$1]}" ]]; then
+    echo "${fg[red]}Profile '$1' not found in '${AWS_CONFIG_FILE:-$HOME/.aws/config}'" >&2
+    echo "Available profiles: ${(j:, :)available_profiles:-no profiles found}${reset_color}" >&2
+    return 1
+  fi
+
+  export AWS_DEFAULT_PROFILE=$1
+  export AWS_PROFILE=$1
+  export AWS_EB_PROFILE=$1
+
+  if [[ "$2" == "login" ]]; then
+    aws sso login
+  fi
+}
+
+# AWS profile switch
+function acp() {
+  if [[ -z "$1" ]]; then
+    unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
+    unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
+    echo AWS profile cleared.
+    return
+  fi
+
+  local -a available_profiles
+  available_profiles=($(aws_profiles))
+  if [[ -z "${available_profiles[(r)$1]}" ]]; then
+    echo "${fg[red]}Profile '$1' not found in '${AWS_CONFIG_FILE:-$HOME/.aws/config}'" >&2
+    echo "Available profiles: ${(j:, :)available_profiles:-no profiles found}${reset_color}" >&2
+    return 1
+  fi
+
+  local profile="$1"
+  local mfa_token="$2"
+
+  # Get fallback credentials for if the aws command fails or no command is run
+  local aws_access_key_id="$(aws configure get aws_access_key_id --profile $profile)"
+  local aws_secret_access_key="$(aws configure get aws_secret_access_key --profile $profile)"
+  local aws_session_token="$(aws configure get aws_session_token --profile $profile)"
+
+
+  # First, if the profile has MFA configured, lets get the token and session duration
+  local mfa_serial="$(aws configure get mfa_serial --profile $profile)"
+  local sess_duration="$(aws configure get duration_seconds --profile $profile)"
+
+  if [[ -n "$mfa_serial" ]]; then
+    local -a mfa_opt
+    if [[ -z "$mfa_token" ]]; then
+      echo -n "Please enter your MFA token for $mfa_serial: "
+      read -r mfa_token
+    fi
+    if [[ -z "$sess_duration" ]]; then
+      echo -n "Please enter the session duration in seconds (900-43200; default: 3600, which is the default maximum for a role): "
+      read -r sess_duration
+    fi
+    mfa_opt=(--serial-number "$mfa_serial" --token-code "$mfa_token" --duration-seconds "${sess_duration:-3600}")
+  fi
+
+  # Now see whether we need to just MFA for the current role, or assume a different one
+  local role_arn="$(aws configure get role_arn --profile $profile)"
+  local sess_name="$(aws configure get role_session_name --profile $profile)"
+
+  if [[ -n "$role_arn" ]]; then
+    # Means we need to assume a specified role
+    aws_command=(aws sts assume-role --role-arn "$role_arn" "${mfa_opt[@]}")
+
+    # Check whether external_id is configured to use while assuming the role
+    local external_id="$(aws configure get external_id --profile $profile)"
+    if [[ -n "$external_id" ]]; then
+      aws_command+=(--external-id "$external_id")
+    fi
+
+    # Get source profile to use to assume role
+    local source_profile="$(aws configure get source_profile --profile $profile)"
+    if [[ -z "$sess_name" ]]; then
+      sess_name="${source_profile:-profile}"
+    fi
+    aws_command+=(--profile="${source_profile:-profile}" --role-session-name "${sess_name}")
+
+    echo "Assuming role $role_arn using profile ${source_profile:-profile}"
+  else
+    # Means we only need to do MFA
+    aws_command=(aws sts get-session-token --profile="$profile" "${mfa_opt[@]}")
+    echo "Obtaining session token for profile $profile"
+  fi
+
+  # Format output of aws command for easier processing
+  aws_command+=(--query '[Credentials.AccessKeyId,Credentials.SecretAccessKey,Credentials.SessionToken]' --output text)
+
+  # Run the aws command to obtain credentials
+  local -a credentials
+  credentials=(${(ps:\t:)"$(${aws_command[@]})"})
+
+  if [[ -n "$credentials" ]]; then
+    aws_access_key_id="${credentials[1]}"
+    aws_secret_access_key="${credentials[2]}"
+    aws_session_token="${credentials[3]}"
+  fi
+
+  # Switch to AWS profile
+  if [[ -n "${aws_access_key_id}" && -n "$aws_secret_access_key" ]]; then
+    export AWS_DEFAULT_PROFILE="$profile"
+    export AWS_PROFILE="$profile"
+    export AWS_EB_PROFILE="$profile"
+    export AWS_ACCESS_KEY_ID="$aws_access_key_id"
+    export AWS_SECRET_ACCESS_KEY="$aws_secret_access_key"
+
+    if [[ -n "$aws_session_token" ]]; then
+      export AWS_SESSION_TOKEN="$aws_session_token"
+    else
+      unset AWS_SESSION_TOKEN
+    fi
+
+    echo "Switched to AWS Profile: $profile"
+  fi
+}
+
+function aws_change_access_key() {
+  if [[ -z "$1" ]]; then
+    echo "usage: $0 <profile>"
+    return 1
+  fi
+
+  echo "Insert the credentials when asked."
+  asp "$1" || return 1
+  AWS_PAGER="" aws iam create-access-key
+  AWS_PAGER="" aws configure --profile "$1"
+
+  echo "You can now safely delete the old access key running \`aws iam delete-access-key --access-key-id ID\`"
+  echo "Your current keys are:"
+  AWS_PAGER="" aws iam list-access-keys
+}
+
+function aws_profiles() {
+  [[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1
+  grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([^[:space:]]+)\][[:space:]]*$/\2/g'
+}
+
+function _aws_profiles() {
+  reply=($(aws_profiles))
+}
+compctl -K _aws_profiles asp acp aws_change_access_key
+
+# AWS prompt
+function aws_prompt_info() {
+  [[ -n "$AWS_PROFILE" ]] || return
+  echo "${ZSH_THEME_AWS_PREFIX=<aws:}${AWS_PROFILE:gs/%/%%}${ZSH_THEME_AWS_SUFFIX=>}"
+}
+
+if [[ "$SHOW_AWS_PROMPT" != false && "$RPROMPT" != *'$(aws_prompt_info)'* ]]; then
+  RPROMPT='$(aws_prompt_info)'"$RPROMPT"
+fi
+
+
+# Load awscli completions
+
+# AWS CLI v2 comes with its own autocompletion. Check if that is there, otherwise fall back
+if command -v aws_completer &> /dev/null; then
+  autoload -Uz bashcompinit && bashcompinit
+  complete -C aws_completer aws
+else
+  function _awscli-homebrew-installed() {
+    # check if Homebrew is installed
+    (( $+commands[brew] )) || return 1
+
+    # speculatively check default brew prefix
+    if [ -h /usr/local/opt/awscli ]; then
+      _brew_prefix=/usr/local/opt/awscli
+    else
+      # ok, it is not in the default prefix
+      # this call to brew is expensive (about 400 ms), so at least let's make it only once
+      _brew_prefix=$(brew --prefix awscli)
+    fi
+  }
+
+  # get aws_zsh_completer.sh location from $PATH
+  _aws_zsh_completer_path="$commands[aws_zsh_completer.sh]"
+
+  # otherwise check common locations
+  if [[ -z $_aws_zsh_completer_path ]]; then
+    # Homebrew
+    if _awscli-homebrew-installed; then
+      _aws_zsh_completer_path=$_brew_prefix/libexec/bin/aws_zsh_completer.sh
+    # Ubuntu
+    elif [[ -e /usr/share/zsh/vendor-completions/_awscli ]]; then
+      _aws_zsh_completer_path=/usr/share/zsh/vendor-completions/_awscli
+    # NixOS
+    elif [[ -e "${commands[aws]:P:h:h}/share/zsh/site-functions/aws_zsh_completer.sh" ]]; then
+      _aws_zsh_completer_path="${commands[aws]:P:h:h}/share/zsh/site-functions/aws_zsh_completer.sh"
+    # RPM
+    else
+      _aws_zsh_completer_path=/usr/share/zsh/site-functions/aws_zsh_completer.sh
+    fi
+  fi
+
+  [[ -r $_aws_zsh_completer_path ]] && source $_aws_zsh_completer_path
+  unset _aws_zsh_completer_path _brew_prefix
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/battery/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/battery/README.md
new file mode 100644 (file)
index 0000000..18e5bd8
--- /dev/null
@@ -0,0 +1,29 @@
+# Battery Plugin
+
+This plugin adds some functions you can use to display battery information in your custom theme.
+
+To use, add `battery` to the list of plugins in your `.zshrc` file:
+
+`plugins=(... battery)`
+
+Then, add the `battery_pct_prompt` function to your custom theme. For example:
+
+```zsh
+RPROMPT='$(battery_pct_prompt) ...'
+```
+
+## Requirements
+
+- On Linux, you must have the `acpi` or `acpitool` commands installed on your operating system.
+  On Debian/Ubuntu, you can do that with `sudo apt install acpi` or `sudo apt install acpitool`.
+
+- On Android (via [Termux](https://play.google.com/store/apps/details?id=com.termux)), you must have:
+
+  1. The `Termux:API` addon app installed:
+     [Google Play](https://play.google.com/store/apps/details?id=com.termux.api) | [F-Droid](https://f-droid.org/packages/com.termux.api/)
+
+  2. The `termux-api` package installed within termux:
+
+     ```sh
+     pkg install termux-api
+     ```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/battery/battery.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/battery/battery.plugin.zsh
new file mode 100644 (file)
index 0000000..db5eeb9
--- /dev/null
@@ -0,0 +1,262 @@
+###########################################
+# Battery plugin for oh-my-zsh            #
+# Original Author: Peter hoeg (peterhoeg) #
+# Email: peter@speartail.com              #
+###########################################
+# Author: Sean Jones (neuralsandwich)     #
+# Email: neuralsandwich@gmail.com         #
+# Modified to add support for Apple Mac   #
+###########################################
+# Author: J (927589452)                   #
+# Modified to add support for FreeBSD     #
+###########################################
+# Author: Avneet Singh (kalsi-avneet)     #
+# Modified to add support for Android     #
+###########################################
+
+if [[ "$OSTYPE" = darwin* ]]; then
+  function battery_is_charging() {
+    ioreg -rc AppleSmartBattery | command grep -q '^.*"ExternalConnected"\ =\ Yes'
+  }
+  function battery_pct() {
+    pmset -g batt | grep -Eo "\d+%" | cut -d% -f1
+  }
+  function battery_pct_remaining() {
+    if battery_is_charging; then
+      echo "External Power"
+    else
+      battery_pct
+    fi
+  }
+  function battery_time_remaining() {
+    local smart_battery_status="$(ioreg -rc "AppleSmartBattery")"
+    if [[ $(echo $smart_battery_status | command grep -c '^.*"ExternalConnected"\ =\ No') -eq 1 ]]; then
+      timeremaining=$(echo $smart_battery_status | command grep '^.*"AvgTimeToEmpty"\ =\ ' | sed -e 's/^.*"AvgTimeToEmpty"\ =\ //')
+      if [ $timeremaining -gt 720 ]; then
+        echo "::"
+      else
+        echo "~$((timeremaining / 60)):$((timeremaining % 60))"
+      fi
+    else
+      echo "∞"
+    fi
+  }
+  function battery_pct_prompt () {
+    local battery_pct color
+    if ioreg -rc AppleSmartBattery | command grep -q '^.*"ExternalConnected"\ =\ No'; then
+      battery_pct=$(battery_pct_remaining)
+      if [[ $battery_pct -gt 50 ]]; then
+        color='green'
+      elif [[ $battery_pct -gt 20 ]]; then
+        color='yellow'
+      else
+        color='red'
+      fi
+      echo "%{$fg[$color]%}[${battery_pct}%%]%{$reset_color%}"
+    else
+      echo "∞"
+    fi
+  }
+
+elif [[ "$OSTYPE" = freebsd* ]]; then
+  function battery_is_charging() {
+    [[ $(sysctl -n hw.acpi.battery.state) -eq 2 ]]
+  }
+  function battery_pct() {
+    if (( $+commands[sysctl] )); then
+      sysctl -n hw.acpi.battery.life
+    fi
+  }
+  function battery_pct_remaining() {
+    if ! battery_is_charging; then
+      battery_pct
+    else
+      echo "External Power"
+    fi
+  }
+  function battery_time_remaining() {
+    local remaining_time
+    remaining_time=$(sysctl -n hw.acpi.battery.time)
+    if [[ $remaining_time -ge 0 ]]; then
+      ((hour = $remaining_time / 60 ))
+      ((minute = $remaining_time % 60 ))
+      printf %02d:%02d $hour $minute
+    fi
+  }
+  function battery_pct_prompt() {
+    local battery_pct color
+    battery_pct=$(battery_pct_remaining)
+    if battery_is_charging; then
+      echo "∞"
+    else
+      if [[ $battery_pct -gt 50 ]]; then
+        color='green'
+      elif [[ $battery_pct -gt 20 ]]; then
+        color='yellow'
+      else
+        color='red'
+      fi
+      echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
+    fi
+  }
+elif [[ "$OSTYPE" = linux-android ]] && (( ${+commands[termux-battery-status]} )); then
+  function battery_is_charging() {
+    termux-battery-status 2>/dev/null | command awk '/status/ { exit ($0 ~ /DISCHARGING/) }'
+  }
+  function battery_pct() {
+    # Sample output:
+    # {
+    #   "health": "GOOD",
+    #   "percentage": 93,
+    #   "plugged": "UNPLUGGED",
+    #   "status": "DISCHARGING",
+    #   "temperature": 29.0,
+    #   "current": 361816
+    # }
+    termux-battery-status 2>/dev/null | command awk '/percentage/ { gsub(/[,]/,""); print $2}'
+  }
+  function battery_pct_remaining() {
+    if ! battery_is_charging; then
+      battery_pct
+    else
+      echo "External Power"
+    fi
+  }
+  function battery_time_remaining() { } # Not available on android
+  function battery_pct_prompt() {
+    local battery_pct color
+    battery_pct=$(battery_pct_remaining)
+    if battery_is_charging; then
+      echo "∞"
+    else
+      if [[ $battery_pct -gt 50 ]]; then
+        color='green'
+      elif [[ $battery_pct -gt 20 ]]; then
+        color='yellow'
+      else
+        color='red'
+      fi
+      echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
+    fi
+  }
+elif [[ "$OSTYPE" = linux*  ]]; then
+  function battery_is_charging() {
+    if (( $+commands[acpitool] )); then
+      ! acpitool 2>/dev/null | command grep -qE '^\s+Battery.*Discharging'
+    elif (( $+commands[acpi] )); then
+      ! acpi 2>/dev/null | command grep -v "rate information unavailable" | command grep -q '^Battery.*Discharging'
+    fi
+  }
+  function battery_pct() {
+    if (( $+commands[acpitool] )); then
+      # Sample output:
+      #   Battery #1     : Unknown, 99.55%
+      #   Battery #2     : Discharging, 49.58%, 01:12:05
+      #   All batteries  : 62.60%, 02:03:03
+      local -i pct=$(acpitool 2>/dev/null | command awk -F, '
+        /^\s+All batteries/ {
+          gsub(/[^0-9.]/, "", $1)
+          pct=$1
+          exit
+        }
+        !pct && /^\s+Battery/ {
+          gsub(/[^0-9.]/, "", $2)
+          pct=$2
+        }
+        END { print pct }
+        ')
+      echo $pct
+    elif (( $+commands[acpi] )); then
+      # Sample output:
+      # Battery 0: Discharging, 0%, rate information unavailable
+      # Battery 1: Full, 100%
+      acpi 2>/dev/null | command awk -F, '
+        /rate information unavailable/ { next }
+        /^Battery.*: /{ gsub(/[^0-9]/, "", $2); print $2; exit }
+      '
+    fi
+  }
+  function battery_pct_remaining() {
+    if ! battery_is_charging; then
+      battery_pct
+    else
+      echo "External Power"
+    fi
+  }
+  function battery_time_remaining() {
+    if ! battery_is_charging; then
+      acpi 2>/dev/null | command grep -v "rate information unavailable" | cut -f3 -d ','
+    fi
+  }
+  function battery_pct_prompt() {
+    local battery_pct color
+    battery_pct=$(battery_pct_remaining)
+    if battery_is_charging; then
+      echo "∞"
+    else
+      if [[ $battery_pct -gt 50 ]]; then
+        color='green'
+      elif [[ $battery_pct -gt 20 ]]; then
+        color='yellow'
+      else
+        color='red'
+      fi
+      echo "%{$fg[$color]%}${battery_pct}%%%{$reset_color%}"
+    fi
+  }
+else
+  # Empty functions so we don't cause errors in prompts
+  function battery_is_charging { false }
+  function battery_pct \
+    battery_pct_remaining \
+    battery_time_remaining \
+    battery_pct_prompt { }
+fi
+
+function battery_level_gauge() {
+  local gauge_slots=${BATTERY_GAUGE_SLOTS:-10}
+  local green_threshold=${BATTERY_GREEN_THRESHOLD:-$(( gauge_slots * 0.6 ))}
+  local yellow_threshold=${BATTERY_YELLOW_THRESHOLD:-$(( gauge_slots * 0.4 ))}
+  local color_green=${BATTERY_COLOR_GREEN:-%F{green}}
+  local color_yellow=${BATTERY_COLOR_YELLOW:-%F{yellow}}
+  local color_red=${BATTERY_COLOR_RED:-%F{red}}
+  local color_reset=${BATTERY_COLOR_RESET:-%{%f%k%b%}}
+  local battery_prefix=${BATTERY_GAUGE_PREFIX:-'['}
+  local battery_suffix=${BATTERY_GAUGE_SUFFIX:-']'}
+  local filled_symbol=${BATTERY_GAUGE_FILLED_SYMBOL:-'▶'}
+  local empty_symbol=${BATTERY_GAUGE_EMPTY_SYMBOL:-'▷'}
+  local charging_color=${BATTERY_CHARGING_COLOR:-$color_yellow}
+  local charging_symbol=${BATTERY_CHARGING_SYMBOL:-'⚡'}
+
+  local -i battery_remaining_percentage=$(battery_pct)
+  local filled empty gauge_color
+
+  if [[ $battery_remaining_percentage =~ [0-9]+ ]]; then
+    filled=$(( ($battery_remaining_percentage * $gauge_slots) / 100 ))
+    empty=$(( $gauge_slots - $filled ))
+
+    if [[ $filled -gt $green_threshold ]]; then
+      gauge_color=$color_green
+    elif [[ $filled -gt $yellow_threshold ]]; then
+      gauge_color=$color_yellow
+    else
+      gauge_color=$color_red
+    fi
+  else
+    filled=$gauge_slots
+    empty=0
+    filled_symbol=${BATTERY_UNKNOWN_SYMBOL:-'.'}
+  fi
+
+  local charging=' '
+  battery_is_charging && charging=$charging_symbol
+
+  # Charging status and prefix
+  print -n ${charging_color}${charging}${color_reset}${battery_prefix}${gauge_color}
+  # Filled slots
+  [[ $filled -gt 0 ]] && printf ${filled_symbol//\%/\%\%}'%.0s' {1..$filled}
+  # Empty slots
+  [[ $filled -lt $gauge_slots ]] && printf ${empty_symbol//\%/\%\%}'%.0s' {1..$empty}
+  # Suffix
+  print -n ${color_reset}${battery_suffix}${color_reset}
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bazel/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/bazel/README.md
new file mode 100644 (file)
index 0000000..fc375d2
--- /dev/null
@@ -0,0 +1,14 @@
+# Bazel plugin
+
+This plugin adds completion for [bazel](https://bazel.build), an open-source build and
+test tool that scalably supports multi-language and multi-platform projects.
+
+To use it, add `bazel` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... bazel)
+```
+
+The plugin has a copy of [the completion script from the git repository][1].
+
+[1]: https://github.com/bazelbuild/bazel/blob/master/scripts/zsh_completion/_bazel
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bazel/_bazel b/stow/oh-my-zsh/.oh-my-zsh/plugins/bazel/_bazel
new file mode 100644 (file)
index 0000000..c34c572
--- /dev/null
@@ -0,0 +1,341 @@
+#compdef bazel
+
+# Copyright 2015 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Installation
+# ------------
+#
+# 1. Add this script to a directory on your $fpath:
+#     fpath[1,0]=~/.zsh/completion/
+#     mkdir -p ~/.zsh/completion/
+#     cp scripts/zsh_completion/_bazel ~/.zsh/completion
+#
+# 2. Optionally, add the following to your .zshrc.
+#     zstyle ':completion:*' use-cache on
+#     zstyle ':completion:*' cache-path ~/.zsh/cache
+#
+#   This way, the completion script does not have to parse Bazel's options
+#   repeatedly.  The directory in cache-path must be created manually.
+#
+# 3. Restart the shell
+#
+# Options
+# -------
+#  completion:init:bazel:* cache-lifetime
+#    Lifetime for the completion cache (if turned on, default: 1 week)
+
+local curcontext="$curcontext" state line
+
+: ${BAZEL_COMPLETION_PACKAGE_PATH:=%workspace%}
+: ${BAZEL:=bazel}
+_bazel_b() { ${BAZEL} --noblock_for_lock "$@" 2>/dev/null; }
+
+# Default cache lifetime is 1 week
+zstyle -s ":completion:${curcontext}:" cache-lifetime lifetime
+if [[ -z "${lifetime}" ]]; then
+  lifetime=$((60*60*24*7))
+fi
+
+_bazel_cache_policy() {
+  local -a oldp
+  oldp=( "$1"(Nms+${lifetime}) )
+  (( $#oldp ))
+}
+
+_set_cache_policy() {
+  zstyle -s ":completion:*:$curcontext*" cache-policy update_policy
+
+  if [[ -z "$update_policy" ]]; then
+    zstyle ":completion:$curcontext*" cache-policy _bazel_cache_policy
+  fi
+}
+
+# Skips over all global arguments.  After invocation, OFFSET contains the
+# position of the bazel command in $words.
+_adapt_subcommand_offset() {
+  OFFSET=2
+  for w in ${words[2,-1]}; do
+    if [[ $w == (#b)-* ]]; then
+      (( OFFSET++ ))
+    else
+      return
+    fi
+  done
+}
+
+# Retrieve the cache but also check that the value is not empty.
+_bazel_safe_retrieve_cache() {
+  _retrieve_cache $1 && [[ ${(P)#2} -gt 0 ]]
+}
+
+# Puts the name of the variable that contains the options for the bazel
+# subcommand handed in as the first argument into the global variable
+# _bazel_cmd_options.
+_bazel_get_options() {
+  local lcmd=$1
+  _bazel_cmd_options=_bazel_${lcmd}_options
+  _bazel_cmd_args=_bazel_${lcmd}_args
+  if [[ ${(P)#_bazel_cmd_options} != 0 ]]; then
+    return
+  fi
+  if _cache_invalid BAZEL_${lcmd}_options || _cache_invalid BAZEL_${lcmd}_args \
+    || ! _bazel_safe_retrieve_cache BAZEL_${lcmd}_options ${_bazel_cmd_options} \
+    || ! _retrieve_cache BAZEL_${lcmd}_args ${_bazel_cmd_args}; then
+    if ! eval "$(_bazel_b help completion)"; then
+      return
+    fi
+    local opts_var
+    if [[ $lcmd == "startup_options" ]]; then
+      opts_var="BAZEL_STARTUP_OPTIONS"
+    else
+      opts_var="BAZEL_COMMAND_${lcmd:u}_FLAGS"
+    fi
+    local -a raw_options
+    if ! eval "raw_options=(\${(@f)$opts_var})"; then
+      return
+    fi
+
+    local -a option_list
+    for opt in $raw_options; do
+      case $opt in
+        --*"={"*)
+          local lst="${${opt##*"={"}%"}"}"
+          local opt="${opt%%=*}="
+          option_list+=("${opt}:string:_values '' ${lst//,/ }") ;;
+        --*=path)
+          option_list+=("${opt%path}:path:_files") ;;
+        --*=label)
+          option_list+=("${opt%label}:target:_bazel_complete_target") ;;
+        --*=*)
+          option_list+=("${opt}:string:") ;;
+        *)
+          option_list+=("$opt") ;;
+      esac
+    done
+
+    local -a cmd_args
+    local cmd_type
+    if eval "cmd_type=\${BAZEL_COMMAND_${lcmd:u}_ARGUMENT}" && [[ -n $cmd_type ]]; then
+      case $cmd_type in
+        label|label-*)
+          cmd_args+=("*::${cmd_type}:_bazel_complete_target_${cmd_type//-/_}") ;;
+        info-key)
+          cmd_args+=('1::key:_bazel_info_key') ;;
+        path)
+          cmd_args+=('1::profile:_path_files') ;;
+        "command|{"*"}")
+          local lst=${${cmd_type#"command|{"}%"}"}
+          cmd_args+=("1::topic:_bazel_help_topic -- ${lst//,/ }") ;;
+      esac
+    fi
+
+    typeset -g "${_bazel_cmd_options}"="${(pj:|:)option_list[*]}"
+    _store_cache BAZEL_${lcmd}_options ${_bazel_cmd_options}
+    typeset -g "${_bazel_cmd_args}"="${(pj:|:)cmd_args[*]}"
+    _store_cache BAZEL_${lcmd}_args ${_bazel_cmd_args}
+  fi
+}
+
+_get_build_targets() {
+  local pkg=$1
+  local rule_re
+  typeset -a completions
+  case $target_type in
+    test)
+      rule_re=".*_test"
+      ;;
+    build)
+      rule_re=".*"
+      ;;
+    bin)
+      rule_re=".*_test|.*_binary"
+      ;;
+  esac
+  completions=(${$(_bazel_b query "kind(\"${rule_re}\", ${pkg}:all)" 2>/dev/null)##*:})
+  if ( (( ${#completions} > 0 )) && [[ $target_type != bin ]] ); then
+    completions+=(all)
+  fi
+  echo ${completions[*]}
+}
+
+# Returns all packages that match $PREFIX.  PREFIX may start with //, in which
+# case the workspace roots are searched.  Otherwise, they are completed based on
+# PWD.
+_get_build_packages() {
+  local workspace pfx
+  typeset -a package_roots paths final_paths
+  workspace=$PWD
+  package_roots=(${(ps.:.)BAZEL_COMPLETION_PACKAGE_PATH})
+  package_roots=(${^package_roots//\%workspace\%/$workspace})
+  if [[ "${(e)PREFIX}" == //* ]]; then
+    pfx=${(e)PREFIX[2,-1]}
+  else
+    pfx=${(e)PREFIX}
+  fi
+  paths=(${^package_roots}/${pfx}*(/))
+  for p in ${paths[*]}; do
+    if [[ -f ${p}/BUILD || -f ${p}/BUILD.bazel ]]; then
+      final_paths+=(${p##*/}:)
+    fi
+    final_paths+=(${p##*/}/)
+  done
+  echo ${final_paths[*]}
+}
+
+_package_remove_slash() {
+  if [[ $KEYS == ':' && $LBUFFER == */ ]]; then
+    LBUFFER=${LBUFFER[1,-2]}
+  fi
+}
+
+# Completion function for BUILD targets, called by the completion system.
+_bazel_complete_target() {
+  local expl
+  typeset -a packages targets
+  if [[ "${(e)PREFIX}" != *:* ]]; then
+    # There is no : in the prefix, completion can be either
+    # a package or a target, if the cwd is a package itself.
+    if [[ -f $PWD/BUILD || -f $PWD/BUILD.bazel ]]; then
+      targets=($(_get_build_targets ""))
+      _description build_target expl "BUILD target"
+      compadd "${expl[@]}" -a targets
+    fi
+    packages=($(_get_build_packages))
+    _description build_package expl "BUILD package"
+    # Chop of the leading path segments from the prefix for display.
+    compset -P '*/'
+    compadd -R _package_remove_slash -S '' "${expl[@]}" -a packages
+  else
+    targets=($(_get_build_targets "${${(e)PREFIX}%:*}"))
+    _description build_target expl "BUILD target"
+    # Ignore the current prefix for the upcoming completion, since we only list
+    # the names of the targets, not the full path.
+    compset -P '*:'
+    compadd "${expl[@]}" -a targets
+  fi
+}
+
+_bazel_complete_target_label() {
+  typeset -g target_type=build
+  _bazel_complete_target
+}
+
+_bazel_complete_target_label_test() {
+  typeset -g target_type=test
+  _bazel_complete_target
+}
+
+_bazel_complete_target_label_bin() {
+  typeset -g target_type=bin
+  _bazel_complete_target
+}
+
+### Actual completion commands
+
+_bazel() {
+  _adapt_subcommand_offset
+  if (( CURRENT - OFFSET > 0 )); then
+    # Remember the subcommand name, stored globally so we can access it
+    # from any subsequent function
+    cmd=${words[OFFSET]//-/_}
+
+    # Set the context for the subcommand.
+    curcontext="${curcontext%:*:*}:bazel-$cmd:"
+    _set_cache_policy
+
+    # Narrow the range of words we are looking at to exclude cmd
+    # name and any leading options
+    (( CURRENT = CURRENT - OFFSET + 1 ))
+    shift $((OFFSET - 1)) words
+    # Run the completion for the subcommand
+    _bazel_get_options $cmd
+    _arguments : \
+      ${(Pps:|:)_bazel_cmd_options} \
+      ${(Pps:|:)_bazel_cmd_args}
+  else
+    _set_cache_policy
+    # Start special handling for global options,
+    # which can be retrieved by calling
+    # $ bazel help startup_options
+    _bazel_get_options startup_options
+    _arguments : \
+      ${(Pps:|:)_bazel_cmd_options} \
+      "*:commands:_bazel_commands"
+  fi
+  return
+}
+
+_get_commands() {
+  # bazel_cmd_list is a global (g) array (a)
+  typeset -ga _bazel_cmd_list
+  # Use `bazel help` instead of `bazel help completion` to get command
+  # descriptions.
+  if _bazel_cmd_list=("${(@f)$(_bazel_b help | awk '
+/Available commands/ { command=1; }
+/  [-a-z]+[ \t]+.+/ { if (command) { printf "%s:", $1; for (i=2; i<=NF; i++) printf "%s ", $i; print "" } }
+/^$/ { command=0; }')}"); then
+    _store_cache BAZEL_commands _bazel_cmd_list
+  fi
+}
+
+# Completion function for bazel subcommands, called by the completion system.
+_bazel_commands() {
+  if [[ ${#_bazel_cmd_list} == 0 ]]; then
+    if _cache_invalid BAZEL_commands \
+      || ! _bazel_safe_retrieve_cache BAZEL_commands _bazel_cmd_list; then
+      _get_commands
+    fi
+  fi
+
+  _describe -t bazel-commands 'Bazel command' _bazel_cmd_list
+}
+
+# Completion function for bazel help options, called by the completion system.
+_bazel_help_topic() {
+  if [[ ${#_bazel_cmd_list} == 0 ]]; then
+    if _cache_invalid BAZEL_commands \
+      || ! _bazel_safe_retrieve_cache BAZEL_commands _bazel_cmd_list; then
+      _get_commands
+    fi
+  fi
+
+  while [[ $# -gt 0 ]]; do
+    if [[ $1 == -- ]]; then
+      shift
+      break
+    fi
+    shift
+  done
+  _bazel_help_list=($@)
+  _bazel_help_list+=($_bazel_cmd_list)
+  _describe -t bazel-help 'Help topic' _bazel_help_list
+}
+
+# Completion function for bazel info keys, called by the completion system.
+_bazel_info_key() {
+  if [[ ${#_bazel_info_keys_list} == 0 ]]; then
+    if _cache_invalid BAZEL_info_keys \
+      || ! _bazel_safe_retrieve_cache BAZEL_info_keys _bazel_info_keys_list; then
+      typeset -ga _bazel_info_keys_list
+      # Use `bazel help` instead of `bazel help completion` to get info-key
+      # descriptions.
+      if _bazel_info_keys_list=("${(@f)$(_bazel_b help info-keys | awk '
+  { printf "%s:", $1; for (i=2; i<=NF; i++) printf "%s ", $i; print "" }')}"); then
+        _store_cache BAZEL_info_keys _bazel_info_keys_list
+      fi
+    fi
+  fi
+  _describe -t bazel-info 'Key' _bazel_info_keys_list
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bbedit/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/bbedit/README.md
new file mode 100644 (file)
index 0000000..263c54c
--- /dev/null
@@ -0,0 +1,20 @@
+## bbedit
+
+Plugin for BBEdit, an HTML and text editor for Mac OS X
+
+### Requirements
+
+ * [BBEdit](https://www.barebones.com/products/bbedit/)
+ * [BBEdit Command-Line Tools](https://www.barebones.com/support/bbedit/cmd-line-tools.html)
+
+### Usage
+
+ * If the `bb` command is called without an argument, launch BBEdit
+
+ * If `bb` is passed a directory, cd to it and open it in BBEdit
+
+ * If `bb` is passed a file, open it in BBEdit
+
+ * If `bbpb` create a new BBEdit document with the contents of the clipboard
+
+ * If `bbd` alias for BBEdit diff tool
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bbedit/bbedit.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/bbedit/bbedit.plugin.zsh
new file mode 100644 (file)
index 0000000..fe9e72c
--- /dev/null
@@ -0,0 +1,21 @@
+alias bbpb='pbpaste | bbedit --clean --view-top'
+
+alias bbd=bbdiff
+
+#
+# If the bb command is called without an argument, launch BBEdit
+# If bb is passed a directory, cd to it and open it in BBEdit
+# If bb is passed a file, open it in BBEdit
+#
+function bb() {
+    if [[ -z "$1" ]]
+    then
+        bbedit --launch
+    else
+        bbedit "$1"
+        if [[ -d "$1" ]]
+        then
+            cd "$1"
+        fi
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bedtools/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/bedtools/README.md
new file mode 100644 (file)
index 0000000..c4de4e3
--- /dev/null
@@ -0,0 +1,5 @@
+# Bedtools plugin
+
+This plugin adds support for the [bedtools suite](http://bedtools.readthedocs.org/en/latest/):
+
+* Adds autocomplete options for all bedtools sub commands.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bedtools/_bedtools b/stow/oh-my-zsh/.oh-my-zsh/plugins/bedtools/_bedtools
new file mode 100644 (file)
index 0000000..ef6c417
--- /dev/null
@@ -0,0 +1,64 @@
+#compdef bedtools
+#autoload
+
+local curcontext="$curcontext" state line ret=1
+local -a _files
+
+_arguments -C \
+  '1: :->cmds' \
+  '2:: :->args' && ret=0
+
+case $state in
+  cmds)
+    _values "bedtools command" \
+        "--contact[Feature requests, bugs, mailing lists, etc.]" \
+        "--help[Print this help menu.]" \
+        "--version[What version of bedtools are you using?.]" \
+        "annotate[Annotate coverage of features from multiple files.]" \
+        "bamtobed[Convert BAM alignments to BED (& other) formats.]" \
+        "bamtofastq[Convert BAM records to FASTQ records.]" \
+        "bed12tobed6[Breaks BED12 intervals into discrete BED6 intervals.]" \
+        "bedpetobam[Convert BEDPE intervals to BAM records.]" \
+        "bedtobam[Convert intervals to BAM records.]" \
+        "closest[Find the closest, potentially non-overlapping interval.]" \
+        "cluster[Cluster (but don't merge) overlapping/nearby intervals.]" \
+        "complement[Extract intervals _not_ represented by an interval file.]" \
+        "coverage[Compute the coverage over defined intervals.]" \
+        "expand[Replicate lines based on lists of values in columns.]" \
+        "fisher[Calculate Fisher statistic b/w two feature files.]" \
+        "flank[Create new intervals from the flanks of existing intervals.]" \
+        "genomecov[Compute the coverage over an entire genome.]" \
+        "getfasta[Use intervals to extract sequences from a FASTA file.]" \
+        "groupby[Group by common cols. & summarize oth. cols. (~ SQL "groupBy")]" \
+        "igv[Create an IGV snapshot batch script.]" \
+        "intersect[Find overlapping intervals in various ways.]" \
+        "jaccard[Calculate the Jaccard statistic b/w two sets of intervals.]" \
+        "links[Create a HTML page of links to UCSC locations.]" \
+        "makewindows[Make interval "windows" across a genome.]" \
+        "map[Apply a function to a column for each overlapping interval.]" \
+        "maskfasta[Use intervals to mask sequences from a FASTA file.]" \
+        "merge[Combine overlapping/nearby intervals into a single interval.]" \
+        "multicov[Counts coverage from multiple BAMs at specific intervals.]" \
+        "multiinter[Identifies common intervals among multiple interval files.]" \
+        "nuc[Profile the nucleotide content of intervals in a FASTA file.]" \
+        "overlap[Computes the amount of overlap from two intervals.]" \
+        "pairtobed[Find pairs that overlap intervals in various ways.]" \
+        "pairtopair[Find pairs that overlap other pairs in various ways.]" \
+        "random[Generate random intervals in a genome.]" \
+        "reldist[Calculate the distribution of relative distances b/w two files.]" \
+        "sample[Sample random records from file using reservoir sampling.]" \
+        "shuffle[Randomly redistrubute intervals in a genome.]" \
+        "slop[Adjust the size of intervals.]" \
+        "sort[Order the intervals in a file.]" \
+        "subtract[Remove intervals based on overlaps b/w two files.]" \
+        "tag[Tag BAM alignments based on overlaps with interval files.]" \
+        "unionbedg[Combines coverage intervals from multiple BEDGRAPH files.]" \
+        "window[Find overlapping intervals within a window around an interval.]" \
+    ret=0
+    ;;
+  *)
+    _files
+    ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bgnotify/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/bgnotify/README.md
new file mode 100644 (file)
index 0000000..1d8fac5
--- /dev/null
@@ -0,0 +1,54 @@
+# bgnotify zsh plugin
+
+cross-platform background notifications for long running commands! Supports OSX and Ubuntu linux.
+
+Standalone homepage: [t413/zsh-background-notify](https://github.com/t413/zsh-background-notify)
+
+----------------------------------
+
+## How to use!
+
+Just add bgnotify to your plugins list in your `.zshrc`
+
+- On OS X you'll need [terminal-notifier](https://github.com/alloy/terminal-notifier)
+  * `brew install terminal-notifier` (or `gem install terminal-notifier`)
+- On ubuntu you're already all set!
+- On windows you can use [notifu](https://www.paralint.com/projects/notifu/) or the Cygwin Ports libnotify package
+
+
+## Screenshots
+
+**Linux**
+
+![screenshot from 2014-11-07 15 58 36](https://cloud.githubusercontent.com/assets/326829/4962187/256b465c-66da-11e4-927d-cc2fc105e31f.png)
+
+**OS X**
+
+![screenshot 2014-11-08 14 15 12](https://cloud.githubusercontent.com/assets/326829/4965780/19fa3eac-6795-11e4-8ed6-0355711123a9.png)
+
+**Windows**
+
+![screenshot from 2014-11-07 15 55 00](https://cloud.githubusercontent.com/assets/326829/4962159/a2625ca0-66d9-11e4-9e91-c5834913190e.png)
+
+
+## Configuration
+
+One can configure a few things:
+
+- `bgnotify_threshold` sets the notification threshold time (default 6 seconds)
+- `function bgnotify_formatted` lets you change the notification
+
+Use these by adding a function definition before the your call to source. Example:
+
+~~~ sh
+bgnotify_threshold=4  ## set your own notification threshold
+
+function bgnotify_formatted {
+  ## $1=exit_status, $2=command, $3=elapsed_time
+  [ $1 -eq 0 ] && title="Holy Smokes Batman!" || title="Holy Graf Zeppelin!"
+  bgnotify "$title -- after $3 s" "$2";
+}
+
+plugins=(git bgnotify)  ## add to plugins list
+source $ZSH/oh-my-zsh.sh  ## existing source call
+~~~
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bgnotify/bgnotify.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/bgnotify/bgnotify.plugin.zsh
new file mode 100644 (file)
index 0000000..479796d
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/env zsh
+
+## setup ##
+
+[[ -o interactive ]] || return #interactive only!
+zmodload zsh/datetime || { print "can't load zsh/datetime"; return } # faster than date()
+autoload -Uz add-zsh-hook || { print "can't add zsh hook!"; return }
+
+(( ${+bgnotify_threshold} )) || bgnotify_threshold=5 #default 10 seconds
+
+
+## definitions ##
+
+if ! (type bgnotify_formatted | grep -q 'function'); then ## allow custom function override
+  function bgnotify_formatted { ## args: (exit_status, command, elapsed_seconds)
+    elapsed="$(( $3 % 60 ))s"
+    (( $3 >= 60 )) && elapsed="$((( $3 % 3600) / 60 ))m $elapsed"
+    (( $3 >= 3600 )) && elapsed="$(( $3 / 3600 ))h $elapsed"
+    [ $1 -eq 0 ] && bgnotify "#win (took $elapsed)" "$2" || bgnotify "#fail (took $elapsed)" "$2"
+  }
+fi
+
+currentAppId () {
+  if (( $+commands[osascript] )); then
+    osascript -e 'tell application (path to frontmost application as text) to id' 2>/dev/null
+  fi
+}
+
+currentWindowId () {
+  if hash osascript 2>/dev/null; then #osx
+    osascript -e 'tell application (path to frontmost application as text) to id of front window' 2&> /dev/null || echo "0"
+  elif (hash notify-send 2>/dev/null || hash kdialog 2>/dev/null); then #ubuntu!
+    xprop -root 2> /dev/null | awk '/NET_ACTIVE_WINDOW/{print $5;exit} END{exit !$5}' || echo "0"
+  else
+    echo $EPOCHSECONDS #fallback for windows
+  fi
+}
+
+bgnotify () { ## args: (title, subtitle)
+  if hash terminal-notifier 2>/dev/null; then #osx
+    local term_id="$bgnotify_appid"
+    if [[ -z "$term_id" ]]; then
+      case "$TERM_PROGRAM" in
+      iTerm.app) term_id='com.googlecode.iterm2' ;;
+      Apple_Terminal) term_id='com.apple.terminal' ;;
+      esac
+    fi
+
+    ## now call terminal-notifier, (hopefully with $term_id!)
+    if [[ -z "$term_id" ]]; then
+      terminal-notifier -message "$2" -title "$1" >/dev/null
+    else
+      terminal-notifier -message "$2" -title "$1" -activate "$term_id" -sender "$term_id" >/dev/null
+    fi
+  elif hash growlnotify 2>/dev/null; then #osx growl
+    growlnotify -m "$1" "$2"
+  elif hash notify-send 2>/dev/null; then #ubuntu gnome!
+    notify-send "$1" "$2"
+  elif hash kdialog 2>/dev/null; then #ubuntu kde!
+    kdialog --title "$1" --passivepopup  "$2" 5
+  elif hash notifu 2>/dev/null; then #cygwyn support!
+    notifu /m "$2" /p "$1"
+  fi
+}
+
+
+## Zsh hooks ##
+
+bgnotify_begin() {
+  bgnotify_timestamp=$EPOCHSECONDS
+  bgnotify_lastcmd="${1:-$2}"
+  bgnotify_appid="$(currentAppId)"
+  bgnotify_windowid=$(currentWindowId)
+}
+
+bgnotify_end() {
+  didexit=$?
+  elapsed=$(( EPOCHSECONDS - bgnotify_timestamp ))
+  past_threshold=$(( elapsed >= bgnotify_threshold ))
+  if (( bgnotify_timestamp > 0 )) && (( past_threshold )); then
+    if [[ $(currentAppId) != "$bgnotify_appid" || $(currentWindowId) != "$bgnotify_windowid" ]]; then
+      print -n "\a"
+      bgnotify_formatted "$didexit" "$bgnotify_lastcmd" "$elapsed"
+    fi
+  fi
+  bgnotify_timestamp=0 #reset it to 0!
+}
+
+## only enable if a local (non-ssh) connection
+if [ -z "$SSH_CLIENT" ] && [ -z "$SSH_TTY" ]; then
+  add-zsh-hook preexec bgnotify_begin
+  add-zsh-hook precmd bgnotify_end
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bower/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/bower/README.md
new file mode 100644 (file)
index 0000000..8877fbd
--- /dev/null
@@ -0,0 +1,17 @@
+# Bower plugin
+
+This plugin adds completion for [Bower](https://bower.io/) and a few useful aliases for common Bower commands.
+
+To use it, add `bower` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... bower)
+```
+
+## Aliases
+
+| Alias | Command         | Description                                            |
+|-------|-----------------|--------------------------------------------------------|
+| bi    | `bower install` | Installs the project dependencies listed in bower.json |
+| bl    | `bower list`    | List local packages and possible updates               |
+| bs    | `bower search`  | Finds all packages or a specific package.              |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bower/_bower b/stow/oh-my-zsh/.oh-my-zsh/plugins/bower/_bower
new file mode 100644 (file)
index 0000000..ae0ca4a
--- /dev/null
@@ -0,0 +1,58 @@
+
+
+# Credits to npm's awesome completion utility.
+#
+# Bower completion script, based on npm completion script.
+
+###-begin-bower-completion-###
+#
+# Installation: bower completion >> ~/.bashrc  (or ~/.zshrc)
+# Or, maybe: bower completion > /usr/local/etc/bash_completion.d/bower
+#
+
+COMP_WORDBREAKS=${COMP_WORDBREAKS/=/}
+COMP_WORDBREAKS=${COMP_WORDBREAKS/@/}
+export COMP_WORDBREAKS
+
+if type complete &>/dev/null; then
+  _bower_completion () {
+    local si="$IFS"
+    IFS=$'\n' COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \
+                           COMP_LINE="$COMP_LINE" \
+                           COMP_POINT="$COMP_POINT" \
+                           bower completion -- "${COMP_WORDS[@]}" \
+                           2>/dev/null)) || return $?
+    IFS="$si"
+  }
+  complete -F _bower_completion bower
+elif type compdef &>/dev/null; then
+  _bower_completion() {
+    si=$IFS
+    compadd -- $(COMP_CWORD=$((CURRENT-1)) \
+                 COMP_LINE=$BUFFER \
+                 COMP_POINT=0 \
+                 bower completion -- "${words[@]}" \
+                 2>/dev/null)
+    IFS=$si
+  }
+  compdef _bower_completion bower
+elif type compctl &>/dev/null; then
+  _bower_completion () {
+    local cword line point words si
+    read -Ac words
+    read -cn cword
+    let cword-=1
+    read -l line
+    read -ln point
+    si="$IFS"
+    IFS=$'\n' reply=($(COMP_CWORD="$cword" \
+                       COMP_LINE="$line" \
+                       COMP_POINT="$point" \
+                       bower completion -- "${words[@]}" \
+                       2>/dev/null)) || return $?
+    IFS="$si"
+  }
+  compctl -K _bower_completion bower
+fi
+###-end-bower-completion-###
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bower/bower.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/bower/bower.plugin.zsh
new file mode 100644 (file)
index 0000000..c4f71c2
--- /dev/null
@@ -0,0 +1,84 @@
+alias bi="bower install"
+alias bisd="bower install --save-dev"
+alias bis="bower install --save"
+alias bl="bower list"
+alias bs="bower search"
+
+_bower_installed_packages () {
+    bower_package_list=$(bower ls --no-color 2>/dev/null| awk 'NR>3{print p}{p=$0}'| cut -d ' ' -f 2|sed 's/#.*//')
+}
+_bower ()
+{
+    local -a _1st_arguments _no_color _dopts _save_dev _force_latest _production
+    local expl
+    typeset -A opt_args
+
+    _no_color=('--no-color[Do not print colors (available in all commands)]')
+
+    _dopts=(
+        '(--save)--save[Save installed packages into the project"s bower.json dependencies]'
+        '(--force)--force[Force fetching remote resources even if a local copy exists on disk]'
+    )
+
+    _save_dev=('(--save-dev)--save-dev[Save installed packages into the project"s bower.json devDependencies]')
+
+    _force_latest=('(--force-latest)--force-latest[Force latest version on conflict]')
+
+    _production=('(--production)--production[Do not install project devDependencies]')
+
+    _1st_arguments=(
+    'cache-clean:Clean the Bower cache, or the specified package caches' \
+    'help:Display help information about Bower' \
+    'info:Version info and description of a particular package' \
+    'init:Interactively create a bower.json file' \
+    'install:Install a package locally' \
+    'link:Symlink a package folder' \
+    'lookup:Look up a package URL by name' \
+    'register:Register a package' \
+    'search:Search for a package by name' \
+    'uninstall:Remove a package' \
+    'update:Update a package' \
+    {ls,list}:'[List all installed packages]'
+    )
+    _arguments \
+    $_no_color \
+    '*:: :->subcmds' && return 0
+
+    if (( CURRENT == 1 )); then
+        _describe -t commands "bower subcommand" _1st_arguments
+        return
+    fi
+
+    case "$words[1]" in
+        install)
+        _arguments \
+        $_dopts \
+        $_save_dev \
+        $_force_latest \
+        $_no_color \
+        $_production
+        ;;
+        update)
+        _arguments \
+        $_dopts \
+        $_no_color \
+        $_force_latest
+        _bower_installed_packages
+        compadd "$@" $(echo $bower_package_list)
+        ;;
+        uninstall)
+        _arguments \
+        $_no_color \
+        $_dopts
+        _bower_installed_packages
+        compadd "$@" $(echo $bower_package_list)
+        ;;
+        *)
+        _arguments \
+        $_no_color \
+        ;;
+    esac
+
+}
+
+compdef _bower bower
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/branch/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/branch/README.md
new file mode 100644 (file)
index 0000000..a15dd22
--- /dev/null
@@ -0,0 +1,49 @@
+# Branch plugin
+
+This plugin displays the current Git or Mercurial branch, fast. If in a Mercurial repository,
+also display the current bookmark, if present.
+
+To use it, add `branch` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... branch)
+```
+
+## Speed test
+
+- `hg branch`:
+
+  ```console
+  $ time hg branch
+  0.11s user 0.14s system 70% cpu 0.355 total
+  ```
+
+- branch plugin:
+
+  ```console
+  $ time zsh /tmp/branch_prompt_info_test.zsh
+  0.00s user 0.01s system 78% cpu 0.014 total
+  ```
+
+## Usage
+
+Copy your theme to `$ZSH_CUSTOM/themes/` and modify it to add `$(branch_prompt_info)` in your prompt.
+This example is for the `robbyrussell` theme:
+
+```diff
+diff --git a/themes/robbyrussell.zsh-theme b/themes/robbyrussell.zsh-theme
+index 2fd5f2cd..9d89a464 100644
+--- a/themes/robbyrussell.zsh-theme
++++ b/themes/robbyrussell.zsh-theme
+@@ -1,5 +1,5 @@
+ PROMPT="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ )"
+-PROMPT+=' %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)'
++PROMPT+=' %{$fg[cyan]%}%c%{$reset_color%} $(branch_prompt_info)'
+ ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
+ ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+```
+
+## Maintainer
+
+Victor Torres (<vpaivatorres@gmail.com>)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/branch/branch.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/branch/branch.plugin.zsh
new file mode 100644 (file)
index 0000000..dd5871f
--- /dev/null
@@ -0,0 +1,35 @@
+# Branch: displays the current Git or Mercurial branch fast.
+# Victor Torres <vpaivatorres@gmail.com>
+# Oct 2, 2015
+
+function branch_prompt_info() {
+  # Start checking in current working directory
+  local branch="" dir="$PWD"
+  while [[ "$dir" != '/' ]]; do
+    # Found .git directory
+    if [[ -d "${dir}/.git" ]]; then
+      branch="${"$(<"${dir}/.git/HEAD")"##*/}"
+      echo '±' "${branch:gs/%/%%}"
+      return
+    fi
+
+    # Found .hg directory
+    if [[ -d "${dir}/.hg" ]]; then
+      if [[ -f "${dir}/.hg/branch" ]]; then
+        branch="$(<"${dir}/.hg/branch")"
+      else
+        branch="default"
+      fi
+
+      if [[ -f "${dir}/.hg/bookmarks.current" ]]; then
+        branch="${branch}/$(<"${dir}/.hg/bookmarks.current")"
+      fi
+
+      echo '☿' "${branch:gs/%/%%}"
+      return
+    fi
+
+    # Check parent directory
+    dir="${dir:h}"
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/brew/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/brew/README.md
new file mode 100644 (file)
index 0000000..9ce2c5b
--- /dev/null
@@ -0,0 +1,37 @@
+# brew plugin
+
+The plugin adds several aliases for common [brew](https://brew.sh) commands.
+
+To use it, add `brew` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... brew)
+```
+
+## Shellenv
+
+If `brew` is not found in the PATH, this plugin will attempt to find it in common
+locations, and execute `brew shellenv` to set the environment appropriately.
+This plugin will also export `HOMEBREW_PREFIX="$(brew --prefix)"` if not previously
+defined for convenience.
+
+## Aliases
+
+| Alias    | Command                               | Description                                                         |
+| -------- | ------------------------------------- | ------------------------------------------------------------------- |
+| `bcubc`  | `brew upgrade --cask && brew cleanup` | Update outdated casks, then run cleanup.                            |
+| `bcubo`  | `brew update && brew outdated --cask` | Update Homebrew data, then list outdated casks.                     |
+| `brewp`  | `brew pin`                            | Pin a specified formula so that it's not upgraded.                  |
+| `brews`  | `brew list -1`                        | List installed formulae or the installed files for a given formula. |
+| `brewsp` | `brew list --pinned`                  | List pinned formulae, or show the version of a given formula.       |
+| `bubc`   | `brew upgrade && brew cleanup`        | Upgrade outdated formulae and casks, then run cleanup.              |
+| `bubo`   | `brew update && brew outdated`        | Update Homebrew data, then list outdated formulae and casks.        |
+| `bubu`   | `bubo && bubc`                        | Do the last two operations above.                                   |
+| `buf`    | `brew upgrade --formula`              | Upgrade only formulas (not casks).                                  |
+
+## Completion
+
+With the release of Homebrew 1.0, they decided to bundle the zsh completion as part of the
+brew installation, so we no longer ship it with the brew plugin; now it only has brew
+aliases. If you find that brew completion no longer works, make sure you have your Homebrew
+installation fully up to date.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/brew/brew.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/brew/brew.plugin.zsh
new file mode 100644 (file)
index 0000000..41420b5
--- /dev/null
@@ -0,0 +1,48 @@
+if (( ! $+commands[brew] )); then
+  if [[ -x /opt/homebrew/bin/brew ]]; then
+    BREW_LOCATION="/opt/homebrew/bin/brew"
+  elif [[ -x /usr/local/bin/brew ]]; then
+    BREW_LOCATION="/usr/local/bin/brew"
+  elif [[ -x /home/linuxbrew/.linuxbrew/bin/brew ]]; then
+    BREW_LOCATION="/home/linuxbrew/.linuxbrew/bin/brew"
+  elif [[ -x "$HOME/.linuxbrew/bin/brew" ]]; then
+    BREW_LOCATION="$HOME/.linuxbrew/bin/brew"
+  else
+    return
+  fi
+
+  # Only add Homebrew installation to PATH, MANPATH, and INFOPATH if brew is
+  # not already on the path, to prevent duplicate entries. This aligns with
+  # the behavior of the brew installer.sh post-install steps.
+  eval "$("$BREW_LOCATION" shellenv)"
+  unset BREW_LOCATION
+fi
+
+if [[ -z "$HOMEBREW_PREFIX" ]]; then
+  # Maintain compatability with potential custom user profiles, where we had
+  # previously relied on always sourcing shellenv. OMZ plugins should not rely
+  # on this to be defined due to out of order processing.
+  export HOMEBREW_PREFIX="$(brew --prefix)"
+fi
+
+alias bcubc='brew upgrade --cask && brew cleanup'
+alias bcubo='brew update && brew outdated --cask'
+alias brewp='brew pin'
+alias brewsp='brew list --pinned'
+alias bubc='brew upgrade && brew cleanup'
+alias bubo='brew update && brew outdated'
+alias bubu='bubo && bubc'
+alias buf='brew upgrade --formula'
+
+function brews() {
+  local formulae="$(brew leaves | xargs brew deps --installed --for-each)"
+  local casks="$(brew list --cask)"
+
+  local blue="$(tput setaf 4)"
+  local bold="$(tput bold)"
+  local off="$(tput sgr0)"
+
+  echo "${blue}==>${off} ${bold}Formulae${off}"
+  echo "${formulae}" | sed "s/^\(.*\):\(.*\)$/\1${blue}\2${off}/"
+  echo "\n${blue}==>${off} ${bold}Casks${off}\n${casks}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/README.md
new file mode 100644 (file)
index 0000000..7b79cbc
--- /dev/null
@@ -0,0 +1,74 @@
+# Bundler
+
+This plugin adds completion for basic bundler commands, as well as aliases and helper functions for
+an easier experience with bundler.
+
+To use it, add `bundler` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... bundler)
+```
+
+## Aliases
+
+| Alias  | Command                              | Description                                                                              |
+|--------|--------------------------------------|------------------------------------------------------------------------------------------|
+| `ba`   | `bundle add`                         | Add gem to the Gemfile and run bundle install                                            |
+| `bck`  | `bundle check`                       | Verifies if dependencies are satisfied by installed gems                                 |
+| `bcn`  | `bundle clean`                       | Cleans up unused gems in your bundler directory                                          |
+| `be`   | `bundle exec`                        | Execute a command in the context of the bundle                                           |
+| `bi`   | `bundle install --jobs=<core_count>` | Install the dependencies specified in your Gemfile (using all cores in bundler >= 1.4.0) |
+| `bl`   | `bundle list`                        | List all the gems in the bundle                                                          |
+| `bo`   | `bundle open`                        | Opens the source directory for a gem in your bundle                                      |
+| `bout` | `bundle outdated`                    | List installed gems with newer versions available                                        |
+| `bp`   | `bundle package`                     | Package your needed .gem files into your application                                     |
+| `bu`   | `bundle update`                      | Update your gems to the latest available versions                                        |
+
+## Gem wrapper
+
+The plugin adds a wrapper for common gems, which:
+
+- Looks for a binstub under `./bin/` and executes it if present.
+- Calls `bundle exec <gem>` otherwise.
+
+Common gems wrapped by default (by name of the executable):
+
+`annotate`, `cap`, `capify`, `cucumber`, `foodcritic`, `guard`, `hanami`, `irb`, `jekyll`, `kitchen`, `knife`, `middleman`, `nanoc`, `pry`, `puma`, `rackup`, `rainbows`, `rake`, `rspec`, `rubocop`, `shotgun`, `sidekiq`, `spec`, `spork`, `spring`, `strainer`, `tailor`, `taps`, `thin`, `thor`, `unicorn` and `unicorn_rails`.
+
+### Settings
+
+You can add or remove gems from the list of wrapped commands.
+Please **use the exact name of the executable** and not the gem name.
+
+#### Include gems to be wrapped (`BUNDLED_COMMANDS`)
+
+Add this before the plugin list in your `.zshrc`:
+
+```sh
+BUNDLED_COMMANDS=(rubocop)
+plugins=(... bundler ...)
+```
+
+This will add the wrapper for the `rubocop` gem (i.e. the executable).
+
+#### Exclude gems from being wrapped (`UNBUNDLED_COMMANDS`)
+
+Add this before the plugin list in your `.zshrc`:
+
+```sh
+UNBUNDLED_COMMANDS=(foreman spin)
+plugins=(... bundler ...)
+```
+
+This will exclude the `foreman` and `spin` gems (i.e. their executable) from being wrapped.
+
+### Excluded gems
+
+These gems should not be called with `bundle exec`. Please see [issue #2923](https://github.com/ohmyzsh/ohmyzsh/pull/2923) on GitHub for clarification:
+
+- `berks`
+- `foreman`
+- `mailcatcher`
+- `rails`
+- `ruby`
+- `spin`
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/_bundler b/stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/_bundler
new file mode 100644 (file)
index 0000000..51678dd
--- /dev/null
@@ -0,0 +1,105 @@
+#compdef bundle
+
+local curcontext="$curcontext" state line _gems _opts ret=1
+
+_arguments -C -A "-v" -A "--version" \
+       '(- 1 *)'{-v,--version}'[display version information]' \
+       '1: :->cmds' \
+       '*:: :->args' && ret=0
+
+case $state in
+       cmds)
+               _values "bundle command" \
+                       "install[Install the gems specified by the Gemfile or Gemfile.lock]" \
+                       "update[Update dependencies to their latest versions]" \
+                       "package[Package the .gem files required by your application]" \
+                       "exec[Execute a script in the context of the current bundle]" \
+                       "config[Specify and read configuration options for bundler]" \
+                       "check[Determine whether the requirements for your application are installed]" \
+                       "list[Show all of the gems in the current bundle]" \
+                       "show[Show the source location of a particular gem in the bundle]" \
+                       "info[Show details of a particular gem in the bundle]" \
+                       "outdated[Show all of the outdated gems in the current bundle]" \
+                       "console[Start an IRB session in the context of the current bundle]" \
+                       "open[Open an installed gem in the editor]" \
+                       "viz[Generate a visual representation of your dependencies]" \
+                       "init[Generate a simple Gemfile, placed in the current directory]" \
+                       "gem[Create a simple gem, suitable for development with bundler]" \
+                       "platform[Displays platform compatibility information]" \
+                       "clean[Cleans up unused gems in your bundler directory]" \
+                       "help[Describe available tasks or one specific task]"
+               ret=0
+               ;;
+       args)
+               case $line[1] in
+                       help)
+                               _values 'commands' \
+                    'install' \
+                    'update' \
+                    'package' \
+                    'exec' \
+                    'config' \
+                    'check' \
+                    'list' \
+                    'show' \
+                    'outdated' \
+                    'console' \
+                    'open' \
+                    'viz' \
+                    'init' \
+                    'gem' \
+                    'platform' \
+                    'help' && ret=0
+                               ;;
+                       install)
+                               _arguments \
+                                       '(--no-color)--no-color[disable colorization in output]' \
+                                       '(--local)--local[do not attempt to connect to rubygems.org]' \
+                                       '(--quiet)--quiet[only output warnings and errors]' \
+                                       '(--gemfile)--gemfile=-[use the specified gemfile instead of Gemfile]:gemfile' \
+                                       '(--system)--system[install to the system location]' \
+                                       '(--deployment)--deployment[install using defaults tuned for deployment environments]' \
+                                       '(--frozen)--frozen[do not allow the Gemfile.lock to be updated after this install]' \
+                                       '(--path)--path=-[specify a different path than the system default]:path:_files' \
+                                       '(--binstubs)--binstubs=-[generate bin stubs for bundled gems to ./bin]:directory:_files' \
+                                       '(--without)--without=-[exclude gems that are part of the specified named group]:groups'
+                               ret=0
+                               ;;
+                       exec)
+                               _normal && ret=0
+                               ;;
+                       clean)
+                               _arguments \
+                                       '(--force)--force[forces clean even if --path is not set]' \
+                                       '(--dry-run)--dry-run[only print out changes, do not actually clean gems]' \
+                                       '(--no-color)--no-color[Disable colorization in output]' \
+                                       '(--verbose)--verbose[Enable verbose output mode]'
+                               ret=0
+                               ;;
+                       outdated)
+                               _arguments \
+                                       '(--pre)--pre[Check for newer pre-release gems]' \
+                                       '(--source)--source[Check against a specific source]' \
+                                       '(--local)--local[Do not attempt to fetch gems remotely and use the gem cache instead]' \
+                                       '(--no-color)--no-color[Disable colorization in output]' \
+                                       '(--verbose)--verbose[Enable verbose output mode]'
+                               ret=0
+                               ;;
+                       (open|show|info)
+                               _gems=( $(bundle show 2> /dev/null | sed -e '/^  \*/!d; s/^  \* \([^ ]*\) .*/\1/') )
+                               if [[ $_gems != "" ]]; then
+                                       _values 'gems' $_gems && ret=0
+                               fi
+                               ;;
+                       *)
+                               _opts=(  $(bundle help $line[1] | sed -e '/^  \[-/!d; s/^  \[\(-[^=]*\)=.*/\1/') )
+                               _opts+=( $(bundle help $line[1] | sed -e '/^  -/!d; s/^  \(-.\), \[\(-[^=]*\)=.*/\1 \2/') )
+                               if [[ $_opts != "" ]]; then
+                                       _values 'options' $_opts && ret=0
+                               fi
+                               ;;
+               esac
+               ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/bundler.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/bundler/bundler.plugin.zsh
new file mode 100644 (file)
index 0000000..c1cbb13
--- /dev/null
@@ -0,0 +1,127 @@
+## Aliases
+
+alias ba="bundle add"
+alias bck="bundle check"
+alias bcn="bundle clean"
+alias be="bundle exec"
+alias bi="bundle_install"
+alias bl="bundle list"
+alias bo="bundle open"
+alias bout="bundle outdated"
+alias bp="bundle package"
+alias bu="bundle update"
+
+## Functions
+
+bundle_install() {
+  # Bail out if bundler is not installed
+  if (( ! $+commands[bundle] )); then
+    echo "Bundler is not installed"
+    return 1
+  fi
+
+  # Bail out if not in a bundled project
+  if ! _within-bundled-project; then
+    echo "Can't 'bundle install' outside a bundled project"
+    return 1
+  fi
+
+  # Check the bundler version is at least 1.4.0
+  autoload -Uz is-at-least
+  local bundler_version=$(bundle version | cut -d' ' -f3)
+  if ! is-at-least 1.4.0 "$bundler_version"; then
+    bundle install "$@"
+    return $?
+  fi
+
+  # If bundler is at least 1.4.0, use all the CPU cores to bundle install
+  if [[ "$OSTYPE" = (darwin|freebsd)* ]]; then
+    local cores_num="$(sysctl -n hw.ncpu)"
+  else
+    local cores_num="$(nproc)"
+  fi
+  BUNDLE_JOBS="$cores_num" bundle install "$@"
+}
+
+## Gem wrapper
+
+bundled_commands=(
+  annotate
+  cap
+  capify
+  cucumber
+  foodcritic
+  guard
+  hanami
+  irb
+  jekyll
+  kitchen
+  knife
+  middleman
+  nanoc
+  pry
+  puma
+  rackup
+  rainbows
+  rake
+  rspec
+  rubocop
+  shotgun
+  sidekiq
+  spec
+  spork
+  spring
+  strainer
+  tailor
+  taps
+  thin
+  thor
+  unicorn
+  unicorn_rails
+)
+
+# Remove $UNBUNDLED_COMMANDS from the bundled_commands list
+bundled_commands=(${bundled_commands:|UNBUNDLED_COMMANDS})
+unset UNBUNDLED_COMMANDS
+
+# Add $BUNDLED_COMMANDS to the bundled_commands list
+bundled_commands+=($BUNDLED_COMMANDS)
+unset BUNDLED_COMMANDS
+
+# Check if in the root or a subdirectory of a bundled project
+_within-bundled-project() {
+  local check_dir="$PWD"
+  while [[ "$check_dir" != "/" ]]; do
+    if [[ -f "$check_dir/Gemfile" || -f "$check_dir/gems.rb" ]]; then
+      return 0
+    fi
+    check_dir="${check_dir:h}"
+  done
+  return 1
+}
+
+_run-with-bundler() {
+  if (( ! $+commands[bundle] )) || ! _within-bundled-project; then
+    "$@"
+    return $?
+  fi
+
+  if [[ -f "./bin/${1}" ]]; then
+    ./bin/${^^@}
+  else
+    bundle exec "$@"
+  fi
+}
+
+for cmd in $bundled_commands; do
+  # Create wrappers for bundled and unbundled execution
+  eval "function unbundled_$cmd () { \"$cmd\" \"\$@\"; }"
+  eval "function bundled_$cmd () { _run-with-bundler \"$cmd\" \"\$@\"; }"
+  alias "$cmd"="bundled_$cmd"
+
+  # Bind completion function to wrapped gem if available
+  if (( $+functions[_$cmd] )); then
+    compdef "_$cmd" "bundled_$cmd"="$cmd"
+  fi
+done
+unset cmd bundled_commands
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cabal/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cabal/README.md
new file mode 100644 (file)
index 0000000..b1106c4
--- /dev/null
@@ -0,0 +1,9 @@
+# Cabal
+
+This plugin provides completion for [Cabal](https://www.haskell.org/cabal/), a build tool for Haskell. It
+also provides a function `cabal_sandbox_info` that prints whether the current working directory is in a sandbox.
+
+To use it, add cabal to the plugins array of your zshrc file:
+```
+plugins=(... cabal)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cabal/cabal.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/cabal/cabal.plugin.zsh
new file mode 100644 (file)
index 0000000..a9a05b0
--- /dev/null
@@ -0,0 +1,93 @@
+function cabal_sandbox_info() {
+    cabal_files=(*.cabal(N))
+    if [ $#cabal_files -gt 0 ]; then
+        if [ -f cabal.sandbox.config ]; then
+            echo "%{$fg[green]%}sandboxed%{$reset_color%}"
+        else
+            echo "%{$fg[red]%}not sandboxed%{$reset_color%}"
+        fi
+    fi
+}
+
+function _cabal_commands() {
+    local ret=1 state
+    _arguments ':subcommand:->subcommand' && ret=0
+
+    case $state in
+      subcommand)
+        subcommands=(
+          "bench:Run the benchmark, if any (configure with UserHooks)"
+          "build:Compile all targets or specific target."
+          "check:Check the package for common mistakes"
+          "clean:Clean up after a build"
+          "copy:Copy the files into the install locations"
+          "configure:Prepare to build the package"
+          "exec:Run a command with the cabal environment"
+          "fetch:Downloads packages for later installation"
+          "freeze:Freeze dependencies."
+          "get:Gets a package's source code"
+          "haddock:Generate Haddock HTML documentation"
+          "help:Help about commands"
+          "hscolour:Generate HsColour colourised code, in HTML format"
+          "info:Display detailed information about a particular package"
+          "init:Interactively create a .cabal file"
+          "install:Installs a list of packages"
+          "list:List packages matching a search string"
+          "register:Register this package with the compiler"
+          "repl:Open an interpreter session for the given target"
+          "report:Upload build reports to a remote server"
+          "run:Runs the compiled executable"
+          "sandbox:Create/modify/delete a sandbox"
+          "sdist:Generate a source distribution file (.tar.gz)"
+          "test:Run the test suite, if any (configure with UserHooks)"
+          "unpack:Unpacks packages for user inspection"
+          "update:Updates list of known packages"
+          "upload:Uploads source packages to Hackage"
+        )
+        _describe -t subcommands 'cabal subcommands' subcommands && ret=0
+    esac
+
+    return ret
+}
+
+compdef _cabal_commands cabal
+
+function _cab_commands() {
+    local ret=1 state
+    _arguments ':subcommand:->subcommand' && ret=0
+
+    case $state in
+      subcommand)
+        subcommands=(
+          "sync:Fetch the latest package index"
+          "install:Install packages"
+          "uninstall:Uninstall packages"
+          "installed:List installed packages"
+          "configure:Configure a cabal package"
+          "build:Build a cabal package"
+          "clean:Clean up a build directory"
+          "outdated:Display outdated packages"
+          "info:Display information of a package"
+          "sdist:Make tar.gz for source distribution"
+          "upload:Uploading tar.gz to HackageDB"
+          "get:Untar a package in the current directory"
+          "deps:Show dependencies of this package"
+          "revdeps:Show reverse dependencies of this package"
+          "check:Check consistency of packages"
+          "genpaths:Generate Paths_<pkg>.hs"
+          "search:Search available packages by package name"
+          "add:Add a source directory"
+          "test:Run tests"
+          "bench:Run benchmarks"
+          "doc:Generate manuals"
+          "ghci:Run GHCi (with a sandbox)"
+          "init:Initialize a sandbox"
+          "help:Display the help message of the command"
+        )
+        _describe -t subcommands 'cab subcommands' subcommands && ret=0
+    esac
+
+    return ret
+}
+
+command -v cab >/dev/null 2>&1 && { compdef _cab_commands cab }
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cake/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cake/README.md
new file mode 100644 (file)
index 0000000..2c2a280
--- /dev/null
@@ -0,0 +1,15 @@
+# Cake
+
+This plugin provides completion for [CakePHP](https://cakephp.org/).
+
+To use it add cake to the plugins array in your zshrc file.
+
+```bash
+plugins=(... cake)
+```
+
+## Note
+
+This plugin generates a cache file of the cake tasks found, named `.cake_task_cache`, in the current working directory.
+It is regenerated when the Cakefile is newer than the cache file. It is advised that you add the cake file to your
+`.gitignore` files.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cake/cake.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/cake/cake.plugin.zsh
new file mode 100644 (file)
index 0000000..2370df9
--- /dev/null
@@ -0,0 +1,33 @@
+# Set this to 1 if you want to cache the tasks
+_cake_cache_task_list=1
+
+# Cache filename
+_cake_task_cache_file='.cake_task_cache'
+
+_cake_get_target_list () {
+       cake | grep '^cake ' | sed -e "s/cake \([^ ]*\) .*/\1/" | grep -v '^$'
+}
+
+_cake_does_target_list_need_generating () {
+
+       if [ ${_cake_cache_task_list} -eq 0 ]; then
+               return 1;
+       fi
+
+       [ ! -f ${_cake_task_cache_file} ] && return 0;
+       [ Cakefile -nt ${_cake_task_cache_file} ] && return 0;
+       return 1;
+}
+
+_cake () {
+       if [ -f Cakefile ]; then
+               if _cake_does_target_list_need_generating; then
+                       _cake_get_target_list > ${_cake_task_cache_file}
+                       compadd `cat ${_cake_task_cache_file}`
+               else
+                       compadd `_cake_get_target_list`
+               fi
+       fi
+}
+
+compdef _cake cake
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cakephp3/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cakephp3/README.md
new file mode 100644 (file)
index 0000000..7e8f664
--- /dev/null
@@ -0,0 +1,16 @@
+# cakephp3 plugin
+
+The plugin adds aliases and autocompletion for [cakephp3](https://book.cakephp.org/3.0/en/index.html).
+
+To use it, add `cakephp3` to the plugins array of your zshrc file:
+```
+plugins=(... cakephp3)
+```
+
+## Aliases
+
+| Alias     | Command                       |
+|-----------|-------------------------------|
+| c3        | `bin/cake`                    |
+| c3cache   | `bin/cake orm_cache clear`    |
+| c3migrate | `bin/cake migrations migrate` |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cakephp3/cakephp3.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/cakephp3/cakephp3.plugin.zsh
new file mode 100644 (file)
index 0000000..dbfbeba
--- /dev/null
@@ -0,0 +1,38 @@
+# CakePHP 3 basic command completion
+_cakephp3_get_command_list () {
+       bin/cake Completion commands
+}
+
+_cakephp3_get_sub_command_list () {
+       bin/cake Completion subcommands ${words[2]}
+}
+
+_cakephp3_get_3rd_argument () {
+       bin/cake ${words[2]} ${words[3]} | \grep '\-\ '| \awk '{print $2}'
+}
+
+_cakephp3 () {
+       local -a has3rdargument
+       has3rdargument=("all" "controller" "fixture" "model" "template")
+       if [ -f bin/cake ]; then
+               if (( CURRENT == 2 )); then
+                       compadd $(_cakephp3_get_command_list)
+               fi
+               if (( CURRENT == 3 )); then
+                       compadd $(_cakephp3_get_sub_command_list)
+               fi
+               if (( CURRENT == 4 )); then
+                       if [[ ${has3rdargument[(i)${words[3]}]} -le ${#has3rdargument} ]]; then
+                               compadd $(_cakephp3_get_3rd_argument)
+                       fi
+               fi
+  fi
+}
+
+compdef _cakephp3 bin/cake
+compdef _cakephp3 cake
+
+#Alias
+alias c3='bin/cake'
+alias c3cache='bin/cake orm_cache clear'
+alias c3migrate='bin/cake migrations migrate'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/README.md
new file mode 100644 (file)
index 0000000..335b794
--- /dev/null
@@ -0,0 +1,14 @@
+# Capistrano
+
+This plugin provides completion for [Capistrano](https://capistranorb.com/).
+
+To use it add capistrano to the plugins array in your zshrc file.
+
+```bash
+plugins=(... capistrano)
+```
+
+For a working completion use the `capit` command instead of `cap`, because cap is a
+[reserved word in zsh](http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcap-Module).
+
+`capit` automatically runs cap with bundler if a Gemfile is found.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/_capistrano b/stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/_capistrano
new file mode 100644 (file)
index 0000000..a79e47b
--- /dev/null
@@ -0,0 +1,49 @@
+#compdef capit
+#autoload
+
+# Added `capit` because `cap` is a reserved word. `cap` completion doesn't work.
+# http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcap-Module
+
+local curcontext="$curcontext" state line ret=1
+local -a _configs
+
+_arguments -C \
+  '1: :->cmds' \
+  '2:: :->args' && ret=0
+
+_cap_tasks() {
+  if [[ -f config/deploy.rb || -f Capfile ]]; then
+    if [[ ! -f .cap_tasks~ ]]; then
+      capit --tasks | sed 's/\(\[\)\(.*\)\(\]\)/\2:/' | awk '{command=$2; $1=$2=$3=""; gsub(/^[ \t\r\n]+/, "", $0); gsub(":", "\\:", command); print command"["$0"]"}' > .cap_tasks~
+    fi
+
+    OLD_IFS=$IFS
+    IFS=$'\n'
+    _values 'cap commands' $(< .cap_tasks~)
+    IFS=$OLD_IFS
+    # zmodload zsh/mapfile
+    # _values ${(f)mapfile[.cap_tasks~]}
+  fi
+}
+
+_cap_stages() {
+  compadd $(find config/deploy -name \*.rb | cut -d/ -f3 | sed s:.rb::g)
+}
+
+case $state in
+  cmds)
+    # check if it uses multistage
+    if [[ -d config/deploy ]]; then
+      _cap_stages
+    else
+      _cap_tasks
+    fi
+    ret=0
+    ;;
+  args)
+    _cap_tasks
+    ret=0
+    ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/capistrano.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/capistrano/capistrano.plugin.zsh
new file mode 100644 (file)
index 0000000..8195728
--- /dev/null
@@ -0,0 +1,11 @@
+# Added `capit` because `cap` is a reserved word. `cap` completion doesn't work.
+# http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fcap-Module
+
+function capit() {
+  if [ -f Gemfile ]
+  then
+    bundle exec cap $*
+  else
+    cap $*
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cask/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cask/README.md
new file mode 100644 (file)
index 0000000..e1335c1
--- /dev/null
@@ -0,0 +1,15 @@
+# Cask plugin
+
+[Cask](https://github.com/cask/cask) is a project management tool for Emacs that helps
+automate the package development cycle; development, dependencies, testing, building,
+packaging and more.
+
+This plugin loads `cask` completion from non-standard locations, such as if installed
+via Homebrew or others. To enable it, add `cask` to your plugins array:
+
+```zsh
+plugins=(... cask)
+```
+
+Make sure you have the `cask` directory in your `$PATH` before loading Oh My Zsh,
+otherwise you'll get a "command not found" error.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cask/cask.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/cask/cask.plugin.zsh
new file mode 100644 (file)
index 0000000..29120b3
--- /dev/null
@@ -0,0 +1,26 @@
+() {
+  emulate -L zsh
+
+  if ! (( $+commands[cask] )); then
+    print "zsh cask plugin: cask command not found" >&2
+    return
+  fi
+
+  cask_base=${commands[cask]:h:h}
+
+  # Plain cask installation location (for Cask 0.7.2 and earlier)
+  comp_files=($cask_base/etc/cask_completion.zsh)
+
+  # Mac Homebrew installs the completion in a different location
+  if (( $+commands[brew] )); then
+    comp_files+=($(brew --prefix)/share/zsh/site-functions/cask_completion.zsh)
+  fi
+
+  # Load first found file
+  for f in $comp_files; do
+    if [[ -f "$f" ]]; then
+      source "$f"
+      break
+    fi
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/README.md
new file mode 100644 (file)
index 0000000..8f26880
--- /dev/null
@@ -0,0 +1,23 @@
+# catimg
+
+Plugin for displaying images on the terminal using the the `catimg.sh` script provided by [posva](https://github.com/posva/catimg)
+
+To use it, add `catimg` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... catimg)
+```
+
+## Requirements
+
+- `convert` (ImageMagick)
+
+## Functions
+
+| Function | Description                              |
+| -------- | ---------------------------------------- |
+| `catimg` | Displays the given image on the terminal |
+
+## Usage examples
+
+[![asciicast](https://asciinema.org/a/204702.png)](https://asciinema.org/a/204702)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/catimg.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/catimg.plugin.zsh
new file mode 100644 (file)
index 0000000..f4ff6f8
--- /dev/null
@@ -0,0 +1,17 @@
+################################################################################
+# catimg script by Eduardo San Martin Morote aka Posva                         #
+# https://posva.net                                                            #
+#                                                                              #
+# Output the content of an image to the stdout using the 256 colors of the     #
+# terminal.                                                                    #
+# GitHub: https://github.com/posva/catimg                                      #
+################################################################################
+
+
+function catimg() {
+  if [[ -x  `which convert` ]]; then
+    zsh $ZSH/plugins/catimg/catimg.sh $@
+  else
+    echo "catimg need convert (ImageMagick) to work)"
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/catimg.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/catimg.sh
new file mode 100644 (file)
index 0000000..f583924
--- /dev/null
@@ -0,0 +1,88 @@
+################################################################################
+# catimg script by Eduardo San Martin Morote aka Posva                         #
+# https://posva.net                                                            #
+#                                                                              #
+# Output the content of an image to the stdout using the 256 colors of the     #
+# terminal.                                                                    #
+# GitHub: https://github.com/posva/catimg                                      #
+################################################################################
+
+function help() {
+  echo "Usage catimg [-h] [-w width] [-c char] img"
+  echo "By default char is \"  \" and w is the terminal width"
+}
+
+# VARIABLES
+COLOR_FILE=$(dirname $0)/colors.png
+CHAR="  "
+
+WIDTH=""
+IMG=""
+
+while getopts qw:c:h opt; do
+  case "$opt" in
+    w) WIDTH="$OPTARG" ;;
+    c) CHAR="$OPTARG" ;;
+    h) help; exit ;;
+    *) help ; exit 1;;
+    esac
+  done
+
+while [ "$1" ]; do
+  IMG="$1"
+  shift
+done
+
+if [ "$IMG" = "" -o ! -f "$IMG" ]; then
+  help
+  exit 1
+fi
+
+if [ ! "$WIDTH" ]; then
+  COLS=$(expr $(tput cols) "/" $(echo -n "$CHAR" | wc -c))
+else
+  COLS=$(expr $WIDTH "/" $(echo -n "$CHAR" | wc -c))
+fi
+WIDTH=$(convert "$IMG" -print "%w\n" /dev/null)
+if [ "$WIDTH" -gt "$COLS" ]; then
+  WIDTH=$COLS
+fi
+
+REMAP=""
+if convert "$IMG" -resize $COLS\> +dither -remap $COLOR_FILE /dev/null ; then
+  REMAP="-remap $COLOR_FILE"
+else
+  echo "The version of convert is too old, don't expect good results :(" >&2
+  #convert "$IMG" -colors 256 PNG8:tmp.png
+  #IMG="tmp.png"
+fi
+
+# Display the image
+I=0
+convert "$IMG" -resize $COLS\> +dither `echo $REMAP` txt:- 2>/dev/null |
+sed -e 's/.*none.*/NO NO NO/g' -e '1d;s/^.*(\(.*\)[,)].*$/\1/g;y/,/ /' |
+while read R G B f; do
+  if [ ! "$R" = "NO" ]; then
+    if [ "$R" -eq "$G" -a "$G" -eq "$B" ]; then
+      ((
+      I++,
+      IDX = 232 + R * 23 / 255
+      ))
+    else
+      ((
+      I++,
+      IDX = 16
+      + R * 5 / 255 * 36
+      + G * 5 / 255 * 6
+      + B * 5 / 255
+      ))
+    fi
+    #echo "$R,$G,$B: $IDX"
+    echo -ne "\e[48;5;${IDX}m${CHAR}"
+  else
+    (( I++ ))
+    echo -ne "\e[0m${CHAR}"
+  fi
+  # New lines
+  (( $I % $WIDTH )) || echo -e "\e[0m"
+done
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/colors.png b/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/colors.png
new file mode 100644 (file)
index 0000000..5f2c812
Binary files /dev/null and b/stow/oh-my-zsh/.oh-my-zsh/plugins/catimg/colors.png differ
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/celery/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/celery/README.md
new file mode 100644 (file)
index 0000000..d2597f7
--- /dev/null
@@ -0,0 +1,9 @@
+# Celery
+
+This plugin provides completion for [Celery](http://www.celeryproject.org/).
+
+To use it add celery to the plugins array in your zshrc file.
+
+```bash
+plugins=(... celery)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/celery/_celery b/stow/oh-my-zsh/.oh-my-zsh/plugins/celery/_celery
new file mode 100644 (file)
index 0000000..63af9fa
--- /dev/null
@@ -0,0 +1,129 @@
+#compdef celery
+#autoload
+
+#celery zsh  completion
+
+_celery () {
+local -a _1st_arguments ifargs dopts controlargs
+
+typeset -A opt_args
+
+_1st_arguments=('worker' 'events' 'beat' 'shell' 'multi' 'amqp' 'status' 'inspect' \
+                'control' 'purge' 'list' 'migrate' 'call' 'result' 'report')
+ifargs=('--app=' '--broker=' '--loader=' '--config=' '--version')
+dopts=('--detach' '--umask=' '--gid=' '--uid=' '--pidfile=' '--logfile=' '--loglevel=')
+controlargs=('--timeout' '--destination')
+_arguments \
+        '(-A --app=)'{-A,--app}'[app instance to use (e.g. module.attr_name):APP]' \
+        '(-b --broker=)'{-b,--broker}'[url to broker.  default is "amqp://guest@localhost//":BROKER]' \
+        '(--loader)--loader[name of custom loader class to use.:LOADER]' \
+        '(--config)--config[Name of the configuration module:CONFIG]' \
+        '(--workdir)--workdir[Optional directory to change to after detaching.:WORKING_DIRECTORY]' \
+        '(-q --quiet)'{-q,--quiet}'[Don"t show as much output.]' \
+        '(-C --no-color)'{-C,--no-color}'[Don"t display colors.]' \
+        '(--version)--version[show program"s version number and exit]' \
+        '(- : *)'{-h,--help}'[show this help message and exit]' \
+        '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+    _describe -t commands "celery subcommand" _1st_arguments
+    return
+fi
+
+case "$words[1]" in
+    worker)
+    _arguments \
+    '(-C --concurrency=)'{-C,--concurrency=}'[Number of child processes processing the queue. The default is the number of CPUs.]' \
+    '(--pool)--pool=:::(processes eventlet gevent threads solo)' \
+    '(--purge --discard)'{--discard,--purge}'[Purges all waiting tasks before the daemon is started.]' \
+    '(-f --logfile=)'{-f,--logfile=}'[Path to log file. If no logfile is specified, stderr is used.]' \
+    '(--loglevel=)--loglevel=:::(critical error warning info debug)' \
+    '(-N --hostname=)'{-N,--hostname=}'[Set custom hostname, e.g. "foo.example.com".]' \
+    '(-B --beat)'{-B,--beat}'[Also run the celerybeat periodic task scheduler.]' \
+    '(-s --schedule=)'{-s,--schedule=}'[Path to the schedule database if running with the -B option. Defaults to celerybeat-schedule.]' \
+    '(-S --statedb=)'{-S,--statedb=}'[Path to the state database.Default: None]' \
+    '(-E --events)'{-E,--events}'[Send events that can be captured by monitors like celeryev, celerymon, and others.]' \
+    '(--time-limit=)--time-limit=[nables a hard time limit (in seconds int/float) for tasks]' \
+    '(--soft-time-limit=)--soft-time-limit=[Enables a soft time limit (in seconds int/float) for tasks]' \
+    '(--maxtasksperchild=)--maxtasksperchild=[Maximum number of tasks a pool worker can execute before it"s terminated and replaced by a new worker.]' \
+    '(-Q --queues=)'{-Q,--queues=}'[List of queues to enable for this worker, separated by comma. By default all configured queues are enabled.]' \
+    '(-I --include=)'{-I,--include=}'[Comma separated list of additional modules to import.]' \
+    '(--pidfile=)--pidfile=[Optional file used to store the process pid.]' \
+    '(--autoscale=)--autoscale=[Enable autoscaling by providing max_concurrency, min_concurrency.]' \
+    '(--autoreload)--autoreload[Enable autoreloading.]' \
+    '(--no-execv)--no-execv[Don"t do execv after multiprocessing child fork.]'
+    compadd -a ifargs
+    ;;
+    inspect)
+    _values -s \
+    'active[dump active tasks (being processed)]' \
+    'active_queues[dump queues being consumed from]' \
+    'ping[ping worker(s)]' \
+    'registered[dump of registered tasks]' \
+    'report[get bugreport info]' \
+    'reserved[dump reserved tasks (waiting to be processed)]' \
+    'revoked[dump of revoked task ids]' \
+    'scheduled[dump scheduled tasks (eta/countdown/retry)]' \
+    'stats[dump worker statistics]'
+    compadd -a controlargs ifargs
+    ;;
+    control)
+    _values -s \
+    'add_consumer[tell worker(s) to start consuming a queue]' \
+    'autoscale[change autoscale settings]' \
+    'cancel_consumer[tell worker(s) to stop consuming a queue]' \
+    'disable_events[tell worker(s) to disable events]' \
+    'enable_events[tell worker(s) to enable events]' \
+    'pool_grow[start more pool processes]' \
+    'pool_shrink[use less pool processes]' \
+    'rate_limit[tell worker(s) to modify the rate limit for a task type]' \
+    'time_limit[tell worker(s) to modify the time limit for a task type.]'
+    compadd -a controlargs ifargs
+    ;;
+    multi)
+    _values -s \
+    '--nosplash[Don"t display program info.]' \
+    '--verbose[Show more output.]' \
+    '--no-color[Don"t display colors.]' \
+    '--quiet[Don"t show as much output.]' \
+    'start' 'restart' 'stopwait' 'stop' 'show' \
+    'names' 'expand' 'get' 'kill'
+    compadd -a ifargs
+    ;;
+    amqp)
+    _values -s \
+    'queue.declare' 'queue.purge' 'exchange.delete' 'basic.publish' \
+    'exchange.declare' 'queue.delete' 'queue.bind' 'basic.get'
+    ;;
+    list)
+    _values -s, 'bindings'
+    ;;
+    shell)
+    _values -s \
+    '--ipython[force iPython.]' \
+    '--bpython[force bpython.]' \
+    '--python[force default Python shell.]' \
+    '--without-tasks[don"t add tasks to locals.]' \
+    '--eventlet[use eventlet.]' \
+    '--gevent[use gevent.]'
+    compadd -a ifargs
+    ;;
+    beat)
+    _arguments \
+    '(-s --schedule=)'{-s,--schedule=}'[Path to the schedule database. Defaults to celerybeat-schedule.]' \
+    '(-S --scheduler=)'{-S,--scheduler=}'[Scheduler class to use. Default is celery.beat.PersistentScheduler.]' \
+    '(--max-interval)--max-interval[]'
+    compadd -a dopts fargs
+    ;;
+    events)
+    _arguments \
+    '(-d --dump)'{-d,--dump}'[Dump events to stdout.]' \
+    '(-c --camera=)'{-c,--camera=}'[Take snapshots of events using this camera.]' \
+    '(-F --frequency=)'{-F,--frequency=}'[Camera: Shutter frequency.  Default is every 1.0 seconds.]' \
+    '(-r --maxrate=)'{-r,--maxrate=}'[Camera: Optional shutter rate limit (e.g. 10/m).]'
+    compadd -a dopts fargs
+    ;;
+    *)
+        ;;
+    esac
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/charm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/charm/README.md
new file mode 100644 (file)
index 0000000..f237dce
--- /dev/null
@@ -0,0 +1,9 @@
+# Charm plugin
+
+This plugin adds completion for the [charm](https://github.com/charmbracelet/charm) CLI.
+
+To use it, add `charm` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... charm)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/charm/charm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/charm/charm.plugin.zsh
new file mode 100644 (file)
index 0000000..52361ce
--- /dev/null
@@ -0,0 +1,14 @@
+# Autocompletion for the Charm CLI (charm).
+if (( ! $+commands[charm] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `charm`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_charm" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _charm
+  _comps[charm]=_charm
+fi
+
+charm completion zsh >| "$ZSH_CACHE_DIR/completions/_charm" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/chruby/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/chruby/README.md
new file mode 100644 (file)
index 0000000..19eb15a
--- /dev/null
@@ -0,0 +1,21 @@
+# chruby plugin
+
+This plugin loads [chruby](https://github.com/postmodern/chruby), a tool that changes the
+current Ruby version, and completion and a prompt function to display the Ruby version.
+Supports brew and manual installation of chruby.
+
+To use it, add `chruby` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... chruby)
+```
+
+## Usage
+
+If you'd prefer to specify an explicit path to load chruby from
+you can set variables like so:
+
+```zsh
+zstyle :omz:plugins:chruby path /local/path/to/chruby.sh
+zstyle :omz:plugins:chruby auto /local/path/to/auto.sh
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/chruby/chruby.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/chruby/chruby.plugin.zsh
new file mode 100644 (file)
index 0000000..d7a28d4
--- /dev/null
@@ -0,0 +1,94 @@
+## load chruby from different locations
+
+_source-from-omz-settings() {
+  local _chruby_path _chruby_auto
+  
+  zstyle -s :omz:plugins:chruby path _chruby_path || return 1
+  zstyle -s :omz:plugins:chruby auto _chruby_auto || return 1
+
+  if [[ -r ${_chruby_path} ]]; then
+    source ${_chruby_path}
+  fi
+
+  if [[ -r ${_chruby_auto} ]]; then
+    source ${_chruby_auto}
+  fi
+}
+
+_source-from-homebrew() {
+  (( $+commands[brew] )) || return 1
+
+  local _brew_prefix
+  # check default brew prefix
+  if [[ -h /usr/local/opt/chruby ]];then
+    _brew_prefix="/usr/local/opt/chruby"
+  else
+    # ok , it is not default prefix 
+    # this call to brew is expensive ( about 400 ms ), so at least let's make it only once
+    _brew_prefix=$(brew --prefix chruby)
+  fi
+
+  [[ -r "$_brew_prefix" ]] || return 1
+
+  source $_brew_prefix/share/chruby/chruby.sh
+  source $_brew_prefix/share/chruby/auto.sh
+}
+
+_load-chruby-dirs() {
+  local dir
+  for dir in "$HOME/.rubies" "$PREFIX/opt/rubies"; do
+    if [[ -d "$dir" ]]; then
+      RUBIES+=("$dir")
+    fi
+  done
+}
+
+# Load chruby
+if _source-from-omz-settings; then
+  _load-chruby-dirs
+elif [[ -r "/usr/local/share/chruby/chruby.sh" ]] ; then
+  source /usr/local/share/chruby/chruby.sh
+  source /usr/local/share/chruby/auto.sh
+  _load-chruby-dirs
+elif _source-from-homebrew; then
+  _load-chruby-dirs
+fi
+
+unfunction _source-from-homebrew _source-from-omz-settings _load-chruby-dirs
+
+
+## chruby utility functions and aliases
+
+# rvm and rbenv plugins also provide this alias
+alias rubies='chruby'
+
+function current_ruby() {
+  local ruby
+  ruby="$(chruby | grep \* | tr -d '* ')"
+  if [[ $(chruby | grep -c \*) -eq 1 ]]; then
+    echo ${ruby}
+  else
+    echo "system"
+  fi
+}
+
+function chruby_prompt_info() {
+  echo "${$(current_ruby):gs/%/%%}"
+}
+
+# Complete chruby command with installed rubies
+_chruby() {
+  compadd $(chruby | tr -d '* ')
+  if PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" command ruby &>/dev/null; then
+    compadd system
+  fi
+}
+
+compdef _chruby chruby
+
+
+# Simple definition completer for ruby-build
+if command ruby-build &> /dev/null; then
+  _ruby-build() { compadd $(ruby-build --definitions) }
+  compdef _ruby-build ruby-build
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/.gitignore b/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/.gitignore
new file mode 100644 (file)
index 0000000..267c504
--- /dev/null
@@ -0,0 +1 @@
+fortunes/chucknorris.dat
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/README.md
new file mode 100644 (file)
index 0000000..b51875d
--- /dev/null
@@ -0,0 +1,38 @@
+# chucknorris
+
+Chuck Norris fortunes plugin for Oh My Zsh. Perfectly suitable as MOTD.
+
+To use it add `chucknorris` to the plugins array in you zshrc file.
+
+```zsh
+plugins=(... chucknorris)
+```
+
+## Usage
+
+| Command     | Description                     |
+| ----------- | ------------------------------- |
+| `chuck`     | Print random Chuck Norris quote |
+| `chuck_cow` | Print quote in cowthink         |
+
+Example: output of `chuck_cow`:
+
+```
+Last login: Fri Jan 30 23:12:26 on ttys001
+ ______________________________________
+( When Chuck Norris plays Monopoly, it )
+( affects the actual world economy.    )
+ --------------------------------------
+        o   ^__^
+         o  (oo)\_______
+            (__)\       )\/\
+                ||----w |
+                ||     ||
+```
+
+## Requirements
+
+- `fortune`
+- `cowsay` if using `chuck_cow`
+
+Available via homebrew, apt, ...
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/chucknorris.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/chucknorris.plugin.zsh
new file mode 100644 (file)
index 0000000..b90abe3
--- /dev/null
@@ -0,0 +1,24 @@
+() {
+  # %x: name of file containing code being executed
+  local fortunes_dir="${${(%):-%x}:h}/fortunes"
+
+  # Aliases
+  alias chuck="fortune -a $fortunes_dir"
+  alias chuck_cow="chuck | cowthink"
+
+  # Automatically generate or update Chuck's compiled fortune data file
+  if [[ "$fortunes_dir/chucknorris" -ot "$fortunes_dir/chucknorris.dat" ]]; then
+    return
+  fi
+
+  # For some reason, Cygwin puts strfile in /usr/sbin, which is not on the path by default
+  local strfile="${commands[strfile]:-/usr/sbin/strfile}"
+  if [[ ! -x "$strfile" ]]; then
+    echo "[oh-my-zsh] chucknorris depends on strfile, which is not installed" >&2
+    echo "[oh-my-zsh] strfile is often provided as part of the 'fortune' package" >&2
+    return
+  fi
+
+  # Generate the compiled fortune data file
+  $strfile "$fortunes_dir/chucknorris" "$fortunes_dir/chucknorris.dat" >/dev/null
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/fortunes/chucknorris b/stow/oh-my-zsh/.oh-my-zsh/plugins/chucknorris/fortunes/chucknorris
new file mode 100644 (file)
index 0000000..9e36ce8
--- /dev/null
@@ -0,0 +1,568 @@
+King Kong climbed the Empire State building in fear of Chuck Norris who was downstairs at the time.
+%
+"2012" is code for, Chuck Norris when he is pissed.
+%
+"The Big Chuck Norris Roundhouse-Kick Theory"
+%
+"The wind cries Chuck Norris"
+%
+"Walker Texas Ranger: The Movie 3-D" was considered by Warner Brothers; however the technology to create the visual effects will never be possible.
+%
+A Handicapped parking sign does not signify that this spot is for handicapped people. It is actually in fact a warning, that the spot belongs to Chuck Norris and that you will be handicapped if you park there.
+%
+Abraham Lincoln didn't die because he was shot, Chuck Norris roundhouse-kicked so fast his foot went back in time and killed Abraham Lincoln.
+%
+Achievement Unlocked: Chuck Norris of Death
+%
+After Chuck counted to infinity the first time, he vowed to count to infinity a second time....by counting the bodies of those previously roundhoused.
+%
+Aliens fear that Chuck Norris might abduct them.
+%
+An angry glare from Chuck Norris is known to kill on the spot.
+%
+Behind every successful man is Chuck Norris.
+%
+Beware of dogs... Dogs, beware of Chuck Norris.
+%
+Bruce Lee didn't defeat Chuck Norris.  Chuck hit Bruce with a Delayed roundhouse kick that was so fast that Lee only felt the impact a year later!
+%
+CNN was originally created as the "Chuck Norris Network" to update Americans with on-the-spot ass kicking in real-time.
+%
+Casinos pay Chuck Norris not to play at anything or wish anyone good luck.
+%
+Chuck Norris - the new standard.
+%
+Chuck Norris CAN balance the light-switch between ON and OFF.
+%
+Chuck Norris CAN believe it's not butter.
+%
+Chuck Norris CAN spell with an I before E even after C.
+%
+Chuck Norris can play the theme from the Twilight Zone with his beard.
+%
+Chuck Norris can power solar panels. At night.
+%
+Chuck Norris watches "the Nat.Geo. Specials" on Discovery Channel.
+%
+Chuck Norris bowled a 301 after constructing another pin out of his beard hair.
+%
+Chuck Norris burnt a fire proof vest, UNDERWATER!
+%
+Chuck Norris can French kiss his elbow.
+%
+Chuck Norris can bake in a freezer.
+%
+Chuck Norris can defuse a bomb by cutting the wrong wire.
+%
+Chuck Norris can dig a hole in air.
+%
+Chuck Norris can divide by zero.
+%
+Chuck Norris can do a regime change with a roundhouse kick.
+%
+Chuck Norris can fit 10 gallons of water in a 5 gallon bucket.
+%
+Chuck Norris can grill a popsicle.
+%
+Chuck Norris can lead a horse to water AND make it drink.
+%
+Chuck Norris can make his own megazord "The Chuck Norris Roundhouse Kickers Ultimate Super Awesome Megazord".
+%
+Chuck Norris can milk an alligator.
+%
+Chuck Norris can play the death waltz with his chin.
+%
+Chuck Norris can roundhouse kick someone through a window without breaking the glass.
+%
+Chuck Norris can roundhouse-kick round houses into squares.
+%
+Chuck Norris can rub two fires together and make a stick!
+%
+Chuck Norris can see in 3D with just one eye.
+%
+Chuck Norris can slam a revolving door.
+%
+Chuck Norris can terminate a repeating decimal.
+%
+Chuck Norris can turn toast back into bread.
+%
+Chuck Norris can win a game of Connect Four in only three moves.
+%
+Chuck Norris can win in a top spinning tournament with a cube.
+%
+Chuck Norris can't perform Hadoukens, he IS a Hadouken.
+%
+Chuck Norris checks under his bed for Fedor Emelianenko because he takes Fedor to the vet regularly.
+%
+Chuck Norris counted to infinity - twice.
+%
+Chuck Norris created Heavy Metal when he was upset.
+%
+Chuck Norris does not get frostbite. Chuck Norris bites frost.
+%
+Chuck Norris does not have a cell phone because he hears everything.
+%
+Chuck Norris does not sleep. He waits.
+%
+Chuck Norris doesn't bowl strikes, he just knocks down one pin and the other nine faint.
+%
+Chuck Norris doesn't call the wrong number, you just answer the wrong phone.
+%
+Chuck Norris doesn't cheat death, he beats it fair and square.
+%
+Chuck Norris doesn't churn butter. He roundhouse kicks the cows and the butter comes straight out.
+%
+Chuck Norris doesn't eat, he just sucks the energy out of food by staring at it.
+%
+Chuck Norris doesn't exhale. The air runs desperately scared out of his lungs.
+%
+Chuck Norris doesn't go hunting.... CHUCK NORRIS GOES KILLING.
+%
+Chuck Norris doesn't let it go.
+%
+Chuck Norris doesn't like Mudkipz.
+%
+Chuck Norris doesn't look for fun. The fun looks for Chuck Norris.
+%
+Chuck Norris doesn't need a bulletproof vest. He catches them with his bare hands.
+%
+Chuck Norris doesn't need air, he is air.
+%
+Chuck Norris doesn't need sunglasses, the sun needs Chuck Norris glasses.
+%
+Chuck Norris doesn't need to brush his teeth, his spit acts as a bleach.
+%
+Chuck Norris doesn't read books. He stares them down until he gets the information he wants.
+%
+Chuck Norris doesn't throw up if he drinks too much. Chuck Norris throws down!
+%
+Chuck Norris doesn't eat salad, he eats vegetarians.
+%
+Chuck Norris doesn't wash his clothes, he disembowels them.
+%
+Chuck Norris doesn't wear a watch. HE decides what time it is.
+%
+Chuck Norris doesn't carry a list. He always knows what to do.
+%
+Chuck Norris drives an ice cream truck covered in human skulls.
+%
+Chuck Norris drowned a man ON LAND.
+%
+Chuck Norris fed the Hunger Games.
+%
+Chuck Norris found the hay in the needle stack.
+%
+Chuck Norris found the last digit of pi.
+%
+Chuck Norris had a knife thrown at him. The knife didn't impale him; he impaled the knife.
+%
+Chuck Norris has a battle cruiser AND a car.
+%
+Chuck Norris has killed the Dead Sea.
+%
+Chuck Norris has made a 148 break at snooker.
+%
+Chuck Norris invented Kentucky Fried Chicken's famous secret recipe, with eleven herbs and spices. But nobody ever mentions the twelfth ingredient: Fear.
+%
+Chuck Norris is allowed two carry-ons.
+%
+Chuck Norris is currently suing NBC, claiming Law and Order are trademarked names for his left and right legs.
+%
+Chuck Norris is currently suing any broadway theater that plays "The Nutcracker". He claims its an infringement on his "other" roundhouse kick.
+%
+Chuck Norris is entitled to his own facts.
+%
+Chuck Norris is my Homeboy.
+%
+Chuck Norris is so fast, he can run around the world and punch himself in the back of the head.
+%
+Chuck Norris is so hard, he uses diamonds as stress balls.
+%
+Chuck Norris is so scary, he makes sharks swim backwards away from him.
+%
+Chuck Norris is ten feet tall, weighs two-tons, breathes fire, and could eat a hammer and take a shotgun blast standing.
+%
+Chuck Norris is the ghost in paranormal activity.
+%
+Chuck Norris is the life of parties he doesn't attend.
+%
+Chuck Norris is the meaning of life. Too bad he's also the meaning of death.
+%
+Chuck Norris is the only man to ever defeat a brick wall in a game of tennis.
+%
+Chuck Norris is the only one who can tear a facebook page!
+%
+Chuck Norris is the reason that the world will end in 2012. He was getting bored with the Earth.
+%
+Chuck Norris is the reason tumbleweeds tumble.
+%
+Chuck Norris is the reason why Waldo is hiding.
+%
+Chuck Norris is waiting for Mt. St. Helens to erupt again. He's hoping the lava is hot enough to soften his beard so he can shave for the first time.
+%
+Chuck Norris isn't allowed at the zoo, because when he's there the animals are too terrified to come out of their cages.
+%
+Chuck Norris made a statue bleed.
+%
+Chuck Norris made the big bang just by clicking his fingers.
+%
+Chuck Norris never trains, because he's Chuck Norris.
+%
+Chuck Norris once cried just to see what it was like. The end result was the creation of life.
+%
+Chuck Norris once cut a knife with a stick of butter.
+%
+Chuck Norris once got a 200 yard punt return.
+%
+Chuck Norris once had a pet monkey named KING KONG.
+%
+Chuck Norris once had a street named after him. The name removed at once, because nobody crosses Chuck Norris, and lives.
+%
+Chuck Norris once had a weak moment, just to know what it felt like.
+%
+Chuck Norris once played Duck Duck Goose with a group of Kindergarteners. Only one kid made it to first grade.
+%
+Chuck Norris once proved p^~p by induction on his beard hairs.
+%
+Chuck Norris once punched the ground to stop an earthquake. The resulting aftershock caused the BP oil spill.
+%
+Chuck Norris once round-house kicked a salesman. Over the phone.
+%
+Chuck Norris once roundhouse kicked a football. The astronomical society now considers it a planet.
+%
+Chuck Norris once thought he was wrong. He was, however, mistaken.
+%
+Chuck Norris once walked down a street with his fists in his pockets. He was then arrested for concealing two deadly weapons.
+%
+Chuck Norris once won the Tour de France riding a "big wheel".
+%
+Chuck Norris originally appeared in the "Street Fighter II" video game, but was removed by Beta Testers because every button caused him to do a roundhouse kick. When asked bout this "glitch," Norris replied, "That's no glitch."
+%
+Chuck Norris owns all number 1 pencils.
+%
+Chuck Norris pees Adamantium.
+%
+Chuck Norris plays Texas Hold'Em with Zeus, every second Wednesday of the month.
+%
+Chuck Norris played "Got your Nose" with Voldemort and won.
+%
+Chuck Norris played the game of thrones and won.
+%
+Chuck Norris protects his bodyguards.
+%
+Chuck Norris rolled a 20 on a 6 sided die.
+%
+Chuck Norris roundhouse kicks people in the face first and asks questions later.
+%
+Chuck Norris sent a BBM to an iPhone.
+%
+Chuck Norris shops at Sam's Club, but leaves without having his receipt checked.
+%
+Chuck Norris splattered tiger blood and Adonis' DNA on Charlie Sheen with 1 roundhouse kick!
+%
+Chuck Norris started Chuck Norris.
+%
+Chuck Norris starts his day with 6 live chickens, two cows, three pigs, and a boiling hot cup of pure fury.
+%
+Chuck Norris told me to put this here.
+%
+Chuck Norris uses a real mouse to move the cursor, type on the keyboard, write e-mails, code entire websites, and make coffee.
+%
+Chuck Norris uses pepper spray to spice up his steaks.
+%
+Chuck Norris was heard in a soundproof room!
+%
+Chuck Norris was once turned down for American Idol. When Simon was questioned about it, he replied "I'm retiring after this season". I wonder why?
+%
+Chuck Norris was originally in Mortal Kombat, but that version was deleted because no one can beat Chuck Norris in a fight.
+%
+Chuck Norris was the image used for Papa Smurf.
+%
+Chuck Norris was the reason why the Great Wall of China was constructed. It failed miserably.
+%
+Chuck Norris was what Willis was talking about.
+%
+Chuck Norris wasn't born on his birthday.
+%
+Chuck Norris watched the first steps on the moon... from his summer home on Mars.
+%
+Chuck Norris went up the creek without a paddle... or a canoe.
+%
+Chuck Norris will attain statehood in 2009. His state flower will be the Magnolia.
+%
+Chuck Norris wins NASCAR races with all right turns.
+%
+Chuck Norris won a stepdance contest by standing on his hands.
+%
+Chuck Norris yells at drill Sergeants.
+%
+Chuck Norris' dog picks up after him.
+%
+Chuck Norris' films are factual documentaries.
+%
+Chuck Norris' first job was as a paperboy. There were no survivors.
+%
+Chuck Norris' glass is never half full or half empty. It stays full even after he takes a drink.
+%
+Chuck Norris' hand is the only hand that can beat a Royal Flush.
+%
+Chuck Norris' personal airplane is called Air Force Chuck.
+%
+Chuck Norris. Enough said.
+%
+Chuck Norris: even Naruto can't believe it.
+%
+Chuck Norris can make sour milk turn fresh.
+%
+Contrary to popular belief, Rome WAS built in a day, by Chuck Norris.
+%
+Contrary to popular belief, America is not a democracy, it is a Chucktatorship.
+%
+Contrary to popular belief, Chuck Norris, not the box jellyfish of northern Australia, is the most venomous creature on Earth.
+%
+Cops don't need badges in their wallets, but only a picture of Chuck Norris.
+%
+Crop circles are Chuck Norris' way of telling the world that sometimes corn needs to lie down.
+%
+Did you hear about the boy who cried Chuck Norris?
+%
+Dog the Bounty Hunter can't track Chuck Norris down.
+%
+Don't get Chuck Norris angry. Last time somebody did that, Chuck Norris made the Grand Canyon.
+%
+Earth's rotation is purely governed by the direction that Chuck Norris is walking.
+%
+Ever wonder what really happened to the dinosaurs? They all dug their own graves when they heard Chuck Norris was coming.
+%
+Every line in a Chuck Norris haiku is "A roundhouse kick to the face." And they all have the correct number of syllables.
+%
+Every phobia known to man has a phobia of Chuck Norris.
+%
+Every time there's an earthquake, you know Chuck Norris is hungry. The earthquake is caused by his stomach growling.
+%
+Evolution's driving mechanism is nature's desperate attempt to escape Chuck Norris.
+%
+Fear of spiders is arachnophobia. Fear of tight spaces is claustrophobia. Fear of Chuck Norris is called Logic.
+%
+Fool me once, shame on you. Fool Chuck Norris once and he will roundhouse you in the face.
+%
+Ghosts can see Chuck Norris.
+%
+Guns don't kill people. Chuck Norris kills people.
+%
+How much wood could a woodchuck chuck if a woodchuck could chuck wood?  No woodchuck could chuck Chuck's wood!
+%
+If Chuck Norris were a calendar, every month would be named Chucktober, and every day he'd kick your ass.
+%
+If Chuck Norris were to get into a fight with another Chuck Norris, Chuck Norris would win.
+%
+If God doesn't know, Chuck does.
+%
+If Goliath listened to Chuck Norris, he would have won.
+%
+If at first you don't succeed, you're not Chuck Norris.
+%
+If you ask Chuck Norris what time it is, he always says, "Two seconds 'til." After you ask, "Two seconds 'til what?" he roundhouse kicks you in the face.
+%
+If you put in the correct cheat code in Halo 2, you can have Master Chief play without his helmet, revealing himself to be Chuck Norris.
+%
+If you see a man in the street who looks like Chuck Norris, but isn't, run: you don't want to be caught in the resulting roundhouse kick to his face.
+%
+If you spell Chuck Norris in Scrabble, you win. Forever.
+%
+In 1945 The US army asked if they could clone Chuck Norris. Instead he said he could sort out the Japanese.
+%
+In Texas, there are five sizes for fountain drinks: small, medium, large, Texas sized, and Chuck Norris sized.  It is a cup made of a human skull.
+%
+In a rain storm Chuck Norris stays dry. Rain drops are scared to hit him.
+%
+In the back of the book of world records, it says "All records are held by Chuck Norris. The ones listed are in second place."
+%
+James Bond has a license to kill. He got it from Chuck Norris.
+%
+Jedis are now taught to use the "Chuck".
+%
+MacGyver immediately tried to make a bomb out of some Q-Tips and Gatorade, but Chuck Norris roundhouse-kicked him in the solar plexus. MacGyver promptly threw up his own heart.
+%
+Machiavelli said it is better to be feared than loved because he was inspired by Chuck Norris.
+%
+May the Force be with Chuck Norris... for its own good.
+%
+Merlin was Chuck Norris' assistant.
+%
+Most people have 23 pairs of chromosomes. Chuck Norris has 72... and they're all poisonous.
+%
+Note to self: Don't be the cashier to tell Chuck Norris his coupons have expired.
+%
+Chuck Norris' keyboard has no control key. Chuck Norris is always in control.
+%
+Once upon a time, Chuck Norris found himself in a town called Shit Creek. He opened a Paddle Store.
+%
+One glance from Chuck Norris and snow turns itself yellow.
+%
+One time a test cheated on Chuck Norris.
+%
+Only Chuck Norris can win the mind game, 'cause he never minds.
+%
+Only Chuck Norris is stronger than an Altoid.
+%
+Outer space exists because it's afraid to be on the same planet with Chuck Norris.
+%
+Ozzy Osbourne once accidentally bit the head off a live bat - Chuck Norris once deliberately bit the head off a live pterodactyl.
+%
+Pluto is actually an orbiting group of British soldiers from the American Revolution who entered space after the Chuck gave them a roundhouse kick to the face.
+%
+Police label anyone attacking Chuck Norris as a Code 45-11.... a suicide.
+%
+Remember the Soviet Union? They decided to quit after watching a DeltaForce marathon on Satellite TV.
+%
+Simon doesn't say... Chuck Norris says.
+%
+Some boots were made for walking. Some boots may walk all over you, but Chuck Norris' boots walk THROUGH you.
+%
+Some kids pee their name in snow. Chuck Norris pees his name in concrete.
+%
+Some people ask for a Kleenex when they sneeze, Chuck Norris asks for a body bag.
+%
+Someone once videotaped Chuck Norris getting pissed off. It was called Walker: Texas Chain Saw Massacre.
+%
+Staring at Chuck Norris for extended periods of time without proper eye protection will cause blindness, and possibly foot sized bruises on the face.
+%
+Taking Karate Lessons = $100, Buying MMA DVD's = $150, Subscribing to a UFC event = $50, Getting a Roundhouse Kick from Chuck Norris = PRICELESS.
+%
+That's not an eclipse. That's the sun hiding from Chuck Norris.
+%
+The Beatles are on iTunes because Chuck Norris bought a Mac.
+%
+The Earth is made up of two-thirds water and one-third Chuck Norris.
+%
+The Earth was almost destroyed by a 50 km wide asteroid in 1984, but Chuck Norris roundhouse kicked it into the Sun.
+%
+The Great Wall of China was originally created to keep Chuck Norris out. It failed miserably.
+%
+The Joneses are trying to keep up with Chuck Norris.
+%
+The Matrix Trilogy would have ended on the first movie had Keanu Reeves said, “I know Chuck Norris.”
+%
+The answer to life, the universe and everything isn't 42. It's Chuck Norris.
+%
+The apple falls far from the tree, when Chuck's roundhouse kick is taken to the trunk.
+%
+The best part of waking up is not Folgers in your cup. it's knowing that Chuck Norris let you live.
+%
+The chief export of Chuck Norris is pain.
+%
+The dictionary references Chuck Norris several times, he is mentioned under Fear, Law, Order and Chucktatorship.
+%
+The leading causes of death in the United States are: 1. Heart Disease 2. Chuck Norris 3. Cancer.
+%
+The letters in Chuck Norris cannot be unscrambled.
+%
+The only place where the Starship Enterprise refuses to boldly go is Chuck Norris' planet... which is all of them.
+%
+The only reason that USA lost the 2011 world cup to Japan is because Chuck Norris wasn't there.
+%
+The only sure things are Death and Taxes, and when Chuck Norris goes to work for the IRS, they'll be the same thing.
+%
+The only way sharks will come near CN underwater is when CN is inside of a cage.
+%
+The only word that rhymes with orange is Chuck Norris.
+%
+The producers of the movie "The Last Airbender" are now in talks with Chuck Norris in Order to star him in their next sequel "The Last Skull Bender".
+%
+The quickest way to a man's heart is with Chuck Norris' fist.
+%
+The reason why Batman only comes out at night is because he's afraid he might encounter Chuck Norris in the morning and afternoon.
+%
+The red phone in the oval office rings directly to Chuck Norris' cell phone.
+%
+The show Survivor had the original premise of putting people on an island with Chuck Norris. There were no survivors, and nobody is brave enough to go to the island to retrieve the footage.
+%
+The square root of Chuck Norris is pain.  Do not try to square Chuck Norris. The result is death.
+%
+The sun only rises every morning because Chuck Norris allows it to.
+%
+The truth hurts, doesn't it? Chuck Norris' truth kills.
+%
+There is no chin behind Chuck Norris' beard. There is only another fist.
+%
+There is no limbo, only a world that doesn't know of Chuck Norris.
+%
+There is no such thing as global warming. Chuck Norris was cold, so he turned the sun up.
+%
+There is no theory of evolution, just a list of creatures Chuck Norris has allowed to live.
+%
+This one time at band camp... BAM! Chuck Norris.
+%
+Those who ignore history, are doomed by Chuck Norris.
+%
+Trick me once, shame on you, trick Chuck Norris.. rest in peace.
+%
+Unlike Jack Bauer, Chuck Norris doesn't need bullets. A quick roundhouse to the face kills twice as fast.
+%
+Walker: Texas Ranger went into syndication before the first episode was shot.
+%
+What was going through the minds of all of Chuck Norris' victims before they died? His shoe.
+%
+Whatever Chuck Norris wants, it will instantly appear.
+%
+When Betty White gets angry, she turns into the Hulk. When Valerie Bertinelli gets mad, she turns into Chuck Norris.
+%
+When Chuck Norris creates a login, it tells him "password not strong enough." He types in his name and it tells him "password too strong."
+%
+When Chuck Norris does a pushup, he isn't lifting himself up, he's pushing the Earth down.
+%
+When Chuck Norris drinks water, the water automatically pasteurized.
+%
+When Chuck Norris goes to Vegas, he doesn't have to gamble. The casinos just give him stacks of money.
+%
+When Chuck Norris goes to rodeos, bulls ride him.
+%
+When Chuck Norris goes to the library, he looks for the Guinness book of records in the comedy section.
+%
+When Chuck Norris inhales helium, his voice doesn't change.
+%
+When Chuck Norris performs a roundhouse kick, he's actually measuring the circumference of the universe.
+%
+When Chuck Norris played the card game War with a friend, France surrendered.
+%
+When Chuck Norris pokes the Pillsbury Doughboy, it's not a laughing matter.
+%
+When Chuck Norris roundhouse-kicks you, he decides when you will feel the impact.
+%
+When Chuck Norris sends in his taxes, he sends blank forms and includes only a picture of himself, crouched and ready to attack. Chuck Norris has not had to pay taxes, ever.
+%
+When Chuck Norris tosses a coin, it lands on both heads and tails.
+%
+When God said "Let there be light!", Chuck Norris said "Only for half the day."
+%
+When Presidents speak, their nation listens. When Chuck Norris blinks, the whole world listens.
+%
+When Steven Seagal kills a ninja, he only takes its hide. When Chuck Norris kills a ninja, he uses every part.
+%
+When chuck Norris was in school, he made his PE teacher run laps.
+%
+When does Chuck Norris run out of shotgun bullets? whenever he wants to.
+%
+When taking the SAT, write "Chuck Norris" for every answer. You will score over 8000.
+%
+When the Boogeyman goes to sleep every night, he checks his closet for Chuck Norris.
+%
+When things go bump in the night, it's Chuck Norris
+%
+While visiting the Hexagon, Chuck Norris was asked to demonstrate his famous roundhouse kick. Henceforth, it has been known as the Pentagon.
+%
+Why didn't the chicken cross the road? Because Chuck Norris got to it first.
+%
+You know Chuck Norris' pet lizard, right? Last I heard, he was in the movie "Godzilla". Oh, and his pet turtle starred in "Gamera" as well.
+%
+http://chucknorrisfacts.com/ is built in Drupal because Chuck Norris knows a good CMS when he sees one.
+%
+Chuck Norris made the first Giraffe by uppercutting a horse.
+%
+Chuck Norris can hear sign language.
+%
+Chuck Norris make onions cry.
+%
+Chuck Norris doesn't shake hands, he makes them tremble.
+%
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cloudfoundry/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cloudfoundry/README.md
new file mode 100644 (file)
index 0000000..89dd9d1
--- /dev/null
@@ -0,0 +1,58 @@
+# Cloudfoundry Plugin
+
+This plugin is intended to offer a few simple aliases for regular users of the [Cloud Foundry Cli][1]. Most are just simple aliases that will save a bit of typing. Others include mini functions and or accept parameters. Take a look at the table below for details.
+
+| Alias    | Command                     | Description                                                              |
+|----------|-----------------------------|--------------------------------------------------------------------------|
+| cfl      | `cf login`                  | Login to Cloud Foundry                                                   |
+| cft      | `cf target`                 | Target the cli at a specific Org/Space in Cloud Foundry                  |
+| cfa      | `cf apps`                   | List all applications in the current Org/Space                           |
+| cfs      | `cf services`               | List all services in the current Org/Space                               |
+| cfm      | `cf marketplace`            | List the services available in the Marketplace                           |
+| cfp      | `cf push`                   | Push your application code to Cloud Foundry                              |
+| cfcs     | `cf create-service`         | Create a service based on a Marketplace offering                         |
+| cfbs     | `cf bind-service`           | Bind an application to a service you created                             |
+| cfus     | `cf unbind-service`         | Unbind a service from an application                                     |
+| cfds     | `cf delete-service`         | Delete a service you no longer have bound                                |
+| cfup     | `cf cups`                   | Create a "user-provided-service"                                         |
+| cflg     | `cf logs`                   | Tail the logs of an application (requires <APP_NAME>)                    |
+| cfr      | `cf routes`                 | List all the routes in the current Space                                 |
+| cfe      | `cf env`                    | Show the environment variables for an application (requires <APP_NAME>)  |
+| cfsh     | `cf ssh`                    | Attach to a running container (requires an <APP_NAME> etc.)              |
+| cfsc     | `cf scale`                  | Scale an application (requires an <APP_NAME> etc.)                       |
+| cfev     | `cf events`                 | Show the application events (requires <APP_NAME>)                        |
+| cfdor    | `cf delete-orphaned-routes` | Delete routes that are no longer bound to applications                   |
+| cfbpk    | `cf buildpacks`             | List the available buildpacks                                            |
+| cfdm     | `cf domains`                | List the domains associates with this Cloud Foundry foundation           |
+| cfsp     | `cf spaces`                 | List all the Spaces in the current Org                                   |
+| cfap     | `cf app`                    | Show the details of a deployed application (requires <APP_NAME>)         |
+| cfh.     | `export CF_HOME=$PWD/.cf`   | Set the current directory as CF_HOME                                     |
+| cfh~     | `export CF_HOME=~/.cf`      | Set the user's root directory as CF_HOME                                 |
+| cfhu     | `unset CF_HOME`             | Unsets CF_HOME                                                           |
+| cfpm     | `cf push -f`                | Push an application using a manifest (requires <MANIFEST_FILE> location) |
+| cflr     | `cf logs --recent`          | Show the recent logs (requires <APP_NAME>)                               |
+| cfsrt    | `cf start`                  | Start an application (requires <APP_NAME>)                               |
+| cfstp    | `cf stop`                   | Stop an application (requires <APP_NAME>)                                |
+| cfstg    | `cf restage`                | Restage an application (requires <APP_NAME>)                             |
+| cfdel    | `cf delete`                 | Delete an application (requires <APP_NAME>)                              |
+| cfsrtall | -                           | Start all apps that are currently in the "Stopped" state                 |
+| cfstpall | -                           | Stop all apps that are currently in the "Started" state                  |
+
+For help and advice on what any of the commands does, consult the built in `cf` help functions as follows:-
+
+```bash
+cf help # List the most popular and commonly used commands
+cf help -a # Complete list of all possible commands
+cf <COMMAND_NAME> --help # Help on a specific command including arguments and examples
+```
+
+Alternatively, seek out the [online documentation][3]. And don't forget, there are loads of great [community plugins for the cf-cli][4] command line tool that can greatly extend its power and usefulness.
+
+## Contributors
+
+Contributed to `oh_my_zsh` by [benwilcock][2].  
+
+[1]: https://docs.cloudfoundry.org/cf-cli/install-go-cli.html
+[2]: https://github.com/benwilcock
+[3]: https://docs.cloudfoundry.org/cf-cli/getting-started.html
+[4]: https://plugins.cloudfoundry.org/
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cloudfoundry/cloudfoundry.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/cloudfoundry/cloudfoundry.plugin.zsh
new file mode 100644 (file)
index 0000000..b671578
--- /dev/null
@@ -0,0 +1,34 @@
+# Some Useful CloudFoundry Aliases & Functions
+alias cfl="cf login"
+alias cft="cf target"
+alias cfa="cf apps"
+alias cfs="cf services"
+alias cfm="cf marketplace"
+alias cfp="cf push"
+alias cfcs="cf create-service"
+alias cfbs="cf bind-service"
+alias cfus="cf unbind-service"
+alias cfds="cf delete-service"
+alias cfup="cf cups"
+alias cflg="cf logs"
+alias cfr="cf routes"
+alias cfe="cf env"
+alias cfsh="cf ssh"
+alias cfsc="cf scale"
+alias cfev="cf events"
+alias cfdor="cf delete-orphaned-routes"
+alias cfbpk="cf buildpacks"
+alias cfdm="cf domains"
+alias cfsp="cf spaces"
+function cfap() { cf app $1 }
+function cfh.() { export CF_HOME=$PWD/.cf }
+function cfh~() { export CF_HOME=~/.cf }
+function cfhu() { unset CF_HOME }
+function cfpm() { cf push -f $1 }
+function cflr() { cf logs $1 --recent }
+function cfsrt() { cf start $1 }
+function cfstp() { cf stop $1 }
+function cfstg() { cf restage $1 }
+function cfdel() { cf delete $1 }
+function cfsrtall() {cf apps | awk '/stopped/ { system("cf start " $1)}'}
+function cfstpall() {cf apps | awk '/started/ { system("cf stop " $1)}'}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/codeclimate/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/codeclimate/README.md
new file mode 100644 (file)
index 0000000..0d712ac
--- /dev/null
@@ -0,0 +1,8 @@
+# codeclimate plugin
+
+This plugin adds autocompletion for the [`codeclimate` CLI](https://github.com/codeclimate/codeclimate).
+
+To use it, add `codeclimate` to the plugins array in your zshrc file:
+```zsh
+plugins=(... codeclimate)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/codeclimate/_codeclimate b/stow/oh-my-zsh/.oh-my-zsh/plugins/codeclimate/_codeclimate
new file mode 100644 (file)
index 0000000..fd2536a
--- /dev/null
@@ -0,0 +1,82 @@
+#compdef codeclimate
+
+_codeclimate_all_engines() {
+  engines_all=(`codeclimate engines:list | tail -n +2 | gawk '{ print $2 }' | gawk -F: '{ print $1 }'`)
+}
+
+_codeclimate_installed_engines() {
+  _codeclimate_all_engines
+
+  engines_installed=()
+
+  if [ -e .codeclimate.yml ]
+  then
+    for engine in $engines_all
+    do
+      if grep -q $engine ".codeclimate.yml"
+      then
+        engines_installed+=$engine
+      fi
+    done
+  fi
+}
+
+_codeclimate_not_installed_engines() {
+  _codeclimate_all_engines
+
+  engines_not_installed=()
+
+  if [ -e .codeclimate.yml ]
+  then
+    for engine in $engines_all
+    do
+      if ! grep -q $engine ".codeclimate.yml"
+      then
+        engines_not_installed+=$engine
+      fi
+    done
+  fi
+}
+
+local curcontext="$curcontext" state line ret=1
+local expl
+local -a engines_all engines_installed engines_not_installed
+
+_arguments \
+  '1: :->cmds' \
+  '*:: :->args' && ret=0
+
+case $state in
+  cmds)
+    _values "bundle command" \
+      "analyze[Analyze all relevant files in the current working directory]" \
+      "console[Start an interactive session providing access to the classes within the CLI]" \
+      "engines\:disable[Prevents the engine from being used in this project]" \
+      "engines\:enable[This engine will be run the next time your project is analyzed]" \
+      "engines\:install[Compares the list of engines in your .codeclimate.yml file to those that are currently installed, then installs any missing engines]" \
+      "engines\:list[Lists all available engines in the Code Climate Docker Hub]" \
+      "engines\:remove[Removes an engine from your .codeclimate.yml file]" \
+      "help[Displays a list of commands that can be passed to the Code Climate CLI]" \
+      "init[Generates a new .codeclimate.yml file in the current working directory]" \
+      "validate-config[Validates the .codeclimate.yml file in the current working directory]" \
+      "version[Displays the current version of the Code Climate CLI]"
+    ret=0
+    ;;
+  args)
+    case $line[1] in
+      engines:enable)
+        _codeclimate_not_installed_engines
+        _wanted engines_not_installed expl 'not installed engines' compadd -a engines_not_installed ;;
+      engines:disable|engines:remove)
+        _codeclimate_installed_engines
+        _wanted engines_installed expl 'installed engines' compadd -a engines_installed ;;
+      analyze)
+        _arguments \
+          '-f:Output Format:(text json)'
+        ret=0
+        ;;
+    esac
+    ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/README.md
new file mode 100644 (file)
index 0000000..2baade8
--- /dev/null
@@ -0,0 +1,31 @@
+# Coffeescript Plugin
+
+This plugin provides aliases for quickly compiling and previewing your
+coffeescript code.
+
+When writing Coffeescript it's very common to want to preview the output of a
+certain snippet of code, either because you want to test the output or because
+you'd like to execute it in a browser console which doesn't accept Coffeescript.
+
+Preview the compiled result of your coffeescript with `cf "code"` as per the
+following:
+
+```zsh
+$ cf 'if a then b else c'
+if (a) {
+  b;
+} else {
+  c;
+}
+```
+
+Also provides the following aliases:
+
+* **cfc:** Copies the compiled JS to your clipboard. Very useful when you want
+           to run the code in a JS console.
+
+* **cfp:** Compiles from your currently copied clipboard. Useful when you want 
+           to compile large/multi-line snippets
+
+* **cfpc:** Paste coffeescript from clipboard, compile to JS, then copy the
+            the result back to clipboard.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/_coffee b/stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/_coffee
new file mode 100644 (file)
index 0000000..e2814f7
--- /dev/null
@@ -0,0 +1,81 @@
+#compdef coffee
+# ------------------------------------------------------------------------------
+# Copyright (c) 2011 Github zsh-users - https://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for Coffee.js v0.6.11 (https://coffeescript.org)
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Mario Fernandez (https://github.com/sirech)
+#  * Dong Weiming (https://github.com/dongweiming)
+#
+# ------------------------------------------------------------------------------
+
+local curcontext="$curcontext" state line ret=1 version
+local -a opts
+typeset -A opt_args
+version=(${(f)"$(_call_program version $words[1] --version)"}) || return ret
+version=${${(z)${version[1]}}[3]}
+
+autoload -Uz is-at-least
+if ! is-at-least 1.6.3 "$version"; then
+  opts+=('(-l --lint)'{-l,--lint}'[pipe the compiled JavaScript through JavaScript Lint]'
+         '(-r --require)'{-r,--require}'[require a library before executing your script]:library')
+fi
+
+
+_arguments -C \
+  '(- *)'{-h,--help}'[display this help message]' \
+  '(- *)'{-v,--version}'[display the version number]' \
+  $opts \
+  '(-b --bare)'{-b,--bare}'[compile without a top-level function wrapper]' \
+  '(-e --eval)'{-e,--eval}'[pass a string from the command line as input]:Inline Script' \
+  '(-i --interactive)'{-i,--interactive}'[run an interactive CoffeeScript REPL]' \
+  '(-j --join)'{-j,--join}'[concatenate the source CoffeeScript before compiling]:Destination JS file:_files -g "*.js"' \
+  '(--nodejs)--nodejs[pass options directly to the "node" binary]' \
+  '(-c --compile)'{-c,--compile}'[compile to JavaScript and save as .js files]' \
+  '(-o --output)'{-o,--output}'[set the output directory for compiled JavaScript]:Output Directory:_files -/' \
+  '(-n -t -p)'{-n,--nodes}'[print out the parse tree that the parser produces]' \
+  '(-n -t -p)'{-p,--print}'[print out the compiled JavaScript]' \
+  '(-n -t -p)'{-t,--tokens}'[print out the tokens that the lexer/rewriter produce]' \
+  '(-s --stdio)'{-s,--stdio}'[listen for and compile scripts over stdio]' \
+  '(-w --watch)'{-w,--watch}'[watch scripts for changes and rerun commands]' \
+  '*:script or directory:_files' && ret=0
+
+return ret
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/coffee.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/coffee/coffee.plugin.zsh
new file mode 100644 (file)
index 0000000..6d1ce5c
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/zsh
+
+# compile a string of coffeescript and print to output
+cf () {
+  coffee -peb "$1"
+}
+# compile & copy to clipboard
+cfc () {
+  cf "$1" | clipcopy
+}
+
+# compile from clipboard & print
+alias cfp='cf "$(clippaste)"'
+
+# compile from clipboard and copy to clipboard
+alias cfpc='cfp | clipcopy'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/.gitignore b/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/.gitignore
new file mode 100644 (file)
index 0000000..8241f5e
--- /dev/null
@@ -0,0 +1 @@
+.less
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/README.md
new file mode 100644 (file)
index 0000000..4da4bc1
--- /dev/null
@@ -0,0 +1,48 @@
+# Colemak plugin
+
+This plugin remaps keys in `zsh`'s [`vi`-style navigation mode](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Keymaps)
+for a [Colemak](https://colemak.com/) keyboard layout, to match the QWERTY position:
+
+![Colemak layout on a US keyboard](https://colemak.com/wiki/images/6/6c/Colemak2.png)
+
+To use it, add it to the plugins array in your `~/.zshrc` file:
+
+```
+plugins=(... colemak)
+```
+
+You will also need to enable `vi` mode, so add another line to `~/.zshrc`:
+```
+bindkey -v
+```
+
+Restart your shell and hit the `<ESC>` key to activate `vicmd` (navigation) mode,
+and start navigating `zsh` with your new keybindings!
+
+## Key bindings for vicmd
+
+| Old        | New        | Binding                   | Description                                        |
+|------------|------------|---------------------------|----------------------------------------------------|
+| `CTRL`+`j` | `CTRL`+`n` | accept-line               | Insert new line                                    |
+| `j`        | `n`        | down-line-or-history      | Move one line down or command history forwards     |
+| `k`        | `e`        | up-line-or-history        | Move one line up or command history backwards      |
+| `l`        | `i`        | vi-forward-char           | Move one character to the right                    |
+| `n`        | `k`        | vi-repeat-search          | Repeat command search forwards                     |
+| `N`        | `K`        | vi-rev-repeat-search      | Repeat command search backwards                    |
+| `i`        | `u`        | vi-insert                 | Enter insert mode                                  |
+| `I`        | `U`        | vi-insert-bol             | Move to first non-blank char and enter insert mode |
+| `<none>`   | `l`        | vi-undo-change            | Undo change                                        |
+| `J`        | `N`        | vi-join                   | Join the current line with the next one            |
+| `e`        | `j`        | vi-forward-word-end       | Move to the end of the next word                   |
+| `E`        | `J`        | vi-forward-blank-word-end | Move to end of the current or next word            |
+
+## Key bindings for less
+
+| Keyboard shortcut | `less` key binding |
+|-------------------|--------------------|
+| `n`               | forw-line          |
+| `e`               | back-line          |
+| `k`               | repeat-search      |
+| `ESC`+`k`         | repeat-search-all  |
+| `K`               | reverse-search     |
+| `ESC`+`K`         | reverse-search-all |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/colemak-less b/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/colemak-less
new file mode 100644 (file)
index 0000000..e4ca4fa
--- /dev/null
@@ -0,0 +1,6 @@
+n    forw-line
+e    back-line
+k    repeat-search
+\ek  repeat-search-all
+K    reverse-search
+\eK  reverse-search-all
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/colemak.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/colemak/colemak.plugin.zsh
new file mode 100644 (file)
index 0000000..e6a46f2
--- /dev/null
@@ -0,0 +1,38 @@
+# ctrl-j newline
+bindkey '^n' accept-line
+bindkey -a '^n' accept-line
+
+# another rotation to match qwerty
+bindkey -a 'n' down-line-or-history
+bindkey -a 'e' up-line-or-history
+bindkey -a 'i' vi-forward-char
+
+# make qwerty
+bindkey -a 'k' vi-repeat-search
+bindkey -a 'K' vi-rev-repeat-search
+bindkey -a 'u' vi-insert
+bindkey -a 'U' vi-insert-bol
+bindkey -a 'l' vi-undo-change
+bindkey -a 'N' vi-join
+
+# spare
+bindkey -a 'j' vi-forward-word-end
+bindkey -a 'J' vi-forward-blank-word-end
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+# New less versions will read this file directly
+export LESSKEYIN="${0:h:A}/colemak-less"
+
+# Only run lesskey if less version is older than v582
+less_ver=$(less --version | awk '{print $2;exit}')
+autoload -Uz is-at-least
+if ! is-at-least 582 $less_ver; then
+  # Old less versions will read this transformed file
+  export LESSKEY="${0:h:A}/.less"
+  lesskey -o "$LESSKEY" "$LESSKEYIN" 2>/dev/null
+fi
+unset less_ver
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/README.md
new file mode 100644 (file)
index 0000000..4cbf64d
--- /dev/null
@@ -0,0 +1,32 @@
+# Colored man pages plugin
+
+This plugin adds colors to man pages.
+
+To use it, add `colored-man-pages` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... colored-man-pages)
+```
+
+It will also automatically colorize man pages displayed by `dman` or `debman`,
+from [`debian-goodies`](https://packages.debian.org/stable/debian-goodies).
+
+You can also try to color other pages by prefixing the respective command with `colored`:
+
+```zsh
+colored git help clone
+```
+
+## Customization
+
+The plugin declares global associative array `less_termcap`, which maps termcap capabilities to escape
+sequences for the `less` pager. This mapping can be further customized by the user after the plugin is
+loaded. Check out sources for more.
+
+For example: `less_termcap[md]` maps to `LESS_TERMCAP_md` which is the escape sequence that tells `less`
+how to print something in bold. It's currently shown in bold red, but if you want to change it, you
+can redefine `less_termcap[md]` in your zshrc file, after OMZ is sourced:
+
+```zsh
+less_termcap[md]="${fg_bold[blue]}" # this tells less to print bold text in bold blue
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/colored-man-pages.plugin.zsh
new file mode 100644 (file)
index 0000000..981992d
--- /dev/null
@@ -0,0 +1,53 @@
+# Requires colors autoload.
+# See termcap(5).
+
+# Set up once, and then reuse. This way it supports user overrides after the
+# plugin is loaded.
+typeset -AHg less_termcap
+
+# bold & blinking mode
+less_termcap[mb]="${fg_bold[red]}"
+less_termcap[md]="${fg_bold[red]}"
+less_termcap[me]="${reset_color}"
+# standout mode
+less_termcap[so]="${fg_bold[yellow]}${bg[blue]}"
+less_termcap[se]="${reset_color}"
+# underlining
+less_termcap[us]="${fg_bold[green]}"
+less_termcap[ue]="${reset_color}"
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+# Absolute path to this file's directory.
+typeset -g __colored_man_pages_dir="${0:A:h}"
+
+function colored() {
+  local -a environment
+
+  # Convert associative array to plain array of NAME=VALUE items.
+  local k v
+  for k v in "${(@kv)less_termcap}"; do
+    environment+=( "LESS_TERMCAP_${k}=${v}" )
+  done
+
+  # Prefer `less` whenever available, since we specifically configured
+  # environment for it.
+  environment+=( PAGER="${commands[less]:-$PAGER}" )
+
+  # See ./nroff script.
+  if [[ "$OSTYPE" = solaris* ]]; then
+    environment+=( PATH="${__colored_man_pages_dir}:$PATH" )
+  fi
+
+  command env $environment "$@"
+}
+
+# Colorize man and dman/debman (from debian-goodies)
+function man \
+  dman \
+  debman {
+  colored $0 "$@"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/nroff b/stow/oh-my-zsh/.oh-my-zsh/plugins/colored-man-pages/nroff
new file mode 100755 (executable)
index 0000000..4ae155d
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# The whole point of this wrapper is to replace emboldening factor -u0 with
+# -u1 under certain circumstances on Solaris.
+
+if [ "$1,$2,$3" = "-u0,-Tlp,-man" ]; then
+  shift
+  exec /usr/bin/nroff -u1 "$@"
+else
+  # Some other invocation of nroff
+  exec /usr/bin/nroff "$@"
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colorize/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/colorize/README.md
new file mode 100644 (file)
index 0000000..405bb6d
--- /dev/null
@@ -0,0 +1,56 @@
+# colorize
+
+With this plugin you can syntax-highlight file contents of over 300 supported languages and other text formats.
+
+Colorize will highlight the content based on the filename extension. If it can't find a syntax-highlighting
+method for a given extension, it will try to find one by looking at the file contents. If no highlight method
+is found it will just cat the file normally, without syntax highlighting.
+
+## Setup
+
+To use it, add colorize to the plugins array of your `~/.zshrc` file:
+```
+plugins=(... colorize)
+```
+
+## Configuration
+
+### Requirements
+
+This plugin requires that at least one of the following tools is installed:
+
+* [Chroma](https://github.com/alecthomas/chroma)
+* [Pygments](https://pygments.org/download/)
+
+### Colorize tool
+
+Colorize supports `pygmentize` and `chroma` as syntax highlighter. By default colorize uses `pygmentize` unless it's not installed and `chroma` is. This can be overridden by the `ZSH_COLORIZE_TOOL` environment variable:
+
+```
+ZSH_COLORIZE_TOOL=chroma
+```
+
+### Styles
+
+Pygments offers multiple styles. By default, the `default` style is used, but you can choose another theme by setting the `ZSH_COLORIZE_STYLE` environment variable:
+
+```
+ZSH_COLORIZE_STYLE="colorful"
+```
+
+### Chroma Formatter Settings
+
+Chroma supports terminal output in 8 color, 256 color, and true-color. If you need to change the default terminal output style from the standard 8 color output, set the `ZSH_COLORIZE_CHROMA_FORMATTER` environment variable:
+
+```
+ZSH_COLORIZE_CHROMA_FORMATTER=terminal256
+```
+
+## Usage
+
+* `ccat <file> [files]`: colorize the contents of the file (or files, if more than one are provided).
+  If no files are passed it will colorize the standard input.
+
+* `cless [less-options] <file> [files]`: colorize the contents of the file (or files, if more than one are provided) and open less.
+  If no files are passed it will colorize the standard input.
+  The LESSOPEN and LESSCLOSE will be overwritten for this to work, but only in a local scope.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/colorize/colorize.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/colorize/colorize.plugin.zsh
new file mode 100644 (file)
index 0000000..a9da6cf
--- /dev/null
@@ -0,0 +1,114 @@
+# Easier alias to use the plugin
+alias ccat="colorize_cat"
+alias cless="colorize_less"
+
+# '$0:A' gets the absolute path of this file
+ZSH_COLORIZE_PLUGIN_PATH=$0:A
+
+colorize_check_requirements() {
+    local -a available_tools
+    available_tools=("chroma" "pygmentize")
+
+    if [ -z "$ZSH_COLORIZE_TOOL" ]; then
+        if (( $+commands[pygmentize] )); then
+            ZSH_COLORIZE_TOOL="pygmentize"
+        elif (( $+commands[chroma] )); then
+            ZSH_COLORIZE_TOOL="chroma"
+        else
+            echo "Neither 'pygments' nor 'chroma' is installed!" >&2
+            return 1
+        fi
+    fi
+
+    if [[ ${available_tools[(Ie)$ZSH_COLORIZE_TOOL]} -eq 0 ]]; then
+        echo "ZSH_COLORIZE_TOOL '$ZSH_COLORIZE_TOOL' not recognized. Available options are 'pygmentize' and 'chroma'." >&2
+        return 1
+    elif (( $+commands["$ZSH_COLORIZE_TOOL"] )); then
+        echo "Package '$ZSH_COLORIZE_TOOL' is not installed!" >&2
+        return 1
+    fi
+}
+
+colorize_cat() {
+    if ! colorize_check_requirements; then
+        return 1
+    fi
+
+    # If the environment variable ZSH_COLORIZE_STYLE
+    # is set, use that theme instead. Otherwise,
+    # use the default.
+    if [ -z "$ZSH_COLORIZE_STYLE" ]; then
+        # Both pygmentize & chroma support 'emacs'
+        ZSH_COLORIZE_STYLE="emacs"
+    fi
+
+    # Use stdin if no arguments have been passed.
+    if [ $# -eq 0 ]; then
+        if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
+            pygmentize -O style="$ZSH_COLORIZE_STYLE" -g
+        else
+            chroma --style="$ZSH_COLORIZE_STYLE" --formatter="${ZSH_COLORIZE_CHROMA_FORMATTER:-terminal}"
+        fi
+        return $?
+    fi
+
+    # Guess lexer from file extension, or guess it from file contents if unsuccessful.
+    local FNAME lexer
+    for FNAME in "$@"; do
+        if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
+            lexer=$(pygmentize -N "$FNAME")
+            if [[ $lexer != text ]]; then
+                pygmentize -O style="$ZSH_COLORIZE_STYLE" -l "$lexer" "$FNAME"
+            else
+                pygmentize -O style="$ZSH_COLORIZE_STYLE" -g "$FNAME"
+            fi
+        else
+            chroma --style="$ZSH_COLORIZE_STYLE" --formatter="${ZSH_COLORIZE_CHROMA_FORMATTER:-terminal}" "$FNAME"
+        fi
+    done
+}
+
+# The less option 'F - Forward forever; like "tail -f".' will not work in this implementation
+# caused by the lack of the ability to follow the file within pygmentize.
+colorize_less() {
+    if ! colorize_check_requirements; then
+        return 1
+    fi
+
+    _cless() {
+        # LESS="-R $LESS" enables raw ANSI colors, while maintain already set options.
+        local LESS="-R $LESS"
+
+        # This variable tells less to pipe every file through the specified command
+        # (see the man page of less INPUT PREPROCESSOR).
+        # 'zsh -ic "colorize_cat %s 2> /dev/null"' would not work for huge files like
+        # the ~/.zsh_history. For such files the tty of the preprocessor will be suspended.
+        # Therefore we must source this file to make colorize_cat available in the
+        # preprocessor without the interactive mode.
+        # `2>/dev/null` will suppress the error for large files 'broken pipe' of the python
+        # script pygmentize, which will show up if less has not fully "loaded the file"
+        # (e.g. when not scrolled to the bottom) while already the next file will be displayed.
+        local LESSOPEN="| zsh -c 'source \"$ZSH_COLORIZE_PLUGIN_PATH\"; \
+        ZSH_COLORIZE_TOOL=$ZSH_COLORIZE_TOOL ZSH_COLORIZE_STYLE=$ZSH_COLORIZE_STYLE \
+        colorize_cat %s 2> /dev/null'"
+
+        # LESSCLOSE will be set to prevent any errors by executing a user script
+        # which assumes that his LESSOPEN has been executed.
+        local LESSCLOSE=""
+
+        LESS="$LESS" LESSOPEN="$LESSOPEN" LESSCLOSE="$LESSCLOSE" command less "$@"
+    }
+
+    if [ -t 0 ]; then
+        _cless "$@"
+    else
+        # The input is not associated with a terminal, therefore colorize_cat will
+        # colorize this input and pass it to less.
+        # Less has now to decide what to use. If any files have been provided, less
+        # will ignore the input by default, otherwise the colorized input will be used.
+        # If files have been supplied and the input has been redirected, this will
+        # lead to unnecessary overhead, but retains the ability to use the less options
+        # without checking for them inside this script.
+        colorize_cat | _cless "$@"
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/command-not-found/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/command-not-found/README.md
new file mode 100644 (file)
index 0000000..5a373c5
--- /dev/null
@@ -0,0 +1,34 @@
+# command-not-found plugin
+
+This plugin uses the command-not-found package for zsh to provide suggested packages to be installed if a command cannot be found.
+
+To use it, add `command-not-found` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... command-not-found)
+```
+
+An example of how this plugin works in Ubuntu:
+```
+$ mutt
+The program 'mutt' can be found in the following packages:
+ * mutt
+ * mutt-kz
+ * mutt-patched
+Try: sudo apt install <selected package>
+```
+
+### Supported platforms
+
+It works out of the box with the command-not-found packages for:
+
+- [Ubuntu](https://www.porcheron.info/command-not-found-for-zsh/)
+- [Debian](https://packages.debian.org/search?keywords=command-not-found)
+- [Arch Linux](https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found)
+- [macOS (Homebrew)](https://github.com/Homebrew/homebrew-command-not-found)
+- [Fedora](https://fedoraproject.org/wiki/Features/PackageKitCommandNotFound)
+- [NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found)
+- [Termux](https://github.com/termux/command-not-found)
+- [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/)
+
+You can add support for other platforms by submitting a Pull Request.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/command-not-found/command-not-found.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/command-not-found/command-not-found.plugin.zsh
new file mode 100644 (file)
index 0000000..cb8a898
--- /dev/null
@@ -0,0 +1,69 @@
+## Platforms with a built-in command-not-found handler init file
+
+for file (
+  # Arch Linux. Must have pkgfile installed: https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found
+  /usr/share/doc/pkgfile/command-not-found.zsh
+  # macOS (M1 and classic Homebrew): https://github.com/Homebrew/homebrew-command-not-found
+  /opt/homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
+  /usr/local/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
+); do
+  if [[ -r "$file" ]]; then
+    source "$file"
+    unset file
+    return 0
+  fi
+done
+unset file
+
+
+## Platforms with manual command_not_found_handler() setup
+
+# Debian and derivatives: https://launchpad.net/ubuntu/+source/command-not-found
+if [[ -x /usr/lib/command-not-found || -x /usr/share/command-not-found/command-not-found ]]; then
+  command_not_found_handler() {
+    if [[ -x /usr/lib/command-not-found ]]; then
+      /usr/lib/command-not-found -- "$1"
+      return $?
+    elif [[ -x /usr/share/command-not-found/command-not-found ]]; then
+      /usr/share/command-not-found/command-not-found -- "$1"
+      return $?
+    else
+      printf "zsh: command not found: %s\n" "$1" >&2
+      return 127
+    fi
+  }
+fi
+
+# Fedora: https://fedoraproject.org/wiki/Features/PackageKitCommandNotFound
+if [[ -x /usr/libexec/pk-command-not-found ]]; then
+  command_not_found_handler() {
+    if [[ -S /var/run/dbus/system_bus_socket && -x /usr/libexec/packagekitd ]]; then
+      /usr/libexec/pk-command-not-found "$@"
+      return $?
+    fi
+
+    printf "zsh: command not found: %s\n" "$1" >&2
+    return 127
+  }
+fi
+
+# NixOS: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found
+if [[ -x /run/current-system/sw/bin/command-not-found ]]; then
+  command_not_found_handler() {
+    /run/current-system/sw/bin/command-not-found "$@"
+  }
+fi
+
+# Termux: https://github.com/termux/command-not-found
+if [[ -x /data/data/com.termux/files/usr/libexec/termux/command-not-found ]]; then
+  command_not_found_handler() {
+    /data/data/com.termux/files/usr/libexec/termux/command-not-found "$1"
+  }
+fi
+
+# SUSE and derivates: https://www.unix.com/man-page/suse/1/command-not-found/
+if [[ -x /usr/bin/command-not-found ]]; then
+  command_not_found_handler() {
+    /usr/bin/command-not-found "$1"
+  }
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/common-aliases/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/common-aliases/README.md
new file mode 100644 (file)
index 0000000..1417c30
--- /dev/null
@@ -0,0 +1,130 @@
+# Common Aliases Plugin
+
+This plugin creates helpful shortcut aliases for many commonly used commands.
+
+To use it add `common-aliases` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... common-aliases)
+```
+
+## Aliases
+
+### ls command
+
+| Alias | Command      | Description                                                                 |
+| ----- | ------------ | --------------------------------------------------------------------------- |
+| l     | `ls -lFh`    | List files as a long list, show size, type, human-readable                  |
+| la    | `ls -lAFh`   | List almost all files as a long list show size, type, human-readable        |
+| lr    | `ls -tRFh`   | List files recursively sorted by date, show type, human-readable            |
+| lt    | `ls -ltFh`   | List files as a long list sorted by date, show type, human-readable         |
+| ll    | `ls -l`      | List files as a long list                                                   |
+| ldot  | `ls -ld .*`  | List dot files as a long list                                               |
+| lS    | `ls -1FSsh`  | List files showing only size and name sorted by size                        |
+| lart  | `ls -1Fcart` | List all files sorted in reverse of create/modification time (oldest first) |
+| lrt   | `ls -1Fcrt`  | List files sorted in reverse of create/modification time(oldest first)      |
+| lsr   | `ls -lARFh`  | List all files and directories recursively                                  |
+| lsn   | `ls -1`      | List files and directories in a single column                               |
+
+### File handling
+
+| Alias | Command               | Description                                                                     |
+| ----- | --------------------- | ------------------------------------------------------------------------------- |
+| rm    | `rm -i`               | Remove a file                                                                   |
+| cp    | `cp -i`               | Copy a file                                                                     |
+| mv    | `mv -i`               | Move a file                                                                     |
+| zshrc | `${=EDITOR} ~/.zshrc` | Quickly access the ~/.zshrc file                                                |
+| dud   | `du -d 1 -h`          | Display the size of files at depth 1 in current location in human-readable form |
+| duf\* | `du -sh`              | Display the size of files in current location in human-readable form            |
+| t     | `tail -f`             | Shorthand for tail which outputs the last part of a file                        |
+
+\* Only if the [`duf`](https://github.com/muesli/duf) command isn't installed.
+
+### find and grep
+
+| Alias | Command                                            | Description                          |
+| ----- | -------------------------------------------------- | ------------------------------------ |
+| fd\*  | `find . -type d -name`                             | Find a directory with the given name |
+| ff    | `find . -type f -name`                             | Find a file with the given name      |
+| grep  | `grep --color`                                     | Searches for a query string          |
+| sgrep | `grep -R -n -H -C 5 --exclude-dir={.git,.svn,CVS}` | Useful for searching within files    |
+
+\* Only if the [`fd`](https://github.com/sharkdp/fd) command isn't installed.
+
+### Other Aliases
+
+| Alias    | Command            | Description                                                 |
+| -------- | ------------------ | ----------------------------------------------------------- |
+| h        | `history`          | Lists all recently used commands                            |
+| hgrep    | `fc -El 0 \| grep` | Searches for a word in the list of previously used commands |
+| help     | `man`              | Opens up the man page for a command                         |
+| p        | `ps -f`            | Displays currently executing processes                      |
+| sortnr   | `sort -n -r`       | Used to sort the lines of a text file                       |
+| unexport | `unset`            | Used to unset an environment variable                       |
+
+## Global aliases
+
+These aliases are expanded in any position in the command line, meaning you can use them even at the
+end of the command you've typed. Examples:
+
+Quickly pipe to less:
+
+```zsh
+$ ls -l /var/log L
+# will run
+$ ls -l /var/log | less
+```
+
+Silences stderr output:
+
+```zsh
+$ find . -type f NE
+# will run
+$ find . -type f 2>/dev/null
+```
+
+| Alias | Command                     | Description                                                 |
+| ----- | --------------------------- | ----------------------------------------------------------- |
+| H     | `\| head`                   | Pipes output to head which outputs the first part of a file |
+| T     | `\| tail`                   | Pipes output to tail which outputs the last part of a file  |
+| G     | `\| grep`                   | Pipes output to grep to search for some word                |
+| L     | `\| less`                   | Pipes output to less, useful for paging                     |
+| M     | `\| most`                   | Pipes output to more, useful for paging                     |
+| LL    | `2>&1 \| less`              | Writes stderr to stdout and passes it to less               |
+| CA    | `2>&1 \| cat -A`            | Writes stderr to stdout and passes it to cat                |
+| NE    | `2 > /dev/null`             | Silences stderr                                             |
+| NUL   | `> /dev/null 2>&1`          | Silences both stdout and stderr                             |
+| P     | `2>&1\| pygmentize -l pytb` | Writes stderr to stdout and passes it to pygmentize         |
+
+## File extension aliases
+
+These are special aliases that are triggered when a file name is passed as the command. For example,
+if the pdf file extension is aliased to `acroread` (a popular Linux pdf reader), when running `file.pdf`
+that file will be open with `acroread`.
+
+### Reading Docs
+
+| Alias | Command    | Description                        |
+| ----- | ---------- | ---------------------------------- |
+| pdf   | `acroread` | Opens up a document using acroread |
+| ps    | `gv`       | Opens up a .ps file using gv       |
+| dvi   | `xdvi`     | Opens up a .dvi file using xdvi    |
+| chm   | `xchm`     | Opens up a .chm file using xchm    |
+| djvu  | `djview`   | Opens up a .djvu file using djview |
+
+### Listing files inside a packed file
+
+| Alias  | Command    | Description                       |
+| ------ | ---------- | --------------------------------- |
+| zip    | `unzip -l` | Lists files inside a .zip file    |
+| rar    | `unrar l`  | Lists files inside a .rar file    |
+| tar    | `tar tf`   | Lists files inside a .tar file    |
+| tar.gz | `echo`     | Lists files inside a .tar.gz file |
+| ace    | `unace l`  | Lists files inside a .ace file    |
+
+### Some other features
+
+- Opens urls in terminal using browser specified by the variable `$BROWSER`
+- Opens C, C++, Tex and text files using editor specified by the variable `$EDITOR`
+- Opens images using image viewer specified by the variable `$XIVIEWER`
+- Opens videos and other media using mplayer
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/common-aliases/common-aliases.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/common-aliases/common-aliases.plugin.zsh
new file mode 100644 (file)
index 0000000..3139b82
--- /dev/null
@@ -0,0 +1,90 @@
+# Advanced Aliases.
+# Use with caution
+#
+
+# ls, the common ones I use a lot shortened for rapid fire usage
+alias l='ls -lFh'     #size,show type,human readable
+alias la='ls -lAFh'   #long list,show almost all,show type,human readable
+alias lr='ls -tRFh'   #sorted by date,recursive,show type,human readable
+alias lt='ls -ltFh'   #long list,sorted by date,show type,human readable
+alias ll='ls -l'      #long list
+alias ldot='ls -ld .*'
+alias lS='ls -1FSsh'
+alias lart='ls -1Fcart'
+alias lrt='ls -1Fcrt'
+alias lsr='ls -lARFh' #Recursive list of files and directories
+alias lsn='ls -1'     #A column contains name of files and directories
+
+alias zshrc='${=EDITOR} ${ZDOTDIR:-$HOME}/.zshrc' # Quick access to the .zshrc file
+
+alias grep='grep --color'
+alias sgrep='grep -R -n -H -C 5 --exclude-dir={.git,.svn,CVS} '
+
+alias t='tail -f'
+
+# Command line head / tail shortcuts
+alias -g H='| head'
+alias -g T='| tail'
+alias -g G='| grep'
+alias -g L="| less"
+alias -g M="| most"
+alias -g LL="2>&1 | less"
+alias -g CA="2>&1 | cat -A"
+alias -g NE="2> /dev/null"
+alias -g NUL="> /dev/null 2>&1"
+alias -g P="2>&1| pygmentize -l pytb"
+
+alias dud='du -d 1 -h'
+(( $+commands[duf] )) || alias duf='du -sh *'
+(( $+commands[fd] )) || alias fd='find . -type d -name'
+alias ff='find . -type f -name'
+
+alias h='history'
+alias hgrep="fc -El 0 | grep"
+alias help='man'
+alias p='ps -f'
+alias sortnr='sort -n -r'
+alias unexport='unset'
+
+alias rm='rm -i'
+alias cp='cp -i'
+alias mv='mv -i'
+
+# zsh is able to auto-do some kungfoo
+# depends on the SUFFIX :)
+autoload -Uz is-at-least
+if is-at-least 4.2.0; then
+  # open browser on urls
+  if [[ -n "$BROWSER" ]]; then
+    _browser_fts=(htm html de org net com at cx nl se dk)
+    for ft in $_browser_fts; do alias -s $ft='$BROWSER'; done
+  fi
+
+  _editor_fts=(cpp cxx cc c hh h inl asc txt TXT tex)
+  for ft in $_editor_fts; do alias -s $ft='$EDITOR'; done
+
+  if [[ -n "$XIVIEWER" ]]; then
+    _image_fts=(jpg jpeg png gif mng tiff tif xpm)
+    for ft in $_image_fts; do alias -s $ft='$XIVIEWER'; done
+  fi
+
+  _media_fts=(ape avi flv m4a mkv mov mp3 mpeg mpg ogg ogm rm wav webm)
+  for ft in $_media_fts; do alias -s $ft=mplayer; done
+
+  #read documents
+  alias -s pdf=acroread
+  alias -s ps=gv
+  alias -s dvi=xdvi
+  alias -s chm=xchm
+  alias -s djvu=djview
+
+  #list whats inside packed file
+  alias -s zip="unzip -l"
+  alias -s rar="unrar l"
+  alias -s tar="tar tf"
+  alias -s tar.gz="echo "
+  alias -s ace="unace l"
+fi
+
+# Make zsh know about hosts already accessed by SSH
+zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/compleat/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/compleat/README.md
new file mode 100644 (file)
index 0000000..af0e383
--- /dev/null
@@ -0,0 +1,9 @@
+# compleat plugin
+
+This plugin looks for [compleat](https://github.com/mbrubeck/compleat) and loads its completion.
+
+To use it, add compleat to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... compleat)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/compleat/compleat.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/compleat/compleat.plugin.zsh
new file mode 100644 (file)
index 0000000..38f1b39
--- /dev/null
@@ -0,0 +1,20 @@
+# ------------------------------------------------------------------------------
+#          FILE:  compleat.plugin.zsh
+#   DESCRIPTION:  oh-my-zsh plugin file.
+#        AUTHOR:  Sorin Ionescu (sorin.ionescu@gmail.com)
+#       VERSION:  1.0.0
+# ------------------------------------------------------------------------------
+
+if (( ${+commands[compleat]} )); then
+  local prefix="${commands[compleat]:h:h}"
+  local setup="${prefix}/share/compleat-1.0/compleat_setup" 
+
+  if [[ -f "$setup" ]]; then
+    if ! bashcompinit >/dev/null 2>&1; then
+      autoload -U bashcompinit
+      bashcompinit -i
+    fi
+
+    source "$setup" 
+  fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/composer/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/composer/README.md
new file mode 100644 (file)
index 0000000..ad6ed24
--- /dev/null
@@ -0,0 +1,35 @@
+# composer
+
+This plugin provides completion for [composer](https://getcomposer.org/), as well as aliases
+for frequent composer commands. It also adds Composer's global binaries to the PATH, using
+Composer if available.
+
+To use it add `composer` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... composer)
+```
+
+Original author: Daniel Gomes <me@danielcsgomes.com>
+
+## Aliases
+
+| Alias  | Command                            | Description                                                                             |
+| ------ | ---------------------------------- | --------------------------------------------------------------------------------------- |
+| `c`    | `composer`                         | Starts composer                                                                         |
+| `ccp`  | `composer create-project`          | Create new project from an existing package                                             |
+| `cdo`  | `composer dump-autoload -o`        | Converts PSR-0/4 autoloading to classmap for a faster autoloader (good for production)  |
+| `cdu`  | `composer dump-autoload`           | Updates the autoloader                                                                  |
+| `cget` | `curl -s <installer> \| php`       | Installs composer in the current directory                                              |
+| `cgr`  | `composer global require`          | Allows require command to run on COMPOSER_HOME directory                                |
+| `cgrm` | `composer global remove`           | Allows remove command to run on COMPOSER_HOME directory                                 |
+| `cgu`  | `composer global update`           | Allows update command to run on COMPOSER_HOME directory                                 |
+| `ci`   | `composer install`                 | Resolves and installs dependencies from `composer.json`                                 |
+| `co`   | `composer outdated`                | Shows a list of installed packages with available updates                               |
+| `cod`  | `composer outdated --direct`       | Shows a list of installed packages with available updates which are direct dependencies |
+| `cr`   | `composer require`                 | Adds new packages to `composer.json`                                                    |
+| `crm`  | `composer remove`                  | Removes packages from `composer.json`                                                   |
+| `cs`   | `composer show`                    | Lists available packages, with optional filtering                                       |
+| `csu`  | `composer self-update`             | Updates composer to the latest version                                                  |
+| `cu`   | `composer update`                  | Updates composer dependencies and `composer.lock` file                                  |
+| `cuh`  | `composer update -d <config-home>` | Updates globally installed packages                                                     |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/composer/composer.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/composer/composer.plugin.zsh
new file mode 100644 (file)
index 0000000..dd0b18e
--- /dev/null
@@ -0,0 +1,76 @@
+## Basic Composer command completion
+# Since Zsh 5.7, an improved composer command completion is provided
+if ! is-at-least 5.7; then
+  _composer () {
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+    _arguments '*:: :->subcmds'
+
+    if (( CURRENT == 1 )) || ( (( CURRENT == 2 )) && [[ "$words[1]" = "global" ]] ); then
+      # Command list
+      local -a subcmds
+      subcmds=("${(@f)"$($_comp_command1 --no-ansi 2>/dev/null | awk '
+        /Available commands/{ r=1 }
+        r == 1 && /^[ \t]*[a-z]+/{
+          gsub(/^[ \t]+/, "")
+          gsub(/  +/, ":")
+          print $0
+        }
+      ')"}")
+      _describe -t commands 'composer command' subcmds
+    else
+      # Required list
+      compadd $($_comp_command1 show -s --no-ansi 2>/dev/null \
+        | sed '1,/requires/d' \
+        | awk 'NF > 0 && !/^requires \(dev\)/{ print $1 }')
+    fi
+  }
+
+  compdef _composer composer
+  compdef _composer composer.phar
+fi
+
+
+## Aliases
+alias c='composer'
+alias ccp='composer create-project'
+alias cdo='composer dump-autoload -o'
+alias cdu='composer dump-autoload'
+alias cget='curl -s https://getcomposer.org/installer | php'
+alias cgr='composer global require'
+alias cgrm='composer global remove'
+alias cgu='composer global update'
+alias ci='composer install'
+alias co='composer outdated'
+alias cod='composer outdated --direct'
+alias cr='composer require'
+alias crm='composer remove'
+alias cs='composer show'
+alias csu='composer self-update'
+alias cu='composer update'
+alias cuh='composer update --working-dir=$(composer config -g home)'
+
+
+## If Composer not found, try to add known directories to $PATH
+if (( ! $+commands[composer] )); then
+  [[ -d "$HOME/.composer/vendor/bin" ]] && export PATH="$PATH:$HOME/.composer/vendor/bin"
+  [[ -d "$HOME/.config/composer/vendor/bin" ]] && export PATH="$PATH:$HOME/.config/composer/vendor/bin"
+
+  # If still not found, don't do the rest of the script
+  (( $+commands[composer] )) || return 0
+fi
+
+
+## Add Composer's global binaries to PATH
+autoload -Uz _store_cache _retrieve_cache _cache_invalid
+_retrieve_cache composer
+
+if [[ -z $__composer_bin_dir ]]; then
+  __composer_bin_dir=$(composer global config bin-dir --absolute 2>/dev/null)
+  _store_cache composer __composer_bin_dir
+fi
+
+# Add Composer's global binaries to PATH
+export PATH="$PATH:$__composer_bin_dir"
+
+unset __composer_bin_dir
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/copybuffer/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/copybuffer/README.md
new file mode 100644 (file)
index 0000000..a53d1c8
--- /dev/null
@@ -0,0 +1,11 @@
+# `copybuffer` plugin
+
+This plugin adds the <kbd>ctrl-o</kbd> keyboard shortcut to copy the current text
+in the command line to the system clipboard.
+
+This is useful if you type a command - and before you hit enter to execute it - want
+to copy it maybe so you can paste it into a script, gist or whatnot.
+
+```zsh
+plugins=(... copybuffer)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/copybuffer/copybuffer.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/copybuffer/copybuffer.plugin.zsh
new file mode 100644 (file)
index 0000000..e67f920
--- /dev/null
@@ -0,0 +1,16 @@
+# copy the active line from the command line buffer 
+# onto the system clipboard
+
+copybuffer () {
+  if which clipcopy &>/dev/null; then
+    printf "%s" "$BUFFER" | clipcopy
+  else
+    zle -M "clipcopy not found. Please make sure you have Oh My Zsh installed correctly."
+  fi
+}
+
+zle -N copybuffer
+
+bindkey -M emacs "^O" copybuffer
+bindkey -M viins "^O" copybuffer
+bindkey -M vicmd "^O" copybuffer
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/copyfile/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/copyfile/README.md
new file mode 100644 (file)
index 0000000..a110b83
--- /dev/null
@@ -0,0 +1,11 @@
+# copyfile plugin
+
+Puts the contents of a file in your system clipboard so you can paste it anywhere.
+
+To use, add `copyfile` to your plugins array:
+
+```zsh
+plugins=(... copyfile)
+```
+
+Then you can run the command `copyfile <filename>` to copy the file named `filename`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/copyfile/copyfile.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/copyfile/copyfile.plugin.zsh
new file mode 100644 (file)
index 0000000..f4eca5a
--- /dev/null
@@ -0,0 +1,7 @@
+# Copies the contents of a given file to the system or X Windows clipboard
+#
+# copyfile <file>
+function copyfile {
+  emulate -L zsh
+  clipcopy $1
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/copypath/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/copypath/README.md
new file mode 100644 (file)
index 0000000..1e5a463
--- /dev/null
@@ -0,0 +1,15 @@
+# copypath plugin
+
+Copies the path of given directory or file to the system clipboard.
+
+To use it, add `copypath` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... copypath)
+```
+
+## Usage
+
+- `copypath`: copies the absolute path of the current directory.
+
+- `copypath <file_or_directory>`: copies the absolute path of the given file.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/copypath/copypath.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/copypath/copypath.plugin.zsh
new file mode 100644 (file)
index 0000000..8fe0a85
--- /dev/null
@@ -0,0 +1,15 @@
+# Copies the path of given directory or file to the system or X Windows clipboard.
+# Copy current directory if no parameter.
+function copypath {
+  # If no argument passed, use current directory
+  local file="${1:-.}"
+
+  # If argument is not an absolute path, prepend $PWD
+  [[ $file = /* ]] || file="$PWD/$file"
+
+  # Copy the absolute path without resolving symlinks
+  # If clipcopy fails, exit the function with an error
+  print -n "${file:a}" | clipcopy || return 1
+
+  echo ${(%):-"%B${file:a}%b copied to clipboard."}
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cp/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cp/README.md
new file mode 100644 (file)
index 0000000..2373424
--- /dev/null
@@ -0,0 +1,32 @@
+# cp plugin
+
+This plugin defines a `cpv` function that uses `rsync` so that you
+get the features and security of this command.
+
+To enable, add `cp` to your `plugins` array in your zshrc file:
+
+```zsh
+plugins=(... cp)
+```
+
+## Description
+
+The enabled options for rsync are:
+
+- `-p`: preserves permissions.
+
+- `-o`: preserves owner.
+
+* `-g`: preserves group.
+
+* `-b`: make a backup of the original file instead of overwriting it, if it exists.
+
+* `-r`: recurse directories.
+
+* `-hhh`: outputs numbers in human-readable format, in units of 1024 (K, M, G, T).
+
+* `--backup-dir="/tmp/rsync-$USERNAME"`: move backup copies to "/tmp/rsync-$USERNAME".
+
+* `-e /dev/null`: only work on local files (disable remote shells).
+
+* `--progress`: display progress.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cp/cp.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/cp/cp.plugin.zsh
new file mode 100644 (file)
index 0000000..a562591
--- /dev/null
@@ -0,0 +1,4 @@
+cpv() {
+    rsync -pogbr -hhh --backup-dir="/tmp/rsync-${USERNAME}" -e /dev/null --progress "$@"
+}
+compdef _files cpv
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cpanm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/cpanm/README.md
new file mode 100644 (file)
index 0000000..13e93d0
--- /dev/null
@@ -0,0 +1,9 @@
+# Cpanm
+
+This plugin provides completion for [Cpanm](https://github.com/miyagawa/cpanminus) ([docs](https://metacpan.org/pod/App::cpanminus)).
+
+To use it add cpanm to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... cpanm)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/cpanm/_cpanm b/stow/oh-my-zsh/.oh-my-zsh/plugins/cpanm/_cpanm
new file mode 100644 (file)
index 0000000..f328dd9
--- /dev/null
@@ -0,0 +1,64 @@
+#compdef cpanm
+
+##
+# cpanminus Z Shell completion script
+##
+#
+# Current supported cpanm version: 1.4000 (Tue Mar  8 01:00:49 PST 2011)
+#
+
+local arguments curcontext="$curcontext"
+typeset -A opt_args
+
+
+arguments=(
+
+# Commands
+#  '(--install -i)'{--install,-i}'[Installs the modules]'
+  '(- :)--self-upgrade[Upgrades itself]'
+  '(- :)--info[Displays distribution info on CPAN]'
+  '(--installdeps)--installdeps[Only install dependencies]'
+  '(--look)--look[Download/unpack the distribution and then open the directory with your shell]'
+  '(- :)'{--help,-h}'[Displays help information]'
+  '(- :)'{--version,-V}'[Displays software version]'
+
+# Options
+  {--force,-f}'[Force install]'
+  {--notest,-n}'[Do not run unit tests]'
+  {--sudo,-S}'[sudo to run install commands]'
+  '(-v --verbose --quiet -q)'{--verbose,-v}'[Turns on chatty output]'
+  '(-q --quiet --verbose -v)'{--quiet,-q}'[Turns off all output]'
+  {--local-lib,-l}'[Specify the install base to install modules]'
+  {--local-lib-contained,-L}'[Specify the install base to install all non-core modules]'
+  '--mirror[Specify the base URL for the mirror (e.g. http://cpan.cpantesters.org/)]:URLs:_urls'
+  '--mirror-only[Use the mirror\''s index file instead of the CPAN Meta DB]'
+  '--prompt[Prompt when configure/build/test fails]'
+  '--reinstall[Reinstall the distribution even if you already have the latest version installed]'
+  '--interactive[Turn on interactive configure]'
+
+  '--scandeps[Scan the dependencies of given modules and output the tree in a text format]'
+  '--format[Specify what format to display the scanned dependency tree]:scandeps format:(tree json yaml dists)'
+
+  '--save-dists[Specify the optional directory path to copy downloaded tarballs]'
+#  '--uninst-shadows[Uninstalls the shadow files of the distribution that you\''re installing]'
+
+  '--auto-cleanup[Number of days that cpanm\''s work directories expire in. Defaults to 7]'
+  '(--no-man-pages)--man-pages[Generates man pages for executables (man1) and libraries (man3)]'
+  '(--man-pages)--no-man-pages[Do not generate man pages]'
+
+
+  # Note: Normally with "--lwp", "--wget" and "--curl" options set to true (which is the default) cpanm tries LWP,
+  #            Wget, cURL and HTTP::Tiny (in that order) and uses the first one available.
+  # (So that the exclusions are not enabled here for the completion)
+  '(--lwp)--lwp[Use LWP module to download stuff]'
+  '(--wget)--wget[Use GNU Wget (if available) to download stuff]'
+  '(--curl)--curl[Use cURL (if available) to download stuff]'
+
+# Other completions
+  '*:Local directory or archive:_files -/ -g "*.(tar.gz|tgz|tar.bz2|zip)(-.)"'
+  #  '*::args: _normal' # this looks for default files (any files)
+)
+_arguments -s $arguments \
+  && return 0
+
+return 1
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dash/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dash/README.md
new file mode 100644 (file)
index 0000000..0ca3e4e
--- /dev/null
@@ -0,0 +1,28 @@
+# Dash plugin
+
+This plugin adds command line functionality for [Dash](https://kapeli.com/dash),
+an API Documentation Browser for macOS. This plugin requires Dash to be installed
+to work.
+
+To use it, add `dash` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... dash)
+```
+
+## Usage
+
+- Open and switch to the dash application.
+```
+dash
+```
+
+- Query for something in dash app: `dash query`
+```
+dash golang 
+```
+
+- You can optionally provide a keyword: `dash [keyword:]query`
+```
+dash python:tuple
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dash/dash.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dash/dash.plugin.zsh
new file mode 100644 (file)
index 0000000..f6801a8
--- /dev/null
@@ -0,0 +1,84 @@
+# Usage: dash [keyword:]query
+dash() { open -a Dash.app dash://"$*" }
+compdef _dash dash
+
+_dash() {
+  # No sense doing this for anything except the 2nd position and if we haven't
+  # specified which docset to query against
+  if [[ $CURRENT -ne 2 || "$words[2]" =~ ":" ]]; then
+    return
+  fi
+
+  local -aU docsets
+  docsets=()
+
+  # Use defaults to get the array of docsets from preferences
+  # Have to smash it into one big line so that each docset is an element of our docsets array
+  # Only output docsets that are actually enabled
+  local -a enabled_docsets
+  enabled_docsets=("${(@f)$(defaults read com.kapeli.dashdoc docsets \
+    | tr -d '\n' | grep -oE '\{.*?\}' | grep -E 'isEnabled = 1;')}")
+
+  local docset name keyword
+  # Now get each docset and output each on their own line
+  for docset in "$enabled_docsets[@]"; do
+    keyword=''
+    # Order of preference as explained to me by @kapeli via email
+    for locator in keyword suggestedKeyword platform; do
+      # Echo the docset, try to find the appropriate keyword
+      # Strip doublequotes and colon from any keyword so that everything has the
+      # same format when output (we'll add the colon in the completion)
+      if [[ "$docset" =~ "$locator = ([^;]*);" ]]; then
+        keyword="${match[1]//[\":]}"
+      fi
+
+      if [[ -z "$keyword" ]]; then
+        continue
+      fi
+
+      # if we fall back to platform, we should do some checking per @kapeli
+      if [[ "$locator" == "platform" ]]; then
+        # Since these are the only special cases right now, let's not do the
+        # expensive processing unless we have to
+        if [[ "$keyword" = (python|java|qt|cocos2d) ]]; then
+          if [[ "$docset" =~ "docsetName = ([^;]*);" ]]; then
+            name="${match[1]//[\":]}"
+            case "$keyword" in
+              python)
+                case "$name" in
+                  "Python 2") keyword="python2" ;;
+                  "Python 3") keyword="python3" ;;
+                esac ;;
+              java)
+                case "$name" in
+                  "Java SE7") keyword="java7" ;;
+                  "Java SE6") keyword="java6" ;;
+                  "Java SE8") keyword="java8" ;;
+                esac ;;
+              qt)
+                case "$name" in
+                  "Qt 5") keyword="qt5" ;;
+                  "Qt 4"|Qt) keyword="qt4" ;;
+                esac ;;
+              cocos2d)
+                case "$name" in
+                  Cocos3D) keyword="cocos3d" ;;
+                esac ;;
+            esac
+          fi
+        fi
+      fi
+
+      # Bail once we have a match
+      break
+    done
+
+    # If we have a keyword, add it to the list!
+    if [[ -n "$keyword" ]]; then
+      docsets+=($keyword)
+    fi
+  done
+
+  # special thanks to [arx] on #zsh for getting me sorted on this piece
+  compadd -qS: -- "$docsets[@]"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/debian/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/debian/README.md
new file mode 100644 (file)
index 0000000..1db534f
--- /dev/null
@@ -0,0 +1,87 @@
+# debian
+
+This plugin provides Debian-related aliases and functions for zsh.
+
+To use it add `debian` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... debian)
+```
+
+## Settings
+
+- `$apt_pref`: use aptitude or apt if installed, fallback is apt-get.
+- `$apt_upgr`: use upgrade or safe-upgrade (for aptitude).
+
+Set `$apt_pref` and `$apt_upgr` to whatever command you want (before sourcing Oh My Zsh) to override this behavior.
+
+## Common Aliases
+
+| Alias  | Command                                                                | Description                                                |
+| ------ | ---------------------------------------------------------------------- | ---------------------------------------------------------- |
+| `age`  | `apt-get`                                                              | Command line tool for handling packages                    |
+| `api`  | `aptitude`                                                             | Same functionality as `apt-get`, provides extra options    |
+| `acs`  | `apt-cache search`                                                     | Command line tool for searching apt software package cache |
+| `aps`  | `aptitude search`                                                      | Searches installed packages using aptitude                 |
+| `as`   | `aptitude -F '* %p -> %d \n(%v/%V)' --no-gui --disable-columns search` | Print searched packages using a custom format              |
+| `afs`  | `apt-file search --regexp`                                             | Search file in packages                                    |
+| `asrc` | `apt-get source`                                                       | Fetch source packages through `apt-get`                    |
+| `app`  | `apt-cache policy`                                                     | Displays priority of package sources                       |
+
+## Superuser Operations Aliases
+
+| Alias    | Command                                                                               | Description                                                                                 |
+| -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
+| `aac`    | `sudo $apt_pref autoclean`                                                            | Clears out the local repository of retrieved package files                                  |
+| `aar`    | `sudo $apt_pref autoremove`                                                           | Removes packages installed automatically that are no longer needed                          |
+| `abd`    | `sudo $apt_pref build-dep`                                                            | Installs all dependencies for building packages                                             |
+| `ac`     | `sudo $apt_pref clean`                                                                | Clears out the local repository of retrieved package files except lock files                |
+| `ad`     | `sudo $apt_pref update`                                                               | Updates the package lists for upgrades for packages                                         |
+| `adg`    | `sudo $apt_pref update && sudo $apt_pref $apt_upgr`                                   | Update and upgrade packages                                                                 |
+| `ads`    | `sudo apt-get dselect-upgrade`                                                        | Installs packages from list and removes all not in the list                                 |
+| `adu`    | `sudo $apt_pref update && sudo $apt_pref dist-upgrade`                                | Smart upgrade that handles dependencies                                                     |
+| `afu`    | `sudo apt-file update`                                                                | Update the files in packages                                                                |
+| `ai`     | `sudo $apt_pref install`                                                              | Command-line tool to install package                                                        |
+| `ail`    | `sed -e 's/ */ /g' -e 's/ *//' \| cut -s -d ' ' -f 1 \| xargs sudo $apt_pref install` | Install all packages given on the command line while using only the first word of each line |
+| `alu`    | `sudo apt update && apt list -u && sudo apt upgrade`                                  | Update, list and upgrade packages                                                           |
+| `ap`     | `sudo $apt_pref purge`                                                                | Removes packages along with configuration files                                             |
+| `au`     | `sudo $apt_pref $apt_upgr`                                                            | Install package upgrades                                                                    |
+| `di`     | `sudo dpkg -i`                                                                        | Install all .deb files in the current directory                                             |
+| `dia`    | `sudo dpkg -i ./*.deb`                                                                | Install all .deb files in the current directory                                             |
+| `kclean` | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))`              | Remove ALL kernel images and headers EXCEPT the one in use                                  |
+
+## Aliases - Commands using `su`
+
+| Alias | Command                                                   |
+| ----- | --------------------------------------------------------- |
+| `aac` | `su -ls "$apt_pref autoclean" root`                       |
+| `aar` | `su -ls "$apt_pref autoremove" root`                      |
+| `ac`  | `su -ls "$apt_pref clean" root`                           |
+| `ad`  | `su -lc "$apt_pref update" root`                          |
+| `adg` | `su -lc "$apt_pref update && aptitude $apt_upgr" root`    |
+| `adu` | `su -lc "$apt_pref update && aptitude dist-upgrade" root` |
+| `afu` | `su -lc "apt-file update"`                                |
+| `au`  | `su -lc "$apt_pref $apt_upgr" root`                       |
+| `dia` | `su -lc "dpkg -i ./*.deb" root`                           |
+
+## Miscellaneous Aliases
+
+| Alias     | Command                                        | Description                    |
+| --------- | ---------------------------------------------- | ------------------------------ |
+| `allpkgs` | `aptitude search -F "%p" --disable-columns ~i` | Display all installed packages |
+| `mydeb`   | `time dpkg-buildpackage -rfakeroot -us -uc`    | Create a basic .deb package    |
+
+## Functions
+
+| Function            | Description                                                     |
+| ------------------- | --------------------------------------------------------------- |
+| `apt-copy`          | Create a simple script that can be used to 'duplicate' a system |
+| `apt-history`       | Displays apt history for a command                              |
+| `apt-list-packages` | List packages by size                                           |
+| `kerndeb`           | Builds kernel packages                                          |
+
+## Authors
+
+- [@AlexBio](https://github.com/AlexBio)
+- [@dbb](https://github.com/dbb)
+- [@Mappleconfusers](https://github.com/Mappleconfusers)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/debian/debian.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/debian/debian.plugin.zsh
new file mode 100644 (file)
index 0000000..2d8c466
--- /dev/null
@@ -0,0 +1,227 @@
+# Use aptitude or apt if installed, fallback is apt-get
+# You can just set apt_pref='apt-get' to override it.
+
+if [[ -z $apt_pref || -z $apt_upgr ]]; then
+    if [[ -e $commands[aptitude] ]]; then
+        apt_pref='aptitude'
+        apt_upgr='safe-upgrade'
+    elif [[ -e $commands[apt] ]]; then
+        apt_pref='apt'
+        apt_upgr='upgrade'
+    else
+        apt_pref='apt-get'
+        apt_upgr='upgrade'
+    fi
+fi
+
+# Use sudo by default if it's installed
+if [[ -e $commands[sudo] ]]; then
+    use_sudo=1
+fi
+
+# Aliases ###################################################################
+# These are for more obscure uses of apt-get and aptitude that aren't covered
+# below.
+alias age='apt-get'
+alias api='aptitude'
+
+# Some self-explanatory aliases
+alias acs="apt-cache search"
+alias aps='aptitude search'
+alias as="aptitude -F '* %p -> %d \n(%v/%V)' --no-gui --disable-columns search"
+
+# apt-file
+alias afs='apt-file search --regexp'
+
+
+# These are apt-get only
+alias asrc='apt-get source'
+alias app='apt-cache policy'
+
+# superuser operations ######################################################
+if [[ $use_sudo -eq 1 ]]; then
+# commands using sudo #######
+    alias aac="sudo $apt_pref autoclean"
+    alias abd="sudo $apt_pref build-dep"
+    alias ac="sudo $apt_pref clean"
+    alias ad="sudo $apt_pref update"
+    alias adg="sudo $apt_pref update && sudo $apt_pref $apt_upgr"
+    alias adu="sudo $apt_pref update && sudo $apt_pref dist-upgrade"
+    alias afu="sudo apt-file update"
+    alias au="sudo $apt_pref $apt_upgr"
+    alias ai="sudo $apt_pref install"
+    # Install all packages given on the command line while using only the first word of each line:
+    # acs ... | ail
+
+    alias ail="sed -e 's/  */ /g' -e 's/ *//' | cut -s -d ' ' -f 1 | xargs sudo $apt_pref install"
+    alias ap="sudo $apt_pref purge"
+    alias aar="sudo $apt_pref autoremove"
+
+    # apt-get only
+    alias ads="sudo apt-get dselect-upgrade"
+
+    # apt only
+    alias alu="sudo apt update && apt list -u && sudo apt upgrade"
+
+    # Install all .deb files in the current directory.
+    # Warning: you will need to put the glob in single quotes if you use:
+    # glob_subst
+    alias dia="sudo dpkg -i ./*.deb"
+    alias di="sudo dpkg -i"
+
+    # Remove ALL kernel images and headers EXCEPT the one in use
+    alias kclean='sudo aptitude remove -P "?and(~i~nlinux-(ima|hea) ?not(~n$(uname -r)))"'
+
+
+# commands using su #########
+else
+    alias aac="su -ls '$apt_pref autoclean' root"
+    function abd() {
+        cmd="su -lc '$apt_pref build-dep $@' root"
+        print "$cmd"
+        eval "$cmd"
+    }
+    alias ac="su -ls '$apt_pref clean' root"
+    alias ad="su -lc '$apt_pref update' root"
+    alias adg="su -lc '$apt_pref update && aptitude $apt_upgr' root"
+    alias adu="su -lc '$apt_pref update && aptitude dist-upgrade' root"
+    alias afu="su -lc '$apt-file update'"
+    alias au="su -lc '$apt_pref $apt_upgr' root"
+    function ai() {
+        cmd="su -lc '$apt_pref install $@' root"
+        print "$cmd"
+        eval "$cmd"
+    }
+    function ap() {
+        cmd="su -lc '$apt_pref purge $@' root"
+        print "$cmd"
+        eval "$cmd"
+    }
+    function aar() {
+        cmd="su -lc '$apt_pref autoremove $@' root"
+        print "$cmd"
+        eval "$cmd"
+    }
+    # Install all .deb files in the current directory
+    # Assumes glob_subst is off
+    alias dia='su -lc "dpkg -i ./*.deb" root'
+    alias di='su -lc "dpkg -i" root'
+
+    # Remove ALL kernel images and headers EXCEPT the one in use
+    alias kclean='su -lc "aptitude remove -P \"?and(~i~nlinux-(ima|hea) ?not(~n$(uname -r)))\"" root'
+fi
+
+# Completion ################################################################
+
+#
+# Registers a compdef for $1 that calls $apt_pref with the commands $2
+# To do that it creates a new completion function called _apt_pref_$2
+#
+function apt_pref_compdef() {
+    local f fb
+    f="_apt_pref_${2}"
+
+    eval "function ${f}() {
+        shift words;
+        service=\"\$apt_pref\";
+        words=(\"\$apt_pref\" '$2' \$words);
+        ((CURRENT++))
+        test \"\${apt_pref}\" = 'aptitude' && _aptitude || _apt
+    }"
+
+    compdef "$f" "$1"
+}
+
+apt_pref_compdef aac "autoclean"
+apt_pref_compdef abd "build-dep"
+apt_pref_compdef ac  "clean"
+apt_pref_compdef ad  "update"
+apt_pref_compdef afu "update"
+apt_pref_compdef au  "$apt_upgr"
+apt_pref_compdef ai  "install"
+apt_pref_compdef ail "install"
+apt_pref_compdef ap  "purge"
+apt_pref_compdef aar  "autoremove"
+apt_pref_compdef ads "dselect-upgrade"
+
+# Misc. #####################################################################
+# print all installed packages
+alias allpkgs='aptitude search -F "%p" --disable-columns ~i'
+
+# Create a basic .deb package
+alias mydeb='time dpkg-buildpackage -rfakeroot -us -uc'
+
+
+# Functions #################################################################
+# create a simple script that can be used to 'duplicate' a system
+function apt-copy() {
+    print '#!/bin/sh'"\n" > apt-copy.sh
+
+    cmd='$apt_pref install'
+
+    for p in ${(f)"$(aptitude search -F "%p" --disable-columns \~i)"}; {
+        cmd="${cmd} ${p}"
+    }
+
+    print $cmd "\n" >> apt-copy.sh
+
+    chmod +x apt-copy.sh
+}
+
+# Prints apt history
+# Usage:
+#   apt-history install
+#   apt-history upgrade
+#   apt-history remove
+#   apt-history rollback
+#   apt-history list
+# Based On: https://linuxcommando.blogspot.com/2008/08/how-to-show-apt-log-history.html
+function apt-history() {
+  case "$1" in
+    install)
+      zgrep --no-filename 'install ' $(ls -rt /var/log/dpkg*)
+      ;;
+    upgrade|remove)
+      zgrep --no-filename $1 $(ls -rt /var/log/dpkg*)
+      ;;
+    rollback)
+      zgrep --no-filename upgrade $(ls -rt /var/log/dpkg*) | \
+        grep "$2" -A10000000 | \
+        grep "$3" -B10000000 | \
+        awk '{print $4"="$5}'
+      ;;
+    list)
+      zgrep --no-filename '' $(ls -rt /var/log/dpkg*)
+      ;;
+    *)
+      echo "Parameters:"
+      echo " install - Lists all packages that have been installed."
+      echo " upgrade - Lists all packages that have been upgraded."
+      echo " remove - Lists all packages that have been removed."
+      echo " rollback - Lists rollback information."
+      echo " list - Lists all contains of dpkg logs."
+      ;;
+  esac
+}
+
+# Kernel-package building shortcut
+function kerndeb() {
+    # temporarily unset MAKEFLAGS ( '-j3' will fail )
+    MAKEFLAGS=$( print - $MAKEFLAGS | perl -pe 's/-j\s*[\d]+//g' )
+    print '$MAKEFLAGS set to '"'$MAKEFLAGS'"
+    appendage='-custom' # this shows up in $(uname -r )
+    revision=$(date +"%Y%m%d") # this shows up in the .deb file name
+
+    make-kpkg clean
+
+    time fakeroot make-kpkg --append-to-version "$appendage" --revision \
+        "$revision" kernel_image kernel_headers
+}
+
+# List packages by size
+function apt-list-packages() {
+    dpkg-query -W --showformat='${Installed-Size} ${Package} ${Status}\n' | \
+    grep -v deinstall | \
+    sort -n | \
+    awk '{print $1" "$2}'
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/deno/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/deno/README.md
new file mode 100644 (file)
index 0000000..6913183
--- /dev/null
@@ -0,0 +1,19 @@
+# Deno Plugin
+
+This plugin sets up completion and aliases for [Deno](https://deno.land).
+
+## Aliases
+
+| Alias | Full command     |
+| ----- | ---------------- |
+| db    | deno bundle      |
+| dc    | deno compile     |
+| dca   | deno cache       |
+| dfmt  | deno fmt         |
+| dh    | deno help        |
+| dli   | deno lint        |
+| drn   | deno run         |
+| drA   | deno run -A      |
+| drw   | deno run --watch |
+| dts   | deno test        |
+| dup   | deno upgrade     |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/deno/deno.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/deno/deno.plugin.zsh
new file mode 100644 (file)
index 0000000..7708f84
--- /dev/null
@@ -0,0 +1,27 @@
+# ALIASES
+alias db='deno bundle'
+alias dc='deno compile'
+alias dca='deno cache'
+alias dfmt='deno fmt'
+alias dh='deno help'
+alias dli='deno lint'
+alias drn='deno run'
+alias drA='deno run -A'
+alias drw='deno run --watch'
+alias dts='deno test'
+alias dup='deno upgrade'
+
+# COMPLETION FUNCTION
+if (( ! $+commands[deno] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `deno`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_deno" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _deno
+  _comps[deno]=_deno
+fi
+
+deno completions zsh >| "$ZSH_CACHE_DIR/completions/_deno" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dircycle/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dircycle/README.md
new file mode 100644 (file)
index 0000000..3c9b3a9
--- /dev/null
@@ -0,0 +1,78 @@
+# dircycle
+
+Plugin for cycling through the directory stack
+
+This plugin enables directory navigation similar to using back and forward on browsers or common file explorers like Finder or Nautilus. It uses a small zle trick that lets you cycle through your directory stack left or right using <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd> / <kbd>Right</kbd> . This is useful when moving back and forth between directories in development environments, and can be thought of as kind of a nondestructive pushd/popd.
+
+## Enabling the plugin
+
+1. Open your `.zshrc` file and add `dircycle` in the plugins section:
+
+   ```zsh
+   plugins=(
+       # all your enabled plugins
+       dircycle
+   )
+   ```
+
+2. Restart the shell or restart your Terminal session:
+
+   ```console
+   $ exec zsh
+   $
+   ```
+
+## Usage Examples
+
+Say you opened these directories on the terminal:
+
+```console
+~$ cd Projects
+~/Projects$ cd Hacktoberfest
+~/Projects/Hacktoberfest$ cd oh-my-zsh
+~/Projects/Hacktoberfest/oh-my-zsh$ dirs -v
+0       ~/Projects/Hacktoberfest/oh-my-zsh
+1       ~/Projects/Hacktoberfest
+2       ~/Projects
+3       ~
+```
+
+By pressing <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd>, the current working directory or `$CWD` will be from `oh-my-zsh` to `Hacktoberfest`. Press it again and it will be at `Projects`.
+
+And by pressing <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd>, the `$CWD` will be from `Projects` to `Hacktoberfest`. Press it again and it will be at `oh-my-zsh`.
+
+Here's a example history table with the same accessed directories like above:
+
+| Current `$CWD`  | Key press                                             | New `$CWD`      |
+| --------------- | ----------------------------------------------------- | --------------- |
+| `oh-my-zsh`     | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd>  | `Hacktoberfest` |
+| `Hacktoberfest` | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd>  | `Projects`      |
+| `Projects`      | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd>  | `~`             |
+| `~`             | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> | `Projects`      |
+| `Projects`      | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> | `Hacktoberfest` |
+| `Hacktoberfest` | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> | `oh-my-zsh`     |
+| `oh-my-zsh`     | <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> | `~`             |
+
+Note the last traversal, when pressing <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd> on a last known `$CWD`, it will change back to the first known `$CWD`, which in the example is `~`.
+
+Here's an asciinema cast demonstrating the example above:
+
+[![asciicast](https://asciinema.org/a/204406.png)](https://asciinema.org/a/204406)
+
+## Functions
+
+| Function             | Description                                                                                               |
+| -------------------- | --------------------------------------------------------------------------------------------------------- |
+| `insert-cycledleft`  | Change `$CWD` to the previous known stack, binded on <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd> |
+| `insert-cycledright` | Change `$CWD` to the next known stack, binded on <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Right</kbd>    |
+
+## Rebinding keys
+
+You can bind these functions to other key sequences, as long as you know the bindkey sequence. For example, these commands bind to <kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Left</kbd> / <kbd>Right</kbd> in `xterm-256color`:
+
+```zsh
+bindkey '^[[1;4D' insert-cycledleft
+bindkey '^[[1;4C' insert-cycledright
+```
+
+You can get the bindkey sequence by pressing <kbd>Ctrl</kbd> + <kbd>V</kbd>, then pressing the keyboard shortcut you want to use.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dircycle/dircycle.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dircycle/dircycle.plugin.zsh
new file mode 100644 (file)
index 0000000..bb69f6b
--- /dev/null
@@ -0,0 +1,54 @@
+# enables cycling through the directory stack using
+# Ctrl+Shift+Left/Right
+#
+# left/right direction follows the order in which directories
+# were visited, like left/right arrows do in a browser
+
+# NO_PUSHD_MINUS syntax:
+#  pushd +N: start counting from left of `dirs' output
+#  pushd -N: start counting from right of `dirs' output
+
+switch-to-dir () {
+       setopt localoptions nopushdminus
+       [[ ${#dirstack} -eq 0 ]] && return 1
+
+       while ! builtin pushd -q $1 &>/dev/null; do
+               # We found a missing directory: pop it out of the dir stack
+               builtin popd -q $1
+
+               # Stop trying if there are no more directories in the dir stack
+               [[ ${#dirstack} -eq 0 ]] && return 1
+       done
+}
+
+insert-cycledleft () {
+       switch-to-dir +1 || return
+
+       local fn
+       for fn (chpwd $chpwd_functions precmd $precmd_functions); do
+               (( $+functions[$fn] )) && $fn
+       done
+       zle reset-prompt
+}
+zle -N insert-cycledleft
+
+insert-cycledright () {
+       switch-to-dir -0 || return
+
+       local fn
+       for fn (chpwd $chpwd_functions precmd $precmd_functions); do
+               (( $+functions[$fn] )) && $fn
+       done
+       zle reset-prompt
+}
+zle -N insert-cycledright
+
+
+# These sequences work for xterm, Apple Terminal.app, and probably others.
+# Not for rxvt-unicode, but it doesn't seem differentiate Ctrl-Shift-Arrow
+# from plain Shift-Arrow, at least by default.
+# iTerm2 does not have these key combinations defined by default; you will need
+# to add them under "Keys" in your profile if you want to use this. You can do
+# this conveniently by loading the "xterm with Numeric Keypad" preset.
+bindkey "\e[1;6D" insert-cycledleft
+bindkey "\e[1;6C" insert-cycledright
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/direnv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/direnv/README.md
new file mode 100644 (file)
index 0000000..8deaf38
--- /dev/null
@@ -0,0 +1,15 @@
+# direnv plugin
+
+This plugin creates the [Direnv](https://direnv.net/) hook.
+
+To use it, add `direnv` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... direnv)
+```
+
+## Requirements
+
+In order to make this work, you will need to have the direnv installed.
+
+More info on the usage and install: https://github.com/direnv/direnv
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/direnv/direnv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/direnv/direnv.plugin.zsh
new file mode 100644 (file)
index 0000000..5e32c4c
--- /dev/null
@@ -0,0 +1,16 @@
+# Don't continue if direnv is not found
+command -v direnv &>/dev/null || return
+
+_direnv_hook() {
+  trap -- '' SIGINT;
+  eval "$(direnv export zsh)";
+  trap - SIGINT;
+}
+typeset -ag precmd_functions;
+if [[ -z ${precmd_functions[(r)_direnv_hook]} ]]; then
+  precmd_functions=( _direnv_hook ${precmd_functions[@]} )
+fi
+typeset -ag chpwd_functions;
+if [[ -z ${chpwd_functions[(r)_direnv_hook]} ]]; then
+  chpwd_functions=( _direnv_hook ${chpwd_functions[@]} )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/README.md
new file mode 100644 (file)
index 0000000..ede9b54
--- /dev/null
@@ -0,0 +1,62 @@
+# Dirhistory plugin
+
+This plugin adds keyboard shortcuts for navigating directory history and hierarchy.
+
+To use it, add `dirhistory` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... dirhistory)
+```
+
+## Keyboard Shortcuts
+
+| Shortcut                          | Description                                               |
+|-----------------------------------|-----------------------------------------------------------|
+| <kbd>Alt</kbd> + <kbd>Left</kbd>  | Go to previous directory                                  |
+| <kbd>Alt</kbd> + <kbd>Right</kbd> | Go to next directory                                      |
+| <kbd>Alt</kbd> + <kbd>Up</kbd>    | Move into the parent directory                            |
+| <kbd>Alt</kbd> + <kbd>Down</kbd>  | Move into the first child directory by alphabetical order |
+
+**For macOS: use the Option key (<kbd>⌥</kbd>) instead of <kbd>Alt</kbd>**.
+
+> NOTE: some terminals might override the <kbd>Alt</kbd> + Arrows key bindings (e.g. Windows Terminal).
+> If these don't work check your terminal settings and change them to a different keyboard shortcut.
+
+## Usage
+
+This plugin allows you to navigate the history of previous working directories using <kbd>Alt</kbd> + <kbd>Left</kbd>
+and <kbd>Alt</kbd> + <kbd>Right</kbd>. <kbd>Alt</kbd> + <kbd>Left</kbd> moves to past directories, and
+<kbd>Alt</kbd> + <kbd>Right</kbd> goes back to recent directories.
+
+**NOTE: the maximum directory history size is 30.**
+
+You can also navigate **directory hierarchies** using <kbd>Alt</kbd> + <kbd>Up</kbd> and <kbd>Alt</kbd> + <kbd>Down</kbd>.
+<kbd>Alt</kbd> + <kbd>Up</kbd> moves to the parent directory, while <kbd>Alt</kbd> + <kbd>Down</kbd> moves into the first
+child directory found in alphabetical order (useful to navigate long empty directories, e.g. Java packages).
+
+For example, if the shell was started, and the following commands were entered:
+
+```shell
+cd ~
+cd /usr
+cd share
+cd doc
+```
+
+the directory stack (`dirs -v`) would look like this:
+
+```console
+$ dirs -v
+0       /usr/share/doc
+1       /usr/share
+2       /usr
+3       ~
+```
+
+then entering <kbd>Alt</kbd> + <kbd>Left</kbd> at the prompt would change directory from `/usr/share/doc` to `/usr/share`,
+then if pressed again to `/usr`, then `~`. If <kbd>Alt</kbd> + <kbd>Right</kbd> were pressed the directory would be changed
+to `/usr` again.
+
+After that, <kbd>Alt</kbd> + <kbd>Down</kbd> will probably go to `/usr/bin` if `bin` is the first directory in alphabetical
+order (depends on your `/usr` folder structure). <kbd>Alt</kbd> + <kbd>Up</kbd> will return to `/usr`, and once more will get
+you to the root folder (`/`).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/dirhistory.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/dirhistory.plugin.zsh
new file mode 100644 (file)
index 0000000..7021fc0
--- /dev/null
@@ -0,0 +1,221 @@
+##
+#   Navigate directory history using ALT-LEFT and ALT-RIGHT. ALT-LEFT moves back to directories
+#   that the user has changed to in the past, and ALT-RIGHT undoes ALT-LEFT.
+#
+#   Navigate directory hierarchy using ALT-UP and ALT-DOWN.
+#   ALT-UP moves to higher hierarchy (cd ..)
+#   ALT-DOWN moves into the first directory found in alphabetical order
+#
+
+dirhistory_past=($PWD)
+dirhistory_future=()
+export dirhistory_past
+export dirhistory_future
+
+export DIRHISTORY_SIZE=30
+
+# Pop the last element of dirhistory_past.
+# Pass the name of the variable to return the result in.
+# Returns the element if the array was not empty,
+# otherwise returns empty string.
+function pop_past() {
+  typeset -g $1="${dirhistory_past[$#dirhistory_past]}"
+  if [[ $#dirhistory_past -gt 0 ]]; then
+    dirhistory_past[$#dirhistory_past]=()
+  fi
+}
+
+function pop_future() {
+  typeset -g $1="${dirhistory_future[$#dirhistory_future]}"
+  if [[ $#dirhistory_future -gt 0 ]]; then
+    dirhistory_future[$#dirhistory_future]=()
+  fi
+}
+
+# Push a new element onto the end of dirhistory_past. If the size of the array
+# is >= DIRHISTORY_SIZE, the array is shifted
+function push_past() {
+  if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then
+    shift dirhistory_past
+  fi
+  if [[ $#dirhistory_past -eq 0 || $dirhistory_past[$#dirhistory_past] != "$1" ]]; then
+    dirhistory_past+=($1)
+  fi
+}
+
+function push_future() {
+  if [[ $#dirhistory_future -ge $DIRHISTORY_SIZE ]]; then
+    shift dirhistory_future
+  fi
+  if [[ $#dirhistory_future -eq 0 || $dirhistory_futuret[$#dirhistory_future] != "$1" ]]; then
+    dirhistory_future+=($1)
+  fi
+}
+
+# Called by zsh when directory changes
+autoload -U add-zsh-hook
+add-zsh-hook chpwd chpwd_dirhistory
+function chpwd_dirhistory() {
+  push_past $PWD
+  # If DIRHISTORY_CD is not set...
+  if [[ -z "${DIRHISTORY_CD+x}" ]]; then
+    # ... clear future.
+    dirhistory_future=()
+  fi
+}
+
+function dirhistory_cd(){
+  DIRHISTORY_CD="1"
+  cd $1
+  unset DIRHISTORY_CD
+}
+
+# Move backward in directory history
+function dirhistory_back() {
+  local cw=""
+  local d=""
+  # Last element in dirhistory_past is the cwd.
+
+  pop_past cw
+  if [[ "" == "$cw" ]]; then
+    # Someone overwrote our variable. Recover it.
+    dirhistory_past=($PWD)
+    return
+  fi
+
+  pop_past d
+  if [[ "" != "$d" ]]; then
+    dirhistory_cd $d
+    push_future $cw
+  else
+    push_past $cw
+  fi
+}
+
+
+# Move forward in directory history
+function dirhistory_forward() {
+  local d=""
+
+  pop_future d
+  if [[ "" != "$d" ]]; then
+    dirhistory_cd $d
+    push_past $d
+  fi
+}
+
+
+# Bind keys to history navigation
+function dirhistory_zle_dirhistory_back() {
+  # Erase current line in buffer
+  zle .kill-buffer
+  dirhistory_back
+  zle .accept-line
+}
+
+function dirhistory_zle_dirhistory_future() {
+  # Erase current line in buffer
+  zle .kill-buffer
+  dirhistory_forward
+  zle .accept-line
+}
+
+zle -N dirhistory_zle_dirhistory_back
+zle -N dirhistory_zle_dirhistory_future
+
+for keymap in emacs vicmd viins; do
+  # dirhistory_back
+  bindkey -M $keymap "\e[3D" dirhistory_zle_dirhistory_back    # xterm in normal mode
+  bindkey -M $keymap "\e[1;3D" dirhistory_zle_dirhistory_back  # xterm in normal mode
+  bindkey -M $keymap "\e\e[D" dirhistory_zle_dirhistory_back   # Putty
+  bindkey -M $keymap "\eO3D" dirhistory_zle_dirhistory_back    # GNU screen
+
+  case "$TERM_PROGRAM" in
+  Apple_Terminal) bindkey -M $keymap "^[b" dirhistory_zle_dirhistory_back ;; # Terminal.app
+  iTerm.app) bindkey -M $keymap "^[^[[D" dirhistory_zle_dirhistory_back ;;   # iTerm2
+  esac
+
+  if (( ${+terminfo[kcub1]} )); then
+    bindkey -M $keymap "^[${terminfo[kcub1]}" dirhistory_zle_dirhistory_back  # urxvt
+  fi
+
+  # dirhistory_future
+  bindkey -M $keymap "\e[3C" dirhistory_zle_dirhistory_future    # xterm in normal mode
+  bindkey -M $keymap "\e[1;3C" dirhistory_zle_dirhistory_future  # xterm in normal mode
+  bindkey -M $keymap "\e\e[C" dirhistory_zle_dirhistory_future   # Putty
+  bindkey -M $keymap "\eO3C" dirhistory_zle_dirhistory_future    # GNU screen
+
+  case "$TERM_PROGRAM" in
+  Apple_Terminal) bindkey -M $keymap "^[f" dirhistory_zle_dirhistory_future ;; # Terminal.app
+  iTerm.app) bindkey -M $keymap "^[^[[C" dirhistory_zle_dirhistory_future ;;   # iTerm2
+  esac
+
+  if (( ${+terminfo[kcuf1]} )); then
+    bindkey -M $keymap "^[${terminfo[kcuf1]}" dirhistory_zle_dirhistory_future # urxvt
+  fi
+done
+
+#
+# HIERARCHY Implemented in this section, in case someone wants to split it to another plugin if it clashes bindings
+#
+
+# Move up in hierarchy
+function dirhistory_up() {
+  cd .. || return 1
+}
+
+# Move down in hierarchy
+function dirhistory_down() {
+  cd "$(find . -mindepth 1 -maxdepth 1 -type d | sort -n | head -n 1)" || return 1
+}
+
+
+# Bind keys to hierarchy navigation
+function dirhistory_zle_dirhistory_up() {
+  zle .kill-buffer   # Erase current line in buffer
+  dirhistory_up
+  zle .accept-line
+}
+
+function dirhistory_zle_dirhistory_down() {
+  zle .kill-buffer   # Erase current line in buffer
+  dirhistory_down
+  zle .accept-line
+}
+
+zle -N dirhistory_zle_dirhistory_up
+zle -N dirhistory_zle_dirhistory_down
+
+for keymap in emacs vicmd viins; do
+  # dirhistory_up
+  bindkey -M $keymap "\e[3A" dirhistory_zle_dirhistory_up    # xterm in normal mode
+  bindkey -M $keymap "\e[1;3A" dirhistory_zle_dirhistory_up  # xterm in normal mode
+  bindkey -M $keymap "\e\e[A" dirhistory_zle_dirhistory_up   # Putty
+  bindkey -M $keymap "\eO3A" dirhistory_zle_dirhistory_up    # GNU screen
+
+  case "$TERM_PROGRAM" in
+  Apple_Terminal) bindkey -M $keymap "^[[A" dirhistory_zle_dirhistory_up ;;  # Terminal.app
+  iTerm.app) bindkey -M $keymap "^[^[[A" dirhistory_zle_dirhistory_up ;;     # iTerm2
+  esac
+
+  if (( ${+terminfo[kcuu1]} )); then
+    bindkey -M $keymap "^[${terminfo[kcuu1]}" dirhistory_zle_dirhistory_up # urxvt
+  fi
+
+  # dirhistory_down
+  bindkey -M $keymap "\e[3B" dirhistory_zle_dirhistory_down    # xterm in normal mode
+  bindkey -M $keymap "\e[1;3B" dirhistory_zle_dirhistory_down  # xterm in normal mode
+  bindkey -M $keymap "\e\e[B" dirhistory_zle_dirhistory_down   # Putty
+  bindkey -M $keymap "\eO3B" dirhistory_zle_dirhistory_down    # GNU screen
+
+  case "$TERM_PROGRAM" in
+  Apple_Terminal) bindkey -M $keymap "^[[B" dirhistory_zle_dirhistory_down ;;  # Terminal.app
+  iTerm.app) bindkey -M $keymap "^[^[[B" dirhistory_zle_dirhistory_down ;;     # iTerm2
+  esac
+
+  if (( ${+terminfo[kcud1]} )); then
+    bindkey -M $keymap "^[${terminfo[kcud1]}" dirhistory_zle_dirhistory_down # urxvt
+  fi
+done
+
+unset keymap
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dirpersist/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dirpersist/README.md
new file mode 100644 (file)
index 0000000..792fb4b
--- /dev/null
@@ -0,0 +1,10 @@
+# Dirpersist plugin
+
+This plugin keeps a running tally of the previous 20 unique directories in the `$HOME/.zdirs` file.
+When you cd to a new directory, it is prepended to the beginning of the file.
+
+To use it, add `dirpersist` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... dirpersist)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dirpersist/dirpersist.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dirpersist/dirpersist.plugin.zsh
new file mode 100644 (file)
index 0000000..daadc38
--- /dev/null
@@ -0,0 +1,21 @@
+# Save dirstack history to .zdirs
+# adapted from:
+# github.com/grml/grml-etc-core/blob/master/etc/zsh/zshrc#L1547
+
+DIRSTACKSIZE=${DIRSTACKSIZE:-20}
+dirstack_file=${dirstack_file:-${HOME}/.zdirs}
+
+if [[ -f ${dirstack_file} ]] && [[ ${#dirstack[*]} -eq 0 ]] ; then
+  dirstack=( ${(f)"$(< $dirstack_file)"} )
+  # "cd -" won't work after login by just setting $OLDPWD, so
+  [[ -d $dirstack[1] ]] && cd $dirstack[1] && cd $OLDPWD
+fi
+
+autoload -U add-zsh-hook
+add-zsh-hook chpwd chpwd_dirpersist
+chpwd_dirpersist() {
+  if (( $DIRSTACKSIZE <= 0 )) || [[ -z $dirstack_file ]]; then return; fi
+  local -ax my_stack
+  my_stack=( ${PWD} ${dirstack} )
+  builtin print -l ${(u)my_stack} >! ${dirstack_file}
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dnf/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dnf/README.md
new file mode 100644 (file)
index 0000000..dc0d1e0
--- /dev/null
@@ -0,0 +1,29 @@
+# dnf plugin
+
+This plugin makes `dnf` usage easier by adding aliases for the most common commands.
+
+`dnf` is the new package manager for RPM-based distributions, which replaces `yum`.
+
+To use it, add `dnf` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... dnf)
+```
+
+## Aliases
+
+| Alias | Command                 | Description              |
+|-------|-------------------------|--------------------------|
+| dnfl  | `dnf list`              | List packages            |
+| dnfli | `dnf list installed`    | List installed packages  |
+| dnfgl | `dnf grouplist`         | List package groups      |
+| dnfmc | `dnf makecache`         | Generate metadata cache  |
+| dnfp  | `dnf info`              | Show package information |
+| dnfs  | `dnf search`            | Search package           |
+| **Use `sudo`**                                             |
+| dnfu  | `sudo dnf upgrade`      | Upgrade package          |
+| dnfi  | `sudo dnf install`      | Install package          |
+| dnfgi | `sudo dnf groupinstall` | Install package group    |
+| dnfr  | `sudo dnf remove`       | Remove package           |
+| dnfgr | `sudo dnf groupremove`  | Remove package group     |
+| dnfc  | `sudo dnf clean all`    | Clean cache              |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dnf/dnf.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dnf/dnf.plugin.zsh
new file mode 100644 (file)
index 0000000..653ce7d
--- /dev/null
@@ -0,0 +1,15 @@
+## Aliases
+
+alias dnfl="dnf list"                       # List packages
+alias dnfli="dnf list installed"            # List installed packages
+alias dnfgl="dnf grouplist"                 # List package groups
+alias dnfmc="dnf makecache"                 # Generate metadata cache
+alias dnfp="dnf info"                       # Show package information
+alias dnfs="dnf search"                     # Search package
+
+alias dnfu="sudo dnf upgrade"               # Upgrade package
+alias dnfi="sudo dnf install"               # Install package
+alias dnfgi="sudo dnf groupinstall"         # Install package group
+alias dnfr="sudo dnf remove"                # Remove package
+alias dnfgr="sudo dnf groupremove"          # Remove package group
+alias dnfc="sudo dnf clean all"             # Clean cache
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dnote/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dnote/README.md
new file mode 100644 (file)
index 0000000..7b41b90
--- /dev/null
@@ -0,0 +1,51 @@
+# Dnote Plugin
+
+This plugin adds auto-completion for [Dnote](https://www.getdnote.com/), a simple command line notebook.
+
+To use it, add `dnote` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(dnote)
+```
+
+## Usage
+
+At the basic level, this plugin completes all Dnote commands.
+
+```zsh
+$ dnote a(press <TAB> here)
+```
+
+would result in:
+
+```zsh
+$ dnote add
+```
+
+For some commands, this plugin dynamically suggests matching book names.
+
+For instance, if you have three books that begin with 'j': 'javascript', 'job', 'js',
+
+```zsh
+$ dnote view j(press <TAB> here)
+```
+
+would result in:
+
+```zsh
+$ dnote v j
+javascript  job         js
+```
+
+As another example,
+
+```zsh
+$ dnote edit ja(press <TAB> here)
+```
+
+would result in:
+
+
+```zsh
+$ dnote v javascript
+``````
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dnote/_dnote b/stow/oh-my-zsh/.oh-my-zsh/plugins/dnote/_dnote
new file mode 100644 (file)
index 0000000..c8b3348
--- /dev/null
@@ -0,0 +1,39 @@
+#compdef dnote
+
+local -a _1st_arguments
+
+_1st_arguments=(
+  'add:add a new note'
+  'view:list books, notes, or view a content'
+  'edit:edit a note or a book'
+  'remove:remove a note or a book'
+  'find:find notes by keywords'
+  'sync:sync data with the server'
+  'login:login to the dnote server'
+  'logout:logout from the dnote server'
+  'version:print the current version'
+  'help:get help about any command'
+)
+
+get_booknames() {
+  local names=$(dnote view --name-only)
+  local -a ret
+
+  while read -r line; do
+    ret+=("${line}")
+  done <<< "$names"
+
+  echo "$ret"
+}
+
+if (( CURRENT == 2 )); then
+  _describe -t commands "dnote subcommand" _1st_arguments
+  return
+elif (( CURRENT == 3 )); then
+  case "$words[2]" in
+    v|view|a|add)
+      _alternative \
+        "names:book names:($(get_booknames))"
+  esac
+fi
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/README.md
new file mode 100644 (file)
index 0000000..13f3c2c
--- /dev/null
@@ -0,0 +1,32 @@
+# Docker-compose
+
+This plugin provides completion for [docker-compose](https://docs.docker.com/compose/) as well as some
+aliases for frequent docker-compose commands.
+
+To use it, add docker-compose to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... docker-compose)
+```
+
+## Aliases
+
+| Alias     | Command                        | Description                                                      |
+|-----------|--------------------------------|------------------------------------------------------------------|
+| dco       | `docker-compose`               | Docker-compose main command                                      |
+| dcb       | `docker-compose build`         | Build containers                                                 |
+| dce       | `docker-compose exec`          | Execute command inside a container                               |
+| dcps      | `docker-compose ps`            | List containers                                                  |
+| dcrestart | `docker-compose restart`       | Restart container                                                |
+| dcrm      | `docker-compose rm`            | Remove container                                                 |
+| dcr       | `docker-compose run`           | Run a command in container                                       |
+| dcstop    | `docker-compose stop`          | Stop a container                                                 |
+| dcup      | `docker-compose up`            | Build, (re)create, start, and attach to containers for a service |
+| dcupb     | `docker-compose up --build`    | Same as `dcup`, but build images before starting containers      |
+| dcupd     | `docker-compose up -d`         | Same as `dcup`, but starts as daemon                             |
+| dcdn      | `docker-compose down`          | Stop and remove containers                                       |
+| dcl       | `docker-compose logs`          | Show logs of container                                           |
+| dclf      | `docker-compose logs -f`       | Show logs and follow output                                      |
+| dcpull    | `docker-compose pull`          | Pull image of a service                                          |
+| dcstart   | `docker-compose start`         | Start a container                                                |
+| dck       | `docker-compose kill`          | Kills containers                                                 |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/_docker-compose b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/_docker-compose
new file mode 100644 (file)
index 0000000..c6b7335
--- /dev/null
@@ -0,0 +1,421 @@
+#compdef docker-compose
+
+# Description
+# -----------
+#  zsh completion for docker-compose
+# -------------------------------------------------------------------------
+# Authors
+# -------
+#  * Steve Durrheimer <s.durrheimer@gmail.com>
+# -------------------------------------------------------------------------
+# Inspiration
+# -----------
+#  * @albers docker-compose bash completion script
+#  * @felixr docker zsh completion script : https://github.com/felixr/docker-zsh-completion
+# -------------------------------------------------------------------------
+
+__docker-compose_q() {
+    docker-compose 2>/dev/null $compose_options "$@"
+}
+
+# All services defined in docker-compose.yml
+__docker-compose_all_services_in_compose_file() {
+    local already_selected
+    local -a services
+    already_selected=$(echo $words | tr " " "|")
+    __docker-compose_q ps --services "$@" \
+        | grep -Ev "^(${already_selected})$"
+}
+
+# All services, even those without an existing container
+__docker-compose_services_all() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    services=$(__docker-compose_all_services_in_compose_file "$@")
+    _alternative "args:services:($services)" && ret=0
+
+    return ret
+}
+
+# All services that are defined by a Dockerfile reference
+__docker-compose_services_from_build() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker-compose_services_all --filter source=build
+}
+
+# All services that are defined by an image
+__docker-compose_services_from_image() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker-compose_services_all --filter source=image
+}
+
+__docker-compose_pausedservices() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker-compose_services_all --filter status=paused
+}
+
+__docker-compose_stoppedservices() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker-compose_services_all --filter status=stopped
+}
+
+__docker-compose_runningservices() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker-compose_services_all --filter status=running
+}
+
+__docker-compose_services() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker-compose_services_all
+}
+
+__docker-compose_caching_policy() {
+    oldp=( "$1"(Nmh+1) )            # 1 hour
+    (( $#oldp ))
+}
+
+__docker-compose_commands() {
+    local cache_policy
+
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __docker-compose_caching_policy
+    fi
+
+    if ( [[ ${+_docker_compose_subcommands} -eq 0 ]] || _cache_invalid docker_compose_subcommands) \
+        && ! _retrieve_cache docker_compose_subcommands;
+    then
+        local -a lines
+        lines=(${(f)"$(_call_program commands docker-compose 2>&1)"})
+        _docker_compose_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I)  *]}]}## #}/ ##/:})
+        (( $#_docker_compose_subcommands > 0 )) && _store_cache docker_compose_subcommands _docker_compose_subcommands
+    fi
+    _describe -t docker-compose-commands "docker-compose command" _docker_compose_subcommands
+}
+
+__docker-compose_subcommand() {
+    local opts_help opts_force_recreate opts_no_recreate opts_no_build opts_remove_orphans opts_timeout opts_no_color opts_no_deps
+
+    opts_help='(: -)--help[Print usage]'
+    opts_force_recreate="(--no-recreate)--force-recreate[Recreate containers even if their configuration and image haven't changed. Incompatible with --no-recreate.]"
+    opts_no_recreate="(--force-recreate)--no-recreate[If containers already exist, don't recreate them. Incompatible with --force-recreate.]"
+    opts_no_build="(--build)--no-build[Don't build an image, even if it's missing.]"
+    opts_remove_orphans="--remove-orphans[Remove containers for services not defined in the Compose file]"
+    opts_timeout=('(-t --timeout)'{-t,--timeout}"[Specify a shutdown timeout in seconds. (default: 10)]:seconds: ")
+    opts_no_color='--no-color[Produce monochrome output.]'
+    opts_no_deps="--no-deps[Don't start linked services.]"
+
+    integer ret=1
+
+    case "$words[1]" in
+        (build)
+            _arguments \
+                $opts_help \
+                "*--build-arg=[Set build-time variables for one service.]:<varname>=<value>: " \
+                '--force-rm[Always remove intermediate containers.]' \
+                '(--quiet -q)'{--quiet,-q}'[Curb build output]' \
+                '(--memory -m)'{--memory,-m}'[Memory limit for the build container.]' \
+                '--no-cache[Do not use cache when building the image.]' \
+                '--pull[Always attempt to pull a newer version of the image.]' \
+                '--compress[Compress the build context using gzip.]' \
+                '--parallel[Build images in parallel.]' \
+                '*:services:__docker-compose_services_from_build' && ret=0
+            ;;
+        (config)
+            _arguments \
+                $opts_help \
+                '(--quiet -q)'{--quiet,-q}"[Only validate the configuration, don't print anything.]" \
+                '--resolve-image-digests[Pin image tags to digests.]' \
+                '--services[Print the service names, one per line.]' \
+                '--volumes[Print the volume names, one per line.]' \
+                '--hash[Print the service config hash, one per line. Set "service1,service2" for a list of specified services.]' \ && ret=0
+            ;;
+        (create)
+            _arguments \
+                $opts_help \
+                $opts_force_recreate \
+                $opts_no_recreate \
+                $opts_no_build \
+                "(--no-build)--build[Build images before creating containers.]" \
+                '*:services:__docker-compose_services' && ret=0
+            ;;
+        (down)
+            _arguments \
+                $opts_help \
+                $opts_timeout \
+                "--rmi[Remove images. Type must be one of: 'all': Remove all images used by any service. 'local': Remove only images that don't have a custom tag set by the \`image\` field.]:type:(all local)" \
+                '(-v --volumes)'{-v,--volumes}"[Remove named volumes declared in the \`volumes\` section of the Compose file and anonymous volumes attached to containers.]" \
+                $opts_remove_orphans && ret=0
+            ;;
+        (events)
+            _arguments \
+                $opts_help \
+                '--json[Output events as a stream of json objects]' \
+                '*:services:__docker-compose_services' && ret=0
+            ;;
+        (exec)
+            _arguments \
+                $opts_help \
+                '-d[Detached mode: Run command in the background.]' \
+                '--privileged[Give extended privileges to the process.]' \
+                '(-u --user)'{-u,--user=}'[Run the command as this user.]:username:_users' \
+                '-T[Disable pseudo-tty allocation. By default `docker-compose exec` allocates a TTY.]' \
+                '--index=[Index of the container if there are multiple instances of a service \[default: 1\]]:index: ' \
+                '*'{-e,--env}'[KEY=VAL Set an environment variable (can be used multiple times)]:environment variable KEY=VAL: ' \
+                '(-w --workdir)'{-w,--workdir=}'[Working directory inside the container]:workdir: ' \
+                '(-):running services:__docker-compose_runningservices' \
+                '(-):command: _command_names -e' \
+                '*::arguments: _normal' && ret=0
+            ;;
+        (help)
+            _arguments ':subcommand:__docker-compose_commands' && ret=0
+            ;;
+    (images)
+        _arguments \
+        $opts_help \
+        '-q[Only display IDs]' \
+        '*:services:__docker-compose_services' && ret=0
+        ;;
+        (kill)
+            _arguments \
+                $opts_help \
+                '-s[SIGNAL to send to the container. Default signal is SIGKILL.]:signal:_signals' \
+                '*:running services:__docker-compose_runningservices' && ret=0
+            ;;
+        (logs)
+            _arguments \
+                $opts_help \
+                '(-f --follow)'{-f,--follow}'[Follow log output]' \
+                $opts_no_color \
+                '--tail=[Number of lines to show from the end of the logs for each container.]:number of lines: ' \
+                '(-t --timestamps)'{-t,--timestamps}'[Show timestamps]' \
+                '*:services:__docker-compose_services' && ret=0
+            ;;
+        (pause)
+            _arguments \
+                $opts_help \
+                '*:running services:__docker-compose_runningservices' && ret=0
+            ;;
+        (port)
+            _arguments \
+                $opts_help \
+                '--protocol=[tcp or udp \[default: tcp\]]:protocol:(tcp udp)' \
+                '--index=[index of the container if there are multiple instances of a service \[default: 1\]]:index: ' \
+                '1:running services:__docker-compose_runningservices' \
+                '2:port:_ports' && ret=0
+            ;;
+        (ps)
+            _arguments \
+                $opts_help \
+                '-q[Only display IDs]' \
+                '--filter KEY=VAL[Filter services by a property]:<filtername>=<value>:' \
+                '*:services:__docker-compose_services' && ret=0
+            ;;
+        (pull)
+            _arguments \
+                $opts_help \
+                '--ignore-pull-failures[Pull what it can and ignores images with pull failures.]' \
+                '--no-parallel[Disable parallel pulling]' \
+                '(-q --quiet)'{-q,--quiet}'[Pull without printing progress information]' \
+                '--include-deps[Also pull services declared as dependencies]' \
+                '*:services:__docker-compose_services_from_image' && ret=0
+            ;;
+        (push)
+            _arguments \
+                $opts_help \
+                '--ignore-push-failures[Push what it can and ignores images with push failures.]' \
+                '*:services:__docker-compose_services' && ret=0
+            ;;
+        (rm)
+            _arguments \
+                $opts_help \
+                '(-f --force)'{-f,--force}"[Don't ask to confirm removal]" \
+                '-v[Remove any anonymous volumes attached to containers]' \
+                '*:stopped services:__docker-compose_stoppedservices' && ret=0
+            ;;
+        (run)
+            _arguments \
+                $opts_help \
+                $opts_no_deps \
+                '-d[Detached mode: Run container in the background, print new container name.]' \
+                '*-e[KEY=VAL Set an environment variable (can be used multiple times)]:environment variable KEY=VAL: ' \
+                '*'{-l,--label}'[KEY=VAL Add or override a label (can be used multiple times)]:label KEY=VAL: ' \
+                '--entrypoint[Overwrite the entrypoint of the image.]:entry point: ' \
+                '--name=[Assign a name to the container]:name: ' \
+                '(-p --publish)'{-p,--publish=}"[Publish a container's port(s) to the host]" \
+                '--rm[Remove container after run. Ignored in detached mode.]' \
+                "--service-ports[Run command with the service's ports enabled and mapped to the host.]" \
+                '-T[Disable pseudo-tty allocation. By default `docker-compose run` allocates a TTY.]' \
+                '(-u --user)'{-u,--user=}'[Run as specified username or uid]:username or uid:_users' \
+                '(-v --volume)*'{-v,--volume=}'[Bind mount a volume]:volume: ' \
+                '(-w --workdir)'{-w,--workdir=}'[Working directory inside the container]:workdir: ' \
+                "--use-aliases[Use the services network aliases in the network(s) the container connects to]" \
+                '(-):services:__docker-compose_services' \
+                '(-):command: _command_names -e' \
+                '*::arguments: _normal' && ret=0
+            ;;
+        (scale)
+            _arguments \
+                $opts_help \
+                $opts_timeout \
+                '*:running services:__docker-compose_runningservices' && ret=0
+            ;;
+        (start)
+            _arguments \
+                $opts_help \
+                '*:stopped services:__docker-compose_stoppedservices' && ret=0
+            ;;
+        (stop|restart)
+            _arguments \
+                $opts_help \
+                $opts_timeout \
+                '*:running services:__docker-compose_runningservices' && ret=0
+            ;;
+        (top)
+            _arguments \
+                $opts_help \
+                '*:running services:__docker-compose_runningservices' && ret=0
+            ;;
+        (unpause)
+            _arguments \
+                $opts_help \
+                '*:paused services:__docker-compose_pausedservices' && ret=0
+            ;;
+        (up)
+            _arguments \
+                $opts_help \
+                '(--abort-on-container-exit)-d[Detached mode: Run containers in the background, print new container names. Incompatible with --abort-on-container-exit and --attach-dependencies.]' \
+                $opts_no_color \
+                $opts_no_deps \
+                $opts_force_recreate \
+                $opts_no_recreate \
+                $opts_no_build \
+                "(--no-build)--build[Build images before starting containers.]" \
+                "(-d)--abort-on-container-exit[Stops all containers if any container was stopped. Incompatible with -d.]" \
+                "(-d)--attach-dependencies[Attach to dependent containers. Incompatible with -d.]" \
+                '(-t --timeout)'{-t,--timeout}"[Use this timeout in seconds for container shutdown when attached or when containers are already running. (default: 10)]:seconds: " \
+                '--scale[SERVICE=NUM Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.]:service scale SERVICE=NUM: ' \
+                '--exit-code-from=[Return the exit code of the selected service container. Implies --abort-on-container-exit]:service:__docker-compose_services' \
+                $opts_remove_orphans \
+                '*:services:__docker-compose_services' && ret=0
+            ;;
+        (version)
+            _arguments \
+                $opts_help \
+                "--short[Shows only Compose's version number.]" && ret=0
+            ;;
+        (*)
+            _message 'Unknown sub command' && ret=1
+            ;;
+    esac
+
+    return ret
+}
+
+_docker-compose() {
+    # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
+    # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
+    if [[ $service != docker-compose ]]; then
+        _call_function - _$service
+        return
+    fi
+
+    local curcontext="$curcontext" state line
+    integer ret=1
+    typeset -A opt_args
+
+    local file_description
+
+    if [[ -n ${words[(r)-f]} || -n ${words[(r)--file]} ]] ; then
+        file_description="Specify an override docker-compose file (default: docker-compose.override.yml)"
+    else
+        file_description="Specify an alternate docker-compose file (default: docker-compose.yml)"
+    fi
+
+    _arguments -C \
+        '(- :)'{-h,--help}'[Get help]' \
+        '*'{-f,--file}"[${file_description}]:file:_files -g '*.yml'" \
+        '(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \
+        '--env-file[Specify an alternate environment file (default: .env)]:env-file:_files' \
+        "--compatibility[If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent]" \
+        '(- :)'{-v,--version}'[Print version and exit]' \
+        '--verbose[Show more output]' \
+        '--log-level=[Set log level]:level:(DEBUG INFO WARNING ERROR CRITICAL)' \
+        '--no-ansi[Do not print ANSI control characters]' \
+        '--ansi=[Control when to print ANSI control characters]:when:(never always auto)' \
+        '(-H --host)'{-H,--host}'[Daemon socket to connect to]:host:' \
+        '--tls[Use TLS; implied by --tlsverify]' \
+        '--tlscacert=[Trust certs signed only by this CA]:ca path:' \
+        '--tlscert=[Path to TLS certificate file]:client cert path:' \
+        '--tlskey=[Path to TLS key file]:tls key path:' \
+        '--tlsverify[Use TLS and verify the remote]' \
+        "--skip-hostname-check[Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address)]" \
+        '(-): :->command' \
+        '(-)*:: :->option-or-argument' && ret=0
+
+    local -a relevant_compose_flags relevant_compose_repeatable_flags relevant_docker_flags compose_options docker_options
+
+    relevant_compose_flags=(
+        "--env-file"
+        "--file" "-f"
+        "--host" "-H"
+        "--project-name" "-p"
+        "--tls"
+        "--tlscacert"
+        "--tlscert"
+        "--tlskey"
+        "--tlsverify"
+        "--skip-hostname-check"
+    )
+
+    relevant_compose_repeatable_flags=(
+        "--file" "-f"
+    )
+
+    relevant_docker_flags=(
+        "--host" "-H"
+        "--tls"
+        "--tlscacert"
+        "--tlscert"
+        "--tlskey"
+        "--tlsverify"
+    )
+
+    for k in "${(@k)opt_args}"; do
+        if [[ -n "${relevant_docker_flags[(r)$k]}" ]]; then
+            docker_options+=$k
+            if [[ -n "$opt_args[$k]" ]]; then
+                docker_options+=$opt_args[$k]
+            fi
+        fi
+        if [[ -n "${relevant_compose_flags[(r)$k]}" ]]; then
+            if [[ -n "${relevant_compose_repeatable_flags[(r)$k]}"  ]]; then
+                values=("${(@s/:/)opt_args[$k]}")
+                for value in $values
+                do
+                    compose_options+=$k
+                    compose_options+=$value
+                done
+            else
+                compose_options+=$k
+                if [[ -n "$opt_args[$k]" ]]; then
+                    compose_options+=$opt_args[$k]
+                fi
+            fi
+        fi
+    done
+
+    case $state in
+        (command)
+            __docker-compose_commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*:*}:docker-compose-$words[1]:
+            __docker-compose_subcommand && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+_docker-compose "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/docker-compose.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-compose/docker-compose.plugin.zsh
new file mode 100644 (file)
index 0000000..b8a4b06
--- /dev/null
@@ -0,0 +1,22 @@
+# support Compose v2 as docker CLI plugin
+(( ${+commands[docker-compose]} )) && dccmd='docker-compose' || dccmd='docker compose'
+
+alias dco="$dccmd"
+alias dcb="$dccmd build"
+alias dce="$dccmd exec"
+alias dcps="$dccmd ps"
+alias dcrestart="$dccmd restart"
+alias dcrm="$dccmd rm"
+alias dcr="$dccmd run"
+alias dcstop="$dccmd stop"
+alias dcup="$dccmd up"
+alias dcupb="$dccmd up --build"
+alias dcupd="$dccmd up -d"
+alias dcdn="$dccmd down"
+alias dcl="$dccmd logs"
+alias dclf="$dccmd logs -f"
+alias dcpull="$dccmd pull"
+alias dcstart="$dccmd start"
+alias dck="$dccmd kill"
+
+unset dccmd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/README.md
new file mode 100644 (file)
index 0000000..308a6cf
--- /dev/null
@@ -0,0 +1,19 @@
+# docker-machine plugin for oh my zsh
+
+### Usage
+
+#### docker-vm
+Will create a docker-machine with the name "dev" (required only once)
+To create a second machine call "docker-vm foobar" or pass any other name
+
+#### docker-up
+This will start your "dev" docker-machine (if necessary) and set it as the active one
+To start a named machine use "docker-up foobar"
+
+#### docker-switch dev
+Use this to activate a running docker-machine (or to switch between multiple machines)
+You need to call either this or docker-up when opening a new terminal
+
+#### docker-stop
+This will stop your "dev" docker-machine
+To stop a named machine use "docker-stop foobar"
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/_docker-machine b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/_docker-machine
new file mode 100644 (file)
index 0000000..fbd36d7
--- /dev/null
@@ -0,0 +1,359 @@
+#compdef docker-machine
+# Description
+# -----------
+#  zsh completion for docker-machine
+#  https://github.com/leonhartX/docker-machine-zsh-completion
+# -------------------------------------------------------------------------
+# Version
+# -------
+#  0.1.1
+# -------------------------------------------------------------------------
+# Authors
+# -------
+#  * Ke Xu <leonhartx.k@gmail.com>
+# -------------------------------------------------------------------------
+# Inspiration
+# -----------
+#  * @sdurrheimer docker-compose-zsh-completion https://github.com/sdurrheimer/docker-compose-zsh-completion
+#  * @ilkka _docker-machine
+
+
+__docker-machine_get_hosts() {
+    [[ $PREFIX = -* ]] && return 1
+    local state
+    declare -a hosts
+    state=$1; shift
+    if [[ $state != all ]]; then
+        hosts=(${(f)"$(_call_program commands docker-machine ls -q --filter state=$state)"})
+    else
+        hosts=(${(f)"$(_call_program commands docker-machine ls -q)"})
+    fi
+    _describe 'host' hosts "$@" && ret=0
+    return ret
+}
+
+__docker-machine_hosts_with_state() {
+    declare -a hosts
+    hosts=(${(f)"$(_call_program commands docker-machine ls -f '{{.Name}}\:{{.DriverName}}\({{.State}}\)\ {{.URL}}')"})
+    _describe 'host' hosts
+}
+
+__docker-machine_hosts_all() {
+    __docker-machine_get_hosts all "$@"
+}
+
+__docker-machine_hosts_running() {
+    __docker-machine_get_hosts Running "$@"
+}
+
+__docker-machine_get_swarm() {
+    declare -a swarms
+    swarms=(${(f)"$(_call_program commands docker-machine ls -f {{.Swarm}} | awk '{print $1}')"})
+    _describe 'swarm' swarms
+}
+
+__docker-machine_hosts_and_files() {
+    _alternative "hosts:host:__docker-machine_hosts_all -qS ':'" 'files:files:_path_files'
+}
+
+__docker-machine_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (driver)
+                _describe -t driver-filter-opts "driver filter" opts_driver && ret=0
+                ;;
+            (swarm)
+                __docker-machine_get_swarm && ret=0
+                ;;
+            (state)
+                opts_state=('Running' 'Paused' 'Saved' 'Stopped' 'Stopping' 'Starting' 'Error')
+                _describe -t state-filter-opts "state filter" opts_state && ret=0
+                ;;
+            (name)
+                __docker-machine_hosts_all && ret=0
+                ;;
+            (label)
+                _message 'label' && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('driver' 'swarm' 'state' 'name' 'label')
+        _describe -t filter-opts "filter" opts -qS "=" && ret=0
+    fi
+    return ret
+}
+
+__get_swarm_discovery() {
+    declare -a masters services
+    local service
+    services=()
+    masters=($(docker-machine ls -f {{.Swarm}} |grep '(master)' |awk '{print $1}'))
+    for master in $masters; do
+         service=${${${(f)"$(_call_program commands docker-machine inspect -f '{{.HostOptions.SwarmOptions.Discovery}}:{{.Name}}' $master)"}/:/\\:}}
+         services=($services $service)
+    done
+    _describe -t services "swarm service" services && ret=0
+    return ret
+}
+
+__get_create_argument() {
+    typeset -g docker_machine_driver
+    if [[ CURRENT -le 2 ]]; then
+        docker_machine_driver="none"
+    elif [[ CURRENT > 2 && $words[CURRENT-2] = '-d' || $words[CURRENT-2] = '--driver' ]]; then
+        docker_machine_driver=$words[CURRENT-1]
+    elif [[ $words[CURRENT-1] =~ '^(-d|--driver)=' ]]; then
+        docker_machine_driver=${${words[CURRENT-1]}/*=/}
+    fi
+    local driver_opt_cmd
+    local -a opts_provider opts_common opts_read_argument
+    opts_read_argument=(
+        ": :->argument"
+    )
+    opts_common=(
+        $opts_help \
+        '(--driver -d)'{--driver=,-d=}'[Driver to create machine with]:dirver:->driver-option' \
+        '--engine-install-url=[Custom URL to use for engine installation]:url' \
+        '*--engine-opt=[Specify arbitrary flags to include with the created engine in the form flag=value]:flag' \
+        '*--engine-insecure-registry=[Specify insecure registries to allow with the created engine]:registry' \
+        '*--engine-registry-mirror=[Specify registry mirrors to use]:mirror' \
+        '*--engine-label=[Specify labels for the created engine]:label' \
+        '--engine-storage-driver=[Specify a storage driver to use with the engine]:storage-driver:->storage-driver-option' \
+        '*--engine-env=[Specify environment variables to set in the engine]:environment' \
+        '--swarm[Configure Machine with Swarm]' \
+        '--swarm-image=[Specify Docker image to use for Swarm]:image' \
+        '--swarm-master[Configure Machine to be a Swarm master]' \
+        '--swarm-discovery=[Discovery service to use with Swarm]:service:->swarm-service' \
+        '--swarm-strategy=[Define a default scheduling strategy for Swarm]:strategy:(spread binpack random)' \
+        '*--swarm-opt=[Define arbitrary flags for swarm]:flag' \
+        '*--swarm-join-opt=[Define arbitrary flags for Swarm join]:flag' \
+        '--swarm-host=[ip/socket to listen on for Swarm master]:host' \
+        '--swarm-addr=[addr to advertise for Swarm (default: detect and use the machine IP)]:address' \
+        '--swarm-experimental[Enable Swarm experimental features]' \
+        '*--tls-san=[Support extra SANs for TLS certs]:option'
+    )
+    driver_opt_cmd="docker-machine create -d $docker_machine_driver | grep $docker_machine_driver | sed -e 's/\(--.*\)\ *\[\1[^]]*\]/*\1/g' -e 's/\(\[[^]]*\)/\\\\\\1\\\\/g' -e 's/\".*\"\(.*\)/\1/g' | awk '{printf \"%s[\", \$1; for(i=2;i<=NF;i++) {printf \"%s \", \$i}; print \"]\"}'"
+    if [[ $docker_machine_driver != "none" ]]; then
+        opts_provider=(${(f)"$(_call_program commands $driver_opt_cmd)"})
+        _arguments \
+            $opts_provider \
+            $opts_read_argument \
+            $opts_common && ret=0
+    else
+        _arguments $opts_common && ret=0
+    fi
+    case $state in
+        (driver-option)
+            _describe -t driver-option "driver" opts_driver && ret=0
+            ;;
+        (storage-driver-option)
+            _describe -t storage-driver-option "storage driver" opts_storage_driver && ret=0
+            ;;
+        (swarm-service)
+            __get_swarm_discovery && ret=0
+            ;;
+        (argument)
+            ret=0
+            ;;
+    esac
+    return ret
+}
+
+
+__docker-machine_subcommand() {
+    local -a opts_help
+    opts_help=("(- :)--help[Print usage]")
+    local -a opts_only_host opts_driver opts_storage_driver opts_state
+    opts_only_host=(
+        "$opts_help"
+        "*:host:__docker-machine_hosts_all"
+    )
+    opts_driver=('amazonec2' 'azure' 'digitalocean' 'exoscale' 'generic' 'google' 'hyperv' 'none' 'openstack' 'rackspace' 'softlayer' 'virtualbox' 'vmwarefusion' 'vmwarevcloudair' 'vmwarevsphere')
+    opts_storage_driver=('overlay' 'aufs' 'btrfs' 'devicemapper' 'vfs' 'zfs')
+    integer ret=1
+
+    case "$words[1]" in
+        (active)
+            _arguments \
+                $opts_help \
+                '(--timeout -t)'{--timeout=,-t=}'[Timeout in seconds, default to 10s]:seconds' && ret=0
+            ;;
+        (config)
+            _arguments \
+                $opts_help \
+                '--swarm[Display the Swarm config instead of the Docker daemon]' \
+                "*:host:__docker-machine_hosts_all" && ret=0
+            ;;
+        (create)
+            __get_create_argument
+           ;;
+        (env)
+            _arguments \
+                $opts_help \
+                '--swarm[Display the Swarm config instead of the Docker daemon]' \
+                '--shell=[Force environment to be configured for a specified shell: \[fish, cmd, powershell\], default is auto-detect]:shell' \
+                '(--unset -u)'{--unset,-u}'[Unset variables instead of setting them]' \
+                '--no-proxy[Add machine IP to NO_PROXY environment variable]' \
+                '*:host:__docker-machine_hosts_running' && ret=0
+            ;;
+        (help)
+            _arguments ':subcommand:__docker-machine_commands' && ret=0
+            ;;
+        (inspect)
+            _arguments \
+                $opts_help \
+                '(--format -f)'{--format=,-f=}'[Format the output using the given go template]:template' \
+                '*:host:__docker-machine_hosts_all' && ret=0
+            ;;
+        (ip)
+            _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_running' && ret=0
+            ;;
+        (kill)
+             _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_with_state' && ret=0
+            ;;
+        (ls)
+            _arguments \
+                $opts_help \
+                '(--quiet -q)'{--quiet,-q}'[Enable quiet mode]' \
+                '*--filter=[Filter output based on conditions provided]:filter:->filter-options' \
+                '(--timeout -t)'{--timeout=,-t=}'[Timeout in seconds, default to 10s]:seconds' \
+                '(--format -f)'{--format=,-f=}'[Pretty-print machines using a Go template]:template' && ret=0
+            case $state in
+                (filter-options)
+                    __docker-machine_filters && ret=0
+                    ;;
+            esac
+            ;;
+        (provision)
+            _arguments $opts_only_host && ret=0
+            ;;
+        (regenerate-certs)
+            _arguments \
+                $opts_help \
+                '(--force -f)'{--force,-f}'[Force rebuild and do not prompt]' \
+                '*:host:__docker-machine_hosts_all' && ret=0
+            ;;
+        (restart)
+            _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_with_state' && ret=0
+            ;;
+        (rm)
+            _arguments \
+                $opts_help \
+                '(--force -f)'{--force,-f}'[Remove local configuration even if machine cannot be removed, also implies an automatic yes (`-y`)]' \
+                '-y[Assumes automatic yes to proceed with remove, without prompting further user confirmation]' \
+                '*:host:__docker-machine_hosts_with_state' && ret=0
+            ;;
+        (scp)
+            _arguments \
+                $opts_help \
+                '(--recursive -r)'{--recursive,-r}'[Copy files recursively (required to copy directories))]' \
+                '*:files:__docker-machine_hosts_and_files' && ret=0
+            ;;
+        (ssh)
+            _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_running' && ret=0
+            ;;
+        (start)
+            _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_with_state' && ret=0
+            ;;
+        (status)
+            _arguments $opts_only_host && ret=0
+            ;;
+        (stop)
+            _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_with_state' && ret=0
+            ;;
+        (upgrade)
+            _arguments $opts_only_host && ret=0
+            ;;
+        (url)
+            _arguments \
+                $opts_help \
+                '*:host:__docker-machine_hosts_running' && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+
+__docker-machine_commands() {
+    local cache_policy
+
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __docker-machine_caching_policy
+    fi
+
+    if ( [[ ${+_docker_machine_subcommands} -eq 0 ]] || _cache_invalid docker_machine_subcommands) \
+        && ! _retrieve_cache docker_machine_subcommands;
+    then
+        local -a lines
+        lines=(${(f)"$(_call_program commands docker-machine 2>&1)"})
+        _docker_machine_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I)  *]}]}## #}/$'\t'##/:})
+        (( $#_docker_machine_subcommands > 0 )) && _store_cache docker_machine_subcommands _docker_machine_subcommands
+    fi
+    _describe -t docker-machine-commands "docker-machine command" _docker_machine_subcommands
+}
+
+__docker-machine_caching_policy() {
+    oldp=( "$1"(Nmh+1) )
+    (( $#oldp ))
+}
+
+_docker-machine() {
+    if [[ $service != docker-machine ]]; then
+        _call_function - _$service
+        return
+    fi
+
+    local curcontext="$curcontext" state line
+    integer ret=1
+    typeset -A opt_args
+
+    _arguments -C \
+        "(- :)"{-h,--help}"[Show help]" \
+        "(-D --debug)"{-D,--debug}"[Enable debug mode]" \
+        '(-s --storage-path)'{-s,--storage-path}'[Configures storage path]:file:_files' \
+        '--tls-ca-cert[CA to verify remotes against]:file:_files' \
+        '--tls-ca-key[Private key to generate certificates]:file:_files' \
+        '--tls-client-cert[Client cert to use for TLS]:file:_files' \
+        '--tls-client-key[Private key used in client TLS auth]:file:_files' \
+        '--github-api-token[Token to use for requests to the Github API]' \
+        '--native-ssh[Use the native (Go-based) SSH implementation.]' \
+        '--bugsnag-api-token[BugSnag API token for crash reporting]' \
+        '(- :)'{-v,--version}'[Print the version]' \
+        "(-): :->command" \
+        "(-)*:: :->option-or-argument" && ret=0
+
+    case $state in
+        (command)
+            __docker-machine_commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*:*}:docker-machine-$words[1]:
+            __docker-machine_subcommand && ret=0
+            ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+_docker-machine "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/docker-machine.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker-machine/docker-machine.plugin.zsh
new file mode 100644 (file)
index 0000000..235d90e
--- /dev/null
@@ -0,0 +1,33 @@
+DEFAULT_MACHINE="default"
+
+docker-up() {
+    if [ -z "$1" ]
+    then
+        docker-machine start "${DEFAULT_MACHINE}"
+        eval $(docker-machine env "${DEFAULT_MACHINE}")
+    else
+        docker-machine start $1
+        eval $(docker-machine env $1)
+    fi
+    echo $DOCKER_HOST
+}
+docker-stop() {
+    if [ -z "$1" ]
+    then
+        docker-machine stop "${DEFAULT_MACHINE}"
+    else
+        docker-machine stop $1
+    fi
+}
+docker-switch() {
+    eval $(docker-machine env $1)
+    echo $DOCKER_HOST
+}
+docker-vm() {
+    if [ -z "$1" ]
+    then
+        docker-machine create -d virtualbox --virtualbox-disk-size 20000 --virtualbox-memory 4096 --virtualbox-cpu-count 2 "${DEFAULT_MACHINE}"
+    else
+        docker-machine create -d virtualbox --virtualbox-disk-size 20000 --virtualbox-memory 4096 --virtualbox-cpu-count 2 $1
+    fi
+}
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker/README.md
new file mode 100644 (file)
index 0000000..606690f
--- /dev/null
@@ -0,0 +1,73 @@
+# Docker plugin
+
+This plugin adds auto-completion and aliases for [docker](https://www.docker.com/).
+
+To use it add `docker` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... docker)
+```
+
+A copy of the completion script from the docker/cli git repo:
+https://github.com/docker/cli/blob/master/contrib/completion/zsh/_docker
+
+## Settings
+
+By default, the completion doesn't allow option-stacking, meaning if you try to
+complete `docker run -it <TAB>` it won't work, because you're _stacking_ the
+`-i` and `-t` options.
+
+[You can enable it](https://github.com/docker/cli/commit/b10fb43048) by **adding
+the lines below to your zshrc file**, but be aware of the side effects:
+
+> This enables Zsh to understand commands like `docker run -it
+> ubuntu`. However, by enabling this, this also makes Zsh complete
+> `docker run -u<tab>` with `docker run -uapprox` which is not valid. The
+> users have to put the space or the equal sign themselves before trying
+> to complete.
+>
+> Therefore, this behavior is disabled by default. To enable it:
+>
+> ```sh
+> zstyle ':completion:*:*:docker:*' option-stacking yes
+> zstyle ':completion:*:*:docker-*:*' option-stacking yes
+> ```
+
+## Aliases
+
+| Alias   | Command                     | Description                                                                              |
+| :------ | :-------------------------- | :--------------------------------------------------------------------------------------- |
+| dbl     | `docker build`              | Build an image from a Dockerfile                                                         |
+| dcin    | `docker container inspect`  | Display detailed information on one or more containers                                   |
+| dlo     | `docker container logs`     | Fetch the logs of a docker container                                                     |
+| dcls     | `docker container ls`       | List all the running docker containers                                                   |
+| dclsa    | `docker container ls -a`    | List all running and stopped containers                                                  |
+| dpo     | `docker container port`     | List port mappings or a specific mapping for the container                               |
+| dpu     | `docker pull`               | Pull an image or a repository from a registry                                            |
+| dr      | `docker container run`      | Create a new container and start it using the specified command                          |
+| drit    | `docker container run -it`  | Create a new container and start it in an interactive shell                              |
+| drm     | `docker container rm`       | Remove the specified container(s)                                                        |
+| drm!    | `docker container rm -f`    | Force the removal of a running container (uses SIGKILL)                                  |
+| dst     | `docker container start`    | Start one or more stopped containers                                                     |
+| dstp    | `docker container stop`     | Stop one or more running containers                                                      |
+| dtop    | `docker top`                | Display the running processes of a container                                             |
+| dxc     | `docker container exec`     | Run a new command in a running container                                                 |
+| dxcit   | `docker container exec -it` | Run a new command in a running container in an interactive shell                         |
+|         |                             | **Docker Images**                                                                        |
+| dib     | `docker image build`        | Build an image from a Dockerfile (same as docker build)                                  |
+| dii     | `docker image inspect`      | Display detailed information on one or more images                                       |
+| dils    | `docker image ls`           | List docker images                                                                       |
+| dipu     | `docker image push`         | Push an image or repository to a remote registry                                         |
+| dirm    | `docker image rm`           | Remove one or more images                                                                |
+| dit     | `docker image tag`          | Add a name and tag to a particular image                                                 |
+|         |                             | **Docker Network**                                                                       |
+| dnc     | `docker network create`     | Create a new network                                                                     |
+| dncn    | `docker network connect`    | Connect a container to a network                                                         |
+| dndcn   | `docker network disconnect` | Disconnect a container from a network                                                    |
+| dni     | `docker network inspect`    | Return information about one or more networks                                            |
+| dnls    | `docker network ls`         | List all networks the engine daemon knows about, including those spanning multiple hosts |
+| dnrm    | `docker network rm`         | Remove one or more networks                                                              |
+|         |                             | **Docker Volume**                                                                        |
+| dvi     | `docker volume inspect`     | Display detailed information about one or more volumes                                   |
+| dvls    | `docker volume ls`          | List all the volumes known to  docker                                                    |
+| dvprune | `docker volume prune`       | Cleanup dangling volumes                                                                 |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker/_docker b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker/_docker
new file mode 100644 (file)
index 0000000..8ee35ab
--- /dev/null
@@ -0,0 +1,3143 @@
+#compdef docker dockerd
+#
+# zsh completion for docker (http://docker.com)
+#
+# version:  0.3.0
+# github:   https://github.com/felixr/docker-zsh-completion
+#
+# contributors:
+#   - Felix Riedel
+#   - Steve Durrheimer
+#   - Vincent Bernat
+#   - Rohan Verma
+#
+# license:
+#
+# Copyright (c) 2013, Felix Riedel
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Short-option stacking can be enabled with:
+#  zstyle ':completion:*:*:docker:*' option-stacking yes
+#  zstyle ':completion:*:*:docker-*:*' option-stacking yes
+__docker_arguments() {
+    if zstyle -t ":completion:${curcontext}:" option-stacking; then
+        print -- -s
+    fi
+}
+
+__docker_get_containers() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local kind type line s
+    declare -a running stopped lines args names
+
+    kind=$1; shift
+    type=$1; shift
+    [[ $kind = (stopped|all) ]] && args=($args -a)
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options ps --format 'table' --no-trunc $args)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1 # Last column, should go to the end of the line
+    lines=(${lines[2,-1]})
+
+    # Container ID
+    if [[ $type = (ids|all) ]]; then
+        for line in $lines; do
+            s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}"
+            s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
+            s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
+            if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = (Exit*|Created*) ]]; then
+                stopped=($stopped $s)
+            else
+                running=($running $s)
+            fi
+        done
+    fi
+
+    # Names: we only display the one without slash. All other names
+    # are generated and may clutter the completion. However, with
+    # Swarm, all names may be prefixed by the swarm node name.
+    if [[ $type = (names|all) ]]; then
+        for line in $lines; do
+            names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}})
+            # First step: find a common prefix and strip it (swarm node case)
+            (( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/}
+            # Second step: only keep the first name without a /
+            s=${${names:#*/*}[1]}
+            # If no name, well give up.
+            (( $#s != 0 )) || continue
+            s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
+            s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
+            if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = (Exit*|Created*) ]]; then
+                stopped=($stopped $s)
+            else
+                running=($running $s)
+            fi
+        done
+    fi
+
+    [[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running "$@" && ret=0
+    [[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped "$@" && ret=0
+    return ret
+}
+
+__docker_complete_stopped_containers() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_containers stopped all "$@"
+}
+
+__docker_complete_running_containers() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_containers running all "$@"
+}
+
+__docker_complete_containers() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_containers all all "$@"
+}
+
+__docker_complete_containers_ids() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_containers all ids "$@"
+}
+
+__docker_complete_containers_names() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_containers all names "$@"
+}
+
+__docker_complete_info_plugins() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    emulate -L zsh
+    setopt extendedglob
+    local -a plugins
+    plugins=(${(ps: :)${(M)${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'Plugins:}%%$'\n'^ *}}:# $1: *}## $1: })
+    _describe -t plugins "$1 plugins" plugins && ret=0
+    return ret
+}
+
+__docker_complete_images() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a images
+    images=(${${${(f)${:-"$(_call_program commands docker $docker_options images)"$'\n'}}[2,-1]}/(#b)([^ ]##) ##([^ ]##) ##([^ ]##)*/${match[3]}:${(r:15:: :::)match[2]} in ${match[1]}})
+    _describe -t docker-images "images" images && ret=0
+    __docker_complete_repositories_with_tags && ret=0
+    return ret
+}
+
+__docker_complete_repositories() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a repos
+    repos=(${${${(f)${:-"$(_call_program commands docker $docker_options images)"$'\n'}}%% *}[2,-1]})
+    repos=(${repos#<none>})
+    _describe -t docker-repos "repositories" repos && ret=0
+    return ret
+}
+
+__docker_complete_repositories_with_tags() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a repos onlyrepos matched
+    declare m
+    repos=(${${${${(f)${:-"$(_call_program commands docker $docker_options images)"$'\n'}}[2,-1]}/ ##/:::}%% *})
+    repos=(${${repos%:::<none>}#<none>})
+    # Check if we have a prefix-match for the current prefix.
+    onlyrepos=(${repos%::*})
+    for m in $onlyrepos; do
+        [[ ${PREFIX##${~~m}} != ${PREFIX} ]] && {
+            # Yes, complete with tags
+            repos=(${${repos/:::/:}/:/\\:})
+            _describe -t docker-repos-with-tags "repositories with tags" repos && ret=0
+            return ret
+        }
+    done
+    # No, only complete repositories
+    onlyrepos=(${${repos%:::*}/:/\\:})
+    _describe -t docker-repos "repositories" onlyrepos -qS : && ret=0
+
+    return ret
+}
+
+__docker_search() {
+    [[ $PREFIX = -* ]] && return 1
+    local cache_policy
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
+    fi
+
+    local searchterm cachename
+    searchterm="${words[$CURRENT]%/}"
+    cachename=_docker-search-$searchterm
+
+    local expl
+    local -a result
+    if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
+        && ! _retrieve_cache ${cachename#_}; then
+        _message "Searching for ${searchterm}..."
+        result=(${${${(f)${:-"$(_call_program commands docker $docker_options search $searchterm)"$'\n'}}%% *}[2,-1]})
+        _store_cache ${cachename#_} result
+    fi
+    _wanted dockersearch expl 'available images' compadd -a result
+}
+
+__docker_get_log_options() {
+    [[ $PREFIX = -* ]] && return 1
+
+    integer ret=1
+    local log_driver=${opt_args[--log-driver]:-"all"}
+    local -a common_options common_options2 awslogs_options fluentd_options gelf_options journald_options json_file_options logentries_options syslog_options splunk_options
+
+    common_options=("max-buffer-size" "mode")
+    common_options2=("env" "env-regex" "labels")
+    awslogs_options=($common_options "awslogs-create-group" "awslogs-datetime-format" "awslogs-group" "awslogs-multiline-pattern" "awslogs-region" "awslogs-stream" "tag")
+    fluentd_options=($common_options $common_options2 "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "fluentd-sub-second-precision" "tag")
+    gcplogs_options=($common_options $common_options2 "gcp-log-cmd" "gcp-meta-id" "gcp-meta-name" "gcp-meta-zone" "gcp-project")
+    gelf_options=($common_options $common_options2 "gelf-address" "gelf-compression-level" "gelf-compression-type" "tag")
+    journald_options=($common_options $common_options2 "tag")
+    json_file_options=($common_options $common_options2 "max-file" "max-size")
+    logentries_options=($common_options $common_options2 "logentries-token" "tag")
+    syslog_options=($common_options $common_options2 "syslog-address" "syslog-facility" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "tag")
+    splunk_options=($common_options $common_options2 "splunk-caname" "splunk-capath" "splunk-format" "splunk-gzip" "splunk-gzip-level" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "splunk-verify-connection" "tag")
+
+    [[ $log_driver = (awslogs|all) ]] && _describe -t awslogs-options "awslogs options" awslogs_options "$@" && ret=0
+    [[ $log_driver = (fluentd|all) ]] && _describe -t fluentd-options "fluentd options" fluentd_options "$@" && ret=0
+    [[ $log_driver = (gcplogs|all) ]] && _describe -t gcplogs-options "gcplogs options" gcplogs_options "$@" && ret=0
+    [[ $log_driver = (gelf|all) ]] && _describe -t gelf-options "gelf options" gelf_options "$@" && ret=0
+    [[ $log_driver = (journald|all) ]] && _describe -t journald-options "journald options" journald_options "$@" && ret=0
+    [[ $log_driver = (json-file|all) ]] && _describe -t json-file-options "json-file options" json_file_options "$@" && ret=0
+    [[ $log_driver = (logentries|all) ]] && _describe -t logentries-options "logentries options" logentries_options "$@" && ret=0
+    [[ $log_driver = (syslog|all) ]] && _describe -t syslog-options "syslog options" syslog_options "$@" && ret=0
+    [[ $log_driver = (splunk|all) ]] && _describe -t splunk-options "splunk options" splunk_options "$@" && ret=0
+
+    return ret
+}
+
+__docker_complete_log_drivers() {
+    [[ $PREFIX = -*  ]] && return 1
+    integer ret=1
+    drivers=(awslogs etwlogs fluentd gcplogs gelf journald json-file none splunk syslog)
+    _describe -t log-drivers "log drivers" drivers && ret=0
+    return ret
+}
+
+__docker_complete_log_options() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (syslog-format)
+                local opts=('rfc3164' 'rfc5424' 'rfc5424micro')
+                _describe -t syslog-format-opts "syslog format options" opts && ret=0
+                ;;
+            (mode)
+                local opts=('blocking' 'non-blocking')
+                _describe -t mode-opts "mode options" opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        __docker_get_log_options -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_detach_keys() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    compset -P "*,"
+    keys=(${:-{a-z}})
+    ctrl_keys=(${:-ctrl-{{a-z},{@,'[','\\','^',']',_}}})
+    _describe -t detach_keys "[a-z]" keys -qS "," && ret=0
+    _describe -t detach_keys-ctrl "'ctrl-' + 'a-z @ [ \\\\ ] ^ _'" ctrl_keys -qS "," && ret=0
+}
+
+__docker_complete_pid() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local -a opts vopts
+
+    opts=('host')
+    vopts=('container')
+
+    if compset -P '*:'; then
+        case "${${words[-1]%:*}#*=}" in
+            (container)
+                __docker_complete_running_containers && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        _describe -t pid-value-opts "PID Options with value" vopts -qS ":" && ret=0
+        _describe -t pid-opts "PID Options" opts && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_runtimes() {
+    [[ $PREFIX = -*  ]] && return 1
+    integer ret=1
+
+    emulate -L zsh
+    setopt extendedglob
+    local -a runtimes_opts
+    runtimes_opts=(${(ps: :)${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'Runtimes: }%%$'\n'^ *}}})
+    _describe -t runtimes-opts "runtimes options" runtimes_opts && ret=0
+}
+
+__docker_complete_ps_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (ancestor)
+                __docker_complete_images && ret=0
+                ;;
+            (before|since)
+                __docker_complete_containers && ret=0
+                ;;
+            (health)
+                health_opts=('healthy' 'none' 'starting' 'unhealthy')
+                _describe -t health-filter-opts "health filter options" health_opts && ret=0
+                ;;
+            (id)
+                __docker_complete_containers_ids && ret=0
+                ;;
+            (is-task)
+                _describe -t boolean-filter-opts "filter options" boolean_opts && ret=0
+                ;;
+            (name)
+                __docker_complete_containers_names && ret=0
+                ;;
+            (network)
+                __docker_complete_networks && ret=0
+                ;;
+            (status)
+                status_opts=('created' 'dead' 'exited' 'paused' 'restarting' 'running' 'removing')
+                _describe -t status-filter-opts "status filter options" status_opts && ret=0
+                ;;
+            (volume)
+                __docker_complete_volumes && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('ancestor' 'before' 'exited' 'expose' 'health' 'id' 'label' 'name' 'network' 'publish' 'since' 'status' 'volume')
+        _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_search_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a boolean_opts opts
+
+    boolean_opts=('true' 'false')
+    opts=('is-automated' 'is-official' 'stars')
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (is-automated|is-official)
+                _describe -t boolean-filter-opts "filter options" boolean_opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_images_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a boolean_opts opts
+
+    boolean_opts=('true' 'false')
+    opts=('before' 'dangling' 'label' 'reference' 'since')
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (before|reference|since)
+                __docker_complete_images && ret=0
+                ;;
+            (dangling)
+                _describe -t boolean-filter-opts "filter options" boolean_opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_events_filter() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a opts
+
+    opts=('container' 'daemon' 'event' 'image' 'label' 'network' 'scope' 'type' 'volume')
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (container)
+                __docker_complete_containers && ret=0
+                ;;
+            (daemon)
+                emulate -L zsh
+                setopt extendedglob
+                local -a daemon_opts
+                daemon_opts=(
+                    ${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'Name: }%%$'\n'^ *}}
+                    ${${(f)${${"$(_call_program commands docker $docker_options info)"##*$'\n'ID: }%%$'\n'^ *}}//:/\\:}
+                )
+                _describe -t daemon-filter-opts "daemon filter options" daemon_opts && ret=0
+                ;;
+            (event)
+                local -a event_opts
+                event_opts=('attach' 'commit' 'connect' 'copy' 'create' 'delete' 'destroy' 'detach' 'die' 'disable' 'disconnect' 'enable' 'exec_create' 'exec_detach'
+                'exec_start' 'export' 'health_status' 'import' 'install' 'kill' 'load'  'mount' 'oom' 'pause' 'pull' 'push' 'reload' 'remove' 'rename' 'resize'
+                'restart' 'save' 'start' 'stop' 'tag' 'top' 'unmount' 'unpause' 'untag' 'update')
+                _describe -t event-filter-opts "event filter options" event_opts && ret=0
+                ;;
+            (image)
+                __docker_complete_images && ret=0
+                ;;
+            (network)
+                __docker_complete_networks && ret=0
+                ;;
+            (scope)
+                local -a scope_opts
+                scope_opts=('local' 'swarm')
+                _describe -t scope-filter-opts "scope filter options" scope_opts && ret=0
+                ;;
+            (type)
+                local -a type_opts
+                type_opts=('container' 'daemon' 'image' 'network' 'volume')
+                _describe -t type-filter-opts "type filter options" type_opts && ret=0
+                ;;
+            (volume)
+                __docker_complete_volumes && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_prune_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a opts
+
+    opts=('until')
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+# BO checkpoint
+
+__docker_checkpoint_commands() {
+    local -a _docker_checkpoint_subcommands
+    _docker_checkpoint_subcommands=(
+        "create:Create a checkpoint from a running container"
+        "ls:List checkpoints for a container"
+        "rm:Remove a checkpoint"
+    )
+    _describe -t docker-checkpoint-commands "docker checkpoint command" _docker_checkpoint_subcommands
+}
+
+__docker_checkpoint_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (create)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--checkpoint-dir=[Use a custom checkpoint storage directory]:dir:_directories" \
+                "($help)--leave-running[Leave the container running after checkpoint]" \
+                "($help -)1:container:__docker_complete_running_containers" \
+                "($help -)2:checkpoint: " && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--checkpoint-dir=[Use a custom checkpoint storage directory]:dir:_directories" \
+                "($help -)1:container:__docker_complete_containers" && ret=0
+            ;;
+        (rm|remove)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--checkpoint-dir=[Use a custom checkpoint storage directory]:dir:_directories" \
+                "($help -)1:container:__docker_complete_containers" \
+                "($help -)2:checkpoint: " && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_checkpoint_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO checkpoint
+
+# BO container
+
+__docker_container_commands() {
+    local -a _docker_container_subcommands
+    _docker_container_subcommands=(
+        "attach:Attach to a running container"
+        "commit:Create a new image from a container's changes"
+        "cp:Copy files/folders between a container and the local filesystem"
+        "create:Create a new container"
+        "diff:Inspect changes on a container's filesystem"
+        "exec:Run a command in a running container"
+        "export:Export a container's filesystem as a tar archive"
+        "inspect:Display detailed information on one or more containers"
+        "kill:Kill one or more running containers"
+        "logs:Fetch the logs of a container"
+        "ls:List containers"
+        "pause:Pause all processes within one or more containers"
+        "port:List port mappings or a specific mapping for the container"
+        "prune:Remove all stopped containers"
+        "rename:Rename a container"
+        "restart:Restart one or more containers"
+        "rm:Remove one or more containers"
+        "run:Run a command in a new container"
+        "start:Start one or more stopped containers"
+        "stats:Display a live stream of container(s) resource usage statistics"
+        "stop:Stop one or more running containers"
+        "top:Display the running processes of a container"
+        "unpause:Unpause all processes within one or more containers"
+        "update:Update configuration of one or more containers"
+        "wait:Block until one or more containers stop, then print their exit codes"
+    )
+    _describe -t docker-container-commands "docker container command" _docker_container_subcommands
+}
+
+__docker_container_subcommand() {
+    local -a _command_args opts_help opts_attach_exec_run_start opts_create_run opts_create_run_update
+    local expl help="--help"
+    integer ret=1
+
+    opts_attach_exec_run_start=(
+        "($help)--detach-keys=[Escape key sequence used to detach a container]:sequence:__docker_complete_detach_keys"
+    )
+    opts_create_run=(
+        "($help -a --attach)"{-a=,--attach=}"[Attach to stdin, stdout or stderr]:device:(STDIN STDOUT STDERR)"
+        "($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: "
+        "($help)*--blkio-weight-device=[Block IO (relative device weight)]:device:Block IO weight: "
+        "($help)*--cap-add=[Add Linux capabilities]:capability: "
+        "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
+        "($help)--cgroupns=[Cgroup namespace mode to use]:cgroup namespace mode: "
+        "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: "
+        "($help)--cidfile=[Write the container ID to the file]:CID file:_files"
+        "($help)--cpus=[Number of CPUs (default 0.000)]:cpus: "
+        "($help)*--device=[Add a host device to the container]:device:_files"
+        "($help)*--device-cgroup-rule=[Add a rule to the cgroup allowed devices list]:device:cgroup: "
+        "($help)*--device-read-bps=[Limit the read rate (bytes per second) from a device]:device:IO rate: "
+        "($help)*--device-read-iops=[Limit the read rate (IO per second) from a device]:device:IO rate: "
+        "($help)*--device-write-bps=[Limit the write rate (bytes per second) to a device]:device:IO rate: "
+        "($help)*--device-write-iops=[Limit the write rate (IO per second) to a device]:device:IO rate: "
+        "($help)--disable-content-trust[Skip image verification]"
+        "($help)*--dns=[Custom DNS servers]:DNS server: "
+        "($help)*--dns-option=[Custom DNS options]:DNS option: "
+        "($help)*--dns-search=[Custom DNS search domains]:DNS domains: "
+        "($help)*--domainname=[Container NIS domain name]:domainname:_hosts"
+        "($help)*"{-e=,--env=}"[Environment variables]:environment variable: "
+        "($help)--entrypoint=[Overwrite the default entrypoint of the image]:entry point: "
+        "($help)*--env-file=[Read environment variables from a file]:environment file:_files"
+        "($help)*--expose=[Expose a port from the container without publishing it]: "
+        "($help)*--gpus=[GPU devices to add to the container ('all' to pass all GPUs)]:device: "
+        "($help)*--group-add=[Set one or more supplementary user groups for the container]:group:_groups"
+        "($help -h --hostname)"{-h=,--hostname=}"[Container host name]:hostname:_hosts"
+        "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]"
+        "($help)--init[Run an init inside the container that forwards signals and reaps processes]"
+        "($help)--ip=[IPv4 address]:IPv4: "
+        "($help)--ip6=[IPv6 address]:IPv6: "
+        "($help)--ipc=[IPC namespace to use]:IPC namespace: "
+        "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)"
+        "($help)*--link=[Add link to another container]:link:->link"
+        "($help)*--link-local-ip=[Container IPv4/IPv6 link-local addresses]:IPv4/IPv6: "
+        "($help)*"{-l=,--label=}"[Container metadata]:label: "
+        "($help)--log-driver=[Default driver for container logs]:logging driver:__docker_complete_log_drivers"
+        "($help)*--log-opt=[Log driver specific options]:log driver options:__docker_complete_log_options"
+        "($help)--mac-address=[Container MAC address]:MAC address: "
+        "($help)*--mount=[Attach a filesystem mount to the container]:mount: "
+        "($help)--name=[Container name]:name: "
+        "($help)--network=[Connect a container to a network]:network mode:(bridge none container host)"
+        "($help)*--network-alias=[Add network-scoped alias for the container]:alias: "
+        "($help)--oom-kill-disable[Disable OOM Killer]"
+        "($help)--oom-score-adj[Tune the host's OOM preferences for containers (accepts -1000 to 1000)]"
+        "($help)--pids-limit[Tune container pids limit (set -1 for unlimited)]"
+        "($help -P --publish-all)"{-P,--publish-all}"[Publish all exposed ports]"
+        "($help)*"{-p=,--publish=}"[Expose a container's port to the host]:port:_ports"
+        "($help)--pid=[PID namespace to use]:PID namespace:__docker_complete_pid"
+        "($help)--privileged[Give extended privileges to this container]"
+        "($help)--read-only[Mount the container's root filesystem as read only]"
+        "($help)*--security-opt=[Security options]:security option: "
+        "($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: "
+        "($help)--stop-signal=[Signal to kill a container]:signal:_signals"
+        "($help)--stop-timeout=[Timeout (in seconds) to stop a container]:time: "
+        "($help)*--sysctl=-[sysctl options]:sysctl: "
+        "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]"
+        "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
+        "($help)*--ulimit=[ulimit options]:ulimit: "
+        "($help)--userns=[Container user namespace]:user namespace:(host)"
+        "($help)--tmpfs[mount tmpfs]"
+        "($help)*-v[Bind mount a volume]:volume: "
+        "($help)--volume-driver=[Optional volume driver for the container]:volume driver:(local)"
+        "($help)*--volumes-from=[Mount volumes from the specified container]:volume: "
+        "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
+    )
+    opts_create_run_update=(
+        "($help)--blkio-weight=[Block IO (relative weight), between 10 and 1000]:Block IO weight:(10 100 500 1000)"
+        "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)"
+        "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: "
+        "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: "
+        "($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: "
+        "($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: "
+        "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: "
+        "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: "
+        "($help)--kernel-memory=[Kernel memory limit in bytes]:Memory limit: "
+        "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: "
+        "($help)--memory-reservation=[Memory soft limit]:Memory limit: "
+        "($help)--memory-swap=[Total memory limit with swap]:Memory limit: "
+        "($help)--pids-limit[Tune container pids limit (set -1 for unlimited)]"
+        "($help)--restart=[Restart policy]:restart policy:(no on-failure always unless-stopped)"
+    )
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (attach)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_attach_exec_run_start \
+                "($help)--no-stdin[Do not attach stdin]" \
+                "($help)--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]" \
+                "($help -):containers:__docker_complete_running_containers" && ret=0
+            ;;
+        (commit)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --author)"{-a=,--author=}"[Author]:author: " \
+                "($help)*"{-c=,--change=}"[Apply Dockerfile instruction to the created image]:Dockerfile:_files" \
+                "($help -m --message)"{-m=,--message=}"[Commit message]:message: " \
+                "($help -p --pause)"{-p,--pause}"[Pause container during commit]" \
+                "($help -):container:__docker_complete_containers" \
+                "($help -): :__docker_complete_repositories_with_tags" && ret=0
+            ;;
+        (cp)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -L --follow-link)"{-L,--follow-link}"[Always follow symbol link]" \
+                "($help -)1:container:->container" \
+                "($help -)2:hostpath:_files" && ret=0
+            case $state in
+                (container)
+                    if compset -P "*:"; then
+                        _files && ret=0
+                    else
+                        __docker_complete_containers -qS ":" && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (create)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_create_run \
+                $opts_create_run_update \
+                "($help -): :__docker_complete_images" \
+                "($help -):command: _command_names -e" \
+                "($help -)*::arguments: _normal" && ret=0
+            case $state in
+                (link)
+                    if compset -P "*:"; then
+                        _wanted alias expl "Alias" compadd -E "" && ret=0
+                    else
+                        __docker_complete_running_containers -qS ":" && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (diff)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:containers:__docker_complete_containers" && ret=0
+            ;;
+        (exec)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_attach_exec_run_start \
+                "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
+                "($help)*"{-e=,--env=}"[Set environment variables]:environment variable: " \
+                "($help)*--env-file=[Read environment variables from a file]:environment file:_files" \
+                "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" \
+                "($help)--privileged[Give extended Linux capabilities to the command]" \
+                "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
+                "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" \
+                "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories" \
+                "($help -):containers:__docker_complete_running_containers" \
+                "($help -)*::command:->anycommand" && ret=0
+            case $state in
+                (anycommand)
+                    shift 1 words
+                    (( CURRENT-- ))
+                    _normal && ret=0
+                    ;;
+            esac
+            ;;
+        (export)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -o --output)"{-o=,--output=}"[Write to a file, instead of stdout]:output file:_files" \
+                "($help -)*:containers:__docker_complete_containers" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help -s --size)"{-s,--size}"[Display total file sizes]" \
+                "($help -)*:containers:__docker_complete_containers" && ret=0
+            ;;
+        (kill)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -s --signal)"{-s=,--signal=}"[Signal to send]:signal:_signals" \
+                "($help -)*:containers:__docker_complete_running_containers" && ret=0
+            ;;
+        (logs)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--details[Show extra details provided to logs]" \
+                "($help -f --follow)"{-f,--follow}"[Follow log output]" \
+                "($help -s --since)"{-s=,--since=}"[Show logs since this timestamp]:timestamp: " \
+                "($help -t --timestamps)"{-t,--timestamps}"[Show timestamps]" \
+                "($help -n --tail)"{-n=,--tail=}"[Number of lines to show from the end of the logs]:lines:(1 10 20 50 all)" \
+                "($help -)*:containers:__docker_complete_containers" && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Show all containers]" \
+                "($help)--before=[Show only container created before...]:containers:__docker_complete_containers" \
+                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_ps_filters" \
+                "($help)--format=[Pretty-print containers using a Go template]:template: " \
+                "($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \
+                "($help -n --last)"{-n=,--last=}"[Show n last created containers (includes all states)]:n:(1 5 10 25 50)" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only show container IDs]" \
+                "($help -s --size)"{-s,--size}"[Display total file sizes]" \
+                "($help)--since=[Show only containers created since...]:containers:__docker_complete_containers" && ret=0
+            ;;
+        (pause|unpause)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:containers:__docker_complete_running_containers" && ret=0
+            ;;
+        (port)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:containers:__docker_complete_running_containers" \
+                "($help -)2:port:_ports" && ret=0
+            ;;
+        (prune)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
+                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
+            ;;
+        (rename)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -):old name:__docker_complete_containers" \
+                "($help -):new name: " && ret=0
+            ;;
+        (restart)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -t --time)"{-t=,--time=}"[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)" \
+                "($help -)*:containers:__docker_complete_containers" && ret=0
+            ;;
+        (rm)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force removal]" \
+                "($help -l --link)"{-l,--link}"[Remove the specified link and not the underlying container]" \
+                "($help -v --volumes)"{-v,--volumes}"[Remove the volumes associated to the container]" \
+                "($help -)*:containers:->values" && ret=0
+            case $state in
+                (values)
+                    if [[ ${words[(r)-f]} == -f || ${words[(r)--force]} == --force ]]; then
+                        __docker_complete_containers && ret=0
+                    else
+                        __docker_complete_stopped_containers && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (run)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_create_run \
+                $opts_create_run_update \
+                $opts_attach_exec_run_start \
+                "($help -d --detach)"{-d,--detach}"[Detached mode: leave the container running in the background]" \
+                "($help)--health-cmd=[Command to run to check health]:command: " \
+                "($help)--health-interval=[Time between running the check]:time: " \
+                "($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)" \
+                "($help)--health-timeout=[Maximum time to allow one check to run]:time: " \
+                "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]" \
+                "($help)--rm[Remove intermediate containers when it exits]" \
+                "($help)--runtime=[Name of the runtime to be used for that container]:runtime:__docker_complete_runtimes" \
+                "($help)--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]" \
+                "($help)--storage-opt=[Storage driver options for the container]:storage options:->storage-opt" \
+                "($help -): :__docker_complete_images" \
+                "($help -):command: _command_names -e" \
+                "($help -)*::arguments: _normal" && ret=0
+            case $state in
+                (link)
+                    if compset -P "*:"; then
+                        _wanted alias expl "Alias" compadd -E "" && ret=0
+                    else
+                        __docker_complete_running_containers -qS ":" && ret=0
+                    fi
+                    ;;
+                (storage-opt)
+                    if compset -P "*="; then
+                        _message "value" && ret=0
+                    else
+                        opts=('size')
+                        _describe -t filter-opts "storage options" opts -qS "=" && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (start)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_attach_exec_run_start \
+                "($help -a --attach)"{-a,--attach}"[Attach container's stdout/stderr and forward all signals]" \
+                "($help -i --interactive)"{-i,--interactive}"[Attach container's stdin]" \
+                "($help -)*:containers:__docker_complete_stopped_containers" && ret=0
+            ;;
+        (stats)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Show all containers (default shows just running)]" \
+                "($help)--format=[Pretty-print images using a Go template]:template: " \
+                "($help)--no-stream[Disable streaming stats and only pull the first result]" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -)*:containers:__docker_complete_running_containers" && ret=0
+            ;;
+        (stop)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -t --time)"{-t=,--time=}"[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)" \
+                "($help -)*:containers:__docker_complete_running_containers" && ret=0
+            ;;
+        (top)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:containers:__docker_complete_running_containers" \
+                "($help -)*:: :->ps-arguments" && ret=0
+            case $state in
+                (ps-arguments)
+                    _ps && ret=0
+                    ;;
+            esac
+            ;;
+        (update)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_create_run_update \
+                "($help -)*: :->values" && ret=0
+            case $state in
+                (values)
+                    if [[ ${words[(r)--kernel-memory*]} = (--kernel-memory*) ]]; then
+                        __docker_complete_stopped_containers && ret=0
+                    else
+                        __docker_complete_containers && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (wait)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:containers:__docker_complete_running_containers" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_container_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO container
+
+# BO image
+
+__docker_image_commands() {
+    local -a _docker_image_subcommands
+    _docker_image_subcommands=(
+        "build:Build an image from a Dockerfile"
+        "history:Show the history of an image"
+        "import:Import the contents from a tarball to create a filesystem image"
+        "inspect:Display detailed information on one or more images"
+        "load:Load an image from a tar archive or STDIN"
+        "ls:List images"
+        "prune:Remove unused images"
+        "pull:Pull an image or a repository from a registry"
+        "push:Push an image or a repository to a registry"
+        "rm:Remove one or more images"
+        "save:Save one or more images to a tar archive (streamed to STDOUT by default)"
+        "tag:Tag an image into a repository"
+    )
+    _describe -t docker-image-commands "docker image command" _docker_image_subcommands
+}
+
+__docker_image_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (build)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: " \
+                "($help)*--build-arg=[Build-time variables]:<varname>=<value>: " \
+                "($help)*--cache-from=[Images to consider as cache sources]: :__docker_complete_repositories_with_tags" \
+                "($help -c --cpu-shares)"{-c=,--cpu-shares=}"[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)" \
+                "($help)--cgroup-parent=[Parent cgroup for the container]:cgroup: " \
+                "($help)--compress[Compress the build context using gzip]" \
+                "($help)--cpu-period=[Limit the CPU CFS (Completely Fair Scheduler) period]:CPU period: " \
+                "($help)--cpu-quota=[Limit the CPU CFS (Completely Fair Scheduler) quota]:CPU quota: " \
+                "($help)--cpu-rt-period=[Limit the CPU real-time period]:CPU real-time period in microseconds: " \
+                "($help)--cpu-rt-runtime=[Limit the CPU real-time runtime]:CPU real-time runtime in microseconds: " \
+                "($help)--cpuset-cpus=[CPUs in which to allow execution]:CPUs: " \
+                "($help)--cpuset-mems=[MEMs in which to allow execution]:MEMs: " \
+                "($help)--disable-content-trust[Skip image verification]" \
+                "($help -f --file)"{-f=,--file=}"[Name of the Dockerfile]:Dockerfile:_files" \
+                "($help)--force-rm[Always remove intermediate containers]" \
+                "($help)--isolation=[Container isolation technology]:isolation:(default hyperv process)" \
+                "($help)*--label=[Set metadata for an image]:label=value: " \
+                "($help -m --memory)"{-m=,--memory=}"[Memory limit]:Memory limit: " \
+                "($help)--memory-swap=[Total memory limit with swap]:Memory limit: " \
+                "($help)--network=[Connect a container to a network]:network mode:(bridge none container host)" \
+                "($help)--no-cache[Do not use cache when building the image]" \
+                "($help)--pull[Attempt to pull a newer version of the image]" \
+                "($help -q --quiet)"{-q,--quiet}"[Suppress verbose build output]" \
+                "($help)--rm[Remove intermediate containers after a successful build]" \
+                "($help)*--shm-size=[Size of '/dev/shm' (format is '<number><unit>')]:shm size: " \
+                "($help)--squash[Squash newly built layers into a single new layer]" \
+                "($help -t --tag)*"{-t=,--tag=}"[Repository, name and tag for the image]: :__docker_complete_repositories_with_tags" \
+                "($help)--target=[Set the target build stage to build.]" \
+                "($help)*--ulimit=[ulimit options]:ulimit: " \
+                "($help)--userns=[Container user namespace]:user namespace:(host)" \
+                "($help -):path or URL:_directories" && ret=0
+            ;;
+        (history)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -H --human)"{-H,--human}"[Print sizes and dates in human readable format]" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \
+                "($help -)*: :__docker_complete_images" && ret=0
+            ;;
+        (import)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-c=,--change=}"[Apply Dockerfile instruction to the created image]:Dockerfile:_files" \
+                "($help -m --message)"{-m=,--message=}"[Commit message for imported image]:message: " \
+                "($help -):URL:(- http:// file://)" \
+                "($help -): :__docker_complete_repositories_with_tags" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help -)*:images:__docker_complete_images" && ret=0
+            ;;
+        (load)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -i --input)"{-i=,--input=}"[Read from tar archive file]:archive file:_files -g \"*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|)|(tbz|tgz|txz))(-.)\"" \
+                "($help -q --quiet)"{-q,--quiet}"[Suppress the load output]" && ret=0
+            ;;
+        (ls|list)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Show all images]" \
+                "($help)--digests[Show digests]" \
+                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_images_filters" \
+                "($help)--format=[Pretty-print images using a Go template]:template: " \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \
+                "($help -): :__docker_complete_repositories" && ret=0
+            ;;
+        (prune)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Remove all unused images, not just dangling ones]" \
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
+                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
+            ;;
+        (pull)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all-tags)"{-a,--all-tags}"[Download all tagged images]" \
+                "($help)--disable-content-trust[Skip image verification]" \
+                "($help -):name:__docker_search" && ret=0
+            ;;
+        (push)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all-tags)"{-a,--all-tags}"[Push all tagged images in the repository]" \
+                "($help)--disable-content-trust[Skip image signing]" \
+                "($help -): :__docker_complete_images" && ret=0
+            ;;
+        (rm)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force removal]" \
+                "($help)--no-prune[Do not delete untagged parents]" \
+                "($help -)*: :__docker_complete_images" && ret=0
+            ;;
+        (save)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -o --output)"{-o=,--output=}"[Write to file]:file:_files" \
+                "($help -)*: :__docker_complete_images" && ret=0
+            ;;
+        (tag)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -):source:__docker_complete_images"\
+                "($help -):destination:__docker_complete_repositories_with_tags" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_container_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO image
+
+# BO network
+
+__docker_network_complete_ls_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (driver)
+                __docker_complete_info_plugins Network && ret=0
+                ;;
+            (id)
+                __docker_complete_networks_ids && ret=0
+                ;;
+            (name)
+                __docker_complete_networks_names && ret=0
+                ;;
+            (scope)
+                opts=('global' 'local' 'swarm')
+                _describe -t scope-filter-opts "Scope filter options" opts && ret=0
+                ;;
+            (type)
+                opts=('builtin' 'custom')
+                _describe -t type-filter-opts "Type filter options" opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('driver' 'id' 'label' 'name' 'scope' 'type')
+        _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_get_networks() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local line s
+    declare -a lines networks
+
+    type=$1; shift
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options network ls)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # Network ID
+    if [[ $type = (ids|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[NETWORK ID]},${end[NETWORK ID]}]%% ##}"
+            s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
+            s="$s, ${${line[${begin[SCOPE]},${end[SCOPE]}]}%% ##}"
+            networks=($networks $s)
+        done
+    fi
+
+    # Names
+    if [[ $type = (names|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
+            s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
+            s="$s, ${${line[${begin[SCOPE]},${end[SCOPE]}]}%% ##}"
+            networks=($networks $s)
+        done
+    fi
+
+    _describe -t networks-list "networks" networks "$@" && ret=0
+    return ret
+}
+
+__docker_complete_networks() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_networks all "$@"
+}
+
+__docker_complete_networks_ids() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_networks ids "$@"
+}
+
+__docker_complete_networks_names() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_get_networks names "$@"
+}
+
+__docker_network_commands() {
+    local -a _docker_network_subcommands
+    _docker_network_subcommands=(
+        "connect:Connect a container to a network"
+        "create:Creates a new network with a name specified by the user"
+        "disconnect:Disconnects a container from a network"
+        "inspect:Displays detailed information on a network"
+        "ls:Lists all the networks created by the user"
+        "prune:Remove all unused networks"
+        "rm:Deletes one or more networks"
+    )
+    _describe -t docker-network-commands "docker network command" _docker_network_subcommands
+}
+
+__docker_network_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (connect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*--alias=[Add network-scoped alias for the container]:alias: " \
+                "($help)--ip=[IPv4 address]:IPv4: " \
+                "($help)--ip6=[IPv6 address]:IPv6: " \
+                "($help)*--link=[Add a link to another container]:link:->link" \
+                "($help)*--link-local-ip=[Add a link-local address for the container]:IPv4/IPv6: " \
+                "($help -)1:network:__docker_complete_networks" \
+                "($help -)2:containers:__docker_complete_containers" && ret=0
+
+            case $state in
+                (link)
+                    if compset -P "*:"; then
+                        _wanted alias expl "Alias" compadd -E "" && ret=0
+                    else
+                        __docker_complete_running_containers -qS ":" && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (create)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help)--attachable[Enable manual container attachment]" \
+                "($help)*--aux-address[Auxiliary IPv4 or IPv6 addresses used by network driver]:key=IP: " \
+                "($help -d --driver)"{-d=,--driver=}"[Driver to manage the Network]:driver:(null host bridge overlay)" \
+                "($help)*--gateway=[IPv4 or IPv6 Gateway for the master subnet]:IP: " \
+                "($help)--internal[Restricts external access to the network]" \
+                "($help)*--ip-range=[Allocate container ip from a sub-range]:IP/mask: " \
+                "($help)--ipam-driver=[IP Address Management Driver]:driver:(default)" \
+                "($help)*--ipam-opt=[Custom IPAM plugin options]:opt=value: " \
+                "($help)--ipv6[Enable IPv6 networking]" \
+                "($help)*--label=[Set metadata on a network]:label=value: " \
+                "($help)*"{-o=,--opt=}"[Driver specific options]:opt=value: " \
+                "($help)*--subnet=[Subnet in CIDR format that represents a network segment]:IP/mask: " \
+                "($help -)1:Network Name: " && ret=0
+            ;;
+        (disconnect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:network:__docker_complete_networks" \
+                "($help -)2:containers:__docker_complete_containers" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help)--verbose[Show detailed information]" \
+                "($help -)*:network:__docker_complete_networks" && ret=0
+            ;;
+        (ls)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--no-trunc[Do not truncate the output]" \
+                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_network_complete_ls_filters" \
+                "($help)--format=[Pretty-print networks using a Go template]:template: " \
+                "($help -q --quiet)"{-q,--quiet}"[Only display network IDs]" && ret=0
+            ;;
+        (prune)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
+                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
+            ;;
+        (rm)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:network:__docker_complete_networks" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_network_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO network
+
+# BO node
+
+__docker_node_complete_ls_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (id)
+                __docker_complete_nodes_ids && ret=0
+                ;;
+            (membership)
+                membership_opts=('accepted' 'pending' 'rejected')
+                _describe -t membership-opts "membership options" membership_opts && ret=0
+                ;;
+            (name)
+                __docker_complete_nodes_names && ret=0
+                ;;
+            (role)
+                role_opts=('manager' 'worker')
+                _describe -t role-opts "role options" role_opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('id' 'label' 'membership' 'name' 'node.label' 'role')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_node_complete_ps_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (desired-state)
+                state_opts=('accepted' 'running' 'shutdown')
+                _describe -t state-opts "desired state options" state_opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('desired-state' 'id' 'label' 'name')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_nodes() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local line s
+    declare -a lines nodes args
+
+    type=$1; shift
+    filter=$1; shift
+    [[ $filter != "none" ]] && args=("-f $filter")
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options node ls $args)"$'\n'}})
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # Node ID
+    if [[ $type = (ids|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[ID]},${end[ID]}]%% ##}"
+            nodes=($nodes $s)
+        done
+    fi
+
+    # Names
+    if [[ $type = (names|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[HOSTNAME]},${end[HOSTNAME]}]%% ##}"
+            nodes=($nodes $s)
+        done
+    fi
+
+    _describe -t nodes-list "nodes" nodes "$@" && ret=0
+    return ret
+}
+
+__docker_complete_nodes() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_nodes all none "$@"
+}
+
+__docker_complete_nodes_ids() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_nodes ids none "$@"
+}
+
+__docker_complete_nodes_names() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_nodes names none "$@"
+}
+
+__docker_complete_pending_nodes() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_nodes all "membership=pending" "$@"
+}
+
+__docker_complete_manager_nodes() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_nodes all "role=manager" "$@"
+}
+
+__docker_complete_worker_nodes() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_nodes all "role=worker" "$@"
+}
+
+__docker_node_commands() {
+    local -a _docker_node_subcommands
+    _docker_node_subcommands=(
+        "demote:Demote a node as manager in the swarm"
+        "inspect:Display detailed information on one or more nodes"
+        "ls:List nodes in the swarm"
+        "promote:Promote a node as manager in the swarm"
+        "rm:Remove one or more nodes from the swarm"
+        "ps:List tasks running on one or more nodes, defaults to current node"
+        "update:Update a node"
+    )
+    _describe -t docker-node-commands "docker node command" _docker_node_subcommands
+}
+
+__docker_node_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (rm|remove)
+             _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force remove a node from the swarm]" \
+                "($help -)*:node:__docker_complete_pending_nodes" && ret=0
+            ;;
+        (demote)
+             _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:node:__docker_complete_manager_nodes" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help)--pretty[Print the information in a human friendly format]" \
+                "($help -)*:node:__docker_complete_nodes" && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_node_complete_ls_filters" \
+                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
+            ;;
+        (promote)
+             _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:node:__docker_complete_worker_nodes" && ret=0
+            ;;
+        (ps)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Display all instances]" \
+                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_node_complete_ps_filters" \
+                "($help)--format=[Format the output using the given go template]:template: " \
+                "($help)--no-resolve[Do not map IDs to Names]" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \
+                "($help -)*:node:__docker_complete_nodes" && ret=0
+            ;;
+        (update)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--availability=[Availability of the node]:availability:(active pause drain)" \
+                "($help)*--label-add=[Add or update a node label]:key=value: " \
+                "($help)*--label-rm=[Remove a node label if exists]:label: " \
+                "($help)--role=[Role of the node]:role:(manager worker)" \
+                "($help -)1:node:__docker_complete_nodes" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_node_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO node
+
+# BO plugin
+
+__docker_plugin_complete_ls_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (capability)
+                opts=('authz' 'ipamdriver' 'logdriver' 'metricscollector' 'networkdriver' 'volumedriver')
+                _describe -t capability-opts "capability options" opts && ret=0
+                ;;
+            (enabled)
+                opts=('false' 'true')
+                _describe -t enabled-opts "enabled options" opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('capability' 'enabled')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_plugins() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local line s
+    declare -a lines plugins args
+
+    filter=$1; shift
+    [[ $filter != "none" ]] && args=("-f $filter")
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options plugin ls $args)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # Name
+    for line in $lines; do
+        s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
+        s="$s:${(l:7:: :::)${${line[${begin[TAG]},${end[TAG]}]}%% ##}}"
+        plugins=($plugins $s)
+    done
+
+    _describe -t plugins-list "plugins" plugins "$@" && ret=0
+    return ret
+}
+
+__docker_complete_plugins() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_plugins none "$@"
+}
+
+__docker_complete_enabled_plugins() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_plugins enabled=true "$@"
+}
+
+__docker_complete_disabled_plugins() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_plugins enabled=false "$@"
+}
+
+__docker_plugin_commands() {
+    local -a _docker_plugin_subcommands
+    _docker_plugin_subcommands=(
+        "disable:Disable a plugin"
+        "enable:Enable a plugin"
+        "inspect:Return low-level information about a plugin"
+        "install:Install a plugin"
+        "ls:List plugins"
+        "push:Push a plugin"
+        "rm:Remove a plugin"
+        "set:Change settings for a plugin"
+        "upgrade:Upgrade an existing plugin"
+    )
+    _describe -t docker-plugin-commands "docker plugin command" _docker_plugin_subcommands
+}
+
+__docker_plugin_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (disable)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force the disable of an active plugin]" \
+                "($help -)1:plugin:__docker_complete_enabled_plugins" && ret=0
+            ;;
+        (enable)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--timeout=[HTTP client timeout (in seconds)]:timeout: " \
+                "($help -)1:plugin:__docker_complete_disabled_plugins" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given Go template]:template: " \
+                "($help -)*:plugin:__docker_complete_plugins" && ret=0
+            ;;
+        (install)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--alias=[Local name for plugin]:alias: " \
+                "($help)--disable[Do not enable the plugin on install]" \
+                "($help)--disable-content-trust[Skip image verification (default true)]" \
+                "($help)--grant-all-permissions[Grant all permissions necessary to run the plugin]" \
+                "($help -)1:plugin:__docker_complete_plugins" \
+                "($help -)*:key=value: " && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_plugin_complete_ls_filters" \
+                "($help --format)--format=[Format the output using the given Go template]:template: " \
+                "($help)--no-trunc[Don't truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
+            ;;
+        (push)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--disable-content-trust[Skip image verification (default true)]" \
+                "($help -)1:plugin:__docker_complete_plugins" && ret=0
+            ;;
+        (rm|remove)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force the removal of an active plugin]" \
+                "($help -)*:plugin:__docker_complete_plugins" && ret=0
+            ;;
+        (set)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:plugin:__docker_complete_plugins" \
+                "($help -)*:key=value: " && ret=0
+            ;;
+        (upgrade)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--disable-content-trust[Skip image verification (default true)]" \
+                "($help)--grant-all-permissions[Grant all permissions necessary to run the plugin]" \
+                "($help)--skip-remote-check[Do not check if specified remote plugin matches existing plugin image]" \
+                "($help -)1:plugin:__docker_complete_plugins" \
+                "($help -):remote: " && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_plugin_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO plugin
+
+# BO secret
+
+__docker_secrets() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local line s
+    declare -a lines secrets
+
+    type=$1; shift
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options secret ls)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # ID
+    if [[ $type = (ids|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[ID]},${end[ID]}]%% ##}"
+            secrets=($secrets $s)
+        done
+    fi
+
+    # Names
+    if [[ $type = (names|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
+            secrets=($secrets $s)
+        done
+    fi
+
+    _describe -t secrets-list "secrets" secrets "$@" && ret=0
+    return ret
+}
+
+__docker_complete_secrets() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_secrets all "$@"
+}
+
+__docker_secret_commands() {
+    local -a _docker_secret_subcommands
+    _docker_secret_subcommands=(
+        "create:Create a secret using stdin as content"
+        "inspect:Display detailed information on one or more secrets"
+        "ls:List secrets"
+        "rm:Remove one or more secrets"
+    )
+    _describe -t docker-secret-commands "docker secret command" _docker_secret_subcommands
+}
+
+__docker_secret_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (create)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help)*"{-l=,--label=}"[Secret labels]:label: " \
+                "($help -):secret: " && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given Go template]:template: " \
+                "($help -)*:secret:__docker_complete_secrets" && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--format=[Format the output using the given go template]:template: " \
+                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
+            ;;
+        (rm|remove)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:secret:__docker_complete_secrets" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_secret_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO secret
+
+# BO service
+
+__docker_service_complete_ls_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (id)
+                __docker_complete_services_ids && ret=0
+                ;;
+            (mode)
+                opts=('global' 'replicated')
+                _describe -t mode-opts "mode options" opts && ret=0
+                ;;
+            (name)
+                __docker_complete_services_names && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('id' 'label' 'mode' 'name')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_service_complete_ps_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (desired-state)
+                state_opts=('accepted' 'running' 'shutdown')
+                _describe -t state-opts "desired state options" state_opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('desired-state' 'id' 'label' 'name')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_service_complete_placement_pref() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (spread)
+                opts=('engine.labels' 'node.labels')
+                _describe -t spread-opts "spread options" opts -qS "." && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('spread')
+        _describe -t pref-opts "placement pref options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_services() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local line s
+    declare -a lines services
+
+    type=$1; shift
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options service ls)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # Service ID
+    if [[ $type = (ids|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[ID]},${end[ID]}]%% ##}"
+            s="$s:${(l:7:: :::)${${line[${begin[IMAGE]},${end[IMAGE]}]}%% ##}}"
+            services=($services $s)
+        done
+    fi
+
+    # Names
+    if [[ $type = (names|all) ]]; then
+        for line in $lines; do
+            s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
+            s="$s:${(l:7:: :::)${${line[${begin[IMAGE]},${end[IMAGE]}]}%% ##}}"
+            services=($services $s)
+        done
+    fi
+
+    _describe -t services-list "services" services "$@" && ret=0
+    return ret
+}
+
+__docker_complete_services() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_services all "$@"
+}
+
+__docker_complete_services_ids() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_services ids "$@"
+}
+
+__docker_complete_services_names() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_services names "$@"
+}
+
+__docker_service_commands() {
+    local -a _docker_service_subcommands
+    _docker_service_subcommands=(
+        "create:Create a new service"
+        "inspect:Display detailed information on one or more services"
+        "logs:Fetch the logs of a service or task"
+        "ls:List services"
+        "rm:Remove one or more services"
+        "rollback:Revert changes to a service's configuration"
+        "scale:Scale one or multiple replicated services"
+        "ps:List the tasks of a service"
+        "update:Update a service"
+    )
+    _describe -t docker-service-commands "docker service command" _docker_service_subcommands
+}
+
+__docker_service_subcommand() {
+    local -a _command_args opts_help opts_create_update
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+    opts_create_update=(
+        "($help)*--cap-add=[Add Linux capabilities]:capability: "
+        "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
+        "($help)*--constraint=[Placement constraints]:constraint: "
+        "($help)--endpoint-mode=[Placement constraints]:mode:(dnsrr vip)"
+        "($help)*"{-e=,--env=}"[Set environment variables]:env: "
+        "($help)--health-cmd=[Command to run to check health]:command: "
+        "($help)--health-interval=[Time between running the check]:time: "
+        "($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)"
+        "($help)--health-timeout=[Maximum time to allow one check to run]:time: "
+        "($help)--hostname=[Service container hostname]:hostname: " \
+        "($help)--isolation=[Service container isolation mode]:isolation:(default process hyperv)" \
+        "($help)*--label=[Service labels]:label: "
+        "($help)--limit-cpu=[Limit CPUs]:value: "
+        "($help)--limit-memory=[Limit Memory]:value: "
+        "($help)--limit-pids[Limit maximum number of processes (default 0 = unlimited)]"
+        "($help)--log-driver=[Logging driver for service]:logging driver:__docker_complete_log_drivers"
+        "($help)*--log-opt=[Logging driver options]:log driver options:__docker_complete_log_options"
+        "($help)*--mount=[Attach a filesystem mount to the service]:mount: "
+        "($help)*--network=[Network attachments]:network: "
+        "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]"
+        "($help)--read-only[Mount the container's root filesystem as read only]"
+        "($help)--replicas=[Number of tasks]:replicas: "
+        "($help)--reserve-cpu=[Reserve CPUs]:value: "
+        "($help)--reserve-memory=[Reserve Memory]:value: "
+        "($help)--restart-condition=[Restart when condition is met]:mode:(any none on-failure)"
+        "($help)--restart-delay=[Delay between restart attempts]:delay: "
+        "($help)--restart-max-attempts=[Maximum number of restarts before giving up]:max-attempts: "
+        "($help)--restart-window=[Window used to evaluate the restart policy]:duration: "
+        "($help)--rollback-delay=[Delay between task rollbacks]:duration: "
+        "($help)--rollback-failure-action=[Action on rollback failure]:action:(continue pause)"
+        "($help)--rollback-max-failure-ratio=[Failure rate to tolerate during a rollback]:failure rate: "
+        "($help)--rollback-monitor=[Duration after each task rollback to monitor for failure]:duration: "
+        "($help)--rollback-parallelism=[Maximum number of tasks rolled back simultaneously]:number: "
+        "($help)*--secret=[Specify secrets to expose to the service]:secret:__docker_complete_secrets"
+        "($help)--stop-grace-period=[Time to wait before force killing a container]:grace period: "
+        "($help)--stop-signal=[Signal to stop the container]:signal:_signals"
+        "($help -t --tty)"{-t,--tty}"[Allocate a pseudo-TTY]"
+        "($help)--update-delay=[Delay between updates]:delay: "
+        "($help)--update-failure-action=[Action on update failure]:mode:(continue pause rollback)"
+        "($help)--update-max-failure-ratio=[Failure rate to tolerate during an update]:fraction: "
+        "($help)--update-monitor=[Duration after each task update to monitor for failure]:window: "
+        "($help)--update-parallelism=[Maximum number of tasks updated simultaneously]:number: "
+        "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
+        "($help)--with-registry-auth[Send registry authentication details to swarm agents]"
+        "($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
+    )
+
+    case "$words[1]" in
+        (create)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_create_update \
+                "($help)*--container-label=[Container labels]:label: " \
+                "($help)*--dns=[Set custom DNS servers]:DNS: " \
+                "($help)*--dns-option=[Set DNS options]:DNS option: " \
+                "($help)*--dns-search=[Set custom DNS search domains]:DNS search: " \
+                "($help)*--env-file=[Read environment variables from a file]:environment file:_files" \
+                "($help)*--group=[Set one or more supplementary user groups for the container]:group: _groups " \
+                "($help)--mode=[Service Mode]:mode:(global replicated)" \
+                "($help)--name=[Service name]:name: " \
+                "($help)*--placement-pref=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \
+                "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " \
+                "($help -): :__docker_complete_images" \
+                "($help -):command: _command_names -e" \
+                "($help -)*::arguments: _normal" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help)--pretty[Print the information in a human friendly format]" \
+                "($help -)*:service:__docker_complete_services" && ret=0
+            ;;
+        (logs)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --follow)"{-f,--follow}"[Follow log output]" \
+                "($help)--no-resolve[Do not map IDs to Names]" \
+                "($help)--no-task-ids[Do not include task IDs]" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help)--since=[Show logs since timestamp]:timestamp: " \
+                "($help -n --tail)"{-n=,--tail=}"[Number of lines to show from the end of the logs]:lines:(1 10 20 50 all)" \
+                "($help -t --timestamps)"{-t,--timestamps}"[Show timestamps]" \
+                "($help -)1:service:__docker_complete_services" && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_service_complete_ls_filters" \
+                "($help)--format=[Pretty-print services using a Go template]:template: " \
+                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0
+            ;;
+        (rm|remove)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)*:service:__docker_complete_services" && ret=0
+            ;;
+        (rollback)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \
+                "($help -q --quiet)"{-q,--quiet}"[Suppress progress output]" \
+                "($help -)*:service:__docker_complete_services" && ret=0
+            ;;
+        (scale)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -d --detach)"{-d=false,--detach=false}"[Disable detached mode]" \
+                "($help -)*:service:->values" && ret=0
+            case $state in
+                (values)
+                    if compset -P '*='; then
+                        _message 'replicas' && ret=0
+                    else
+                        __docker_complete_services -qS "="
+                    fi
+                    ;;
+            esac
+            ;;
+        (ps)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_service_complete_ps_filters" \
+                "($help)--format=[Format the output using the given go template]:template: " \
+                "($help)--no-resolve[Do not map IDs to Names]" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only display task IDs]" \
+                "($help -)*:service:__docker_complete_services" && ret=0
+            ;;
+        (update)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                $opts_create_update \
+                "($help)--arg=[Service command args]:arguments: _normal" \
+                "($help)*--container-label-add=[Add or update container labels]:label: " \
+                "($help)*--container-label-rm=[Remove a container label by its key]:label: " \
+                "($help)*--dns-add=[Add or update custom DNS servers]:DNS: " \
+                "($help)*--dns-rm=[Remove custom DNS servers]:DNS: " \
+                "($help)*--dns-option-add=[Add or update DNS options]:DNS option: " \
+                "($help)*--dns-option-rm=[Remove DNS options]:DNS option: " \
+                "($help)*--dns-search-add=[Add or update custom DNS search domains]:DNS search: " \
+                "($help)*--dns-search-rm=[Remove DNS search domains]:DNS search: " \
+                "($help)--force[Force update]" \
+                "($help)*--group-add=[Add additional supplementary user groups to the container]:group:_groups" \
+                "($help)*--group-rm=[Remove previously added supplementary user groups from the container]:group:_groups" \
+                "($help)--image=[Service image tag]:image:__docker_complete_repositories" \
+                "($help)*--placement-pref-add=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \
+                "($help)*--placement-pref-rm=[Remove a placement preference]:pref:__docker_service_complete_placement_pref" \
+                "($help)*--publish-add=[Add or update a port]:port: " \
+                "($help)*--publish-rm=[Remove a port(target-port mandatory)]:port: " \
+                "($help)--rollback[Rollback to previous specification]" \
+                "($help -)1:service:__docker_complete_services" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_service_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO service
+
+# BO stack
+
+__docker_stack_complete_ps_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (desired-state)
+                state_opts=('accepted' 'running' 'shutdown')
+                _describe -t state-opts "desired state options" state_opts && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('desired-state' 'id' 'name')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_stack_complete_services_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('id' 'label' 'name')
+        _describe -t filter-opts "filter options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_stacks() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    local line s
+    declare -a lines stacks
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options stack ls)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # Service NAME
+    for line in $lines; do
+        s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
+        stacks=($stacks $s)
+    done
+
+    _describe -t stacks-list "stacks" stacks "$@" && ret=0
+    return ret
+}
+
+__docker_complete_stacks() {
+    [[ $PREFIX = -* ]] && return 1
+    __docker_stacks "$@"
+}
+
+__docker_stack_commands() {
+    local -a _docker_stack_subcommands
+    _docker_stack_subcommands=(
+        "deploy:Deploy a new stack or update an existing stack"
+        "ls:List stacks"
+        "ps:List the tasks in the stack"
+        "rm:Remove the stack"
+        "services:List the services in the stack"
+    )
+    _describe -t docker-stack-commands "docker stack command" _docker_stack_subcommands
+}
+
+__docker_stack_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (deploy|up)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -c --compose-file)"{-c=,--compose-file=}"[Path to a Compose file, or '-' to read from stdin]:compose file:_files -g \"*.(yml|yaml)\"" \
+                "($help)--with-registry-auth[Send registry authentication details to Swarm agents]" \
+                "($help -):stack:__docker_complete_stacks" && ret=0
+            ;;
+        (ls|list)
+            _arguments $(__docker_arguments) \
+                $opts_help && ret=0
+            ;;
+        (ps)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Display all tasks]" \
+                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_ps_filters" \
+                "($help)--format=[Format the output using the given go template]:template: " \
+                "($help)--no-resolve[Do not map IDs to Names]" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -q --quiet)"{-q,--quiet}"[Only display task IDs]" \
+                "($help -):stack:__docker_complete_stacks" && ret=0
+            ;;
+        (rm|remove|down)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -):stack:__docker_complete_stacks" && ret=0
+            ;;
+        (services)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_services_filters" \
+                "($help)--format=[Pretty-print services using a Go template]:template: " \
+                "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \
+                "($help -):stack:__docker_complete_stacks" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_stack_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO stack
+
+# BO swarm
+
+__docker_swarm_commands() {
+    local -a _docker_swarm_subcommands
+    _docker_swarm_subcommands=(
+        "init:Initialize a swarm"
+        "join:Join a swarm as a node and/or manager"
+        "join-token:Manage join tokens"
+        "leave:Leave a swarm"
+        "unlock:Unlock swarm"
+        "unlock-key:Manage the unlock key"
+        "update:Update the swarm"
+    )
+    _describe -t docker-swarm-commands "docker swarm command" _docker_swarm_subcommands
+}
+
+__docker_swarm_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (init)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--advertise-addr=[Advertised address]:ip\:port: " \
+                "($help)--data-path-addr=[Data path IP or interface]:ip " \
+                "($help)--data-path-port=[Data Path Port]:port " \
+                "($help)--default-addr-pool=[Default address pool]" \
+                "($help)--default-addr-pool-mask-length=[Default address pool subnet mask length]" \
+                "($help)--autolock[Enable manager autolocking]" \
+                "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
+                "($help)--cert-expiry=[Validity period for node certificates]:duration: " \
+                "($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
+                "($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
+                "($help)--force-new-cluster[Force create a new cluster from current state]" \
+                "($help)--listen-addr=[Listen address]:ip\:port: " \
+                "($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
+                "($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
+                "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
+            ;;
+        (join)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help)--advertise-addr=[Advertised address]:ip\:port: " \
+                "($help)--data-path-addr=[Data path IP or interface]:ip " \
+                "($help)--availability=[Availability of the node]:availability:(active drain pause)" \
+                "($help)--listen-addr=[Listen address]:ip\:port: " \
+                "($help)--token=[Token for entry into the swarm]:secret: " \
+                "($help -):host\:port: " && ret=0
+            ;;
+        (join-token)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -q --quiet)"{-q,--quiet}"[Only display token]" \
+                "($help)--rotate[Rotate join token]" \
+                "($help -):role:(manager worker)" && ret=0
+            ;;
+        (leave)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force this node to leave the swarm, ignoring warnings]" && ret=0
+            ;;
+        (unlock)
+            _arguments $(__docker_arguments) \
+                $opts_help && ret=0
+            ;;
+        (unlock-key)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -q --quiet)"{-q,--quiet}"[Only display token]" \
+                "($help)--rotate[Rotate unlock token]" && ret=0
+            ;;
+        (update)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--autolock[Enable manager autolocking]" \
+                "($help)--cert-expiry=[Validity period for node certificates]:duration: " \
+                "($help)--dispatcher-heartbeat=[Dispatcher heartbeat period]:duration: " \
+                "($help)*--external-ca=[Specifications of one or more certificate signing endpoints]:endpoint: " \
+                "($help)--max-snapshots[Number of additional Raft snapshots to retain]" \
+                "($help)--snapshot-interval[Number of log entries between Raft snapshots]" \
+                "($help)--task-history-limit=[Task history retention limit]:limit: " && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_network_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO swarm
+
+# BO system
+
+__docker_system_commands() {
+    local -a _docker_system_subcommands
+    _docker_system_subcommands=(
+        "df:Show docker filesystem usage"
+        "events:Get real time events from the server"
+        "info:Display system-wide information"
+        "prune:Remove unused data"
+    )
+    _describe -t docker-system-commands "docker system command" _docker_system_subcommands
+}
+
+__docker_system_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (df)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -v --verbose)"{-v,--verbose}"[Show detailed information on space usage]" && ret=0
+            ;;
+        (events)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_events_filter" \
+                "($help)--since=[Events created since this timestamp]:timestamp: " \
+                "($help)--until=[Events created until this timestamp]:timestamp: " \
+                "($help)--format=[Format the output using the given go template]:template: " && ret=0
+            ;;
+        (info)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " && ret=0
+            ;;
+        (prune)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -a --all)"{-a,--all}"[Remove all unused data, not just dangling ones]" \
+                "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \
+                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" \
+                "($help)--volumes=[Remove all unused volumes]" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO system
+
+# BO volume
+
+__docker_volume_complete_ls_filters() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+
+    if compset -P '*='; then
+        case "${${words[-1]%=*}#*=}" in
+            (dangling)
+                dangling_opts=('true' 'false')
+                _describe -t dangling-filter-opts "Dangling Filter Options" dangling_opts && ret=0
+                ;;
+            (driver)
+                __docker_complete_info_plugins Volume && ret=0
+                ;;
+            (name)
+                __docker_complete_volumes && ret=0
+                ;;
+            *)
+                _message 'value' && ret=0
+                ;;
+        esac
+    else
+        opts=('dangling' 'driver' 'label' 'name')
+        _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0
+    fi
+
+    return ret
+}
+
+__docker_complete_volumes() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a lines volumes
+
+    lines=(${(f)${:-"$(_call_program commands docker $docker_options volume ls)"$'\n'}})
+
+    # Parse header line to find columns
+    local i=1 j=1 k header=${lines[1]}
+    declare -A begin end
+    while (( j < ${#header} - 1 )); do
+        i=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 1 ))
+        j=$(( i + ${${header[$i,-1]}[(i)  ]} - 1 ))
+        k=$(( j + ${${header[$j,-1]}[(i)[^ ]]} - 2 ))
+        begin[${header[$i,$((j-1))]}]=$i
+        end[${header[$i,$((j-1))]}]=$k
+    done
+    end[${header[$i,$((j-1))]}]=-1
+    lines=(${lines[2,-1]})
+
+    # Names
+    local line s
+    for line in $lines; do
+        s="${line[${begin[VOLUME NAME]},${end[VOLUME NAME]}]%% ##}"
+        s="$s:${(l:7:: :::)${${line[${begin[DRIVER]},${end[DRIVER]}]}%% ##}}"
+        volumes=($volumes $s)
+    done
+
+    _describe -t volumes-list "volumes" volumes && ret=0
+    return ret
+}
+
+__docker_volume_commands() {
+    local -a _docker_volume_subcommands
+    _docker_volume_subcommands=(
+        "create:Create a volume"
+        "inspect:Display detailed information on one or more volumes"
+        "ls:List volumes"
+        "prune:Remove all unused volumes"
+        "rm:Remove one or more volumes"
+    )
+    _describe -t docker-volume-commands "docker volume command" _docker_volume_subcommands
+}
+
+__docker_volume_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (create)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help -d --driver)"{-d=,--driver=}"[Volume driver name]:Driver name:(local)" \
+                "($help)*--label=[Set metadata for a volume]:label=value: " \
+                "($help)*"{-o=,--opt=}"[Driver specific options]:Driver option: " \
+                "($help -)1:Volume name: " && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help -)1:volume:__docker_complete_volumes" && ret=0
+            ;;
+        (ls)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_volume_complete_ls_filters" \
+                "($help)--format=[Pretty-print volumes using a Go template]:template: " \
+                "($help -q --quiet)"{-q,--quiet}"[Only display volume names]" && ret=0
+            ;;
+        (prune)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0
+            ;;
+        (rm)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --force)"{-f,--force}"[Force the removal of one or more volumes]" \
+                "($help -):volume:__docker_complete_volumes" && ret=0
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO volume
+
+# BO context
+
+__docker_complete_contexts() {
+    [[ $PREFIX = -* ]] && return 1
+    integer ret=1
+    declare -a contexts
+
+    contexts=(${(f)${:-"$(_call_program commands docker $docker_options context ls -q)"$'\n'}})
+
+    _describe -t context-list "context" contexts && ret=0
+    return ret
+}
+
+__docker_context_commands() {
+    local -a _docker_context_subcommands
+    _docker_context_subcommands=(
+        "create:Create new context"
+        "inspect:Display detailed information on one or more contexts"
+        "list:List available contexts"
+        "rm:Remove one or more contexts"
+        "show:Print the current context"
+        "update:Update a context"
+        "use:Set the default context"
+    )
+    _describe -t docker-context-commands "docker context command" _docker_context_subcommands
+}
+
+__docker_context_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (create)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
+                "($help)--description=[Description of the context]:description:" \
+                "($help)--docker=[Set the docker endpoint]:docker:" \
+                "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
+                "($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \
+                "($help -):name: " && ret=0
+            ;;
+        (use)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:context:__docker_complete_contexts" && ret=0
+            ;;
+        (inspect)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:context:__docker_complete_contexts" && ret=0
+            ;;
+        (rm)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -)1:context:__docker_complete_contexts" && ret=0
+            ;;
+        (update)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
+                "($help)--description=[Description of the context]:description:" \
+                "($help)--docker=[Set the docker endpoint]:docker:" \
+                "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
+                "($help -):name:" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+# EO context
+
+__docker_caching_policy() {
+  oldp=( "$1"(Nmh+1) )     # 1 hour
+  (( $#oldp ))
+}
+
+__docker_commands() {
+    local cache_policy
+    integer force_invalidation=0
+
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
+    fi
+
+    if ( (( ! ${+_docker_hide_legacy_commands} )) || _cache_invalid docker_hide_legacy_commands ) \
+       && ! _retrieve_cache docker_hide_legacy_commands;
+    then
+        _docker_hide_legacy_commands="${DOCKER_HIDE_LEGACY_COMMANDS}"
+        _store_cache docker_hide_legacy_commands _docker_hide_legacy_commands
+    fi
+
+    if [[ "${_docker_hide_legacy_commands}" != "${DOCKER_HIDE_LEGACY_COMMANDS}" ]]; then
+        force_invalidation=1
+        _docker_hide_legacy_commands="${DOCKER_HIDE_LEGACY_COMMANDS}"
+        _store_cache docker_hide_legacy_commands _docker_hide_legacy_commands
+    fi
+
+    if ( [[ ${+_docker_subcommands} -eq 0 ]] || _cache_invalid docker_subcommands ) \
+        && ! _retrieve_cache docker_subcommands || [[ ${force_invalidation} -eq 1 ]];
+    then
+        local -a lines
+        lines=(${(f)"$(_call_program commands docker 2>&1)"})
+        _docker_subcommands=(${${${(M)${lines[$((${lines[(i)*Commands:]} + 1)),-1]}:# *}## #}/\*# ##/:})
+        _docker_subcommands=($_docker_subcommands 'daemon:Enable daemon mode' 'help:Show help for a command')
+        (( $#_docker_subcommands > 2 )) && _store_cache docker_subcommands _docker_subcommands
+    fi
+    _describe -t docker-commands "docker command" _docker_subcommands
+}
+
+__docker_subcommand() {
+    local -a _command_args opts_help
+    local expl help="--help"
+    integer ret=1
+
+    opts_help=("(: -)--help[Print usage]")
+
+    case "$words[1]" in
+        (attach|commit|cp|create|diff|exec|export|kill|logs|pause|unpause|port|rename|restart|rm|run|start|stats|stop|top|update|wait)
+            __docker_container_subcommand && ret=0
+            ;;
+        (build|history|import|load|pull|push|save|tag)
+            __docker_image_subcommand && ret=0
+            ;;
+        (checkpoint)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_checkpoint_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_checkpoint_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (container)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_container_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_container_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (context)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_context_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_context_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (daemon)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help)*--add-runtime=[Register an additional OCI compatible runtime]:runtime:__docker_complete_runtimes" \
+                "($help)*--allow-nondistributable-artifacts=[Push nondistributable artifacts to specified registries]:registry: " \
+                "($help)--api-cors-header=[CORS headers in the Engine API]:CORS headers: " \
+                "($help)*--authorization-plugin=[Authorization plugins to load]" \
+                "($help -b --bridge)"{-b=,--bridge=}"[Attach containers to a network bridge]:bridge:_net_interfaces" \
+                "($help)--bip=[Network bridge IP]:IP address: " \
+                "($help)--cgroup-parent=[Parent cgroup for all containers]:cgroup: " \
+                "($help)--cluster-advertise=[Address or interface name to advertise]:Instance to advertise (host\:port): " \
+                "($help)--cluster-store=[URL of the distributed storage backend]:Cluster Store:->cluster-store" \
+                "($help)*--cluster-store-opt=[Cluster store options]:Cluster options:->cluster-store-options" \
+                "($help)--config-file=[Path to daemon configuration file]:Config File:_files" \
+                "($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \
+                "($help)--containerd-namespace=[Containerd namespace to use]:containerd namespace:" \
+                "($help)--containerd-plugins-namespace=[Containerd namespace to use for plugins]:containerd namespace:" \
+                "($help)--data-root=[Root directory of persisted Docker data]:path:_directories" \
+                "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
+                "($help)--default-gateway[Container default gateway IPv4 address]:IPv4 address: " \
+                "($help)--default-gateway-v6[Container default gateway IPv6 address]:IPv6 address: " \
+                "($help)--default-shm-size=[Default shm size for containers]:size:" \
+                "($help)*--default-ulimit=[Default ulimits for containers]:ulimit: " \
+                "($help)*--dns=[DNS server to use]:DNS: " \
+                "($help)*--dns-opt=[DNS options to use]:DNS option: " \
+                "($help)*--dns-search=[DNS search domains to use]:DNS search: " \
+                "($help)*--exec-opt=[Runtime execution options]:runtime execution options: " \
+                "($help)--exec-root=[Root directory for execution state files]:path:_directories" \
+                "($help)--experimental[Enable experimental features]" \
+                "($help)--fixed-cidr=[IPv4 subnet for fixed IPs]:IPv4 subnet: " \
+                "($help)--fixed-cidr-v6=[IPv6 subnet for fixed IPs]:IPv6 subnet: " \
+                "($help -G --group)"{-G=,--group=}"[Group for the unix socket]:group:_groups" \
+                "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
+                "($help)--icc[Enable inter-container communication]" \
+                "($help)--init[Run an init inside containers to forward signals and reap processes]" \
+                "($help)--init-path=[Path to the docker-init binary]:docker-init binary:_files" \
+                "($help)*--insecure-registry=[Enable insecure registry communication]:registry: " \
+                "($help)--ip=[Default IP when binding container ports]" \
+                "($help)--ip-forward[Enable net.ipv4.ip_forward]" \
+                "($help)--ip-masq[Enable IP masquerading]" \
+                "($help)--iptables[Enable addition of iptables rules]" \
+                "($help)--ipv6[Enable IPv6 networking]" \
+                "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
+                "($help)*--label=[Key=value labels]:label: " \
+                "($help)--live-restore[Enable live restore of docker when containers are still running]" \
+                "($help)--log-driver=[Default driver for container logs]:logging driver:__docker_complete_log_drivers" \
+                "($help)*--log-opt=[Default log driver options for containers]:log driver options:__docker_complete_log_options" \
+                "($help)--max-concurrent-downloads[Set the max concurrent downloads for each pull]" \
+                "($help)--max-concurrent-uploads[Set the max concurrent uploads for each push]" \
+                "($help)--max-download-attempts[Set the max download attempts for each pull]" \
+                "($help)--mtu=[Network MTU]:mtu:(0 576 1420 1500 9000)" \
+                "($help)--oom-score-adjust=[Set the oom_score_adj for the daemon]:oom-score:(-500)" \
+                "($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \
+                "($help)--raw-logs[Full timestamps without ANSI coloring]" \
+                "($help)*--registry-mirror=[Preferred Docker registry mirror]:registry mirror: " \
+                "($help)--seccomp-profile=[Path to seccomp profile]:path:_files -g \"*.json\"" \
+                "($help -s --storage-driver)"{-s=,--storage-driver=}"[Storage driver to use]:driver:(aufs btrfs devicemapper overlay overlay2 vfs zfs)" \
+                "($help)--selinux-enabled[Enable selinux support]" \
+                "($help)--shutdown-timeout=[Set the shutdown timeout value in seconds]:time: " \
+                "($help)*--storage-opt=[Storage driver options]:storage driver options: " \
+                "($help)--tls[Use TLS]" \
+                "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g \"*.(pem|crt)\"" \
+                "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g \"*.(pem|crt)\"" \
+                "($help)--tlskey=[Path to TLS key file]:Key file:_files -g \"*.(pem|key)\"" \
+                "($help)--tlsverify[Use TLS and verify the remote]" \
+                "($help)--userns-remap=[User/Group setting for user namespaces]:user\:group:->users-groups" \
+                "($help)--userland-proxy[Use userland proxy for loopback traffic]" \
+                "($help)--userland-proxy-path=[Path to the userland proxy binary]:binary:_files" \
+                "($help)--validate[Validate daemon configuration and exit]" && ret=0
+
+            case $state in
+                (cluster-store)
+                    if compset -P '*://'; then
+                        _message 'host:port' && ret=0
+                    else
+                        store=('consul' 'etcd' 'zk')
+                        _describe -t cluster-store "Cluster Store" store -qS "://" && ret=0
+                    fi
+                    ;;
+                (cluster-store-options)
+                    if compset -P '*='; then
+                        _files && ret=0
+                    else
+                        opts=('discovery.heartbeat' 'discovery.ttl' 'kv.cacertfile' 'kv.certfile' 'kv.keyfile' 'kv.path')
+                        _describe -t cluster-store-opts "Cluster Store Options" opts -qS "=" && ret=0
+                    fi
+                    ;;
+                (users-groups)
+                    if compset -P '*:'; then
+                        _groups && ret=0
+                    else
+                        _describe -t userns-default "default Docker user management" '(default)' && ret=0
+                        _users && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (events|info)
+            __docker_system_subcommand && ret=0
+            ;;
+        (image)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_image_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_image_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (images)
+            words[1]='ls'
+            __docker_image_subcommand && ret=0
+            ;;
+        (inspect)
+            local state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " \
+                "($help -s --size)"{-s,--size}"[Display total file sizes if the type is container]" \
+                "($help)--type=[Return JSON for specified type]:type:(container image network node plugin service volume)" \
+                "($help -)*: :->values" && ret=0
+
+            case $state in
+                (values)
+                    if [[ ${words[(r)--type=container]} == --type=container ]]; then
+                        __docker_complete_containers && ret=0
+                    elif [[ ${words[(r)--type=image]} == --type=image ]]; then
+                        __docker_complete_images && ret=0
+                    elif [[ ${words[(r)--type=network]} == --type=network ]]; then
+                        __docker_complete_networks && ret=0
+                    elif [[ ${words[(r)--type=node]} == --type=node ]]; then
+                        __docker_complete_nodes && ret=0
+                    elif [[ ${words[(r)--type=plugin]} == --type=plugin ]]; then
+                        __docker_complete_plugins && ret=0
+                    elif [[ ${words[(r)--type=service]} == --type=secrets ]]; then
+                        __docker_complete_secrets && ret=0
+                    elif [[ ${words[(r)--type=service]} == --type=service ]]; then
+                        __docker_complete_services && ret=0
+                    elif [[ ${words[(r)--type=volume]} == --type=volume ]]; then
+                        __docker_complete_volumes && ret=0
+                    else
+                        __docker_complete_containers
+                        __docker_complete_images
+                        __docker_complete_networks
+                        __docker_complete_nodes
+                        __docker_complete_plugins
+                        __docker_complete_secrets
+                        __docker_complete_services
+                        __docker_complete_volumes && ret=0
+                    fi
+                    ;;
+            esac
+            ;;
+        (login)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help -p --password)"{-p=,--password=}"[Password]:password: " \
+                "($help)--password-stdin[Read password from stdin]" \
+                "($help -u --username)"{-u=,--username=}"[Username]:username: " \
+                "($help -)1:server: " && ret=0
+            ;;
+        (logout)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help -)1:server: " && ret=0
+            ;;
+        (network)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_network_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_network_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (node)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_node_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_node_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (plugin)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_plugin_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_plugin_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (ps)
+            words[1]='ls'
+            __docker_container_subcommand && ret=0
+            ;;
+        (rmi)
+            words[1]='rm'
+            __docker_image_subcommand && ret=0
+            ;;
+        (search)
+            _arguments $(__docker_arguments) -A '-*' \
+                $opts_help \
+                "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_search_filters" \
+                "($help)--limit=[Maximum returned search results]:limit:(1 5 10 25 50)" \
+                "($help)--no-trunc[Do not truncate output]" \
+                "($help -):term: " && ret=0
+            ;;
+        (secret)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_secret_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_secret_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (service)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_service_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_service_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (stack)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_stack_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_stack_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (swarm)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_swarm_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_swarm_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (system)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_system_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_system_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (version)
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -f --format)"{-f=,--format=}"[Format the output using the given go template]:template: " && ret=0
+            ;;
+        (volume)
+            local curcontext="$curcontext" state
+            _arguments $(__docker_arguments) \
+                $opts_help \
+                "($help -): :->command" \
+                "($help -)*:: :->option-or-argument" && ret=0
+
+            case $state in
+                (command)
+                    __docker_volume_commands && ret=0
+                    ;;
+                (option-or-argument)
+                    curcontext=${curcontext%:*:*}:docker-${words[-1]}:
+                    __docker_volume_subcommand && ret=0
+                    ;;
+            esac
+            ;;
+        (help)
+            _arguments $(__docker_arguments) ":subcommand:__docker_commands" && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+_docker() {
+    # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
+    # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
+    if [[ $service != docker ]]; then
+        _call_function - _$service
+        return
+    fi
+
+    local curcontext="$curcontext" state line help="-h --help"
+    integer ret=1
+    typeset -A opt_args
+
+    _arguments $(__docker_arguments) -C \
+        "(: -)"{-h,--help}"[Print usage]" \
+        "($help)--config[Location of client config files]:path:_directories" \
+        "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \
+        "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \
+        "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \
+        "($help)--tls[Use TLS]" \
+        "($help)--tlscacert=[Trust certs signed only by this CA]:PEM file:_files -g "*.(pem|crt)"" \
+        "($help)--tlscert=[Path to TLS certificate file]:PEM file:_files -g "*.(pem|crt)"" \
+        "($help)--tlskey=[Path to TLS key file]:Key file:_files -g "*.(pem|key)"" \
+        "($help)--tlsverify[Use TLS and verify the remote]" \
+        "($help)--userland-proxy[Use userland proxy for loopback traffic]" \
+        "($help -v --version)"{-v,--version}"[Print version information and quit]" \
+        "($help -): :->command" \
+        "($help -)*:: :->option-or-argument" && ret=0
+
+    local host=${opt_args[-H]}${opt_args[--host]}
+    local config=${opt_args[--config]}
+    local docker_options="${host:+--host $host} ${config:+--config $config}"
+
+    case $state in
+        (command)
+            __docker_commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*:*}:docker-$words[1]:
+            __docker_subcommand && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+_dockerd() {
+    integer ret=1
+    words[1]='daemon'
+    __docker_subcommand && ret=0
+    return ret
+}
+
+_docker "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 4
+# indent-tabs-mode: nil
+# sh-basic-offset: 4
+# End:
+# vim: ft=zsh sw=4 ts=4 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/docker/docker.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/docker/docker.plugin.zsh
new file mode 100644 (file)
index 0000000..9c8ad8a
--- /dev/null
@@ -0,0 +1,39 @@
+alias dbl='docker build'
+alias dpu='docker pull'
+alias dtop='docker top'
+
+# docker containers
+alias dcin='docker container inspect'
+alias dlo='docker container logs'
+alias dcls='docker container ls'
+alias dclsa='docker container ls -a'
+alias dpo='docker container port'
+alias dr='docker container run'
+alias drit='docker container run -it'
+alias drm='docker container rm'
+alias 'drm!'='docker container rm -f'
+alias dst='docker container start'
+alias dstp='docker container stop'
+alias dxc='docker container exec'
+alias dxcit='docker container exec -it'
+
+# docker images
+alias dib='docker image build'
+alias dii='docker image inspect'
+alias dils='docker image ls'
+alias dipu='docker image push'
+alias dirm='docker image rm'
+alias dit='docker image tag'
+
+# docker network
+alias dnc='docker network create'
+alias dncn='docker network connect'
+alias dndcn='docker network disconnect'
+alias dni='docker network inspect'
+alias dnls='docker network ls'
+alias dnrm='docker network rm'
+
+# docker volume
+alias dvi='docker volume inspect'
+alias dvls='docker volume ls'
+alias dvprune='docker volume prune'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/doctl/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/doctl/README.md
new file mode 100644 (file)
index 0000000..a81e90b
--- /dev/null
@@ -0,0 +1,9 @@
+# Doctl
+
+This plugin provides completion for [Doctl](https://github.com/digitalocean/doctl).
+
+To use it add doctl to the plugins array in your zshrc file.
+
+```bash
+plugins=(... doctl)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/doctl/doctl.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/doctl/doctl.plugin.zsh
new file mode 100644 (file)
index 0000000..d23ed08
--- /dev/null
@@ -0,0 +1,9 @@
+# Autocompletion for doctl, the command line tool for DigitalOcean service
+#
+# doctl project: https://github.com/digitalocean/doctl
+#
+# Author: https://github.com/HalisCz
+
+if [ $commands[doctl] ]; then
+  source <(doctl completion zsh)
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dotenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dotenv/README.md
new file mode 100644 (file)
index 0000000..ab9d329
--- /dev/null
@@ -0,0 +1,92 @@
+# dotenv
+
+Automatically load your project ENV variables from `.env` file when you `cd` into project root directory.
+
+Storing configuration in the environment is one of the tenets of a [twelve-factor app](https://www.12factor.net). Anything that is likely to change between deployment environments, such as resource handles for databases or credentials for external services, should be extracted from the code into environment variables.
+
+To use it, add `dotenv` to the plugins array in your zshrc file:
+
+```sh
+plugins=(... dotenv)
+```
+
+## Usage
+
+Create `.env` file inside your project root directory and put your ENV variables there.
+
+For example:
+
+```sh
+export AWS_S3_TOKEN=d84a83539134f28f412c652b09f9f98eff96c9a
+export SECRET_KEY=7c6c72d959416d5aa368a409362ec6e2ac90d7f
+export MONGO_URI=mongodb://127.0.0.1:27017
+export PORT=3001
+```
+
+`export` is optional. This format works as well:
+
+```sh
+AWS_S3_TOKEN=d84a83539134f28f412c652b09f9f98eff96c9a
+SECRET_KEY=7c6c72d959416d5aa368a409362ec6e2ac90d7f
+MONGO_URI=mongodb://127.0.0.1:27017
+PORT=3001
+```
+
+You can even mix both formats, although it's probably a bad idea.
+
+## Settings
+
+### ZSH_DOTENV_FILE
+
+You can also modify the name of the file to be loaded with the variable `ZSH_DOTENV_FILE`.
+If the variable isn't set, the plugin will default to use `.env`.
+For example, this will make the plugin look for files named `.dotenv` and load them:
+
+```zsh
+# in ~/.zshrc, before Oh My Zsh is sourced:
+ZSH_DOTENV_FILE=.dotenv
+```
+
+### ZSH_DOTENV_PROMPT
+
+Set `ZSH_DOTENV_PROMPT=false` in your zshrc file if you don't want the confirmation message.
+You can also choose the `Always` option when prompted to always allow sourcing the .env file
+in that directory. See the next section for more details.
+
+### ZSH_DOTENV_ALLOWED_LIST, ZSH_DOTENV_DISALLOWED_LIST
+
+The default behavior of the plugin is to always ask whether to source a dotenv file. There's
+a **Y**es, **N**o, **A**lways and N**e**ver option. If you choose Always, the directory of the .env file
+will be added to an allowed list; if you choose Never, it will be added to a disallowed list.
+If a directory is found in either of those lists, the plugin won't ask for confirmation and will
+instead either source the .env file or proceed without action respectively.
+
+The allowed and disallowed lists are saved by default in `$ZSH_CACHE_DIR/dotenv-allowed.list` and
+`$ZSH_CACHE_DIR/dotenv-disallowed.list` respectively. If you want to change that location,
+change the `$ZSH_DOTENV_ALLOWED_LIST` and `$ZSH_DOTENV_DISALLOWED_LIST` variables, like so:
+
+```zsh
+# in ~/.zshrc, before Oh My Zsh is sourced:
+ZSH_DOTENV_ALLOWED_LIST=/path/to/dotenv/allowed/list
+ZSH_DOTENV_DISALLOWED_LIST=/path/to/dotenv/disallowed/list
+```
+
+The file is just a list of directories, separated by a newline character. If you want
+to change your decision, just edit the file and remove the line for the directory you want to
+change.
+
+NOTE: if a directory is found in both the allowed and disallowed lists, the disallowed list
+takes preference, _i.e._ the .env file will never be sourced.
+
+## Version Control
+
+**It's strongly recommended to add `.env` file to `.gitignore`**, because usually it contains sensitive information such as your credentials, secret keys, passwords etc. You don't want to commit this file, it's supposed to be local only.
+
+## Disclaimer
+
+This plugin only sources the `.env` file. Nothing less, nothing more. It doesn't do any checks. It's designed to be the fastest and simplest option. You're responsible for the `.env` file content. You can put some code (or weird symbols) there, but do it on your own risk. `dotenv` is the basic tool, yet it does the job.
+
+If you need more advanced and feature-rich ENV management, check out these awesome projects:
+
+* [direnv](https://github.com/direnv/direnv)
+* [zsh-autoenv](https://github.com/Tarrasch/zsh-autoenv)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dotenv/dotenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dotenv/dotenv.plugin.zsh
new file mode 100644 (file)
index 0000000..46cd4b1
--- /dev/null
@@ -0,0 +1,67 @@
+## Settings
+
+# Filename of the dotenv file to look for
+: ${ZSH_DOTENV_FILE:=.env}
+
+# Path to the file containing allowed paths
+: ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"}
+: ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"}
+
+
+## Functions
+
+source_env() {
+  if [[ ! -f "$ZSH_DOTENV_FILE" ]]; then
+    return
+  fi
+
+  if [[ "$ZSH_DOTENV_PROMPT" != false ]]; then
+    local confirmation dirpath="${PWD:A}"
+
+    # make sure there is an (dis-)allowed file
+    touch "$ZSH_DOTENV_ALLOWED_LIST"
+    touch "$ZSH_DOTENV_DISALLOWED_LIST"
+
+    # early return if disallowed
+    if command grep -Fx -q "$dirpath" "$ZSH_DOTENV_DISALLOWED_LIST" &>/dev/null; then
+      return
+    fi
+
+    # check if current directory's .env file is allowed or ask for confirmation
+    if ! command grep -Fx -q "$dirpath" "$ZSH_DOTENV_ALLOWED_LIST" &>/dev/null; then
+      # get cursor column and print new line before prompt if not at line beginning
+      local column
+      echo -ne "\e[6n" > /dev/tty
+      read -t 1 -s -d R column < /dev/tty
+      column="${column##*\[*;}"
+      [[ $column -eq 1 ]] || echo
+
+      # print same-line prompt and output newline character if necessary
+      echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([Y]es/[n]o/[a]lways/n[e]ver) "
+      read -k 1 confirmation
+      [[ "$confirmation" = $'\n' ]] || echo
+
+      # check input
+      case "$confirmation" in
+        [nN]) return ;;
+        [aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;;
+        [eE]) echo "$dirpath" >> "$ZSH_DOTENV_DISALLOWED_LIST"; return ;;
+        *) ;; # interpret anything else as a yes
+      esac
+    fi
+  fi
+
+  # test .env syntax
+  zsh -fn $ZSH_DOTENV_FILE || {
+    echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2
+    return 1
+  }
+
+  setopt localoptions allexport
+  source $ZSH_DOTENV_FILE
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook chpwd source_env
+
+source_env
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dotnet/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/dotnet/README.md
new file mode 100644 (file)
index 0000000..87dfd8f
--- /dev/null
@@ -0,0 +1,24 @@
+# .NET Core CLI plugin
+
+This plugin provides completion and useful aliases for [.NET Core CLI](https://dotnet.microsoft.com/).
+
+To use it, add `dotnet` to the plugins array in your zshrc file.
+
+```
+plugins=(... dotnet)
+```
+
+## Aliases
+
+| Alias | Command          | Description                                                       |
+|-------|------------------|-------------------------------------------------------------------|
+| dn    | dotnet new       | Create a new .NET project or file.                                |
+| dr    | dotnet run       | Build and run a .NET project output.                              |
+| dt    | dotnet test      | Run unit tests using the test runner specified in a .NET project. |
+| dw    | dotnet watch     | Watch for source file changes and restart the dotnet command.     |
+| dwr   | dotnet watch run | Watch for source file changes and restart the `run` command.      |
+| ds    | dotnet sln       | Modify Visual Studio solution files.                              |
+| da    | dotnet add       | Add a package or reference to a .NET project.                     |
+| dp    | dotnet pack      | Create a NuGet package.                                           |
+| dng   | dotnet nuget     | Provides additional NuGet commands.                               |
+| db    | dotnet build     | Build a .NET project                                              |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/dotnet/dotnet.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/dotnet/dotnet.plugin.zsh
new file mode 100644 (file)
index 0000000..8ea31cd
--- /dev/null
@@ -0,0 +1,33 @@
+# This scripts is copied from (MIT License):
+# https://github.com/dotnet/toolset/blob/master/scripts/register-completions.zsh
+
+_dotnet_zsh_complete() 
+{
+  local completions=("$(dotnet complete "$words")")
+
+  # If the completion list is empty, just continue with filename selection
+  if [ -z "$completions" ]
+  then
+    _arguments '*::arguments: _normal'
+    return
+  fi
+
+  # This is not a variable assignment, don't remove spaces!
+  _values = "${(ps:\n:)completions}"
+}
+
+compdef _dotnet_zsh_complete dotnet
+
+# Aliases bellow are here for backwards compatibility
+# added by Shaun Tabone (https://github.com/xontab) 
+
+alias dn='dotnet new'
+alias dr='dotnet run'
+alias dt='dotnet test'
+alias dw='dotnet watch'
+alias dwr='dotnet watch run'
+alias ds='dotnet sln'
+alias da='dotnet add'
+alias dp='dotnet pack'
+alias dng='dotnet nuget'
+alias db='dotnet build'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/droplr/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/droplr/README.md
new file mode 100644 (file)
index 0000000..6daa254
--- /dev/null
@@ -0,0 +1,19 @@
+# droplr
+
+Use [Droplr](https://droplr.com/) from the command line to upload files and shorten
+links. It needs to have [Droplr.app](https://droplr.com/apps) installed and logged
+in. MacOS only.
+
+To use it, add `droplr` to the `$plugins` variable in your zshrc file:
+
+```zsh
+plugins=(... droplr)
+```
+
+Author: [Fabio Fernandes](https://github.com/fabiofl)
+
+## Examples
+
+- Upload a file: `droplr ./path/to/file/`
+
+- Shorten a link: `droplr https://example.com`
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/droplr/droplr.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/droplr/droplr.plugin.zsh
new file mode 100644 (file)
index 0000000..af0a212
--- /dev/null
@@ -0,0 +1,15 @@
+# Only compatible with MacOS
+[[ "$OSTYPE" == darwin* ]] || return
+
+droplr() {
+    if [[ $# -eq 0 ]]; then
+        echo You need to specify a parameter. >&2
+        return 1
+    fi
+
+    if [[ "$1" =~ ^https?:// ]]; then
+        osascript -e 'tell app "Droplr" to shorten "'"$1"'"'
+    else
+        open -ga /Applications/Droplr.app "$1"
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/drush/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/drush/README.md
new file mode 100644 (file)
index 0000000..29b429e
--- /dev/null
@@ -0,0 +1,66 @@
+# Drush
+
+This plugin adds aliases and functions for [Drush](https://www.drush.org), a command-line shell
+and Unix scripting interface for Drupal. It also adds completion for the `drush` command.
+
+To enable it, add `drush` to the plugins array in zshrc file:
+
+```zsh
+plugins=(... drush)
+```
+
+## Aliases
+
+| Alias   | Command                                                     | Description                                                          |
+| ------- | ----------------------------------------------------------- | -------------------------------------------------------------------- |
+| `dr`    | `drush`                                                     | Display drush help                                                   |
+| `drca`  | `drush cc all`                                              | _(Deprecated in Drush 8)_ Clear all drupal caches                    |
+| `drcb`  | `drush cc block`                                            | _(Deprecated in Drush 8)_ Clear block cache                          |
+| `drcex` | `drush config:export -y`                                    | Export Drupal configuration to a directory                           |
+| `drcg`  | `drush cc registry`                                         | _(Deprecated in Drush 8)_ Clear registry cache                       |
+| `drcim` | `drush config:import -y`                                    | Import config from a config directory                                |
+| `drcj`  | `drush cc css-js`                                           | Clear css-js cache                                                   |
+| `drcm`  | `drush cc menu`                                             | Clear menu cache                                                     |
+| `drcml` | `drush cc module-list`                                      | Clear module-list cache                                              |
+| `drcr`  | `drush core-cron`                                           | Run all cron hooks in all active modules for specified site          |
+| `drct`  | `drush cc theme-registry`                                   | Clear theme-registry cache                                           |
+| `drcv`  | `drush cc views`                                            | Clear views cache _(make sure that the views module is enabled)_     |
+| `drdmp` | `drush drush sql-dump --ordered-dump --result-file=dumpsql` | Backup database in a new dump.sql file                               |
+| `drf`   | `drush features`                                            | Display features status                                              |
+| `drfr`  | `drush features-revert -y`                                  | Revert a feature module on your site                                 |
+| `drfra` | `drush features-revert-all`                                 | Revert all enabled feature module on your site                       |
+| `drfu`  | `drush features-update -y`                                  | Update a feature module on your site                                 |
+| `drif`  | `drush image-flush --all`                                   | Flush all derived images                                             |
+| `drpm`  | `drush pm-list --type=module`                               | Show a list of available modules                                     |
+| `drst`  | `drush core-status`                                         | Provides a birds-eye view of the current Drupal installation, if any |
+| `druli` | `drush user:login`                                          | Display a one time login link for user ID 1, or another user         |
+| `drup`  | `drush updatedb`                                            | Apply any database updates required (as with running update.php)     |
+| `drups` | `drush updatedb-status`                                     | List any pending database updates                                    |
+| `drv`   | `drush version`                                             | Show drush version                                                   |
+| `drvd`  | `drush variable-del`                                        | Delete a variable                                                    |
+| `drvg`  | `drush variable-get`                                        | Get a list of some or all site variables and values                  |
+| `drvs`  | `drush variable-set`                                        | Set a variable                                                       |
+| `drws`  | `drush watchdog:show`                                       | Show watchdog messages                                               |
+| `drwse` | `drush watchdog:show --extended`                            | Show watchdog messages with extended information                     |
+| `drwst` | `drush watchdog:tail`                                       | Tail watchdog messages                                              |
+
+## Functions
+
+- `dren`: download and enable one or more extensions (modules or themes). Must be
+  invoked with one or more parameters, e.g.: `dren devel` or `dren devel module_filter views`.
+
+- `drf`: edit drushrc, site alias, and Drupal settings.php files.
+  Can be invoked with one or without parameters, e.g.: `drf 1`.
+
+- `dris`: disable one or more extensions (modules or themes). Must be invoked with
+  one or more parameters, e.g.: `dris devel` or `dris devel module_filter views`.
+
+- `drpu`: uninstall one or more modules. Must be invoked with one or more
+  parameters, e.g.: `drpu devel` or `drpu devel module_filter views`.
+
+- `drnew`: creates a brand new drupal website. Note: as soon as the installation
+  is complete, `drush` will print a username and a random password into the terminal:
+
+  ```text
+  Installation complete.  User name: admin  User password: cf7t8yqNEm
+  ```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/drush/drush.complete.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/drush/drush.complete.sh
new file mode 100644 (file)
index 0000000..38b882e
--- /dev/null
@@ -0,0 +1,50 @@
+# BASH completion script for Drush.
+#
+# Place this in your /etc/bash_completion.d/ directory or source it from your
+# ~/.bash_completion or ~/.bash_profile files.  Alternatively, source
+# examples/example.bashrc instead, as it will automatically find and source
+# this file.
+#
+# If you're using ZSH instead of BASH, add the following to your ~/.zshrc file
+# and source it.
+#
+#   autoload bashcompinit
+#   bashcompinit
+#   source /path/to/your/drush.complete.sh
+
+# Ensure drush is available.
+which drush > /dev/null || alias drush &> /dev/null || return
+
+__drush_ps1() {
+  f="${TMPDIR:-/tmp/}/drush-env-${USER}/drush-drupal-site-$$"
+  if [ -f $f ]
+  then
+    __DRUPAL_SITE=$(cat "$f")
+  else
+    __DRUPAL_SITE="$DRUPAL_SITE"
+  fi
+
+  # Set DRUSH_PS1_SHOWCOLORHINTS to a non-empty value and define a
+  # __drush_ps1_colorize_alias() function for color hints in your Drush PS1
+  # prompt. See example.prompt.sh for an example implementation.
+  if [ -n "${__DRUPAL_SITE-}" ] && [ -n "${DRUSH_PS1_SHOWCOLORHINTS-}" ]; then
+    __drush_ps1_colorize_alias
+  fi
+
+  [[ -n "$__DRUPAL_SITE" ]] && printf "${1:- (%s)}" "$__DRUPAL_SITE"
+}
+
+# Completion function, uses the "drush complete" command to retrieve
+# completions for a specific command line COMP_WORDS.
+_drush_completion() {
+  # Set IFS to newline (locally), since we only use newline separators, and
+  # need to retain spaces (or not) after completions.
+  local IFS=$'\n'
+  # The '< /dev/null' is a work around for a bug in php libedit stdin handling.
+  # Note that libedit in place of libreadline in some distributions. See:
+  # https://bugs.launchpad.net/ubuntu/+source/php5/+bug/322214
+  COMPREPLY=( $(drush --early=includes/complete.inc "${COMP_WORDS[@]}" < /dev/null 2> /dev/null) )
+}
+
+# Register our completion function. We include common short aliases for Drush.
+complete -o bashdefault -o default -o nospace -F _drush_completion d dr drush drush5 drush6 drush7 drush8 drush.php
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/drush/drush.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/drush/drush.plugin.zsh
new file mode 100644 (file)
index 0000000..48e8ddb
--- /dev/null
@@ -0,0 +1,107 @@
+# Functions
+function dren() {
+  drush en "$@" -y
+}
+
+function dris() {
+  drush pm-disable "$@" -y
+}
+
+function drpu() {
+  drush pm-uninstall "$@" -y
+}
+
+function drf() {
+  if [[ -z "$1" ]] then
+    drush core-config
+  else
+    drush core-config --choice=$1
+  fi
+}
+
+function drfi() {
+  case "$1" in
+  fields) drush field-info fields ;;
+  types) drush field-info types ;;
+  *) drush field-info ;;
+  esac
+}
+
+function drnew() {
+  (
+    cd
+    echo "Website's name: "
+    read WEBSITE_NAME
+
+    HOST=http://$(hostname -i)/
+
+    if [[ $WEBSITE_NAME == "" ]] then
+      MINUTES=$(date +%M:%S)
+      WEBSITE_NAME="Drupal-$MINUTES"
+      echo "Your website will be named: $WEBSITE_NAME"
+    fi
+
+    drush dl drupal --drupal-project-rename=$WEBSITE_NAME
+
+    echo "Type your localhost directory: (Leave empty for /var/www/html/)"
+    read DIRECTORY
+
+    if [[ $DIRECTORY == "" ]] then
+      DIRECTORY="/var/www/html/"
+    fi
+
+    echo "Moving to $DIRECTORY$WEBSITE_NAME"
+    sudo mv $WEBSITE_NAME $DIRECTORY
+    cd $DIRECTORY$WEBSITE_NAME
+
+    echo "Database's user: "
+    read DATABASE_USR
+    echo "Database's password: "
+    read -s DATABASE_PWD
+    echo "Database's name for your project: "
+    read DATABASE
+
+    DB_URL="mysql://$DATABASE_USR:$DATABASE_PWD@localhost/$DATABASE"
+    drush site-install standard --db-url=$DB_URL --site-name=$WEBSITE_NAME
+
+    open_command $HOST$WEBSITE_NAME
+    echo "Done"
+  )
+}
+
+# Aliases
+alias dr="drush"
+alias drca="drush cc all" # Deprecated for Drush 8
+alias drcb="drush cc block" # Deprecated for Drush 8
+alias drcex="drush config:export -y"
+alias drcg="drush cc registry" # Deprecated for Drush 8
+alias drcim="drush config:import -y"
+alias drcj="drush cc css-js"
+alias drcm="drush cc menu"
+alias drcml="drush cc module-list"
+alias drcr="drush core-cron"
+alias drct="drush cc theme-registry"
+alias drcv="drush cc views"
+alias drdmp="drush sql-dump --ordered-dump --result-file=dump.sql"
+alias drf="drush features"
+alias drfr="drush features-revert -y"
+alias drfra="drush features-revert-all"
+alias drfu="drush features-update -y"
+alias drif="drush image-flush --all"
+alias drpm="drush pm-list --type=module"
+alias drst="drush core-status"
+alias druli="drush user:login"
+alias drup="drush updatedb"
+alias drups="drush updatedb-status"
+alias drv="drush version"
+alias drvd="drush variable-del"
+alias drvg="drush variable-get"
+alias drvs="drush variable-set"
+alias drws="drush watchdog:show"
+alias drwse="drush watchdog:show --extended"
+alias drwst="drush watchdog:tail"
+
+# Enable drush autocomplete support
+autoload bashcompinit
+bashcompinit
+source $(dirname $0)/drush.complete.sh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/eecms/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/eecms/README.md
new file mode 100644 (file)
index 0000000..c538355
--- /dev/null
@@ -0,0 +1,11 @@
+# eecms plugin
+
+This plugin adds auto-completion of console commands for [`eecms`](https://github.com/ExpressionEngine/ExpressionEngine).
+
+To use it, add `eecms` to the plugins array of your `.zshrc` file:
+```
+plugins=(... eecms)
+```
+
+It also adds the alias `eecms` which finds the eecms file in the current project
+and runs it with php.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/eecms/eecms.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/eecms/eecms.plugin.zsh
new file mode 100644 (file)
index 0000000..ee10fbb
--- /dev/null
@@ -0,0 +1,20 @@
+# ExpressionEngine CMS basic command completion
+
+_eecms_console () {
+    echo "php $(find . -maxdepth 3 -mindepth 1 -name 'eecms' -type f | head -n 1)"
+}
+
+_eecms_get_command_list () {
+    `_eecms_console` | sed "/Available commands/,/^/d" | sed "s/[[:space:]].*//g"
+}
+
+_eecms () {
+    compadd `_eecms_get_command_list`
+}
+
+compdef _eecms '`_eecms_console`'
+compdef _eecms 'system/ee/eecms'
+compdef _eecms eecms
+
+#Alias
+alias eecms='`_eecms_console`'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/README.md
new file mode 100644 (file)
index 0000000..c8e33b5
--- /dev/null
@@ -0,0 +1,30 @@
+# Emacs plugin
+
+This plugin utilizes the Emacs daemon capability, allowing the user to quickly open frames, whether they are opened in a terminal via a ssh connection, or X frames opened on the same host. The plugin also provides some aliases for such operations.
+
+- You don't have the cost of starting Emacs all the time anymore
+- Opening a file is as fast as Emacs does not have anything else to do.
+- You can share opened buffered across opened frames.
+- Configuration changes made at runtime are applied to all frames.
+
+**NOTE:** requires Emacs 24 and newer.
+
+To use it, add emacs to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... emacs)
+```
+
+## Aliases
+
+The plugin uses a custom launcher (which we'll call here `$EMACS_LAUNCHER`) that is just a wrapper around [`emacsclient`](https://www.emacswiki.org/emacs/EmacsClient).
+
+| Alias  | Command                                            | Description                                                    |
+|--------|----------------------------------------------------|----------------------------------------------------------------|
+| emacs  | `$EMACS_LAUNCHER --no-wait`                        | Opens a temporary emacsclient frame                            |
+| e      | `emacs`                                            | Same as emacs alias                                            |
+| te     | `$EMACS_LAUNCHER -nw`                              | Open terminal emacsclient                                      |
+| eeval  | `$EMACS_LAUNCHER --eval`                           | Same as `M-x eval` but from outside Emacs                      |
+| eframe | `emacsclient --alternate-editor "" --create-frame` | Create new X frame                                             |
+| efile  | -                                                  | Print the path to the file open in the current buffer          |
+| ecd    | -                                                  | Print the directory of the file open in the the current buffer |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/emacs.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/emacs.plugin.zsh
new file mode 100644 (file)
index 0000000..fede5b0
--- /dev/null
@@ -0,0 +1,68 @@
+# Emacs 23 daemon capability is a killing feature.
+# One emacs process handles all your frames whether
+# you use a frame opened in a terminal via a ssh connection or X frames
+# opened on the same host.
+
+# Benefits are multiple
+# - You don't have the cost of starting Emacs all the time anymore
+# - Opening a file is as fast as Emacs does not have anything else to do.
+# - You can share opened buffered across opened frames.
+# - Configuration changes made at runtime are applied to all frames.
+
+# Require emacs version to be minimum 24
+autoload -Uz is-at-least
+is-at-least 24 "${${(Az)"$(emacsclient --version 2>/dev/null)"}[2]}" || return 0
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+# Path to custom emacsclient launcher
+export EMACS_PLUGIN_LAUNCHER="${0:A:h}/emacsclient.sh"
+
+# set EDITOR if not already defined.
+export EDITOR="${EDITOR:-${EMACS_PLUGIN_LAUNCHER}}"
+
+alias emacs="$EMACS_PLUGIN_LAUNCHER --no-wait"
+alias e=emacs
+# open terminal emacsclient
+alias te="$EMACS_PLUGIN_LAUNCHER -nw"
+
+# same than M-x eval but from outside Emacs.
+alias eeval="$EMACS_PLUGIN_LAUNCHER --eval"
+# create a new X frame
+alias eframe='emacsclient --alternate-editor "" --create-frame'
+
+# Emacs ANSI Term tracking
+if [[ -n "$INSIDE_EMACS" ]]; then
+  chpwd_emacs() { print -P "\033AnSiTc %d"; }
+  print -P "\033AnSiTc %d"    # Track current working directory
+  print -P "\033AnSiTu %n"    # Track username
+
+  # add chpwd hook
+  autoload -Uz add-zsh-hook
+  add-zsh-hook chpwd chpwd_emacs
+fi
+
+# Write to standard output the path to the file
+# opened in the current buffer.
+function efile {
+  local cmd="(buffer-file-name (window-buffer))"
+  local file="$("$EMACS_PLUGIN_LAUNCHER" --eval "$cmd" | tr -d \")"
+
+  if [[ -z "$file" ]]; then
+    echo "Can't deduce current buffer filename." >&2
+    return 1
+  fi
+
+  echo "$file"
+}
+
+# Write to standard output the directory of the file
+# opened in the the current buffer
+function ecd {
+  local file
+  file="$(efile)" || return $?
+  echo "${file:h}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/emacsclient.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emacs/emacsclient.sh
new file mode 100755 (executable)
index 0000000..96893c9
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+emacsfun() {
+  local cmd frames
+
+  # Build the Emacs Lisp command to check for suitable frames
+  # See https://www.gnu.org/software/emacs/manual/html_node/elisp/Frames.html#index-framep
+  case "$*" in
+  *-t*|*--tty*|*-nw*) cmd="(memq 't (mapcar 'framep (frame-list)))" ;; # if != nil, there are tty frames
+  *) cmd="(delete 't (mapcar 'framep (frame-list)))" ;; # if != nil, there are graphical terminals (x, w32, ns)
+  esac
+
+  # Check if there are suitable frames
+  frames="$(emacsclient -a '' -n -e "$cmd" 2>/dev/null |sed 's/.*\x07//g' )"
+
+  # Only create another X frame if there isn't one present
+  if [ -z "$frames" -o "$frames" = nil ]; then
+    emacsclient --alternate-editor "" --create-frame "$@"
+    return $?
+  fi
+
+  emacsclient --alternate-editor "" "$@"
+}
+
+# Adapted from https://github.com/davidshepherd7/emacs-read-stdin/blob/master/emacs-read-stdin.sh
+# If the second argument is - then write stdin to a tempfile and open the
+# tempfile. (first argument will be `--no-wait` passed in by the plugin.zsh)
+if [ $# -ge 2 -a "$2" = "-" ]; then
+  # Create a tempfile to hold stdin
+  tempfile="$(mktemp --tmpdir emacs-stdin-$USERNAME.XXXXXXX 2>/dev/null \
+    || mktemp -t emacs-stdin-$USERNAME)" # support BSD mktemp
+  # Redirect stdin to the tempfile
+  cat - > "$tempfile"
+  # Reset $2 to the tempfile so that "$@" works as expected
+  set -- "$1" "$tempfile" "${@:3}"
+fi
+
+emacsfun "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/README.md
new file mode 100644 (file)
index 0000000..419704a
--- /dev/null
@@ -0,0 +1,33 @@
+# Ember CLI
+
+This plugin adds completion and aliases for using [`ember-cli`](https://cli.emberjs.com/).
+
+To use it, add `ember-cli` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ember-cli)
+```
+
+## Aliases
+
+| Alias | Command              |
+| ----- | -------------------- |
+| `ea`  | `ember addon`        |
+| `eb`  | `ember build`        |
+| `ed`  | `ember destroy`      |
+| `eg`  | `ember generate`     |
+| `eh`  | `ember help`         |
+| `ei`  | `ember install`      |
+| `ein` | `ember init`         |
+| `es`  | `ember serve`        |
+| `et`  | `ember test`         |
+| `ets` | `ember test --serve` |
+| `eu`  | `ember update`       |
+| `ev`  | `ember version`      |
+
+## Maintainers
+
+- [BilalBudhani](https://github.com/BilalBudhani)
+- [eubenesa](https://github.com/eubenesa)
+- [scottkidder](https://github.com/scottkidder]
+- [t-sauer](https://www.github.com/t-sauer)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/_ember-cli b/stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/_ember-cli
new file mode 100644 (file)
index 0000000..41c3c1f
--- /dev/null
@@ -0,0 +1,189 @@
+#compdef ember
+
+local curcontext="$curcontext" state line ret=1
+
+_arguments -C -A "--version" -A "--help" \
+  '(- 1 *)--help' \
+  '(- 1 *)--version' \
+  '1: :->cmds' \
+  '*:: :->args' && ret=0
+
+case $state in
+  cmds)
+    _values "ember command" \
+      "addon[Generates a new folder structure for building an addon, complete with test harness]" \
+      "asset-sizes[Shows the sizes of your asset files]" \
+      "build[Builds your app and places it into the output path (dist/ by default)]" \
+      "destroy[Destroys code generated by generate command]" \
+      "generate[Generates new code from blueprints]" \
+      "help[Outputs the usage instructions for all commands or the provided command]" \
+      "init[Creates a new ember-cli project in the current folder]" \
+      "install[Installs an ember-cli addon from npm]" \
+      "new[Creates a new directory and runs ember init in it]" \
+      "serve[Builds and serves your app, rebuilding on file changes]" \
+      "test[Runs your app's test suite]" \
+      "version[outputs ember-cli version]"
+    ret=0
+    ;;
+  args)
+    case $line[1] in
+      help)
+        _values 'commands' \
+          'addon' \
+          'asset-sizes' \
+          'build' \
+          'destroy' \
+          'generate' \
+          'help' \
+          'init' \
+          'install' \
+          'new' \
+          'serve' \
+          'test' \
+          'vesion' && ret=0
+        ;;
+      addon)
+        _arguments \
+          '(--blueprint)--blueprint=-' \
+          '(--directory)--directory=-' \
+          '(--dry-run)--dry-run' \
+          '(--skip-bower)--skip-bower' \
+          '(--skip-git)--skip-git' \
+          '(--skip-npm)--skip-npm' \
+          '(--verbose)--verbose'
+        ;;
+      asset-sizes)
+        _arguments \
+          '(--output-path)--output-path=-'
+        ;;
+      build)
+        _arguments \
+          '(--environment)--environment=-' \
+          '(--output-path)--output-path=-' \
+          '(--output-path)--suppress-sizes' \
+          '(--watch)--watch' \
+          '(--watcher)--watcher=-' \
+          '(-dev)-dev' \
+          '(-prod)-prod'
+        ;;
+      destroy|generate)
+        _values 'arguments' \
+          '(--classic)--classic' \
+          '(--dry-run)--dry-run' \
+          '(--dummy)--dummy' \
+          '(--in-repo-addon)--in-repo-addon-=' \
+          '(--pod)--pod' \
+          '(--verbose)--verbose' && ret=0
+        _values 'blueprints' \
+          'acceptance-test' \
+          'adapter' \
+          'adapter-test' \
+          'component' \
+          'component-addon' \
+          'component-test' \
+          'controller' \
+          'controller-test' \
+          'helper' \
+          'helper-addon' \
+          'helper-test' \
+          'initializer' \
+          'initializer-addon' \
+          'initializer-test' \
+          'instance-initializer' \
+          'instance-initializer-addon' \
+          'instance-initializer-test' \
+          'mixin' \
+          'mixin-test' \
+          'model' \
+          'model-test' \
+          'resource' \
+          'route' \
+          'route-addon' \
+          'route-test' \
+          'serializer' \
+          'serializer-test' \
+          'service' \
+          'service-test' \
+          'template' \
+          'test-helper' \
+          'transform' \
+          'transform-test' \
+          'util' \
+          'util-test' \
+          'view' \
+          'view-test' \
+          'addon' \
+          'addon-import' \
+          'app' \
+          'blueprint' \
+          'http-mock' \
+          'http-proxy' \
+          'in-repo-addon' \
+          'lib' \
+          'server' \
+          'vendor-shim' && ret=0
+        ;;
+      init)
+        _arguments \
+          '(--blueprint)--blueprint=-' \
+          '(--name)--name=-' \
+          '(--dry-run)--dry-run' \
+          '(--skip-bower)--skip-bower' \
+          '(--skip-npm)--skip-npm' \
+          '(--verbose)--verbose'
+        ;;
+      install)
+        _arguments \
+          '(--save-dev)--save-dev' \
+          '(--save)--save'
+        ;;
+      new)
+        _arguments \
+          '(--blueprint)--blueprint=-' \
+          '(--directory)--directory=-' \
+          '(--dry-run)--dry-run' \
+          '(--skip-bower)--skip-bower' \
+          '(--skip-git)--skip-git' \
+          '(--skip-npm)--skip-npm' \
+          '(--verbose)--verbose'
+        ;;
+      serve)
+        _arguments \
+          '(--port)--port=-[To use a port different than 4200. Pass 0 to automatically pick an available port.]' \
+          '(--host)--host=-[Listens on all interfaces by default]' \
+          '(--proxy)--proxy=-' \
+          '(--secure-proxy)--secure-proxy[Set to false to proxy self-signed SSL certificates]' \
+          '(--transparent-proxy)--transparent-proxy[Set to false to omit x-forwarded-* headers when proxying]' \
+          '(--watcher)--watcher=-' \
+          '(--live-reload)--live-reload' \
+          '(--live-reload-host)--live-reload-host=-[Defaults to host]' \
+          '(--live-reload-base-url)--live-reload-base-url=-[Defaults to baseURL]' \
+          '(--live-reload-port)--live-reload-port=-[Defaults to port number within \[49152...65535\]]' \
+          '(--environment)--environment=-' \
+          '(--output-path)--output-path=-' \
+          '(--ssl)--ssl' \
+          '(--ssl-key)--ssl-key=-' \
+          '(--ssl-cert)--ssl-cert=-'
+        ;;
+      test)
+        _arguments \
+          '(--environment)--environment=-' \
+          '(--config-file)--config-file=-' \
+          '(--server)--server' \
+          '(--host)--host=-' \
+          '(--test-port)--test-port=-[The test port to use when running with --server.]' \
+          '(--filter)--filter=-[A string to filter tests to run]' \
+          '(--module)--module=-[The name of a test module to run]' \
+          '(--watcher)--watcher=-' \
+          '(--launch)--launch=-[A comma separated list of browsers to launch for tests.]' \
+          '(--reporter)--reporter=-[Test reporter to use \[tap|dot|xunit\] (default: tap)]' \
+          '(--silent)--silent[Suppress any output except for the test report]' \
+          '(--test-page)--test-page=-[Test page to invoke]' \
+          '(--path)--path=-[Reuse an existing build at given path.]' \
+          '(--query)--query=-[A query string to append to the test page URL.]'
+        ;;
+    esac
+    ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/ember-cli.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ember-cli/ember-cli.plugin.zsh
new file mode 100644 (file)
index 0000000..de46b98
--- /dev/null
@@ -0,0 +1,12 @@
+alias ea='ember addon'
+alias eb='ember build'
+alias ed='ember destroy'
+alias eg='ember generate'
+alias eh='ember help'
+alias ei='ember install'
+alias ein='ember init'
+alias es='ember serve'
+alias et='ember test'
+alias ets='ember test --serve'
+alias eu='ember update'
+alias ev='ember version'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji-clock/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji-clock/README.md
new file mode 100644 (file)
index 0000000..4934f38
--- /dev/null
@@ -0,0 +1,14 @@
+# emoji-clock
+
+The plugin displays current time as an emoji symbol with half hour accuracy.
+
+To use it, add `emoji-clock` to the plugins array of your zshrc file:
+```
+plugins=(... emoji-clock)
+```
+
+## Features
+
+| Function          | Description                                                          |
+|-------------------|----------------------------------------------------------------------|
+| `emoji-clock`     | Displays current time in clock emoji symbol with half hour accuracy  |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji-clock/emoji-clock.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji-clock/emoji-clock.plugin.zsh
new file mode 100644 (file)
index 0000000..bdd606f
--- /dev/null
@@ -0,0 +1,33 @@
+# ------------------------------------------------------------------------------
+#          FILE: emoji-clock.plugin.zsh
+#   DESCRIPTION: The current time with half hour accuracy as an emoji symbol.
+#                Inspired by Andre Torrez' "Put A Burger In Your Shell"
+#                https://notes.torrez.org/2013/04/put-a-burger-in-your-shell.html
+#        AUTHOR: Alexis Hildebrandt (afh[at]surryhill.net)
+#       VERSION: 1.0.0
+# -----------------------------------------------------------------------------
+
+function emoji-clock() {
+  # Add 15 minutes to the current time and save the value as $minutes.
+  (( minutes = $(date '+%M') + 15 ))
+  (( hour = $(date '+%I') + minutes / 60 ))
+  # make sure minutes and hours don't exceed 60 nor 12 respectively
+  (( minutes %= 60 )); (( hour %= 12 ))
+
+  case $hour in
+     0) clock="🕛"; [ $minutes -ge 30 ] && clock="🕧";;
+     1) clock="🕐"; [ $minutes -ge 30 ] && clock="🕜";;
+     2) clock="🕑"; [ $minutes -ge 30 ] && clock="🕝";;
+     3) clock="🕒"; [ $minutes -ge 30 ] && clock="🕞";;
+     4) clock="🕓"; [ $minutes -ge 30 ] && clock="🕟";;
+     5) clock="🕔"; [ $minutes -ge 30 ] && clock="🕠";;
+     6) clock="🕕"; [ $minutes -ge 30 ] && clock="🕡";;
+     7) clock="🕖"; [ $minutes -ge 30 ] && clock="🕢";;
+     8) clock="🕗"; [ $minutes -ge 30 ] && clock="🕣";;
+     9) clock="🕘"; [ $minutes -ge 30 ] && clock="🕤";;
+    10) clock="🕙"; [ $minutes -ge 30 ] && clock="🕥";;
+    11) clock="🕚"; [ $minutes -ge 30 ] && clock="🕦";;
+     *) clock="⌛";;
+  esac
+  echo $clock
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/README.md
new file mode 100644 (file)
index 0000000..4154ea0
--- /dev/null
@@ -0,0 +1,127 @@
+# emoji plugin
+
+Support for conveniently working with Unicode emoji in Zsh.
+
+## Features
+
+This plugin provides support for working with Unicode emoji characters in `zsh` using human-readable identifiers. It provides global variables which map emoji names to the actual characters, country names to their flags, and some named groupings of emoji. It also provides associated functions for displaying them.
+
+#### Variables
+
+Variable          | Description
+----------------- | --------------------------------
+  $emoji          | Maps emoji names to characters (except flags)
+  $emoji_flags    | Maps country names to flag characters (using region indicators)
+  $emoji_groups   | Named groups of emoji. Keys are group names; values are whitespace-separated lists of character names
+
+You may define new emoji groups at run time by modifying `$emoji_groups`. The special group name `all` is reserved for use by the plugin. You should not modify `$emoji` or `$emoji_flags`.
+
+#### Functions
+
+Function         | Description
+---------------- | -------------------------------
+  random_emoji   | Prints a random emoji character
+  display_emoji  | Displays emoji, along with their names
+
+## Usage and Examples
+
+To output a specific emoji, use:
+```
+$> echo $emoji[<name>]
+```
+E.g.:
+```
+$> echo $emoji[mouse_face]
+```
+
+To output a random emoji, use:
+```
+$> random_emoji
+```
+To output a random emoji from a particular group, use:
+```
+$> random_emoji <group>
+```
+E.g.:
+```
+$> random_emoji fruits
+$> random_emoji animals
+$> random_emoji vehicles
+$> random_emoji faces
+```
+
+The defined group names can be found with `echo ${(k)emoji_groups}`.
+
+To list all available emoji with their names, use:
+```
+$> display_emoji
+$> display_emoji faces
+$> display_emoji people
+```
+
+To use emoji in a prompt:
+```
+PROMPT="$emoji[penguin]  > ""
+PROMPT='$(random_emoji fruits)  > '
+surfer=$emoji[surfer]
+PROMPT="$surfer  > "
+```
+
+##  Technical Details
+
+The emoji names and codes are sourced from Unicode Technical Report \#51, which provides information on emoji support in Unicode. It can be found at https://www.unicode.org/reports/tr51/index.html.
+
+The group definitions are added by this OMZ plugin. They are not based on external definitions.
+
+The values in the `$emoji*` maps are the emoji characters themselves, not escape sequences or other forms that require interpretation. They can be used in any context and do not require escape sequence support from commands like `echo` or `print`.
+
+The emoji in the main `$emoji` map are standalone character sequences which can all be output on their own, without worrying about combining characters. The values may actually be multi-code-point sequences, instead of a single code point, and may include combining characters in those sequences. But they're arranged so their effects do not extend beyond that sequence.
+
+The exception to this is the skin tone / hair style variation selectors. These are included in the main `$emoji` map because they can be displayed on their own, as well as used as combining characters. (If they follow a character that is not one of the emoji characters they combine with, they are displayed as color swatches.)
+
+
+##  Experimental Features
+
+This defines some additional variables and functions, but these are experimental and subject to change at any time. You shouldn't rely on them being available. They're mostly for the use of emoji plugin developers to help decide what to include in future revisions.
+
+Variables:
+
+Variable          | Description
+----------------- | --------------------------------
+  $emoji_skintone | Skin tone modifiers (from Unicode 8.0)
+
+
+#### Skin Tone Variation Selection
+
+This includes experimental support for the skin tone Variation Selectors introduced with Unicode 8.0, which let you select different skin tones for emoji involving humans.
+
+NOTE: This really is experimental. The skin tone selectors are a relatively new feature and may not be supported by all systems. And the support in this plugin is a work in progress. It may not work in all places. In fact, I haven't gotten it to work anywhere yet. -apjanke
+
+The "variation selectors" are combining characters which change the appearance of the preceding character. A variation selector character can be output immediately following a human emoji to change its skin tone color. You can also output a variation selector on its own to display a color swatch of that skin tone.
+
+The `$emoji_skintone` associative array maps skin tone IDs to the variation selector characters. To use one, output it immediately following a smiley or other human emoji.
+
+```
+echo $emoji[waving_hand]$emoji_skintone[5]
+```
+
+Note that `$emoji_skintone` is an associative array, and its keys are the *names* of "Fitzpatrick Skin Type" groups, not linear indexes into a normal array. The names are `1_2`, `3`, `4`, `5`, and `6`. (Types 1 and 2 are combined into a single color.) See the [Diversity section in Unicode TR 51](https://www.unicode.org/reports/tr51/index.html#Diversity) for details.
+
+####  Gemoji support
+
+The [gemoji project](https://github.com/github/gemoji) seems to be the de facto main source for short names and other emoji-related metadata that isn't included in the official Unicode reports. So, our list of emojis incorporates some of their aliases to make your life more convenient:
+
+```
+echo $emoji[grinning_face_with_smiling_eyes]
+echo $emoji[smile]
+```
+
+These two commands yield the same emoji (😄). The first name is the official one, in the Unicode reference, and the second one is the alias that was in Gemoji's database.
+
+##  TODO
+
+These are things that could be enhanced in future revisions of the plugin.
+
+* Incorporate CLDR data for ordering and groupings
+* Short :bracket: style names (from gemoji)
+* ZWJ combining function?
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji-char-definitions.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji-char-definitions.zsh
new file mode 100644 (file)
index 0000000..b37c142
--- /dev/null
@@ -0,0 +1,7274 @@
+
+# emoji-char-definitions.zsh - Emoji definitions for oh-my-zsh emoji plugin
+#
+# This file is auto-generated by update_emoji.py. Do not edit it manually.
+#
+# This contains the definition for:
+#   $emoji         - which maps character names to Unicode characters
+#   $emoji_flags   - maps country names to Unicode flag characters using region
+#                    indicators
+#   $emoji_mod     - maps modifier components to Unicode characters
+#   $emoji_groups  - a single associative array to avoid cluttering up the
+#                    global namespace, and to allow adding additional group
+#                    definitions at run time. The keys are the group names, and
+#                    the values are whitespace-separated lists of emoji
+#                    character names.
+
+# Main emoji
+typeset -gAH emoji
+# National flags
+typeset -gAH emoji_flags
+# Combining modifiers
+typeset -gAH emoji_mod
+# Emoji groups
+typeset -gAH emoji_groups
+emoji[grinning_face]=$'\U1F600'
+emoji[grinning]=$'\U1F600'
+emoji[grinning_face_with_big_eyes]=$'\U1F603'
+emoji[smiley]=$'\U1F603'
+emoji[grinning_face_with_smiling_eyes]=$'\U1F604'
+emoji[smile]=$'\U1F604'
+emoji[beaming_face_with_smiling_eyes]=$'\U1F601'
+emoji[grin]=$'\U1F601'
+emoji[grinning_squinting_face]=$'\U1F606'
+emoji[laughing]=$'\U1F606'
+emoji[satisfied]=$'\U1F606'
+emoji[grinning_face_with_sweat]=$'\U1F605'
+emoji[sweat_smile]=$'\U1F605'
+emoji[rolling_on_the_floor_laughing]=$'\U1F923'
+emoji[rofl]=$'\U1F923'
+emoji[face_with_tears_of_joy]=$'\U1F602'
+emoji[joy]=$'\U1F602'
+emoji[slightly_smiling_face]=$'\U1F642'
+emoji[upside_down_face]=$'\U1F643'
+emoji[winking_face]=$'\U1F609'
+emoji[wink]=$'\U1F609'
+emoji[smiling_face_with_smiling_eyes]=$'\U1F60A'
+emoji[blush]=$'\U1F60A'
+emoji[smiling_face_with_halo]=$'\U1F607'
+emoji[innocent]=$'\U1F607'
+emoji[smiling_face_with_hearts]=$'\U1F970'
+emoji[smiling_face_with_three_hearts]=$'\U1F970'
+emoji[smiling_face_with_heart_eyes]=$'\U1F60D'
+emoji[heart_eyes]=$'\U1F60D'
+emoji[star_struck]=$'\U1F929'
+emoji[face_blowing_a_kiss]=$'\U1F618'
+emoji[kissing_heart]=$'\U1F618'
+emoji[kissing_face]=$'\U1F617'
+emoji[kissing]=$'\U1F617'
+emoji[smiling_face]=$'\U263A\UFE0F'
+emoji[relaxed]=$'\U263A\UFE0F'
+emoji[smiling_face_unqualified]=$'\U263A'
+emoji[kissing_face_with_closed_eyes]=$'\U1F61A'
+emoji[kissing_closed_eyes]=$'\U1F61A'
+emoji[kissing_face_with_smiling_eyes]=$'\U1F619'
+emoji[kissing_smiling_eyes]=$'\U1F619'
+emoji[face_savoring_food]=$'\U1F60B'
+emoji[yum]=$'\U1F60B'
+emoji[face_with_tongue]=$'\U1F61B'
+emoji[stuck_out_tongue]=$'\U1F61B'
+emoji[winking_face_with_tongue]=$'\U1F61C'
+emoji[stuck_out_tongue_winking_eye]=$'\U1F61C'
+emoji[zany_face]=$'\U1F92A'
+emoji[squinting_face_with_tongue]=$'\U1F61D'
+emoji[stuck_out_tongue_closed_eyes]=$'\U1F61D'
+emoji[money_mouth_face]=$'\U1F911'
+emoji[hugging_face]=$'\U1F917'
+emoji[hugs]=$'\U1F917'
+emoji[face_with_hand_over_mouth]=$'\U1F92D'
+emoji[hand_over_mouth]=$'\U1F92D'
+emoji[shushing_face]=$'\U1F92B'
+emoji[thinking_face]=$'\U1F914'
+emoji[thinking]=$'\U1F914'
+emoji[zipper_mouth_face]=$'\U1F910'
+emoji[face_with_raised_eyebrow]=$'\U1F928'
+emoji[raised_eyebrow]=$'\U1F928'
+emoji[neutral_face]=$'\U1F610'
+emoji[expressionless_face]=$'\U1F611'
+emoji[expressionless]=$'\U1F611'
+emoji[face_without_mouth]=$'\U1F636'
+emoji[no_mouth]=$'\U1F636'
+emoji[smirking_face]=$'\U1F60F'
+emoji[smirk]=$'\U1F60F'
+emoji[unamused_face]=$'\U1F612'
+emoji[unamused]=$'\U1F612'
+emoji[face_with_rolling_eyes]=$'\U1F644'
+emoji[roll_eyes]=$'\U1F644'
+emoji[grimacing_face]=$'\U1F62C'
+emoji[grimacing]=$'\U1F62C'
+emoji[lying_face]=$'\U1F925'
+emoji[relieved_face]=$'\U1F60C'
+emoji[relieved]=$'\U1F60C'
+emoji[pensive_face]=$'\U1F614'
+emoji[pensive]=$'\U1F614'
+emoji[sleepy_face]=$'\U1F62A'
+emoji[sleepy]=$'\U1F62A'
+emoji[drooling_face]=$'\U1F924'
+emoji[sleeping_face]=$'\U1F634'
+emoji[sleeping]=$'\U1F634'
+emoji[face_with_medical_mask]=$'\U1F637'
+emoji[mask]=$'\U1F637'
+emoji[face_with_thermometer]=$'\U1F912'
+emoji[face_with_head_bandage]=$'\U1F915'
+emoji[nauseated_face]=$'\U1F922'
+emoji[face_vomiting]=$'\U1F92E'
+emoji[vomiting_face]=$'\U1F92E'
+emoji[sneezing_face]=$'\U1F927'
+emoji[hot_face]=$'\U1F975'
+emoji[cold_face]=$'\U1F976'
+emoji[woozy_face]=$'\U1F974'
+emoji[dizzy_face]=$'\U1F635'
+emoji[exploding_head]=$'\U1F92F'
+emoji[cowboy_hat_face]=$'\U1F920'
+emoji[partying_face]=$'\U1F973'
+emoji[smiling_face_with_sunglasses]=$'\U1F60E'
+emoji[nerd_face]=$'\U1F913'
+emoji[face_with_monocle]=$'\U1F9D0'
+emoji[monocle_face]=$'\U1F9D0'
+emoji[confused_face]=$'\U1F615'
+emoji[confused]=$'\U1F615'
+emoji[worried_face]=$'\U1F61F'
+emoji[worried]=$'\U1F61F'
+emoji[slightly_frowning_face]=$'\U1F641'
+emoji[slightly_frowning_face_1]=$'\U2639\UFE0F'
+emoji[frowning_face_unqualified]=$'\U2639'
+emoji[frowning_face]=$'\U2639'
+emoji[face_with_open_mouth]=$'\U1F62E'
+emoji[open_mouth]=$'\U1F62E'
+emoji[hushed_face]=$'\U1F62F'
+emoji[hushed]=$'\U1F62F'
+emoji[astonished_face]=$'\U1F632'
+emoji[astonished]=$'\U1F632'
+emoji[flushed_face]=$'\U1F633'
+emoji[flushed]=$'\U1F633'
+emoji[pleading_face]=$'\U1F97A'
+emoji[frowning_face_with_open_mouth]=$'\U1F626'
+emoji[frowning]=$'\U1F626'
+emoji[anguished_face]=$'\U1F627'
+emoji[anguished]=$'\U1F627'
+emoji[fearful_face]=$'\U1F628'
+emoji[fearful]=$'\U1F628'
+emoji[anxious_face_with_sweat]=$'\U1F630'
+emoji[cold_sweat]=$'\U1F630'
+emoji[sad_but_relieved_face]=$'\U1F625'
+emoji[disappointed_relieved]=$'\U1F625'
+emoji[crying_face]=$'\U1F622'
+emoji[cry]=$'\U1F622'
+emoji[loudly_crying_face]=$'\U1F62D'
+emoji[sob]=$'\U1F62D'
+emoji[face_screaming_in_fear]=$'\U1F631'
+emoji[scream]=$'\U1F631'
+emoji[confounded_face]=$'\U1F616'
+emoji[confounded]=$'\U1F616'
+emoji[persevering_face]=$'\U1F623'
+emoji[persevere]=$'\U1F623'
+emoji[disappointed_face]=$'\U1F61E'
+emoji[disappointed]=$'\U1F61E'
+emoji[downcast_face_with_sweat]=$'\U1F613'
+emoji[sweat]=$'\U1F613'
+emoji[weary_face]=$'\U1F629'
+emoji[weary]=$'\U1F629'
+emoji[tired_face]=$'\U1F62B'
+emoji[yawning_face]=$'\U1F971'
+emoji[face_with_steam_from_nose]=$'\U1F624'
+emoji[triumph]=$'\U1F624'
+emoji[pouting_face]=$'\U1F621'
+emoji[rage]=$'\U1F621'
+emoji[pout]=$'\U1F621'
+emoji[angry_face]=$'\U1F620'
+emoji[angry]=$'\U1F620'
+emoji[face_with_symbols_on_mouth]=$'\U1F92C'
+emoji[cursing_face]=$'\U1F92C'
+emoji[smiling_face_with_horns]=$'\U1F608'
+emoji[smiling_imp]=$'\U1F608'
+emoji[angry_face_with_horns]=$'\U1F47F'
+emoji[imp]=$'\U1F47F'
+emoji[skull]=$'\U1F480'
+emoji[skull_and_crossbones]=$'\U2620\UFE0F'
+emoji[skull_and_crossbones_unqualified]=$'\U2620'
+emoji[pile_of_poo]=$'\U1F4A9'
+emoji[hankey]=$'\U1F4A9'
+emoji[poop]=$'\U1F4A9'
+emoji[shit]=$'\U1F4A9'
+emoji[clown_face]=$'\U1F921'
+emoji[ogre]=$'\U1F479'
+emoji[japanese_ogre]=$'\U1F479'
+emoji[goblin]=$'\U1F47A'
+emoji[japanese_goblin]=$'\U1F47A'
+emoji[ghost]=$'\U1F47B'
+emoji[alien]=$'\U1F47D'
+emoji[alien_monster]=$'\U1F47E'
+emoji[space_invader]=$'\U1F47E'
+emoji[robot]=$'\U1F916'
+emoji[grinning_cat]=$'\U1F63A'
+emoji[smiley_cat]=$'\U1F63A'
+emoji[grinning_cat_with_smiling_eyes]=$'\U1F638'
+emoji[smile_cat]=$'\U1F638'
+emoji[cat_with_tears_of_joy]=$'\U1F639'
+emoji[joy_cat]=$'\U1F639'
+emoji[smiling_cat_with_heart_eyes]=$'\U1F63B'
+emoji[heart_eyes_cat]=$'\U1F63B'
+emoji[cat_with_wry_smile]=$'\U1F63C'
+emoji[smirk_cat]=$'\U1F63C'
+emoji[kissing_cat]=$'\U1F63D'
+emoji[weary_cat]=$'\U1F640'
+emoji[scream_cat]=$'\U1F640'
+emoji[crying_cat]=$'\U1F63F'
+emoji[crying_cat_face]=$'\U1F63F'
+emoji[pouting_cat]=$'\U1F63E'
+emoji[see_no_evil_monkey]=$'\U1F648'
+emoji[see_no_evil]=$'\U1F648'
+emoji[hear_no_evil_monkey]=$'\U1F649'
+emoji[hear_no_evil]=$'\U1F649'
+emoji[speak_no_evil_monkey]=$'\U1F64A'
+emoji[speak_no_evil]=$'\U1F64A'
+emoji[kiss_mark]=$'\U1F48B'
+emoji[love_letter]=$'\U1F48C'
+emoji[heart_with_arrow]=$'\U1F498'
+emoji[cupid]=$'\U1F498'
+emoji[heart_with_ribbon]=$'\U1F49D'
+emoji[gift_heart]=$'\U1F49D'
+emoji[sparkling_heart]=$'\U1F496'
+emoji[growing_heart]=$'\U1F497'
+emoji[heartpulse]=$'\U1F497'
+emoji[beating_heart]=$'\U1F493'
+emoji[heartbeat]=$'\U1F493'
+emoji[revolving_hearts]=$'\U1F49E'
+emoji[two_hearts]=$'\U1F495'
+emoji[heart_decoration]=$'\U1F49F'
+emoji[heart_exclamation]=$'\U2763\UFE0F'
+emoji[heavy_heart_exclamation]=$'\U2763\UFE0F'
+emoji[heart_exclamation_unqualified]=$'\U2763'
+emoji[broken_heart]=$'\U1F494'
+emoji[red_heart]=$'\U2764\UFE0F'
+emoji[heart]=$'\U2764\UFE0F'
+emoji[red_heart_unqualified]=$'\U2764'
+emoji[orange_heart]=$'\U1F9E1'
+emoji[yellow_heart]=$'\U1F49B'
+emoji[green_heart]=$'\U1F49A'
+emoji[blue_heart]=$'\U1F499'
+emoji[purple_heart]=$'\U1F49C'
+emoji[brown_heart]=$'\U1F90E'
+emoji[black_heart]=$'\U1F5A4'
+emoji[white_heart]=$'\U1F90D'
+emoji[hundred_points]=$'\U1F4AF'
+emoji[100]=$'\U1F4AF'
+emoji[anger_symbol]=$'\U1F4A2'
+emoji[anger]=$'\U1F4A2'
+emoji[collision]=$'\U1F4A5'
+emoji[boom]=$'\U1F4A5'
+emoji[dizzy]=$'\U1F4AB'
+emoji[sweat_droplets]=$'\U1F4A6'
+emoji[sweat_drops]=$'\U1F4A6'
+emoji[dashing_away]=$'\U1F4A8'
+emoji[dash]=$'\U1F4A8'
+emoji[hole]=$'\U1F573\UFE0F'
+emoji[hole_unqualified]=$'\U1F573'
+emoji[bomb]=$'\U1F4A3'
+emoji[speech_balloon]=$'\U1F4AC'
+emoji[eye_in_speech_bubble]=$'\U1F441\UFE0F\U200D\U1F5E8\UFE0F'
+emoji[eye_speech_bubble]=$'\U1F441\UFE0F\U200D\U1F5E8\UFE0F'
+emoji[eye_in_speech_bubble_unqualified]=$'\U1F441\U200D\U1F5E8\UFE0F'
+emoji[eye_in_speech_bubble_unqualified_1]=$'\U1F441\UFE0F\U200D\U1F5E8'
+emoji[eye_in_speech_bubble_unqualified_2]=$'\U1F441\U200D\U1F5E8'
+emoji[left_speech_bubble]=$'\U1F5E8\UFE0F'
+emoji[left_speech_bubble_unqualified]=$'\U1F5E8'
+emoji[right_anger_bubble]=$'\U1F5EF\UFE0F'
+emoji[right_anger_bubble_unqualified]=$'\U1F5EF'
+emoji[thought_balloon]=$'\U1F4AD'
+emoji[zzz]=$'\U1F4A4'
+emoji[waving_hand]=$'\U1F44B'
+emoji[wave]=$'\U1F44B'
+emoji[waving_hand_light_skin_tone]=$'\U1F44B\U1F3FB'
+emoji[waving_hand_medium_light_skin_tone]=$'\U1F44B\U1F3FC'
+emoji[waving_hand_medium_skin_tone]=$'\U1F44B\U1F3FD'
+emoji[waving_hand_medium_dark_skin_tone]=$'\U1F44B\U1F3FE'
+emoji[waving_hand_dark_skin_tone]=$'\U1F44B\U1F3FF'
+emoji[raised_back_of_hand]=$'\U1F91A'
+emoji[raised_back_of_hand_light_skin_tone]=$'\U1F91A\U1F3FB'
+emoji[raised_back_of_hand_medium_light_skin_tone]=$'\U1F91A\U1F3FC'
+emoji[raised_back_of_hand_medium_skin_tone]=$'\U1F91A\U1F3FD'
+emoji[raised_back_of_hand_medium_dark_skin_tone]=$'\U1F91A\U1F3FE'
+emoji[raised_back_of_hand_dark_skin_tone]=$'\U1F91A\U1F3FF'
+emoji[hand_with_fingers_splayed]=$'\U1F590\UFE0F'
+emoji[hand_with_fingers_splayed_unqualified]=$'\U1F590'
+emoji[raised_hand_with_fingers_splayed]=$'\U1F590'
+emoji[hand_with_fingers_splayed_light_skin_tone]=$'\U1F590\U1F3FB'
+emoji[hand_with_fingers_splayed_medium_light_skin_tone]=$'\U1F590\U1F3FC'
+emoji[hand_with_fingers_splayed_medium_skin_tone]=$'\U1F590\U1F3FD'
+emoji[hand_with_fingers_splayed_medium_dark_skin_tone]=$'\U1F590\U1F3FE'
+emoji[hand_with_fingers_splayed_dark_skin_tone]=$'\U1F590\U1F3FF'
+emoji[raised_hand]=$'\U270B'
+emoji[hand]=$'\U270B'
+emoji[raised_hand_light_skin_tone]=$'\U270B\U1F3FB'
+emoji[raised_hand_medium_light_skin_tone]=$'\U270B\U1F3FC'
+emoji[raised_hand_medium_skin_tone]=$'\U270B\U1F3FD'
+emoji[raised_hand_medium_dark_skin_tone]=$'\U270B\U1F3FE'
+emoji[raised_hand_dark_skin_tone]=$'\U270B\U1F3FF'
+emoji[vulcan_salute]=$'\U1F596'
+emoji[vulcan_salute_light_skin_tone]=$'\U1F596\U1F3FB'
+emoji[vulcan_salute_medium_light_skin_tone]=$'\U1F596\U1F3FC'
+emoji[vulcan_salute_medium_skin_tone]=$'\U1F596\U1F3FD'
+emoji[vulcan_salute_medium_dark_skin_tone]=$'\U1F596\U1F3FE'
+emoji[vulcan_salute_dark_skin_tone]=$'\U1F596\U1F3FF'
+emoji[OK_hand]=$'\U1F44C'
+emoji[ok_hand]=$'\U1F44C'
+emoji[OK_hand_light_skin_tone]=$'\U1F44C\U1F3FB'
+emoji[OK_hand_medium_light_skin_tone]=$'\U1F44C\U1F3FC'
+emoji[OK_hand_medium_skin_tone]=$'\U1F44C\U1F3FD'
+emoji[OK_hand_medium_dark_skin_tone]=$'\U1F44C\U1F3FE'
+emoji[OK_hand_dark_skin_tone]=$'\U1F44C\U1F3FF'
+emoji[pinching_hand]=$'\U1F90F'
+emoji[pinching_hand_light_skin_tone]=$'\U1F90F\U1F3FB'
+emoji[pinching_hand_medium_light_skin_tone]=$'\U1F90F\U1F3FC'
+emoji[pinching_hand_medium_skin_tone]=$'\U1F90F\U1F3FD'
+emoji[pinching_hand_medium_dark_skin_tone]=$'\U1F90F\U1F3FE'
+emoji[pinching_hand_dark_skin_tone]=$'\U1F90F\U1F3FF'
+emoji[victory_hand]=$'\U270C\UFE0F'
+emoji[v]=$'\U270C\UFE0F'
+emoji[victory_hand_unqualified]=$'\U270C'
+emoji[victory_hand_light_skin_tone]=$'\U270C\U1F3FB'
+emoji[victory_hand_medium_light_skin_tone]=$'\U270C\U1F3FC'
+emoji[victory_hand_medium_skin_tone]=$'\U270C\U1F3FD'
+emoji[victory_hand_medium_dark_skin_tone]=$'\U270C\U1F3FE'
+emoji[victory_hand_dark_skin_tone]=$'\U270C\U1F3FF'
+emoji[crossed_fingers]=$'\U1F91E'
+emoji[crossed_fingers_light_skin_tone]=$'\U1F91E\U1F3FB'
+emoji[crossed_fingers_medium_light_skin_tone]=$'\U1F91E\U1F3FC'
+emoji[crossed_fingers_medium_skin_tone]=$'\U1F91E\U1F3FD'
+emoji[crossed_fingers_medium_dark_skin_tone]=$'\U1F91E\U1F3FE'
+emoji[crossed_fingers_dark_skin_tone]=$'\U1F91E\U1F3FF'
+emoji[love_you_gesture]=$'\U1F91F'
+emoji[love_you_gesture_light_skin_tone]=$'\U1F91F\U1F3FB'
+emoji[love_you_gesture_medium_light_skin_tone]=$'\U1F91F\U1F3FC'
+emoji[love_you_gesture_medium_skin_tone]=$'\U1F91F\U1F3FD'
+emoji[love_you_gesture_medium_dark_skin_tone]=$'\U1F91F\U1F3FE'
+emoji[love_you_gesture_dark_skin_tone]=$'\U1F91F\U1F3FF'
+emoji[sign_of_the_horns]=$'\U1F918'
+emoji[metal]=$'\U1F918'
+emoji[sign_of_the_horns_light_skin_tone]=$'\U1F918\U1F3FB'
+emoji[sign_of_the_horns_medium_light_skin_tone]=$'\U1F918\U1F3FC'
+emoji[sign_of_the_horns_medium_skin_tone]=$'\U1F918\U1F3FD'
+emoji[sign_of_the_horns_medium_dark_skin_tone]=$'\U1F918\U1F3FE'
+emoji[sign_of_the_horns_dark_skin_tone]=$'\U1F918\U1F3FF'
+emoji[call_me_hand]=$'\U1F919'
+emoji[call_me_hand_light_skin_tone]=$'\U1F919\U1F3FB'
+emoji[call_me_hand_medium_light_skin_tone]=$'\U1F919\U1F3FC'
+emoji[call_me_hand_medium_skin_tone]=$'\U1F919\U1F3FD'
+emoji[call_me_hand_medium_dark_skin_tone]=$'\U1F919\U1F3FE'
+emoji[call_me_hand_dark_skin_tone]=$'\U1F919\U1F3FF'
+emoji[backhand_index_pointing_left]=$'\U1F448'
+emoji[point_left]=$'\U1F448'
+emoji[backhand_index_pointing_left_light_skin_tone]=$'\U1F448\U1F3FB'
+emoji[backhand_index_pointing_left_medium_light_skin_tone]=$'\U1F448\U1F3FC'
+emoji[backhand_index_pointing_left_medium_skin_tone]=$'\U1F448\U1F3FD'
+emoji[backhand_index_pointing_left_medium_dark_skin_tone]=$'\U1F448\U1F3FE'
+emoji[backhand_index_pointing_left_dark_skin_tone]=$'\U1F448\U1F3FF'
+emoji[backhand_index_pointing_right]=$'\U1F449'
+emoji[point_right]=$'\U1F449'
+emoji[backhand_index_pointing_right_light_skin_tone]=$'\U1F449\U1F3FB'
+emoji[backhand_index_pointing_right_medium_light_skin_tone]=$'\U1F449\U1F3FC'
+emoji[backhand_index_pointing_right_medium_skin_tone]=$'\U1F449\U1F3FD'
+emoji[backhand_index_pointing_right_medium_dark_skin_tone]=$'\U1F449\U1F3FE'
+emoji[backhand_index_pointing_right_dark_skin_tone]=$'\U1F449\U1F3FF'
+emoji[backhand_index_pointing_up]=$'\U1F446'
+emoji[point_up_2]=$'\U1F446'
+emoji[backhand_index_pointing_up_light_skin_tone]=$'\U1F446\U1F3FB'
+emoji[backhand_index_pointing_up_medium_light_skin_tone]=$'\U1F446\U1F3FC'
+emoji[backhand_index_pointing_up_medium_skin_tone]=$'\U1F446\U1F3FD'
+emoji[backhand_index_pointing_up_medium_dark_skin_tone]=$'\U1F446\U1F3FE'
+emoji[backhand_index_pointing_up_dark_skin_tone]=$'\U1F446\U1F3FF'
+emoji[middle_finger]=$'\U1F595'
+emoji[fu]=$'\U1F595'
+emoji[middle_finger_light_skin_tone]=$'\U1F595\U1F3FB'
+emoji[middle_finger_medium_light_skin_tone]=$'\U1F595\U1F3FC'
+emoji[middle_finger_medium_skin_tone]=$'\U1F595\U1F3FD'
+emoji[middle_finger_medium_dark_skin_tone]=$'\U1F595\U1F3FE'
+emoji[middle_finger_dark_skin_tone]=$'\U1F595\U1F3FF'
+emoji[backhand_index_pointing_down]=$'\U1F447'
+emoji[point_down]=$'\U1F447'
+emoji[backhand_index_pointing_down_light_skin_tone]=$'\U1F447\U1F3FB'
+emoji[backhand_index_pointing_down_medium_light_skin_tone]=$'\U1F447\U1F3FC'
+emoji[backhand_index_pointing_down_medium_skin_tone]=$'\U1F447\U1F3FD'
+emoji[backhand_index_pointing_down_medium_dark_skin_tone]=$'\U1F447\U1F3FE'
+emoji[backhand_index_pointing_down_dark_skin_tone]=$'\U1F447\U1F3FF'
+emoji[index_pointing_up]=$'\U261D\UFE0F'
+emoji[point_up]=$'\U261D\UFE0F'
+emoji[index_pointing_up_unqualified]=$'\U261D'
+emoji[index_pointing_up_light_skin_tone]=$'\U261D\U1F3FB'
+emoji[index_pointing_up_medium_light_skin_tone]=$'\U261D\U1F3FC'
+emoji[index_pointing_up_medium_skin_tone]=$'\U261D\U1F3FD'
+emoji[index_pointing_up_medium_dark_skin_tone]=$'\U261D\U1F3FE'
+emoji[index_pointing_up_dark_skin_tone]=$'\U261D\U1F3FF'
+emoji[thumbs_up]=$'\U1F44D'
+emoji[+1]=$'\U1F44D'
+emoji[thumbsup]=$'\U1F44D'
+emoji[thumbs_up_light_skin_tone]=$'\U1F44D\U1F3FB'
+emoji[thumbs_up_medium_light_skin_tone]=$'\U1F44D\U1F3FC'
+emoji[thumbs_up_medium_skin_tone]=$'\U1F44D\U1F3FD'
+emoji[thumbs_up_medium_dark_skin_tone]=$'\U1F44D\U1F3FE'
+emoji[thumbs_up_dark_skin_tone]=$'\U1F44D\U1F3FF'
+emoji[thumbs_down]=$'\U1F44E'
+emoji[-1]=$'\U1F44E'
+emoji[thumbsdown]=$'\U1F44E'
+emoji[thumbs_down_light_skin_tone]=$'\U1F44E\U1F3FB'
+emoji[thumbs_down_medium_light_skin_tone]=$'\U1F44E\U1F3FC'
+emoji[thumbs_down_medium_skin_tone]=$'\U1F44E\U1F3FD'
+emoji[thumbs_down_medium_dark_skin_tone]=$'\U1F44E\U1F3FE'
+emoji[thumbs_down_dark_skin_tone]=$'\U1F44E\U1F3FF'
+emoji[raised_fist]=$'\U270A'
+emoji[fist_raised]=$'\U270A'
+emoji[fist]=$'\U270A'
+emoji[raised_fist_light_skin_tone]=$'\U270A\U1F3FB'
+emoji[raised_fist_medium_light_skin_tone]=$'\U270A\U1F3FC'
+emoji[raised_fist_medium_skin_tone]=$'\U270A\U1F3FD'
+emoji[raised_fist_medium_dark_skin_tone]=$'\U270A\U1F3FE'
+emoji[raised_fist_dark_skin_tone]=$'\U270A\U1F3FF'
+emoji[oncoming_fist]=$'\U1F44A'
+emoji[fist_oncoming]=$'\U1F44A'
+emoji[facepunch]=$'\U1F44A'
+emoji[punch]=$'\U1F44A'
+emoji[oncoming_fist_light_skin_tone]=$'\U1F44A\U1F3FB'
+emoji[oncoming_fist_medium_light_skin_tone]=$'\U1F44A\U1F3FC'
+emoji[oncoming_fist_medium_skin_tone]=$'\U1F44A\U1F3FD'
+emoji[oncoming_fist_medium_dark_skin_tone]=$'\U1F44A\U1F3FE'
+emoji[oncoming_fist_dark_skin_tone]=$'\U1F44A\U1F3FF'
+emoji[left_facing_fist]=$'\U1F91B'
+emoji[fist_left]=$'\U1F91B'
+emoji[left_facing_fist_light_skin_tone]=$'\U1F91B\U1F3FB'
+emoji[left_facing_fist_medium_light_skin_tone]=$'\U1F91B\U1F3FC'
+emoji[left_facing_fist_medium_skin_tone]=$'\U1F91B\U1F3FD'
+emoji[left_facing_fist_medium_dark_skin_tone]=$'\U1F91B\U1F3FE'
+emoji[left_facing_fist_dark_skin_tone]=$'\U1F91B\U1F3FF'
+emoji[right_facing_fist]=$'\U1F91C'
+emoji[fist_right]=$'\U1F91C'
+emoji[right_facing_fist_light_skin_tone]=$'\U1F91C\U1F3FB'
+emoji[right_facing_fist_medium_light_skin_tone]=$'\U1F91C\U1F3FC'
+emoji[right_facing_fist_medium_skin_tone]=$'\U1F91C\U1F3FD'
+emoji[right_facing_fist_medium_dark_skin_tone]=$'\U1F91C\U1F3FE'
+emoji[right_facing_fist_dark_skin_tone]=$'\U1F91C\U1F3FF'
+emoji[clapping_hands]=$'\U1F44F'
+emoji[clap]=$'\U1F44F'
+emoji[clapping_hands_light_skin_tone]=$'\U1F44F\U1F3FB'
+emoji[clapping_hands_medium_light_skin_tone]=$'\U1F44F\U1F3FC'
+emoji[clapping_hands_medium_skin_tone]=$'\U1F44F\U1F3FD'
+emoji[clapping_hands_medium_dark_skin_tone]=$'\U1F44F\U1F3FE'
+emoji[clapping_hands_dark_skin_tone]=$'\U1F44F\U1F3FF'
+emoji[raising_hands]=$'\U1F64C'
+emoji[raised_hands]=$'\U1F64C'
+emoji[raising_hands_light_skin_tone]=$'\U1F64C\U1F3FB'
+emoji[raising_hands_medium_light_skin_tone]=$'\U1F64C\U1F3FC'
+emoji[raising_hands_medium_skin_tone]=$'\U1F64C\U1F3FD'
+emoji[raising_hands_medium_dark_skin_tone]=$'\U1F64C\U1F3FE'
+emoji[raising_hands_dark_skin_tone]=$'\U1F64C\U1F3FF'
+emoji[open_hands]=$'\U1F450'
+emoji[open_hands_light_skin_tone]=$'\U1F450\U1F3FB'
+emoji[open_hands_medium_light_skin_tone]=$'\U1F450\U1F3FC'
+emoji[open_hands_medium_skin_tone]=$'\U1F450\U1F3FD'
+emoji[open_hands_medium_dark_skin_tone]=$'\U1F450\U1F3FE'
+emoji[open_hands_dark_skin_tone]=$'\U1F450\U1F3FF'
+emoji[palms_up_together]=$'\U1F932'
+emoji[palms_up_together_light_skin_tone]=$'\U1F932\U1F3FB'
+emoji[palms_up_together_medium_light_skin_tone]=$'\U1F932\U1F3FC'
+emoji[palms_up_together_medium_skin_tone]=$'\U1F932\U1F3FD'
+emoji[palms_up_together_medium_dark_skin_tone]=$'\U1F932\U1F3FE'
+emoji[palms_up_together_dark_skin_tone]=$'\U1F932\U1F3FF'
+emoji[handshake]=$'\U1F91D'
+emoji[folded_hands]=$'\U1F64F'
+emoji[pray]=$'\U1F64F'
+emoji[folded_hands_light_skin_tone]=$'\U1F64F\U1F3FB'
+emoji[folded_hands_medium_light_skin_tone]=$'\U1F64F\U1F3FC'
+emoji[folded_hands_medium_skin_tone]=$'\U1F64F\U1F3FD'
+emoji[folded_hands_medium_dark_skin_tone]=$'\U1F64F\U1F3FE'
+emoji[folded_hands_dark_skin_tone]=$'\U1F64F\U1F3FF'
+emoji[writing_hand]=$'\U270D\UFE0F'
+emoji[writing_hand_unqualified]=$'\U270D'
+emoji[writing_hand_light_skin_tone]=$'\U270D\U1F3FB'
+emoji[writing_hand_medium_light_skin_tone]=$'\U270D\U1F3FC'
+emoji[writing_hand_medium_skin_tone]=$'\U270D\U1F3FD'
+emoji[writing_hand_medium_dark_skin_tone]=$'\U270D\U1F3FE'
+emoji[writing_hand_dark_skin_tone]=$'\U270D\U1F3FF'
+emoji[nail_polish]=$'\U1F485'
+emoji[nail_care]=$'\U1F485'
+emoji[nail_polish_light_skin_tone]=$'\U1F485\U1F3FB'
+emoji[nail_polish_medium_light_skin_tone]=$'\U1F485\U1F3FC'
+emoji[nail_polish_medium_skin_tone]=$'\U1F485\U1F3FD'
+emoji[nail_polish_medium_dark_skin_tone]=$'\U1F485\U1F3FE'
+emoji[nail_polish_dark_skin_tone]=$'\U1F485\U1F3FF'
+emoji[selfie]=$'\U1F933'
+emoji[selfie_light_skin_tone]=$'\U1F933\U1F3FB'
+emoji[selfie_medium_light_skin_tone]=$'\U1F933\U1F3FC'
+emoji[selfie_medium_skin_tone]=$'\U1F933\U1F3FD'
+emoji[selfie_medium_dark_skin_tone]=$'\U1F933\U1F3FE'
+emoji[selfie_dark_skin_tone]=$'\U1F933\U1F3FF'
+emoji[flexed_biceps]=$'\U1F4AA'
+emoji[muscle]=$'\U1F4AA'
+emoji[flexed_biceps_light_skin_tone]=$'\U1F4AA\U1F3FB'
+emoji[flexed_biceps_medium_light_skin_tone]=$'\U1F4AA\U1F3FC'
+emoji[flexed_biceps_medium_skin_tone]=$'\U1F4AA\U1F3FD'
+emoji[flexed_biceps_medium_dark_skin_tone]=$'\U1F4AA\U1F3FE'
+emoji[flexed_biceps_dark_skin_tone]=$'\U1F4AA\U1F3FF'
+emoji[mechanical_arm]=$'\U1F9BE'
+emoji[mechanical_leg]=$'\U1F9BF'
+emoji[mechanical_leg_1]=$'\U1F9B5'
+emoji[leg]=$'\U1F9B5'
+emoji[leg_light_skin_tone]=$'\U1F9B5\U1F3FB'
+emoji[leg_medium_light_skin_tone]=$'\U1F9B5\U1F3FC'
+emoji[leg_medium_skin_tone]=$'\U1F9B5\U1F3FD'
+emoji[leg_medium_dark_skin_tone]=$'\U1F9B5\U1F3FE'
+emoji[leg_dark_skin_tone]=$'\U1F9B5\U1F3FF'
+emoji[foot]=$'\U1F9B6'
+emoji[foot_light_skin_tone]=$'\U1F9B6\U1F3FB'
+emoji[foot_medium_light_skin_tone]=$'\U1F9B6\U1F3FC'
+emoji[foot_medium_skin_tone]=$'\U1F9B6\U1F3FD'
+emoji[foot_medium_dark_skin_tone]=$'\U1F9B6\U1F3FE'
+emoji[foot_dark_skin_tone]=$'\U1F9B6\U1F3FF'
+emoji[ear]=$'\U1F442'
+emoji[ear_light_skin_tone]=$'\U1F442\U1F3FB'
+emoji[ear_medium_light_skin_tone]=$'\U1F442\U1F3FC'
+emoji[ear_medium_skin_tone]=$'\U1F442\U1F3FD'
+emoji[ear_medium_dark_skin_tone]=$'\U1F442\U1F3FE'
+emoji[ear_dark_skin_tone]=$'\U1F442\U1F3FF'
+emoji[ear_with_hearing_aid]=$'\U1F9BB'
+emoji[ear_with_hearing_aid_light_skin_tone]=$'\U1F9BB\U1F3FB'
+emoji[ear_with_hearing_aid_medium_light_skin_tone]=$'\U1F9BB\U1F3FC'
+emoji[ear_with_hearing_aid_medium_skin_tone]=$'\U1F9BB\U1F3FD'
+emoji[ear_with_hearing_aid_medium_dark_skin_tone]=$'\U1F9BB\U1F3FE'
+emoji[ear_with_hearing_aid_dark_skin_tone]=$'\U1F9BB\U1F3FF'
+emoji[nose]=$'\U1F443'
+emoji[nose_light_skin_tone]=$'\U1F443\U1F3FB'
+emoji[nose_medium_light_skin_tone]=$'\U1F443\U1F3FC'
+emoji[nose_medium_skin_tone]=$'\U1F443\U1F3FD'
+emoji[nose_medium_dark_skin_tone]=$'\U1F443\U1F3FE'
+emoji[nose_dark_skin_tone]=$'\U1F443\U1F3FF'
+emoji[brain]=$'\U1F9E0'
+emoji[tooth]=$'\U1F9B7'
+emoji[bone]=$'\U1F9B4'
+emoji[eyes]=$'\U1F440'
+emoji[eyes_1]=$'\U1F441\UFE0F'
+emoji[eye_unqualified]=$'\U1F441'
+emoji[eye]=$'\U1F441'
+emoji[tongue]=$'\U1F445'
+emoji[mouth]=$'\U1F444'
+emoji[lips]=$'\U1F444'
+emoji[baby]=$'\U1F476'
+emoji[baby_light_skin_tone]=$'\U1F476\U1F3FB'
+emoji[baby_medium_light_skin_tone]=$'\U1F476\U1F3FC'
+emoji[baby_medium_skin_tone]=$'\U1F476\U1F3FD'
+emoji[baby_medium_dark_skin_tone]=$'\U1F476\U1F3FE'
+emoji[baby_dark_skin_tone]=$'\U1F476\U1F3FF'
+emoji[child]=$'\U1F9D2'
+emoji[child_light_skin_tone]=$'\U1F9D2\U1F3FB'
+emoji[child_medium_light_skin_tone]=$'\U1F9D2\U1F3FC'
+emoji[child_medium_skin_tone]=$'\U1F9D2\U1F3FD'
+emoji[child_medium_dark_skin_tone]=$'\U1F9D2\U1F3FE'
+emoji[child_dark_skin_tone]=$'\U1F9D2\U1F3FF'
+emoji[boy]=$'\U1F466'
+emoji[boy_light_skin_tone]=$'\U1F466\U1F3FB'
+emoji[boy_medium_light_skin_tone]=$'\U1F466\U1F3FC'
+emoji[boy_medium_skin_tone]=$'\U1F466\U1F3FD'
+emoji[boy_medium_dark_skin_tone]=$'\U1F466\U1F3FE'
+emoji[boy_dark_skin_tone]=$'\U1F466\U1F3FF'
+emoji[girl]=$'\U1F467'
+emoji[girl_light_skin_tone]=$'\U1F467\U1F3FB'
+emoji[girl_medium_light_skin_tone]=$'\U1F467\U1F3FC'
+emoji[girl_medium_skin_tone]=$'\U1F467\U1F3FD'
+emoji[girl_medium_dark_skin_tone]=$'\U1F467\U1F3FE'
+emoji[girl_dark_skin_tone]=$'\U1F467\U1F3FF'
+emoji[person]=$'\U1F9D1'
+emoji[adult]=$'\U1F9D1'
+emoji[person_light_skin_tone]=$'\U1F9D1\U1F3FB'
+emoji[person_medium_light_skin_tone]=$'\U1F9D1\U1F3FC'
+emoji[person_medium_skin_tone]=$'\U1F9D1\U1F3FD'
+emoji[person_medium_dark_skin_tone]=$'\U1F9D1\U1F3FE'
+emoji[person_dark_skin_tone]=$'\U1F9D1\U1F3FF'
+emoji[person_blond_hair]=$'\U1F471'
+emoji[blond_haired_person]=$'\U1F471'
+emoji[person_light_skin_tone_blond_hair]=$'\U1F471\U1F3FB'
+emoji[person_medium_light_skin_tone_blond_hair]=$'\U1F471\U1F3FC'
+emoji[person_medium_skin_tone_blond_hair]=$'\U1F471\U1F3FD'
+emoji[person_medium_dark_skin_tone_blond_hair]=$'\U1F471\U1F3FE'
+emoji[person_dark_skin_tone_blond_hair]=$'\U1F471\U1F3FF'
+emoji[man]=$'\U1F468'
+emoji[man_light_skin_tone]=$'\U1F468\U1F3FB'
+emoji[man_medium_light_skin_tone]=$'\U1F468\U1F3FC'
+emoji[man_medium_skin_tone]=$'\U1F468\U1F3FD'
+emoji[man_medium_dark_skin_tone]=$'\U1F468\U1F3FE'
+emoji[man_dark_skin_tone]=$'\U1F468\U1F3FF'
+emoji[man_beard]=$'\U1F9D4'
+emoji[bearded_person]=$'\U1F9D4'
+emoji[man_light_skin_tone_beard]=$'\U1F9D4\U1F3FB'
+emoji[man_medium_light_skin_tone_beard]=$'\U1F9D4\U1F3FC'
+emoji[man_medium_skin_tone_beard]=$'\U1F9D4\U1F3FD'
+emoji[man_medium_dark_skin_tone_beard]=$'\U1F9D4\U1F3FE'
+emoji[man_dark_skin_tone_beard]=$'\U1F9D4\U1F3FF'
+emoji[man_blond_hair]=$'\U1F471\U200D\U2642\UFE0F'
+emoji[man_blond_hair_minimally]=$'\U1F471\U200D\U2642'
+emoji[blond_haired_man]=$'\U1F471\U200D\U2642'
+emoji[man_light_skin_tone_blond_hair]=$'\U1F471\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_light_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FB\U200D\U2642'
+emoji[man_medium_light_skin_tone_blond_hair]=$'\U1F471\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_medium_light_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FC\U200D\U2642'
+emoji[man_medium_skin_tone_blond_hair]=$'\U1F471\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_medium_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FD\U200D\U2642'
+emoji[man_medium_dark_skin_tone_blond_hair]=$'\U1F471\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_medium_dark_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FE\U200D\U2642'
+emoji[man_dark_skin_tone_blond_hair]=$'\U1F471\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_dark_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FF\U200D\U2642'
+emoji[man_red_hair]=$'\U1F468\U200D\U1F9B0'
+emoji[red_haired_man]=$'\U1F468\U200D\U1F9B0'
+emoji[man_light_skin_tone_red_hair]=$'\U1F468\U1F3FB\U200D\U1F9B0'
+emoji[man_medium_light_skin_tone_red_hair]=$'\U1F468\U1F3FC\U200D\U1F9B0'
+emoji[man_medium_skin_tone_red_hair]=$'\U1F468\U1F3FD\U200D\U1F9B0'
+emoji[man_medium_dark_skin_tone_red_hair]=$'\U1F468\U1F3FE\U200D\U1F9B0'
+emoji[man_dark_skin_tone_red_hair]=$'\U1F468\U1F3FF\U200D\U1F9B0'
+emoji[man_curly_hair]=$'\U1F468\U200D\U1F9B1'
+emoji[curly_haired_man]=$'\U1F468\U200D\U1F9B1'
+emoji[man_light_skin_tone_curly_hair]=$'\U1F468\U1F3FB\U200D\U1F9B1'
+emoji[man_medium_light_skin_tone_curly_hair]=$'\U1F468\U1F3FC\U200D\U1F9B1'
+emoji[man_medium_skin_tone_curly_hair]=$'\U1F468\U1F3FD\U200D\U1F9B1'
+emoji[man_medium_dark_skin_tone_curly_hair]=$'\U1F468\U1F3FE\U200D\U1F9B1'
+emoji[man_dark_skin_tone_curly_hair]=$'\U1F468\U1F3FF\U200D\U1F9B1'
+emoji[man_white_hair]=$'\U1F468\U200D\U1F9B3'
+emoji[white_haired_man]=$'\U1F468\U200D\U1F9B3'
+emoji[man_light_skin_tone_white_hair]=$'\U1F468\U1F3FB\U200D\U1F9B3'
+emoji[man_medium_light_skin_tone_white_hair]=$'\U1F468\U1F3FC\U200D\U1F9B3'
+emoji[man_medium_skin_tone_white_hair]=$'\U1F468\U1F3FD\U200D\U1F9B3'
+emoji[man_medium_dark_skin_tone_white_hair]=$'\U1F468\U1F3FE\U200D\U1F9B3'
+emoji[man_dark_skin_tone_white_hair]=$'\U1F468\U1F3FF\U200D\U1F9B3'
+emoji[man_bald]=$'\U1F468\U200D\U1F9B2'
+emoji[bald_man]=$'\U1F468\U200D\U1F9B2'
+emoji[man_light_skin_tone_bald]=$'\U1F468\U1F3FB\U200D\U1F9B2'
+emoji[man_medium_light_skin_tone_bald]=$'\U1F468\U1F3FC\U200D\U1F9B2'
+emoji[man_medium_skin_tone_bald]=$'\U1F468\U1F3FD\U200D\U1F9B2'
+emoji[man_medium_dark_skin_tone_bald]=$'\U1F468\U1F3FE\U200D\U1F9B2'
+emoji[man_dark_skin_tone_bald]=$'\U1F468\U1F3FF\U200D\U1F9B2'
+emoji[woman]=$'\U1F469'
+emoji[woman_light_skin_tone]=$'\U1F469\U1F3FB'
+emoji[woman_medium_light_skin_tone]=$'\U1F469\U1F3FC'
+emoji[woman_medium_skin_tone]=$'\U1F469\U1F3FD'
+emoji[woman_medium_dark_skin_tone]=$'\U1F469\U1F3FE'
+emoji[woman_dark_skin_tone]=$'\U1F469\U1F3FF'
+emoji[woman_blond_hair]=$'\U1F471\U200D\U2640\UFE0F'
+emoji[woman_blond_hair_minimally]=$'\U1F471\U200D\U2640'
+emoji[blond_haired_woman]=$'\U1F471\U200D\U2640'
+emoji[blonde_woman]=$'\U1F471\U200D\U2640'
+emoji[woman_light_skin_tone_blond_hair]=$'\U1F471\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_light_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FB\U200D\U2640'
+emoji[woman_medium_light_skin_tone_blond_hair]=$'\U1F471\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_medium_light_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FC\U200D\U2640'
+emoji[woman_medium_skin_tone_blond_hair]=$'\U1F471\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_medium_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FD\U200D\U2640'
+emoji[woman_medium_dark_skin_tone_blond_hair]=$'\U1F471\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_medium_dark_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FE\U200D\U2640'
+emoji[woman_dark_skin_tone_blond_hair]=$'\U1F471\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_dark_skin_tone_blond_hair_minimally]=$'\U1F471\U1F3FF\U200D\U2640'
+emoji[woman_red_hair]=$'\U1F469\U200D\U1F9B0'
+emoji[red_haired_woman]=$'\U1F469\U200D\U1F9B0'
+emoji[woman_light_skin_tone_red_hair]=$'\U1F469\U1F3FB\U200D\U1F9B0'
+emoji[woman_medium_light_skin_tone_red_hair]=$'\U1F469\U1F3FC\U200D\U1F9B0'
+emoji[woman_medium_skin_tone_red_hair]=$'\U1F469\U1F3FD\U200D\U1F9B0'
+emoji[woman_medium_dark_skin_tone_red_hair]=$'\U1F469\U1F3FE\U200D\U1F9B0'
+emoji[woman_dark_skin_tone_red_hair]=$'\U1F469\U1F3FF\U200D\U1F9B0'
+emoji[woman_curly_hair]=$'\U1F469\U200D\U1F9B1'
+emoji[curly_haired_woman]=$'\U1F469\U200D\U1F9B1'
+emoji[woman_light_skin_tone_curly_hair]=$'\U1F469\U1F3FB\U200D\U1F9B1'
+emoji[woman_medium_light_skin_tone_curly_hair]=$'\U1F469\U1F3FC\U200D\U1F9B1'
+emoji[woman_medium_skin_tone_curly_hair]=$'\U1F469\U1F3FD\U200D\U1F9B1'
+emoji[woman_medium_dark_skin_tone_curly_hair]=$'\U1F469\U1F3FE\U200D\U1F9B1'
+emoji[woman_dark_skin_tone_curly_hair]=$'\U1F469\U1F3FF\U200D\U1F9B1'
+emoji[woman_white_hair]=$'\U1F469\U200D\U1F9B3'
+emoji[white_haired_woman]=$'\U1F469\U200D\U1F9B3'
+emoji[woman_light_skin_tone_white_hair]=$'\U1F469\U1F3FB\U200D\U1F9B3'
+emoji[woman_medium_light_skin_tone_white_hair]=$'\U1F469\U1F3FC\U200D\U1F9B3'
+emoji[woman_medium_skin_tone_white_hair]=$'\U1F469\U1F3FD\U200D\U1F9B3'
+emoji[woman_medium_dark_skin_tone_white_hair]=$'\U1F469\U1F3FE\U200D\U1F9B3'
+emoji[woman_dark_skin_tone_white_hair]=$'\U1F469\U1F3FF\U200D\U1F9B3'
+emoji[woman_bald]=$'\U1F469\U200D\U1F9B2'
+emoji[bald_woman]=$'\U1F469\U200D\U1F9B2'
+emoji[woman_light_skin_tone_bald]=$'\U1F469\U1F3FB\U200D\U1F9B2'
+emoji[woman_medium_light_skin_tone_bald]=$'\U1F469\U1F3FC\U200D\U1F9B2'
+emoji[woman_medium_skin_tone_bald]=$'\U1F469\U1F3FD\U200D\U1F9B2'
+emoji[woman_medium_dark_skin_tone_bald]=$'\U1F469\U1F3FE\U200D\U1F9B2'
+emoji[woman_dark_skin_tone_bald]=$'\U1F469\U1F3FF\U200D\U1F9B2'
+emoji[older_person]=$'\U1F9D3'
+emoji[older_adult]=$'\U1F9D3'
+emoji[older_person_light_skin_tone]=$'\U1F9D3\U1F3FB'
+emoji[older_person_medium_light_skin_tone]=$'\U1F9D3\U1F3FC'
+emoji[older_person_medium_skin_tone]=$'\U1F9D3\U1F3FD'
+emoji[older_person_medium_dark_skin_tone]=$'\U1F9D3\U1F3FE'
+emoji[older_person_dark_skin_tone]=$'\U1F9D3\U1F3FF'
+emoji[old_man]=$'\U1F474'
+emoji[older_man]=$'\U1F474'
+emoji[old_man_light_skin_tone]=$'\U1F474\U1F3FB'
+emoji[old_man_medium_light_skin_tone]=$'\U1F474\U1F3FC'
+emoji[old_man_medium_skin_tone]=$'\U1F474\U1F3FD'
+emoji[old_man_medium_dark_skin_tone]=$'\U1F474\U1F3FE'
+emoji[old_man_dark_skin_tone]=$'\U1F474\U1F3FF'
+emoji[old_woman]=$'\U1F475'
+emoji[older_woman]=$'\U1F475'
+emoji[old_woman_light_skin_tone]=$'\U1F475\U1F3FB'
+emoji[old_woman_medium_light_skin_tone]=$'\U1F475\U1F3FC'
+emoji[old_woman_medium_skin_tone]=$'\U1F475\U1F3FD'
+emoji[old_woman_medium_dark_skin_tone]=$'\U1F475\U1F3FE'
+emoji[old_woman_dark_skin_tone]=$'\U1F475\U1F3FF'
+emoji[person_frowning]=$'\U1F64D'
+emoji[frowning_person]=$'\U1F64D'
+emoji[person_frowning_light_skin_tone]=$'\U1F64D\U1F3FB'
+emoji[person_frowning_medium_light_skin_tone]=$'\U1F64D\U1F3FC'
+emoji[person_frowning_medium_skin_tone]=$'\U1F64D\U1F3FD'
+emoji[person_frowning_medium_dark_skin_tone]=$'\U1F64D\U1F3FE'
+emoji[person_frowning_dark_skin_tone]=$'\U1F64D\U1F3FF'
+emoji[man_frowning]=$'\U1F64D\U200D\U2642\UFE0F'
+emoji[man_frowning_minimally]=$'\U1F64D\U200D\U2642'
+emoji[frowning_man]=$'\U1F64D\U200D\U2642'
+emoji[man_frowning_light_skin_tone]=$'\U1F64D\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_frowning_light_skin_tone_minimally]=$'\U1F64D\U1F3FB\U200D\U2642'
+emoji[man_frowning_medium_light_skin_tone]=$'\U1F64D\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_frowning_medium_light_skin_tone_minimally]=$'\U1F64D\U1F3FC\U200D\U2642'
+emoji[man_frowning_medium_skin_tone]=$'\U1F64D\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_frowning_medium_skin_tone_minimally]=$'\U1F64D\U1F3FD\U200D\U2642'
+emoji[man_frowning_medium_dark_skin_tone]=$'\U1F64D\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_frowning_medium_dark_skin_tone_minimally]=$'\U1F64D\U1F3FE\U200D\U2642'
+emoji[man_frowning_dark_skin_tone]=$'\U1F64D\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_frowning_dark_skin_tone_minimally]=$'\U1F64D\U1F3FF\U200D\U2642'
+emoji[woman_frowning]=$'\U1F64D\U200D\U2640\UFE0F'
+emoji[woman_frowning_minimally]=$'\U1F64D\U200D\U2640'
+emoji[frowning_woman]=$'\U1F64D\U200D\U2640'
+emoji[woman_frowning_light_skin_tone]=$'\U1F64D\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_frowning_light_skin_tone_minimally]=$'\U1F64D\U1F3FB\U200D\U2640'
+emoji[woman_frowning_medium_light_skin_tone]=$'\U1F64D\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_frowning_medium_light_skin_tone_minimally]=$'\U1F64D\U1F3FC\U200D\U2640'
+emoji[woman_frowning_medium_skin_tone]=$'\U1F64D\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_frowning_medium_skin_tone_minimally]=$'\U1F64D\U1F3FD\U200D\U2640'
+emoji[woman_frowning_medium_dark_skin_tone]=$'\U1F64D\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_frowning_medium_dark_skin_tone_minimally]=$'\U1F64D\U1F3FE\U200D\U2640'
+emoji[woman_frowning_dark_skin_tone]=$'\U1F64D\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_frowning_dark_skin_tone_minimally]=$'\U1F64D\U1F3FF\U200D\U2640'
+emoji[person_pouting]=$'\U1F64E'
+emoji[person_pouting_light_skin_tone]=$'\U1F64E\U1F3FB'
+emoji[person_pouting_medium_light_skin_tone]=$'\U1F64E\U1F3FC'
+emoji[person_pouting_medium_skin_tone]=$'\U1F64E\U1F3FD'
+emoji[person_pouting_medium_dark_skin_tone]=$'\U1F64E\U1F3FE'
+emoji[person_pouting_dark_skin_tone]=$'\U1F64E\U1F3FF'
+emoji[man_pouting]=$'\U1F64E\U200D\U2642\UFE0F'
+emoji[man_pouting_minimally]=$'\U1F64E\U200D\U2642'
+emoji[pouting_man]=$'\U1F64E\U200D\U2642'
+emoji[man_pouting_light_skin_tone]=$'\U1F64E\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_pouting_light_skin_tone_minimally]=$'\U1F64E\U1F3FB\U200D\U2642'
+emoji[man_pouting_medium_light_skin_tone]=$'\U1F64E\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_pouting_medium_light_skin_tone_minimally]=$'\U1F64E\U1F3FC\U200D\U2642'
+emoji[man_pouting_medium_skin_tone]=$'\U1F64E\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_pouting_medium_skin_tone_minimally]=$'\U1F64E\U1F3FD\U200D\U2642'
+emoji[man_pouting_medium_dark_skin_tone]=$'\U1F64E\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_pouting_medium_dark_skin_tone_minimally]=$'\U1F64E\U1F3FE\U200D\U2642'
+emoji[man_pouting_dark_skin_tone]=$'\U1F64E\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_pouting_dark_skin_tone_minimally]=$'\U1F64E\U1F3FF\U200D\U2642'
+emoji[woman_pouting]=$'\U1F64E\U200D\U2640\UFE0F'
+emoji[woman_pouting_minimally]=$'\U1F64E\U200D\U2640'
+emoji[pouting_woman]=$'\U1F64E\U200D\U2640'
+emoji[woman_pouting_light_skin_tone]=$'\U1F64E\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_pouting_light_skin_tone_minimally]=$'\U1F64E\U1F3FB\U200D\U2640'
+emoji[woman_pouting_medium_light_skin_tone]=$'\U1F64E\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_pouting_medium_light_skin_tone_minimally]=$'\U1F64E\U1F3FC\U200D\U2640'
+emoji[woman_pouting_medium_skin_tone]=$'\U1F64E\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_pouting_medium_skin_tone_minimally]=$'\U1F64E\U1F3FD\U200D\U2640'
+emoji[woman_pouting_medium_dark_skin_tone]=$'\U1F64E\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_pouting_medium_dark_skin_tone_minimally]=$'\U1F64E\U1F3FE\U200D\U2640'
+emoji[woman_pouting_dark_skin_tone]=$'\U1F64E\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_pouting_dark_skin_tone_minimally]=$'\U1F64E\U1F3FF\U200D\U2640'
+emoji[person_gesturing_NO]=$'\U1F645'
+emoji[no_good]=$'\U1F645'
+emoji[person_gesturing_NO_light_skin_tone]=$'\U1F645\U1F3FB'
+emoji[person_gesturing_NO_medium_light_skin_tone]=$'\U1F645\U1F3FC'
+emoji[person_gesturing_NO_medium_skin_tone]=$'\U1F645\U1F3FD'
+emoji[person_gesturing_NO_medium_dark_skin_tone]=$'\U1F645\U1F3FE'
+emoji[person_gesturing_NO_dark_skin_tone]=$'\U1F645\U1F3FF'
+emoji[man_gesturing_NO]=$'\U1F645\U200D\U2642\UFE0F'
+emoji[man_gesturing_NO_minimally]=$'\U1F645\U200D\U2642'
+emoji[no_good_man]=$'\U1F645\U200D\U2642'
+emoji[ng_man]=$'\U1F645\U200D\U2642'
+emoji[man_gesturing_NO_light_skin_tone]=$'\U1F645\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_gesturing_NO_light_skin_tone_minimally]=$'\U1F645\U1F3FB\U200D\U2642'
+emoji[man_gesturing_NO_medium_light_skin_tone]=$'\U1F645\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_gesturing_NO_medium_light_skin_tone_minimally]=$'\U1F645\U1F3FC\U200D\U2642'
+emoji[man_gesturing_NO_medium_skin_tone]=$'\U1F645\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_gesturing_NO_medium_skin_tone_minimally]=$'\U1F645\U1F3FD\U200D\U2642'
+emoji[man_gesturing_NO_medium_dark_skin_tone]=$'\U1F645\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_gesturing_NO_medium_dark_skin_tone_minimally]=$'\U1F645\U1F3FE\U200D\U2642'
+emoji[man_gesturing_NO_dark_skin_tone]=$'\U1F645\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_gesturing_NO_dark_skin_tone_minimally]=$'\U1F645\U1F3FF\U200D\U2642'
+emoji[woman_gesturing_NO]=$'\U1F645\U200D\U2640\UFE0F'
+emoji[woman_gesturing_NO_minimally]=$'\U1F645\U200D\U2640'
+emoji[no_good_woman]=$'\U1F645\U200D\U2640'
+emoji[ng_woman]=$'\U1F645\U200D\U2640'
+emoji[woman_gesturing_NO_light_skin_tone]=$'\U1F645\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_gesturing_NO_light_skin_tone_minimally]=$'\U1F645\U1F3FB\U200D\U2640'
+emoji[woman_gesturing_NO_medium_light_skin_tone]=$'\U1F645\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_gesturing_NO_medium_light_skin_tone_minimally]=$'\U1F645\U1F3FC\U200D\U2640'
+emoji[woman_gesturing_NO_medium_skin_tone]=$'\U1F645\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_gesturing_NO_medium_skin_tone_minimally]=$'\U1F645\U1F3FD\U200D\U2640'
+emoji[woman_gesturing_NO_medium_dark_skin_tone]=$'\U1F645\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_gesturing_NO_medium_dark_skin_tone_minimally]=$'\U1F645\U1F3FE\U200D\U2640'
+emoji[woman_gesturing_NO_dark_skin_tone]=$'\U1F645\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_gesturing_NO_dark_skin_tone_minimally]=$'\U1F645\U1F3FF\U200D\U2640'
+emoji[person_gesturing_OK]=$'\U1F646'
+emoji[ok_person]=$'\U1F646'
+emoji[person_gesturing_OK_light_skin_tone]=$'\U1F646\U1F3FB'
+emoji[person_gesturing_OK_medium_light_skin_tone]=$'\U1F646\U1F3FC'
+emoji[person_gesturing_OK_medium_skin_tone]=$'\U1F646\U1F3FD'
+emoji[person_gesturing_OK_medium_dark_skin_tone]=$'\U1F646\U1F3FE'
+emoji[person_gesturing_OK_dark_skin_tone]=$'\U1F646\U1F3FF'
+emoji[man_gesturing_OK]=$'\U1F646\U200D\U2642\UFE0F'
+emoji[man_gesturing_OK_minimally]=$'\U1F646\U200D\U2642'
+emoji[ok_man]=$'\U1F646\U200D\U2642'
+emoji[man_gesturing_OK_light_skin_tone]=$'\U1F646\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_gesturing_OK_light_skin_tone_minimally]=$'\U1F646\U1F3FB\U200D\U2642'
+emoji[man_gesturing_OK_medium_light_skin_tone]=$'\U1F646\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_gesturing_OK_medium_light_skin_tone_minimally]=$'\U1F646\U1F3FC\U200D\U2642'
+emoji[man_gesturing_OK_medium_skin_tone]=$'\U1F646\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_gesturing_OK_medium_skin_tone_minimally]=$'\U1F646\U1F3FD\U200D\U2642'
+emoji[man_gesturing_OK_medium_dark_skin_tone]=$'\U1F646\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_gesturing_OK_medium_dark_skin_tone_minimally]=$'\U1F646\U1F3FE\U200D\U2642'
+emoji[man_gesturing_OK_dark_skin_tone]=$'\U1F646\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_gesturing_OK_dark_skin_tone_minimally]=$'\U1F646\U1F3FF\U200D\U2642'
+emoji[woman_gesturing_OK]=$'\U1F646\U200D\U2640\UFE0F'
+emoji[woman_gesturing_OK_minimally]=$'\U1F646\U200D\U2640'
+emoji[ok_woman]=$'\U1F646\U200D\U2640'
+emoji[woman_gesturing_OK_light_skin_tone]=$'\U1F646\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_gesturing_OK_light_skin_tone_minimally]=$'\U1F646\U1F3FB\U200D\U2640'
+emoji[woman_gesturing_OK_medium_light_skin_tone]=$'\U1F646\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_gesturing_OK_medium_light_skin_tone_minimally]=$'\U1F646\U1F3FC\U200D\U2640'
+emoji[woman_gesturing_OK_medium_skin_tone]=$'\U1F646\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_gesturing_OK_medium_skin_tone_minimally]=$'\U1F646\U1F3FD\U200D\U2640'
+emoji[woman_gesturing_OK_medium_dark_skin_tone]=$'\U1F646\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_gesturing_OK_medium_dark_skin_tone_minimally]=$'\U1F646\U1F3FE\U200D\U2640'
+emoji[woman_gesturing_OK_dark_skin_tone]=$'\U1F646\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_gesturing_OK_dark_skin_tone_minimally]=$'\U1F646\U1F3FF\U200D\U2640'
+emoji[person_tipping_hand]=$'\U1F481'
+emoji[tipping_hand_person]=$'\U1F481'
+emoji[information_desk_person]=$'\U1F481'
+emoji[person_tipping_hand_light_skin_tone]=$'\U1F481\U1F3FB'
+emoji[person_tipping_hand_medium_light_skin_tone]=$'\U1F481\U1F3FC'
+emoji[person_tipping_hand_medium_skin_tone]=$'\U1F481\U1F3FD'
+emoji[person_tipping_hand_medium_dark_skin_tone]=$'\U1F481\U1F3FE'
+emoji[person_tipping_hand_dark_skin_tone]=$'\U1F481\U1F3FF'
+emoji[man_tipping_hand]=$'\U1F481\U200D\U2642\UFE0F'
+emoji[man_tipping_hand_minimally]=$'\U1F481\U200D\U2642'
+emoji[tipping_hand_man]=$'\U1F481\U200D\U2642'
+emoji[sassy_man]=$'\U1F481\U200D\U2642'
+emoji[man_tipping_hand_light_skin_tone]=$'\U1F481\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_tipping_hand_light_skin_tone_minimally]=$'\U1F481\U1F3FB\U200D\U2642'
+emoji[man_tipping_hand_medium_light_skin_tone]=$'\U1F481\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_tipping_hand_medium_light_skin_tone_minimally]=$'\U1F481\U1F3FC\U200D\U2642'
+emoji[man_tipping_hand_medium_skin_tone]=$'\U1F481\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_tipping_hand_medium_skin_tone_minimally]=$'\U1F481\U1F3FD\U200D\U2642'
+emoji[man_tipping_hand_medium_dark_skin_tone]=$'\U1F481\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_tipping_hand_medium_dark_skin_tone_minimally]=$'\U1F481\U1F3FE\U200D\U2642'
+emoji[man_tipping_hand_dark_skin_tone]=$'\U1F481\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_tipping_hand_dark_skin_tone_minimally]=$'\U1F481\U1F3FF\U200D\U2642'
+emoji[woman_tipping_hand]=$'\U1F481\U200D\U2640\UFE0F'
+emoji[woman_tipping_hand_minimally]=$'\U1F481\U200D\U2640'
+emoji[tipping_hand_woman]=$'\U1F481\U200D\U2640'
+emoji[sassy_woman]=$'\U1F481\U200D\U2640'
+emoji[woman_tipping_hand_light_skin_tone]=$'\U1F481\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_tipping_hand_light_skin_tone_minimally]=$'\U1F481\U1F3FB\U200D\U2640'
+emoji[woman_tipping_hand_medium_light_skin_tone]=$'\U1F481\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_tipping_hand_medium_light_skin_tone_minimally]=$'\U1F481\U1F3FC\U200D\U2640'
+emoji[woman_tipping_hand_medium_skin_tone]=$'\U1F481\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_tipping_hand_medium_skin_tone_minimally]=$'\U1F481\U1F3FD\U200D\U2640'
+emoji[woman_tipping_hand_medium_dark_skin_tone]=$'\U1F481\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_tipping_hand_medium_dark_skin_tone_minimally]=$'\U1F481\U1F3FE\U200D\U2640'
+emoji[woman_tipping_hand_dark_skin_tone]=$'\U1F481\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_tipping_hand_dark_skin_tone_minimally]=$'\U1F481\U1F3FF\U200D\U2640'
+emoji[person_raising_hand]=$'\U1F64B'
+emoji[raising_hand]=$'\U1F64B'
+emoji[person_raising_hand_light_skin_tone]=$'\U1F64B\U1F3FB'
+emoji[person_raising_hand_medium_light_skin_tone]=$'\U1F64B\U1F3FC'
+emoji[person_raising_hand_medium_skin_tone]=$'\U1F64B\U1F3FD'
+emoji[person_raising_hand_medium_dark_skin_tone]=$'\U1F64B\U1F3FE'
+emoji[person_raising_hand_dark_skin_tone]=$'\U1F64B\U1F3FF'
+emoji[man_raising_hand]=$'\U1F64B\U200D\U2642\UFE0F'
+emoji[man_raising_hand_minimally]=$'\U1F64B\U200D\U2642'
+emoji[raising_hand_man]=$'\U1F64B\U200D\U2642'
+emoji[man_raising_hand_light_skin_tone]=$'\U1F64B\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_raising_hand_light_skin_tone_minimally]=$'\U1F64B\U1F3FB\U200D\U2642'
+emoji[man_raising_hand_medium_light_skin_tone]=$'\U1F64B\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_raising_hand_medium_light_skin_tone_minimally]=$'\U1F64B\U1F3FC\U200D\U2642'
+emoji[man_raising_hand_medium_skin_tone]=$'\U1F64B\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_raising_hand_medium_skin_tone_minimally]=$'\U1F64B\U1F3FD\U200D\U2642'
+emoji[man_raising_hand_medium_dark_skin_tone]=$'\U1F64B\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_raising_hand_medium_dark_skin_tone_minimally]=$'\U1F64B\U1F3FE\U200D\U2642'
+emoji[man_raising_hand_dark_skin_tone]=$'\U1F64B\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_raising_hand_dark_skin_tone_minimally]=$'\U1F64B\U1F3FF\U200D\U2642'
+emoji[woman_raising_hand]=$'\U1F64B\U200D\U2640\UFE0F'
+emoji[woman_raising_hand_minimally]=$'\U1F64B\U200D\U2640'
+emoji[raising_hand_woman]=$'\U1F64B\U200D\U2640'
+emoji[woman_raising_hand_light_skin_tone]=$'\U1F64B\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_raising_hand_light_skin_tone_minimally]=$'\U1F64B\U1F3FB\U200D\U2640'
+emoji[woman_raising_hand_medium_light_skin_tone]=$'\U1F64B\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_raising_hand_medium_light_skin_tone_minimally]=$'\U1F64B\U1F3FC\U200D\U2640'
+emoji[woman_raising_hand_medium_skin_tone]=$'\U1F64B\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_raising_hand_medium_skin_tone_minimally]=$'\U1F64B\U1F3FD\U200D\U2640'
+emoji[woman_raising_hand_medium_dark_skin_tone]=$'\U1F64B\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_raising_hand_medium_dark_skin_tone_minimally]=$'\U1F64B\U1F3FE\U200D\U2640'
+emoji[woman_raising_hand_dark_skin_tone]=$'\U1F64B\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_raising_hand_dark_skin_tone_minimally]=$'\U1F64B\U1F3FF\U200D\U2640'
+emoji[deaf_person]=$'\U1F9CF'
+emoji[deaf_person_light_skin_tone]=$'\U1F9CF\U1F3FB'
+emoji[deaf_person_medium_light_skin_tone]=$'\U1F9CF\U1F3FC'
+emoji[deaf_person_medium_skin_tone]=$'\U1F9CF\U1F3FD'
+emoji[deaf_person_medium_dark_skin_tone]=$'\U1F9CF\U1F3FE'
+emoji[deaf_person_dark_skin_tone]=$'\U1F9CF\U1F3FF'
+emoji[deaf_man]=$'\U1F9CF\U200D\U2642\UFE0F'
+emoji[deaf_man_minimally]=$'\U1F9CF\U200D\U2642'
+emoji[deaf_man_light_skin_tone]=$'\U1F9CF\U1F3FB\U200D\U2642\UFE0F'
+emoji[deaf_man_light_skin_tone_minimally]=$'\U1F9CF\U1F3FB\U200D\U2642'
+emoji[deaf_man_medium_light_skin_tone]=$'\U1F9CF\U1F3FC\U200D\U2642\UFE0F'
+emoji[deaf_man_medium_light_skin_tone_minimally]=$'\U1F9CF\U1F3FC\U200D\U2642'
+emoji[deaf_man_medium_skin_tone]=$'\U1F9CF\U1F3FD\U200D\U2642\UFE0F'
+emoji[deaf_man_medium_skin_tone_minimally]=$'\U1F9CF\U1F3FD\U200D\U2642'
+emoji[deaf_man_medium_dark_skin_tone]=$'\U1F9CF\U1F3FE\U200D\U2642\UFE0F'
+emoji[deaf_man_medium_dark_skin_tone_minimally]=$'\U1F9CF\U1F3FE\U200D\U2642'
+emoji[deaf_man_dark_skin_tone]=$'\U1F9CF\U1F3FF\U200D\U2642\UFE0F'
+emoji[deaf_man_dark_skin_tone_minimally]=$'\U1F9CF\U1F3FF\U200D\U2642'
+emoji[deaf_woman]=$'\U1F9CF\U200D\U2640\UFE0F'
+emoji[deaf_woman_minimally]=$'\U1F9CF\U200D\U2640'
+emoji[deaf_woman_light_skin_tone]=$'\U1F9CF\U1F3FB\U200D\U2640\UFE0F'
+emoji[deaf_woman_light_skin_tone_minimally]=$'\U1F9CF\U1F3FB\U200D\U2640'
+emoji[deaf_woman_medium_light_skin_tone]=$'\U1F9CF\U1F3FC\U200D\U2640\UFE0F'
+emoji[deaf_woman_medium_light_skin_tone_minimally]=$'\U1F9CF\U1F3FC\U200D\U2640'
+emoji[deaf_woman_medium_skin_tone]=$'\U1F9CF\U1F3FD\U200D\U2640\UFE0F'
+emoji[deaf_woman_medium_skin_tone_minimally]=$'\U1F9CF\U1F3FD\U200D\U2640'
+emoji[deaf_woman_medium_dark_skin_tone]=$'\U1F9CF\U1F3FE\U200D\U2640\UFE0F'
+emoji[deaf_woman_medium_dark_skin_tone_minimally]=$'\U1F9CF\U1F3FE\U200D\U2640'
+emoji[deaf_woman_dark_skin_tone]=$'\U1F9CF\U1F3FF\U200D\U2640\UFE0F'
+emoji[deaf_woman_dark_skin_tone_minimally]=$'\U1F9CF\U1F3FF\U200D\U2640'
+emoji[person_bowing]=$'\U1F647'
+emoji[bow]=$'\U1F647'
+emoji[person_bowing_light_skin_tone]=$'\U1F647\U1F3FB'
+emoji[person_bowing_medium_light_skin_tone]=$'\U1F647\U1F3FC'
+emoji[person_bowing_medium_skin_tone]=$'\U1F647\U1F3FD'
+emoji[person_bowing_medium_dark_skin_tone]=$'\U1F647\U1F3FE'
+emoji[person_bowing_dark_skin_tone]=$'\U1F647\U1F3FF'
+emoji[man_bowing]=$'\U1F647\U200D\U2642\UFE0F'
+emoji[man_bowing_minimally]=$'\U1F647\U200D\U2642'
+emoji[bowing_man]=$'\U1F647\U200D\U2642'
+emoji[man_bowing_light_skin_tone]=$'\U1F647\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_bowing_light_skin_tone_minimally]=$'\U1F647\U1F3FB\U200D\U2642'
+emoji[man_bowing_medium_light_skin_tone]=$'\U1F647\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_bowing_medium_light_skin_tone_minimally]=$'\U1F647\U1F3FC\U200D\U2642'
+emoji[man_bowing_medium_skin_tone]=$'\U1F647\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_bowing_medium_skin_tone_minimally]=$'\U1F647\U1F3FD\U200D\U2642'
+emoji[man_bowing_medium_dark_skin_tone]=$'\U1F647\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_bowing_medium_dark_skin_tone_minimally]=$'\U1F647\U1F3FE\U200D\U2642'
+emoji[man_bowing_dark_skin_tone]=$'\U1F647\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_bowing_dark_skin_tone_minimally]=$'\U1F647\U1F3FF\U200D\U2642'
+emoji[woman_bowing]=$'\U1F647\U200D\U2640\UFE0F'
+emoji[woman_bowing_minimally]=$'\U1F647\U200D\U2640'
+emoji[bowing_woman]=$'\U1F647\U200D\U2640'
+emoji[woman_bowing_light_skin_tone]=$'\U1F647\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_bowing_light_skin_tone_minimally]=$'\U1F647\U1F3FB\U200D\U2640'
+emoji[woman_bowing_medium_light_skin_tone]=$'\U1F647\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_bowing_medium_light_skin_tone_minimally]=$'\U1F647\U1F3FC\U200D\U2640'
+emoji[woman_bowing_medium_skin_tone]=$'\U1F647\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_bowing_medium_skin_tone_minimally]=$'\U1F647\U1F3FD\U200D\U2640'
+emoji[woman_bowing_medium_dark_skin_tone]=$'\U1F647\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_bowing_medium_dark_skin_tone_minimally]=$'\U1F647\U1F3FE\U200D\U2640'
+emoji[woman_bowing_dark_skin_tone]=$'\U1F647\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_bowing_dark_skin_tone_minimally]=$'\U1F647\U1F3FF\U200D\U2640'
+emoji[person_facepalming]=$'\U1F926'
+emoji[facepalm]=$'\U1F926'
+emoji[person_facepalming_light_skin_tone]=$'\U1F926\U1F3FB'
+emoji[person_facepalming_medium_light_skin_tone]=$'\U1F926\U1F3FC'
+emoji[person_facepalming_medium_skin_tone]=$'\U1F926\U1F3FD'
+emoji[person_facepalming_medium_dark_skin_tone]=$'\U1F926\U1F3FE'
+emoji[person_facepalming_dark_skin_tone]=$'\U1F926\U1F3FF'
+emoji[man_facepalming]=$'\U1F926\U200D\U2642\UFE0F'
+emoji[man_facepalming_minimally]=$'\U1F926\U200D\U2642'
+emoji[man_facepalming_light_skin_tone]=$'\U1F926\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_facepalming_light_skin_tone_minimally]=$'\U1F926\U1F3FB\U200D\U2642'
+emoji[man_facepalming_medium_light_skin_tone]=$'\U1F926\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_facepalming_medium_light_skin_tone_minimally]=$'\U1F926\U1F3FC\U200D\U2642'
+emoji[man_facepalming_medium_skin_tone]=$'\U1F926\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_facepalming_medium_skin_tone_minimally]=$'\U1F926\U1F3FD\U200D\U2642'
+emoji[man_facepalming_medium_dark_skin_tone]=$'\U1F926\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_facepalming_medium_dark_skin_tone_minimally]=$'\U1F926\U1F3FE\U200D\U2642'
+emoji[man_facepalming_dark_skin_tone]=$'\U1F926\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_facepalming_dark_skin_tone_minimally]=$'\U1F926\U1F3FF\U200D\U2642'
+emoji[woman_facepalming]=$'\U1F926\U200D\U2640\UFE0F'
+emoji[woman_facepalming_minimally]=$'\U1F926\U200D\U2640'
+emoji[woman_facepalming_light_skin_tone]=$'\U1F926\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_facepalming_light_skin_tone_minimally]=$'\U1F926\U1F3FB\U200D\U2640'
+emoji[woman_facepalming_medium_light_skin_tone]=$'\U1F926\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_facepalming_medium_light_skin_tone_minimally]=$'\U1F926\U1F3FC\U200D\U2640'
+emoji[woman_facepalming_medium_skin_tone]=$'\U1F926\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_facepalming_medium_skin_tone_minimally]=$'\U1F926\U1F3FD\U200D\U2640'
+emoji[woman_facepalming_medium_dark_skin_tone]=$'\U1F926\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_facepalming_medium_dark_skin_tone_minimally]=$'\U1F926\U1F3FE\U200D\U2640'
+emoji[woman_facepalming_dark_skin_tone]=$'\U1F926\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_facepalming_dark_skin_tone_minimally]=$'\U1F926\U1F3FF\U200D\U2640'
+emoji[person_shrugging]=$'\U1F937'
+emoji[shrug]=$'\U1F937'
+emoji[person_shrugging_light_skin_tone]=$'\U1F937\U1F3FB'
+emoji[person_shrugging_medium_light_skin_tone]=$'\U1F937\U1F3FC'
+emoji[person_shrugging_medium_skin_tone]=$'\U1F937\U1F3FD'
+emoji[person_shrugging_medium_dark_skin_tone]=$'\U1F937\U1F3FE'
+emoji[person_shrugging_dark_skin_tone]=$'\U1F937\U1F3FF'
+emoji[man_shrugging]=$'\U1F937\U200D\U2642\UFE0F'
+emoji[man_shrugging_minimally]=$'\U1F937\U200D\U2642'
+emoji[man_shrugging_light_skin_tone]=$'\U1F937\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_shrugging_light_skin_tone_minimally]=$'\U1F937\U1F3FB\U200D\U2642'
+emoji[man_shrugging_medium_light_skin_tone]=$'\U1F937\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_shrugging_medium_light_skin_tone_minimally]=$'\U1F937\U1F3FC\U200D\U2642'
+emoji[man_shrugging_medium_skin_tone]=$'\U1F937\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_shrugging_medium_skin_tone_minimally]=$'\U1F937\U1F3FD\U200D\U2642'
+emoji[man_shrugging_medium_dark_skin_tone]=$'\U1F937\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_shrugging_medium_dark_skin_tone_minimally]=$'\U1F937\U1F3FE\U200D\U2642'
+emoji[man_shrugging_dark_skin_tone]=$'\U1F937\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_shrugging_dark_skin_tone_minimally]=$'\U1F937\U1F3FF\U200D\U2642'
+emoji[woman_shrugging]=$'\U1F937\U200D\U2640\UFE0F'
+emoji[woman_shrugging_minimally]=$'\U1F937\U200D\U2640'
+emoji[woman_shrugging_light_skin_tone]=$'\U1F937\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_shrugging_light_skin_tone_minimally]=$'\U1F937\U1F3FB\U200D\U2640'
+emoji[woman_shrugging_medium_light_skin_tone]=$'\U1F937\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_shrugging_medium_light_skin_tone_minimally]=$'\U1F937\U1F3FC\U200D\U2640'
+emoji[woman_shrugging_medium_skin_tone]=$'\U1F937\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_shrugging_medium_skin_tone_minimally]=$'\U1F937\U1F3FD\U200D\U2640'
+emoji[woman_shrugging_medium_dark_skin_tone]=$'\U1F937\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_shrugging_medium_dark_skin_tone_minimally]=$'\U1F937\U1F3FE\U200D\U2640'
+emoji[woman_shrugging_dark_skin_tone]=$'\U1F937\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_shrugging_dark_skin_tone_minimally]=$'\U1F937\U1F3FF\U200D\U2640'
+emoji[man_health_worker]=$'\U1F468\U200D\U2695\UFE0F'
+emoji[man_health_worker_minimally]=$'\U1F468\U200D\U2695'
+emoji[man_health_worker_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U2695\UFE0F'
+emoji[man_health_worker_light_skin_tone_minimally]=$'\U1F468\U1F3FB\U200D\U2695'
+emoji[man_health_worker_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U2695\UFE0F'
+emoji[man_health_worker_medium_light_skin_tone_minimally]=$'\U1F468\U1F3FC\U200D\U2695'
+emoji[man_health_worker_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U2695\UFE0F'
+emoji[man_health_worker_medium_skin_tone_minimally]=$'\U1F468\U1F3FD\U200D\U2695'
+emoji[man_health_worker_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U2695\UFE0F'
+emoji[man_health_worker_medium_dark_skin_tone_minimally]=$'\U1F468\U1F3FE\U200D\U2695'
+emoji[man_health_worker_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U2695\UFE0F'
+emoji[man_health_worker_dark_skin_tone_minimally]=$'\U1F468\U1F3FF\U200D\U2695'
+emoji[woman_health_worker]=$'\U1F469\U200D\U2695\UFE0F'
+emoji[woman_health_worker_minimally]=$'\U1F469\U200D\U2695'
+emoji[woman_health_worker_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U2695\UFE0F'
+emoji[woman_health_worker_light_skin_tone_minimally]=$'\U1F469\U1F3FB\U200D\U2695'
+emoji[woman_health_worker_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U2695\UFE0F'
+emoji[woman_health_worker_medium_light_skin_tone_minimally]=$'\U1F469\U1F3FC\U200D\U2695'
+emoji[woman_health_worker_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U2695\UFE0F'
+emoji[woman_health_worker_medium_skin_tone_minimally]=$'\U1F469\U1F3FD\U200D\U2695'
+emoji[woman_health_worker_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U2695\UFE0F'
+emoji[woman_health_worker_medium_dark_skin_tone_minimally]=$'\U1F469\U1F3FE\U200D\U2695'
+emoji[woman_health_worker_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U2695\UFE0F'
+emoji[woman_health_worker_dark_skin_tone_minimally]=$'\U1F469\U1F3FF\U200D\U2695'
+emoji[man_student]=$'\U1F468\U200D\U1F393'
+emoji[man_student_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F393'
+emoji[man_student_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F393'
+emoji[man_student_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F393'
+emoji[man_student_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F393'
+emoji[man_student_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F393'
+emoji[woman_student]=$'\U1F469\U200D\U1F393'
+emoji[woman_student_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F393'
+emoji[woman_student_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F393'
+emoji[woman_student_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F393'
+emoji[woman_student_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F393'
+emoji[woman_student_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F393'
+emoji[man_teacher]=$'\U1F468\U200D\U1F3EB'
+emoji[man_teacher_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F3EB'
+emoji[man_teacher_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F3EB'
+emoji[man_teacher_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F3EB'
+emoji[man_teacher_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F3EB'
+emoji[man_teacher_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F3EB'
+emoji[woman_teacher]=$'\U1F469\U200D\U1F3EB'
+emoji[woman_teacher_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F3EB'
+emoji[woman_teacher_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F3EB'
+emoji[woman_teacher_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F3EB'
+emoji[woman_teacher_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F3EB'
+emoji[woman_teacher_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F3EB'
+emoji[man_judge]=$'\U1F468\U200D\U2696\UFE0F'
+emoji[man_judge_minimally]=$'\U1F468\U200D\U2696'
+emoji[man_judge_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U2696\UFE0F'
+emoji[man_judge_light_skin_tone_minimally]=$'\U1F468\U1F3FB\U200D\U2696'
+emoji[man_judge_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U2696\UFE0F'
+emoji[man_judge_medium_light_skin_tone_minimally]=$'\U1F468\U1F3FC\U200D\U2696'
+emoji[man_judge_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U2696\UFE0F'
+emoji[man_judge_medium_skin_tone_minimally]=$'\U1F468\U1F3FD\U200D\U2696'
+emoji[man_judge_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U2696\UFE0F'
+emoji[man_judge_medium_dark_skin_tone_minimally]=$'\U1F468\U1F3FE\U200D\U2696'
+emoji[man_judge_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U2696\UFE0F'
+emoji[man_judge_dark_skin_tone_minimally]=$'\U1F468\U1F3FF\U200D\U2696'
+emoji[woman_judge]=$'\U1F469\U200D\U2696\UFE0F'
+emoji[woman_judge_minimally]=$'\U1F469\U200D\U2696'
+emoji[woman_judge_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U2696\UFE0F'
+emoji[woman_judge_light_skin_tone_minimally]=$'\U1F469\U1F3FB\U200D\U2696'
+emoji[woman_judge_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U2696\UFE0F'
+emoji[woman_judge_medium_light_skin_tone_minimally]=$'\U1F469\U1F3FC\U200D\U2696'
+emoji[woman_judge_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U2696\UFE0F'
+emoji[woman_judge_medium_skin_tone_minimally]=$'\U1F469\U1F3FD\U200D\U2696'
+emoji[woman_judge_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U2696\UFE0F'
+emoji[woman_judge_medium_dark_skin_tone_minimally]=$'\U1F469\U1F3FE\U200D\U2696'
+emoji[woman_judge_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U2696\UFE0F'
+emoji[woman_judge_dark_skin_tone_minimally]=$'\U1F469\U1F3FF\U200D\U2696'
+emoji[man_farmer]=$'\U1F468\U200D\U1F33E'
+emoji[man_farmer_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F33E'
+emoji[man_farmer_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F33E'
+emoji[man_farmer_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F33E'
+emoji[man_farmer_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F33E'
+emoji[man_farmer_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F33E'
+emoji[woman_farmer]=$'\U1F469\U200D\U1F33E'
+emoji[woman_farmer_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F33E'
+emoji[woman_farmer_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F33E'
+emoji[woman_farmer_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F33E'
+emoji[woman_farmer_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F33E'
+emoji[woman_farmer_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F33E'
+emoji[man_cook]=$'\U1F468\U200D\U1F373'
+emoji[man_cook_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F373'
+emoji[man_cook_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F373'
+emoji[man_cook_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F373'
+emoji[man_cook_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F373'
+emoji[man_cook_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F373'
+emoji[woman_cook]=$'\U1F469\U200D\U1F373'
+emoji[woman_cook_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F373'
+emoji[woman_cook_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F373'
+emoji[woman_cook_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F373'
+emoji[woman_cook_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F373'
+emoji[woman_cook_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F373'
+emoji[man_mechanic]=$'\U1F468\U200D\U1F527'
+emoji[man_mechanic_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F527'
+emoji[man_mechanic_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F527'
+emoji[man_mechanic_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F527'
+emoji[man_mechanic_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F527'
+emoji[man_mechanic_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F527'
+emoji[woman_mechanic]=$'\U1F469\U200D\U1F527'
+emoji[woman_mechanic_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F527'
+emoji[woman_mechanic_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F527'
+emoji[woman_mechanic_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F527'
+emoji[woman_mechanic_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F527'
+emoji[woman_mechanic_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F527'
+emoji[man_factory_worker]=$'\U1F468\U200D\U1F3ED'
+emoji[man_factory_worker_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F3ED'
+emoji[man_factory_worker_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F3ED'
+emoji[man_factory_worker_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F3ED'
+emoji[man_factory_worker_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F3ED'
+emoji[man_factory_worker_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F3ED'
+emoji[woman_factory_worker]=$'\U1F469\U200D\U1F3ED'
+emoji[woman_factory_worker_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F3ED'
+emoji[woman_factory_worker_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F3ED'
+emoji[woman_factory_worker_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F3ED'
+emoji[woman_factory_worker_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F3ED'
+emoji[woman_factory_worker_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F3ED'
+emoji[man_office_worker]=$'\U1F468\U200D\U1F4BC'
+emoji[man_office_worker_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F4BC'
+emoji[man_office_worker_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F4BC'
+emoji[man_office_worker_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F4BC'
+emoji[man_office_worker_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F4BC'
+emoji[man_office_worker_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F4BC'
+emoji[woman_office_worker]=$'\U1F469\U200D\U1F4BC'
+emoji[woman_office_worker_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F4BC'
+emoji[woman_office_worker_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F4BC'
+emoji[woman_office_worker_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F4BC'
+emoji[woman_office_worker_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F4BC'
+emoji[woman_office_worker_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F4BC'
+emoji[man_scientist]=$'\U1F468\U200D\U1F52C'
+emoji[man_scientist_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F52C'
+emoji[man_scientist_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F52C'
+emoji[man_scientist_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F52C'
+emoji[man_scientist_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F52C'
+emoji[man_scientist_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F52C'
+emoji[woman_scientist]=$'\U1F469\U200D\U1F52C'
+emoji[woman_scientist_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F52C'
+emoji[woman_scientist_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F52C'
+emoji[woman_scientist_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F52C'
+emoji[woman_scientist_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F52C'
+emoji[woman_scientist_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F52C'
+emoji[man_technologist]=$'\U1F468\U200D\U1F4BB'
+emoji[man_technologist_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F4BB'
+emoji[man_technologist_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F4BB'
+emoji[man_technologist_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F4BB'
+emoji[man_technologist_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F4BB'
+emoji[man_technologist_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F4BB'
+emoji[woman_technologist]=$'\U1F469\U200D\U1F4BB'
+emoji[woman_technologist_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F4BB'
+emoji[woman_technologist_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F4BB'
+emoji[woman_technologist_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F4BB'
+emoji[woman_technologist_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F4BB'
+emoji[woman_technologist_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F4BB'
+emoji[man_singer]=$'\U1F468\U200D\U1F3A4'
+emoji[man_singer_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F3A4'
+emoji[man_singer_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F3A4'
+emoji[man_singer_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F3A4'
+emoji[man_singer_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F3A4'
+emoji[man_singer_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F3A4'
+emoji[woman_singer]=$'\U1F469\U200D\U1F3A4'
+emoji[woman_singer_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F3A4'
+emoji[woman_singer_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F3A4'
+emoji[woman_singer_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F3A4'
+emoji[woman_singer_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F3A4'
+emoji[woman_singer_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F3A4'
+emoji[man_artist]=$'\U1F468\U200D\U1F3A8'
+emoji[man_artist_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F3A8'
+emoji[man_artist_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F3A8'
+emoji[man_artist_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F3A8'
+emoji[man_artist_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F3A8'
+emoji[man_artist_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F3A8'
+emoji[woman_artist]=$'\U1F469\U200D\U1F3A8'
+emoji[woman_artist_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F3A8'
+emoji[woman_artist_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F3A8'
+emoji[woman_artist_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F3A8'
+emoji[woman_artist_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F3A8'
+emoji[woman_artist_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F3A8'
+emoji[man_pilot]=$'\U1F468\U200D\U2708\UFE0F'
+emoji[man_pilot_minimally]=$'\U1F468\U200D\U2708'
+emoji[man_pilot_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U2708\UFE0F'
+emoji[man_pilot_light_skin_tone_minimally]=$'\U1F468\U1F3FB\U200D\U2708'
+emoji[man_pilot_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U2708\UFE0F'
+emoji[man_pilot_medium_light_skin_tone_minimally]=$'\U1F468\U1F3FC\U200D\U2708'
+emoji[man_pilot_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U2708\UFE0F'
+emoji[man_pilot_medium_skin_tone_minimally]=$'\U1F468\U1F3FD\U200D\U2708'
+emoji[man_pilot_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U2708\UFE0F'
+emoji[man_pilot_medium_dark_skin_tone_minimally]=$'\U1F468\U1F3FE\U200D\U2708'
+emoji[man_pilot_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U2708\UFE0F'
+emoji[man_pilot_dark_skin_tone_minimally]=$'\U1F468\U1F3FF\U200D\U2708'
+emoji[woman_pilot]=$'\U1F469\U200D\U2708\UFE0F'
+emoji[woman_pilot_minimally]=$'\U1F469\U200D\U2708'
+emoji[woman_pilot_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U2708\UFE0F'
+emoji[woman_pilot_light_skin_tone_minimally]=$'\U1F469\U1F3FB\U200D\U2708'
+emoji[woman_pilot_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U2708\UFE0F'
+emoji[woman_pilot_medium_light_skin_tone_minimally]=$'\U1F469\U1F3FC\U200D\U2708'
+emoji[woman_pilot_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U2708\UFE0F'
+emoji[woman_pilot_medium_skin_tone_minimally]=$'\U1F469\U1F3FD\U200D\U2708'
+emoji[woman_pilot_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U2708\UFE0F'
+emoji[woman_pilot_medium_dark_skin_tone_minimally]=$'\U1F469\U1F3FE\U200D\U2708'
+emoji[woman_pilot_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U2708\UFE0F'
+emoji[woman_pilot_dark_skin_tone_minimally]=$'\U1F469\U1F3FF\U200D\U2708'
+emoji[man_astronaut]=$'\U1F468\U200D\U1F680'
+emoji[man_astronaut_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F680'
+emoji[man_astronaut_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F680'
+emoji[man_astronaut_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F680'
+emoji[man_astronaut_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F680'
+emoji[man_astronaut_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F680'
+emoji[woman_astronaut]=$'\U1F469\U200D\U1F680'
+emoji[woman_astronaut_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F680'
+emoji[woman_astronaut_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F680'
+emoji[woman_astronaut_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F680'
+emoji[woman_astronaut_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F680'
+emoji[woman_astronaut_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F680'
+emoji[man_firefighter]=$'\U1F468\U200D\U1F692'
+emoji[man_firefighter_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F692'
+emoji[man_firefighter_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F692'
+emoji[man_firefighter_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F692'
+emoji[man_firefighter_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F692'
+emoji[man_firefighter_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F692'
+emoji[woman_firefighter]=$'\U1F469\U200D\U1F692'
+emoji[woman_firefighter_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F692'
+emoji[woman_firefighter_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F692'
+emoji[woman_firefighter_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F692'
+emoji[woman_firefighter_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F692'
+emoji[woman_firefighter_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F692'
+emoji[police_officer]=$'\U1F46E'
+emoji[cop]=$'\U1F46E'
+emoji[police_officer_light_skin_tone]=$'\U1F46E\U1F3FB'
+emoji[police_officer_medium_light_skin_tone]=$'\U1F46E\U1F3FC'
+emoji[police_officer_medium_skin_tone]=$'\U1F46E\U1F3FD'
+emoji[police_officer_medium_dark_skin_tone]=$'\U1F46E\U1F3FE'
+emoji[police_officer_dark_skin_tone]=$'\U1F46E\U1F3FF'
+emoji[man_police_officer]=$'\U1F46E\U200D\U2642\UFE0F'
+emoji[man_police_officer_minimally]=$'\U1F46E\U200D\U2642'
+emoji[policeman]=$'\U1F46E\U200D\U2642'
+emoji[man_police_officer_light_skin_tone]=$'\U1F46E\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_police_officer_light_skin_tone_minimally]=$'\U1F46E\U1F3FB\U200D\U2642'
+emoji[man_police_officer_medium_light_skin_tone]=$'\U1F46E\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_police_officer_medium_light_skin_tone_minimally]=$'\U1F46E\U1F3FC\U200D\U2642'
+emoji[man_police_officer_medium_skin_tone]=$'\U1F46E\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_police_officer_medium_skin_tone_minimally]=$'\U1F46E\U1F3FD\U200D\U2642'
+emoji[man_police_officer_medium_dark_skin_tone]=$'\U1F46E\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_police_officer_medium_dark_skin_tone_minimally]=$'\U1F46E\U1F3FE\U200D\U2642'
+emoji[man_police_officer_dark_skin_tone]=$'\U1F46E\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_police_officer_dark_skin_tone_minimally]=$'\U1F46E\U1F3FF\U200D\U2642'
+emoji[woman_police_officer]=$'\U1F46E\U200D\U2640\UFE0F'
+emoji[woman_police_officer_minimally]=$'\U1F46E\U200D\U2640'
+emoji[policewoman]=$'\U1F46E\U200D\U2640'
+emoji[woman_police_officer_light_skin_tone]=$'\U1F46E\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_police_officer_light_skin_tone_minimally]=$'\U1F46E\U1F3FB\U200D\U2640'
+emoji[woman_police_officer_medium_light_skin_tone]=$'\U1F46E\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_police_officer_medium_light_skin_tone_minimally]=$'\U1F46E\U1F3FC\U200D\U2640'
+emoji[woman_police_officer_medium_skin_tone]=$'\U1F46E\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_police_officer_medium_skin_tone_minimally]=$'\U1F46E\U1F3FD\U200D\U2640'
+emoji[woman_police_officer_medium_dark_skin_tone]=$'\U1F46E\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_police_officer_medium_dark_skin_tone_minimally]=$'\U1F46E\U1F3FE\U200D\U2640'
+emoji[woman_police_officer_dark_skin_tone]=$'\U1F46E\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_police_officer_dark_skin_tone_minimally]=$'\U1F46E\U1F3FF\U200D\U2640'
+emoji[detective]=$'\U1F575\UFE0F'
+emoji[detective_unqualified]=$'\U1F575'
+emoji[detective_light_skin_tone]=$'\U1F575\U1F3FB'
+emoji[detective_medium_light_skin_tone]=$'\U1F575\U1F3FC'
+emoji[detective_medium_skin_tone]=$'\U1F575\U1F3FD'
+emoji[detective_medium_dark_skin_tone]=$'\U1F575\U1F3FE'
+emoji[detective_dark_skin_tone]=$'\U1F575\U1F3FF'
+emoji[man_detective]=$'\U1F575\UFE0F\U200D\U2642\UFE0F'
+emoji[male_detective]=$'\U1F575\UFE0F\U200D\U2642\UFE0F'
+emoji[man_detective_unqualified]=$'\U1F575\U200D\U2642\UFE0F'
+emoji[man_detective_unqualified_1]=$'\U1F575\UFE0F\U200D\U2642'
+emoji[man_detective_unqualified_2]=$'\U1F575\U200D\U2642'
+emoji[man_detective_light_skin_tone]=$'\U1F575\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_detective_light_skin_tone_minimally]=$'\U1F575\U1F3FB\U200D\U2642'
+emoji[man_detective_medium_light_skin_tone]=$'\U1F575\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_detective_medium_light_skin_tone_minimally]=$'\U1F575\U1F3FC\U200D\U2642'
+emoji[man_detective_medium_skin_tone]=$'\U1F575\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_detective_medium_skin_tone_minimally]=$'\U1F575\U1F3FD\U200D\U2642'
+emoji[man_detective_medium_dark_skin_tone]=$'\U1F575\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_detective_medium_dark_skin_tone_minimally]=$'\U1F575\U1F3FE\U200D\U2642'
+emoji[man_detective_dark_skin_tone]=$'\U1F575\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_detective_dark_skin_tone_minimally]=$'\U1F575\U1F3FF\U200D\U2642'
+emoji[woman_detective]=$'\U1F575\UFE0F\U200D\U2640\UFE0F'
+emoji[female_detective]=$'\U1F575\UFE0F\U200D\U2640\UFE0F'
+emoji[woman_detective_unqualified]=$'\U1F575\U200D\U2640\UFE0F'
+emoji[woman_detective_unqualified_1]=$'\U1F575\UFE0F\U200D\U2640'
+emoji[woman_detective_unqualified_2]=$'\U1F575\U200D\U2640'
+emoji[woman_detective_light_skin_tone]=$'\U1F575\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_detective_light_skin_tone_minimally]=$'\U1F575\U1F3FB\U200D\U2640'
+emoji[woman_detective_medium_light_skin_tone]=$'\U1F575\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_detective_medium_light_skin_tone_minimally]=$'\U1F575\U1F3FC\U200D\U2640'
+emoji[woman_detective_medium_skin_tone]=$'\U1F575\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_detective_medium_skin_tone_minimally]=$'\U1F575\U1F3FD\U200D\U2640'
+emoji[woman_detective_medium_dark_skin_tone]=$'\U1F575\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_detective_medium_dark_skin_tone_minimally]=$'\U1F575\U1F3FE\U200D\U2640'
+emoji[woman_detective_dark_skin_tone]=$'\U1F575\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_detective_dark_skin_tone_minimally]=$'\U1F575\U1F3FF\U200D\U2640'
+emoji[guard]=$'\U1F482'
+emoji[guard_light_skin_tone]=$'\U1F482\U1F3FB'
+emoji[guard_medium_light_skin_tone]=$'\U1F482\U1F3FC'
+emoji[guard_medium_skin_tone]=$'\U1F482\U1F3FD'
+emoji[guard_medium_dark_skin_tone]=$'\U1F482\U1F3FE'
+emoji[guard_dark_skin_tone]=$'\U1F482\U1F3FF'
+emoji[man_guard]=$'\U1F482\U200D\U2642\UFE0F'
+emoji[man_guard_minimally]=$'\U1F482\U200D\U2642'
+emoji[guardsman]=$'\U1F482\U200D\U2642'
+emoji[man_guard_light_skin_tone]=$'\U1F482\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_guard_light_skin_tone_minimally]=$'\U1F482\U1F3FB\U200D\U2642'
+emoji[man_guard_medium_light_skin_tone]=$'\U1F482\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_guard_medium_light_skin_tone_minimally]=$'\U1F482\U1F3FC\U200D\U2642'
+emoji[man_guard_medium_skin_tone]=$'\U1F482\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_guard_medium_skin_tone_minimally]=$'\U1F482\U1F3FD\U200D\U2642'
+emoji[man_guard_medium_dark_skin_tone]=$'\U1F482\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_guard_medium_dark_skin_tone_minimally]=$'\U1F482\U1F3FE\U200D\U2642'
+emoji[man_guard_dark_skin_tone]=$'\U1F482\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_guard_dark_skin_tone_minimally]=$'\U1F482\U1F3FF\U200D\U2642'
+emoji[woman_guard]=$'\U1F482\U200D\U2640\UFE0F'
+emoji[woman_guard_minimally]=$'\U1F482\U200D\U2640'
+emoji[guardswoman]=$'\U1F482\U200D\U2640'
+emoji[woman_guard_light_skin_tone]=$'\U1F482\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_guard_light_skin_tone_minimally]=$'\U1F482\U1F3FB\U200D\U2640'
+emoji[woman_guard_medium_light_skin_tone]=$'\U1F482\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_guard_medium_light_skin_tone_minimally]=$'\U1F482\U1F3FC\U200D\U2640'
+emoji[woman_guard_medium_skin_tone]=$'\U1F482\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_guard_medium_skin_tone_minimally]=$'\U1F482\U1F3FD\U200D\U2640'
+emoji[woman_guard_medium_dark_skin_tone]=$'\U1F482\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_guard_medium_dark_skin_tone_minimally]=$'\U1F482\U1F3FE\U200D\U2640'
+emoji[woman_guard_dark_skin_tone]=$'\U1F482\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_guard_dark_skin_tone_minimally]=$'\U1F482\U1F3FF\U200D\U2640'
+emoji[construction_worker]=$'\U1F477'
+emoji[construction_worker_light_skin_tone]=$'\U1F477\U1F3FB'
+emoji[construction_worker_medium_light_skin_tone]=$'\U1F477\U1F3FC'
+emoji[construction_worker_medium_skin_tone]=$'\U1F477\U1F3FD'
+emoji[construction_worker_medium_dark_skin_tone]=$'\U1F477\U1F3FE'
+emoji[construction_worker_dark_skin_tone]=$'\U1F477\U1F3FF'
+emoji[man_construction_worker]=$'\U1F477\U200D\U2642\UFE0F'
+emoji[man_construction_worker_minimally]=$'\U1F477\U200D\U2642'
+emoji[construction_worker_man]=$'\U1F477\U200D\U2642'
+emoji[man_construction_worker_light_skin_tone]=$'\U1F477\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_construction_worker_light_skin_tone_minimally]=$'\U1F477\U1F3FB\U200D\U2642'
+emoji[man_construction_worker_medium_light_skin_tone]=$'\U1F477\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_construction_worker_medium_light_skin_tone_minimally]=$'\U1F477\U1F3FC\U200D\U2642'
+emoji[man_construction_worker_medium_skin_tone]=$'\U1F477\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_construction_worker_medium_skin_tone_minimally]=$'\U1F477\U1F3FD\U200D\U2642'
+emoji[man_construction_worker_medium_dark_skin_tone]=$'\U1F477\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_construction_worker_medium_dark_skin_tone_minimally]=$'\U1F477\U1F3FE\U200D\U2642'
+emoji[man_construction_worker_dark_skin_tone]=$'\U1F477\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_construction_worker_dark_skin_tone_minimally]=$'\U1F477\U1F3FF\U200D\U2642'
+emoji[woman_construction_worker]=$'\U1F477\U200D\U2640\UFE0F'
+emoji[woman_construction_worker_minimally]=$'\U1F477\U200D\U2640'
+emoji[construction_worker_woman]=$'\U1F477\U200D\U2640'
+emoji[woman_construction_worker_light_skin_tone]=$'\U1F477\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_construction_worker_light_skin_tone_minimally]=$'\U1F477\U1F3FB\U200D\U2640'
+emoji[woman_construction_worker_medium_light_skin_tone]=$'\U1F477\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_construction_worker_medium_light_skin_tone_minimally]=$'\U1F477\U1F3FC\U200D\U2640'
+emoji[woman_construction_worker_medium_skin_tone]=$'\U1F477\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_construction_worker_medium_skin_tone_minimally]=$'\U1F477\U1F3FD\U200D\U2640'
+emoji[woman_construction_worker_medium_dark_skin_tone]=$'\U1F477\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_construction_worker_medium_dark_skin_tone_minimally]=$'\U1F477\U1F3FE\U200D\U2640'
+emoji[woman_construction_worker_dark_skin_tone]=$'\U1F477\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_construction_worker_dark_skin_tone_minimally]=$'\U1F477\U1F3FF\U200D\U2640'
+emoji[prince]=$'\U1F934'
+emoji[prince_light_skin_tone]=$'\U1F934\U1F3FB'
+emoji[prince_medium_light_skin_tone]=$'\U1F934\U1F3FC'
+emoji[prince_medium_skin_tone]=$'\U1F934\U1F3FD'
+emoji[prince_medium_dark_skin_tone]=$'\U1F934\U1F3FE'
+emoji[prince_dark_skin_tone]=$'\U1F934\U1F3FF'
+emoji[princess]=$'\U1F478'
+emoji[princess_light_skin_tone]=$'\U1F478\U1F3FB'
+emoji[princess_medium_light_skin_tone]=$'\U1F478\U1F3FC'
+emoji[princess_medium_skin_tone]=$'\U1F478\U1F3FD'
+emoji[princess_medium_dark_skin_tone]=$'\U1F478\U1F3FE'
+emoji[princess_dark_skin_tone]=$'\U1F478\U1F3FF'
+emoji[person_wearing_turban]=$'\U1F473'
+emoji[person_with_turban]=$'\U1F473'
+emoji[person_wearing_turban_light_skin_tone]=$'\U1F473\U1F3FB'
+emoji[person_wearing_turban_medium_light_skin_tone]=$'\U1F473\U1F3FC'
+emoji[person_wearing_turban_medium_skin_tone]=$'\U1F473\U1F3FD'
+emoji[person_wearing_turban_medium_dark_skin_tone]=$'\U1F473\U1F3FE'
+emoji[person_wearing_turban_dark_skin_tone]=$'\U1F473\U1F3FF'
+emoji[man_wearing_turban]=$'\U1F473\U200D\U2642\UFE0F'
+emoji[man_wearing_turban_minimally]=$'\U1F473\U200D\U2642'
+emoji[man_with_turban]=$'\U1F473\U200D\U2642'
+emoji[man_wearing_turban_light_skin_tone]=$'\U1F473\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_wearing_turban_light_skin_tone_minimally]=$'\U1F473\U1F3FB\U200D\U2642'
+emoji[man_wearing_turban_medium_light_skin_tone]=$'\U1F473\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_wearing_turban_medium_light_skin_tone_minimally]=$'\U1F473\U1F3FC\U200D\U2642'
+emoji[man_wearing_turban_medium_skin_tone]=$'\U1F473\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_wearing_turban_medium_skin_tone_minimally]=$'\U1F473\U1F3FD\U200D\U2642'
+emoji[man_wearing_turban_medium_dark_skin_tone]=$'\U1F473\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_wearing_turban_medium_dark_skin_tone_minimally]=$'\U1F473\U1F3FE\U200D\U2642'
+emoji[man_wearing_turban_dark_skin_tone]=$'\U1F473\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_wearing_turban_dark_skin_tone_minimally]=$'\U1F473\U1F3FF\U200D\U2642'
+emoji[woman_wearing_turban]=$'\U1F473\U200D\U2640\UFE0F'
+emoji[woman_wearing_turban_minimally]=$'\U1F473\U200D\U2640'
+emoji[woman_with_turban]=$'\U1F473\U200D\U2640'
+emoji[woman_wearing_turban_light_skin_tone]=$'\U1F473\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_wearing_turban_light_skin_tone_minimally]=$'\U1F473\U1F3FB\U200D\U2640'
+emoji[woman_wearing_turban_medium_light_skin_tone]=$'\U1F473\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_wearing_turban_medium_light_skin_tone_minimally]=$'\U1F473\U1F3FC\U200D\U2640'
+emoji[woman_wearing_turban_medium_skin_tone]=$'\U1F473\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_wearing_turban_medium_skin_tone_minimally]=$'\U1F473\U1F3FD\U200D\U2640'
+emoji[woman_wearing_turban_medium_dark_skin_tone]=$'\U1F473\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_wearing_turban_medium_dark_skin_tone_minimally]=$'\U1F473\U1F3FE\U200D\U2640'
+emoji[woman_wearing_turban_dark_skin_tone]=$'\U1F473\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_wearing_turban_dark_skin_tone_minimally]=$'\U1F473\U1F3FF\U200D\U2640'
+emoji[man_with_Chinese_cap]=$'\U1F472'
+emoji[man_with_gua_pi_mao]=$'\U1F472'
+emoji[man_with_Chinese_cap_light_skin_tone]=$'\U1F472\U1F3FB'
+emoji[man_with_Chinese_cap_medium_light_skin_tone]=$'\U1F472\U1F3FC'
+emoji[man_with_Chinese_cap_medium_skin_tone]=$'\U1F472\U1F3FD'
+emoji[man_with_Chinese_cap_medium_dark_skin_tone]=$'\U1F472\U1F3FE'
+emoji[man_with_Chinese_cap_dark_skin_tone]=$'\U1F472\U1F3FF'
+emoji[woman_with_headscarf]=$'\U1F9D5'
+emoji[woman_with_headscarf_light_skin_tone]=$'\U1F9D5\U1F3FB'
+emoji[woman_with_headscarf_medium_light_skin_tone]=$'\U1F9D5\U1F3FC'
+emoji[woman_with_headscarf_medium_skin_tone]=$'\U1F9D5\U1F3FD'
+emoji[woman_with_headscarf_medium_dark_skin_tone]=$'\U1F9D5\U1F3FE'
+emoji[woman_with_headscarf_dark_skin_tone]=$'\U1F9D5\U1F3FF'
+emoji[man_in_tuxedo]=$'\U1F935'
+emoji[man_in_tuxedo_light_skin_tone]=$'\U1F935\U1F3FB'
+emoji[man_in_tuxedo_medium_light_skin_tone]=$'\U1F935\U1F3FC'
+emoji[man_in_tuxedo_medium_skin_tone]=$'\U1F935\U1F3FD'
+emoji[man_in_tuxedo_medium_dark_skin_tone]=$'\U1F935\U1F3FE'
+emoji[man_in_tuxedo_dark_skin_tone]=$'\U1F935\U1F3FF'
+emoji[bride_with_veil]=$'\U1F470'
+emoji[bride_with_veil_light_skin_tone]=$'\U1F470\U1F3FB'
+emoji[bride_with_veil_medium_light_skin_tone]=$'\U1F470\U1F3FC'
+emoji[bride_with_veil_medium_skin_tone]=$'\U1F470\U1F3FD'
+emoji[bride_with_veil_medium_dark_skin_tone]=$'\U1F470\U1F3FE'
+emoji[bride_with_veil_dark_skin_tone]=$'\U1F470\U1F3FF'
+emoji[pregnant_woman]=$'\U1F930'
+emoji[pregnant_woman_light_skin_tone]=$'\U1F930\U1F3FB'
+emoji[pregnant_woman_medium_light_skin_tone]=$'\U1F930\U1F3FC'
+emoji[pregnant_woman_medium_skin_tone]=$'\U1F930\U1F3FD'
+emoji[pregnant_woman_medium_dark_skin_tone]=$'\U1F930\U1F3FE'
+emoji[pregnant_woman_dark_skin_tone]=$'\U1F930\U1F3FF'
+emoji[breast_feeding]=$'\U1F931'
+emoji[breast_feeding_light_skin_tone]=$'\U1F931\U1F3FB'
+emoji[breast_feeding_medium_light_skin_tone]=$'\U1F931\U1F3FC'
+emoji[breast_feeding_medium_skin_tone]=$'\U1F931\U1F3FD'
+emoji[breast_feeding_medium_dark_skin_tone]=$'\U1F931\U1F3FE'
+emoji[breast_feeding_dark_skin_tone]=$'\U1F931\U1F3FF'
+emoji[baby_angel]=$'\U1F47C'
+emoji[angel]=$'\U1F47C'
+emoji[baby_angel_light_skin_tone]=$'\U1F47C\U1F3FB'
+emoji[baby_angel_medium_light_skin_tone]=$'\U1F47C\U1F3FC'
+emoji[baby_angel_medium_skin_tone]=$'\U1F47C\U1F3FD'
+emoji[baby_angel_medium_dark_skin_tone]=$'\U1F47C\U1F3FE'
+emoji[baby_angel_dark_skin_tone]=$'\U1F47C\U1F3FF'
+emoji[Santa_Claus]=$'\U1F385'
+emoji[santa]=$'\U1F385'
+emoji[Santa_Claus_light_skin_tone]=$'\U1F385\U1F3FB'
+emoji[Santa_Claus_medium_light_skin_tone]=$'\U1F385\U1F3FC'
+emoji[Santa_Claus_medium_skin_tone]=$'\U1F385\U1F3FD'
+emoji[Santa_Claus_medium_dark_skin_tone]=$'\U1F385\U1F3FE'
+emoji[Santa_Claus_dark_skin_tone]=$'\U1F385\U1F3FF'
+emoji[Mrs_Claus]=$'\U1F936'
+emoji[mrs_claus]=$'\U1F936'
+emoji[Mrs_Claus_light_skin_tone]=$'\U1F936\U1F3FB'
+emoji[Mrs_Claus_medium_light_skin_tone]=$'\U1F936\U1F3FC'
+emoji[Mrs_Claus_medium_skin_tone]=$'\U1F936\U1F3FD'
+emoji[Mrs_Claus_medium_dark_skin_tone]=$'\U1F936\U1F3FE'
+emoji[Mrs_Claus_dark_skin_tone]=$'\U1F936\U1F3FF'
+emoji[superhero]=$'\U1F9B8'
+emoji[superhero_light_skin_tone]=$'\U1F9B8\U1F3FB'
+emoji[superhero_medium_light_skin_tone]=$'\U1F9B8\U1F3FC'
+emoji[superhero_medium_skin_tone]=$'\U1F9B8\U1F3FD'
+emoji[superhero_medium_dark_skin_tone]=$'\U1F9B8\U1F3FE'
+emoji[superhero_dark_skin_tone]=$'\U1F9B8\U1F3FF'
+emoji[man_superhero]=$'\U1F9B8\U200D\U2642\UFE0F'
+emoji[man_superhero_minimally]=$'\U1F9B8\U200D\U2642'
+emoji[superhero_man]=$'\U1F9B8\U200D\U2642'
+emoji[man_superhero_light_skin_tone]=$'\U1F9B8\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_superhero_light_skin_tone_minimally]=$'\U1F9B8\U1F3FB\U200D\U2642'
+emoji[man_superhero_medium_light_skin_tone]=$'\U1F9B8\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_superhero_medium_light_skin_tone_minimally]=$'\U1F9B8\U1F3FC\U200D\U2642'
+emoji[man_superhero_medium_skin_tone]=$'\U1F9B8\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_superhero_medium_skin_tone_minimally]=$'\U1F9B8\U1F3FD\U200D\U2642'
+emoji[man_superhero_medium_dark_skin_tone]=$'\U1F9B8\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_superhero_medium_dark_skin_tone_minimally]=$'\U1F9B8\U1F3FE\U200D\U2642'
+emoji[man_superhero_dark_skin_tone]=$'\U1F9B8\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_superhero_dark_skin_tone_minimally]=$'\U1F9B8\U1F3FF\U200D\U2642'
+emoji[woman_superhero]=$'\U1F9B8\U200D\U2640\UFE0F'
+emoji[woman_superhero_minimally]=$'\U1F9B8\U200D\U2640'
+emoji[superhero_woman]=$'\U1F9B8\U200D\U2640'
+emoji[woman_superhero_light_skin_tone]=$'\U1F9B8\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_superhero_light_skin_tone_minimally]=$'\U1F9B8\U1F3FB\U200D\U2640'
+emoji[woman_superhero_medium_light_skin_tone]=$'\U1F9B8\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_superhero_medium_light_skin_tone_minimally]=$'\U1F9B8\U1F3FC\U200D\U2640'
+emoji[woman_superhero_medium_skin_tone]=$'\U1F9B8\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_superhero_medium_skin_tone_minimally]=$'\U1F9B8\U1F3FD\U200D\U2640'
+emoji[woman_superhero_medium_dark_skin_tone]=$'\U1F9B8\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_superhero_medium_dark_skin_tone_minimally]=$'\U1F9B8\U1F3FE\U200D\U2640'
+emoji[woman_superhero_dark_skin_tone]=$'\U1F9B8\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_superhero_dark_skin_tone_minimally]=$'\U1F9B8\U1F3FF\U200D\U2640'
+emoji[supervillain]=$'\U1F9B9'
+emoji[supervillain_light_skin_tone]=$'\U1F9B9\U1F3FB'
+emoji[supervillain_medium_light_skin_tone]=$'\U1F9B9\U1F3FC'
+emoji[supervillain_medium_skin_tone]=$'\U1F9B9\U1F3FD'
+emoji[supervillain_medium_dark_skin_tone]=$'\U1F9B9\U1F3FE'
+emoji[supervillain_dark_skin_tone]=$'\U1F9B9\U1F3FF'
+emoji[man_supervillain]=$'\U1F9B9\U200D\U2642\UFE0F'
+emoji[man_supervillain_minimally]=$'\U1F9B9\U200D\U2642'
+emoji[supervillain_man]=$'\U1F9B9\U200D\U2642'
+emoji[man_supervillain_light_skin_tone]=$'\U1F9B9\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_supervillain_light_skin_tone_minimally]=$'\U1F9B9\U1F3FB\U200D\U2642'
+emoji[man_supervillain_medium_light_skin_tone]=$'\U1F9B9\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_supervillain_medium_light_skin_tone_minimally]=$'\U1F9B9\U1F3FC\U200D\U2642'
+emoji[man_supervillain_medium_skin_tone]=$'\U1F9B9\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_supervillain_medium_skin_tone_minimally]=$'\U1F9B9\U1F3FD\U200D\U2642'
+emoji[man_supervillain_medium_dark_skin_tone]=$'\U1F9B9\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_supervillain_medium_dark_skin_tone_minimally]=$'\U1F9B9\U1F3FE\U200D\U2642'
+emoji[man_supervillain_dark_skin_tone]=$'\U1F9B9\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_supervillain_dark_skin_tone_minimally]=$'\U1F9B9\U1F3FF\U200D\U2642'
+emoji[woman_supervillain]=$'\U1F9B9\U200D\U2640\UFE0F'
+emoji[woman_supervillain_minimally]=$'\U1F9B9\U200D\U2640'
+emoji[supervillain_woman]=$'\U1F9B9\U200D\U2640'
+emoji[woman_supervillain_light_skin_tone]=$'\U1F9B9\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_supervillain_light_skin_tone_minimally]=$'\U1F9B9\U1F3FB\U200D\U2640'
+emoji[woman_supervillain_medium_light_skin_tone]=$'\U1F9B9\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_supervillain_medium_light_skin_tone_minimally]=$'\U1F9B9\U1F3FC\U200D\U2640'
+emoji[woman_supervillain_medium_skin_tone]=$'\U1F9B9\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_supervillain_medium_skin_tone_minimally]=$'\U1F9B9\U1F3FD\U200D\U2640'
+emoji[woman_supervillain_medium_dark_skin_tone]=$'\U1F9B9\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_supervillain_medium_dark_skin_tone_minimally]=$'\U1F9B9\U1F3FE\U200D\U2640'
+emoji[woman_supervillain_dark_skin_tone]=$'\U1F9B9\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_supervillain_dark_skin_tone_minimally]=$'\U1F9B9\U1F3FF\U200D\U2640'
+emoji[mage]=$'\U1F9D9'
+emoji[mage_light_skin_tone]=$'\U1F9D9\U1F3FB'
+emoji[mage_medium_light_skin_tone]=$'\U1F9D9\U1F3FC'
+emoji[mage_medium_skin_tone]=$'\U1F9D9\U1F3FD'
+emoji[mage_medium_dark_skin_tone]=$'\U1F9D9\U1F3FE'
+emoji[mage_dark_skin_tone]=$'\U1F9D9\U1F3FF'
+emoji[man_mage]=$'\U1F9D9\U200D\U2642\UFE0F'
+emoji[man_mage_minimally]=$'\U1F9D9\U200D\U2642'
+emoji[mage_man]=$'\U1F9D9\U200D\U2642'
+emoji[man_mage_light_skin_tone]=$'\U1F9D9\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_mage_light_skin_tone_minimally]=$'\U1F9D9\U1F3FB\U200D\U2642'
+emoji[man_mage_medium_light_skin_tone]=$'\U1F9D9\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_mage_medium_light_skin_tone_minimally]=$'\U1F9D9\U1F3FC\U200D\U2642'
+emoji[man_mage_medium_skin_tone]=$'\U1F9D9\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_mage_medium_skin_tone_minimally]=$'\U1F9D9\U1F3FD\U200D\U2642'
+emoji[man_mage_medium_dark_skin_tone]=$'\U1F9D9\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_mage_medium_dark_skin_tone_minimally]=$'\U1F9D9\U1F3FE\U200D\U2642'
+emoji[man_mage_dark_skin_tone]=$'\U1F9D9\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_mage_dark_skin_tone_minimally]=$'\U1F9D9\U1F3FF\U200D\U2642'
+emoji[woman_mage]=$'\U1F9D9\U200D\U2640\UFE0F'
+emoji[woman_mage_minimally]=$'\U1F9D9\U200D\U2640'
+emoji[mage_woman]=$'\U1F9D9\U200D\U2640'
+emoji[woman_mage_light_skin_tone]=$'\U1F9D9\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_mage_light_skin_tone_minimally]=$'\U1F9D9\U1F3FB\U200D\U2640'
+emoji[woman_mage_medium_light_skin_tone]=$'\U1F9D9\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_mage_medium_light_skin_tone_minimally]=$'\U1F9D9\U1F3FC\U200D\U2640'
+emoji[woman_mage_medium_skin_tone]=$'\U1F9D9\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_mage_medium_skin_tone_minimally]=$'\U1F9D9\U1F3FD\U200D\U2640'
+emoji[woman_mage_medium_dark_skin_tone]=$'\U1F9D9\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_mage_medium_dark_skin_tone_minimally]=$'\U1F9D9\U1F3FE\U200D\U2640'
+emoji[woman_mage_dark_skin_tone]=$'\U1F9D9\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_mage_dark_skin_tone_minimally]=$'\U1F9D9\U1F3FF\U200D\U2640'
+emoji[fairy]=$'\U1F9DA'
+emoji[fairy_light_skin_tone]=$'\U1F9DA\U1F3FB'
+emoji[fairy_medium_light_skin_tone]=$'\U1F9DA\U1F3FC'
+emoji[fairy_medium_skin_tone]=$'\U1F9DA\U1F3FD'
+emoji[fairy_medium_dark_skin_tone]=$'\U1F9DA\U1F3FE'
+emoji[fairy_dark_skin_tone]=$'\U1F9DA\U1F3FF'
+emoji[man_fairy]=$'\U1F9DA\U200D\U2642\UFE0F'
+emoji[man_fairy_minimally]=$'\U1F9DA\U200D\U2642'
+emoji[fairy_man]=$'\U1F9DA\U200D\U2642'
+emoji[man_fairy_light_skin_tone]=$'\U1F9DA\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_fairy_light_skin_tone_minimally]=$'\U1F9DA\U1F3FB\U200D\U2642'
+emoji[man_fairy_medium_light_skin_tone]=$'\U1F9DA\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_fairy_medium_light_skin_tone_minimally]=$'\U1F9DA\U1F3FC\U200D\U2642'
+emoji[man_fairy_medium_skin_tone]=$'\U1F9DA\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_fairy_medium_skin_tone_minimally]=$'\U1F9DA\U1F3FD\U200D\U2642'
+emoji[man_fairy_medium_dark_skin_tone]=$'\U1F9DA\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_fairy_medium_dark_skin_tone_minimally]=$'\U1F9DA\U1F3FE\U200D\U2642'
+emoji[man_fairy_dark_skin_tone]=$'\U1F9DA\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_fairy_dark_skin_tone_minimally]=$'\U1F9DA\U1F3FF\U200D\U2642'
+emoji[woman_fairy]=$'\U1F9DA\U200D\U2640\UFE0F'
+emoji[woman_fairy_minimally]=$'\U1F9DA\U200D\U2640'
+emoji[fairy_woman]=$'\U1F9DA\U200D\U2640'
+emoji[woman_fairy_light_skin_tone]=$'\U1F9DA\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_fairy_light_skin_tone_minimally]=$'\U1F9DA\U1F3FB\U200D\U2640'
+emoji[woman_fairy_medium_light_skin_tone]=$'\U1F9DA\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_fairy_medium_light_skin_tone_minimally]=$'\U1F9DA\U1F3FC\U200D\U2640'
+emoji[woman_fairy_medium_skin_tone]=$'\U1F9DA\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_fairy_medium_skin_tone_minimally]=$'\U1F9DA\U1F3FD\U200D\U2640'
+emoji[woman_fairy_medium_dark_skin_tone]=$'\U1F9DA\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_fairy_medium_dark_skin_tone_minimally]=$'\U1F9DA\U1F3FE\U200D\U2640'
+emoji[woman_fairy_dark_skin_tone]=$'\U1F9DA\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_fairy_dark_skin_tone_minimally]=$'\U1F9DA\U1F3FF\U200D\U2640'
+emoji[vampire]=$'\U1F9DB'
+emoji[vampire_light_skin_tone]=$'\U1F9DB\U1F3FB'
+emoji[vampire_medium_light_skin_tone]=$'\U1F9DB\U1F3FC'
+emoji[vampire_medium_skin_tone]=$'\U1F9DB\U1F3FD'
+emoji[vampire_medium_dark_skin_tone]=$'\U1F9DB\U1F3FE'
+emoji[vampire_dark_skin_tone]=$'\U1F9DB\U1F3FF'
+emoji[man_vampire]=$'\U1F9DB\U200D\U2642\UFE0F'
+emoji[man_vampire_minimally]=$'\U1F9DB\U200D\U2642'
+emoji[vampire_man]=$'\U1F9DB\U200D\U2642'
+emoji[man_vampire_light_skin_tone]=$'\U1F9DB\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_vampire_light_skin_tone_minimally]=$'\U1F9DB\U1F3FB\U200D\U2642'
+emoji[man_vampire_medium_light_skin_tone]=$'\U1F9DB\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_vampire_medium_light_skin_tone_minimally]=$'\U1F9DB\U1F3FC\U200D\U2642'
+emoji[man_vampire_medium_skin_tone]=$'\U1F9DB\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_vampire_medium_skin_tone_minimally]=$'\U1F9DB\U1F3FD\U200D\U2642'
+emoji[man_vampire_medium_dark_skin_tone]=$'\U1F9DB\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_vampire_medium_dark_skin_tone_minimally]=$'\U1F9DB\U1F3FE\U200D\U2642'
+emoji[man_vampire_dark_skin_tone]=$'\U1F9DB\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_vampire_dark_skin_tone_minimally]=$'\U1F9DB\U1F3FF\U200D\U2642'
+emoji[woman_vampire]=$'\U1F9DB\U200D\U2640\UFE0F'
+emoji[woman_vampire_minimally]=$'\U1F9DB\U200D\U2640'
+emoji[vampire_woman]=$'\U1F9DB\U200D\U2640'
+emoji[woman_vampire_light_skin_tone]=$'\U1F9DB\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_vampire_light_skin_tone_minimally]=$'\U1F9DB\U1F3FB\U200D\U2640'
+emoji[woman_vampire_medium_light_skin_tone]=$'\U1F9DB\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_vampire_medium_light_skin_tone_minimally]=$'\U1F9DB\U1F3FC\U200D\U2640'
+emoji[woman_vampire_medium_skin_tone]=$'\U1F9DB\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_vampire_medium_skin_tone_minimally]=$'\U1F9DB\U1F3FD\U200D\U2640'
+emoji[woman_vampire_medium_dark_skin_tone]=$'\U1F9DB\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_vampire_medium_dark_skin_tone_minimally]=$'\U1F9DB\U1F3FE\U200D\U2640'
+emoji[woman_vampire_dark_skin_tone]=$'\U1F9DB\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_vampire_dark_skin_tone_minimally]=$'\U1F9DB\U1F3FF\U200D\U2640'
+emoji[merperson]=$'\U1F9DC'
+emoji[merperson_light_skin_tone]=$'\U1F9DC\U1F3FB'
+emoji[merperson_medium_light_skin_tone]=$'\U1F9DC\U1F3FC'
+emoji[merperson_medium_skin_tone]=$'\U1F9DC\U1F3FD'
+emoji[merperson_medium_dark_skin_tone]=$'\U1F9DC\U1F3FE'
+emoji[merperson_dark_skin_tone]=$'\U1F9DC\U1F3FF'
+emoji[merman]=$'\U1F9DC\U200D\U2642\UFE0F'
+emoji[merman_minimally]=$'\U1F9DC\U200D\U2642'
+emoji[merman_light_skin_tone]=$'\U1F9DC\U1F3FB\U200D\U2642\UFE0F'
+emoji[merman_light_skin_tone_minimally]=$'\U1F9DC\U1F3FB\U200D\U2642'
+emoji[merman_medium_light_skin_tone]=$'\U1F9DC\U1F3FC\U200D\U2642\UFE0F'
+emoji[merman_medium_light_skin_tone_minimally]=$'\U1F9DC\U1F3FC\U200D\U2642'
+emoji[merman_medium_skin_tone]=$'\U1F9DC\U1F3FD\U200D\U2642\UFE0F'
+emoji[merman_medium_skin_tone_minimally]=$'\U1F9DC\U1F3FD\U200D\U2642'
+emoji[merman_medium_dark_skin_tone]=$'\U1F9DC\U1F3FE\U200D\U2642\UFE0F'
+emoji[merman_medium_dark_skin_tone_minimally]=$'\U1F9DC\U1F3FE\U200D\U2642'
+emoji[merman_dark_skin_tone]=$'\U1F9DC\U1F3FF\U200D\U2642\UFE0F'
+emoji[merman_dark_skin_tone_minimally]=$'\U1F9DC\U1F3FF\U200D\U2642'
+emoji[mermaid]=$'\U1F9DC\U200D\U2640\UFE0F'
+emoji[mermaid_minimally]=$'\U1F9DC\U200D\U2640'
+emoji[mermaid_light_skin_tone]=$'\U1F9DC\U1F3FB\U200D\U2640\UFE0F'
+emoji[mermaid_light_skin_tone_minimally]=$'\U1F9DC\U1F3FB\U200D\U2640'
+emoji[mermaid_medium_light_skin_tone]=$'\U1F9DC\U1F3FC\U200D\U2640\UFE0F'
+emoji[mermaid_medium_light_skin_tone_minimally]=$'\U1F9DC\U1F3FC\U200D\U2640'
+emoji[mermaid_medium_skin_tone]=$'\U1F9DC\U1F3FD\U200D\U2640\UFE0F'
+emoji[mermaid_medium_skin_tone_minimally]=$'\U1F9DC\U1F3FD\U200D\U2640'
+emoji[mermaid_medium_dark_skin_tone]=$'\U1F9DC\U1F3FE\U200D\U2640\UFE0F'
+emoji[mermaid_medium_dark_skin_tone_minimally]=$'\U1F9DC\U1F3FE\U200D\U2640'
+emoji[mermaid_dark_skin_tone]=$'\U1F9DC\U1F3FF\U200D\U2640\UFE0F'
+emoji[mermaid_dark_skin_tone_minimally]=$'\U1F9DC\U1F3FF\U200D\U2640'
+emoji[elf]=$'\U1F9DD'
+emoji[elf_light_skin_tone]=$'\U1F9DD\U1F3FB'
+emoji[elf_medium_light_skin_tone]=$'\U1F9DD\U1F3FC'
+emoji[elf_medium_skin_tone]=$'\U1F9DD\U1F3FD'
+emoji[elf_medium_dark_skin_tone]=$'\U1F9DD\U1F3FE'
+emoji[elf_dark_skin_tone]=$'\U1F9DD\U1F3FF'
+emoji[man_elf]=$'\U1F9DD\U200D\U2642\UFE0F'
+emoji[man_elf_minimally]=$'\U1F9DD\U200D\U2642'
+emoji[elf_man]=$'\U1F9DD\U200D\U2642'
+emoji[man_elf_light_skin_tone]=$'\U1F9DD\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_elf_light_skin_tone_minimally]=$'\U1F9DD\U1F3FB\U200D\U2642'
+emoji[man_elf_medium_light_skin_tone]=$'\U1F9DD\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_elf_medium_light_skin_tone_minimally]=$'\U1F9DD\U1F3FC\U200D\U2642'
+emoji[man_elf_medium_skin_tone]=$'\U1F9DD\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_elf_medium_skin_tone_minimally]=$'\U1F9DD\U1F3FD\U200D\U2642'
+emoji[man_elf_medium_dark_skin_tone]=$'\U1F9DD\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_elf_medium_dark_skin_tone_minimally]=$'\U1F9DD\U1F3FE\U200D\U2642'
+emoji[man_elf_dark_skin_tone]=$'\U1F9DD\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_elf_dark_skin_tone_minimally]=$'\U1F9DD\U1F3FF\U200D\U2642'
+emoji[woman_elf]=$'\U1F9DD\U200D\U2640\UFE0F'
+emoji[woman_elf_minimally]=$'\U1F9DD\U200D\U2640'
+emoji[elf_woman]=$'\U1F9DD\U200D\U2640'
+emoji[woman_elf_light_skin_tone]=$'\U1F9DD\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_elf_light_skin_tone_minimally]=$'\U1F9DD\U1F3FB\U200D\U2640'
+emoji[woman_elf_medium_light_skin_tone]=$'\U1F9DD\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_elf_medium_light_skin_tone_minimally]=$'\U1F9DD\U1F3FC\U200D\U2640'
+emoji[woman_elf_medium_skin_tone]=$'\U1F9DD\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_elf_medium_skin_tone_minimally]=$'\U1F9DD\U1F3FD\U200D\U2640'
+emoji[woman_elf_medium_dark_skin_tone]=$'\U1F9DD\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_elf_medium_dark_skin_tone_minimally]=$'\U1F9DD\U1F3FE\U200D\U2640'
+emoji[woman_elf_dark_skin_tone]=$'\U1F9DD\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_elf_dark_skin_tone_minimally]=$'\U1F9DD\U1F3FF\U200D\U2640'
+emoji[genie]=$'\U1F9DE'
+emoji[man_genie]=$'\U1F9DE\U200D\U2642\UFE0F'
+emoji[man_genie_minimally]=$'\U1F9DE\U200D\U2642'
+emoji[genie_man]=$'\U1F9DE\U200D\U2642'
+emoji[woman_genie]=$'\U1F9DE\U200D\U2640\UFE0F'
+emoji[woman_genie_minimally]=$'\U1F9DE\U200D\U2640'
+emoji[genie_woman]=$'\U1F9DE\U200D\U2640'
+emoji[zombie]=$'\U1F9DF'
+emoji[man_zombie]=$'\U1F9DF\U200D\U2642\UFE0F'
+emoji[man_zombie_minimally]=$'\U1F9DF\U200D\U2642'
+emoji[zombie_man]=$'\U1F9DF\U200D\U2642'
+emoji[woman_zombie]=$'\U1F9DF\U200D\U2640\UFE0F'
+emoji[woman_zombie_minimally]=$'\U1F9DF\U200D\U2640'
+emoji[zombie_woman]=$'\U1F9DF\U200D\U2640'
+emoji[person_getting_massage]=$'\U1F486'
+emoji[massage]=$'\U1F486'
+emoji[person_getting_massage_light_skin_tone]=$'\U1F486\U1F3FB'
+emoji[person_getting_massage_medium_light_skin_tone]=$'\U1F486\U1F3FC'
+emoji[person_getting_massage_medium_skin_tone]=$'\U1F486\U1F3FD'
+emoji[person_getting_massage_medium_dark_skin_tone]=$'\U1F486\U1F3FE'
+emoji[person_getting_massage_dark_skin_tone]=$'\U1F486\U1F3FF'
+emoji[man_getting_massage]=$'\U1F486\U200D\U2642\UFE0F'
+emoji[man_getting_massage_minimally]=$'\U1F486\U200D\U2642'
+emoji[massage_man]=$'\U1F486\U200D\U2642'
+emoji[man_getting_massage_light_skin_tone]=$'\U1F486\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_getting_massage_light_skin_tone_minimally]=$'\U1F486\U1F3FB\U200D\U2642'
+emoji[man_getting_massage_medium_light_skin_tone]=$'\U1F486\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_getting_massage_medium_light_skin_tone_minimally]=$'\U1F486\U1F3FC\U200D\U2642'
+emoji[man_getting_massage_medium_skin_tone]=$'\U1F486\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_getting_massage_medium_skin_tone_minimally]=$'\U1F486\U1F3FD\U200D\U2642'
+emoji[man_getting_massage_medium_dark_skin_tone]=$'\U1F486\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_getting_massage_medium_dark_skin_tone_minimally]=$'\U1F486\U1F3FE\U200D\U2642'
+emoji[man_getting_massage_dark_skin_tone]=$'\U1F486\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_getting_massage_dark_skin_tone_minimally]=$'\U1F486\U1F3FF\U200D\U2642'
+emoji[woman_getting_massage]=$'\U1F486\U200D\U2640\UFE0F'
+emoji[woman_getting_massage_minimally]=$'\U1F486\U200D\U2640'
+emoji[massage_woman]=$'\U1F486\U200D\U2640'
+emoji[woman_getting_massage_light_skin_tone]=$'\U1F486\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_getting_massage_light_skin_tone_minimally]=$'\U1F486\U1F3FB\U200D\U2640'
+emoji[woman_getting_massage_medium_light_skin_tone]=$'\U1F486\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_getting_massage_medium_light_skin_tone_minimally]=$'\U1F486\U1F3FC\U200D\U2640'
+emoji[woman_getting_massage_medium_skin_tone]=$'\U1F486\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_getting_massage_medium_skin_tone_minimally]=$'\U1F486\U1F3FD\U200D\U2640'
+emoji[woman_getting_massage_medium_dark_skin_tone]=$'\U1F486\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_getting_massage_medium_dark_skin_tone_minimally]=$'\U1F486\U1F3FE\U200D\U2640'
+emoji[woman_getting_massage_dark_skin_tone]=$'\U1F486\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_getting_massage_dark_skin_tone_minimally]=$'\U1F486\U1F3FF\U200D\U2640'
+emoji[person_getting_haircut]=$'\U1F487'
+emoji[haircut]=$'\U1F487'
+emoji[person_getting_haircut_light_skin_tone]=$'\U1F487\U1F3FB'
+emoji[person_getting_haircut_medium_light_skin_tone]=$'\U1F487\U1F3FC'
+emoji[person_getting_haircut_medium_skin_tone]=$'\U1F487\U1F3FD'
+emoji[person_getting_haircut_medium_dark_skin_tone]=$'\U1F487\U1F3FE'
+emoji[person_getting_haircut_dark_skin_tone]=$'\U1F487\U1F3FF'
+emoji[man_getting_haircut]=$'\U1F487\U200D\U2642\UFE0F'
+emoji[man_getting_haircut_minimally]=$'\U1F487\U200D\U2642'
+emoji[haircut_man]=$'\U1F487\U200D\U2642'
+emoji[man_getting_haircut_light_skin_tone]=$'\U1F487\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_getting_haircut_light_skin_tone_minimally]=$'\U1F487\U1F3FB\U200D\U2642'
+emoji[man_getting_haircut_medium_light_skin_tone]=$'\U1F487\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_getting_haircut_medium_light_skin_tone_minimally]=$'\U1F487\U1F3FC\U200D\U2642'
+emoji[man_getting_haircut_medium_skin_tone]=$'\U1F487\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_getting_haircut_medium_skin_tone_minimally]=$'\U1F487\U1F3FD\U200D\U2642'
+emoji[man_getting_haircut_medium_dark_skin_tone]=$'\U1F487\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_getting_haircut_medium_dark_skin_tone_minimally]=$'\U1F487\U1F3FE\U200D\U2642'
+emoji[man_getting_haircut_dark_skin_tone]=$'\U1F487\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_getting_haircut_dark_skin_tone_minimally]=$'\U1F487\U1F3FF\U200D\U2642'
+emoji[woman_getting_haircut]=$'\U1F487\U200D\U2640\UFE0F'
+emoji[woman_getting_haircut_minimally]=$'\U1F487\U200D\U2640'
+emoji[haircut_woman]=$'\U1F487\U200D\U2640'
+emoji[woman_getting_haircut_light_skin_tone]=$'\U1F487\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_getting_haircut_light_skin_tone_minimally]=$'\U1F487\U1F3FB\U200D\U2640'
+emoji[woman_getting_haircut_medium_light_skin_tone]=$'\U1F487\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_getting_haircut_medium_light_skin_tone_minimally]=$'\U1F487\U1F3FC\U200D\U2640'
+emoji[woman_getting_haircut_medium_skin_tone]=$'\U1F487\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_getting_haircut_medium_skin_tone_minimally]=$'\U1F487\U1F3FD\U200D\U2640'
+emoji[woman_getting_haircut_medium_dark_skin_tone]=$'\U1F487\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_getting_haircut_medium_dark_skin_tone_minimally]=$'\U1F487\U1F3FE\U200D\U2640'
+emoji[woman_getting_haircut_dark_skin_tone]=$'\U1F487\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_getting_haircut_dark_skin_tone_minimally]=$'\U1F487\U1F3FF\U200D\U2640'
+emoji[person_walking]=$'\U1F6B6'
+emoji[walking]=$'\U1F6B6'
+emoji[person_walking_light_skin_tone]=$'\U1F6B6\U1F3FB'
+emoji[person_walking_medium_light_skin_tone]=$'\U1F6B6\U1F3FC'
+emoji[person_walking_medium_skin_tone]=$'\U1F6B6\U1F3FD'
+emoji[person_walking_medium_dark_skin_tone]=$'\U1F6B6\U1F3FE'
+emoji[person_walking_dark_skin_tone]=$'\U1F6B6\U1F3FF'
+emoji[man_walking]=$'\U1F6B6\U200D\U2642\UFE0F'
+emoji[man_walking_minimally]=$'\U1F6B6\U200D\U2642'
+emoji[walking_man]=$'\U1F6B6\U200D\U2642'
+emoji[man_walking_light_skin_tone]=$'\U1F6B6\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_walking_light_skin_tone_minimally]=$'\U1F6B6\U1F3FB\U200D\U2642'
+emoji[man_walking_medium_light_skin_tone]=$'\U1F6B6\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_walking_medium_light_skin_tone_minimally]=$'\U1F6B6\U1F3FC\U200D\U2642'
+emoji[man_walking_medium_skin_tone]=$'\U1F6B6\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_walking_medium_skin_tone_minimally]=$'\U1F6B6\U1F3FD\U200D\U2642'
+emoji[man_walking_medium_dark_skin_tone]=$'\U1F6B6\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_walking_medium_dark_skin_tone_minimally]=$'\U1F6B6\U1F3FE\U200D\U2642'
+emoji[man_walking_dark_skin_tone]=$'\U1F6B6\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_walking_dark_skin_tone_minimally]=$'\U1F6B6\U1F3FF\U200D\U2642'
+emoji[woman_walking]=$'\U1F6B6\U200D\U2640\UFE0F'
+emoji[woman_walking_minimally]=$'\U1F6B6\U200D\U2640'
+emoji[walking_woman]=$'\U1F6B6\U200D\U2640'
+emoji[woman_walking_light_skin_tone]=$'\U1F6B6\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_walking_light_skin_tone_minimally]=$'\U1F6B6\U1F3FB\U200D\U2640'
+emoji[woman_walking_medium_light_skin_tone]=$'\U1F6B6\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_walking_medium_light_skin_tone_minimally]=$'\U1F6B6\U1F3FC\U200D\U2640'
+emoji[woman_walking_medium_skin_tone]=$'\U1F6B6\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_walking_medium_skin_tone_minimally]=$'\U1F6B6\U1F3FD\U200D\U2640'
+emoji[woman_walking_medium_dark_skin_tone]=$'\U1F6B6\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_walking_medium_dark_skin_tone_minimally]=$'\U1F6B6\U1F3FE\U200D\U2640'
+emoji[woman_walking_dark_skin_tone]=$'\U1F6B6\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_walking_dark_skin_tone_minimally]=$'\U1F6B6\U1F3FF\U200D\U2640'
+emoji[person_standing]=$'\U1F9CD'
+emoji[standing_person]=$'\U1F9CD'
+emoji[person_standing_light_skin_tone]=$'\U1F9CD\U1F3FB'
+emoji[person_standing_medium_light_skin_tone]=$'\U1F9CD\U1F3FC'
+emoji[person_standing_medium_skin_tone]=$'\U1F9CD\U1F3FD'
+emoji[person_standing_medium_dark_skin_tone]=$'\U1F9CD\U1F3FE'
+emoji[person_standing_dark_skin_tone]=$'\U1F9CD\U1F3FF'
+emoji[man_standing]=$'\U1F9CD\U200D\U2642\UFE0F'
+emoji[man_standing_minimally]=$'\U1F9CD\U200D\U2642'
+emoji[standing_man]=$'\U1F9CD\U200D\U2642'
+emoji[man_standing_light_skin_tone]=$'\U1F9CD\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_standing_light_skin_tone_minimally]=$'\U1F9CD\U1F3FB\U200D\U2642'
+emoji[man_standing_medium_light_skin_tone]=$'\U1F9CD\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_standing_medium_light_skin_tone_minimally]=$'\U1F9CD\U1F3FC\U200D\U2642'
+emoji[man_standing_medium_skin_tone]=$'\U1F9CD\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_standing_medium_skin_tone_minimally]=$'\U1F9CD\U1F3FD\U200D\U2642'
+emoji[man_standing_medium_dark_skin_tone]=$'\U1F9CD\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_standing_medium_dark_skin_tone_minimally]=$'\U1F9CD\U1F3FE\U200D\U2642'
+emoji[man_standing_dark_skin_tone]=$'\U1F9CD\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_standing_dark_skin_tone_minimally]=$'\U1F9CD\U1F3FF\U200D\U2642'
+emoji[woman_standing]=$'\U1F9CD\U200D\U2640\UFE0F'
+emoji[woman_standing_minimally]=$'\U1F9CD\U200D\U2640'
+emoji[standing_woman]=$'\U1F9CD\U200D\U2640'
+emoji[woman_standing_light_skin_tone]=$'\U1F9CD\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_standing_light_skin_tone_minimally]=$'\U1F9CD\U1F3FB\U200D\U2640'
+emoji[woman_standing_medium_light_skin_tone]=$'\U1F9CD\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_standing_medium_light_skin_tone_minimally]=$'\U1F9CD\U1F3FC\U200D\U2640'
+emoji[woman_standing_medium_skin_tone]=$'\U1F9CD\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_standing_medium_skin_tone_minimally]=$'\U1F9CD\U1F3FD\U200D\U2640'
+emoji[woman_standing_medium_dark_skin_tone]=$'\U1F9CD\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_standing_medium_dark_skin_tone_minimally]=$'\U1F9CD\U1F3FE\U200D\U2640'
+emoji[woman_standing_dark_skin_tone]=$'\U1F9CD\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_standing_dark_skin_tone_minimally]=$'\U1F9CD\U1F3FF\U200D\U2640'
+emoji[person_kneeling]=$'\U1F9CE'
+emoji[kneeling_person]=$'\U1F9CE'
+emoji[person_kneeling_light_skin_tone]=$'\U1F9CE\U1F3FB'
+emoji[person_kneeling_medium_light_skin_tone]=$'\U1F9CE\U1F3FC'
+emoji[person_kneeling_medium_skin_tone]=$'\U1F9CE\U1F3FD'
+emoji[person_kneeling_medium_dark_skin_tone]=$'\U1F9CE\U1F3FE'
+emoji[person_kneeling_dark_skin_tone]=$'\U1F9CE\U1F3FF'
+emoji[man_kneeling]=$'\U1F9CE\U200D\U2642\UFE0F'
+emoji[man_kneeling_minimally]=$'\U1F9CE\U200D\U2642'
+emoji[kneeling_man]=$'\U1F9CE\U200D\U2642'
+emoji[man_kneeling_light_skin_tone]=$'\U1F9CE\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_kneeling_light_skin_tone_minimally]=$'\U1F9CE\U1F3FB\U200D\U2642'
+emoji[man_kneeling_medium_light_skin_tone]=$'\U1F9CE\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_kneeling_medium_light_skin_tone_minimally]=$'\U1F9CE\U1F3FC\U200D\U2642'
+emoji[man_kneeling_medium_skin_tone]=$'\U1F9CE\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_kneeling_medium_skin_tone_minimally]=$'\U1F9CE\U1F3FD\U200D\U2642'
+emoji[man_kneeling_medium_dark_skin_tone]=$'\U1F9CE\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_kneeling_medium_dark_skin_tone_minimally]=$'\U1F9CE\U1F3FE\U200D\U2642'
+emoji[man_kneeling_dark_skin_tone]=$'\U1F9CE\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_kneeling_dark_skin_tone_minimally]=$'\U1F9CE\U1F3FF\U200D\U2642'
+emoji[woman_kneeling]=$'\U1F9CE\U200D\U2640\UFE0F'
+emoji[woman_kneeling_minimally]=$'\U1F9CE\U200D\U2640'
+emoji[kneeling_woman]=$'\U1F9CE\U200D\U2640'
+emoji[woman_kneeling_light_skin_tone]=$'\U1F9CE\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_kneeling_light_skin_tone_minimally]=$'\U1F9CE\U1F3FB\U200D\U2640'
+emoji[woman_kneeling_medium_light_skin_tone]=$'\U1F9CE\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_kneeling_medium_light_skin_tone_minimally]=$'\U1F9CE\U1F3FC\U200D\U2640'
+emoji[woman_kneeling_medium_skin_tone]=$'\U1F9CE\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_kneeling_medium_skin_tone_minimally]=$'\U1F9CE\U1F3FD\U200D\U2640'
+emoji[woman_kneeling_medium_dark_skin_tone]=$'\U1F9CE\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_kneeling_medium_dark_skin_tone_minimally]=$'\U1F9CE\U1F3FE\U200D\U2640'
+emoji[woman_kneeling_dark_skin_tone]=$'\U1F9CE\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_kneeling_dark_skin_tone_minimally]=$'\U1F9CE\U1F3FF\U200D\U2640'
+emoji[man_with_probing_cane]=$'\U1F468\U200D\U1F9AF'
+emoji[man_with_probing_cane_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F9AF'
+emoji[man_with_probing_cane_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F9AF'
+emoji[man_with_probing_cane_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F9AF'
+emoji[man_with_probing_cane_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F9AF'
+emoji[man_with_probing_cane_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F9AF'
+emoji[woman_with_probing_cane]=$'\U1F469\U200D\U1F9AF'
+emoji[woman_with_probing_cane_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F9AF'
+emoji[woman_with_probing_cane_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F9AF'
+emoji[woman_with_probing_cane_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F9AF'
+emoji[woman_with_probing_cane_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F9AF'
+emoji[woman_with_probing_cane_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F9AF'
+emoji[man_in_motorized_wheelchair]=$'\U1F468\U200D\U1F9BC'
+emoji[man_in_motorized_wheelchair_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F9BC'
+emoji[man_in_motorized_wheelchair_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F9BC'
+emoji[man_in_motorized_wheelchair_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F9BC'
+emoji[man_in_motorized_wheelchair_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F9BC'
+emoji[man_in_motorized_wheelchair_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F9BC'
+emoji[woman_in_motorized_wheelchair]=$'\U1F469\U200D\U1F9BC'
+emoji[woman_in_motorized_wheelchair_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F9BC'
+emoji[woman_in_motorized_wheelchair_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F9BC'
+emoji[woman_in_motorized_wheelchair_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F9BC'
+emoji[woman_in_motorized_wheelchair_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F9BC'
+emoji[woman_in_motorized_wheelchair_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F9BC'
+emoji[man_in_manual_wheelchair]=$'\U1F468\U200D\U1F9BD'
+emoji[man_in_manual_wheelchair_light_skin_tone]=$'\U1F468\U1F3FB\U200D\U1F9BD'
+emoji[man_in_manual_wheelchair_medium_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F9BD'
+emoji[man_in_manual_wheelchair_medium_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F9BD'
+emoji[man_in_manual_wheelchair_medium_dark_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F9BD'
+emoji[man_in_manual_wheelchair_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F9BD'
+emoji[woman_in_manual_wheelchair]=$'\U1F469\U200D\U1F9BD'
+emoji[woman_in_manual_wheelchair_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F9BD'
+emoji[woman_in_manual_wheelchair_medium_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F9BD'
+emoji[woman_in_manual_wheelchair_medium_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F9BD'
+emoji[woman_in_manual_wheelchair_medium_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F9BD'
+emoji[woman_in_manual_wheelchair_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F9BD'
+emoji[person_running]=$'\U1F3C3'
+emoji[runner]=$'\U1F3C3'
+emoji[running]=$'\U1F3C3'
+emoji[person_running_light_skin_tone]=$'\U1F3C3\U1F3FB'
+emoji[person_running_medium_light_skin_tone]=$'\U1F3C3\U1F3FC'
+emoji[person_running_medium_skin_tone]=$'\U1F3C3\U1F3FD'
+emoji[person_running_medium_dark_skin_tone]=$'\U1F3C3\U1F3FE'
+emoji[person_running_dark_skin_tone]=$'\U1F3C3\U1F3FF'
+emoji[man_running]=$'\U1F3C3\U200D\U2642\UFE0F'
+emoji[man_running_minimally]=$'\U1F3C3\U200D\U2642'
+emoji[running_man]=$'\U1F3C3\U200D\U2642'
+emoji[man_running_light_skin_tone]=$'\U1F3C3\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_running_light_skin_tone_minimally]=$'\U1F3C3\U1F3FB\U200D\U2642'
+emoji[man_running_medium_light_skin_tone]=$'\U1F3C3\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_running_medium_light_skin_tone_minimally]=$'\U1F3C3\U1F3FC\U200D\U2642'
+emoji[man_running_medium_skin_tone]=$'\U1F3C3\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_running_medium_skin_tone_minimally]=$'\U1F3C3\U1F3FD\U200D\U2642'
+emoji[man_running_medium_dark_skin_tone]=$'\U1F3C3\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_running_medium_dark_skin_tone_minimally]=$'\U1F3C3\U1F3FE\U200D\U2642'
+emoji[man_running_dark_skin_tone]=$'\U1F3C3\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_running_dark_skin_tone_minimally]=$'\U1F3C3\U1F3FF\U200D\U2642'
+emoji[woman_running]=$'\U1F3C3\U200D\U2640\UFE0F'
+emoji[woman_running_minimally]=$'\U1F3C3\U200D\U2640'
+emoji[running_woman]=$'\U1F3C3\U200D\U2640'
+emoji[woman_running_light_skin_tone]=$'\U1F3C3\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_running_light_skin_tone_minimally]=$'\U1F3C3\U1F3FB\U200D\U2640'
+emoji[woman_running_medium_light_skin_tone]=$'\U1F3C3\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_running_medium_light_skin_tone_minimally]=$'\U1F3C3\U1F3FC\U200D\U2640'
+emoji[woman_running_medium_skin_tone]=$'\U1F3C3\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_running_medium_skin_tone_minimally]=$'\U1F3C3\U1F3FD\U200D\U2640'
+emoji[woman_running_medium_dark_skin_tone]=$'\U1F3C3\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_running_medium_dark_skin_tone_minimally]=$'\U1F3C3\U1F3FE\U200D\U2640'
+emoji[woman_running_dark_skin_tone]=$'\U1F3C3\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_running_dark_skin_tone_minimally]=$'\U1F3C3\U1F3FF\U200D\U2640'
+emoji[woman_dancing]=$'\U1F483'
+emoji[dancer]=$'\U1F483'
+emoji[woman_dancing_light_skin_tone]=$'\U1F483\U1F3FB'
+emoji[woman_dancing_medium_light_skin_tone]=$'\U1F483\U1F3FC'
+emoji[woman_dancing_medium_skin_tone]=$'\U1F483\U1F3FD'
+emoji[woman_dancing_medium_dark_skin_tone]=$'\U1F483\U1F3FE'
+emoji[woman_dancing_dark_skin_tone]=$'\U1F483\U1F3FF'
+emoji[woman_dancing_dark_skin_tone_1]=$'\U1F57A'
+emoji[man_dancing]=$'\U1F57A'
+emoji[man_dancing_light_skin_tone]=$'\U1F57A\U1F3FB'
+emoji[man_dancing_medium_light_skin_tone]=$'\U1F57A\U1F3FC'
+emoji[man_dancing_medium_skin_tone]=$'\U1F57A\U1F3FD'
+emoji[man_dancing_medium_dark_skin_tone]=$'\U1F57A\U1F3FE'
+emoji[man_dancing_dark_skin_tone]=$'\U1F57A\U1F3FF'
+emoji[man_in_suit_levitating]=$'\U1F574\UFE0F'
+emoji[man_in_suit_levitating_unqualified]=$'\U1F574'
+emoji[business_suit_levitating]=$'\U1F574'
+emoji[man_in_suit_levitating_light_skin_tone]=$'\U1F574\U1F3FB'
+emoji[man_in_suit_levitating_medium_light_skin_tone]=$'\U1F574\U1F3FC'
+emoji[man_in_suit_levitating_medium_skin_tone]=$'\U1F574\U1F3FD'
+emoji[man_in_suit_levitating_medium_dark_skin_tone]=$'\U1F574\U1F3FE'
+emoji[man_in_suit_levitating_dark_skin_tone]=$'\U1F574\U1F3FF'
+emoji[people_with_bunny_ears]=$'\U1F46F'
+emoji[dancers]=$'\U1F46F'
+emoji[men_with_bunny_ears]=$'\U1F46F\U200D\U2642\UFE0F'
+emoji[men_with_bunny_ears_minimally]=$'\U1F46F\U200D\U2642'
+emoji[dancing_men]=$'\U1F46F\U200D\U2642'
+emoji[women_with_bunny_ears]=$'\U1F46F\U200D\U2640\UFE0F'
+emoji[women_with_bunny_ears_minimally]=$'\U1F46F\U200D\U2640'
+emoji[dancing_women]=$'\U1F46F\U200D\U2640'
+emoji[person_in_steamy_room]=$'\U1F9D6'
+emoji[sauna_person]=$'\U1F9D6'
+emoji[person_in_steamy_room_light_skin_tone]=$'\U1F9D6\U1F3FB'
+emoji[person_in_steamy_room_medium_light_skin_tone]=$'\U1F9D6\U1F3FC'
+emoji[person_in_steamy_room_medium_skin_tone]=$'\U1F9D6\U1F3FD'
+emoji[person_in_steamy_room_medium_dark_skin_tone]=$'\U1F9D6\U1F3FE'
+emoji[person_in_steamy_room_dark_skin_tone]=$'\U1F9D6\U1F3FF'
+emoji[man_in_steamy_room]=$'\U1F9D6\U200D\U2642\UFE0F'
+emoji[man_in_steamy_room_minimally]=$'\U1F9D6\U200D\U2642'
+emoji[sauna_man]=$'\U1F9D6\U200D\U2642'
+emoji[man_in_steamy_room_light_skin_tone]=$'\U1F9D6\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_in_steamy_room_light_skin_tone_minimally]=$'\U1F9D6\U1F3FB\U200D\U2642'
+emoji[man_in_steamy_room_medium_light_skin_tone]=$'\U1F9D6\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_in_steamy_room_medium_light_skin_tone_minimally]=$'\U1F9D6\U1F3FC\U200D\U2642'
+emoji[man_in_steamy_room_medium_skin_tone]=$'\U1F9D6\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_in_steamy_room_medium_skin_tone_minimally]=$'\U1F9D6\U1F3FD\U200D\U2642'
+emoji[man_in_steamy_room_medium_dark_skin_tone]=$'\U1F9D6\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_in_steamy_room_medium_dark_skin_tone_minimally]=$'\U1F9D6\U1F3FE\U200D\U2642'
+emoji[man_in_steamy_room_dark_skin_tone]=$'\U1F9D6\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_in_steamy_room_dark_skin_tone_minimally]=$'\U1F9D6\U1F3FF\U200D\U2642'
+emoji[woman_in_steamy_room]=$'\U1F9D6\U200D\U2640\UFE0F'
+emoji[woman_in_steamy_room_minimally]=$'\U1F9D6\U200D\U2640'
+emoji[sauna_woman]=$'\U1F9D6\U200D\U2640'
+emoji[woman_in_steamy_room_light_skin_tone]=$'\U1F9D6\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_in_steamy_room_light_skin_tone_minimally]=$'\U1F9D6\U1F3FB\U200D\U2640'
+emoji[woman_in_steamy_room_medium_light_skin_tone]=$'\U1F9D6\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_in_steamy_room_medium_light_skin_tone_minimally]=$'\U1F9D6\U1F3FC\U200D\U2640'
+emoji[woman_in_steamy_room_medium_skin_tone]=$'\U1F9D6\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_in_steamy_room_medium_skin_tone_minimally]=$'\U1F9D6\U1F3FD\U200D\U2640'
+emoji[woman_in_steamy_room_medium_dark_skin_tone]=$'\U1F9D6\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_in_steamy_room_medium_dark_skin_tone_minimally]=$'\U1F9D6\U1F3FE\U200D\U2640'
+emoji[woman_in_steamy_room_dark_skin_tone]=$'\U1F9D6\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_in_steamy_room_dark_skin_tone_minimally]=$'\U1F9D6\U1F3FF\U200D\U2640'
+emoji[person_climbing]=$'\U1F9D7'
+emoji[climbing]=$'\U1F9D7'
+emoji[person_climbing_light_skin_tone]=$'\U1F9D7\U1F3FB'
+emoji[person_climbing_medium_light_skin_tone]=$'\U1F9D7\U1F3FC'
+emoji[person_climbing_medium_skin_tone]=$'\U1F9D7\U1F3FD'
+emoji[person_climbing_medium_dark_skin_tone]=$'\U1F9D7\U1F3FE'
+emoji[person_climbing_dark_skin_tone]=$'\U1F9D7\U1F3FF'
+emoji[man_climbing]=$'\U1F9D7\U200D\U2642\UFE0F'
+emoji[man_climbing_minimally]=$'\U1F9D7\U200D\U2642'
+emoji[climbing_man]=$'\U1F9D7\U200D\U2642'
+emoji[man_climbing_light_skin_tone]=$'\U1F9D7\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_climbing_light_skin_tone_minimally]=$'\U1F9D7\U1F3FB\U200D\U2642'
+emoji[man_climbing_medium_light_skin_tone]=$'\U1F9D7\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_climbing_medium_light_skin_tone_minimally]=$'\U1F9D7\U1F3FC\U200D\U2642'
+emoji[man_climbing_medium_skin_tone]=$'\U1F9D7\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_climbing_medium_skin_tone_minimally]=$'\U1F9D7\U1F3FD\U200D\U2642'
+emoji[man_climbing_medium_dark_skin_tone]=$'\U1F9D7\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_climbing_medium_dark_skin_tone_minimally]=$'\U1F9D7\U1F3FE\U200D\U2642'
+emoji[man_climbing_dark_skin_tone]=$'\U1F9D7\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_climbing_dark_skin_tone_minimally]=$'\U1F9D7\U1F3FF\U200D\U2642'
+emoji[woman_climbing]=$'\U1F9D7\U200D\U2640\UFE0F'
+emoji[woman_climbing_minimally]=$'\U1F9D7\U200D\U2640'
+emoji[climbing_woman]=$'\U1F9D7\U200D\U2640'
+emoji[woman_climbing_light_skin_tone]=$'\U1F9D7\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_climbing_light_skin_tone_minimally]=$'\U1F9D7\U1F3FB\U200D\U2640'
+emoji[woman_climbing_medium_light_skin_tone]=$'\U1F9D7\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_climbing_medium_light_skin_tone_minimally]=$'\U1F9D7\U1F3FC\U200D\U2640'
+emoji[woman_climbing_medium_skin_tone]=$'\U1F9D7\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_climbing_medium_skin_tone_minimally]=$'\U1F9D7\U1F3FD\U200D\U2640'
+emoji[woman_climbing_medium_dark_skin_tone]=$'\U1F9D7\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_climbing_medium_dark_skin_tone_minimally]=$'\U1F9D7\U1F3FE\U200D\U2640'
+emoji[woman_climbing_dark_skin_tone]=$'\U1F9D7\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_climbing_dark_skin_tone_minimally]=$'\U1F9D7\U1F3FF\U200D\U2640'
+emoji[person_fencing]=$'\U1F93A'
+emoji[horse_racing]=$'\U1F3C7'
+emoji[horse_racing_light_skin_tone]=$'\U1F3C7\U1F3FB'
+emoji[horse_racing_medium_light_skin_tone]=$'\U1F3C7\U1F3FC'
+emoji[horse_racing_medium_skin_tone]=$'\U1F3C7\U1F3FD'
+emoji[horse_racing_medium_dark_skin_tone]=$'\U1F3C7\U1F3FE'
+emoji[horse_racing_dark_skin_tone]=$'\U1F3C7\U1F3FF'
+emoji[skier]=$'\U26F7\UFE0F'
+emoji[skier_unqualified]=$'\U26F7'
+emoji[snowboarder]=$'\U1F3C2'
+emoji[snowboarder_light_skin_tone]=$'\U1F3C2\U1F3FB'
+emoji[snowboarder_medium_light_skin_tone]=$'\U1F3C2\U1F3FC'
+emoji[snowboarder_medium_skin_tone]=$'\U1F3C2\U1F3FD'
+emoji[snowboarder_medium_dark_skin_tone]=$'\U1F3C2\U1F3FE'
+emoji[snowboarder_dark_skin_tone]=$'\U1F3C2\U1F3FF'
+emoji[person_golfing]=$'\U1F3CC\UFE0F'
+emoji[person_golfing_unqualified]=$'\U1F3CC'
+emoji[golfing]=$'\U1F3CC'
+emoji[person_golfing_light_skin_tone]=$'\U1F3CC\U1F3FB'
+emoji[person_golfing_medium_light_skin_tone]=$'\U1F3CC\U1F3FC'
+emoji[person_golfing_medium_skin_tone]=$'\U1F3CC\U1F3FD'
+emoji[person_golfing_medium_dark_skin_tone]=$'\U1F3CC\U1F3FE'
+emoji[person_golfing_dark_skin_tone]=$'\U1F3CC\U1F3FF'
+emoji[man_golfing]=$'\U1F3CC\UFE0F\U200D\U2642\UFE0F'
+emoji[golfing_man]=$'\U1F3CC\UFE0F\U200D\U2642\UFE0F'
+emoji[man_golfing_unqualified]=$'\U1F3CC\U200D\U2642\UFE0F'
+emoji[man_golfing_unqualified_1]=$'\U1F3CC\UFE0F\U200D\U2642'
+emoji[man_golfing_unqualified_2]=$'\U1F3CC\U200D\U2642'
+emoji[man_golfing_light_skin_tone]=$'\U1F3CC\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_golfing_light_skin_tone_minimally]=$'\U1F3CC\U1F3FB\U200D\U2642'
+emoji[man_golfing_medium_light_skin_tone]=$'\U1F3CC\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_golfing_medium_light_skin_tone_minimally]=$'\U1F3CC\U1F3FC\U200D\U2642'
+emoji[man_golfing_medium_skin_tone]=$'\U1F3CC\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_golfing_medium_skin_tone_minimally]=$'\U1F3CC\U1F3FD\U200D\U2642'
+emoji[man_golfing_medium_dark_skin_tone]=$'\U1F3CC\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_golfing_medium_dark_skin_tone_minimally]=$'\U1F3CC\U1F3FE\U200D\U2642'
+emoji[man_golfing_dark_skin_tone]=$'\U1F3CC\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_golfing_dark_skin_tone_minimally]=$'\U1F3CC\U1F3FF\U200D\U2642'
+emoji[woman_golfing]=$'\U1F3CC\UFE0F\U200D\U2640\UFE0F'
+emoji[golfing_woman]=$'\U1F3CC\UFE0F\U200D\U2640\UFE0F'
+emoji[woman_golfing_unqualified]=$'\U1F3CC\U200D\U2640\UFE0F'
+emoji[woman_golfing_unqualified_1]=$'\U1F3CC\UFE0F\U200D\U2640'
+emoji[woman_golfing_unqualified_2]=$'\U1F3CC\U200D\U2640'
+emoji[woman_golfing_light_skin_tone]=$'\U1F3CC\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_golfing_light_skin_tone_minimally]=$'\U1F3CC\U1F3FB\U200D\U2640'
+emoji[woman_golfing_medium_light_skin_tone]=$'\U1F3CC\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_golfing_medium_light_skin_tone_minimally]=$'\U1F3CC\U1F3FC\U200D\U2640'
+emoji[woman_golfing_medium_skin_tone]=$'\U1F3CC\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_golfing_medium_skin_tone_minimally]=$'\U1F3CC\U1F3FD\U200D\U2640'
+emoji[woman_golfing_medium_dark_skin_tone]=$'\U1F3CC\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_golfing_medium_dark_skin_tone_minimally]=$'\U1F3CC\U1F3FE\U200D\U2640'
+emoji[woman_golfing_dark_skin_tone]=$'\U1F3CC\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_golfing_dark_skin_tone_minimally]=$'\U1F3CC\U1F3FF\U200D\U2640'
+emoji[person_surfing]=$'\U1F3C4'
+emoji[surfer]=$'\U1F3C4'
+emoji[person_surfing_light_skin_tone]=$'\U1F3C4\U1F3FB'
+emoji[person_surfing_medium_light_skin_tone]=$'\U1F3C4\U1F3FC'
+emoji[person_surfing_medium_skin_tone]=$'\U1F3C4\U1F3FD'
+emoji[person_surfing_medium_dark_skin_tone]=$'\U1F3C4\U1F3FE'
+emoji[person_surfing_dark_skin_tone]=$'\U1F3C4\U1F3FF'
+emoji[man_surfing]=$'\U1F3C4\U200D\U2642\UFE0F'
+emoji[man_surfing_minimally]=$'\U1F3C4\U200D\U2642'
+emoji[surfing_man]=$'\U1F3C4\U200D\U2642'
+emoji[man_surfing_light_skin_tone]=$'\U1F3C4\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_surfing_light_skin_tone_minimally]=$'\U1F3C4\U1F3FB\U200D\U2642'
+emoji[man_surfing_medium_light_skin_tone]=$'\U1F3C4\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_surfing_medium_light_skin_tone_minimally]=$'\U1F3C4\U1F3FC\U200D\U2642'
+emoji[man_surfing_medium_skin_tone]=$'\U1F3C4\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_surfing_medium_skin_tone_minimally]=$'\U1F3C4\U1F3FD\U200D\U2642'
+emoji[man_surfing_medium_dark_skin_tone]=$'\U1F3C4\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_surfing_medium_dark_skin_tone_minimally]=$'\U1F3C4\U1F3FE\U200D\U2642'
+emoji[man_surfing_dark_skin_tone]=$'\U1F3C4\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_surfing_dark_skin_tone_minimally]=$'\U1F3C4\U1F3FF\U200D\U2642'
+emoji[woman_surfing]=$'\U1F3C4\U200D\U2640\UFE0F'
+emoji[woman_surfing_minimally]=$'\U1F3C4\U200D\U2640'
+emoji[surfing_woman]=$'\U1F3C4\U200D\U2640'
+emoji[woman_surfing_light_skin_tone]=$'\U1F3C4\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_surfing_light_skin_tone_minimally]=$'\U1F3C4\U1F3FB\U200D\U2640'
+emoji[woman_surfing_medium_light_skin_tone]=$'\U1F3C4\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_surfing_medium_light_skin_tone_minimally]=$'\U1F3C4\U1F3FC\U200D\U2640'
+emoji[woman_surfing_medium_skin_tone]=$'\U1F3C4\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_surfing_medium_skin_tone_minimally]=$'\U1F3C4\U1F3FD\U200D\U2640'
+emoji[woman_surfing_medium_dark_skin_tone]=$'\U1F3C4\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_surfing_medium_dark_skin_tone_minimally]=$'\U1F3C4\U1F3FE\U200D\U2640'
+emoji[woman_surfing_dark_skin_tone]=$'\U1F3C4\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_surfing_dark_skin_tone_minimally]=$'\U1F3C4\U1F3FF\U200D\U2640'
+emoji[person_rowing_boat]=$'\U1F6A3'
+emoji[rowboat]=$'\U1F6A3'
+emoji[person_rowing_boat_light_skin_tone]=$'\U1F6A3\U1F3FB'
+emoji[person_rowing_boat_medium_light_skin_tone]=$'\U1F6A3\U1F3FC'
+emoji[person_rowing_boat_medium_skin_tone]=$'\U1F6A3\U1F3FD'
+emoji[person_rowing_boat_medium_dark_skin_tone]=$'\U1F6A3\U1F3FE'
+emoji[person_rowing_boat_dark_skin_tone]=$'\U1F6A3\U1F3FF'
+emoji[man_rowing_boat]=$'\U1F6A3\U200D\U2642\UFE0F'
+emoji[man_rowing_boat_minimally]=$'\U1F6A3\U200D\U2642'
+emoji[rowing_man]=$'\U1F6A3\U200D\U2642'
+emoji[man_rowing_boat_light_skin_tone]=$'\U1F6A3\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_rowing_boat_light_skin_tone_minimally]=$'\U1F6A3\U1F3FB\U200D\U2642'
+emoji[man_rowing_boat_medium_light_skin_tone]=$'\U1F6A3\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_rowing_boat_medium_light_skin_tone_minimally]=$'\U1F6A3\U1F3FC\U200D\U2642'
+emoji[man_rowing_boat_medium_skin_tone]=$'\U1F6A3\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_rowing_boat_medium_skin_tone_minimally]=$'\U1F6A3\U1F3FD\U200D\U2642'
+emoji[man_rowing_boat_medium_dark_skin_tone]=$'\U1F6A3\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_rowing_boat_medium_dark_skin_tone_minimally]=$'\U1F6A3\U1F3FE\U200D\U2642'
+emoji[man_rowing_boat_dark_skin_tone]=$'\U1F6A3\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_rowing_boat_dark_skin_tone_minimally]=$'\U1F6A3\U1F3FF\U200D\U2642'
+emoji[woman_rowing_boat]=$'\U1F6A3\U200D\U2640\UFE0F'
+emoji[woman_rowing_boat_minimally]=$'\U1F6A3\U200D\U2640'
+emoji[rowing_woman]=$'\U1F6A3\U200D\U2640'
+emoji[woman_rowing_boat_light_skin_tone]=$'\U1F6A3\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_rowing_boat_light_skin_tone_minimally]=$'\U1F6A3\U1F3FB\U200D\U2640'
+emoji[woman_rowing_boat_medium_light_skin_tone]=$'\U1F6A3\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_rowing_boat_medium_light_skin_tone_minimally]=$'\U1F6A3\U1F3FC\U200D\U2640'
+emoji[woman_rowing_boat_medium_skin_tone]=$'\U1F6A3\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_rowing_boat_medium_skin_tone_minimally]=$'\U1F6A3\U1F3FD\U200D\U2640'
+emoji[woman_rowing_boat_medium_dark_skin_tone]=$'\U1F6A3\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_rowing_boat_medium_dark_skin_tone_minimally]=$'\U1F6A3\U1F3FE\U200D\U2640'
+emoji[woman_rowing_boat_dark_skin_tone]=$'\U1F6A3\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_rowing_boat_dark_skin_tone_minimally]=$'\U1F6A3\U1F3FF\U200D\U2640'
+emoji[person_swimming]=$'\U1F3CA'
+emoji[swimmer]=$'\U1F3CA'
+emoji[person_swimming_light_skin_tone]=$'\U1F3CA\U1F3FB'
+emoji[person_swimming_medium_light_skin_tone]=$'\U1F3CA\U1F3FC'
+emoji[person_swimming_medium_skin_tone]=$'\U1F3CA\U1F3FD'
+emoji[person_swimming_medium_dark_skin_tone]=$'\U1F3CA\U1F3FE'
+emoji[person_swimming_dark_skin_tone]=$'\U1F3CA\U1F3FF'
+emoji[man_swimming]=$'\U1F3CA\U200D\U2642\UFE0F'
+emoji[man_swimming_minimally]=$'\U1F3CA\U200D\U2642'
+emoji[swimming_man]=$'\U1F3CA\U200D\U2642'
+emoji[man_swimming_light_skin_tone]=$'\U1F3CA\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_swimming_light_skin_tone_minimally]=$'\U1F3CA\U1F3FB\U200D\U2642'
+emoji[man_swimming_medium_light_skin_tone]=$'\U1F3CA\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_swimming_medium_light_skin_tone_minimally]=$'\U1F3CA\U1F3FC\U200D\U2642'
+emoji[man_swimming_medium_skin_tone]=$'\U1F3CA\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_swimming_medium_skin_tone_minimally]=$'\U1F3CA\U1F3FD\U200D\U2642'
+emoji[man_swimming_medium_dark_skin_tone]=$'\U1F3CA\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_swimming_medium_dark_skin_tone_minimally]=$'\U1F3CA\U1F3FE\U200D\U2642'
+emoji[man_swimming_dark_skin_tone]=$'\U1F3CA\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_swimming_dark_skin_tone_minimally]=$'\U1F3CA\U1F3FF\U200D\U2642'
+emoji[woman_swimming]=$'\U1F3CA\U200D\U2640\UFE0F'
+emoji[woman_swimming_minimally]=$'\U1F3CA\U200D\U2640'
+emoji[swimming_woman]=$'\U1F3CA\U200D\U2640'
+emoji[woman_swimming_light_skin_tone]=$'\U1F3CA\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_swimming_light_skin_tone_minimally]=$'\U1F3CA\U1F3FB\U200D\U2640'
+emoji[woman_swimming_medium_light_skin_tone]=$'\U1F3CA\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_swimming_medium_light_skin_tone_minimally]=$'\U1F3CA\U1F3FC\U200D\U2640'
+emoji[woman_swimming_medium_skin_tone]=$'\U1F3CA\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_swimming_medium_skin_tone_minimally]=$'\U1F3CA\U1F3FD\U200D\U2640'
+emoji[woman_swimming_medium_dark_skin_tone]=$'\U1F3CA\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_swimming_medium_dark_skin_tone_minimally]=$'\U1F3CA\U1F3FE\U200D\U2640'
+emoji[woman_swimming_dark_skin_tone]=$'\U1F3CA\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_swimming_dark_skin_tone_minimally]=$'\U1F3CA\U1F3FF\U200D\U2640'
+emoji[person_bouncing_ball]=$'\U26F9\UFE0F'
+emoji[person_bouncing_ball_unqualified]=$'\U26F9'
+emoji[bouncing_ball_person]=$'\U26F9'
+emoji[person_bouncing_ball_light_skin_tone]=$'\U26F9\U1F3FB'
+emoji[person_bouncing_ball_medium_light_skin_tone]=$'\U26F9\U1F3FC'
+emoji[person_bouncing_ball_medium_skin_tone]=$'\U26F9\U1F3FD'
+emoji[person_bouncing_ball_medium_dark_skin_tone]=$'\U26F9\U1F3FE'
+emoji[person_bouncing_ball_dark_skin_tone]=$'\U26F9\U1F3FF'
+emoji[man_bouncing_ball]=$'\U26F9\UFE0F\U200D\U2642\UFE0F'
+emoji[bouncing_ball_man]=$'\U26F9\UFE0F\U200D\U2642\UFE0F'
+emoji[basketball_man]=$'\U26F9\UFE0F\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_unqualified]=$'\U26F9\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_unqualified_1]=$'\U26F9\UFE0F\U200D\U2642'
+emoji[man_bouncing_ball_unqualified_2]=$'\U26F9\U200D\U2642'
+emoji[man_bouncing_ball_light_skin_tone]=$'\U26F9\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_light_skin_tone_minimally]=$'\U26F9\U1F3FB\U200D\U2642'
+emoji[man_bouncing_ball_medium_light_skin_tone]=$'\U26F9\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_medium_light_skin_tone_minimally]=$'\U26F9\U1F3FC\U200D\U2642'
+emoji[man_bouncing_ball_medium_skin_tone]=$'\U26F9\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_medium_skin_tone_minimally]=$'\U26F9\U1F3FD\U200D\U2642'
+emoji[man_bouncing_ball_medium_dark_skin_tone]=$'\U26F9\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_medium_dark_skin_tone_minimally]=$'\U26F9\U1F3FE\U200D\U2642'
+emoji[man_bouncing_ball_dark_skin_tone]=$'\U26F9\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_bouncing_ball_dark_skin_tone_minimally]=$'\U26F9\U1F3FF\U200D\U2642'
+emoji[woman_bouncing_ball]=$'\U26F9\UFE0F\U200D\U2640\UFE0F'
+emoji[bouncing_ball_woman]=$'\U26F9\UFE0F\U200D\U2640\UFE0F'
+emoji[basketball_woman]=$'\U26F9\UFE0F\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_unqualified]=$'\U26F9\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_unqualified_1]=$'\U26F9\UFE0F\U200D\U2640'
+emoji[woman_bouncing_ball_unqualified_2]=$'\U26F9\U200D\U2640'
+emoji[woman_bouncing_ball_light_skin_tone]=$'\U26F9\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_light_skin_tone_minimally]=$'\U26F9\U1F3FB\U200D\U2640'
+emoji[woman_bouncing_ball_medium_light_skin_tone]=$'\U26F9\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_medium_light_skin_tone_minimally]=$'\U26F9\U1F3FC\U200D\U2640'
+emoji[woman_bouncing_ball_medium_skin_tone]=$'\U26F9\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_medium_skin_tone_minimally]=$'\U26F9\U1F3FD\U200D\U2640'
+emoji[woman_bouncing_ball_medium_dark_skin_tone]=$'\U26F9\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_medium_dark_skin_tone_minimally]=$'\U26F9\U1F3FE\U200D\U2640'
+emoji[woman_bouncing_ball_dark_skin_tone]=$'\U26F9\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_bouncing_ball_dark_skin_tone_minimally]=$'\U26F9\U1F3FF\U200D\U2640'
+emoji[person_lifting_weights]=$'\U1F3CB\UFE0F'
+emoji[person_lifting_weights_unqualified]=$'\U1F3CB'
+emoji[weight_lifting]=$'\U1F3CB'
+emoji[person_lifting_weights_light_skin_tone]=$'\U1F3CB\U1F3FB'
+emoji[person_lifting_weights_medium_light_skin_tone]=$'\U1F3CB\U1F3FC'
+emoji[person_lifting_weights_medium_skin_tone]=$'\U1F3CB\U1F3FD'
+emoji[person_lifting_weights_medium_dark_skin_tone]=$'\U1F3CB\U1F3FE'
+emoji[person_lifting_weights_dark_skin_tone]=$'\U1F3CB\U1F3FF'
+emoji[man_lifting_weights]=$'\U1F3CB\UFE0F\U200D\U2642\UFE0F'
+emoji[weight_lifting_man]=$'\U1F3CB\UFE0F\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_unqualified]=$'\U1F3CB\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_unqualified_1]=$'\U1F3CB\UFE0F\U200D\U2642'
+emoji[man_lifting_weights_unqualified_2]=$'\U1F3CB\U200D\U2642'
+emoji[man_lifting_weights_light_skin_tone]=$'\U1F3CB\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_light_skin_tone_minimally]=$'\U1F3CB\U1F3FB\U200D\U2642'
+emoji[man_lifting_weights_medium_light_skin_tone]=$'\U1F3CB\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_medium_light_skin_tone_minimally]=$'\U1F3CB\U1F3FC\U200D\U2642'
+emoji[man_lifting_weights_medium_skin_tone]=$'\U1F3CB\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_medium_skin_tone_minimally]=$'\U1F3CB\U1F3FD\U200D\U2642'
+emoji[man_lifting_weights_medium_dark_skin_tone]=$'\U1F3CB\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_medium_dark_skin_tone_minimally]=$'\U1F3CB\U1F3FE\U200D\U2642'
+emoji[man_lifting_weights_dark_skin_tone]=$'\U1F3CB\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_lifting_weights_dark_skin_tone_minimally]=$'\U1F3CB\U1F3FF\U200D\U2642'
+emoji[woman_lifting_weights]=$'\U1F3CB\UFE0F\U200D\U2640\UFE0F'
+emoji[weight_lifting_woman]=$'\U1F3CB\UFE0F\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_unqualified]=$'\U1F3CB\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_unqualified_1]=$'\U1F3CB\UFE0F\U200D\U2640'
+emoji[woman_lifting_weights_unqualified_2]=$'\U1F3CB\U200D\U2640'
+emoji[woman_lifting_weights_light_skin_tone]=$'\U1F3CB\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_light_skin_tone_minimally]=$'\U1F3CB\U1F3FB\U200D\U2640'
+emoji[woman_lifting_weights_medium_light_skin_tone]=$'\U1F3CB\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_medium_light_skin_tone_minimally]=$'\U1F3CB\U1F3FC\U200D\U2640'
+emoji[woman_lifting_weights_medium_skin_tone]=$'\U1F3CB\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_medium_skin_tone_minimally]=$'\U1F3CB\U1F3FD\U200D\U2640'
+emoji[woman_lifting_weights_medium_dark_skin_tone]=$'\U1F3CB\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_medium_dark_skin_tone_minimally]=$'\U1F3CB\U1F3FE\U200D\U2640'
+emoji[woman_lifting_weights_dark_skin_tone]=$'\U1F3CB\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_lifting_weights_dark_skin_tone_minimally]=$'\U1F3CB\U1F3FF\U200D\U2640'
+emoji[person_biking]=$'\U1F6B4'
+emoji[bicyclist]=$'\U1F6B4'
+emoji[person_biking_light_skin_tone]=$'\U1F6B4\U1F3FB'
+emoji[person_biking_medium_light_skin_tone]=$'\U1F6B4\U1F3FC'
+emoji[person_biking_medium_skin_tone]=$'\U1F6B4\U1F3FD'
+emoji[person_biking_medium_dark_skin_tone]=$'\U1F6B4\U1F3FE'
+emoji[person_biking_dark_skin_tone]=$'\U1F6B4\U1F3FF'
+emoji[man_biking]=$'\U1F6B4\U200D\U2642\UFE0F'
+emoji[man_biking_minimally]=$'\U1F6B4\U200D\U2642'
+emoji[biking_man]=$'\U1F6B4\U200D\U2642'
+emoji[man_biking_light_skin_tone]=$'\U1F6B4\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_biking_light_skin_tone_minimally]=$'\U1F6B4\U1F3FB\U200D\U2642'
+emoji[man_biking_medium_light_skin_tone]=$'\U1F6B4\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_biking_medium_light_skin_tone_minimally]=$'\U1F6B4\U1F3FC\U200D\U2642'
+emoji[man_biking_medium_skin_tone]=$'\U1F6B4\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_biking_medium_skin_tone_minimally]=$'\U1F6B4\U1F3FD\U200D\U2642'
+emoji[man_biking_medium_dark_skin_tone]=$'\U1F6B4\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_biking_medium_dark_skin_tone_minimally]=$'\U1F6B4\U1F3FE\U200D\U2642'
+emoji[man_biking_dark_skin_tone]=$'\U1F6B4\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_biking_dark_skin_tone_minimally]=$'\U1F6B4\U1F3FF\U200D\U2642'
+emoji[woman_biking]=$'\U1F6B4\U200D\U2640\UFE0F'
+emoji[woman_biking_minimally]=$'\U1F6B4\U200D\U2640'
+emoji[biking_woman]=$'\U1F6B4\U200D\U2640'
+emoji[woman_biking_light_skin_tone]=$'\U1F6B4\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_biking_light_skin_tone_minimally]=$'\U1F6B4\U1F3FB\U200D\U2640'
+emoji[woman_biking_medium_light_skin_tone]=$'\U1F6B4\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_biking_medium_light_skin_tone_minimally]=$'\U1F6B4\U1F3FC\U200D\U2640'
+emoji[woman_biking_medium_skin_tone]=$'\U1F6B4\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_biking_medium_skin_tone_minimally]=$'\U1F6B4\U1F3FD\U200D\U2640'
+emoji[woman_biking_medium_dark_skin_tone]=$'\U1F6B4\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_biking_medium_dark_skin_tone_minimally]=$'\U1F6B4\U1F3FE\U200D\U2640'
+emoji[woman_biking_dark_skin_tone]=$'\U1F6B4\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_biking_dark_skin_tone_minimally]=$'\U1F6B4\U1F3FF\U200D\U2640'
+emoji[person_mountain_biking]=$'\U1F6B5'
+emoji[mountain_bicyclist]=$'\U1F6B5'
+emoji[person_mountain_biking_light_skin_tone]=$'\U1F6B5\U1F3FB'
+emoji[person_mountain_biking_medium_light_skin_tone]=$'\U1F6B5\U1F3FC'
+emoji[person_mountain_biking_medium_skin_tone]=$'\U1F6B5\U1F3FD'
+emoji[person_mountain_biking_medium_dark_skin_tone]=$'\U1F6B5\U1F3FE'
+emoji[person_mountain_biking_dark_skin_tone]=$'\U1F6B5\U1F3FF'
+emoji[man_mountain_biking]=$'\U1F6B5\U200D\U2642\UFE0F'
+emoji[man_mountain_biking_minimally]=$'\U1F6B5\U200D\U2642'
+emoji[mountain_biking_man]=$'\U1F6B5\U200D\U2642'
+emoji[man_mountain_biking_light_skin_tone]=$'\U1F6B5\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_mountain_biking_light_skin_tone_minimally]=$'\U1F6B5\U1F3FB\U200D\U2642'
+emoji[man_mountain_biking_medium_light_skin_tone]=$'\U1F6B5\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_mountain_biking_medium_light_skin_tone_minimally]=$'\U1F6B5\U1F3FC\U200D\U2642'
+emoji[man_mountain_biking_medium_skin_tone]=$'\U1F6B5\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_mountain_biking_medium_skin_tone_minimally]=$'\U1F6B5\U1F3FD\U200D\U2642'
+emoji[man_mountain_biking_medium_dark_skin_tone]=$'\U1F6B5\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_mountain_biking_medium_dark_skin_tone_minimally]=$'\U1F6B5\U1F3FE\U200D\U2642'
+emoji[man_mountain_biking_dark_skin_tone]=$'\U1F6B5\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_mountain_biking_dark_skin_tone_minimally]=$'\U1F6B5\U1F3FF\U200D\U2642'
+emoji[woman_mountain_biking]=$'\U1F6B5\U200D\U2640\UFE0F'
+emoji[woman_mountain_biking_minimally]=$'\U1F6B5\U200D\U2640'
+emoji[mountain_biking_woman]=$'\U1F6B5\U200D\U2640'
+emoji[woman_mountain_biking_light_skin_tone]=$'\U1F6B5\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_mountain_biking_light_skin_tone_minimally]=$'\U1F6B5\U1F3FB\U200D\U2640'
+emoji[woman_mountain_biking_medium_light_skin_tone]=$'\U1F6B5\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_mountain_biking_medium_light_skin_tone_minimally]=$'\U1F6B5\U1F3FC\U200D\U2640'
+emoji[woman_mountain_biking_medium_skin_tone]=$'\U1F6B5\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_mountain_biking_medium_skin_tone_minimally]=$'\U1F6B5\U1F3FD\U200D\U2640'
+emoji[woman_mountain_biking_medium_dark_skin_tone]=$'\U1F6B5\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_mountain_biking_medium_dark_skin_tone_minimally]=$'\U1F6B5\U1F3FE\U200D\U2640'
+emoji[woman_mountain_biking_dark_skin_tone]=$'\U1F6B5\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_mountain_biking_dark_skin_tone_minimally]=$'\U1F6B5\U1F3FF\U200D\U2640'
+emoji[person_cartwheeling]=$'\U1F938'
+emoji[cartwheeling]=$'\U1F938'
+emoji[person_cartwheeling_light_skin_tone]=$'\U1F938\U1F3FB'
+emoji[person_cartwheeling_medium_light_skin_tone]=$'\U1F938\U1F3FC'
+emoji[person_cartwheeling_medium_skin_tone]=$'\U1F938\U1F3FD'
+emoji[person_cartwheeling_medium_dark_skin_tone]=$'\U1F938\U1F3FE'
+emoji[person_cartwheeling_dark_skin_tone]=$'\U1F938\U1F3FF'
+emoji[man_cartwheeling]=$'\U1F938\U200D\U2642\UFE0F'
+emoji[man_cartwheeling_minimally]=$'\U1F938\U200D\U2642'
+emoji[man_cartwheeling_light_skin_tone]=$'\U1F938\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_cartwheeling_light_skin_tone_minimally]=$'\U1F938\U1F3FB\U200D\U2642'
+emoji[man_cartwheeling_medium_light_skin_tone]=$'\U1F938\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_cartwheeling_medium_light_skin_tone_minimally]=$'\U1F938\U1F3FC\U200D\U2642'
+emoji[man_cartwheeling_medium_skin_tone]=$'\U1F938\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_cartwheeling_medium_skin_tone_minimally]=$'\U1F938\U1F3FD\U200D\U2642'
+emoji[man_cartwheeling_medium_dark_skin_tone]=$'\U1F938\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_cartwheeling_medium_dark_skin_tone_minimally]=$'\U1F938\U1F3FE\U200D\U2642'
+emoji[man_cartwheeling_dark_skin_tone]=$'\U1F938\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_cartwheeling_dark_skin_tone_minimally]=$'\U1F938\U1F3FF\U200D\U2642'
+emoji[woman_cartwheeling]=$'\U1F938\U200D\U2640\UFE0F'
+emoji[woman_cartwheeling_minimally]=$'\U1F938\U200D\U2640'
+emoji[woman_cartwheeling_light_skin_tone]=$'\U1F938\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_cartwheeling_light_skin_tone_minimally]=$'\U1F938\U1F3FB\U200D\U2640'
+emoji[woman_cartwheeling_medium_light_skin_tone]=$'\U1F938\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_cartwheeling_medium_light_skin_tone_minimally]=$'\U1F938\U1F3FC\U200D\U2640'
+emoji[woman_cartwheeling_medium_skin_tone]=$'\U1F938\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_cartwheeling_medium_skin_tone_minimally]=$'\U1F938\U1F3FD\U200D\U2640'
+emoji[woman_cartwheeling_medium_dark_skin_tone]=$'\U1F938\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_cartwheeling_medium_dark_skin_tone_minimally]=$'\U1F938\U1F3FE\U200D\U2640'
+emoji[woman_cartwheeling_dark_skin_tone]=$'\U1F938\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_cartwheeling_dark_skin_tone_minimally]=$'\U1F938\U1F3FF\U200D\U2640'
+emoji[people_wrestling]=$'\U1F93C'
+emoji[wrestling]=$'\U1F93C'
+emoji[men_wrestling]=$'\U1F93C\U200D\U2642\UFE0F'
+emoji[men_wrestling_minimally]=$'\U1F93C\U200D\U2642'
+emoji[women_wrestling]=$'\U1F93C\U200D\U2640\UFE0F'
+emoji[women_wrestling_minimally]=$'\U1F93C\U200D\U2640'
+emoji[person_playing_water_polo]=$'\U1F93D'
+emoji[water_polo]=$'\U1F93D'
+emoji[person_playing_water_polo_light_skin_tone]=$'\U1F93D\U1F3FB'
+emoji[person_playing_water_polo_medium_light_skin_tone]=$'\U1F93D\U1F3FC'
+emoji[person_playing_water_polo_medium_skin_tone]=$'\U1F93D\U1F3FD'
+emoji[person_playing_water_polo_medium_dark_skin_tone]=$'\U1F93D\U1F3FE'
+emoji[person_playing_water_polo_dark_skin_tone]=$'\U1F93D\U1F3FF'
+emoji[man_playing_water_polo]=$'\U1F93D\U200D\U2642\UFE0F'
+emoji[man_playing_water_polo_minimally]=$'\U1F93D\U200D\U2642'
+emoji[man_playing_water_polo_light_skin_tone]=$'\U1F93D\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_playing_water_polo_light_skin_tone_minimally]=$'\U1F93D\U1F3FB\U200D\U2642'
+emoji[man_playing_water_polo_medium_light_skin_tone]=$'\U1F93D\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_playing_water_polo_medium_light_skin_tone_minimally]=$'\U1F93D\U1F3FC\U200D\U2642'
+emoji[man_playing_water_polo_medium_skin_tone]=$'\U1F93D\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_playing_water_polo_medium_skin_tone_minimally]=$'\U1F93D\U1F3FD\U200D\U2642'
+emoji[man_playing_water_polo_medium_dark_skin_tone]=$'\U1F93D\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_playing_water_polo_medium_dark_skin_tone_minimally]=$'\U1F93D\U1F3FE\U200D\U2642'
+emoji[man_playing_water_polo_dark_skin_tone]=$'\U1F93D\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_playing_water_polo_dark_skin_tone_minimally]=$'\U1F93D\U1F3FF\U200D\U2642'
+emoji[woman_playing_water_polo]=$'\U1F93D\U200D\U2640\UFE0F'
+emoji[woman_playing_water_polo_minimally]=$'\U1F93D\U200D\U2640'
+emoji[woman_playing_water_polo_light_skin_tone]=$'\U1F93D\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_playing_water_polo_light_skin_tone_minimally]=$'\U1F93D\U1F3FB\U200D\U2640'
+emoji[woman_playing_water_polo_medium_light_skin_tone]=$'\U1F93D\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_playing_water_polo_medium_light_skin_tone_minimally]=$'\U1F93D\U1F3FC\U200D\U2640'
+emoji[woman_playing_water_polo_medium_skin_tone]=$'\U1F93D\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_playing_water_polo_medium_skin_tone_minimally]=$'\U1F93D\U1F3FD\U200D\U2640'
+emoji[woman_playing_water_polo_medium_dark_skin_tone]=$'\U1F93D\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_playing_water_polo_medium_dark_skin_tone_minimally]=$'\U1F93D\U1F3FE\U200D\U2640'
+emoji[woman_playing_water_polo_dark_skin_tone]=$'\U1F93D\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_playing_water_polo_dark_skin_tone_minimally]=$'\U1F93D\U1F3FF\U200D\U2640'
+emoji[person_playing_handball]=$'\U1F93E'
+emoji[handball_person]=$'\U1F93E'
+emoji[person_playing_handball_light_skin_tone]=$'\U1F93E\U1F3FB'
+emoji[person_playing_handball_medium_light_skin_tone]=$'\U1F93E\U1F3FC'
+emoji[person_playing_handball_medium_skin_tone]=$'\U1F93E\U1F3FD'
+emoji[person_playing_handball_medium_dark_skin_tone]=$'\U1F93E\U1F3FE'
+emoji[person_playing_handball_dark_skin_tone]=$'\U1F93E\U1F3FF'
+emoji[man_playing_handball]=$'\U1F93E\U200D\U2642\UFE0F'
+emoji[man_playing_handball_minimally]=$'\U1F93E\U200D\U2642'
+emoji[man_playing_handball_light_skin_tone]=$'\U1F93E\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_playing_handball_light_skin_tone_minimally]=$'\U1F93E\U1F3FB\U200D\U2642'
+emoji[man_playing_handball_medium_light_skin_tone]=$'\U1F93E\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_playing_handball_medium_light_skin_tone_minimally]=$'\U1F93E\U1F3FC\U200D\U2642'
+emoji[man_playing_handball_medium_skin_tone]=$'\U1F93E\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_playing_handball_medium_skin_tone_minimally]=$'\U1F93E\U1F3FD\U200D\U2642'
+emoji[man_playing_handball_medium_dark_skin_tone]=$'\U1F93E\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_playing_handball_medium_dark_skin_tone_minimally]=$'\U1F93E\U1F3FE\U200D\U2642'
+emoji[man_playing_handball_dark_skin_tone]=$'\U1F93E\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_playing_handball_dark_skin_tone_minimally]=$'\U1F93E\U1F3FF\U200D\U2642'
+emoji[woman_playing_handball]=$'\U1F93E\U200D\U2640\UFE0F'
+emoji[woman_playing_handball_minimally]=$'\U1F93E\U200D\U2640'
+emoji[woman_playing_handball_light_skin_tone]=$'\U1F93E\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_playing_handball_light_skin_tone_minimally]=$'\U1F93E\U1F3FB\U200D\U2640'
+emoji[woman_playing_handball_medium_light_skin_tone]=$'\U1F93E\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_playing_handball_medium_light_skin_tone_minimally]=$'\U1F93E\U1F3FC\U200D\U2640'
+emoji[woman_playing_handball_medium_skin_tone]=$'\U1F93E\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_playing_handball_medium_skin_tone_minimally]=$'\U1F93E\U1F3FD\U200D\U2640'
+emoji[woman_playing_handball_medium_dark_skin_tone]=$'\U1F93E\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_playing_handball_medium_dark_skin_tone_minimally]=$'\U1F93E\U1F3FE\U200D\U2640'
+emoji[woman_playing_handball_dark_skin_tone]=$'\U1F93E\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_playing_handball_dark_skin_tone_minimally]=$'\U1F93E\U1F3FF\U200D\U2640'
+emoji[person_juggling]=$'\U1F939'
+emoji[juggling_person]=$'\U1F939'
+emoji[person_juggling_light_skin_tone]=$'\U1F939\U1F3FB'
+emoji[person_juggling_medium_light_skin_tone]=$'\U1F939\U1F3FC'
+emoji[person_juggling_medium_skin_tone]=$'\U1F939\U1F3FD'
+emoji[person_juggling_medium_dark_skin_tone]=$'\U1F939\U1F3FE'
+emoji[person_juggling_dark_skin_tone]=$'\U1F939\U1F3FF'
+emoji[man_juggling]=$'\U1F939\U200D\U2642\UFE0F'
+emoji[man_juggling_minimally]=$'\U1F939\U200D\U2642'
+emoji[man_juggling_light_skin_tone]=$'\U1F939\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_juggling_light_skin_tone_minimally]=$'\U1F939\U1F3FB\U200D\U2642'
+emoji[man_juggling_medium_light_skin_tone]=$'\U1F939\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_juggling_medium_light_skin_tone_minimally]=$'\U1F939\U1F3FC\U200D\U2642'
+emoji[man_juggling_medium_skin_tone]=$'\U1F939\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_juggling_medium_skin_tone_minimally]=$'\U1F939\U1F3FD\U200D\U2642'
+emoji[man_juggling_medium_dark_skin_tone]=$'\U1F939\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_juggling_medium_dark_skin_tone_minimally]=$'\U1F939\U1F3FE\U200D\U2642'
+emoji[man_juggling_dark_skin_tone]=$'\U1F939\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_juggling_dark_skin_tone_minimally]=$'\U1F939\U1F3FF\U200D\U2642'
+emoji[woman_juggling]=$'\U1F939\U200D\U2640\UFE0F'
+emoji[woman_juggling_minimally]=$'\U1F939\U200D\U2640'
+emoji[woman_juggling_light_skin_tone]=$'\U1F939\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_juggling_light_skin_tone_minimally]=$'\U1F939\U1F3FB\U200D\U2640'
+emoji[woman_juggling_medium_light_skin_tone]=$'\U1F939\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_juggling_medium_light_skin_tone_minimally]=$'\U1F939\U1F3FC\U200D\U2640'
+emoji[woman_juggling_medium_skin_tone]=$'\U1F939\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_juggling_medium_skin_tone_minimally]=$'\U1F939\U1F3FD\U200D\U2640'
+emoji[woman_juggling_medium_dark_skin_tone]=$'\U1F939\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_juggling_medium_dark_skin_tone_minimally]=$'\U1F939\U1F3FE\U200D\U2640'
+emoji[woman_juggling_dark_skin_tone]=$'\U1F939\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_juggling_dark_skin_tone_minimally]=$'\U1F939\U1F3FF\U200D\U2640'
+emoji[person_in_lotus_position]=$'\U1F9D8'
+emoji[lotus_position]=$'\U1F9D8'
+emoji[person_in_lotus_position_light_skin_tone]=$'\U1F9D8\U1F3FB'
+emoji[person_in_lotus_position_medium_light_skin_tone]=$'\U1F9D8\U1F3FC'
+emoji[person_in_lotus_position_medium_skin_tone]=$'\U1F9D8\U1F3FD'
+emoji[person_in_lotus_position_medium_dark_skin_tone]=$'\U1F9D8\U1F3FE'
+emoji[person_in_lotus_position_dark_skin_tone]=$'\U1F9D8\U1F3FF'
+emoji[man_in_lotus_position]=$'\U1F9D8\U200D\U2642\UFE0F'
+emoji[man_in_lotus_position_minimally]=$'\U1F9D8\U200D\U2642'
+emoji[lotus_position_man]=$'\U1F9D8\U200D\U2642'
+emoji[man_in_lotus_position_light_skin_tone]=$'\U1F9D8\U1F3FB\U200D\U2642\UFE0F'
+emoji[man_in_lotus_position_light_skin_tone_minimally]=$'\U1F9D8\U1F3FB\U200D\U2642'
+emoji[man_in_lotus_position_medium_light_skin_tone]=$'\U1F9D8\U1F3FC\U200D\U2642\UFE0F'
+emoji[man_in_lotus_position_medium_light_skin_tone_minimally]=$'\U1F9D8\U1F3FC\U200D\U2642'
+emoji[man_in_lotus_position_medium_skin_tone]=$'\U1F9D8\U1F3FD\U200D\U2642\UFE0F'
+emoji[man_in_lotus_position_medium_skin_tone_minimally]=$'\U1F9D8\U1F3FD\U200D\U2642'
+emoji[man_in_lotus_position_medium_dark_skin_tone]=$'\U1F9D8\U1F3FE\U200D\U2642\UFE0F'
+emoji[man_in_lotus_position_medium_dark_skin_tone_minimally]=$'\U1F9D8\U1F3FE\U200D\U2642'
+emoji[man_in_lotus_position_dark_skin_tone]=$'\U1F9D8\U1F3FF\U200D\U2642\UFE0F'
+emoji[man_in_lotus_position_dark_skin_tone_minimally]=$'\U1F9D8\U1F3FF\U200D\U2642'
+emoji[woman_in_lotus_position]=$'\U1F9D8\U200D\U2640\UFE0F'
+emoji[woman_in_lotus_position_minimally]=$'\U1F9D8\U200D\U2640'
+emoji[lotus_position_woman]=$'\U1F9D8\U200D\U2640'
+emoji[woman_in_lotus_position_light_skin_tone]=$'\U1F9D8\U1F3FB\U200D\U2640\UFE0F'
+emoji[woman_in_lotus_position_light_skin_tone_minimally]=$'\U1F9D8\U1F3FB\U200D\U2640'
+emoji[woman_in_lotus_position_medium_light_skin_tone]=$'\U1F9D8\U1F3FC\U200D\U2640\UFE0F'
+emoji[woman_in_lotus_position_medium_light_skin_tone_minimally]=$'\U1F9D8\U1F3FC\U200D\U2640'
+emoji[woman_in_lotus_position_medium_skin_tone]=$'\U1F9D8\U1F3FD\U200D\U2640\UFE0F'
+emoji[woman_in_lotus_position_medium_skin_tone_minimally]=$'\U1F9D8\U1F3FD\U200D\U2640'
+emoji[woman_in_lotus_position_medium_dark_skin_tone]=$'\U1F9D8\U1F3FE\U200D\U2640\UFE0F'
+emoji[woman_in_lotus_position_medium_dark_skin_tone_minimally]=$'\U1F9D8\U1F3FE\U200D\U2640'
+emoji[woman_in_lotus_position_dark_skin_tone]=$'\U1F9D8\U1F3FF\U200D\U2640\UFE0F'
+emoji[woman_in_lotus_position_dark_skin_tone_minimally]=$'\U1F9D8\U1F3FF\U200D\U2640'
+emoji[person_taking_bath]=$'\U1F6C0'
+emoji[bath]=$'\U1F6C0'
+emoji[person_taking_bath_light_skin_tone]=$'\U1F6C0\U1F3FB'
+emoji[person_taking_bath_medium_light_skin_tone]=$'\U1F6C0\U1F3FC'
+emoji[person_taking_bath_medium_skin_tone]=$'\U1F6C0\U1F3FD'
+emoji[person_taking_bath_medium_dark_skin_tone]=$'\U1F6C0\U1F3FE'
+emoji[person_taking_bath_dark_skin_tone]=$'\U1F6C0\U1F3FF'
+emoji[person_in_bed]=$'\U1F6CC'
+emoji[sleeping_bed]=$'\U1F6CC'
+emoji[person_in_bed_light_skin_tone]=$'\U1F6CC\U1F3FB'
+emoji[person_in_bed_medium_light_skin_tone]=$'\U1F6CC\U1F3FC'
+emoji[person_in_bed_medium_skin_tone]=$'\U1F6CC\U1F3FD'
+emoji[person_in_bed_medium_dark_skin_tone]=$'\U1F6CC\U1F3FE'
+emoji[person_in_bed_dark_skin_tone]=$'\U1F6CC\U1F3FF'
+emoji[people_holding_hands]=$'\U1F9D1\U200D\U1F91D\U200D\U1F9D1'
+emoji[people_holding_hands_light_skin_tone]=$'\U1F9D1\U1F3FB\U200D\U1F91D\U200D\U1F9D1\U1F3FB'
+emoji[people_holding_hands_medium_light_skin_tone_light_skin_tone]=$'\U1F9D1\U1F3FC\U200D\U1F91D\U200D\U1F9D1\U1F3FB'
+emoji[people_holding_hands_medium_light_skin_tone_light_skin_tone_1]=$'\U1F9D1\U1F3FC\U200D\U1F91D\U200D\U1F9D1\U1F3FC'
+emoji[people_holding_hands_medium_skin_tone_light_skin_tone]=$'\U1F9D1\U1F3FD\U200D\U1F91D\U200D\U1F9D1\U1F3FB'
+emoji[people_holding_hands_medium_skin_tone_medium_light_skin_tone]=$'\U1F9D1\U1F3FD\U200D\U1F91D\U200D\U1F9D1\U1F3FC'
+emoji[people_holding_hands_medium_skin_tone_medium_light_skin_tone_1]=$'\U1F9D1\U1F3FD\U200D\U1F91D\U200D\U1F9D1\U1F3FD'
+emoji[people_holding_hands_medium_dark_skin_tone_light_skin_tone]=$'\U1F9D1\U1F3FE\U200D\U1F91D\U200D\U1F9D1\U1F3FB'
+emoji[people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone]=$'\U1F9D1\U1F3FE\U200D\U1F91D\U200D\U1F9D1\U1F3FC'
+emoji[people_holding_hands_medium_dark_skin_tone_medium_skin_tone]=$'\U1F9D1\U1F3FE\U200D\U1F91D\U200D\U1F9D1\U1F3FD'
+emoji[people_holding_hands_medium_dark_skin_tone_medium_skin_tone_1]=$'\U1F9D1\U1F3FE\U200D\U1F91D\U200D\U1F9D1\U1F3FE'
+emoji[people_holding_hands_dark_skin_tone_light_skin_tone]=$'\U1F9D1\U1F3FF\U200D\U1F91D\U200D\U1F9D1\U1F3FB'
+emoji[people_holding_hands_dark_skin_tone_medium_light_skin_tone]=$'\U1F9D1\U1F3FF\U200D\U1F91D\U200D\U1F9D1\U1F3FC'
+emoji[people_holding_hands_dark_skin_tone_medium_skin_tone]=$'\U1F9D1\U1F3FF\U200D\U1F91D\U200D\U1F9D1\U1F3FD'
+emoji[people_holding_hands_dark_skin_tone_medium_dark_skin_tone]=$'\U1F9D1\U1F3FF\U200D\U1F91D\U200D\U1F9D1\U1F3FE'
+emoji[people_holding_hands_dark_skin_tone_medium_dark_skin_tone_1]=$'\U1F9D1\U1F3FF\U200D\U1F91D\U200D\U1F9D1\U1F3FF'
+emoji[women_holding_hands]=$'\U1F46D'
+emoji[two_women_holding_hands]=$'\U1F46D'
+emoji[women_holding_hands_light_skin_tone]=$'\U1F46D\U1F3FB'
+emoji[women_holding_hands_medium_light_skin_tone_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F91D\U200D\U1F469\U1F3FB'
+emoji[women_holding_hands_medium_light_skin_tone_light_skin_tone_1]=$'\U1F46D\U1F3FC'
+emoji[women_holding_hands_medium_skin_tone_light_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F91D\U200D\U1F469\U1F3FB'
+emoji[women_holding_hands_medium_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F91D\U200D\U1F469\U1F3FC'
+emoji[women_holding_hands_medium_skin_tone_medium_light_skin_tone_1]=$'\U1F46D\U1F3FD'
+emoji[women_holding_hands_medium_dark_skin_tone_light_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F469\U1F3FB'
+emoji[women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F469\U1F3FC'
+emoji[women_holding_hands_medium_dark_skin_tone_medium_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F469\U1F3FD'
+emoji[women_holding_hands_medium_dark_skin_tone_medium_skin_tone_1]=$'\U1F46D\U1F3FE'
+emoji[women_holding_hands_dark_skin_tone_light_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F469\U1F3FB'
+emoji[women_holding_hands_dark_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F469\U1F3FC'
+emoji[women_holding_hands_dark_skin_tone_medium_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F469\U1F3FD'
+emoji[women_holding_hands_dark_skin_tone_medium_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F469\U1F3FE'
+emoji[women_holding_hands_dark_skin_tone_medium_dark_skin_tone_1]=$'\U1F46D\U1F3FF'
+emoji[woman_and_man_holding_hands]=$'\U1F46B'
+emoji[couple]=$'\U1F46B'
+emoji[woman_and_man_holding_hands_light_skin_tone]=$'\U1F46B\U1F3FB'
+emoji[woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[woman_and_man_holding_hands_light_skin_tone_medium_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F91D\U200D\U1F468\U1F3FD'
+emoji[woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F91D\U200D\U1F468\U1F3FE'
+emoji[woman_and_man_holding_hands_light_skin_tone_dark_skin_tone]=$'\U1F469\U1F3FB\U200D\U1F91D\U200D\U1F468\U1F3FF'
+emoji[woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone_1]=$'\U1F46B\U1F3FC'
+emoji[woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F91D\U200D\U1F468\U1F3FD'
+emoji[woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F91D\U200D\U1F468\U1F3FE'
+emoji[woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone]=$'\U1F469\U1F3FC\U200D\U1F91D\U200D\U1F468\U1F3FF'
+emoji[woman_and_man_holding_hands_medium_skin_tone_light_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone_1]=$'\U1F46B\U1F3FD'
+emoji[woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F91D\U200D\U1F468\U1F3FE'
+emoji[woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone]=$'\U1F469\U1F3FD\U200D\U1F91D\U200D\U1F468\U1F3FF'
+emoji[woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FD'
+emoji[woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone_1]=$'\U1F46B\U1F3FE'
+emoji[woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone]=$'\U1F469\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FF'
+emoji[woman_and_man_holding_hands_dark_skin_tone_light_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FD'
+emoji[woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone]=$'\U1F469\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FE'
+emoji[woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone_1]=$'\U1F46B\U1F3FF'
+emoji[men_holding_hands]=$'\U1F46C'
+emoji[two_men_holding_hands]=$'\U1F46C'
+emoji[men_holding_hands_light_skin_tone]=$'\U1F46C\U1F3FB'
+emoji[men_holding_hands_medium_light_skin_tone_light_skin_tone]=$'\U1F468\U1F3FC\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[men_holding_hands_medium_light_skin_tone_light_skin_tone_1]=$'\U1F46C\U1F3FC'
+emoji[men_holding_hands_medium_skin_tone_light_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[men_holding_hands_medium_skin_tone_medium_light_skin_tone]=$'\U1F468\U1F3FD\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[men_holding_hands_medium_skin_tone_medium_light_skin_tone_1]=$'\U1F46C\U1F3FD'
+emoji[men_holding_hands_medium_dark_skin_tone_light_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[men_holding_hands_medium_dark_skin_tone_medium_skin_tone]=$'\U1F468\U1F3FE\U200D\U1F91D\U200D\U1F468\U1F3FD'
+emoji[men_holding_hands_medium_dark_skin_tone_medium_skin_tone_1]=$'\U1F46C\U1F3FE'
+emoji[men_holding_hands_dark_skin_tone_light_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FB'
+emoji[men_holding_hands_dark_skin_tone_medium_light_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FC'
+emoji[men_holding_hands_dark_skin_tone_medium_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FD'
+emoji[men_holding_hands_dark_skin_tone_medium_dark_skin_tone]=$'\U1F468\U1F3FF\U200D\U1F91D\U200D\U1F468\U1F3FE'
+emoji[men_holding_hands_dark_skin_tone_medium_dark_skin_tone_1]=$'\U1F46C\U1F3FF'
+emoji[kiss]=$'\U1F48F'
+emoji[couplekiss]=$'\U1F48F'
+emoji[kiss_woman_man]=$'\U1F469\U200D\U2764\UFE0F\U200D\U1F48B\U200D\U1F468'
+emoji[couplekiss_man_woman]=$'\U1F469\U200D\U2764\UFE0F\U200D\U1F48B\U200D\U1F468'
+emoji[kiss_woman_man_minimally]=$'\U1F469\U200D\U2764\U200D\U1F48B\U200D\U1F468'
+emoji[kiss_man_man]=$'\U1F468\U200D\U2764\UFE0F\U200D\U1F48B\U200D\U1F468'
+emoji[couplekiss_man_man]=$'\U1F468\U200D\U2764\UFE0F\U200D\U1F48B\U200D\U1F468'
+emoji[kiss_man_man_minimally]=$'\U1F468\U200D\U2764\U200D\U1F48B\U200D\U1F468'
+emoji[kiss_woman_woman]=$'\U1F469\U200D\U2764\UFE0F\U200D\U1F48B\U200D\U1F469'
+emoji[couplekiss_woman_woman]=$'\U1F469\U200D\U2764\UFE0F\U200D\U1F48B\U200D\U1F469'
+emoji[kiss_woman_woman_minimally]=$'\U1F469\U200D\U2764\U200D\U1F48B\U200D\U1F469'
+emoji[couple_with_heart]=$'\U1F491'
+emoji[couple_with_heart_woman_man]=$'\U1F469\U200D\U2764\UFE0F\U200D\U1F468'
+emoji[couple_with_heart_woman_man_minimally]=$'\U1F469\U200D\U2764\U200D\U1F468'
+emoji[couple_with_heart_man_man]=$'\U1F468\U200D\U2764\UFE0F\U200D\U1F468'
+emoji[couple_with_heart_man_man_minimally]=$'\U1F468\U200D\U2764\U200D\U1F468'
+emoji[couple_with_heart_woman_woman]=$'\U1F469\U200D\U2764\UFE0F\U200D\U1F469'
+emoji[couple_with_heart_woman_woman_minimally]=$'\U1F469\U200D\U2764\U200D\U1F469'
+emoji[family]=$'\U1F46A'
+emoji[family_man_woman_boy]=$'\U1F468\U200D\U1F469\U200D\U1F466'
+emoji[family_man_woman_girl]=$'\U1F468\U200D\U1F469\U200D\U1F467'
+emoji[family_man_woman_girl_boy]=$'\U1F468\U200D\U1F469\U200D\U1F467\U200D\U1F466'
+emoji[family_man_woman_boy_boy]=$'\U1F468\U200D\U1F469\U200D\U1F466\U200D\U1F466'
+emoji[family_man_woman_girl_girl]=$'\U1F468\U200D\U1F469\U200D\U1F467\U200D\U1F467'
+emoji[family_man_man_boy]=$'\U1F468\U200D\U1F468\U200D\U1F466'
+emoji[family_man_man_girl]=$'\U1F468\U200D\U1F468\U200D\U1F467'
+emoji[family_man_man_girl_boy]=$'\U1F468\U200D\U1F468\U200D\U1F467\U200D\U1F466'
+emoji[family_man_man_boy_boy]=$'\U1F468\U200D\U1F468\U200D\U1F466\U200D\U1F466'
+emoji[family_man_man_girl_girl]=$'\U1F468\U200D\U1F468\U200D\U1F467\U200D\U1F467'
+emoji[family_woman_woman_boy]=$'\U1F469\U200D\U1F469\U200D\U1F466'
+emoji[family_woman_woman_girl]=$'\U1F469\U200D\U1F469\U200D\U1F467'
+emoji[family_woman_woman_girl_boy]=$'\U1F469\U200D\U1F469\U200D\U1F467\U200D\U1F466'
+emoji[family_woman_woman_boy_boy]=$'\U1F469\U200D\U1F469\U200D\U1F466\U200D\U1F466'
+emoji[family_woman_woman_girl_girl]=$'\U1F469\U200D\U1F469\U200D\U1F467\U200D\U1F467'
+emoji[family_man_boy]=$'\U1F468\U200D\U1F466'
+emoji[family_man_boy_boy]=$'\U1F468\U200D\U1F466\U200D\U1F466'
+emoji[family_man_girl]=$'\U1F468\U200D\U1F467'
+emoji[family_man_girl_boy]=$'\U1F468\U200D\U1F467\U200D\U1F466'
+emoji[family_man_girl_girl]=$'\U1F468\U200D\U1F467\U200D\U1F467'
+emoji[family_woman_boy]=$'\U1F469\U200D\U1F466'
+emoji[family_woman_boy_boy]=$'\U1F469\U200D\U1F466\U200D\U1F466'
+emoji[family_woman_girl]=$'\U1F469\U200D\U1F467'
+emoji[family_woman_girl_boy]=$'\U1F469\U200D\U1F467\U200D\U1F466'
+emoji[family_woman_girl_girl]=$'\U1F469\U200D\U1F467\U200D\U1F467'
+emoji[speaking_head]=$'\U1F5E3\UFE0F'
+emoji[speaking_head_unqualified]=$'\U1F5E3'
+emoji[bust_in_silhouette]=$'\U1F464'
+emoji[busts_in_silhouette]=$'\U1F465'
+emoji[footprints]=$'\U1F463'
+emoji_mod[light_skin_tone]=$'\U1F3FB'
+emoji_mod[medium_light_skin_tone]=$'\U1F3FC'
+emoji_mod[medium_skin_tone]=$'\U1F3FD'
+emoji_mod[medium_dark_skin_tone]=$'\U1F3FE'
+emoji_mod[medium_dark_skin_tone_1]=$'\U1F3FF'
+emoji_mod[red_hair]=$'\U1F9B0'
+emoji_mod[curly_hair]=$'\U1F9B1'
+emoji_mod[white_hair]=$'\U1F9B3'
+emoji_mod[bald]=$'\U1F9B2'
+emoji[monkey_face]=$'\U1F435'
+emoji[monkey_face_1]=$'\U1F412'
+emoji[monkey]=$'\U1F412'
+emoji[gorilla]=$'\U1F98D'
+emoji[orangutan]=$'\U1F9A7'
+emoji[dog_face]=$'\U1F436'
+emoji[dog]=$'\U1F436'
+emoji[dog_face_1]=$'\U1F415'
+emoji[dog2]=$'\U1F415'
+emoji[guide_dog]=$'\U1F9AE'
+emoji[service_dog]=$'\U1F415\U200D\U1F9BA'
+emoji[poodle]=$'\U1F429'
+emoji[wolf]=$'\U1F43A'
+emoji[fox]=$'\U1F98A'
+emoji[fox_face]=$'\U1F98A'
+emoji[raccoon]=$'\U1F99D'
+emoji[cat_face]=$'\U1F431'
+emoji[cat]=$'\U1F431'
+emoji[cat_face_1]=$'\U1F408'
+emoji[cat2]=$'\U1F408'
+emoji[lion]=$'\U1F981'
+emoji[tiger_face]=$'\U1F42F'
+emoji[tiger]=$'\U1F42F'
+emoji[tiger_face_1]=$'\U1F405'
+emoji[tiger2]=$'\U1F405'
+emoji[leopard]=$'\U1F406'
+emoji[horse_face]=$'\U1F434'
+emoji[horse]=$'\U1F434'
+emoji[horse_face_1]=$'\U1F40E'
+emoji[racehorse]=$'\U1F40E'
+emoji[unicorn]=$'\U1F984'
+emoji[zebra]=$'\U1F993'
+emoji[deer]=$'\U1F98C'
+emoji[cow_face]=$'\U1F42E'
+emoji[ox]=$'\U1F402'
+emoji[water_buffalo]=$'\U1F403'
+emoji[cow]=$'\U1F404'
+emoji[cow2]=$'\U1F404'
+emoji[pig_face]=$'\U1F437'
+emoji[pig]=$'\U1F437'
+emoji[pig_face_1]=$'\U1F416'
+emoji[pig2]=$'\U1F416'
+emoji[boar]=$'\U1F417'
+emoji[pig_nose]=$'\U1F43D'
+emoji[ram]=$'\U1F40F'
+emoji[ewe]=$'\U1F411'
+emoji[sheep]=$'\U1F411'
+emoji[goat]=$'\U1F410'
+emoji[camel]=$'\U1F42A'
+emoji[dromedary_camel]=$'\U1F42A'
+emoji[two_hump_camel]=$'\U1F42B'
+emoji[llama]=$'\U1F999'
+emoji[giraffe]=$'\U1F992'
+emoji[elephant]=$'\U1F418'
+emoji[rhinoceros]=$'\U1F98F'
+emoji[hippopotamus]=$'\U1F99B'
+emoji[mouse_face]=$'\U1F42D'
+emoji[mouse]=$'\U1F42D'
+emoji[mouse_face_1]=$'\U1F401'
+emoji[mouse2]=$'\U1F401'
+emoji[rat]=$'\U1F400'
+emoji[hamster]=$'\U1F439'
+emoji[rabbit_face]=$'\U1F430'
+emoji[rabbit]=$'\U1F430'
+emoji[rabbit_face_1]=$'\U1F407'
+emoji[rabbit2]=$'\U1F407'
+emoji[chipmunk]=$'\U1F43F\UFE0F'
+emoji[chipmunk_unqualified]=$'\U1F43F'
+emoji[hedgehog]=$'\U1F994'
+emoji[bat]=$'\U1F987'
+emoji[bear]=$'\U1F43B'
+emoji[koala]=$'\U1F428'
+emoji[panda]=$'\U1F43C'
+emoji[panda_face]=$'\U1F43C'
+emoji[sloth]=$'\U1F9A5'
+emoji[otter]=$'\U1F9A6'
+emoji[skunk]=$'\U1F9A8'
+emoji[kangaroo]=$'\U1F998'
+emoji[badger]=$'\U1F9A1'
+emoji[paw_prints]=$'\U1F43E'
+emoji[feet]=$'\U1F43E'
+emoji[turkey]=$'\U1F983'
+emoji[chicken]=$'\U1F414'
+emoji[rooster]=$'\U1F413'
+emoji[hatching_chick]=$'\U1F423'
+emoji[baby_chick]=$'\U1F424'
+emoji[front_facing_baby_chick]=$'\U1F425'
+emoji[hatched_chick]=$'\U1F425'
+emoji[bird]=$'\U1F426'
+emoji[penguin]=$'\U1F427'
+emoji[dove]=$'\U1F54A\UFE0F'
+emoji[dove_unqualified]=$'\U1F54A'
+emoji[eagle]=$'\U1F985'
+emoji[duck]=$'\U1F986'
+emoji[swan]=$'\U1F9A2'
+emoji[owl]=$'\U1F989'
+emoji[flamingo]=$'\U1F9A9'
+emoji[peacock]=$'\U1F99A'
+emoji[parrot]=$'\U1F99C'
+emoji[frog]=$'\U1F438'
+emoji[crocodile]=$'\U1F40A'
+emoji[turtle]=$'\U1F422'
+emoji[lizard]=$'\U1F98E'
+emoji[snake]=$'\U1F40D'
+emoji[dragon_face]=$'\U1F432'
+emoji[dragon_face_1]=$'\U1F409'
+emoji[dragon]=$'\U1F409'
+emoji[sauropod]=$'\U1F995'
+emoji[T_Rex]=$'\U1F996'
+emoji[t-rex]=$'\U1F996'
+emoji[spouting_whale]=$'\U1F433'
+emoji[whale]=$'\U1F433'
+emoji[spouting_whale_1]=$'\U1F40B'
+emoji[whale2]=$'\U1F40B'
+emoji[dolphin]=$'\U1F42C'
+emoji[flipper]=$'\U1F42C'
+emoji[fish]=$'\U1F41F'
+emoji[tropical_fish]=$'\U1F420'
+emoji[blowfish]=$'\U1F421'
+emoji[shark]=$'\U1F988'
+emoji[octopus]=$'\U1F419'
+emoji[spiral_shell]=$'\U1F41A'
+emoji[shell]=$'\U1F41A'
+emoji[snail]=$'\U1F40C'
+emoji[butterfly]=$'\U1F98B'
+emoji[bug]=$'\U1F41B'
+emoji[ant]=$'\U1F41C'
+emoji[honeybee]=$'\U1F41D'
+emoji[bee]=$'\U1F41D'
+emoji[lady_beetle]=$'\U1F41E'
+emoji[beetle]=$'\U1F41E'
+emoji[cricket]=$'\U1F997'
+emoji[spider]=$'\U1F577\UFE0F'
+emoji[spider_unqualified]=$'\U1F577'
+emoji[spider_web]=$'\U1F578\UFE0F'
+emoji[spider_web_unqualified]=$'\U1F578'
+emoji[scorpion]=$'\U1F982'
+emoji[mosquito]=$'\U1F99F'
+emoji[microbe]=$'\U1F9A0'
+emoji[bouquet]=$'\U1F490'
+emoji[cherry_blossom]=$'\U1F338'
+emoji[white_flower]=$'\U1F4AE'
+emoji[rosette]=$'\U1F3F5\UFE0F'
+emoji[rosette_unqualified]=$'\U1F3F5'
+emoji[rosette_unqualified_1]=$'\U1F339'
+emoji[rose]=$'\U1F339'
+emoji[wilted_flower]=$'\U1F940'
+emoji[hibiscus]=$'\U1F33A'
+emoji[sunflower]=$'\U1F33B'
+emoji[blossom]=$'\U1F33C'
+emoji[tulip]=$'\U1F337'
+emoji[seedling]=$'\U1F331'
+emoji[evergreen_tree]=$'\U1F332'
+emoji[deciduous_tree]=$'\U1F333'
+emoji[palm_tree]=$'\U1F334'
+emoji[cactus]=$'\U1F335'
+emoji[sheaf_of_rice]=$'\U1F33E'
+emoji[ear_of_rice]=$'\U1F33E'
+emoji[herb]=$'\U1F33F'
+emoji[shamrock]=$'\U2618\UFE0F'
+emoji[shamrock_unqualified]=$'\U2618'
+emoji[four_leaf_clover]=$'\U1F340'
+emoji[maple_leaf]=$'\U1F341'
+emoji[fallen_leaf]=$'\U1F342'
+emoji[leaf_fluttering_in_wind]=$'\U1F343'
+emoji[leaves]=$'\U1F343'
+emoji[grapes]=$'\U1F347'
+emoji[melon]=$'\U1F348'
+emoji[watermelon]=$'\U1F349'
+emoji[tangerine]=$'\U1F34A'
+emoji[orange]=$'\U1F34A'
+emoji[mandarin]=$'\U1F34A'
+emoji[lemon]=$'\U1F34B'
+emoji[banana]=$'\U1F34C'
+emoji[pineapple]=$'\U1F34D'
+emoji[mango]=$'\U1F96D'
+emoji[red_apple]=$'\U1F34E'
+emoji[apple]=$'\U1F34E'
+emoji[green_apple]=$'\U1F34F'
+emoji[pear]=$'\U1F350'
+emoji[peach]=$'\U1F351'
+emoji[cherries]=$'\U1F352'
+emoji[strawberry]=$'\U1F353'
+emoji[kiwi_fruit]=$'\U1F95D'
+emoji[tomato]=$'\U1F345'
+emoji[coconut]=$'\U1F965'
+emoji[avocado]=$'\U1F951'
+emoji[eggplant]=$'\U1F346'
+emoji[potato]=$'\U1F954'
+emoji[carrot]=$'\U1F955'
+emoji[ear_of_corn]=$'\U1F33D'
+emoji[corn]=$'\U1F33D'
+emoji[hot_pepper]=$'\U1F336\UFE0F'
+emoji[hot_pepper_unqualified]=$'\U1F336'
+emoji[cucumber]=$'\U1F952'
+emoji[leafy_green]=$'\U1F96C'
+emoji[broccoli]=$'\U1F966'
+emoji[garlic]=$'\U1F9C4'
+emoji[onion]=$'\U1F9C5'
+emoji[mushroom]=$'\U1F344'
+emoji[peanuts]=$'\U1F95C'
+emoji[chestnut]=$'\U1F330'
+emoji[bread]=$'\U1F35E'
+emoji[croissant]=$'\U1F950'
+emoji[baguette_bread]=$'\U1F956'
+emoji[pretzel]=$'\U1F968'
+emoji[bagel]=$'\U1F96F'
+emoji[pancakes]=$'\U1F95E'
+emoji[waffle]=$'\U1F9C7'
+emoji[cheese_wedge]=$'\U1F9C0'
+emoji[cheese]=$'\U1F9C0'
+emoji[meat_on_bone]=$'\U1F356'
+emoji[poultry_leg]=$'\U1F357'
+emoji[cut_of_meat]=$'\U1F969'
+emoji[bacon]=$'\U1F953'
+emoji[hamburger]=$'\U1F354'
+emoji[french_fries]=$'\U1F35F'
+emoji[fries]=$'\U1F35F'
+emoji[pizza]=$'\U1F355'
+emoji[hot_dog]=$'\U1F32D'
+emoji[hotdog]=$'\U1F32D'
+emoji[sandwich]=$'\U1F96A'
+emoji[taco]=$'\U1F32E'
+emoji[burrito]=$'\U1F32F'
+emoji[stuffed_flatbread]=$'\U1F959'
+emoji[falafel]=$'\U1F9C6'
+emoji[egg]=$'\U1F95A'
+emoji[cooking]=$'\U1F373'
+emoji[fried_egg]=$'\U1F373'
+emoji[shallow_pan_of_food]=$'\U1F958'
+emoji[pot_of_food]=$'\U1F372'
+emoji[stew]=$'\U1F372'
+emoji[bowl_with_spoon]=$'\U1F963'
+emoji[green_salad]=$'\U1F957'
+emoji[popcorn]=$'\U1F37F'
+emoji[butter]=$'\U1F9C8'
+emoji[salt]=$'\U1F9C2'
+emoji[canned_food]=$'\U1F96B'
+emoji[bento_box]=$'\U1F371'
+emoji[bento]=$'\U1F371'
+emoji[rice_cracker]=$'\U1F358'
+emoji[rice_ball]=$'\U1F359'
+emoji[cooked_rice]=$'\U1F35A'
+emoji[rice]=$'\U1F35A'
+emoji[curry_rice]=$'\U1F35B'
+emoji[curry]=$'\U1F35B'
+emoji[steaming_bowl]=$'\U1F35C'
+emoji[ramen]=$'\U1F35C'
+emoji[spaghetti]=$'\U1F35D'
+emoji[roasted_sweet_potato]=$'\U1F360'
+emoji[sweet_potato]=$'\U1F360'
+emoji[oden]=$'\U1F362'
+emoji[sushi]=$'\U1F363'
+emoji[fried_shrimp]=$'\U1F364'
+emoji[fish_cake_with_swirl]=$'\U1F365'
+emoji[fish_cake]=$'\U1F365'
+emoji[moon_cake]=$'\U1F96E'
+emoji[dango]=$'\U1F361'
+emoji[dumpling]=$'\U1F95F'
+emoji[fortune_cookie]=$'\U1F960'
+emoji[takeout_box]=$'\U1F961'
+emoji[crab]=$'\U1F980'
+emoji[lobster]=$'\U1F99E'
+emoji[shrimp]=$'\U1F990'
+emoji[squid]=$'\U1F991'
+emoji[oyster]=$'\U1F9AA'
+emoji[soft_ice_cream]=$'\U1F366'
+emoji[icecream]=$'\U1F366'
+emoji[shaved_ice]=$'\U1F367'
+emoji[ice_cream]=$'\U1F368'
+emoji[doughnut]=$'\U1F369'
+emoji[cookie]=$'\U1F36A'
+emoji[birthday_cake]=$'\U1F382'
+emoji[birthday]=$'\U1F382'
+emoji[shortcake]=$'\U1F370'
+emoji[cake]=$'\U1F370'
+emoji[cupcake]=$'\U1F9C1'
+emoji[pie]=$'\U1F967'
+emoji[chocolate_bar]=$'\U1F36B'
+emoji[candy]=$'\U1F36C'
+emoji[lollipop]=$'\U1F36D'
+emoji[custard]=$'\U1F36E'
+emoji[honey_pot]=$'\U1F36F'
+emoji[baby_bottle]=$'\U1F37C'
+emoji[glass_of_milk]=$'\U1F95B'
+emoji[milk_glass]=$'\U1F95B'
+emoji[hot_beverage]=$'\U2615'
+emoji[coffee]=$'\U2615'
+emoji[teacup_without_handle]=$'\U1F375'
+emoji[tea]=$'\U1F375'
+emoji[sake]=$'\U1F376'
+emoji[bottle_with_popping_cork]=$'\U1F37E'
+emoji[champagne]=$'\U1F37E'
+emoji[wine_glass]=$'\U1F377'
+emoji[cocktail_glass]=$'\U1F378'
+emoji[cocktail]=$'\U1F378'
+emoji[tropical_drink]=$'\U1F379'
+emoji[beer_mug]=$'\U1F37A'
+emoji[beer]=$'\U1F37A'
+emoji[clinking_beer_mugs]=$'\U1F37B'
+emoji[beers]=$'\U1F37B'
+emoji[clinking_glasses]=$'\U1F942'
+emoji[tumbler_glass]=$'\U1F943'
+emoji[cup_with_straw]=$'\U1F964'
+emoji[beverage_box]=$'\U1F9C3'
+emoji[mate]=$'\U1F9C9'
+emoji[ice_cube]=$'\U1F9CA'
+emoji[chopsticks]=$'\U1F962'
+emoji[fork_and_knife_with_plate]=$'\U1F37D\UFE0F'
+emoji[fork_and_knife_with_plate_unqualified]=$'\U1F37D'
+emoji[plate_with_cutlery]=$'\U1F37D'
+emoji[fork_and_knife_with_plate_unqualified_1]=$'\U1F374'
+emoji[fork_and_knife]=$'\U1F374'
+emoji[spoon]=$'\U1F944'
+emoji[kitchen_knife]=$'\U1F52A'
+emoji[hocho]=$'\U1F52A'
+emoji[knife]=$'\U1F52A'
+emoji[amphora]=$'\U1F3FA'
+emoji[globe_showing_Europe_Africa]=$'\U1F30D'
+emoji[earth_africa]=$'\U1F30D'
+emoji[globe_showing_Americas]=$'\U1F30E'
+emoji[earth_americas]=$'\U1F30E'
+emoji[globe_showing_Asia_Australia]=$'\U1F30F'
+emoji[earth_asia]=$'\U1F30F'
+emoji[globe_with_meridians]=$'\U1F310'
+emoji[world_map]=$'\U1F5FA\UFE0F'
+emoji[world_map_unqualified]=$'\U1F5FA'
+emoji[map_of_Japan]=$'\U1F5FE'
+emoji[japan]=$'\U1F5FE'
+emoji[compass]=$'\U1F9ED'
+emoji[snow_capped_mountain]=$'\U1F3D4\UFE0F'
+emoji[snow_capped_mountain_unqualified]=$'\U1F3D4'
+emoji[mountain_snow]=$'\U1F3D4'
+emoji[snow_capped_mountain_unqualified_1]=$'\U26F0\UFE0F'
+emoji[snow_capped_mountain_unqualified_2]=$'\U26F0'
+emoji[mountain]=$'\U26F0'
+emoji[volcano]=$'\U1F30B'
+emoji[mount_fuji]=$'\U1F5FB'
+emoji[camping]=$'\U1F3D5\UFE0F'
+emoji[camping_unqualified]=$'\U1F3D5'
+emoji[beach_with_umbrella]=$'\U1F3D6\UFE0F'
+emoji[beach_with_umbrella_unqualified]=$'\U1F3D6'
+emoji[beach_umbrella]=$'\U1F3D6'
+emoji[desert]=$'\U1F3DC\UFE0F'
+emoji[desert_unqualified]=$'\U1F3DC'
+emoji[desert_island]=$'\U1F3DD\UFE0F'
+emoji[desert_island_unqualified]=$'\U1F3DD'
+emoji[national_park]=$'\U1F3DE\UFE0F'
+emoji[national_park_unqualified]=$'\U1F3DE'
+emoji[stadium]=$'\U1F3DF\UFE0F'
+emoji[stadium_unqualified]=$'\U1F3DF'
+emoji[classical_building]=$'\U1F3DB\UFE0F'
+emoji[classical_building_unqualified]=$'\U1F3DB'
+emoji[building_construction]=$'\U1F3D7\UFE0F'
+emoji[building_construction_unqualified]=$'\U1F3D7'
+emoji[brick]=$'\U1F9F1'
+emoji[bricks]=$'\U1F9F1'
+emoji[houses]=$'\U1F3D8\UFE0F'
+emoji[houses_unqualified]=$'\U1F3D8'
+emoji[derelict_house]=$'\U1F3DA\UFE0F'
+emoji[derelict_house_unqualified]=$'\U1F3DA'
+emoji[derelict_house_unqualified_1]=$'\U1F3E0'
+emoji[house]=$'\U1F3E0'
+emoji[house_with_garden]=$'\U1F3E1'
+emoji[office_building]=$'\U1F3E2'
+emoji[office]=$'\U1F3E2'
+emoji[Japanese_post_office]=$'\U1F3E3'
+emoji[post_office]=$'\U1F3E3'
+emoji[Japanese_post_office_1]=$'\U1F3E4'
+emoji[european_post_office]=$'\U1F3E4'
+emoji[hospital]=$'\U1F3E5'
+emoji[bank]=$'\U1F3E6'
+emoji[hotel]=$'\U1F3E8'
+emoji[love_hotel]=$'\U1F3E9'
+emoji[convenience_store]=$'\U1F3EA'
+emoji[school]=$'\U1F3EB'
+emoji[department_store]=$'\U1F3EC'
+emoji[factory]=$'\U1F3ED'
+emoji[Japanese_castle]=$'\U1F3EF'
+emoji[japanese_castle]=$'\U1F3EF'
+emoji[Japanese_castle_1]=$'\U1F3F0'
+emoji[european_castle]=$'\U1F3F0'
+emoji[wedding]=$'\U1F492'
+emoji[Tokyo_tower]=$'\U1F5FC'
+emoji[tokyo_tower]=$'\U1F5FC'
+emoji[Statue_of_Liberty]=$'\U1F5FD'
+emoji[statue_of_liberty]=$'\U1F5FD'
+emoji[church]=$'\U26EA'
+emoji[mosque]=$'\U1F54C'
+emoji[hindu_temple]=$'\U1F6D5'
+emoji[synagogue]=$'\U1F54D'
+emoji[shinto_shrine]=$'\U26E9\UFE0F'
+emoji[shinto_shrine_unqualified]=$'\U26E9'
+emoji[kaaba]=$'\U1F54B'
+emoji[fountain]=$'\U26F2'
+emoji[tent]=$'\U26FA'
+emoji[foggy]=$'\U1F301'
+emoji[night_with_stars]=$'\U1F303'
+emoji[cityscape]=$'\U1F3D9\UFE0F'
+emoji[cityscape_unqualified]=$'\U1F3D9'
+emoji[sunrise_over_mountains]=$'\U1F304'
+emoji[sunrise_over_mountains_1]=$'\U1F305'
+emoji[sunrise]=$'\U1F305'
+emoji[cityscape_at_dusk]=$'\U1F306'
+emoji[city_sunset]=$'\U1F306'
+emoji[sunset]=$'\U1F307'
+emoji[city_sunrise]=$'\U1F307'
+emoji[bridge_at_night]=$'\U1F309'
+emoji[hot_springs]=$'\U2668\UFE0F'
+emoji[hotsprings]=$'\U2668\UFE0F'
+emoji[hot_springs_unqualified]=$'\U2668'
+emoji[carousel_horse]=$'\U1F3A0'
+emoji[ferris_wheel]=$'\U1F3A1'
+emoji[roller_coaster]=$'\U1F3A2'
+emoji[barber_pole]=$'\U1F488'
+emoji[barber]=$'\U1F488'
+emoji[circus_tent]=$'\U1F3AA'
+emoji[locomotive]=$'\U1F682'
+emoji[steam_locomotive]=$'\U1F682'
+emoji[railway_car]=$'\U1F683'
+emoji[high_speed_train]=$'\U1F684'
+emoji[bullettrain_side]=$'\U1F684'
+emoji[bullet_train]=$'\U1F685'
+emoji[bullettrain_front]=$'\U1F685'
+emoji[bullet_train_1]=$'\U1F686'
+emoji[train2]=$'\U1F686'
+emoji[metro]=$'\U1F687'
+emoji[light_rail]=$'\U1F688'
+emoji[station]=$'\U1F689'
+emoji[tram]=$'\U1F68A'
+emoji[monorail]=$'\U1F69D'
+emoji[mountain_railway]=$'\U1F69E'
+emoji[tram_car]=$'\U1F68B'
+emoji[train]=$'\U1F68B'
+emoji[bus]=$'\U1F68C'
+emoji[oncoming_bus]=$'\U1F68D'
+emoji[trolleybus]=$'\U1F68E'
+emoji[minibus]=$'\U1F690'
+emoji[ambulance]=$'\U1F691'
+emoji[fire_engine]=$'\U1F692'
+emoji[police_car]=$'\U1F693'
+emoji[oncoming_police_car]=$'\U1F694'
+emoji[taxi]=$'\U1F695'
+emoji[oncoming_taxi]=$'\U1F696'
+emoji[automobile]=$'\U1F697'
+emoji[car]=$'\U1F697'
+emoji[red_car]=$'\U1F697'
+emoji[oncoming_automobile]=$'\U1F698'
+emoji[sport_utility_vehicle]=$'\U1F699'
+emoji[blue_car]=$'\U1F699'
+emoji[delivery_truck]=$'\U1F69A'
+emoji[truck]=$'\U1F69A'
+emoji[articulated_lorry]=$'\U1F69B'
+emoji[tractor]=$'\U1F69C'
+emoji[racing_car]=$'\U1F3CE\UFE0F'
+emoji[racing_car_unqualified]=$'\U1F3CE'
+emoji[motorcycle]=$'\U1F3CD\UFE0F'
+emoji[motorcycle_unqualified]=$'\U1F3CD'
+emoji[motor_scooter]=$'\U1F6F5'
+emoji[manual_wheelchair]=$'\U1F9BD'
+emoji[motorized_wheelchair]=$'\U1F9BC'
+emoji[auto_rickshaw]=$'\U1F6FA'
+emoji[bicycle]=$'\U1F6B2'
+emoji[bike]=$'\U1F6B2'
+emoji[kick_scooter]=$'\U1F6F4'
+emoji[skateboard]=$'\U1F6F9'
+emoji[bus_stop]=$'\U1F68F'
+emoji[busstop]=$'\U1F68F'
+emoji[motorway]=$'\U1F6E3\UFE0F'
+emoji[motorway_unqualified]=$'\U1F6E3'
+emoji[railway_track]=$'\U1F6E4\UFE0F'
+emoji[railway_track_unqualified]=$'\U1F6E4'
+emoji[oil_drum]=$'\U1F6E2\UFE0F'
+emoji[oil_drum_unqualified]=$'\U1F6E2'
+emoji[fuel_pump]=$'\U26FD'
+emoji[fuelpump]=$'\U26FD'
+emoji[police_car_light]=$'\U1F6A8'
+emoji[rotating_light]=$'\U1F6A8'
+emoji[horizontal_traffic_light]=$'\U1F6A5'
+emoji[traffic_light]=$'\U1F6A5'
+emoji[vertical_traffic_light]=$'\U1F6A6'
+emoji[stop_sign]=$'\U1F6D1'
+emoji[construction]=$'\U1F6A7'
+emoji[anchor]=$'\U2693'
+emoji[sailboat]=$'\U26F5'
+emoji[boat]=$'\U26F5'
+emoji[canoe]=$'\U1F6F6'
+emoji[speedboat]=$'\U1F6A4'
+emoji[passenger_ship]=$'\U1F6F3\UFE0F'
+emoji[passenger_ship_unqualified]=$'\U1F6F3'
+emoji[ferry]=$'\U26F4\UFE0F'
+emoji[ferry_unqualified]=$'\U26F4'
+emoji[motor_boat]=$'\U1F6E5\UFE0F'
+emoji[motor_boat_unqualified]=$'\U1F6E5'
+emoji[ship]=$'\U1F6A2'
+emoji[airplane]=$'\U2708\UFE0F'
+emoji[airplane_unqualified]=$'\U2708'
+emoji[small_airplane]=$'\U1F6E9\UFE0F'
+emoji[small_airplane_unqualified]=$'\U1F6E9'
+emoji[airplane_departure]=$'\U1F6EB'
+emoji[flight_departure]=$'\U1F6EB'
+emoji[airplane_arrival]=$'\U1F6EC'
+emoji[flight_arrival]=$'\U1F6EC'
+emoji[parachute]=$'\U1FA82'
+emoji[seat]=$'\U1F4BA'
+emoji[helicopter]=$'\U1F681'
+emoji[suspension_railway]=$'\U1F69F'
+emoji[mountain_cableway]=$'\U1F6A0'
+emoji[aerial_tramway]=$'\U1F6A1'
+emoji[satellite]=$'\U1F6F0\UFE0F'
+emoji[satellite_unqualified]=$'\U1F6F0'
+emoji[artificial_satellite]=$'\U1F6F0'
+emoji[rocket]=$'\U1F680'
+emoji[flying_saucer]=$'\U1F6F8'
+emoji[bellhop_bell]=$'\U1F6CE\UFE0F'
+emoji[bellhop_bell_unqualified]=$'\U1F6CE'
+emoji[luggage]=$'\U1F9F3'
+emoji[hourglass_done]=$'\U231B'
+emoji[hourglass]=$'\U231B'
+emoji[hourglass_not_done]=$'\U23F3'
+emoji[hourglass_flowing_sand]=$'\U23F3'
+emoji[watch]=$'\U231A'
+emoji[alarm_clock]=$'\U23F0'
+emoji[stopwatch]=$'\U23F1\UFE0F'
+emoji[stopwatch_unqualified]=$'\U23F1'
+emoji[timer_clock]=$'\U23F2\UFE0F'
+emoji[timer_clock_unqualified]=$'\U23F2'
+emoji[mantelpiece_clock]=$'\U1F570\UFE0F'
+emoji[mantelpiece_clock_unqualified]=$'\U1F570'
+emoji[twelve_o_clock]=$'\U1F55B'
+emoji[clock12]=$'\U1F55B'
+emoji[twelve_thirty]=$'\U1F567'
+emoji[clock1230]=$'\U1F567'
+emoji[one_o_clock]=$'\U1F550'
+emoji[clock1]=$'\U1F550'
+emoji[one_thirty]=$'\U1F55C'
+emoji[clock130]=$'\U1F55C'
+emoji[two_o_clock]=$'\U1F551'
+emoji[clock2]=$'\U1F551'
+emoji[two_thirty]=$'\U1F55D'
+emoji[clock230]=$'\U1F55D'
+emoji[three_o_clock]=$'\U1F552'
+emoji[clock3]=$'\U1F552'
+emoji[three_thirty]=$'\U1F55E'
+emoji[clock330]=$'\U1F55E'
+emoji[four_o_clock]=$'\U1F553'
+emoji[clock4]=$'\U1F553'
+emoji[four_thirty]=$'\U1F55F'
+emoji[clock430]=$'\U1F55F'
+emoji[five_o_clock]=$'\U1F554'
+emoji[clock5]=$'\U1F554'
+emoji[five_thirty]=$'\U1F560'
+emoji[clock530]=$'\U1F560'
+emoji[six_o_clock]=$'\U1F555'
+emoji[clock6]=$'\U1F555'
+emoji[six_thirty]=$'\U1F561'
+emoji[clock630]=$'\U1F561'
+emoji[seven_o_clock]=$'\U1F556'
+emoji[clock7]=$'\U1F556'
+emoji[seven_thirty]=$'\U1F562'
+emoji[clock730]=$'\U1F562'
+emoji[eight_o_clock]=$'\U1F557'
+emoji[clock8]=$'\U1F557'
+emoji[eight_thirty]=$'\U1F563'
+emoji[clock830]=$'\U1F563'
+emoji[nine_o_clock]=$'\U1F558'
+emoji[clock9]=$'\U1F558'
+emoji[nine_thirty]=$'\U1F564'
+emoji[clock930]=$'\U1F564'
+emoji[ten_o_clock]=$'\U1F559'
+emoji[clock10]=$'\U1F559'
+emoji[ten_thirty]=$'\U1F565'
+emoji[clock1030]=$'\U1F565'
+emoji[eleven_o_clock]=$'\U1F55A'
+emoji[clock11]=$'\U1F55A'
+emoji[eleven_thirty]=$'\U1F566'
+emoji[clock1130]=$'\U1F566'
+emoji[new_moon]=$'\U1F311'
+emoji[waxing_crescent_moon]=$'\U1F312'
+emoji[first_quarter_moon]=$'\U1F313'
+emoji[waxing_gibbous_moon]=$'\U1F314'
+emoji[moon]=$'\U1F314'
+emoji[full_moon]=$'\U1F315'
+emoji[waning_gibbous_moon]=$'\U1F316'
+emoji[last_quarter_moon]=$'\U1F317'
+emoji[waning_crescent_moon]=$'\U1F318'
+emoji[waning_crescent_moon_1]=$'\U1F319'
+emoji[crescent_moon]=$'\U1F319'
+emoji[new_moon_face]=$'\U1F31A'
+emoji[new_moon_with_face]=$'\U1F31A'
+emoji[first_quarter_moon_face]=$'\U1F31B'
+emoji[first_quarter_moon_with_face]=$'\U1F31B'
+emoji[last_quarter_moon_face]=$'\U1F31C'
+emoji[last_quarter_moon_with_face]=$'\U1F31C'
+emoji[thermometer]=$'\U1F321\UFE0F'
+emoji[thermometer_unqualified]=$'\U1F321'
+emoji[sun]=$'\U2600\UFE0F'
+emoji[sunny]=$'\U2600\UFE0F'
+emoji[sun_unqualified]=$'\U2600'
+emoji[full_moon_face]=$'\U1F31D'
+emoji[full_moon_with_face]=$'\U1F31D'
+emoji[sun_with_face]=$'\U1F31E'
+emoji[ringed_planet]=$'\U1FA90'
+emoji[star]=$'\U2B50'
+emoji[glowing_star]=$'\U1F31F'
+emoji[star2]=$'\U1F31F'
+emoji[shooting_star]=$'\U1F320'
+emoji[stars]=$'\U1F320'
+emoji[milky_way]=$'\U1F30C'
+emoji[cloud]=$'\U2601\UFE0F'
+emoji[cloud_unqualified]=$'\U2601'
+emoji[sun_behind_cloud]=$'\U26C5'
+emoji[partly_sunny]=$'\U26C5'
+emoji[cloud_with_lightning_and_rain]=$'\U26C8\UFE0F'
+emoji[cloud_with_lightning_and_rain_unqualified]=$'\U26C8'
+emoji[sun_behind_small_cloud]=$'\U1F324\UFE0F'
+emoji[sun_behind_small_cloud_unqualified]=$'\U1F324'
+emoji[sun_behind_large_cloud]=$'\U1F325\UFE0F'
+emoji[sun_behind_large_cloud_unqualified]=$'\U1F325'
+emoji[sun_behind_rain_cloud]=$'\U1F326\UFE0F'
+emoji[sun_behind_rain_cloud_unqualified]=$'\U1F326'
+emoji[cloud_with_rain]=$'\U1F327\UFE0F'
+emoji[cloud_with_rain_unqualified]=$'\U1F327'
+emoji[cloud_with_snow]=$'\U1F328\UFE0F'
+emoji[cloud_with_snow_unqualified]=$'\U1F328'
+emoji[cloud_with_lightning]=$'\U1F329\UFE0F'
+emoji[cloud_with_lightning_unqualified]=$'\U1F329'
+emoji[tornado]=$'\U1F32A\UFE0F'
+emoji[tornado_unqualified]=$'\U1F32A'
+emoji[fog]=$'\U1F32B\UFE0F'
+emoji[fog_unqualified]=$'\U1F32B'
+emoji[wind_face]=$'\U1F32C\UFE0F'
+emoji[wind_face_unqualified]=$'\U1F32C'
+emoji[cyclone]=$'\U1F300'
+emoji[rainbow]=$'\U1F308'
+emoji[closed_umbrella]=$'\U1F302'
+emoji[closed_umbrella_1]=$'\U2602\UFE0F'
+emoji[open_umbrella]=$'\U2602\UFE0F'
+emoji[umbrella_unqualified]=$'\U2602'
+emoji[umbrella_with_rain_drops]=$'\U2614'
+emoji[umbrella]=$'\U2614'
+emoji[umbrella_on_ground]=$'\U26F1\UFE0F'
+emoji[umbrella_on_ground_unqualified]=$'\U26F1'
+emoji[parasol_on_ground]=$'\U26F1'
+emoji[high_voltage]=$'\U26A1'
+emoji[zap]=$'\U26A1'
+emoji[snowflake]=$'\U2744\UFE0F'
+emoji[snowflake_unqualified]=$'\U2744'
+emoji[snowman]=$'\U2603\UFE0F'
+emoji[snowman_with_snow]=$'\U2603\UFE0F'
+emoji[snowman_unqualified]=$'\U2603'
+emoji[snowman_without_snow]=$'\U26C4'
+emoji[comet]=$'\U2604\UFE0F'
+emoji[comet_unqualified]=$'\U2604'
+emoji[fire]=$'\U1F525'
+emoji[droplet]=$'\U1F4A7'
+emoji[water_wave]=$'\U1F30A'
+emoji[ocean]=$'\U1F30A'
+emoji[jack_o_lantern]=$'\U1F383'
+emoji[Christmas_tree]=$'\U1F384'
+emoji[christmas_tree]=$'\U1F384'
+emoji[fireworks]=$'\U1F386'
+emoji[sparkler]=$'\U1F387'
+emoji[firecracker]=$'\U1F9E8'
+emoji[sparkles]=$'\U2728'
+emoji[balloon]=$'\U1F388'
+emoji[party_popper]=$'\U1F389'
+emoji[tada]=$'\U1F389'
+emoji[confetti_ball]=$'\U1F38A'
+emoji[tanabata_tree]=$'\U1F38B'
+emoji[pine_decoration]=$'\U1F38D'
+emoji[bamboo]=$'\U1F38D'
+emoji[Japanese_dolls]=$'\U1F38E'
+emoji[dolls]=$'\U1F38E'
+emoji[carp_streamer]=$'\U1F38F'
+emoji[flags]=$'\U1F38F'
+emoji[wind_chime]=$'\U1F390'
+emoji[moon_viewing_ceremony]=$'\U1F391'
+emoji[rice_scene]=$'\U1F391'
+emoji[red_envelope]=$'\U1F9E7'
+emoji[ribbon]=$'\U1F380'
+emoji[wrapped_gift]=$'\U1F381'
+emoji[gift]=$'\U1F381'
+emoji[reminder_ribbon]=$'\U1F397\UFE0F'
+emoji[reminder_ribbon_unqualified]=$'\U1F397'
+emoji[admission_tickets]=$'\U1F39F\UFE0F'
+emoji[admission_tickets_unqualified]=$'\U1F39F'
+emoji[tickets]=$'\U1F39F'
+emoji[admission_tickets_unqualified_1]=$'\U1F3AB'
+emoji[ticket]=$'\U1F3AB'
+emoji[military_medal]=$'\U1F396\UFE0F'
+emoji[military_medal_unqualified]=$'\U1F396'
+emoji[medal_military]=$'\U1F396'
+emoji[trophy]=$'\U1F3C6'
+emoji[sports_medal]=$'\U1F3C5'
+emoji[medal_sports]=$'\U1F3C5'
+emoji[1st_place_medal]=$'\U1F947'
+emoji[2nd_place_medal]=$'\U1F948'
+emoji[3rd_place_medal]=$'\U1F949'
+emoji[soccer_ball]=$'\U26BD'
+emoji[soccer]=$'\U26BD'
+emoji[baseball]=$'\U26BE'
+emoji[softball]=$'\U1F94E'
+emoji[basketball]=$'\U1F3C0'
+emoji[volleyball]=$'\U1F3D0'
+emoji[american_football]=$'\U1F3C8'
+emoji[football]=$'\U1F3C8'
+emoji[rugby_football]=$'\U1F3C9'
+emoji[tennis]=$'\U1F3BE'
+emoji[flying_disc]=$'\U1F94F'
+emoji[bowling]=$'\U1F3B3'
+emoji[cricket_game]=$'\U1F3CF'
+emoji[field_hockey]=$'\U1F3D1'
+emoji[ice_hockey]=$'\U1F3D2'
+emoji[lacrosse]=$'\U1F94D'
+emoji[ping_pong]=$'\U1F3D3'
+emoji[badminton]=$'\U1F3F8'
+emoji[boxing_glove]=$'\U1F94A'
+emoji[martial_arts_uniform]=$'\U1F94B'
+emoji[goal_net]=$'\U1F945'
+emoji[flag_in_hole]=$'\U26F3'
+emoji[golf]=$'\U26F3'
+emoji[ice_skate]=$'\U26F8\UFE0F'
+emoji[ice_skate_unqualified]=$'\U26F8'
+emoji[fishing_pole]=$'\U1F3A3'
+emoji[fishing_pole_and_fish]=$'\U1F3A3'
+emoji[diving_mask]=$'\U1F93F'
+emoji[running_shirt]=$'\U1F3BD'
+emoji[running_shirt_with_sash]=$'\U1F3BD'
+emoji[skis]=$'\U1F3BF'
+emoji[ski]=$'\U1F3BF'
+emoji[sled]=$'\U1F6F7'
+emoji[curling_stone]=$'\U1F94C'
+emoji[direct_hit]=$'\U1F3AF'
+emoji[dart]=$'\U1F3AF'
+emoji[yo_yo]=$'\U1FA80'
+emoji[kite]=$'\U1FA81'
+emoji[pool_8_ball]=$'\U1F3B1'
+emoji[8ball]=$'\U1F3B1'
+emoji[crystal_ball]=$'\U1F52E'
+emoji[nazar_amulet]=$'\U1F9FF'
+emoji[video_game]=$'\U1F3AE'
+emoji[joystick]=$'\U1F579\UFE0F'
+emoji[joystick_unqualified]=$'\U1F579'
+emoji[slot_machine]=$'\U1F3B0'
+emoji[game_die]=$'\U1F3B2'
+emoji[puzzle_piece]=$'\U1F9E9'
+emoji[jigsaw]=$'\U1F9E9'
+emoji[teddy_bear]=$'\U1F9F8'
+emoji[spade_suit]=$'\U2660\UFE0F'
+emoji[spades]=$'\U2660\UFE0F'
+emoji[spade_suit_unqualified]=$'\U2660'
+emoji[heart_suit]=$'\U2665\UFE0F'
+emoji[hearts]=$'\U2665\UFE0F'
+emoji[heart_suit_unqualified]=$'\U2665'
+emoji[diamond_suit]=$'\U2666\UFE0F'
+emoji[diamonds]=$'\U2666\UFE0F'
+emoji[diamond_suit_unqualified]=$'\U2666'
+emoji[club_suit]=$'\U2663\UFE0F'
+emoji[clubs]=$'\U2663\UFE0F'
+emoji[club_suit_unqualified]=$'\U2663'
+emoji[chess_pawn]=$'\U265F\UFE0F'
+emoji[chess_pawn_unqualified]=$'\U265F'
+emoji[joker]=$'\U1F0CF'
+emoji[black_joker]=$'\U1F0CF'
+emoji[mahjong_red_dragon]=$'\U1F004'
+emoji[mahjong]=$'\U1F004'
+emoji[flower_playing_cards]=$'\U1F3B4'
+emoji[performing_arts]=$'\U1F3AD'
+emoji[framed_picture]=$'\U1F5BC\UFE0F'
+emoji[framed_picture_unqualified]=$'\U1F5BC'
+emoji[artist_palette]=$'\U1F3A8'
+emoji[art]=$'\U1F3A8'
+emoji[thread]=$'\U1F9F5'
+emoji[yarn]=$'\U1F9F6'
+emoji[glasses]=$'\U1F453'
+emoji[eyeglasses]=$'\U1F453'
+emoji[sunglasses]=$'\U1F576\UFE0F'
+emoji[sunglasses_unqualified]=$'\U1F576'
+emoji[dark_sunglasses]=$'\U1F576'
+emoji[goggles]=$'\U1F97D'
+emoji[lab_coat]=$'\U1F97C'
+emoji[safety_vest]=$'\U1F9BA'
+emoji[necktie]=$'\U1F454'
+emoji[t_shirt]=$'\U1F455'
+emoji[shirt]=$'\U1F455'
+emoji[tshirt]=$'\U1F455'
+emoji[jeans]=$'\U1F456'
+emoji[scarf]=$'\U1F9E3'
+emoji[gloves]=$'\U1F9E4'
+emoji[coat]=$'\U1F9E5'
+emoji[socks]=$'\U1F9E6'
+emoji[dress]=$'\U1F457'
+emoji[kimono]=$'\U1F458'
+emoji[sari]=$'\U1F97B'
+emoji[one_piece_swimsuit]=$'\U1FA71'
+emoji[swim_brief]=$'\U1FA72'
+emoji[shorts]=$'\U1FA73'
+emoji[bikini]=$'\U1F459'
+emoji[woman_s_clothes]=$'\U1F45A'
+emoji[womans_clothes]=$'\U1F45A'
+emoji[purse]=$'\U1F45B'
+emoji[handbag]=$'\U1F45C'
+emoji[clutch_bag]=$'\U1F45D'
+emoji[pouch]=$'\U1F45D'
+emoji[shopping_bags]=$'\U1F6CD\UFE0F'
+emoji[shopping_bags_unqualified]=$'\U1F6CD'
+emoji[shopping]=$'\U1F6CD'
+emoji[backpack]=$'\U1F392'
+emoji[school_satchel]=$'\U1F392'
+emoji[man_s_shoe]=$'\U1F45E'
+emoji[mans_shoe]=$'\U1F45E'
+emoji[shoe]=$'\U1F45E'
+emoji[running_shoe]=$'\U1F45F'
+emoji[athletic_shoe]=$'\U1F45F'
+emoji[hiking_boot]=$'\U1F97E'
+emoji[flat_shoe]=$'\U1F97F'
+emoji[high_heeled_shoe]=$'\U1F460'
+emoji[high_heel]=$'\U1F460'
+emoji[woman_s_sandal]=$'\U1F461'
+emoji[sandal]=$'\U1F461'
+emoji[ballet_shoes]=$'\U1FA70'
+emoji[woman_s_boot]=$'\U1F462'
+emoji[boot]=$'\U1F462'
+emoji[crown]=$'\U1F451'
+emoji[woman_s_hat]=$'\U1F452'
+emoji[womans_hat]=$'\U1F452'
+emoji[top_hat]=$'\U1F3A9'
+emoji[tophat]=$'\U1F3A9'
+emoji[graduation_cap]=$'\U1F393'
+emoji[mortar_board]=$'\U1F393'
+emoji[billed_cap]=$'\U1F9E2'
+emoji[rescue_worker_s_helmet]=$'\U26D1\UFE0F'
+emoji[rescue_worker_s_helmet_unqualified]=$'\U26D1'
+emoji[rescue_worker_helmet]=$'\U26D1'
+emoji[prayer_beads]=$'\U1F4FF'
+emoji[lipstick]=$'\U1F484'
+emoji[ring]=$'\U1F48D'
+emoji[gem_stone]=$'\U1F48E'
+emoji[gem]=$'\U1F48E'
+emoji[muted_speaker]=$'\U1F507'
+emoji[mute]=$'\U1F507'
+emoji[speaker_low_volume]=$'\U1F508'
+emoji[speaker]=$'\U1F508'
+emoji[speaker_medium_volume]=$'\U1F509'
+emoji[sound]=$'\U1F509'
+emoji[speaker_high_volume]=$'\U1F50A'
+emoji[loud_sound]=$'\U1F50A'
+emoji[loudspeaker]=$'\U1F4E2'
+emoji[megaphone]=$'\U1F4E3'
+emoji[mega]=$'\U1F4E3'
+emoji[postal_horn]=$'\U1F4EF'
+emoji[bell]=$'\U1F514'
+emoji[bell_with_slash]=$'\U1F515'
+emoji[no_bell]=$'\U1F515'
+emoji[musical_score]=$'\U1F3BC'
+emoji[musical_note]=$'\U1F3B5'
+emoji[musical_notes]=$'\U1F3B6'
+emoji[notes]=$'\U1F3B6'
+emoji[studio_microphone]=$'\U1F399\UFE0F'
+emoji[studio_microphone_unqualified]=$'\U1F399'
+emoji[level_slider]=$'\U1F39A\UFE0F'
+emoji[level_slider_unqualified]=$'\U1F39A'
+emoji[control_knobs]=$'\U1F39B\UFE0F'
+emoji[control_knobs_unqualified]=$'\U1F39B'
+emoji[microphone]=$'\U1F3A4'
+emoji[headphone]=$'\U1F3A7'
+emoji[headphones]=$'\U1F3A7'
+emoji[radio]=$'\U1F4FB'
+emoji[saxophone]=$'\U1F3B7'
+emoji[guitar]=$'\U1F3B8'
+emoji[musical_keyboard]=$'\U1F3B9'
+emoji[trumpet]=$'\U1F3BA'
+emoji[violin]=$'\U1F3BB'
+emoji[banjo]=$'\U1FA95'
+emoji[drum]=$'\U1F941'
+emoji[mobile_phone]=$'\U1F4F1'
+emoji[iphone]=$'\U1F4F1'
+emoji[mobile_phone_with_arrow]=$'\U1F4F2'
+emoji[calling]=$'\U1F4F2'
+emoji[telephone]=$'\U260E\UFE0F'
+emoji[phone]=$'\U260E\UFE0F'
+emoji[telephone_unqualified]=$'\U260E'
+emoji[telephone_receiver]=$'\U1F4DE'
+emoji[pager]=$'\U1F4DF'
+emoji[fax_machine]=$'\U1F4E0'
+emoji[fax]=$'\U1F4E0'
+emoji[battery]=$'\U1F50B'
+emoji[electric_plug]=$'\U1F50C'
+emoji[laptop_computer]=$'\U1F4BB'
+emoji[computer]=$'\U1F4BB'
+emoji[desktop_computer]=$'\U1F5A5\UFE0F'
+emoji[desktop_computer_unqualified]=$'\U1F5A5'
+emoji[printer]=$'\U1F5A8\UFE0F'
+emoji[printer_unqualified]=$'\U1F5A8'
+emoji[keyboard]=$'\U2328\UFE0F'
+emoji[keyboard_unqualified]=$'\U2328'
+emoji[computer_mouse]=$'\U1F5B1\UFE0F'
+emoji[computer_mouse_unqualified]=$'\U1F5B1'
+emoji[trackball]=$'\U1F5B2\UFE0F'
+emoji[trackball_unqualified]=$'\U1F5B2'
+emoji[computer_disk]=$'\U1F4BD'
+emoji[minidisc]=$'\U1F4BD'
+emoji[floppy_disk]=$'\U1F4BE'
+emoji[optical_disk]=$'\U1F4BF'
+emoji[cd]=$'\U1F4BF'
+emoji[dvd]=$'\U1F4C0'
+emoji[abacus]=$'\U1F9EE'
+emoji[movie_camera]=$'\U1F3A5'
+emoji[film_frames]=$'\U1F39E\UFE0F'
+emoji[film_frames_unqualified]=$'\U1F39E'
+emoji[film_strip]=$'\U1F39E'
+emoji[film_projector]=$'\U1F4FD\UFE0F'
+emoji[film_projector_unqualified]=$'\U1F4FD'
+emoji[clapper_board]=$'\U1F3AC'
+emoji[clapper]=$'\U1F3AC'
+emoji[television]=$'\U1F4FA'
+emoji[tv]=$'\U1F4FA'
+emoji[camera]=$'\U1F4F7'
+emoji[camera_with_flash]=$'\U1F4F8'
+emoji[camera_flash]=$'\U1F4F8'
+emoji[video_camera]=$'\U1F4F9'
+emoji[videocassette]=$'\U1F4FC'
+emoji[vhs]=$'\U1F4FC'
+emoji[magnifying_glass_tilted_left]=$'\U1F50D'
+emoji[mag]=$'\U1F50D'
+emoji[magnifying_glass_tilted_right]=$'\U1F50E'
+emoji[mag_right]=$'\U1F50E'
+emoji[candle]=$'\U1F56F\UFE0F'
+emoji[candle_unqualified]=$'\U1F56F'
+emoji[light_bulb]=$'\U1F4A1'
+emoji[bulb]=$'\U1F4A1'
+emoji[flashlight]=$'\U1F526'
+emoji[red_paper_lantern]=$'\U1F3EE'
+emoji[izakaya_lantern]=$'\U1F3EE'
+emoji[lantern]=$'\U1F3EE'
+emoji[diya_lamp]=$'\U1FA94'
+emoji[notebook_with_decorative_cover]=$'\U1F4D4'
+emoji[closed_book]=$'\U1F4D5'
+emoji[open_book]=$'\U1F4D6'
+emoji[book]=$'\U1F4D6'
+emoji[green_book]=$'\U1F4D7'
+emoji[blue_book]=$'\U1F4D8'
+emoji[orange_book]=$'\U1F4D9'
+emoji[books]=$'\U1F4DA'
+emoji[notebook]=$'\U1F4D3'
+emoji[ledger]=$'\U1F4D2'
+emoji[page_with_curl]=$'\U1F4C3'
+emoji[scroll]=$'\U1F4DC'
+emoji[page_facing_up]=$'\U1F4C4'
+emoji[newspaper]=$'\U1F4F0'
+emoji[rolled_up_newspaper]=$'\U1F5DE\UFE0F'
+emoji[rolled_up_newspaper_unqualified]=$'\U1F5DE'
+emoji[newspaper_roll]=$'\U1F5DE'
+emoji[bookmark_tabs]=$'\U1F4D1'
+emoji[bookmark_tabs_1]=$'\U1F516'
+emoji[bookmark]=$'\U1F516'
+emoji[label]=$'\U1F3F7\UFE0F'
+emoji[label_unqualified]=$'\U1F3F7'
+emoji[money_bag]=$'\U1F4B0'
+emoji[moneybag]=$'\U1F4B0'
+emoji[yen_banknote]=$'\U1F4B4'
+emoji[yen]=$'\U1F4B4'
+emoji[dollar_banknote]=$'\U1F4B5'
+emoji[dollar]=$'\U1F4B5'
+emoji[euro_banknote]=$'\U1F4B6'
+emoji[euro]=$'\U1F4B6'
+emoji[pound_banknote]=$'\U1F4B7'
+emoji[pound]=$'\U1F4B7'
+emoji[money_with_wings]=$'\U1F4B8'
+emoji[credit_card]=$'\U1F4B3'
+emoji[receipt]=$'\U1F9FE'
+emoji[chart_increasing_with_yen]=$'\U1F4B9'
+emoji[chart]=$'\U1F4B9'
+emoji[currency_exchange]=$'\U1F4B1'
+emoji[heavy_dollar_sign]=$'\U1F4B2'
+emoji[envelope]=$'\U2709\UFE0F'
+emoji[email]=$'\U2709\UFE0F'
+emoji[envelope_unqualified]=$'\U2709'
+emoji[e_mail]=$'\U1F4E7'
+emoji[e-mail]=$'\U1F4E7'
+emoji[incoming_envelope]=$'\U1F4E8'
+emoji[envelope_with_arrow]=$'\U1F4E9'
+emoji[outbox_tray]=$'\U1F4E4'
+emoji[inbox_tray]=$'\U1F4E5'
+emoji[package]=$'\U1F4E6'
+emoji[closed_mailbox_with_raised_flag]=$'\U1F4EB'
+emoji[mailbox]=$'\U1F4EB'
+emoji[closed_mailbox_with_lowered_flag]=$'\U1F4EA'
+emoji[mailbox_closed]=$'\U1F4EA'
+emoji[open_mailbox_with_raised_flag]=$'\U1F4EC'
+emoji[mailbox_with_mail]=$'\U1F4EC'
+emoji[open_mailbox_with_lowered_flag]=$'\U1F4ED'
+emoji[mailbox_with_no_mail]=$'\U1F4ED'
+emoji[postbox]=$'\U1F4EE'
+emoji[ballot_box_with_ballot]=$'\U1F5F3\UFE0F'
+emoji[ballot_box_with_ballot_unqualified]=$'\U1F5F3'
+emoji[ballot_box]=$'\U1F5F3'
+emoji[pencil]=$'\U270F\UFE0F'
+emoji[pencil2]=$'\U270F\UFE0F'
+emoji[pencil_unqualified]=$'\U270F'
+emoji[black_nib]=$'\U2712\UFE0F'
+emoji[black_nib_unqualified]=$'\U2712'
+emoji[fountain_pen]=$'\U1F58B\UFE0F'
+emoji[fountain_pen_unqualified]=$'\U1F58B'
+emoji[fountain_pen_unqualified_1]=$'\U1F58A\UFE0F'
+emoji[fountain_pen_unqualified_2]=$'\U1F58A'
+emoji[pen]=$'\U1F58A'
+emoji[paintbrush]=$'\U1F58C\UFE0F'
+emoji[paintbrush_unqualified]=$'\U1F58C'
+emoji[crayon]=$'\U1F58D\UFE0F'
+emoji[crayon_unqualified]=$'\U1F58D'
+emoji[memo]=$'\U1F4DD'
+emoji[briefcase]=$'\U1F4BC'
+emoji[file_folder]=$'\U1F4C1'
+emoji[open_file_folder]=$'\U1F4C2'
+emoji[card_index_dividers]=$'\U1F5C2\UFE0F'
+emoji[card_index_dividers_unqualified]=$'\U1F5C2'
+emoji[calendar]=$'\U1F4C5'
+emoji[date]=$'\U1F4C5'
+emoji[tear_off_calendar]=$'\U1F4C6'
+emoji[spiral_notepad]=$'\U1F5D2\UFE0F'
+emoji[spiral_notepad_unqualified]=$'\U1F5D2'
+emoji[spiral_calendar]=$'\U1F5D3\UFE0F'
+emoji[spiral_calendar_unqualified]=$'\U1F5D3'
+emoji[card_index]=$'\U1F4C7'
+emoji[chart_increasing]=$'\U1F4C8'
+emoji[chart_with_upwards_trend]=$'\U1F4C8'
+emoji[chart_decreasing]=$'\U1F4C9'
+emoji[chart_with_downwards_trend]=$'\U1F4C9'
+emoji[bar_chart]=$'\U1F4CA'
+emoji[clipboard]=$'\U1F4CB'
+emoji[pushpin]=$'\U1F4CC'
+emoji[round_pushpin]=$'\U1F4CD'
+emoji[paperclip]=$'\U1F4CE'
+emoji[linked_paperclips]=$'\U1F587\UFE0F'
+emoji[linked_paperclips_unqualified]=$'\U1F587'
+emoji[paperclips]=$'\U1F587'
+emoji[straight_ruler]=$'\U1F4CF'
+emoji[triangular_ruler]=$'\U1F4D0'
+emoji[scissors]=$'\U2702\UFE0F'
+emoji[scissors_unqualified]=$'\U2702'
+emoji[card_file_box]=$'\U1F5C3\UFE0F'
+emoji[card_file_box_unqualified]=$'\U1F5C3'
+emoji[file_cabinet]=$'\U1F5C4\UFE0F'
+emoji[file_cabinet_unqualified]=$'\U1F5C4'
+emoji[wastebasket]=$'\U1F5D1\UFE0F'
+emoji[wastebasket_unqualified]=$'\U1F5D1'
+emoji[locked]=$'\U1F512'
+emoji[lock]=$'\U1F512'
+emoji[unlocked]=$'\U1F513'
+emoji[unlock]=$'\U1F513'
+emoji[locked_with_pen]=$'\U1F50F'
+emoji[lock_with_ink_pen]=$'\U1F50F'
+emoji[locked_with_key]=$'\U1F510'
+emoji[closed_lock_with_key]=$'\U1F510'
+emoji[locked_with_key_1]=$'\U1F511'
+emoji[key]=$'\U1F511'
+emoji[old_key]=$'\U1F5DD\UFE0F'
+emoji[old_key_unqualified]=$'\U1F5DD'
+emoji[hammer]=$'\U1F528'
+emoji[axe]=$'\U1FA93'
+emoji[pick]=$'\U26CF\UFE0F'
+emoji[pick_unqualified]=$'\U26CF'
+emoji[hammer_and_pick]=$'\U2692\UFE0F'
+emoji[hammer_and_pick_unqualified]=$'\U2692'
+emoji[hammer_and_wrench]=$'\U1F6E0\UFE0F'
+emoji[hammer_and_wrench_unqualified]=$'\U1F6E0'
+emoji[dagger]=$'\U1F5E1\UFE0F'
+emoji[dagger_unqualified]=$'\U1F5E1'
+emoji[crossed_swords]=$'\U2694\UFE0F'
+emoji[crossed_swords_unqualified]=$'\U2694'
+emoji[pistol]=$'\U1F52B'
+emoji[gun]=$'\U1F52B'
+emoji[bow_and_arrow]=$'\U1F3F9'
+emoji[shield]=$'\U1F6E1\UFE0F'
+emoji[shield_unqualified]=$'\U1F6E1'
+emoji[wrench]=$'\U1F527'
+emoji[nut_and_bolt]=$'\U1F529'
+emoji[gear]=$'\U2699\UFE0F'
+emoji[gear_unqualified]=$'\U2699'
+emoji[clamp]=$'\U1F5DC\UFE0F'
+emoji[clamp_unqualified]=$'\U1F5DC'
+emoji[balance_scale]=$'\U2696\UFE0F'
+emoji[balance_scale_unqualified]=$'\U2696'
+emoji[probing_cane]=$'\U1F9AF'
+emoji[link]=$'\U1F517'
+emoji[chains]=$'\U26D3\UFE0F'
+emoji[chains_unqualified]=$'\U26D3'
+emoji[toolbox]=$'\U1F9F0'
+emoji[magnet]=$'\U1F9F2'
+emoji[alembic]=$'\U2697\UFE0F'
+emoji[alembic_unqualified]=$'\U2697'
+emoji[test_tube]=$'\U1F9EA'
+emoji[petri_dish]=$'\U1F9EB'
+emoji[dna]=$'\U1F9EC'
+emoji[microscope]=$'\U1F52C'
+emoji[telescope]=$'\U1F52D'
+emoji[satellite_antenna]=$'\U1F4E1'
+emoji[syringe]=$'\U1F489'
+emoji[drop_of_blood]=$'\U1FA78'
+emoji[pill]=$'\U1F48A'
+emoji[adhesive_bandage]=$'\U1FA79'
+emoji[stethoscope]=$'\U1FA7A'
+emoji[door]=$'\U1F6AA'
+emoji[bed]=$'\U1F6CF\UFE0F'
+emoji[bed_unqualified]=$'\U1F6CF'
+emoji[couch_and_lamp]=$'\U1F6CB\UFE0F'
+emoji[couch_and_lamp_unqualified]=$'\U1F6CB'
+emoji[chair]=$'\U1FA91'
+emoji[toilet]=$'\U1F6BD'
+emoji[shower]=$'\U1F6BF'
+emoji[bathtub]=$'\U1F6C1'
+emoji[razor]=$'\U1FA92'
+emoji[lotion_bottle]=$'\U1F9F4'
+emoji[safety_pin]=$'\U1F9F7'
+emoji[broom]=$'\U1F9F9'
+emoji[basket]=$'\U1F9FA'
+emoji[roll_of_paper]=$'\U1F9FB'
+emoji[soap]=$'\U1F9FC'
+emoji[sponge]=$'\U1F9FD'
+emoji[fire_extinguisher]=$'\U1F9EF'
+emoji[shopping_cart]=$'\U1F6D2'
+emoji[cigarette]=$'\U1F6AC'
+emoji[smoking]=$'\U1F6AC'
+emoji[coffin]=$'\U26B0\UFE0F'
+emoji[coffin_unqualified]=$'\U26B0'
+emoji[funeral_urn]=$'\U26B1\UFE0F'
+emoji[funeral_urn_unqualified]=$'\U26B1'
+emoji[moai]=$'\U1F5FF'
+emoji[moyai]=$'\U1F5FF'
+emoji[ATM_sign]=$'\U1F3E7'
+emoji[atm]=$'\U1F3E7'
+emoji[litter_in_bin_sign]=$'\U1F6AE'
+emoji[put_litter_in_its_place]=$'\U1F6AE'
+emoji[potable_water]=$'\U1F6B0'
+emoji[wheelchair_symbol]=$'\U267F'
+emoji[wheelchair]=$'\U267F'
+emoji[men_s_room]=$'\U1F6B9'
+emoji[mens]=$'\U1F6B9'
+emoji[women_s_room]=$'\U1F6BA'
+emoji[womens]=$'\U1F6BA'
+emoji[restroom]=$'\U1F6BB'
+emoji[baby_symbol]=$'\U1F6BC'
+emoji[water_closet]=$'\U1F6BE'
+emoji[wc]=$'\U1F6BE'
+emoji[passport_control]=$'\U1F6C2'
+emoji[customs]=$'\U1F6C3'
+emoji[baggage_claim]=$'\U1F6C4'
+emoji[left_luggage]=$'\U1F6C5'
+emoji[warning]=$'\U26A0\UFE0F'
+emoji[warning_unqualified]=$'\U26A0'
+emoji[children_crossing]=$'\U1F6B8'
+emoji[no_entry]=$'\U26D4'
+emoji[prohibited]=$'\U1F6AB'
+emoji[no_entry_sign]=$'\U1F6AB'
+emoji[no_bicycles]=$'\U1F6B3'
+emoji[no_smoking]=$'\U1F6AD'
+emoji[no_littering]=$'\U1F6AF'
+emoji[do_not_litter]=$'\U1F6AF'
+emoji[non_potable_water]=$'\U1F6B1'
+emoji[non-potable_water]=$'\U1F6B1'
+emoji[no_pedestrians]=$'\U1F6B7'
+emoji[no_mobile_phones]=$'\U1F4F5'
+emoji[no_one_under_eighteen]=$'\U1F51E'
+emoji[underage]=$'\U1F51E'
+emoji[radioactive]=$'\U2622\UFE0F'
+emoji[radioactive_unqualified]=$'\U2622'
+emoji[biohazard]=$'\U2623\UFE0F'
+emoji[biohazard_unqualified]=$'\U2623'
+emoji[up_arrow]=$'\U2B06\UFE0F'
+emoji[arrow_up]=$'\U2B06\UFE0F'
+emoji[up_arrow_unqualified]=$'\U2B06'
+emoji[up_right_arrow]=$'\U2197\UFE0F'
+emoji[arrow_upper_right]=$'\U2197\UFE0F'
+emoji[up_right_arrow_unqualified]=$'\U2197'
+emoji[up_right_arrow_unqualified_1]=$'\U27A1\UFE0F'
+emoji[arrow_right]=$'\U27A1\UFE0F'
+emoji[up_right_arrow_unqualified_2]=$'\U27A1'
+emoji[down_right_arrow]=$'\U2198\UFE0F'
+emoji[arrow_lower_right]=$'\U2198\UFE0F'
+emoji[down_right_arrow_unqualified]=$'\U2198'
+emoji[down_arrow]=$'\U2B07\UFE0F'
+emoji[arrow_down]=$'\U2B07\UFE0F'
+emoji[down_arrow_unqualified]=$'\U2B07'
+emoji[down_left_arrow]=$'\U2199\UFE0F'
+emoji[arrow_lower_left]=$'\U2199\UFE0F'
+emoji[down_left_arrow_unqualified]=$'\U2199'
+emoji[down_left_arrow_unqualified_1]=$'\U2B05\UFE0F'
+emoji[arrow_left]=$'\U2B05\UFE0F'
+emoji[down_left_arrow_unqualified_2]=$'\U2B05'
+emoji[up_left_arrow]=$'\U2196\UFE0F'
+emoji[arrow_upper_left]=$'\U2196\UFE0F'
+emoji[up_left_arrow_unqualified]=$'\U2196'
+emoji[up_down_arrow]=$'\U2195\UFE0F'
+emoji[arrow_up_down]=$'\U2195\UFE0F'
+emoji[up_down_arrow_unqualified]=$'\U2195'
+emoji[left_right_arrow]=$'\U2194\UFE0F'
+emoji[left_right_arrow_unqualified]=$'\U2194'
+emoji[right_arrow_curving_left]=$'\U21A9\UFE0F'
+emoji[leftwards_arrow_with_hook]=$'\U21A9\UFE0F'
+emoji[right_arrow_curving_left_unqualified]=$'\U21A9'
+emoji[left_arrow_curving_right]=$'\U21AA\UFE0F'
+emoji[arrow_right_hook]=$'\U21AA\UFE0F'
+emoji[left_arrow_curving_right_unqualified]=$'\U21AA'
+emoji[right_arrow_curving_up]=$'\U2934\UFE0F'
+emoji[arrow_heading_up]=$'\U2934\UFE0F'
+emoji[right_arrow_curving_up_unqualified]=$'\U2934'
+emoji[right_arrow_curving_down]=$'\U2935\UFE0F'
+emoji[arrow_heading_down]=$'\U2935\UFE0F'
+emoji[right_arrow_curving_down_unqualified]=$'\U2935'
+emoji[clockwise_vertical_arrows]=$'\U1F503'
+emoji[arrows_clockwise]=$'\U1F503'
+emoji[counterclockwise_arrows_button]=$'\U1F504'
+emoji[arrows_counterclockwise]=$'\U1F504'
+emoji[BACK_arrow]=$'\U1F519'
+emoji[back]=$'\U1F519'
+emoji[END_arrow]=$'\U1F51A'
+emoji[end]=$'\U1F51A'
+emoji[ON_arrow]=$'\U1F51B'
+emoji[on]=$'\U1F51B'
+emoji[SOON_arrow]=$'\U1F51C'
+emoji[soon]=$'\U1F51C'
+emoji[TOP_arrow]=$'\U1F51D'
+emoji[top]=$'\U1F51D'
+emoji[place_of_worship]=$'\U1F6D0'
+emoji[atom_symbol]=$'\U269B\UFE0F'
+emoji[atom_symbol_unqualified]=$'\U269B'
+emoji[atom_symbol_unqualified_1]=$'\U1F549\UFE0F'
+emoji[om_unqualified]=$'\U1F549'
+emoji[om]=$'\U1F549'
+emoji[star_of_David]=$'\U2721\UFE0F'
+emoji[star_of_david]=$'\U2721\UFE0F'
+emoji[star_of_David_unqualified]=$'\U2721'
+emoji[wheel_of_dharma]=$'\U2638\UFE0F'
+emoji[wheel_of_dharma_unqualified]=$'\U2638'
+emoji[yin_yang]=$'\U262F\UFE0F'
+emoji[yin_yang_unqualified]=$'\U262F'
+emoji[latin_cross]=$'\U271D\UFE0F'
+emoji[latin_cross_unqualified]=$'\U271D'
+emoji[orthodox_cross]=$'\U2626\UFE0F'
+emoji[orthodox_cross_unqualified]=$'\U2626'
+emoji[star_and_crescent]=$'\U262A\UFE0F'
+emoji[star_and_crescent_unqualified]=$'\U262A'
+emoji[peace_symbol]=$'\U262E\UFE0F'
+emoji[peace_symbol_unqualified]=$'\U262E'
+emoji[menorah]=$'\U1F54E'
+emoji[dotted_six_pointed_star]=$'\U1F52F'
+emoji[six_pointed_star]=$'\U1F52F'
+emoji[Aries]=$'\U2648'
+emoji[aries]=$'\U2648'
+emoji[Taurus]=$'\U2649'
+emoji[taurus]=$'\U2649'
+emoji[Gemini]=$'\U264A'
+emoji[gemini]=$'\U264A'
+emoji[Cancer]=$'\U264B'
+emoji[cancer]=$'\U264B'
+emoji[Leo]=$'\U264C'
+emoji[leo]=$'\U264C'
+emoji[Virgo]=$'\U264D'
+emoji[virgo]=$'\U264D'
+emoji[Libra]=$'\U264E'
+emoji[libra]=$'\U264E'
+emoji[Scorpio]=$'\U264F'
+emoji[scorpius]=$'\U264F'
+emoji[Sagittarius]=$'\U2650'
+emoji[sagittarius]=$'\U2650'
+emoji[Capricorn]=$'\U2651'
+emoji[capricorn]=$'\U2651'
+emoji[Aquarius]=$'\U2652'
+emoji[aquarius]=$'\U2652'
+emoji[Pisces]=$'\U2653'
+emoji[pisces]=$'\U2653'
+emoji[Ophiuchus]=$'\U26CE'
+emoji[ophiuchus]=$'\U26CE'
+emoji[shuffle_tracks_button]=$'\U1F500'
+emoji[twisted_rightwards_arrows]=$'\U1F500'
+emoji[repeat_button]=$'\U1F501'
+emoji[repeat]=$'\U1F501'
+emoji[repeat_single_button]=$'\U1F502'
+emoji[repeat_one]=$'\U1F502'
+emoji[play_button]=$'\U25B6\UFE0F'
+emoji[arrow_forward]=$'\U25B6\UFE0F'
+emoji[play_button_unqualified]=$'\U25B6'
+emoji[fast_forward_button]=$'\U23E9'
+emoji[fast_forward]=$'\U23E9'
+emoji[next_track_button]=$'\U23ED\UFE0F'
+emoji[next_track_button_unqualified]=$'\U23ED'
+emoji[play_or_pause_button]=$'\U23EF\UFE0F'
+emoji[play_or_pause_button_unqualified]=$'\U23EF'
+emoji[reverse_button]=$'\U25C0\UFE0F'
+emoji[arrow_backward]=$'\U25C0\UFE0F'
+emoji[reverse_button_unqualified]=$'\U25C0'
+emoji[fast_reverse_button]=$'\U23EA'
+emoji[rewind]=$'\U23EA'
+emoji[last_track_button]=$'\U23EE\UFE0F'
+emoji[last_track_button_unqualified]=$'\U23EE'
+emoji[previous_track_button]=$'\U23EE'
+emoji[upwards_button]=$'\U1F53C'
+emoji[arrow_up_small]=$'\U1F53C'
+emoji[fast_up_button]=$'\U23EB'
+emoji[arrow_double_up]=$'\U23EB'
+emoji[downwards_button]=$'\U1F53D'
+emoji[arrow_down_small]=$'\U1F53D'
+emoji[fast_down_button]=$'\U23EC'
+emoji[arrow_double_down]=$'\U23EC'
+emoji[pause_button]=$'\U23F8\UFE0F'
+emoji[pause_button_unqualified]=$'\U23F8'
+emoji[stop_button]=$'\U23F9\UFE0F'
+emoji[stop_button_unqualified]=$'\U23F9'
+emoji[record_button]=$'\U23FA\UFE0F'
+emoji[record_button_unqualified]=$'\U23FA'
+emoji[eject_button]=$'\U23CF\UFE0F'
+emoji[eject_button_unqualified]=$'\U23CF'
+emoji[cinema]=$'\U1F3A6'
+emoji[dim_button]=$'\U1F505'
+emoji[low_brightness]=$'\U1F505'
+emoji[bright_button]=$'\U1F506'
+emoji[high_brightness]=$'\U1F506'
+emoji[antenna_bars]=$'\U1F4F6'
+emoji[signal_strength]=$'\U1F4F6'
+emoji[vibration_mode]=$'\U1F4F3'
+emoji[mobile_phone_off]=$'\U1F4F4'
+emoji[female_sign]=$'\U2640\UFE0F'
+emoji[female_sign_unqualified]=$'\U2640'
+emoji[female_sign_unqualified_1]=$'\U2642\UFE0F'
+emoji[male_sign]=$'\U2642\UFE0F'
+emoji[female_sign_unqualified_2]=$'\U2642'
+emoji[medical_symbol]=$'\U2695\UFE0F'
+emoji[medical_symbol_unqualified]=$'\U2695'
+emoji[infinity]=$'\U267E\UFE0F'
+emoji[infinity_unqualified]=$'\U267E'
+emoji[recycling_symbol]=$'\U267B\UFE0F'
+emoji[recycle]=$'\U267B\UFE0F'
+emoji[recycling_symbol_unqualified]=$'\U267B'
+emoji[fleur_de_lis]=$'\U269C\UFE0F'
+emoji[fleur_de_lis_unqualified]=$'\U269C'
+emoji[trident_emblem]=$'\U1F531'
+emoji[trident]=$'\U1F531'
+emoji[name_badge]=$'\U1F4DB'
+emoji[Japanese_symbol_for_beginner]=$'\U1F530'
+emoji[beginner]=$'\U1F530'
+emoji[hollow_red_circle]=$'\U2B55'
+emoji[o]=$'\U2B55'
+emoji[check_mark_button]=$'\U2705'
+emoji[white_check_mark]=$'\U2705'
+emoji[check_box_with_check]=$'\U2611\UFE0F'
+emoji[ballot_box_with_check]=$'\U2611\UFE0F'
+emoji[check_box_with_check_unqualified]=$'\U2611'
+emoji[check_mark]=$'\U2714\UFE0F'
+emoji[heavy_check_mark]=$'\U2714\UFE0F'
+emoji[check_mark_unqualified]=$'\U2714'
+emoji[multiplication_sign]=$'\U2716\UFE0F'
+emoji[heavy_multiplication_x]=$'\U2716\UFE0F'
+emoji[multiplication_sign_unqualified]=$'\U2716'
+emoji[cross_mark]=$'\U274C'
+emoji[x]=$'\U274C'
+emoji[cross_mark_button]=$'\U274E'
+emoji[negative_squared_cross_mark]=$'\U274E'
+emoji[plus_sign]=$'\U2795'
+emoji[heavy_plus_sign]=$'\U2795'
+emoji[minus_sign]=$'\U2796'
+emoji[heavy_minus_sign]=$'\U2796'
+emoji[division_sign]=$'\U2797'
+emoji[heavy_division_sign]=$'\U2797'
+emoji[curly_loop]=$'\U27B0'
+emoji[double_curly_loop]=$'\U27BF'
+emoji[loop]=$'\U27BF'
+emoji[part_alternation_mark]=$'\U303D\UFE0F'
+emoji[part_alternation_mark_unqualified]=$'\U303D'
+emoji[eight_spoked_asterisk]=$'\U2733\UFE0F'
+emoji[eight_spoked_asterisk_unqualified]=$'\U2733'
+emoji[eight_pointed_star]=$'\U2734\UFE0F'
+emoji[eight_pointed_black_star]=$'\U2734\UFE0F'
+emoji[eight_pointed_star_unqualified]=$'\U2734'
+emoji[sparkle]=$'\U2747\UFE0F'
+emoji[sparkle_unqualified]=$'\U2747'
+emoji[double_exclamation_mark]=$'\U203C\UFE0F'
+emoji[bangbang]=$'\U203C\UFE0F'
+emoji[double_exclamation_mark_unqualified]=$'\U203C'
+emoji[exclamation_question_mark]=$'\U2049\UFE0F'
+emoji[interrobang]=$'\U2049\UFE0F'
+emoji[exclamation_question_mark_unqualified]=$'\U2049'
+emoji[exclamation_question_mark_unqualified_1]=$'\U2753'
+emoji[question]=$'\U2753'
+emoji[white_question_mark]=$'\U2754'
+emoji[grey_question]=$'\U2754'
+emoji[white_exclamation_mark]=$'\U2755'
+emoji[grey_exclamation]=$'\U2755'
+emoji[white_exclamation_mark_1]=$'\U2757'
+emoji[exclamation]=$'\U2757'
+emoji[heavy_exclamation_mark]=$'\U2757'
+emoji[wavy_dash]=$'\U3030\UFE0F'
+emoji[wavy_dash_unqualified]=$'\U3030'
+emoji[copyright]=$'\U00A9\UFE0F'
+emoji[copyright_unqualified]=$'\U00A9'
+emoji[registered]=$'\U00AE\UFE0F'
+emoji[registered_unqualified]=$'\U00AE'
+emoji[trade_mark]=$'\U2122\UFE0F'
+emoji[tm]=$'\U2122\UFE0F'
+emoji[trade_mark_unqualified]=$'\U2122'
+emoji[keycap_#]=$'\U0023\UFE0F\U20E3'
+emoji[hash]=$'\U0023\UFE0F\U20E3'
+emoji[keycap_#_unqualified]=$'\U0023\U20E3'
+emoji[keycap_*]=$'\U002A\UFE0F\U20E3'
+emoji[asterisk]=$'\U002A\UFE0F\U20E3'
+emoji[keycap_*_unqualified]=$'\U002A\U20E3'
+emoji[keycap_0]=$'\U0030\UFE0F\U20E3'
+emoji[zero]=$'\U0030\UFE0F\U20E3'
+emoji[keycap_0_unqualified]=$'\U0030\U20E3'
+emoji[keycap_1]=$'\U0031\UFE0F\U20E3'
+emoji[one]=$'\U0031\UFE0F\U20E3'
+emoji[keycap_1_unqualified]=$'\U0031\U20E3'
+emoji[keycap_2]=$'\U0032\UFE0F\U20E3'
+emoji[two]=$'\U0032\UFE0F\U20E3'
+emoji[keycap_2_unqualified]=$'\U0032\U20E3'
+emoji[keycap_3]=$'\U0033\UFE0F\U20E3'
+emoji[three]=$'\U0033\UFE0F\U20E3'
+emoji[keycap_3_unqualified]=$'\U0033\U20E3'
+emoji[keycap_4]=$'\U0034\UFE0F\U20E3'
+emoji[four]=$'\U0034\UFE0F\U20E3'
+emoji[keycap_4_unqualified]=$'\U0034\U20E3'
+emoji[keycap_5]=$'\U0035\UFE0F\U20E3'
+emoji[five]=$'\U0035\UFE0F\U20E3'
+emoji[keycap_5_unqualified]=$'\U0035\U20E3'
+emoji[keycap_6]=$'\U0036\UFE0F\U20E3'
+emoji[six]=$'\U0036\UFE0F\U20E3'
+emoji[keycap_6_unqualified]=$'\U0036\U20E3'
+emoji[keycap_7]=$'\U0037\UFE0F\U20E3'
+emoji[seven]=$'\U0037\UFE0F\U20E3'
+emoji[keycap_7_unqualified]=$'\U0037\U20E3'
+emoji[keycap_8]=$'\U0038\UFE0F\U20E3'
+emoji[eight]=$'\U0038\UFE0F\U20E3'
+emoji[keycap_8_unqualified]=$'\U0038\U20E3'
+emoji[keycap_9]=$'\U0039\UFE0F\U20E3'
+emoji[nine]=$'\U0039\UFE0F\U20E3'
+emoji[keycap_9_unqualified]=$'\U0039\U20E3'
+emoji[keycap_10]=$'\U1F51F'
+emoji[keycap_ten]=$'\U1F51F'
+emoji[input_latin_uppercase]=$'\U1F520'
+emoji[capital_abcd]=$'\U1F520'
+emoji[input_latin_lowercase]=$'\U1F521'
+emoji[abcd]=$'\U1F521'
+emoji[input_numbers]=$'\U1F522'
+emoji[1234]=$'\U1F522'
+emoji[input_symbols]=$'\U1F523'
+emoji[symbols]=$'\U1F523'
+emoji[input_latin_letters]=$'\U1F524'
+emoji[abc]=$'\U1F524'
+emoji[A_button_blood_type_]=$'\U1F170\UFE0F'
+emoji[a]=$'\U1F170\UFE0F'
+emoji[A_button_blood_type__unqualified]=$'\U1F170'
+emoji[AB_button_blood_type_]=$'\U1F18E'
+emoji[ab]=$'\U1F18E'
+emoji[AB_button_blood_type__1]=$'\U1F171\UFE0F'
+emoji[b]=$'\U1F171\UFE0F'
+emoji[B_button_blood_type__unqualified]=$'\U1F171'
+emoji[CL_button]=$'\U1F191'
+emoji[cl]=$'\U1F191'
+emoji[COOL_button]=$'\U1F192'
+emoji[cool]=$'\U1F192'
+emoji[FREE_button]=$'\U1F193'
+emoji[free]=$'\U1F193'
+emoji[information]=$'\U2139\UFE0F'
+emoji[information_source]=$'\U2139\UFE0F'
+emoji[information_unqualified]=$'\U2139'
+emoji[ID_button]=$'\U1F194'
+emoji[id]=$'\U1F194'
+emoji[circled_M]=$'\U24C2\UFE0F'
+emoji[m]=$'\U24C2\UFE0F'
+emoji[circled_M_unqualified]=$'\U24C2'
+emoji[NEW_button]=$'\U1F195'
+emoji[new]=$'\U1F195'
+emoji[NG_button]=$'\U1F196'
+emoji[ng]=$'\U1F196'
+emoji[O_button_blood_type_]=$'\U1F17E\UFE0F'
+emoji[o2]=$'\U1F17E\UFE0F'
+emoji[O_button_blood_type__unqualified]=$'\U1F17E'
+emoji[OK_button]=$'\U1F197'
+emoji[ok]=$'\U1F197'
+emoji[P_button]=$'\U1F17F\UFE0F'
+emoji[parking]=$'\U1F17F\UFE0F'
+emoji[P_button_unqualified]=$'\U1F17F'
+emoji[SOS_button]=$'\U1F198'
+emoji[sos]=$'\U1F198'
+emoji[UP_button]=$'\U1F199'
+emoji[up]=$'\U1F199'
+emoji[VS_button]=$'\U1F19A'
+emoji[vs]=$'\U1F19A'
+emoji[Japanese_here_button]=$'\U1F201'
+emoji[koko]=$'\U1F201'
+emoji[Japanese_service_charge_button]=$'\U1F202\UFE0F'
+emoji[sa]=$'\U1F202\UFE0F'
+emoji[Japanese_service_charge_button_unqualified]=$'\U1F202'
+emoji[Japanese_monthly_amount_button]=$'\U1F237\UFE0F'
+emoji[u6708]=$'\U1F237\UFE0F'
+emoji[Japanese_monthly_amount_button_unqualified]=$'\U1F237'
+emoji[Japanese_not_free_of_charge_button]=$'\U1F236'
+emoji[u6709]=$'\U1F236'
+emoji[Japanese_reserved_button]=$'\U1F22F'
+emoji[u6307]=$'\U1F22F'
+emoji[Japanese_bargain_button]=$'\U1F250'
+emoji[ideograph_advantage]=$'\U1F250'
+emoji[Japanese_discount_button]=$'\U1F239'
+emoji[u5272]=$'\U1F239'
+emoji[Japanese_free_of_charge_button]=$'\U1F21A'
+emoji[u7121]=$'\U1F21A'
+emoji[Japanese_prohibited_button]=$'\U1F232'
+emoji[u7981]=$'\U1F232'
+emoji[Japanese_acceptable_button]=$'\U1F251'
+emoji[accept]=$'\U1F251'
+emoji[Japanese_application_button]=$'\U1F238'
+emoji[u7533]=$'\U1F238'
+emoji[Japanese_passing_grade_button]=$'\U1F234'
+emoji[u5408]=$'\U1F234'
+emoji[Japanese_vacancy_button]=$'\U1F233'
+emoji[u7a7a]=$'\U1F233'
+emoji[Japanese_congratulations_button]=$'\U3297\UFE0F'
+emoji[congratulations]=$'\U3297\UFE0F'
+emoji[Japanese_congratulations_button_unqualified]=$'\U3297'
+emoji[Japanese_secret_button]=$'\U3299\UFE0F'
+emoji[secret]=$'\U3299\UFE0F'
+emoji[Japanese_secret_button_unqualified]=$'\U3299'
+emoji[Japanese_open_for_business_button]=$'\U1F23A'
+emoji[u55b6]=$'\U1F23A'
+emoji[Japanese_no_vacancy_button]=$'\U1F235'
+emoji[u6e80]=$'\U1F235'
+emoji[red_circle]=$'\U1F534'
+emoji[orange_circle]=$'\U1F7E0'
+emoji[yellow_circle]=$'\U1F7E1'
+emoji[green_circle]=$'\U1F7E2'
+emoji[blue_circle]=$'\U1F535'
+emoji[large_blue_circle]=$'\U1F535'
+emoji[purple_circle]=$'\U1F7E3'
+emoji[brown_circle]=$'\U1F7E4'
+emoji[black_circle]=$'\U26AB'
+emoji[white_circle]=$'\U26AA'
+emoji[red_square]=$'\U1F7E5'
+emoji[orange_square]=$'\U1F7E7'
+emoji[yellow_square]=$'\U1F7E8'
+emoji[green_square]=$'\U1F7E9'
+emoji[blue_square]=$'\U1F7E6'
+emoji[purple_square]=$'\U1F7EA'
+emoji[brown_square]=$'\U1F7EB'
+emoji[black_large_square]=$'\U2B1B'
+emoji[white_large_square]=$'\U2B1C'
+emoji[black_medium_square]=$'\U25FC\UFE0F'
+emoji[black_medium_square_unqualified]=$'\U25FC'
+emoji[white_medium_square]=$'\U25FB\UFE0F'
+emoji[white_medium_square_unqualified]=$'\U25FB'
+emoji[black_medium_small_square]=$'\U25FE'
+emoji[white_medium_small_square]=$'\U25FD'
+emoji[black_small_square]=$'\U25AA\UFE0F'
+emoji[black_small_square_unqualified]=$'\U25AA'
+emoji[white_small_square]=$'\U25AB\UFE0F'
+emoji[white_small_square_unqualified]=$'\U25AB'
+emoji[large_orange_diamond]=$'\U1F536'
+emoji[large_blue_diamond]=$'\U1F537'
+emoji[small_orange_diamond]=$'\U1F538'
+emoji[small_blue_diamond]=$'\U1F539'
+emoji[red_triangle_pointed_up]=$'\U1F53A'
+emoji[small_red_triangle]=$'\U1F53A'
+emoji[red_triangle_pointed_down]=$'\U1F53B'
+emoji[small_red_triangle_down]=$'\U1F53B'
+emoji[diamond_with_a_dot]=$'\U1F4A0'
+emoji[diamond_shape_with_a_dot_inside]=$'\U1F4A0'
+emoji[radio_button]=$'\U1F518'
+emoji[white_square_button]=$'\U1F533'
+emoji[black_square_button]=$'\U1F532'
+emoji_flags[chequered_flag]=$'\U1F3C1'
+emoji_flags[checkered_flag]=$'\U1F3C1'
+emoji_flags[triangular_flag]=$'\U1F6A9'
+emoji_flags[triangular_flag_on_post]=$'\U1F6A9'
+emoji_flags[crossed_flags]=$'\U1F38C'
+emoji_flags[black_flag]=$'\U1F3F4'
+emoji_flags[white_flag]=$'\U1F3F3\UFE0F'
+emoji_flags[white_flag_unqualified]=$'\U1F3F3'
+emoji_flags[rainbow_flag]=$'\U1F3F3\UFE0F\U200D\U1F308'
+emoji_flags[rainbow_flag_unqualified]=$'\U1F3F3\U200D\U1F308'
+emoji_flags[pirate_flag]=$'\U1F3F4\U200D\U2620\UFE0F'
+emoji_flags[pirate_flag_minimally]=$'\U1F3F4\U200D\U2620'
+emoji_flags[Ascension_Island]=$'\U1F1E6\U1F1E8'
+emoji_flags[ascension_island]=$'\U1F1E6\U1F1E8'
+emoji_flags[Andorra]=$'\U1F1E6\U1F1E9'
+emoji_flags[AD]=$'\U1F1E6\U1F1E9'
+emoji_flags[AND]=$'\U1F1E6\U1F1E9'
+emoji_flags[andorra]=$'\U1F1E6\U1F1E9'
+emoji_flags[United_Arab_Emirates]=$'\U1F1E6\U1F1EA'
+emoji_flags[AE]=$'\U1F1E6\U1F1EA'
+emoji_flags[ARE]=$'\U1F1E6\U1F1EA'
+emoji_flags[united_arab_emirates]=$'\U1F1E6\U1F1EA'
+emoji_flags[Afghanistan]=$'\U1F1E6\U1F1EB'
+emoji_flags[AF]=$'\U1F1E6\U1F1EB'
+emoji_flags[AFG]=$'\U1F1E6\U1F1EB'
+emoji_flags[afghanistan]=$'\U1F1E6\U1F1EB'
+emoji_flags[Antigua_and_Barbuda]=$'\U1F1E6\U1F1EC'
+emoji_flags[AG]=$'\U1F1E6\U1F1EC'
+emoji_flags[ATG]=$'\U1F1E6\U1F1EC'
+emoji_flags[antigua_barbuda]=$'\U1F1E6\U1F1EC'
+emoji_flags[Anguilla]=$'\U1F1E6\U1F1EE'
+emoji_flags[AI]=$'\U1F1E6\U1F1EE'
+emoji_flags[AIA]=$'\U1F1E6\U1F1EE'
+emoji_flags[anguilla]=$'\U1F1E6\U1F1EE'
+emoji_flags[Albania]=$'\U1F1E6\U1F1F1'
+emoji_flags[AL]=$'\U1F1E6\U1F1F1'
+emoji_flags[ALB]=$'\U1F1E6\U1F1F1'
+emoji_flags[albania]=$'\U1F1E6\U1F1F1'
+emoji_flags[Armenia]=$'\U1F1E6\U1F1F2'
+emoji_flags[AM]=$'\U1F1E6\U1F1F2'
+emoji_flags[ARM]=$'\U1F1E6\U1F1F2'
+emoji_flags[armenia]=$'\U1F1E6\U1F1F2'
+emoji_flags[Angola]=$'\U1F1E6\U1F1F4'
+emoji_flags[AO]=$'\U1F1E6\U1F1F4'
+emoji_flags[AGO]=$'\U1F1E6\U1F1F4'
+emoji_flags[angola]=$'\U1F1E6\U1F1F4'
+emoji_flags[Antarctica]=$'\U1F1E6\U1F1F6'
+emoji_flags[AQ]=$'\U1F1E6\U1F1F6'
+emoji_flags[ATA]=$'\U1F1E6\U1F1F6'
+emoji_flags[antarctica]=$'\U1F1E6\U1F1F6'
+emoji_flags[Argentina]=$'\U1F1E6\U1F1F7'
+emoji_flags[AR]=$'\U1F1E6\U1F1F7'
+emoji_flags[ARG]=$'\U1F1E6\U1F1F7'
+emoji_flags[argentina]=$'\U1F1E6\U1F1F7'
+emoji_flags[American_Samoa]=$'\U1F1E6\U1F1F8'
+emoji_flags[AS]=$'\U1F1E6\U1F1F8'
+emoji_flags[ASM]=$'\U1F1E6\U1F1F8'
+emoji_flags[american_samoa]=$'\U1F1E6\U1F1F8'
+emoji_flags[Austria]=$'\U1F1E6\U1F1F9'
+emoji_flags[AT]=$'\U1F1E6\U1F1F9'
+emoji_flags[AUT]=$'\U1F1E6\U1F1F9'
+emoji_flags[austria]=$'\U1F1E6\U1F1F9'
+emoji_flags[Australia]=$'\U1F1E6\U1F1FA'
+emoji_flags[AU]=$'\U1F1E6\U1F1FA'
+emoji_flags[AUS]=$'\U1F1E6\U1F1FA'
+emoji_flags[australia]=$'\U1F1E6\U1F1FA'
+emoji_flags[Aruba]=$'\U1F1E6\U1F1FC'
+emoji_flags[AW]=$'\U1F1E6\U1F1FC'
+emoji_flags[ABW]=$'\U1F1E6\U1F1FC'
+emoji_flags[aruba]=$'\U1F1E6\U1F1FC'
+emoji_flags[Åland_Islands]=$'\U1F1E6\U1F1FD'
+emoji_flags[AX]=$'\U1F1E6\U1F1FD'
+emoji_flags[ALA]=$'\U1F1E6\U1F1FD'
+emoji_flags[aland_islands]=$'\U1F1E6\U1F1FD'
+emoji_flags[Azerbaijan]=$'\U1F1E6\U1F1FF'
+emoji_flags[AZ]=$'\U1F1E6\U1F1FF'
+emoji_flags[AZE]=$'\U1F1E6\U1F1FF'
+emoji_flags[azerbaijan]=$'\U1F1E6\U1F1FF'
+emoji_flags[Bosnia_and_Herzegovina]=$'\U1F1E7\U1F1E6'
+emoji_flags[BA]=$'\U1F1E7\U1F1E6'
+emoji_flags[BIH]=$'\U1F1E7\U1F1E6'
+emoji_flags[bosnia_herzegovina]=$'\U1F1E7\U1F1E6'
+emoji_flags[Barbados]=$'\U1F1E7\U1F1E7'
+emoji_flags[BB]=$'\U1F1E7\U1F1E7'
+emoji_flags[BRB]=$'\U1F1E7\U1F1E7'
+emoji_flags[barbados]=$'\U1F1E7\U1F1E7'
+emoji_flags[Bangladesh]=$'\U1F1E7\U1F1E9'
+emoji_flags[BD]=$'\U1F1E7\U1F1E9'
+emoji_flags[BGD]=$'\U1F1E7\U1F1E9'
+emoji_flags[bangladesh]=$'\U1F1E7\U1F1E9'
+emoji_flags[Belgium]=$'\U1F1E7\U1F1EA'
+emoji_flags[BE]=$'\U1F1E7\U1F1EA'
+emoji_flags[BEL]=$'\U1F1E7\U1F1EA'
+emoji_flags[belgium]=$'\U1F1E7\U1F1EA'
+emoji_flags[Burkina_Faso]=$'\U1F1E7\U1F1EB'
+emoji_flags[BF]=$'\U1F1E7\U1F1EB'
+emoji_flags[BFA]=$'\U1F1E7\U1F1EB'
+emoji_flags[burkina_faso]=$'\U1F1E7\U1F1EB'
+emoji_flags[Bulgaria]=$'\U1F1E7\U1F1EC'
+emoji_flags[BG]=$'\U1F1E7\U1F1EC'
+emoji_flags[BGR]=$'\U1F1E7\U1F1EC'
+emoji_flags[bulgaria]=$'\U1F1E7\U1F1EC'
+emoji_flags[Bahrain]=$'\U1F1E7\U1F1ED'
+emoji_flags[BH]=$'\U1F1E7\U1F1ED'
+emoji_flags[BHR]=$'\U1F1E7\U1F1ED'
+emoji_flags[bahrain]=$'\U1F1E7\U1F1ED'
+emoji_flags[Burundi]=$'\U1F1E7\U1F1EE'
+emoji_flags[BI]=$'\U1F1E7\U1F1EE'
+emoji_flags[BDI]=$'\U1F1E7\U1F1EE'
+emoji_flags[burundi]=$'\U1F1E7\U1F1EE'
+emoji_flags[Benin]=$'\U1F1E7\U1F1EF'
+emoji_flags[BJ]=$'\U1F1E7\U1F1EF'
+emoji_flags[BEN]=$'\U1F1E7\U1F1EF'
+emoji_flags[benin]=$'\U1F1E7\U1F1EF'
+emoji_flags[St_Barthélemy]=$'\U1F1E7\U1F1F1'
+emoji_flags[BL]=$'\U1F1E7\U1F1F1'
+emoji_flags[BLM]=$'\U1F1E7\U1F1F1'
+emoji_flags[st_barthelemy]=$'\U1F1E7\U1F1F1'
+emoji_flags[Bermuda]=$'\U1F1E7\U1F1F2'
+emoji_flags[BM]=$'\U1F1E7\U1F1F2'
+emoji_flags[BMU]=$'\U1F1E7\U1F1F2'
+emoji_flags[bermuda]=$'\U1F1E7\U1F1F2'
+emoji_flags[Brunei]=$'\U1F1E7\U1F1F3'
+emoji_flags[BN]=$'\U1F1E7\U1F1F3'
+emoji_flags[BRN]=$'\U1F1E7\U1F1F3'
+emoji_flags[brunei]=$'\U1F1E7\U1F1F3'
+emoji_flags[Bolivia]=$'\U1F1E7\U1F1F4'
+emoji_flags[BO]=$'\U1F1E7\U1F1F4'
+emoji_flags[BOL]=$'\U1F1E7\U1F1F4'
+emoji_flags[bolivia]=$'\U1F1E7\U1F1F4'
+emoji_flags[Caribbean_Netherlands]=$'\U1F1E7\U1F1F6'
+emoji_flags[BQ]=$'\U1F1E7\U1F1F6'
+emoji_flags[BES]=$'\U1F1E7\U1F1F6'
+emoji_flags[caribbean_netherlands]=$'\U1F1E7\U1F1F6'
+emoji_flags[Brazil]=$'\U1F1E7\U1F1F7'
+emoji_flags[BR]=$'\U1F1E7\U1F1F7'
+emoji_flags[BRA]=$'\U1F1E7\U1F1F7'
+emoji_flags[brazil]=$'\U1F1E7\U1F1F7'
+emoji_flags[Bahamas]=$'\U1F1E7\U1F1F8'
+emoji_flags[BS]=$'\U1F1E7\U1F1F8'
+emoji_flags[BHS]=$'\U1F1E7\U1F1F8'
+emoji_flags[bahamas]=$'\U1F1E7\U1F1F8'
+emoji_flags[Bhutan]=$'\U1F1E7\U1F1F9'
+emoji_flags[BT]=$'\U1F1E7\U1F1F9'
+emoji_flags[BTN]=$'\U1F1E7\U1F1F9'
+emoji_flags[bhutan]=$'\U1F1E7\U1F1F9'
+emoji_flags[Bouvet_Island]=$'\U1F1E7\U1F1FB'
+emoji_flags[BV]=$'\U1F1E7\U1F1FB'
+emoji_flags[BVT]=$'\U1F1E7\U1F1FB'
+emoji_flags[bouvet_island]=$'\U1F1E7\U1F1FB'
+emoji_flags[Botswana]=$'\U1F1E7\U1F1FC'
+emoji_flags[BW]=$'\U1F1E7\U1F1FC'
+emoji_flags[BWA]=$'\U1F1E7\U1F1FC'
+emoji_flags[botswana]=$'\U1F1E7\U1F1FC'
+emoji_flags[Belarus]=$'\U1F1E7\U1F1FE'
+emoji_flags[BY]=$'\U1F1E7\U1F1FE'
+emoji_flags[BLR]=$'\U1F1E7\U1F1FE'
+emoji_flags[belarus]=$'\U1F1E7\U1F1FE'
+emoji_flags[Belize]=$'\U1F1E7\U1F1FF'
+emoji_flags[BZ]=$'\U1F1E7\U1F1FF'
+emoji_flags[BLZ]=$'\U1F1E7\U1F1FF'
+emoji_flags[belize]=$'\U1F1E7\U1F1FF'
+emoji_flags[Canada]=$'\U1F1E8\U1F1E6'
+emoji_flags[CA]=$'\U1F1E8\U1F1E6'
+emoji_flags[CAN]=$'\U1F1E8\U1F1E6'
+emoji_flags[canada]=$'\U1F1E8\U1F1E6'
+emoji_flags[Cocos_Keeling_Islands]=$'\U1F1E8\U1F1E8'
+emoji_flags[CC]=$'\U1F1E8\U1F1E8'
+emoji_flags[CCK]=$'\U1F1E8\U1F1E8'
+emoji_flags[cocos_islands]=$'\U1F1E8\U1F1E8'
+emoji_flags[Congo__Kinshasa]=$'\U1F1E8\U1F1E9'
+emoji_flags[CD]=$'\U1F1E8\U1F1E9'
+emoji_flags[COD]=$'\U1F1E8\U1F1E9'
+emoji_flags[congo_kinshasa]=$'\U1F1E8\U1F1E9'
+emoji_flags[Central_African_Republic]=$'\U1F1E8\U1F1EB'
+emoji_flags[CF]=$'\U1F1E8\U1F1EB'
+emoji_flags[CAF]=$'\U1F1E8\U1F1EB'
+emoji_flags[central_african_republic]=$'\U1F1E8\U1F1EB'
+emoji_flags[Congo__Brazzaville]=$'\U1F1E8\U1F1EC'
+emoji_flags[CG]=$'\U1F1E8\U1F1EC'
+emoji_flags[COG]=$'\U1F1E8\U1F1EC'
+emoji_flags[congo_brazzaville]=$'\U1F1E8\U1F1EC'
+emoji_flags[Switzerland]=$'\U1F1E8\U1F1ED'
+emoji_flags[CH]=$'\U1F1E8\U1F1ED'
+emoji_flags[CHE]=$'\U1F1E8\U1F1ED'
+emoji_flags[switzerland]=$'\U1F1E8\U1F1ED'
+emoji_flags[Côte_d_Ivoire]=$'\U1F1E8\U1F1EE'
+emoji_flags[CI]=$'\U1F1E8\U1F1EE'
+emoji_flags[CIV]=$'\U1F1E8\U1F1EE'
+emoji_flags[cote_divoire]=$'\U1F1E8\U1F1EE'
+emoji_flags[Cook_Islands]=$'\U1F1E8\U1F1F0'
+emoji_flags[CK]=$'\U1F1E8\U1F1F0'
+emoji_flags[COK]=$'\U1F1E8\U1F1F0'
+emoji_flags[cook_islands]=$'\U1F1E8\U1F1F0'
+emoji_flags[Chile]=$'\U1F1E8\U1F1F1'
+emoji_flags[CL]=$'\U1F1E8\U1F1F1'
+emoji_flags[CHL]=$'\U1F1E8\U1F1F1'
+emoji_flags[chile]=$'\U1F1E8\U1F1F1'
+emoji_flags[Cameroon]=$'\U1F1E8\U1F1F2'
+emoji_flags[CM]=$'\U1F1E8\U1F1F2'
+emoji_flags[CMR]=$'\U1F1E8\U1F1F2'
+emoji_flags[cameroon]=$'\U1F1E8\U1F1F2'
+emoji_flags[China]=$'\U1F1E8\U1F1F3'
+emoji_flags[CN]=$'\U1F1E8\U1F1F3'
+emoji_flags[CHN]=$'\U1F1E8\U1F1F3'
+emoji_flags[cn]=$'\U1F1E8\U1F1F3'
+emoji_flags[Colombia]=$'\U1F1E8\U1F1F4'
+emoji_flags[CO]=$'\U1F1E8\U1F1F4'
+emoji_flags[COL]=$'\U1F1E8\U1F1F4'
+emoji_flags[colombia]=$'\U1F1E8\U1F1F4'
+emoji_flags[Clipperton_Island]=$'\U1F1E8\U1F1F5'
+emoji_flags[clipperton_island]=$'\U1F1E8\U1F1F5'
+emoji_flags[Costa_Rica]=$'\U1F1E8\U1F1F7'
+emoji_flags[CR]=$'\U1F1E8\U1F1F7'
+emoji_flags[CRI]=$'\U1F1E8\U1F1F7'
+emoji_flags[costa_rica]=$'\U1F1E8\U1F1F7'
+emoji_flags[Cuba]=$'\U1F1E8\U1F1FA'
+emoji_flags[CU]=$'\U1F1E8\U1F1FA'
+emoji_flags[CUB]=$'\U1F1E8\U1F1FA'
+emoji_flags[cuba]=$'\U1F1E8\U1F1FA'
+emoji_flags[Cape_Verde]=$'\U1F1E8\U1F1FB'
+emoji_flags[CV]=$'\U1F1E8\U1F1FB'
+emoji_flags[CPV]=$'\U1F1E8\U1F1FB'
+emoji_flags[cape_verde]=$'\U1F1E8\U1F1FB'
+emoji_flags[Curaçao]=$'\U1F1E8\U1F1FC'
+emoji_flags[CW]=$'\U1F1E8\U1F1FC'
+emoji_flags[CUW]=$'\U1F1E8\U1F1FC'
+emoji_flags[curacao]=$'\U1F1E8\U1F1FC'
+emoji_flags[Christmas_Island]=$'\U1F1E8\U1F1FD'
+emoji_flags[CX]=$'\U1F1E8\U1F1FD'
+emoji_flags[CXR]=$'\U1F1E8\U1F1FD'
+emoji_flags[christmas_island]=$'\U1F1E8\U1F1FD'
+emoji_flags[Cyprus]=$'\U1F1E8\U1F1FE'
+emoji_flags[CY]=$'\U1F1E8\U1F1FE'
+emoji_flags[CYP]=$'\U1F1E8\U1F1FE'
+emoji_flags[cyprus]=$'\U1F1E8\U1F1FE'
+emoji_flags[Czechia]=$'\U1F1E8\U1F1FF'
+emoji_flags[CZ]=$'\U1F1E8\U1F1FF'
+emoji_flags[CZE]=$'\U1F1E8\U1F1FF'
+emoji_flags[czech_republic]=$'\U1F1E8\U1F1FF'
+emoji_flags[Germany]=$'\U1F1E9\U1F1EA'
+emoji_flags[DE]=$'\U1F1E9\U1F1EA'
+emoji_flags[DEU]=$'\U1F1E9\U1F1EA'
+emoji_flags[de]=$'\U1F1E9\U1F1EA'
+emoji_flags[Diego_Garcia]=$'\U1F1E9\U1F1EC'
+emoji_flags[diego_garcia]=$'\U1F1E9\U1F1EC'
+emoji_flags[Djibouti]=$'\U1F1E9\U1F1EF'
+emoji_flags[DJ]=$'\U1F1E9\U1F1EF'
+emoji_flags[DJI]=$'\U1F1E9\U1F1EF'
+emoji_flags[djibouti]=$'\U1F1E9\U1F1EF'
+emoji_flags[Denmark]=$'\U1F1E9\U1F1F0'
+emoji_flags[DK]=$'\U1F1E9\U1F1F0'
+emoji_flags[DNK]=$'\U1F1E9\U1F1F0'
+emoji_flags[denmark]=$'\U1F1E9\U1F1F0'
+emoji_flags[Dominica]=$'\U1F1E9\U1F1F2'
+emoji_flags[DM]=$'\U1F1E9\U1F1F2'
+emoji_flags[DMA]=$'\U1F1E9\U1F1F2'
+emoji_flags[dominica]=$'\U1F1E9\U1F1F2'
+emoji_flags[Dominican_Republic]=$'\U1F1E9\U1F1F4'
+emoji_flags[DO]=$'\U1F1E9\U1F1F4'
+emoji_flags[DOM]=$'\U1F1E9\U1F1F4'
+emoji_flags[dominican_republic]=$'\U1F1E9\U1F1F4'
+emoji_flags[Algeria]=$'\U1F1E9\U1F1FF'
+emoji_flags[DZ]=$'\U1F1E9\U1F1FF'
+emoji_flags[DZA]=$'\U1F1E9\U1F1FF'
+emoji_flags[algeria]=$'\U1F1E9\U1F1FF'
+emoji_flags[Ceuta_and_Melilla]=$'\U1F1EA\U1F1E6'
+emoji_flags[ceuta_melilla]=$'\U1F1EA\U1F1E6'
+emoji_flags[Ecuador]=$'\U1F1EA\U1F1E8'
+emoji_flags[EC]=$'\U1F1EA\U1F1E8'
+emoji_flags[ECU]=$'\U1F1EA\U1F1E8'
+emoji_flags[ecuador]=$'\U1F1EA\U1F1E8'
+emoji_flags[Estonia]=$'\U1F1EA\U1F1EA'
+emoji_flags[EE]=$'\U1F1EA\U1F1EA'
+emoji_flags[EST]=$'\U1F1EA\U1F1EA'
+emoji_flags[estonia]=$'\U1F1EA\U1F1EA'
+emoji_flags[Egypt]=$'\U1F1EA\U1F1EC'
+emoji_flags[EG]=$'\U1F1EA\U1F1EC'
+emoji_flags[EGY]=$'\U1F1EA\U1F1EC'
+emoji_flags[egypt]=$'\U1F1EA\U1F1EC'
+emoji_flags[Western_Sahara]=$'\U1F1EA\U1F1ED'
+emoji_flags[EH]=$'\U1F1EA\U1F1ED'
+emoji_flags[ESH]=$'\U1F1EA\U1F1ED'
+emoji_flags[western_sahara]=$'\U1F1EA\U1F1ED'
+emoji_flags[Eritrea]=$'\U1F1EA\U1F1F7'
+emoji_flags[ER]=$'\U1F1EA\U1F1F7'
+emoji_flags[ERI]=$'\U1F1EA\U1F1F7'
+emoji_flags[eritrea]=$'\U1F1EA\U1F1F7'
+emoji_flags[Spain]=$'\U1F1EA\U1F1F8'
+emoji_flags[ES]=$'\U1F1EA\U1F1F8'
+emoji_flags[ESP]=$'\U1F1EA\U1F1F8'
+emoji_flags[es]=$'\U1F1EA\U1F1F8'
+emoji_flags[Ethiopia]=$'\U1F1EA\U1F1F9'
+emoji_flags[ET]=$'\U1F1EA\U1F1F9'
+emoji_flags[ETH]=$'\U1F1EA\U1F1F9'
+emoji_flags[ethiopia]=$'\U1F1EA\U1F1F9'
+emoji_flags[European_Union]=$'\U1F1EA\U1F1FA'
+emoji_flags[eu]=$'\U1F1EA\U1F1FA'
+emoji_flags[european_union]=$'\U1F1EA\U1F1FA'
+emoji_flags[Finland]=$'\U1F1EB\U1F1EE'
+emoji_flags[FI]=$'\U1F1EB\U1F1EE'
+emoji_flags[FIN]=$'\U1F1EB\U1F1EE'
+emoji_flags[finland]=$'\U1F1EB\U1F1EE'
+emoji_flags[Fiji]=$'\U1F1EB\U1F1EF'
+emoji_flags[FJ]=$'\U1F1EB\U1F1EF'
+emoji_flags[FJI]=$'\U1F1EB\U1F1EF'
+emoji_flags[fiji]=$'\U1F1EB\U1F1EF'
+emoji_flags[Falkland_Islands]=$'\U1F1EB\U1F1F0'
+emoji_flags[FK]=$'\U1F1EB\U1F1F0'
+emoji_flags[FLK]=$'\U1F1EB\U1F1F0'
+emoji_flags[falkland_islands]=$'\U1F1EB\U1F1F0'
+emoji_flags[Micronesia]=$'\U1F1EB\U1F1F2'
+emoji_flags[FM]=$'\U1F1EB\U1F1F2'
+emoji_flags[FSM]=$'\U1F1EB\U1F1F2'
+emoji_flags[micronesia]=$'\U1F1EB\U1F1F2'
+emoji_flags[Faroe_Islands]=$'\U1F1EB\U1F1F4'
+emoji_flags[FO]=$'\U1F1EB\U1F1F4'
+emoji_flags[FRO]=$'\U1F1EB\U1F1F4'
+emoji_flags[faroe_islands]=$'\U1F1EB\U1F1F4'
+emoji_flags[France]=$'\U1F1EB\U1F1F7'
+emoji_flags[FR]=$'\U1F1EB\U1F1F7'
+emoji_flags[FRA]=$'\U1F1EB\U1F1F7'
+emoji_flags[fr]=$'\U1F1EB\U1F1F7'
+emoji_flags[Gabon]=$'\U1F1EC\U1F1E6'
+emoji_flags[GA]=$'\U1F1EC\U1F1E6'
+emoji_flags[GAB]=$'\U1F1EC\U1F1E6'
+emoji_flags[gabon]=$'\U1F1EC\U1F1E6'
+emoji_flags[United_Kingdom]=$'\U1F1EC\U1F1E7'
+emoji_flags[GB]=$'\U1F1EC\U1F1E7'
+emoji_flags[GBR]=$'\U1F1EC\U1F1E7'
+emoji_flags[gb]=$'\U1F1EC\U1F1E7'
+emoji_flags[uk]=$'\U1F1EC\U1F1E7'
+emoji_flags[Grenada]=$'\U1F1EC\U1F1E9'
+emoji_flags[GD]=$'\U1F1EC\U1F1E9'
+emoji_flags[GRD]=$'\U1F1EC\U1F1E9'
+emoji_flags[grenada]=$'\U1F1EC\U1F1E9'
+emoji_flags[Georgia]=$'\U1F1EC\U1F1EA'
+emoji_flags[GE]=$'\U1F1EC\U1F1EA'
+emoji_flags[GEO]=$'\U1F1EC\U1F1EA'
+emoji_flags[georgia]=$'\U1F1EC\U1F1EA'
+emoji_flags[French_Guiana]=$'\U1F1EC\U1F1EB'
+emoji_flags[GF]=$'\U1F1EC\U1F1EB'
+emoji_flags[GUF]=$'\U1F1EC\U1F1EB'
+emoji_flags[french_guiana]=$'\U1F1EC\U1F1EB'
+emoji_flags[Guernsey]=$'\U1F1EC\U1F1EC'
+emoji_flags[GG]=$'\U1F1EC\U1F1EC'
+emoji_flags[GGY]=$'\U1F1EC\U1F1EC'
+emoji_flags[guernsey]=$'\U1F1EC\U1F1EC'
+emoji_flags[Ghana]=$'\U1F1EC\U1F1ED'
+emoji_flags[GH]=$'\U1F1EC\U1F1ED'
+emoji_flags[GHA]=$'\U1F1EC\U1F1ED'
+emoji_flags[ghana]=$'\U1F1EC\U1F1ED'
+emoji_flags[Gibraltar]=$'\U1F1EC\U1F1EE'
+emoji_flags[GI]=$'\U1F1EC\U1F1EE'
+emoji_flags[GIB]=$'\U1F1EC\U1F1EE'
+emoji_flags[gibraltar]=$'\U1F1EC\U1F1EE'
+emoji_flags[Greenland]=$'\U1F1EC\U1F1F1'
+emoji_flags[GL]=$'\U1F1EC\U1F1F1'
+emoji_flags[GRL]=$'\U1F1EC\U1F1F1'
+emoji_flags[greenland]=$'\U1F1EC\U1F1F1'
+emoji_flags[Gambia]=$'\U1F1EC\U1F1F2'
+emoji_flags[GM]=$'\U1F1EC\U1F1F2'
+emoji_flags[GMB]=$'\U1F1EC\U1F1F2'
+emoji_flags[gambia]=$'\U1F1EC\U1F1F2'
+emoji_flags[Guinea]=$'\U1F1EC\U1F1F3'
+emoji_flags[GN]=$'\U1F1EC\U1F1F3'
+emoji_flags[GIN]=$'\U1F1EC\U1F1F3'
+emoji_flags[guinea]=$'\U1F1EC\U1F1F3'
+emoji_flags[Guadeloupe]=$'\U1F1EC\U1F1F5'
+emoji_flags[GP]=$'\U1F1EC\U1F1F5'
+emoji_flags[GLP]=$'\U1F1EC\U1F1F5'
+emoji_flags[guadeloupe]=$'\U1F1EC\U1F1F5'
+emoji_flags[Equatorial_Guinea]=$'\U1F1EC\U1F1F6'
+emoji_flags[GQ]=$'\U1F1EC\U1F1F6'
+emoji_flags[GNQ]=$'\U1F1EC\U1F1F6'
+emoji_flags[equatorial_guinea]=$'\U1F1EC\U1F1F6'
+emoji_flags[Greece]=$'\U1F1EC\U1F1F7'
+emoji_flags[GR]=$'\U1F1EC\U1F1F7'
+emoji_flags[GRC]=$'\U1F1EC\U1F1F7'
+emoji_flags[greece]=$'\U1F1EC\U1F1F7'
+emoji_flags[South_Georgia_and_South_Sandwich_Islands]=$'\U1F1EC\U1F1F8'
+emoji_flags[GS]=$'\U1F1EC\U1F1F8'
+emoji_flags[SGS]=$'\U1F1EC\U1F1F8'
+emoji_flags[south_georgia_south_sandwich_islands]=$'\U1F1EC\U1F1F8'
+emoji_flags[Guatemala]=$'\U1F1EC\U1F1F9'
+emoji_flags[GT]=$'\U1F1EC\U1F1F9'
+emoji_flags[GTM]=$'\U1F1EC\U1F1F9'
+emoji_flags[guatemala]=$'\U1F1EC\U1F1F9'
+emoji_flags[Guam]=$'\U1F1EC\U1F1FA'
+emoji_flags[GU]=$'\U1F1EC\U1F1FA'
+emoji_flags[GUM]=$'\U1F1EC\U1F1FA'
+emoji_flags[guam]=$'\U1F1EC\U1F1FA'
+emoji_flags[Guinea_Bissau]=$'\U1F1EC\U1F1FC'
+emoji_flags[GW]=$'\U1F1EC\U1F1FC'
+emoji_flags[GNB]=$'\U1F1EC\U1F1FC'
+emoji_flags[guinea_bissau]=$'\U1F1EC\U1F1FC'
+emoji_flags[Guyana]=$'\U1F1EC\U1F1FE'
+emoji_flags[GY]=$'\U1F1EC\U1F1FE'
+emoji_flags[GUY]=$'\U1F1EC\U1F1FE'
+emoji_flags[guyana]=$'\U1F1EC\U1F1FE'
+emoji_flags[Hong_Kong_SAR_China]=$'\U1F1ED\U1F1F0'
+emoji_flags[HK]=$'\U1F1ED\U1F1F0'
+emoji_flags[HKG]=$'\U1F1ED\U1F1F0'
+emoji_flags[hong_kong]=$'\U1F1ED\U1F1F0'
+emoji_flags[Heard_and_McDonald_Islands]=$'\U1F1ED\U1F1F2'
+emoji_flags[HM]=$'\U1F1ED\U1F1F2'
+emoji_flags[HMD]=$'\U1F1ED\U1F1F2'
+emoji_flags[heard_mcdonald_islands]=$'\U1F1ED\U1F1F2'
+emoji_flags[Honduras]=$'\U1F1ED\U1F1F3'
+emoji_flags[HN]=$'\U1F1ED\U1F1F3'
+emoji_flags[HND]=$'\U1F1ED\U1F1F3'
+emoji_flags[honduras]=$'\U1F1ED\U1F1F3'
+emoji_flags[Croatia]=$'\U1F1ED\U1F1F7'
+emoji_flags[HR]=$'\U1F1ED\U1F1F7'
+emoji_flags[HRV]=$'\U1F1ED\U1F1F7'
+emoji_flags[croatia]=$'\U1F1ED\U1F1F7'
+emoji_flags[Haiti]=$'\U1F1ED\U1F1F9'
+emoji_flags[HT]=$'\U1F1ED\U1F1F9'
+emoji_flags[HTI]=$'\U1F1ED\U1F1F9'
+emoji_flags[haiti]=$'\U1F1ED\U1F1F9'
+emoji_flags[Hungary]=$'\U1F1ED\U1F1FA'
+emoji_flags[HU]=$'\U1F1ED\U1F1FA'
+emoji_flags[HUN]=$'\U1F1ED\U1F1FA'
+emoji_flags[hungary]=$'\U1F1ED\U1F1FA'
+emoji_flags[Canary_Islands]=$'\U1F1EE\U1F1E8'
+emoji_flags[canary_islands]=$'\U1F1EE\U1F1E8'
+emoji_flags[Indonesia]=$'\U1F1EE\U1F1E9'
+emoji_flags[ID]=$'\U1F1EE\U1F1E9'
+emoji_flags[IDN]=$'\U1F1EE\U1F1E9'
+emoji_flags[indonesia]=$'\U1F1EE\U1F1E9'
+emoji_flags[Ireland]=$'\U1F1EE\U1F1EA'
+emoji_flags[IE]=$'\U1F1EE\U1F1EA'
+emoji_flags[IRL]=$'\U1F1EE\U1F1EA'
+emoji_flags[ireland]=$'\U1F1EE\U1F1EA'
+emoji_flags[Israel]=$'\U1F1EE\U1F1F1'
+emoji_flags[IL]=$'\U1F1EE\U1F1F1'
+emoji_flags[ISR]=$'\U1F1EE\U1F1F1'
+emoji_flags[israel]=$'\U1F1EE\U1F1F1'
+emoji_flags[Isle_of_Man]=$'\U1F1EE\U1F1F2'
+emoji_flags[IM]=$'\U1F1EE\U1F1F2'
+emoji_flags[IMN]=$'\U1F1EE\U1F1F2'
+emoji_flags[isle_of_man]=$'\U1F1EE\U1F1F2'
+emoji_flags[India]=$'\U1F1EE\U1F1F3'
+emoji_flags[IN]=$'\U1F1EE\U1F1F3'
+emoji_flags[IND]=$'\U1F1EE\U1F1F3'
+emoji_flags[india]=$'\U1F1EE\U1F1F3'
+emoji_flags[British_Indian_Ocean_Territory]=$'\U1F1EE\U1F1F4'
+emoji_flags[IO]=$'\U1F1EE\U1F1F4'
+emoji_flags[IOT]=$'\U1F1EE\U1F1F4'
+emoji_flags[british_indian_ocean_territory]=$'\U1F1EE\U1F1F4'
+emoji_flags[Iraq]=$'\U1F1EE\U1F1F6'
+emoji_flags[IQ]=$'\U1F1EE\U1F1F6'
+emoji_flags[IRQ]=$'\U1F1EE\U1F1F6'
+emoji_flags[iraq]=$'\U1F1EE\U1F1F6'
+emoji_flags[Iran]=$'\U1F1EE\U1F1F7'
+emoji_flags[IR]=$'\U1F1EE\U1F1F7'
+emoji_flags[IRN]=$'\U1F1EE\U1F1F7'
+emoji_flags[iran]=$'\U1F1EE\U1F1F7'
+emoji_flags[Iceland]=$'\U1F1EE\U1F1F8'
+emoji_flags[IS]=$'\U1F1EE\U1F1F8'
+emoji_flags[ISL]=$'\U1F1EE\U1F1F8'
+emoji_flags[iceland]=$'\U1F1EE\U1F1F8'
+emoji_flags[Italy]=$'\U1F1EE\U1F1F9'
+emoji_flags[IT]=$'\U1F1EE\U1F1F9'
+emoji_flags[ITA]=$'\U1F1EE\U1F1F9'
+emoji_flags[it]=$'\U1F1EE\U1F1F9'
+emoji_flags[Jersey]=$'\U1F1EF\U1F1EA'
+emoji_flags[JE]=$'\U1F1EF\U1F1EA'
+emoji_flags[JEY]=$'\U1F1EF\U1F1EA'
+emoji_flags[jersey]=$'\U1F1EF\U1F1EA'
+emoji_flags[Jamaica]=$'\U1F1EF\U1F1F2'
+emoji_flags[JM]=$'\U1F1EF\U1F1F2'
+emoji_flags[JAM]=$'\U1F1EF\U1F1F2'
+emoji_flags[jamaica]=$'\U1F1EF\U1F1F2'
+emoji_flags[Jordan]=$'\U1F1EF\U1F1F4'
+emoji_flags[JO]=$'\U1F1EF\U1F1F4'
+emoji_flags[JOR]=$'\U1F1EF\U1F1F4'
+emoji_flags[jordan]=$'\U1F1EF\U1F1F4'
+emoji_flags[Japan]=$'\U1F1EF\U1F1F5'
+emoji_flags[JP]=$'\U1F1EF\U1F1F5'
+emoji_flags[JPN]=$'\U1F1EF\U1F1F5'
+emoji_flags[jp]=$'\U1F1EF\U1F1F5'
+emoji_flags[Kenya]=$'\U1F1F0\U1F1EA'
+emoji_flags[KE]=$'\U1F1F0\U1F1EA'
+emoji_flags[KEN]=$'\U1F1F0\U1F1EA'
+emoji_flags[kenya]=$'\U1F1F0\U1F1EA'
+emoji_flags[Kyrgyzstan]=$'\U1F1F0\U1F1EC'
+emoji_flags[KG]=$'\U1F1F0\U1F1EC'
+emoji_flags[KGZ]=$'\U1F1F0\U1F1EC'
+emoji_flags[kyrgyzstan]=$'\U1F1F0\U1F1EC'
+emoji_flags[Cambodia]=$'\U1F1F0\U1F1ED'
+emoji_flags[KH]=$'\U1F1F0\U1F1ED'
+emoji_flags[KHM]=$'\U1F1F0\U1F1ED'
+emoji_flags[cambodia]=$'\U1F1F0\U1F1ED'
+emoji_flags[Kiribati]=$'\U1F1F0\U1F1EE'
+emoji_flags[KI]=$'\U1F1F0\U1F1EE'
+emoji_flags[KIR]=$'\U1F1F0\U1F1EE'
+emoji_flags[kiribati]=$'\U1F1F0\U1F1EE'
+emoji_flags[Comoros]=$'\U1F1F0\U1F1F2'
+emoji_flags[KM]=$'\U1F1F0\U1F1F2'
+emoji_flags[COM]=$'\U1F1F0\U1F1F2'
+emoji_flags[comoros]=$'\U1F1F0\U1F1F2'
+emoji_flags[St_Kitts_and_Nevis]=$'\U1F1F0\U1F1F3'
+emoji_flags[KN]=$'\U1F1F0\U1F1F3'
+emoji_flags[KNA]=$'\U1F1F0\U1F1F3'
+emoji_flags[st_kitts_nevis]=$'\U1F1F0\U1F1F3'
+emoji_flags[North_Korea]=$'\U1F1F0\U1F1F5'
+emoji_flags[KP]=$'\U1F1F0\U1F1F5'
+emoji_flags[PRK]=$'\U1F1F0\U1F1F5'
+emoji_flags[north_korea]=$'\U1F1F0\U1F1F5'
+emoji_flags[South_Korea]=$'\U1F1F0\U1F1F7'
+emoji_flags[KR]=$'\U1F1F0\U1F1F7'
+emoji_flags[KOR]=$'\U1F1F0\U1F1F7'
+emoji_flags[kr]=$'\U1F1F0\U1F1F7'
+emoji_flags[Kuwait]=$'\U1F1F0\U1F1FC'
+emoji_flags[KW]=$'\U1F1F0\U1F1FC'
+emoji_flags[KWT]=$'\U1F1F0\U1F1FC'
+emoji_flags[kuwait]=$'\U1F1F0\U1F1FC'
+emoji_flags[Cayman_Islands]=$'\U1F1F0\U1F1FE'
+emoji_flags[KY]=$'\U1F1F0\U1F1FE'
+emoji_flags[CYM]=$'\U1F1F0\U1F1FE'
+emoji_flags[cayman_islands]=$'\U1F1F0\U1F1FE'
+emoji_flags[Kazakhstan]=$'\U1F1F0\U1F1FF'
+emoji_flags[KZ]=$'\U1F1F0\U1F1FF'
+emoji_flags[KAZ]=$'\U1F1F0\U1F1FF'
+emoji_flags[kazakhstan]=$'\U1F1F0\U1F1FF'
+emoji_flags[Laos]=$'\U1F1F1\U1F1E6'
+emoji_flags[LA]=$'\U1F1F1\U1F1E6'
+emoji_flags[LAO]=$'\U1F1F1\U1F1E6'
+emoji_flags[laos]=$'\U1F1F1\U1F1E6'
+emoji_flags[Lebanon]=$'\U1F1F1\U1F1E7'
+emoji_flags[LB]=$'\U1F1F1\U1F1E7'
+emoji_flags[LBN]=$'\U1F1F1\U1F1E7'
+emoji_flags[lebanon]=$'\U1F1F1\U1F1E7'
+emoji_flags[St_Lucia]=$'\U1F1F1\U1F1E8'
+emoji_flags[LC]=$'\U1F1F1\U1F1E8'
+emoji_flags[LCA]=$'\U1F1F1\U1F1E8'
+emoji_flags[st_lucia]=$'\U1F1F1\U1F1E8'
+emoji_flags[Liechtenstein]=$'\U1F1F1\U1F1EE'
+emoji_flags[LI]=$'\U1F1F1\U1F1EE'
+emoji_flags[LIE]=$'\U1F1F1\U1F1EE'
+emoji_flags[liechtenstein]=$'\U1F1F1\U1F1EE'
+emoji_flags[Sri_Lanka]=$'\U1F1F1\U1F1F0'
+emoji_flags[LK]=$'\U1F1F1\U1F1F0'
+emoji_flags[LKA]=$'\U1F1F1\U1F1F0'
+emoji_flags[sri_lanka]=$'\U1F1F1\U1F1F0'
+emoji_flags[Liberia]=$'\U1F1F1\U1F1F7'
+emoji_flags[LR]=$'\U1F1F1\U1F1F7'
+emoji_flags[LBR]=$'\U1F1F1\U1F1F7'
+emoji_flags[liberia]=$'\U1F1F1\U1F1F7'
+emoji_flags[Lesotho]=$'\U1F1F1\U1F1F8'
+emoji_flags[LS]=$'\U1F1F1\U1F1F8'
+emoji_flags[LSO]=$'\U1F1F1\U1F1F8'
+emoji_flags[lesotho]=$'\U1F1F1\U1F1F8'
+emoji_flags[Lithuania]=$'\U1F1F1\U1F1F9'
+emoji_flags[LT]=$'\U1F1F1\U1F1F9'
+emoji_flags[LTU]=$'\U1F1F1\U1F1F9'
+emoji_flags[lithuania]=$'\U1F1F1\U1F1F9'
+emoji_flags[Luxembourg]=$'\U1F1F1\U1F1FA'
+emoji_flags[LU]=$'\U1F1F1\U1F1FA'
+emoji_flags[LUX]=$'\U1F1F1\U1F1FA'
+emoji_flags[luxembourg]=$'\U1F1F1\U1F1FA'
+emoji_flags[Latvia]=$'\U1F1F1\U1F1FB'
+emoji_flags[LV]=$'\U1F1F1\U1F1FB'
+emoji_flags[LVA]=$'\U1F1F1\U1F1FB'
+emoji_flags[latvia]=$'\U1F1F1\U1F1FB'
+emoji_flags[Libya]=$'\U1F1F1\U1F1FE'
+emoji_flags[LY]=$'\U1F1F1\U1F1FE'
+emoji_flags[LBY]=$'\U1F1F1\U1F1FE'
+emoji_flags[libya]=$'\U1F1F1\U1F1FE'
+emoji_flags[Morocco]=$'\U1F1F2\U1F1E6'
+emoji_flags[MA]=$'\U1F1F2\U1F1E6'
+emoji_flags[MAR]=$'\U1F1F2\U1F1E6'
+emoji_flags[morocco]=$'\U1F1F2\U1F1E6'
+emoji_flags[Monaco]=$'\U1F1F2\U1F1E8'
+emoji_flags[MC]=$'\U1F1F2\U1F1E8'
+emoji_flags[MCO]=$'\U1F1F2\U1F1E8'
+emoji_flags[monaco]=$'\U1F1F2\U1F1E8'
+emoji_flags[Moldova]=$'\U1F1F2\U1F1E9'
+emoji_flags[MD]=$'\U1F1F2\U1F1E9'
+emoji_flags[MDA]=$'\U1F1F2\U1F1E9'
+emoji_flags[moldova]=$'\U1F1F2\U1F1E9'
+emoji_flags[Montenegro]=$'\U1F1F2\U1F1EA'
+emoji_flags[ME]=$'\U1F1F2\U1F1EA'
+emoji_flags[MNE]=$'\U1F1F2\U1F1EA'
+emoji_flags[montenegro]=$'\U1F1F2\U1F1EA'
+emoji_flags[St_Martin]=$'\U1F1F2\U1F1EB'
+emoji_flags[MF]=$'\U1F1F2\U1F1EB'
+emoji_flags[MAF]=$'\U1F1F2\U1F1EB'
+emoji_flags[st_martin]=$'\U1F1F2\U1F1EB'
+emoji_flags[Madagascar]=$'\U1F1F2\U1F1EC'
+emoji_flags[MG]=$'\U1F1F2\U1F1EC'
+emoji_flags[MDG]=$'\U1F1F2\U1F1EC'
+emoji_flags[madagascar]=$'\U1F1F2\U1F1EC'
+emoji_flags[Marshall_Islands]=$'\U1F1F2\U1F1ED'
+emoji_flags[MH]=$'\U1F1F2\U1F1ED'
+emoji_flags[MHL]=$'\U1F1F2\U1F1ED'
+emoji_flags[marshall_islands]=$'\U1F1F2\U1F1ED'
+emoji_flags[Macedonia]=$'\U1F1F2\U1F1F0'
+emoji_flags[MK]=$'\U1F1F2\U1F1F0'
+emoji_flags[MKD]=$'\U1F1F2\U1F1F0'
+emoji_flags[macedonia]=$'\U1F1F2\U1F1F0'
+emoji_flags[Mali]=$'\U1F1F2\U1F1F1'
+emoji_flags[ML]=$'\U1F1F2\U1F1F1'
+emoji_flags[MLI]=$'\U1F1F2\U1F1F1'
+emoji_flags[mali]=$'\U1F1F2\U1F1F1'
+emoji_flags[Myanmar_Burma_]=$'\U1F1F2\U1F1F2'
+emoji_flags[MM]=$'\U1F1F2\U1F1F2'
+emoji_flags[MMR]=$'\U1F1F2\U1F1F2'
+emoji_flags[myanmar]=$'\U1F1F2\U1F1F2'
+emoji_flags[Mongolia]=$'\U1F1F2\U1F1F3'
+emoji_flags[MN]=$'\U1F1F2\U1F1F3'
+emoji_flags[MNG]=$'\U1F1F2\U1F1F3'
+emoji_flags[mongolia]=$'\U1F1F2\U1F1F3'
+emoji_flags[Macao_SAR_China]=$'\U1F1F2\U1F1F4'
+emoji_flags[MO]=$'\U1F1F2\U1F1F4'
+emoji_flags[MAC]=$'\U1F1F2\U1F1F4'
+emoji_flags[macau]=$'\U1F1F2\U1F1F4'
+emoji_flags[Northern_Mariana_Islands]=$'\U1F1F2\U1F1F5'
+emoji_flags[MP]=$'\U1F1F2\U1F1F5'
+emoji_flags[MNP]=$'\U1F1F2\U1F1F5'
+emoji_flags[northern_mariana_islands]=$'\U1F1F2\U1F1F5'
+emoji_flags[Martinique]=$'\U1F1F2\U1F1F6'
+emoji_flags[MQ]=$'\U1F1F2\U1F1F6'
+emoji_flags[MTQ]=$'\U1F1F2\U1F1F6'
+emoji_flags[martinique]=$'\U1F1F2\U1F1F6'
+emoji_flags[Mauritania]=$'\U1F1F2\U1F1F7'
+emoji_flags[MR]=$'\U1F1F2\U1F1F7'
+emoji_flags[MRT]=$'\U1F1F2\U1F1F7'
+emoji_flags[mauritania]=$'\U1F1F2\U1F1F7'
+emoji_flags[Montserrat]=$'\U1F1F2\U1F1F8'
+emoji_flags[MS]=$'\U1F1F2\U1F1F8'
+emoji_flags[MSR]=$'\U1F1F2\U1F1F8'
+emoji_flags[montserrat]=$'\U1F1F2\U1F1F8'
+emoji_flags[Malta]=$'\U1F1F2\U1F1F9'
+emoji_flags[MT]=$'\U1F1F2\U1F1F9'
+emoji_flags[MLT]=$'\U1F1F2\U1F1F9'
+emoji_flags[malta]=$'\U1F1F2\U1F1F9'
+emoji_flags[Mauritius]=$'\U1F1F2\U1F1FA'
+emoji_flags[MU]=$'\U1F1F2\U1F1FA'
+emoji_flags[MUS]=$'\U1F1F2\U1F1FA'
+emoji_flags[mauritius]=$'\U1F1F2\U1F1FA'
+emoji_flags[Maldives]=$'\U1F1F2\U1F1FB'
+emoji_flags[MV]=$'\U1F1F2\U1F1FB'
+emoji_flags[MDV]=$'\U1F1F2\U1F1FB'
+emoji_flags[maldives]=$'\U1F1F2\U1F1FB'
+emoji_flags[Malawi]=$'\U1F1F2\U1F1FC'
+emoji_flags[MW]=$'\U1F1F2\U1F1FC'
+emoji_flags[MWI]=$'\U1F1F2\U1F1FC'
+emoji_flags[malawi]=$'\U1F1F2\U1F1FC'
+emoji_flags[Mexico]=$'\U1F1F2\U1F1FD'
+emoji_flags[MX]=$'\U1F1F2\U1F1FD'
+emoji_flags[MEX]=$'\U1F1F2\U1F1FD'
+emoji_flags[mexico]=$'\U1F1F2\U1F1FD'
+emoji_flags[Malaysia]=$'\U1F1F2\U1F1FE'
+emoji_flags[MY]=$'\U1F1F2\U1F1FE'
+emoji_flags[MYS]=$'\U1F1F2\U1F1FE'
+emoji_flags[malaysia]=$'\U1F1F2\U1F1FE'
+emoji_flags[Mozambique]=$'\U1F1F2\U1F1FF'
+emoji_flags[MZ]=$'\U1F1F2\U1F1FF'
+emoji_flags[MOZ]=$'\U1F1F2\U1F1FF'
+emoji_flags[mozambique]=$'\U1F1F2\U1F1FF'
+emoji_flags[Namibia]=$'\U1F1F3\U1F1E6'
+emoji_flags[NA]=$'\U1F1F3\U1F1E6'
+emoji_flags[NAM]=$'\U1F1F3\U1F1E6'
+emoji_flags[namibia]=$'\U1F1F3\U1F1E6'
+emoji_flags[New_Caledonia]=$'\U1F1F3\U1F1E8'
+emoji_flags[NC]=$'\U1F1F3\U1F1E8'
+emoji_flags[NCL]=$'\U1F1F3\U1F1E8'
+emoji_flags[new_caledonia]=$'\U1F1F3\U1F1E8'
+emoji_flags[Niger]=$'\U1F1F3\U1F1EA'
+emoji_flags[NE]=$'\U1F1F3\U1F1EA'
+emoji_flags[NER]=$'\U1F1F3\U1F1EA'
+emoji_flags[niger]=$'\U1F1F3\U1F1EA'
+emoji_flags[Norfolk_Island]=$'\U1F1F3\U1F1EB'
+emoji_flags[NF]=$'\U1F1F3\U1F1EB'
+emoji_flags[NFK]=$'\U1F1F3\U1F1EB'
+emoji_flags[norfolk_island]=$'\U1F1F3\U1F1EB'
+emoji_flags[Nigeria]=$'\U1F1F3\U1F1EC'
+emoji_flags[NG]=$'\U1F1F3\U1F1EC'
+emoji_flags[NGA]=$'\U1F1F3\U1F1EC'
+emoji_flags[nigeria]=$'\U1F1F3\U1F1EC'
+emoji_flags[Nicaragua]=$'\U1F1F3\U1F1EE'
+emoji_flags[NI]=$'\U1F1F3\U1F1EE'
+emoji_flags[NIC]=$'\U1F1F3\U1F1EE'
+emoji_flags[nicaragua]=$'\U1F1F3\U1F1EE'
+emoji_flags[Netherlands]=$'\U1F1F3\U1F1F1'
+emoji_flags[NL]=$'\U1F1F3\U1F1F1'
+emoji_flags[NLD]=$'\U1F1F3\U1F1F1'
+emoji_flags[netherlands]=$'\U1F1F3\U1F1F1'
+emoji_flags[Norway]=$'\U1F1F3\U1F1F4'
+emoji_flags[NO]=$'\U1F1F3\U1F1F4'
+emoji_flags[NOR]=$'\U1F1F3\U1F1F4'
+emoji_flags[norway]=$'\U1F1F3\U1F1F4'
+emoji_flags[Nepal]=$'\U1F1F3\U1F1F5'
+emoji_flags[NP]=$'\U1F1F3\U1F1F5'
+emoji_flags[NPL]=$'\U1F1F3\U1F1F5'
+emoji_flags[nepal]=$'\U1F1F3\U1F1F5'
+emoji_flags[Nauru]=$'\U1F1F3\U1F1F7'
+emoji_flags[NR]=$'\U1F1F3\U1F1F7'
+emoji_flags[NRU]=$'\U1F1F3\U1F1F7'
+emoji_flags[nauru]=$'\U1F1F3\U1F1F7'
+emoji_flags[Niue]=$'\U1F1F3\U1F1FA'
+emoji_flags[NU]=$'\U1F1F3\U1F1FA'
+emoji_flags[NIU]=$'\U1F1F3\U1F1FA'
+emoji_flags[niue]=$'\U1F1F3\U1F1FA'
+emoji_flags[New_Zealand]=$'\U1F1F3\U1F1FF'
+emoji_flags[NZ]=$'\U1F1F3\U1F1FF'
+emoji_flags[NZL]=$'\U1F1F3\U1F1FF'
+emoji_flags[new_zealand]=$'\U1F1F3\U1F1FF'
+emoji_flags[Oman]=$'\U1F1F4\U1F1F2'
+emoji_flags[OM]=$'\U1F1F4\U1F1F2'
+emoji_flags[OMN]=$'\U1F1F4\U1F1F2'
+emoji_flags[oman]=$'\U1F1F4\U1F1F2'
+emoji_flags[Panama]=$'\U1F1F5\U1F1E6'
+emoji_flags[PA]=$'\U1F1F5\U1F1E6'
+emoji_flags[PAN]=$'\U1F1F5\U1F1E6'
+emoji_flags[panama]=$'\U1F1F5\U1F1E6'
+emoji_flags[Peru]=$'\U1F1F5\U1F1EA'
+emoji_flags[PE]=$'\U1F1F5\U1F1EA'
+emoji_flags[PER]=$'\U1F1F5\U1F1EA'
+emoji_flags[peru]=$'\U1F1F5\U1F1EA'
+emoji_flags[French_Polynesia]=$'\U1F1F5\U1F1EB'
+emoji_flags[PF]=$'\U1F1F5\U1F1EB'
+emoji_flags[PYF]=$'\U1F1F5\U1F1EB'
+emoji_flags[french_polynesia]=$'\U1F1F5\U1F1EB'
+emoji_flags[Papua_New_Guinea]=$'\U1F1F5\U1F1EC'
+emoji_flags[PG]=$'\U1F1F5\U1F1EC'
+emoji_flags[PNG]=$'\U1F1F5\U1F1EC'
+emoji_flags[papua_new_guinea]=$'\U1F1F5\U1F1EC'
+emoji_flags[Philippines]=$'\U1F1F5\U1F1ED'
+emoji_flags[PH]=$'\U1F1F5\U1F1ED'
+emoji_flags[PHL]=$'\U1F1F5\U1F1ED'
+emoji_flags[philippines]=$'\U1F1F5\U1F1ED'
+emoji_flags[Pakistan]=$'\U1F1F5\U1F1F0'
+emoji_flags[PK]=$'\U1F1F5\U1F1F0'
+emoji_flags[PAK]=$'\U1F1F5\U1F1F0'
+emoji_flags[pakistan]=$'\U1F1F5\U1F1F0'
+emoji_flags[Poland]=$'\U1F1F5\U1F1F1'
+emoji_flags[PL]=$'\U1F1F5\U1F1F1'
+emoji_flags[POL]=$'\U1F1F5\U1F1F1'
+emoji_flags[poland]=$'\U1F1F5\U1F1F1'
+emoji_flags[St_Pierre_and_Miquelon]=$'\U1F1F5\U1F1F2'
+emoji_flags[PM]=$'\U1F1F5\U1F1F2'
+emoji_flags[SPM]=$'\U1F1F5\U1F1F2'
+emoji_flags[st_pierre_miquelon]=$'\U1F1F5\U1F1F2'
+emoji_flags[Pitcairn_Islands]=$'\U1F1F5\U1F1F3'
+emoji_flags[PN]=$'\U1F1F5\U1F1F3'
+emoji_flags[PCN]=$'\U1F1F5\U1F1F3'
+emoji_flags[pitcairn_islands]=$'\U1F1F5\U1F1F3'
+emoji_flags[Puerto_Rico]=$'\U1F1F5\U1F1F7'
+emoji_flags[PR]=$'\U1F1F5\U1F1F7'
+emoji_flags[PRI]=$'\U1F1F5\U1F1F7'
+emoji_flags[puerto_rico]=$'\U1F1F5\U1F1F7'
+emoji_flags[Palestinian_Territories]=$'\U1F1F5\U1F1F8'
+emoji_flags[PS]=$'\U1F1F5\U1F1F8'
+emoji_flags[PSE]=$'\U1F1F5\U1F1F8'
+emoji_flags[palestinian_territories]=$'\U1F1F5\U1F1F8'
+emoji_flags[Portugal]=$'\U1F1F5\U1F1F9'
+emoji_flags[PT]=$'\U1F1F5\U1F1F9'
+emoji_flags[PRT]=$'\U1F1F5\U1F1F9'
+emoji_flags[portugal]=$'\U1F1F5\U1F1F9'
+emoji_flags[Palau]=$'\U1F1F5\U1F1FC'
+emoji_flags[PW]=$'\U1F1F5\U1F1FC'
+emoji_flags[PLW]=$'\U1F1F5\U1F1FC'
+emoji_flags[palau]=$'\U1F1F5\U1F1FC'
+emoji_flags[Paraguay]=$'\U1F1F5\U1F1FE'
+emoji_flags[PY]=$'\U1F1F5\U1F1FE'
+emoji_flags[PRY]=$'\U1F1F5\U1F1FE'
+emoji_flags[paraguay]=$'\U1F1F5\U1F1FE'
+emoji_flags[Qatar]=$'\U1F1F6\U1F1E6'
+emoji_flags[QA]=$'\U1F1F6\U1F1E6'
+emoji_flags[QAT]=$'\U1F1F6\U1F1E6'
+emoji_flags[qatar]=$'\U1F1F6\U1F1E6'
+emoji_flags[Réunion]=$'\U1F1F7\U1F1EA'
+emoji_flags[RE]=$'\U1F1F7\U1F1EA'
+emoji_flags[REU]=$'\U1F1F7\U1F1EA'
+emoji_flags[reunion]=$'\U1F1F7\U1F1EA'
+emoji_flags[Romania]=$'\U1F1F7\U1F1F4'
+emoji_flags[RO]=$'\U1F1F7\U1F1F4'
+emoji_flags[ROU]=$'\U1F1F7\U1F1F4'
+emoji_flags[romania]=$'\U1F1F7\U1F1F4'
+emoji_flags[Serbia]=$'\U1F1F7\U1F1F8'
+emoji_flags[RS]=$'\U1F1F7\U1F1F8'
+emoji_flags[SRB]=$'\U1F1F7\U1F1F8'
+emoji_flags[serbia]=$'\U1F1F7\U1F1F8'
+emoji_flags[Russia]=$'\U1F1F7\U1F1FA'
+emoji_flags[RU]=$'\U1F1F7\U1F1FA'
+emoji_flags[RUS]=$'\U1F1F7\U1F1FA'
+emoji_flags[ru]=$'\U1F1F7\U1F1FA'
+emoji_flags[Rwanda]=$'\U1F1F7\U1F1FC'
+emoji_flags[RW]=$'\U1F1F7\U1F1FC'
+emoji_flags[RWA]=$'\U1F1F7\U1F1FC'
+emoji_flags[rwanda]=$'\U1F1F7\U1F1FC'
+emoji_flags[Saudi_Arabia]=$'\U1F1F8\U1F1E6'
+emoji_flags[SA]=$'\U1F1F8\U1F1E6'
+emoji_flags[SAU]=$'\U1F1F8\U1F1E6'
+emoji_flags[saudi_arabia]=$'\U1F1F8\U1F1E6'
+emoji_flags[Solomon_Islands]=$'\U1F1F8\U1F1E7'
+emoji_flags[SB]=$'\U1F1F8\U1F1E7'
+emoji_flags[SLB]=$'\U1F1F8\U1F1E7'
+emoji_flags[solomon_islands]=$'\U1F1F8\U1F1E7'
+emoji_flags[Seychelles]=$'\U1F1F8\U1F1E8'
+emoji_flags[SC]=$'\U1F1F8\U1F1E8'
+emoji_flags[SYC]=$'\U1F1F8\U1F1E8'
+emoji_flags[seychelles]=$'\U1F1F8\U1F1E8'
+emoji_flags[Sudan]=$'\U1F1F8\U1F1E9'
+emoji_flags[SD]=$'\U1F1F8\U1F1E9'
+emoji_flags[SDN]=$'\U1F1F8\U1F1E9'
+emoji_flags[sudan]=$'\U1F1F8\U1F1E9'
+emoji_flags[Sweden]=$'\U1F1F8\U1F1EA'
+emoji_flags[SE]=$'\U1F1F8\U1F1EA'
+emoji_flags[SWE]=$'\U1F1F8\U1F1EA'
+emoji_flags[sweden]=$'\U1F1F8\U1F1EA'
+emoji_flags[Singapore]=$'\U1F1F8\U1F1EC'
+emoji_flags[SG]=$'\U1F1F8\U1F1EC'
+emoji_flags[SGP]=$'\U1F1F8\U1F1EC'
+emoji_flags[singapore]=$'\U1F1F8\U1F1EC'
+emoji_flags[St_Helena]=$'\U1F1F8\U1F1ED'
+emoji_flags[SH]=$'\U1F1F8\U1F1ED'
+emoji_flags[SHN]=$'\U1F1F8\U1F1ED'
+emoji_flags[st_helena]=$'\U1F1F8\U1F1ED'
+emoji_flags[Slovenia]=$'\U1F1F8\U1F1EE'
+emoji_flags[SI]=$'\U1F1F8\U1F1EE'
+emoji_flags[SVN]=$'\U1F1F8\U1F1EE'
+emoji_flags[slovenia]=$'\U1F1F8\U1F1EE'
+emoji_flags[Svalbard_and_Jan_Mayen]=$'\U1F1F8\U1F1EF'
+emoji_flags[SJ]=$'\U1F1F8\U1F1EF'
+emoji_flags[SJM]=$'\U1F1F8\U1F1EF'
+emoji_flags[svalbard_jan_mayen]=$'\U1F1F8\U1F1EF'
+emoji_flags[Slovakia]=$'\U1F1F8\U1F1F0'
+emoji_flags[SK]=$'\U1F1F8\U1F1F0'
+emoji_flags[SVK]=$'\U1F1F8\U1F1F0'
+emoji_flags[slovakia]=$'\U1F1F8\U1F1F0'
+emoji_flags[Sierra_Leone]=$'\U1F1F8\U1F1F1'
+emoji_flags[SL]=$'\U1F1F8\U1F1F1'
+emoji_flags[SLE]=$'\U1F1F8\U1F1F1'
+emoji_flags[sierra_leone]=$'\U1F1F8\U1F1F1'
+emoji_flags[San_Marino]=$'\U1F1F8\U1F1F2'
+emoji_flags[SM]=$'\U1F1F8\U1F1F2'
+emoji_flags[SMR]=$'\U1F1F8\U1F1F2'
+emoji_flags[san_marino]=$'\U1F1F8\U1F1F2'
+emoji_flags[Senegal]=$'\U1F1F8\U1F1F3'
+emoji_flags[SN]=$'\U1F1F8\U1F1F3'
+emoji_flags[SEN]=$'\U1F1F8\U1F1F3'
+emoji_flags[senegal]=$'\U1F1F8\U1F1F3'
+emoji_flags[Somalia]=$'\U1F1F8\U1F1F4'
+emoji_flags[SO]=$'\U1F1F8\U1F1F4'
+emoji_flags[SOM]=$'\U1F1F8\U1F1F4'
+emoji_flags[somalia]=$'\U1F1F8\U1F1F4'
+emoji_flags[Suriname]=$'\U1F1F8\U1F1F7'
+emoji_flags[SR]=$'\U1F1F8\U1F1F7'
+emoji_flags[SUR]=$'\U1F1F8\U1F1F7'
+emoji_flags[suriname]=$'\U1F1F8\U1F1F7'
+emoji_flags[South_Sudan]=$'\U1F1F8\U1F1F8'
+emoji_flags[SS]=$'\U1F1F8\U1F1F8'
+emoji_flags[SSD]=$'\U1F1F8\U1F1F8'
+emoji_flags[south_sudan]=$'\U1F1F8\U1F1F8'
+emoji_flags[São_Tomé_and_Príncipe]=$'\U1F1F8\U1F1F9'
+emoji_flags[sao_tome_principe]=$'\U1F1F8\U1F1F9'
+emoji_flags[El_Salvador]=$'\U1F1F8\U1F1FB'
+emoji_flags[SV]=$'\U1F1F8\U1F1FB'
+emoji_flags[SLV]=$'\U1F1F8\U1F1FB'
+emoji_flags[el_salvador]=$'\U1F1F8\U1F1FB'
+emoji_flags[Sint_Maarten]=$'\U1F1F8\U1F1FD'
+emoji_flags[SX]=$'\U1F1F8\U1F1FD'
+emoji_flags[SXM]=$'\U1F1F8\U1F1FD'
+emoji_flags[sint_maarten]=$'\U1F1F8\U1F1FD'
+emoji_flags[Syria]=$'\U1F1F8\U1F1FE'
+emoji_flags[SY]=$'\U1F1F8\U1F1FE'
+emoji_flags[SYR]=$'\U1F1F8\U1F1FE'
+emoji_flags[syria]=$'\U1F1F8\U1F1FE'
+emoji_flags[Eswatini]=$'\U1F1F8\U1F1FF'
+emoji_flags[SZ]=$'\U1F1F8\U1F1FF'
+emoji_flags[SWZ]=$'\U1F1F8\U1F1FF'
+emoji_flags[swaziland]=$'\U1F1F8\U1F1FF'
+emoji_flags[Tristan_da_Cunha]=$'\U1F1F9\U1F1E6'
+emoji_flags[tristan_da_cunha]=$'\U1F1F9\U1F1E6'
+emoji_flags[Turks_and_Caicos_Islands]=$'\U1F1F9\U1F1E8'
+emoji_flags[TC]=$'\U1F1F9\U1F1E8'
+emoji_flags[TCA]=$'\U1F1F9\U1F1E8'
+emoji_flags[turks_caicos_islands]=$'\U1F1F9\U1F1E8'
+emoji_flags[Chad]=$'\U1F1F9\U1F1E9'
+emoji_flags[TD]=$'\U1F1F9\U1F1E9'
+emoji_flags[TCD]=$'\U1F1F9\U1F1E9'
+emoji_flags[chad]=$'\U1F1F9\U1F1E9'
+emoji_flags[French_Southern_Territories]=$'\U1F1F9\U1F1EB'
+emoji_flags[TF]=$'\U1F1F9\U1F1EB'
+emoji_flags[ATF]=$'\U1F1F9\U1F1EB'
+emoji_flags[french_southern_territories]=$'\U1F1F9\U1F1EB'
+emoji_flags[Togo]=$'\U1F1F9\U1F1EC'
+emoji_flags[TG]=$'\U1F1F9\U1F1EC'
+emoji_flags[TGO]=$'\U1F1F9\U1F1EC'
+emoji_flags[togo]=$'\U1F1F9\U1F1EC'
+emoji_flags[Thailand]=$'\U1F1F9\U1F1ED'
+emoji_flags[TH]=$'\U1F1F9\U1F1ED'
+emoji_flags[THA]=$'\U1F1F9\U1F1ED'
+emoji_flags[thailand]=$'\U1F1F9\U1F1ED'
+emoji_flags[Tajikistan]=$'\U1F1F9\U1F1EF'
+emoji_flags[TJ]=$'\U1F1F9\U1F1EF'
+emoji_flags[TJK]=$'\U1F1F9\U1F1EF'
+emoji_flags[tajikistan]=$'\U1F1F9\U1F1EF'
+emoji_flags[Tokelau]=$'\U1F1F9\U1F1F0'
+emoji_flags[TK]=$'\U1F1F9\U1F1F0'
+emoji_flags[TKL]=$'\U1F1F9\U1F1F0'
+emoji_flags[tokelau]=$'\U1F1F9\U1F1F0'
+emoji_flags[Timor_Leste]=$'\U1F1F9\U1F1F1'
+emoji_flags[TL]=$'\U1F1F9\U1F1F1'
+emoji_flags[TLS]=$'\U1F1F9\U1F1F1'
+emoji_flags[timor_leste]=$'\U1F1F9\U1F1F1'
+emoji_flags[Turkmenistan]=$'\U1F1F9\U1F1F2'
+emoji_flags[TM]=$'\U1F1F9\U1F1F2'
+emoji_flags[TKM]=$'\U1F1F9\U1F1F2'
+emoji_flags[turkmenistan]=$'\U1F1F9\U1F1F2'
+emoji_flags[Tunisia]=$'\U1F1F9\U1F1F3'
+emoji_flags[TN]=$'\U1F1F9\U1F1F3'
+emoji_flags[TUN]=$'\U1F1F9\U1F1F3'
+emoji_flags[tunisia]=$'\U1F1F9\U1F1F3'
+emoji_flags[Tonga]=$'\U1F1F9\U1F1F4'
+emoji_flags[TO]=$'\U1F1F9\U1F1F4'
+emoji_flags[TON]=$'\U1F1F9\U1F1F4'
+emoji_flags[tonga]=$'\U1F1F9\U1F1F4'
+emoji_flags[Turkey]=$'\U1F1F9\U1F1F7'
+emoji_flags[TR]=$'\U1F1F9\U1F1F7'
+emoji_flags[TUR]=$'\U1F1F9\U1F1F7'
+emoji_flags[tr]=$'\U1F1F9\U1F1F7'
+emoji_flags[Trinidad_and_Tobago]=$'\U1F1F9\U1F1F9'
+emoji_flags[TT]=$'\U1F1F9\U1F1F9'
+emoji_flags[TTO]=$'\U1F1F9\U1F1F9'
+emoji_flags[trinidad_tobago]=$'\U1F1F9\U1F1F9'
+emoji_flags[Tuvalu]=$'\U1F1F9\U1F1FB'
+emoji_flags[TV]=$'\U1F1F9\U1F1FB'
+emoji_flags[TUV]=$'\U1F1F9\U1F1FB'
+emoji_flags[tuvalu]=$'\U1F1F9\U1F1FB'
+emoji_flags[Taiwan]=$'\U1F1F9\U1F1FC'
+emoji_flags[TW]=$'\U1F1F9\U1F1FC'
+emoji_flags[TWN]=$'\U1F1F9\U1F1FC'
+emoji_flags[taiwan]=$'\U1F1F9\U1F1FC'
+emoji_flags[Tanzania]=$'\U1F1F9\U1F1FF'
+emoji_flags[TZ]=$'\U1F1F9\U1F1FF'
+emoji_flags[TZA]=$'\U1F1F9\U1F1FF'
+emoji_flags[tanzania]=$'\U1F1F9\U1F1FF'
+emoji_flags[Ukraine]=$'\U1F1FA\U1F1E6'
+emoji_flags[UA]=$'\U1F1FA\U1F1E6'
+emoji_flags[UKR]=$'\U1F1FA\U1F1E6'
+emoji_flags[ukraine]=$'\U1F1FA\U1F1E6'
+emoji_flags[Uganda]=$'\U1F1FA\U1F1EC'
+emoji_flags[UG]=$'\U1F1FA\U1F1EC'
+emoji_flags[UGA]=$'\U1F1FA\U1F1EC'
+emoji_flags[uganda]=$'\U1F1FA\U1F1EC'
+emoji_flags[U_S_Outlying_Islands]=$'\U1F1FA\U1F1F2'
+emoji_flags[us_outlying_islands]=$'\U1F1FA\U1F1F2'
+emoji_flags[United_Nations]=$'\U1F1FA\U1F1F3'
+emoji_flags[united_nations]=$'\U1F1FA\U1F1F3'
+emoji_flags[United_States]=$'\U1F1FA\U1F1F8'
+emoji_flags[US]=$'\U1F1FA\U1F1F8'
+emoji_flags[USA]=$'\U1F1FA\U1F1F8'
+emoji_flags[us]=$'\U1F1FA\U1F1F8'
+emoji_flags[Uruguay]=$'\U1F1FA\U1F1FE'
+emoji_flags[UY]=$'\U1F1FA\U1F1FE'
+emoji_flags[URY]=$'\U1F1FA\U1F1FE'
+emoji_flags[uruguay]=$'\U1F1FA\U1F1FE'
+emoji_flags[Uzbekistan]=$'\U1F1FA\U1F1FF'
+emoji_flags[UZ]=$'\U1F1FA\U1F1FF'
+emoji_flags[UZB]=$'\U1F1FA\U1F1FF'
+emoji_flags[uzbekistan]=$'\U1F1FA\U1F1FF'
+emoji_flags[Vatican_City]=$'\U1F1FB\U1F1E6'
+emoji_flags[VA]=$'\U1F1FB\U1F1E6'
+emoji_flags[VAT]=$'\U1F1FB\U1F1E6'
+emoji_flags[vatican_city]=$'\U1F1FB\U1F1E6'
+emoji_flags[St_Vincent_and_Grenadines]=$'\U1F1FB\U1F1E8'
+emoji_flags[VC]=$'\U1F1FB\U1F1E8'
+emoji_flags[VCT]=$'\U1F1FB\U1F1E8'
+emoji_flags[st_vincent_grenadines]=$'\U1F1FB\U1F1E8'
+emoji_flags[Venezuela]=$'\U1F1FB\U1F1EA'
+emoji_flags[VE]=$'\U1F1FB\U1F1EA'
+emoji_flags[VEN]=$'\U1F1FB\U1F1EA'
+emoji_flags[venezuela]=$'\U1F1FB\U1F1EA'
+emoji_flags[British_Virgin_Islands]=$'\U1F1FB\U1F1EC'
+emoji_flags[VG]=$'\U1F1FB\U1F1EC'
+emoji_flags[VGB]=$'\U1F1FB\U1F1EC'
+emoji_flags[british_virgin_islands]=$'\U1F1FB\U1F1EC'
+emoji_flags[U_S_Virgin_Islands]=$'\U1F1FB\U1F1EE'
+emoji_flags[VI]=$'\U1F1FB\U1F1EE'
+emoji_flags[VIR]=$'\U1F1FB\U1F1EE'
+emoji_flags[us_virgin_islands]=$'\U1F1FB\U1F1EE'
+emoji_flags[Vietnam]=$'\U1F1FB\U1F1F3'
+emoji_flags[VN]=$'\U1F1FB\U1F1F3'
+emoji_flags[VNM]=$'\U1F1FB\U1F1F3'
+emoji_flags[vietnam]=$'\U1F1FB\U1F1F3'
+emoji_flags[Vanuatu]=$'\U1F1FB\U1F1FA'
+emoji_flags[VU]=$'\U1F1FB\U1F1FA'
+emoji_flags[VUT]=$'\U1F1FB\U1F1FA'
+emoji_flags[vanuatu]=$'\U1F1FB\U1F1FA'
+emoji_flags[Wallis_and_Futuna]=$'\U1F1FC\U1F1EB'
+emoji_flags[WF]=$'\U1F1FC\U1F1EB'
+emoji_flags[WLF]=$'\U1F1FC\U1F1EB'
+emoji_flags[wallis_futuna]=$'\U1F1FC\U1F1EB'
+emoji_flags[Samoa]=$'\U1F1FC\U1F1F8'
+emoji_flags[WS]=$'\U1F1FC\U1F1F8'
+emoji_flags[WSM]=$'\U1F1FC\U1F1F8'
+emoji_flags[samoa]=$'\U1F1FC\U1F1F8'
+emoji_flags[Kosovo]=$'\U1F1FD\U1F1F0'
+emoji_flags[XK]=$'\U1F1FD\U1F1F0'
+emoji_flags[XKX]=$'\U1F1FD\U1F1F0'
+emoji_flags[kosovo]=$'\U1F1FD\U1F1F0'
+emoji_flags[Yemen]=$'\U1F1FE\U1F1EA'
+emoji_flags[YE]=$'\U1F1FE\U1F1EA'
+emoji_flags[YEM]=$'\U1F1FE\U1F1EA'
+emoji_flags[yemen]=$'\U1F1FE\U1F1EA'
+emoji_flags[Mayotte]=$'\U1F1FE\U1F1F9'
+emoji_flags[YT]=$'\U1F1FE\U1F1F9'
+emoji_flags[MYT]=$'\U1F1FE\U1F1F9'
+emoji_flags[mayotte]=$'\U1F1FE\U1F1F9'
+emoji_flags[South_Africa]=$'\U1F1FF\U1F1E6'
+emoji_flags[ZA]=$'\U1F1FF\U1F1E6'
+emoji_flags[ZAF]=$'\U1F1FF\U1F1E6'
+emoji_flags[south_africa]=$'\U1F1FF\U1F1E6'
+emoji_flags[Zambia]=$'\U1F1FF\U1F1F2'
+emoji_flags[ZM]=$'\U1F1FF\U1F1F2'
+emoji_flags[ZMB]=$'\U1F1FF\U1F1F2'
+emoji_flags[zambia]=$'\U1F1FF\U1F1F2'
+emoji_flags[Zimbabwe]=$'\U1F1FF\U1F1FC'
+emoji_flags[ZW]=$'\U1F1FF\U1F1FC'
+emoji_flags[ZWE]=$'\U1F1FF\U1F1FC'
+emoji_flags[zimbabwe]=$'\U1F1FF\U1F1FC'
+emoji_flags[England]=$'\U1F3F4\UE0067\UE0062\UE0065\UE006E\UE0067\UE007F'
+emoji_flags[england]=$'\U1F3F4\UE0067\UE0062\UE0065\UE006E\UE0067\UE007F'
+emoji_flags[Scotland]=$'\U1F3F4\UE0067\UE0062\UE0073\UE0063\UE0074\UE007F'
+emoji_flags[scotland]=$'\U1F3F4\UE0067\UE0062\UE0073\UE0063\UE0074\UE007F'
+emoji_flags[Wales]=$'\U1F3F4\UE0067\UE0062\UE0077\UE006C\UE0073\UE007F'
+emoji_flags[wales]=$'\U1F3F4\UE0067\UE0062\UE0077\UE006C\UE0073\UE007F'
+
+emoji_groups[fruits]="
+  grapes
+  melon
+  watermelon
+  tangerine
+  lemon
+  banana
+  pineapple
+  mango
+  red_apple
+  green_apple
+  pear
+  peach
+  cherries
+  strawberry
+  kiwi_fruit
+  tomato
+  coconut
+"
+
+emoji_groups[vehicles]="
+  locomotive
+  railway_car
+  high_speed_train
+  bullet_train
+  bullet_train_1
+  metro
+  light_rail
+  station
+  tram
+  monorail
+  mountain_railway
+  tram_car
+  bus
+  oncoming_bus
+  trolleybus
+  minibus
+  ambulance
+  fire_engine
+  police_car
+  oncoming_police_car
+  taxi
+  oncoming_taxi
+  automobile
+  oncoming_automobile
+  sport_utility_vehicle
+  delivery_truck
+  articulated_lorry
+  tractor
+  racing_car
+  motorcycle
+  motor_scooter
+  manual_wheelchair
+  motorized_wheelchair
+  auto_rickshaw
+  bicycle
+  kick_scooter
+  skateboard
+  bus_stop
+  motorway
+  railway_track
+  oil_drum
+  fuel_pump
+  police_car_light
+  horizontal_traffic_light
+  vertical_traffic_light
+  stop_sign
+  construction
+  anchor
+  sailboat
+  canoe
+  speedboat
+  passenger_ship
+  ferry
+  motor_boat
+  ship
+  airplane
+  small_airplane
+  airplane_departure
+  airplane_arrival
+  parachute
+  seat
+  helicopter
+  suspension_railway
+  mountain_cableway
+  aerial_tramway
+  satellite
+  rocket
+  flying_saucer
+  ATM_sign
+  litter_in_bin_sign
+  potable_water
+  wheelchair_symbol
+  men_s_room
+  women_s_room
+  restroom
+  baby_symbol
+  water_closet
+  passport_control
+  customs
+  baggage_claim
+  left_luggage
+"
+
+emoji_groups[hands]="
+  waving_hand
+  waving_hand_light_skin_tone
+  waving_hand_medium_light_skin_tone
+  waving_hand_medium_skin_tone
+  waving_hand_medium_dark_skin_tone
+  waving_hand_dark_skin_tone
+  raised_back_of_hand
+  raised_back_of_hand_light_skin_tone
+  raised_back_of_hand_medium_light_skin_tone
+  raised_back_of_hand_medium_skin_tone
+  raised_back_of_hand_medium_dark_skin_tone
+  raised_back_of_hand_dark_skin_tone
+  hand_with_fingers_splayed
+  hand_with_fingers_splayed_light_skin_tone
+  hand_with_fingers_splayed_medium_light_skin_tone
+  hand_with_fingers_splayed_medium_skin_tone
+  hand_with_fingers_splayed_medium_dark_skin_tone
+  hand_with_fingers_splayed_dark_skin_tone
+  raised_hand
+  raised_hand_light_skin_tone
+  raised_hand_medium_light_skin_tone
+  raised_hand_medium_skin_tone
+  raised_hand_medium_dark_skin_tone
+  raised_hand_dark_skin_tone
+  vulcan_salute
+  vulcan_salute_light_skin_tone
+  vulcan_salute_medium_light_skin_tone
+  vulcan_salute_medium_skin_tone
+  vulcan_salute_medium_dark_skin_tone
+  vulcan_salute_dark_skin_tone
+  OK_hand
+  OK_hand_light_skin_tone
+  OK_hand_medium_light_skin_tone
+  OK_hand_medium_skin_tone
+  OK_hand_medium_dark_skin_tone
+  OK_hand_dark_skin_tone
+  pinching_hand
+  pinching_hand_light_skin_tone
+  pinching_hand_medium_light_skin_tone
+  pinching_hand_medium_skin_tone
+  pinching_hand_medium_dark_skin_tone
+  pinching_hand_dark_skin_tone
+  victory_hand
+  victory_hand_light_skin_tone
+  victory_hand_medium_light_skin_tone
+  victory_hand_medium_skin_tone
+  victory_hand_medium_dark_skin_tone
+  victory_hand_dark_skin_tone
+  crossed_fingers
+  crossed_fingers_light_skin_tone
+  crossed_fingers_medium_light_skin_tone
+  crossed_fingers_medium_skin_tone
+  crossed_fingers_medium_dark_skin_tone
+  crossed_fingers_dark_skin_tone
+  love_you_gesture
+  love_you_gesture_light_skin_tone
+  love_you_gesture_medium_light_skin_tone
+  love_you_gesture_medium_skin_tone
+  love_you_gesture_medium_dark_skin_tone
+  love_you_gesture_dark_skin_tone
+  sign_of_the_horns
+  sign_of_the_horns_light_skin_tone
+  sign_of_the_horns_medium_light_skin_tone
+  sign_of_the_horns_medium_skin_tone
+  sign_of_the_horns_medium_dark_skin_tone
+  sign_of_the_horns_dark_skin_tone
+  call_me_hand
+  call_me_hand_light_skin_tone
+  call_me_hand_medium_light_skin_tone
+  call_me_hand_medium_skin_tone
+  call_me_hand_medium_dark_skin_tone
+  call_me_hand_dark_skin_tone
+  backhand_index_pointing_left
+  backhand_index_pointing_left_light_skin_tone
+  backhand_index_pointing_left_medium_light_skin_tone
+  backhand_index_pointing_left_medium_skin_tone
+  backhand_index_pointing_left_medium_dark_skin_tone
+  backhand_index_pointing_left_dark_skin_tone
+  backhand_index_pointing_right
+  backhand_index_pointing_right_light_skin_tone
+  backhand_index_pointing_right_medium_light_skin_tone
+  backhand_index_pointing_right_medium_skin_tone
+  backhand_index_pointing_right_medium_dark_skin_tone
+  backhand_index_pointing_right_dark_skin_tone
+  backhand_index_pointing_up
+  backhand_index_pointing_up_light_skin_tone
+  backhand_index_pointing_up_medium_light_skin_tone
+  backhand_index_pointing_up_medium_skin_tone
+  backhand_index_pointing_up_medium_dark_skin_tone
+  backhand_index_pointing_up_dark_skin_tone
+  middle_finger
+  middle_finger_light_skin_tone
+  middle_finger_medium_light_skin_tone
+  middle_finger_medium_skin_tone
+  middle_finger_medium_dark_skin_tone
+  middle_finger_dark_skin_tone
+  backhand_index_pointing_down
+  backhand_index_pointing_down_light_skin_tone
+  backhand_index_pointing_down_medium_light_skin_tone
+  backhand_index_pointing_down_medium_skin_tone
+  backhand_index_pointing_down_medium_dark_skin_tone
+  backhand_index_pointing_down_dark_skin_tone
+  index_pointing_up
+  index_pointing_up_light_skin_tone
+  index_pointing_up_medium_light_skin_tone
+  index_pointing_up_medium_skin_tone
+  index_pointing_up_medium_dark_skin_tone
+  index_pointing_up_dark_skin_tone
+  thumbs_up
+  thumbs_up_light_skin_tone
+  thumbs_up_medium_light_skin_tone
+  thumbs_up_medium_skin_tone
+  thumbs_up_medium_dark_skin_tone
+  thumbs_up_dark_skin_tone
+  thumbs_down
+  thumbs_down_light_skin_tone
+  thumbs_down_medium_light_skin_tone
+  thumbs_down_medium_skin_tone
+  thumbs_down_medium_dark_skin_tone
+  thumbs_down_dark_skin_tone
+  raised_fist
+  raised_fist_light_skin_tone
+  raised_fist_medium_light_skin_tone
+  raised_fist_medium_skin_tone
+  raised_fist_medium_dark_skin_tone
+  raised_fist_dark_skin_tone
+  oncoming_fist
+  oncoming_fist_light_skin_tone
+  oncoming_fist_medium_light_skin_tone
+  oncoming_fist_medium_skin_tone
+  oncoming_fist_medium_dark_skin_tone
+  oncoming_fist_dark_skin_tone
+  left_facing_fist
+  left_facing_fist_light_skin_tone
+  left_facing_fist_medium_light_skin_tone
+  left_facing_fist_medium_skin_tone
+  left_facing_fist_medium_dark_skin_tone
+  left_facing_fist_dark_skin_tone
+  right_facing_fist
+  right_facing_fist_light_skin_tone
+  right_facing_fist_medium_light_skin_tone
+  right_facing_fist_medium_skin_tone
+  right_facing_fist_medium_dark_skin_tone
+  right_facing_fist_dark_skin_tone
+  writing_hand
+  writing_hand_light_skin_tone
+  writing_hand_medium_light_skin_tone
+  writing_hand_medium_skin_tone
+  writing_hand_medium_dark_skin_tone
+  writing_hand_dark_skin_tone
+  nail_polish
+  nail_polish_light_skin_tone
+  nail_polish_medium_light_skin_tone
+  nail_polish_medium_skin_tone
+  nail_polish_medium_dark_skin_tone
+  nail_polish_dark_skin_tone
+  selfie
+  selfie_light_skin_tone
+  selfie_medium_light_skin_tone
+  selfie_medium_skin_tone
+  selfie_medium_dark_skin_tone
+  selfie_dark_skin_tone
+"
+
+emoji_groups[people]="
+  person_frowning
+  person_frowning_light_skin_tone
+  person_frowning_medium_light_skin_tone
+  person_frowning_medium_skin_tone
+  person_frowning_medium_dark_skin_tone
+  person_frowning_dark_skin_tone
+  man_frowning
+  man_frowning_light_skin_tone
+  man_frowning_medium_light_skin_tone
+  man_frowning_medium_skin_tone
+  man_frowning_medium_dark_skin_tone
+  man_frowning_dark_skin_tone
+  woman_frowning
+  woman_frowning_light_skin_tone
+  woman_frowning_medium_light_skin_tone
+  woman_frowning_medium_skin_tone
+  woman_frowning_medium_dark_skin_tone
+  woman_frowning_dark_skin_tone
+  person_pouting
+  person_pouting_light_skin_tone
+  person_pouting_medium_light_skin_tone
+  person_pouting_medium_skin_tone
+  person_pouting_medium_dark_skin_tone
+  person_pouting_dark_skin_tone
+  man_pouting
+  man_pouting_light_skin_tone
+  man_pouting_medium_light_skin_tone
+  man_pouting_medium_skin_tone
+  man_pouting_medium_dark_skin_tone
+  man_pouting_dark_skin_tone
+  woman_pouting
+  woman_pouting_light_skin_tone
+  woman_pouting_medium_light_skin_tone
+  woman_pouting_medium_skin_tone
+  woman_pouting_medium_dark_skin_tone
+  woman_pouting_dark_skin_tone
+  person_gesturing_NO
+  person_gesturing_NO_light_skin_tone
+  person_gesturing_NO_medium_light_skin_tone
+  person_gesturing_NO_medium_skin_tone
+  person_gesturing_NO_medium_dark_skin_tone
+  person_gesturing_NO_dark_skin_tone
+  man_gesturing_NO
+  man_gesturing_NO_light_skin_tone
+  man_gesturing_NO_medium_light_skin_tone
+  man_gesturing_NO_medium_skin_tone
+  man_gesturing_NO_medium_dark_skin_tone
+  man_gesturing_NO_dark_skin_tone
+  woman_gesturing_NO
+  woman_gesturing_NO_light_skin_tone
+  woman_gesturing_NO_medium_light_skin_tone
+  woman_gesturing_NO_medium_skin_tone
+  woman_gesturing_NO_medium_dark_skin_tone
+  woman_gesturing_NO_dark_skin_tone
+  person_gesturing_OK
+  person_gesturing_OK_light_skin_tone
+  person_gesturing_OK_medium_light_skin_tone
+  person_gesturing_OK_medium_skin_tone
+  person_gesturing_OK_medium_dark_skin_tone
+  person_gesturing_OK_dark_skin_tone
+  man_gesturing_OK
+  man_gesturing_OK_light_skin_tone
+  man_gesturing_OK_medium_light_skin_tone
+  man_gesturing_OK_medium_skin_tone
+  man_gesturing_OK_medium_dark_skin_tone
+  man_gesturing_OK_dark_skin_tone
+  woman_gesturing_OK
+  woman_gesturing_OK_light_skin_tone
+  woman_gesturing_OK_medium_light_skin_tone
+  woman_gesturing_OK_medium_skin_tone
+  woman_gesturing_OK_medium_dark_skin_tone
+  woman_gesturing_OK_dark_skin_tone
+  person_tipping_hand
+  person_tipping_hand_light_skin_tone
+  person_tipping_hand_medium_light_skin_tone
+  person_tipping_hand_medium_skin_tone
+  person_tipping_hand_medium_dark_skin_tone
+  person_tipping_hand_dark_skin_tone
+  man_tipping_hand
+  man_tipping_hand_light_skin_tone
+  man_tipping_hand_medium_light_skin_tone
+  man_tipping_hand_medium_skin_tone
+  man_tipping_hand_medium_dark_skin_tone
+  man_tipping_hand_dark_skin_tone
+  woman_tipping_hand
+  woman_tipping_hand_light_skin_tone
+  woman_tipping_hand_medium_light_skin_tone
+  woman_tipping_hand_medium_skin_tone
+  woman_tipping_hand_medium_dark_skin_tone
+  woman_tipping_hand_dark_skin_tone
+  person_raising_hand
+  person_raising_hand_light_skin_tone
+  person_raising_hand_medium_light_skin_tone
+  person_raising_hand_medium_skin_tone
+  person_raising_hand_medium_dark_skin_tone
+  person_raising_hand_dark_skin_tone
+  man_raising_hand
+  man_raising_hand_light_skin_tone
+  man_raising_hand_medium_light_skin_tone
+  man_raising_hand_medium_skin_tone
+  man_raising_hand_medium_dark_skin_tone
+  man_raising_hand_dark_skin_tone
+  woman_raising_hand
+  woman_raising_hand_light_skin_tone
+  woman_raising_hand_medium_light_skin_tone
+  woman_raising_hand_medium_skin_tone
+  woman_raising_hand_medium_dark_skin_tone
+  woman_raising_hand_dark_skin_tone
+  deaf_person
+  deaf_person_light_skin_tone
+  deaf_person_medium_light_skin_tone
+  deaf_person_medium_skin_tone
+  deaf_person_medium_dark_skin_tone
+  deaf_person_dark_skin_tone
+  deaf_man
+  deaf_man_light_skin_tone
+  deaf_man_medium_light_skin_tone
+  deaf_man_medium_skin_tone
+  deaf_man_medium_dark_skin_tone
+  deaf_man_dark_skin_tone
+  deaf_woman
+  deaf_woman_light_skin_tone
+  deaf_woman_medium_light_skin_tone
+  deaf_woman_medium_skin_tone
+  deaf_woman_medium_dark_skin_tone
+  deaf_woman_dark_skin_tone
+  person_bowing
+  person_bowing_light_skin_tone
+  person_bowing_medium_light_skin_tone
+  person_bowing_medium_skin_tone
+  person_bowing_medium_dark_skin_tone
+  person_bowing_dark_skin_tone
+  man_bowing
+  man_bowing_light_skin_tone
+  man_bowing_medium_light_skin_tone
+  man_bowing_medium_skin_tone
+  man_bowing_medium_dark_skin_tone
+  man_bowing_dark_skin_tone
+  woman_bowing
+  woman_bowing_light_skin_tone
+  woman_bowing_medium_light_skin_tone
+  woman_bowing_medium_skin_tone
+  woman_bowing_medium_dark_skin_tone
+  woman_bowing_dark_skin_tone
+  person_facepalming
+  person_facepalming_light_skin_tone
+  person_facepalming_medium_light_skin_tone
+  person_facepalming_medium_skin_tone
+  person_facepalming_medium_dark_skin_tone
+  person_facepalming_dark_skin_tone
+  man_facepalming
+  man_facepalming_light_skin_tone
+  man_facepalming_medium_light_skin_tone
+  man_facepalming_medium_skin_tone
+  man_facepalming_medium_dark_skin_tone
+  man_facepalming_dark_skin_tone
+  woman_facepalming
+  woman_facepalming_light_skin_tone
+  woman_facepalming_medium_light_skin_tone
+  woman_facepalming_medium_skin_tone
+  woman_facepalming_medium_dark_skin_tone
+  woman_facepalming_dark_skin_tone
+  person_shrugging
+  person_shrugging_light_skin_tone
+  person_shrugging_medium_light_skin_tone
+  person_shrugging_medium_skin_tone
+  person_shrugging_medium_dark_skin_tone
+  person_shrugging_dark_skin_tone
+  man_shrugging
+  man_shrugging_light_skin_tone
+  man_shrugging_medium_light_skin_tone
+  man_shrugging_medium_skin_tone
+  man_shrugging_medium_dark_skin_tone
+  man_shrugging_dark_skin_tone
+  woman_shrugging
+  woman_shrugging_light_skin_tone
+  woman_shrugging_medium_light_skin_tone
+  woman_shrugging_medium_skin_tone
+  woman_shrugging_medium_dark_skin_tone
+  woman_shrugging_dark_skin_tone
+  man_health_worker
+  man_health_worker_light_skin_tone
+  man_health_worker_medium_light_skin_tone
+  man_health_worker_medium_skin_tone
+  man_health_worker_medium_dark_skin_tone
+  man_health_worker_dark_skin_tone
+  woman_health_worker
+  woman_health_worker_light_skin_tone
+  woman_health_worker_medium_light_skin_tone
+  woman_health_worker_medium_skin_tone
+  woman_health_worker_medium_dark_skin_tone
+  woman_health_worker_dark_skin_tone
+  man_student
+  man_student_light_skin_tone
+  man_student_medium_light_skin_tone
+  man_student_medium_skin_tone
+  man_student_medium_dark_skin_tone
+  man_student_dark_skin_tone
+  woman_student
+  woman_student_light_skin_tone
+  woman_student_medium_light_skin_tone
+  woman_student_medium_skin_tone
+  woman_student_medium_dark_skin_tone
+  woman_student_dark_skin_tone
+  man_teacher
+  man_teacher_light_skin_tone
+  man_teacher_medium_light_skin_tone
+  man_teacher_medium_skin_tone
+  man_teacher_medium_dark_skin_tone
+  man_teacher_dark_skin_tone
+  woman_teacher
+  woman_teacher_light_skin_tone
+  woman_teacher_medium_light_skin_tone
+  woman_teacher_medium_skin_tone
+  woman_teacher_medium_dark_skin_tone
+  woman_teacher_dark_skin_tone
+  man_judge
+  man_judge_light_skin_tone
+  man_judge_medium_light_skin_tone
+  man_judge_medium_skin_tone
+  man_judge_medium_dark_skin_tone
+  man_judge_dark_skin_tone
+  woman_judge
+  woman_judge_light_skin_tone
+  woman_judge_medium_light_skin_tone
+  woman_judge_medium_skin_tone
+  woman_judge_medium_dark_skin_tone
+  woman_judge_dark_skin_tone
+  man_farmer
+  man_farmer_light_skin_tone
+  man_farmer_medium_light_skin_tone
+  man_farmer_medium_skin_tone
+  man_farmer_medium_dark_skin_tone
+  man_farmer_dark_skin_tone
+  woman_farmer
+  woman_farmer_light_skin_tone
+  woman_farmer_medium_light_skin_tone
+  woman_farmer_medium_skin_tone
+  woman_farmer_medium_dark_skin_tone
+  woman_farmer_dark_skin_tone
+  man_cook
+  man_cook_light_skin_tone
+  man_cook_medium_light_skin_tone
+  man_cook_medium_skin_tone
+  man_cook_medium_dark_skin_tone
+  man_cook_dark_skin_tone
+  woman_cook
+  woman_cook_light_skin_tone
+  woman_cook_medium_light_skin_tone
+  woman_cook_medium_skin_tone
+  woman_cook_medium_dark_skin_tone
+  woman_cook_dark_skin_tone
+  man_mechanic
+  man_mechanic_light_skin_tone
+  man_mechanic_medium_light_skin_tone
+  man_mechanic_medium_skin_tone
+  man_mechanic_medium_dark_skin_tone
+  man_mechanic_dark_skin_tone
+  woman_mechanic
+  woman_mechanic_light_skin_tone
+  woman_mechanic_medium_light_skin_tone
+  woman_mechanic_medium_skin_tone
+  woman_mechanic_medium_dark_skin_tone
+  woman_mechanic_dark_skin_tone
+  man_factory_worker
+  man_factory_worker_light_skin_tone
+  man_factory_worker_medium_light_skin_tone
+  man_factory_worker_medium_skin_tone
+  man_factory_worker_medium_dark_skin_tone
+  man_factory_worker_dark_skin_tone
+  woman_factory_worker
+  woman_factory_worker_light_skin_tone
+  woman_factory_worker_medium_light_skin_tone
+  woman_factory_worker_medium_skin_tone
+  woman_factory_worker_medium_dark_skin_tone
+  woman_factory_worker_dark_skin_tone
+  man_office_worker
+  man_office_worker_light_skin_tone
+  man_office_worker_medium_light_skin_tone
+  man_office_worker_medium_skin_tone
+  man_office_worker_medium_dark_skin_tone
+  man_office_worker_dark_skin_tone
+  woman_office_worker
+  woman_office_worker_light_skin_tone
+  woman_office_worker_medium_light_skin_tone
+  woman_office_worker_medium_skin_tone
+  woman_office_worker_medium_dark_skin_tone
+  woman_office_worker_dark_skin_tone
+  man_scientist
+  man_scientist_light_skin_tone
+  man_scientist_medium_light_skin_tone
+  man_scientist_medium_skin_tone
+  man_scientist_medium_dark_skin_tone
+  man_scientist_dark_skin_tone
+  woman_scientist
+  woman_scientist_light_skin_tone
+  woman_scientist_medium_light_skin_tone
+  woman_scientist_medium_skin_tone
+  woman_scientist_medium_dark_skin_tone
+  woman_scientist_dark_skin_tone
+  man_technologist
+  man_technologist_light_skin_tone
+  man_technologist_medium_light_skin_tone
+  man_technologist_medium_skin_tone
+  man_technologist_medium_dark_skin_tone
+  man_technologist_dark_skin_tone
+  woman_technologist
+  woman_technologist_light_skin_tone
+  woman_technologist_medium_light_skin_tone
+  woman_technologist_medium_skin_tone
+  woman_technologist_medium_dark_skin_tone
+  woman_technologist_dark_skin_tone
+  man_singer
+  man_singer_light_skin_tone
+  man_singer_medium_light_skin_tone
+  man_singer_medium_skin_tone
+  man_singer_medium_dark_skin_tone
+  man_singer_dark_skin_tone
+  woman_singer
+  woman_singer_light_skin_tone
+  woman_singer_medium_light_skin_tone
+  woman_singer_medium_skin_tone
+  woman_singer_medium_dark_skin_tone
+  woman_singer_dark_skin_tone
+  man_artist
+  man_artist_light_skin_tone
+  man_artist_medium_light_skin_tone
+  man_artist_medium_skin_tone
+  man_artist_medium_dark_skin_tone
+  man_artist_dark_skin_tone
+  woman_artist
+  woman_artist_light_skin_tone
+  woman_artist_medium_light_skin_tone
+  woman_artist_medium_skin_tone
+  woman_artist_medium_dark_skin_tone
+  woman_artist_dark_skin_tone
+  man_pilot
+  man_pilot_light_skin_tone
+  man_pilot_medium_light_skin_tone
+  man_pilot_medium_skin_tone
+  man_pilot_medium_dark_skin_tone
+  man_pilot_dark_skin_tone
+  woman_pilot
+  woman_pilot_light_skin_tone
+  woman_pilot_medium_light_skin_tone
+  woman_pilot_medium_skin_tone
+  woman_pilot_medium_dark_skin_tone
+  woman_pilot_dark_skin_tone
+  man_astronaut
+  man_astronaut_light_skin_tone
+  man_astronaut_medium_light_skin_tone
+  man_astronaut_medium_skin_tone
+  man_astronaut_medium_dark_skin_tone
+  man_astronaut_dark_skin_tone
+  woman_astronaut
+  woman_astronaut_light_skin_tone
+  woman_astronaut_medium_light_skin_tone
+  woman_astronaut_medium_skin_tone
+  woman_astronaut_medium_dark_skin_tone
+  woman_astronaut_dark_skin_tone
+  man_firefighter
+  man_firefighter_light_skin_tone
+  man_firefighter_medium_light_skin_tone
+  man_firefighter_medium_skin_tone
+  man_firefighter_medium_dark_skin_tone
+  man_firefighter_dark_skin_tone
+  woman_firefighter
+  woman_firefighter_light_skin_tone
+  woman_firefighter_medium_light_skin_tone
+  woman_firefighter_medium_skin_tone
+  woman_firefighter_medium_dark_skin_tone
+  woman_firefighter_dark_skin_tone
+  police_officer
+  police_officer_light_skin_tone
+  police_officer_medium_light_skin_tone
+  police_officer_medium_skin_tone
+  police_officer_medium_dark_skin_tone
+  police_officer_dark_skin_tone
+  man_police_officer
+  man_police_officer_light_skin_tone
+  man_police_officer_medium_light_skin_tone
+  man_police_officer_medium_skin_tone
+  man_police_officer_medium_dark_skin_tone
+  man_police_officer_dark_skin_tone
+  woman_police_officer
+  woman_police_officer_light_skin_tone
+  woman_police_officer_medium_light_skin_tone
+  woman_police_officer_medium_skin_tone
+  woman_police_officer_medium_dark_skin_tone
+  woman_police_officer_dark_skin_tone
+  detective
+  detective_light_skin_tone
+  detective_medium_light_skin_tone
+  detective_medium_skin_tone
+  detective_medium_dark_skin_tone
+  detective_dark_skin_tone
+  man_detective
+  man_detective_light_skin_tone
+  man_detective_medium_light_skin_tone
+  man_detective_medium_skin_tone
+  man_detective_medium_dark_skin_tone
+  man_detective_dark_skin_tone
+  woman_detective
+  woman_detective_light_skin_tone
+  woman_detective_medium_light_skin_tone
+  woman_detective_medium_skin_tone
+  woman_detective_medium_dark_skin_tone
+  woman_detective_dark_skin_tone
+  guard
+  guard_light_skin_tone
+  guard_medium_light_skin_tone
+  guard_medium_skin_tone
+  guard_medium_dark_skin_tone
+  guard_dark_skin_tone
+  man_guard
+  man_guard_light_skin_tone
+  man_guard_medium_light_skin_tone
+  man_guard_medium_skin_tone
+  man_guard_medium_dark_skin_tone
+  man_guard_dark_skin_tone
+  woman_guard
+  woman_guard_light_skin_tone
+  woman_guard_medium_light_skin_tone
+  woman_guard_medium_skin_tone
+  woman_guard_medium_dark_skin_tone
+  woman_guard_dark_skin_tone
+  construction_worker
+  construction_worker_light_skin_tone
+  construction_worker_medium_light_skin_tone
+  construction_worker_medium_skin_tone
+  construction_worker_medium_dark_skin_tone
+  construction_worker_dark_skin_tone
+  man_construction_worker
+  man_construction_worker_light_skin_tone
+  man_construction_worker_medium_light_skin_tone
+  man_construction_worker_medium_skin_tone
+  man_construction_worker_medium_dark_skin_tone
+  man_construction_worker_dark_skin_tone
+  woman_construction_worker
+  woman_construction_worker_light_skin_tone
+  woman_construction_worker_medium_light_skin_tone
+  woman_construction_worker_medium_skin_tone
+  woman_construction_worker_medium_dark_skin_tone
+  woman_construction_worker_dark_skin_tone
+  prince
+  prince_light_skin_tone
+  prince_medium_light_skin_tone
+  prince_medium_skin_tone
+  prince_medium_dark_skin_tone
+  prince_dark_skin_tone
+  princess
+  princess_light_skin_tone
+  princess_medium_light_skin_tone
+  princess_medium_skin_tone
+  princess_medium_dark_skin_tone
+  princess_dark_skin_tone
+  person_wearing_turban
+  person_wearing_turban_light_skin_tone
+  person_wearing_turban_medium_light_skin_tone
+  person_wearing_turban_medium_skin_tone
+  person_wearing_turban_medium_dark_skin_tone
+  person_wearing_turban_dark_skin_tone
+  man_wearing_turban
+  man_wearing_turban_light_skin_tone
+  man_wearing_turban_medium_light_skin_tone
+  man_wearing_turban_medium_skin_tone
+  man_wearing_turban_medium_dark_skin_tone
+  man_wearing_turban_dark_skin_tone
+  woman_wearing_turban
+  woman_wearing_turban_light_skin_tone
+  woman_wearing_turban_medium_light_skin_tone
+  woman_wearing_turban_medium_skin_tone
+  woman_wearing_turban_medium_dark_skin_tone
+  woman_wearing_turban_dark_skin_tone
+  man_with_Chinese_cap
+  man_with_Chinese_cap_light_skin_tone
+  man_with_Chinese_cap_medium_light_skin_tone
+  man_with_Chinese_cap_medium_skin_tone
+  man_with_Chinese_cap_medium_dark_skin_tone
+  man_with_Chinese_cap_dark_skin_tone
+  woman_with_headscarf
+  woman_with_headscarf_light_skin_tone
+  woman_with_headscarf_medium_light_skin_tone
+  woman_with_headscarf_medium_skin_tone
+  woman_with_headscarf_medium_dark_skin_tone
+  woman_with_headscarf_dark_skin_tone
+  man_in_tuxedo
+  man_in_tuxedo_light_skin_tone
+  man_in_tuxedo_medium_light_skin_tone
+  man_in_tuxedo_medium_skin_tone
+  man_in_tuxedo_medium_dark_skin_tone
+  man_in_tuxedo_dark_skin_tone
+  bride_with_veil
+  bride_with_veil_light_skin_tone
+  bride_with_veil_medium_light_skin_tone
+  bride_with_veil_medium_skin_tone
+  bride_with_veil_medium_dark_skin_tone
+  bride_with_veil_dark_skin_tone
+  pregnant_woman
+  pregnant_woman_light_skin_tone
+  pregnant_woman_medium_light_skin_tone
+  pregnant_woman_medium_skin_tone
+  pregnant_woman_medium_dark_skin_tone
+  pregnant_woman_dark_skin_tone
+  breast_feeding
+  breast_feeding_light_skin_tone
+  breast_feeding_medium_light_skin_tone
+  breast_feeding_medium_skin_tone
+  breast_feeding_medium_dark_skin_tone
+  breast_feeding_dark_skin_tone
+  baby_angel
+  baby_angel_light_skin_tone
+  baby_angel_medium_light_skin_tone
+  baby_angel_medium_skin_tone
+  baby_angel_medium_dark_skin_tone
+  baby_angel_dark_skin_tone
+  Santa_Claus
+  Santa_Claus_light_skin_tone
+  Santa_Claus_medium_light_skin_tone
+  Santa_Claus_medium_skin_tone
+  Santa_Claus_medium_dark_skin_tone
+  Santa_Claus_dark_skin_tone
+  Mrs_Claus
+  Mrs_Claus_light_skin_tone
+  Mrs_Claus_medium_light_skin_tone
+  Mrs_Claus_medium_skin_tone
+  Mrs_Claus_medium_dark_skin_tone
+  Mrs_Claus_dark_skin_tone
+  superhero
+  superhero_light_skin_tone
+  superhero_medium_light_skin_tone
+  superhero_medium_skin_tone
+  superhero_medium_dark_skin_tone
+  superhero_dark_skin_tone
+  man_superhero
+  man_superhero_light_skin_tone
+  man_superhero_medium_light_skin_tone
+  man_superhero_medium_skin_tone
+  man_superhero_medium_dark_skin_tone
+  man_superhero_dark_skin_tone
+  woman_superhero
+  woman_superhero_light_skin_tone
+  woman_superhero_medium_light_skin_tone
+  woman_superhero_medium_skin_tone
+  woman_superhero_medium_dark_skin_tone
+  woman_superhero_dark_skin_tone
+  supervillain
+  supervillain_light_skin_tone
+  supervillain_medium_light_skin_tone
+  supervillain_medium_skin_tone
+  supervillain_medium_dark_skin_tone
+  supervillain_dark_skin_tone
+  man_supervillain
+  man_supervillain_light_skin_tone
+  man_supervillain_medium_light_skin_tone
+  man_supervillain_medium_skin_tone
+  man_supervillain_medium_dark_skin_tone
+  man_supervillain_dark_skin_tone
+  woman_supervillain
+  woman_supervillain_light_skin_tone
+  woman_supervillain_medium_light_skin_tone
+  woman_supervillain_medium_skin_tone
+  woman_supervillain_medium_dark_skin_tone
+  woman_supervillain_dark_skin_tone
+  mage
+  mage_light_skin_tone
+  mage_medium_light_skin_tone
+  mage_medium_skin_tone
+  mage_medium_dark_skin_tone
+  mage_dark_skin_tone
+  man_mage
+  man_mage_light_skin_tone
+  man_mage_medium_light_skin_tone
+  man_mage_medium_skin_tone
+  man_mage_medium_dark_skin_tone
+  man_mage_dark_skin_tone
+  woman_mage
+  woman_mage_light_skin_tone
+  woman_mage_medium_light_skin_tone
+  woman_mage_medium_skin_tone
+  woman_mage_medium_dark_skin_tone
+  woman_mage_dark_skin_tone
+  fairy
+  fairy_light_skin_tone
+  fairy_medium_light_skin_tone
+  fairy_medium_skin_tone
+  fairy_medium_dark_skin_tone
+  fairy_dark_skin_tone
+  man_fairy
+  man_fairy_light_skin_tone
+  man_fairy_medium_light_skin_tone
+  man_fairy_medium_skin_tone
+  man_fairy_medium_dark_skin_tone
+  man_fairy_dark_skin_tone
+  woman_fairy
+  woman_fairy_light_skin_tone
+  woman_fairy_medium_light_skin_tone
+  woman_fairy_medium_skin_tone
+  woman_fairy_medium_dark_skin_tone
+  woman_fairy_dark_skin_tone
+  vampire
+  vampire_light_skin_tone
+  vampire_medium_light_skin_tone
+  vampire_medium_skin_tone
+  vampire_medium_dark_skin_tone
+  vampire_dark_skin_tone
+  man_vampire
+  man_vampire_light_skin_tone
+  man_vampire_medium_light_skin_tone
+  man_vampire_medium_skin_tone
+  man_vampire_medium_dark_skin_tone
+  man_vampire_dark_skin_tone
+  woman_vampire
+  woman_vampire_light_skin_tone
+  woman_vampire_medium_light_skin_tone
+  woman_vampire_medium_skin_tone
+  woman_vampire_medium_dark_skin_tone
+  woman_vampire_dark_skin_tone
+  merperson
+  merperson_light_skin_tone
+  merperson_medium_light_skin_tone
+  merperson_medium_skin_tone
+  merperson_medium_dark_skin_tone
+  merperson_dark_skin_tone
+  merman
+  merman_light_skin_tone
+  merman_medium_light_skin_tone
+  merman_medium_skin_tone
+  merman_medium_dark_skin_tone
+  merman_dark_skin_tone
+  mermaid
+  mermaid_light_skin_tone
+  mermaid_medium_light_skin_tone
+  mermaid_medium_skin_tone
+  mermaid_medium_dark_skin_tone
+  mermaid_dark_skin_tone
+  elf
+  elf_light_skin_tone
+  elf_medium_light_skin_tone
+  elf_medium_skin_tone
+  elf_medium_dark_skin_tone
+  elf_dark_skin_tone
+  man_elf
+  man_elf_light_skin_tone
+  man_elf_medium_light_skin_tone
+  man_elf_medium_skin_tone
+  man_elf_medium_dark_skin_tone
+  man_elf_dark_skin_tone
+  woman_elf
+  woman_elf_light_skin_tone
+  woman_elf_medium_light_skin_tone
+  woman_elf_medium_skin_tone
+  woman_elf_medium_dark_skin_tone
+  woman_elf_dark_skin_tone
+  genie
+  man_genie
+  woman_genie
+  zombie
+  man_zombie
+  woman_zombie
+  person_getting_massage
+  person_getting_massage_light_skin_tone
+  person_getting_massage_medium_light_skin_tone
+  person_getting_massage_medium_skin_tone
+  person_getting_massage_medium_dark_skin_tone
+  person_getting_massage_dark_skin_tone
+  man_getting_massage
+  man_getting_massage_light_skin_tone
+  man_getting_massage_medium_light_skin_tone
+  man_getting_massage_medium_skin_tone
+  man_getting_massage_medium_dark_skin_tone
+  man_getting_massage_dark_skin_tone
+  woman_getting_massage
+  woman_getting_massage_light_skin_tone
+  woman_getting_massage_medium_light_skin_tone
+  woman_getting_massage_medium_skin_tone
+  woman_getting_massage_medium_dark_skin_tone
+  woman_getting_massage_dark_skin_tone
+  person_getting_haircut
+  person_getting_haircut_light_skin_tone
+  person_getting_haircut_medium_light_skin_tone
+  person_getting_haircut_medium_skin_tone
+  person_getting_haircut_medium_dark_skin_tone
+  person_getting_haircut_dark_skin_tone
+  man_getting_haircut
+  man_getting_haircut_light_skin_tone
+  man_getting_haircut_medium_light_skin_tone
+  man_getting_haircut_medium_skin_tone
+  man_getting_haircut_medium_dark_skin_tone
+  man_getting_haircut_dark_skin_tone
+  woman_getting_haircut
+  woman_getting_haircut_light_skin_tone
+  woman_getting_haircut_medium_light_skin_tone
+  woman_getting_haircut_medium_skin_tone
+  woman_getting_haircut_medium_dark_skin_tone
+  woman_getting_haircut_dark_skin_tone
+  person_walking
+  person_walking_light_skin_tone
+  person_walking_medium_light_skin_tone
+  person_walking_medium_skin_tone
+  person_walking_medium_dark_skin_tone
+  person_walking_dark_skin_tone
+  man_walking
+  man_walking_light_skin_tone
+  man_walking_medium_light_skin_tone
+  man_walking_medium_skin_tone
+  man_walking_medium_dark_skin_tone
+  man_walking_dark_skin_tone
+  woman_walking
+  woman_walking_light_skin_tone
+  woman_walking_medium_light_skin_tone
+  woman_walking_medium_skin_tone
+  woman_walking_medium_dark_skin_tone
+  woman_walking_dark_skin_tone
+  person_standing
+  person_standing_light_skin_tone
+  person_standing_medium_light_skin_tone
+  person_standing_medium_skin_tone
+  person_standing_medium_dark_skin_tone
+  person_standing_dark_skin_tone
+  man_standing
+  man_standing_light_skin_tone
+  man_standing_medium_light_skin_tone
+  man_standing_medium_skin_tone
+  man_standing_medium_dark_skin_tone
+  man_standing_dark_skin_tone
+  woman_standing
+  woman_standing_light_skin_tone
+  woman_standing_medium_light_skin_tone
+  woman_standing_medium_skin_tone
+  woman_standing_medium_dark_skin_tone
+  woman_standing_dark_skin_tone
+  person_kneeling
+  person_kneeling_light_skin_tone
+  person_kneeling_medium_light_skin_tone
+  person_kneeling_medium_skin_tone
+  person_kneeling_medium_dark_skin_tone
+  person_kneeling_dark_skin_tone
+  man_kneeling
+  man_kneeling_light_skin_tone
+  man_kneeling_medium_light_skin_tone
+  man_kneeling_medium_skin_tone
+  man_kneeling_medium_dark_skin_tone
+  man_kneeling_dark_skin_tone
+  woman_kneeling
+  woman_kneeling_light_skin_tone
+  woman_kneeling_medium_light_skin_tone
+  woman_kneeling_medium_skin_tone
+  woman_kneeling_medium_dark_skin_tone
+  woman_kneeling_dark_skin_tone
+  man_with_probing_cane
+  man_with_probing_cane_light_skin_tone
+  man_with_probing_cane_medium_light_skin_tone
+  man_with_probing_cane_medium_skin_tone
+  man_with_probing_cane_medium_dark_skin_tone
+  man_with_probing_cane_dark_skin_tone
+  woman_with_probing_cane
+  woman_with_probing_cane_light_skin_tone
+  woman_with_probing_cane_medium_light_skin_tone
+  woman_with_probing_cane_medium_skin_tone
+  woman_with_probing_cane_medium_dark_skin_tone
+  woman_with_probing_cane_dark_skin_tone
+  man_in_motorized_wheelchair
+  man_in_motorized_wheelchair_light_skin_tone
+  man_in_motorized_wheelchair_medium_light_skin_tone
+  man_in_motorized_wheelchair_medium_skin_tone
+  man_in_motorized_wheelchair_medium_dark_skin_tone
+  man_in_motorized_wheelchair_dark_skin_tone
+  woman_in_motorized_wheelchair
+  woman_in_motorized_wheelchair_light_skin_tone
+  woman_in_motorized_wheelchair_medium_light_skin_tone
+  woman_in_motorized_wheelchair_medium_skin_tone
+  woman_in_motorized_wheelchair_medium_dark_skin_tone
+  woman_in_motorized_wheelchair_dark_skin_tone
+  man_in_manual_wheelchair
+  man_in_manual_wheelchair_light_skin_tone
+  man_in_manual_wheelchair_medium_light_skin_tone
+  man_in_manual_wheelchair_medium_skin_tone
+  man_in_manual_wheelchair_medium_dark_skin_tone
+  man_in_manual_wheelchair_dark_skin_tone
+  woman_in_manual_wheelchair
+  woman_in_manual_wheelchair_light_skin_tone
+  woman_in_manual_wheelchair_medium_light_skin_tone
+  woman_in_manual_wheelchair_medium_skin_tone
+  woman_in_manual_wheelchair_medium_dark_skin_tone
+  woman_in_manual_wheelchair_dark_skin_tone
+  person_running
+  person_running_light_skin_tone
+  person_running_medium_light_skin_tone
+  person_running_medium_skin_tone
+  person_running_medium_dark_skin_tone
+  person_running_dark_skin_tone
+  man_running
+  man_running_light_skin_tone
+  man_running_medium_light_skin_tone
+  man_running_medium_skin_tone
+  man_running_medium_dark_skin_tone
+  man_running_dark_skin_tone
+  woman_running
+  woman_running_light_skin_tone
+  woman_running_medium_light_skin_tone
+  woman_running_medium_skin_tone
+  woman_running_medium_dark_skin_tone
+  woman_running_dark_skin_tone
+  woman_dancing
+  woman_dancing_light_skin_tone
+  woman_dancing_medium_light_skin_tone
+  woman_dancing_medium_skin_tone
+  woman_dancing_medium_dark_skin_tone
+  woman_dancing_dark_skin_tone
+  woman_dancing_dark_skin_tone_1
+  man_dancing_light_skin_tone
+  man_dancing_medium_light_skin_tone
+  man_dancing_medium_skin_tone
+  man_dancing_medium_dark_skin_tone
+  man_dancing_dark_skin_tone
+  man_in_suit_levitating
+  man_in_suit_levitating_light_skin_tone
+  man_in_suit_levitating_medium_light_skin_tone
+  man_in_suit_levitating_medium_skin_tone
+  man_in_suit_levitating_medium_dark_skin_tone
+  man_in_suit_levitating_dark_skin_tone
+  people_with_bunny_ears
+  men_with_bunny_ears
+  women_with_bunny_ears
+  person_in_steamy_room
+  person_in_steamy_room_light_skin_tone
+  person_in_steamy_room_medium_light_skin_tone
+  person_in_steamy_room_medium_skin_tone
+  person_in_steamy_room_medium_dark_skin_tone
+  person_in_steamy_room_dark_skin_tone
+  man_in_steamy_room
+  man_in_steamy_room_light_skin_tone
+  man_in_steamy_room_medium_light_skin_tone
+  man_in_steamy_room_medium_skin_tone
+  man_in_steamy_room_medium_dark_skin_tone
+  man_in_steamy_room_dark_skin_tone
+  woman_in_steamy_room
+  woman_in_steamy_room_light_skin_tone
+  woman_in_steamy_room_medium_light_skin_tone
+  woman_in_steamy_room_medium_skin_tone
+  woman_in_steamy_room_medium_dark_skin_tone
+  woman_in_steamy_room_dark_skin_tone
+  person_climbing
+  person_climbing_light_skin_tone
+  person_climbing_medium_light_skin_tone
+  person_climbing_medium_skin_tone
+  person_climbing_medium_dark_skin_tone
+  person_climbing_dark_skin_tone
+  man_climbing
+  man_climbing_light_skin_tone
+  man_climbing_medium_light_skin_tone
+  man_climbing_medium_skin_tone
+  man_climbing_medium_dark_skin_tone
+  man_climbing_dark_skin_tone
+  woman_climbing
+  woman_climbing_light_skin_tone
+  woman_climbing_medium_light_skin_tone
+  woman_climbing_medium_skin_tone
+  woman_climbing_medium_dark_skin_tone
+  woman_climbing_dark_skin_tone
+  person_fencing
+  horse_racing
+  horse_racing_light_skin_tone
+  horse_racing_medium_light_skin_tone
+  horse_racing_medium_skin_tone
+  horse_racing_medium_dark_skin_tone
+  horse_racing_dark_skin_tone
+  skier
+  snowboarder
+  snowboarder_light_skin_tone
+  snowboarder_medium_light_skin_tone
+  snowboarder_medium_skin_tone
+  snowboarder_medium_dark_skin_tone
+  snowboarder_dark_skin_tone
+  person_golfing
+  person_golfing_light_skin_tone
+  person_golfing_medium_light_skin_tone
+  person_golfing_medium_skin_tone
+  person_golfing_medium_dark_skin_tone
+  person_golfing_dark_skin_tone
+  man_golfing
+  man_golfing_light_skin_tone
+  man_golfing_medium_light_skin_tone
+  man_golfing_medium_skin_tone
+  man_golfing_medium_dark_skin_tone
+  man_golfing_dark_skin_tone
+  woman_golfing
+  woman_golfing_light_skin_tone
+  woman_golfing_medium_light_skin_tone
+  woman_golfing_medium_skin_tone
+  woman_golfing_medium_dark_skin_tone
+  woman_golfing_dark_skin_tone
+  person_surfing
+  person_surfing_light_skin_tone
+  person_surfing_medium_light_skin_tone
+  person_surfing_medium_skin_tone
+  person_surfing_medium_dark_skin_tone
+  person_surfing_dark_skin_tone
+  man_surfing
+  man_surfing_light_skin_tone
+  man_surfing_medium_light_skin_tone
+  man_surfing_medium_skin_tone
+  man_surfing_medium_dark_skin_tone
+  man_surfing_dark_skin_tone
+  woman_surfing
+  woman_surfing_light_skin_tone
+  woman_surfing_medium_light_skin_tone
+  woman_surfing_medium_skin_tone
+  woman_surfing_medium_dark_skin_tone
+  woman_surfing_dark_skin_tone
+  person_rowing_boat
+  person_rowing_boat_light_skin_tone
+  person_rowing_boat_medium_light_skin_tone
+  person_rowing_boat_medium_skin_tone
+  person_rowing_boat_medium_dark_skin_tone
+  person_rowing_boat_dark_skin_tone
+  man_rowing_boat
+  man_rowing_boat_light_skin_tone
+  man_rowing_boat_medium_light_skin_tone
+  man_rowing_boat_medium_skin_tone
+  man_rowing_boat_medium_dark_skin_tone
+  man_rowing_boat_dark_skin_tone
+  woman_rowing_boat
+  woman_rowing_boat_light_skin_tone
+  woman_rowing_boat_medium_light_skin_tone
+  woman_rowing_boat_medium_skin_tone
+  woman_rowing_boat_medium_dark_skin_tone
+  woman_rowing_boat_dark_skin_tone
+  person_swimming
+  person_swimming_light_skin_tone
+  person_swimming_medium_light_skin_tone
+  person_swimming_medium_skin_tone
+  person_swimming_medium_dark_skin_tone
+  person_swimming_dark_skin_tone
+  man_swimming
+  man_swimming_light_skin_tone
+  man_swimming_medium_light_skin_tone
+  man_swimming_medium_skin_tone
+  man_swimming_medium_dark_skin_tone
+  man_swimming_dark_skin_tone
+  woman_swimming
+  woman_swimming_light_skin_tone
+  woman_swimming_medium_light_skin_tone
+  woman_swimming_medium_skin_tone
+  woman_swimming_medium_dark_skin_tone
+  woman_swimming_dark_skin_tone
+  person_bouncing_ball
+  person_bouncing_ball_light_skin_tone
+  person_bouncing_ball_medium_light_skin_tone
+  person_bouncing_ball_medium_skin_tone
+  person_bouncing_ball_medium_dark_skin_tone
+  person_bouncing_ball_dark_skin_tone
+  man_bouncing_ball
+  man_bouncing_ball_light_skin_tone
+  man_bouncing_ball_medium_light_skin_tone
+  man_bouncing_ball_medium_skin_tone
+  man_bouncing_ball_medium_dark_skin_tone
+  man_bouncing_ball_dark_skin_tone
+  woman_bouncing_ball
+  woman_bouncing_ball_light_skin_tone
+  woman_bouncing_ball_medium_light_skin_tone
+  woman_bouncing_ball_medium_skin_tone
+  woman_bouncing_ball_medium_dark_skin_tone
+  woman_bouncing_ball_dark_skin_tone
+  person_lifting_weights
+  person_lifting_weights_light_skin_tone
+  person_lifting_weights_medium_light_skin_tone
+  person_lifting_weights_medium_skin_tone
+  person_lifting_weights_medium_dark_skin_tone
+  person_lifting_weights_dark_skin_tone
+  man_lifting_weights
+  man_lifting_weights_light_skin_tone
+  man_lifting_weights_medium_light_skin_tone
+  man_lifting_weights_medium_skin_tone
+  man_lifting_weights_medium_dark_skin_tone
+  man_lifting_weights_dark_skin_tone
+  woman_lifting_weights
+  woman_lifting_weights_light_skin_tone
+  woman_lifting_weights_medium_light_skin_tone
+  woman_lifting_weights_medium_skin_tone
+  woman_lifting_weights_medium_dark_skin_tone
+  woman_lifting_weights_dark_skin_tone
+  person_biking
+  person_biking_light_skin_tone
+  person_biking_medium_light_skin_tone
+  person_biking_medium_skin_tone
+  person_biking_medium_dark_skin_tone
+  person_biking_dark_skin_tone
+  man_biking
+  man_biking_light_skin_tone
+  man_biking_medium_light_skin_tone
+  man_biking_medium_skin_tone
+  man_biking_medium_dark_skin_tone
+  man_biking_dark_skin_tone
+  woman_biking
+  woman_biking_light_skin_tone
+  woman_biking_medium_light_skin_tone
+  woman_biking_medium_skin_tone
+  woman_biking_medium_dark_skin_tone
+  woman_biking_dark_skin_tone
+  person_mountain_biking
+  person_mountain_biking_light_skin_tone
+  person_mountain_biking_medium_light_skin_tone
+  person_mountain_biking_medium_skin_tone
+  person_mountain_biking_medium_dark_skin_tone
+  person_mountain_biking_dark_skin_tone
+  man_mountain_biking
+  man_mountain_biking_light_skin_tone
+  man_mountain_biking_medium_light_skin_tone
+  man_mountain_biking_medium_skin_tone
+  man_mountain_biking_medium_dark_skin_tone
+  man_mountain_biking_dark_skin_tone
+  woman_mountain_biking
+  woman_mountain_biking_light_skin_tone
+  woman_mountain_biking_medium_light_skin_tone
+  woman_mountain_biking_medium_skin_tone
+  woman_mountain_biking_medium_dark_skin_tone
+  woman_mountain_biking_dark_skin_tone
+  person_cartwheeling
+  person_cartwheeling_light_skin_tone
+  person_cartwheeling_medium_light_skin_tone
+  person_cartwheeling_medium_skin_tone
+  person_cartwheeling_medium_dark_skin_tone
+  person_cartwheeling_dark_skin_tone
+  man_cartwheeling
+  man_cartwheeling_light_skin_tone
+  man_cartwheeling_medium_light_skin_tone
+  man_cartwheeling_medium_skin_tone
+  man_cartwheeling_medium_dark_skin_tone
+  man_cartwheeling_dark_skin_tone
+  woman_cartwheeling
+  woman_cartwheeling_light_skin_tone
+  woman_cartwheeling_medium_light_skin_tone
+  woman_cartwheeling_medium_skin_tone
+  woman_cartwheeling_medium_dark_skin_tone
+  woman_cartwheeling_dark_skin_tone
+  people_wrestling
+  men_wrestling
+  women_wrestling
+  person_playing_water_polo
+  person_playing_water_polo_light_skin_tone
+  person_playing_water_polo_medium_light_skin_tone
+  person_playing_water_polo_medium_skin_tone
+  person_playing_water_polo_medium_dark_skin_tone
+  person_playing_water_polo_dark_skin_tone
+  man_playing_water_polo
+  man_playing_water_polo_light_skin_tone
+  man_playing_water_polo_medium_light_skin_tone
+  man_playing_water_polo_medium_skin_tone
+  man_playing_water_polo_medium_dark_skin_tone
+  man_playing_water_polo_dark_skin_tone
+  woman_playing_water_polo
+  woman_playing_water_polo_light_skin_tone
+  woman_playing_water_polo_medium_light_skin_tone
+  woman_playing_water_polo_medium_skin_tone
+  woman_playing_water_polo_medium_dark_skin_tone
+  woman_playing_water_polo_dark_skin_tone
+  person_playing_handball
+  person_playing_handball_light_skin_tone
+  person_playing_handball_medium_light_skin_tone
+  person_playing_handball_medium_skin_tone
+  person_playing_handball_medium_dark_skin_tone
+  person_playing_handball_dark_skin_tone
+  man_playing_handball
+  man_playing_handball_light_skin_tone
+  man_playing_handball_medium_light_skin_tone
+  man_playing_handball_medium_skin_tone
+  man_playing_handball_medium_dark_skin_tone
+  man_playing_handball_dark_skin_tone
+  woman_playing_handball
+  woman_playing_handball_light_skin_tone
+  woman_playing_handball_medium_light_skin_tone
+  woman_playing_handball_medium_skin_tone
+  woman_playing_handball_medium_dark_skin_tone
+  woman_playing_handball_dark_skin_tone
+  person_juggling
+  person_juggling_light_skin_tone
+  person_juggling_medium_light_skin_tone
+  person_juggling_medium_skin_tone
+  person_juggling_medium_dark_skin_tone
+  person_juggling_dark_skin_tone
+  man_juggling
+  man_juggling_light_skin_tone
+  man_juggling_medium_light_skin_tone
+  man_juggling_medium_skin_tone
+  man_juggling_medium_dark_skin_tone
+  man_juggling_dark_skin_tone
+  woman_juggling
+  woman_juggling_light_skin_tone
+  woman_juggling_medium_light_skin_tone
+  woman_juggling_medium_skin_tone
+  woman_juggling_medium_dark_skin_tone
+  woman_juggling_dark_skin_tone
+  person_in_lotus_position
+  person_in_lotus_position_light_skin_tone
+  person_in_lotus_position_medium_light_skin_tone
+  person_in_lotus_position_medium_skin_tone
+  person_in_lotus_position_medium_dark_skin_tone
+  person_in_lotus_position_dark_skin_tone
+  man_in_lotus_position
+  man_in_lotus_position_light_skin_tone
+  man_in_lotus_position_medium_light_skin_tone
+  man_in_lotus_position_medium_skin_tone
+  man_in_lotus_position_medium_dark_skin_tone
+  man_in_lotus_position_dark_skin_tone
+  woman_in_lotus_position
+  woman_in_lotus_position_light_skin_tone
+  woman_in_lotus_position_medium_light_skin_tone
+  woman_in_lotus_position_medium_skin_tone
+  woman_in_lotus_position_medium_dark_skin_tone
+  woman_in_lotus_position_dark_skin_tone
+  person_taking_bath
+  person_taking_bath_light_skin_tone
+  person_taking_bath_medium_light_skin_tone
+  person_taking_bath_medium_skin_tone
+  person_taking_bath_medium_dark_skin_tone
+  person_taking_bath_dark_skin_tone
+  person_in_bed
+  person_in_bed_light_skin_tone
+  person_in_bed_medium_light_skin_tone
+  person_in_bed_medium_skin_tone
+  person_in_bed_medium_dark_skin_tone
+  person_in_bed_dark_skin_tone
+  people_holding_hands
+  people_holding_hands_light_skin_tone
+  people_holding_hands_medium_light_skin_tone_light_skin_tone
+  people_holding_hands_medium_light_skin_tone_light_skin_tone_1
+  people_holding_hands_medium_skin_tone_light_skin_tone
+  people_holding_hands_medium_skin_tone_medium_light_skin_tone
+  people_holding_hands_medium_skin_tone_medium_light_skin_tone_1
+  people_holding_hands_medium_dark_skin_tone_light_skin_tone
+  people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone
+  people_holding_hands_medium_dark_skin_tone_medium_skin_tone
+  people_holding_hands_medium_dark_skin_tone_medium_skin_tone_1
+  people_holding_hands_dark_skin_tone_light_skin_tone
+  people_holding_hands_dark_skin_tone_medium_light_skin_tone
+  people_holding_hands_dark_skin_tone_medium_skin_tone
+  people_holding_hands_dark_skin_tone_medium_dark_skin_tone
+  people_holding_hands_dark_skin_tone_medium_dark_skin_tone_1
+  women_holding_hands
+  women_holding_hands_light_skin_tone
+  women_holding_hands_medium_light_skin_tone_light_skin_tone
+  women_holding_hands_medium_light_skin_tone_light_skin_tone_1
+  women_holding_hands_medium_skin_tone_light_skin_tone
+  women_holding_hands_medium_skin_tone_medium_light_skin_tone
+  women_holding_hands_medium_skin_tone_medium_light_skin_tone_1
+  women_holding_hands_medium_dark_skin_tone_light_skin_tone
+  women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone
+  women_holding_hands_medium_dark_skin_tone_medium_skin_tone
+  women_holding_hands_medium_dark_skin_tone_medium_skin_tone_1
+  women_holding_hands_dark_skin_tone_light_skin_tone
+  women_holding_hands_dark_skin_tone_medium_light_skin_tone
+  women_holding_hands_dark_skin_tone_medium_skin_tone
+  women_holding_hands_dark_skin_tone_medium_dark_skin_tone
+  women_holding_hands_dark_skin_tone_medium_dark_skin_tone_1
+  woman_and_man_holding_hands
+  woman_and_man_holding_hands_light_skin_tone
+  woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone
+  woman_and_man_holding_hands_light_skin_tone_medium_skin_tone
+  woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone
+  woman_and_man_holding_hands_light_skin_tone_dark_skin_tone
+  woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone
+  woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone_1
+  woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone
+  woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone
+  woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone
+  woman_and_man_holding_hands_medium_skin_tone_light_skin_tone
+  woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone
+  woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone_1
+  woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone
+  woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone
+  woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone
+  woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone
+  woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone
+  woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone_1
+  woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone
+  woman_and_man_holding_hands_dark_skin_tone_light_skin_tone
+  woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone
+  woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone
+  woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone
+  woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone_1
+  men_holding_hands
+  men_holding_hands_light_skin_tone
+  men_holding_hands_medium_light_skin_tone_light_skin_tone
+  men_holding_hands_medium_light_skin_tone_light_skin_tone_1
+  men_holding_hands_medium_skin_tone_light_skin_tone
+  men_holding_hands_medium_skin_tone_medium_light_skin_tone
+  men_holding_hands_medium_skin_tone_medium_light_skin_tone_1
+  men_holding_hands_medium_dark_skin_tone_light_skin_tone
+  men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone
+  men_holding_hands_medium_dark_skin_tone_medium_skin_tone
+  men_holding_hands_medium_dark_skin_tone_medium_skin_tone_1
+  men_holding_hands_dark_skin_tone_light_skin_tone
+  men_holding_hands_dark_skin_tone_medium_light_skin_tone
+  men_holding_hands_dark_skin_tone_medium_skin_tone
+  men_holding_hands_dark_skin_tone_medium_dark_skin_tone
+  men_holding_hands_dark_skin_tone_medium_dark_skin_tone_1
+  kiss
+  kiss_woman_man
+  kiss_man_man
+  kiss_woman_woman
+  couple_with_heart
+  couple_with_heart_woman_man
+  couple_with_heart_man_man
+  couple_with_heart_woman_woman
+  family
+  family_man_woman_boy
+  family_man_woman_girl
+  family_man_woman_girl_boy
+  family_man_woman_boy_boy
+  family_man_woman_girl_girl
+  family_man_man_boy
+  family_man_man_girl
+  family_man_man_girl_boy
+  family_man_man_boy_boy
+  family_man_man_girl_girl
+  family_woman_woman_boy
+  family_woman_woman_girl
+  family_woman_woman_girl_boy
+  family_woman_woman_boy_boy
+  family_woman_woman_girl_girl
+  family_man_boy
+  family_man_boy_boy
+  family_man_girl
+  family_man_girl_boy
+  family_man_girl_girl
+  family_woman_boy
+  family_woman_boy_boy
+  family_woman_girl
+  family_woman_girl_boy
+  family_woman_girl_girl
+  speaking_head
+  bust_in_silhouette
+  busts_in_silhouette
+  footprints
+"
+
+emoji_groups[animals]="
+  monkey_face
+  monkey_face_1
+  gorilla
+  orangutan
+  dog_face
+  dog_face_1
+  guide_dog
+  service_dog
+  poodle
+  wolf
+  fox
+  raccoon
+  cat_face
+  cat_face_1
+  lion
+  tiger_face
+  tiger_face_1
+  leopard
+  horse_face
+  horse_face_1
+  unicorn
+  zebra
+  deer
+  cow_face
+  ox
+  water_buffalo
+  cow
+  pig_face
+  pig_face_1
+  boar
+  pig_nose
+  ram
+  ewe
+  goat
+  camel
+  two_hump_camel
+  llama
+  giraffe
+  elephant
+  rhinoceros
+  hippopotamus
+  mouse_face
+  mouse_face_1
+  rat
+  hamster
+  rabbit_face
+  rabbit_face_1
+  chipmunk
+  hedgehog
+  bat
+  bear
+  koala
+  panda
+  sloth
+  otter
+  skunk
+  kangaroo
+  badger
+  paw_prints
+  turkey
+  chicken
+  rooster
+  hatching_chick
+  baby_chick
+  front_facing_baby_chick
+  bird
+  penguin
+  dove
+  eagle
+  duck
+  swan
+  owl
+  flamingo
+  peacock
+  parrot
+  frog
+  crocodile
+  turtle
+  lizard
+  snake
+  dragon_face
+  dragon_face_1
+  sauropod
+  T_Rex
+  spouting_whale
+  spouting_whale_1
+  dolphin
+  fish
+  tropical_fish
+  blowfish
+  shark
+  octopus
+  spiral_shell
+  snail
+  butterfly
+  bug
+  ant
+  honeybee
+  lady_beetle
+  cricket
+  spider
+  spider_web
+  scorpion
+  mosquito
+  microbe
+"
+
+emoji_groups[faces]="
+  grinning_face
+  grinning_face_with_big_eyes
+  grinning_face_with_smiling_eyes
+  beaming_face_with_smiling_eyes
+  grinning_squinting_face
+  grinning_face_with_sweat
+  rolling_on_the_floor_laughing
+  face_with_tears_of_joy
+  slightly_smiling_face
+  upside_down_face
+  winking_face
+  smiling_face_with_smiling_eyes
+  smiling_face_with_halo
+  smiling_face_with_hearts
+  smiling_face_with_heart_eyes
+  star_struck
+  face_blowing_a_kiss
+  kissing_face
+  smiling_face
+  kissing_face_with_closed_eyes
+  kissing_face_with_smiling_eyes
+  face_savoring_food
+  face_with_tongue
+  winking_face_with_tongue
+  zany_face
+  squinting_face_with_tongue
+  money_mouth_face
+  hugging_face
+  face_with_hand_over_mouth
+  shushing_face
+  thinking_face
+  zipper_mouth_face
+  face_with_raised_eyebrow
+  neutral_face
+  expressionless_face
+  face_without_mouth
+  smirking_face
+  unamused_face
+  face_with_rolling_eyes
+  grimacing_face
+  lying_face
+  relieved_face
+  pensive_face
+  sleepy_face
+  drooling_face
+  sleeping_face
+  face_with_medical_mask
+  face_with_thermometer
+  face_with_head_bandage
+  nauseated_face
+  face_vomiting
+  sneezing_face
+  hot_face
+  cold_face
+  woozy_face
+  dizzy_face
+  exploding_head
+  cowboy_hat_face
+  partying_face
+  smiling_face_with_sunglasses
+  nerd_face
+  face_with_monocle
+  confused_face
+  worried_face
+  slightly_frowning_face
+  slightly_frowning_face_1
+  face_with_open_mouth
+  hushed_face
+  astonished_face
+  flushed_face
+  pleading_face
+  frowning_face_with_open_mouth
+  anguished_face
+  fearful_face
+  anxious_face_with_sweat
+  sad_but_relieved_face
+  crying_face
+  loudly_crying_face
+  face_screaming_in_fear
+  confounded_face
+  persevering_face
+  disappointed_face
+  downcast_face_with_sweat
+  weary_face
+  tired_face
+  yawning_face
+  face_with_steam_from_nose
+  pouting_face
+  angry_face
+  face_with_symbols_on_mouth
+  smiling_face_with_horns
+  angry_face_with_horns
+  skull
+  skull_and_crossbones
+  pile_of_poo
+  clown_face
+  ogre
+  goblin
+  ghost
+  alien
+  alien_monster
+  robot
+"
+
+emoji_groups[flags]="
+  chequered_flag
+  triangular_flag
+  crossed_flags
+  black_flag
+  white_flag
+  rainbow_flag
+  pirate_flag
+  Ascension_Island
+  Andorra
+  United_Arab_Emirates
+  Afghanistan
+  Antigua_and_Barbuda
+  Anguilla
+  Albania
+  Armenia
+  Angola
+  Antarctica
+  Argentina
+  American_Samoa
+  Austria
+  Australia
+  Aruba
+  Åland_Islands
+  Azerbaijan
+  Bosnia_and_Herzegovina
+  Barbados
+  Bangladesh
+  Belgium
+  Burkina_Faso
+  Bulgaria
+  Bahrain
+  Burundi
+  Benin
+  St_Barthélemy
+  Bermuda
+  Brunei
+  Bolivia
+  Caribbean_Netherlands
+  Brazil
+  Bahamas
+  Bhutan
+  Bouvet_Island
+  Botswana
+  Belarus
+  Belize
+  Canada
+  Cocos_Keeling_Islands
+  Congo__Kinshasa
+  Central_African_Republic
+  Congo__Brazzaville
+  Switzerland
+  Côte_d_Ivoire
+  Cook_Islands
+  Chile
+  Cameroon
+  China
+  Colombia
+  Clipperton_Island
+  Costa_Rica
+  Cuba
+  Cape_Verde
+  Curaçao
+  Christmas_Island
+  Cyprus
+  Czechia
+  Germany
+  Diego_Garcia
+  Djibouti
+  Denmark
+  Dominica
+  Dominican_Republic
+  Algeria
+  Ceuta_and_Melilla
+  Ecuador
+  Estonia
+  Egypt
+  Western_Sahara
+  Eritrea
+  Spain
+  Ethiopia
+  European_Union
+  Finland
+  Fiji
+  Falkland_Islands
+  Micronesia
+  Faroe_Islands
+  France
+  Gabon
+  United_Kingdom
+  Grenada
+  Georgia
+  French_Guiana
+  Guernsey
+  Ghana
+  Gibraltar
+  Greenland
+  Gambia
+  Guinea
+  Guadeloupe
+  Equatorial_Guinea
+  Greece
+  South_Georgia_and_South_Sandwich_Islands
+  Guatemala
+  Guam
+  Guinea_Bissau
+  Guyana
+  Hong_Kong_SAR_China
+  Heard_and_McDonald_Islands
+  Honduras
+  Croatia
+  Haiti
+  Hungary
+  Canary_Islands
+  Indonesia
+  Ireland
+  Israel
+  Isle_of_Man
+  India
+  British_Indian_Ocean_Territory
+  Iraq
+  Iran
+  Iceland
+  Italy
+  Jersey
+  Jamaica
+  Jordan
+  Japan
+  Kenya
+  Kyrgyzstan
+  Cambodia
+  Kiribati
+  Comoros
+  St_Kitts_and_Nevis
+  North_Korea
+  South_Korea
+  Kuwait
+  Cayman_Islands
+  Kazakhstan
+  Laos
+  Lebanon
+  St_Lucia
+  Liechtenstein
+  Sri_Lanka
+  Liberia
+  Lesotho
+  Lithuania
+  Luxembourg
+  Latvia
+  Libya
+  Morocco
+  Monaco
+  Moldova
+  Montenegro
+  St_Martin
+  Madagascar
+  Marshall_Islands
+  Macedonia
+  Mali
+  Myanmar_Burma_
+  Mongolia
+  Macao_SAR_China
+  Northern_Mariana_Islands
+  Martinique
+  Mauritania
+  Montserrat
+  Malta
+  Mauritius
+  Maldives
+  Malawi
+  Mexico
+  Malaysia
+  Mozambique
+  Namibia
+  New_Caledonia
+  Niger
+  Norfolk_Island
+  Nigeria
+  Nicaragua
+  Netherlands
+  Norway
+  Nepal
+  Nauru
+  Niue
+  New_Zealand
+  Oman
+  Panama
+  Peru
+  French_Polynesia
+  Papua_New_Guinea
+  Philippines
+  Pakistan
+  Poland
+  St_Pierre_and_Miquelon
+  Pitcairn_Islands
+  Puerto_Rico
+  Palestinian_Territories
+  Portugal
+  Palau
+  Paraguay
+  Qatar
+  Réunion
+  Romania
+  Serbia
+  Russia
+  Rwanda
+  Saudi_Arabia
+  Solomon_Islands
+  Seychelles
+  Sudan
+  Sweden
+  Singapore
+  St_Helena
+  Slovenia
+  Svalbard_and_Jan_Mayen
+  Slovakia
+  Sierra_Leone
+  San_Marino
+  Senegal
+  Somalia
+  Suriname
+  South_Sudan
+  São_Tomé_and_Príncipe
+  El_Salvador
+  Sint_Maarten
+  Syria
+  Eswatini
+  Tristan_da_Cunha
+  Turks_and_Caicos_Islands
+  Chad
+  French_Southern_Territories
+  Togo
+  Thailand
+  Tajikistan
+  Tokelau
+  Timor_Leste
+  Turkmenistan
+  Tunisia
+  Tonga
+  Turkey
+  Trinidad_and_Tobago
+  Tuvalu
+  Taiwan
+  Tanzania
+  Ukraine
+  Uganda
+  U_S_Outlying_Islands
+  United_Nations
+  United_States
+  Uruguay
+  Uzbekistan
+  Vatican_City
+  St_Vincent_and_Grenadines
+  Venezuela
+  British_Virgin_Islands
+  U_S_Virgin_Islands
+  Vietnam
+  Vanuatu
+  Wallis_and_Futuna
+  Samoa
+  Kosovo
+  Yemen
+  Mayotte
+  South_Africa
+  Zambia
+  Zimbabwe
+  England
+  Scotland
+  Wales
+"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji-data.txt b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji-data.txt
new file mode 100644 (file)
index 0000000..59b7e92
--- /dev/null
@@ -0,0 +1,4122 @@
+# emoji-data.txt
+# (Originally emoji-test.txt)
+# (Retrieved from https://unicode.org/Public/emoji/12.0/emoji-test.txt)
+
+# Date: 2019-01-27, 15:43:01 GMT
+# © 2019 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Emoji Keyboard/Display Test Data for UTS #51
+# Version: 12.0
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr51
+#
+# This file provides data for testing which emoji forms should be in keyboards and which should also be displayed/processed.
+# Format: code points; status # emoji name
+#     Code points — list of one or more hex code points, separated by spaces
+#     Status
+#       component           — an Emoji_Component,
+#                             excluding Regional_Indicators, ASCII, and non-Emoji.
+#       fully-qualified     — a fully-qualified emoji (see ED-18 in UTS #51),
+#                             excluding Emoji_Component
+#       minimally-qualified — a minimally-qualified emoji (see ED-18a in UTS #51)
+#       unqualified         — a unqualified emoji (See ED-19 in UTS #51)
+# Notes:
+#   • This includes the emoji components that need emoji presentation (skin tone and hair)
+#     when isolated, but omits the components that need not have an emoji
+#     presentation when isolated.
+#   • The RGI set is covered by the listed fully-qualified emoji. 
+#   • The listed minimally-qualified and unqualified cover all cases where an
+#     element of the RGI set is missing one or more emoji presentation selectors.
+#   • The file is in CLDR order, not codepoint order. This is recommended (but not required!) for keyboard palettes.
+#   • The groups and subgroups are illustrative. See the Emoji Order chart for more information.
+
+
+# group: Smileys & Emotion
+
+# subgroup: face-smiling
+1F600                                      ; fully-qualified     # 😀 grinning face
+1F603                                      ; fully-qualified     # 😃 grinning face with big eyes
+1F604                                      ; fully-qualified     # 😄 grinning face with smiling eyes
+1F601                                      ; fully-qualified     # 😁 beaming face with smiling eyes
+1F606                                      ; fully-qualified     # 😆 grinning squinting face
+1F605                                      ; fully-qualified     # 😅 grinning face with sweat
+1F923                                      ; fully-qualified     # 🤣 rolling on the floor laughing
+1F602                                      ; fully-qualified     # 😂 face with tears of joy
+1F642                                      ; fully-qualified     # 🙂 slightly smiling face
+1F643                                      ; fully-qualified     # 🙃 upside-down face
+1F609                                      ; fully-qualified     # 😉 winking face
+1F60A                                      ; fully-qualified     # 😊 smiling face with smiling eyes
+1F607                                      ; fully-qualified     # 😇 smiling face with halo
+
+# subgroup: face-affection
+1F970                                      ; fully-qualified     # 🥰 smiling face with hearts
+1F60D                                      ; fully-qualified     # 😍 smiling face with heart-eyes
+1F929                                      ; fully-qualified     # 🤩 star-struck
+1F618                                      ; fully-qualified     # 😘 face blowing a kiss
+1F617                                      ; fully-qualified     # 😗 kissing face
+263A FE0F                                  ; fully-qualified     # ☺️ smiling face
+263A                                       ; unqualified         # ☺ smiling face
+1F61A                                      ; fully-qualified     # 😚 kissing face with closed eyes
+1F619                                      ; fully-qualified     # 😙 kissing face with smiling eyes
+
+# subgroup: face-tongue
+1F60B                                      ; fully-qualified     # 😋 face savoring food
+1F61B                                      ; fully-qualified     # 😛 face with tongue
+1F61C                                      ; fully-qualified     # 😜 winking face with tongue
+1F92A                                      ; fully-qualified     # 🤪 zany face
+1F61D                                      ; fully-qualified     # 😝 squinting face with tongue
+1F911                                      ; fully-qualified     # 🤑 money-mouth face
+
+# subgroup: face-hand
+1F917                                      ; fully-qualified     # 🤗 hugging face
+1F92D                                      ; fully-qualified     # 🤭 face with hand over mouth
+1F92B                                      ; fully-qualified     # 🤫 shushing face
+1F914                                      ; fully-qualified     # 🤔 thinking face
+
+# subgroup: face-neutral-skeptical
+1F910                                      ; fully-qualified     # 🤐 zipper-mouth face
+1F928                                      ; fully-qualified     # 🤨 face with raised eyebrow
+1F610                                      ; fully-qualified     # 😐 neutral face
+1F611                                      ; fully-qualified     # 😑 expressionless face
+1F636                                      ; fully-qualified     # 😶 face without mouth
+1F60F                                      ; fully-qualified     # 😏 smirking face
+1F612                                      ; fully-qualified     # 😒 unamused face
+1F644                                      ; fully-qualified     # 🙄 face with rolling eyes
+1F62C                                      ; fully-qualified     # 😬 grimacing face
+1F925                                      ; fully-qualified     # 🤥 lying face
+
+# subgroup: face-sleepy
+1F60C                                      ; fully-qualified     # 😌 relieved face
+1F614                                      ; fully-qualified     # 😔 pensive face
+1F62A                                      ; fully-qualified     # 😪 sleepy face
+1F924                                      ; fully-qualified     # 🤤 drooling face
+1F634                                      ; fully-qualified     # 😴 sleeping face
+
+# subgroup: face-unwell
+1F637                                      ; fully-qualified     # 😷 face with medical mask
+1F912                                      ; fully-qualified     # 🤒 face with thermometer
+1F915                                      ; fully-qualified     # 🤕 face with head-bandage
+1F922                                      ; fully-qualified     # 🤢 nauseated face
+1F92E                                      ; fully-qualified     # 🤮 face vomiting
+1F927                                      ; fully-qualified     # 🤧 sneezing face
+1F975                                      ; fully-qualified     # 🥵 hot face
+1F976                                      ; fully-qualified     # 🥶 cold face
+1F974                                      ; fully-qualified     # 🥴 woozy face
+1F635                                      ; fully-qualified     # 😵 dizzy face
+1F92F                                      ; fully-qualified     # 🤯 exploding head
+
+# subgroup: face-hat
+1F920                                      ; fully-qualified     # 🤠 cowboy hat face
+1F973                                      ; fully-qualified     # 🥳 partying face
+
+# subgroup: face-glasses
+1F60E                                      ; fully-qualified     # 😎 smiling face with sunglasses
+1F913                                      ; fully-qualified     # 🤓 nerd face
+1F9D0                                      ; fully-qualified     # 🧐 face with monocle
+
+# subgroup: face-concerned
+1F615                                      ; fully-qualified     # 😕 confused face
+1F61F                                      ; fully-qualified     # 😟 worried face
+1F641                                      ; fully-qualified     # 🙁 slightly frowning face
+2639 FE0F                                  ; fully-qualified     # ☹️ frowning face
+2639                                       ; unqualified         # ☹ frowning face
+1F62E                                      ; fully-qualified     # 😮 face with open mouth
+1F62F                                      ; fully-qualified     # 😯 hushed face
+1F632                                      ; fully-qualified     # 😲 astonished face
+1F633                                      ; fully-qualified     # 😳 flushed face
+1F97A                                      ; fully-qualified     # 🥺 pleading face
+1F626                                      ; fully-qualified     # 😦 frowning face with open mouth
+1F627                                      ; fully-qualified     # 😧 anguished face
+1F628                                      ; fully-qualified     # 😨 fearful face
+1F630                                      ; fully-qualified     # 😰 anxious face with sweat
+1F625                                      ; fully-qualified     # 😥 sad but relieved face
+1F622                                      ; fully-qualified     # 😢 crying face
+1F62D                                      ; fully-qualified     # 😭 loudly crying face
+1F631                                      ; fully-qualified     # 😱 face screaming in fear
+1F616                                      ; fully-qualified     # 😖 confounded face
+1F623                                      ; fully-qualified     # 😣 persevering face
+1F61E                                      ; fully-qualified     # 😞 disappointed face
+1F613                                      ; fully-qualified     # 😓 downcast face with sweat
+1F629                                      ; fully-qualified     # 😩 weary face
+1F62B                                      ; fully-qualified     # 😫 tired face
+1F971                                      ; fully-qualified     # 🥱 yawning face
+
+# subgroup: face-negative
+1F624                                      ; fully-qualified     # 😤 face with steam from nose
+1F621                                      ; fully-qualified     # 😡 pouting face
+1F620                                      ; fully-qualified     # 😠 angry face
+1F92C                                      ; fully-qualified     # 🤬 face with symbols on mouth
+1F608                                      ; fully-qualified     # 😈 smiling face with horns
+1F47F                                      ; fully-qualified     # 👿 angry face with horns
+1F480                                      ; fully-qualified     # 💀 skull
+2620 FE0F                                  ; fully-qualified     # ☠️ skull and crossbones
+2620                                       ; unqualified         # ☠ skull and crossbones
+
+# subgroup: face-costume
+1F4A9                                      ; fully-qualified     # 💩 pile of poo
+1F921                                      ; fully-qualified     # 🤡 clown face
+1F479                                      ; fully-qualified     # 👹 ogre
+1F47A                                      ; fully-qualified     # 👺 goblin
+1F47B                                      ; fully-qualified     # 👻 ghost
+1F47D                                      ; fully-qualified     # 👽 alien
+1F47E                                      ; fully-qualified     # 👾 alien monster
+1F916                                      ; fully-qualified     # 🤖 robot
+
+# subgroup: cat-face
+1F63A                                      ; fully-qualified     # 😺 grinning cat
+1F638                                      ; fully-qualified     # 😸 grinning cat with smiling eyes
+1F639                                      ; fully-qualified     # 😹 cat with tears of joy
+1F63B                                      ; fully-qualified     # 😻 smiling cat with heart-eyes
+1F63C                                      ; fully-qualified     # 😼 cat with wry smile
+1F63D                                      ; fully-qualified     # 😽 kissing cat
+1F640                                      ; fully-qualified     # 🙀 weary cat
+1F63F                                      ; fully-qualified     # 😿 crying cat
+1F63E                                      ; fully-qualified     # 😾 pouting cat
+
+# subgroup: monkey-face
+1F648                                      ; fully-qualified     # 🙈 see-no-evil monkey
+1F649                                      ; fully-qualified     # 🙉 hear-no-evil monkey
+1F64A                                      ; fully-qualified     # 🙊 speak-no-evil monkey
+
+# subgroup: emotion
+1F48B                                      ; fully-qualified     # 💋 kiss mark
+1F48C                                      ; fully-qualified     # 💌 love letter
+1F498                                      ; fully-qualified     # 💘 heart with arrow
+1F49D                                      ; fully-qualified     # 💝 heart with ribbon
+1F496                                      ; fully-qualified     # 💖 sparkling heart
+1F497                                      ; fully-qualified     # 💗 growing heart
+1F493                                      ; fully-qualified     # 💓 beating heart
+1F49E                                      ; fully-qualified     # 💞 revolving hearts
+1F495                                      ; fully-qualified     # 💕 two hearts
+1F49F                                      ; fully-qualified     # 💟 heart decoration
+2763 FE0F                                  ; fully-qualified     # ❣️ heart exclamation
+2763                                       ; unqualified         # ❣ heart exclamation
+1F494                                      ; fully-qualified     # 💔 broken heart
+2764 FE0F                                  ; fully-qualified     # ❤️ red heart
+2764                                       ; unqualified         # ❤ red heart
+1F9E1                                      ; fully-qualified     # 🧡 orange heart
+1F49B                                      ; fully-qualified     # 💛 yellow heart
+1F49A                                      ; fully-qualified     # 💚 green heart
+1F499                                      ; fully-qualified     # 💙 blue heart
+1F49C                                      ; fully-qualified     # 💜 purple heart
+1F90E                                      ; fully-qualified     # 🤎 brown heart
+1F5A4                                      ; fully-qualified     # 🖤 black heart
+1F90D                                      ; fully-qualified     # 🤍 white heart
+1F4AF                                      ; fully-qualified     # 💯 hundred points
+1F4A2                                      ; fully-qualified     # 💢 anger symbol
+1F4A5                                      ; fully-qualified     # 💥 collision
+1F4AB                                      ; fully-qualified     # 💫 dizzy
+1F4A6                                      ; fully-qualified     # 💦 sweat droplets
+1F4A8                                      ; fully-qualified     # 💨 dashing away
+1F573 FE0F                                 ; fully-qualified     # 🕳️ hole
+1F573                                      ; unqualified         # 🕳 hole
+1F4A3                                      ; fully-qualified     # 💣 bomb
+1F4AC                                      ; fully-qualified     # 💬 speech balloon
+1F441 FE0F 200D 1F5E8 FE0F                 ; fully-qualified     # 👁️‍🗨️ eye in speech bubble
+1F441 200D 1F5E8 FE0F                      ; unqualified         # 👁‍🗨️ eye in speech bubble
+1F441 FE0F 200D 1F5E8                      ; unqualified         # 👁️‍🗨 eye in speech bubble
+1F441 200D 1F5E8                           ; unqualified         # 👁‍🗨 eye in speech bubble
+1F5E8 FE0F                                 ; fully-qualified     # 🗨️ left speech bubble
+1F5E8                                      ; unqualified         # 🗨 left speech bubble
+1F5EF FE0F                                 ; fully-qualified     # 🗯️ right anger bubble
+1F5EF                                      ; unqualified         # 🗯 right anger bubble
+1F4AD                                      ; fully-qualified     # 💭 thought balloon
+1F4A4                                      ; fully-qualified     # 💤 zzz
+
+# Smileys & Emotion subtotal:          160
+# Smileys & Emotion subtotal:          160     w/o modifiers
+
+# group: People & Body
+
+# subgroup: hand-fingers-open
+1F44B                                      ; fully-qualified     # 👋 waving hand
+1F44B 1F3FB                                ; fully-qualified     # 👋🏻 waving hand: light skin tone
+1F44B 1F3FC                                ; fully-qualified     # 👋🏼 waving hand: medium-light skin tone
+1F44B 1F3FD                                ; fully-qualified     # 👋🏽 waving hand: medium skin tone
+1F44B 1F3FE                                ; fully-qualified     # 👋🏾 waving hand: medium-dark skin tone
+1F44B 1F3FF                                ; fully-qualified     # 👋🏿 waving hand: dark skin tone
+1F91A                                      ; fully-qualified     # 🤚 raised back of hand
+1F91A 1F3FB                                ; fully-qualified     # 🤚🏻 raised back of hand: light skin tone
+1F91A 1F3FC                                ; fully-qualified     # 🤚🏼 raised back of hand: medium-light skin tone
+1F91A 1F3FD                                ; fully-qualified     # 🤚🏽 raised back of hand: medium skin tone
+1F91A 1F3FE                                ; fully-qualified     # 🤚🏾 raised back of hand: medium-dark skin tone
+1F91A 1F3FF                                ; fully-qualified     # 🤚🏿 raised back of hand: dark skin tone
+1F590 FE0F                                 ; fully-qualified     # 🖐️ hand with fingers splayed
+1F590                                      ; unqualified         # 🖐 hand with fingers splayed
+1F590 1F3FB                                ; fully-qualified     # 🖐🏻 hand with fingers splayed: light skin tone
+1F590 1F3FC                                ; fully-qualified     # 🖐🏼 hand with fingers splayed: medium-light skin tone
+1F590 1F3FD                                ; fully-qualified     # 🖐🏽 hand with fingers splayed: medium skin tone
+1F590 1F3FE                                ; fully-qualified     # 🖐🏾 hand with fingers splayed: medium-dark skin tone
+1F590 1F3FF                                ; fully-qualified     # 🖐🏿 hand with fingers splayed: dark skin tone
+270B                                       ; fully-qualified     # ✋ raised hand
+270B 1F3FB                                 ; fully-qualified     # ✋🏻 raised hand: light skin tone
+270B 1F3FC                                 ; fully-qualified     # ✋🏼 raised hand: medium-light skin tone
+270B 1F3FD                                 ; fully-qualified     # ✋🏽 raised hand: medium skin tone
+270B 1F3FE                                 ; fully-qualified     # ✋🏾 raised hand: medium-dark skin tone
+270B 1F3FF                                 ; fully-qualified     # ✋🏿 raised hand: dark skin tone
+1F596                                      ; fully-qualified     # 🖖 vulcan salute
+1F596 1F3FB                                ; fully-qualified     # 🖖🏻 vulcan salute: light skin tone
+1F596 1F3FC                                ; fully-qualified     # 🖖🏼 vulcan salute: medium-light skin tone
+1F596 1F3FD                                ; fully-qualified     # 🖖🏽 vulcan salute: medium skin tone
+1F596 1F3FE                                ; fully-qualified     # 🖖🏾 vulcan salute: medium-dark skin tone
+1F596 1F3FF                                ; fully-qualified     # 🖖🏿 vulcan salute: dark skin tone
+
+# subgroup: hand-fingers-partial
+1F44C                                      ; fully-qualified     # 👌 OK hand
+1F44C 1F3FB                                ; fully-qualified     # 👌🏻 OK hand: light skin tone
+1F44C 1F3FC                                ; fully-qualified     # 👌🏼 OK hand: medium-light skin tone
+1F44C 1F3FD                                ; fully-qualified     # 👌🏽 OK hand: medium skin tone
+1F44C 1F3FE                                ; fully-qualified     # 👌🏾 OK hand: medium-dark skin tone
+1F44C 1F3FF                                ; fully-qualified     # 👌🏿 OK hand: dark skin tone
+1F90F                                      ; fully-qualified     # 🤏 pinching hand
+1F90F 1F3FB                                ; fully-qualified     # 🤏🏻 pinching hand: light skin tone
+1F90F 1F3FC                                ; fully-qualified     # 🤏🏼 pinching hand: medium-light skin tone
+1F90F 1F3FD                                ; fully-qualified     # 🤏🏽 pinching hand: medium skin tone
+1F90F 1F3FE                                ; fully-qualified     # 🤏🏾 pinching hand: medium-dark skin tone
+1F90F 1F3FF                                ; fully-qualified     # 🤏🏿 pinching hand: dark skin tone
+270C FE0F                                  ; fully-qualified     # ✌️ victory hand
+270C                                       ; unqualified         # ✌ victory hand
+270C 1F3FB                                 ; fully-qualified     # ✌🏻 victory hand: light skin tone
+270C 1F3FC                                 ; fully-qualified     # ✌🏼 victory hand: medium-light skin tone
+270C 1F3FD                                 ; fully-qualified     # ✌🏽 victory hand: medium skin tone
+270C 1F3FE                                 ; fully-qualified     # ✌🏾 victory hand: medium-dark skin tone
+270C 1F3FF                                 ; fully-qualified     # ✌🏿 victory hand: dark skin tone
+1F91E                                      ; fully-qualified     # 🤞 crossed fingers
+1F91E 1F3FB                                ; fully-qualified     # 🤞🏻 crossed fingers: light skin tone
+1F91E 1F3FC                                ; fully-qualified     # 🤞🏼 crossed fingers: medium-light skin tone
+1F91E 1F3FD                                ; fully-qualified     # 🤞🏽 crossed fingers: medium skin tone
+1F91E 1F3FE                                ; fully-qualified     # 🤞🏾 crossed fingers: medium-dark skin tone
+1F91E 1F3FF                                ; fully-qualified     # 🤞🏿 crossed fingers: dark skin tone
+1F91F                                      ; fully-qualified     # 🤟 love-you gesture
+1F91F 1F3FB                                ; fully-qualified     # 🤟🏻 love-you gesture: light skin tone
+1F91F 1F3FC                                ; fully-qualified     # 🤟🏼 love-you gesture: medium-light skin tone
+1F91F 1F3FD                                ; fully-qualified     # 🤟🏽 love-you gesture: medium skin tone
+1F91F 1F3FE                                ; fully-qualified     # 🤟🏾 love-you gesture: medium-dark skin tone
+1F91F 1F3FF                                ; fully-qualified     # 🤟🏿 love-you gesture: dark skin tone
+1F918                                      ; fully-qualified     # 🤘 sign of the horns
+1F918 1F3FB                                ; fully-qualified     # 🤘🏻 sign of the horns: light skin tone
+1F918 1F3FC                                ; fully-qualified     # 🤘🏼 sign of the horns: medium-light skin tone
+1F918 1F3FD                                ; fully-qualified     # 🤘🏽 sign of the horns: medium skin tone
+1F918 1F3FE                                ; fully-qualified     # 🤘🏾 sign of the horns: medium-dark skin tone
+1F918 1F3FF                                ; fully-qualified     # 🤘🏿 sign of the horns: dark skin tone
+1F919                                      ; fully-qualified     # 🤙 call me hand
+1F919 1F3FB                                ; fully-qualified     # 🤙🏻 call me hand: light skin tone
+1F919 1F3FC                                ; fully-qualified     # 🤙🏼 call me hand: medium-light skin tone
+1F919 1F3FD                                ; fully-qualified     # 🤙🏽 call me hand: medium skin tone
+1F919 1F3FE                                ; fully-qualified     # 🤙🏾 call me hand: medium-dark skin tone
+1F919 1F3FF                                ; fully-qualified     # 🤙🏿 call me hand: dark skin tone
+
+# subgroup: hand-single-finger
+1F448                                      ; fully-qualified     # 👈 backhand index pointing left
+1F448 1F3FB                                ; fully-qualified     # 👈🏻 backhand index pointing left: light skin tone
+1F448 1F3FC                                ; fully-qualified     # 👈🏼 backhand index pointing left: medium-light skin tone
+1F448 1F3FD                                ; fully-qualified     # 👈🏽 backhand index pointing left: medium skin tone
+1F448 1F3FE                                ; fully-qualified     # 👈🏾 backhand index pointing left: medium-dark skin tone
+1F448 1F3FF                                ; fully-qualified     # 👈🏿 backhand index pointing left: dark skin tone
+1F449                                      ; fully-qualified     # 👉 backhand index pointing right
+1F449 1F3FB                                ; fully-qualified     # 👉🏻 backhand index pointing right: light skin tone
+1F449 1F3FC                                ; fully-qualified     # 👉🏼 backhand index pointing right: medium-light skin tone
+1F449 1F3FD                                ; fully-qualified     # 👉🏽 backhand index pointing right: medium skin tone
+1F449 1F3FE                                ; fully-qualified     # 👉🏾 backhand index pointing right: medium-dark skin tone
+1F449 1F3FF                                ; fully-qualified     # 👉🏿 backhand index pointing right: dark skin tone
+1F446                                      ; fully-qualified     # 👆 backhand index pointing up
+1F446 1F3FB                                ; fully-qualified     # 👆🏻 backhand index pointing up: light skin tone
+1F446 1F3FC                                ; fully-qualified     # 👆🏼 backhand index pointing up: medium-light skin tone
+1F446 1F3FD                                ; fully-qualified     # 👆🏽 backhand index pointing up: medium skin tone
+1F446 1F3FE                                ; fully-qualified     # 👆🏾 backhand index pointing up: medium-dark skin tone
+1F446 1F3FF                                ; fully-qualified     # 👆🏿 backhand index pointing up: dark skin tone
+1F595                                      ; fully-qualified     # 🖕 middle finger
+1F595 1F3FB                                ; fully-qualified     # 🖕🏻 middle finger: light skin tone
+1F595 1F3FC                                ; fully-qualified     # 🖕🏼 middle finger: medium-light skin tone
+1F595 1F3FD                                ; fully-qualified     # 🖕🏽 middle finger: medium skin tone
+1F595 1F3FE                                ; fully-qualified     # 🖕🏾 middle finger: medium-dark skin tone
+1F595 1F3FF                                ; fully-qualified     # 🖕🏿 middle finger: dark skin tone
+1F447                                      ; fully-qualified     # 👇 backhand index pointing down
+1F447 1F3FB                                ; fully-qualified     # 👇🏻 backhand index pointing down: light skin tone
+1F447 1F3FC                                ; fully-qualified     # 👇🏼 backhand index pointing down: medium-light skin tone
+1F447 1F3FD                                ; fully-qualified     # 👇🏽 backhand index pointing down: medium skin tone
+1F447 1F3FE                                ; fully-qualified     # 👇🏾 backhand index pointing down: medium-dark skin tone
+1F447 1F3FF                                ; fully-qualified     # 👇🏿 backhand index pointing down: dark skin tone
+261D FE0F                                  ; fully-qualified     # ☝️ index pointing up
+261D                                       ; unqualified         # ☝ index pointing up
+261D 1F3FB                                 ; fully-qualified     # ☝🏻 index pointing up: light skin tone
+261D 1F3FC                                 ; fully-qualified     # ☝🏼 index pointing up: medium-light skin tone
+261D 1F3FD                                 ; fully-qualified     # ☝🏽 index pointing up: medium skin tone
+261D 1F3FE                                 ; fully-qualified     # ☝🏾 index pointing up: medium-dark skin tone
+261D 1F3FF                                 ; fully-qualified     # ☝🏿 index pointing up: dark skin tone
+
+# subgroup: hand-fingers-closed
+1F44D                                      ; fully-qualified     # 👍 thumbs up
+1F44D 1F3FB                                ; fully-qualified     # 👍🏻 thumbs up: light skin tone
+1F44D 1F3FC                                ; fully-qualified     # 👍🏼 thumbs up: medium-light skin tone
+1F44D 1F3FD                                ; fully-qualified     # 👍🏽 thumbs up: medium skin tone
+1F44D 1F3FE                                ; fully-qualified     # 👍🏾 thumbs up: medium-dark skin tone
+1F44D 1F3FF                                ; fully-qualified     # 👍🏿 thumbs up: dark skin tone
+1F44E                                      ; fully-qualified     # 👎 thumbs down
+1F44E 1F3FB                                ; fully-qualified     # 👎🏻 thumbs down: light skin tone
+1F44E 1F3FC                                ; fully-qualified     # 👎🏼 thumbs down: medium-light skin tone
+1F44E 1F3FD                                ; fully-qualified     # 👎🏽 thumbs down: medium skin tone
+1F44E 1F3FE                                ; fully-qualified     # 👎🏾 thumbs down: medium-dark skin tone
+1F44E 1F3FF                                ; fully-qualified     # 👎🏿 thumbs down: dark skin tone
+270A                                       ; fully-qualified     # ✊ raised fist
+270A 1F3FB                                 ; fully-qualified     # ✊🏻 raised fist: light skin tone
+270A 1F3FC                                 ; fully-qualified     # ✊🏼 raised fist: medium-light skin tone
+270A 1F3FD                                 ; fully-qualified     # ✊🏽 raised fist: medium skin tone
+270A 1F3FE                                 ; fully-qualified     # ✊🏾 raised fist: medium-dark skin tone
+270A 1F3FF                                 ; fully-qualified     # ✊🏿 raised fist: dark skin tone
+1F44A                                      ; fully-qualified     # 👊 oncoming fist
+1F44A 1F3FB                                ; fully-qualified     # 👊🏻 oncoming fist: light skin tone
+1F44A 1F3FC                                ; fully-qualified     # 👊🏼 oncoming fist: medium-light skin tone
+1F44A 1F3FD                                ; fully-qualified     # 👊🏽 oncoming fist: medium skin tone
+1F44A 1F3FE                                ; fully-qualified     # 👊🏾 oncoming fist: medium-dark skin tone
+1F44A 1F3FF                                ; fully-qualified     # 👊🏿 oncoming fist: dark skin tone
+1F91B                                      ; fully-qualified     # 🤛 left-facing fist
+1F91B 1F3FB                                ; fully-qualified     # 🤛🏻 left-facing fist: light skin tone
+1F91B 1F3FC                                ; fully-qualified     # 🤛🏼 left-facing fist: medium-light skin tone
+1F91B 1F3FD                                ; fully-qualified     # 🤛🏽 left-facing fist: medium skin tone
+1F91B 1F3FE                                ; fully-qualified     # 🤛🏾 left-facing fist: medium-dark skin tone
+1F91B 1F3FF                                ; fully-qualified     # 🤛🏿 left-facing fist: dark skin tone
+1F91C                                      ; fully-qualified     # 🤜 right-facing fist
+1F91C 1F3FB                                ; fully-qualified     # 🤜🏻 right-facing fist: light skin tone
+1F91C 1F3FC                                ; fully-qualified     # 🤜🏼 right-facing fist: medium-light skin tone
+1F91C 1F3FD                                ; fully-qualified     # 🤜🏽 right-facing fist: medium skin tone
+1F91C 1F3FE                                ; fully-qualified     # 🤜🏾 right-facing fist: medium-dark skin tone
+1F91C 1F3FF                                ; fully-qualified     # 🤜🏿 right-facing fist: dark skin tone
+
+# subgroup: hands
+1F44F                                      ; fully-qualified     # 👏 clapping hands
+1F44F 1F3FB                                ; fully-qualified     # 👏🏻 clapping hands: light skin tone
+1F44F 1F3FC                                ; fully-qualified     # 👏🏼 clapping hands: medium-light skin tone
+1F44F 1F3FD                                ; fully-qualified     # 👏🏽 clapping hands: medium skin tone
+1F44F 1F3FE                                ; fully-qualified     # 👏🏾 clapping hands: medium-dark skin tone
+1F44F 1F3FF                                ; fully-qualified     # 👏🏿 clapping hands: dark skin tone
+1F64C                                      ; fully-qualified     # 🙌 raising hands
+1F64C 1F3FB                                ; fully-qualified     # 🙌🏻 raising hands: light skin tone
+1F64C 1F3FC                                ; fully-qualified     # 🙌🏼 raising hands: medium-light skin tone
+1F64C 1F3FD                                ; fully-qualified     # 🙌🏽 raising hands: medium skin tone
+1F64C 1F3FE                                ; fully-qualified     # 🙌🏾 raising hands: medium-dark skin tone
+1F64C 1F3FF                                ; fully-qualified     # 🙌🏿 raising hands: dark skin tone
+1F450                                      ; fully-qualified     # 👐 open hands
+1F450 1F3FB                                ; fully-qualified     # 👐🏻 open hands: light skin tone
+1F450 1F3FC                                ; fully-qualified     # 👐🏼 open hands: medium-light skin tone
+1F450 1F3FD                                ; fully-qualified     # 👐🏽 open hands: medium skin tone
+1F450 1F3FE                                ; fully-qualified     # 👐🏾 open hands: medium-dark skin tone
+1F450 1F3FF                                ; fully-qualified     # 👐🏿 open hands: dark skin tone
+1F932                                      ; fully-qualified     # 🤲 palms up together
+1F932 1F3FB                                ; fully-qualified     # 🤲🏻 palms up together: light skin tone
+1F932 1F3FC                                ; fully-qualified     # 🤲🏼 palms up together: medium-light skin tone
+1F932 1F3FD                                ; fully-qualified     # 🤲🏽 palms up together: medium skin tone
+1F932 1F3FE                                ; fully-qualified     # 🤲🏾 palms up together: medium-dark skin tone
+1F932 1F3FF                                ; fully-qualified     # 🤲🏿 palms up together: dark skin tone
+1F91D                                      ; fully-qualified     # 🤝 handshake
+1F64F                                      ; fully-qualified     # 🙏 folded hands
+1F64F 1F3FB                                ; fully-qualified     # 🙏🏻 folded hands: light skin tone
+1F64F 1F3FC                                ; fully-qualified     # 🙏🏼 folded hands: medium-light skin tone
+1F64F 1F3FD                                ; fully-qualified     # 🙏🏽 folded hands: medium skin tone
+1F64F 1F3FE                                ; fully-qualified     # 🙏🏾 folded hands: medium-dark skin tone
+1F64F 1F3FF                                ; fully-qualified     # 🙏🏿 folded hands: dark skin tone
+
+# subgroup: hand-prop
+270D FE0F                                  ; fully-qualified     # ✍️ writing hand
+270D                                       ; unqualified         # ✍ writing hand
+270D 1F3FB                                 ; fully-qualified     # ✍🏻 writing hand: light skin tone
+270D 1F3FC                                 ; fully-qualified     # ✍🏼 writing hand: medium-light skin tone
+270D 1F3FD                                 ; fully-qualified     # ✍🏽 writing hand: medium skin tone
+270D 1F3FE                                 ; fully-qualified     # ✍🏾 writing hand: medium-dark skin tone
+270D 1F3FF                                 ; fully-qualified     # ✍🏿 writing hand: dark skin tone
+1F485                                      ; fully-qualified     # 💅 nail polish
+1F485 1F3FB                                ; fully-qualified     # 💅🏻 nail polish: light skin tone
+1F485 1F3FC                                ; fully-qualified     # 💅🏼 nail polish: medium-light skin tone
+1F485 1F3FD                                ; fully-qualified     # 💅🏽 nail polish: medium skin tone
+1F485 1F3FE                                ; fully-qualified     # 💅🏾 nail polish: medium-dark skin tone
+1F485 1F3FF                                ; fully-qualified     # 💅🏿 nail polish: dark skin tone
+1F933                                      ; fully-qualified     # 🤳 selfie
+1F933 1F3FB                                ; fully-qualified     # 🤳🏻 selfie: light skin tone
+1F933 1F3FC                                ; fully-qualified     # 🤳🏼 selfie: medium-light skin tone
+1F933 1F3FD                                ; fully-qualified     # 🤳🏽 selfie: medium skin tone
+1F933 1F3FE                                ; fully-qualified     # 🤳🏾 selfie: medium-dark skin tone
+1F933 1F3FF                                ; fully-qualified     # 🤳🏿 selfie: dark skin tone
+
+# subgroup: body-parts
+1F4AA                                      ; fully-qualified     # 💪 flexed biceps
+1F4AA 1F3FB                                ; fully-qualified     # 💪🏻 flexed biceps: light skin tone
+1F4AA 1F3FC                                ; fully-qualified     # 💪🏼 flexed biceps: medium-light skin tone
+1F4AA 1F3FD                                ; fully-qualified     # 💪🏽 flexed biceps: medium skin tone
+1F4AA 1F3FE                                ; fully-qualified     # 💪🏾 flexed biceps: medium-dark skin tone
+1F4AA 1F3FF                                ; fully-qualified     # 💪🏿 flexed biceps: dark skin tone
+1F9BE                                      ; fully-qualified     # 🦾 mechanical arm
+1F9BF                                      ; fully-qualified     # 🦿 mechanical leg
+1F9B5                                      ; fully-qualified     # 🦵 leg
+1F9B5 1F3FB                                ; fully-qualified     # 🦵🏻 leg: light skin tone
+1F9B5 1F3FC                                ; fully-qualified     # 🦵🏼 leg: medium-light skin tone
+1F9B5 1F3FD                                ; fully-qualified     # 🦵🏽 leg: medium skin tone
+1F9B5 1F3FE                                ; fully-qualified     # 🦵🏾 leg: medium-dark skin tone
+1F9B5 1F3FF                                ; fully-qualified     # 🦵🏿 leg: dark skin tone
+1F9B6                                      ; fully-qualified     # 🦶 foot
+1F9B6 1F3FB                                ; fully-qualified     # 🦶🏻 foot: light skin tone
+1F9B6 1F3FC                                ; fully-qualified     # 🦶🏼 foot: medium-light skin tone
+1F9B6 1F3FD                                ; fully-qualified     # 🦶🏽 foot: medium skin tone
+1F9B6 1F3FE                                ; fully-qualified     # 🦶🏾 foot: medium-dark skin tone
+1F9B6 1F3FF                                ; fully-qualified     # 🦶🏿 foot: dark skin tone
+1F442                                      ; fully-qualified     # 👂 ear
+1F442 1F3FB                                ; fully-qualified     # 👂🏻 ear: light skin tone
+1F442 1F3FC                                ; fully-qualified     # 👂🏼 ear: medium-light skin tone
+1F442 1F3FD                                ; fully-qualified     # 👂🏽 ear: medium skin tone
+1F442 1F3FE                                ; fully-qualified     # 👂🏾 ear: medium-dark skin tone
+1F442 1F3FF                                ; fully-qualified     # 👂🏿 ear: dark skin tone
+1F9BB                                      ; fully-qualified     # 🦻 ear with hearing aid
+1F9BB 1F3FB                                ; fully-qualified     # 🦻🏻 ear with hearing aid: light skin tone
+1F9BB 1F3FC                                ; fully-qualified     # 🦻🏼 ear with hearing aid: medium-light skin tone
+1F9BB 1F3FD                                ; fully-qualified     # 🦻🏽 ear with hearing aid: medium skin tone
+1F9BB 1F3FE                                ; fully-qualified     # 🦻🏾 ear with hearing aid: medium-dark skin tone
+1F9BB 1F3FF                                ; fully-qualified     # 🦻🏿 ear with hearing aid: dark skin tone
+1F443                                      ; fully-qualified     # 👃 nose
+1F443 1F3FB                                ; fully-qualified     # 👃🏻 nose: light skin tone
+1F443 1F3FC                                ; fully-qualified     # 👃🏼 nose: medium-light skin tone
+1F443 1F3FD                                ; fully-qualified     # 👃🏽 nose: medium skin tone
+1F443 1F3FE                                ; fully-qualified     # 👃🏾 nose: medium-dark skin tone
+1F443 1F3FF                                ; fully-qualified     # 👃🏿 nose: dark skin tone
+1F9E0                                      ; fully-qualified     # 🧠 brain
+1F9B7                                      ; fully-qualified     # 🦷 tooth
+1F9B4                                      ; fully-qualified     # 🦴 bone
+1F440                                      ; fully-qualified     # 👀 eyes
+1F441 FE0F                                 ; fully-qualified     # 👁️ eye
+1F441                                      ; unqualified         # 👁 eye
+1F445                                      ; fully-qualified     # 👅 tongue
+1F444                                      ; fully-qualified     # 👄 mouth
+
+# subgroup: person
+1F476                                      ; fully-qualified     # 👶 baby
+1F476 1F3FB                                ; fully-qualified     # 👶🏻 baby: light skin tone
+1F476 1F3FC                                ; fully-qualified     # 👶🏼 baby: medium-light skin tone
+1F476 1F3FD                                ; fully-qualified     # 👶🏽 baby: medium skin tone
+1F476 1F3FE                                ; fully-qualified     # 👶🏾 baby: medium-dark skin tone
+1F476 1F3FF                                ; fully-qualified     # 👶🏿 baby: dark skin tone
+1F9D2                                      ; fully-qualified     # 🧒 child
+1F9D2 1F3FB                                ; fully-qualified     # 🧒🏻 child: light skin tone
+1F9D2 1F3FC                                ; fully-qualified     # 🧒🏼 child: medium-light skin tone
+1F9D2 1F3FD                                ; fully-qualified     # 🧒🏽 child: medium skin tone
+1F9D2 1F3FE                                ; fully-qualified     # 🧒🏾 child: medium-dark skin tone
+1F9D2 1F3FF                                ; fully-qualified     # 🧒🏿 child: dark skin tone
+1F466                                      ; fully-qualified     # 👦 boy
+1F466 1F3FB                                ; fully-qualified     # 👦🏻 boy: light skin tone
+1F466 1F3FC                                ; fully-qualified     # 👦🏼 boy: medium-light skin tone
+1F466 1F3FD                                ; fully-qualified     # 👦🏽 boy: medium skin tone
+1F466 1F3FE                                ; fully-qualified     # 👦🏾 boy: medium-dark skin tone
+1F466 1F3FF                                ; fully-qualified     # 👦🏿 boy: dark skin tone
+1F467                                      ; fully-qualified     # 👧 girl
+1F467 1F3FB                                ; fully-qualified     # 👧🏻 girl: light skin tone
+1F467 1F3FC                                ; fully-qualified     # 👧🏼 girl: medium-light skin tone
+1F467 1F3FD                                ; fully-qualified     # 👧🏽 girl: medium skin tone
+1F467 1F3FE                                ; fully-qualified     # 👧🏾 girl: medium-dark skin tone
+1F467 1F3FF                                ; fully-qualified     # 👧🏿 girl: dark skin tone
+1F9D1                                      ; fully-qualified     # 🧑 person
+1F9D1 1F3FB                                ; fully-qualified     # 🧑🏻 person: light skin tone
+1F9D1 1F3FC                                ; fully-qualified     # 🧑🏼 person: medium-light skin tone
+1F9D1 1F3FD                                ; fully-qualified     # 🧑🏽 person: medium skin tone
+1F9D1 1F3FE                                ; fully-qualified     # 🧑🏾 person: medium-dark skin tone
+1F9D1 1F3FF                                ; fully-qualified     # 🧑🏿 person: dark skin tone
+1F471                                      ; fully-qualified     # 👱 person: blond hair
+1F471 1F3FB                                ; fully-qualified     # 👱🏻 person: light skin tone, blond hair
+1F471 1F3FC                                ; fully-qualified     # 👱🏼 person: medium-light skin tone, blond hair
+1F471 1F3FD                                ; fully-qualified     # 👱🏽 person: medium skin tone, blond hair
+1F471 1F3FE                                ; fully-qualified     # 👱🏾 person: medium-dark skin tone, blond hair
+1F471 1F3FF                                ; fully-qualified     # 👱🏿 person: dark skin tone, blond hair
+1F468                                      ; fully-qualified     # 👨 man
+1F468 1F3FB                                ; fully-qualified     # 👨🏻 man: light skin tone
+1F468 1F3FC                                ; fully-qualified     # 👨🏼 man: medium-light skin tone
+1F468 1F3FD                                ; fully-qualified     # 👨🏽 man: medium skin tone
+1F468 1F3FE                                ; fully-qualified     # 👨🏾 man: medium-dark skin tone
+1F468 1F3FF                                ; fully-qualified     # 👨🏿 man: dark skin tone
+1F9D4                                      ; fully-qualified     # 🧔 man: beard
+1F9D4 1F3FB                                ; fully-qualified     # 🧔🏻 man: light skin tone, beard
+1F9D4 1F3FC                                ; fully-qualified     # 🧔🏼 man: medium-light skin tone, beard
+1F9D4 1F3FD                                ; fully-qualified     # 🧔🏽 man: medium skin tone, beard
+1F9D4 1F3FE                                ; fully-qualified     # 🧔🏾 man: medium-dark skin tone, beard
+1F9D4 1F3FF                                ; fully-qualified     # 🧔🏿 man: dark skin tone, beard
+1F471 200D 2642 FE0F                       ; fully-qualified     # 👱‍♂️ man: blond hair
+1F471 200D 2642                            ; minimally-qualified # 👱‍♂ man: blond hair
+1F471 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 👱🏻‍♂️ man: light skin tone, blond hair
+1F471 1F3FB 200D 2642                      ; minimally-qualified # 👱🏻‍♂ man: light skin tone, blond hair
+1F471 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 👱🏼‍♂️ man: medium-light skin tone, blond hair
+1F471 1F3FC 200D 2642                      ; minimally-qualified # 👱🏼‍♂ man: medium-light skin tone, blond hair
+1F471 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 👱🏽‍♂️ man: medium skin tone, blond hair
+1F471 1F3FD 200D 2642                      ; minimally-qualified # 👱🏽‍♂ man: medium skin tone, blond hair
+1F471 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 👱🏾‍♂️ man: medium-dark skin tone, blond hair
+1F471 1F3FE 200D 2642                      ; minimally-qualified # 👱🏾‍♂ man: medium-dark skin tone, blond hair
+1F471 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 👱🏿‍♂️ man: dark skin tone, blond hair
+1F471 1F3FF 200D 2642                      ; minimally-qualified # 👱🏿‍♂ man: dark skin tone, blond hair
+1F468 200D 1F9B0                           ; fully-qualified     # 👨‍🦰 man: red hair
+1F468 1F3FB 200D 1F9B0                     ; fully-qualified     # 👨🏻‍🦰 man: light skin tone, red hair
+1F468 1F3FC 200D 1F9B0                     ; fully-qualified     # 👨🏼‍🦰 man: medium-light skin tone, red hair
+1F468 1F3FD 200D 1F9B0                     ; fully-qualified     # 👨🏽‍🦰 man: medium skin tone, red hair
+1F468 1F3FE 200D 1F9B0                     ; fully-qualified     # 👨🏾‍🦰 man: medium-dark skin tone, red hair
+1F468 1F3FF 200D 1F9B0                     ; fully-qualified     # 👨🏿‍🦰 man: dark skin tone, red hair
+1F468 200D 1F9B1                           ; fully-qualified     # 👨‍🦱 man: curly hair
+1F468 1F3FB 200D 1F9B1                     ; fully-qualified     # 👨🏻‍🦱 man: light skin tone, curly hair
+1F468 1F3FC 200D 1F9B1                     ; fully-qualified     # 👨🏼‍🦱 man: medium-light skin tone, curly hair
+1F468 1F3FD 200D 1F9B1                     ; fully-qualified     # 👨🏽‍🦱 man: medium skin tone, curly hair
+1F468 1F3FE 200D 1F9B1                     ; fully-qualified     # 👨🏾‍🦱 man: medium-dark skin tone, curly hair
+1F468 1F3FF 200D 1F9B1                     ; fully-qualified     # 👨🏿‍🦱 man: dark skin tone, curly hair
+1F468 200D 1F9B3                           ; fully-qualified     # 👨‍🦳 man: white hair
+1F468 1F3FB 200D 1F9B3                     ; fully-qualified     # 👨🏻‍🦳 man: light skin tone, white hair
+1F468 1F3FC 200D 1F9B3                     ; fully-qualified     # 👨🏼‍🦳 man: medium-light skin tone, white hair
+1F468 1F3FD 200D 1F9B3                     ; fully-qualified     # 👨🏽‍🦳 man: medium skin tone, white hair
+1F468 1F3FE 200D 1F9B3                     ; fully-qualified     # 👨🏾‍🦳 man: medium-dark skin tone, white hair
+1F468 1F3FF 200D 1F9B3                     ; fully-qualified     # 👨🏿‍🦳 man: dark skin tone, white hair
+1F468 200D 1F9B2                           ; fully-qualified     # 👨‍🦲 man: bald
+1F468 1F3FB 200D 1F9B2                     ; fully-qualified     # 👨🏻‍🦲 man: light skin tone, bald
+1F468 1F3FC 200D 1F9B2                     ; fully-qualified     # 👨🏼‍🦲 man: medium-light skin tone, bald
+1F468 1F3FD 200D 1F9B2                     ; fully-qualified     # 👨🏽‍🦲 man: medium skin tone, bald
+1F468 1F3FE 200D 1F9B2                     ; fully-qualified     # 👨🏾‍🦲 man: medium-dark skin tone, bald
+1F468 1F3FF 200D 1F9B2                     ; fully-qualified     # 👨🏿‍🦲 man: dark skin tone, bald
+1F469                                      ; fully-qualified     # 👩 woman
+1F469 1F3FB                                ; fully-qualified     # 👩🏻 woman: light skin tone
+1F469 1F3FC                                ; fully-qualified     # 👩🏼 woman: medium-light skin tone
+1F469 1F3FD                                ; fully-qualified     # 👩🏽 woman: medium skin tone
+1F469 1F3FE                                ; fully-qualified     # 👩🏾 woman: medium-dark skin tone
+1F469 1F3FF                                ; fully-qualified     # 👩🏿 woman: dark skin tone
+1F471 200D 2640 FE0F                       ; fully-qualified     # 👱‍♀️ woman: blond hair
+1F471 200D 2640                            ; minimally-qualified # 👱‍♀ woman: blond hair
+1F471 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 👱🏻‍♀️ woman: light skin tone, blond hair
+1F471 1F3FB 200D 2640                      ; minimally-qualified # 👱🏻‍♀ woman: light skin tone, blond hair
+1F471 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 👱🏼‍♀️ woman: medium-light skin tone, blond hair
+1F471 1F3FC 200D 2640                      ; minimally-qualified # 👱🏼‍♀ woman: medium-light skin tone, blond hair
+1F471 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 👱🏽‍♀️ woman: medium skin tone, blond hair
+1F471 1F3FD 200D 2640                      ; minimally-qualified # 👱🏽‍♀ woman: medium skin tone, blond hair
+1F471 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 👱🏾‍♀️ woman: medium-dark skin tone, blond hair
+1F471 1F3FE 200D 2640                      ; minimally-qualified # 👱🏾‍♀ woman: medium-dark skin tone, blond hair
+1F471 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 👱🏿‍♀️ woman: dark skin tone, blond hair
+1F471 1F3FF 200D 2640                      ; minimally-qualified # 👱🏿‍♀ woman: dark skin tone, blond hair
+1F469 200D 1F9B0                           ; fully-qualified     # 👩‍🦰 woman: red hair
+1F469 1F3FB 200D 1F9B0                     ; fully-qualified     # 👩🏻‍🦰 woman: light skin tone, red hair
+1F469 1F3FC 200D 1F9B0                     ; fully-qualified     # 👩🏼‍🦰 woman: medium-light skin tone, red hair
+1F469 1F3FD 200D 1F9B0                     ; fully-qualified     # 👩🏽‍🦰 woman: medium skin tone, red hair
+1F469 1F3FE 200D 1F9B0                     ; fully-qualified     # 👩🏾‍🦰 woman: medium-dark skin tone, red hair
+1F469 1F3FF 200D 1F9B0                     ; fully-qualified     # 👩🏿‍🦰 woman: dark skin tone, red hair
+1F469 200D 1F9B1                           ; fully-qualified     # 👩‍🦱 woman: curly hair
+1F469 1F3FB 200D 1F9B1                     ; fully-qualified     # 👩🏻‍🦱 woman: light skin tone, curly hair
+1F469 1F3FC 200D 1F9B1                     ; fully-qualified     # 👩🏼‍🦱 woman: medium-light skin tone, curly hair
+1F469 1F3FD 200D 1F9B1                     ; fully-qualified     # 👩🏽‍🦱 woman: medium skin tone, curly hair
+1F469 1F3FE 200D 1F9B1                     ; fully-qualified     # 👩🏾‍🦱 woman: medium-dark skin tone, curly hair
+1F469 1F3FF 200D 1F9B1                     ; fully-qualified     # 👩🏿‍🦱 woman: dark skin tone, curly hair
+1F469 200D 1F9B3                           ; fully-qualified     # 👩‍🦳 woman: white hair
+1F469 1F3FB 200D 1F9B3                     ; fully-qualified     # 👩🏻‍🦳 woman: light skin tone, white hair
+1F469 1F3FC 200D 1F9B3                     ; fully-qualified     # 👩🏼‍🦳 woman: medium-light skin tone, white hair
+1F469 1F3FD 200D 1F9B3                     ; fully-qualified     # 👩🏽‍🦳 woman: medium skin tone, white hair
+1F469 1F3FE 200D 1F9B3                     ; fully-qualified     # 👩🏾‍🦳 woman: medium-dark skin tone, white hair
+1F469 1F3FF 200D 1F9B3                     ; fully-qualified     # 👩🏿‍🦳 woman: dark skin tone, white hair
+1F469 200D 1F9B2                           ; fully-qualified     # 👩‍🦲 woman: bald
+1F469 1F3FB 200D 1F9B2                     ; fully-qualified     # 👩🏻‍🦲 woman: light skin tone, bald
+1F469 1F3FC 200D 1F9B2                     ; fully-qualified     # 👩🏼‍🦲 woman: medium-light skin tone, bald
+1F469 1F3FD 200D 1F9B2                     ; fully-qualified     # 👩🏽‍🦲 woman: medium skin tone, bald
+1F469 1F3FE 200D 1F9B2                     ; fully-qualified     # 👩🏾‍🦲 woman: medium-dark skin tone, bald
+1F469 1F3FF 200D 1F9B2                     ; fully-qualified     # 👩🏿‍🦲 woman: dark skin tone, bald
+1F9D3                                      ; fully-qualified     # 🧓 older person
+1F9D3 1F3FB                                ; fully-qualified     # 🧓🏻 older person: light skin tone
+1F9D3 1F3FC                                ; fully-qualified     # 🧓🏼 older person: medium-light skin tone
+1F9D3 1F3FD                                ; fully-qualified     # 🧓🏽 older person: medium skin tone
+1F9D3 1F3FE                                ; fully-qualified     # 🧓🏾 older person: medium-dark skin tone
+1F9D3 1F3FF                                ; fully-qualified     # 🧓🏿 older person: dark skin tone
+1F474                                      ; fully-qualified     # 👴 old man
+1F474 1F3FB                                ; fully-qualified     # 👴🏻 old man: light skin tone
+1F474 1F3FC                                ; fully-qualified     # 👴🏼 old man: medium-light skin tone
+1F474 1F3FD                                ; fully-qualified     # 👴🏽 old man: medium skin tone
+1F474 1F3FE                                ; fully-qualified     # 👴🏾 old man: medium-dark skin tone
+1F474 1F3FF                                ; fully-qualified     # 👴🏿 old man: dark skin tone
+1F475                                      ; fully-qualified     # 👵 old woman
+1F475 1F3FB                                ; fully-qualified     # 👵🏻 old woman: light skin tone
+1F475 1F3FC                                ; fully-qualified     # 👵🏼 old woman: medium-light skin tone
+1F475 1F3FD                                ; fully-qualified     # 👵🏽 old woman: medium skin tone
+1F475 1F3FE                                ; fully-qualified     # 👵🏾 old woman: medium-dark skin tone
+1F475 1F3FF                                ; fully-qualified     # 👵🏿 old woman: dark skin tone
+
+# subgroup: person-gesture
+1F64D                                      ; fully-qualified     # 🙍 person frowning
+1F64D 1F3FB                                ; fully-qualified     # 🙍🏻 person frowning: light skin tone
+1F64D 1F3FC                                ; fully-qualified     # 🙍🏼 person frowning: medium-light skin tone
+1F64D 1F3FD                                ; fully-qualified     # 🙍🏽 person frowning: medium skin tone
+1F64D 1F3FE                                ; fully-qualified     # 🙍🏾 person frowning: medium-dark skin tone
+1F64D 1F3FF                                ; fully-qualified     # 🙍🏿 person frowning: dark skin tone
+1F64D 200D 2642 FE0F                       ; fully-qualified     # 🙍‍♂️ man frowning
+1F64D 200D 2642                            ; minimally-qualified # 🙍‍♂ man frowning
+1F64D 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🙍🏻‍♂️ man frowning: light skin tone
+1F64D 1F3FB 200D 2642                      ; minimally-qualified # 🙍🏻‍♂ man frowning: light skin tone
+1F64D 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🙍🏼‍♂️ man frowning: medium-light skin tone
+1F64D 1F3FC 200D 2642                      ; minimally-qualified # 🙍🏼‍♂ man frowning: medium-light skin tone
+1F64D 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🙍🏽‍♂️ man frowning: medium skin tone
+1F64D 1F3FD 200D 2642                      ; minimally-qualified # 🙍🏽‍♂ man frowning: medium skin tone
+1F64D 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🙍🏾‍♂️ man frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2642                      ; minimally-qualified # 🙍🏾‍♂ man frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🙍🏿‍♂️ man frowning: dark skin tone
+1F64D 1F3FF 200D 2642                      ; minimally-qualified # 🙍🏿‍♂ man frowning: dark skin tone
+1F64D 200D 2640 FE0F                       ; fully-qualified     # 🙍‍♀️ woman frowning
+1F64D 200D 2640                            ; minimally-qualified # 🙍‍♀ woman frowning
+1F64D 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🙍🏻‍♀️ woman frowning: light skin tone
+1F64D 1F3FB 200D 2640                      ; minimally-qualified # 🙍🏻‍♀ woman frowning: light skin tone
+1F64D 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🙍🏼‍♀️ woman frowning: medium-light skin tone
+1F64D 1F3FC 200D 2640                      ; minimally-qualified # 🙍🏼‍♀ woman frowning: medium-light skin tone
+1F64D 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🙍🏽‍♀️ woman frowning: medium skin tone
+1F64D 1F3FD 200D 2640                      ; minimally-qualified # 🙍🏽‍♀ woman frowning: medium skin tone
+1F64D 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🙍🏾‍♀️ woman frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2640                      ; minimally-qualified # 🙍🏾‍♀ woman frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🙍🏿‍♀️ woman frowning: dark skin tone
+1F64D 1F3FF 200D 2640                      ; minimally-qualified # 🙍🏿‍♀ woman frowning: dark skin tone
+1F64E                                      ; fully-qualified     # 🙎 person pouting
+1F64E 1F3FB                                ; fully-qualified     # 🙎🏻 person pouting: light skin tone
+1F64E 1F3FC                                ; fully-qualified     # 🙎🏼 person pouting: medium-light skin tone
+1F64E 1F3FD                                ; fully-qualified     # 🙎🏽 person pouting: medium skin tone
+1F64E 1F3FE                                ; fully-qualified     # 🙎🏾 person pouting: medium-dark skin tone
+1F64E 1F3FF                                ; fully-qualified     # 🙎🏿 person pouting: dark skin tone
+1F64E 200D 2642 FE0F                       ; fully-qualified     # 🙎‍♂️ man pouting
+1F64E 200D 2642                            ; minimally-qualified # 🙎‍♂ man pouting
+1F64E 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🙎🏻‍♂️ man pouting: light skin tone
+1F64E 1F3FB 200D 2642                      ; minimally-qualified # 🙎🏻‍♂ man pouting: light skin tone
+1F64E 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🙎🏼‍♂️ man pouting: medium-light skin tone
+1F64E 1F3FC 200D 2642                      ; minimally-qualified # 🙎🏼‍♂ man pouting: medium-light skin tone
+1F64E 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🙎🏽‍♂️ man pouting: medium skin tone
+1F64E 1F3FD 200D 2642                      ; minimally-qualified # 🙎🏽‍♂ man pouting: medium skin tone
+1F64E 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🙎🏾‍♂️ man pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2642                      ; minimally-qualified # 🙎🏾‍♂ man pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🙎🏿‍♂️ man pouting: dark skin tone
+1F64E 1F3FF 200D 2642                      ; minimally-qualified # 🙎🏿‍♂ man pouting: dark skin tone
+1F64E 200D 2640 FE0F                       ; fully-qualified     # 🙎‍♀️ woman pouting
+1F64E 200D 2640                            ; minimally-qualified # 🙎‍♀ woman pouting
+1F64E 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🙎🏻‍♀️ woman pouting: light skin tone
+1F64E 1F3FB 200D 2640                      ; minimally-qualified # 🙎🏻‍♀ woman pouting: light skin tone
+1F64E 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🙎🏼‍♀️ woman pouting: medium-light skin tone
+1F64E 1F3FC 200D 2640                      ; minimally-qualified # 🙎🏼‍♀ woman pouting: medium-light skin tone
+1F64E 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🙎🏽‍♀️ woman pouting: medium skin tone
+1F64E 1F3FD 200D 2640                      ; minimally-qualified # 🙎🏽‍♀ woman pouting: medium skin tone
+1F64E 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🙎🏾‍♀️ woman pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2640                      ; minimally-qualified # 🙎🏾‍♀ woman pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🙎🏿‍♀️ woman pouting: dark skin tone
+1F64E 1F3FF 200D 2640                      ; minimally-qualified # 🙎🏿‍♀ woman pouting: dark skin tone
+1F645                                      ; fully-qualified     # 🙅 person gesturing NO
+1F645 1F3FB                                ; fully-qualified     # 🙅🏻 person gesturing NO: light skin tone
+1F645 1F3FC                                ; fully-qualified     # 🙅🏼 person gesturing NO: medium-light skin tone
+1F645 1F3FD                                ; fully-qualified     # 🙅🏽 person gesturing NO: medium skin tone
+1F645 1F3FE                                ; fully-qualified     # 🙅🏾 person gesturing NO: medium-dark skin tone
+1F645 1F3FF                                ; fully-qualified     # 🙅🏿 person gesturing NO: dark skin tone
+1F645 200D 2642 FE0F                       ; fully-qualified     # 🙅‍♂️ man gesturing NO
+1F645 200D 2642                            ; minimally-qualified # 🙅‍♂ man gesturing NO
+1F645 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🙅🏻‍♂️ man gesturing NO: light skin tone
+1F645 1F3FB 200D 2642                      ; minimally-qualified # 🙅🏻‍♂ man gesturing NO: light skin tone
+1F645 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🙅🏼‍♂️ man gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2642                      ; minimally-qualified # 🙅🏼‍♂ man gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🙅🏽‍♂️ man gesturing NO: medium skin tone
+1F645 1F3FD 200D 2642                      ; minimally-qualified # 🙅🏽‍♂ man gesturing NO: medium skin tone
+1F645 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🙅🏾‍♂️ man gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2642                      ; minimally-qualified # 🙅🏾‍♂ man gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🙅🏿‍♂️ man gesturing NO: dark skin tone
+1F645 1F3FF 200D 2642                      ; minimally-qualified # 🙅🏿‍♂ man gesturing NO: dark skin tone
+1F645 200D 2640 FE0F                       ; fully-qualified     # 🙅‍♀️ woman gesturing NO
+1F645 200D 2640                            ; minimally-qualified # 🙅‍♀ woman gesturing NO
+1F645 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🙅🏻‍♀️ woman gesturing NO: light skin tone
+1F645 1F3FB 200D 2640                      ; minimally-qualified # 🙅🏻‍♀ woman gesturing NO: light skin tone
+1F645 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🙅🏼‍♀️ woman gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2640                      ; minimally-qualified # 🙅🏼‍♀ woman gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🙅🏽‍♀️ woman gesturing NO: medium skin tone
+1F645 1F3FD 200D 2640                      ; minimally-qualified # 🙅🏽‍♀ woman gesturing NO: medium skin tone
+1F645 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🙅🏾‍♀️ woman gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2640                      ; minimally-qualified # 🙅🏾‍♀ woman gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🙅🏿‍♀️ woman gesturing NO: dark skin tone
+1F645 1F3FF 200D 2640                      ; minimally-qualified # 🙅🏿‍♀ woman gesturing NO: dark skin tone
+1F646                                      ; fully-qualified     # 🙆 person gesturing OK
+1F646 1F3FB                                ; fully-qualified     # 🙆🏻 person gesturing OK: light skin tone
+1F646 1F3FC                                ; fully-qualified     # 🙆🏼 person gesturing OK: medium-light skin tone
+1F646 1F3FD                                ; fully-qualified     # 🙆🏽 person gesturing OK: medium skin tone
+1F646 1F3FE                                ; fully-qualified     # 🙆🏾 person gesturing OK: medium-dark skin tone
+1F646 1F3FF                                ; fully-qualified     # 🙆🏿 person gesturing OK: dark skin tone
+1F646 200D 2642 FE0F                       ; fully-qualified     # 🙆‍♂️ man gesturing OK
+1F646 200D 2642                            ; minimally-qualified # 🙆‍♂ man gesturing OK
+1F646 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🙆🏻‍♂️ man gesturing OK: light skin tone
+1F646 1F3FB 200D 2642                      ; minimally-qualified # 🙆🏻‍♂ man gesturing OK: light skin tone
+1F646 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🙆🏼‍♂️ man gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2642                      ; minimally-qualified # 🙆🏼‍♂ man gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🙆🏽‍♂️ man gesturing OK: medium skin tone
+1F646 1F3FD 200D 2642                      ; minimally-qualified # 🙆🏽‍♂ man gesturing OK: medium skin tone
+1F646 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🙆🏾‍♂️ man gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2642                      ; minimally-qualified # 🙆🏾‍♂ man gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🙆🏿‍♂️ man gesturing OK: dark skin tone
+1F646 1F3FF 200D 2642                      ; minimally-qualified # 🙆🏿‍♂ man gesturing OK: dark skin tone
+1F646 200D 2640 FE0F                       ; fully-qualified     # 🙆‍♀️ woman gesturing OK
+1F646 200D 2640                            ; minimally-qualified # 🙆‍♀ woman gesturing OK
+1F646 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🙆🏻‍♀️ woman gesturing OK: light skin tone
+1F646 1F3FB 200D 2640                      ; minimally-qualified # 🙆🏻‍♀ woman gesturing OK: light skin tone
+1F646 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🙆🏼‍♀️ woman gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2640                      ; minimally-qualified # 🙆🏼‍♀ woman gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🙆🏽‍♀️ woman gesturing OK: medium skin tone
+1F646 1F3FD 200D 2640                      ; minimally-qualified # 🙆🏽‍♀ woman gesturing OK: medium skin tone
+1F646 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🙆🏾‍♀️ woman gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2640                      ; minimally-qualified # 🙆🏾‍♀ woman gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🙆🏿‍♀️ woman gesturing OK: dark skin tone
+1F646 1F3FF 200D 2640                      ; minimally-qualified # 🙆🏿‍♀ woman gesturing OK: dark skin tone
+1F481                                      ; fully-qualified     # 💁 person tipping hand
+1F481 1F3FB                                ; fully-qualified     # 💁🏻 person tipping hand: light skin tone
+1F481 1F3FC                                ; fully-qualified     # 💁🏼 person tipping hand: medium-light skin tone
+1F481 1F3FD                                ; fully-qualified     # 💁🏽 person tipping hand: medium skin tone
+1F481 1F3FE                                ; fully-qualified     # 💁🏾 person tipping hand: medium-dark skin tone
+1F481 1F3FF                                ; fully-qualified     # 💁🏿 person tipping hand: dark skin tone
+1F481 200D 2642 FE0F                       ; fully-qualified     # 💁‍♂️ man tipping hand
+1F481 200D 2642                            ; minimally-qualified # 💁‍♂ man tipping hand
+1F481 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 💁🏻‍♂️ man tipping hand: light skin tone
+1F481 1F3FB 200D 2642                      ; minimally-qualified # 💁🏻‍♂ man tipping hand: light skin tone
+1F481 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 💁🏼‍♂️ man tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2642                      ; minimally-qualified # 💁🏼‍♂ man tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 💁🏽‍♂️ man tipping hand: medium skin tone
+1F481 1F3FD 200D 2642                      ; minimally-qualified # 💁🏽‍♂ man tipping hand: medium skin tone
+1F481 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 💁🏾‍♂️ man tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2642                      ; minimally-qualified # 💁🏾‍♂ man tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 💁🏿‍♂️ man tipping hand: dark skin tone
+1F481 1F3FF 200D 2642                      ; minimally-qualified # 💁🏿‍♂ man tipping hand: dark skin tone
+1F481 200D 2640 FE0F                       ; fully-qualified     # 💁‍♀️ woman tipping hand
+1F481 200D 2640                            ; minimally-qualified # 💁‍♀ woman tipping hand
+1F481 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 💁🏻‍♀️ woman tipping hand: light skin tone
+1F481 1F3FB 200D 2640                      ; minimally-qualified # 💁🏻‍♀ woman tipping hand: light skin tone
+1F481 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 💁🏼‍♀️ woman tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2640                      ; minimally-qualified # 💁🏼‍♀ woman tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 💁🏽‍♀️ woman tipping hand: medium skin tone
+1F481 1F3FD 200D 2640                      ; minimally-qualified # 💁🏽‍♀ woman tipping hand: medium skin tone
+1F481 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 💁🏾‍♀️ woman tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2640                      ; minimally-qualified # 💁🏾‍♀ woman tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 💁🏿‍♀️ woman tipping hand: dark skin tone
+1F481 1F3FF 200D 2640                      ; minimally-qualified # 💁🏿‍♀ woman tipping hand: dark skin tone
+1F64B                                      ; fully-qualified     # 🙋 person raising hand
+1F64B 1F3FB                                ; fully-qualified     # 🙋🏻 person raising hand: light skin tone
+1F64B 1F3FC                                ; fully-qualified     # 🙋🏼 person raising hand: medium-light skin tone
+1F64B 1F3FD                                ; fully-qualified     # 🙋🏽 person raising hand: medium skin tone
+1F64B 1F3FE                                ; fully-qualified     # 🙋🏾 person raising hand: medium-dark skin tone
+1F64B 1F3FF                                ; fully-qualified     # 🙋🏿 person raising hand: dark skin tone
+1F64B 200D 2642 FE0F                       ; fully-qualified     # 🙋‍♂️ man raising hand
+1F64B 200D 2642                            ; minimally-qualified # 🙋‍♂ man raising hand
+1F64B 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🙋🏻‍♂️ man raising hand: light skin tone
+1F64B 1F3FB 200D 2642                      ; minimally-qualified # 🙋🏻‍♂ man raising hand: light skin tone
+1F64B 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🙋🏼‍♂️ man raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2642                      ; minimally-qualified # 🙋🏼‍♂ man raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🙋🏽‍♂️ man raising hand: medium skin tone
+1F64B 1F3FD 200D 2642                      ; minimally-qualified # 🙋🏽‍♂ man raising hand: medium skin tone
+1F64B 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🙋🏾‍♂️ man raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2642                      ; minimally-qualified # 🙋🏾‍♂ man raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🙋🏿‍♂️ man raising hand: dark skin tone
+1F64B 1F3FF 200D 2642                      ; minimally-qualified # 🙋🏿‍♂ man raising hand: dark skin tone
+1F64B 200D 2640 FE0F                       ; fully-qualified     # 🙋‍♀️ woman raising hand
+1F64B 200D 2640                            ; minimally-qualified # 🙋‍♀ woman raising hand
+1F64B 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🙋🏻‍♀️ woman raising hand: light skin tone
+1F64B 1F3FB 200D 2640                      ; minimally-qualified # 🙋🏻‍♀ woman raising hand: light skin tone
+1F64B 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🙋🏼‍♀️ woman raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2640                      ; minimally-qualified # 🙋🏼‍♀ woman raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🙋🏽‍♀️ woman raising hand: medium skin tone
+1F64B 1F3FD 200D 2640                      ; minimally-qualified # 🙋🏽‍♀ woman raising hand: medium skin tone
+1F64B 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🙋🏾‍♀️ woman raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2640                      ; minimally-qualified # 🙋🏾‍♀ woman raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🙋🏿‍♀️ woman raising hand: dark skin tone
+1F64B 1F3FF 200D 2640                      ; minimally-qualified # 🙋🏿‍♀ woman raising hand: dark skin tone
+1F9CF                                      ; fully-qualified     # 🧏 deaf person
+1F9CF 1F3FB                                ; fully-qualified     # 🧏🏻 deaf person: light skin tone
+1F9CF 1F3FC                                ; fully-qualified     # 🧏🏼 deaf person: medium-light skin tone
+1F9CF 1F3FD                                ; fully-qualified     # 🧏🏽 deaf person: medium skin tone
+1F9CF 1F3FE                                ; fully-qualified     # 🧏🏾 deaf person: medium-dark skin tone
+1F9CF 1F3FF                                ; fully-qualified     # 🧏🏿 deaf person: dark skin tone
+1F9CF 200D 2642 FE0F                       ; fully-qualified     # 🧏‍♂️ deaf man
+1F9CF 200D 2642                            ; minimally-qualified # 🧏‍♂ deaf man
+1F9CF 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧏🏻‍♂️ deaf man: light skin tone
+1F9CF 1F3FB 200D 2642                      ; minimally-qualified # 🧏🏻‍♂ deaf man: light skin tone
+1F9CF 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧏🏼‍♂️ deaf man: medium-light skin tone
+1F9CF 1F3FC 200D 2642                      ; minimally-qualified # 🧏🏼‍♂ deaf man: medium-light skin tone
+1F9CF 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧏🏽‍♂️ deaf man: medium skin tone
+1F9CF 1F3FD 200D 2642                      ; minimally-qualified # 🧏🏽‍♂ deaf man: medium skin tone
+1F9CF 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧏🏾‍♂️ deaf man: medium-dark skin tone
+1F9CF 1F3FE 200D 2642                      ; minimally-qualified # 🧏🏾‍♂ deaf man: medium-dark skin tone
+1F9CF 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧏🏿‍♂️ deaf man: dark skin tone
+1F9CF 1F3FF 200D 2642                      ; minimally-qualified # 🧏🏿‍♂ deaf man: dark skin tone
+1F9CF 200D 2640 FE0F                       ; fully-qualified     # 🧏‍♀️ deaf woman
+1F9CF 200D 2640                            ; minimally-qualified # 🧏‍♀ deaf woman
+1F9CF 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧏🏻‍♀️ deaf woman: light skin tone
+1F9CF 1F3FB 200D 2640                      ; minimally-qualified # 🧏🏻‍♀ deaf woman: light skin tone
+1F9CF 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧏🏼‍♀️ deaf woman: medium-light skin tone
+1F9CF 1F3FC 200D 2640                      ; minimally-qualified # 🧏🏼‍♀ deaf woman: medium-light skin tone
+1F9CF 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧏🏽‍♀️ deaf woman: medium skin tone
+1F9CF 1F3FD 200D 2640                      ; minimally-qualified # 🧏🏽‍♀ deaf woman: medium skin tone
+1F9CF 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧏🏾‍♀️ deaf woman: medium-dark skin tone
+1F9CF 1F3FE 200D 2640                      ; minimally-qualified # 🧏🏾‍♀ deaf woman: medium-dark skin tone
+1F9CF 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧏🏿‍♀️ deaf woman: dark skin tone
+1F9CF 1F3FF 200D 2640                      ; minimally-qualified # 🧏🏿‍♀ deaf woman: dark skin tone
+1F647                                      ; fully-qualified     # 🙇 person bowing
+1F647 1F3FB                                ; fully-qualified     # 🙇🏻 person bowing: light skin tone
+1F647 1F3FC                                ; fully-qualified     # 🙇🏼 person bowing: medium-light skin tone
+1F647 1F3FD                                ; fully-qualified     # 🙇🏽 person bowing: medium skin tone
+1F647 1F3FE                                ; fully-qualified     # 🙇🏾 person bowing: medium-dark skin tone
+1F647 1F3FF                                ; fully-qualified     # 🙇🏿 person bowing: dark skin tone
+1F647 200D 2642 FE0F                       ; fully-qualified     # 🙇‍♂️ man bowing
+1F647 200D 2642                            ; minimally-qualified # 🙇‍♂ man bowing
+1F647 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🙇🏻‍♂️ man bowing: light skin tone
+1F647 1F3FB 200D 2642                      ; minimally-qualified # 🙇🏻‍♂ man bowing: light skin tone
+1F647 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🙇🏼‍♂️ man bowing: medium-light skin tone
+1F647 1F3FC 200D 2642                      ; minimally-qualified # 🙇🏼‍♂ man bowing: medium-light skin tone
+1F647 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🙇🏽‍♂️ man bowing: medium skin tone
+1F647 1F3FD 200D 2642                      ; minimally-qualified # 🙇🏽‍♂ man bowing: medium skin tone
+1F647 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🙇🏾‍♂️ man bowing: medium-dark skin tone
+1F647 1F3FE 200D 2642                      ; minimally-qualified # 🙇🏾‍♂ man bowing: medium-dark skin tone
+1F647 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🙇🏿‍♂️ man bowing: dark skin tone
+1F647 1F3FF 200D 2642                      ; minimally-qualified # 🙇🏿‍♂ man bowing: dark skin tone
+1F647 200D 2640 FE0F                       ; fully-qualified     # 🙇‍♀️ woman bowing
+1F647 200D 2640                            ; minimally-qualified # 🙇‍♀ woman bowing
+1F647 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🙇🏻‍♀️ woman bowing: light skin tone
+1F647 1F3FB 200D 2640                      ; minimally-qualified # 🙇🏻‍♀ woman bowing: light skin tone
+1F647 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🙇🏼‍♀️ woman bowing: medium-light skin tone
+1F647 1F3FC 200D 2640                      ; minimally-qualified # 🙇🏼‍♀ woman bowing: medium-light skin tone
+1F647 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🙇🏽‍♀️ woman bowing: medium skin tone
+1F647 1F3FD 200D 2640                      ; minimally-qualified # 🙇🏽‍♀ woman bowing: medium skin tone
+1F647 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🙇🏾‍♀️ woman bowing: medium-dark skin tone
+1F647 1F3FE 200D 2640                      ; minimally-qualified # 🙇🏾‍♀ woman bowing: medium-dark skin tone
+1F647 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🙇🏿‍♀️ woman bowing: dark skin tone
+1F647 1F3FF 200D 2640                      ; minimally-qualified # 🙇🏿‍♀ woman bowing: dark skin tone
+1F926                                      ; fully-qualified     # 🤦 person facepalming
+1F926 1F3FB                                ; fully-qualified     # 🤦🏻 person facepalming: light skin tone
+1F926 1F3FC                                ; fully-qualified     # 🤦🏼 person facepalming: medium-light skin tone
+1F926 1F3FD                                ; fully-qualified     # 🤦🏽 person facepalming: medium skin tone
+1F926 1F3FE                                ; fully-qualified     # 🤦🏾 person facepalming: medium-dark skin tone
+1F926 1F3FF                                ; fully-qualified     # 🤦🏿 person facepalming: dark skin tone
+1F926 200D 2642 FE0F                       ; fully-qualified     # 🤦‍♂️ man facepalming
+1F926 200D 2642                            ; minimally-qualified # 🤦‍♂ man facepalming
+1F926 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🤦🏻‍♂️ man facepalming: light skin tone
+1F926 1F3FB 200D 2642                      ; minimally-qualified # 🤦🏻‍♂ man facepalming: light skin tone
+1F926 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🤦🏼‍♂️ man facepalming: medium-light skin tone
+1F926 1F3FC 200D 2642                      ; minimally-qualified # 🤦🏼‍♂ man facepalming: medium-light skin tone
+1F926 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🤦🏽‍♂️ man facepalming: medium skin tone
+1F926 1F3FD 200D 2642                      ; minimally-qualified # 🤦🏽‍♂ man facepalming: medium skin tone
+1F926 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🤦🏾‍♂️ man facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2642                      ; minimally-qualified # 🤦🏾‍♂ man facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🤦🏿‍♂️ man facepalming: dark skin tone
+1F926 1F3FF 200D 2642                      ; minimally-qualified # 🤦🏿‍♂ man facepalming: dark skin tone
+1F926 200D 2640 FE0F                       ; fully-qualified     # 🤦‍♀️ woman facepalming
+1F926 200D 2640                            ; minimally-qualified # 🤦‍♀ woman facepalming
+1F926 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🤦🏻‍♀️ woman facepalming: light skin tone
+1F926 1F3FB 200D 2640                      ; minimally-qualified # 🤦🏻‍♀ woman facepalming: light skin tone
+1F926 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🤦🏼‍♀️ woman facepalming: medium-light skin tone
+1F926 1F3FC 200D 2640                      ; minimally-qualified # 🤦🏼‍♀ woman facepalming: medium-light skin tone
+1F926 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🤦🏽‍♀️ woman facepalming: medium skin tone
+1F926 1F3FD 200D 2640                      ; minimally-qualified # 🤦🏽‍♀ woman facepalming: medium skin tone
+1F926 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🤦🏾‍♀️ woman facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2640                      ; minimally-qualified # 🤦🏾‍♀ woman facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🤦🏿‍♀️ woman facepalming: dark skin tone
+1F926 1F3FF 200D 2640                      ; minimally-qualified # 🤦🏿‍♀ woman facepalming: dark skin tone
+1F937                                      ; fully-qualified     # 🤷 person shrugging
+1F937 1F3FB                                ; fully-qualified     # 🤷🏻 person shrugging: light skin tone
+1F937 1F3FC                                ; fully-qualified     # 🤷🏼 person shrugging: medium-light skin tone
+1F937 1F3FD                                ; fully-qualified     # 🤷🏽 person shrugging: medium skin tone
+1F937 1F3FE                                ; fully-qualified     # 🤷🏾 person shrugging: medium-dark skin tone
+1F937 1F3FF                                ; fully-qualified     # 🤷🏿 person shrugging: dark skin tone
+1F937 200D 2642 FE0F                       ; fully-qualified     # 🤷‍♂️ man shrugging
+1F937 200D 2642                            ; minimally-qualified # 🤷‍♂ man shrugging
+1F937 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🤷🏻‍♂️ man shrugging: light skin tone
+1F937 1F3FB 200D 2642                      ; minimally-qualified # 🤷🏻‍♂ man shrugging: light skin tone
+1F937 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🤷🏼‍♂️ man shrugging: medium-light skin tone
+1F937 1F3FC 200D 2642                      ; minimally-qualified # 🤷🏼‍♂ man shrugging: medium-light skin tone
+1F937 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🤷🏽‍♂️ man shrugging: medium skin tone
+1F937 1F3FD 200D 2642                      ; minimally-qualified # 🤷🏽‍♂ man shrugging: medium skin tone
+1F937 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🤷🏾‍♂️ man shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2642                      ; minimally-qualified # 🤷🏾‍♂ man shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🤷🏿‍♂️ man shrugging: dark skin tone
+1F937 1F3FF 200D 2642                      ; minimally-qualified # 🤷🏿‍♂ man shrugging: dark skin tone
+1F937 200D 2640 FE0F                       ; fully-qualified     # 🤷‍♀️ woman shrugging
+1F937 200D 2640                            ; minimally-qualified # 🤷‍♀ woman shrugging
+1F937 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🤷🏻‍♀️ woman shrugging: light skin tone
+1F937 1F3FB 200D 2640                      ; minimally-qualified # 🤷🏻‍♀ woman shrugging: light skin tone
+1F937 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🤷🏼‍♀️ woman shrugging: medium-light skin tone
+1F937 1F3FC 200D 2640                      ; minimally-qualified # 🤷🏼‍♀ woman shrugging: medium-light skin tone
+1F937 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🤷🏽‍♀️ woman shrugging: medium skin tone
+1F937 1F3FD 200D 2640                      ; minimally-qualified # 🤷🏽‍♀ woman shrugging: medium skin tone
+1F937 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🤷🏾‍♀️ woman shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2640                      ; minimally-qualified # 🤷🏾‍♀ woman shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🤷🏿‍♀️ woman shrugging: dark skin tone
+1F937 1F3FF 200D 2640                      ; minimally-qualified # 🤷🏿‍♀ woman shrugging: dark skin tone
+
+# subgroup: person-role
+1F468 200D 2695 FE0F                       ; fully-qualified     # 👨‍⚕️ man health worker
+1F468 200D 2695                            ; minimally-qualified # 👨‍⚕ man health worker
+1F468 1F3FB 200D 2695 FE0F                 ; fully-qualified     # 👨🏻‍⚕️ man health worker: light skin tone
+1F468 1F3FB 200D 2695                      ; minimally-qualified # 👨🏻‍⚕ man health worker: light skin tone
+1F468 1F3FC 200D 2695 FE0F                 ; fully-qualified     # 👨🏼‍⚕️ man health worker: medium-light skin tone
+1F468 1F3FC 200D 2695                      ; minimally-qualified # 👨🏼‍⚕ man health worker: medium-light skin tone
+1F468 1F3FD 200D 2695 FE0F                 ; fully-qualified     # 👨🏽‍⚕️ man health worker: medium skin tone
+1F468 1F3FD 200D 2695                      ; minimally-qualified # 👨🏽‍⚕ man health worker: medium skin tone
+1F468 1F3FE 200D 2695 FE0F                 ; fully-qualified     # 👨🏾‍⚕️ man health worker: medium-dark skin tone
+1F468 1F3FE 200D 2695                      ; minimally-qualified # 👨🏾‍⚕ man health worker: medium-dark skin tone
+1F468 1F3FF 200D 2695 FE0F                 ; fully-qualified     # 👨🏿‍⚕️ man health worker: dark skin tone
+1F468 1F3FF 200D 2695                      ; minimally-qualified # 👨🏿‍⚕ man health worker: dark skin tone
+1F469 200D 2695 FE0F                       ; fully-qualified     # 👩‍⚕️ woman health worker
+1F469 200D 2695                            ; minimally-qualified # 👩‍⚕ woman health worker
+1F469 1F3FB 200D 2695 FE0F                 ; fully-qualified     # 👩🏻‍⚕️ woman health worker: light skin tone
+1F469 1F3FB 200D 2695                      ; minimally-qualified # 👩🏻‍⚕ woman health worker: light skin tone
+1F469 1F3FC 200D 2695 FE0F                 ; fully-qualified     # 👩🏼‍⚕️ woman health worker: medium-light skin tone
+1F469 1F3FC 200D 2695                      ; minimally-qualified # 👩🏼‍⚕ woman health worker: medium-light skin tone
+1F469 1F3FD 200D 2695 FE0F                 ; fully-qualified     # 👩🏽‍⚕️ woman health worker: medium skin tone
+1F469 1F3FD 200D 2695                      ; minimally-qualified # 👩🏽‍⚕ woman health worker: medium skin tone
+1F469 1F3FE 200D 2695 FE0F                 ; fully-qualified     # 👩🏾‍⚕️ woman health worker: medium-dark skin tone
+1F469 1F3FE 200D 2695                      ; minimally-qualified # 👩🏾‍⚕ woman health worker: medium-dark skin tone
+1F469 1F3FF 200D 2695 FE0F                 ; fully-qualified     # 👩🏿‍⚕️ woman health worker: dark skin tone
+1F469 1F3FF 200D 2695                      ; minimally-qualified # 👩🏿‍⚕ woman health worker: dark skin tone
+1F468 200D 1F393                           ; fully-qualified     # 👨‍🎓 man student
+1F468 1F3FB 200D 1F393                     ; fully-qualified     # 👨🏻‍🎓 man student: light skin tone
+1F468 1F3FC 200D 1F393                     ; fully-qualified     # 👨🏼‍🎓 man student: medium-light skin tone
+1F468 1F3FD 200D 1F393                     ; fully-qualified     # 👨🏽‍🎓 man student: medium skin tone
+1F468 1F3FE 200D 1F393                     ; fully-qualified     # 👨🏾‍🎓 man student: medium-dark skin tone
+1F468 1F3FF 200D 1F393                     ; fully-qualified     # 👨🏿‍🎓 man student: dark skin tone
+1F469 200D 1F393                           ; fully-qualified     # 👩‍🎓 woman student
+1F469 1F3FB 200D 1F393                     ; fully-qualified     # 👩🏻‍🎓 woman student: light skin tone
+1F469 1F3FC 200D 1F393                     ; fully-qualified     # 👩🏼‍🎓 woman student: medium-light skin tone
+1F469 1F3FD 200D 1F393                     ; fully-qualified     # 👩🏽‍🎓 woman student: medium skin tone
+1F469 1F3FE 200D 1F393                     ; fully-qualified     # 👩🏾‍🎓 woman student: medium-dark skin tone
+1F469 1F3FF 200D 1F393                     ; fully-qualified     # 👩🏿‍🎓 woman student: dark skin tone
+1F468 200D 1F3EB                           ; fully-qualified     # 👨‍🏫 man teacher
+1F468 1F3FB 200D 1F3EB                     ; fully-qualified     # 👨🏻‍🏫 man teacher: light skin tone
+1F468 1F3FC 200D 1F3EB                     ; fully-qualified     # 👨🏼‍🏫 man teacher: medium-light skin tone
+1F468 1F3FD 200D 1F3EB                     ; fully-qualified     # 👨🏽‍🏫 man teacher: medium skin tone
+1F468 1F3FE 200D 1F3EB                     ; fully-qualified     # 👨🏾‍🏫 man teacher: medium-dark skin tone
+1F468 1F3FF 200D 1F3EB                     ; fully-qualified     # 👨🏿‍🏫 man teacher: dark skin tone
+1F469 200D 1F3EB                           ; fully-qualified     # 👩‍🏫 woman teacher
+1F469 1F3FB 200D 1F3EB                     ; fully-qualified     # 👩🏻‍🏫 woman teacher: light skin tone
+1F469 1F3FC 200D 1F3EB                     ; fully-qualified     # 👩🏼‍🏫 woman teacher: medium-light skin tone
+1F469 1F3FD 200D 1F3EB                     ; fully-qualified     # 👩🏽‍🏫 woman teacher: medium skin tone
+1F469 1F3FE 200D 1F3EB                     ; fully-qualified     # 👩🏾‍🏫 woman teacher: medium-dark skin tone
+1F469 1F3FF 200D 1F3EB                     ; fully-qualified     # 👩🏿‍🏫 woman teacher: dark skin tone
+1F468 200D 2696 FE0F                       ; fully-qualified     # 👨‍⚖️ man judge
+1F468 200D 2696                            ; minimally-qualified # 👨‍⚖ man judge
+1F468 1F3FB 200D 2696 FE0F                 ; fully-qualified     # 👨🏻‍⚖️ man judge: light skin tone
+1F468 1F3FB 200D 2696                      ; minimally-qualified # 👨🏻‍⚖ man judge: light skin tone
+1F468 1F3FC 200D 2696 FE0F                 ; fully-qualified     # 👨🏼‍⚖️ man judge: medium-light skin tone
+1F468 1F3FC 200D 2696                      ; minimally-qualified # 👨🏼‍⚖ man judge: medium-light skin tone
+1F468 1F3FD 200D 2696 FE0F                 ; fully-qualified     # 👨🏽‍⚖️ man judge: medium skin tone
+1F468 1F3FD 200D 2696                      ; minimally-qualified # 👨🏽‍⚖ man judge: medium skin tone
+1F468 1F3FE 200D 2696 FE0F                 ; fully-qualified     # 👨🏾‍⚖️ man judge: medium-dark skin tone
+1F468 1F3FE 200D 2696                      ; minimally-qualified # 👨🏾‍⚖ man judge: medium-dark skin tone
+1F468 1F3FF 200D 2696 FE0F                 ; fully-qualified     # 👨🏿‍⚖️ man judge: dark skin tone
+1F468 1F3FF 200D 2696                      ; minimally-qualified # 👨🏿‍⚖ man judge: dark skin tone
+1F469 200D 2696 FE0F                       ; fully-qualified     # 👩‍⚖️ woman judge
+1F469 200D 2696                            ; minimally-qualified # 👩‍⚖ woman judge
+1F469 1F3FB 200D 2696 FE0F                 ; fully-qualified     # 👩🏻‍⚖️ woman judge: light skin tone
+1F469 1F3FB 200D 2696                      ; minimally-qualified # 👩🏻‍⚖ woman judge: light skin tone
+1F469 1F3FC 200D 2696 FE0F                 ; fully-qualified     # 👩🏼‍⚖️ woman judge: medium-light skin tone
+1F469 1F3FC 200D 2696                      ; minimally-qualified # 👩🏼‍⚖ woman judge: medium-light skin tone
+1F469 1F3FD 200D 2696 FE0F                 ; fully-qualified     # 👩🏽‍⚖️ woman judge: medium skin tone
+1F469 1F3FD 200D 2696                      ; minimally-qualified # 👩🏽‍⚖ woman judge: medium skin tone
+1F469 1F3FE 200D 2696 FE0F                 ; fully-qualified     # 👩🏾‍⚖️ woman judge: medium-dark skin tone
+1F469 1F3FE 200D 2696                      ; minimally-qualified # 👩🏾‍⚖ woman judge: medium-dark skin tone
+1F469 1F3FF 200D 2696 FE0F                 ; fully-qualified     # 👩🏿‍⚖️ woman judge: dark skin tone
+1F469 1F3FF 200D 2696                      ; minimally-qualified # 👩🏿‍⚖ woman judge: dark skin tone
+1F468 200D 1F33E                           ; fully-qualified     # 👨‍🌾 man farmer
+1F468 1F3FB 200D 1F33E                     ; fully-qualified     # 👨🏻‍🌾 man farmer: light skin tone
+1F468 1F3FC 200D 1F33E                     ; fully-qualified     # 👨🏼‍🌾 man farmer: medium-light skin tone
+1F468 1F3FD 200D 1F33E                     ; fully-qualified     # 👨🏽‍🌾 man farmer: medium skin tone
+1F468 1F3FE 200D 1F33E                     ; fully-qualified     # 👨🏾‍🌾 man farmer: medium-dark skin tone
+1F468 1F3FF 200D 1F33E                     ; fully-qualified     # 👨🏿‍🌾 man farmer: dark skin tone
+1F469 200D 1F33E                           ; fully-qualified     # 👩‍🌾 woman farmer
+1F469 1F3FB 200D 1F33E                     ; fully-qualified     # 👩🏻‍🌾 woman farmer: light skin tone
+1F469 1F3FC 200D 1F33E                     ; fully-qualified     # 👩🏼‍🌾 woman farmer: medium-light skin tone
+1F469 1F3FD 200D 1F33E                     ; fully-qualified     # 👩🏽‍🌾 woman farmer: medium skin tone
+1F469 1F3FE 200D 1F33E                     ; fully-qualified     # 👩🏾‍🌾 woman farmer: medium-dark skin tone
+1F469 1F3FF 200D 1F33E                     ; fully-qualified     # 👩🏿‍🌾 woman farmer: dark skin tone
+1F468 200D 1F373                           ; fully-qualified     # 👨‍🍳 man cook
+1F468 1F3FB 200D 1F373                     ; fully-qualified     # 👨🏻‍🍳 man cook: light skin tone
+1F468 1F3FC 200D 1F373                     ; fully-qualified     # 👨🏼‍🍳 man cook: medium-light skin tone
+1F468 1F3FD 200D 1F373                     ; fully-qualified     # 👨🏽‍🍳 man cook: medium skin tone
+1F468 1F3FE 200D 1F373                     ; fully-qualified     # 👨🏾‍🍳 man cook: medium-dark skin tone
+1F468 1F3FF 200D 1F373                     ; fully-qualified     # 👨🏿‍🍳 man cook: dark skin tone
+1F469 200D 1F373                           ; fully-qualified     # 👩‍🍳 woman cook
+1F469 1F3FB 200D 1F373                     ; fully-qualified     # 👩🏻‍🍳 woman cook: light skin tone
+1F469 1F3FC 200D 1F373                     ; fully-qualified     # 👩🏼‍🍳 woman cook: medium-light skin tone
+1F469 1F3FD 200D 1F373                     ; fully-qualified     # 👩🏽‍🍳 woman cook: medium skin tone
+1F469 1F3FE 200D 1F373                     ; fully-qualified     # 👩🏾‍🍳 woman cook: medium-dark skin tone
+1F469 1F3FF 200D 1F373                     ; fully-qualified     # 👩🏿‍🍳 woman cook: dark skin tone
+1F468 200D 1F527                           ; fully-qualified     # 👨‍🔧 man mechanic
+1F468 1F3FB 200D 1F527                     ; fully-qualified     # 👨🏻‍🔧 man mechanic: light skin tone
+1F468 1F3FC 200D 1F527                     ; fully-qualified     # 👨🏼‍🔧 man mechanic: medium-light skin tone
+1F468 1F3FD 200D 1F527                     ; fully-qualified     # 👨🏽‍🔧 man mechanic: medium skin tone
+1F468 1F3FE 200D 1F527                     ; fully-qualified     # 👨🏾‍🔧 man mechanic: medium-dark skin tone
+1F468 1F3FF 200D 1F527                     ; fully-qualified     # 👨🏿‍🔧 man mechanic: dark skin tone
+1F469 200D 1F527                           ; fully-qualified     # 👩‍🔧 woman mechanic
+1F469 1F3FB 200D 1F527                     ; fully-qualified     # 👩🏻‍🔧 woman mechanic: light skin tone
+1F469 1F3FC 200D 1F527                     ; fully-qualified     # 👩🏼‍🔧 woman mechanic: medium-light skin tone
+1F469 1F3FD 200D 1F527                     ; fully-qualified     # 👩🏽‍🔧 woman mechanic: medium skin tone
+1F469 1F3FE 200D 1F527                     ; fully-qualified     # 👩🏾‍🔧 woman mechanic: medium-dark skin tone
+1F469 1F3FF 200D 1F527                     ; fully-qualified     # 👩🏿‍🔧 woman mechanic: dark skin tone
+1F468 200D 1F3ED                           ; fully-qualified     # 👨‍🏭 man factory worker
+1F468 1F3FB 200D 1F3ED                     ; fully-qualified     # 👨🏻‍🏭 man factory worker: light skin tone
+1F468 1F3FC 200D 1F3ED                     ; fully-qualified     # 👨🏼‍🏭 man factory worker: medium-light skin tone
+1F468 1F3FD 200D 1F3ED                     ; fully-qualified     # 👨🏽‍🏭 man factory worker: medium skin tone
+1F468 1F3FE 200D 1F3ED                     ; fully-qualified     # 👨🏾‍🏭 man factory worker: medium-dark skin tone
+1F468 1F3FF 200D 1F3ED                     ; fully-qualified     # 👨🏿‍🏭 man factory worker: dark skin tone
+1F469 200D 1F3ED                           ; fully-qualified     # 👩‍🏭 woman factory worker
+1F469 1F3FB 200D 1F3ED                     ; fully-qualified     # 👩🏻‍🏭 woman factory worker: light skin tone
+1F469 1F3FC 200D 1F3ED                     ; fully-qualified     # 👩🏼‍🏭 woman factory worker: medium-light skin tone
+1F469 1F3FD 200D 1F3ED                     ; fully-qualified     # 👩🏽‍🏭 woman factory worker: medium skin tone
+1F469 1F3FE 200D 1F3ED                     ; fully-qualified     # 👩🏾‍🏭 woman factory worker: medium-dark skin tone
+1F469 1F3FF 200D 1F3ED                     ; fully-qualified     # 👩🏿‍🏭 woman factory worker: dark skin tone
+1F468 200D 1F4BC                           ; fully-qualified     # 👨‍💼 man office worker
+1F468 1F3FB 200D 1F4BC                     ; fully-qualified     # 👨🏻‍💼 man office worker: light skin tone
+1F468 1F3FC 200D 1F4BC                     ; fully-qualified     # 👨🏼‍💼 man office worker: medium-light skin tone
+1F468 1F3FD 200D 1F4BC                     ; fully-qualified     # 👨🏽‍💼 man office worker: medium skin tone
+1F468 1F3FE 200D 1F4BC                     ; fully-qualified     # 👨🏾‍💼 man office worker: medium-dark skin tone
+1F468 1F3FF 200D 1F4BC                     ; fully-qualified     # 👨🏿‍💼 man office worker: dark skin tone
+1F469 200D 1F4BC                           ; fully-qualified     # 👩‍💼 woman office worker
+1F469 1F3FB 200D 1F4BC                     ; fully-qualified     # 👩🏻‍💼 woman office worker: light skin tone
+1F469 1F3FC 200D 1F4BC                     ; fully-qualified     # 👩🏼‍💼 woman office worker: medium-light skin tone
+1F469 1F3FD 200D 1F4BC                     ; fully-qualified     # 👩🏽‍💼 woman office worker: medium skin tone
+1F469 1F3FE 200D 1F4BC                     ; fully-qualified     # 👩🏾‍💼 woman office worker: medium-dark skin tone
+1F469 1F3FF 200D 1F4BC                     ; fully-qualified     # 👩🏿‍💼 woman office worker: dark skin tone
+1F468 200D 1F52C                           ; fully-qualified     # 👨‍🔬 man scientist
+1F468 1F3FB 200D 1F52C                     ; fully-qualified     # 👨🏻‍🔬 man scientist: light skin tone
+1F468 1F3FC 200D 1F52C                     ; fully-qualified     # 👨🏼‍🔬 man scientist: medium-light skin tone
+1F468 1F3FD 200D 1F52C                     ; fully-qualified     # 👨🏽‍🔬 man scientist: medium skin tone
+1F468 1F3FE 200D 1F52C                     ; fully-qualified     # 👨🏾‍🔬 man scientist: medium-dark skin tone
+1F468 1F3FF 200D 1F52C                     ; fully-qualified     # 👨🏿‍🔬 man scientist: dark skin tone
+1F469 200D 1F52C                           ; fully-qualified     # 👩‍🔬 woman scientist
+1F469 1F3FB 200D 1F52C                     ; fully-qualified     # 👩🏻‍🔬 woman scientist: light skin tone
+1F469 1F3FC 200D 1F52C                     ; fully-qualified     # 👩🏼‍🔬 woman scientist: medium-light skin tone
+1F469 1F3FD 200D 1F52C                     ; fully-qualified     # 👩🏽‍🔬 woman scientist: medium skin tone
+1F469 1F3FE 200D 1F52C                     ; fully-qualified     # 👩🏾‍🔬 woman scientist: medium-dark skin tone
+1F469 1F3FF 200D 1F52C                     ; fully-qualified     # 👩🏿‍🔬 woman scientist: dark skin tone
+1F468 200D 1F4BB                           ; fully-qualified     # 👨‍💻 man technologist
+1F468 1F3FB 200D 1F4BB                     ; fully-qualified     # 👨🏻‍💻 man technologist: light skin tone
+1F468 1F3FC 200D 1F4BB                     ; fully-qualified     # 👨🏼‍💻 man technologist: medium-light skin tone
+1F468 1F3FD 200D 1F4BB                     ; fully-qualified     # 👨🏽‍💻 man technologist: medium skin tone
+1F468 1F3FE 200D 1F4BB                     ; fully-qualified     # 👨🏾‍💻 man technologist: medium-dark skin tone
+1F468 1F3FF 200D 1F4BB                     ; fully-qualified     # 👨🏿‍💻 man technologist: dark skin tone
+1F469 200D 1F4BB                           ; fully-qualified     # 👩‍💻 woman technologist
+1F469 1F3FB 200D 1F4BB                     ; fully-qualified     # 👩🏻‍💻 woman technologist: light skin tone
+1F469 1F3FC 200D 1F4BB                     ; fully-qualified     # 👩🏼‍💻 woman technologist: medium-light skin tone
+1F469 1F3FD 200D 1F4BB                     ; fully-qualified     # 👩🏽‍💻 woman technologist: medium skin tone
+1F469 1F3FE 200D 1F4BB                     ; fully-qualified     # 👩🏾‍💻 woman technologist: medium-dark skin tone
+1F469 1F3FF 200D 1F4BB                     ; fully-qualified     # 👩🏿‍💻 woman technologist: dark skin tone
+1F468 200D 1F3A4                           ; fully-qualified     # 👨‍🎤 man singer
+1F468 1F3FB 200D 1F3A4                     ; fully-qualified     # 👨🏻‍🎤 man singer: light skin tone
+1F468 1F3FC 200D 1F3A4                     ; fully-qualified     # 👨🏼‍🎤 man singer: medium-light skin tone
+1F468 1F3FD 200D 1F3A4                     ; fully-qualified     # 👨🏽‍🎤 man singer: medium skin tone
+1F468 1F3FE 200D 1F3A4                     ; fully-qualified     # 👨🏾‍🎤 man singer: medium-dark skin tone
+1F468 1F3FF 200D 1F3A4                     ; fully-qualified     # 👨🏿‍🎤 man singer: dark skin tone
+1F469 200D 1F3A4                           ; fully-qualified     # 👩‍🎤 woman singer
+1F469 1F3FB 200D 1F3A4                     ; fully-qualified     # 👩🏻‍🎤 woman singer: light skin tone
+1F469 1F3FC 200D 1F3A4                     ; fully-qualified     # 👩🏼‍🎤 woman singer: medium-light skin tone
+1F469 1F3FD 200D 1F3A4                     ; fully-qualified     # 👩🏽‍🎤 woman singer: medium skin tone
+1F469 1F3FE 200D 1F3A4                     ; fully-qualified     # 👩🏾‍🎤 woman singer: medium-dark skin tone
+1F469 1F3FF 200D 1F3A4                     ; fully-qualified     # 👩🏿‍🎤 woman singer: dark skin tone
+1F468 200D 1F3A8                           ; fully-qualified     # 👨‍🎨 man artist
+1F468 1F3FB 200D 1F3A8                     ; fully-qualified     # 👨🏻‍🎨 man artist: light skin tone
+1F468 1F3FC 200D 1F3A8                     ; fully-qualified     # 👨🏼‍🎨 man artist: medium-light skin tone
+1F468 1F3FD 200D 1F3A8                     ; fully-qualified     # 👨🏽‍🎨 man artist: medium skin tone
+1F468 1F3FE 200D 1F3A8                     ; fully-qualified     # 👨🏾‍🎨 man artist: medium-dark skin tone
+1F468 1F3FF 200D 1F3A8                     ; fully-qualified     # 👨🏿‍🎨 man artist: dark skin tone
+1F469 200D 1F3A8                           ; fully-qualified     # 👩‍🎨 woman artist
+1F469 1F3FB 200D 1F3A8                     ; fully-qualified     # 👩🏻‍🎨 woman artist: light skin tone
+1F469 1F3FC 200D 1F3A8                     ; fully-qualified     # 👩🏼‍🎨 woman artist: medium-light skin tone
+1F469 1F3FD 200D 1F3A8                     ; fully-qualified     # 👩🏽‍🎨 woman artist: medium skin tone
+1F469 1F3FE 200D 1F3A8                     ; fully-qualified     # 👩🏾‍🎨 woman artist: medium-dark skin tone
+1F469 1F3FF 200D 1F3A8                     ; fully-qualified     # 👩🏿‍🎨 woman artist: dark skin tone
+1F468 200D 2708 FE0F                       ; fully-qualified     # 👨‍✈️ man pilot
+1F468 200D 2708                            ; minimally-qualified # 👨‍✈ man pilot
+1F468 1F3FB 200D 2708 FE0F                 ; fully-qualified     # 👨🏻‍✈️ man pilot: light skin tone
+1F468 1F3FB 200D 2708                      ; minimally-qualified # 👨🏻‍✈ man pilot: light skin tone
+1F468 1F3FC 200D 2708 FE0F                 ; fully-qualified     # 👨🏼‍✈️ man pilot: medium-light skin tone
+1F468 1F3FC 200D 2708                      ; minimally-qualified # 👨🏼‍✈ man pilot: medium-light skin tone
+1F468 1F3FD 200D 2708 FE0F                 ; fully-qualified     # 👨🏽‍✈️ man pilot: medium skin tone
+1F468 1F3FD 200D 2708                      ; minimally-qualified # 👨🏽‍✈ man pilot: medium skin tone
+1F468 1F3FE 200D 2708 FE0F                 ; fully-qualified     # 👨🏾‍✈️ man pilot: medium-dark skin tone
+1F468 1F3FE 200D 2708                      ; minimally-qualified # 👨🏾‍✈ man pilot: medium-dark skin tone
+1F468 1F3FF 200D 2708 FE0F                 ; fully-qualified     # 👨🏿‍✈️ man pilot: dark skin tone
+1F468 1F3FF 200D 2708                      ; minimally-qualified # 👨🏿‍✈ man pilot: dark skin tone
+1F469 200D 2708 FE0F                       ; fully-qualified     # 👩‍✈️ woman pilot
+1F469 200D 2708                            ; minimally-qualified # 👩‍✈ woman pilot
+1F469 1F3FB 200D 2708 FE0F                 ; fully-qualified     # 👩🏻‍✈️ woman pilot: light skin tone
+1F469 1F3FB 200D 2708                      ; minimally-qualified # 👩🏻‍✈ woman pilot: light skin tone
+1F469 1F3FC 200D 2708 FE0F                 ; fully-qualified     # 👩🏼‍✈️ woman pilot: medium-light skin tone
+1F469 1F3FC 200D 2708                      ; minimally-qualified # 👩🏼‍✈ woman pilot: medium-light skin tone
+1F469 1F3FD 200D 2708 FE0F                 ; fully-qualified     # 👩🏽‍✈️ woman pilot: medium skin tone
+1F469 1F3FD 200D 2708                      ; minimally-qualified # 👩🏽‍✈ woman pilot: medium skin tone
+1F469 1F3FE 200D 2708 FE0F                 ; fully-qualified     # 👩🏾‍✈️ woman pilot: medium-dark skin tone
+1F469 1F3FE 200D 2708                      ; minimally-qualified # 👩🏾‍✈ woman pilot: medium-dark skin tone
+1F469 1F3FF 200D 2708 FE0F                 ; fully-qualified     # 👩🏿‍✈️ woman pilot: dark skin tone
+1F469 1F3FF 200D 2708                      ; minimally-qualified # 👩🏿‍✈ woman pilot: dark skin tone
+1F468 200D 1F680                           ; fully-qualified     # 👨‍🚀 man astronaut
+1F468 1F3FB 200D 1F680                     ; fully-qualified     # 👨🏻‍🚀 man astronaut: light skin tone
+1F468 1F3FC 200D 1F680                     ; fully-qualified     # 👨🏼‍🚀 man astronaut: medium-light skin tone
+1F468 1F3FD 200D 1F680                     ; fully-qualified     # 👨🏽‍🚀 man astronaut: medium skin tone
+1F468 1F3FE 200D 1F680                     ; fully-qualified     # 👨🏾‍🚀 man astronaut: medium-dark skin tone
+1F468 1F3FF 200D 1F680                     ; fully-qualified     # 👨🏿‍🚀 man astronaut: dark skin tone
+1F469 200D 1F680                           ; fully-qualified     # 👩‍🚀 woman astronaut
+1F469 1F3FB 200D 1F680                     ; fully-qualified     # 👩🏻‍🚀 woman astronaut: light skin tone
+1F469 1F3FC 200D 1F680                     ; fully-qualified     # 👩🏼‍🚀 woman astronaut: medium-light skin tone
+1F469 1F3FD 200D 1F680                     ; fully-qualified     # 👩🏽‍🚀 woman astronaut: medium skin tone
+1F469 1F3FE 200D 1F680                     ; fully-qualified     # 👩🏾‍🚀 woman astronaut: medium-dark skin tone
+1F469 1F3FF 200D 1F680                     ; fully-qualified     # 👩🏿‍🚀 woman astronaut: dark skin tone
+1F468 200D 1F692                           ; fully-qualified     # 👨‍🚒 man firefighter
+1F468 1F3FB 200D 1F692                     ; fully-qualified     # 👨🏻‍🚒 man firefighter: light skin tone
+1F468 1F3FC 200D 1F692                     ; fully-qualified     # 👨🏼‍🚒 man firefighter: medium-light skin tone
+1F468 1F3FD 200D 1F692                     ; fully-qualified     # 👨🏽‍🚒 man firefighter: medium skin tone
+1F468 1F3FE 200D 1F692                     ; fully-qualified     # 👨🏾‍🚒 man firefighter: medium-dark skin tone
+1F468 1F3FF 200D 1F692                     ; fully-qualified     # 👨🏿‍🚒 man firefighter: dark skin tone
+1F469 200D 1F692                           ; fully-qualified     # 👩‍🚒 woman firefighter
+1F469 1F3FB 200D 1F692                     ; fully-qualified     # 👩🏻‍🚒 woman firefighter: light skin tone
+1F469 1F3FC 200D 1F692                     ; fully-qualified     # 👩🏼‍🚒 woman firefighter: medium-light skin tone
+1F469 1F3FD 200D 1F692                     ; fully-qualified     # 👩🏽‍🚒 woman firefighter: medium skin tone
+1F469 1F3FE 200D 1F692                     ; fully-qualified     # 👩🏾‍🚒 woman firefighter: medium-dark skin tone
+1F469 1F3FF 200D 1F692                     ; fully-qualified     # 👩🏿‍🚒 woman firefighter: dark skin tone
+1F46E                                      ; fully-qualified     # 👮 police officer
+1F46E 1F3FB                                ; fully-qualified     # 👮🏻 police officer: light skin tone
+1F46E 1F3FC                                ; fully-qualified     # 👮🏼 police officer: medium-light skin tone
+1F46E 1F3FD                                ; fully-qualified     # 👮🏽 police officer: medium skin tone
+1F46E 1F3FE                                ; fully-qualified     # 👮🏾 police officer: medium-dark skin tone
+1F46E 1F3FF                                ; fully-qualified     # 👮🏿 police officer: dark skin tone
+1F46E 200D 2642 FE0F                       ; fully-qualified     # 👮‍♂️ man police officer
+1F46E 200D 2642                            ; minimally-qualified # 👮‍♂ man police officer
+1F46E 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 👮🏻‍♂️ man police officer: light skin tone
+1F46E 1F3FB 200D 2642                      ; minimally-qualified # 👮🏻‍♂ man police officer: light skin tone
+1F46E 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 👮🏼‍♂️ man police officer: medium-light skin tone
+1F46E 1F3FC 200D 2642                      ; minimally-qualified # 👮🏼‍♂ man police officer: medium-light skin tone
+1F46E 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 👮🏽‍♂️ man police officer: medium skin tone
+1F46E 1F3FD 200D 2642                      ; minimally-qualified # 👮🏽‍♂ man police officer: medium skin tone
+1F46E 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 👮🏾‍♂️ man police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2642                      ; minimally-qualified # 👮🏾‍♂ man police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 👮🏿‍♂️ man police officer: dark skin tone
+1F46E 1F3FF 200D 2642                      ; minimally-qualified # 👮🏿‍♂ man police officer: dark skin tone
+1F46E 200D 2640 FE0F                       ; fully-qualified     # 👮‍♀️ woman police officer
+1F46E 200D 2640                            ; minimally-qualified # 👮‍♀ woman police officer
+1F46E 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 👮🏻‍♀️ woman police officer: light skin tone
+1F46E 1F3FB 200D 2640                      ; minimally-qualified # 👮🏻‍♀ woman police officer: light skin tone
+1F46E 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 👮🏼‍♀️ woman police officer: medium-light skin tone
+1F46E 1F3FC 200D 2640                      ; minimally-qualified # 👮🏼‍♀ woman police officer: medium-light skin tone
+1F46E 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 👮🏽‍♀️ woman police officer: medium skin tone
+1F46E 1F3FD 200D 2640                      ; minimally-qualified # 👮🏽‍♀ woman police officer: medium skin tone
+1F46E 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 👮🏾‍♀️ woman police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2640                      ; minimally-qualified # 👮🏾‍♀ woman police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 👮🏿‍♀️ woman police officer: dark skin tone
+1F46E 1F3FF 200D 2640                      ; minimally-qualified # 👮🏿‍♀ woman police officer: dark skin tone
+1F575 FE0F                                 ; fully-qualified     # 🕵️ detective
+1F575                                      ; unqualified         # 🕵 detective
+1F575 1F3FB                                ; fully-qualified     # 🕵🏻 detective: light skin tone
+1F575 1F3FC                                ; fully-qualified     # 🕵🏼 detective: medium-light skin tone
+1F575 1F3FD                                ; fully-qualified     # 🕵🏽 detective: medium skin tone
+1F575 1F3FE                                ; fully-qualified     # 🕵🏾 detective: medium-dark skin tone
+1F575 1F3FF                                ; fully-qualified     # 🕵🏿 detective: dark skin tone
+1F575 FE0F 200D 2642 FE0F                  ; fully-qualified     # 🕵️‍♂️ man detective
+1F575 200D 2642 FE0F                       ; unqualified         # 🕵‍♂️ man detective
+1F575 FE0F 200D 2642                       ; unqualified         # 🕵️‍♂ man detective
+1F575 200D 2642                            ; unqualified         # 🕵‍♂ man detective
+1F575 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🕵🏻‍♂️ man detective: light skin tone
+1F575 1F3FB 200D 2642                      ; minimally-qualified # 🕵🏻‍♂ man detective: light skin tone
+1F575 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🕵🏼‍♂️ man detective: medium-light skin tone
+1F575 1F3FC 200D 2642                      ; minimally-qualified # 🕵🏼‍♂ man detective: medium-light skin tone
+1F575 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🕵🏽‍♂️ man detective: medium skin tone
+1F575 1F3FD 200D 2642                      ; minimally-qualified # 🕵🏽‍♂ man detective: medium skin tone
+1F575 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🕵🏾‍♂️ man detective: medium-dark skin tone
+1F575 1F3FE 200D 2642                      ; minimally-qualified # 🕵🏾‍♂ man detective: medium-dark skin tone
+1F575 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🕵🏿‍♂️ man detective: dark skin tone
+1F575 1F3FF 200D 2642                      ; minimally-qualified # 🕵🏿‍♂ man detective: dark skin tone
+1F575 FE0F 200D 2640 FE0F                  ; fully-qualified     # 🕵️‍♀️ woman detective
+1F575 200D 2640 FE0F                       ; unqualified         # 🕵‍♀️ woman detective
+1F575 FE0F 200D 2640                       ; unqualified         # 🕵️‍♀ woman detective
+1F575 200D 2640                            ; unqualified         # 🕵‍♀ woman detective
+1F575 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🕵🏻‍♀️ woman detective: light skin tone
+1F575 1F3FB 200D 2640                      ; minimally-qualified # 🕵🏻‍♀ woman detective: light skin tone
+1F575 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🕵🏼‍♀️ woman detective: medium-light skin tone
+1F575 1F3FC 200D 2640                      ; minimally-qualified # 🕵🏼‍♀ woman detective: medium-light skin tone
+1F575 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🕵🏽‍♀️ woman detective: medium skin tone
+1F575 1F3FD 200D 2640                      ; minimally-qualified # 🕵🏽‍♀ woman detective: medium skin tone
+1F575 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🕵🏾‍♀️ woman detective: medium-dark skin tone
+1F575 1F3FE 200D 2640                      ; minimally-qualified # 🕵🏾‍♀ woman detective: medium-dark skin tone
+1F575 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🕵🏿‍♀️ woman detective: dark skin tone
+1F575 1F3FF 200D 2640                      ; minimally-qualified # 🕵🏿‍♀ woman detective: dark skin tone
+1F482                                      ; fully-qualified     # 💂 guard
+1F482 1F3FB                                ; fully-qualified     # 💂🏻 guard: light skin tone
+1F482 1F3FC                                ; fully-qualified     # 💂🏼 guard: medium-light skin tone
+1F482 1F3FD                                ; fully-qualified     # 💂🏽 guard: medium skin tone
+1F482 1F3FE                                ; fully-qualified     # 💂🏾 guard: medium-dark skin tone
+1F482 1F3FF                                ; fully-qualified     # 💂🏿 guard: dark skin tone
+1F482 200D 2642 FE0F                       ; fully-qualified     # 💂‍♂️ man guard
+1F482 200D 2642                            ; minimally-qualified # 💂‍♂ man guard
+1F482 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 💂🏻‍♂️ man guard: light skin tone
+1F482 1F3FB 200D 2642                      ; minimally-qualified # 💂🏻‍♂ man guard: light skin tone
+1F482 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 💂🏼‍♂️ man guard: medium-light skin tone
+1F482 1F3FC 200D 2642                      ; minimally-qualified # 💂🏼‍♂ man guard: medium-light skin tone
+1F482 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 💂🏽‍♂️ man guard: medium skin tone
+1F482 1F3FD 200D 2642                      ; minimally-qualified # 💂🏽‍♂ man guard: medium skin tone
+1F482 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 💂🏾‍♂️ man guard: medium-dark skin tone
+1F482 1F3FE 200D 2642                      ; minimally-qualified # 💂🏾‍♂ man guard: medium-dark skin tone
+1F482 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 💂🏿‍♂️ man guard: dark skin tone
+1F482 1F3FF 200D 2642                      ; minimally-qualified # 💂🏿‍♂ man guard: dark skin tone
+1F482 200D 2640 FE0F                       ; fully-qualified     # 💂‍♀️ woman guard
+1F482 200D 2640                            ; minimally-qualified # 💂‍♀ woman guard
+1F482 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 💂🏻‍♀️ woman guard: light skin tone
+1F482 1F3FB 200D 2640                      ; minimally-qualified # 💂🏻‍♀ woman guard: light skin tone
+1F482 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 💂🏼‍♀️ woman guard: medium-light skin tone
+1F482 1F3FC 200D 2640                      ; minimally-qualified # 💂🏼‍♀ woman guard: medium-light skin tone
+1F482 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 💂🏽‍♀️ woman guard: medium skin tone
+1F482 1F3FD 200D 2640                      ; minimally-qualified # 💂🏽‍♀ woman guard: medium skin tone
+1F482 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 💂🏾‍♀️ woman guard: medium-dark skin tone
+1F482 1F3FE 200D 2640                      ; minimally-qualified # 💂🏾‍♀ woman guard: medium-dark skin tone
+1F482 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 💂🏿‍♀️ woman guard: dark skin tone
+1F482 1F3FF 200D 2640                      ; minimally-qualified # 💂🏿‍♀ woman guard: dark skin tone
+1F477                                      ; fully-qualified     # 👷 construction worker
+1F477 1F3FB                                ; fully-qualified     # 👷🏻 construction worker: light skin tone
+1F477 1F3FC                                ; fully-qualified     # 👷🏼 construction worker: medium-light skin tone
+1F477 1F3FD                                ; fully-qualified     # 👷🏽 construction worker: medium skin tone
+1F477 1F3FE                                ; fully-qualified     # 👷🏾 construction worker: medium-dark skin tone
+1F477 1F3FF                                ; fully-qualified     # 👷🏿 construction worker: dark skin tone
+1F477 200D 2642 FE0F                       ; fully-qualified     # 👷‍♂️ man construction worker
+1F477 200D 2642                            ; minimally-qualified # 👷‍♂ man construction worker
+1F477 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 👷🏻‍♂️ man construction worker: light skin tone
+1F477 1F3FB 200D 2642                      ; minimally-qualified # 👷🏻‍♂ man construction worker: light skin tone
+1F477 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 👷🏼‍♂️ man construction worker: medium-light skin tone
+1F477 1F3FC 200D 2642                      ; minimally-qualified # 👷🏼‍♂ man construction worker: medium-light skin tone
+1F477 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 👷🏽‍♂️ man construction worker: medium skin tone
+1F477 1F3FD 200D 2642                      ; minimally-qualified # 👷🏽‍♂ man construction worker: medium skin tone
+1F477 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 👷🏾‍♂️ man construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2642                      ; minimally-qualified # 👷🏾‍♂ man construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 👷🏿‍♂️ man construction worker: dark skin tone
+1F477 1F3FF 200D 2642                      ; minimally-qualified # 👷🏿‍♂ man construction worker: dark skin tone
+1F477 200D 2640 FE0F                       ; fully-qualified     # 👷‍♀️ woman construction worker
+1F477 200D 2640                            ; minimally-qualified # 👷‍♀ woman construction worker
+1F477 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 👷🏻‍♀️ woman construction worker: light skin tone
+1F477 1F3FB 200D 2640                      ; minimally-qualified # 👷🏻‍♀ woman construction worker: light skin tone
+1F477 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 👷🏼‍♀️ woman construction worker: medium-light skin tone
+1F477 1F3FC 200D 2640                      ; minimally-qualified # 👷🏼‍♀ woman construction worker: medium-light skin tone
+1F477 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 👷🏽‍♀️ woman construction worker: medium skin tone
+1F477 1F3FD 200D 2640                      ; minimally-qualified # 👷🏽‍♀ woman construction worker: medium skin tone
+1F477 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 👷🏾‍♀️ woman construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2640                      ; minimally-qualified # 👷🏾‍♀ woman construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 👷🏿‍♀️ woman construction worker: dark skin tone
+1F477 1F3FF 200D 2640                      ; minimally-qualified # 👷🏿‍♀ woman construction worker: dark skin tone
+1F934                                      ; fully-qualified     # 🤴 prince
+1F934 1F3FB                                ; fully-qualified     # 🤴🏻 prince: light skin tone
+1F934 1F3FC                                ; fully-qualified     # 🤴🏼 prince: medium-light skin tone
+1F934 1F3FD                                ; fully-qualified     # 🤴🏽 prince: medium skin tone
+1F934 1F3FE                                ; fully-qualified     # 🤴🏾 prince: medium-dark skin tone
+1F934 1F3FF                                ; fully-qualified     # 🤴🏿 prince: dark skin tone
+1F478                                      ; fully-qualified     # 👸 princess
+1F478 1F3FB                                ; fully-qualified     # 👸🏻 princess: light skin tone
+1F478 1F3FC                                ; fully-qualified     # 👸🏼 princess: medium-light skin tone
+1F478 1F3FD                                ; fully-qualified     # 👸🏽 princess: medium skin tone
+1F478 1F3FE                                ; fully-qualified     # 👸🏾 princess: medium-dark skin tone
+1F478 1F3FF                                ; fully-qualified     # 👸🏿 princess: dark skin tone
+1F473                                      ; fully-qualified     # 👳 person wearing turban
+1F473 1F3FB                                ; fully-qualified     # 👳🏻 person wearing turban: light skin tone
+1F473 1F3FC                                ; fully-qualified     # 👳🏼 person wearing turban: medium-light skin tone
+1F473 1F3FD                                ; fully-qualified     # 👳🏽 person wearing turban: medium skin tone
+1F473 1F3FE                                ; fully-qualified     # 👳🏾 person wearing turban: medium-dark skin tone
+1F473 1F3FF                                ; fully-qualified     # 👳🏿 person wearing turban: dark skin tone
+1F473 200D 2642 FE0F                       ; fully-qualified     # 👳‍♂️ man wearing turban
+1F473 200D 2642                            ; minimally-qualified # 👳‍♂ man wearing turban
+1F473 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 👳🏻‍♂️ man wearing turban: light skin tone
+1F473 1F3FB 200D 2642                      ; minimally-qualified # 👳🏻‍♂ man wearing turban: light skin tone
+1F473 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 👳🏼‍♂️ man wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2642                      ; minimally-qualified # 👳🏼‍♂ man wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 👳🏽‍♂️ man wearing turban: medium skin tone
+1F473 1F3FD 200D 2642                      ; minimally-qualified # 👳🏽‍♂ man wearing turban: medium skin tone
+1F473 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 👳🏾‍♂️ man wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2642                      ; minimally-qualified # 👳🏾‍♂ man wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 👳🏿‍♂️ man wearing turban: dark skin tone
+1F473 1F3FF 200D 2642                      ; minimally-qualified # 👳🏿‍♂ man wearing turban: dark skin tone
+1F473 200D 2640 FE0F                       ; fully-qualified     # 👳‍♀️ woman wearing turban
+1F473 200D 2640                            ; minimally-qualified # 👳‍♀ woman wearing turban
+1F473 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 👳🏻‍♀️ woman wearing turban: light skin tone
+1F473 1F3FB 200D 2640                      ; minimally-qualified # 👳🏻‍♀ woman wearing turban: light skin tone
+1F473 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 👳🏼‍♀️ woman wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2640                      ; minimally-qualified # 👳🏼‍♀ woman wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 👳🏽‍♀️ woman wearing turban: medium skin tone
+1F473 1F3FD 200D 2640                      ; minimally-qualified # 👳🏽‍♀ woman wearing turban: medium skin tone
+1F473 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 👳🏾‍♀️ woman wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2640                      ; minimally-qualified # 👳🏾‍♀ woman wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 👳🏿‍♀️ woman wearing turban: dark skin tone
+1F473 1F3FF 200D 2640                      ; minimally-qualified # 👳🏿‍♀ woman wearing turban: dark skin tone
+1F472                                      ; fully-qualified     # 👲 man with Chinese cap
+1F472 1F3FB                                ; fully-qualified     # 👲🏻 man with Chinese cap: light skin tone
+1F472 1F3FC                                ; fully-qualified     # 👲🏼 man with Chinese cap: medium-light skin tone
+1F472 1F3FD                                ; fully-qualified     # 👲🏽 man with Chinese cap: medium skin tone
+1F472 1F3FE                                ; fully-qualified     # 👲🏾 man with Chinese cap: medium-dark skin tone
+1F472 1F3FF                                ; fully-qualified     # 👲🏿 man with Chinese cap: dark skin tone
+1F9D5                                      ; fully-qualified     # 🧕 woman with headscarf
+1F9D5 1F3FB                                ; fully-qualified     # 🧕🏻 woman with headscarf: light skin tone
+1F9D5 1F3FC                                ; fully-qualified     # 🧕🏼 woman with headscarf: medium-light skin tone
+1F9D5 1F3FD                                ; fully-qualified     # 🧕🏽 woman with headscarf: medium skin tone
+1F9D5 1F3FE                                ; fully-qualified     # 🧕🏾 woman with headscarf: medium-dark skin tone
+1F9D5 1F3FF                                ; fully-qualified     # 🧕🏿 woman with headscarf: dark skin tone
+1F935                                      ; fully-qualified     # 🤵 man in tuxedo
+1F935 1F3FB                                ; fully-qualified     # 🤵🏻 man in tuxedo: light skin tone
+1F935 1F3FC                                ; fully-qualified     # 🤵🏼 man in tuxedo: medium-light skin tone
+1F935 1F3FD                                ; fully-qualified     # 🤵🏽 man in tuxedo: medium skin tone
+1F935 1F3FE                                ; fully-qualified     # 🤵🏾 man in tuxedo: medium-dark skin tone
+1F935 1F3FF                                ; fully-qualified     # 🤵🏿 man in tuxedo: dark skin tone
+1F470                                      ; fully-qualified     # 👰 bride with veil
+1F470 1F3FB                                ; fully-qualified     # 👰🏻 bride with veil: light skin tone
+1F470 1F3FC                                ; fully-qualified     # 👰🏼 bride with veil: medium-light skin tone
+1F470 1F3FD                                ; fully-qualified     # 👰🏽 bride with veil: medium skin tone
+1F470 1F3FE                                ; fully-qualified     # 👰🏾 bride with veil: medium-dark skin tone
+1F470 1F3FF                                ; fully-qualified     # 👰🏿 bride with veil: dark skin tone
+1F930                                      ; fully-qualified     # 🤰 pregnant woman
+1F930 1F3FB                                ; fully-qualified     # 🤰🏻 pregnant woman: light skin tone
+1F930 1F3FC                                ; fully-qualified     # 🤰🏼 pregnant woman: medium-light skin tone
+1F930 1F3FD                                ; fully-qualified     # 🤰🏽 pregnant woman: medium skin tone
+1F930 1F3FE                                ; fully-qualified     # 🤰🏾 pregnant woman: medium-dark skin tone
+1F930 1F3FF                                ; fully-qualified     # 🤰🏿 pregnant woman: dark skin tone
+1F931                                      ; fully-qualified     # 🤱 breast-feeding
+1F931 1F3FB                                ; fully-qualified     # 🤱🏻 breast-feeding: light skin tone
+1F931 1F3FC                                ; fully-qualified     # 🤱🏼 breast-feeding: medium-light skin tone
+1F931 1F3FD                                ; fully-qualified     # 🤱🏽 breast-feeding: medium skin tone
+1F931 1F3FE                                ; fully-qualified     # 🤱🏾 breast-feeding: medium-dark skin tone
+1F931 1F3FF                                ; fully-qualified     # 🤱🏿 breast-feeding: dark skin tone
+
+# subgroup: person-fantasy
+1F47C                                      ; fully-qualified     # 👼 baby angel
+1F47C 1F3FB                                ; fully-qualified     # 👼🏻 baby angel: light skin tone
+1F47C 1F3FC                                ; fully-qualified     # 👼🏼 baby angel: medium-light skin tone
+1F47C 1F3FD                                ; fully-qualified     # 👼🏽 baby angel: medium skin tone
+1F47C 1F3FE                                ; fully-qualified     # 👼🏾 baby angel: medium-dark skin tone
+1F47C 1F3FF                                ; fully-qualified     # 👼🏿 baby angel: dark skin tone
+1F385                                      ; fully-qualified     # 🎅 Santa Claus
+1F385 1F3FB                                ; fully-qualified     # 🎅🏻 Santa Claus: light skin tone
+1F385 1F3FC                                ; fully-qualified     # 🎅🏼 Santa Claus: medium-light skin tone
+1F385 1F3FD                                ; fully-qualified     # 🎅🏽 Santa Claus: medium skin tone
+1F385 1F3FE                                ; fully-qualified     # 🎅🏾 Santa Claus: medium-dark skin tone
+1F385 1F3FF                                ; fully-qualified     # 🎅🏿 Santa Claus: dark skin tone
+1F936                                      ; fully-qualified     # 🤶 Mrs. Claus
+1F936 1F3FB                                ; fully-qualified     # 🤶🏻 Mrs. Claus: light skin tone
+1F936 1F3FC                                ; fully-qualified     # 🤶🏼 Mrs. Claus: medium-light skin tone
+1F936 1F3FD                                ; fully-qualified     # 🤶🏽 Mrs. Claus: medium skin tone
+1F936 1F3FE                                ; fully-qualified     # 🤶🏾 Mrs. Claus: medium-dark skin tone
+1F936 1F3FF                                ; fully-qualified     # 🤶🏿 Mrs. Claus: dark skin tone
+1F9B8                                      ; fully-qualified     # 🦸 superhero
+1F9B8 1F3FB                                ; fully-qualified     # 🦸🏻 superhero: light skin tone
+1F9B8 1F3FC                                ; fully-qualified     # 🦸🏼 superhero: medium-light skin tone
+1F9B8 1F3FD                                ; fully-qualified     # 🦸🏽 superhero: medium skin tone
+1F9B8 1F3FE                                ; fully-qualified     # 🦸🏾 superhero: medium-dark skin tone
+1F9B8 1F3FF                                ; fully-qualified     # 🦸🏿 superhero: dark skin tone
+1F9B8 200D 2642 FE0F                       ; fully-qualified     # 🦸‍♂️ man superhero
+1F9B8 200D 2642                            ; minimally-qualified # 🦸‍♂ man superhero
+1F9B8 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🦸🏻‍♂️ man superhero: light skin tone
+1F9B8 1F3FB 200D 2642                      ; minimally-qualified # 🦸🏻‍♂ man superhero: light skin tone
+1F9B8 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🦸🏼‍♂️ man superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2642                      ; minimally-qualified # 🦸🏼‍♂ man superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🦸🏽‍♂️ man superhero: medium skin tone
+1F9B8 1F3FD 200D 2642                      ; minimally-qualified # 🦸🏽‍♂ man superhero: medium skin tone
+1F9B8 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🦸🏾‍♂️ man superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2642                      ; minimally-qualified # 🦸🏾‍♂ man superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🦸🏿‍♂️ man superhero: dark skin tone
+1F9B8 1F3FF 200D 2642                      ; minimally-qualified # 🦸🏿‍♂ man superhero: dark skin tone
+1F9B8 200D 2640 FE0F                       ; fully-qualified     # 🦸‍♀️ woman superhero
+1F9B8 200D 2640                            ; minimally-qualified # 🦸‍♀ woman superhero
+1F9B8 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🦸🏻‍♀️ woman superhero: light skin tone
+1F9B8 1F3FB 200D 2640                      ; minimally-qualified # 🦸🏻‍♀ woman superhero: light skin tone
+1F9B8 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🦸🏼‍♀️ woman superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2640                      ; minimally-qualified # 🦸🏼‍♀ woman superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🦸🏽‍♀️ woman superhero: medium skin tone
+1F9B8 1F3FD 200D 2640                      ; minimally-qualified # 🦸🏽‍♀ woman superhero: medium skin tone
+1F9B8 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🦸🏾‍♀️ woman superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2640                      ; minimally-qualified # 🦸🏾‍♀ woman superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🦸🏿‍♀️ woman superhero: dark skin tone
+1F9B8 1F3FF 200D 2640                      ; minimally-qualified # 🦸🏿‍♀ woman superhero: dark skin tone
+1F9B9                                      ; fully-qualified     # 🦹 supervillain
+1F9B9 1F3FB                                ; fully-qualified     # 🦹🏻 supervillain: light skin tone
+1F9B9 1F3FC                                ; fully-qualified     # 🦹🏼 supervillain: medium-light skin tone
+1F9B9 1F3FD                                ; fully-qualified     # 🦹🏽 supervillain: medium skin tone
+1F9B9 1F3FE                                ; fully-qualified     # 🦹🏾 supervillain: medium-dark skin tone
+1F9B9 1F3FF                                ; fully-qualified     # 🦹🏿 supervillain: dark skin tone
+1F9B9 200D 2642 FE0F                       ; fully-qualified     # 🦹‍♂️ man supervillain
+1F9B9 200D 2642                            ; minimally-qualified # 🦹‍♂ man supervillain
+1F9B9 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🦹🏻‍♂️ man supervillain: light skin tone
+1F9B9 1F3FB 200D 2642                      ; minimally-qualified # 🦹🏻‍♂ man supervillain: light skin tone
+1F9B9 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🦹🏼‍♂️ man supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2642                      ; minimally-qualified # 🦹🏼‍♂ man supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🦹🏽‍♂️ man supervillain: medium skin tone
+1F9B9 1F3FD 200D 2642                      ; minimally-qualified # 🦹🏽‍♂ man supervillain: medium skin tone
+1F9B9 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🦹🏾‍♂️ man supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2642                      ; minimally-qualified # 🦹🏾‍♂ man supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🦹🏿‍♂️ man supervillain: dark skin tone
+1F9B9 1F3FF 200D 2642                      ; minimally-qualified # 🦹🏿‍♂ man supervillain: dark skin tone
+1F9B9 200D 2640 FE0F                       ; fully-qualified     # 🦹‍♀️ woman supervillain
+1F9B9 200D 2640                            ; minimally-qualified # 🦹‍♀ woman supervillain
+1F9B9 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🦹🏻‍♀️ woman supervillain: light skin tone
+1F9B9 1F3FB 200D 2640                      ; minimally-qualified # 🦹🏻‍♀ woman supervillain: light skin tone
+1F9B9 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🦹🏼‍♀️ woman supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2640                      ; minimally-qualified # 🦹🏼‍♀ woman supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🦹🏽‍♀️ woman supervillain: medium skin tone
+1F9B9 1F3FD 200D 2640                      ; minimally-qualified # 🦹🏽‍♀ woman supervillain: medium skin tone
+1F9B9 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🦹🏾‍♀️ woman supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2640                      ; minimally-qualified # 🦹🏾‍♀ woman supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🦹🏿‍♀️ woman supervillain: dark skin tone
+1F9B9 1F3FF 200D 2640                      ; minimally-qualified # 🦹🏿‍♀ woman supervillain: dark skin tone
+1F9D9                                      ; fully-qualified     # 🧙 mage
+1F9D9 1F3FB                                ; fully-qualified     # 🧙🏻 mage: light skin tone
+1F9D9 1F3FC                                ; fully-qualified     # 🧙🏼 mage: medium-light skin tone
+1F9D9 1F3FD                                ; fully-qualified     # 🧙🏽 mage: medium skin tone
+1F9D9 1F3FE                                ; fully-qualified     # 🧙🏾 mage: medium-dark skin tone
+1F9D9 1F3FF                                ; fully-qualified     # 🧙🏿 mage: dark skin tone
+1F9D9 200D 2642 FE0F                       ; fully-qualified     # 🧙‍♂️ man mage
+1F9D9 200D 2642                            ; minimally-qualified # 🧙‍♂ man mage
+1F9D9 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧙🏻‍♂️ man mage: light skin tone
+1F9D9 1F3FB 200D 2642                      ; minimally-qualified # 🧙🏻‍♂ man mage: light skin tone
+1F9D9 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧙🏼‍♂️ man mage: medium-light skin tone
+1F9D9 1F3FC 200D 2642                      ; minimally-qualified # 🧙🏼‍♂ man mage: medium-light skin tone
+1F9D9 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧙🏽‍♂️ man mage: medium skin tone
+1F9D9 1F3FD 200D 2642                      ; minimally-qualified # 🧙🏽‍♂ man mage: medium skin tone
+1F9D9 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧙🏾‍♂️ man mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2642                      ; minimally-qualified # 🧙🏾‍♂ man mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧙🏿‍♂️ man mage: dark skin tone
+1F9D9 1F3FF 200D 2642                      ; minimally-qualified # 🧙🏿‍♂ man mage: dark skin tone
+1F9D9 200D 2640 FE0F                       ; fully-qualified     # 🧙‍♀️ woman mage
+1F9D9 200D 2640                            ; minimally-qualified # 🧙‍♀ woman mage
+1F9D9 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧙🏻‍♀️ woman mage: light skin tone
+1F9D9 1F3FB 200D 2640                      ; minimally-qualified # 🧙🏻‍♀ woman mage: light skin tone
+1F9D9 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧙🏼‍♀️ woman mage: medium-light skin tone
+1F9D9 1F3FC 200D 2640                      ; minimally-qualified # 🧙🏼‍♀ woman mage: medium-light skin tone
+1F9D9 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧙🏽‍♀️ woman mage: medium skin tone
+1F9D9 1F3FD 200D 2640                      ; minimally-qualified # 🧙🏽‍♀ woman mage: medium skin tone
+1F9D9 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧙🏾‍♀️ woman mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2640                      ; minimally-qualified # 🧙🏾‍♀ woman mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧙🏿‍♀️ woman mage: dark skin tone
+1F9D9 1F3FF 200D 2640                      ; minimally-qualified # 🧙🏿‍♀ woman mage: dark skin tone
+1F9DA                                      ; fully-qualified     # 🧚 fairy
+1F9DA 1F3FB                                ; fully-qualified     # 🧚🏻 fairy: light skin tone
+1F9DA 1F3FC                                ; fully-qualified     # 🧚🏼 fairy: medium-light skin tone
+1F9DA 1F3FD                                ; fully-qualified     # 🧚🏽 fairy: medium skin tone
+1F9DA 1F3FE                                ; fully-qualified     # 🧚🏾 fairy: medium-dark skin tone
+1F9DA 1F3FF                                ; fully-qualified     # 🧚🏿 fairy: dark skin tone
+1F9DA 200D 2642 FE0F                       ; fully-qualified     # 🧚‍♂️ man fairy
+1F9DA 200D 2642                            ; minimally-qualified # 🧚‍♂ man fairy
+1F9DA 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧚🏻‍♂️ man fairy: light skin tone
+1F9DA 1F3FB 200D 2642                      ; minimally-qualified # 🧚🏻‍♂ man fairy: light skin tone
+1F9DA 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧚🏼‍♂️ man fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2642                      ; minimally-qualified # 🧚🏼‍♂ man fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧚🏽‍♂️ man fairy: medium skin tone
+1F9DA 1F3FD 200D 2642                      ; minimally-qualified # 🧚🏽‍♂ man fairy: medium skin tone
+1F9DA 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧚🏾‍♂️ man fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2642                      ; minimally-qualified # 🧚🏾‍♂ man fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧚🏿‍♂️ man fairy: dark skin tone
+1F9DA 1F3FF 200D 2642                      ; minimally-qualified # 🧚🏿‍♂ man fairy: dark skin tone
+1F9DA 200D 2640 FE0F                       ; fully-qualified     # 🧚‍♀️ woman fairy
+1F9DA 200D 2640                            ; minimally-qualified # 🧚‍♀ woman fairy
+1F9DA 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧚🏻‍♀️ woman fairy: light skin tone
+1F9DA 1F3FB 200D 2640                      ; minimally-qualified # 🧚🏻‍♀ woman fairy: light skin tone
+1F9DA 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧚🏼‍♀️ woman fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2640                      ; minimally-qualified # 🧚🏼‍♀ woman fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧚🏽‍♀️ woman fairy: medium skin tone
+1F9DA 1F3FD 200D 2640                      ; minimally-qualified # 🧚🏽‍♀ woman fairy: medium skin tone
+1F9DA 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧚🏾‍♀️ woman fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2640                      ; minimally-qualified # 🧚🏾‍♀ woman fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧚🏿‍♀️ woman fairy: dark skin tone
+1F9DA 1F3FF 200D 2640                      ; minimally-qualified # 🧚🏿‍♀ woman fairy: dark skin tone
+1F9DB                                      ; fully-qualified     # 🧛 vampire
+1F9DB 1F3FB                                ; fully-qualified     # 🧛🏻 vampire: light skin tone
+1F9DB 1F3FC                                ; fully-qualified     # 🧛🏼 vampire: medium-light skin tone
+1F9DB 1F3FD                                ; fully-qualified     # 🧛🏽 vampire: medium skin tone
+1F9DB 1F3FE                                ; fully-qualified     # 🧛🏾 vampire: medium-dark skin tone
+1F9DB 1F3FF                                ; fully-qualified     # 🧛🏿 vampire: dark skin tone
+1F9DB 200D 2642 FE0F                       ; fully-qualified     # 🧛‍♂️ man vampire
+1F9DB 200D 2642                            ; minimally-qualified # 🧛‍♂ man vampire
+1F9DB 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧛🏻‍♂️ man vampire: light skin tone
+1F9DB 1F3FB 200D 2642                      ; minimally-qualified # 🧛🏻‍♂ man vampire: light skin tone
+1F9DB 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧛🏼‍♂️ man vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2642                      ; minimally-qualified # 🧛🏼‍♂ man vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧛🏽‍♂️ man vampire: medium skin tone
+1F9DB 1F3FD 200D 2642                      ; minimally-qualified # 🧛🏽‍♂ man vampire: medium skin tone
+1F9DB 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧛🏾‍♂️ man vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2642                      ; minimally-qualified # 🧛🏾‍♂ man vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧛🏿‍♂️ man vampire: dark skin tone
+1F9DB 1F3FF 200D 2642                      ; minimally-qualified # 🧛🏿‍♂ man vampire: dark skin tone
+1F9DB 200D 2640 FE0F                       ; fully-qualified     # 🧛‍♀️ woman vampire
+1F9DB 200D 2640                            ; minimally-qualified # 🧛‍♀ woman vampire
+1F9DB 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧛🏻‍♀️ woman vampire: light skin tone
+1F9DB 1F3FB 200D 2640                      ; minimally-qualified # 🧛🏻‍♀ woman vampire: light skin tone
+1F9DB 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧛🏼‍♀️ woman vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2640                      ; minimally-qualified # 🧛🏼‍♀ woman vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧛🏽‍♀️ woman vampire: medium skin tone
+1F9DB 1F3FD 200D 2640                      ; minimally-qualified # 🧛🏽‍♀ woman vampire: medium skin tone
+1F9DB 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧛🏾‍♀️ woman vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2640                      ; minimally-qualified # 🧛🏾‍♀ woman vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧛🏿‍♀️ woman vampire: dark skin tone
+1F9DB 1F3FF 200D 2640                      ; minimally-qualified # 🧛🏿‍♀ woman vampire: dark skin tone
+1F9DC                                      ; fully-qualified     # 🧜 merperson
+1F9DC 1F3FB                                ; fully-qualified     # 🧜🏻 merperson: light skin tone
+1F9DC 1F3FC                                ; fully-qualified     # 🧜🏼 merperson: medium-light skin tone
+1F9DC 1F3FD                                ; fully-qualified     # 🧜🏽 merperson: medium skin tone
+1F9DC 1F3FE                                ; fully-qualified     # 🧜🏾 merperson: medium-dark skin tone
+1F9DC 1F3FF                                ; fully-qualified     # 🧜🏿 merperson: dark skin tone
+1F9DC 200D 2642 FE0F                       ; fully-qualified     # 🧜‍♂️ merman
+1F9DC 200D 2642                            ; minimally-qualified # 🧜‍♂ merman
+1F9DC 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧜🏻‍♂️ merman: light skin tone
+1F9DC 1F3FB 200D 2642                      ; minimally-qualified # 🧜🏻‍♂ merman: light skin tone
+1F9DC 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧜🏼‍♂️ merman: medium-light skin tone
+1F9DC 1F3FC 200D 2642                      ; minimally-qualified # 🧜🏼‍♂ merman: medium-light skin tone
+1F9DC 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧜🏽‍♂️ merman: medium skin tone
+1F9DC 1F3FD 200D 2642                      ; minimally-qualified # 🧜🏽‍♂ merman: medium skin tone
+1F9DC 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧜🏾‍♂️ merman: medium-dark skin tone
+1F9DC 1F3FE 200D 2642                      ; minimally-qualified # 🧜🏾‍♂ merman: medium-dark skin tone
+1F9DC 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧜🏿‍♂️ merman: dark skin tone
+1F9DC 1F3FF 200D 2642                      ; minimally-qualified # 🧜🏿‍♂ merman: dark skin tone
+1F9DC 200D 2640 FE0F                       ; fully-qualified     # 🧜‍♀️ mermaid
+1F9DC 200D 2640                            ; minimally-qualified # 🧜‍♀ mermaid
+1F9DC 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧜🏻‍♀️ mermaid: light skin tone
+1F9DC 1F3FB 200D 2640                      ; minimally-qualified # 🧜🏻‍♀ mermaid: light skin tone
+1F9DC 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧜🏼‍♀️ mermaid: medium-light skin tone
+1F9DC 1F3FC 200D 2640                      ; minimally-qualified # 🧜🏼‍♀ mermaid: medium-light skin tone
+1F9DC 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧜🏽‍♀️ mermaid: medium skin tone
+1F9DC 1F3FD 200D 2640                      ; minimally-qualified # 🧜🏽‍♀ mermaid: medium skin tone
+1F9DC 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧜🏾‍♀️ mermaid: medium-dark skin tone
+1F9DC 1F3FE 200D 2640                      ; minimally-qualified # 🧜🏾‍♀ mermaid: medium-dark skin tone
+1F9DC 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧜🏿‍♀️ mermaid: dark skin tone
+1F9DC 1F3FF 200D 2640                      ; minimally-qualified # 🧜🏿‍♀ mermaid: dark skin tone
+1F9DD                                      ; fully-qualified     # 🧝 elf
+1F9DD 1F3FB                                ; fully-qualified     # 🧝🏻 elf: light skin tone
+1F9DD 1F3FC                                ; fully-qualified     # 🧝🏼 elf: medium-light skin tone
+1F9DD 1F3FD                                ; fully-qualified     # 🧝🏽 elf: medium skin tone
+1F9DD 1F3FE                                ; fully-qualified     # 🧝🏾 elf: medium-dark skin tone
+1F9DD 1F3FF                                ; fully-qualified     # 🧝🏿 elf: dark skin tone
+1F9DD 200D 2642 FE0F                       ; fully-qualified     # 🧝‍♂️ man elf
+1F9DD 200D 2642                            ; minimally-qualified # 🧝‍♂ man elf
+1F9DD 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧝🏻‍♂️ man elf: light skin tone
+1F9DD 1F3FB 200D 2642                      ; minimally-qualified # 🧝🏻‍♂ man elf: light skin tone
+1F9DD 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧝🏼‍♂️ man elf: medium-light skin tone
+1F9DD 1F3FC 200D 2642                      ; minimally-qualified # 🧝🏼‍♂ man elf: medium-light skin tone
+1F9DD 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧝🏽‍♂️ man elf: medium skin tone
+1F9DD 1F3FD 200D 2642                      ; minimally-qualified # 🧝🏽‍♂ man elf: medium skin tone
+1F9DD 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧝🏾‍♂️ man elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2642                      ; minimally-qualified # 🧝🏾‍♂ man elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧝🏿‍♂️ man elf: dark skin tone
+1F9DD 1F3FF 200D 2642                      ; minimally-qualified # 🧝🏿‍♂ man elf: dark skin tone
+1F9DD 200D 2640 FE0F                       ; fully-qualified     # 🧝‍♀️ woman elf
+1F9DD 200D 2640                            ; minimally-qualified # 🧝‍♀ woman elf
+1F9DD 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧝🏻‍♀️ woman elf: light skin tone
+1F9DD 1F3FB 200D 2640                      ; minimally-qualified # 🧝🏻‍♀ woman elf: light skin tone
+1F9DD 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧝🏼‍♀️ woman elf: medium-light skin tone
+1F9DD 1F3FC 200D 2640                      ; minimally-qualified # 🧝🏼‍♀ woman elf: medium-light skin tone
+1F9DD 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧝🏽‍♀️ woman elf: medium skin tone
+1F9DD 1F3FD 200D 2640                      ; minimally-qualified # 🧝🏽‍♀ woman elf: medium skin tone
+1F9DD 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧝🏾‍♀️ woman elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2640                      ; minimally-qualified # 🧝🏾‍♀ woman elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧝🏿‍♀️ woman elf: dark skin tone
+1F9DD 1F3FF 200D 2640                      ; minimally-qualified # 🧝🏿‍♀ woman elf: dark skin tone
+1F9DE                                      ; fully-qualified     # 🧞 genie
+1F9DE 200D 2642 FE0F                       ; fully-qualified     # 🧞‍♂️ man genie
+1F9DE 200D 2642                            ; minimally-qualified # 🧞‍♂ man genie
+1F9DE 200D 2640 FE0F                       ; fully-qualified     # 🧞‍♀️ woman genie
+1F9DE 200D 2640                            ; minimally-qualified # 🧞‍♀ woman genie
+1F9DF                                      ; fully-qualified     # 🧟 zombie
+1F9DF 200D 2642 FE0F                       ; fully-qualified     # 🧟‍♂️ man zombie
+1F9DF 200D 2642                            ; minimally-qualified # 🧟‍♂ man zombie
+1F9DF 200D 2640 FE0F                       ; fully-qualified     # 🧟‍♀️ woman zombie
+1F9DF 200D 2640                            ; minimally-qualified # 🧟‍♀ woman zombie
+
+# subgroup: person-activity
+1F486                                      ; fully-qualified     # 💆 person getting massage
+1F486 1F3FB                                ; fully-qualified     # 💆🏻 person getting massage: light skin tone
+1F486 1F3FC                                ; fully-qualified     # 💆🏼 person getting massage: medium-light skin tone
+1F486 1F3FD                                ; fully-qualified     # 💆🏽 person getting massage: medium skin tone
+1F486 1F3FE                                ; fully-qualified     # 💆🏾 person getting massage: medium-dark skin tone
+1F486 1F3FF                                ; fully-qualified     # 💆🏿 person getting massage: dark skin tone
+1F486 200D 2642 FE0F                       ; fully-qualified     # 💆‍♂️ man getting massage
+1F486 200D 2642                            ; minimally-qualified # 💆‍♂ man getting massage
+1F486 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 💆🏻‍♂️ man getting massage: light skin tone
+1F486 1F3FB 200D 2642                      ; minimally-qualified # 💆🏻‍♂ man getting massage: light skin tone
+1F486 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 💆🏼‍♂️ man getting massage: medium-light skin tone
+1F486 1F3FC 200D 2642                      ; minimally-qualified # 💆🏼‍♂ man getting massage: medium-light skin tone
+1F486 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 💆🏽‍♂️ man getting massage: medium skin tone
+1F486 1F3FD 200D 2642                      ; minimally-qualified # 💆🏽‍♂ man getting massage: medium skin tone
+1F486 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 💆🏾‍♂️ man getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2642                      ; minimally-qualified # 💆🏾‍♂ man getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 💆🏿‍♂️ man getting massage: dark skin tone
+1F486 1F3FF 200D 2642                      ; minimally-qualified # 💆🏿‍♂ man getting massage: dark skin tone
+1F486 200D 2640 FE0F                       ; fully-qualified     # 💆‍♀️ woman getting massage
+1F486 200D 2640                            ; minimally-qualified # 💆‍♀ woman getting massage
+1F486 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 💆🏻‍♀️ woman getting massage: light skin tone
+1F486 1F3FB 200D 2640                      ; minimally-qualified # 💆🏻‍♀ woman getting massage: light skin tone
+1F486 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 💆🏼‍♀️ woman getting massage: medium-light skin tone
+1F486 1F3FC 200D 2640                      ; minimally-qualified # 💆🏼‍♀ woman getting massage: medium-light skin tone
+1F486 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 💆🏽‍♀️ woman getting massage: medium skin tone
+1F486 1F3FD 200D 2640                      ; minimally-qualified # 💆🏽‍♀ woman getting massage: medium skin tone
+1F486 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 💆🏾‍♀️ woman getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2640                      ; minimally-qualified # 💆🏾‍♀ woman getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 💆🏿‍♀️ woman getting massage: dark skin tone
+1F486 1F3FF 200D 2640                      ; minimally-qualified # 💆🏿‍♀ woman getting massage: dark skin tone
+1F487                                      ; fully-qualified     # 💇 person getting haircut
+1F487 1F3FB                                ; fully-qualified     # 💇🏻 person getting haircut: light skin tone
+1F487 1F3FC                                ; fully-qualified     # 💇🏼 person getting haircut: medium-light skin tone
+1F487 1F3FD                                ; fully-qualified     # 💇🏽 person getting haircut: medium skin tone
+1F487 1F3FE                                ; fully-qualified     # 💇🏾 person getting haircut: medium-dark skin tone
+1F487 1F3FF                                ; fully-qualified     # 💇🏿 person getting haircut: dark skin tone
+1F487 200D 2642 FE0F                       ; fully-qualified     # 💇‍♂️ man getting haircut
+1F487 200D 2642                            ; minimally-qualified # 💇‍♂ man getting haircut
+1F487 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 💇🏻‍♂️ man getting haircut: light skin tone
+1F487 1F3FB 200D 2642                      ; minimally-qualified # 💇🏻‍♂ man getting haircut: light skin tone
+1F487 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 💇🏼‍♂️ man getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2642                      ; minimally-qualified # 💇🏼‍♂ man getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 💇🏽‍♂️ man getting haircut: medium skin tone
+1F487 1F3FD 200D 2642                      ; minimally-qualified # 💇🏽‍♂ man getting haircut: medium skin tone
+1F487 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 💇🏾‍♂️ man getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2642                      ; minimally-qualified # 💇🏾‍♂ man getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 💇🏿‍♂️ man getting haircut: dark skin tone
+1F487 1F3FF 200D 2642                      ; minimally-qualified # 💇🏿‍♂ man getting haircut: dark skin tone
+1F487 200D 2640 FE0F                       ; fully-qualified     # 💇‍♀️ woman getting haircut
+1F487 200D 2640                            ; minimally-qualified # 💇‍♀ woman getting haircut
+1F487 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 💇🏻‍♀️ woman getting haircut: light skin tone
+1F487 1F3FB 200D 2640                      ; minimally-qualified # 💇🏻‍♀ woman getting haircut: light skin tone
+1F487 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 💇🏼‍♀️ woman getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2640                      ; minimally-qualified # 💇🏼‍♀ woman getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 💇🏽‍♀️ woman getting haircut: medium skin tone
+1F487 1F3FD 200D 2640                      ; minimally-qualified # 💇🏽‍♀ woman getting haircut: medium skin tone
+1F487 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 💇🏾‍♀️ woman getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2640                      ; minimally-qualified # 💇🏾‍♀ woman getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 💇🏿‍♀️ woman getting haircut: dark skin tone
+1F487 1F3FF 200D 2640                      ; minimally-qualified # 💇🏿‍♀ woman getting haircut: dark skin tone
+1F6B6                                      ; fully-qualified     # 🚶 person walking
+1F6B6 1F3FB                                ; fully-qualified     # 🚶🏻 person walking: light skin tone
+1F6B6 1F3FC                                ; fully-qualified     # 🚶🏼 person walking: medium-light skin tone
+1F6B6 1F3FD                                ; fully-qualified     # 🚶🏽 person walking: medium skin tone
+1F6B6 1F3FE                                ; fully-qualified     # 🚶🏾 person walking: medium-dark skin tone
+1F6B6 1F3FF                                ; fully-qualified     # 🚶🏿 person walking: dark skin tone
+1F6B6 200D 2642 FE0F                       ; fully-qualified     # 🚶‍♂️ man walking
+1F6B6 200D 2642                            ; minimally-qualified # 🚶‍♂ man walking
+1F6B6 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🚶🏻‍♂️ man walking: light skin tone
+1F6B6 1F3FB 200D 2642                      ; minimally-qualified # 🚶🏻‍♂ man walking: light skin tone
+1F6B6 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🚶🏼‍♂️ man walking: medium-light skin tone
+1F6B6 1F3FC 200D 2642                      ; minimally-qualified # 🚶🏼‍♂ man walking: medium-light skin tone
+1F6B6 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🚶🏽‍♂️ man walking: medium skin tone
+1F6B6 1F3FD 200D 2642                      ; minimally-qualified # 🚶🏽‍♂ man walking: medium skin tone
+1F6B6 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🚶🏾‍♂️ man walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2642                      ; minimally-qualified # 🚶🏾‍♂ man walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🚶🏿‍♂️ man walking: dark skin tone
+1F6B6 1F3FF 200D 2642                      ; minimally-qualified # 🚶🏿‍♂ man walking: dark skin tone
+1F6B6 200D 2640 FE0F                       ; fully-qualified     # 🚶‍♀️ woman walking
+1F6B6 200D 2640                            ; minimally-qualified # 🚶‍♀ woman walking
+1F6B6 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🚶🏻‍♀️ woman walking: light skin tone
+1F6B6 1F3FB 200D 2640                      ; minimally-qualified # 🚶🏻‍♀ woman walking: light skin tone
+1F6B6 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🚶🏼‍♀️ woman walking: medium-light skin tone
+1F6B6 1F3FC 200D 2640                      ; minimally-qualified # 🚶🏼‍♀ woman walking: medium-light skin tone
+1F6B6 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🚶🏽‍♀️ woman walking: medium skin tone
+1F6B6 1F3FD 200D 2640                      ; minimally-qualified # 🚶🏽‍♀ woman walking: medium skin tone
+1F6B6 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🚶🏾‍♀️ woman walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2640                      ; minimally-qualified # 🚶🏾‍♀ woman walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🚶🏿‍♀️ woman walking: dark skin tone
+1F6B6 1F3FF 200D 2640                      ; minimally-qualified # 🚶🏿‍♀ woman walking: dark skin tone
+1F9CD                                      ; fully-qualified     # 🧍 person standing
+1F9CD 1F3FB                                ; fully-qualified     # 🧍🏻 person standing: light skin tone
+1F9CD 1F3FC                                ; fully-qualified     # 🧍🏼 person standing: medium-light skin tone
+1F9CD 1F3FD                                ; fully-qualified     # 🧍🏽 person standing: medium skin tone
+1F9CD 1F3FE                                ; fully-qualified     # 🧍🏾 person standing: medium-dark skin tone
+1F9CD 1F3FF                                ; fully-qualified     # 🧍🏿 person standing: dark skin tone
+1F9CD 200D 2642 FE0F                       ; fully-qualified     # 🧍‍♂️ man standing
+1F9CD 200D 2642                            ; minimally-qualified # 🧍‍♂ man standing
+1F9CD 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧍🏻‍♂️ man standing: light skin tone
+1F9CD 1F3FB 200D 2642                      ; minimally-qualified # 🧍🏻‍♂ man standing: light skin tone
+1F9CD 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧍🏼‍♂️ man standing: medium-light skin tone
+1F9CD 1F3FC 200D 2642                      ; minimally-qualified # 🧍🏼‍♂ man standing: medium-light skin tone
+1F9CD 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧍🏽‍♂️ man standing: medium skin tone
+1F9CD 1F3FD 200D 2642                      ; minimally-qualified # 🧍🏽‍♂ man standing: medium skin tone
+1F9CD 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧍🏾‍♂️ man standing: medium-dark skin tone
+1F9CD 1F3FE 200D 2642                      ; minimally-qualified # 🧍🏾‍♂ man standing: medium-dark skin tone
+1F9CD 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧍🏿‍♂️ man standing: dark skin tone
+1F9CD 1F3FF 200D 2642                      ; minimally-qualified # 🧍🏿‍♂ man standing: dark skin tone
+1F9CD 200D 2640 FE0F                       ; fully-qualified     # 🧍‍♀️ woman standing
+1F9CD 200D 2640                            ; minimally-qualified # 🧍‍♀ woman standing
+1F9CD 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧍🏻‍♀️ woman standing: light skin tone
+1F9CD 1F3FB 200D 2640                      ; minimally-qualified # 🧍🏻‍♀ woman standing: light skin tone
+1F9CD 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧍🏼‍♀️ woman standing: medium-light skin tone
+1F9CD 1F3FC 200D 2640                      ; minimally-qualified # 🧍🏼‍♀ woman standing: medium-light skin tone
+1F9CD 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧍🏽‍♀️ woman standing: medium skin tone
+1F9CD 1F3FD 200D 2640                      ; minimally-qualified # 🧍🏽‍♀ woman standing: medium skin tone
+1F9CD 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧍🏾‍♀️ woman standing: medium-dark skin tone
+1F9CD 1F3FE 200D 2640                      ; minimally-qualified # 🧍🏾‍♀ woman standing: medium-dark skin tone
+1F9CD 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧍🏿‍♀️ woman standing: dark skin tone
+1F9CD 1F3FF 200D 2640                      ; minimally-qualified # 🧍🏿‍♀ woman standing: dark skin tone
+1F9CE                                      ; fully-qualified     # 🧎 person kneeling
+1F9CE 1F3FB                                ; fully-qualified     # 🧎🏻 person kneeling: light skin tone
+1F9CE 1F3FC                                ; fully-qualified     # 🧎🏼 person kneeling: medium-light skin tone
+1F9CE 1F3FD                                ; fully-qualified     # 🧎🏽 person kneeling: medium skin tone
+1F9CE 1F3FE                                ; fully-qualified     # 🧎🏾 person kneeling: medium-dark skin tone
+1F9CE 1F3FF                                ; fully-qualified     # 🧎🏿 person kneeling: dark skin tone
+1F9CE 200D 2642 FE0F                       ; fully-qualified     # 🧎‍♂️ man kneeling
+1F9CE 200D 2642                            ; minimally-qualified # 🧎‍♂ man kneeling
+1F9CE 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧎🏻‍♂️ man kneeling: light skin tone
+1F9CE 1F3FB 200D 2642                      ; minimally-qualified # 🧎🏻‍♂ man kneeling: light skin tone
+1F9CE 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧎🏼‍♂️ man kneeling: medium-light skin tone
+1F9CE 1F3FC 200D 2642                      ; minimally-qualified # 🧎🏼‍♂ man kneeling: medium-light skin tone
+1F9CE 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧎🏽‍♂️ man kneeling: medium skin tone
+1F9CE 1F3FD 200D 2642                      ; minimally-qualified # 🧎🏽‍♂ man kneeling: medium skin tone
+1F9CE 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧎🏾‍♂️ man kneeling: medium-dark skin tone
+1F9CE 1F3FE 200D 2642                      ; minimally-qualified # 🧎🏾‍♂ man kneeling: medium-dark skin tone
+1F9CE 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧎🏿‍♂️ man kneeling: dark skin tone
+1F9CE 1F3FF 200D 2642                      ; minimally-qualified # 🧎🏿‍♂ man kneeling: dark skin tone
+1F9CE 200D 2640 FE0F                       ; fully-qualified     # 🧎‍♀️ woman kneeling
+1F9CE 200D 2640                            ; minimally-qualified # 🧎‍♀ woman kneeling
+1F9CE 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧎🏻‍♀️ woman kneeling: light skin tone
+1F9CE 1F3FB 200D 2640                      ; minimally-qualified # 🧎🏻‍♀ woman kneeling: light skin tone
+1F9CE 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧎🏼‍♀️ woman kneeling: medium-light skin tone
+1F9CE 1F3FC 200D 2640                      ; minimally-qualified # 🧎🏼‍♀ woman kneeling: medium-light skin tone
+1F9CE 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧎🏽‍♀️ woman kneeling: medium skin tone
+1F9CE 1F3FD 200D 2640                      ; minimally-qualified # 🧎🏽‍♀ woman kneeling: medium skin tone
+1F9CE 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧎🏾‍♀️ woman kneeling: medium-dark skin tone
+1F9CE 1F3FE 200D 2640                      ; minimally-qualified # 🧎🏾‍♀ woman kneeling: medium-dark skin tone
+1F9CE 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧎🏿‍♀️ woman kneeling: dark skin tone
+1F9CE 1F3FF 200D 2640                      ; minimally-qualified # 🧎🏿‍♀ woman kneeling: dark skin tone
+1F468 200D 1F9AF                           ; fully-qualified     # 👨‍🦯 man with probing cane
+1F468 1F3FB 200D 1F9AF                     ; fully-qualified     # 👨🏻‍🦯 man with probing cane: light skin tone
+1F468 1F3FC 200D 1F9AF                     ; fully-qualified     # 👨🏼‍🦯 man with probing cane: medium-light skin tone
+1F468 1F3FD 200D 1F9AF                     ; fully-qualified     # 👨🏽‍🦯 man with probing cane: medium skin tone
+1F468 1F3FE 200D 1F9AF                     ; fully-qualified     # 👨🏾‍🦯 man with probing cane: medium-dark skin tone
+1F468 1F3FF 200D 1F9AF                     ; fully-qualified     # 👨🏿‍🦯 man with probing cane: dark skin tone
+1F469 200D 1F9AF                           ; fully-qualified     # 👩‍🦯 woman with probing cane
+1F469 1F3FB 200D 1F9AF                     ; fully-qualified     # 👩🏻‍🦯 woman with probing cane: light skin tone
+1F469 1F3FC 200D 1F9AF                     ; fully-qualified     # 👩🏼‍🦯 woman with probing cane: medium-light skin tone
+1F469 1F3FD 200D 1F9AF                     ; fully-qualified     # 👩🏽‍🦯 woman with probing cane: medium skin tone
+1F469 1F3FE 200D 1F9AF                     ; fully-qualified     # 👩🏾‍🦯 woman with probing cane: medium-dark skin tone
+1F469 1F3FF 200D 1F9AF                     ; fully-qualified     # 👩🏿‍🦯 woman with probing cane: dark skin tone
+1F468 200D 1F9BC                           ; fully-qualified     # 👨‍🦼 man in motorized wheelchair
+1F468 1F3FB 200D 1F9BC                     ; fully-qualified     # 👨🏻‍🦼 man in motorized wheelchair: light skin tone
+1F468 1F3FC 200D 1F9BC                     ; fully-qualified     # 👨🏼‍🦼 man in motorized wheelchair: medium-light skin tone
+1F468 1F3FD 200D 1F9BC                     ; fully-qualified     # 👨🏽‍🦼 man in motorized wheelchair: medium skin tone
+1F468 1F3FE 200D 1F9BC                     ; fully-qualified     # 👨🏾‍🦼 man in motorized wheelchair: medium-dark skin tone
+1F468 1F3FF 200D 1F9BC                     ; fully-qualified     # 👨🏿‍🦼 man in motorized wheelchair: dark skin tone
+1F469 200D 1F9BC                           ; fully-qualified     # 👩‍🦼 woman in motorized wheelchair
+1F469 1F3FB 200D 1F9BC                     ; fully-qualified     # 👩🏻‍🦼 woman in motorized wheelchair: light skin tone
+1F469 1F3FC 200D 1F9BC                     ; fully-qualified     # 👩🏼‍🦼 woman in motorized wheelchair: medium-light skin tone
+1F469 1F3FD 200D 1F9BC                     ; fully-qualified     # 👩🏽‍🦼 woman in motorized wheelchair: medium skin tone
+1F469 1F3FE 200D 1F9BC                     ; fully-qualified     # 👩🏾‍🦼 woman in motorized wheelchair: medium-dark skin tone
+1F469 1F3FF 200D 1F9BC                     ; fully-qualified     # 👩🏿‍🦼 woman in motorized wheelchair: dark skin tone
+1F468 200D 1F9BD                           ; fully-qualified     # 👨‍🦽 man in manual wheelchair
+1F468 1F3FB 200D 1F9BD                     ; fully-qualified     # 👨🏻‍🦽 man in manual wheelchair: light skin tone
+1F468 1F3FC 200D 1F9BD                     ; fully-qualified     # 👨🏼‍🦽 man in manual wheelchair: medium-light skin tone
+1F468 1F3FD 200D 1F9BD                     ; fully-qualified     # 👨🏽‍🦽 man in manual wheelchair: medium skin tone
+1F468 1F3FE 200D 1F9BD                     ; fully-qualified     # 👨🏾‍🦽 man in manual wheelchair: medium-dark skin tone
+1F468 1F3FF 200D 1F9BD                     ; fully-qualified     # 👨🏿‍🦽 man in manual wheelchair: dark skin tone
+1F469 200D 1F9BD                           ; fully-qualified     # 👩‍🦽 woman in manual wheelchair
+1F469 1F3FB 200D 1F9BD                     ; fully-qualified     # 👩🏻‍🦽 woman in manual wheelchair: light skin tone
+1F469 1F3FC 200D 1F9BD                     ; fully-qualified     # 👩🏼‍🦽 woman in manual wheelchair: medium-light skin tone
+1F469 1F3FD 200D 1F9BD                     ; fully-qualified     # 👩🏽‍🦽 woman in manual wheelchair: medium skin tone
+1F469 1F3FE 200D 1F9BD                     ; fully-qualified     # 👩🏾‍🦽 woman in manual wheelchair: medium-dark skin tone
+1F469 1F3FF 200D 1F9BD                     ; fully-qualified     # 👩🏿‍🦽 woman in manual wheelchair: dark skin tone
+1F3C3                                      ; fully-qualified     # 🏃 person running
+1F3C3 1F3FB                                ; fully-qualified     # 🏃🏻 person running: light skin tone
+1F3C3 1F3FC                                ; fully-qualified     # 🏃🏼 person running: medium-light skin tone
+1F3C3 1F3FD                                ; fully-qualified     # 🏃🏽 person running: medium skin tone
+1F3C3 1F3FE                                ; fully-qualified     # 🏃🏾 person running: medium-dark skin tone
+1F3C3 1F3FF                                ; fully-qualified     # 🏃🏿 person running: dark skin tone
+1F3C3 200D 2642 FE0F                       ; fully-qualified     # 🏃‍♂️ man running
+1F3C3 200D 2642                            ; minimally-qualified # 🏃‍♂ man running
+1F3C3 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🏃🏻‍♂️ man running: light skin tone
+1F3C3 1F3FB 200D 2642                      ; minimally-qualified # 🏃🏻‍♂ man running: light skin tone
+1F3C3 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🏃🏼‍♂️ man running: medium-light skin tone
+1F3C3 1F3FC 200D 2642                      ; minimally-qualified # 🏃🏼‍♂ man running: medium-light skin tone
+1F3C3 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🏃🏽‍♂️ man running: medium skin tone
+1F3C3 1F3FD 200D 2642                      ; minimally-qualified # 🏃🏽‍♂ man running: medium skin tone
+1F3C3 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🏃🏾‍♂️ man running: medium-dark skin tone
+1F3C3 1F3FE 200D 2642                      ; minimally-qualified # 🏃🏾‍♂ man running: medium-dark skin tone
+1F3C3 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🏃🏿‍♂️ man running: dark skin tone
+1F3C3 1F3FF 200D 2642                      ; minimally-qualified # 🏃🏿‍♂ man running: dark skin tone
+1F3C3 200D 2640 FE0F                       ; fully-qualified     # 🏃‍♀️ woman running
+1F3C3 200D 2640                            ; minimally-qualified # 🏃‍♀ woman running
+1F3C3 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🏃🏻‍♀️ woman running: light skin tone
+1F3C3 1F3FB 200D 2640                      ; minimally-qualified # 🏃🏻‍♀ woman running: light skin tone
+1F3C3 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🏃🏼‍♀️ woman running: medium-light skin tone
+1F3C3 1F3FC 200D 2640                      ; minimally-qualified # 🏃🏼‍♀ woman running: medium-light skin tone
+1F3C3 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🏃🏽‍♀️ woman running: medium skin tone
+1F3C3 1F3FD 200D 2640                      ; minimally-qualified # 🏃🏽‍♀ woman running: medium skin tone
+1F3C3 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🏃🏾‍♀️ woman running: medium-dark skin tone
+1F3C3 1F3FE 200D 2640                      ; minimally-qualified # 🏃🏾‍♀ woman running: medium-dark skin tone
+1F3C3 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🏃🏿‍♀️ woman running: dark skin tone
+1F3C3 1F3FF 200D 2640                      ; minimally-qualified # 🏃🏿‍♀ woman running: dark skin tone
+1F483                                      ; fully-qualified     # 💃 woman dancing
+1F483 1F3FB                                ; fully-qualified     # 💃🏻 woman dancing: light skin tone
+1F483 1F3FC                                ; fully-qualified     # 💃🏼 woman dancing: medium-light skin tone
+1F483 1F3FD                                ; fully-qualified     # 💃🏽 woman dancing: medium skin tone
+1F483 1F3FE                                ; fully-qualified     # 💃🏾 woman dancing: medium-dark skin tone
+1F483 1F3FF                                ; fully-qualified     # 💃🏿 woman dancing: dark skin tone
+1F57A                                      ; fully-qualified     # 🕺 man dancing
+1F57A 1F3FB                                ; fully-qualified     # 🕺🏻 man dancing: light skin tone
+1F57A 1F3FC                                ; fully-qualified     # 🕺🏼 man dancing: medium-light skin tone
+1F57A 1F3FD                                ; fully-qualified     # 🕺🏽 man dancing: medium skin tone
+1F57A 1F3FE                                ; fully-qualified     # 🕺🏾 man dancing: medium-dark skin tone
+1F57A 1F3FF                                ; fully-qualified     # 🕺🏿 man dancing: dark skin tone
+1F574 FE0F                                 ; fully-qualified     # 🕴️ man in suit levitating
+1F574                                      ; unqualified         # 🕴 man in suit levitating
+1F574 1F3FB                                ; fully-qualified     # 🕴🏻 man in suit levitating: light skin tone
+1F574 1F3FC                                ; fully-qualified     # 🕴🏼 man in suit levitating: medium-light skin tone
+1F574 1F3FD                                ; fully-qualified     # 🕴🏽 man in suit levitating: medium skin tone
+1F574 1F3FE                                ; fully-qualified     # 🕴🏾 man in suit levitating: medium-dark skin tone
+1F574 1F3FF                                ; fully-qualified     # 🕴🏿 man in suit levitating: dark skin tone
+1F46F                                      ; fully-qualified     # 👯 people with bunny ears
+1F46F 200D 2642 FE0F                       ; fully-qualified     # 👯‍♂️ men with bunny ears
+1F46F 200D 2642                            ; minimally-qualified # 👯‍♂ men with bunny ears
+1F46F 200D 2640 FE0F                       ; fully-qualified     # 👯‍♀️ women with bunny ears
+1F46F 200D 2640                            ; minimally-qualified # 👯‍♀ women with bunny ears
+1F9D6                                      ; fully-qualified     # 🧖 person in steamy room
+1F9D6 1F3FB                                ; fully-qualified     # 🧖🏻 person in steamy room: light skin tone
+1F9D6 1F3FC                                ; fully-qualified     # 🧖🏼 person in steamy room: medium-light skin tone
+1F9D6 1F3FD                                ; fully-qualified     # 🧖🏽 person in steamy room: medium skin tone
+1F9D6 1F3FE                                ; fully-qualified     # 🧖🏾 person in steamy room: medium-dark skin tone
+1F9D6 1F3FF                                ; fully-qualified     # 🧖🏿 person in steamy room: dark skin tone
+1F9D6 200D 2642 FE0F                       ; fully-qualified     # 🧖‍♂️ man in steamy room
+1F9D6 200D 2642                            ; minimally-qualified # 🧖‍♂ man in steamy room
+1F9D6 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧖🏻‍♂️ man in steamy room: light skin tone
+1F9D6 1F3FB 200D 2642                      ; minimally-qualified # 🧖🏻‍♂ man in steamy room: light skin tone
+1F9D6 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧖🏼‍♂️ man in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2642                      ; minimally-qualified # 🧖🏼‍♂ man in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧖🏽‍♂️ man in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2642                      ; minimally-qualified # 🧖🏽‍♂ man in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧖🏾‍♂️ man in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2642                      ; minimally-qualified # 🧖🏾‍♂ man in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧖🏿‍♂️ man in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2642                      ; minimally-qualified # 🧖🏿‍♂ man in steamy room: dark skin tone
+1F9D6 200D 2640 FE0F                       ; fully-qualified     # 🧖‍♀️ woman in steamy room
+1F9D6 200D 2640                            ; minimally-qualified # 🧖‍♀ woman in steamy room
+1F9D6 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧖🏻‍♀️ woman in steamy room: light skin tone
+1F9D6 1F3FB 200D 2640                      ; minimally-qualified # 🧖🏻‍♀ woman in steamy room: light skin tone
+1F9D6 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧖🏼‍♀️ woman in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2640                      ; minimally-qualified # 🧖🏼‍♀ woman in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧖🏽‍♀️ woman in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2640                      ; minimally-qualified # 🧖🏽‍♀ woman in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧖🏾‍♀️ woman in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2640                      ; minimally-qualified # 🧖🏾‍♀ woman in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧖🏿‍♀️ woman in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2640                      ; minimally-qualified # 🧖🏿‍♀ woman in steamy room: dark skin tone
+1F9D7                                      ; fully-qualified     # 🧗 person climbing
+1F9D7 1F3FB                                ; fully-qualified     # 🧗🏻 person climbing: light skin tone
+1F9D7 1F3FC                                ; fully-qualified     # 🧗🏼 person climbing: medium-light skin tone
+1F9D7 1F3FD                                ; fully-qualified     # 🧗🏽 person climbing: medium skin tone
+1F9D7 1F3FE                                ; fully-qualified     # 🧗🏾 person climbing: medium-dark skin tone
+1F9D7 1F3FF                                ; fully-qualified     # 🧗🏿 person climbing: dark skin tone
+1F9D7 200D 2642 FE0F                       ; fully-qualified     # 🧗‍♂️ man climbing
+1F9D7 200D 2642                            ; minimally-qualified # 🧗‍♂ man climbing
+1F9D7 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧗🏻‍♂️ man climbing: light skin tone
+1F9D7 1F3FB 200D 2642                      ; minimally-qualified # 🧗🏻‍♂ man climbing: light skin tone
+1F9D7 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧗🏼‍♂️ man climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2642                      ; minimally-qualified # 🧗🏼‍♂ man climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧗🏽‍♂️ man climbing: medium skin tone
+1F9D7 1F3FD 200D 2642                      ; minimally-qualified # 🧗🏽‍♂ man climbing: medium skin tone
+1F9D7 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧗🏾‍♂️ man climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2642                      ; minimally-qualified # 🧗🏾‍♂ man climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧗🏿‍♂️ man climbing: dark skin tone
+1F9D7 1F3FF 200D 2642                      ; minimally-qualified # 🧗🏿‍♂ man climbing: dark skin tone
+1F9D7 200D 2640 FE0F                       ; fully-qualified     # 🧗‍♀️ woman climbing
+1F9D7 200D 2640                            ; minimally-qualified # 🧗‍♀ woman climbing
+1F9D7 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧗🏻‍♀️ woman climbing: light skin tone
+1F9D7 1F3FB 200D 2640                      ; minimally-qualified # 🧗🏻‍♀ woman climbing: light skin tone
+1F9D7 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧗🏼‍♀️ woman climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2640                      ; minimally-qualified # 🧗🏼‍♀ woman climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧗🏽‍♀️ woman climbing: medium skin tone
+1F9D7 1F3FD 200D 2640                      ; minimally-qualified # 🧗🏽‍♀ woman climbing: medium skin tone
+1F9D7 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧗🏾‍♀️ woman climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2640                      ; minimally-qualified # 🧗🏾‍♀ woman climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧗🏿‍♀️ woman climbing: dark skin tone
+1F9D7 1F3FF 200D 2640                      ; minimally-qualified # 🧗🏿‍♀ woman climbing: dark skin tone
+
+# subgroup: person-sport
+1F93A                                      ; fully-qualified     # 🤺 person fencing
+1F3C7                                      ; fully-qualified     # 🏇 horse racing
+1F3C7 1F3FB                                ; fully-qualified     # 🏇🏻 horse racing: light skin tone
+1F3C7 1F3FC                                ; fully-qualified     # 🏇🏼 horse racing: medium-light skin tone
+1F3C7 1F3FD                                ; fully-qualified     # 🏇🏽 horse racing: medium skin tone
+1F3C7 1F3FE                                ; fully-qualified     # 🏇🏾 horse racing: medium-dark skin tone
+1F3C7 1F3FF                                ; fully-qualified     # 🏇🏿 horse racing: dark skin tone
+26F7 FE0F                                  ; fully-qualified     # ⛷️ skier
+26F7                                       ; unqualified         # ⛷ skier
+1F3C2                                      ; fully-qualified     # 🏂 snowboarder
+1F3C2 1F3FB                                ; fully-qualified     # 🏂🏻 snowboarder: light skin tone
+1F3C2 1F3FC                                ; fully-qualified     # 🏂🏼 snowboarder: medium-light skin tone
+1F3C2 1F3FD                                ; fully-qualified     # 🏂🏽 snowboarder: medium skin tone
+1F3C2 1F3FE                                ; fully-qualified     # 🏂🏾 snowboarder: medium-dark skin tone
+1F3C2 1F3FF                                ; fully-qualified     # 🏂🏿 snowboarder: dark skin tone
+1F3CC FE0F                                 ; fully-qualified     # 🏌️ person golfing
+1F3CC                                      ; unqualified         # 🏌 person golfing
+1F3CC 1F3FB                                ; fully-qualified     # 🏌🏻 person golfing: light skin tone
+1F3CC 1F3FC                                ; fully-qualified     # 🏌🏼 person golfing: medium-light skin tone
+1F3CC 1F3FD                                ; fully-qualified     # 🏌🏽 person golfing: medium skin tone
+1F3CC 1F3FE                                ; fully-qualified     # 🏌🏾 person golfing: medium-dark skin tone
+1F3CC 1F3FF                                ; fully-qualified     # 🏌🏿 person golfing: dark skin tone
+1F3CC FE0F 200D 2642 FE0F                  ; fully-qualified     # 🏌️‍♂️ man golfing
+1F3CC 200D 2642 FE0F                       ; unqualified         # 🏌‍♂️ man golfing
+1F3CC FE0F 200D 2642                       ; unqualified         # 🏌️‍♂ man golfing
+1F3CC 200D 2642                            ; unqualified         # 🏌‍♂ man golfing
+1F3CC 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🏌🏻‍♂️ man golfing: light skin tone
+1F3CC 1F3FB 200D 2642                      ; minimally-qualified # 🏌🏻‍♂ man golfing: light skin tone
+1F3CC 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🏌🏼‍♂️ man golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2642                      ; minimally-qualified # 🏌🏼‍♂ man golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🏌🏽‍♂️ man golfing: medium skin tone
+1F3CC 1F3FD 200D 2642                      ; minimally-qualified # 🏌🏽‍♂ man golfing: medium skin tone
+1F3CC 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🏌🏾‍♂️ man golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2642                      ; minimally-qualified # 🏌🏾‍♂ man golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🏌🏿‍♂️ man golfing: dark skin tone
+1F3CC 1F3FF 200D 2642                      ; minimally-qualified # 🏌🏿‍♂ man golfing: dark skin tone
+1F3CC FE0F 200D 2640 FE0F                  ; fully-qualified     # 🏌️‍♀️ woman golfing
+1F3CC 200D 2640 FE0F                       ; unqualified         # 🏌‍♀️ woman golfing
+1F3CC FE0F 200D 2640                       ; unqualified         # 🏌️‍♀ woman golfing
+1F3CC 200D 2640                            ; unqualified         # 🏌‍♀ woman golfing
+1F3CC 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🏌🏻‍♀️ woman golfing: light skin tone
+1F3CC 1F3FB 200D 2640                      ; minimally-qualified # 🏌🏻‍♀ woman golfing: light skin tone
+1F3CC 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🏌🏼‍♀️ woman golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2640                      ; minimally-qualified # 🏌🏼‍♀ woman golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🏌🏽‍♀️ woman golfing: medium skin tone
+1F3CC 1F3FD 200D 2640                      ; minimally-qualified # 🏌🏽‍♀ woman golfing: medium skin tone
+1F3CC 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🏌🏾‍♀️ woman golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2640                      ; minimally-qualified # 🏌🏾‍♀ woman golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🏌🏿‍♀️ woman golfing: dark skin tone
+1F3CC 1F3FF 200D 2640                      ; minimally-qualified # 🏌🏿‍♀ woman golfing: dark skin tone
+1F3C4                                      ; fully-qualified     # 🏄 person surfing
+1F3C4 1F3FB                                ; fully-qualified     # 🏄🏻 person surfing: light skin tone
+1F3C4 1F3FC                                ; fully-qualified     # 🏄🏼 person surfing: medium-light skin tone
+1F3C4 1F3FD                                ; fully-qualified     # 🏄🏽 person surfing: medium skin tone
+1F3C4 1F3FE                                ; fully-qualified     # 🏄🏾 person surfing: medium-dark skin tone
+1F3C4 1F3FF                                ; fully-qualified     # 🏄🏿 person surfing: dark skin tone
+1F3C4 200D 2642 FE0F                       ; fully-qualified     # 🏄‍♂️ man surfing
+1F3C4 200D 2642                            ; minimally-qualified # 🏄‍♂ man surfing
+1F3C4 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🏄🏻‍♂️ man surfing: light skin tone
+1F3C4 1F3FB 200D 2642                      ; minimally-qualified # 🏄🏻‍♂ man surfing: light skin tone
+1F3C4 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🏄🏼‍♂️ man surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2642                      ; minimally-qualified # 🏄🏼‍♂ man surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🏄🏽‍♂️ man surfing: medium skin tone
+1F3C4 1F3FD 200D 2642                      ; minimally-qualified # 🏄🏽‍♂ man surfing: medium skin tone
+1F3C4 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🏄🏾‍♂️ man surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2642                      ; minimally-qualified # 🏄🏾‍♂ man surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🏄🏿‍♂️ man surfing: dark skin tone
+1F3C4 1F3FF 200D 2642                      ; minimally-qualified # 🏄🏿‍♂ man surfing: dark skin tone
+1F3C4 200D 2640 FE0F                       ; fully-qualified     # 🏄‍♀️ woman surfing
+1F3C4 200D 2640                            ; minimally-qualified # 🏄‍♀ woman surfing
+1F3C4 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🏄🏻‍♀️ woman surfing: light skin tone
+1F3C4 1F3FB 200D 2640                      ; minimally-qualified # 🏄🏻‍♀ woman surfing: light skin tone
+1F3C4 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🏄🏼‍♀️ woman surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2640                      ; minimally-qualified # 🏄🏼‍♀ woman surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🏄🏽‍♀️ woman surfing: medium skin tone
+1F3C4 1F3FD 200D 2640                      ; minimally-qualified # 🏄🏽‍♀ woman surfing: medium skin tone
+1F3C4 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🏄🏾‍♀️ woman surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2640                      ; minimally-qualified # 🏄🏾‍♀ woman surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🏄🏿‍♀️ woman surfing: dark skin tone
+1F3C4 1F3FF 200D 2640                      ; minimally-qualified # 🏄🏿‍♀ woman surfing: dark skin tone
+1F6A3                                      ; fully-qualified     # 🚣 person rowing boat
+1F6A3 1F3FB                                ; fully-qualified     # 🚣🏻 person rowing boat: light skin tone
+1F6A3 1F3FC                                ; fully-qualified     # 🚣🏼 person rowing boat: medium-light skin tone
+1F6A3 1F3FD                                ; fully-qualified     # 🚣🏽 person rowing boat: medium skin tone
+1F6A3 1F3FE                                ; fully-qualified     # 🚣🏾 person rowing boat: medium-dark skin tone
+1F6A3 1F3FF                                ; fully-qualified     # 🚣🏿 person rowing boat: dark skin tone
+1F6A3 200D 2642 FE0F                       ; fully-qualified     # 🚣‍♂️ man rowing boat
+1F6A3 200D 2642                            ; minimally-qualified # 🚣‍♂ man rowing boat
+1F6A3 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🚣🏻‍♂️ man rowing boat: light skin tone
+1F6A3 1F3FB 200D 2642                      ; minimally-qualified # 🚣🏻‍♂ man rowing boat: light skin tone
+1F6A3 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🚣🏼‍♂️ man rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2642                      ; minimally-qualified # 🚣🏼‍♂ man rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🚣🏽‍♂️ man rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2642                      ; minimally-qualified # 🚣🏽‍♂ man rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🚣🏾‍♂️ man rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2642                      ; minimally-qualified # 🚣🏾‍♂ man rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🚣🏿‍♂️ man rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2642                      ; minimally-qualified # 🚣🏿‍♂ man rowing boat: dark skin tone
+1F6A3 200D 2640 FE0F                       ; fully-qualified     # 🚣‍♀️ woman rowing boat
+1F6A3 200D 2640                            ; minimally-qualified # 🚣‍♀ woman rowing boat
+1F6A3 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🚣🏻‍♀️ woman rowing boat: light skin tone
+1F6A3 1F3FB 200D 2640                      ; minimally-qualified # 🚣🏻‍♀ woman rowing boat: light skin tone
+1F6A3 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🚣🏼‍♀️ woman rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2640                      ; minimally-qualified # 🚣🏼‍♀ woman rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🚣🏽‍♀️ woman rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2640                      ; minimally-qualified # 🚣🏽‍♀ woman rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🚣🏾‍♀️ woman rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2640                      ; minimally-qualified # 🚣🏾‍♀ woman rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🚣🏿‍♀️ woman rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2640                      ; minimally-qualified # 🚣🏿‍♀ woman rowing boat: dark skin tone
+1F3CA                                      ; fully-qualified     # 🏊 person swimming
+1F3CA 1F3FB                                ; fully-qualified     # 🏊🏻 person swimming: light skin tone
+1F3CA 1F3FC                                ; fully-qualified     # 🏊🏼 person swimming: medium-light skin tone
+1F3CA 1F3FD                                ; fully-qualified     # 🏊🏽 person swimming: medium skin tone
+1F3CA 1F3FE                                ; fully-qualified     # 🏊🏾 person swimming: medium-dark skin tone
+1F3CA 1F3FF                                ; fully-qualified     # 🏊🏿 person swimming: dark skin tone
+1F3CA 200D 2642 FE0F                       ; fully-qualified     # 🏊‍♂️ man swimming
+1F3CA 200D 2642                            ; minimally-qualified # 🏊‍♂ man swimming
+1F3CA 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🏊🏻‍♂️ man swimming: light skin tone
+1F3CA 1F3FB 200D 2642                      ; minimally-qualified # 🏊🏻‍♂ man swimming: light skin tone
+1F3CA 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🏊🏼‍♂️ man swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2642                      ; minimally-qualified # 🏊🏼‍♂ man swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🏊🏽‍♂️ man swimming: medium skin tone
+1F3CA 1F3FD 200D 2642                      ; minimally-qualified # 🏊🏽‍♂ man swimming: medium skin tone
+1F3CA 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🏊🏾‍♂️ man swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2642                      ; minimally-qualified # 🏊🏾‍♂ man swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🏊🏿‍♂️ man swimming: dark skin tone
+1F3CA 1F3FF 200D 2642                      ; minimally-qualified # 🏊🏿‍♂ man swimming: dark skin tone
+1F3CA 200D 2640 FE0F                       ; fully-qualified     # 🏊‍♀️ woman swimming
+1F3CA 200D 2640                            ; minimally-qualified # 🏊‍♀ woman swimming
+1F3CA 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🏊🏻‍♀️ woman swimming: light skin tone
+1F3CA 1F3FB 200D 2640                      ; minimally-qualified # 🏊🏻‍♀ woman swimming: light skin tone
+1F3CA 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🏊🏼‍♀️ woman swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2640                      ; minimally-qualified # 🏊🏼‍♀ woman swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🏊🏽‍♀️ woman swimming: medium skin tone
+1F3CA 1F3FD 200D 2640                      ; minimally-qualified # 🏊🏽‍♀ woman swimming: medium skin tone
+1F3CA 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🏊🏾‍♀️ woman swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2640                      ; minimally-qualified # 🏊🏾‍♀ woman swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🏊🏿‍♀️ woman swimming: dark skin tone
+1F3CA 1F3FF 200D 2640                      ; minimally-qualified # 🏊🏿‍♀ woman swimming: dark skin tone
+26F9 FE0F                                  ; fully-qualified     # ⛹️ person bouncing ball
+26F9                                       ; unqualified         # ⛹ person bouncing ball
+26F9 1F3FB                                 ; fully-qualified     # ⛹🏻 person bouncing ball: light skin tone
+26F9 1F3FC                                 ; fully-qualified     # ⛹🏼 person bouncing ball: medium-light skin tone
+26F9 1F3FD                                 ; fully-qualified     # ⛹🏽 person bouncing ball: medium skin tone
+26F9 1F3FE                                 ; fully-qualified     # ⛹🏾 person bouncing ball: medium-dark skin tone
+26F9 1F3FF                                 ; fully-qualified     # ⛹🏿 person bouncing ball: dark skin tone
+26F9 FE0F 200D 2642 FE0F                   ; fully-qualified     # ⛹️‍♂️ man bouncing ball
+26F9 200D 2642 FE0F                        ; unqualified         # ⛹‍♂️ man bouncing ball
+26F9 FE0F 200D 2642                        ; unqualified         # ⛹️‍♂ man bouncing ball
+26F9 200D 2642                             ; unqualified         # ⛹‍♂ man bouncing ball
+26F9 1F3FB 200D 2642 FE0F                  ; fully-qualified     # ⛹🏻‍♂️ man bouncing ball: light skin tone
+26F9 1F3FB 200D 2642                       ; minimally-qualified # ⛹🏻‍♂ man bouncing ball: light skin tone
+26F9 1F3FC 200D 2642 FE0F                  ; fully-qualified     # ⛹🏼‍♂️ man bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2642                       ; minimally-qualified # ⛹🏼‍♂ man bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2642 FE0F                  ; fully-qualified     # ⛹🏽‍♂️ man bouncing ball: medium skin tone
+26F9 1F3FD 200D 2642                       ; minimally-qualified # ⛹🏽‍♂ man bouncing ball: medium skin tone
+26F9 1F3FE 200D 2642 FE0F                  ; fully-qualified     # ⛹🏾‍♂️ man bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2642                       ; minimally-qualified # ⛹🏾‍♂ man bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2642 FE0F                  ; fully-qualified     # ⛹🏿‍♂️ man bouncing ball: dark skin tone
+26F9 1F3FF 200D 2642                       ; minimally-qualified # ⛹🏿‍♂ man bouncing ball: dark skin tone
+26F9 FE0F 200D 2640 FE0F                   ; fully-qualified     # ⛹️‍♀️ woman bouncing ball
+26F9 200D 2640 FE0F                        ; unqualified         # ⛹‍♀️ woman bouncing ball
+26F9 FE0F 200D 2640                        ; unqualified         # ⛹️‍♀ woman bouncing ball
+26F9 200D 2640                             ; unqualified         # ⛹‍♀ woman bouncing ball
+26F9 1F3FB 200D 2640 FE0F                  ; fully-qualified     # ⛹🏻‍♀️ woman bouncing ball: light skin tone
+26F9 1F3FB 200D 2640                       ; minimally-qualified # ⛹🏻‍♀ woman bouncing ball: light skin tone
+26F9 1F3FC 200D 2640 FE0F                  ; fully-qualified     # ⛹🏼‍♀️ woman bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2640                       ; minimally-qualified # ⛹🏼‍♀ woman bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2640 FE0F                  ; fully-qualified     # ⛹🏽‍♀️ woman bouncing ball: medium skin tone
+26F9 1F3FD 200D 2640                       ; minimally-qualified # ⛹🏽‍♀ woman bouncing ball: medium skin tone
+26F9 1F3FE 200D 2640 FE0F                  ; fully-qualified     # ⛹🏾‍♀️ woman bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2640                       ; minimally-qualified # ⛹🏾‍♀ woman bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2640 FE0F                  ; fully-qualified     # ⛹🏿‍♀️ woman bouncing ball: dark skin tone
+26F9 1F3FF 200D 2640                       ; minimally-qualified # ⛹🏿‍♀ woman bouncing ball: dark skin tone
+1F3CB FE0F                                 ; fully-qualified     # 🏋️ person lifting weights
+1F3CB                                      ; unqualified         # 🏋 person lifting weights
+1F3CB 1F3FB                                ; fully-qualified     # 🏋🏻 person lifting weights: light skin tone
+1F3CB 1F3FC                                ; fully-qualified     # 🏋🏼 person lifting weights: medium-light skin tone
+1F3CB 1F3FD                                ; fully-qualified     # 🏋🏽 person lifting weights: medium skin tone
+1F3CB 1F3FE                                ; fully-qualified     # 🏋🏾 person lifting weights: medium-dark skin tone
+1F3CB 1F3FF                                ; fully-qualified     # 🏋🏿 person lifting weights: dark skin tone
+1F3CB FE0F 200D 2642 FE0F                  ; fully-qualified     # 🏋️‍♂️ man lifting weights
+1F3CB 200D 2642 FE0F                       ; unqualified         # 🏋‍♂️ man lifting weights
+1F3CB FE0F 200D 2642                       ; unqualified         # 🏋️‍♂ man lifting weights
+1F3CB 200D 2642                            ; unqualified         # 🏋‍♂ man lifting weights
+1F3CB 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🏋🏻‍♂️ man lifting weights: light skin tone
+1F3CB 1F3FB 200D 2642                      ; minimally-qualified # 🏋🏻‍♂ man lifting weights: light skin tone
+1F3CB 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🏋🏼‍♂️ man lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2642                      ; minimally-qualified # 🏋🏼‍♂ man lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🏋🏽‍♂️ man lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2642                      ; minimally-qualified # 🏋🏽‍♂ man lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🏋🏾‍♂️ man lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2642                      ; minimally-qualified # 🏋🏾‍♂ man lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🏋🏿‍♂️ man lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2642                      ; minimally-qualified # 🏋🏿‍♂ man lifting weights: dark skin tone
+1F3CB FE0F 200D 2640 FE0F                  ; fully-qualified     # 🏋️‍♀️ woman lifting weights
+1F3CB 200D 2640 FE0F                       ; unqualified         # 🏋‍♀️ woman lifting weights
+1F3CB FE0F 200D 2640                       ; unqualified         # 🏋️‍♀ woman lifting weights
+1F3CB 200D 2640                            ; unqualified         # 🏋‍♀ woman lifting weights
+1F3CB 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🏋🏻‍♀️ woman lifting weights: light skin tone
+1F3CB 1F3FB 200D 2640                      ; minimally-qualified # 🏋🏻‍♀ woman lifting weights: light skin tone
+1F3CB 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🏋🏼‍♀️ woman lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2640                      ; minimally-qualified # 🏋🏼‍♀ woman lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🏋🏽‍♀️ woman lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2640                      ; minimally-qualified # 🏋🏽‍♀ woman lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🏋🏾‍♀️ woman lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2640                      ; minimally-qualified # 🏋🏾‍♀ woman lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🏋🏿‍♀️ woman lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2640                      ; minimally-qualified # 🏋🏿‍♀ woman lifting weights: dark skin tone
+1F6B4                                      ; fully-qualified     # 🚴 person biking
+1F6B4 1F3FB                                ; fully-qualified     # 🚴🏻 person biking: light skin tone
+1F6B4 1F3FC                                ; fully-qualified     # 🚴🏼 person biking: medium-light skin tone
+1F6B4 1F3FD                                ; fully-qualified     # 🚴🏽 person biking: medium skin tone
+1F6B4 1F3FE                                ; fully-qualified     # 🚴🏾 person biking: medium-dark skin tone
+1F6B4 1F3FF                                ; fully-qualified     # 🚴🏿 person biking: dark skin tone
+1F6B4 200D 2642 FE0F                       ; fully-qualified     # 🚴‍♂️ man biking
+1F6B4 200D 2642                            ; minimally-qualified # 🚴‍♂ man biking
+1F6B4 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🚴🏻‍♂️ man biking: light skin tone
+1F6B4 1F3FB 200D 2642                      ; minimally-qualified # 🚴🏻‍♂ man biking: light skin tone
+1F6B4 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🚴🏼‍♂️ man biking: medium-light skin tone
+1F6B4 1F3FC 200D 2642                      ; minimally-qualified # 🚴🏼‍♂ man biking: medium-light skin tone
+1F6B4 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🚴🏽‍♂️ man biking: medium skin tone
+1F6B4 1F3FD 200D 2642                      ; minimally-qualified # 🚴🏽‍♂ man biking: medium skin tone
+1F6B4 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🚴🏾‍♂️ man biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2642                      ; minimally-qualified # 🚴🏾‍♂ man biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🚴🏿‍♂️ man biking: dark skin tone
+1F6B4 1F3FF 200D 2642                      ; minimally-qualified # 🚴🏿‍♂ man biking: dark skin tone
+1F6B4 200D 2640 FE0F                       ; fully-qualified     # 🚴‍♀️ woman biking
+1F6B4 200D 2640                            ; minimally-qualified # 🚴‍♀ woman biking
+1F6B4 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🚴🏻‍♀️ woman biking: light skin tone
+1F6B4 1F3FB 200D 2640                      ; minimally-qualified # 🚴🏻‍♀ woman biking: light skin tone
+1F6B4 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🚴🏼‍♀️ woman biking: medium-light skin tone
+1F6B4 1F3FC 200D 2640                      ; minimally-qualified # 🚴🏼‍♀ woman biking: medium-light skin tone
+1F6B4 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🚴🏽‍♀️ woman biking: medium skin tone
+1F6B4 1F3FD 200D 2640                      ; minimally-qualified # 🚴🏽‍♀ woman biking: medium skin tone
+1F6B4 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🚴🏾‍♀️ woman biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2640                      ; minimally-qualified # 🚴🏾‍♀ woman biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🚴🏿‍♀️ woman biking: dark skin tone
+1F6B4 1F3FF 200D 2640                      ; minimally-qualified # 🚴🏿‍♀ woman biking: dark skin tone
+1F6B5                                      ; fully-qualified     # 🚵 person mountain biking
+1F6B5 1F3FB                                ; fully-qualified     # 🚵🏻 person mountain biking: light skin tone
+1F6B5 1F3FC                                ; fully-qualified     # 🚵🏼 person mountain biking: medium-light skin tone
+1F6B5 1F3FD                                ; fully-qualified     # 🚵🏽 person mountain biking: medium skin tone
+1F6B5 1F3FE                                ; fully-qualified     # 🚵🏾 person mountain biking: medium-dark skin tone
+1F6B5 1F3FF                                ; fully-qualified     # 🚵🏿 person mountain biking: dark skin tone
+1F6B5 200D 2642 FE0F                       ; fully-qualified     # 🚵‍♂️ man mountain biking
+1F6B5 200D 2642                            ; minimally-qualified # 🚵‍♂ man mountain biking
+1F6B5 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🚵🏻‍♂️ man mountain biking: light skin tone
+1F6B5 1F3FB 200D 2642                      ; minimally-qualified # 🚵🏻‍♂ man mountain biking: light skin tone
+1F6B5 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🚵🏼‍♂️ man mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2642                      ; minimally-qualified # 🚵🏼‍♂ man mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🚵🏽‍♂️ man mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2642                      ; minimally-qualified # 🚵🏽‍♂ man mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🚵🏾‍♂️ man mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2642                      ; minimally-qualified # 🚵🏾‍♂ man mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🚵🏿‍♂️ man mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2642                      ; minimally-qualified # 🚵🏿‍♂ man mountain biking: dark skin tone
+1F6B5 200D 2640 FE0F                       ; fully-qualified     # 🚵‍♀️ woman mountain biking
+1F6B5 200D 2640                            ; minimally-qualified # 🚵‍♀ woman mountain biking
+1F6B5 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🚵🏻‍♀️ woman mountain biking: light skin tone
+1F6B5 1F3FB 200D 2640                      ; minimally-qualified # 🚵🏻‍♀ woman mountain biking: light skin tone
+1F6B5 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🚵🏼‍♀️ woman mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2640                      ; minimally-qualified # 🚵🏼‍♀ woman mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🚵🏽‍♀️ woman mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2640                      ; minimally-qualified # 🚵🏽‍♀ woman mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🚵🏾‍♀️ woman mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2640                      ; minimally-qualified # 🚵🏾‍♀ woman mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🚵🏿‍♀️ woman mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2640                      ; minimally-qualified # 🚵🏿‍♀ woman mountain biking: dark skin tone
+1F938                                      ; fully-qualified     # 🤸 person cartwheeling
+1F938 1F3FB                                ; fully-qualified     # 🤸🏻 person cartwheeling: light skin tone
+1F938 1F3FC                                ; fully-qualified     # 🤸🏼 person cartwheeling: medium-light skin tone
+1F938 1F3FD                                ; fully-qualified     # 🤸🏽 person cartwheeling: medium skin tone
+1F938 1F3FE                                ; fully-qualified     # 🤸🏾 person cartwheeling: medium-dark skin tone
+1F938 1F3FF                                ; fully-qualified     # 🤸🏿 person cartwheeling: dark skin tone
+1F938 200D 2642 FE0F                       ; fully-qualified     # 🤸‍♂️ man cartwheeling
+1F938 200D 2642                            ; minimally-qualified # 🤸‍♂ man cartwheeling
+1F938 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🤸🏻‍♂️ man cartwheeling: light skin tone
+1F938 1F3FB 200D 2642                      ; minimally-qualified # 🤸🏻‍♂ man cartwheeling: light skin tone
+1F938 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🤸🏼‍♂️ man cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2642                      ; minimally-qualified # 🤸🏼‍♂ man cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🤸🏽‍♂️ man cartwheeling: medium skin tone
+1F938 1F3FD 200D 2642                      ; minimally-qualified # 🤸🏽‍♂ man cartwheeling: medium skin tone
+1F938 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🤸🏾‍♂️ man cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2642                      ; minimally-qualified # 🤸🏾‍♂ man cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🤸🏿‍♂️ man cartwheeling: dark skin tone
+1F938 1F3FF 200D 2642                      ; minimally-qualified # 🤸🏿‍♂ man cartwheeling: dark skin tone
+1F938 200D 2640 FE0F                       ; fully-qualified     # 🤸‍♀️ woman cartwheeling
+1F938 200D 2640                            ; minimally-qualified # 🤸‍♀ woman cartwheeling
+1F938 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🤸🏻‍♀️ woman cartwheeling: light skin tone
+1F938 1F3FB 200D 2640                      ; minimally-qualified # 🤸🏻‍♀ woman cartwheeling: light skin tone
+1F938 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🤸🏼‍♀️ woman cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2640                      ; minimally-qualified # 🤸🏼‍♀ woman cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🤸🏽‍♀️ woman cartwheeling: medium skin tone
+1F938 1F3FD 200D 2640                      ; minimally-qualified # 🤸🏽‍♀ woman cartwheeling: medium skin tone
+1F938 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🤸🏾‍♀️ woman cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2640                      ; minimally-qualified # 🤸🏾‍♀ woman cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🤸🏿‍♀️ woman cartwheeling: dark skin tone
+1F938 1F3FF 200D 2640                      ; minimally-qualified # 🤸🏿‍♀ woman cartwheeling: dark skin tone
+1F93C                                      ; fully-qualified     # 🤼 people wrestling
+1F93C 200D 2642 FE0F                       ; fully-qualified     # 🤼‍♂️ men wrestling
+1F93C 200D 2642                            ; minimally-qualified # 🤼‍♂ men wrestling
+1F93C 200D 2640 FE0F                       ; fully-qualified     # 🤼‍♀️ women wrestling
+1F93C 200D 2640                            ; minimally-qualified # 🤼‍♀ women wrestling
+1F93D                                      ; fully-qualified     # 🤽 person playing water polo
+1F93D 1F3FB                                ; fully-qualified     # 🤽🏻 person playing water polo: light skin tone
+1F93D 1F3FC                                ; fully-qualified     # 🤽🏼 person playing water polo: medium-light skin tone
+1F93D 1F3FD                                ; fully-qualified     # 🤽🏽 person playing water polo: medium skin tone
+1F93D 1F3FE                                ; fully-qualified     # 🤽🏾 person playing water polo: medium-dark skin tone
+1F93D 1F3FF                                ; fully-qualified     # 🤽🏿 person playing water polo: dark skin tone
+1F93D 200D 2642 FE0F                       ; fully-qualified     # 🤽‍♂️ man playing water polo
+1F93D 200D 2642                            ; minimally-qualified # 🤽‍♂ man playing water polo
+1F93D 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🤽🏻‍♂️ man playing water polo: light skin tone
+1F93D 1F3FB 200D 2642                      ; minimally-qualified # 🤽🏻‍♂ man playing water polo: light skin tone
+1F93D 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🤽🏼‍♂️ man playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2642                      ; minimally-qualified # 🤽🏼‍♂ man playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🤽🏽‍♂️ man playing water polo: medium skin tone
+1F93D 1F3FD 200D 2642                      ; minimally-qualified # 🤽🏽‍♂ man playing water polo: medium skin tone
+1F93D 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🤽🏾‍♂️ man playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2642                      ; minimally-qualified # 🤽🏾‍♂ man playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🤽🏿‍♂️ man playing water polo: dark skin tone
+1F93D 1F3FF 200D 2642                      ; minimally-qualified # 🤽🏿‍♂ man playing water polo: dark skin tone
+1F93D 200D 2640 FE0F                       ; fully-qualified     # 🤽‍♀️ woman playing water polo
+1F93D 200D 2640                            ; minimally-qualified # 🤽‍♀ woman playing water polo
+1F93D 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🤽🏻‍♀️ woman playing water polo: light skin tone
+1F93D 1F3FB 200D 2640                      ; minimally-qualified # 🤽🏻‍♀ woman playing water polo: light skin tone
+1F93D 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🤽🏼‍♀️ woman playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2640                      ; minimally-qualified # 🤽🏼‍♀ woman playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🤽🏽‍♀️ woman playing water polo: medium skin tone
+1F93D 1F3FD 200D 2640                      ; minimally-qualified # 🤽🏽‍♀ woman playing water polo: medium skin tone
+1F93D 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🤽🏾‍♀️ woman playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2640                      ; minimally-qualified # 🤽🏾‍♀ woman playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🤽🏿‍♀️ woman playing water polo: dark skin tone
+1F93D 1F3FF 200D 2640                      ; minimally-qualified # 🤽🏿‍♀ woman playing water polo: dark skin tone
+1F93E                                      ; fully-qualified     # 🤾 person playing handball
+1F93E 1F3FB                                ; fully-qualified     # 🤾🏻 person playing handball: light skin tone
+1F93E 1F3FC                                ; fully-qualified     # 🤾🏼 person playing handball: medium-light skin tone
+1F93E 1F3FD                                ; fully-qualified     # 🤾🏽 person playing handball: medium skin tone
+1F93E 1F3FE                                ; fully-qualified     # 🤾🏾 person playing handball: medium-dark skin tone
+1F93E 1F3FF                                ; fully-qualified     # 🤾🏿 person playing handball: dark skin tone
+1F93E 200D 2642 FE0F                       ; fully-qualified     # 🤾‍♂️ man playing handball
+1F93E 200D 2642                            ; minimally-qualified # 🤾‍♂ man playing handball
+1F93E 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🤾🏻‍♂️ man playing handball: light skin tone
+1F93E 1F3FB 200D 2642                      ; minimally-qualified # 🤾🏻‍♂ man playing handball: light skin tone
+1F93E 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🤾🏼‍♂️ man playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2642                      ; minimally-qualified # 🤾🏼‍♂ man playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🤾🏽‍♂️ man playing handball: medium skin tone
+1F93E 1F3FD 200D 2642                      ; minimally-qualified # 🤾🏽‍♂ man playing handball: medium skin tone
+1F93E 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🤾🏾‍♂️ man playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2642                      ; minimally-qualified # 🤾🏾‍♂ man playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🤾🏿‍♂️ man playing handball: dark skin tone
+1F93E 1F3FF 200D 2642                      ; minimally-qualified # 🤾🏿‍♂ man playing handball: dark skin tone
+1F93E 200D 2640 FE0F                       ; fully-qualified     # 🤾‍♀️ woman playing handball
+1F93E 200D 2640                            ; minimally-qualified # 🤾‍♀ woman playing handball
+1F93E 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🤾🏻‍♀️ woman playing handball: light skin tone
+1F93E 1F3FB 200D 2640                      ; minimally-qualified # 🤾🏻‍♀ woman playing handball: light skin tone
+1F93E 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🤾🏼‍♀️ woman playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2640                      ; minimally-qualified # 🤾🏼‍♀ woman playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🤾🏽‍♀️ woman playing handball: medium skin tone
+1F93E 1F3FD 200D 2640                      ; minimally-qualified # 🤾🏽‍♀ woman playing handball: medium skin tone
+1F93E 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🤾🏾‍♀️ woman playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2640                      ; minimally-qualified # 🤾🏾‍♀ woman playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🤾🏿‍♀️ woman playing handball: dark skin tone
+1F93E 1F3FF 200D 2640                      ; minimally-qualified # 🤾🏿‍♀ woman playing handball: dark skin tone
+1F939                                      ; fully-qualified     # 🤹 person juggling
+1F939 1F3FB                                ; fully-qualified     # 🤹🏻 person juggling: light skin tone
+1F939 1F3FC                                ; fully-qualified     # 🤹🏼 person juggling: medium-light skin tone
+1F939 1F3FD                                ; fully-qualified     # 🤹🏽 person juggling: medium skin tone
+1F939 1F3FE                                ; fully-qualified     # 🤹🏾 person juggling: medium-dark skin tone
+1F939 1F3FF                                ; fully-qualified     # 🤹🏿 person juggling: dark skin tone
+1F939 200D 2642 FE0F                       ; fully-qualified     # 🤹‍♂️ man juggling
+1F939 200D 2642                            ; minimally-qualified # 🤹‍♂ man juggling
+1F939 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🤹🏻‍♂️ man juggling: light skin tone
+1F939 1F3FB 200D 2642                      ; minimally-qualified # 🤹🏻‍♂ man juggling: light skin tone
+1F939 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🤹🏼‍♂️ man juggling: medium-light skin tone
+1F939 1F3FC 200D 2642                      ; minimally-qualified # 🤹🏼‍♂ man juggling: medium-light skin tone
+1F939 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🤹🏽‍♂️ man juggling: medium skin tone
+1F939 1F3FD 200D 2642                      ; minimally-qualified # 🤹🏽‍♂ man juggling: medium skin tone
+1F939 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🤹🏾‍♂️ man juggling: medium-dark skin tone
+1F939 1F3FE 200D 2642                      ; minimally-qualified # 🤹🏾‍♂ man juggling: medium-dark skin tone
+1F939 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🤹🏿‍♂️ man juggling: dark skin tone
+1F939 1F3FF 200D 2642                      ; minimally-qualified # 🤹🏿‍♂ man juggling: dark skin tone
+1F939 200D 2640 FE0F                       ; fully-qualified     # 🤹‍♀️ woman juggling
+1F939 200D 2640                            ; minimally-qualified # 🤹‍♀ woman juggling
+1F939 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🤹🏻‍♀️ woman juggling: light skin tone
+1F939 1F3FB 200D 2640                      ; minimally-qualified # 🤹🏻‍♀ woman juggling: light skin tone
+1F939 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🤹🏼‍♀️ woman juggling: medium-light skin tone
+1F939 1F3FC 200D 2640                      ; minimally-qualified # 🤹🏼‍♀ woman juggling: medium-light skin tone
+1F939 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🤹🏽‍♀️ woman juggling: medium skin tone
+1F939 1F3FD 200D 2640                      ; minimally-qualified # 🤹🏽‍♀ woman juggling: medium skin tone
+1F939 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🤹🏾‍♀️ woman juggling: medium-dark skin tone
+1F939 1F3FE 200D 2640                      ; minimally-qualified # 🤹🏾‍♀ woman juggling: medium-dark skin tone
+1F939 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🤹🏿‍♀️ woman juggling: dark skin tone
+1F939 1F3FF 200D 2640                      ; minimally-qualified # 🤹🏿‍♀ woman juggling: dark skin tone
+
+# subgroup: person-resting
+1F9D8                                      ; fully-qualified     # 🧘 person in lotus position
+1F9D8 1F3FB                                ; fully-qualified     # 🧘🏻 person in lotus position: light skin tone
+1F9D8 1F3FC                                ; fully-qualified     # 🧘🏼 person in lotus position: medium-light skin tone
+1F9D8 1F3FD                                ; fully-qualified     # 🧘🏽 person in lotus position: medium skin tone
+1F9D8 1F3FE                                ; fully-qualified     # 🧘🏾 person in lotus position: medium-dark skin tone
+1F9D8 1F3FF                                ; fully-qualified     # 🧘🏿 person in lotus position: dark skin tone
+1F9D8 200D 2642 FE0F                       ; fully-qualified     # 🧘‍♂️ man in lotus position
+1F9D8 200D 2642                            ; minimally-qualified # 🧘‍♂ man in lotus position
+1F9D8 1F3FB 200D 2642 FE0F                 ; fully-qualified     # 🧘🏻‍♂️ man in lotus position: light skin tone
+1F9D8 1F3FB 200D 2642                      ; minimally-qualified # 🧘🏻‍♂ man in lotus position: light skin tone
+1F9D8 1F3FC 200D 2642 FE0F                 ; fully-qualified     # 🧘🏼‍♂️ man in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2642                      ; minimally-qualified # 🧘🏼‍♂ man in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2642 FE0F                 ; fully-qualified     # 🧘🏽‍♂️ man in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2642                      ; minimally-qualified # 🧘🏽‍♂ man in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2642 FE0F                 ; fully-qualified     # 🧘🏾‍♂️ man in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2642                      ; minimally-qualified # 🧘🏾‍♂ man in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2642 FE0F                 ; fully-qualified     # 🧘🏿‍♂️ man in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2642                      ; minimally-qualified # 🧘🏿‍♂ man in lotus position: dark skin tone
+1F9D8 200D 2640 FE0F                       ; fully-qualified     # 🧘‍♀️ woman in lotus position
+1F9D8 200D 2640                            ; minimally-qualified # 🧘‍♀ woman in lotus position
+1F9D8 1F3FB 200D 2640 FE0F                 ; fully-qualified     # 🧘🏻‍♀️ woman in lotus position: light skin tone
+1F9D8 1F3FB 200D 2640                      ; minimally-qualified # 🧘🏻‍♀ woman in lotus position: light skin tone
+1F9D8 1F3FC 200D 2640 FE0F                 ; fully-qualified     # 🧘🏼‍♀️ woman in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2640                      ; minimally-qualified # 🧘🏼‍♀ woman in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2640 FE0F                 ; fully-qualified     # 🧘🏽‍♀️ woman in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2640                      ; minimally-qualified # 🧘🏽‍♀ woman in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2640 FE0F                 ; fully-qualified     # 🧘🏾‍♀️ woman in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2640                      ; minimally-qualified # 🧘🏾‍♀ woman in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2640 FE0F                 ; fully-qualified     # 🧘🏿‍♀️ woman in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2640                      ; minimally-qualified # 🧘🏿‍♀ woman in lotus position: dark skin tone
+1F6C0                                      ; fully-qualified     # 🛀 person taking bath
+1F6C0 1F3FB                                ; fully-qualified     # 🛀🏻 person taking bath: light skin tone
+1F6C0 1F3FC                                ; fully-qualified     # 🛀🏼 person taking bath: medium-light skin tone
+1F6C0 1F3FD                                ; fully-qualified     # 🛀🏽 person taking bath: medium skin tone
+1F6C0 1F3FE                                ; fully-qualified     # 🛀🏾 person taking bath: medium-dark skin tone
+1F6C0 1F3FF                                ; fully-qualified     # 🛀🏿 person taking bath: dark skin tone
+1F6CC                                      ; fully-qualified     # 🛌 person in bed
+1F6CC 1F3FB                                ; fully-qualified     # 🛌🏻 person in bed: light skin tone
+1F6CC 1F3FC                                ; fully-qualified     # 🛌🏼 person in bed: medium-light skin tone
+1F6CC 1F3FD                                ; fully-qualified     # 🛌🏽 person in bed: medium skin tone
+1F6CC 1F3FE                                ; fully-qualified     # 🛌🏾 person in bed: medium-dark skin tone
+1F6CC 1F3FF                                ; fully-qualified     # 🛌🏿 person in bed: dark skin tone
+
+# subgroup: family
+1F9D1 200D 1F91D 200D 1F9D1                ; fully-qualified     # 🧑‍🤝‍🧑 people holding hands
+1F9D1 1F3FB 200D 1F91D 200D 1F9D1 1F3FB    ; fully-qualified     # 🧑🏻‍🤝‍🧑🏻 people holding hands: light skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FB    ; fully-qualified     # 🧑🏼‍🤝‍🧑🏻 people holding hands: medium-light skin tone, light skin tone
+1F9D1 1F3FC 200D 1F91D 200D 1F9D1 1F3FC    ; fully-qualified     # 🧑🏼‍🤝‍🧑🏼 people holding hands: medium-light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FB    ; fully-qualified     # 🧑🏽‍🤝‍🧑🏻 people holding hands: medium skin tone, light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FC    ; fully-qualified     # 🧑🏽‍🤝‍🧑🏼 people holding hands: medium skin tone, medium-light skin tone
+1F9D1 1F3FD 200D 1F91D 200D 1F9D1 1F3FD    ; fully-qualified     # 🧑🏽‍🤝‍🧑🏽 people holding hands: medium skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FB    ; fully-qualified     # 🧑🏾‍🤝‍🧑🏻 people holding hands: medium-dark skin tone, light skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FC    ; fully-qualified     # 🧑🏾‍🤝‍🧑🏼 people holding hands: medium-dark skin tone, medium-light skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FD    ; fully-qualified     # 🧑🏾‍🤝‍🧑🏽 people holding hands: medium-dark skin tone, medium skin tone
+1F9D1 1F3FE 200D 1F91D 200D 1F9D1 1F3FE    ; fully-qualified     # 🧑🏾‍🤝‍🧑🏾 people holding hands: medium-dark skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FB    ; fully-qualified     # 🧑🏿‍🤝‍🧑🏻 people holding hands: dark skin tone, light skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FC    ; fully-qualified     # 🧑🏿‍🤝‍🧑🏼 people holding hands: dark skin tone, medium-light skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FD    ; fully-qualified     # 🧑🏿‍🤝‍🧑🏽 people holding hands: dark skin tone, medium skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FE    ; fully-qualified     # 🧑🏿‍🤝‍🧑🏾 people holding hands: dark skin tone, medium-dark skin tone
+1F9D1 1F3FF 200D 1F91D 200D 1F9D1 1F3FF    ; fully-qualified     # 🧑🏿‍🤝‍🧑🏿 people holding hands: dark skin tone
+1F46D                                      ; fully-qualified     # 👭 women holding hands
+1F46D 1F3FB                                ; fully-qualified     # 👭🏻 women holding hands: light skin tone
+1F469 1F3FC 200D 1F91D 200D 1F469 1F3FB    ; fully-qualified     # 👩🏼‍🤝‍👩🏻 women holding hands: medium-light skin tone, light skin tone
+1F46D 1F3FC                                ; fully-qualified     # 👭🏼 women holding hands: medium-light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FB    ; fully-qualified     # 👩🏽‍🤝‍👩🏻 women holding hands: medium skin tone, light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F469 1F3FC    ; fully-qualified     # 👩🏽‍🤝‍👩🏼 women holding hands: medium skin tone, medium-light skin tone
+1F46D 1F3FD                                ; fully-qualified     # 👭🏽 women holding hands: medium skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FB    ; fully-qualified     # 👩🏾‍🤝‍👩🏻 women holding hands: medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FC    ; fully-qualified     # 👩🏾‍🤝‍👩🏼 women holding hands: medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F469 1F3FD    ; fully-qualified     # 👩🏾‍🤝‍👩🏽 women holding hands: medium-dark skin tone, medium skin tone
+1F46D 1F3FE                                ; fully-qualified     # 👭🏾 women holding hands: medium-dark skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FB    ; fully-qualified     # 👩🏿‍🤝‍👩🏻 women holding hands: dark skin tone, light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FC    ; fully-qualified     # 👩🏿‍🤝‍👩🏼 women holding hands: dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FD    ; fully-qualified     # 👩🏿‍🤝‍👩🏽 women holding hands: dark skin tone, medium skin tone
+1F469 1F3FF 200D 1F91D 200D 1F469 1F3FE    ; fully-qualified     # 👩🏿‍🤝‍👩🏾 women holding hands: dark skin tone, medium-dark skin tone
+1F46D 1F3FF                                ; fully-qualified     # 👭🏿 women holding hands: dark skin tone
+1F46B                                      ; fully-qualified     # 👫 woman and man holding hands
+1F46B 1F3FB                                ; fully-qualified     # 👫🏻 woman and man holding hands: light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👩🏻‍🤝‍👨🏼 woman and man holding hands: light skin tone, medium-light skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FD    ; fully-qualified     # 👩🏻‍🤝‍👨🏽 woman and man holding hands: light skin tone, medium skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FE    ; fully-qualified     # 👩🏻‍🤝‍👨🏾 woman and man holding hands: light skin tone, medium-dark skin tone
+1F469 1F3FB 200D 1F91D 200D 1F468 1F3FF    ; fully-qualified     # 👩🏻‍🤝‍👨🏿 woman and man holding hands: light skin tone, dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👩🏼‍🤝‍👨🏻 woman and man holding hands: medium-light skin tone, light skin tone
+1F46B 1F3FC                                ; fully-qualified     # 👫🏼 woman and man holding hands: medium-light skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FD    ; fully-qualified     # 👩🏼‍🤝‍👨🏽 woman and man holding hands: medium-light skin tone, medium skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FE    ; fully-qualified     # 👩🏼‍🤝‍👨🏾 woman and man holding hands: medium-light skin tone, medium-dark skin tone
+1F469 1F3FC 200D 1F91D 200D 1F468 1F3FF    ; fully-qualified     # 👩🏼‍🤝‍👨🏿 woman and man holding hands: medium-light skin tone, dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👩🏽‍🤝‍👨🏻 woman and man holding hands: medium skin tone, light skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👩🏽‍🤝‍👨🏼 woman and man holding hands: medium skin tone, medium-light skin tone
+1F46B 1F3FD                                ; fully-qualified     # 👫🏽 woman and man holding hands: medium skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FE    ; fully-qualified     # 👩🏽‍🤝‍👨🏾 woman and man holding hands: medium skin tone, medium-dark skin tone
+1F469 1F3FD 200D 1F91D 200D 1F468 1F3FF    ; fully-qualified     # 👩🏽‍🤝‍👨🏿 woman and man holding hands: medium skin tone, dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👩🏾‍🤝‍👨🏻 woman and man holding hands: medium-dark skin tone, light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👩🏾‍🤝‍👨🏼 woman and man holding hands: medium-dark skin tone, medium-light skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FD    ; fully-qualified     # 👩🏾‍🤝‍👨🏽 woman and man holding hands: medium-dark skin tone, medium skin tone
+1F46B 1F3FE                                ; fully-qualified     # 👫🏾 woman and man holding hands: medium-dark skin tone
+1F469 1F3FE 200D 1F91D 200D 1F468 1F3FF    ; fully-qualified     # 👩🏾‍🤝‍👨🏿 woman and man holding hands: medium-dark skin tone, dark skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👩🏿‍🤝‍👨🏻 woman and man holding hands: dark skin tone, light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👩🏿‍🤝‍👨🏼 woman and man holding hands: dark skin tone, medium-light skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FD    ; fully-qualified     # 👩🏿‍🤝‍👨🏽 woman and man holding hands: dark skin tone, medium skin tone
+1F469 1F3FF 200D 1F91D 200D 1F468 1F3FE    ; fully-qualified     # 👩🏿‍🤝‍👨🏾 woman and man holding hands: dark skin tone, medium-dark skin tone
+1F46B 1F3FF                                ; fully-qualified     # 👫🏿 woman and man holding hands: dark skin tone
+1F46C                                      ; fully-qualified     # 👬 men holding hands
+1F46C 1F3FB                                ; fully-qualified     # 👬🏻 men holding hands: light skin tone
+1F468 1F3FC 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👨🏼‍🤝‍👨🏻 men holding hands: medium-light skin tone, light skin tone
+1F46C 1F3FC                                ; fully-qualified     # 👬🏼 men holding hands: medium-light skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👨🏽‍🤝‍👨🏻 men holding hands: medium skin tone, light skin tone
+1F468 1F3FD 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👨🏽‍🤝‍👨🏼 men holding hands: medium skin tone, medium-light skin tone
+1F46C 1F3FD                                ; fully-qualified     # 👬🏽 men holding hands: medium skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👨🏾‍🤝‍👨🏻 men holding hands: medium-dark skin tone, light skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👨🏾‍🤝‍👨🏼 men holding hands: medium-dark skin tone, medium-light skin tone
+1F468 1F3FE 200D 1F91D 200D 1F468 1F3FD    ; fully-qualified     # 👨🏾‍🤝‍👨🏽 men holding hands: medium-dark skin tone, medium skin tone
+1F46C 1F3FE                                ; fully-qualified     # 👬🏾 men holding hands: medium-dark skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FB    ; fully-qualified     # 👨🏿‍🤝‍👨🏻 men holding hands: dark skin tone, light skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FC    ; fully-qualified     # 👨🏿‍🤝‍👨🏼 men holding hands: dark skin tone, medium-light skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FD    ; fully-qualified     # 👨🏿‍🤝‍👨🏽 men holding hands: dark skin tone, medium skin tone
+1F468 1F3FF 200D 1F91D 200D 1F468 1F3FE    ; fully-qualified     # 👨🏿‍🤝‍👨🏾 men holding hands: dark skin tone, medium-dark skin tone
+1F46C 1F3FF                                ; fully-qualified     # 👬🏿 men holding hands: dark skin tone
+1F48F                                      ; fully-qualified     # 💏 kiss
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified     # 👩‍❤️‍💋‍👨 kiss: woman, man
+1F469 200D 2764 200D 1F48B 200D 1F468      ; minimally-qualified # 👩‍❤‍💋‍👨 kiss: woman, man
+1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified     # 👨‍❤️‍💋‍👨 kiss: man, man
+1F468 200D 2764 200D 1F48B 200D 1F468      ; minimally-qualified # 👨‍❤‍💋‍👨 kiss: man, man
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; fully-qualified     # 👩‍❤️‍💋‍👩 kiss: woman, woman
+1F469 200D 2764 200D 1F48B 200D 1F469      ; minimally-qualified # 👩‍❤‍💋‍👩 kiss: woman, woman
+1F491                                      ; fully-qualified     # 💑 couple with heart
+1F469 200D 2764 FE0F 200D 1F468            ; fully-qualified     # 👩‍❤️‍👨 couple with heart: woman, man
+1F469 200D 2764 200D 1F468                 ; minimally-qualified # 👩‍❤‍👨 couple with heart: woman, man
+1F468 200D 2764 FE0F 200D 1F468            ; fully-qualified     # 👨‍❤️‍👨 couple with heart: man, man
+1F468 200D 2764 200D 1F468                 ; minimally-qualified # 👨‍❤‍👨 couple with heart: man, man
+1F469 200D 2764 FE0F 200D 1F469            ; fully-qualified     # 👩‍❤️‍👩 couple with heart: woman, woman
+1F469 200D 2764 200D 1F469                 ; minimally-qualified # 👩‍❤‍👩 couple with heart: woman, woman
+1F46A                                      ; fully-qualified     # 👪 family
+1F468 200D 1F469 200D 1F466                ; fully-qualified     # 👨‍👩‍👦 family: man, woman, boy
+1F468 200D 1F469 200D 1F467                ; fully-qualified     # 👨‍👩‍👧 family: man, woman, girl
+1F468 200D 1F469 200D 1F467 200D 1F466     ; fully-qualified     # 👨‍👩‍👧‍👦 family: man, woman, girl, boy
+1F468 200D 1F469 200D 1F466 200D 1F466     ; fully-qualified     # 👨‍👩‍👦‍👦 family: man, woman, boy, boy
+1F468 200D 1F469 200D 1F467 200D 1F467     ; fully-qualified     # 👨‍👩‍👧‍👧 family: man, woman, girl, girl
+1F468 200D 1F468 200D 1F466                ; fully-qualified     # 👨‍👨‍👦 family: man, man, boy
+1F468 200D 1F468 200D 1F467                ; fully-qualified     # 👨‍👨‍👧 family: man, man, girl
+1F468 200D 1F468 200D 1F467 200D 1F466     ; fully-qualified     # 👨‍👨‍👧‍👦 family: man, man, girl, boy
+1F468 200D 1F468 200D 1F466 200D 1F466     ; fully-qualified     # 👨‍👨‍👦‍👦 family: man, man, boy, boy
+1F468 200D 1F468 200D 1F467 200D 1F467     ; fully-qualified     # 👨‍👨‍👧‍👧 family: man, man, girl, girl
+1F469 200D 1F469 200D 1F466                ; fully-qualified     # 👩‍👩‍👦 family: woman, woman, boy
+1F469 200D 1F469 200D 1F467                ; fully-qualified     # 👩‍👩‍👧 family: woman, woman, girl
+1F469 200D 1F469 200D 1F467 200D 1F466     ; fully-qualified     # 👩‍👩‍👧‍👦 family: woman, woman, girl, boy
+1F469 200D 1F469 200D 1F466 200D 1F466     ; fully-qualified     # 👩‍👩‍👦‍👦 family: woman, woman, boy, boy
+1F469 200D 1F469 200D 1F467 200D 1F467     ; fully-qualified     # 👩‍👩‍👧‍👧 family: woman, woman, girl, girl
+1F468 200D 1F466                           ; fully-qualified     # 👨‍👦 family: man, boy
+1F468 200D 1F466 200D 1F466                ; fully-qualified     # 👨‍👦‍👦 family: man, boy, boy
+1F468 200D 1F467                           ; fully-qualified     # 👨‍👧 family: man, girl
+1F468 200D 1F467 200D 1F466                ; fully-qualified     # 👨‍👧‍👦 family: man, girl, boy
+1F468 200D 1F467 200D 1F467                ; fully-qualified     # 👨‍👧‍👧 family: man, girl, girl
+1F469 200D 1F466                           ; fully-qualified     # 👩‍👦 family: woman, boy
+1F469 200D 1F466 200D 1F466                ; fully-qualified     # 👩‍👦‍👦 family: woman, boy, boy
+1F469 200D 1F467                           ; fully-qualified     # 👩‍👧 family: woman, girl
+1F469 200D 1F467 200D 1F466                ; fully-qualified     # 👩‍👧‍👦 family: woman, girl, boy
+1F469 200D 1F467 200D 1F467                ; fully-qualified     # 👩‍👧‍👧 family: woman, girl, girl
+
+# subgroup: person-symbol
+1F5E3 FE0F                                 ; fully-qualified     # 🗣️ speaking head
+1F5E3                                      ; unqualified         # 🗣 speaking head
+1F464                                      ; fully-qualified     # 👤 bust in silhouette
+1F465                                      ; fully-qualified     # 👥 busts in silhouette
+1F463                                      ; fully-qualified     # 👣 footprints
+
+# People & Body subtotal:              2212
+# People & Body subtotal:              447     w/o modifiers
+
+# group: Component
+
+# subgroup: skin-tone
+1F3FB                                      ; component           # 🏻 light skin tone
+1F3FC                                      ; component           # 🏼 medium-light skin tone
+1F3FD                                      ; component           # 🏽 medium skin tone
+1F3FE                                      ; component           # 🏾 medium-dark skin tone
+1F3FF                                      ; component           # 🏿 dark skin tone
+
+# subgroup: hair-style
+1F9B0                                      ; component           # 🦰 red hair
+1F9B1                                      ; component           # 🦱 curly hair
+1F9B3                                      ; component           # 🦳 white hair
+1F9B2                                      ; component           # 🦲 bald
+
+# Component subtotal:          9
+# Component subtotal:          4       w/o modifiers
+
+# group: Animals & Nature
+
+# subgroup: animal-mammal
+1F435                                      ; fully-qualified     # 🐵 monkey face
+1F412                                      ; fully-qualified     # 🐒 monkey
+1F98D                                      ; fully-qualified     # 🦍 gorilla
+1F9A7                                      ; fully-qualified     # 🦧 orangutan
+1F436                                      ; fully-qualified     # 🐶 dog face
+1F415                                      ; fully-qualified     # 🐕 dog
+1F9AE                                      ; fully-qualified     # 🦮 guide dog
+1F415 200D 1F9BA                           ; fully-qualified     # 🐕‍🦺 service dog
+1F429                                      ; fully-qualified     # 🐩 poodle
+1F43A                                      ; fully-qualified     # 🐺 wolf
+1F98A                                      ; fully-qualified     # 🦊 fox
+1F99D                                      ; fully-qualified     # 🦝 raccoon
+1F431                                      ; fully-qualified     # 🐱 cat face
+1F408                                      ; fully-qualified     # 🐈 cat
+1F981                                      ; fully-qualified     # 🦁 lion
+1F42F                                      ; fully-qualified     # 🐯 tiger face
+1F405                                      ; fully-qualified     # 🐅 tiger
+1F406                                      ; fully-qualified     # 🐆 leopard
+1F434                                      ; fully-qualified     # 🐴 horse face
+1F40E                                      ; fully-qualified     # 🐎 horse
+1F984                                      ; fully-qualified     # 🦄 unicorn
+1F993                                      ; fully-qualified     # 🦓 zebra
+1F98C                                      ; fully-qualified     # 🦌 deer
+1F42E                                      ; fully-qualified     # 🐮 cow face
+1F402                                      ; fully-qualified     # 🐂 ox
+1F403                                      ; fully-qualified     # 🐃 water buffalo
+1F404                                      ; fully-qualified     # 🐄 cow
+1F437                                      ; fully-qualified     # 🐷 pig face
+1F416                                      ; fully-qualified     # 🐖 pig
+1F417                                      ; fully-qualified     # 🐗 boar
+1F43D                                      ; fully-qualified     # 🐽 pig nose
+1F40F                                      ; fully-qualified     # 🐏 ram
+1F411                                      ; fully-qualified     # 🐑 ewe
+1F410                                      ; fully-qualified     # 🐐 goat
+1F42A                                      ; fully-qualified     # 🐪 camel
+1F42B                                      ; fully-qualified     # 🐫 two-hump camel
+1F999                                      ; fully-qualified     # 🦙 llama
+1F992                                      ; fully-qualified     # 🦒 giraffe
+1F418                                      ; fully-qualified     # 🐘 elephant
+1F98F                                      ; fully-qualified     # 🦏 rhinoceros
+1F99B                                      ; fully-qualified     # 🦛 hippopotamus
+1F42D                                      ; fully-qualified     # 🐭 mouse face
+1F401                                      ; fully-qualified     # 🐁 mouse
+1F400                                      ; fully-qualified     # 🐀 rat
+1F439                                      ; fully-qualified     # 🐹 hamster
+1F430                                      ; fully-qualified     # 🐰 rabbit face
+1F407                                      ; fully-qualified     # 🐇 rabbit
+1F43F FE0F                                 ; fully-qualified     # 🐿️ chipmunk
+1F43F                                      ; unqualified         # 🐿 chipmunk
+1F994                                      ; fully-qualified     # 🦔 hedgehog
+1F987                                      ; fully-qualified     # 🦇 bat
+1F43B                                      ; fully-qualified     # 🐻 bear
+1F428                                      ; fully-qualified     # 🐨 koala
+1F43C                                      ; fully-qualified     # 🐼 panda
+1F9A5                                      ; fully-qualified     # 🦥 sloth
+1F9A6                                      ; fully-qualified     # 🦦 otter
+1F9A8                                      ; fully-qualified     # 🦨 skunk
+1F998                                      ; fully-qualified     # 🦘 kangaroo
+1F9A1                                      ; fully-qualified     # 🦡 badger
+1F43E                                      ; fully-qualified     # 🐾 paw prints
+
+# subgroup: animal-bird
+1F983                                      ; fully-qualified     # 🦃 turkey
+1F414                                      ; fully-qualified     # 🐔 chicken
+1F413                                      ; fully-qualified     # 🐓 rooster
+1F423                                      ; fully-qualified     # 🐣 hatching chick
+1F424                                      ; fully-qualified     # 🐤 baby chick
+1F425                                      ; fully-qualified     # 🐥 front-facing baby chick
+1F426                                      ; fully-qualified     # 🐦 bird
+1F427                                      ; fully-qualified     # 🐧 penguin
+1F54A FE0F                                 ; fully-qualified     # 🕊️ dove
+1F54A                                      ; unqualified         # 🕊 dove
+1F985                                      ; fully-qualified     # 🦅 eagle
+1F986                                      ; fully-qualified     # 🦆 duck
+1F9A2                                      ; fully-qualified     # 🦢 swan
+1F989                                      ; fully-qualified     # 🦉 owl
+1F9A9                                      ; fully-qualified     # 🦩 flamingo
+1F99A                                      ; fully-qualified     # 🦚 peacock
+1F99C                                      ; fully-qualified     # 🦜 parrot
+
+# subgroup: animal-amphibian
+1F438                                      ; fully-qualified     # 🐸 frog
+
+# subgroup: animal-reptile
+1F40A                                      ; fully-qualified     # 🐊 crocodile
+1F422                                      ; fully-qualified     # 🐢 turtle
+1F98E                                      ; fully-qualified     # 🦎 lizard
+1F40D                                      ; fully-qualified     # 🐍 snake
+1F432                                      ; fully-qualified     # 🐲 dragon face
+1F409                                      ; fully-qualified     # 🐉 dragon
+1F995                                      ; fully-qualified     # 🦕 sauropod
+1F996                                      ; fully-qualified     # 🦖 T-Rex
+
+# subgroup: animal-marine
+1F433                                      ; fully-qualified     # 🐳 spouting whale
+1F40B                                      ; fully-qualified     # 🐋 whale
+1F42C                                      ; fully-qualified     # 🐬 dolphin
+1F41F                                      ; fully-qualified     # 🐟 fish
+1F420                                      ; fully-qualified     # 🐠 tropical fish
+1F421                                      ; fully-qualified     # 🐡 blowfish
+1F988                                      ; fully-qualified     # 🦈 shark
+1F419                                      ; fully-qualified     # 🐙 octopus
+1F41A                                      ; fully-qualified     # 🐚 spiral shell
+
+# subgroup: animal-bug
+1F40C                                      ; fully-qualified     # 🐌 snail
+1F98B                                      ; fully-qualified     # 🦋 butterfly
+1F41B                                      ; fully-qualified     # 🐛 bug
+1F41C                                      ; fully-qualified     # 🐜 ant
+1F41D                                      ; fully-qualified     # 🐝 honeybee
+1F41E                                      ; fully-qualified     # 🐞 lady beetle
+1F997                                      ; fully-qualified     # 🦗 cricket
+1F577 FE0F                                 ; fully-qualified     # 🕷️ spider
+1F577                                      ; unqualified         # 🕷 spider
+1F578 FE0F                                 ; fully-qualified     # 🕸️ spider web
+1F578                                      ; unqualified         # 🕸 spider web
+1F982                                      ; fully-qualified     # 🦂 scorpion
+1F99F                                      ; fully-qualified     # 🦟 mosquito
+1F9A0                                      ; fully-qualified     # 🦠 microbe
+
+# subgroup: plant-flower
+1F490                                      ; fully-qualified     # 💐 bouquet
+1F338                                      ; fully-qualified     # 🌸 cherry blossom
+1F4AE                                      ; fully-qualified     # 💮 white flower
+1F3F5 FE0F                                 ; fully-qualified     # 🏵️ rosette
+1F3F5                                      ; unqualified         # 🏵 rosette
+1F339                                      ; fully-qualified     # 🌹 rose
+1F940                                      ; fully-qualified     # 🥀 wilted flower
+1F33A                                      ; fully-qualified     # 🌺 hibiscus
+1F33B                                      ; fully-qualified     # 🌻 sunflower
+1F33C                                      ; fully-qualified     # 🌼 blossom
+1F337                                      ; fully-qualified     # 🌷 tulip
+
+# subgroup: plant-other
+1F331                                      ; fully-qualified     # 🌱 seedling
+1F332                                      ; fully-qualified     # 🌲 evergreen tree
+1F333                                      ; fully-qualified     # 🌳 deciduous tree
+1F334                                      ; fully-qualified     # 🌴 palm tree
+1F335                                      ; fully-qualified     # 🌵 cactus
+1F33E                                      ; fully-qualified     # 🌾 sheaf of rice
+1F33F                                      ; fully-qualified     # 🌿 herb
+2618 FE0F                                  ; fully-qualified     # ☘️ shamrock
+2618                                       ; unqualified         # ☘ shamrock
+1F340                                      ; fully-qualified     # 🍀 four leaf clover
+1F341                                      ; fully-qualified     # 🍁 maple leaf
+1F342                                      ; fully-qualified     # 🍂 fallen leaf
+1F343                                      ; fully-qualified     # 🍃 leaf fluttering in wind
+
+# Animals & Nature subtotal:           133
+# Animals & Nature subtotal:           133     w/o modifiers
+
+# group: Food & Drink
+
+# subgroup: food-fruit
+1F347                                      ; fully-qualified     # 🍇 grapes
+1F348                                      ; fully-qualified     # 🍈 melon
+1F349                                      ; fully-qualified     # 🍉 watermelon
+1F34A                                      ; fully-qualified     # 🍊 tangerine
+1F34B                                      ; fully-qualified     # 🍋 lemon
+1F34C                                      ; fully-qualified     # 🍌 banana
+1F34D                                      ; fully-qualified     # 🍍 pineapple
+1F96D                                      ; fully-qualified     # 🥭 mango
+1F34E                                      ; fully-qualified     # 🍎 red apple
+1F34F                                      ; fully-qualified     # 🍏 green apple
+1F350                                      ; fully-qualified     # 🍐 pear
+1F351                                      ; fully-qualified     # 🍑 peach
+1F352                                      ; fully-qualified     # 🍒 cherries
+1F353                                      ; fully-qualified     # 🍓 strawberry
+1F95D                                      ; fully-qualified     # 🥝 kiwi fruit
+1F345                                      ; fully-qualified     # 🍅 tomato
+1F965                                      ; fully-qualified     # 🥥 coconut
+
+# subgroup: food-vegetable
+1F951                                      ; fully-qualified     # 🥑 avocado
+1F346                                      ; fully-qualified     # 🍆 eggplant
+1F954                                      ; fully-qualified     # 🥔 potato
+1F955                                      ; fully-qualified     # 🥕 carrot
+1F33D                                      ; fully-qualified     # 🌽 ear of corn
+1F336 FE0F                                 ; fully-qualified     # 🌶️ hot pepper
+1F336                                      ; unqualified         # 🌶 hot pepper
+1F952                                      ; fully-qualified     # 🥒 cucumber
+1F96C                                      ; fully-qualified     # 🥬 leafy green
+1F966                                      ; fully-qualified     # 🥦 broccoli
+1F9C4                                      ; fully-qualified     # 🧄 garlic
+1F9C5                                      ; fully-qualified     # 🧅 onion
+1F344                                      ; fully-qualified     # 🍄 mushroom
+1F95C                                      ; fully-qualified     # 🥜 peanuts
+1F330                                      ; fully-qualified     # 🌰 chestnut
+
+# subgroup: food-prepared
+1F35E                                      ; fully-qualified     # 🍞 bread
+1F950                                      ; fully-qualified     # 🥐 croissant
+1F956                                      ; fully-qualified     # 🥖 baguette bread
+1F968                                      ; fully-qualified     # 🥨 pretzel
+1F96F                                      ; fully-qualified     # 🥯 bagel
+1F95E                                      ; fully-qualified     # 🥞 pancakes
+1F9C7                                      ; fully-qualified     # 🧇 waffle
+1F9C0                                      ; fully-qualified     # 🧀 cheese wedge
+1F356                                      ; fully-qualified     # 🍖 meat on bone
+1F357                                      ; fully-qualified     # 🍗 poultry leg
+1F969                                      ; fully-qualified     # 🥩 cut of meat
+1F953                                      ; fully-qualified     # 🥓 bacon
+1F354                                      ; fully-qualified     # 🍔 hamburger
+1F35F                                      ; fully-qualified     # 🍟 french fries
+1F355                                      ; fully-qualified     # 🍕 pizza
+1F32D                                      ; fully-qualified     # 🌭 hot dog
+1F96A                                      ; fully-qualified     # 🥪 sandwich
+1F32E                                      ; fully-qualified     # 🌮 taco
+1F32F                                      ; fully-qualified     # 🌯 burrito
+1F959                                      ; fully-qualified     # 🥙 stuffed flatbread
+1F9C6                                      ; fully-qualified     # 🧆 falafel
+1F95A                                      ; fully-qualified     # 🥚 egg
+1F373                                      ; fully-qualified     # 🍳 cooking
+1F958                                      ; fully-qualified     # 🥘 shallow pan of food
+1F372                                      ; fully-qualified     # 🍲 pot of food
+1F963                                      ; fully-qualified     # 🥣 bowl with spoon
+1F957                                      ; fully-qualified     # 🥗 green salad
+1F37F                                      ; fully-qualified     # 🍿 popcorn
+1F9C8                                      ; fully-qualified     # 🧈 butter
+1F9C2                                      ; fully-qualified     # 🧂 salt
+1F96B                                      ; fully-qualified     # 🥫 canned food
+
+# subgroup: food-asian
+1F371                                      ; fully-qualified     # 🍱 bento box
+1F358                                      ; fully-qualified     # 🍘 rice cracker
+1F359                                      ; fully-qualified     # 🍙 rice ball
+1F35A                                      ; fully-qualified     # 🍚 cooked rice
+1F35B                                      ; fully-qualified     # 🍛 curry rice
+1F35C                                      ; fully-qualified     # 🍜 steaming bowl
+1F35D                                      ; fully-qualified     # 🍝 spaghetti
+1F360                                      ; fully-qualified     # 🍠 roasted sweet potato
+1F362                                      ; fully-qualified     # 🍢 oden
+1F363                                      ; fully-qualified     # 🍣 sushi
+1F364                                      ; fully-qualified     # 🍤 fried shrimp
+1F365                                      ; fully-qualified     # 🍥 fish cake with swirl
+1F96E                                      ; fully-qualified     # 🥮 moon cake
+1F361                                      ; fully-qualified     # 🍡 dango
+1F95F                                      ; fully-qualified     # 🥟 dumpling
+1F960                                      ; fully-qualified     # 🥠 fortune cookie
+1F961                                      ; fully-qualified     # 🥡 takeout box
+
+# subgroup: food-marine
+1F980                                      ; fully-qualified     # 🦀 crab
+1F99E                                      ; fully-qualified     # 🦞 lobster
+1F990                                      ; fully-qualified     # 🦐 shrimp
+1F991                                      ; fully-qualified     # 🦑 squid
+1F9AA                                      ; fully-qualified     # 🦪 oyster
+
+# subgroup: food-sweet
+1F366                                      ; fully-qualified     # 🍦 soft ice cream
+1F367                                      ; fully-qualified     # 🍧 shaved ice
+1F368                                      ; fully-qualified     # 🍨 ice cream
+1F369                                      ; fully-qualified     # 🍩 doughnut
+1F36A                                      ; fully-qualified     # 🍪 cookie
+1F382                                      ; fully-qualified     # 🎂 birthday cake
+1F370                                      ; fully-qualified     # 🍰 shortcake
+1F9C1                                      ; fully-qualified     # 🧁 cupcake
+1F967                                      ; fully-qualified     # 🥧 pie
+1F36B                                      ; fully-qualified     # 🍫 chocolate bar
+1F36C                                      ; fully-qualified     # 🍬 candy
+1F36D                                      ; fully-qualified     # 🍭 lollipop
+1F36E                                      ; fully-qualified     # 🍮 custard
+1F36F                                      ; fully-qualified     # 🍯 honey pot
+
+# subgroup: drink
+1F37C                                      ; fully-qualified     # 🍼 baby bottle
+1F95B                                      ; fully-qualified     # 🥛 glass of milk
+2615                                       ; fully-qualified     # ☕ hot beverage
+1F375                                      ; fully-qualified     # 🍵 teacup without handle
+1F376                                      ; fully-qualified     # 🍶 sake
+1F37E                                      ; fully-qualified     # 🍾 bottle with popping cork
+1F377                                      ; fully-qualified     # 🍷 wine glass
+1F378                                      ; fully-qualified     # 🍸 cocktail glass
+1F379                                      ; fully-qualified     # 🍹 tropical drink
+1F37A                                      ; fully-qualified     # 🍺 beer mug
+1F37B                                      ; fully-qualified     # 🍻 clinking beer mugs
+1F942                                      ; fully-qualified     # 🥂 clinking glasses
+1F943                                      ; fully-qualified     # 🥃 tumbler glass
+1F964                                      ; fully-qualified     # 🥤 cup with straw
+1F9C3                                      ; fully-qualified     # 🧃 beverage box
+1F9C9                                      ; fully-qualified     # 🧉 mate
+1F9CA                                      ; fully-qualified     # 🧊 ice cube
+
+# subgroup: dishware
+1F962                                      ; fully-qualified     # 🥢 chopsticks
+1F37D FE0F                                 ; fully-qualified     # 🍽️ fork and knife with plate
+1F37D                                      ; unqualified         # 🍽 fork and knife with plate
+1F374                                      ; fully-qualified     # 🍴 fork and knife
+1F944                                      ; fully-qualified     # 🥄 spoon
+1F52A                                      ; fully-qualified     # 🔪 kitchen knife
+1F3FA                                      ; fully-qualified     # 🏺 amphora
+
+# Food & Drink subtotal:               123
+# Food & Drink subtotal:               123     w/o modifiers
+
+# group: Travel & Places
+
+# subgroup: place-map
+1F30D                                      ; fully-qualified     # 🌍 globe showing Europe-Africa
+1F30E                                      ; fully-qualified     # 🌎 globe showing Americas
+1F30F                                      ; fully-qualified     # 🌏 globe showing Asia-Australia
+1F310                                      ; fully-qualified     # 🌐 globe with meridians
+1F5FA FE0F                                 ; fully-qualified     # 🗺️ world map
+1F5FA                                      ; unqualified         # 🗺 world map
+1F5FE                                      ; fully-qualified     # 🗾 map of Japan
+1F9ED                                      ; fully-qualified     # 🧭 compass
+
+# subgroup: place-geographic
+1F3D4 FE0F                                 ; fully-qualified     # 🏔️ snow-capped mountain
+1F3D4                                      ; unqualified         # 🏔 snow-capped mountain
+26F0 FE0F                                  ; fully-qualified     # ⛰️ mountain
+26F0                                       ; unqualified         # ⛰ mountain
+1F30B                                      ; fully-qualified     # 🌋 volcano
+1F5FB                                      ; fully-qualified     # 🗻 mount fuji
+1F3D5 FE0F                                 ; fully-qualified     # 🏕️ camping
+1F3D5                                      ; unqualified         # 🏕 camping
+1F3D6 FE0F                                 ; fully-qualified     # 🏖️ beach with umbrella
+1F3D6                                      ; unqualified         # 🏖 beach with umbrella
+1F3DC FE0F                                 ; fully-qualified     # 🏜️ desert
+1F3DC                                      ; unqualified         # 🏜 desert
+1F3DD FE0F                                 ; fully-qualified     # 🏝️ desert island
+1F3DD                                      ; unqualified         # 🏝 desert island
+1F3DE FE0F                                 ; fully-qualified     # 🏞️ national park
+1F3DE                                      ; unqualified         # 🏞 national park
+
+# subgroup: place-building
+1F3DF FE0F                                 ; fully-qualified     # 🏟️ stadium
+1F3DF                                      ; unqualified         # 🏟 stadium
+1F3DB FE0F                                 ; fully-qualified     # 🏛️ classical building
+1F3DB                                      ; unqualified         # 🏛 classical building
+1F3D7 FE0F                                 ; fully-qualified     # 🏗️ building construction
+1F3D7                                      ; unqualified         # 🏗 building construction
+1F9F1                                      ; fully-qualified     # 🧱 brick
+1F3D8 FE0F                                 ; fully-qualified     # 🏘️ houses
+1F3D8                                      ; unqualified         # 🏘 houses
+1F3DA FE0F                                 ; fully-qualified     # 🏚️ derelict house
+1F3DA                                      ; unqualified         # 🏚 derelict house
+1F3E0                                      ; fully-qualified     # 🏠 house
+1F3E1                                      ; fully-qualified     # 🏡 house with garden
+1F3E2                                      ; fully-qualified     # 🏢 office building
+1F3E3                                      ; fully-qualified     # 🏣 Japanese post office
+1F3E4                                      ; fully-qualified     # 🏤 post office
+1F3E5                                      ; fully-qualified     # 🏥 hospital
+1F3E6                                      ; fully-qualified     # 🏦 bank
+1F3E8                                      ; fully-qualified     # 🏨 hotel
+1F3E9                                      ; fully-qualified     # 🏩 love hotel
+1F3EA                                      ; fully-qualified     # 🏪 convenience store
+1F3EB                                      ; fully-qualified     # 🏫 school
+1F3EC                                      ; fully-qualified     # 🏬 department store
+1F3ED                                      ; fully-qualified     # 🏭 factory
+1F3EF                                      ; fully-qualified     # 🏯 Japanese castle
+1F3F0                                      ; fully-qualified     # 🏰 castle
+1F492                                      ; fully-qualified     # 💒 wedding
+1F5FC                                      ; fully-qualified     # 🗼 Tokyo tower
+1F5FD                                      ; fully-qualified     # 🗽 Statue of Liberty
+
+# subgroup: place-religious
+26EA                                       ; fully-qualified     # ⛪ church
+1F54C                                      ; fully-qualified     # 🕌 mosque
+1F6D5                                      ; fully-qualified     # 🛕 hindu temple
+1F54D                                      ; fully-qualified     # 🕍 synagogue
+26E9 FE0F                                  ; fully-qualified     # ⛩️ shinto shrine
+26E9                                       ; unqualified         # ⛩ shinto shrine
+1F54B                                      ; fully-qualified     # 🕋 kaaba
+
+# subgroup: place-other
+26F2                                       ; fully-qualified     # ⛲ fountain
+26FA                                       ; fully-qualified     # ⛺ tent
+1F301                                      ; fully-qualified     # 🌁 foggy
+1F303                                      ; fully-qualified     # 🌃 night with stars
+1F3D9 FE0F                                 ; fully-qualified     # 🏙️ cityscape
+1F3D9                                      ; unqualified         # 🏙 cityscape
+1F304                                      ; fully-qualified     # 🌄 sunrise over mountains
+1F305                                      ; fully-qualified     # 🌅 sunrise
+1F306                                      ; fully-qualified     # 🌆 cityscape at dusk
+1F307                                      ; fully-qualified     # 🌇 sunset
+1F309                                      ; fully-qualified     # 🌉 bridge at night
+2668 FE0F                                  ; fully-qualified     # ♨️ hot springs
+2668                                       ; unqualified         # ♨ hot springs
+1F3A0                                      ; fully-qualified     # 🎠 carousel horse
+1F3A1                                      ; fully-qualified     # 🎡 ferris wheel
+1F3A2                                      ; fully-qualified     # 🎢 roller coaster
+1F488                                      ; fully-qualified     # 💈 barber pole
+1F3AA                                      ; fully-qualified     # 🎪 circus tent
+
+# subgroup: transport-ground
+1F682                                      ; fully-qualified     # 🚂 locomotive
+1F683                                      ; fully-qualified     # 🚃 railway car
+1F684                                      ; fully-qualified     # 🚄 high-speed train
+1F685                                      ; fully-qualified     # 🚅 bullet train
+1F686                                      ; fully-qualified     # 🚆 train
+1F687                                      ; fully-qualified     # 🚇 metro
+1F688                                      ; fully-qualified     # 🚈 light rail
+1F689                                      ; fully-qualified     # 🚉 station
+1F68A                                      ; fully-qualified     # 🚊 tram
+1F69D                                      ; fully-qualified     # 🚝 monorail
+1F69E                                      ; fully-qualified     # 🚞 mountain railway
+1F68B                                      ; fully-qualified     # 🚋 tram car
+1F68C                                      ; fully-qualified     # 🚌 bus
+1F68D                                      ; fully-qualified     # 🚍 oncoming bus
+1F68E                                      ; fully-qualified     # 🚎 trolleybus
+1F690                                      ; fully-qualified     # 🚐 minibus
+1F691                                      ; fully-qualified     # 🚑 ambulance
+1F692                                      ; fully-qualified     # 🚒 fire engine
+1F693                                      ; fully-qualified     # 🚓 police car
+1F694                                      ; fully-qualified     # 🚔 oncoming police car
+1F695                                      ; fully-qualified     # 🚕 taxi
+1F696                                      ; fully-qualified     # 🚖 oncoming taxi
+1F697                                      ; fully-qualified     # 🚗 automobile
+1F698                                      ; fully-qualified     # 🚘 oncoming automobile
+1F699                                      ; fully-qualified     # 🚙 sport utility vehicle
+1F69A                                      ; fully-qualified     # 🚚 delivery truck
+1F69B                                      ; fully-qualified     # 🚛 articulated lorry
+1F69C                                      ; fully-qualified     # 🚜 tractor
+1F3CE FE0F                                 ; fully-qualified     # 🏎️ racing car
+1F3CE                                      ; unqualified         # 🏎 racing car
+1F3CD FE0F                                 ; fully-qualified     # 🏍️ motorcycle
+1F3CD                                      ; unqualified         # 🏍 motorcycle
+1F6F5                                      ; fully-qualified     # 🛵 motor scooter
+1F9BD                                      ; fully-qualified     # 🦽 manual wheelchair
+1F9BC                                      ; fully-qualified     # 🦼 motorized wheelchair
+1F6FA                                      ; fully-qualified     # 🛺 auto rickshaw
+1F6B2                                      ; fully-qualified     # 🚲 bicycle
+1F6F4                                      ; fully-qualified     # 🛴 kick scooter
+1F6F9                                      ; fully-qualified     # 🛹 skateboard
+1F68F                                      ; fully-qualified     # 🚏 bus stop
+1F6E3 FE0F                                 ; fully-qualified     # 🛣️ motorway
+1F6E3                                      ; unqualified         # 🛣 motorway
+1F6E4 FE0F                                 ; fully-qualified     # 🛤️ railway track
+1F6E4                                      ; unqualified         # 🛤 railway track
+1F6E2 FE0F                                 ; fully-qualified     # 🛢️ oil drum
+1F6E2                                      ; unqualified         # 🛢 oil drum
+26FD                                       ; fully-qualified     # ⛽ fuel pump
+1F6A8                                      ; fully-qualified     # 🚨 police car light
+1F6A5                                      ; fully-qualified     # 🚥 horizontal traffic light
+1F6A6                                      ; fully-qualified     # 🚦 vertical traffic light
+1F6D1                                      ; fully-qualified     # 🛑 stop sign
+1F6A7                                      ; fully-qualified     # 🚧 construction
+
+# subgroup: transport-water
+2693                                       ; fully-qualified     # ⚓ anchor
+26F5                                       ; fully-qualified     # ⛵ sailboat
+1F6F6                                      ; fully-qualified     # 🛶 canoe
+1F6A4                                      ; fully-qualified     # 🚤 speedboat
+1F6F3 FE0F                                 ; fully-qualified     # 🛳️ passenger ship
+1F6F3                                      ; unqualified         # 🛳 passenger ship
+26F4 FE0F                                  ; fully-qualified     # ⛴️ ferry
+26F4                                       ; unqualified         # ⛴ ferry
+1F6E5 FE0F                                 ; fully-qualified     # 🛥️ motor boat
+1F6E5                                      ; unqualified         # 🛥 motor boat
+1F6A2                                      ; fully-qualified     # 🚢 ship
+
+# subgroup: transport-air
+2708 FE0F                                  ; fully-qualified     # ✈️ airplane
+2708                                       ; unqualified         # ✈ airplane
+1F6E9 FE0F                                 ; fully-qualified     # 🛩️ small airplane
+1F6E9                                      ; unqualified         # 🛩 small airplane
+1F6EB                                      ; fully-qualified     # 🛫 airplane departure
+1F6EC                                      ; fully-qualified     # 🛬 airplane arrival
+1FA82                                      ; fully-qualified     # 🪂 parachute
+1F4BA                                      ; fully-qualified     # 💺 seat
+1F681                                      ; fully-qualified     # 🚁 helicopter
+1F69F                                      ; fully-qualified     # 🚟 suspension railway
+1F6A0                                      ; fully-qualified     # 🚠 mountain cableway
+1F6A1                                      ; fully-qualified     # 🚡 aerial tramway
+1F6F0 FE0F                                 ; fully-qualified     # 🛰️ satellite
+1F6F0                                      ; unqualified         # 🛰 satellite
+1F680                                      ; fully-qualified     # 🚀 rocket
+1F6F8                                      ; fully-qualified     # 🛸 flying saucer
+
+# subgroup: hotel
+1F6CE FE0F                                 ; fully-qualified     # 🛎️ bellhop bell
+1F6CE                                      ; unqualified         # 🛎 bellhop bell
+1F9F3                                      ; fully-qualified     # 🧳 luggage
+
+# subgroup: time
+231B                                       ; fully-qualified     # ⌛ hourglass done
+23F3                                       ; fully-qualified     # ⏳ hourglass not done
+231A                                       ; fully-qualified     # ⌚ watch
+23F0                                       ; fully-qualified     # ⏰ alarm clock
+23F1 FE0F                                  ; fully-qualified     # ⏱️ stopwatch
+23F1                                       ; unqualified         # ⏱ stopwatch
+23F2 FE0F                                  ; fully-qualified     # ⏲️ timer clock
+23F2                                       ; unqualified         # ⏲ timer clock
+1F570 FE0F                                 ; fully-qualified     # 🕰️ mantelpiece clock
+1F570                                      ; unqualified         # 🕰 mantelpiece clock
+1F55B                                      ; fully-qualified     # 🕛 twelve o’clock
+1F567                                      ; fully-qualified     # 🕧 twelve-thirty
+1F550                                      ; fully-qualified     # 🕐 one o’clock
+1F55C                                      ; fully-qualified     # 🕜 one-thirty
+1F551                                      ; fully-qualified     # 🕑 two o’clock
+1F55D                                      ; fully-qualified     # 🕝 two-thirty
+1F552                                      ; fully-qualified     # 🕒 three o’clock
+1F55E                                      ; fully-qualified     # 🕞 three-thirty
+1F553                                      ; fully-qualified     # 🕓 four o’clock
+1F55F                                      ; fully-qualified     # 🕟 four-thirty
+1F554                                      ; fully-qualified     # 🕔 five o’clock
+1F560                                      ; fully-qualified     # 🕠 five-thirty
+1F555                                      ; fully-qualified     # 🕕 six o’clock
+1F561                                      ; fully-qualified     # 🕡 six-thirty
+1F556                                      ; fully-qualified     # 🕖 seven o’clock
+1F562                                      ; fully-qualified     # 🕢 seven-thirty
+1F557                                      ; fully-qualified     # 🕗 eight o’clock
+1F563                                      ; fully-qualified     # 🕣 eight-thirty
+1F558                                      ; fully-qualified     # 🕘 nine o’clock
+1F564                                      ; fully-qualified     # 🕤 nine-thirty
+1F559                                      ; fully-qualified     # 🕙 ten o’clock
+1F565                                      ; fully-qualified     # 🕥 ten-thirty
+1F55A                                      ; fully-qualified     # 🕚 eleven o’clock
+1F566                                      ; fully-qualified     # 🕦 eleven-thirty
+
+# subgroup: sky & weather
+1F311                                      ; fully-qualified     # 🌑 new moon
+1F312                                      ; fully-qualified     # 🌒 waxing crescent moon
+1F313                                      ; fully-qualified     # 🌓 first quarter moon
+1F314                                      ; fully-qualified     # 🌔 waxing gibbous moon
+1F315                                      ; fully-qualified     # 🌕 full moon
+1F316                                      ; fully-qualified     # 🌖 waning gibbous moon
+1F317                                      ; fully-qualified     # 🌗 last quarter moon
+1F318                                      ; fully-qualified     # 🌘 waning crescent moon
+1F319                                      ; fully-qualified     # 🌙 crescent moon
+1F31A                                      ; fully-qualified     # 🌚 new moon face
+1F31B                                      ; fully-qualified     # 🌛 first quarter moon face
+1F31C                                      ; fully-qualified     # 🌜 last quarter moon face
+1F321 FE0F                                 ; fully-qualified     # 🌡️ thermometer
+1F321                                      ; unqualified         # 🌡 thermometer
+2600 FE0F                                  ; fully-qualified     # ☀️ sun
+2600                                       ; unqualified         # ☀ sun
+1F31D                                      ; fully-qualified     # 🌝 full moon face
+1F31E                                      ; fully-qualified     # 🌞 sun with face
+1FA90                                      ; fully-qualified     # 🪐 ringed planet
+2B50                                       ; fully-qualified     # ⭐ star
+1F31F                                      ; fully-qualified     # 🌟 glowing star
+1F320                                      ; fully-qualified     # 🌠 shooting star
+1F30C                                      ; fully-qualified     # 🌌 milky way
+2601 FE0F                                  ; fully-qualified     # ☁️ cloud
+2601                                       ; unqualified         # ☁ cloud
+26C5                                       ; fully-qualified     # ⛅ sun behind cloud
+26C8 FE0F                                  ; fully-qualified     # ⛈️ cloud with lightning and rain
+26C8                                       ; unqualified         # ⛈ cloud with lightning and rain
+1F324 FE0F                                 ; fully-qualified     # 🌤️ sun behind small cloud
+1F324                                      ; unqualified         # 🌤 sun behind small cloud
+1F325 FE0F                                 ; fully-qualified     # 🌥️ sun behind large cloud
+1F325                                      ; unqualified         # 🌥 sun behind large cloud
+1F326 FE0F                                 ; fully-qualified     # 🌦️ sun behind rain cloud
+1F326                                      ; unqualified         # 🌦 sun behind rain cloud
+1F327 FE0F                                 ; fully-qualified     # 🌧️ cloud with rain
+1F327                                      ; unqualified         # 🌧 cloud with rain
+1F328 FE0F                                 ; fully-qualified     # 🌨️ cloud with snow
+1F328                                      ; unqualified         # 🌨 cloud with snow
+1F329 FE0F                                 ; fully-qualified     # 🌩️ cloud with lightning
+1F329                                      ; unqualified         # 🌩 cloud with lightning
+1F32A FE0F                                 ; fully-qualified     # 🌪️ tornado
+1F32A                                      ; unqualified         # 🌪 tornado
+1F32B FE0F                                 ; fully-qualified     # 🌫️ fog
+1F32B                                      ; unqualified         # 🌫 fog
+1F32C FE0F                                 ; fully-qualified     # 🌬️ wind face
+1F32C                                      ; unqualified         # 🌬 wind face
+1F300                                      ; fully-qualified     # 🌀 cyclone
+1F308                                      ; fully-qualified     # 🌈 rainbow
+1F302                                      ; fully-qualified     # 🌂 closed umbrella
+2602 FE0F                                  ; fully-qualified     # ☂️ umbrella
+2602                                       ; unqualified         # ☂ umbrella
+2614                                       ; fully-qualified     # ☔ umbrella with rain drops
+26F1 FE0F                                  ; fully-qualified     # ⛱️ umbrella on ground
+26F1                                       ; unqualified         # ⛱ umbrella on ground
+26A1                                       ; fully-qualified     # ⚡ high voltage
+2744 FE0F                                  ; fully-qualified     # ❄️ snowflake
+2744                                       ; unqualified         # ❄ snowflake
+2603 FE0F                                  ; fully-qualified     # ☃️ snowman
+2603                                       ; unqualified         # ☃ snowman
+26C4                                       ; fully-qualified     # ⛄ snowman without snow
+2604 FE0F                                  ; fully-qualified     # ☄️ comet
+2604                                       ; unqualified         # ☄ comet
+1F525                                      ; fully-qualified     # 🔥 fire
+1F4A7                                      ; fully-qualified     # 💧 droplet
+1F30A                                      ; fully-qualified     # 🌊 water wave
+
+# Travel & Places subtotal:            259
+# Travel & Places subtotal:            259     w/o modifiers
+
+# group: Activities
+
+# subgroup: event
+1F383                                      ; fully-qualified     # 🎃 jack-o-lantern
+1F384                                      ; fully-qualified     # 🎄 Christmas tree
+1F386                                      ; fully-qualified     # 🎆 fireworks
+1F387                                      ; fully-qualified     # 🎇 sparkler
+1F9E8                                      ; fully-qualified     # 🧨 firecracker
+2728                                       ; fully-qualified     # ✨ sparkles
+1F388                                      ; fully-qualified     # 🎈 balloon
+1F389                                      ; fully-qualified     # 🎉 party popper
+1F38A                                      ; fully-qualified     # 🎊 confetti ball
+1F38B                                      ; fully-qualified     # 🎋 tanabata tree
+1F38D                                      ; fully-qualified     # 🎍 pine decoration
+1F38E                                      ; fully-qualified     # 🎎 Japanese dolls
+1F38F                                      ; fully-qualified     # 🎏 carp streamer
+1F390                                      ; fully-qualified     # 🎐 wind chime
+1F391                                      ; fully-qualified     # 🎑 moon viewing ceremony
+1F9E7                                      ; fully-qualified     # 🧧 red envelope
+1F380                                      ; fully-qualified     # 🎀 ribbon
+1F381                                      ; fully-qualified     # 🎁 wrapped gift
+1F397 FE0F                                 ; fully-qualified     # 🎗️ reminder ribbon
+1F397                                      ; unqualified         # 🎗 reminder ribbon
+1F39F FE0F                                 ; fully-qualified     # 🎟️ admission tickets
+1F39F                                      ; unqualified         # 🎟 admission tickets
+1F3AB                                      ; fully-qualified     # 🎫 ticket
+
+# subgroup: award-medal
+1F396 FE0F                                 ; fully-qualified     # 🎖️ military medal
+1F396                                      ; unqualified         # 🎖 military medal
+1F3C6                                      ; fully-qualified     # 🏆 trophy
+1F3C5                                      ; fully-qualified     # 🏅 sports medal
+1F947                                      ; fully-qualified     # 🥇 1st place medal
+1F948                                      ; fully-qualified     # 🥈 2nd place medal
+1F949                                      ; fully-qualified     # 🥉 3rd place medal
+
+# subgroup: sport
+26BD                                       ; fully-qualified     # ⚽ soccer ball
+26BE                                       ; fully-qualified     # ⚾ baseball
+1F94E                                      ; fully-qualified     # 🥎 softball
+1F3C0                                      ; fully-qualified     # 🏀 basketball
+1F3D0                                      ; fully-qualified     # 🏐 volleyball
+1F3C8                                      ; fully-qualified     # 🏈 american football
+1F3C9                                      ; fully-qualified     # 🏉 rugby football
+1F3BE                                      ; fully-qualified     # 🎾 tennis
+1F94F                                      ; fully-qualified     # 🥏 flying disc
+1F3B3                                      ; fully-qualified     # 🎳 bowling
+1F3CF                                      ; fully-qualified     # 🏏 cricket game
+1F3D1                                      ; fully-qualified     # 🏑 field hockey
+1F3D2                                      ; fully-qualified     # 🏒 ice hockey
+1F94D                                      ; fully-qualified     # 🥍 lacrosse
+1F3D3                                      ; fully-qualified     # 🏓 ping pong
+1F3F8                                      ; fully-qualified     # 🏸 badminton
+1F94A                                      ; fully-qualified     # 🥊 boxing glove
+1F94B                                      ; fully-qualified     # 🥋 martial arts uniform
+1F945                                      ; fully-qualified     # 🥅 goal net
+26F3                                       ; fully-qualified     # ⛳ flag in hole
+26F8 FE0F                                  ; fully-qualified     # ⛸️ ice skate
+26F8                                       ; unqualified         # ⛸ ice skate
+1F3A3                                      ; fully-qualified     # 🎣 fishing pole
+1F93F                                      ; fully-qualified     # 🤿 diving mask
+1F3BD                                      ; fully-qualified     # 🎽 running shirt
+1F3BF                                      ; fully-qualified     # 🎿 skis
+1F6F7                                      ; fully-qualified     # 🛷 sled
+1F94C                                      ; fully-qualified     # 🥌 curling stone
+
+# subgroup: game
+1F3AF                                      ; fully-qualified     # 🎯 direct hit
+1FA80                                      ; fully-qualified     # 🪀 yo-yo
+1FA81                                      ; fully-qualified     # 🪁 kite
+1F3B1                                      ; fully-qualified     # 🎱 pool 8 ball
+1F52E                                      ; fully-qualified     # 🔮 crystal ball
+1F9FF                                      ; fully-qualified     # 🧿 nazar amulet
+1F3AE                                      ; fully-qualified     # 🎮 video game
+1F579 FE0F                                 ; fully-qualified     # 🕹️ joystick
+1F579                                      ; unqualified         # 🕹 joystick
+1F3B0                                      ; fully-qualified     # 🎰 slot machine
+1F3B2                                      ; fully-qualified     # 🎲 game die
+1F9E9                                      ; fully-qualified     # 🧩 puzzle piece
+1F9F8                                      ; fully-qualified     # 🧸 teddy bear
+2660 FE0F                                  ; fully-qualified     # ♠️ spade suit
+2660                                       ; unqualified         # ♠ spade suit
+2665 FE0F                                  ; fully-qualified     # ♥️ heart suit
+2665                                       ; unqualified         # ♥ heart suit
+2666 FE0F                                  ; fully-qualified     # ♦️ diamond suit
+2666                                       ; unqualified         # ♦ diamond suit
+2663 FE0F                                  ; fully-qualified     # ♣️ club suit
+2663                                       ; unqualified         # ♣ club suit
+265F FE0F                                  ; fully-qualified     # ♟️ chess pawn
+265F                                       ; unqualified         # ♟ chess pawn
+1F0CF                                      ; fully-qualified     # 🃏 joker
+1F004                                      ; fully-qualified     # 🀄 mahjong red dragon
+1F3B4                                      ; fully-qualified     # 🎴 flower playing cards
+
+# subgroup: arts & crafts
+1F3AD                                      ; fully-qualified     # 🎭 performing arts
+1F5BC FE0F                                 ; fully-qualified     # 🖼️ framed picture
+1F5BC                                      ; unqualified         # 🖼 framed picture
+1F3A8                                      ; fully-qualified     # 🎨 artist palette
+1F9F5                                      ; fully-qualified     # 🧵 thread
+1F9F6                                      ; fully-qualified     # 🧶 yarn
+
+# Activities subtotal:         90
+# Activities subtotal:         90      w/o modifiers
+
+# group: Objects
+
+# subgroup: clothing
+1F453                                      ; fully-qualified     # 👓 glasses
+1F576 FE0F                                 ; fully-qualified     # 🕶️ sunglasses
+1F576                                      ; unqualified         # 🕶 sunglasses
+1F97D                                      ; fully-qualified     # 🥽 goggles
+1F97C                                      ; fully-qualified     # 🥼 lab coat
+1F9BA                                      ; fully-qualified     # 🦺 safety vest
+1F454                                      ; fully-qualified     # 👔 necktie
+1F455                                      ; fully-qualified     # 👕 t-shirt
+1F456                                      ; fully-qualified     # 👖 jeans
+1F9E3                                      ; fully-qualified     # 🧣 scarf
+1F9E4                                      ; fully-qualified     # 🧤 gloves
+1F9E5                                      ; fully-qualified     # 🧥 coat
+1F9E6                                      ; fully-qualified     # 🧦 socks
+1F457                                      ; fully-qualified     # 👗 dress
+1F458                                      ; fully-qualified     # 👘 kimono
+1F97B                                      ; fully-qualified     # 🥻 sari
+1FA71                                      ; fully-qualified     # 🩱 one-piece swimsuit
+1FA72                                      ; fully-qualified     # 🩲 swim brief
+1FA73                                      ; fully-qualified     # 🩳 shorts
+1F459                                      ; fully-qualified     # 👙 bikini
+1F45A                                      ; fully-qualified     # 👚 woman’s clothes
+1F45B                                      ; fully-qualified     # 👛 purse
+1F45C                                      ; fully-qualified     # 👜 handbag
+1F45D                                      ; fully-qualified     # 👝 clutch bag
+1F6CD FE0F                                 ; fully-qualified     # 🛍️ shopping bags
+1F6CD                                      ; unqualified         # 🛍 shopping bags
+1F392                                      ; fully-qualified     # 🎒 backpack
+1F45E                                      ; fully-qualified     # 👞 man’s shoe
+1F45F                                      ; fully-qualified     # 👟 running shoe
+1F97E                                      ; fully-qualified     # 🥾 hiking boot
+1F97F                                      ; fully-qualified     # 🥿 flat shoe
+1F460                                      ; fully-qualified     # 👠 high-heeled shoe
+1F461                                      ; fully-qualified     # 👡 woman’s sandal
+1FA70                                      ; fully-qualified     # 🩰 ballet shoes
+1F462                                      ; fully-qualified     # 👢 woman’s boot
+1F451                                      ; fully-qualified     # 👑 crown
+1F452                                      ; fully-qualified     # 👒 woman’s hat
+1F3A9                                      ; fully-qualified     # 🎩 top hat
+1F393                                      ; fully-qualified     # 🎓 graduation cap
+1F9E2                                      ; fully-qualified     # 🧢 billed cap
+26D1 FE0F                                  ; fully-qualified     # ⛑️ rescue worker’s helmet
+26D1                                       ; unqualified         # ⛑ rescue worker’s helmet
+1F4FF                                      ; fully-qualified     # 📿 prayer beads
+1F484                                      ; fully-qualified     # 💄 lipstick
+1F48D                                      ; fully-qualified     # 💍 ring
+1F48E                                      ; fully-qualified     # 💎 gem stone
+
+# subgroup: sound
+1F507                                      ; fully-qualified     # 🔇 muted speaker
+1F508                                      ; fully-qualified     # 🔈 speaker low volume
+1F509                                      ; fully-qualified     # 🔉 speaker medium volume
+1F50A                                      ; fully-qualified     # 🔊 speaker high volume
+1F4E2                                      ; fully-qualified     # 📢 loudspeaker
+1F4E3                                      ; fully-qualified     # 📣 megaphone
+1F4EF                                      ; fully-qualified     # 📯 postal horn
+1F514                                      ; fully-qualified     # 🔔 bell
+1F515                                      ; fully-qualified     # 🔕 bell with slash
+
+# subgroup: music
+1F3BC                                      ; fully-qualified     # 🎼 musical score
+1F3B5                                      ; fully-qualified     # 🎵 musical note
+1F3B6                                      ; fully-qualified     # 🎶 musical notes
+1F399 FE0F                                 ; fully-qualified     # 🎙️ studio microphone
+1F399                                      ; unqualified         # 🎙 studio microphone
+1F39A FE0F                                 ; fully-qualified     # 🎚️ level slider
+1F39A                                      ; unqualified         # 🎚 level slider
+1F39B FE0F                                 ; fully-qualified     # 🎛️ control knobs
+1F39B                                      ; unqualified         # 🎛 control knobs
+1F3A4                                      ; fully-qualified     # 🎤 microphone
+1F3A7                                      ; fully-qualified     # 🎧 headphone
+1F4FB                                      ; fully-qualified     # 📻 radio
+
+# subgroup: musical-instrument
+1F3B7                                      ; fully-qualified     # 🎷 saxophone
+1F3B8                                      ; fully-qualified     # 🎸 guitar
+1F3B9                                      ; fully-qualified     # 🎹 musical keyboard
+1F3BA                                      ; fully-qualified     # 🎺 trumpet
+1F3BB                                      ; fully-qualified     # 🎻 violin
+1FA95                                      ; fully-qualified     # 🪕 banjo
+1F941                                      ; fully-qualified     # 🥁 drum
+
+# subgroup: phone
+1F4F1                                      ; fully-qualified     # 📱 mobile phone
+1F4F2                                      ; fully-qualified     # 📲 mobile phone with arrow
+260E FE0F                                  ; fully-qualified     # ☎️ telephone
+260E                                       ; unqualified         # ☎ telephone
+1F4DE                                      ; fully-qualified     # 📞 telephone receiver
+1F4DF                                      ; fully-qualified     # 📟 pager
+1F4E0                                      ; fully-qualified     # 📠 fax machine
+
+# subgroup: computer
+1F50B                                      ; fully-qualified     # 🔋 battery
+1F50C                                      ; fully-qualified     # 🔌 electric plug
+1F4BB                                      ; fully-qualified     # 💻 laptop computer
+1F5A5 FE0F                                 ; fully-qualified     # 🖥️ desktop computer
+1F5A5                                      ; unqualified         # 🖥 desktop computer
+1F5A8 FE0F                                 ; fully-qualified     # 🖨️ printer
+1F5A8                                      ; unqualified         # 🖨 printer
+2328 FE0F                                  ; fully-qualified     # ⌨️ keyboard
+2328                                       ; unqualified         # ⌨ keyboard
+1F5B1 FE0F                                 ; fully-qualified     # 🖱️ computer mouse
+1F5B1                                      ; unqualified         # 🖱 computer mouse
+1F5B2 FE0F                                 ; fully-qualified     # 🖲️ trackball
+1F5B2                                      ; unqualified         # 🖲 trackball
+1F4BD                                      ; fully-qualified     # 💽 computer disk
+1F4BE                                      ; fully-qualified     # 💾 floppy disk
+1F4BF                                      ; fully-qualified     # 💿 optical disk
+1F4C0                                      ; fully-qualified     # 📀 dvd
+1F9EE                                      ; fully-qualified     # 🧮 abacus
+
+# subgroup: light & video
+1F3A5                                      ; fully-qualified     # 🎥 movie camera
+1F39E FE0F                                 ; fully-qualified     # 🎞️ film frames
+1F39E                                      ; unqualified         # 🎞 film frames
+1F4FD FE0F                                 ; fully-qualified     # 📽️ film projector
+1F4FD                                      ; unqualified         # 📽 film projector
+1F3AC                                      ; fully-qualified     # 🎬 clapper board
+1F4FA                                      ; fully-qualified     # 📺 television
+1F4F7                                      ; fully-qualified     # 📷 camera
+1F4F8                                      ; fully-qualified     # 📸 camera with flash
+1F4F9                                      ; fully-qualified     # 📹 video camera
+1F4FC                                      ; fully-qualified     # 📼 videocassette
+1F50D                                      ; fully-qualified     # 🔍 magnifying glass tilted left
+1F50E                                      ; fully-qualified     # 🔎 magnifying glass tilted right
+1F56F FE0F                                 ; fully-qualified     # 🕯️ candle
+1F56F                                      ; unqualified         # 🕯 candle
+1F4A1                                      ; fully-qualified     # 💡 light bulb
+1F526                                      ; fully-qualified     # 🔦 flashlight
+1F3EE                                      ; fully-qualified     # 🏮 red paper lantern
+1FA94                                      ; fully-qualified     # 🪔 diya lamp
+
+# subgroup: book-paper
+1F4D4                                      ; fully-qualified     # 📔 notebook with decorative cover
+1F4D5                                      ; fully-qualified     # 📕 closed book
+1F4D6                                      ; fully-qualified     # 📖 open book
+1F4D7                                      ; fully-qualified     # 📗 green book
+1F4D8                                      ; fully-qualified     # 📘 blue book
+1F4D9                                      ; fully-qualified     # 📙 orange book
+1F4DA                                      ; fully-qualified     # 📚 books
+1F4D3                                      ; fully-qualified     # 📓 notebook
+1F4D2                                      ; fully-qualified     # 📒 ledger
+1F4C3                                      ; fully-qualified     # 📃 page with curl
+1F4DC                                      ; fully-qualified     # 📜 scroll
+1F4C4                                      ; fully-qualified     # 📄 page facing up
+1F4F0                                      ; fully-qualified     # 📰 newspaper
+1F5DE FE0F                                 ; fully-qualified     # 🗞️ rolled-up newspaper
+1F5DE                                      ; unqualified         # 🗞 rolled-up newspaper
+1F4D1                                      ; fully-qualified     # 📑 bookmark tabs
+1F516                                      ; fully-qualified     # 🔖 bookmark
+1F3F7 FE0F                                 ; fully-qualified     # 🏷️ label
+1F3F7                                      ; unqualified         # 🏷 label
+
+# subgroup: money
+1F4B0                                      ; fully-qualified     # 💰 money bag
+1F4B4                                      ; fully-qualified     # 💴 yen banknote
+1F4B5                                      ; fully-qualified     # 💵 dollar banknote
+1F4B6                                      ; fully-qualified     # 💶 euro banknote
+1F4B7                                      ; fully-qualified     # 💷 pound banknote
+1F4B8                                      ; fully-qualified     # 💸 money with wings
+1F4B3                                      ; fully-qualified     # 💳 credit card
+1F9FE                                      ; fully-qualified     # 🧾 receipt
+1F4B9                                      ; fully-qualified     # 💹 chart increasing with yen
+1F4B1                                      ; fully-qualified     # 💱 currency exchange
+1F4B2                                      ; fully-qualified     # 💲 heavy dollar sign
+
+# subgroup: mail
+2709 FE0F                                  ; fully-qualified     # ✉️ envelope
+2709                                       ; unqualified         # ✉ envelope
+1F4E7                                      ; fully-qualified     # 📧 e-mail
+1F4E8                                      ; fully-qualified     # 📨 incoming envelope
+1F4E9                                      ; fully-qualified     # 📩 envelope with arrow
+1F4E4                                      ; fully-qualified     # 📤 outbox tray
+1F4E5                                      ; fully-qualified     # 📥 inbox tray
+1F4E6                                      ; fully-qualified     # 📦 package
+1F4EB                                      ; fully-qualified     # 📫 closed mailbox with raised flag
+1F4EA                                      ; fully-qualified     # 📪 closed mailbox with lowered flag
+1F4EC                                      ; fully-qualified     # 📬 open mailbox with raised flag
+1F4ED                                      ; fully-qualified     # 📭 open mailbox with lowered flag
+1F4EE                                      ; fully-qualified     # 📮 postbox
+1F5F3 FE0F                                 ; fully-qualified     # 🗳️ ballot box with ballot
+1F5F3                                      ; unqualified         # 🗳 ballot box with ballot
+
+# subgroup: writing
+270F FE0F                                  ; fully-qualified     # ✏️ pencil
+270F                                       ; unqualified         # ✏ pencil
+2712 FE0F                                  ; fully-qualified     # ✒️ black nib
+2712                                       ; unqualified         # ✒ black nib
+1F58B FE0F                                 ; fully-qualified     # 🖋️ fountain pen
+1F58B                                      ; unqualified         # 🖋 fountain pen
+1F58A FE0F                                 ; fully-qualified     # 🖊️ pen
+1F58A                                      ; unqualified         # 🖊 pen
+1F58C FE0F                                 ; fully-qualified     # 🖌️ paintbrush
+1F58C                                      ; unqualified         # 🖌 paintbrush
+1F58D FE0F                                 ; fully-qualified     # 🖍️ crayon
+1F58D                                      ; unqualified         # 🖍 crayon
+1F4DD                                      ; fully-qualified     # 📝 memo
+
+# subgroup: office
+1F4BC                                      ; fully-qualified     # 💼 briefcase
+1F4C1                                      ; fully-qualified     # 📁 file folder
+1F4C2                                      ; fully-qualified     # 📂 open file folder
+1F5C2 FE0F                                 ; fully-qualified     # 🗂️ card index dividers
+1F5C2                                      ; unqualified         # 🗂 card index dividers
+1F4C5                                      ; fully-qualified     # 📅 calendar
+1F4C6                                      ; fully-qualified     # 📆 tear-off calendar
+1F5D2 FE0F                                 ; fully-qualified     # 🗒️ spiral notepad
+1F5D2                                      ; unqualified         # 🗒 spiral notepad
+1F5D3 FE0F                                 ; fully-qualified     # 🗓️ spiral calendar
+1F5D3                                      ; unqualified         # 🗓 spiral calendar
+1F4C7                                      ; fully-qualified     # 📇 card index
+1F4C8                                      ; fully-qualified     # 📈 chart increasing
+1F4C9                                      ; fully-qualified     # 📉 chart decreasing
+1F4CA                                      ; fully-qualified     # 📊 bar chart
+1F4CB                                      ; fully-qualified     # 📋 clipboard
+1F4CC                                      ; fully-qualified     # 📌 pushpin
+1F4CD                                      ; fully-qualified     # 📍 round pushpin
+1F4CE                                      ; fully-qualified     # 📎 paperclip
+1F587 FE0F                                 ; fully-qualified     # 🖇️ linked paperclips
+1F587                                      ; unqualified         # 🖇 linked paperclips
+1F4CF                                      ; fully-qualified     # 📏 straight ruler
+1F4D0                                      ; fully-qualified     # 📐 triangular ruler
+2702 FE0F                                  ; fully-qualified     # ✂️ scissors
+2702                                       ; unqualified         # ✂ scissors
+1F5C3 FE0F                                 ; fully-qualified     # 🗃️ card file box
+1F5C3                                      ; unqualified         # 🗃 card file box
+1F5C4 FE0F                                 ; fully-qualified     # 🗄️ file cabinet
+1F5C4                                      ; unqualified         # 🗄 file cabinet
+1F5D1 FE0F                                 ; fully-qualified     # 🗑️ wastebasket
+1F5D1                                      ; unqualified         # 🗑 wastebasket
+
+# subgroup: lock
+1F512                                      ; fully-qualified     # 🔒 locked
+1F513                                      ; fully-qualified     # 🔓 unlocked
+1F50F                                      ; fully-qualified     # 🔏 locked with pen
+1F510                                      ; fully-qualified     # 🔐 locked with key
+1F511                                      ; fully-qualified     # 🔑 key
+1F5DD FE0F                                 ; fully-qualified     # 🗝️ old key
+1F5DD                                      ; unqualified         # 🗝 old key
+
+# subgroup: tool
+1F528                                      ; fully-qualified     # 🔨 hammer
+1FA93                                      ; fully-qualified     # 🪓 axe
+26CF FE0F                                  ; fully-qualified     # ⛏️ pick
+26CF                                       ; unqualified         # ⛏ pick
+2692 FE0F                                  ; fully-qualified     # ⚒️ hammer and pick
+2692                                       ; unqualified         # ⚒ hammer and pick
+1F6E0 FE0F                                 ; fully-qualified     # 🛠️ hammer and wrench
+1F6E0                                      ; unqualified         # 🛠 hammer and wrench
+1F5E1 FE0F                                 ; fully-qualified     # 🗡️ dagger
+1F5E1                                      ; unqualified         # 🗡 dagger
+2694 FE0F                                  ; fully-qualified     # ⚔️ crossed swords
+2694                                       ; unqualified         # ⚔ crossed swords
+1F52B                                      ; fully-qualified     # 🔫 pistol
+1F3F9                                      ; fully-qualified     # 🏹 bow and arrow
+1F6E1 FE0F                                 ; fully-qualified     # 🛡️ shield
+1F6E1                                      ; unqualified         # 🛡 shield
+1F527                                      ; fully-qualified     # 🔧 wrench
+1F529                                      ; fully-qualified     # 🔩 nut and bolt
+2699 FE0F                                  ; fully-qualified     # ⚙️ gear
+2699                                       ; unqualified         # ⚙ gear
+1F5DC FE0F                                 ; fully-qualified     # 🗜️ clamp
+1F5DC                                      ; unqualified         # 🗜 clamp
+2696 FE0F                                  ; fully-qualified     # ⚖️ balance scale
+2696                                       ; unqualified         # ⚖ balance scale
+1F9AF                                      ; fully-qualified     # 🦯 probing cane
+1F517                                      ; fully-qualified     # 🔗 link
+26D3 FE0F                                  ; fully-qualified     # ⛓️ chains
+26D3                                       ; unqualified         # ⛓ chains
+1F9F0                                      ; fully-qualified     # 🧰 toolbox
+1F9F2                                      ; fully-qualified     # 🧲 magnet
+
+# subgroup: science
+2697 FE0F                                  ; fully-qualified     # ⚗️ alembic
+2697                                       ; unqualified         # ⚗ alembic
+1F9EA                                      ; fully-qualified     # 🧪 test tube
+1F9EB                                      ; fully-qualified     # 🧫 petri dish
+1F9EC                                      ; fully-qualified     # 🧬 dna
+1F52C                                      ; fully-qualified     # 🔬 microscope
+1F52D                                      ; fully-qualified     # 🔭 telescope
+1F4E1                                      ; fully-qualified     # 📡 satellite antenna
+
+# subgroup: medical
+1F489                                      ; fully-qualified     # 💉 syringe
+1FA78                                      ; fully-qualified     # 🩸 drop of blood
+1F48A                                      ; fully-qualified     # 💊 pill
+1FA79                                      ; fully-qualified     # 🩹 adhesive bandage
+1FA7A                                      ; fully-qualified     # 🩺 stethoscope
+
+# subgroup: household
+1F6AA                                      ; fully-qualified     # 🚪 door
+1F6CF FE0F                                 ; fully-qualified     # 🛏️ bed
+1F6CF                                      ; unqualified         # 🛏 bed
+1F6CB FE0F                                 ; fully-qualified     # 🛋️ couch and lamp
+1F6CB                                      ; unqualified         # 🛋 couch and lamp
+1FA91                                      ; fully-qualified     # 🪑 chair
+1F6BD                                      ; fully-qualified     # 🚽 toilet
+1F6BF                                      ; fully-qualified     # 🚿 shower
+1F6C1                                      ; fully-qualified     # 🛁 bathtub
+1FA92                                      ; fully-qualified     # 🪒 razor
+1F9F4                                      ; fully-qualified     # 🧴 lotion bottle
+1F9F7                                      ; fully-qualified     # 🧷 safety pin
+1F9F9                                      ; fully-qualified     # 🧹 broom
+1F9FA                                      ; fully-qualified     # 🧺 basket
+1F9FB                                      ; fully-qualified     # 🧻 roll of paper
+1F9FC                                      ; fully-qualified     # 🧼 soap
+1F9FD                                      ; fully-qualified     # 🧽 sponge
+1F9EF                                      ; fully-qualified     # 🧯 fire extinguisher
+1F6D2                                      ; fully-qualified     # 🛒 shopping cart
+
+# subgroup: other-object
+1F6AC                                      ; fully-qualified     # 🚬 cigarette
+26B0 FE0F                                  ; fully-qualified     # ⚰️ coffin
+26B0                                       ; unqualified         # ⚰ coffin
+26B1 FE0F                                  ; fully-qualified     # ⚱️ funeral urn
+26B1                                       ; unqualified         # ⚱ funeral urn
+1F5FF                                      ; fully-qualified     # 🗿 moai
+
+# Objects subtotal:            282
+# Objects subtotal:            282     w/o modifiers
+
+# group: Symbols
+
+# subgroup: transport-sign
+1F3E7                                      ; fully-qualified     # 🏧 ATM sign
+1F6AE                                      ; fully-qualified     # 🚮 litter in bin sign
+1F6B0                                      ; fully-qualified     # 🚰 potable water
+267F                                       ; fully-qualified     # ♿ wheelchair symbol
+1F6B9                                      ; fully-qualified     # 🚹 men’s room
+1F6BA                                      ; fully-qualified     # 🚺 women’s room
+1F6BB                                      ; fully-qualified     # 🚻 restroom
+1F6BC                                      ; fully-qualified     # 🚼 baby symbol
+1F6BE                                      ; fully-qualified     # 🚾 water closet
+1F6C2                                      ; fully-qualified     # 🛂 passport control
+1F6C3                                      ; fully-qualified     # 🛃 customs
+1F6C4                                      ; fully-qualified     # 🛄 baggage claim
+1F6C5                                      ; fully-qualified     # 🛅 left luggage
+
+# subgroup: warning
+26A0 FE0F                                  ; fully-qualified     # ⚠️ warning
+26A0                                       ; unqualified         # ⚠ warning
+1F6B8                                      ; fully-qualified     # 🚸 children crossing
+26D4                                       ; fully-qualified     # ⛔ no entry
+1F6AB                                      ; fully-qualified     # 🚫 prohibited
+1F6B3                                      ; fully-qualified     # 🚳 no bicycles
+1F6AD                                      ; fully-qualified     # 🚭 no smoking
+1F6AF                                      ; fully-qualified     # 🚯 no littering
+1F6B1                                      ; fully-qualified     # 🚱 non-potable water
+1F6B7                                      ; fully-qualified     # 🚷 no pedestrians
+1F4F5                                      ; fully-qualified     # 📵 no mobile phones
+1F51E                                      ; fully-qualified     # 🔞 no one under eighteen
+2622 FE0F                                  ; fully-qualified     # ☢️ radioactive
+2622                                       ; unqualified         # ☢ radioactive
+2623 FE0F                                  ; fully-qualified     # ☣️ biohazard
+2623                                       ; unqualified         # ☣ biohazard
+
+# subgroup: arrow
+2B06 FE0F                                  ; fully-qualified     # ⬆️ up arrow
+2B06                                       ; unqualified         # ⬆ up arrow
+2197 FE0F                                  ; fully-qualified     # ↗️ up-right arrow
+2197                                       ; unqualified         # ↗ up-right arrow
+27A1 FE0F                                  ; fully-qualified     # ➡️ right arrow
+27A1                                       ; unqualified         # ➡ right arrow
+2198 FE0F                                  ; fully-qualified     # ↘️ down-right arrow
+2198                                       ; unqualified         # ↘ down-right arrow
+2B07 FE0F                                  ; fully-qualified     # ⬇️ down arrow
+2B07                                       ; unqualified         # ⬇ down arrow
+2199 FE0F                                  ; fully-qualified     # ↙️ down-left arrow
+2199                                       ; unqualified         # ↙ down-left arrow
+2B05 FE0F                                  ; fully-qualified     # ⬅️ left arrow
+2B05                                       ; unqualified         # ⬅ left arrow
+2196 FE0F                                  ; fully-qualified     # ↖️ up-left arrow
+2196                                       ; unqualified         # ↖ up-left arrow
+2195 FE0F                                  ; fully-qualified     # ↕️ up-down arrow
+2195                                       ; unqualified         # ↕ up-down arrow
+2194 FE0F                                  ; fully-qualified     # ↔️ left-right arrow
+2194                                       ; unqualified         # ↔ left-right arrow
+21A9 FE0F                                  ; fully-qualified     # ↩️ right arrow curving left
+21A9                                       ; unqualified         # ↩ right arrow curving left
+21AA FE0F                                  ; fully-qualified     # ↪️ left arrow curving right
+21AA                                       ; unqualified         # ↪ left arrow curving right
+2934 FE0F                                  ; fully-qualified     # ⤴️ right arrow curving up
+2934                                       ; unqualified         # ⤴ right arrow curving up
+2935 FE0F                                  ; fully-qualified     # ⤵️ right arrow curving down
+2935                                       ; unqualified         # ⤵ right arrow curving down
+1F503                                      ; fully-qualified     # 🔃 clockwise vertical arrows
+1F504                                      ; fully-qualified     # 🔄 counterclockwise arrows button
+1F519                                      ; fully-qualified     # 🔙 BACK arrow
+1F51A                                      ; fully-qualified     # 🔚 END arrow
+1F51B                                      ; fully-qualified     # 🔛 ON! arrow
+1F51C                                      ; fully-qualified     # 🔜 SOON arrow
+1F51D                                      ; fully-qualified     # 🔝 TOP arrow
+
+# subgroup: religion
+1F6D0                                      ; fully-qualified     # 🛐 place of worship
+269B FE0F                                  ; fully-qualified     # ⚛️ atom symbol
+269B                                       ; unqualified         # ⚛ atom symbol
+1F549 FE0F                                 ; fully-qualified     # 🕉️ om
+1F549                                      ; unqualified         # 🕉 om
+2721 FE0F                                  ; fully-qualified     # ✡️ star of David
+2721                                       ; unqualified         # ✡ star of David
+2638 FE0F                                  ; fully-qualified     # ☸️ wheel of dharma
+2638                                       ; unqualified         # ☸ wheel of dharma
+262F FE0F                                  ; fully-qualified     # ☯️ yin yang
+262F                                       ; unqualified         # ☯ yin yang
+271D FE0F                                  ; fully-qualified     # ✝️ latin cross
+271D                                       ; unqualified         # ✝ latin cross
+2626 FE0F                                  ; fully-qualified     # ☦️ orthodox cross
+2626                                       ; unqualified         # ☦ orthodox cross
+262A FE0F                                  ; fully-qualified     # ☪️ star and crescent
+262A                                       ; unqualified         # ☪ star and crescent
+262E FE0F                                  ; fully-qualified     # ☮️ peace symbol
+262E                                       ; unqualified         # ☮ peace symbol
+1F54E                                      ; fully-qualified     # 🕎 menorah
+1F52F                                      ; fully-qualified     # 🔯 dotted six-pointed star
+
+# subgroup: zodiac
+2648                                       ; fully-qualified     # ♈ Aries
+2649                                       ; fully-qualified     # ♉ Taurus
+264A                                       ; fully-qualified     # ♊ Gemini
+264B                                       ; fully-qualified     # ♋ Cancer
+264C                                       ; fully-qualified     # ♌ Leo
+264D                                       ; fully-qualified     # ♍ Virgo
+264E                                       ; fully-qualified     # ♎ Libra
+264F                                       ; fully-qualified     # ♏ Scorpio
+2650                                       ; fully-qualified     # ♐ Sagittarius
+2651                                       ; fully-qualified     # ♑ Capricorn
+2652                                       ; fully-qualified     # ♒ Aquarius
+2653                                       ; fully-qualified     # ♓ Pisces
+26CE                                       ; fully-qualified     # ⛎ Ophiuchus
+
+# subgroup: av-symbol
+1F500                                      ; fully-qualified     # 🔀 shuffle tracks button
+1F501                                      ; fully-qualified     # 🔁 repeat button
+1F502                                      ; fully-qualified     # 🔂 repeat single button
+25B6 FE0F                                  ; fully-qualified     # ▶️ play button
+25B6                                       ; unqualified         # ▶ play button
+23E9                                       ; fully-qualified     # ⏩ fast-forward button
+23ED FE0F                                  ; fully-qualified     # ⏭️ next track button
+23ED                                       ; unqualified         # ⏭ next track button
+23EF FE0F                                  ; fully-qualified     # ⏯️ play or pause button
+23EF                                       ; unqualified         # ⏯ play or pause button
+25C0 FE0F                                  ; fully-qualified     # ◀️ reverse button
+25C0                                       ; unqualified         # ◀ reverse button
+23EA                                       ; fully-qualified     # ⏪ fast reverse button
+23EE FE0F                                  ; fully-qualified     # ⏮️ last track button
+23EE                                       ; unqualified         # ⏮ last track button
+1F53C                                      ; fully-qualified     # 🔼 upwards button
+23EB                                       ; fully-qualified     # ⏫ fast up button
+1F53D                                      ; fully-qualified     # 🔽 downwards button
+23EC                                       ; fully-qualified     # ⏬ fast down button
+23F8 FE0F                                  ; fully-qualified     # ⏸️ pause button
+23F8                                       ; unqualified         # ⏸ pause button
+23F9 FE0F                                  ; fully-qualified     # ⏹️ stop button
+23F9                                       ; unqualified         # ⏹ stop button
+23FA FE0F                                  ; fully-qualified     # ⏺️ record button
+23FA                                       ; unqualified         # ⏺ record button
+23CF FE0F                                  ; fully-qualified     # ⏏️ eject button
+23CF                                       ; unqualified         # ⏏ eject button
+1F3A6                                      ; fully-qualified     # 🎦 cinema
+1F505                                      ; fully-qualified     # 🔅 dim button
+1F506                                      ; fully-qualified     # 🔆 bright button
+1F4F6                                      ; fully-qualified     # 📶 antenna bars
+1F4F3                                      ; fully-qualified     # 📳 vibration mode
+1F4F4                                      ; fully-qualified     # 📴 mobile phone off
+
+# subgroup: gender
+2640 FE0F                                  ; fully-qualified     # ♀️ female sign
+2640                                       ; unqualified         # ♀ female sign
+2642 FE0F                                  ; fully-qualified     # ♂️ male sign
+2642                                       ; unqualified         # ♂ male sign
+
+# subgroup: other-symbol
+2695 FE0F                                  ; fully-qualified     # ⚕️ medical symbol
+2695                                       ; unqualified         # ⚕ medical symbol
+267E FE0F                                  ; fully-qualified     # ♾️ infinity
+267E                                       ; unqualified         # ♾ infinity
+267B FE0F                                  ; fully-qualified     # ♻️ recycling symbol
+267B                                       ; unqualified         # ♻ recycling symbol
+269C FE0F                                  ; fully-qualified     # ⚜️ fleur-de-lis
+269C                                       ; unqualified         # ⚜ fleur-de-lis
+1F531                                      ; fully-qualified     # 🔱 trident emblem
+1F4DB                                      ; fully-qualified     # 📛 name badge
+1F530                                      ; fully-qualified     # 🔰 Japanese symbol for beginner
+2B55                                       ; fully-qualified     # ⭕ hollow red circle
+2705                                       ; fully-qualified     # ✅ check mark button
+2611 FE0F                                  ; fully-qualified     # ☑️ check box with check
+2611                                       ; unqualified         # ☑ check box with check
+2714 FE0F                                  ; fully-qualified     # ✔️ check mark
+2714                                       ; unqualified         # ✔ check mark
+2716 FE0F                                  ; fully-qualified     # ✖️ multiplication sign
+2716                                       ; unqualified         # ✖ multiplication sign
+274C                                       ; fully-qualified     # ❌ cross mark
+274E                                       ; fully-qualified     # ❎ cross mark button
+2795                                       ; fully-qualified     # ➕ plus sign
+2796                                       ; fully-qualified     # ➖ minus sign
+2797                                       ; fully-qualified     # ➗ division sign
+27B0                                       ; fully-qualified     # ➰ curly loop
+27BF                                       ; fully-qualified     # ➿ double curly loop
+303D FE0F                                  ; fully-qualified     # 〽️ part alternation mark
+303D                                       ; unqualified         # 〽 part alternation mark
+2733 FE0F                                  ; fully-qualified     # ✳️ eight-spoked asterisk
+2733                                       ; unqualified         # ✳ eight-spoked asterisk
+2734 FE0F                                  ; fully-qualified     # ✴️ eight-pointed star
+2734                                       ; unqualified         # ✴ eight-pointed star
+2747 FE0F                                  ; fully-qualified     # ❇️ sparkle
+2747                                       ; unqualified         # ❇ sparkle
+203C FE0F                                  ; fully-qualified     # ‼️ double exclamation mark
+203C                                       ; unqualified         # ‼ double exclamation mark
+2049 FE0F                                  ; fully-qualified     # ⁉️ exclamation question mark
+2049                                       ; unqualified         # ⁉ exclamation question mark
+2753                                       ; fully-qualified     # ❓ question mark
+2754                                       ; fully-qualified     # ❔ white question mark
+2755                                       ; fully-qualified     # ❕ white exclamation mark
+2757                                       ; fully-qualified     # ❗ exclamation mark
+3030 FE0F                                  ; fully-qualified     # 〰️ wavy dash
+3030                                       ; unqualified         # 〰 wavy dash
+00A9 FE0F                                  ; fully-qualified     # ©️ copyright
+00A9                                       ; unqualified         # © copyright
+00AE FE0F                                  ; fully-qualified     # ®️ registered
+00AE                                       ; unqualified         # ® registered
+2122 FE0F                                  ; fully-qualified     # ™️ trade mark
+2122                                       ; unqualified         # ™ trade mark
+
+# subgroup: keycap
+0023 FE0F 20E3                             ; fully-qualified     # #️⃣ keycap: #
+0023 20E3                                  ; unqualified         # #⃣ keycap: #
+002A FE0F 20E3                             ; fully-qualified     # *️⃣ keycap: *
+002A 20E3                                  ; unqualified         # *⃣ keycap: *
+0030 FE0F 20E3                             ; fully-qualified     # 0️⃣ keycap: 0
+0030 20E3                                  ; unqualified         # 0⃣ keycap: 0
+0031 FE0F 20E3                             ; fully-qualified     # 1️⃣ keycap: 1
+0031 20E3                                  ; unqualified         # 1⃣ keycap: 1
+0032 FE0F 20E3                             ; fully-qualified     # 2️⃣ keycap: 2
+0032 20E3                                  ; unqualified         # 2⃣ keycap: 2
+0033 FE0F 20E3                             ; fully-qualified     # 3️⃣ keycap: 3
+0033 20E3                                  ; unqualified         # 3⃣ keycap: 3
+0034 FE0F 20E3                             ; fully-qualified     # 4️⃣ keycap: 4
+0034 20E3                                  ; unqualified         # 4⃣ keycap: 4
+0035 FE0F 20E3                             ; fully-qualified     # 5️⃣ keycap: 5
+0035 20E3                                  ; unqualified         # 5⃣ keycap: 5
+0036 FE0F 20E3                             ; fully-qualified     # 6️⃣ keycap: 6
+0036 20E3                                  ; unqualified         # 6⃣ keycap: 6
+0037 FE0F 20E3                             ; fully-qualified     # 7️⃣ keycap: 7
+0037 20E3                                  ; unqualified         # 7⃣ keycap: 7
+0038 FE0F 20E3                             ; fully-qualified     # 8️⃣ keycap: 8
+0038 20E3                                  ; unqualified         # 8⃣ keycap: 8
+0039 FE0F 20E3                             ; fully-qualified     # 9️⃣ keycap: 9
+0039 20E3                                  ; unqualified         # 9⃣ keycap: 9
+1F51F                                      ; fully-qualified     # 🔟 keycap: 10
+
+# subgroup: alphanum
+1F520                                      ; fully-qualified     # 🔠 input latin uppercase
+1F521                                      ; fully-qualified     # 🔡 input latin lowercase
+1F522                                      ; fully-qualified     # 🔢 input numbers
+1F523                                      ; fully-qualified     # 🔣 input symbols
+1F524                                      ; fully-qualified     # 🔤 input latin letters
+1F170 FE0F                                 ; fully-qualified     # 🅰️ A button (blood type)
+1F170                                      ; unqualified         # 🅰 A button (blood type)
+1F18E                                      ; fully-qualified     # 🆎 AB button (blood type)
+1F171 FE0F                                 ; fully-qualified     # 🅱️ B button (blood type)
+1F171                                      ; unqualified         # 🅱 B button (blood type)
+1F191                                      ; fully-qualified     # 🆑 CL button
+1F192                                      ; fully-qualified     # 🆒 COOL button
+1F193                                      ; fully-qualified     # 🆓 FREE button
+2139 FE0F                                  ; fully-qualified     # ℹ️ information
+2139                                       ; unqualified         # ℹ information
+1F194                                      ; fully-qualified     # 🆔 ID button
+24C2 FE0F                                  ; fully-qualified     # Ⓜ️ circled M
+24C2                                       ; unqualified         # Ⓜ circled M
+1F195                                      ; fully-qualified     # 🆕 NEW button
+1F196                                      ; fully-qualified     # 🆖 NG button
+1F17E FE0F                                 ; fully-qualified     # 🅾️ O button (blood type)
+1F17E                                      ; unqualified         # 🅾 O button (blood type)
+1F197                                      ; fully-qualified     # 🆗 OK button
+1F17F FE0F                                 ; fully-qualified     # 🅿️ P button
+1F17F                                      ; unqualified         # 🅿 P button
+1F198                                      ; fully-qualified     # 🆘 SOS button
+1F199                                      ; fully-qualified     # 🆙 UP! button
+1F19A                                      ; fully-qualified     # 🆚 VS button
+1F201                                      ; fully-qualified     # 🈁 Japanese “here” button
+1F202 FE0F                                 ; fully-qualified     # 🈂️ Japanese “service charge” button
+1F202                                      ; unqualified         # 🈂 Japanese “service charge” button
+1F237 FE0F                                 ; fully-qualified     # 🈷️ Japanese “monthly amount” button
+1F237                                      ; unqualified         # 🈷 Japanese “monthly amount” button
+1F236                                      ; fully-qualified     # 🈶 Japanese “not free of charge” button
+1F22F                                      ; fully-qualified     # 🈯 Japanese “reserved” button
+1F250                                      ; fully-qualified     # 🉐 Japanese “bargain” button
+1F239                                      ; fully-qualified     # 🈹 Japanese “discount” button
+1F21A                                      ; fully-qualified     # 🈚 Japanese “free of charge” button
+1F232                                      ; fully-qualified     # 🈲 Japanese “prohibited” button
+1F251                                      ; fully-qualified     # 🉑 Japanese “acceptable” button
+1F238                                      ; fully-qualified     # 🈸 Japanese “application” button
+1F234                                      ; fully-qualified     # 🈴 Japanese “passing grade” button
+1F233                                      ; fully-qualified     # 🈳 Japanese “vacancy” button
+3297 FE0F                                  ; fully-qualified     # ㊗️ Japanese “congratulations” button
+3297                                       ; unqualified         # ㊗ Japanese “congratulations” button
+3299 FE0F                                  ; fully-qualified     # ㊙️ Japanese “secret” button
+3299                                       ; unqualified         # ㊙ Japanese “secret” button
+1F23A                                      ; fully-qualified     # 🈺 Japanese “open for business” button
+1F235                                      ; fully-qualified     # 🈵 Japanese “no vacancy” button
+
+# subgroup: geometric
+1F534                                      ; fully-qualified     # 🔴 red circle
+1F7E0                                      ; fully-qualified     # 🟠 orange circle
+1F7E1                                      ; fully-qualified     # 🟡 yellow circle
+1F7E2                                      ; fully-qualified     # 🟢 green circle
+1F535                                      ; fully-qualified     # 🔵 blue circle
+1F7E3                                      ; fully-qualified     # 🟣 purple circle
+1F7E4                                      ; fully-qualified     # 🟤 brown circle
+26AB                                       ; fully-qualified     # ⚫ black circle
+26AA                                       ; fully-qualified     # ⚪ white circle
+1F7E5                                      ; fully-qualified     # 🟥 red square
+1F7E7                                      ; fully-qualified     # 🟧 orange square
+1F7E8                                      ; fully-qualified     # 🟨 yellow square
+1F7E9                                      ; fully-qualified     # 🟩 green square
+1F7E6                                      ; fully-qualified     # 🟦 blue square
+1F7EA                                      ; fully-qualified     # 🟪 purple square
+1F7EB                                      ; fully-qualified     # 🟫 brown square
+2B1B                                       ; fully-qualified     # ⬛ black large square
+2B1C                                       ; fully-qualified     # ⬜ white large square
+25FC FE0F                                  ; fully-qualified     # ◼️ black medium square
+25FC                                       ; unqualified         # ◼ black medium square
+25FB FE0F                                  ; fully-qualified     # ◻️ white medium square
+25FB                                       ; unqualified         # ◻ white medium square
+25FE                                       ; fully-qualified     # ◾ black medium-small square
+25FD                                       ; fully-qualified     # ◽ white medium-small square
+25AA FE0F                                  ; fully-qualified     # ▪️ black small square
+25AA                                       ; unqualified         # ▪ black small square
+25AB FE0F                                  ; fully-qualified     # ▫️ white small square
+25AB                                       ; unqualified         # ▫ white small square
+1F536                                      ; fully-qualified     # 🔶 large orange diamond
+1F537                                      ; fully-qualified     # 🔷 large blue diamond
+1F538                                      ; fully-qualified     # 🔸 small orange diamond
+1F539                                      ; fully-qualified     # 🔹 small blue diamond
+1F53A                                      ; fully-qualified     # 🔺 red triangle pointed up
+1F53B                                      ; fully-qualified     # 🔻 red triangle pointed down
+1F4A0                                      ; fully-qualified     # 💠 diamond with a dot
+1F518                                      ; fully-qualified     # 🔘 radio button
+1F533                                      ; fully-qualified     # 🔳 white square button
+1F532                                      ; fully-qualified     # 🔲 black square button
+
+# Symbols subtotal:            297
+# Symbols subtotal:            297     w/o modifiers
+
+# group: Flags
+
+# subgroup: flag
+1F3C1                                      ; fully-qualified     # 🏁 chequered flag
+1F6A9                                      ; fully-qualified     # 🚩 triangular flag
+1F38C                                      ; fully-qualified     # 🎌 crossed flags
+1F3F4                                      ; fully-qualified     # 🏴 black flag
+1F3F3 FE0F                                 ; fully-qualified     # 🏳️ white flag
+1F3F3                                      ; unqualified         # 🏳 white flag
+1F3F3 FE0F 200D 1F308                      ; fully-qualified     # 🏳️‍🌈 rainbow flag
+1F3F3 200D 1F308                           ; unqualified         # 🏳‍🌈 rainbow flag
+1F3F4 200D 2620 FE0F                       ; fully-qualified     # 🏴‍☠️ pirate flag
+1F3F4 200D 2620                            ; minimally-qualified # 🏴‍☠ pirate flag
+
+# subgroup: country-flag
+1F1E6 1F1E8                                ; fully-qualified     # 🇦🇨 flag: Ascension Island
+1F1E6 1F1E9                                ; fully-qualified     # 🇦🇩 flag: Andorra
+1F1E6 1F1EA                                ; fully-qualified     # 🇦🇪 flag: United Arab Emirates
+1F1E6 1F1EB                                ; fully-qualified     # 🇦🇫 flag: Afghanistan
+1F1E6 1F1EC                                ; fully-qualified     # 🇦🇬 flag: Antigua & Barbuda
+1F1E6 1F1EE                                ; fully-qualified     # 🇦🇮 flag: Anguilla
+1F1E6 1F1F1                                ; fully-qualified     # 🇦🇱 flag: Albania
+1F1E6 1F1F2                                ; fully-qualified     # 🇦🇲 flag: Armenia
+1F1E6 1F1F4                                ; fully-qualified     # 🇦🇴 flag: Angola
+1F1E6 1F1F6                                ; fully-qualified     # 🇦🇶 flag: Antarctica
+1F1E6 1F1F7                                ; fully-qualified     # 🇦🇷 flag: Argentina
+1F1E6 1F1F8                                ; fully-qualified     # 🇦🇸 flag: American Samoa
+1F1E6 1F1F9                                ; fully-qualified     # 🇦🇹 flag: Austria
+1F1E6 1F1FA                                ; fully-qualified     # 🇦🇺 flag: Australia
+1F1E6 1F1FC                                ; fully-qualified     # 🇦🇼 flag: Aruba
+1F1E6 1F1FD                                ; fully-qualified     # 🇦🇽 flag: Åland Islands
+1F1E6 1F1FF                                ; fully-qualified     # 🇦🇿 flag: Azerbaijan
+1F1E7 1F1E6                                ; fully-qualified     # 🇧🇦 flag: Bosnia & Herzegovina
+1F1E7 1F1E7                                ; fully-qualified     # 🇧🇧 flag: Barbados
+1F1E7 1F1E9                                ; fully-qualified     # 🇧🇩 flag: Bangladesh
+1F1E7 1F1EA                                ; fully-qualified     # 🇧🇪 flag: Belgium
+1F1E7 1F1EB                                ; fully-qualified     # 🇧🇫 flag: Burkina Faso
+1F1E7 1F1EC                                ; fully-qualified     # 🇧🇬 flag: Bulgaria
+1F1E7 1F1ED                                ; fully-qualified     # 🇧🇭 flag: Bahrain
+1F1E7 1F1EE                                ; fully-qualified     # 🇧🇮 flag: Burundi
+1F1E7 1F1EF                                ; fully-qualified     # 🇧🇯 flag: Benin
+1F1E7 1F1F1                                ; fully-qualified     # 🇧🇱 flag: St. Barthélemy
+1F1E7 1F1F2                                ; fully-qualified     # 🇧🇲 flag: Bermuda
+1F1E7 1F1F3                                ; fully-qualified     # 🇧🇳 flag: Brunei
+1F1E7 1F1F4                                ; fully-qualified     # 🇧🇴 flag: Bolivia
+1F1E7 1F1F6                                ; fully-qualified     # 🇧🇶 flag: Caribbean Netherlands
+1F1E7 1F1F7                                ; fully-qualified     # 🇧🇷 flag: Brazil
+1F1E7 1F1F8                                ; fully-qualified     # 🇧🇸 flag: Bahamas
+1F1E7 1F1F9                                ; fully-qualified     # 🇧🇹 flag: Bhutan
+1F1E7 1F1FB                                ; fully-qualified     # 🇧🇻 flag: Bouvet Island
+1F1E7 1F1FC                                ; fully-qualified     # 🇧🇼 flag: Botswana
+1F1E7 1F1FE                                ; fully-qualified     # 🇧🇾 flag: Belarus
+1F1E7 1F1FF                                ; fully-qualified     # 🇧🇿 flag: Belize
+1F1E8 1F1E6                                ; fully-qualified     # 🇨🇦 flag: Canada
+1F1E8 1F1E8                                ; fully-qualified     # 🇨🇨 flag: Cocos (Keeling) Islands
+1F1E8 1F1E9                                ; fully-qualified     # 🇨🇩 flag: Congo - Kinshasa
+1F1E8 1F1EB                                ; fully-qualified     # 🇨🇫 flag: Central African Republic
+1F1E8 1F1EC                                ; fully-qualified     # 🇨🇬 flag: Congo - Brazzaville
+1F1E8 1F1ED                                ; fully-qualified     # 🇨🇭 flag: Switzerland
+1F1E8 1F1EE                                ; fully-qualified     # 🇨🇮 flag: Côte d’Ivoire
+1F1E8 1F1F0                                ; fully-qualified     # 🇨🇰 flag: Cook Islands
+1F1E8 1F1F1                                ; fully-qualified     # 🇨🇱 flag: Chile
+1F1E8 1F1F2                                ; fully-qualified     # 🇨🇲 flag: Cameroon
+1F1E8 1F1F3                                ; fully-qualified     # 🇨🇳 flag: China
+1F1E8 1F1F4                                ; fully-qualified     # 🇨🇴 flag: Colombia
+1F1E8 1F1F5                                ; fully-qualified     # 🇨🇵 flag: Clipperton Island
+1F1E8 1F1F7                                ; fully-qualified     # 🇨🇷 flag: Costa Rica
+1F1E8 1F1FA                                ; fully-qualified     # 🇨🇺 flag: Cuba
+1F1E8 1F1FB                                ; fully-qualified     # 🇨🇻 flag: Cape Verde
+1F1E8 1F1FC                                ; fully-qualified     # 🇨🇼 flag: Curaçao
+1F1E8 1F1FD                                ; fully-qualified     # 🇨🇽 flag: Christmas Island
+1F1E8 1F1FE                                ; fully-qualified     # 🇨🇾 flag: Cyprus
+1F1E8 1F1FF                                ; fully-qualified     # 🇨🇿 flag: Czechia
+1F1E9 1F1EA                                ; fully-qualified     # 🇩🇪 flag: Germany
+1F1E9 1F1EC                                ; fully-qualified     # 🇩🇬 flag: Diego Garcia
+1F1E9 1F1EF                                ; fully-qualified     # 🇩🇯 flag: Djibouti
+1F1E9 1F1F0                                ; fully-qualified     # 🇩🇰 flag: Denmark
+1F1E9 1F1F2                                ; fully-qualified     # 🇩🇲 flag: Dominica
+1F1E9 1F1F4                                ; fully-qualified     # 🇩🇴 flag: Dominican Republic
+1F1E9 1F1FF                                ; fully-qualified     # 🇩🇿 flag: Algeria
+1F1EA 1F1E6                                ; fully-qualified     # 🇪🇦 flag: Ceuta & Melilla
+1F1EA 1F1E8                                ; fully-qualified     # 🇪🇨 flag: Ecuador
+1F1EA 1F1EA                                ; fully-qualified     # 🇪🇪 flag: Estonia
+1F1EA 1F1EC                                ; fully-qualified     # 🇪🇬 flag: Egypt
+1F1EA 1F1ED                                ; fully-qualified     # 🇪🇭 flag: Western Sahara
+1F1EA 1F1F7                                ; fully-qualified     # 🇪🇷 flag: Eritrea
+1F1EA 1F1F8                                ; fully-qualified     # 🇪🇸 flag: Spain
+1F1EA 1F1F9                                ; fully-qualified     # 🇪🇹 flag: Ethiopia
+1F1EA 1F1FA                                ; fully-qualified     # 🇪🇺 flag: European Union
+1F1EB 1F1EE                                ; fully-qualified     # 🇫🇮 flag: Finland
+1F1EB 1F1EF                                ; fully-qualified     # 🇫🇯 flag: Fiji
+1F1EB 1F1F0                                ; fully-qualified     # 🇫🇰 flag: Falkland Islands
+1F1EB 1F1F2                                ; fully-qualified     # 🇫🇲 flag: Micronesia
+1F1EB 1F1F4                                ; fully-qualified     # 🇫🇴 flag: Faroe Islands
+1F1EB 1F1F7                                ; fully-qualified     # 🇫🇷 flag: France
+1F1EC 1F1E6                                ; fully-qualified     # 🇬🇦 flag: Gabon
+1F1EC 1F1E7                                ; fully-qualified     # 🇬🇧 flag: United Kingdom
+1F1EC 1F1E9                                ; fully-qualified     # 🇬🇩 flag: Grenada
+1F1EC 1F1EA                                ; fully-qualified     # 🇬🇪 flag: Georgia
+1F1EC 1F1EB                                ; fully-qualified     # 🇬🇫 flag: French Guiana
+1F1EC 1F1EC                                ; fully-qualified     # 🇬🇬 flag: Guernsey
+1F1EC 1F1ED                                ; fully-qualified     # 🇬🇭 flag: Ghana
+1F1EC 1F1EE                                ; fully-qualified     # 🇬🇮 flag: Gibraltar
+1F1EC 1F1F1                                ; fully-qualified     # 🇬🇱 flag: Greenland
+1F1EC 1F1F2                                ; fully-qualified     # 🇬🇲 flag: Gambia
+1F1EC 1F1F3                                ; fully-qualified     # 🇬🇳 flag: Guinea
+1F1EC 1F1F5                                ; fully-qualified     # 🇬🇵 flag: Guadeloupe
+1F1EC 1F1F6                                ; fully-qualified     # 🇬🇶 flag: Equatorial Guinea
+1F1EC 1F1F7                                ; fully-qualified     # 🇬🇷 flag: Greece
+1F1EC 1F1F8                                ; fully-qualified     # 🇬🇸 flag: South Georgia & South Sandwich Islands
+1F1EC 1F1F9                                ; fully-qualified     # 🇬🇹 flag: Guatemala
+1F1EC 1F1FA                                ; fully-qualified     # 🇬🇺 flag: Guam
+1F1EC 1F1FC                                ; fully-qualified     # 🇬🇼 flag: Guinea-Bissau
+1F1EC 1F1FE                                ; fully-qualified     # 🇬🇾 flag: Guyana
+1F1ED 1F1F0                                ; fully-qualified     # 🇭🇰 flag: Hong Kong SAR China
+1F1ED 1F1F2                                ; fully-qualified     # 🇭🇲 flag: Heard & McDonald Islands
+1F1ED 1F1F3                                ; fully-qualified     # 🇭🇳 flag: Honduras
+1F1ED 1F1F7                                ; fully-qualified     # 🇭🇷 flag: Croatia
+1F1ED 1F1F9                                ; fully-qualified     # 🇭🇹 flag: Haiti
+1F1ED 1F1FA                                ; fully-qualified     # 🇭🇺 flag: Hungary
+1F1EE 1F1E8                                ; fully-qualified     # 🇮🇨 flag: Canary Islands
+1F1EE 1F1E9                                ; fully-qualified     # 🇮🇩 flag: Indonesia
+1F1EE 1F1EA                                ; fully-qualified     # 🇮🇪 flag: Ireland
+1F1EE 1F1F1                                ; fully-qualified     # 🇮🇱 flag: Israel
+1F1EE 1F1F2                                ; fully-qualified     # 🇮🇲 flag: Isle of Man
+1F1EE 1F1F3                                ; fully-qualified     # 🇮🇳 flag: India
+1F1EE 1F1F4                                ; fully-qualified     # 🇮🇴 flag: British Indian Ocean Territory
+1F1EE 1F1F6                                ; fully-qualified     # 🇮🇶 flag: Iraq
+1F1EE 1F1F7                                ; fully-qualified     # 🇮🇷 flag: Iran
+1F1EE 1F1F8                                ; fully-qualified     # 🇮🇸 flag: Iceland
+1F1EE 1F1F9                                ; fully-qualified     # 🇮🇹 flag: Italy
+1F1EF 1F1EA                                ; fully-qualified     # 🇯🇪 flag: Jersey
+1F1EF 1F1F2                                ; fully-qualified     # 🇯🇲 flag: Jamaica
+1F1EF 1F1F4                                ; fully-qualified     # 🇯🇴 flag: Jordan
+1F1EF 1F1F5                                ; fully-qualified     # 🇯🇵 flag: Japan
+1F1F0 1F1EA                                ; fully-qualified     # 🇰🇪 flag: Kenya
+1F1F0 1F1EC                                ; fully-qualified     # 🇰🇬 flag: Kyrgyzstan
+1F1F0 1F1ED                                ; fully-qualified     # 🇰🇭 flag: Cambodia
+1F1F0 1F1EE                                ; fully-qualified     # 🇰🇮 flag: Kiribati
+1F1F0 1F1F2                                ; fully-qualified     # 🇰🇲 flag: Comoros
+1F1F0 1F1F3                                ; fully-qualified     # 🇰🇳 flag: St. Kitts & Nevis
+1F1F0 1F1F5                                ; fully-qualified     # 🇰🇵 flag: North Korea
+1F1F0 1F1F7                                ; fully-qualified     # 🇰🇷 flag: South Korea
+1F1F0 1F1FC                                ; fully-qualified     # 🇰🇼 flag: Kuwait
+1F1F0 1F1FE                                ; fully-qualified     # 🇰🇾 flag: Cayman Islands
+1F1F0 1F1FF                                ; fully-qualified     # 🇰🇿 flag: Kazakhstan
+1F1F1 1F1E6                                ; fully-qualified     # 🇱🇦 flag: Laos
+1F1F1 1F1E7                                ; fully-qualified     # 🇱🇧 flag: Lebanon
+1F1F1 1F1E8                                ; fully-qualified     # 🇱🇨 flag: St. Lucia
+1F1F1 1F1EE                                ; fully-qualified     # 🇱🇮 flag: Liechtenstein
+1F1F1 1F1F0                                ; fully-qualified     # 🇱🇰 flag: Sri Lanka
+1F1F1 1F1F7                                ; fully-qualified     # 🇱🇷 flag: Liberia
+1F1F1 1F1F8                                ; fully-qualified     # 🇱🇸 flag: Lesotho
+1F1F1 1F1F9                                ; fully-qualified     # 🇱🇹 flag: Lithuania
+1F1F1 1F1FA                                ; fully-qualified     # 🇱🇺 flag: Luxembourg
+1F1F1 1F1FB                                ; fully-qualified     # 🇱🇻 flag: Latvia
+1F1F1 1F1FE                                ; fully-qualified     # 🇱🇾 flag: Libya
+1F1F2 1F1E6                                ; fully-qualified     # 🇲🇦 flag: Morocco
+1F1F2 1F1E8                                ; fully-qualified     # 🇲🇨 flag: Monaco
+1F1F2 1F1E9                                ; fully-qualified     # 🇲🇩 flag: Moldova
+1F1F2 1F1EA                                ; fully-qualified     # 🇲🇪 flag: Montenegro
+1F1F2 1F1EB                                ; fully-qualified     # 🇲🇫 flag: St. Martin
+1F1F2 1F1EC                                ; fully-qualified     # 🇲🇬 flag: Madagascar
+1F1F2 1F1ED                                ; fully-qualified     # 🇲🇭 flag: Marshall Islands
+1F1F2 1F1F0                                ; fully-qualified     # 🇲🇰 flag: Macedonia
+1F1F2 1F1F1                                ; fully-qualified     # 🇲🇱 flag: Mali
+1F1F2 1F1F2                                ; fully-qualified     # 🇲🇲 flag: Myanmar (Burma)
+1F1F2 1F1F3                                ; fully-qualified     # 🇲🇳 flag: Mongolia
+1F1F2 1F1F4                                ; fully-qualified     # 🇲🇴 flag: Macao SAR China
+1F1F2 1F1F5                                ; fully-qualified     # 🇲🇵 flag: Northern Mariana Islands
+1F1F2 1F1F6                                ; fully-qualified     # 🇲🇶 flag: Martinique
+1F1F2 1F1F7                                ; fully-qualified     # 🇲🇷 flag: Mauritania
+1F1F2 1F1F8                                ; fully-qualified     # 🇲🇸 flag: Montserrat
+1F1F2 1F1F9                                ; fully-qualified     # 🇲🇹 flag: Malta
+1F1F2 1F1FA                                ; fully-qualified     # 🇲🇺 flag: Mauritius
+1F1F2 1F1FB                                ; fully-qualified     # 🇲🇻 flag: Maldives
+1F1F2 1F1FC                                ; fully-qualified     # 🇲🇼 flag: Malawi
+1F1F2 1F1FD                                ; fully-qualified     # 🇲🇽 flag: Mexico
+1F1F2 1F1FE                                ; fully-qualified     # 🇲🇾 flag: Malaysia
+1F1F2 1F1FF                                ; fully-qualified     # 🇲🇿 flag: Mozambique
+1F1F3 1F1E6                                ; fully-qualified     # 🇳🇦 flag: Namibia
+1F1F3 1F1E8                                ; fully-qualified     # 🇳🇨 flag: New Caledonia
+1F1F3 1F1EA                                ; fully-qualified     # 🇳🇪 flag: Niger
+1F1F3 1F1EB                                ; fully-qualified     # 🇳🇫 flag: Norfolk Island
+1F1F3 1F1EC                                ; fully-qualified     # 🇳🇬 flag: Nigeria
+1F1F3 1F1EE                                ; fully-qualified     # 🇳🇮 flag: Nicaragua
+1F1F3 1F1F1                                ; fully-qualified     # 🇳🇱 flag: Netherlands
+1F1F3 1F1F4                                ; fully-qualified     # 🇳🇴 flag: Norway
+1F1F3 1F1F5                                ; fully-qualified     # 🇳🇵 flag: Nepal
+1F1F3 1F1F7                                ; fully-qualified     # 🇳🇷 flag: Nauru
+1F1F3 1F1FA                                ; fully-qualified     # 🇳🇺 flag: Niue
+1F1F3 1F1FF                                ; fully-qualified     # 🇳🇿 flag: New Zealand
+1F1F4 1F1F2                                ; fully-qualified     # 🇴🇲 flag: Oman
+1F1F5 1F1E6                                ; fully-qualified     # 🇵🇦 flag: Panama
+1F1F5 1F1EA                                ; fully-qualified     # 🇵🇪 flag: Peru
+1F1F5 1F1EB                                ; fully-qualified     # 🇵🇫 flag: French Polynesia
+1F1F5 1F1EC                                ; fully-qualified     # 🇵🇬 flag: Papua New Guinea
+1F1F5 1F1ED                                ; fully-qualified     # 🇵🇭 flag: Philippines
+1F1F5 1F1F0                                ; fully-qualified     # 🇵🇰 flag: Pakistan
+1F1F5 1F1F1                                ; fully-qualified     # 🇵🇱 flag: Poland
+1F1F5 1F1F2                                ; fully-qualified     # 🇵🇲 flag: St. Pierre & Miquelon
+1F1F5 1F1F3                                ; fully-qualified     # 🇵🇳 flag: Pitcairn Islands
+1F1F5 1F1F7                                ; fully-qualified     # 🇵🇷 flag: Puerto Rico
+1F1F5 1F1F8                                ; fully-qualified     # 🇵🇸 flag: Palestinian Territories
+1F1F5 1F1F9                                ; fully-qualified     # 🇵🇹 flag: Portugal
+1F1F5 1F1FC                                ; fully-qualified     # 🇵🇼 flag: Palau
+1F1F5 1F1FE                                ; fully-qualified     # 🇵🇾 flag: Paraguay
+1F1F6 1F1E6                                ; fully-qualified     # 🇶🇦 flag: Qatar
+1F1F7 1F1EA                                ; fully-qualified     # 🇷🇪 flag: Réunion
+1F1F7 1F1F4                                ; fully-qualified     # 🇷🇴 flag: Romania
+1F1F7 1F1F8                                ; fully-qualified     # 🇷🇸 flag: Serbia
+1F1F7 1F1FA                                ; fully-qualified     # 🇷🇺 flag: Russia
+1F1F7 1F1FC                                ; fully-qualified     # 🇷🇼 flag: Rwanda
+1F1F8 1F1E6                                ; fully-qualified     # 🇸🇦 flag: Saudi Arabia
+1F1F8 1F1E7                                ; fully-qualified     # 🇸🇧 flag: Solomon Islands
+1F1F8 1F1E8                                ; fully-qualified     # 🇸🇨 flag: Seychelles
+1F1F8 1F1E9                                ; fully-qualified     # 🇸🇩 flag: Sudan
+1F1F8 1F1EA                                ; fully-qualified     # 🇸🇪 flag: Sweden
+1F1F8 1F1EC                                ; fully-qualified     # 🇸🇬 flag: Singapore
+1F1F8 1F1ED                                ; fully-qualified     # 🇸🇭 flag: St. Helena
+1F1F8 1F1EE                                ; fully-qualified     # 🇸🇮 flag: Slovenia
+1F1F8 1F1EF                                ; fully-qualified     # 🇸🇯 flag: Svalbard & Jan Mayen
+1F1F8 1F1F0                                ; fully-qualified     # 🇸🇰 flag: Slovakia
+1F1F8 1F1F1                                ; fully-qualified     # 🇸🇱 flag: Sierra Leone
+1F1F8 1F1F2                                ; fully-qualified     # 🇸🇲 flag: San Marino
+1F1F8 1F1F3                                ; fully-qualified     # 🇸🇳 flag: Senegal
+1F1F8 1F1F4                                ; fully-qualified     # 🇸🇴 flag: Somalia
+1F1F8 1F1F7                                ; fully-qualified     # 🇸🇷 flag: Suriname
+1F1F8 1F1F8                                ; fully-qualified     # 🇸🇸 flag: South Sudan
+1F1F8 1F1F9                                ; fully-qualified     # 🇸🇹 flag: São Tomé & Príncipe
+1F1F8 1F1FB                                ; fully-qualified     # 🇸🇻 flag: El Salvador
+1F1F8 1F1FD                                ; fully-qualified     # 🇸🇽 flag: Sint Maarten
+1F1F8 1F1FE                                ; fully-qualified     # 🇸🇾 flag: Syria
+1F1F8 1F1FF                                ; fully-qualified     # 🇸🇿 flag: Eswatini
+1F1F9 1F1E6                                ; fully-qualified     # 🇹🇦 flag: Tristan da Cunha
+1F1F9 1F1E8                                ; fully-qualified     # 🇹🇨 flag: Turks & Caicos Islands
+1F1F9 1F1E9                                ; fully-qualified     # 🇹🇩 flag: Chad
+1F1F9 1F1EB                                ; fully-qualified     # 🇹🇫 flag: French Southern Territories
+1F1F9 1F1EC                                ; fully-qualified     # 🇹🇬 flag: Togo
+1F1F9 1F1ED                                ; fully-qualified     # 🇹🇭 flag: Thailand
+1F1F9 1F1EF                                ; fully-qualified     # 🇹🇯 flag: Tajikistan
+1F1F9 1F1F0                                ; fully-qualified     # 🇹🇰 flag: Tokelau
+1F1F9 1F1F1                                ; fully-qualified     # 🇹🇱 flag: Timor-Leste
+1F1F9 1F1F2                                ; fully-qualified     # 🇹🇲 flag: Turkmenistan
+1F1F9 1F1F3                                ; fully-qualified     # 🇹🇳 flag: Tunisia
+1F1F9 1F1F4                                ; fully-qualified     # 🇹🇴 flag: Tonga
+1F1F9 1F1F7                                ; fully-qualified     # 🇹🇷 flag: Turkey
+1F1F9 1F1F9                                ; fully-qualified     # 🇹🇹 flag: Trinidad & Tobago
+1F1F9 1F1FB                                ; fully-qualified     # 🇹🇻 flag: Tuvalu
+1F1F9 1F1FC                                ; fully-qualified     # 🇹🇼 flag: Taiwan
+1F1F9 1F1FF                                ; fully-qualified     # 🇹🇿 flag: Tanzania
+1F1FA 1F1E6                                ; fully-qualified     # 🇺🇦 flag: Ukraine
+1F1FA 1F1EC                                ; fully-qualified     # 🇺🇬 flag: Uganda
+1F1FA 1F1F2                                ; fully-qualified     # 🇺🇲 flag: U.S. Outlying Islands
+1F1FA 1F1F3                                ; fully-qualified     # 🇺🇳 flag: United Nations
+1F1FA 1F1F8                                ; fully-qualified     # 🇺🇸 flag: United States
+1F1FA 1F1FE                                ; fully-qualified     # 🇺🇾 flag: Uruguay
+1F1FA 1F1FF                                ; fully-qualified     # 🇺🇿 flag: Uzbekistan
+1F1FB 1F1E6                                ; fully-qualified     # 🇻🇦 flag: Vatican City
+1F1FB 1F1E8                                ; fully-qualified     # 🇻🇨 flag: St. Vincent & Grenadines
+1F1FB 1F1EA                                ; fully-qualified     # 🇻🇪 flag: Venezuela
+1F1FB 1F1EC                                ; fully-qualified     # 🇻🇬 flag: British Virgin Islands
+1F1FB 1F1EE                                ; fully-qualified     # 🇻🇮 flag: U.S. Virgin Islands
+1F1FB 1F1F3                                ; fully-qualified     # 🇻🇳 flag: Vietnam
+1F1FB 1F1FA                                ; fully-qualified     # 🇻🇺 flag: Vanuatu
+1F1FC 1F1EB                                ; fully-qualified     # 🇼🇫 flag: Wallis & Futuna
+1F1FC 1F1F8                                ; fully-qualified     # 🇼🇸 flag: Samoa
+1F1FD 1F1F0                                ; fully-qualified     # 🇽🇰 flag: Kosovo
+1F1FE 1F1EA                                ; fully-qualified     # 🇾🇪 flag: Yemen
+1F1FE 1F1F9                                ; fully-qualified     # 🇾🇹 flag: Mayotte
+1F1FF 1F1E6                                ; fully-qualified     # 🇿🇦 flag: South Africa
+1F1FF 1F1F2                                ; fully-qualified     # 🇿🇲 flag: Zambia
+1F1FF 1F1FC                                ; fully-qualified     # 🇿🇼 flag: Zimbabwe
+
+# subgroup: subdivision-flag
+1F3F4 E0067 E0062 E0065 E006E E0067 E007F  ; fully-qualified     # 🏴󠁧󠁢󠁥󠁮󠁧󠁿 flag: England
+1F3F4 E0067 E0062 E0073 E0063 E0074 E007F  ; fully-qualified     # 🏴󠁧󠁢󠁳󠁣󠁴󠁿 flag: Scotland
+1F3F4 E0067 E0062 E0077 E006C E0073 E007F  ; fully-qualified     # 🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales
+
+# Flags subtotal:              271
+# Flags subtotal:              271     w/o modifiers
+
+# Status Counts
+# fully-qualified : 3010
+# minimally-qualified : 571
+# unqualified : 246
+# component : 9
+
+#EOF
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/emoji.plugin.zsh
new file mode 100644 (file)
index 0000000..f9e476e
--- /dev/null
@@ -0,0 +1,110 @@
+# emoji plugin
+#
+# Makes emoji support available within ZSH
+#
+# See the README for documentation.
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+_omz_emoji_plugin_dir="${0:h}"
+
+() {
+
+local LC_ALL=en_US.UTF-8
+
+typeset -gAH emoji_skintone
+
+source "$_omz_emoji_plugin_dir/emoji-char-definitions.zsh"
+unset _omz_emoji_plugin_dir
+
+# These additional emoji are not in the definition file, but are useful in conjunction with it
+
+# This is a combining character that can be placed after any other character to surround
+# it in a "keycap" symbol.
+# The digits 0-9 are already in the emoji table as keycap_digit_<N>, keycap_ten, etc. 
+# It's unclear whether this should be in the $emoji array, because those characters are all ones
+# which can be displayed on their own.
+
+emoji[regional_indicator_symbol_letter_d_regional_indicator_symbol_letter_e]=$'\xF0\x9F\x87\xA9\xF0\x9F\x87\xAA'
+emoji[regional_indicator_symbol_letter_g_regional_indicator_symbol_letter_b]=$'\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7'
+emoji[regional_indicator_symbol_letter_c_regional_indicator_symbol_letter_n]=$'\xF0\x9F\x87\xA8\xF0\x9F\x87\xB3'
+emoji[regional_indicator_symbol_letter_j_regional_indicator_symbol_letter_p]=$'\xF0\x9F\x87\xAF\xF0\x9F\x87\xB5'
+emoji[regional_indicator_symbol_letter_k_regional_indicator_symbol_letter_r]=$'\xF0\x9F\x87\xB0\xF0\x9F\x87\xB7'
+emoji[regional_indicator_symbol_letter_f_regional_indicator_symbol_letter_r]=$'\xF0\x9F\x87\xAB\xF0\x9F\x87\xB7'
+emoji[regional_indicator_symbol_letter_e_regional_indicator_symbol_letter_s]=$'\xF0\x9F\x87\xAA\xF0\x9F\x87\xB8'
+emoji[regional_indicator_symbol_letter_i_regional_indicator_symbol_letter_t]=$'\xF0\x9F\x87\xAE\xF0\x9F\x87\xB9'
+emoji[regional_indicator_symbol_letter_u_regional_indicator_symbol_letter_s]=$'\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8'
+emoji[regional_indicator_symbol_letter_r_regional_indicator_symbol_letter_u]=$'\xF0\x9F\x87\xB7\xF0\x9F\x87\xBA'
+
+# Easier access to skin tone modifiers
+emoji_skintone[1_2]=$'\U1F3FB'
+emoji_skintone[3]=$'\U1F3FC'
+emoji_skintone[4]=$'\U1F3FD'
+emoji_skintone[5]=$'\U1F3FE'
+emoji_skintone[6]=$'\U1F3FF'
+}
+
+# Prints a random emoji character
+#
+#  random_emoji [group]
+#
+function random_emoji() {
+  local group=$1
+  local names
+  if [[ -z "$group" || "$group" == "all" ]]; then
+       names=(${(k)emoji})
+  else
+       names=(${=emoji_groups[$group]})
+  fi
+  local list_size=${#names}
+  [[ $list_size -eq 0 ]] && return 1
+  local random_index=$(( ( RANDOM % $list_size ) + 1 ))
+  local name=${names[$random_index]}
+  if [[ "$group" == "flags" ]]; then 
+    echo ${emoji_flags[$name]}
+  else 
+    echo ${emoji[$name]}
+  fi
+}
+
+# Displays a listing of emoji with their names
+#
+# display_emoji [group]
+#
+function display_emoji() {
+  local group=$1
+  local names
+  if [[ -z "$group" || "$group" == "all" ]]; then
+       names=(${(k)emoji})
+  else
+    names=(${=emoji_groups[$group]})
+  fi
+  # The extra spaces in output here are a hack for readability, since some
+  # terminals treat these emoji chars as single-width.
+  local counter=1
+  for i in $names; do
+    if [[ "$group" == "flags" ]]; then 
+      printf '%s  ' "$emoji_flags[$i]"
+    else 
+      printf '%s  ' "$emoji[$i]" 
+    fi
+    # New line every 20 emoji, to avoid weirdnesses
+    if (($counter % 20 == 0)); then
+      printf "\n" 
+    fi
+    let counter=$counter+1
+  done
+  print
+  for i in $names; do
+    if [[ "$group" == "flags" ]]; then 
+      echo "${emoji_flags[$i]}  = $i"
+    else 
+      echo "${emoji[$i]}  = $i"
+    fi
+  done
+}
+
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/gemoji_db.json b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/gemoji_db.json
new file mode 100644 (file)
index 0000000..9227c26
--- /dev/null
@@ -0,0 +1,21538 @@
+[
+  {
+    "emoji": "😀"
+  , "description": "grinning face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "grinning"
+    ]
+  , "tags": [
+      "smile"
+    , "happy"
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😃"
+  , "description": "grinning face with big eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smiley"
+    ]
+  , "tags": [
+      "happy"
+    , "joy"
+    , "haha"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😄"
+  , "description": "grinning face with smiling eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smile"
+    ]
+  , "tags": [
+      "happy"
+    , "joy"
+    , "laugh"
+    , "pleased"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😁"
+  , "description": "beaming face with smiling eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "grin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😆"
+  , "description": "grinning squinting face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "laughing"
+    , "satisfied"
+    ]
+  , "tags": [
+      "happy"
+    , "haha"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😅"
+  , "description": "grinning face with sweat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sweat_smile"
+    ]
+  , "tags": [
+      "hot"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤣"
+  , "description": "rolling on the floor laughing"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "rofl"
+    ]
+  , "tags": [
+      "lol"
+    , "laughing"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "😂"
+  , "description": "face with tears of joy"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "joy"
+    ]
+  , "tags": [
+      "tears"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙂"
+  , "description": "slightly smiling face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "slightly_smiling_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🙃"
+  , "description": "upside-down face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "upside_down_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "😉"
+  , "description": "winking face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "wink"
+    ]
+  , "tags": [
+      "flirt"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😊"
+  , "description": "smiling face with smiling eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "blush"
+    ]
+  , "tags": [
+      "proud"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😇"
+  , "description": "smiling face with halo"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "innocent"
+    ]
+  , "tags": [
+      "angel"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥰"
+  , "description": "smiling face with hearts"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smiling_face_with_three_hearts"
+    ]
+  , "tags": [
+      "love"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😍"
+  , "description": "smiling face with heart-eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heart_eyes"
+    ]
+  , "tags": [
+      "love"
+    , "crush"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤩"
+  , "description": "star-struck"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "star_struck"
+    ]
+  , "tags": [
+      "eyes"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😘"
+  , "description": "face blowing a kiss"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "kissing_heart"
+    ]
+  , "tags": [
+      "flirt"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😗"
+  , "description": "kissing face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "kissing"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☺️"
+  , "description": "smiling face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "relaxed"
+    ]
+  , "tags": [
+      "blush"
+    , "pleased"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😚"
+  , "description": "kissing face with closed eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "kissing_closed_eyes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😙"
+  , "description": "kissing face with smiling eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "kissing_smiling_eyes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😋"
+  , "description": "face savoring food"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "yum"
+    ]
+  , "tags": [
+      "tongue"
+    , "lick"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😛"
+  , "description": "face with tongue"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "stuck_out_tongue"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😜"
+  , "description": "winking face with tongue"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "stuck_out_tongue_winking_eye"
+    ]
+  , "tags": [
+      "prank"
+    , "silly"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤪"
+  , "description": "zany face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "zany_face"
+    ]
+  , "tags": [
+      "goofy"
+    , "wacky"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😝"
+  , "description": "squinting face with tongue"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "stuck_out_tongue_closed_eyes"
+    ]
+  , "tags": [
+      "prank"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤑"
+  , "description": "money-mouth face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "money_mouth_face"
+    ]
+  , "tags": [
+      "rich"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🤗"
+  , "description": "hugging face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hugs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🤭"
+  , "description": "face with hand over mouth"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hand_over_mouth"
+    ]
+  , "tags": [
+      "quiet"
+    , "whoops"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🤫"
+  , "description": "shushing face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "shushing_face"
+    ]
+  , "tags": [
+      "silence"
+    , "quiet"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🤔"
+  , "description": "thinking face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "thinking"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🤐"
+  , "description": "zipper-mouth face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "zipper_mouth_face"
+    ]
+  , "tags": [
+      "silence"
+    , "hush"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🤨"
+  , "description": "face with raised eyebrow"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "raised_eyebrow"
+    ]
+  , "tags": [
+      "suspicious"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😐"
+  , "description": "neutral face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "neutral_face"
+    ]
+  , "tags": [
+      "meh"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😑"
+  , "description": "expressionless face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "expressionless"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😶"
+  , "description": "face without mouth"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "no_mouth"
+    ]
+  , "tags": [
+      "mute"
+    , "silence"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😏"
+  , "description": "smirking face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smirk"
+    ]
+  , "tags": [
+      "smug"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😒"
+  , "description": "unamused face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "unamused"
+    ]
+  , "tags": [
+      "meh"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙄"
+  , "description": "face with rolling eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "roll_eyes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "😬"
+  , "description": "grimacing face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "grimacing"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤥"
+  , "description": "lying face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "lying_face"
+    ]
+  , "tags": [
+      "liar"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "😌"
+  , "description": "relieved face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "relieved"
+    ]
+  , "tags": [
+      "whew"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😔"
+  , "description": "pensive face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "pensive"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😪"
+  , "description": "sleepy face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sleepy"
+    ]
+  , "tags": [
+      "tired"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤤"
+  , "description": "drooling face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "drooling_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "😴"
+  , "description": "sleeping face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sleeping"
+    ]
+  , "tags": [
+      "zzz"
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😷"
+  , "description": "face with medical mask"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "mask"
+    ]
+  , "tags": [
+      "sick"
+    , "ill"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤒"
+  , "description": "face with thermometer"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "face_with_thermometer"
+    ]
+  , "tags": [
+      "sick"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🤕"
+  , "description": "face with head-bandage"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "face_with_head_bandage"
+    ]
+  , "tags": [
+      "hurt"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🤢"
+  , "description": "nauseated face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "nauseated_face"
+    ]
+  , "tags": [
+      "sick"
+    , "barf"
+    , "disgusted"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🤮"
+  , "description": "face vomiting"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "vomiting_face"
+    ]
+  , "tags": [
+      "barf"
+    , "sick"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🤧"
+  , "description": "sneezing face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sneezing_face"
+    ]
+  , "tags": [
+      "achoo"
+    , "sick"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥵"
+  , "description": "hot face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hot_face"
+    ]
+  , "tags": [
+      "heat"
+    , "sweating"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥶"
+  , "description": "cold face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "cold_face"
+    ]
+  , "tags": [
+      "freezing"
+    , "ice"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥴"
+  , "description": "woozy face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "woozy_face"
+    ]
+  , "tags": [
+      "groggy"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😵"
+  , "description": "dizzy face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "dizzy_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤯"
+  , "description": "exploding head"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "exploding_head"
+    ]
+  , "tags": [
+      "mind"
+    , "blown"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🤠"
+  , "description": "cowboy hat face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "cowboy_hat_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥳"
+  , "description": "partying face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "partying_face"
+    ]
+  , "tags": [
+      "celebration"
+    , "birthday"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😎"
+  , "description": "smiling face with sunglasses"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sunglasses"
+    ]
+  , "tags": [
+      "cool"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤓"
+  , "description": "nerd face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "nerd_face"
+    ]
+  , "tags": [
+      "geek"
+    , "glasses"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🧐"
+  , "description": "face with monocle"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "monocle_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😕"
+  , "description": "confused face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "confused"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😟"
+  , "description": "worried face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "worried"
+    ]
+  , "tags": [
+      "nervous"
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙁"
+  , "description": "slightly frowning face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "slightly_frowning_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☹"
+  , "description": "frowning face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "frowning_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "😮"
+  , "description": "face with open mouth"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "open_mouth"
+    ]
+  , "tags": [
+      "surprise"
+    , "impressed"
+    , "wow"
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😯"
+  , "description": "hushed face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hushed"
+    ]
+  , "tags": [
+      "silence"
+    , "speechless"
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😲"
+  , "description": "astonished face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "astonished"
+    ]
+  , "tags": [
+      "amazed"
+    , "gasp"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😳"
+  , "description": "flushed face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "flushed"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥺"
+  , "description": "pleading face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "pleading_face"
+    ]
+  , "tags": [
+      "puppy"
+    , "eyes"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😦"
+  , "description": "frowning face with open mouth"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "frowning"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😧"
+  , "description": "anguished face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "anguished"
+    ]
+  , "tags": [
+      "stunned"
+    ]
+  , "unicode_version": "6.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😨"
+  , "description": "fearful face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "fearful"
+    ]
+  , "tags": [
+      "scared"
+    , "shocked"
+    , "oops"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😰"
+  , "description": "anxious face with sweat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "cold_sweat"
+    ]
+  , "tags": [
+      "nervous"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😥"
+  , "description": "sad but relieved face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "disappointed_relieved"
+    ]
+  , "tags": [
+      "phew"
+    , "sweat"
+    , "nervous"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😢"
+  , "description": "crying face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "cry"
+    ]
+  , "tags": [
+      "sad"
+    , "tear"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😭"
+  , "description": "loudly crying face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sob"
+    ]
+  , "tags": [
+      "sad"
+    , "cry"
+    , "bawling"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😱"
+  , "description": "face screaming in fear"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "scream"
+    ]
+  , "tags": [
+      "horror"
+    , "shocked"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😖"
+  , "description": "confounded face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "confounded"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😣"
+  , "description": "persevering face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "persevere"
+    ]
+  , "tags": [
+      "struggling"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😞"
+  , "description": "disappointed face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "disappointed"
+    ]
+  , "tags": [
+      "sad"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😓"
+  , "description": "downcast face with sweat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sweat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😩"
+  , "description": "weary face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "weary"
+    ]
+  , "tags": [
+      "tired"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😫"
+  , "description": "tired face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "tired_face"
+    ]
+  , "tags": [
+      "upset"
+    , "whine"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥱"
+  , "description": "yawning face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "yawning_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "😤"
+  , "description": "face with steam from nose"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "triumph"
+    ]
+  , "tags": [
+      "smug"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😡"
+  , "description": "pouting face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "rage"
+    , "pout"
+    ]
+  , "tags": [
+      "angry"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😠"
+  , "description": "angry face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "angry"
+    ]
+  , "tags": [
+      "mad"
+    , "annoyed"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤬"
+  , "description": "face with symbols on mouth"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "cursing_face"
+    ]
+  , "tags": [
+      "foul"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "😈"
+  , "description": "smiling face with horns"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smiling_imp"
+    ]
+  , "tags": [
+      "devil"
+    , "evil"
+    , "horns"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👿"
+  , "description": "angry face with horns"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "imp"
+    ]
+  , "tags": [
+      "angry"
+    , "devil"
+    , "evil"
+    , "horns"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💀"
+  , "description": "skull"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "skull"
+    ]
+  , "tags": [
+      "dead"
+    , "danger"
+    , "poison"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☠"
+  , "description": "skull and crossbones"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "skull_and_crossbones"
+    ]
+  , "tags": [
+      "danger"
+    , "pirate"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💩"
+  , "description": "pile of poo"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hankey"
+    , "poop"
+    , "shit"
+    ]
+  , "tags": [
+      "crap"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤡"
+  , "description": "clown face"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "clown_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "👹"
+  , "description": "ogre"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "japanese_ogre"
+    ]
+  , "tags": [
+      "monster"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👺"
+  , "description": "goblin"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "japanese_goblin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👻"
+  , "description": "ghost"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "ghost"
+    ]
+  , "tags": [
+      "halloween"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👽"
+  , "description": "alien"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "alien"
+    ]
+  , "tags": [
+      "ufo"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👾"
+  , "description": "alien monster"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "space_invader"
+    ]
+  , "tags": [
+      "game"
+    , "retro"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤖"
+  , "description": "robot"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "robot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "😺"
+  , "description": "grinning cat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smiley_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😸"
+  , "description": "grinning cat with smiling eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smile_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😹"
+  , "description": "cat with tears of joy"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "joy_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😻"
+  , "description": "smiling cat with heart-eyes"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heart_eyes_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😼"
+  , "description": "cat with wry smile"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "smirk_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😽"
+  , "description": "kissing cat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "kissing_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙀"
+  , "description": "weary cat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "scream_cat"
+    ]
+  , "tags": [
+      "horror"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😿"
+  , "description": "crying cat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "crying_cat_face"
+    ]
+  , "tags": [
+      "sad"
+    , "tear"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "😾"
+  , "description": "pouting cat"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "pouting_cat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙈"
+  , "description": "see-no-evil monkey"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "see_no_evil"
+    ]
+  , "tags": [
+      "monkey"
+    , "blind"
+    , "ignore"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙉"
+  , "description": "hear-no-evil monkey"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hear_no_evil"
+    ]
+  , "tags": [
+      "monkey"
+    , "deaf"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🙊"
+  , "description": "speak-no-evil monkey"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "speak_no_evil"
+    ]
+  , "tags": [
+      "monkey"
+    , "mute"
+    , "hush"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💋"
+  , "description": "kiss mark"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "kiss"
+    ]
+  , "tags": [
+      "lipstick"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💌"
+  , "description": "love letter"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "love_letter"
+    ]
+  , "tags": [
+      "email"
+    , "envelope"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💘"
+  , "description": "heart with arrow"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "cupid"
+    ]
+  , "tags": [
+      "love"
+    , "heart"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💝"
+  , "description": "heart with ribbon"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "gift_heart"
+    ]
+  , "tags": [
+      "chocolates"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💖"
+  , "description": "sparkling heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sparkling_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💗"
+  , "description": "growing heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heartpulse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💓"
+  , "description": "beating heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heartbeat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💞"
+  , "description": "revolving hearts"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "revolving_hearts"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💕"
+  , "description": "two hearts"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "two_hearts"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💟"
+  , "description": "heart decoration"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heart_decoration"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❣️"
+  , "description": "heart exclamation"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heavy_heart_exclamation"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💔"
+  , "description": "broken heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "broken_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❤️"
+  , "description": "red heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "heart"
+    ]
+  , "tags": [
+      "love"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧡"
+  , "description": "orange heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "orange_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "💛"
+  , "description": "yellow heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "yellow_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💚"
+  , "description": "green heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "green_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💙"
+  , "description": "blue heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "blue_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💜"
+  , "description": "purple heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "purple_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤎"
+  , "description": "brown heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "brown_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🖤"
+  , "description": "black heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "black_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🤍"
+  , "description": "white heart"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "white_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "💯"
+  , "description": "hundred points"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "100"
+    ]
+  , "tags": [
+      "score"
+    , "perfect"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💢"
+  , "description": "anger symbol"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "anger"
+    ]
+  , "tags": [
+      "angry"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💥"
+  , "description": "collision"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "boom"
+    , "collision"
+    ]
+  , "tags": [
+      "explode"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💫"
+  , "description": "dizzy"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "dizzy"
+    ]
+  , "tags": [
+      "star"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💦"
+  , "description": "sweat droplets"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "sweat_drops"
+    ]
+  , "tags": [
+      "water"
+    , "workout"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💨"
+  , "description": "dashing away"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "dash"
+    ]
+  , "tags": [
+      "wind"
+    , "blow"
+    , "fast"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕳"
+  , "description": "hole"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "hole"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💣"
+  , "description": "bomb"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "bomb"
+    ]
+  , "tags": [
+      "boom"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💬"
+  , "description": "speech balloon"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "speech_balloon"
+    ]
+  , "tags": [
+      "comment"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👁️‍🗨️"
+  , "description": "eye in speech bubble"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "eye_speech_bubble"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🗨"
+  , "description": "left speech bubble"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "left_speech_bubble"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🗯"
+  , "description": "right anger bubble"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "right_anger_bubble"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💭"
+  , "description": "thought balloon"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "thought_balloon"
+    ]
+  , "tags": [
+      "thinking"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💤"
+  , "description": "zzz"
+  , "category": "Smileys & Emotion"
+  , "aliases": [
+      "zzz"
+    ]
+  , "tags": [
+      "sleeping"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👋"
+  , "description": "waving hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "wave"
+    ]
+  , "tags": [
+      "goodbye"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤚"
+  , "description": "raised back of hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "raised_back_of_hand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🖐"
+  , "description": "hand with fingers splayed"
+  , "category": "People & Body"
+  , "aliases": [
+      "raised_hand_with_fingers_splayed"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "✋"
+  , "description": "raised hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "hand"
+    , "raised_hand"
+    ]
+  , "tags": [
+      "highfive"
+    , "stop"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🖖"
+  , "description": "vulcan salute"
+  , "category": "People & Body"
+  , "aliases": [
+      "vulcan_salute"
+    ]
+  , "tags": [
+      "prosper"
+    , "spock"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "8.3"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👌"
+  , "description": "OK hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "ok_hand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤏"
+  , "description": "pinching hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "pinching_hand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "✌️"
+  , "description": "victory hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "v"
+    ]
+  , "tags": [
+      "victory"
+    , "peace"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤞"
+  , "description": "crossed fingers"
+  , "category": "People & Body"
+  , "aliases": [
+      "crossed_fingers"
+    ]
+  , "tags": [
+      "luck"
+    , "hopeful"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤟"
+  , "description": "love-you gesture"
+  , "category": "People & Body"
+  , "aliases": [
+      "love_you_gesture"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤘"
+  , "description": "sign of the horns"
+  , "category": "People & Body"
+  , "aliases": [
+      "metal"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤙"
+  , "description": "call me hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "call_me_hand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👈"
+  , "description": "backhand index pointing left"
+  , "category": "People & Body"
+  , "aliases": [
+      "point_left"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👉"
+  , "description": "backhand index pointing right"
+  , "category": "People & Body"
+  , "aliases": [
+      "point_right"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👆"
+  , "description": "backhand index pointing up"
+  , "category": "People & Body"
+  , "aliases": [
+      "point_up_2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🖕"
+  , "description": "middle finger"
+  , "category": "People & Body"
+  , "aliases": [
+      "middle_finger"
+    , "fu"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👇"
+  , "description": "backhand index pointing down"
+  , "category": "People & Body"
+  , "aliases": [
+      "point_down"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "☝️"
+  , "description": "index pointing up"
+  , "category": "People & Body"
+  , "aliases": [
+      "point_up"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👍"
+  , "description": "thumbs up"
+  , "category": "People & Body"
+  , "aliases": [
+      "+1"
+    , "thumbsup"
+    ]
+  , "tags": [
+      "approve"
+    , "ok"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👎"
+  , "description": "thumbs down"
+  , "category": "People & Body"
+  , "aliases": [
+      "-1"
+    , "thumbsdown"
+    ]
+  , "tags": [
+      "disapprove"
+    , "bury"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "✊"
+  , "description": "raised fist"
+  , "category": "People & Body"
+  , "aliases": [
+      "fist_raised"
+    , "fist"
+    ]
+  , "tags": [
+      "power"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👊"
+  , "description": "oncoming fist"
+  , "category": "People & Body"
+  , "aliases": [
+      "fist_oncoming"
+    , "facepunch"
+    , "punch"
+    ]
+  , "tags": [
+      "attack"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤛"
+  , "description": "left-facing fist"
+  , "category": "People & Body"
+  , "aliases": [
+      "fist_left"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤜"
+  , "description": "right-facing fist"
+  , "category": "People & Body"
+  , "aliases": [
+      "fist_right"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👏"
+  , "description": "clapping hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "clap"
+    ]
+  , "tags": [
+      "praise"
+    , "applause"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙌"
+  , "description": "raising hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "raised_hands"
+    ]
+  , "tags": [
+      "hooray"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👐"
+  , "description": "open hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "open_hands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤲"
+  , "description": "palms up together"
+  , "category": "People & Body"
+  , "aliases": [
+      "palms_up_together"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤝"
+  , "description": "handshake"
+  , "category": "People & Body"
+  , "aliases": [
+      "handshake"
+    ]
+  , "tags": [
+      "deal"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🙏"
+  , "description": "folded hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "pray"
+    ]
+  , "tags": [
+      "please"
+    , "hope"
+    , "wish"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "✍️"
+  , "description": "writing hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "writing_hand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💅"
+  , "description": "nail polish"
+  , "category": "People & Body"
+  , "aliases": [
+      "nail_care"
+    ]
+  , "tags": [
+      "beauty"
+    , "manicure"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤳"
+  , "description": "selfie"
+  , "category": "People & Body"
+  , "aliases": [
+      "selfie"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💪"
+  , "description": "flexed biceps"
+  , "category": "People & Body"
+  , "aliases": [
+      "muscle"
+    ]
+  , "tags": [
+      "flex"
+    , "bicep"
+    , "strong"
+    , "workout"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦾"
+  , "description": "mechanical arm"
+  , "category": "People & Body"
+  , "aliases": [
+      "mechanical_arm"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦿"
+  , "description": "mechanical leg"
+  , "category": "People & Body"
+  , "aliases": [
+      "mechanical_leg"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦵"
+  , "description": "leg"
+  , "category": "People & Body"
+  , "aliases": [
+      "leg"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦶"
+  , "description": "foot"
+  , "category": "People & Body"
+  , "aliases": [
+      "foot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👂"
+  , "description": "ear"
+  , "category": "People & Body"
+  , "aliases": [
+      "ear"
+    ]
+  , "tags": [
+      "hear"
+    , "sound"
+    , "listen"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦻"
+  , "description": "ear with hearing aid"
+  , "category": "People & Body"
+  , "aliases": [
+      "ear_with_hearing_aid"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👃"
+  , "description": "nose"
+  , "category": "People & Body"
+  , "aliases": [
+      "nose"
+    ]
+  , "tags": [
+      "smell"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧠"
+  , "description": "brain"
+  , "category": "People & Body"
+  , "aliases": [
+      "brain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦷"
+  , "description": "tooth"
+  , "category": "People & Body"
+  , "aliases": [
+      "tooth"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦴"
+  , "description": "bone"
+  , "category": "People & Body"
+  , "aliases": [
+      "bone"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👀"
+  , "description": "eyes"
+  , "category": "People & Body"
+  , "aliases": [
+      "eyes"
+    ]
+  , "tags": [
+      "look"
+    , "see"
+    , "watch"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👁"
+  , "description": "eye"
+  , "category": "People & Body"
+  , "aliases": [
+      "eye"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "👅"
+  , "description": "tongue"
+  , "category": "People & Body"
+  , "aliases": [
+      "tongue"
+    ]
+  , "tags": [
+      "taste"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👄"
+  , "description": "mouth"
+  , "category": "People & Body"
+  , "aliases": [
+      "lips"
+    ]
+  , "tags": [
+      "kiss"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👶"
+  , "description": "baby"
+  , "category": "People & Body"
+  , "aliases": [
+      "baby"
+    ]
+  , "tags": [
+      "child"
+    , "newborn"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧒"
+  , "description": "child"
+  , "category": "People & Body"
+  , "aliases": [
+      "child"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👦"
+  , "description": "boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "boy"
+    ]
+  , "tags": [
+      "child"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👧"
+  , "description": "girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "girl"
+    ]
+  , "tags": [
+      "child"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧑"
+  , "description": "person"
+  , "category": "People & Body"
+  , "aliases": [
+      "adult"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👱"
+  , "description": "person: blond hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "blond_haired_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨"
+  , "description": "man"
+  , "category": "People & Body"
+  , "aliases": [
+      "man"
+    ]
+  , "tags": [
+      "mustache"
+    , "father"
+    , "dad"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧔"
+  , "description": "man: beard"
+  , "category": "People & Body"
+  , "aliases": [
+      "bearded_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👱‍♂"
+  , "description": "man: blond hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "blond_haired_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦰"
+  , "description": "man: red hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "red_haired_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦱"
+  , "description": "man: curly hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "curly_haired_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦳"
+  , "description": "man: white hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "white_haired_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦲"
+  , "description": "man: bald"
+  , "category": "People & Body"
+  , "aliases": [
+      "bald_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩"
+  , "description": "woman"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman"
+    ]
+  , "tags": [
+      "girls"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👱‍♀"
+  , "description": "woman: blond hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "blond_haired_woman"
+    , "blonde_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦰"
+  , "description": "woman: red hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "red_haired_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦱"
+  , "description": "woman: curly hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "curly_haired_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦳"
+  , "description": "woman: white hair"
+  , "category": "People & Body"
+  , "aliases": [
+      "white_haired_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦲"
+  , "description": "woman: bald"
+  , "category": "People & Body"
+  , "aliases": [
+      "bald_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧓"
+  , "description": "older person"
+  , "category": "People & Body"
+  , "aliases": [
+      "older_adult"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👴"
+  , "description": "old man"
+  , "category": "People & Body"
+  , "aliases": [
+      "older_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👵"
+  , "description": "old woman"
+  , "category": "People & Body"
+  , "aliases": [
+      "older_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙍"
+  , "description": "person frowning"
+  , "category": "People & Body"
+  , "aliases": [
+      "frowning_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙍‍♂"
+  , "description": "man frowning"
+  , "category": "People & Body"
+  , "aliases": [
+      "frowning_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙍‍♀"
+  , "description": "woman frowning"
+  , "category": "People & Body"
+  , "aliases": [
+      "frowning_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙎"
+  , "description": "person pouting"
+  , "category": "People & Body"
+  , "aliases": [
+      "pouting_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙎‍♂"
+  , "description": "man pouting"
+  , "category": "People & Body"
+  , "aliases": [
+      "pouting_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙎‍♀"
+  , "description": "woman pouting"
+  , "category": "People & Body"
+  , "aliases": [
+      "pouting_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙅"
+  , "description": "person gesturing NO"
+  , "category": "People & Body"
+  , "aliases": [
+      "no_good"
+    ]
+  , "tags": [
+      "stop"
+    , "halt"
+    , "denied"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙅‍♂"
+  , "description": "man gesturing NO"
+  , "category": "People & Body"
+  , "aliases": [
+      "no_good_man"
+    , "ng_man"
+    ]
+  , "tags": [
+      "stop"
+    , "halt"
+    , "denied"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙅‍♀"
+  , "description": "woman gesturing NO"
+  , "category": "People & Body"
+  , "aliases": [
+      "no_good_woman"
+    , "ng_woman"
+    ]
+  , "tags": [
+      "stop"
+    , "halt"
+    , "denied"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙆"
+  , "description": "person gesturing OK"
+  , "category": "People & Body"
+  , "aliases": [
+      "ok_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙆‍♂"
+  , "description": "man gesturing OK"
+  , "category": "People & Body"
+  , "aliases": [
+      "ok_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙆‍♀"
+  , "description": "woman gesturing OK"
+  , "category": "People & Body"
+  , "aliases": [
+      "ok_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💁"
+  , "description": "person tipping hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "tipping_hand_person"
+    , "information_desk_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💁‍♂"
+  , "description": "man tipping hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "tipping_hand_man"
+    , "sassy_man"
+    ]
+  , "tags": [
+      "information"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💁‍♀"
+  , "description": "woman tipping hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "tipping_hand_woman"
+    , "sassy_woman"
+    ]
+  , "tags": [
+      "information"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙋"
+  , "description": "person raising hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "raising_hand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙋‍♂"
+  , "description": "man raising hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "raising_hand_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙋‍♀"
+  , "description": "woman raising hand"
+  , "category": "People & Body"
+  , "aliases": [
+      "raising_hand_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧏"
+  , "description": "deaf person"
+  , "category": "People & Body"
+  , "aliases": [
+      "deaf_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧏‍♂"
+  , "description": "deaf man"
+  , "category": "People & Body"
+  , "aliases": [
+      "deaf_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧏‍♀"
+  , "description": "deaf woman"
+  , "category": "People & Body"
+  , "aliases": [
+      "deaf_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙇"
+  , "description": "person bowing"
+  , "category": "People & Body"
+  , "aliases": [
+      "bow"
+    ]
+  , "tags": [
+      "respect"
+    , "thanks"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙇‍♂"
+  , "description": "man bowing"
+  , "category": "People & Body"
+  , "aliases": [
+      "bowing_man"
+    ]
+  , "tags": [
+      "respect"
+    , "thanks"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🙇‍♀"
+  , "description": "woman bowing"
+  , "category": "People & Body"
+  , "aliases": [
+      "bowing_woman"
+    ]
+  , "tags": [
+      "respect"
+    , "thanks"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤦"
+  , "description": "person facepalming"
+  , "category": "People & Body"
+  , "aliases": [
+      "facepalm"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤦‍♂"
+  , "description": "man facepalming"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_facepalming"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤦‍♀"
+  , "description": "woman facepalming"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_facepalming"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤷"
+  , "description": "person shrugging"
+  , "category": "People & Body"
+  , "aliases": [
+      "shrug"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤷‍♂"
+  , "description": "man shrugging"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_shrugging"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤷‍♀"
+  , "description": "woman shrugging"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_shrugging"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍⚕"
+  , "description": "man health worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_health_worker"
+    ]
+  , "tags": [
+      "doctor"
+    , "nurse"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍⚕"
+  , "description": "woman health worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_health_worker"
+    ]
+  , "tags": [
+      "doctor"
+    , "nurse"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🎓"
+  , "description": "man student"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_student"
+    ]
+  , "tags": [
+      "graduation"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🎓"
+  , "description": "woman student"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_student"
+    ]
+  , "tags": [
+      "graduation"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🏫"
+  , "description": "man teacher"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_teacher"
+    ]
+  , "tags": [
+      "school"
+    , "professor"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🏫"
+  , "description": "woman teacher"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_teacher"
+    ]
+  , "tags": [
+      "school"
+    , "professor"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍⚖"
+  , "description": "man judge"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_judge"
+    ]
+  , "tags": [
+      "justice"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍⚖"
+  , "description": "woman judge"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_judge"
+    ]
+  , "tags": [
+      "justice"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🌾"
+  , "description": "man farmer"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_farmer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🌾"
+  , "description": "woman farmer"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_farmer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🍳"
+  , "description": "man cook"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_cook"
+    ]
+  , "tags": [
+      "chef"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🍳"
+  , "description": "woman cook"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_cook"
+    ]
+  , "tags": [
+      "chef"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🔧"
+  , "description": "man mechanic"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_mechanic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🔧"
+  , "description": "woman mechanic"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_mechanic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🏭"
+  , "description": "man factory worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_factory_worker"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🏭"
+  , "description": "woman factory worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_factory_worker"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍💼"
+  , "description": "man office worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_office_worker"
+    ]
+  , "tags": [
+      "business"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍💼"
+  , "description": "woman office worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_office_worker"
+    ]
+  , "tags": [
+      "business"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🔬"
+  , "description": "man scientist"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_scientist"
+    ]
+  , "tags": [
+      "research"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🔬"
+  , "description": "woman scientist"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_scientist"
+    ]
+  , "tags": [
+      "research"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍💻"
+  , "description": "man technologist"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_technologist"
+    ]
+  , "tags": [
+      "coder"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍💻"
+  , "description": "woman technologist"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_technologist"
+    ]
+  , "tags": [
+      "coder"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🎤"
+  , "description": "man singer"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_singer"
+    ]
+  , "tags": [
+      "rockstar"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🎤"
+  , "description": "woman singer"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_singer"
+    ]
+  , "tags": [
+      "rockstar"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🎨"
+  , "description": "man artist"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_artist"
+    ]
+  , "tags": [
+      "painter"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🎨"
+  , "description": "woman artist"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_artist"
+    ]
+  , "tags": [
+      "painter"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍✈"
+  , "description": "man pilot"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_pilot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍✈"
+  , "description": "woman pilot"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_pilot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🚀"
+  , "description": "man astronaut"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_astronaut"
+    ]
+  , "tags": [
+      "space"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🚀"
+  , "description": "woman astronaut"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_astronaut"
+    ]
+  , "tags": [
+      "space"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🚒"
+  , "description": "man firefighter"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_firefighter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🚒"
+  , "description": "woman firefighter"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_firefighter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👮"
+  , "description": "police officer"
+  , "category": "People & Body"
+  , "aliases": [
+      "police_officer"
+    , "cop"
+    ]
+  , "tags": [
+      "law"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👮‍♂"
+  , "description": "man police officer"
+  , "category": "People & Body"
+  , "aliases": [
+      "policeman"
+    ]
+  , "tags": [
+      "law"
+    , "cop"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👮‍♀"
+  , "description": "woman police officer"
+  , "category": "People & Body"
+  , "aliases": [
+      "policewoman"
+    ]
+  , "tags": [
+      "law"
+    , "cop"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🕵"
+  , "description": "detective"
+  , "category": "People & Body"
+  , "aliases": [
+      "detective"
+    ]
+  , "tags": [
+      "sleuth"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🕵️‍♂️"
+  , "description": "man detective"
+  , "category": "People & Body"
+  , "aliases": [
+      "male_detective"
+    ]
+  , "tags": [
+      "sleuth"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🕵️‍♀️"
+  , "description": "woman detective"
+  , "category": "People & Body"
+  , "aliases": [
+      "female_detective"
+    ]
+  , "tags": [
+      "sleuth"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💂"
+  , "description": "guard"
+  , "category": "People & Body"
+  , "aliases": [
+      "guard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💂‍♂"
+  , "description": "man guard"
+  , "category": "People & Body"
+  , "aliases": [
+      "guardsman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💂‍♀"
+  , "description": "woman guard"
+  , "category": "People & Body"
+  , "aliases": [
+      "guardswoman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👷"
+  , "description": "construction worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "construction_worker"
+    ]
+  , "tags": [
+      "helmet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👷‍♂"
+  , "description": "man construction worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "construction_worker_man"
+    ]
+  , "tags": [
+      "helmet"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👷‍♀"
+  , "description": "woman construction worker"
+  , "category": "People & Body"
+  , "aliases": [
+      "construction_worker_woman"
+    ]
+  , "tags": [
+      "helmet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤴"
+  , "description": "prince"
+  , "category": "People & Body"
+  , "aliases": [
+      "prince"
+    ]
+  , "tags": [
+      "crown"
+    , "royal"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👸"
+  , "description": "princess"
+  , "category": "People & Body"
+  , "aliases": [
+      "princess"
+    ]
+  , "tags": [
+      "crown"
+    , "royal"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👳"
+  , "description": "person wearing turban"
+  , "category": "People & Body"
+  , "aliases": [
+      "person_with_turban"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👳‍♂"
+  , "description": "man wearing turban"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_with_turban"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👳‍♀"
+  , "description": "woman wearing turban"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_with_turban"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👲"
+  , "description": "man with Chinese cap"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_with_gua_pi_mao"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧕"
+  , "description": "woman with headscarf"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_with_headscarf"
+    ]
+  , "tags": [
+      "hijab"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤵"
+  , "description": "man in tuxedo"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_in_tuxedo"
+    ]
+  , "tags": [
+      "groom"
+    , "marriage"
+    , "wedding"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👰"
+  , "description": "bride with veil"
+  , "category": "People & Body"
+  , "aliases": [
+      "bride_with_veil"
+    ]
+  , "tags": [
+      "marriage"
+    , "wedding"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤰"
+  , "description": "pregnant woman"
+  , "category": "People & Body"
+  , "aliases": [
+      "pregnant_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤱"
+  , "description": "breast-feeding"
+  , "category": "People & Body"
+  , "aliases": [
+      "breast_feeding"
+    ]
+  , "tags": [
+      "nursing"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👼"
+  , "description": "baby angel"
+  , "category": "People & Body"
+  , "aliases": [
+      "angel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🎅"
+  , "description": "Santa Claus"
+  , "category": "People & Body"
+  , "aliases": [
+      "santa"
+    ]
+  , "tags": [
+      "christmas"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤶"
+  , "description": "Mrs. Claus"
+  , "category": "People & Body"
+  , "aliases": [
+      "mrs_claus"
+    ]
+  , "tags": [
+      "santa"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦸"
+  , "description": "superhero"
+  , "category": "People & Body"
+  , "aliases": [
+      "superhero"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦸‍♂"
+  , "description": "man superhero"
+  , "category": "People & Body"
+  , "aliases": [
+      "superhero_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦸‍♀"
+  , "description": "woman superhero"
+  , "category": "People & Body"
+  , "aliases": [
+      "superhero_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦹"
+  , "description": "supervillain"
+  , "category": "People & Body"
+  , "aliases": [
+      "supervillain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦹‍♂"
+  , "description": "man supervillain"
+  , "category": "People & Body"
+  , "aliases": [
+      "supervillain_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🦹‍♀"
+  , "description": "woman supervillain"
+  , "category": "People & Body"
+  , "aliases": [
+      "supervillain_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧙"
+  , "description": "mage"
+  , "category": "People & Body"
+  , "aliases": [
+      "mage"
+    ]
+  , "tags": [
+      "wizard"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧙‍♂"
+  , "description": "man mage"
+  , "category": "People & Body"
+  , "aliases": [
+      "mage_man"
+    ]
+  , "tags": [
+      "wizard"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧙‍♀"
+  , "description": "woman mage"
+  , "category": "People & Body"
+  , "aliases": [
+      "mage_woman"
+    ]
+  , "tags": [
+      "wizard"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧚"
+  , "description": "fairy"
+  , "category": "People & Body"
+  , "aliases": [
+      "fairy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧚‍♂"
+  , "description": "man fairy"
+  , "category": "People & Body"
+  , "aliases": [
+      "fairy_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧚‍♀"
+  , "description": "woman fairy"
+  , "category": "People & Body"
+  , "aliases": [
+      "fairy_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧛"
+  , "description": "vampire"
+  , "category": "People & Body"
+  , "aliases": [
+      "vampire"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧛‍♂"
+  , "description": "man vampire"
+  , "category": "People & Body"
+  , "aliases": [
+      "vampire_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧛‍♀"
+  , "description": "woman vampire"
+  , "category": "People & Body"
+  , "aliases": [
+      "vampire_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧜"
+  , "description": "merperson"
+  , "category": "People & Body"
+  , "aliases": [
+      "merperson"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧜‍♂"
+  , "description": "merman"
+  , "category": "People & Body"
+  , "aliases": [
+      "merman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧜‍♀"
+  , "description": "mermaid"
+  , "category": "People & Body"
+  , "aliases": [
+      "mermaid"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧝"
+  , "description": "elf"
+  , "category": "People & Body"
+  , "aliases": [
+      "elf"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧝‍♂"
+  , "description": "man elf"
+  , "category": "People & Body"
+  , "aliases": [
+      "elf_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧝‍♀"
+  , "description": "woman elf"
+  , "category": "People & Body"
+  , "aliases": [
+      "elf_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧞"
+  , "description": "genie"
+  , "category": "People & Body"
+  , "aliases": [
+      "genie"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧞‍♂"
+  , "description": "man genie"
+  , "category": "People & Body"
+  , "aliases": [
+      "genie_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧞‍♀"
+  , "description": "woman genie"
+  , "category": "People & Body"
+  , "aliases": [
+      "genie_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧟"
+  , "description": "zombie"
+  , "category": "People & Body"
+  , "aliases": [
+      "zombie"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧟‍♂"
+  , "description": "man zombie"
+  , "category": "People & Body"
+  , "aliases": [
+      "zombie_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧟‍♀"
+  , "description": "woman zombie"
+  , "category": "People & Body"
+  , "aliases": [
+      "zombie_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "💆"
+  , "description": "person getting massage"
+  , "category": "People & Body"
+  , "aliases": [
+      "massage"
+    ]
+  , "tags": [
+      "spa"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💆‍♂"
+  , "description": "man getting massage"
+  , "category": "People & Body"
+  , "aliases": [
+      "massage_man"
+    ]
+  , "tags": [
+      "spa"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💆‍♀"
+  , "description": "woman getting massage"
+  , "category": "People & Body"
+  , "aliases": [
+      "massage_woman"
+    ]
+  , "tags": [
+      "spa"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💇"
+  , "description": "person getting haircut"
+  , "category": "People & Body"
+  , "aliases": [
+      "haircut"
+    ]
+  , "tags": [
+      "beauty"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💇‍♂"
+  , "description": "man getting haircut"
+  , "category": "People & Body"
+  , "aliases": [
+      "haircut_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💇‍♀"
+  , "description": "woman getting haircut"
+  , "category": "People & Body"
+  , "aliases": [
+      "haircut_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚶"
+  , "description": "person walking"
+  , "category": "People & Body"
+  , "aliases": [
+      "walking"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚶‍♂"
+  , "description": "man walking"
+  , "category": "People & Body"
+  , "aliases": [
+      "walking_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚶‍♀"
+  , "description": "woman walking"
+  , "category": "People & Body"
+  , "aliases": [
+      "walking_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧍"
+  , "description": "person standing"
+  , "category": "People & Body"
+  , "aliases": [
+      "standing_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧍‍♂"
+  , "description": "man standing"
+  , "category": "People & Body"
+  , "aliases": [
+      "standing_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧍‍♀"
+  , "description": "woman standing"
+  , "category": "People & Body"
+  , "aliases": [
+      "standing_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧎"
+  , "description": "person kneeling"
+  , "category": "People & Body"
+  , "aliases": [
+      "kneeling_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧎‍♂"
+  , "description": "man kneeling"
+  , "category": "People & Body"
+  , "aliases": [
+      "kneeling_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧎‍♀"
+  , "description": "woman kneeling"
+  , "category": "People & Body"
+  , "aliases": [
+      "kneeling_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦯"
+  , "description": "man with probing cane"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_with_probing_cane"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦯"
+  , "description": "woman with probing cane"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_with_probing_cane"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦼"
+  , "description": "man in motorized wheelchair"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_in_motorized_wheelchair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦼"
+  , "description": "woman in motorized wheelchair"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_in_motorized_wheelchair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👨‍🦽"
+  , "description": "man in manual wheelchair"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_in_manual_wheelchair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👩‍🦽"
+  , "description": "woman in manual wheelchair"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_in_manual_wheelchair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏃"
+  , "description": "person running"
+  , "category": "People & Body"
+  , "aliases": [
+      "runner"
+    , "running"
+    ]
+  , "tags": [
+      "exercise"
+    , "workout"
+    , "marathon"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏃‍♂"
+  , "description": "man running"
+  , "category": "People & Body"
+  , "aliases": [
+      "running_man"
+    ]
+  , "tags": [
+      "exercise"
+    , "workout"
+    , "marathon"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏃‍♀"
+  , "description": "woman running"
+  , "category": "People & Body"
+  , "aliases": [
+      "running_woman"
+    ]
+  , "tags": [
+      "exercise"
+    , "workout"
+    , "marathon"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💃"
+  , "description": "woman dancing"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_dancing"
+    , "dancer"
+    ]
+  , "tags": [
+      "dress"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🕺"
+  , "description": "man dancing"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_dancing"
+    ]
+  , "tags": [
+      "dancer"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🕴"
+  , "description": "man in suit levitating"
+  , "category": "People & Body"
+  , "aliases": [
+      "business_suit_levitating"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👯"
+  , "description": "people with bunny ears"
+  , "category": "People & Body"
+  , "aliases": [
+      "dancers"
+    ]
+  , "tags": [
+      "bunny"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👯‍♂"
+  , "description": "men with bunny ears"
+  , "category": "People & Body"
+  , "aliases": [
+      "dancing_men"
+    ]
+  , "tags": [
+      "bunny"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👯‍♀"
+  , "description": "women with bunny ears"
+  , "category": "People & Body"
+  , "aliases": [
+      "dancing_women"
+    ]
+  , "tags": [
+      "bunny"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧖"
+  , "description": "person in steamy room"
+  , "category": "People & Body"
+  , "aliases": [
+      "sauna_person"
+    ]
+  , "tags": [
+      "steamy"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧖‍♂"
+  , "description": "man in steamy room"
+  , "category": "People & Body"
+  , "aliases": [
+      "sauna_man"
+    ]
+  , "tags": [
+      "steamy"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧖‍♀"
+  , "description": "woman in steamy room"
+  , "category": "People & Body"
+  , "aliases": [
+      "sauna_woman"
+    ]
+  , "tags": [
+      "steamy"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧗"
+  , "description": "person climbing"
+  , "category": "People & Body"
+  , "aliases": [
+      "climbing"
+    ]
+  , "tags": [
+      "bouldering"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧗‍♂"
+  , "description": "man climbing"
+  , "category": "People & Body"
+  , "aliases": [
+      "climbing_man"
+    ]
+  , "tags": [
+      "bouldering"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧗‍♀"
+  , "description": "woman climbing"
+  , "category": "People & Body"
+  , "aliases": [
+      "climbing_woman"
+    ]
+  , "tags": [
+      "bouldering"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤺"
+  , "description": "person fencing"
+  , "category": "People & Body"
+  , "aliases": [
+      "person_fencing"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🏇"
+  , "description": "horse racing"
+  , "category": "People & Body"
+  , "aliases": [
+      "horse_racing"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "⛷"
+  , "description": "skier"
+  , "category": "People & Body"
+  , "aliases": [
+      "skier"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏂"
+  , "description": "snowboarder"
+  , "category": "People & Body"
+  , "aliases": [
+      "snowboarder"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏌"
+  , "description": "person golfing"
+  , "category": "People & Body"
+  , "aliases": [
+      "golfing"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏌️‍♂️"
+  , "description": "man golfing"
+  , "category": "People & Body"
+  , "aliases": [
+      "golfing_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏌️‍♀️"
+  , "description": "woman golfing"
+  , "category": "People & Body"
+  , "aliases": [
+      "golfing_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏄"
+  , "description": "person surfing"
+  , "category": "People & Body"
+  , "aliases": [
+      "surfer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏄‍♂"
+  , "description": "man surfing"
+  , "category": "People & Body"
+  , "aliases": [
+      "surfing_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏄‍♀"
+  , "description": "woman surfing"
+  , "category": "People & Body"
+  , "aliases": [
+      "surfing_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚣"
+  , "description": "person rowing boat"
+  , "category": "People & Body"
+  , "aliases": [
+      "rowboat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚣‍♂"
+  , "description": "man rowing boat"
+  , "category": "People & Body"
+  , "aliases": [
+      "rowing_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚣‍♀"
+  , "description": "woman rowing boat"
+  , "category": "People & Body"
+  , "aliases": [
+      "rowing_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏊"
+  , "description": "person swimming"
+  , "category": "People & Body"
+  , "aliases": [
+      "swimmer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏊‍♂"
+  , "description": "man swimming"
+  , "category": "People & Body"
+  , "aliases": [
+      "swimming_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏊‍♀"
+  , "description": "woman swimming"
+  , "category": "People & Body"
+  , "aliases": [
+      "swimming_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "⛹"
+  , "description": "person bouncing ball"
+  , "category": "People & Body"
+  , "aliases": [
+      "bouncing_ball_person"
+    ]
+  , "tags": [
+      "basketball"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "⛹️‍♂️"
+  , "description": "man bouncing ball"
+  , "category": "People & Body"
+  , "aliases": [
+      "bouncing_ball_man"
+    , "basketball_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "⛹️‍♀️"
+  , "description": "woman bouncing ball"
+  , "category": "People & Body"
+  , "aliases": [
+      "bouncing_ball_woman"
+    , "basketball_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏋"
+  , "description": "person lifting weights"
+  , "category": "People & Body"
+  , "aliases": [
+      "weight_lifting"
+    ]
+  , "tags": [
+      "gym"
+    , "workout"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏋️‍♂️"
+  , "description": "man lifting weights"
+  , "category": "People & Body"
+  , "aliases": [
+      "weight_lifting_man"
+    ]
+  , "tags": [
+      "gym"
+    , "workout"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🏋️‍♀️"
+  , "description": "woman lifting weights"
+  , "category": "People & Body"
+  , "aliases": [
+      "weight_lifting_woman"
+    ]
+  , "tags": [
+      "gym"
+    , "workout"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚴"
+  , "description": "person biking"
+  , "category": "People & Body"
+  , "aliases": [
+      "bicyclist"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚴‍♂"
+  , "description": "man biking"
+  , "category": "People & Body"
+  , "aliases": [
+      "biking_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚴‍♀"
+  , "description": "woman biking"
+  , "category": "People & Body"
+  , "aliases": [
+      "biking_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚵"
+  , "description": "person mountain biking"
+  , "category": "People & Body"
+  , "aliases": [
+      "mountain_bicyclist"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚵‍♂"
+  , "description": "man mountain biking"
+  , "category": "People & Body"
+  , "aliases": [
+      "mountain_biking_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🚵‍♀"
+  , "description": "woman mountain biking"
+  , "category": "People & Body"
+  , "aliases": [
+      "mountain_biking_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤸"
+  , "description": "person cartwheeling"
+  , "category": "People & Body"
+  , "aliases": [
+      "cartwheeling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤸‍♂"
+  , "description": "man cartwheeling"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_cartwheeling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤸‍♀"
+  , "description": "woman cartwheeling"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_cartwheeling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤼"
+  , "description": "people wrestling"
+  , "category": "People & Body"
+  , "aliases": [
+      "wrestling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🤼‍♂"
+  , "description": "men wrestling"
+  , "category": "People & Body"
+  , "aliases": [
+      "men_wrestling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🤼‍♀"
+  , "description": "women wrestling"
+  , "category": "People & Body"
+  , "aliases": [
+      "women_wrestling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🤽"
+  , "description": "person playing water polo"
+  , "category": "People & Body"
+  , "aliases": [
+      "water_polo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤽‍♂"
+  , "description": "man playing water polo"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_playing_water_polo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤽‍♀"
+  , "description": "woman playing water polo"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_playing_water_polo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤾"
+  , "description": "person playing handball"
+  , "category": "People & Body"
+  , "aliases": [
+      "handball_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤾‍♂"
+  , "description": "man playing handball"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_playing_handball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤾‍♀"
+  , "description": "woman playing handball"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_playing_handball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤹"
+  , "description": "person juggling"
+  , "category": "People & Body"
+  , "aliases": [
+      "juggling_person"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤹‍♂"
+  , "description": "man juggling"
+  , "category": "People & Body"
+  , "aliases": [
+      "man_juggling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🤹‍♀"
+  , "description": "woman juggling"
+  , "category": "People & Body"
+  , "aliases": [
+      "woman_juggling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧘"
+  , "description": "person in lotus position"
+  , "category": "People & Body"
+  , "aliases": [
+      "lotus_position"
+    ]
+  , "tags": [
+      "meditation"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧘‍♂"
+  , "description": "man in lotus position"
+  , "category": "People & Body"
+  , "aliases": [
+      "lotus_position_man"
+    ]
+  , "tags": [
+      "meditation"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧘‍♀"
+  , "description": "woman in lotus position"
+  , "category": "People & Body"
+  , "aliases": [
+      "lotus_position_woman"
+    ]
+  , "tags": [
+      "meditation"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🛀"
+  , "description": "person taking bath"
+  , "category": "People & Body"
+  , "aliases": [
+      "bath"
+    ]
+  , "tags": [
+      "shower"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🛌"
+  , "description": "person in bed"
+  , "category": "People & Body"
+  , "aliases": [
+      "sleeping_bed"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "🧑‍🤝‍🧑"
+  , "description": "people holding hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "people_holding_hands"
+    ]
+  , "tags": [
+      "couple"
+    , "date"
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👭"
+  , "description": "women holding hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "two_women_holding_hands"
+    ]
+  , "tags": [
+      "couple"
+    , "date"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👫"
+  , "description": "woman and man holding hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "couple"
+    ]
+  , "tags": [
+      "date"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "👬"
+  , "description": "men holding hands"
+  , "category": "People & Body"
+  , "aliases": [
+      "two_men_holding_hands"
+    ]
+  , "tags": [
+      "couple"
+    , "date"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  , "skin_tones": true
+  }
+, {
+    "emoji": "💏"
+  , "description": "kiss"
+  , "category": "People & Body"
+  , "aliases": [
+      "couplekiss"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👩‍❤️‍💋‍👨"
+  , "description": "kiss: woman, man"
+  , "category": "People & Body"
+  , "aliases": [
+      "couplekiss_man_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👨‍❤️‍💋‍👨"
+  , "description": "kiss: man, man"
+  , "category": "People & Body"
+  , "aliases": [
+      "couplekiss_man_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍❤️‍💋‍👩"
+  , "description": "kiss: woman, woman"
+  , "category": "People & Body"
+  , "aliases": [
+      "couplekiss_woman_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "💑"
+  , "description": "couple with heart"
+  , "category": "People & Body"
+  , "aliases": [
+      "couple_with_heart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👩‍❤️‍👨"
+  , "description": "couple with heart: woman, man"
+  , "category": "People & Body"
+  , "aliases": [
+      "couple_with_heart_woman_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👨‍❤️‍👨"
+  , "description": "couple with heart: man, man"
+  , "category": "People & Body"
+  , "aliases": [
+      "couple_with_heart_man_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍❤️‍👩"
+  , "description": "couple with heart: woman, woman"
+  , "category": "People & Body"
+  , "aliases": [
+      "couple_with_heart_woman_woman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👪"
+  , "description": "family"
+  , "category": "People & Body"
+  , "aliases": [
+      "family"
+    ]
+  , "tags": [
+      "home"
+    , "parents"
+    , "child"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👨‍👩‍👦"
+  , "description": "family: man, woman, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_woman_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👨‍👩‍👧"
+  , "description": "family: man, woman, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_woman_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👩‍👧‍👦"
+  , "description": "family: man, woman, girl, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_woman_girl_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👩‍👦‍👦"
+  , "description": "family: man, woman, boy, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_woman_boy_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👩‍👧‍👧"
+  , "description": "family: man, woman, girl, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_woman_girl_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👨‍👦"
+  , "description": "family: man, man, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_man_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👨‍👧"
+  , "description": "family: man, man, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_man_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👨‍👧‍👦"
+  , "description": "family: man, man, girl, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_man_girl_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👨‍👦‍👦"
+  , "description": "family: man, man, boy, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_man_boy_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👨‍👧‍👧"
+  , "description": "family: man, man, girl, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_man_girl_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍👩‍👦"
+  , "description": "family: woman, woman, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_woman_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍👩‍👧"
+  , "description": "family: woman, woman, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_woman_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍👩‍👧‍👦"
+  , "description": "family: woman, woman, girl, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_woman_girl_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍👩‍👦‍👦"
+  , "description": "family: woman, woman, boy, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_woman_boy_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👩‍👩‍👧‍👧"
+  , "description": "family: woman, woman, girl, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_woman_girl_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "👨‍👦"
+  , "description": "family: man, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👨‍👦‍👦"
+  , "description": "family: man, boy, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_boy_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👨‍👧"
+  , "description": "family: man, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👨‍👧‍👦"
+  , "description": "family: man, girl, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_girl_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👨‍👧‍👧"
+  , "description": "family: man, girl, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_man_girl_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👩‍👦"
+  , "description": "family: woman, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👩‍👦‍👦"
+  , "description": "family: woman, boy, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_boy_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👩‍👧"
+  , "description": "family: woman, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👩‍👧‍👦"
+  , "description": "family: woman, girl, boy"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_girl_boy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "👩‍👧‍👧"
+  , "description": "family: woman, girl, girl"
+  , "category": "People & Body"
+  , "aliases": [
+      "family_woman_girl_girl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "🗣"
+  , "description": "speaking head"
+  , "category": "People & Body"
+  , "aliases": [
+      "speaking_head"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "👤"
+  , "description": "bust in silhouette"
+  , "category": "People & Body"
+  , "aliases": [
+      "bust_in_silhouette"
+    ]
+  , "tags": [
+      "user"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👥"
+  , "description": "busts in silhouette"
+  , "category": "People & Body"
+  , "aliases": [
+      "busts_in_silhouette"
+    ]
+  , "tags": [
+      "users"
+    , "group"
+    , "team"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👣"
+  , "description": "footprints"
+  , "category": "People & Body"
+  , "aliases": [
+      "footprints"
+    ]
+  , "tags": [
+      "feet"
+    , "tracks"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐵"
+  , "description": "monkey face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "monkey_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐒"
+  , "description": "monkey"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "monkey"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦍"
+  , "description": "gorilla"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "gorilla"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦧"
+  , "description": "orangutan"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "orangutan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🐶"
+  , "description": "dog face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dog"
+    ]
+  , "tags": [
+      "pet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐕"
+  , "description": "dog"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dog2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦮"
+  , "description": "guide dog"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "guide_dog"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🐕‍🦺"
+  , "description": "service dog"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "service_dog"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🐩"
+  , "description": "poodle"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "poodle"
+    ]
+  , "tags": [
+      "dog"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐺"
+  , "description": "wolf"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "wolf"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦊"
+  , "description": "fox"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "fox_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦝"
+  , "description": "raccoon"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "raccoon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🐱"
+  , "description": "cat face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cat"
+    ]
+  , "tags": [
+      "pet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐈"
+  , "description": "cat"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cat2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦁"
+  , "description": "lion"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "lion"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🐯"
+  , "description": "tiger face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "tiger"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐅"
+  , "description": "tiger"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "tiger2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐆"
+  , "description": "leopard"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "leopard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐴"
+  , "description": "horse face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "horse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐎"
+  , "description": "horse"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "racehorse"
+    ]
+  , "tags": [
+      "speed"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦄"
+  , "description": "unicorn"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "unicorn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦓"
+  , "description": "zebra"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "zebra"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦌"
+  , "description": "deer"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "deer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🐮"
+  , "description": "cow face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cow"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐂"
+  , "description": "ox"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "ox"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐃"
+  , "description": "water buffalo"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "water_buffalo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐄"
+  , "description": "cow"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cow2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐷"
+  , "description": "pig face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "pig"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐖"
+  , "description": "pig"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "pig2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐗"
+  , "description": "boar"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "boar"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐽"
+  , "description": "pig nose"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "pig_nose"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐏"
+  , "description": "ram"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "ram"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐑"
+  , "description": "ewe"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "sheep"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐐"
+  , "description": "goat"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "goat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐪"
+  , "description": "camel"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dromedary_camel"
+    ]
+  , "tags": [
+      "desert"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐫"
+  , "description": "two-hump camel"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "camel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦙"
+  , "description": "llama"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "llama"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦒"
+  , "description": "giraffe"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "giraffe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🐘"
+  , "description": "elephant"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "elephant"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦏"
+  , "description": "rhinoceros"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rhinoceros"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦛"
+  , "description": "hippopotamus"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "hippopotamus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🐭"
+  , "description": "mouse face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "mouse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐁"
+  , "description": "mouse"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "mouse2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐀"
+  , "description": "rat"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐹"
+  , "description": "hamster"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "hamster"
+    ]
+  , "tags": [
+      "pet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐰"
+  , "description": "rabbit face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rabbit"
+    ]
+  , "tags": [
+      "bunny"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐇"
+  , "description": "rabbit"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rabbit2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐿"
+  , "description": "chipmunk"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "chipmunk"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦔"
+  , "description": "hedgehog"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "hedgehog"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦇"
+  , "description": "bat"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "bat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🐻"
+  , "description": "bear"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "bear"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐨"
+  , "description": "koala"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "koala"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐼"
+  , "description": "panda"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "panda_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦥"
+  , "description": "sloth"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "sloth"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦦"
+  , "description": "otter"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "otter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦨"
+  , "description": "skunk"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "skunk"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦘"
+  , "description": "kangaroo"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "kangaroo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦡"
+  , "description": "badger"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "badger"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🐾"
+  , "description": "paw prints"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "feet"
+    , "paw_prints"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦃"
+  , "description": "turkey"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "turkey"
+    ]
+  , "tags": [
+      "thanksgiving"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🐔"
+  , "description": "chicken"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "chicken"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐓"
+  , "description": "rooster"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rooster"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐣"
+  , "description": "hatching chick"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "hatching_chick"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐤"
+  , "description": "baby chick"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "baby_chick"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐥"
+  , "description": "front-facing baby chick"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "hatched_chick"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐦"
+  , "description": "bird"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "bird"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐧"
+  , "description": "penguin"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "penguin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕊"
+  , "description": "dove"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dove"
+    ]
+  , "tags": [
+      "peace"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦅"
+  , "description": "eagle"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "eagle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦆"
+  , "description": "duck"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "duck"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦢"
+  , "description": "swan"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "swan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦉"
+  , "description": "owl"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "owl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦩"
+  , "description": "flamingo"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "flamingo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦚"
+  , "description": "peacock"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "peacock"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦜"
+  , "description": "parrot"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "parrot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🐸"
+  , "description": "frog"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "frog"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐊"
+  , "description": "crocodile"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "crocodile"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐢"
+  , "description": "turtle"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "turtle"
+    ]
+  , "tags": [
+      "slow"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦎"
+  , "description": "lizard"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "lizard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🐍"
+  , "description": "snake"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "snake"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐲"
+  , "description": "dragon face"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dragon_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐉"
+  , "description": "dragon"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dragon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦕"
+  , "description": "sauropod"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "sauropod"
+    ]
+  , "tags": [
+      "dinosaur"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦖"
+  , "description": "T-Rex"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "t-rex"
+    ]
+  , "tags": [
+      "dinosaur"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🐳"
+  , "description": "spouting whale"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "whale"
+    ]
+  , "tags": [
+      "sea"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐋"
+  , "description": "whale"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "whale2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐬"
+  , "description": "dolphin"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "dolphin"
+    , "flipper"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐟"
+  , "description": "fish"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "fish"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐠"
+  , "description": "tropical fish"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "tropical_fish"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐡"
+  , "description": "blowfish"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "blowfish"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦈"
+  , "description": "shark"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "shark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🐙"
+  , "description": "octopus"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "octopus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐚"
+  , "description": "spiral shell"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "shell"
+    ]
+  , "tags": [
+      "sea"
+    , "beach"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐌"
+  , "description": "snail"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "snail"
+    ]
+  , "tags": [
+      "slow"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦋"
+  , "description": "butterfly"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "butterfly"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🐛"
+  , "description": "bug"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "bug"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐜"
+  , "description": "ant"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "ant"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐝"
+  , "description": "honeybee"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "bee"
+    , "honeybee"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🐞"
+  , "description": "lady beetle"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "beetle"
+    ]
+  , "tags": [
+      "bug"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🦗"
+  , "description": "cricket"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cricket"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🕷"
+  , "description": "spider"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "spider"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🕸"
+  , "description": "spider web"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "spider_web"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦂"
+  , "description": "scorpion"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "scorpion"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦟"
+  , "description": "mosquito"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "mosquito"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦠"
+  , "description": "microbe"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "microbe"
+    ]
+  , "tags": [
+      "germ"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "💐"
+  , "description": "bouquet"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "bouquet"
+    ]
+  , "tags": [
+      "flowers"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌸"
+  , "description": "cherry blossom"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cherry_blossom"
+    ]
+  , "tags": [
+      "flower"
+    , "spring"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💮"
+  , "description": "white flower"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "white_flower"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏵"
+  , "description": "rosette"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rosette"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌹"
+  , "description": "rose"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "rose"
+    ]
+  , "tags": [
+      "flower"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥀"
+  , "description": "wilted flower"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "wilted_flower"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🌺"
+  , "description": "hibiscus"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "hibiscus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌻"
+  , "description": "sunflower"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "sunflower"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌼"
+  , "description": "blossom"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "blossom"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌷"
+  , "description": "tulip"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "tulip"
+    ]
+  , "tags": [
+      "flower"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌱"
+  , "description": "seedling"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "seedling"
+    ]
+  , "tags": [
+      "plant"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌲"
+  , "description": "evergreen tree"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "evergreen_tree"
+    ]
+  , "tags": [
+      "wood"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌳"
+  , "description": "deciduous tree"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "deciduous_tree"
+    ]
+  , "tags": [
+      "wood"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌴"
+  , "description": "palm tree"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "palm_tree"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌵"
+  , "description": "cactus"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "cactus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌾"
+  , "description": "sheaf of rice"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "ear_of_rice"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌿"
+  , "description": "herb"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "herb"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☘"
+  , "description": "shamrock"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "shamrock"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🍀"
+  , "description": "four leaf clover"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "four_leaf_clover"
+    ]
+  , "tags": [
+      "luck"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍁"
+  , "description": "maple leaf"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "maple_leaf"
+    ]
+  , "tags": [
+      "canada"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍂"
+  , "description": "fallen leaf"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "fallen_leaf"
+    ]
+  , "tags": [
+      "autumn"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍃"
+  , "description": "leaf fluttering in wind"
+  , "category": "Animals & Nature"
+  , "aliases": [
+      "leaves"
+    ]
+  , "tags": [
+      "leaf"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍇"
+  , "description": "grapes"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "grapes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍈"
+  , "description": "melon"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "melon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍉"
+  , "description": "watermelon"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "watermelon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍊"
+  , "description": "tangerine"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "tangerine"
+    , "orange"
+    , "mandarin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍋"
+  , "description": "lemon"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "lemon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍌"
+  , "description": "banana"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "banana"
+    ]
+  , "tags": [
+      "fruit"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍍"
+  , "description": "pineapple"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "pineapple"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥭"
+  , "description": "mango"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "mango"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🍎"
+  , "description": "red apple"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "apple"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍏"
+  , "description": "green apple"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "green_apple"
+    ]
+  , "tags": [
+      "fruit"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍐"
+  , "description": "pear"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "pear"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍑"
+  , "description": "peach"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "peach"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍒"
+  , "description": "cherries"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cherries"
+    ]
+  , "tags": [
+      "fruit"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍓"
+  , "description": "strawberry"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "strawberry"
+    ]
+  , "tags": [
+      "fruit"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥝"
+  , "description": "kiwi fruit"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "kiwi_fruit"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🍅"
+  , "description": "tomato"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "tomato"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥥"
+  , "description": "coconut"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "coconut"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥑"
+  , "description": "avocado"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "avocado"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🍆"
+  , "description": "eggplant"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "eggplant"
+    ]
+  , "tags": [
+      "aubergine"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥔"
+  , "description": "potato"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "potato"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥕"
+  , "description": "carrot"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "carrot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🌽"
+  , "description": "ear of corn"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "corn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌶"
+  , "description": "hot pepper"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "hot_pepper"
+    ]
+  , "tags": [
+      "spicy"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥒"
+  , "description": "cucumber"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cucumber"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥬"
+  , "description": "leafy green"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "leafy_green"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥦"
+  , "description": "broccoli"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "broccoli"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧄"
+  , "description": "garlic"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "garlic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🧅"
+  , "description": "onion"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "onion"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🍄"
+  , "description": "mushroom"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "mushroom"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥜"
+  , "description": "peanuts"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "peanuts"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🌰"
+  , "description": "chestnut"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "chestnut"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍞"
+  , "description": "bread"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "bread"
+    ]
+  , "tags": [
+      "toast"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥐"
+  , "description": "croissant"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "croissant"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥖"
+  , "description": "baguette bread"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "baguette_bread"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥨"
+  , "description": "pretzel"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "pretzel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥯"
+  , "description": "bagel"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "bagel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥞"
+  , "description": "pancakes"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "pancakes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🧇"
+  , "description": "waffle"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "waffle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🧀"
+  , "description": "cheese wedge"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cheese"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🍖"
+  , "description": "meat on bone"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "meat_on_bone"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍗"
+  , "description": "poultry leg"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "poultry_leg"
+    ]
+  , "tags": [
+      "meat"
+    , "chicken"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥩"
+  , "description": "cut of meat"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cut_of_meat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥓"
+  , "description": "bacon"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "bacon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🍔"
+  , "description": "hamburger"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "hamburger"
+    ]
+  , "tags": [
+      "burger"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍟"
+  , "description": "french fries"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "fries"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍕"
+  , "description": "pizza"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "pizza"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌭"
+  , "description": "hot dog"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "hotdog"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥪"
+  , "description": "sandwich"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "sandwich"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🌮"
+  , "description": "taco"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "taco"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌯"
+  , "description": "burrito"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "burrito"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥙"
+  , "description": "stuffed flatbread"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "stuffed_flatbread"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🧆"
+  , "description": "falafel"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "falafel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🥚"
+  , "description": "egg"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "egg"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🍳"
+  , "description": "cooking"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "fried_egg"
+    ]
+  , "tags": [
+      "breakfast"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥘"
+  , "description": "shallow pan of food"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "shallow_pan_of_food"
+    ]
+  , "tags": [
+      "paella"
+    , "curry"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🍲"
+  , "description": "pot of food"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "stew"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥣"
+  , "description": "bowl with spoon"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "bowl_with_spoon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥗"
+  , "description": "green salad"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "green_salad"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🍿"
+  , "description": "popcorn"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "popcorn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🧈"
+  , "description": "butter"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "butter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🧂"
+  , "description": "salt"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "salt"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥫"
+  , "description": "canned food"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "canned_food"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🍱"
+  , "description": "bento box"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "bento"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍘"
+  , "description": "rice cracker"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "rice_cracker"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍙"
+  , "description": "rice ball"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "rice_ball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍚"
+  , "description": "cooked rice"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "rice"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍛"
+  , "description": "curry rice"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "curry"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍜"
+  , "description": "steaming bowl"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "ramen"
+    ]
+  , "tags": [
+      "noodle"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍝"
+  , "description": "spaghetti"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "spaghetti"
+    ]
+  , "tags": [
+      "pasta"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍠"
+  , "description": "roasted sweet potato"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "sweet_potato"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍢"
+  , "description": "oden"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "oden"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍣"
+  , "description": "sushi"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "sushi"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍤"
+  , "description": "fried shrimp"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "fried_shrimp"
+    ]
+  , "tags": [
+      "tempura"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍥"
+  , "description": "fish cake with swirl"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "fish_cake"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥮"
+  , "description": "moon cake"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "moon_cake"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🍡"
+  , "description": "dango"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "dango"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥟"
+  , "description": "dumpling"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "dumpling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥠"
+  , "description": "fortune cookie"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "fortune_cookie"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥡"
+  , "description": "takeout box"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "takeout_box"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦀"
+  , "description": "crab"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "crab"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦞"
+  , "description": "lobster"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "lobster"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦐"
+  , "description": "shrimp"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "shrimp"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦑"
+  , "description": "squid"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "squid"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦪"
+  , "description": "oyster"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "oyster"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🍦"
+  , "description": "soft ice cream"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "icecream"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍧"
+  , "description": "shaved ice"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "shaved_ice"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍨"
+  , "description": "ice cream"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "ice_cream"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍩"
+  , "description": "doughnut"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "doughnut"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍪"
+  , "description": "cookie"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cookie"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎂"
+  , "description": "birthday cake"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "birthday"
+    ]
+  , "tags": [
+      "party"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍰"
+  , "description": "shortcake"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cake"
+    ]
+  , "tags": [
+      "dessert"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧁"
+  , "description": "cupcake"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cupcake"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥧"
+  , "description": "pie"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "pie"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🍫"
+  , "description": "chocolate bar"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "chocolate_bar"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍬"
+  , "description": "candy"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "candy"
+    ]
+  , "tags": [
+      "sweet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍭"
+  , "description": "lollipop"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "lollipop"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍮"
+  , "description": "custard"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "custard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍯"
+  , "description": "honey pot"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "honey_pot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍼"
+  , "description": "baby bottle"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "baby_bottle"
+    ]
+  , "tags": [
+      "milk"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥛"
+  , "description": "glass of milk"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "milk_glass"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "☕"
+  , "description": "hot beverage"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "coffee"
+    ]
+  , "tags": [
+      "cafe"
+    , "espresso"
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍵"
+  , "description": "teacup without handle"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "tea"
+    ]
+  , "tags": [
+      "green"
+    , "breakfast"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍶"
+  , "description": "sake"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "sake"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍾"
+  , "description": "bottle with popping cork"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "champagne"
+    ]
+  , "tags": [
+      "bottle"
+    , "bubbly"
+    , "celebration"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🍷"
+  , "description": "wine glass"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "wine_glass"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍸"
+  , "description": "cocktail glass"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cocktail"
+    ]
+  , "tags": [
+      "drink"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍹"
+  , "description": "tropical drink"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "tropical_drink"
+    ]
+  , "tags": [
+      "summer"
+    , "vacation"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍺"
+  , "description": "beer mug"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "beer"
+    ]
+  , "tags": [
+      "drink"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🍻"
+  , "description": "clinking beer mugs"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "beers"
+    ]
+  , "tags": [
+      "drinks"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥂"
+  , "description": "clinking glasses"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "clinking_glasses"
+    ]
+  , "tags": [
+      "cheers"
+    , "toast"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥃"
+  , "description": "tumbler glass"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "tumbler_glass"
+    ]
+  , "tags": [
+      "whisky"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥤"
+  , "description": "cup with straw"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "cup_with_straw"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧃"
+  , "description": "beverage box"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "beverage_box"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🧉"
+  , "description": "mate"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "mate"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🧊"
+  , "description": "ice cube"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "ice_cube"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🥢"
+  , "description": "chopsticks"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "chopsticks"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🍽"
+  , "description": "fork and knife with plate"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "plate_with_cutlery"
+    ]
+  , "tags": [
+      "dining"
+    , "dinner"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🍴"
+  , "description": "fork and knife"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "fork_and_knife"
+    ]
+  , "tags": [
+      "cutlery"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥄"
+  , "description": "spoon"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "spoon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🔪"
+  , "description": "kitchen knife"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "hocho"
+    , "knife"
+    ]
+  , "tags": [
+      "cut"
+    , "chop"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏺"
+  , "description": "amphora"
+  , "category": "Food & Drink"
+  , "aliases": [
+      "amphora"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌍"
+  , "description": "globe showing Europe-Africa"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "earth_africa"
+    ]
+  , "tags": [
+      "globe"
+    , "world"
+    , "international"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌎"
+  , "description": "globe showing Americas"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "earth_americas"
+    ]
+  , "tags": [
+      "globe"
+    , "world"
+    , "international"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌏"
+  , "description": "globe showing Asia-Australia"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "earth_asia"
+    ]
+  , "tags": [
+      "globe"
+    , "world"
+    , "international"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌐"
+  , "description": "globe with meridians"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "globe_with_meridians"
+    ]
+  , "tags": [
+      "world"
+    , "global"
+    , "international"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗺"
+  , "description": "world map"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "world_map"
+    ]
+  , "tags": [
+      "travel"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗾"
+  , "description": "map of Japan"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "japan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧭"
+  , "description": "compass"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "compass"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🏔"
+  , "description": "snow-capped mountain"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mountain_snow"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⛰"
+  , "description": "mountain"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mountain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌋"
+  , "description": "volcano"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "volcano"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗻"
+  , "description": "mount fuji"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mount_fuji"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏕"
+  , "description": "camping"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "camping"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏖"
+  , "description": "beach with umbrella"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "beach_umbrella"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏜"
+  , "description": "desert"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "desert"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏝"
+  , "description": "desert island"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "desert_island"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏞"
+  , "description": "national park"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "national_park"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏟"
+  , "description": "stadium"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "stadium"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏛"
+  , "description": "classical building"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "classical_building"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏗"
+  , "description": "building construction"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "building_construction"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🧱"
+  , "description": "brick"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bricks"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🏘"
+  , "description": "houses"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "houses"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏚"
+  , "description": "derelict house"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "derelict_house"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏠"
+  , "description": "house"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "house"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏡"
+  , "description": "house with garden"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "house_with_garden"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏢"
+  , "description": "office building"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "office"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏣"
+  , "description": "Japanese post office"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "post_office"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏤"
+  , "description": "post office"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "european_post_office"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏥"
+  , "description": "hospital"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "hospital"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏦"
+  , "description": "bank"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bank"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏨"
+  , "description": "hotel"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "hotel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏩"
+  , "description": "love hotel"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "love_hotel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏪"
+  , "description": "convenience store"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "convenience_store"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏫"
+  , "description": "school"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "school"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏬"
+  , "description": "department store"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "department_store"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏭"
+  , "description": "factory"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "factory"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏯"
+  , "description": "Japanese castle"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "japanese_castle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏰"
+  , "description": "castle"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "european_castle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💒"
+  , "description": "wedding"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "wedding"
+    ]
+  , "tags": [
+      "marriage"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗼"
+  , "description": "Tokyo tower"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "tokyo_tower"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗽"
+  , "description": "Statue of Liberty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "statue_of_liberty"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛪"
+  , "description": "church"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "church"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕌"
+  , "description": "mosque"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mosque"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛕"
+  , "description": "hindu temple"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "hindu_temple"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🕍"
+  , "description": "synagogue"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "synagogue"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⛩"
+  , "description": "shinto shrine"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "shinto_shrine"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🕋"
+  , "description": "kaaba"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "kaaba"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⛲"
+  , "description": "fountain"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "fountain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛺"
+  , "description": "tent"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "tent"
+    ]
+  , "tags": [
+      "camping"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌁"
+  , "description": "foggy"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "foggy"
+    ]
+  , "tags": [
+      "karl"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌃"
+  , "description": "night with stars"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "night_with_stars"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏙"
+  , "description": "cityscape"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cityscape"
+    ]
+  , "tags": [
+      "skyline"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌄"
+  , "description": "sunrise over mountains"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sunrise_over_mountains"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌅"
+  , "description": "sunrise"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sunrise"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌆"
+  , "description": "cityscape at dusk"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "city_sunset"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌇"
+  , "description": "sunset"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "city_sunrise"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌉"
+  , "description": "bridge at night"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bridge_at_night"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♨️"
+  , "description": "hot springs"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "hotsprings"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎠"
+  , "description": "carousel horse"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "carousel_horse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎡"
+  , "description": "ferris wheel"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "ferris_wheel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎢"
+  , "description": "roller coaster"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "roller_coaster"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💈"
+  , "description": "barber pole"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "barber"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎪"
+  , "description": "circus tent"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "circus_tent"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚂"
+  , "description": "locomotive"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "steam_locomotive"
+    ]
+  , "tags": [
+      "train"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚃"
+  , "description": "railway car"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "railway_car"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚄"
+  , "description": "high-speed train"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bullettrain_side"
+    ]
+  , "tags": [
+      "train"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚅"
+  , "description": "bullet train"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bullettrain_front"
+    ]
+  , "tags": [
+      "train"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚆"
+  , "description": "train"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "train2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚇"
+  , "description": "metro"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "metro"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚈"
+  , "description": "light rail"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "light_rail"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚉"
+  , "description": "station"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "station"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚊"
+  , "description": "tram"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "tram"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚝"
+  , "description": "monorail"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "monorail"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚞"
+  , "description": "mountain railway"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mountain_railway"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚋"
+  , "description": "tram car"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "train"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚌"
+  , "description": "bus"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚍"
+  , "description": "oncoming bus"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "oncoming_bus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚎"
+  , "description": "trolleybus"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "trolleybus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚐"
+  , "description": "minibus"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "minibus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚑"
+  , "description": "ambulance"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "ambulance"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚒"
+  , "description": "fire engine"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "fire_engine"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚓"
+  , "description": "police car"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "police_car"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚔"
+  , "description": "oncoming police car"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "oncoming_police_car"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚕"
+  , "description": "taxi"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "taxi"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚖"
+  , "description": "oncoming taxi"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "oncoming_taxi"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚗"
+  , "description": "automobile"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "car"
+    , "red_car"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚘"
+  , "description": "oncoming automobile"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "oncoming_automobile"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚙"
+  , "description": "sport utility vehicle"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "blue_car"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚚"
+  , "description": "delivery truck"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "truck"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚛"
+  , "description": "articulated lorry"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "articulated_lorry"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚜"
+  , "description": "tractor"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "tractor"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏎"
+  , "description": "racing car"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "racing_car"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏍"
+  , "description": "motorcycle"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "motorcycle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛵"
+  , "description": "motor scooter"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "motor_scooter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🦽"
+  , "description": "manual wheelchair"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "manual_wheelchair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🦼"
+  , "description": "motorized wheelchair"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "motorized_wheelchair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🛺"
+  , "description": "auto rickshaw"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "auto_rickshaw"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🚲"
+  , "description": "bicycle"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bike"
+    ]
+  , "tags": [
+      "bicycle"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛴"
+  , "description": "kick scooter"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "kick_scooter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🛹"
+  , "description": "skateboard"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "skateboard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🚏"
+  , "description": "bus stop"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "busstop"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛣"
+  , "description": "motorway"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "motorway"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛤"
+  , "description": "railway track"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "railway_track"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛢"
+  , "description": "oil drum"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "oil_drum"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⛽"
+  , "description": "fuel pump"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "fuelpump"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚨"
+  , "description": "police car light"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "rotating_light"
+    ]
+  , "tags": [
+      "911"
+    , "emergency"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚥"
+  , "description": "horizontal traffic light"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "traffic_light"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚦"
+  , "description": "vertical traffic light"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "vertical_traffic_light"
+    ]
+  , "tags": [
+      "semaphore"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛑"
+  , "description": "stop sign"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "stop_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🚧"
+  , "description": "construction"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "construction"
+    ]
+  , "tags": [
+      "wip"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚓"
+  , "description": "anchor"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "anchor"
+    ]
+  , "tags": [
+      "ship"
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛵"
+  , "description": "sailboat"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "boat"
+    , "sailboat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛶"
+  , "description": "canoe"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "canoe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🚤"
+  , "description": "speedboat"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "speedboat"
+    ]
+  , "tags": [
+      "ship"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛳"
+  , "description": "passenger ship"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "passenger_ship"
+    ]
+  , "tags": [
+      "cruise"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⛴"
+  , "description": "ferry"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "ferry"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛥"
+  , "description": "motor boat"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "motor_boat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🚢"
+  , "description": "ship"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "ship"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✈️"
+  , "description": "airplane"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "airplane"
+    ]
+  , "tags": [
+      "flight"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛩"
+  , "description": "small airplane"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "small_airplane"
+    ]
+  , "tags": [
+      "flight"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛫"
+  , "description": "airplane departure"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "flight_departure"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛬"
+  , "description": "airplane arrival"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "flight_arrival"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🪂"
+  , "description": "parachute"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "parachute"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "💺"
+  , "description": "seat"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "seat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚁"
+  , "description": "helicopter"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "helicopter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚟"
+  , "description": "suspension railway"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "suspension_railway"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚠"
+  , "description": "mountain cableway"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mountain_cableway"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚡"
+  , "description": "aerial tramway"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "aerial_tramway"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛰"
+  , "description": "satellite"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "artificial_satellite"
+    ]
+  , "tags": [
+      "orbit"
+    , "space"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🚀"
+  , "description": "rocket"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "rocket"
+    ]
+  , "tags": [
+      "ship"
+    , "launch"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛸"
+  , "description": "flying saucer"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "flying_saucer"
+    ]
+  , "tags": [
+      "ufo"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🛎"
+  , "description": "bellhop bell"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "bellhop_bell"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🧳"
+  , "description": "luggage"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "luggage"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "⌛"
+  , "description": "hourglass done"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "hourglass"
+    ]
+  , "tags": [
+      "time"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏳"
+  , "description": "hourglass not done"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "hourglass_flowing_sand"
+    ]
+  , "tags": [
+      "time"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⌚"
+  , "description": "watch"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "watch"
+    ]
+  , "tags": [
+      "time"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏰"
+  , "description": "alarm clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "alarm_clock"
+    ]
+  , "tags": [
+      "morning"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏱"
+  , "description": "stopwatch"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "stopwatch"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⏲"
+  , "description": "timer clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "timer_clock"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🕰"
+  , "description": "mantelpiece clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "mantelpiece_clock"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🕛"
+  , "description": "twelve o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock12"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕧"
+  , "description": "twelve-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock1230"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕐"
+  , "description": "one o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock1"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕜"
+  , "description": "one-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock130"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕑"
+  , "description": "two o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕝"
+  , "description": "two-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock230"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕒"
+  , "description": "three o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock3"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕞"
+  , "description": "three-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock330"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕓"
+  , "description": "four o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock4"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕟"
+  , "description": "four-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock430"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕔"
+  , "description": "five o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock5"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕠"
+  , "description": "five-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock530"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕕"
+  , "description": "six o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock6"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕡"
+  , "description": "six-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock630"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕖"
+  , "description": "seven o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock7"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕢"
+  , "description": "seven-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock730"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕗"
+  , "description": "eight o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock8"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕣"
+  , "description": "eight-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock830"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕘"
+  , "description": "nine o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock9"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕤"
+  , "description": "nine-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock930"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕙"
+  , "description": "ten o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock10"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕥"
+  , "description": "ten-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock1030"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕚"
+  , "description": "eleven o’clock"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock11"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕦"
+  , "description": "eleven-thirty"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "clock1130"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌑"
+  , "description": "new moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "new_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌒"
+  , "description": "waxing crescent moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "waxing_crescent_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌓"
+  , "description": "first quarter moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "first_quarter_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌔"
+  , "description": "waxing gibbous moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "moon"
+    , "waxing_gibbous_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌕"
+  , "description": "full moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "full_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌖"
+  , "description": "waning gibbous moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "waning_gibbous_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌗"
+  , "description": "last quarter moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "last_quarter_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌘"
+  , "description": "waning crescent moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "waning_crescent_moon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌙"
+  , "description": "crescent moon"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "crescent_moon"
+    ]
+  , "tags": [
+      "night"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌚"
+  , "description": "new moon face"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "new_moon_with_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌛"
+  , "description": "first quarter moon face"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "first_quarter_moon_with_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌜"
+  , "description": "last quarter moon face"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "last_quarter_moon_with_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌡"
+  , "description": "thermometer"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "thermometer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☀️"
+  , "description": "sun"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sunny"
+    ]
+  , "tags": [
+      "weather"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌝"
+  , "description": "full moon face"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "full_moon_with_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌞"
+  , "description": "sun with face"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sun_with_face"
+    ]
+  , "tags": [
+      "summer"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🪐"
+  , "description": "ringed planet"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "ringed_planet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "⭐"
+  , "description": "star"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "star"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌟"
+  , "description": "glowing star"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "star2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌠"
+  , "description": "shooting star"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "stars"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌌"
+  , "description": "milky way"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "milky_way"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☁️"
+  , "description": "cloud"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cloud"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛅"
+  , "description": "sun behind cloud"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "partly_sunny"
+    ]
+  , "tags": [
+      "weather"
+    , "cloud"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛈"
+  , "description": "cloud with lightning and rain"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cloud_with_lightning_and_rain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌤"
+  , "description": "sun behind small cloud"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sun_behind_small_cloud"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌥"
+  , "description": "sun behind large cloud"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sun_behind_large_cloud"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌦"
+  , "description": "sun behind rain cloud"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "sun_behind_rain_cloud"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌧"
+  , "description": "cloud with rain"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cloud_with_rain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌨"
+  , "description": "cloud with snow"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cloud_with_snow"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌩"
+  , "description": "cloud with lightning"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cloud_with_lightning"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌪"
+  , "description": "tornado"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "tornado"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌫"
+  , "description": "fog"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "fog"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌬"
+  , "description": "wind face"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "wind_face"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🌀"
+  , "description": "cyclone"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "cyclone"
+    ]
+  , "tags": [
+      "swirl"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌈"
+  , "description": "rainbow"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "rainbow"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌂"
+  , "description": "closed umbrella"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "closed_umbrella"
+    ]
+  , "tags": [
+      "weather"
+    , "rain"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☂️"
+  , "description": "umbrella"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "open_umbrella"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☔"
+  , "description": "umbrella with rain drops"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "umbrella"
+    ]
+  , "tags": [
+      "rain"
+    , "weather"
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛱"
+  , "description": "umbrella on ground"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "parasol_on_ground"
+    ]
+  , "tags": [
+      "beach_umbrella"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⚡"
+  , "description": "high voltage"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "zap"
+    ]
+  , "tags": [
+      "lightning"
+    , "thunder"
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❄️"
+  , "description": "snowflake"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "snowflake"
+    ]
+  , "tags": [
+      "winter"
+    , "cold"
+    , "weather"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☃️"
+  , "description": "snowman"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "snowman_with_snow"
+    ]
+  , "tags": [
+      "winter"
+    , "christmas"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⛄"
+  , "description": "snowman without snow"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "snowman"
+    ]
+  , "tags": [
+      "winter"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☄"
+  , "description": "comet"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "comet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔥"
+  , "description": "fire"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "fire"
+    ]
+  , "tags": [
+      "burn"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💧"
+  , "description": "droplet"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "droplet"
+    ]
+  , "tags": [
+      "water"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🌊"
+  , "description": "water wave"
+  , "category": "Travel & Places"
+  , "aliases": [
+      "ocean"
+    ]
+  , "tags": [
+      "sea"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎃"
+  , "description": "jack-o-lantern"
+  , "category": "Activities"
+  , "aliases": [
+      "jack_o_lantern"
+    ]
+  , "tags": [
+      "halloween"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎄"
+  , "description": "Christmas tree"
+  , "category": "Activities"
+  , "aliases": [
+      "christmas_tree"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎆"
+  , "description": "fireworks"
+  , "category": "Activities"
+  , "aliases": [
+      "fireworks"
+    ]
+  , "tags": [
+      "festival"
+    , "celebration"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎇"
+  , "description": "sparkler"
+  , "category": "Activities"
+  , "aliases": [
+      "sparkler"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧨"
+  , "description": "firecracker"
+  , "category": "Activities"
+  , "aliases": [
+      "firecracker"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "✨"
+  , "description": "sparkles"
+  , "category": "Activities"
+  , "aliases": [
+      "sparkles"
+    ]
+  , "tags": [
+      "shiny"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎈"
+  , "description": "balloon"
+  , "category": "Activities"
+  , "aliases": [
+      "balloon"
+    ]
+  , "tags": [
+      "party"
+    , "birthday"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎉"
+  , "description": "party popper"
+  , "category": "Activities"
+  , "aliases": [
+      "tada"
+    ]
+  , "tags": [
+      "hooray"
+    , "party"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎊"
+  , "description": "confetti ball"
+  , "category": "Activities"
+  , "aliases": [
+      "confetti_ball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎋"
+  , "description": "tanabata tree"
+  , "category": "Activities"
+  , "aliases": [
+      "tanabata_tree"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎍"
+  , "description": "pine decoration"
+  , "category": "Activities"
+  , "aliases": [
+      "bamboo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎎"
+  , "description": "Japanese dolls"
+  , "category": "Activities"
+  , "aliases": [
+      "dolls"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎏"
+  , "description": "carp streamer"
+  , "category": "Activities"
+  , "aliases": [
+      "flags"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎐"
+  , "description": "wind chime"
+  , "category": "Activities"
+  , "aliases": [
+      "wind_chime"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎑"
+  , "description": "moon viewing ceremony"
+  , "category": "Activities"
+  , "aliases": [
+      "rice_scene"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧧"
+  , "description": "red envelope"
+  , "category": "Activities"
+  , "aliases": [
+      "red_envelope"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🎀"
+  , "description": "ribbon"
+  , "category": "Activities"
+  , "aliases": [
+      "ribbon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎁"
+  , "description": "wrapped gift"
+  , "category": "Activities"
+  , "aliases": [
+      "gift"
+    ]
+  , "tags": [
+      "present"
+    , "birthday"
+    , "christmas"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎗"
+  , "description": "reminder ribbon"
+  , "category": "Activities"
+  , "aliases": [
+      "reminder_ribbon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎟"
+  , "description": "admission tickets"
+  , "category": "Activities"
+  , "aliases": [
+      "tickets"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎫"
+  , "description": "ticket"
+  , "category": "Activities"
+  , "aliases": [
+      "ticket"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎖"
+  , "description": "military medal"
+  , "category": "Activities"
+  , "aliases": [
+      "medal_military"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏆"
+  , "description": "trophy"
+  , "category": "Activities"
+  , "aliases": [
+      "trophy"
+    ]
+  , "tags": [
+      "award"
+    , "contest"
+    , "winner"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏅"
+  , "description": "sports medal"
+  , "category": "Activities"
+  , "aliases": [
+      "medal_sports"
+    ]
+  , "tags": [
+      "gold"
+    , "winner"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥇"
+  , "description": "1st place medal"
+  , "category": "Activities"
+  , "aliases": [
+      "1st_place_medal"
+    ]
+  , "tags": [
+      "gold"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥈"
+  , "description": "2nd place medal"
+  , "category": "Activities"
+  , "aliases": [
+      "2nd_place_medal"
+    ]
+  , "tags": [
+      "silver"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥉"
+  , "description": "3rd place medal"
+  , "category": "Activities"
+  , "aliases": [
+      "3rd_place_medal"
+    ]
+  , "tags": [
+      "bronze"
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "⚽"
+  , "description": "soccer ball"
+  , "category": "Activities"
+  , "aliases": [
+      "soccer"
+    ]
+  , "tags": [
+      "sports"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚾"
+  , "description": "baseball"
+  , "category": "Activities"
+  , "aliases": [
+      "baseball"
+    ]
+  , "tags": [
+      "sports"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥎"
+  , "description": "softball"
+  , "category": "Activities"
+  , "aliases": [
+      "softball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🏀"
+  , "description": "basketball"
+  , "category": "Activities"
+  , "aliases": [
+      "basketball"
+    ]
+  , "tags": [
+      "sports"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏐"
+  , "description": "volleyball"
+  , "category": "Activities"
+  , "aliases": [
+      "volleyball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏈"
+  , "description": "american football"
+  , "category": "Activities"
+  , "aliases": [
+      "football"
+    ]
+  , "tags": [
+      "sports"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏉"
+  , "description": "rugby football"
+  , "category": "Activities"
+  , "aliases": [
+      "rugby_football"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎾"
+  , "description": "tennis"
+  , "category": "Activities"
+  , "aliases": [
+      "tennis"
+    ]
+  , "tags": [
+      "sports"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥏"
+  , "description": "flying disc"
+  , "category": "Activities"
+  , "aliases": [
+      "flying_disc"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🎳"
+  , "description": "bowling"
+  , "category": "Activities"
+  , "aliases": [
+      "bowling"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏏"
+  , "description": "cricket game"
+  , "category": "Activities"
+  , "aliases": [
+      "cricket_game"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏑"
+  , "description": "field hockey"
+  , "category": "Activities"
+  , "aliases": [
+      "field_hockey"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏒"
+  , "description": "ice hockey"
+  , "category": "Activities"
+  , "aliases": [
+      "ice_hockey"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥍"
+  , "description": "lacrosse"
+  , "category": "Activities"
+  , "aliases": [
+      "lacrosse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🏓"
+  , "description": "ping pong"
+  , "category": "Activities"
+  , "aliases": [
+      "ping_pong"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏸"
+  , "description": "badminton"
+  , "category": "Activities"
+  , "aliases": [
+      "badminton"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥊"
+  , "description": "boxing glove"
+  , "category": "Activities"
+  , "aliases": [
+      "boxing_glove"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥋"
+  , "description": "martial arts uniform"
+  , "category": "Activities"
+  , "aliases": [
+      "martial_arts_uniform"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🥅"
+  , "description": "goal net"
+  , "category": "Activities"
+  , "aliases": [
+      "goal_net"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "⛳"
+  , "description": "flag in hole"
+  , "category": "Activities"
+  , "aliases": [
+      "golf"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛸"
+  , "description": "ice skate"
+  , "category": "Activities"
+  , "aliases": [
+      "ice_skate"
+    ]
+  , "tags": [
+      "skating"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎣"
+  , "description": "fishing pole"
+  , "category": "Activities"
+  , "aliases": [
+      "fishing_pole_and_fish"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🤿"
+  , "description": "diving mask"
+  , "category": "Activities"
+  , "aliases": [
+      "diving_mask"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🎽"
+  , "description": "running shirt"
+  , "category": "Activities"
+  , "aliases": [
+      "running_shirt_with_sash"
+    ]
+  , "tags": [
+      "marathon"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎿"
+  , "description": "skis"
+  , "category": "Activities"
+  , "aliases": [
+      "ski"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛷"
+  , "description": "sled"
+  , "category": "Activities"
+  , "aliases": [
+      "sled"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥌"
+  , "description": "curling stone"
+  , "category": "Activities"
+  , "aliases": [
+      "curling_stone"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🎯"
+  , "description": "direct hit"
+  , "category": "Activities"
+  , "aliases": [
+      "dart"
+    ]
+  , "tags": [
+      "target"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🪀"
+  , "description": "yo-yo"
+  , "category": "Activities"
+  , "aliases": [
+      "yo_yo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🪁"
+  , "description": "kite"
+  , "category": "Activities"
+  , "aliases": [
+      "kite"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🎱"
+  , "description": "pool 8 ball"
+  , "category": "Activities"
+  , "aliases": [
+      "8ball"
+    ]
+  , "tags": [
+      "pool"
+    , "billiards"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔮"
+  , "description": "crystal ball"
+  , "category": "Activities"
+  , "aliases": [
+      "crystal_ball"
+    ]
+  , "tags": [
+      "fortune"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧿"
+  , "description": "nazar amulet"
+  , "category": "Activities"
+  , "aliases": [
+      "nazar_amulet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🎮"
+  , "description": "video game"
+  , "category": "Activities"
+  , "aliases": [
+      "video_game"
+    ]
+  , "tags": [
+      "play"
+    , "controller"
+    , "console"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕹"
+  , "description": "joystick"
+  , "category": "Activities"
+  , "aliases": [
+      "joystick"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎰"
+  , "description": "slot machine"
+  , "category": "Activities"
+  , "aliases": [
+      "slot_machine"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎲"
+  , "description": "game die"
+  , "category": "Activities"
+  , "aliases": [
+      "game_die"
+    ]
+  , "tags": [
+      "dice"
+    , "gambling"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧩"
+  , "description": "puzzle piece"
+  , "category": "Activities"
+  , "aliases": [
+      "jigsaw"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧸"
+  , "description": "teddy bear"
+  , "category": "Activities"
+  , "aliases": [
+      "teddy_bear"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "♠️"
+  , "description": "spade suit"
+  , "category": "Activities"
+  , "aliases": [
+      "spades"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♥️"
+  , "description": "heart suit"
+  , "category": "Activities"
+  , "aliases": [
+      "hearts"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♦️"
+  , "description": "diamond suit"
+  , "category": "Activities"
+  , "aliases": [
+      "diamonds"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♣️"
+  , "description": "club suit"
+  , "category": "Activities"
+  , "aliases": [
+      "clubs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♟"
+  , "description": "chess pawn"
+  , "category": "Activities"
+  , "aliases": [
+      "chess_pawn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🃏"
+  , "description": "joker"
+  , "category": "Activities"
+  , "aliases": [
+      "black_joker"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🀄"
+  , "description": "mahjong red dragon"
+  , "category": "Activities"
+  , "aliases": [
+      "mahjong"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎴"
+  , "description": "flower playing cards"
+  , "category": "Activities"
+  , "aliases": [
+      "flower_playing_cards"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎭"
+  , "description": "performing arts"
+  , "category": "Activities"
+  , "aliases": [
+      "performing_arts"
+    ]
+  , "tags": [
+      "theater"
+    , "drama"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🖼"
+  , "description": "framed picture"
+  , "category": "Activities"
+  , "aliases": [
+      "framed_picture"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎨"
+  , "description": "artist palette"
+  , "category": "Activities"
+  , "aliases": [
+      "art"
+    ]
+  , "tags": [
+      "design"
+    , "paint"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧵"
+  , "description": "thread"
+  , "category": "Activities"
+  , "aliases": [
+      "thread"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧶"
+  , "description": "yarn"
+  , "category": "Activities"
+  , "aliases": [
+      "yarn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👓"
+  , "description": "glasses"
+  , "category": "Objects"
+  , "aliases": [
+      "eyeglasses"
+    ]
+  , "tags": [
+      "glasses"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕶"
+  , "description": "sunglasses"
+  , "category": "Objects"
+  , "aliases": [
+      "dark_sunglasses"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🥽"
+  , "description": "goggles"
+  , "category": "Objects"
+  , "aliases": [
+      "goggles"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥼"
+  , "description": "lab coat"
+  , "category": "Objects"
+  , "aliases": [
+      "lab_coat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🦺"
+  , "description": "safety vest"
+  , "category": "Objects"
+  , "aliases": [
+      "safety_vest"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "👔"
+  , "description": "necktie"
+  , "category": "Objects"
+  , "aliases": [
+      "necktie"
+    ]
+  , "tags": [
+      "shirt"
+    , "formal"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👕"
+  , "description": "t-shirt"
+  , "category": "Objects"
+  , "aliases": [
+      "shirt"
+    , "tshirt"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👖"
+  , "description": "jeans"
+  , "category": "Objects"
+  , "aliases": [
+      "jeans"
+    ]
+  , "tags": [
+      "pants"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧣"
+  , "description": "scarf"
+  , "category": "Objects"
+  , "aliases": [
+      "scarf"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧤"
+  , "description": "gloves"
+  , "category": "Objects"
+  , "aliases": [
+      "gloves"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧥"
+  , "description": "coat"
+  , "category": "Objects"
+  , "aliases": [
+      "coat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧦"
+  , "description": "socks"
+  , "category": "Objects"
+  , "aliases": [
+      "socks"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👗"
+  , "description": "dress"
+  , "category": "Objects"
+  , "aliases": [
+      "dress"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👘"
+  , "description": "kimono"
+  , "category": "Objects"
+  , "aliases": [
+      "kimono"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥻"
+  , "description": "sari"
+  , "category": "Objects"
+  , "aliases": [
+      "sari"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🩱"
+  , "description": "one-piece swimsuit"
+  , "category": "Objects"
+  , "aliases": [
+      "one_piece_swimsuit"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🩲"
+  , "description": "swim brief"
+  , "category": "Objects"
+  , "aliases": [
+      "swim_brief"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🩳"
+  , "description": "shorts"
+  , "category": "Objects"
+  , "aliases": [
+      "shorts"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "👙"
+  , "description": "bikini"
+  , "category": "Objects"
+  , "aliases": [
+      "bikini"
+    ]
+  , "tags": [
+      "beach"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👚"
+  , "description": "woman’s clothes"
+  , "category": "Objects"
+  , "aliases": [
+      "womans_clothes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👛"
+  , "description": "purse"
+  , "category": "Objects"
+  , "aliases": [
+      "purse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👜"
+  , "description": "handbag"
+  , "category": "Objects"
+  , "aliases": [
+      "handbag"
+    ]
+  , "tags": [
+      "bag"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👝"
+  , "description": "clutch bag"
+  , "category": "Objects"
+  , "aliases": [
+      "pouch"
+    ]
+  , "tags": [
+      "bag"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛍"
+  , "description": "shopping bags"
+  , "category": "Objects"
+  , "aliases": [
+      "shopping"
+    ]
+  , "tags": [
+      "bags"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎒"
+  , "description": "backpack"
+  , "category": "Objects"
+  , "aliases": [
+      "school_satchel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👞"
+  , "description": "man’s shoe"
+  , "category": "Objects"
+  , "aliases": [
+      "mans_shoe"
+    , "shoe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👟"
+  , "description": "running shoe"
+  , "category": "Objects"
+  , "aliases": [
+      "athletic_shoe"
+    ]
+  , "tags": [
+      "sneaker"
+    , "sport"
+    , "running"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🥾"
+  , "description": "hiking boot"
+  , "category": "Objects"
+  , "aliases": [
+      "hiking_boot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🥿"
+  , "description": "flat shoe"
+  , "category": "Objects"
+  , "aliases": [
+      "flat_shoe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "👠"
+  , "description": "high-heeled shoe"
+  , "category": "Objects"
+  , "aliases": [
+      "high_heel"
+    ]
+  , "tags": [
+      "shoe"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👡"
+  , "description": "woman’s sandal"
+  , "category": "Objects"
+  , "aliases": [
+      "sandal"
+    ]
+  , "tags": [
+      "shoe"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🩰"
+  , "description": "ballet shoes"
+  , "category": "Objects"
+  , "aliases": [
+      "ballet_shoes"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "👢"
+  , "description": "woman’s boot"
+  , "category": "Objects"
+  , "aliases": [
+      "boot"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👑"
+  , "description": "crown"
+  , "category": "Objects"
+  , "aliases": [
+      "crown"
+    ]
+  , "tags": [
+      "king"
+    , "queen"
+    , "royal"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "👒"
+  , "description": "woman’s hat"
+  , "category": "Objects"
+  , "aliases": [
+      "womans_hat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎩"
+  , "description": "top hat"
+  , "category": "Objects"
+  , "aliases": [
+      "tophat"
+    ]
+  , "tags": [
+      "hat"
+    , "classy"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎓"
+  , "description": "graduation cap"
+  , "category": "Objects"
+  , "aliases": [
+      "mortar_board"
+    ]
+  , "tags": [
+      "education"
+    , "college"
+    , "university"
+    , "graduation"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧢"
+  , "description": "billed cap"
+  , "category": "Objects"
+  , "aliases": [
+      "billed_cap"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "⛑"
+  , "description": "rescue worker’s helmet"
+  , "category": "Objects"
+  , "aliases": [
+      "rescue_worker_helmet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📿"
+  , "description": "prayer beads"
+  , "category": "Objects"
+  , "aliases": [
+      "prayer_beads"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💄"
+  , "description": "lipstick"
+  , "category": "Objects"
+  , "aliases": [
+      "lipstick"
+    ]
+  , "tags": [
+      "makeup"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💍"
+  , "description": "ring"
+  , "category": "Objects"
+  , "aliases": [
+      "ring"
+    ]
+  , "tags": [
+      "wedding"
+    , "marriage"
+    , "engaged"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💎"
+  , "description": "gem stone"
+  , "category": "Objects"
+  , "aliases": [
+      "gem"
+    ]
+  , "tags": [
+      "diamond"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔇"
+  , "description": "muted speaker"
+  , "category": "Objects"
+  , "aliases": [
+      "mute"
+    ]
+  , "tags": [
+      "sound"
+    , "volume"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔈"
+  , "description": "speaker low volume"
+  , "category": "Objects"
+  , "aliases": [
+      "speaker"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔉"
+  , "description": "speaker medium volume"
+  , "category": "Objects"
+  , "aliases": [
+      "sound"
+    ]
+  , "tags": [
+      "volume"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔊"
+  , "description": "speaker high volume"
+  , "category": "Objects"
+  , "aliases": [
+      "loud_sound"
+    ]
+  , "tags": [
+      "volume"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📢"
+  , "description": "loudspeaker"
+  , "category": "Objects"
+  , "aliases": [
+      "loudspeaker"
+    ]
+  , "tags": [
+      "announcement"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📣"
+  , "description": "megaphone"
+  , "category": "Objects"
+  , "aliases": [
+      "mega"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📯"
+  , "description": "postal horn"
+  , "category": "Objects"
+  , "aliases": [
+      "postal_horn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔔"
+  , "description": "bell"
+  , "category": "Objects"
+  , "aliases": [
+      "bell"
+    ]
+  , "tags": [
+      "sound"
+    , "notification"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔕"
+  , "description": "bell with slash"
+  , "category": "Objects"
+  , "aliases": [
+      "no_bell"
+    ]
+  , "tags": [
+      "volume"
+    , "off"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎼"
+  , "description": "musical score"
+  , "category": "Objects"
+  , "aliases": [
+      "musical_score"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎵"
+  , "description": "musical note"
+  , "category": "Objects"
+  , "aliases": [
+      "musical_note"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎶"
+  , "description": "musical notes"
+  , "category": "Objects"
+  , "aliases": [
+      "notes"
+    ]
+  , "tags": [
+      "music"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎙"
+  , "description": "studio microphone"
+  , "category": "Objects"
+  , "aliases": [
+      "studio_microphone"
+    ]
+  , "tags": [
+      "podcast"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎚"
+  , "description": "level slider"
+  , "category": "Objects"
+  , "aliases": [
+      "level_slider"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎛"
+  , "description": "control knobs"
+  , "category": "Objects"
+  , "aliases": [
+      "control_knobs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎤"
+  , "description": "microphone"
+  , "category": "Objects"
+  , "aliases": [
+      "microphone"
+    ]
+  , "tags": [
+      "sing"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎧"
+  , "description": "headphone"
+  , "category": "Objects"
+  , "aliases": [
+      "headphones"
+    ]
+  , "tags": [
+      "music"
+    , "earphones"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📻"
+  , "description": "radio"
+  , "category": "Objects"
+  , "aliases": [
+      "radio"
+    ]
+  , "tags": [
+      "podcast"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎷"
+  , "description": "saxophone"
+  , "category": "Objects"
+  , "aliases": [
+      "saxophone"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎸"
+  , "description": "guitar"
+  , "category": "Objects"
+  , "aliases": [
+      "guitar"
+    ]
+  , "tags": [
+      "rock"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎹"
+  , "description": "musical keyboard"
+  , "category": "Objects"
+  , "aliases": [
+      "musical_keyboard"
+    ]
+  , "tags": [
+      "piano"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎺"
+  , "description": "trumpet"
+  , "category": "Objects"
+  , "aliases": [
+      "trumpet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎻"
+  , "description": "violin"
+  , "category": "Objects"
+  , "aliases": [
+      "violin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🪕"
+  , "description": "banjo"
+  , "category": "Objects"
+  , "aliases": [
+      "banjo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🥁"
+  , "description": "drum"
+  , "category": "Objects"
+  , "aliases": [
+      "drum"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "📱"
+  , "description": "mobile phone"
+  , "category": "Objects"
+  , "aliases": [
+      "iphone"
+    ]
+  , "tags": [
+      "smartphone"
+    , "mobile"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📲"
+  , "description": "mobile phone with arrow"
+  , "category": "Objects"
+  , "aliases": [
+      "calling"
+    ]
+  , "tags": [
+      "call"
+    , "incoming"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☎️"
+  , "description": "telephone"
+  , "category": "Objects"
+  , "aliases": [
+      "phone"
+    , "telephone"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📞"
+  , "description": "telephone receiver"
+  , "category": "Objects"
+  , "aliases": [
+      "telephone_receiver"
+    ]
+  , "tags": [
+      "phone"
+    , "call"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📟"
+  , "description": "pager"
+  , "category": "Objects"
+  , "aliases": [
+      "pager"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📠"
+  , "description": "fax machine"
+  , "category": "Objects"
+  , "aliases": [
+      "fax"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔋"
+  , "description": "battery"
+  , "category": "Objects"
+  , "aliases": [
+      "battery"
+    ]
+  , "tags": [
+      "power"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔌"
+  , "description": "electric plug"
+  , "category": "Objects"
+  , "aliases": [
+      "electric_plug"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💻"
+  , "description": "laptop computer"
+  , "category": "Objects"
+  , "aliases": [
+      "computer"
+    ]
+  , "tags": [
+      "desktop"
+    , "screen"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🖥"
+  , "description": "desktop computer"
+  , "category": "Objects"
+  , "aliases": [
+      "desktop_computer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🖨"
+  , "description": "printer"
+  , "category": "Objects"
+  , "aliases": [
+      "printer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⌨"
+  , "description": "keyboard"
+  , "category": "Objects"
+  , "aliases": [
+      "keyboard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🖱"
+  , "description": "computer mouse"
+  , "category": "Objects"
+  , "aliases": [
+      "computer_mouse"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🖲"
+  , "description": "trackball"
+  , "category": "Objects"
+  , "aliases": [
+      "trackball"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💽"
+  , "description": "computer disk"
+  , "category": "Objects"
+  , "aliases": [
+      "minidisc"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💾"
+  , "description": "floppy disk"
+  , "category": "Objects"
+  , "aliases": [
+      "floppy_disk"
+    ]
+  , "tags": [
+      "save"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💿"
+  , "description": "optical disk"
+  , "category": "Objects"
+  , "aliases": [
+      "cd"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📀"
+  , "description": "dvd"
+  , "category": "Objects"
+  , "aliases": [
+      "dvd"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧮"
+  , "description": "abacus"
+  , "category": "Objects"
+  , "aliases": [
+      "abacus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🎥"
+  , "description": "movie camera"
+  , "category": "Objects"
+  , "aliases": [
+      "movie_camera"
+    ]
+  , "tags": [
+      "film"
+    , "video"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎞"
+  , "description": "film frames"
+  , "category": "Objects"
+  , "aliases": [
+      "film_strip"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📽"
+  , "description": "film projector"
+  , "category": "Objects"
+  , "aliases": [
+      "film_projector"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🎬"
+  , "description": "clapper board"
+  , "category": "Objects"
+  , "aliases": [
+      "clapper"
+    ]
+  , "tags": [
+      "film"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📺"
+  , "description": "television"
+  , "category": "Objects"
+  , "aliases": [
+      "tv"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📷"
+  , "description": "camera"
+  , "category": "Objects"
+  , "aliases": [
+      "camera"
+    ]
+  , "tags": [
+      "photo"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📸"
+  , "description": "camera with flash"
+  , "category": "Objects"
+  , "aliases": [
+      "camera_flash"
+    ]
+  , "tags": [
+      "photo"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📹"
+  , "description": "video camera"
+  , "category": "Objects"
+  , "aliases": [
+      "video_camera"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📼"
+  , "description": "videocassette"
+  , "category": "Objects"
+  , "aliases": [
+      "vhs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔍"
+  , "description": "magnifying glass tilted left"
+  , "category": "Objects"
+  , "aliases": [
+      "mag"
+    ]
+  , "tags": [
+      "search"
+    , "zoom"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔎"
+  , "description": "magnifying glass tilted right"
+  , "category": "Objects"
+  , "aliases": [
+      "mag_right"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🕯"
+  , "description": "candle"
+  , "category": "Objects"
+  , "aliases": [
+      "candle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💡"
+  , "description": "light bulb"
+  , "category": "Objects"
+  , "aliases": [
+      "bulb"
+    ]
+  , "tags": [
+      "idea"
+    , "light"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔦"
+  , "description": "flashlight"
+  , "category": "Objects"
+  , "aliases": [
+      "flashlight"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏮"
+  , "description": "red paper lantern"
+  , "category": "Objects"
+  , "aliases": [
+      "izakaya_lantern"
+    , "lantern"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🪔"
+  , "description": "diya lamp"
+  , "category": "Objects"
+  , "aliases": [
+      "diya_lamp"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "📔"
+  , "description": "notebook with decorative cover"
+  , "category": "Objects"
+  , "aliases": [
+      "notebook_with_decorative_cover"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📕"
+  , "description": "closed book"
+  , "category": "Objects"
+  , "aliases": [
+      "closed_book"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📖"
+  , "description": "open book"
+  , "category": "Objects"
+  , "aliases": [
+      "book"
+    , "open_book"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📗"
+  , "description": "green book"
+  , "category": "Objects"
+  , "aliases": [
+      "green_book"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📘"
+  , "description": "blue book"
+  , "category": "Objects"
+  , "aliases": [
+      "blue_book"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📙"
+  , "description": "orange book"
+  , "category": "Objects"
+  , "aliases": [
+      "orange_book"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📚"
+  , "description": "books"
+  , "category": "Objects"
+  , "aliases": [
+      "books"
+    ]
+  , "tags": [
+      "library"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📓"
+  , "description": "notebook"
+  , "category": "Objects"
+  , "aliases": [
+      "notebook"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📒"
+  , "description": "ledger"
+  , "category": "Objects"
+  , "aliases": [
+      "ledger"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📃"
+  , "description": "page with curl"
+  , "category": "Objects"
+  , "aliases": [
+      "page_with_curl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📜"
+  , "description": "scroll"
+  , "category": "Objects"
+  , "aliases": [
+      "scroll"
+    ]
+  , "tags": [
+      "document"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📄"
+  , "description": "page facing up"
+  , "category": "Objects"
+  , "aliases": [
+      "page_facing_up"
+    ]
+  , "tags": [
+      "document"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📰"
+  , "description": "newspaper"
+  , "category": "Objects"
+  , "aliases": [
+      "newspaper"
+    ]
+  , "tags": [
+      "press"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗞"
+  , "description": "rolled-up newspaper"
+  , "category": "Objects"
+  , "aliases": [
+      "newspaper_roll"
+    ]
+  , "tags": [
+      "press"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📑"
+  , "description": "bookmark tabs"
+  , "category": "Objects"
+  , "aliases": [
+      "bookmark_tabs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔖"
+  , "description": "bookmark"
+  , "category": "Objects"
+  , "aliases": [
+      "bookmark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏷"
+  , "description": "label"
+  , "category": "Objects"
+  , "aliases": [
+      "label"
+    ]
+  , "tags": [
+      "tag"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "💰"
+  , "description": "money bag"
+  , "category": "Objects"
+  , "aliases": [
+      "moneybag"
+    ]
+  , "tags": [
+      "dollar"
+    , "cream"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💴"
+  , "description": "yen banknote"
+  , "category": "Objects"
+  , "aliases": [
+      "yen"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💵"
+  , "description": "dollar banknote"
+  , "category": "Objects"
+  , "aliases": [
+      "dollar"
+    ]
+  , "tags": [
+      "money"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💶"
+  , "description": "euro banknote"
+  , "category": "Objects"
+  , "aliases": [
+      "euro"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💷"
+  , "description": "pound banknote"
+  , "category": "Objects"
+  , "aliases": [
+      "pound"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💸"
+  , "description": "money with wings"
+  , "category": "Objects"
+  , "aliases": [
+      "money_with_wings"
+    ]
+  , "tags": [
+      "dollar"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💳"
+  , "description": "credit card"
+  , "category": "Objects"
+  , "aliases": [
+      "credit_card"
+    ]
+  , "tags": [
+      "subscription"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🧾"
+  , "description": "receipt"
+  , "category": "Objects"
+  , "aliases": [
+      "receipt"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "💹"
+  , "description": "chart increasing with yen"
+  , "category": "Objects"
+  , "aliases": [
+      "chart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💱"
+  , "description": "currency exchange"
+  , "category": "Objects"
+  , "aliases": [
+      "currency_exchange"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💲"
+  , "description": "heavy dollar sign"
+  , "category": "Objects"
+  , "aliases": [
+      "heavy_dollar_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✉️"
+  , "description": "envelope"
+  , "category": "Objects"
+  , "aliases": [
+      "email"
+    , "envelope"
+    ]
+  , "tags": [
+      "letter"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📧"
+  , "description": "e-mail"
+  , "category": "Objects"
+  , "aliases": [
+      "e-mail"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📨"
+  , "description": "incoming envelope"
+  , "category": "Objects"
+  , "aliases": [
+      "incoming_envelope"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📩"
+  , "description": "envelope with arrow"
+  , "category": "Objects"
+  , "aliases": [
+      "envelope_with_arrow"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📤"
+  , "description": "outbox tray"
+  , "category": "Objects"
+  , "aliases": [
+      "outbox_tray"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📥"
+  , "description": "inbox tray"
+  , "category": "Objects"
+  , "aliases": [
+      "inbox_tray"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📦"
+  , "description": "package"
+  , "category": "Objects"
+  , "aliases": [
+      "package"
+    ]
+  , "tags": [
+      "shipping"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📫"
+  , "description": "closed mailbox with raised flag"
+  , "category": "Objects"
+  , "aliases": [
+      "mailbox"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📪"
+  , "description": "closed mailbox with lowered flag"
+  , "category": "Objects"
+  , "aliases": [
+      "mailbox_closed"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📬"
+  , "description": "open mailbox with raised flag"
+  , "category": "Objects"
+  , "aliases": [
+      "mailbox_with_mail"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📭"
+  , "description": "open mailbox with lowered flag"
+  , "category": "Objects"
+  , "aliases": [
+      "mailbox_with_no_mail"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📮"
+  , "description": "postbox"
+  , "category": "Objects"
+  , "aliases": [
+      "postbox"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗳"
+  , "description": "ballot box with ballot"
+  , "category": "Objects"
+  , "aliases": [
+      "ballot_box"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "✏️"
+  , "description": "pencil"
+  , "category": "Objects"
+  , "aliases": [
+      "pencil2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✒️"
+  , "description": "black nib"
+  , "category": "Objects"
+  , "aliases": [
+      "black_nib"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🖋"
+  , "description": "fountain pen"
+  , "category": "Objects"
+  , "aliases": [
+      "fountain_pen"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🖊"
+  , "description": "pen"
+  , "category": "Objects"
+  , "aliases": [
+      "pen"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🖌"
+  , "description": "paintbrush"
+  , "category": "Objects"
+  , "aliases": [
+      "paintbrush"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🖍"
+  , "description": "crayon"
+  , "category": "Objects"
+  , "aliases": [
+      "crayon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📝"
+  , "description": "memo"
+  , "category": "Objects"
+  , "aliases": [
+      "memo"
+    , "pencil"
+    ]
+  , "tags": [
+      "document"
+    , "note"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💼"
+  , "description": "briefcase"
+  , "category": "Objects"
+  , "aliases": [
+      "briefcase"
+    ]
+  , "tags": [
+      "business"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📁"
+  , "description": "file folder"
+  , "category": "Objects"
+  , "aliases": [
+      "file_folder"
+    ]
+  , "tags": [
+      "directory"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📂"
+  , "description": "open file folder"
+  , "category": "Objects"
+  , "aliases": [
+      "open_file_folder"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗂"
+  , "description": "card index dividers"
+  , "category": "Objects"
+  , "aliases": [
+      "card_index_dividers"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📅"
+  , "description": "calendar"
+  , "category": "Objects"
+  , "aliases": [
+      "date"
+    ]
+  , "tags": [
+      "calendar"
+    , "schedule"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📆"
+  , "description": "tear-off calendar"
+  , "category": "Objects"
+  , "aliases": [
+      "calendar"
+    ]
+  , "tags": [
+      "schedule"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗒"
+  , "description": "spiral notepad"
+  , "category": "Objects"
+  , "aliases": [
+      "spiral_notepad"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗓"
+  , "description": "spiral calendar"
+  , "category": "Objects"
+  , "aliases": [
+      "spiral_calendar"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📇"
+  , "description": "card index"
+  , "category": "Objects"
+  , "aliases": [
+      "card_index"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📈"
+  , "description": "chart increasing"
+  , "category": "Objects"
+  , "aliases": [
+      "chart_with_upwards_trend"
+    ]
+  , "tags": [
+      "graph"
+    , "metrics"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📉"
+  , "description": "chart decreasing"
+  , "category": "Objects"
+  , "aliases": [
+      "chart_with_downwards_trend"
+    ]
+  , "tags": [
+      "graph"
+    , "metrics"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📊"
+  , "description": "bar chart"
+  , "category": "Objects"
+  , "aliases": [
+      "bar_chart"
+    ]
+  , "tags": [
+      "stats"
+    , "metrics"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📋"
+  , "description": "clipboard"
+  , "category": "Objects"
+  , "aliases": [
+      "clipboard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📌"
+  , "description": "pushpin"
+  , "category": "Objects"
+  , "aliases": [
+      "pushpin"
+    ]
+  , "tags": [
+      "location"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📍"
+  , "description": "round pushpin"
+  , "category": "Objects"
+  , "aliases": [
+      "round_pushpin"
+    ]
+  , "tags": [
+      "location"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📎"
+  , "description": "paperclip"
+  , "category": "Objects"
+  , "aliases": [
+      "paperclip"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🖇"
+  , "description": "linked paperclips"
+  , "category": "Objects"
+  , "aliases": [
+      "paperclips"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "📏"
+  , "description": "straight ruler"
+  , "category": "Objects"
+  , "aliases": [
+      "straight_ruler"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📐"
+  , "description": "triangular ruler"
+  , "category": "Objects"
+  , "aliases": [
+      "triangular_ruler"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✂️"
+  , "description": "scissors"
+  , "category": "Objects"
+  , "aliases": [
+      "scissors"
+    ]
+  , "tags": [
+      "cut"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗃"
+  , "description": "card file box"
+  , "category": "Objects"
+  , "aliases": [
+      "card_file_box"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗄"
+  , "description": "file cabinet"
+  , "category": "Objects"
+  , "aliases": [
+      "file_cabinet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗑"
+  , "description": "wastebasket"
+  , "category": "Objects"
+  , "aliases": [
+      "wastebasket"
+    ]
+  , "tags": [
+      "trash"
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔒"
+  , "description": "locked"
+  , "category": "Objects"
+  , "aliases": [
+      "lock"
+    ]
+  , "tags": [
+      "security"
+    , "private"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔓"
+  , "description": "unlocked"
+  , "category": "Objects"
+  , "aliases": [
+      "unlock"
+    ]
+  , "tags": [
+      "security"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔏"
+  , "description": "locked with pen"
+  , "category": "Objects"
+  , "aliases": [
+      "lock_with_ink_pen"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔐"
+  , "description": "locked with key"
+  , "category": "Objects"
+  , "aliases": [
+      "closed_lock_with_key"
+    ]
+  , "tags": [
+      "security"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔑"
+  , "description": "key"
+  , "category": "Objects"
+  , "aliases": [
+      "key"
+    ]
+  , "tags": [
+      "lock"
+    , "password"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🗝"
+  , "description": "old key"
+  , "category": "Objects"
+  , "aliases": [
+      "old_key"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔨"
+  , "description": "hammer"
+  , "category": "Objects"
+  , "aliases": [
+      "hammer"
+    ]
+  , "tags": [
+      "tool"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🪓"
+  , "description": "axe"
+  , "category": "Objects"
+  , "aliases": [
+      "axe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "⛏"
+  , "description": "pick"
+  , "category": "Objects"
+  , "aliases": [
+      "pick"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⚒"
+  , "description": "hammer and pick"
+  , "category": "Objects"
+  , "aliases": [
+      "hammer_and_pick"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛠"
+  , "description": "hammer and wrench"
+  , "category": "Objects"
+  , "aliases": [
+      "hammer_and_wrench"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗡"
+  , "description": "dagger"
+  , "category": "Objects"
+  , "aliases": [
+      "dagger"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⚔"
+  , "description": "crossed swords"
+  , "category": "Objects"
+  , "aliases": [
+      "crossed_swords"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔫"
+  , "description": "pistol"
+  , "category": "Objects"
+  , "aliases": [
+      "gun"
+    ]
+  , "tags": [
+      "shoot"
+    , "weapon"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏹"
+  , "description": "bow and arrow"
+  , "category": "Objects"
+  , "aliases": [
+      "bow_and_arrow"
+    ]
+  , "tags": [
+      "archery"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛡"
+  , "description": "shield"
+  , "category": "Objects"
+  , "aliases": [
+      "shield"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔧"
+  , "description": "wrench"
+  , "category": "Objects"
+  , "aliases": [
+      "wrench"
+    ]
+  , "tags": [
+      "tool"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔩"
+  , "description": "nut and bolt"
+  , "category": "Objects"
+  , "aliases": [
+      "nut_and_bolt"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚙"
+  , "description": "gear"
+  , "category": "Objects"
+  , "aliases": [
+      "gear"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗜"
+  , "description": "clamp"
+  , "category": "Objects"
+  , "aliases": [
+      "clamp"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⚖"
+  , "description": "balance scale"
+  , "category": "Objects"
+  , "aliases": [
+      "balance_scale"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🦯"
+  , "description": "probing cane"
+  , "category": "Objects"
+  , "aliases": [
+      "probing_cane"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🔗"
+  , "description": "link"
+  , "category": "Objects"
+  , "aliases": [
+      "link"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛓"
+  , "description": "chains"
+  , "category": "Objects"
+  , "aliases": [
+      "chains"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🧰"
+  , "description": "toolbox"
+  , "category": "Objects"
+  , "aliases": [
+      "toolbox"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧲"
+  , "description": "magnet"
+  , "category": "Objects"
+  , "aliases": [
+      "magnet"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "⚗"
+  , "description": "alembic"
+  , "category": "Objects"
+  , "aliases": [
+      "alembic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🧪"
+  , "description": "test tube"
+  , "category": "Objects"
+  , "aliases": [
+      "test_tube"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧫"
+  , "description": "petri dish"
+  , "category": "Objects"
+  , "aliases": [
+      "petri_dish"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧬"
+  , "description": "dna"
+  , "category": "Objects"
+  , "aliases": [
+      "dna"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🔬"
+  , "description": "microscope"
+  , "category": "Objects"
+  , "aliases": [
+      "microscope"
+    ]
+  , "tags": [
+      "science"
+    , "laboratory"
+    , "investigate"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔭"
+  , "description": "telescope"
+  , "category": "Objects"
+  , "aliases": [
+      "telescope"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📡"
+  , "description": "satellite antenna"
+  , "category": "Objects"
+  , "aliases": [
+      "satellite"
+    ]
+  , "tags": [
+      "signal"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💉"
+  , "description": "syringe"
+  , "category": "Objects"
+  , "aliases": [
+      "syringe"
+    ]
+  , "tags": [
+      "health"
+    , "hospital"
+    , "needle"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🩸"
+  , "description": "drop of blood"
+  , "category": "Objects"
+  , "aliases": [
+      "drop_of_blood"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "💊"
+  , "description": "pill"
+  , "category": "Objects"
+  , "aliases": [
+      "pill"
+    ]
+  , "tags": [
+      "health"
+    , "medicine"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🩹"
+  , "description": "adhesive bandage"
+  , "category": "Objects"
+  , "aliases": [
+      "adhesive_bandage"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🩺"
+  , "description": "stethoscope"
+  , "category": "Objects"
+  , "aliases": [
+      "stethoscope"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🚪"
+  , "description": "door"
+  , "category": "Objects"
+  , "aliases": [
+      "door"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛏"
+  , "description": "bed"
+  , "category": "Objects"
+  , "aliases": [
+      "bed"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🛋"
+  , "description": "couch and lamp"
+  , "category": "Objects"
+  , "aliases": [
+      "couch_and_lamp"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🪑"
+  , "description": "chair"
+  , "category": "Objects"
+  , "aliases": [
+      "chair"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🚽"
+  , "description": "toilet"
+  , "category": "Objects"
+  , "aliases": [
+      "toilet"
+    ]
+  , "tags": [
+      "wc"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚿"
+  , "description": "shower"
+  , "category": "Objects"
+  , "aliases": [
+      "shower"
+    ]
+  , "tags": [
+      "bath"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛁"
+  , "description": "bathtub"
+  , "category": "Objects"
+  , "aliases": [
+      "bathtub"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🪒"
+  , "description": "razor"
+  , "category": "Objects"
+  , "aliases": [
+      "razor"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🧴"
+  , "description": "lotion bottle"
+  , "category": "Objects"
+  , "aliases": [
+      "lotion_bottle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧷"
+  , "description": "safety pin"
+  , "category": "Objects"
+  , "aliases": [
+      "safety_pin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧹"
+  , "description": "broom"
+  , "category": "Objects"
+  , "aliases": [
+      "broom"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧺"
+  , "description": "basket"
+  , "category": "Objects"
+  , "aliases": [
+      "basket"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧻"
+  , "description": "roll of paper"
+  , "category": "Objects"
+  , "aliases": [
+      "roll_of_paper"
+    ]
+  , "tags": [
+      "toilet"
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧼"
+  , "description": "soap"
+  , "category": "Objects"
+  , "aliases": [
+      "soap"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧽"
+  , "description": "sponge"
+  , "category": "Objects"
+  , "aliases": [
+      "sponge"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🧯"
+  , "description": "fire extinguisher"
+  , "category": "Objects"
+  , "aliases": [
+      "fire_extinguisher"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🛒"
+  , "description": "shopping cart"
+  , "category": "Objects"
+  , "aliases": [
+      "shopping_cart"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "9.0"
+  , "ios_version": "10.2"
+  }
+, {
+    "emoji": "🚬"
+  , "description": "cigarette"
+  , "category": "Objects"
+  , "aliases": [
+      "smoking"
+    ]
+  , "tags": [
+      "cigarette"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚰"
+  , "description": "coffin"
+  , "category": "Objects"
+  , "aliases": [
+      "coffin"
+    ]
+  , "tags": [
+      "funeral"
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⚱"
+  , "description": "funeral urn"
+  , "category": "Objects"
+  , "aliases": [
+      "funeral_urn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🗿"
+  , "description": "moai"
+  , "category": "Objects"
+  , "aliases": [
+      "moyai"
+    ]
+  , "tags": [
+      "stone"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏧"
+  , "description": "ATM sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "atm"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚮"
+  , "description": "litter in bin sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "put_litter_in_its_place"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚰"
+  , "description": "potable water"
+  , "category": "Symbols"
+  , "aliases": [
+      "potable_water"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♿"
+  , "description": "wheelchair symbol"
+  , "category": "Symbols"
+  , "aliases": [
+      "wheelchair"
+    ]
+  , "tags": [
+      "accessibility"
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚹"
+  , "description": "men’s room"
+  , "category": "Symbols"
+  , "aliases": [
+      "mens"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚺"
+  , "description": "women’s room"
+  , "category": "Symbols"
+  , "aliases": [
+      "womens"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚻"
+  , "description": "restroom"
+  , "category": "Symbols"
+  , "aliases": [
+      "restroom"
+    ]
+  , "tags": [
+      "toilet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚼"
+  , "description": "baby symbol"
+  , "category": "Symbols"
+  , "aliases": [
+      "baby_symbol"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚾"
+  , "description": "water closet"
+  , "category": "Symbols"
+  , "aliases": [
+      "wc"
+    ]
+  , "tags": [
+      "toilet"
+    , "restroom"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛂"
+  , "description": "passport control"
+  , "category": "Symbols"
+  , "aliases": [
+      "passport_control"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛃"
+  , "description": "customs"
+  , "category": "Symbols"
+  , "aliases": [
+      "customs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛄"
+  , "description": "baggage claim"
+  , "category": "Symbols"
+  , "aliases": [
+      "baggage_claim"
+    ]
+  , "tags": [
+      "airport"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛅"
+  , "description": "left luggage"
+  , "category": "Symbols"
+  , "aliases": [
+      "left_luggage"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚠️"
+  , "description": "warning"
+  , "category": "Symbols"
+  , "aliases": [
+      "warning"
+    ]
+  , "tags": [
+      "wip"
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚸"
+  , "description": "children crossing"
+  , "category": "Symbols"
+  , "aliases": [
+      "children_crossing"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛔"
+  , "description": "no entry"
+  , "category": "Symbols"
+  , "aliases": [
+      "no_entry"
+    ]
+  , "tags": [
+      "limit"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚫"
+  , "description": "prohibited"
+  , "category": "Symbols"
+  , "aliases": [
+      "no_entry_sign"
+    ]
+  , "tags": [
+      "block"
+    , "forbidden"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚳"
+  , "description": "no bicycles"
+  , "category": "Symbols"
+  , "aliases": [
+      "no_bicycles"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚭"
+  , "description": "no smoking"
+  , "category": "Symbols"
+  , "aliases": [
+      "no_smoking"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚯"
+  , "description": "no littering"
+  , "category": "Symbols"
+  , "aliases": [
+      "do_not_litter"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚱"
+  , "description": "non-potable water"
+  , "category": "Symbols"
+  , "aliases": [
+      "non-potable_water"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚷"
+  , "description": "no pedestrians"
+  , "category": "Symbols"
+  , "aliases": [
+      "no_pedestrians"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📵"
+  , "description": "no mobile phones"
+  , "category": "Symbols"
+  , "aliases": [
+      "no_mobile_phones"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔞"
+  , "description": "no one under eighteen"
+  , "category": "Symbols"
+  , "aliases": [
+      "underage"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☢"
+  , "description": "radioactive"
+  , "category": "Symbols"
+  , "aliases": [
+      "radioactive"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☣"
+  , "description": "biohazard"
+  , "category": "Symbols"
+  , "aliases": [
+      "biohazard"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⬆️"
+  , "description": "up arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_up"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↗️"
+  , "description": "up-right arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_upper_right"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "➡️"
+  , "description": "right arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_right"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↘️"
+  , "description": "down-right arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_lower_right"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⬇️"
+  , "description": "down arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_down"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↙️"
+  , "description": "down-left arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_lower_left"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⬅️"
+  , "description": "left arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_left"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↖️"
+  , "description": "up-left arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_upper_left"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↕️"
+  , "description": "up-down arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_up_down"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↔️"
+  , "description": "left-right arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "left_right_arrow"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↩️"
+  , "description": "right arrow curving left"
+  , "category": "Symbols"
+  , "aliases": [
+      "leftwards_arrow_with_hook"
+    ]
+  , "tags": [
+      "return"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "↪️"
+  , "description": "left arrow curving right"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_right_hook"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⤴️"
+  , "description": "right arrow curving up"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_heading_up"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⤵️"
+  , "description": "right arrow curving down"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_heading_down"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔃"
+  , "description": "clockwise vertical arrows"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrows_clockwise"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔄"
+  , "description": "counterclockwise arrows button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrows_counterclockwise"
+    ]
+  , "tags": [
+      "sync"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔙"
+  , "description": "BACK arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "back"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔚"
+  , "description": "END arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "end"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔛"
+  , "description": "ON! arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "on"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔜"
+  , "description": "SOON arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "soon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔝"
+  , "description": "TOP arrow"
+  , "category": "Symbols"
+  , "aliases": [
+      "top"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🛐"
+  , "description": "place of worship"
+  , "category": "Symbols"
+  , "aliases": [
+      "place_of_worship"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⚛"
+  , "description": "atom symbol"
+  , "category": "Symbols"
+  , "aliases": [
+      "atom_symbol"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🕉"
+  , "description": "om"
+  , "category": "Symbols"
+  , "aliases": [
+      "om"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "✡️"
+  , "description": "star of David"
+  , "category": "Symbols"
+  , "aliases": [
+      "star_of_david"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☸"
+  , "description": "wheel of dharma"
+  , "category": "Symbols"
+  , "aliases": [
+      "wheel_of_dharma"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☯️"
+  , "description": "yin yang"
+  , "category": "Symbols"
+  , "aliases": [
+      "yin_yang"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "✝️"
+  , "description": "latin cross"
+  , "category": "Symbols"
+  , "aliases": [
+      "latin_cross"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☦"
+  , "description": "orthodox cross"
+  , "category": "Symbols"
+  , "aliases": [
+      "orthodox_cross"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☪"
+  , "description": "star and crescent"
+  , "category": "Symbols"
+  , "aliases": [
+      "star_and_crescent"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "☮"
+  , "description": "peace symbol"
+  , "category": "Symbols"
+  , "aliases": [
+      "peace_symbol"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🕎"
+  , "description": "menorah"
+  , "category": "Symbols"
+  , "aliases": [
+      "menorah"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔯"
+  , "description": "dotted six-pointed star"
+  , "category": "Symbols"
+  , "aliases": [
+      "six_pointed_star"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♈"
+  , "description": "Aries"
+  , "category": "Symbols"
+  , "aliases": [
+      "aries"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♉"
+  , "description": "Taurus"
+  , "category": "Symbols"
+  , "aliases": [
+      "taurus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♊"
+  , "description": "Gemini"
+  , "category": "Symbols"
+  , "aliases": [
+      "gemini"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♋"
+  , "description": "Cancer"
+  , "category": "Symbols"
+  , "aliases": [
+      "cancer"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♌"
+  , "description": "Leo"
+  , "category": "Symbols"
+  , "aliases": [
+      "leo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♍"
+  , "description": "Virgo"
+  , "category": "Symbols"
+  , "aliases": [
+      "virgo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♎"
+  , "description": "Libra"
+  , "category": "Symbols"
+  , "aliases": [
+      "libra"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♏"
+  , "description": "Scorpio"
+  , "category": "Symbols"
+  , "aliases": [
+      "scorpius"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♐"
+  , "description": "Sagittarius"
+  , "category": "Symbols"
+  , "aliases": [
+      "sagittarius"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♑"
+  , "description": "Capricorn"
+  , "category": "Symbols"
+  , "aliases": [
+      "capricorn"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♒"
+  , "description": "Aquarius"
+  , "category": "Symbols"
+  , "aliases": [
+      "aquarius"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♓"
+  , "description": "Pisces"
+  , "category": "Symbols"
+  , "aliases": [
+      "pisces"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⛎"
+  , "description": "Ophiuchus"
+  , "category": "Symbols"
+  , "aliases": [
+      "ophiuchus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔀"
+  , "description": "shuffle tracks button"
+  , "category": "Symbols"
+  , "aliases": [
+      "twisted_rightwards_arrows"
+    ]
+  , "tags": [
+      "shuffle"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔁"
+  , "description": "repeat button"
+  , "category": "Symbols"
+  , "aliases": [
+      "repeat"
+    ]
+  , "tags": [
+      "loop"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔂"
+  , "description": "repeat single button"
+  , "category": "Symbols"
+  , "aliases": [
+      "repeat_one"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "▶️"
+  , "description": "play button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_forward"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏩"
+  , "description": "fast-forward button"
+  , "category": "Symbols"
+  , "aliases": [
+      "fast_forward"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏭"
+  , "description": "next track button"
+  , "category": "Symbols"
+  , "aliases": [
+      "next_track_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⏯"
+  , "description": "play or pause button"
+  , "category": "Symbols"
+  , "aliases": [
+      "play_or_pause_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "◀️"
+  , "description": "reverse button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_backward"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏪"
+  , "description": "fast reverse button"
+  , "category": "Symbols"
+  , "aliases": [
+      "rewind"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏮"
+  , "description": "last track button"
+  , "category": "Symbols"
+  , "aliases": [
+      "previous_track_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔼"
+  , "description": "upwards button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_up_small"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏫"
+  , "description": "fast up button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_double_up"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔽"
+  , "description": "downwards button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_down_small"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏬"
+  , "description": "fast down button"
+  , "category": "Symbols"
+  , "aliases": [
+      "arrow_double_down"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⏸"
+  , "description": "pause button"
+  , "category": "Symbols"
+  , "aliases": [
+      "pause_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⏹"
+  , "description": "stop button"
+  , "category": "Symbols"
+  , "aliases": [
+      "stop_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⏺"
+  , "description": "record button"
+  , "category": "Symbols"
+  , "aliases": [
+      "record_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "⏏️"
+  , "description": "eject button"
+  , "category": "Symbols"
+  , "aliases": [
+      "eject_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🎦"
+  , "description": "cinema"
+  , "category": "Symbols"
+  , "aliases": [
+      "cinema"
+    ]
+  , "tags": [
+      "film"
+    , "movie"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔅"
+  , "description": "dim button"
+  , "category": "Symbols"
+  , "aliases": [
+      "low_brightness"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔆"
+  , "description": "bright button"
+  , "category": "Symbols"
+  , "aliases": [
+      "high_brightness"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📶"
+  , "description": "antenna bars"
+  , "category": "Symbols"
+  , "aliases": [
+      "signal_strength"
+    ]
+  , "tags": [
+      "wifi"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📳"
+  , "description": "vibration mode"
+  , "category": "Symbols"
+  , "aliases": [
+      "vibration_mode"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📴"
+  , "description": "mobile phone off"
+  , "category": "Symbols"
+  , "aliases": [
+      "mobile_phone_off"
+    ]
+  , "tags": [
+      "mute"
+    , "off"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "♀️"
+  , "description": "female sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "female_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "♂️"
+  , "description": "male sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "male_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "⚕"
+  , "description": "medical symbol"
+  , "category": "Symbols"
+  , "aliases": [
+      "medical_symbol"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "♾"
+  , "description": "infinity"
+  , "category": "Symbols"
+  , "aliases": [
+      "infinity"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "♻️"
+  , "description": "recycling symbol"
+  , "category": "Symbols"
+  , "aliases": [
+      "recycle"
+    ]
+  , "tags": [
+      "environment"
+    , "green"
+    ]
+  , "unicode_version": "3.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚜"
+  , "description": "fleur-de-lis"
+  , "category": "Symbols"
+  , "aliases": [
+      "fleur_de_lis"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🔱"
+  , "description": "trident emblem"
+  , "category": "Symbols"
+  , "aliases": [
+      "trident"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "📛"
+  , "description": "name badge"
+  , "category": "Symbols"
+  , "aliases": [
+      "name_badge"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔰"
+  , "description": "Japanese symbol for beginner"
+  , "category": "Symbols"
+  , "aliases": [
+      "beginner"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⭕"
+  , "description": "hollow red circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "o"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✅"
+  , "description": "check mark button"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_check_mark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "☑️"
+  , "description": "check box with check"
+  , "category": "Symbols"
+  , "aliases": [
+      "ballot_box_with_check"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✔️"
+  , "description": "check mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "heavy_check_mark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✖️"
+  , "description": "multiplication sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "heavy_multiplication_x"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❌"
+  , "description": "cross mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "x"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❎"
+  , "description": "cross mark button"
+  , "category": "Symbols"
+  , "aliases": [
+      "negative_squared_cross_mark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "➕"
+  , "description": "plus sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "heavy_plus_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "➖"
+  , "description": "minus sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "heavy_minus_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "➗"
+  , "description": "division sign"
+  , "category": "Symbols"
+  , "aliases": [
+      "heavy_division_sign"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "➰"
+  , "description": "curly loop"
+  , "category": "Symbols"
+  , "aliases": [
+      "curly_loop"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "➿"
+  , "description": "double curly loop"
+  , "category": "Symbols"
+  , "aliases": [
+      "loop"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "〽️"
+  , "description": "part alternation mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "part_alternation_mark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✳️"
+  , "description": "eight-spoked asterisk"
+  , "category": "Symbols"
+  , "aliases": [
+      "eight_spoked_asterisk"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "✴️"
+  , "description": "eight-pointed star"
+  , "category": "Symbols"
+  , "aliases": [
+      "eight_pointed_black_star"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❇️"
+  , "description": "sparkle"
+  , "category": "Symbols"
+  , "aliases": [
+      "sparkle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "‼️"
+  , "description": "double exclamation mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "bangbang"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⁉️"
+  , "description": "exclamation question mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "interrobang"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❓"
+  , "description": "question mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "question"
+    ]
+  , "tags": [
+      "confused"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❔"
+  , "description": "white question mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "grey_question"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❕"
+  , "description": "white exclamation mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "grey_exclamation"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "❗"
+  , "description": "exclamation mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "exclamation"
+    , "heavy_exclamation_mark"
+    ]
+  , "tags": [
+      "bang"
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "〰️"
+  , "description": "wavy dash"
+  , "category": "Symbols"
+  , "aliases": [
+      "wavy_dash"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "©️"
+  , "description": "copyright"
+  , "category": "Symbols"
+  , "aliases": [
+      "copyright"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "®️"
+  , "description": "registered"
+  , "category": "Symbols"
+  , "aliases": [
+      "registered"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "™️"
+  , "description": "trade mark"
+  , "category": "Symbols"
+  , "aliases": [
+      "tm"
+    ]
+  , "tags": [
+      "trademark"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "#️⃣"
+  , "description": "keycap: #"
+  , "category": "Symbols"
+  , "aliases": [
+      "hash"
+    ]
+  , "tags": [
+      "number"
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "*️⃣"
+  , "description": "keycap: *"
+  , "category": "Symbols"
+  , "aliases": [
+      "asterisk"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "0️⃣"
+  , "description": "keycap: 0"
+  , "category": "Symbols"
+  , "aliases": [
+      "zero"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "1️⃣"
+  , "description": "keycap: 1"
+  , "category": "Symbols"
+  , "aliases": [
+      "one"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "2️⃣"
+  , "description": "keycap: 2"
+  , "category": "Symbols"
+  , "aliases": [
+      "two"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "3️⃣"
+  , "description": "keycap: 3"
+  , "category": "Symbols"
+  , "aliases": [
+      "three"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "4️⃣"
+  , "description": "keycap: 4"
+  , "category": "Symbols"
+  , "aliases": [
+      "four"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "5️⃣"
+  , "description": "keycap: 5"
+  , "category": "Symbols"
+  , "aliases": [
+      "five"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "6️⃣"
+  , "description": "keycap: 6"
+  , "category": "Symbols"
+  , "aliases": [
+      "six"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "7️⃣"
+  , "description": "keycap: 7"
+  , "category": "Symbols"
+  , "aliases": [
+      "seven"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "8️⃣"
+  , "description": "keycap: 8"
+  , "category": "Symbols"
+  , "aliases": [
+      "eight"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "9️⃣"
+  , "description": "keycap: 9"
+  , "category": "Symbols"
+  , "aliases": [
+      "nine"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔟"
+  , "description": "keycap: 10"
+  , "category": "Symbols"
+  , "aliases": [
+      "keycap_ten"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔠"
+  , "description": "input latin uppercase"
+  , "category": "Symbols"
+  , "aliases": [
+      "capital_abcd"
+    ]
+  , "tags": [
+      "letters"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔡"
+  , "description": "input latin lowercase"
+  , "category": "Symbols"
+  , "aliases": [
+      "abcd"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔢"
+  , "description": "input numbers"
+  , "category": "Symbols"
+  , "aliases": [
+      "1234"
+    ]
+  , "tags": [
+      "numbers"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔣"
+  , "description": "input symbols"
+  , "category": "Symbols"
+  , "aliases": [
+      "symbols"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔤"
+  , "description": "input latin letters"
+  , "category": "Symbols"
+  , "aliases": [
+      "abc"
+    ]
+  , "tags": [
+      "alphabet"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🅰️"
+  , "description": "A button (blood type)"
+  , "category": "Symbols"
+  , "aliases": [
+      "a"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆎"
+  , "description": "AB button (blood type)"
+  , "category": "Symbols"
+  , "aliases": [
+      "ab"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🅱️"
+  , "description": "B button (blood type)"
+  , "category": "Symbols"
+  , "aliases": [
+      "b"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆑"
+  , "description": "CL button"
+  , "category": "Symbols"
+  , "aliases": [
+      "cl"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆒"
+  , "description": "COOL button"
+  , "category": "Symbols"
+  , "aliases": [
+      "cool"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆓"
+  , "description": "FREE button"
+  , "category": "Symbols"
+  , "aliases": [
+      "free"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "ℹ️"
+  , "description": "information"
+  , "category": "Symbols"
+  , "aliases": [
+      "information_source"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆔"
+  , "description": "ID button"
+  , "category": "Symbols"
+  , "aliases": [
+      "id"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "Ⓜ️"
+  , "description": "circled M"
+  , "category": "Symbols"
+  , "aliases": [
+      "m"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆕"
+  , "description": "NEW button"
+  , "category": "Symbols"
+  , "aliases": [
+      "new"
+    ]
+  , "tags": [
+      "fresh"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆖"
+  , "description": "NG button"
+  , "category": "Symbols"
+  , "aliases": [
+      "ng"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🅾️"
+  , "description": "O button (blood type)"
+  , "category": "Symbols"
+  , "aliases": [
+      "o2"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆗"
+  , "description": "OK button"
+  , "category": "Symbols"
+  , "aliases": [
+      "ok"
+    ]
+  , "tags": [
+      "yes"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🅿️"
+  , "description": "P button"
+  , "category": "Symbols"
+  , "aliases": [
+      "parking"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆘"
+  , "description": "SOS button"
+  , "category": "Symbols"
+  , "aliases": [
+      "sos"
+    ]
+  , "tags": [
+      "help"
+    , "emergency"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆙"
+  , "description": "UP! button"
+  , "category": "Symbols"
+  , "aliases": [
+      "up"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🆚"
+  , "description": "VS button"
+  , "category": "Symbols"
+  , "aliases": [
+      "vs"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈁"
+  , "description": "Japanese “here” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "koko"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈂️"
+  , "description": "Japanese “service charge” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "sa"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈷️"
+  , "description": "Japanese “monthly amount” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u6708"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈶"
+  , "description": "Japanese “not free of charge” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u6709"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈯"
+  , "description": "Japanese “reserved” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u6307"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🉐"
+  , "description": "Japanese “bargain” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "ideograph_advantage"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈹"
+  , "description": "Japanese “discount” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u5272"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈚"
+  , "description": "Japanese “free of charge” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u7121"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈲"
+  , "description": "Japanese “prohibited” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u7981"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🉑"
+  , "description": "Japanese “acceptable” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "accept"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈸"
+  , "description": "Japanese “application” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u7533"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈴"
+  , "description": "Japanese “passing grade” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u5408"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈳"
+  , "description": "Japanese “vacancy” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u7a7a"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "㊗️"
+  , "description": "Japanese “congratulations” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "congratulations"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "㊙️"
+  , "description": "Japanese “secret” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "secret"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈺"
+  , "description": "Japanese “open for business” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u55b6"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🈵"
+  , "description": "Japanese “no vacancy” button"
+  , "category": "Symbols"
+  , "aliases": [
+      "u6e80"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔴"
+  , "description": "red circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "red_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🟠"
+  , "description": "orange circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "orange_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟡"
+  , "description": "yellow circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "yellow_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟢"
+  , "description": "green circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "green_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🔵"
+  , "description": "blue circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "large_blue_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🟣"
+  , "description": "purple circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "purple_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟤"
+  , "description": "brown circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "brown_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "⚫"
+  , "description": "black circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "black_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⚪"
+  , "description": "white circle"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_circle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "4.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🟥"
+  , "description": "red square"
+  , "category": "Symbols"
+  , "aliases": [
+      "red_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟧"
+  , "description": "orange square"
+  , "category": "Symbols"
+  , "aliases": [
+      "orange_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟨"
+  , "description": "yellow square"
+  , "category": "Symbols"
+  , "aliases": [
+      "yellow_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟩"
+  , "description": "green square"
+  , "category": "Symbols"
+  , "aliases": [
+      "green_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟦"
+  , "description": "blue square"
+  , "category": "Symbols"
+  , "aliases": [
+      "blue_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟪"
+  , "description": "purple square"
+  , "category": "Symbols"
+  , "aliases": [
+      "purple_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "🟫"
+  , "description": "brown square"
+  , "category": "Symbols"
+  , "aliases": [
+      "brown_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "12.0"
+  , "ios_version": "13.0"
+  }
+, {
+    "emoji": "⬛"
+  , "description": "black large square"
+  , "category": "Symbols"
+  , "aliases": [
+      "black_large_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "⬜"
+  , "description": "white large square"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_large_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "5.1"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "◼️"
+  , "description": "black medium square"
+  , "category": "Symbols"
+  , "aliases": [
+      "black_medium_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "◻️"
+  , "description": "white medium square"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_medium_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "◾"
+  , "description": "black medium-small square"
+  , "category": "Symbols"
+  , "aliases": [
+      "black_medium_small_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "◽"
+  , "description": "white medium-small square"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_medium_small_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "3.2"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "▪️"
+  , "description": "black small square"
+  , "category": "Symbols"
+  , "aliases": [
+      "black_small_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "▫️"
+  , "description": "white small square"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_small_square"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": ""
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔶"
+  , "description": "large orange diamond"
+  , "category": "Symbols"
+  , "aliases": [
+      "large_orange_diamond"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔷"
+  , "description": "large blue diamond"
+  , "category": "Symbols"
+  , "aliases": [
+      "large_blue_diamond"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔸"
+  , "description": "small orange diamond"
+  , "category": "Symbols"
+  , "aliases": [
+      "small_orange_diamond"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔹"
+  , "description": "small blue diamond"
+  , "category": "Symbols"
+  , "aliases": [
+      "small_blue_diamond"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔺"
+  , "description": "red triangle pointed up"
+  , "category": "Symbols"
+  , "aliases": [
+      "small_red_triangle"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔻"
+  , "description": "red triangle pointed down"
+  , "category": "Symbols"
+  , "aliases": [
+      "small_red_triangle_down"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "💠"
+  , "description": "diamond with a dot"
+  , "category": "Symbols"
+  , "aliases": [
+      "diamond_shape_with_a_dot_inside"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔘"
+  , "description": "radio button"
+  , "category": "Symbols"
+  , "aliases": [
+      "radio_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔳"
+  , "description": "white square button"
+  , "category": "Symbols"
+  , "aliases": [
+      "white_square_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🔲"
+  , "description": "black square button"
+  , "category": "Symbols"
+  , "aliases": [
+      "black_square_button"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏁"
+  , "description": "chequered flag"
+  , "category": "Flags"
+  , "aliases": [
+      "checkered_flag"
+    ]
+  , "tags": [
+      "milestone"
+    , "finish"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🚩"
+  , "description": "triangular flag"
+  , "category": "Flags"
+  , "aliases": [
+      "triangular_flag_on_post"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🎌"
+  , "description": "crossed flags"
+  , "category": "Flags"
+  , "aliases": [
+      "crossed_flags"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🏴"
+  , "description": "black flag"
+  , "category": "Flags"
+  , "aliases": [
+      "black_flag"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏳"
+  , "description": "white flag"
+  , "category": "Flags"
+  , "aliases": [
+      "white_flag"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "7.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🏳️‍🌈"
+  , "description": "rainbow flag"
+  , "category": "Flags"
+  , "aliases": [
+      "rainbow_flag"
+    ]
+  , "tags": [
+      "pride"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "10.0"
+  }
+, {
+    "emoji": "🏴‍☠"
+  , "description": "pirate flag"
+  , "category": "Flags"
+  , "aliases": [
+      "pirate_flag"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇦🇨"
+  , "description": "flag: Ascension Island"
+  , "category": "Flags"
+  , "aliases": [
+      "ascension_island"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇦🇩"
+  , "description": "flag: Andorra"
+  , "category": "Flags"
+  , "aliases": [
+      "andorra"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇪"
+  , "description": "flag: United Arab Emirates"
+  , "category": "Flags"
+  , "aliases": [
+      "united_arab_emirates"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇫"
+  , "description": "flag: Afghanistan"
+  , "category": "Flags"
+  , "aliases": [
+      "afghanistan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇬"
+  , "description": "flag: Antigua & Barbuda"
+  , "category": "Flags"
+  , "aliases": [
+      "antigua_barbuda"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇮"
+  , "description": "flag: Anguilla"
+  , "category": "Flags"
+  , "aliases": [
+      "anguilla"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇱"
+  , "description": "flag: Albania"
+  , "category": "Flags"
+  , "aliases": [
+      "albania"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇲"
+  , "description": "flag: Armenia"
+  , "category": "Flags"
+  , "aliases": [
+      "armenia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇴"
+  , "description": "flag: Angola"
+  , "category": "Flags"
+  , "aliases": [
+      "angola"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇶"
+  , "description": "flag: Antarctica"
+  , "category": "Flags"
+  , "aliases": [
+      "antarctica"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇦🇷"
+  , "description": "flag: Argentina"
+  , "category": "Flags"
+  , "aliases": [
+      "argentina"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇸"
+  , "description": "flag: American Samoa"
+  , "category": "Flags"
+  , "aliases": [
+      "american_samoa"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇹"
+  , "description": "flag: Austria"
+  , "category": "Flags"
+  , "aliases": [
+      "austria"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇺"
+  , "description": "flag: Australia"
+  , "category": "Flags"
+  , "aliases": [
+      "australia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇼"
+  , "description": "flag: Aruba"
+  , "category": "Flags"
+  , "aliases": [
+      "aruba"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇦🇽"
+  , "description": "flag: Åland Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "aland_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇦🇿"
+  , "description": "flag: Azerbaijan"
+  , "category": "Flags"
+  , "aliases": [
+      "azerbaijan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇦"
+  , "description": "flag: Bosnia & Herzegovina"
+  , "category": "Flags"
+  , "aliases": [
+      "bosnia_herzegovina"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇧"
+  , "description": "flag: Barbados"
+  , "category": "Flags"
+  , "aliases": [
+      "barbados"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇩"
+  , "description": "flag: Bangladesh"
+  , "category": "Flags"
+  , "aliases": [
+      "bangladesh"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇪"
+  , "description": "flag: Belgium"
+  , "category": "Flags"
+  , "aliases": [
+      "belgium"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇫"
+  , "description": "flag: Burkina Faso"
+  , "category": "Flags"
+  , "aliases": [
+      "burkina_faso"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇬"
+  , "description": "flag: Bulgaria"
+  , "category": "Flags"
+  , "aliases": [
+      "bulgaria"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇭"
+  , "description": "flag: Bahrain"
+  , "category": "Flags"
+  , "aliases": [
+      "bahrain"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇮"
+  , "description": "flag: Burundi"
+  , "category": "Flags"
+  , "aliases": [
+      "burundi"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇯"
+  , "description": "flag: Benin"
+  , "category": "Flags"
+  , "aliases": [
+      "benin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇱"
+  , "description": "flag: St. Barthélemy"
+  , "category": "Flags"
+  , "aliases": [
+      "st_barthelemy"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇧🇲"
+  , "description": "flag: Bermuda"
+  , "category": "Flags"
+  , "aliases": [
+      "bermuda"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇳"
+  , "description": "flag: Brunei"
+  , "category": "Flags"
+  , "aliases": [
+      "brunei"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇴"
+  , "description": "flag: Bolivia"
+  , "category": "Flags"
+  , "aliases": [
+      "bolivia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇶"
+  , "description": "flag: Caribbean Netherlands"
+  , "category": "Flags"
+  , "aliases": [
+      "caribbean_netherlands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇧🇷"
+  , "description": "flag: Brazil"
+  , "category": "Flags"
+  , "aliases": [
+      "brazil"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇸"
+  , "description": "flag: Bahamas"
+  , "category": "Flags"
+  , "aliases": [
+      "bahamas"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇹"
+  , "description": "flag: Bhutan"
+  , "category": "Flags"
+  , "aliases": [
+      "bhutan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇻"
+  , "description": "flag: Bouvet Island"
+  , "category": "Flags"
+  , "aliases": [
+      "bouvet_island"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇧🇼"
+  , "description": "flag: Botswana"
+  , "category": "Flags"
+  , "aliases": [
+      "botswana"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇾"
+  , "description": "flag: Belarus"
+  , "category": "Flags"
+  , "aliases": [
+      "belarus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇧🇿"
+  , "description": "flag: Belize"
+  , "category": "Flags"
+  , "aliases": [
+      "belize"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇦"
+  , "description": "flag: Canada"
+  , "category": "Flags"
+  , "aliases": [
+      "canada"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇨"
+  , "description": "flag: Cocos (Keeling) Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "cocos_islands"
+    ]
+  , "tags": [
+      "keeling"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇨🇩"
+  , "description": "flag: Congo - Kinshasa"
+  , "category": "Flags"
+  , "aliases": [
+      "congo_kinshasa"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇫"
+  , "description": "flag: Central African Republic"
+  , "category": "Flags"
+  , "aliases": [
+      "central_african_republic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇬"
+  , "description": "flag: Congo - Brazzaville"
+  , "category": "Flags"
+  , "aliases": [
+      "congo_brazzaville"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇭"
+  , "description": "flag: Switzerland"
+  , "category": "Flags"
+  , "aliases": [
+      "switzerland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇮"
+  , "description": "flag: Côte d’Ivoire"
+  , "category": "Flags"
+  , "aliases": [
+      "cote_divoire"
+    ]
+  , "tags": [
+      "ivory"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇰"
+  , "description": "flag: Cook Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "cook_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇱"
+  , "description": "flag: Chile"
+  , "category": "Flags"
+  , "aliases": [
+      "chile"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇲"
+  , "description": "flag: Cameroon"
+  , "category": "Flags"
+  , "aliases": [
+      "cameroon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇳"
+  , "description": "flag: China"
+  , "category": "Flags"
+  , "aliases": [
+      "cn"
+    ]
+  , "tags": [
+      "china"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇨🇴"
+  , "description": "flag: Colombia"
+  , "category": "Flags"
+  , "aliases": [
+      "colombia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇵"
+  , "description": "flag: Clipperton Island"
+  , "category": "Flags"
+  , "aliases": [
+      "clipperton_island"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇨🇷"
+  , "description": "flag: Costa Rica"
+  , "category": "Flags"
+  , "aliases": [
+      "costa_rica"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇺"
+  , "description": "flag: Cuba"
+  , "category": "Flags"
+  , "aliases": [
+      "cuba"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇻"
+  , "description": "flag: Cape Verde"
+  , "category": "Flags"
+  , "aliases": [
+      "cape_verde"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇼"
+  , "description": "flag: Curaçao"
+  , "category": "Flags"
+  , "aliases": [
+      "curacao"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇽"
+  , "description": "flag: Christmas Island"
+  , "category": "Flags"
+  , "aliases": [
+      "christmas_island"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇨🇾"
+  , "description": "flag: Cyprus"
+  , "category": "Flags"
+  , "aliases": [
+      "cyprus"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇨🇿"
+  , "description": "flag: Czechia"
+  , "category": "Flags"
+  , "aliases": [
+      "czech_republic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇩🇪"
+  , "description": "flag: Germany"
+  , "category": "Flags"
+  , "aliases": [
+      "de"
+    ]
+  , "tags": [
+      "flag"
+    , "germany"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇩🇬"
+  , "description": "flag: Diego Garcia"
+  , "category": "Flags"
+  , "aliases": [
+      "diego_garcia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇩🇯"
+  , "description": "flag: Djibouti"
+  , "category": "Flags"
+  , "aliases": [
+      "djibouti"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇩🇰"
+  , "description": "flag: Denmark"
+  , "category": "Flags"
+  , "aliases": [
+      "denmark"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇩🇲"
+  , "description": "flag: Dominica"
+  , "category": "Flags"
+  , "aliases": [
+      "dominica"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇩🇴"
+  , "description": "flag: Dominican Republic"
+  , "category": "Flags"
+  , "aliases": [
+      "dominican_republic"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇩🇿"
+  , "description": "flag: Algeria"
+  , "category": "Flags"
+  , "aliases": [
+      "algeria"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇪🇦"
+  , "description": "flag: Ceuta & Melilla"
+  , "category": "Flags"
+  , "aliases": [
+      "ceuta_melilla"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇪🇨"
+  , "description": "flag: Ecuador"
+  , "category": "Flags"
+  , "aliases": [
+      "ecuador"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇪🇪"
+  , "description": "flag: Estonia"
+  , "category": "Flags"
+  , "aliases": [
+      "estonia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇪🇬"
+  , "description": "flag: Egypt"
+  , "category": "Flags"
+  , "aliases": [
+      "egypt"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇪🇭"
+  , "description": "flag: Western Sahara"
+  , "category": "Flags"
+  , "aliases": [
+      "western_sahara"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇪🇷"
+  , "description": "flag: Eritrea"
+  , "category": "Flags"
+  , "aliases": [
+      "eritrea"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇪🇸"
+  , "description": "flag: Spain"
+  , "category": "Flags"
+  , "aliases": [
+      "es"
+    ]
+  , "tags": [
+      "spain"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇪🇹"
+  , "description": "flag: Ethiopia"
+  , "category": "Flags"
+  , "aliases": [
+      "ethiopia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇪🇺"
+  , "description": "flag: European Union"
+  , "category": "Flags"
+  , "aliases": [
+      "eu"
+    , "european_union"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇫🇮"
+  , "description": "flag: Finland"
+  , "category": "Flags"
+  , "aliases": [
+      "finland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇫🇯"
+  , "description": "flag: Fiji"
+  , "category": "Flags"
+  , "aliases": [
+      "fiji"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇫🇰"
+  , "description": "flag: Falkland Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "falkland_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇫🇲"
+  , "description": "flag: Micronesia"
+  , "category": "Flags"
+  , "aliases": [
+      "micronesia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇫🇴"
+  , "description": "flag: Faroe Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "faroe_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇫🇷"
+  , "description": "flag: France"
+  , "category": "Flags"
+  , "aliases": [
+      "fr"
+    ]
+  , "tags": [
+      "france"
+    , "french"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇬🇦"
+  , "description": "flag: Gabon"
+  , "category": "Flags"
+  , "aliases": [
+      "gabon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇧"
+  , "description": "flag: United Kingdom"
+  , "category": "Flags"
+  , "aliases": [
+      "gb"
+    , "uk"
+    ]
+  , "tags": [
+      "flag"
+    , "british"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇬🇩"
+  , "description": "flag: Grenada"
+  , "category": "Flags"
+  , "aliases": [
+      "grenada"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇪"
+  , "description": "flag: Georgia"
+  , "category": "Flags"
+  , "aliases": [
+      "georgia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇫"
+  , "description": "flag: French Guiana"
+  , "category": "Flags"
+  , "aliases": [
+      "french_guiana"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇬"
+  , "description": "flag: Guernsey"
+  , "category": "Flags"
+  , "aliases": [
+      "guernsey"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇬🇭"
+  , "description": "flag: Ghana"
+  , "category": "Flags"
+  , "aliases": [
+      "ghana"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇮"
+  , "description": "flag: Gibraltar"
+  , "category": "Flags"
+  , "aliases": [
+      "gibraltar"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇱"
+  , "description": "flag: Greenland"
+  , "category": "Flags"
+  , "aliases": [
+      "greenland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇬🇲"
+  , "description": "flag: Gambia"
+  , "category": "Flags"
+  , "aliases": [
+      "gambia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇳"
+  , "description": "flag: Guinea"
+  , "category": "Flags"
+  , "aliases": [
+      "guinea"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇵"
+  , "description": "flag: Guadeloupe"
+  , "category": "Flags"
+  , "aliases": [
+      "guadeloupe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇬🇶"
+  , "description": "flag: Equatorial Guinea"
+  , "category": "Flags"
+  , "aliases": [
+      "equatorial_guinea"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇷"
+  , "description": "flag: Greece"
+  , "category": "Flags"
+  , "aliases": [
+      "greece"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇸"
+  , "description": "flag: South Georgia & South Sandwich Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "south_georgia_south_sandwich_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇬🇹"
+  , "description": "flag: Guatemala"
+  , "category": "Flags"
+  , "aliases": [
+      "guatemala"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇺"
+  , "description": "flag: Guam"
+  , "category": "Flags"
+  , "aliases": [
+      "guam"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇼"
+  , "description": "flag: Guinea-Bissau"
+  , "category": "Flags"
+  , "aliases": [
+      "guinea_bissau"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇬🇾"
+  , "description": "flag: Guyana"
+  , "category": "Flags"
+  , "aliases": [
+      "guyana"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇭🇰"
+  , "description": "flag: Hong Kong SAR China"
+  , "category": "Flags"
+  , "aliases": [
+      "hong_kong"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇭🇲"
+  , "description": "flag: Heard & McDonald Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "heard_mcdonald_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇭🇳"
+  , "description": "flag: Honduras"
+  , "category": "Flags"
+  , "aliases": [
+      "honduras"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇭🇷"
+  , "description": "flag: Croatia"
+  , "category": "Flags"
+  , "aliases": [
+      "croatia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇭🇹"
+  , "description": "flag: Haiti"
+  , "category": "Flags"
+  , "aliases": [
+      "haiti"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇭🇺"
+  , "description": "flag: Hungary"
+  , "category": "Flags"
+  , "aliases": [
+      "hungary"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇨"
+  , "description": "flag: Canary Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "canary_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇮🇩"
+  , "description": "flag: Indonesia"
+  , "category": "Flags"
+  , "aliases": [
+      "indonesia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇪"
+  , "description": "flag: Ireland"
+  , "category": "Flags"
+  , "aliases": [
+      "ireland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇱"
+  , "description": "flag: Israel"
+  , "category": "Flags"
+  , "aliases": [
+      "israel"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇲"
+  , "description": "flag: Isle of Man"
+  , "category": "Flags"
+  , "aliases": [
+      "isle_of_man"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇮🇳"
+  , "description": "flag: India"
+  , "category": "Flags"
+  , "aliases": [
+      "india"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇴"
+  , "description": "flag: British Indian Ocean Territory"
+  , "category": "Flags"
+  , "aliases": [
+      "british_indian_ocean_territory"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇮🇶"
+  , "description": "flag: Iraq"
+  , "category": "Flags"
+  , "aliases": [
+      "iraq"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇷"
+  , "description": "flag: Iran"
+  , "category": "Flags"
+  , "aliases": [
+      "iran"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇸"
+  , "description": "flag: Iceland"
+  , "category": "Flags"
+  , "aliases": [
+      "iceland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇮🇹"
+  , "description": "flag: Italy"
+  , "category": "Flags"
+  , "aliases": [
+      "it"
+    ]
+  , "tags": [
+      "italy"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇯🇪"
+  , "description": "flag: Jersey"
+  , "category": "Flags"
+  , "aliases": [
+      "jersey"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇯🇲"
+  , "description": "flag: Jamaica"
+  , "category": "Flags"
+  , "aliases": [
+      "jamaica"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇯🇴"
+  , "description": "flag: Jordan"
+  , "category": "Flags"
+  , "aliases": [
+      "jordan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇯🇵"
+  , "description": "flag: Japan"
+  , "category": "Flags"
+  , "aliases": [
+      "jp"
+    ]
+  , "tags": [
+      "japan"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇰🇪"
+  , "description": "flag: Kenya"
+  , "category": "Flags"
+  , "aliases": [
+      "kenya"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇬"
+  , "description": "flag: Kyrgyzstan"
+  , "category": "Flags"
+  , "aliases": [
+      "kyrgyzstan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇭"
+  , "description": "flag: Cambodia"
+  , "category": "Flags"
+  , "aliases": [
+      "cambodia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇮"
+  , "description": "flag: Kiribati"
+  , "category": "Flags"
+  , "aliases": [
+      "kiribati"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇲"
+  , "description": "flag: Comoros"
+  , "category": "Flags"
+  , "aliases": [
+      "comoros"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇳"
+  , "description": "flag: St. Kitts & Nevis"
+  , "category": "Flags"
+  , "aliases": [
+      "st_kitts_nevis"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇵"
+  , "description": "flag: North Korea"
+  , "category": "Flags"
+  , "aliases": [
+      "north_korea"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇷"
+  , "description": "flag: South Korea"
+  , "category": "Flags"
+  , "aliases": [
+      "kr"
+    ]
+  , "tags": [
+      "korea"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇰🇼"
+  , "description": "flag: Kuwait"
+  , "category": "Flags"
+  , "aliases": [
+      "kuwait"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇾"
+  , "description": "flag: Cayman Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "cayman_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇰🇿"
+  , "description": "flag: Kazakhstan"
+  , "category": "Flags"
+  , "aliases": [
+      "kazakhstan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇦"
+  , "description": "flag: Laos"
+  , "category": "Flags"
+  , "aliases": [
+      "laos"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇧"
+  , "description": "flag: Lebanon"
+  , "category": "Flags"
+  , "aliases": [
+      "lebanon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇨"
+  , "description": "flag: St. Lucia"
+  , "category": "Flags"
+  , "aliases": [
+      "st_lucia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇮"
+  , "description": "flag: Liechtenstein"
+  , "category": "Flags"
+  , "aliases": [
+      "liechtenstein"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇰"
+  , "description": "flag: Sri Lanka"
+  , "category": "Flags"
+  , "aliases": [
+      "sri_lanka"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇷"
+  , "description": "flag: Liberia"
+  , "category": "Flags"
+  , "aliases": [
+      "liberia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇸"
+  , "description": "flag: Lesotho"
+  , "category": "Flags"
+  , "aliases": [
+      "lesotho"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇹"
+  , "description": "flag: Lithuania"
+  , "category": "Flags"
+  , "aliases": [
+      "lithuania"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇺"
+  , "description": "flag: Luxembourg"
+  , "category": "Flags"
+  , "aliases": [
+      "luxembourg"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇻"
+  , "description": "flag: Latvia"
+  , "category": "Flags"
+  , "aliases": [
+      "latvia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇱🇾"
+  , "description": "flag: Libya"
+  , "category": "Flags"
+  , "aliases": [
+      "libya"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇦"
+  , "description": "flag: Morocco"
+  , "category": "Flags"
+  , "aliases": [
+      "morocco"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇨"
+  , "description": "flag: Monaco"
+  , "category": "Flags"
+  , "aliases": [
+      "monaco"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇲🇩"
+  , "description": "flag: Moldova"
+  , "category": "Flags"
+  , "aliases": [
+      "moldova"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇪"
+  , "description": "flag: Montenegro"
+  , "category": "Flags"
+  , "aliases": [
+      "montenegro"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇫"
+  , "description": "flag: St. Martin"
+  , "category": "Flags"
+  , "aliases": [
+      "st_martin"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇲🇬"
+  , "description": "flag: Madagascar"
+  , "category": "Flags"
+  , "aliases": [
+      "madagascar"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇭"
+  , "description": "flag: Marshall Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "marshall_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇲🇰"
+  , "description": "flag: Macedonia"
+  , "category": "Flags"
+  , "aliases": [
+      "macedonia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇱"
+  , "description": "flag: Mali"
+  , "category": "Flags"
+  , "aliases": [
+      "mali"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇲"
+  , "description": "flag: Myanmar (Burma)"
+  , "category": "Flags"
+  , "aliases": [
+      "myanmar"
+    ]
+  , "tags": [
+      "burma"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇳"
+  , "description": "flag: Mongolia"
+  , "category": "Flags"
+  , "aliases": [
+      "mongolia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇴"
+  , "description": "flag: Macao SAR China"
+  , "category": "Flags"
+  , "aliases": [
+      "macau"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇵"
+  , "description": "flag: Northern Mariana Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "northern_mariana_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇶"
+  , "description": "flag: Martinique"
+  , "category": "Flags"
+  , "aliases": [
+      "martinique"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇲🇷"
+  , "description": "flag: Mauritania"
+  , "category": "Flags"
+  , "aliases": [
+      "mauritania"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇸"
+  , "description": "flag: Montserrat"
+  , "category": "Flags"
+  , "aliases": [
+      "montserrat"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇹"
+  , "description": "flag: Malta"
+  , "category": "Flags"
+  , "aliases": [
+      "malta"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇺"
+  , "description": "flag: Mauritius"
+  , "category": "Flags"
+  , "aliases": [
+      "mauritius"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇲🇻"
+  , "description": "flag: Maldives"
+  , "category": "Flags"
+  , "aliases": [
+      "maldives"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇼"
+  , "description": "flag: Malawi"
+  , "category": "Flags"
+  , "aliases": [
+      "malawi"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇽"
+  , "description": "flag: Mexico"
+  , "category": "Flags"
+  , "aliases": [
+      "mexico"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇾"
+  , "description": "flag: Malaysia"
+  , "category": "Flags"
+  , "aliases": [
+      "malaysia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇲🇿"
+  , "description": "flag: Mozambique"
+  , "category": "Flags"
+  , "aliases": [
+      "mozambique"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇦"
+  , "description": "flag: Namibia"
+  , "category": "Flags"
+  , "aliases": [
+      "namibia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇨"
+  , "description": "flag: New Caledonia"
+  , "category": "Flags"
+  , "aliases": [
+      "new_caledonia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇪"
+  , "description": "flag: Niger"
+  , "category": "Flags"
+  , "aliases": [
+      "niger"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇫"
+  , "description": "flag: Norfolk Island"
+  , "category": "Flags"
+  , "aliases": [
+      "norfolk_island"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇳🇬"
+  , "description": "flag: Nigeria"
+  , "category": "Flags"
+  , "aliases": [
+      "nigeria"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇮"
+  , "description": "flag: Nicaragua"
+  , "category": "Flags"
+  , "aliases": [
+      "nicaragua"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇱"
+  , "description": "flag: Netherlands"
+  , "category": "Flags"
+  , "aliases": [
+      "netherlands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇴"
+  , "description": "flag: Norway"
+  , "category": "Flags"
+  , "aliases": [
+      "norway"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇵"
+  , "description": "flag: Nepal"
+  , "category": "Flags"
+  , "aliases": [
+      "nepal"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇷"
+  , "description": "flag: Nauru"
+  , "category": "Flags"
+  , "aliases": [
+      "nauru"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇳🇺"
+  , "description": "flag: Niue"
+  , "category": "Flags"
+  , "aliases": [
+      "niue"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇳🇿"
+  , "description": "flag: New Zealand"
+  , "category": "Flags"
+  , "aliases": [
+      "new_zealand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇴🇲"
+  , "description": "flag: Oman"
+  , "category": "Flags"
+  , "aliases": [
+      "oman"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇦"
+  , "description": "flag: Panama"
+  , "category": "Flags"
+  , "aliases": [
+      "panama"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇪"
+  , "description": "flag: Peru"
+  , "category": "Flags"
+  , "aliases": [
+      "peru"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇫"
+  , "description": "flag: French Polynesia"
+  , "category": "Flags"
+  , "aliases": [
+      "french_polynesia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇵🇬"
+  , "description": "flag: Papua New Guinea"
+  , "category": "Flags"
+  , "aliases": [
+      "papua_new_guinea"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇭"
+  , "description": "flag: Philippines"
+  , "category": "Flags"
+  , "aliases": [
+      "philippines"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇰"
+  , "description": "flag: Pakistan"
+  , "category": "Flags"
+  , "aliases": [
+      "pakistan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇱"
+  , "description": "flag: Poland"
+  , "category": "Flags"
+  , "aliases": [
+      "poland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇲"
+  , "description": "flag: St. Pierre & Miquelon"
+  , "category": "Flags"
+  , "aliases": [
+      "st_pierre_miquelon"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇵🇳"
+  , "description": "flag: Pitcairn Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "pitcairn_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇵🇷"
+  , "description": "flag: Puerto Rico"
+  , "category": "Flags"
+  , "aliases": [
+      "puerto_rico"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇸"
+  , "description": "flag: Palestinian Territories"
+  , "category": "Flags"
+  , "aliases": [
+      "palestinian_territories"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇹"
+  , "description": "flag: Portugal"
+  , "category": "Flags"
+  , "aliases": [
+      "portugal"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇼"
+  , "description": "flag: Palau"
+  , "category": "Flags"
+  , "aliases": [
+      "palau"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇵🇾"
+  , "description": "flag: Paraguay"
+  , "category": "Flags"
+  , "aliases": [
+      "paraguay"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇶🇦"
+  , "description": "flag: Qatar"
+  , "category": "Flags"
+  , "aliases": [
+      "qatar"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇷🇪"
+  , "description": "flag: Réunion"
+  , "category": "Flags"
+  , "aliases": [
+      "reunion"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇷🇴"
+  , "description": "flag: Romania"
+  , "category": "Flags"
+  , "aliases": [
+      "romania"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇷🇸"
+  , "description": "flag: Serbia"
+  , "category": "Flags"
+  , "aliases": [
+      "serbia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇷🇺"
+  , "description": "flag: Russia"
+  , "category": "Flags"
+  , "aliases": [
+      "ru"
+    ]
+  , "tags": [
+      "russia"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇷🇼"
+  , "description": "flag: Rwanda"
+  , "category": "Flags"
+  , "aliases": [
+      "rwanda"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇦"
+  , "description": "flag: Saudi Arabia"
+  , "category": "Flags"
+  , "aliases": [
+      "saudi_arabia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇧"
+  , "description": "flag: Solomon Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "solomon_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇨"
+  , "description": "flag: Seychelles"
+  , "category": "Flags"
+  , "aliases": [
+      "seychelles"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇩"
+  , "description": "flag: Sudan"
+  , "category": "Flags"
+  , "aliases": [
+      "sudan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇪"
+  , "description": "flag: Sweden"
+  , "category": "Flags"
+  , "aliases": [
+      "sweden"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇬"
+  , "description": "flag: Singapore"
+  , "category": "Flags"
+  , "aliases": [
+      "singapore"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇭"
+  , "description": "flag: St. Helena"
+  , "category": "Flags"
+  , "aliases": [
+      "st_helena"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇸🇮"
+  , "description": "flag: Slovenia"
+  , "category": "Flags"
+  , "aliases": [
+      "slovenia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇯"
+  , "description": "flag: Svalbard & Jan Mayen"
+  , "category": "Flags"
+  , "aliases": [
+      "svalbard_jan_mayen"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇸🇰"
+  , "description": "flag: Slovakia"
+  , "category": "Flags"
+  , "aliases": [
+      "slovakia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇱"
+  , "description": "flag: Sierra Leone"
+  , "category": "Flags"
+  , "aliases": [
+      "sierra_leone"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇲"
+  , "description": "flag: San Marino"
+  , "category": "Flags"
+  , "aliases": [
+      "san_marino"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇳"
+  , "description": "flag: Senegal"
+  , "category": "Flags"
+  , "aliases": [
+      "senegal"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇴"
+  , "description": "flag: Somalia"
+  , "category": "Flags"
+  , "aliases": [
+      "somalia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇷"
+  , "description": "flag: Suriname"
+  , "category": "Flags"
+  , "aliases": [
+      "suriname"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇸"
+  , "description": "flag: South Sudan"
+  , "category": "Flags"
+  , "aliases": [
+      "south_sudan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇹"
+  , "description": "flag: São Tomé & Príncipe"
+  , "category": "Flags"
+  , "aliases": [
+      "sao_tome_principe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇻"
+  , "description": "flag: El Salvador"
+  , "category": "Flags"
+  , "aliases": [
+      "el_salvador"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇽"
+  , "description": "flag: Sint Maarten"
+  , "category": "Flags"
+  , "aliases": [
+      "sint_maarten"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇾"
+  , "description": "flag: Syria"
+  , "category": "Flags"
+  , "aliases": [
+      "syria"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇸🇿"
+  , "description": "flag: Eswatini"
+  , "category": "Flags"
+  , "aliases": [
+      "swaziland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇦"
+  , "description": "flag: Tristan da Cunha"
+  , "category": "Flags"
+  , "aliases": [
+      "tristan_da_cunha"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇹🇨"
+  , "description": "flag: Turks & Caicos Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "turks_caicos_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇩"
+  , "description": "flag: Chad"
+  , "category": "Flags"
+  , "aliases": [
+      "chad"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇹🇫"
+  , "description": "flag: French Southern Territories"
+  , "category": "Flags"
+  , "aliases": [
+      "french_southern_territories"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇬"
+  , "description": "flag: Togo"
+  , "category": "Flags"
+  , "aliases": [
+      "togo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇭"
+  , "description": "flag: Thailand"
+  , "category": "Flags"
+  , "aliases": [
+      "thailand"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇯"
+  , "description": "flag: Tajikistan"
+  , "category": "Flags"
+  , "aliases": [
+      "tajikistan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇰"
+  , "description": "flag: Tokelau"
+  , "category": "Flags"
+  , "aliases": [
+      "tokelau"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇹🇱"
+  , "description": "flag: Timor-Leste"
+  , "category": "Flags"
+  , "aliases": [
+      "timor_leste"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇲"
+  , "description": "flag: Turkmenistan"
+  , "category": "Flags"
+  , "aliases": [
+      "turkmenistan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇳"
+  , "description": "flag: Tunisia"
+  , "category": "Flags"
+  , "aliases": [
+      "tunisia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇴"
+  , "description": "flag: Tonga"
+  , "category": "Flags"
+  , "aliases": [
+      "tonga"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇷"
+  , "description": "flag: Turkey"
+  , "category": "Flags"
+  , "aliases": [
+      "tr"
+    ]
+  , "tags": [
+      "turkey"
+    ]
+  , "unicode_version": "8.0"
+  , "ios_version": "9.1"
+  }
+, {
+    "emoji": "🇹🇹"
+  , "description": "flag: Trinidad & Tobago"
+  , "category": "Flags"
+  , "aliases": [
+      "trinidad_tobago"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇻"
+  , "description": "flag: Tuvalu"
+  , "category": "Flags"
+  , "aliases": [
+      "tuvalu"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇹🇼"
+  , "description": "flag: Taiwan"
+  , "category": "Flags"
+  , "aliases": [
+      "taiwan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇹🇿"
+  , "description": "flag: Tanzania"
+  , "category": "Flags"
+  , "aliases": [
+      "tanzania"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇺🇦"
+  , "description": "flag: Ukraine"
+  , "category": "Flags"
+  , "aliases": [
+      "ukraine"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇺🇬"
+  , "description": "flag: Uganda"
+  , "category": "Flags"
+  , "aliases": [
+      "uganda"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇺🇲"
+  , "description": "flag: U.S. Outlying Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "us_outlying_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇺🇳"
+  , "description": "flag: United Nations"
+  , "category": "Flags"
+  , "aliases": [
+      "united_nations"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🇺🇸"
+  , "description": "flag: United States"
+  , "category": "Flags"
+  , "aliases": [
+      "us"
+    ]
+  , "tags": [
+      "flag"
+    , "united"
+    , "america"
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "6.0"
+  }
+, {
+    "emoji": "🇺🇾"
+  , "description": "flag: Uruguay"
+  , "category": "Flags"
+  , "aliases": [
+      "uruguay"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇺🇿"
+  , "description": "flag: Uzbekistan"
+  , "category": "Flags"
+  , "aliases": [
+      "uzbekistan"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇻🇦"
+  , "description": "flag: Vatican City"
+  , "category": "Flags"
+  , "aliases": [
+      "vatican_city"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇻🇨"
+  , "description": "flag: St. Vincent & Grenadines"
+  , "category": "Flags"
+  , "aliases": [
+      "st_vincent_grenadines"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇻🇪"
+  , "description": "flag: Venezuela"
+  , "category": "Flags"
+  , "aliases": [
+      "venezuela"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇻🇬"
+  , "description": "flag: British Virgin Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "british_virgin_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇻🇮"
+  , "description": "flag: U.S. Virgin Islands"
+  , "category": "Flags"
+  , "aliases": [
+      "us_virgin_islands"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇻🇳"
+  , "description": "flag: Vietnam"
+  , "category": "Flags"
+  , "aliases": [
+      "vietnam"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇻🇺"
+  , "description": "flag: Vanuatu"
+  , "category": "Flags"
+  , "aliases": [
+      "vanuatu"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇼🇫"
+  , "description": "flag: Wallis & Futuna"
+  , "category": "Flags"
+  , "aliases": [
+      "wallis_futuna"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇼🇸"
+  , "description": "flag: Samoa"
+  , "category": "Flags"
+  , "aliases": [
+      "samoa"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇽🇰"
+  , "description": "flag: Kosovo"
+  , "category": "Flags"
+  , "aliases": [
+      "kosovo"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇾🇪"
+  , "description": "flag: Yemen"
+  , "category": "Flags"
+  , "aliases": [
+      "yemen"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇾🇹"
+  , "description": "flag: Mayotte"
+  , "category": "Flags"
+  , "aliases": [
+      "mayotte"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "9.0"
+  }
+, {
+    "emoji": "🇿🇦"
+  , "description": "flag: South Africa"
+  , "category": "Flags"
+  , "aliases": [
+      "south_africa"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇿🇲"
+  , "description": "flag: Zambia"
+  , "category": "Flags"
+  , "aliases": [
+      "zambia"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🇿🇼"
+  , "description": "flag: Zimbabwe"
+  , "category": "Flags"
+  , "aliases": [
+      "zimbabwe"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "6.0"
+  , "ios_version": "8.3"
+  }
+, {
+    "emoji": "🏴󠁧󠁢󠁥󠁮󠁧󠁿"
+  , "description": "flag: England"
+  , "category": "Flags"
+  , "aliases": [
+      "england"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🏴󠁧󠁢󠁳󠁣󠁴󠁿"
+  , "description": "flag: Scotland"
+  , "category": "Flags"
+  , "aliases": [
+      "scotland"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+, {
+    "emoji": "🏴󠁧󠁢󠁷󠁬󠁳󠁿"
+  , "description": "flag: Wales"
+  , "category": "Flags"
+  , "aliases": [
+      "wales"
+    ]
+  , "tags": [
+    ]
+  , "unicode_version": "11.0"
+  , "ios_version": "12.1"
+  }
+]
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/update_emoji.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/emoji/update_emoji.py
new file mode 100644 (file)
index 0000000..18b3c06
--- /dev/null
@@ -0,0 +1,213 @@
+"""
+Update Emoji.py
+Refeshes OMZ emoji database based on the latest Unicode spec
+"""
+import re
+import json
+
+spec = open("emoji-data.txt", "r")
+
+# Regexes
+# regex_emoji will return, respectively:
+# the code points, its type (status), the actual emoji, and its official name
+regex_emoji = r"^([\w ].*?\S)\s*;\s*([\w-]+)\s*#\s*(.*?)\s(\S.*).*$"
+# regex_group returns the group of subgroup that a line opens
+regex_group = r"^#\s*(group|subgroup):\s*(.*)$"
+
+headers = """
+# emoji-char-definitions.zsh - Emoji definitions for oh-my-zsh emoji plugin
+#
+# This file is auto-generated by update_emoji.py. Do not edit it manually.
+#
+# This contains the definition for:
+#   $emoji         - which maps character names to Unicode characters
+#   $emoji_flags   - maps country names to Unicode flag characters using region
+#                    indicators
+#   $emoji_mod     - maps modifier components to Unicode characters
+#   $emoji_groups  - a single associative array to avoid cluttering up the
+#                    global namespace, and to allow adding additional group
+#                    definitions at run time. The keys are the group names, and
+#                    the values are whitespace-separated lists of emoji
+#                    character names.
+
+# Main emoji
+typeset -gAH emoji
+# National flags
+typeset -gAH emoji_flags
+# Combining modifiers
+typeset -gAH emoji_mod
+# Emoji groups
+typeset -gAH emoji_groups
+"""
+
+#######
+# Adding country codes
+#######
+# This is the only part of this script that relies on an external library
+# (country_converter), and is hence commented out by default.
+# You can uncomment it to have country codes added as aliases for flag
+# emojis. (By default, when you install this extension, country codes are
+# included as aliases, but not if you re-run this script without uncommenting.)
+# Warning: country_converter is very verbose, and will print warnings all over
+# your terminal.
+
+# import country_converter as coco # pylint: disable=wrong-import-position
+# cc = coco.CountryConverter()
+
+# def country_iso(_all_names, _omz_name):
+#     """ Using the external library country_converter,
+#         this function can detect the ISO2 and ISO3 codes
+#         of the country. It takes as argument the array
+#         with all the names of the emoji, and returns that array."""
+#     omz_no_underscore = re.sub(r'_', r' ', _omz_name)
+#     iso2 = cc.convert(names=[omz_no_underscore], to='ISO2')
+#     if iso2 != 'not found':
+#         _all_names.append(iso2)
+#         iso3 = cc.convert(names=[omz_no_underscore], to='ISO3')
+#         _all_names.append(iso3)
+#     return _all_names
+
+
+#######
+# Helper functions
+#######
+
+def code_to_omz(_code_points):
+    """ Returns a ZSH-compatible Unicode string from the code point(s) """
+    return r'\U' + r'\U'.join(_code_points.split(' '))
+
+def name_to_omz(_name, _group, _subgroup, _status):
+    """ Returns a reasonable snake_case name for the emoji. """
+    def snake_case(_string):
+        """ Does the regex work of snake_case """
+        remove_dots = re.sub(r'\.\(\)', r'', _string)
+        replace_ands = re.sub(r'\&', r'and', remove_dots)
+        remove_whitespace = re.sub(r'[^\#\*\w]', r'_', replace_ands)
+        return re.sub(r'__', r'_', remove_whitespace)
+
+    shortname = ""
+    split_at_colon = lambda s: s.split(": ")
+    # Special treatment by group and subgroup
+    # If the emoji is a flag, we strip "flag" from its name
+    if _group == "Flags" and len(split_at_colon(_name)) > 1:
+        shortname = snake_case(split_at_colon(_name)[1])
+    else:
+        shortname = snake_case(_name)
+    # Special treatment by status
+    # Enables us to have every emoji combination,
+    # even the one that are not officially sanctionned
+    # and are implemented by, say, only one vendor
+    if _status == "unqualified":
+        shortname += "_unqualified"
+    elif _status == "minimally-qualified":
+        shortname += "_minimally"
+    return shortname
+
+def increment_name(_shortname):
+    """ Increment the short name by 1. If you get, say,
+    'woman_detective_unqualified', it returns
+    'woman_detective_unqualified_1', and then
+    'woman_detective_unqualified_2', etc. """
+    last_char = _shortname[-1]
+    if last_char.isdigit():
+        num = int(last_char)
+        return _shortname[:-1] + str(num + 1)
+    return _shortname + "_1"
+
+########
+# Going through every line
+########
+
+group, subgroup, short_name_buffer = "", "", ""
+emoji_database = []
+for line in spec:
+    # First, test if this line opens a group or subgroup
+    group_match = re.findall(regex_group, line)
+    if group_match != []:
+        gr_or_sub, name = group_match[0]
+        if gr_or_sub == "group":
+            group = name
+        elif gr_or_sub == "subgroup":
+            subgroup = name
+        continue # Moving on...
+    # Second, test if this line references one emoji
+    emoji_match = re.findall(regex_emoji, line)
+    if emoji_match != []:
+        code_points, status, emoji, name = emoji_match[0]
+        omz_codes = code_to_omz(code_points)
+        omz_name = name_to_omz(name, group, subgroup, status)
+        # If this emoji has the same shortname as the preceding one
+        if omz_name in short_name_buffer:
+            omz_name = increment_name(short_name_buffer)
+        short_name_buffer = omz_name
+        emoji_database.append(
+            [omz_codes, status, emoji, omz_name, group, subgroup])
+spec.close()
+
+########
+# Write to emoji-char-definitions.zsh
+########
+
+# Aliases for emojis are retrieved through the DB of Gemoji
+# Retrieved on Aug 9 2019 from the following URL:
+# https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json
+
+gemoji_db = open("gemoji_db.json")
+j = json.load(gemoji_db)
+aliases_map = {entry['emoji']: entry['aliases'] for entry in j}
+all_omz_names = [emoji_data[3] for emoji_data in emoji_database]
+
+# Let's begin writing to this file
+output = open("emoji-char-definitions.zsh", "w")
+output.write(headers)
+
+emoji_groups = {"fruits": "\n", "vehicles": "\n", "hands": "\n",
+                "people": "\n", "animals": "\n", "faces": "\n",
+                "flags": "\n"}
+
+# First, write every emoji down
+for _omz_codes, _status, _emoji, _omz_name, _group, _subgroup in emoji_database:
+
+    # One emoji can be mapped to multiple names (aliases or country codes)
+    names_for_this_emoji = [_omz_name]
+
+    # Variable that indicates in which map the emoji will be located
+    emoji_map = "emoji"
+    if _status == "component":
+        emoji_map = "emoji_mod"
+    if _group == "Flags":
+        emoji_map = "emoji_flags"
+        # Adding country codes (Optional, see above)
+        # names_for_this_emoji = country_iso(names_for_this_emoji, _omz_name)
+
+    # Check if there is an alias available in the Gemoji DB
+    if _emoji in aliases_map.keys():
+        for alias in aliases_map[_emoji]:
+            if alias not in all_omz_names:
+                names_for_this_emoji.append(alias)
+
+    # And now we write to the definitions file
+    for one_name in names_for_this_emoji:
+        output.write(f"{emoji_map}[{one_name}]=$'{_omz_codes}'\n")
+
+    # Storing the emoji in defined subgroups for the next step
+    if _status == "fully-qualified":
+        if _subgroup == "food-fruit":
+            emoji_groups["fruits"] += f"  {_omz_name}\n"
+        elif "transport-" in _subgroup:
+            emoji_groups["vehicles"] += f"  {_omz_name}\n"
+        elif "hand-" in _subgroup:
+            emoji_groups["hands"] += f"  {_omz_name}\n"
+        elif "person-" in _subgroup or _subgroup == "family":
+            emoji_groups["people"] += f"  {_omz_name}\n"
+        elif "animal-" in _subgroup:
+            emoji_groups["animals"] += f"  {_omz_name}\n"
+        elif "face-" in _subgroup:
+            emoji_groups["faces"] += f"  {_omz_name}\n"
+        elif _group == "Flags":
+            emoji_groups["flags"] += f"  {_omz_name}\n"
+
+# Second, write the subgroups to the end of the file
+for name, string in emoji_groups.items():
+    output.write(f'\nemoji_groups[{name}]="{string}"\n')
+output.close()
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/README.md
new file mode 100644 (file)
index 0000000..ee57170
--- /dev/null
@@ -0,0 +1,39 @@
+# emotty plugin
+
+This plugin returns an emoji for the current $TTY number so it can be used
+in a prompt.
+
+To use it, add emotty to the plugins array in your zshrc file:
+```
+plugins=(... emotty)
+```
+
+**NOTE:** it requires the [emoji plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/emoji).
+
+## Usage
+
+The function `emotty` displays an emoji from the current character set (default: `emoji`), based
+on the number associated to the `$TTY`.
+
+There are different sets of emoji characters available, to choose a different
+set, set `$emotty_set` to the name of the set you would like to use, e.g.:
+```
+emotty_set=nature
+```
+
+### Character Sets
+
+- emoji
+- loral
+- love
+- nature
+- stellar
+- zodiac
+
+Use the `display_emotty` function to list the emojis in the current character set, or
+the character set passed as the first argument. For example:
+
+```
+$ display_emotty zodiac
+<list of all the emojis in the zodiac character set>
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty.plugin.zsh
new file mode 100644 (file)
index 0000000..661169a
--- /dev/null
@@ -0,0 +1,55 @@
+# ------------------------------------------------------------------------------
+#          FILE: emotty.plugin.zsh
+#   DESCRIPTION: Return an emoji for the current $TTY number.
+#        AUTHOR: Alexis Hildebrandt (afh[at]surryhill.net)
+#       VERSION: 1.0.0
+#       DEPENDS: emoji plugin
+#       
+# There are different sets of emoji characters available, to choose a different
+# set export emotty_set to the name of the set you would like to use, e.g.:
+# % export emotty_set=nature
+# ------------------------------------------------------------------------------
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+typeset -gAH _emotty_sets
+local _emotty_plugin_dir="${0:h}"
+source "$_emotty_plugin_dir/emotty_stellar_set.zsh"
+source "$_emotty_plugin_dir/emotty_floral_set.zsh"
+source "$_emotty_plugin_dir/emotty_zodiac_set.zsh"
+source "$_emotty_plugin_dir/emotty_nature_set.zsh"
+source "$_emotty_plugin_dir/emotty_emoji_set.zsh"
+source "$_emotty_plugin_dir/emotty_love_set.zsh"
+unset _emotty_plugin_dir
+
+emotty_default_set=emoji
+
+function emotty() {
+  # Use emotty set defined by user, fallback to default
+  local emotty=${_emotty_sets[${emotty_set:-$emotty_default_set}]}
+
+  # Parse tty number via prompt expansion. %l equals:
+  # - N      if tty = /dev/ttyN
+  # - pts/N  if tty = /dev/pts/N
+  local tty=${${(%):-%l}##pts/}
+  # Normalize it to an emotty set index
+  (( tty = (tty % ${#${=emotty}}) + 1 ))
+
+  local character_name=${${=emotty}[tty]}
+  echo "${emoji[${character_name}]}${emoji2[emoji_style]}"
+}
+
+function display_emotty() {
+  local name=${1:-$emotty_set}
+  echo $name
+  for i in ${=_emotty_sets[$name]}; do
+    printf "${emoji[$i]}${emoji2[emoji_style]}  "
+  done
+  print
+  for i in ${=_emotty_sets[$name]}; do
+    print "${emoji[$i]}${emoji2[emoji_style]}  = $i"
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_emoji_set.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_emoji_set.zsh
new file mode 100644 (file)
index 0000000..00e3171
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env zsh
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+_emotty_sets[emoji]="
+  crystal_ball
+  ghost
+  jack_o_lantern
+  see_no_evil_monkey
+  hear_no_evil_monkey
+  speak_no_evil_monkey
+  smiling_cat_face_with_open_mouth
+  extraterrestrial_alien
+  rocket
+  billiards
+  bomb
+  pill
+  japanese_symbol_for_beginner
+  direct_hit
+  cyclone
+  diamond_shape_with_a_dot_inside
+  sparkle
+  eight_spoked_asterisk
+  eight_pointed_black_star
+  "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_floral_set.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_floral_set.zsh
new file mode 100644 (file)
index 0000000..f761fea
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/env zsh
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+_emotty_sets[floral]="
+  hibiscus
+  cherry_blossom
+  blossom
+  sunflower
+  bouquet
+  tulip
+  rose
+  four_leaf_clover
+  seedling
+  herb
+  palm_tree
+  evergreen_tree
+  deciduous_tree
+  "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_love_set.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_love_set.zsh
new file mode 100644 (file)
index 0000000..8f19e69
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env zsh
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+# Note: The heavy_black_heart emoji requires $emoji2[emoji_style]
+# to be rendered as the emoji red heart.
+_emotty_sets[love]="
+  green_heart
+  blue_heart
+  purple_heart
+  yellow_heart
+  heavy_black_heart
+  broken_heart
+  heart_with_arrow
+  heart_with_ribbon
+  sparkling_heart
+  two_hearts
+  revolving_hearts
+  growing_heart
+  beating_heart
+  heart_decoration
+  couple_with_heart
+  kiss
+  man_and_woman_holding_hands
+  two_women_holding_hands
+  two_men_holding_hands
+  kiss_mark
+  smiling_face_with_heart_shaped_eyes
+  kissing_face
+  face_throwing_a_kiss
+  kissing_face_with_smiling_eyes
+  kissing_face_with_closed_eyes
+  smiling_cat_face_with_heart_shaped_eyes
+  kissing_cat_face_with_closed_eyes
+  "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_nature_set.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_nature_set.zsh
new file mode 100644 (file)
index 0000000..8dab4c1
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/env zsh
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+_emotty_sets[nature]="
+  mouse_face
+  hamster_face
+  rabbit_face
+  dog_face
+  cat_face
+  tiger_face
+  bear_face
+  monkey_face
+  koala
+  panda_face
+  chicken
+  baby_chick
+  bird
+  penguin
+  cow_face
+  pig_face
+  frog_face
+  boar
+  wolf_face
+  horse_face
+  snail
+  bug
+  ant
+  honeybee
+  lady_beetle
+  spouting_whale
+  dolphin
+  octopus
+  fish
+  tropical_fish
+  snake
+  turtle
+  lemon
+  tangerine
+  peach
+  mushroom
+  tomato
+  strawberry
+  red_apple
+  cherries
+  grapes
+  aubergine
+  watermelon
+  banana
+  pineapple
+  melon
+  pear
+  green_apple
+  ear_of_maize
+  sunflower
+  seedling
+  herb
+  four_leaf_clover
+  "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_stellar_set.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_stellar_set.zsh
new file mode 100644 (file)
index 0000000..8e7e610
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env zsh
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+# NOTE: The following emoji show as $'character' in the title
+#  white_medium_star
+#  sparkles
+#  dizzy_symbol
+
+_emotty_sets[stellar]="
+  full_moon_symbol
+  waning_gibbous_moon_symbol
+  waning_crescent_moon_symbol
+  last_quarter_moon_symbol
+  new_moon_symbol
+  new_moon_with_face
+  waxing_crescent_moon_symbol
+  first_quarter_moon_symbol
+  waxing_gibbous_moon_symbol
+  full_moon_with_face
+  sun_with_face
+  glowing_star
+  crescent_moon
+  first_quarter_moon_with_face
+  last_quarter_moon_with_face
+  "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_zodiac_set.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/emotty/emotty_zodiac_set.zsh
new file mode 100644 (file)
index 0000000..bde6e3d
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/env zsh
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+_emotty_sets[zodiac]="
+  aries
+  taurus
+  gemini
+  cancer
+  leo
+  virgo
+  libra
+  scorpius
+  sagittarius
+  capricorn
+  aquarius
+  pisces
+  rat
+  ox
+  tiger
+  rabbit
+  dragon
+  snake
+  horse
+  goat
+  monkey
+  rooster
+  dog
+  pig
+  "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/encode64/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/encode64/README.md
new file mode 100644 (file)
index 0000000..86320cf
--- /dev/null
@@ -0,0 +1,58 @@
+# encode64
+
+Alias plugin for encoding or decoding using `base64` command.
+
+To use it, add `encode64` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... encode64)
+```
+
+## Functions and Aliases
+
+| Function   | Alias | Description                    |
+| ---------- | ----- | ------------------------------ |
+| `encode64` | `e64` | Encodes given data to base64   |
+| `decode64` | `d64` | Decodes given data from base64 |
+
+## Usage and examples
+
+### Encoding
+
+- From parameter
+
+  ```console
+  $ encode64 "oh-my-zsh"
+  b2gtbXktenNo
+  $ e64 "oh-my-zsh"
+  b2gtbXktenNo
+  ```
+
+- From piping
+
+  ```console
+  $ echo "oh-my-zsh" | encode64
+  b2gtbXktenNo==
+  $ echo "oh-my-zsh" | e64
+  b2gtbXktenNo==
+  ```
+
+### Decoding
+
+- From parameter
+
+  ```console
+  $ decode64 b2gtbXktenNo
+  oh-my-zsh%
+  $ d64 b2gtbXktenNo
+  oh-my-zsh%
+  ```
+
+- From piping
+
+  ```console
+  $ echo "b2gtbXktenNoCg==" | decode64
+  oh-my-zsh
+  $ echo "b2gtbXktenNoCg==" | d64
+  oh-my-zsh
+  ```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/encode64/encode64.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/encode64/encode64.plugin.zsh
new file mode 100644 (file)
index 0000000..979e067
--- /dev/null
@@ -0,0 +1,17 @@
+encode64() {
+    if [[ $# -eq 0 ]]; then
+        cat | base64
+    else
+        printf '%s' $1 | base64
+    fi
+}
+
+decode64() {
+    if [[ $# -eq 0 ]]; then
+        cat | base64 --decode
+    else
+        printf '%s' $1 | base64 --decode
+    fi
+}
+alias e64=encode64
+alias d64=decode64
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/extract/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/extract/README.md
new file mode 100644 (file)
index 0000000..44f0b05
--- /dev/null
@@ -0,0 +1,60 @@
+# extract plugin
+
+This plugin defines a function called `extract` that extracts the archive file
+you pass it, and it supports a wide variety of archive filetypes.
+
+This way you don't have to know what specific command extracts a file, you just
+do `extract <filename>` and the function takes care of the rest.
+
+To use it, add `extract` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... extract)
+```
+
+## Supported file extensions
+
+| Extension         | Description                          |
+|:------------------|:-------------------------------------|
+| `7z`              | 7zip file                            |
+| `Z`               | Z archive (LZW)                      |
+| `apk`             | Android app file                     |
+| `aar`             | Android library file                 |
+| `bz2`             | Bzip2 file                           |
+| `cab`             | Microsoft cabinet archive            |
+| `cpio`            | Cpio archive                         |
+| `deb`             | Debian package                       |
+| `ear`             | Enterprise Application aRchive       |
+| `gz`              | Gzip file                            |
+| `ipa`             | iOS app package                      |
+| `ipsw`            | iOS firmware file                    |
+| `jar`             | Java Archive                         |
+| `lrz`             | LRZ archive                          |
+| `lz4`             | LZ4 archive                          |
+| `lzma`            | LZMA archive                         |
+| `rar`             | WinRAR archive                       |
+| `rpm`             | RPM package                          |
+| `sublime-package` | Sublime Text package                 |
+| `tar`             | Tarball                              |
+| `tar.bz2`         | Tarball with bzip2 compression       |
+| `tar.gz`          | Tarball with gzip compression        |
+| `tar.lrz`         | Tarball with lrzip compression       |
+| `tar.lz`          | Tarball with lzip compression        |
+| `tar.lz4`         | Tarball with lz4 compression         |
+| `tar.xz`          | Tarball with lzma2 compression       |
+| `tar.zma`         | Tarball with lzma compression        |
+| `tar.zst`         | Tarball with zstd compression        |
+| `tbz`             | Tarball with bzip compression        |
+| `tbz2`            | Tarball with bzip2 compression       |
+| `tgz`             | Tarball with gzip compression        |
+| `tlz`             | Tarball with lzma compression        |
+| `txz`             | Tarball with lzma2 compression       |
+| `tzst`            | Tarball with zstd compression        |
+| `war`             | Web Application archive (Java-based) |
+| `xpi`             | Mozilla XPI module file              |
+| `xz`              | LZMA2 archive                        |
+| `zip`             | Zip archive                          |
+| `zst`             | Zstandard file (zstd)                |
+
+See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for
+more information regarding archive formats.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/extract/_extract b/stow/oh-my-zsh/.oh-my-zsh/plugins/extract/_extract
new file mode 100644 (file)
index 0000000..27b099c
--- /dev/null
@@ -0,0 +1,7 @@
+#compdef extract
+#autoload
+
+_arguments \
+  '(-r --remove)'{-r,--remove}'[Remove archive.]' \
+  "*::archive file:_files -g '(#i)*.(7z|Z|apk|aar|bz2|cab|cpio|deb|ear|gz|ipa|ipsw|jar|lrz|lz4|lzma|rar|rpm|sublime-package|tar|tar.bz2|tar.gz|tar.lrz|tar.lz|tar.lz4|tar.xz|tar.zma|tar.zst|tbz|tbz2|tgz|tlz|txz|tzst|war|whl|xpi|xz|zip|zst)(-.)'" \
+    && return 0
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/extract/extract.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/extract/extract.plugin.zsh
new file mode 100644 (file)
index 0000000..1112dd5
--- /dev/null
@@ -0,0 +1,85 @@
+alias x=extract
+
+extract() {
+  setopt localoptions noautopushd
+
+  if (( $# == 0 )); then
+    cat >&2 <<'EOF'
+Usage: extract [-option] [file ...]
+
+Options:
+    -r, --remove    Remove archive after unpacking.
+EOF
+  fi
+
+  local remove_archive=1
+  if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then
+    remove_archive=0
+    shift
+  fi
+
+  local pwd="$PWD"
+  while (( $# > 0 )); do
+    if [[ ! -f "$1" ]]; then
+      echo "extract: '$1' is not a valid file" >&2
+      shift
+      continue
+    fi
+
+    local success=0
+    local extract_dir="${1:t:r}"
+    local file="$1" full_path="${1:A}"
+    case "${file:l}" in
+      (*.tar.gz|*.tgz) (( $+commands[pigz] )) && { pigz -dc "$file" | tar xv } || tar zxvf "$file" ;;
+      (*.tar.bz2|*.tbz|*.tbz2) tar xvjf "$file" ;;
+      (*.tar.xz|*.txz)
+        tar --xz --help &> /dev/null \
+        && tar --xz -xvf "$file" \
+        || xzcat "$file" | tar xvf - ;;
+      (*.tar.zma|*.tlz)
+        tar --lzma --help &> /dev/null \
+        && tar --lzma -xvf "$file" \
+        || lzcat "$file" | tar xvf - ;;
+      (*.tar.zst|*.tzst)
+        tar --zstd --help &> /dev/null \
+        && tar --zstd -xvf "$file" \
+        || zstdcat "$file" | tar xvf - ;;
+      (*.tar) tar xvf "$file" ;;
+      (*.tar.lz) (( $+commands[lzip] )) && tar xvf "$file" ;;
+      (*.tar.lz4) lz4 -c -d "$file" | tar xvf - ;;
+      (*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$file" ;;
+      (*.gz) (( $+commands[pigz] )) && pigz -dk "$file" || gunzip -k "$file" ;;
+      (*.bz2) bunzip2 "$file" ;;
+      (*.xz) unxz "$file" ;;
+      (*.lrz) (( $+commands[lrunzip] )) && lrunzip "$file" ;;
+      (*.lz4) lz4 -d "$file" ;;
+      (*.lzma) unlzma "$file" ;;
+      (*.z) uncompress "$file" ;;
+      (*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl) unzip "$file" -d "$extract_dir" ;;
+      (*.rar) unrar x -ad "$file" ;;
+      (*.rpm)
+        command mkdir -p "$extract_dir" && builtin cd -q "$extract_dir" \
+        && rpm2cpio "$full_path" | cpio --quiet -id ;;
+      (*.7z) 7za x "$file" ;;
+      (*.deb)
+        command mkdir -p "$extract_dir/control" "$extract_dir/data"
+        builtin cd -q "$extract_dir"; ar vx "$full_path" > /dev/null
+        builtin cd -q control; extract ../control.tar.*
+        builtin cd -q ../data; extract ../data.tar.*
+        builtin cd -q ..; command rm *.tar.* debian-binary ;;
+      (*.zst) unzstd "$file" ;;
+      (*.cab) cabextract -d "$extract_dir" "$file" ;;
+      (*.cpio) cpio -idmvF "$file" ;;
+      (*)
+        echo "extract: '$file' cannot be extracted" >&2
+        success=1 ;;
+    esac
+
+    (( success = success > 0 ? success : $? ))
+    (( success == 0 && remove_archive == 0 )) && rm "$full_path"
+    shift
+
+    # Go back to original working directory in case we ran cd previously
+    builtin cd -q "$pwd"
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/README.md
new file mode 100644 (file)
index 0000000..f121d2e
--- /dev/null
@@ -0,0 +1,9 @@
+# Fabric
+
+This plugin provides completion for [Fabric](https://www.fabfile.org/).
+
+To use it add fabric to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... fabric)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/_fab b/stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/_fab
new file mode 100644 (file)
index 0000000..9102dad
--- /dev/null
@@ -0,0 +1,69 @@
+#compdef fab
+#autoload
+
+local curcontext=$curcontext state line
+declare -A opt_args
+
+declare -a target_list
+target_list=("${(@f)$(fab -l 2>/dev/null | awk '{
+    if (NF == 0 || NR == 1) next
+    if (NF < 2) print $1
+    else {
+        docstring=substr($0, index($0,$2))
+        gsub(":", "\\:", docstring)
+        print $1":"docstring
+    }
+}')}")
+
+_fab_targets() {
+    [[ -n "$target_list" ]] || return
+    _describe -t commands "fabric targets" target_list
+}
+
+output_levels=(
+    'status: Status messages, i.e. noting when Fabric is done running, if the user used a keyboard interrupt, or when servers are disconnected from. These messages are almost always relevant and rarely verbose.'
+    'aborts: Abort messages. Like status messages, these should really only be turned off when using Fabric as a library, and possibly not even then. Note that even if this output group is turned off, aborts will still occur – there just won’t be any output about why Fabric aborted!'
+    'warnings: Warning messages. These are often turned off when one expects a given operation to fail, such as when using grep to test existence of text in a file. If paired with setting env.warn_only to True, this can result in fully silent warnings when remote programs fail. As with aborts, this setting does not control actual warning behavior, only whether warning messages are printed or hidden.'
+    'running: Printouts of commands being executed or files transferred, e.g. [myserver] run: ls /var/www. Also controls printing of tasks being run, e.g. [myserver] Executing task ''foo''.'
+    'stdout: Local, or remote, stdout, i.e. non-error output from commands.'
+    'stderr: Local, or remote, stderr, i.e. error-related output from commands.'
+    'user: User-generated output, i.e. local output printed by fabfile code via use of the fastprint or puts functions.'
+)
+
+_arguments -w -S -C \
+  '(-)'{-h,--help}'[show this help message and exit]: :->noargs' \
+  '(-)'{-V,--version}'[show program''s version number and exit]: :->noargs' \
+  '(-)--list[print list of possible commands and exit]: :->noargs' \
+  '(-)--shortlist[print non-verbose list of possible commands and exit]: :->noargs' \
+  '(--reject-unknown-hosts)--reject-unknown-hosts[reject unknown hosts]' \
+  '(--no-pty)--no-pty[do not use pseudo-terminal in run/sudo]' \
+  "(-d+ --display=-)"{-d+,--display=-}"[print detailed info about a given command]: :_fab_targets" \
+  '(-D --disable-known-hosts)'{-D,--disable-known-hosts}'[do not load user known_hosts file]' \
+  '(-r --reject-unknown-hosts)'{-r,--reject-unknown-hosts}'[reject unknown hosts]' \
+  '(-u+ --user=-)'{-u+,--user=-}'[username to use when connecting to remote hosts]: :' \
+  '(-p+ --password=-)'{-p+,--password=-}'[password for use with authentication and/or sudo]: :' \
+  '(-H+ --hosts=-)'{-H+,--hosts=-}'[comma separated list of hosts to operate on]: :' \
+  '(-R+ --roles=-)'{-R+,--roles=-}'[comma separated list of roles to operate on]: :' \
+  '(-a --no-agent)'{-a,--no-agent}'[don''t use the running SSH agent]' \
+  '(-k --no-keys)'{-k,--no-keys}'[don''t load private key files from ~/.ssh/]' \
+  '(-w --warn-only)'{-w,--warn-only}'[warn instead of abort, when commands fail]' \
+  '-i+[path to SSH private key file. May be repeated]: :_files' \
+  "(-f+ --fabfile=)"{-f+,--fabfile=}"[Python module file to import]: :_files -g *.py" \
+  '(-c+ --config=-)'{-c+,--config=-}'[specify location of config file to use]: :_files' \
+  '(-s+ --shell=-)'{-s+,--shell=-}'[specify a new shell, defaults to ''/bin/bash -l -c'']: :' \
+  '(--hide=-)--hide=-[comma-separated list of output levels to hide]: :->levels' \
+  '(--show=-)--show=-[comma-separated list of output levels to show]: :->levels' \
+  '*::: :->subcmds' && return 0
+
+if [[ CURRENT -ge 1 ]]; then
+    case $state in
+        noargs)
+             _message "nothing to complete";;
+        levels)
+            _describe -t commands "output levels" output_levels;;
+        *)
+            _fab_targets;;
+    esac
+
+    return
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/fabric.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fabric/fabric.plugin.zsh
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fancy-ctrl-z/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fancy-ctrl-z/README.md
new file mode 100644 (file)
index 0000000..f1b1dfa
--- /dev/null
@@ -0,0 +1,14 @@
+# Use Ctrl-Z to switch back to Vim
+
+I frequently need to execute random commands in my shell. To achieve it I pause 
+Vim by pressing Ctrl-z, type command and press fg<Enter> to switch back to Vim.
+The fg part really hurts me. I just wanted to hit Ctrl-z once again to get back 
+to Vim. I could not find a solution, so I developed one on my own that 
+works wonderfully with ZSH.
+
+Source: http://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/
+
+Credits: 
+- original idea by @sheerun
+- added to OMZ by @mbologna
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fancy-ctrl-z/fancy-ctrl-z.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fancy-ctrl-z/fancy-ctrl-z.plugin.zsh
new file mode 100644 (file)
index 0000000..82b9688
--- /dev/null
@@ -0,0 +1,12 @@
+fancy-ctrl-z () {
+  if [[ $#BUFFER -eq 0 ]]; then
+    BUFFER="fg"
+    zle accept-line -w
+  else
+    zle push-input -w
+    zle clear-screen -w
+  fi
+}
+zle -N fancy-ctrl-z
+bindkey '^Z' fancy-ctrl-z
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fasd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fasd/README.md
new file mode 100644 (file)
index 0000000..a5c74e5
--- /dev/null
@@ -0,0 +1,21 @@
+# fasd
+
+[`Fasd`](https://github.com/clvv/fasd) (pronounced similar to "fast") is a command-line productivity booster. Fasd offers quick access to files and directories for POSIX shells.
+
+To use it, add `fasd` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... fasd)
+```
+
+## Installation
+
+Please find detailed installation guide [`here`](https://github.com/clvv/fasd#install)
+
+## Aliases
+
+| Alias | Command                                   | Description                                                 |
+|-------|-------------------------------------------|-------------------------------------------------------------|
+| v     | `fasd -f -e "$EDITOR"`                    | List frequent/recent files matching the given filename.     |
+| o     | `fasd -a -e xdg-open`                     | List frequent/recent files and directories matching.        |
+| j     | `fasd_cd -d -i`                           | cd with interactive selection                               |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fasd/fasd.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fasd/fasd.plugin.zsh
new file mode 100644 (file)
index 0000000..6538d09
--- /dev/null
@@ -0,0 +1,16 @@
+# check if fasd is installed
+if (( ! ${+commands[fasd]} )); then
+  return
+fi
+
+fasd_cache="${ZSH_CACHE_DIR}/fasd-init-cache"
+if [[ "$commands[fasd]" -nt "$fasd_cache" || ! -s "$fasd_cache" ]]; then
+  fasd --init posix-alias zsh-hook zsh-ccomp zsh-ccomp-install \
+    zsh-wcomp zsh-wcomp-install >| "$fasd_cache"
+fi
+source "$fasd_cache"
+unset fasd_cache
+
+alias v='f -e "$EDITOR"'
+alias o='a -e xdg-open'
+alias j='zz'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fastfile/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fastfile/README.md
new file mode 100644 (file)
index 0000000..32f619f
--- /dev/null
@@ -0,0 +1,85 @@
+# Fastfile plugin
+
+This plugin adds a way to reference certain files or folders used frequently using
+a global alias or shortcut.
+
+To use it, add `fastfile` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... fastfile)
+```
+
+## Usage
+
+Example: you access folder `/code/project/backend/database` very frequently.
+
+First, generate a shortcut with the name `pjdb`:
+
+```zsh
+$ fastfile pjdb /code/project/backend/database
+```
+
+Next time you want to access it, use `§pjdb`. For example:
+
+```zsh
+$ cd §pjdb
+$ subl §pjdb
+```
+
+where § is the fastfile prefix (see [below](#options) for how to change).
+
+**Note:** shortcuts with spaces in the name are assigned a global alias
+where the spaces have been substituted with underscores (`_`). For example:
+a shortcut named `"hello world"` corresponds with `§hello_world`.
+
+## Functions
+
+- `fastfile <shortcut_name> [path/to/file/or/folder]`: generate a shortcut.
+  If the second argument is not provided, the current directory is used.
+
+- `fastfile_print <shortcut_name>`: prints a shortcut, with the format
+  `<prefix><shortcut_name> -> <shortcut_path>`.
+
+- `fastfile_ls`: lists all shortcuts.
+
+- `fastfile_rm <shortcut_name>`: remove a shortcut.
+
+- `fastfile_sync`: generates the global aliases for the shortcuts.
+
+### Internal functions
+
+- `fastfile_resolv <shortcut_name>`: resolves the location of the shortcut
+  file, i.e., the file in the fastfile directory where the shortcut path
+  is stored.
+
+- `fastfile_get <shortcut_name>`: get the real path of the shortcut.
+
+## Aliases
+
+| Alias  | Function         |
+|--------|------------------|
+| ff     | `fastfile`       |
+| ffp    | `fastfile_print` |
+| ffrm   | `fastfile_rm`    |
+| ffls   | `fastfile_ls`    |
+| ffsync | `fastfile_sync`  |
+
+## Options
+
+These are options you can set to change certain parts of the plugin. To change
+them, add `<variable>=<value>` to your zshrc file, before Oh My Zsh is sourced.
+For example: `fastfile_var_prefix='@'`.
+
+- `fastfile_var_prefix`: prefix for the global aliases created. Controls the prefix of the
+  created global aliases.  
+  **Default:** `§` (section sign), easy to type in a german keyboard via the combination
+  [`⇧ Shift`+`3`](https://en.wikipedia.org/wiki/German_keyboard_layout#/media/File:KB_Germany.svg),
+  or using `⌥ Option`+`6` in macOS.
+
+- `fastfile_dir`: directory where the fastfile shortcuts are stored. Needs to end
+  with a trailing slash.  
+  **Default:** `$HOME/.fastfile/`.
+
+## Author
+
+- [Karolin Varner](https://github.com/koraa)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fastfile/fastfile.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fastfile/fastfile.plugin.zsh
new file mode 100644 (file)
index 0000000..896fed5
--- /dev/null
@@ -0,0 +1,128 @@
+###########################
+# Settings
+
+# These can be overwritten any time.
+# If they are not set yet, they will be
+# overwritten with their default values
+
+default fastfile_dir        "${HOME}/.fastfile"
+default fastfile_var_prefix "§"
+
+###########################
+# Impl
+
+#
+# Generate a shortcut
+#
+# Arguments:
+#    1. name - The name of the shortcut (default: name of the file)
+#    2. file - The file or directory to make the shortcut for
+# STDOUT:
+#    => fastfile_print
+#
+function fastfile() {
+    test "$2" || 2="."
+    file=$(readlink -f "$2")
+
+    test "$1" || 1="$(basename "$file")"
+    name=$(echo "$1" | tr " " "_")
+
+
+    mkdir -p "${fastfile_dir}"
+    echo "$file" > "$(fastfile_resolv "$name")"
+
+    fastfile_sync
+    fastfile_print "$name"
+}
+
+#
+# Resolve the location of a shortcut file (the database file, where the value is written!)
+#
+# Arguments:
+#    1. name - The name of the shortcut
+# STDOUT:
+#   The path to the shortcut file
+#
+function fastfile_resolv() {
+    echo "${fastfile_dir}/${1}"
+}
+
+#
+# Get the real path of a shortcut
+#
+# Arguments:
+#    1. name - The name of the shortcut
+# STDOUT:
+#    The path
+#
+function fastfile_get() {
+    cat "$(fastfile_resolv "$1")"
+}
+
+#
+# Print a shortcut
+#
+# Arguments:
+#    1. name - The name of the shortcut
+# STDOUT:
+#    Name and value of the shortcut
+#
+function fastfile_print() {
+    echo "${fastfile_var_prefix}${1} -> $(fastfile_get "$1")"
+}
+
+#
+# List all shortcuts
+#
+# STDOUT:
+#    (=> fastfile_print) for each shortcut
+#
+function fastfile_ls() {
+    for f in "${fastfile_dir}"/*(N); do
+        file=$(basename "$f") # To enable simpler handling of spaces in file names
+        varkey=$(echo "$file" | tr " " "_")
+
+        # Special format for columns
+        echo "${fastfile_var_prefix}${varkey}|->|$(fastfile_get "$file")"
+    done | column -t -s "|"
+}
+
+#
+# Remove a shortcut
+#
+# Arguments:
+#    1. name - The name of the shortcut (default: name of the file)
+# STDOUT:
+#    => fastfile_print
+#
+function fastfile_rm() {
+    fastfile_print "$1"
+    rm "$(fastfile_resolv "$1")"
+    unalias "${fastfile_var_prefix}${1}"
+}
+
+#
+# Generate the aliases for the shortcuts
+#
+function fastfile_sync() {
+    for f in "${fastfile_dir}"/*(N); do
+        file=$(basename "$f") # To enable simpler handling of spaces in file names
+        varkey=$(echo "$file" | tr " " "_")
+
+        alias -g "${fastfile_var_prefix}${varkey}"="'$(fastfile_get "$file")'"
+    done
+}
+
+##################################
+# Shortcuts
+
+alias ff=fastfile
+alias ffp=fastfile_print
+alias ffrm=fastfile_rm
+alias ffls=fastfile_ls
+alias ffsync=fastfile_sync
+
+##################################
+# Init
+
+fastfile_sync
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fbterm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fbterm/README.md
new file mode 100644 (file)
index 0000000..70ce56d
--- /dev/null
@@ -0,0 +1,10 @@
+# fbterm
+
+This plugin automatically starts [fbterm](https://github.com/zhangyuanwei/fbterm)
+if on a real TTY (`/dev/tty*`).
+
+To use it, add `fbterm` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... fbterm)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fbterm/fbterm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fbterm/fbterm.plugin.zsh
new file mode 100644 (file)
index 0000000..bc25320
--- /dev/null
@@ -0,0 +1,7 @@
+# start fbterm automatically in /dev/tty*
+
+if (( ${+commands[fbterm]} )); then
+       if [[ "$TTY" = /dev/tty* ]] ; then
+               fbterm && exit
+       fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fd/README.md
new file mode 100644 (file)
index 0000000..f334161
--- /dev/null
@@ -0,0 +1,9 @@
+# fd
+
+This plugin adds completion for the file search tool [`fd`](https://github.com/sharkdp/fd), also known as `fd-find`.
+
+To use it, add `fd` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... fd)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fd/_fd b/stow/oh-my-zsh/.oh-my-zsh/plugins/fd/_fd
new file mode 100644 (file)
index 0000000..45b8ca4
--- /dev/null
@@ -0,0 +1,273 @@
+#compdef fd
+
+##
+# zsh completion function for fd
+#
+# Based on ripgrep completion function.
+# Originally based on code from the zsh-users project — see copyright notice
+# below.
+
+autoload -U is-at-least
+
+_fd() {
+  local curcontext="$curcontext" no='!' ret=1
+  local -a context line state state_descr _arguments_options fd_types fd_args
+  local -A opt_args
+
+  if is-at-least 5.2; then
+    _arguments_options=( -s -S )
+  else
+    _arguments_options=( -s )
+  fi
+
+  fd_types=(
+    {f,file}'\:"regular files"'
+    {d,directory}'\:"directories"'
+    {l,symlink}'\:"symbolic links"'
+    {e,empty}'\:"empty files or directories"'
+    {x,executable}'\:"executable (files)"'
+    {s,socket}'\:"sockets"'
+    {p,pipe}'\:"named pipes (FIFOs)"'
+  )
+
+  # Do not complete rare options unless either the current prefix
+  # matches one of those options or the user has the `complete-all`
+  # style set. Note that this prefix check has to be updated manually to account
+  # for all of the potential negation options listed below!
+  if
+    # (--[bpsu]* => match all options marked with '$no')
+    [[ $PREFIX$SUFFIX == --[bopsu]* ]] ||
+    zstyle -t ":complete:$curcontext:*" complete-all
+  then
+    no=
+  fi
+
+  # We make heavy use of argument groups here to prevent the option specs from
+  # growing unwieldy. These aren't supported in zsh <5.4, though, so we'll strip
+  # them out below if necessary. This makes the exclusions inaccurate on those
+  # older versions, but oh well — it's not that big a deal
+  fd_args=(
+    + '(hidden)' # hidden files
+    {-H,--hidden}'[search hidden files/directories]'
+
+    + '(no-ignore-full)' # all ignore files
+    '(no-ignore-partial)'{-I,--no-ignore}"[don't respect .(git|fd)ignore and global ignore files]"
+    $no'(no-ignore-partial)*'{-u,--unrestricted}'[alias for --no-ignore, when repeated also alias for --hidden]'
+
+    + no-ignore-partial # some ignore files
+    "(no-ignore-full --no-ignore-vcs)--no-ignore-vcs[don't respect .gitignore files]"
+    "!(no-ignore-full --no-global-ignore-file)--no-global-ignore-file[don't respect the global ignore file]"
+    $no'(no-ignore-full --no-ignore-parent)--no-ignore-parent[]'
+
+    + '(case)' # case-sensitivity
+    {-s,--case-sensitive}'[perform a case-sensitive search]'
+    {-i,--ignore-case}'[perform a case-insensitive search]'
+
+    + '(regex-pattern)' # regex-based search pattern
+    '(no-regex-pattern)--regex[perform a regex-based search (default)]'
+
+    + '(no-regex-pattern)' # non-regex-based search pattern
+    {-g,--glob}'[perform a glob-based search]'
+    {-F,--fixed-strings}'[treat pattern as literal string instead of a regex]'
+
+    + '(match-full)' # match against full path
+    {-p,--full-path}'[match the pattern against the full path instead of the basename]'
+
+    + '(follow)' # follow symlinks
+    {-L,--follow}'[follow symbolic links to directories]'
+
+    + '(abs-path)' # show absolute paths
+    '(long-listing)'{-a,--absolute-path}'[show absolute paths instead of relative paths]'
+
+    + '(null-sep)' # use null separator for output
+    '(long-listing)'{-0,--print0}'[separate search results by the null character]'
+
+    + '(long-listing)' # long-listing output
+    '(abs-path null-sep max-results exec-cmds)'{-l,--list-details}'[use a long listing format with file metadata]'
+
+    + '(max-results)' # max number of results
+    '(long-listing exec-cmds)--max-results=[limit number of search results to given count and quit]:count'
+    '(long-listing exec-cmds)-1[limit to a single search result and quit]'
+
+    + '(fs-errors)' # file-system errors
+    $no'--show-errors[enable the display of filesystem errors]'
+
+    + '(fs-traversal)' # file-system traversal
+    $no"--one-file-system[don't descend into directories on other file systems]"
+    '!--mount'
+    '!--xdev'
+
+    + dir-depth # directory depth
+    '(--exact-depth -d --max-depth)'{-d+,--max-depth=}'[set max directory depth to descend when searching]:depth'
+    '!(--exact-depth -d --max-depth)--maxdepth:depth'
+    '(--exact-depth --min-depth)--min-depth=[set directory depth to descend before start searching]:depth'
+    '(--exact-depth -d --max-depth --maxdepth --min-depth)--exact-depth=[only search at the exact given directory depth]:depth'
+
+    + prune # pruning
+    "--prune[don't traverse into matching directories]"
+
+    + filter-misc # filter search
+    '*'{-t+,--type=}"[filter search by type]:type:(($fd_types))"
+    '*'{-e+,--extension=}'[filter search by file extension]:extension'
+    '*'{-E+,--exclude=}'[exclude files/directories that match the given glob pattern]:glob pattern'
+    '*'{-S+,--size=}'[limit search by file size]:size limit:->size'
+    '(-o --owner)'{-o+,--owner=}'[filter by owning user and/or group]:owner and/or group:->owner'
+
+    + ignore-file # extra ignore files
+    '*--ignore-file=[add a custom, low-precedence ignore-file with .gitignore format]: :_files'
+
+    + '(filter-mtime-newer)' # filter by files modified after than
+    '--changed-within=[limit search to files/directories modified within the given date/duration]:date or duration'
+    '!--change-newer-than=:date/duration'
+    '!--newer=:date/duration'
+
+    + '(filter-mtime-older)' # filter by files modified before than
+    '--changed-before=[limit search to files/directories modified before the given date/duration]:date or duration'
+    '!--change-older-than=:date/duration'
+    '!--older=:date/duration'
+
+    + '(color)' # colorize output
+    {-c+,--color=}'[declare when to colorize search results]:when to colorize:((
+      auto\:"show colors if the output goes to an interactive console (default)"
+      never\:"do not use colorized output"
+      always\:"always use colorized output"
+    ))'
+
+    + '(threads)'
+    {-j+,--threads=}'[set the number of threads for searching and executing]:number of threads'
+
+    + '(exec-cmds)' # execute command
+    '(long-listing max-results)'{-x+,--exec=}'[execute command for each search result]:command: _command_names -e:*\;::program arguments: _normal'
+    '(long-listing max-results)'{-X+,--exec-batch=}'[execute command for all search results at once]:command: _command_names -e:*\;::program arguments: _normal'
+    '(long-listing max-results)--batch-size=[max number of args for each -X call]:size'
+
+    + other
+    '!(--max-buffer-time)--max-buffer-time=[set amount of time to buffer before showing output]:time (ms)'
+
+    + '(about)' # about flags
+    '(: * -)'{-h,--help}'[display help message]'
+    '(: * -)'{-v,--version}'[display version information]'
+
+    + path-sep # set path separator for output
+    $no'(--path-separator)--path-separator=[set the path separator to use when printing file paths]:path separator'
+
+    + search-path
+    $no'(--base-directory)--base-directory=[change the current working directory to the given path]:directory:_files -/'
+    $no'(*)*--search-path=[set search path (instead of positional <path> arguments)]:directory:_files -/'
+
+    + strip-cwd-prefix
+    $no'(strip-cwd-prefix exec-cmds)--strip-cwd-prefix[Strip ./ prefix when output is redirected]'
+
+    + args # positional arguments
+    '1: :_guard "^-*" pattern'
+    '(--search-path)*:directory:_files -/'
+  )
+
+  # Strip out argument groups where unsupported (see above)
+  is-at-least 5.4 ||
+  fd_args=( ${(@)args:#(#i)(+|[a-z0-9][a-z0-9_-]#|\([a-z0-9][a-z0-9_-]#\))} )
+
+  _arguments $_arguments_options : $fd_args && ret=0
+
+  case ${state} in
+    owner)
+      compset -P '(\\|)\!'
+      if compset -P '*:'; then
+        _groups && ret=0
+      else
+        if
+          compset -S ':*' ||
+          # Do not add the colon suffix when completing "!user<TAB>
+          # (with a starting double-quote) otherwise pressing tab again
+          # after the inserted colon "!user:<TAB> will complete history modifiers
+          [[ $IPREFIX == (\\|\!)*  && ($QIPREFIX == \"* && -z $QISUFFIX) ]]
+        then
+          _users && ret=0
+        else
+          local q
+          # Since quotes are needed when using the negation prefix !,
+          # automatically remove the colon suffix also when closing the quote
+          if [[ $QIPREFIX == [\'\"]* ]]; then
+            q=${QIPREFIX:0:1}
+          fi
+          _users -r ": \t\n\-$q" -S : && ret=0
+        fi
+      fi
+      ;;
+
+    size)
+      if compset -P '[-+][0-9]##'; then
+        local -a suff=(
+          'B:bytes'
+          'K:kilobytes  (10^3  = 1000   bytes)'
+          'M:megabytes  (10^6  = 1000^2 bytes)'
+          'G:gigabytes  (10^9  = 1000^3 bytes)'
+          'T:terabytes  (10^12 = 1000^4 bytes)'
+          'Ki:kibibytes  ( 2^10 = 1024   bytes)'
+          'Mi:mebibytes  ( 2^20 = 1024^2 bytes)'
+          'Gi:gigibytes  ( 2^30 = 1024^3 bytes)'
+          'Ti:tebibytes  ( 2^40 = 1024^4 bytes)'
+        )
+        _describe -t units 'size limit units' suff -V 'units'
+      elif compset -P '[-+]'; then
+        _message -e 'size limit number (full format: <+-><number><unit>)'
+      else
+        _values 'size limit prefix (full format: <prefix><number><unit>)' \
+          '\+[file size must be greater or equal to]'\
+          '-[file size must be less than or equal to]' && ret=0
+      fi
+      ;;
+  esac
+
+  return ret
+}
+
+_fd "$@"
+
+# ------------------------------------------------------------------------------
+# Copyright (c) 2011 GitHub zsh-users - http://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for fd
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * smancill (https://github.com/smancill)
+#
+# ------------------------------------------------------------------------------
+
+# Local Variables:
+# mode: shell-script
+# coding: utf-8-unix
+# indent-tabs-mode: nil
+# sh-indentation: 2
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fig/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fig/README.md
new file mode 100644 (file)
index 0000000..3861958
--- /dev/null
@@ -0,0 +1,9 @@
+# Fig plugin
+
+This plugin sets up completion for [Fig](https://fig.io/).
+
+To use it, add `fig` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... fig)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fig/fig.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fig/fig.plugin.zsh
new file mode 100644 (file)
index 0000000..cddb6c7
--- /dev/null
@@ -0,0 +1,13 @@
+if ! (( $+commands[fig] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `fig`. Otherwise, compinit will have already done that
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_fig" ]]; then
+  autoload -Uz _fig
+  typeset -g -A _comps
+  _comps[fig]=_fig
+fi
+
+fig completion zsh >| "$ZSH_CACHE_DIR/completions/_fig" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/firewalld/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/firewalld/README.md
new file mode 100644 (file)
index 0000000..8b5bc74
--- /dev/null
@@ -0,0 +1,22 @@
+# FirewallD Plugin
+
+This plugin adds some aliases and functions for FirewallD using the `firewalld-cmd` command. To use it, add firewalld to your plugins array.
+
+```zsh
+plugins=(... firewalld)
+```
+
+## Aliases
+
+| Alias | Command                                    | Description                  |
+| :---- | :----------------------------------------- | :--------------------------- |
+| fw    | `sudo firewall-cmd`                        | Shorthand                    |
+| fwr   | `sudo firewall-cmd --reload`               | Reload current configuration |
+| fwp   | `sudo firewall-cmd --permanent`            | Create permanent rule        |
+| fwrp  | `sudo firewall-cmd --runtime-to-permanent` | Save current configuration   |
+
+## Functions
+
+| Function | Description                                                |
+| :------- | :--------------------------------------------------------- |
+| fwl      | Lists configuration from all active zones and direct rules |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/firewalld/firewalld.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/firewalld/firewalld.plugin.zsh
new file mode 100644 (file)
index 0000000..5b10906
--- /dev/null
@@ -0,0 +1,17 @@
+alias fw="sudo firewall-cmd"
+alias fwp="sudo firewall-cmd --permanent"
+alias fwr="sudo firewall-cmd --reload"
+alias fwrp="sudo firewall-cmd --runtime-to-permanent"
+
+function fwl () {
+  # converts output to zsh array ()
+  # @f flag split on new line
+  zones=("${(@f)$(sudo firewall-cmd --get-active-zones | grep -v 'interfaces\|sources')}")
+
+  for i in $zones; do
+    sudo firewall-cmd --zone $i --list-all
+  done
+
+  echo 'Direct Rules:'
+  sudo firewall-cmd --direct --get-all-rules
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/flutter/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/flutter/README.md
new file mode 100644 (file)
index 0000000..e5a4fd2
--- /dev/null
@@ -0,0 +1,28 @@
+## Flutter plugin
+
+The Flutter plugin provides completion and useful aliases
+
+To use it, add `flutter` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... flutter)
+```
+
+## Aliases
+
+| Alias      | Command                 | Description                                                                |
+| :--------- | :---------------------- | :------------------------------------------------------------------------- |
+| `fl`       | `flutter`               | Shorthand for flutter command                                              |
+| `flattach` | `flutter attach`        | Attaches flutter to a running flutter application with enabled observatory |
+| `flb`      | `flutter build`         | Build flutter application                                                  |
+| `flchnl`   | `flutter channel`       | Switches flutter channel (requires input of desired channel)               |
+| `flc`      | `flutter clean`         | Cleans flutter project                                                     |
+| `fldvcs`   | `flutter devices`       | List connected devices (if any)                                            |
+| `fldoc`    | `flutter doctor`        | Runs flutter doctor                                                        |
+| `flpub`    | `flutter pub`           | Shorthand for flutter pub command                                          |
+| `flget`    | `flutter pub get`       | Installs dependencies                                                      |
+| `flr`      | `flutter run`           | Runs flutter app                                                           |
+| `flrd`     | `flutter run --debug`   | Runs flutter app in debug mode (default mode)                              |
+| `flrp`     | `flutter run --profile` | Runs flutter app in profile mode                                           |
+| `flrr`     | `flutter run --release` | Runs flutter app in release mode                                           |
+| `flupgrd`  | `flutter upgrade`       | Upgrades flutter version depending on the current channel                  |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/flutter/flutter.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/flutter/flutter.plugin.zsh
new file mode 100644 (file)
index 0000000..44d196c
--- /dev/null
@@ -0,0 +1,29 @@
+alias fl="flutter"
+alias flattach="flutter attach"
+alias flb="flutter build"
+alias flchnl="flutter channel"
+alias flc="flutter clean"
+alias fldvcs="flutter devices"
+alias fldoc="flutter doctor"
+alias flpub="flutter pub"
+alias flget="flutter pub get"
+alias flr="flutter run"
+alias flrd="flutter run --debug"
+alias flrp="flutter run --profile"
+alias flrr="flutter run --release"
+alias flupgrd="flutter upgrade"
+
+# COMPLETION FUNCTION
+if (( ! $+commands[flutter] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `flutter`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_flutter" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _flutter
+  _comps[flutter]=_flutter
+fi
+
+flutter zsh-completion >| "$ZSH_CACHE_DIR/completions/_flutter" &|
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fnm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fnm/README.md
new file mode 100644 (file)
index 0000000..00fab5c
--- /dev/null
@@ -0,0 +1,9 @@
+# fnm plugin
+
+This plugin adds autocompletion for [fnm](https://github.com/Schniz/fnm) - a Node.js version manager.
+
+To use it, add `fnm` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... fnm)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fnm/fnm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fnm/fnm.plugin.zsh
new file mode 100644 (file)
index 0000000..6219025
--- /dev/null
@@ -0,0 +1,13 @@
+if (( ! $+commands[fnm] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `fnm`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_fnm" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _fnm
+  _comps[fnm]=_fnm
+fi
+
+fnm completions --shell=zsh >| "$ZSH_CACHE_DIR/completions/_fnm" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/forklift/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/forklift/README.md
new file mode 100644 (file)
index 0000000..7dfd8bf
--- /dev/null
@@ -0,0 +1,23 @@
+# forklift
+
+Plugin for ForkLift, an FTP application for OS X.
+
+To use it, add `forklift` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... forklift)
+```
+
+## Requirements
+
+* [ForkLift](https://binarynights.com/)
+
+## Usage
+
+`fl [<file_or_folder>]`
+
+* If `fl` is called without arguments then the current folder is opened in ForkLift. This is equivalent to `fl .`.
+
+* If `fl` is called with a directory as the argument, then that directory is opened in ForkLift
+
+* If `fl` is called with a non-directory file as the argument, then the file's parent directory is opened.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/forklift/forklift.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/forklift/forklift.plugin.zsh
new file mode 100644 (file)
index 0000000..8588948
--- /dev/null
@@ -0,0 +1,122 @@
+# Open folder in ForkLift.app or ForkLift2.app from console
+# Author: Adam Strzelecki nanoant.com, modified by Bodo Tasche bitboxer.de
+#         Updated to support ForkLift 2 and ForkLift 3 by Johan Kaving
+#         Updated to support ForkLift from Setapp by Paul Rudkin
+#
+# Usage:
+#   fl [<folder>]
+#
+# Opens specified directory or current working directory in ForkLift.app
+#
+# Notes:
+# It assumes Shift+Cmd+G launches go to folder panel and Cmd+N opens new
+# app window.
+#
+# https://gist.github.com/3313481
+function fl {
+  if [ ! -z "$1" ]; then
+    DIR=$1
+    if [ ! -d "$DIR" ]; then
+      DIR=$(dirname $DIR)
+    fi
+    if [ "$DIR" != "." ]; then
+      PWD=`cd "$DIR";pwd`
+    fi
+  fi
+  osascript 2>&1 1>/dev/null <<END
+
+  try
+    tell application "Finder"
+        set forkLiftSetapp to name of application file id "com.binarynights.forklift-setapp"
+    end tell
+  on error err_msg number err_num
+    set forkLiftSetapp to null
+  end try
+  try
+    tell application "Finder"
+        set forkLift3 to name of application file id "com.binarynights.ForkLift-3"
+    end tell
+  on error err_msg number err_num
+    set forkLift3 to null
+  end try
+  try
+    tell application "Finder"
+        set forkLift2 to name of application file id "com.binarynights.ForkLift2"
+    end tell
+  on error err_msg number err_num
+    set forkLift2 to null
+  end try
+  try
+    tell application "Finder"
+        set forkLift to name of application file id "com.binarynights.ForkLift"
+    end tell
+  on error err_msg number err_num
+    set forkLift to null
+  end try
+
+  if forkLiftSetapp is not null and application forkLiftSetapp is running then
+    tell application forkLiftSetapp
+        activate
+        set forkLiftVersion to version
+    end tell   
+  else if forkLift3 is not null and application forkLift3 is running then
+    tell application forkLift3
+        activate
+        set forkLiftVersion to version
+    end tell
+  else if forkLift2 is not null and application forkLift2 is running then
+    tell application forkLift2
+        activate
+        set forkLiftVersion to version
+    end tell
+  else if forkLift is not null and application forkLift is running then
+    tell application forkLift
+        activate
+        set forkLiftVersion to version
+    end tell
+  else
+    if forkLiftSetapp is not null then
+        set appName to forkLiftSetapp
+    else if forkLift3 is not null then
+        set appName to forkLift3
+    else if forkLift2 is not null then
+        set appName to forkLift2
+    else if forkLift is not null then
+        set appName to forkLift
+    end if
+    
+    tell application appName
+        activate
+        set forkLiftVersion to version
+    end tell
+    repeat until application appName is running
+        delay 1
+    end repeat
+    tell application appName
+        activate
+    end tell
+  end if
+
+  tell application "System Events"
+    tell application process "ForkLift"
+        try
+            set topWindow to window 1
+        on error
+            keystroke "n" using command down
+            set topWindow to window 1
+        end try
+        keystroke "g" using {command down, shift down}
+        if forkLiftVersion starts with "3" then
+            tell pop over of list of group of splitter group of splitter group of topWindow
+                set value of text field 1 to "$PWD"
+            end tell
+        else
+            tell sheet 1 of topWindow
+                set value of text field 1 to "$PWD"
+            end tell
+        end if
+        keystroke return
+    end tell
+  end tell
+END
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/README.md
new file mode 100644 (file)
index 0000000..5bb47b7
--- /dev/null
@@ -0,0 +1,7 @@
+## Fossil Plugin
+
+This plugin adds completion support and prompt for fossil repositories.
+The prompt will display the current branch and status been dirty or clean.
+
+### CONTRIBUTOR
+ - Jefferson González ([jgmdev](https://github.com/jgmdev))
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/_fossil b/stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/_fossil
new file mode 100644 (file)
index 0000000..d2d48bd
--- /dev/null
@@ -0,0 +1,32 @@
+#compdef fossil
+
+function _fossil_get_command_list () {
+  fossil help -a | grep -v "Usage|Common|This is"
+}
+
+function _fossil () {
+  local context state state_descr line
+  typeset -A opt_args
+
+  _arguments \
+    '1: :->command'\
+    '2: :->subcommand'
+
+  case $state in
+    command)
+      local _OUTPUT=$(fossil branch 2>&1 | grep "use --repo")
+      if [[ -z "$_OUTPUT" ]]; then
+        compadd "$(_fossil_get_command_list)"
+      else
+        compadd clone init import help version
+      fi ;;
+    subcommand)
+      case "$words[2]" in
+      help) compadd "$(_fossil_get_command_list)" ;;
+      add) compadd "$(fossil extra)" ;;
+      *) compcall -D ;;
+      esac ;;
+  esac
+}
+
+_fossil "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/fossil.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fossil/fossil.plugin.zsh
new file mode 100644 (file)
index 0000000..fadf609
--- /dev/null
@@ -0,0 +1,56 @@
+_FOSSIL_PROMPT=""
+
+# Prefix at the very beginning of the prompt, before the branch name
+ZSH_THEME_FOSSIL_PROMPT_PREFIX="%{$fg_bold[blue]%}fossil:(%{$fg_bold[red]%}"
+
+# At the very end of the prompt
+ZSH_THEME_FOSSIL_PROMPT_SUFFIX="%{$fg_bold[blue]%})"
+
+# Text to display if the branch is dirty
+ZSH_THEME_FOSSIL_PROMPT_DIRTY=" %{$fg_bold[red]%}✖"
+
+# Text to display if the branch is clean
+ZSH_THEME_FOSSIL_PROMPT_CLEAN=" %{$fg_bold[green]%}✔"
+
+function fossil_prompt_info() {
+  local branch=$(fossil branch current 2>&1)
+
+  # if we're not in a fossil repo, don't show anything
+  ! command grep -q "use --repo" <<< "$branch" || return
+
+  local changes=$(fossil changes)
+  local dirty="$ZSH_THEME_FOSSIL_PROMPT_CLEAN"
+
+  if [[ -n "$changes" ]]; then
+    dirty="$ZSH_THEME_FOSSIL_PROMPT_DIRTY"
+  fi
+
+  printf '%s %s %s %s %s' \
+    "$ZSH_THEME_FOSSIL_PROMPT_PREFIX" \
+    "${branch:gs/%/%%}" \
+    "$ZSH_THEME_FOSSIL_PROMPT_SUFFIX" \
+    "$dirty" \
+    "%{$reset_color%}"
+}
+
+function _fossil_prompt () {
+  local current=`echo $PROMPT $RPROMPT | grep fossil`
+
+  if [ "$_FOSSIL_PROMPT" = "" -o "$current" = "" ]; then
+    local _prompt=${PROMPT}
+    local _rprompt=${RPROMPT}
+
+    local is_prompt=`echo $PROMPT | grep git`
+
+    if [ "$is_prompt" = "" ]; then
+      RPROMPT="$_rprompt"'$(fossil_prompt_info)'
+    else
+      PROMPT="$_prompt"'$(fossil_prompt_info) '
+    fi
+
+    _FOSSIL_PROMPT="1"
+  fi
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd _fossil_prompt
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/README.md
new file mode 100644 (file)
index 0000000..0500589
--- /dev/null
@@ -0,0 +1,75 @@
+## Introduction
+
+> Searches for your frontend web development made easier
+
+## Installation
+
+Open your `~/.zshrc` file and enable the `frontend-search` plugin:
+
+```zsh
+
+plugins=( ... frontend-search)
+
+```
+
+## Usage
+
+You can use the frontend-search plugin in these two forms:
+
+- `frontend <context> <term> [more terms if you want]`
+- `<context> <term> [more terms if you want]`
+
+For example, these two are equivalent:
+
+```zsh
+$ angular dependency injection
+# Will turn into ...
+$ frontend angular dependency injection
+```
+
+Available search contexts are:
+
+| context       | URL                                                                         |
+| ------------- | --------------------------------------------------------------------------- |
+| angular       | `https://angular.io/?search=`                                               |
+| angularjs     | `https://google.com/search?as_sitesearch=angularjs.org&as_q=`               |
+| bem           | `https://google.com/search?as_sitesearch=bem.info&as_q=`                    |
+| bootsnipp     | `https://bootsnipp.com/search?q=`                                           |
+| bundlephobia  | `https://bundlephobia.com/result?p=`                                        |
+| caniuse       | `https://caniuse.com/#search=`                                              |
+| codepen       | `https://codepen.io/search?q=`                                              |
+| compassdoc    | `http://compass-style.org/search?q=`                                        |
+| cssflow       | `http://www.cssflow.com/search?q=`                                          |
+| dartlang      | `https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:`     |
+| emberjs       | `https://www.google.com/search?as_sitesearch=emberjs.com/&as_q=`            |
+| flowtype      | `https://google.com/search?as_sitesearch=flow.org/en/docs/&as_q=`           |
+| fontello      | `http://fontello.com/#search=`                                              |
+| github        | `https://github.com/search?q=`                                              |
+| html5please   | `https://html5please.com/#`                                                 |
+| jestjs        | `https://www.google.com/search?as_sitesearch=jestjs.io&as_q=`               |
+| jquery        | `https://api.jquery.com/?s=`                                                |
+| lodash        | `https://devdocs.io/lodash/index#`                                          |
+| mdn           | `https://developer.mozilla.org/search?q=`                                   |
+| nodejs        | `https://www.google.com/search?as_sitesearch=nodejs.org/en/docs/&as_q=`     |
+| npmjs         | `https://www.npmjs.com/search?q=`                                           |
+| packagephobia | `https://packagephobia.now.sh/result?p=`                                    |
+| qunit         | `https://api.qunitjs.com/?s=`                                               |
+| reactjs       | `https://google.com/search?as_sitesearch=facebook.github.io/react&as_q=`    |
+| smacss        | `https://google.com/search?as_sitesearch=smacss.com&as_q=`                  |
+| stackoverflow | `https://stackoverflow.com/search?q=`                                       |
+| typescript    | `https://google.com/search?as_sitesearch=www.typescriptlang.org/docs&as_q=` |
+| unheap        | `http://www.unheap.com/?s=`                                                 |
+| vuejs         | `https://www.google.com/search?as_sitesearch=vuejs.org&as_q=`               |
+
+If you want to have another context, open an Issue and tell us!
+
+## Fallback search behaviour
+
+The plugin will use Google as a fallback if the docs site for a search context does not have a search function. You can set the fallback search engine to DuckDuckGo by setting  `FRONTEND_SEARCH_FALLBACK='duckduckgo'` in your `~/.zshrc` file before Oh My Zsh is sourced.
+
+## Author
+
+**Wilson Mendes (willmendesneto)**
+
+- <https://twitter.com/willmendesneto>
+- <https://github.com/willmendesneto>
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/_frontend b/stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/_frontend
new file mode 100644 (file)
index 0000000..15f8d23
--- /dev/null
@@ -0,0 +1,161 @@
+#compdef frontend
+
+zstyle ':completion:*:descriptions' format '%B%d%b'
+zstyle ':completion::complete:frontend:*:commands' group-name commands
+zstyle ':completion::complete:frontend:*:frontend_points' group-name frontend_points
+zstyle ':completion::complete:frontend::' list-grouped
+
+zmodload zsh/mapfile
+
+function _frontend() {
+  local CONFIG=$HOME/.frontend-search
+  local ret=1
+
+  local -a commands
+  local -a frontend_points
+
+  frontend_points=( "${(f)mapfile[$CONFIG]//$HOME/~}" )
+
+  commands=(
+    'angular: Search in Angular.io website'
+    'angularjs: Search in docs.angularjs.org website'
+    'bem: Search in BEM website'
+    'bootsnipp: Search in bootsnipp website'
+    'bundlephobia: Search in Bundlephobia website'
+    'caniuse: Search in Can I Use website'
+    'codepen: Search in codepen website'
+    'compassdoc: Search in COMPASS website'
+    'cssflow: Search in cssflow website'
+    'dartlang: Search in Dart website'
+    'emberjs: Search in Ember website'
+    'flowtype: Search in Flowtype website'
+    'fontello: Search in fontello website'
+    'github: Search in GitHub website'
+    'html5please: Search in HTML5 Please website'
+    'jestjs: Search in Jest website'
+    'jquery: Search in jQuery website'
+    'lodash: Search in Lo-Dash website'
+    'mdn: Search in MDN website'
+    'nodejs: Search in NodeJS website'
+    'npmjs: Search in NPMJS website'
+    'packagephobia: Search in Packagephobia website'
+    'qunit: Search in Qunit website'
+    'reactjs: Search in React website'
+    'smacss: Search in SMACSS website'
+    'stackoverflow: Search in StackOverflow website'
+    'typescript: Search in TypeScript website'
+    'unheap: Search in unheap website'
+    'vuejs: Search in VueJS website'
+  )
+
+  _arguments -C \
+    '1: :->first_arg' \
+    '2: :->second_arg' && ret=0
+
+  case $state in
+    first_arg)
+      _describe -t frontend_points "Warp points" frontend_points && ret=0
+      _describe -t commands "Commands" commands && ret=0
+      ;;
+    second_arg)
+      case $words[2] in
+        jquery)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        mdn)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        compassdoc)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        html5please)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        caniuse)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        dartlang)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        lodash)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        qunit)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        fontello)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        github)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        bootsnipp)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        cssflow)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        codepen)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        unheap)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        bem)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        smacss)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        angularjs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        reactjs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        emberjs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        stackoverflow)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        npmjs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        bundlephobia)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        packagephobia)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        flowtype)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        typescript)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        vuejs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        nodejs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+        jestjs)
+          _describe -t points "Warp points" frontend_points && ret=0
+          ;;
+      esac
+      ;;
+  esac
+
+  return $ret
+}
+
+_frontend "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/frontend-search.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/frontend-search/frontend-search.plugin.zsh
new file mode 100644 (file)
index 0000000..b9e2fe9
--- /dev/null
@@ -0,0 +1,111 @@
+alias angular='frontend angular'
+alias angularjs='frontend angularjs'
+alias bem='frontend bem'
+alias bootsnipp='frontend bootsnipp'
+alias bundlephobia='frontend bundlephobia'
+alias caniuse='frontend caniuse'
+alias codepen='frontend codepen'
+alias compassdoc='frontend compassdoc'
+alias cssflow='frontend cssflow'
+alias dartlang='frontend dartlang'
+alias emberjs='frontend emberjs'
+alias flowtype='frontend flowtype'
+alias fontello='frontend fontello'
+alias github='frontend github'
+alias html5please='frontend html5please'
+alias jestjs='frontend jestjs'
+alias jquery='frontend jquery'
+alias lodash='frontend lodash'
+alias mdn='frontend mdn'
+alias nodejs='frontend nodejs'
+alias npmjs='frontend npmjs'
+alias packagephobia='frontend packagephobia'
+alias qunit='frontend qunit'
+alias reactjs='frontend reactjs'
+alias smacss='frontend smacss'
+alias stackoverflow='frontend stackoverflow'
+alias typescript='frontend typescript'
+alias unheap='frontend unheap'
+alias vuejs='frontend vuejs'
+
+function _frontend_fallback() {
+  case "$FRONTEND_SEARCH_FALLBACK" in
+    duckduckgo) echo "https://duckduckgo.com/?sites=$1&q=" ;;
+    *) echo "https://google.com/search?as_sitesearch=$1&as_q=" ;;
+  esac
+}
+
+function frontend() {
+  emulate -L zsh
+
+  # define search context URLS
+  local -A urls
+  urls=(
+    angular        'https://angular.io/?search='
+    angularjs      $(_frontend_fallback 'angularjs.org')
+    bem            $(_frontend_fallback 'bem.info')
+    bootsnipp      'https://bootsnipp.com/search?q='
+    bundlephobia   'https://bundlephobia.com/result?p='
+    caniuse        'https://caniuse.com/#search='
+    codepen        'https://codepen.io/search/pens?q='
+    compassdoc     'http://compass-style.org/search?q='
+    cssflow        'http://www.cssflow.com/search?q='
+    dartlang       'https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:'
+    emberjs        $(_frontend_fallback 'emberjs.com/')
+    flowtype       $(_frontend_fallback 'flow.org/en/docs/')
+    fontello       'http://fontello.com/#search='
+    github         'https://github.com/search?q='
+    html5please    'https://html5please.com/#'
+    jestjs         $(_frontend_fallback 'jestjs.io')
+    jquery         'https://api.jquery.com/?s='
+    lodash         'https://devdocs.io/lodash/index#'
+    mdn            'https://developer.mozilla.org/search?q='
+    nodejs         $(_frontend_fallback 'nodejs.org/en/docs/')
+    npmjs          'https://www.npmjs.com/search?q='
+    packagephobia  'https://packagephobia.now.sh/result?p='
+    qunit          'https://api.qunitjs.com/?s='
+    reactjs        $(_frontend_fallback 'reactjs.org/')
+    smacss         $(_frontend_fallback 'smacss.com')
+    stackoverflow  'https://stackoverflow.com/search?q='
+    typescript     $(_frontend_fallback 'www.typescriptlang.org/docs')
+    unheap         'http://www.unheap.com/?s='
+    vuejs          $(_frontend_fallback 'vuejs.org')
+  )
+
+  # show help for command list
+  if [[ $# -lt 2 ]]; then
+    print -P "Usage: frontend %Ucontext%u %Uterm%u [...%Umore%u] (or just: %Ucontext%u %Uterm%u [...%Umore%u])"
+    print -P ""
+    print -P "%Uterm%u and what follows is what will be searched for in the %Ucontext%u website,"
+    print -P "and %Ucontext%u is one of the following:"
+    print -P ""
+    print -P "  angular, angularjs, bem, bootsnipp, caniuse, codepen, compassdoc, cssflow, packagephobia"
+    print -P "  dartlang, emberjs, fontello, flowtype, github, html5please, jestjs, jquery, lodash,"
+    print -P "  mdn, npmjs, nodejs, qunit, reactjs, smacss, stackoverflow, unheap, vuejs, bundlephobia"
+    print -P ""
+    print -P "For example: frontend npmjs mocha (or just: npmjs mocha)."
+    print -P ""
+    return 1
+  fi
+
+  # check whether the search context is supported
+  if [[ -z "$urls[$1]" ]]; then
+    echo "Search context \"$1\" currently not supported."
+    echo ""
+    echo "Valid contexts are:"
+    echo ""
+    echo "  angular, angularjs, bem, bootsnipp, caniuse, codepen, compassdoc, cssflow, packagephobia"
+    echo "  dartlang, emberjs, fontello, github, html5please, jest, jquery, lodash,"
+    echo "  mdn, npmjs, nodejs, qunit, reactjs, smacss, stackoverflow, unheap, vuejs, bundlephobia"
+    echo ""
+    return 1
+  fi
+
+  # build search url:
+  # join arguments passed with '%20', then append to search context URL
+  url="${urls[$1]}$(omz_urlencode -P ${@[2,-1]})"
+
+  echo "Opening $url ..."
+
+  open_command "$url"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fzf/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/fzf/README.md
new file mode 100644 (file)
index 0000000..beedf46
--- /dev/null
@@ -0,0 +1,52 @@
+# fzf
+
+This plugin tries to find [junegunn's fzf](https://github.com/junegunn/fzf) based on where
+it's been installed, and enables its fuzzy auto-completion and key bindings.
+
+To use it, add `fzf` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... fzf)
+```
+
+## Settings
+
+All these settings should go in your zshrc file, before Oh My Zsh is sourced.
+
+### `FZF_BASE`
+
+Set to fzf installation directory path:
+
+```zsh
+export FZF_BASE=/path/to/fzf/install/dir
+```
+
+### `FZF_DEFAULT_COMMAND`
+
+Set default command to use when input is tty:
+
+```zsh
+export FZF_DEFAULT_COMMAND='<your fzf default command>'
+```
+
+If not set, the plugin will try to set it to these, in the order in which they're found:
+
+- [`fd`](https://github.com/sharkdp/fd)
+- [`rg`](https://github.com/BurntSushi/ripgrep)
+- [`ag`](https://github.com/ggreer/the_silver_searcher)
+
+### `DISABLE_FZF_AUTO_COMPLETION`
+
+Set whether to load fzf auto-completion:
+
+```zsh
+DISABLE_FZF_AUTO_COMPLETION="true"
+```
+
+### `DISABLE_FZF_KEY_BINDINGS`
+
+Set whether to disable key bindings (CTRL-T, CTRL-R, ALT-C):
+
+```zsh
+DISABLE_FZF_KEY_BINDINGS="true"
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/fzf/fzf.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/fzf/fzf.plugin.zsh
new file mode 100644 (file)
index 0000000..a946cf7
--- /dev/null
@@ -0,0 +1,228 @@
+function fzf_setup_using_base_dir() {
+  local fzf_base fzf_shell fzfdirs dir
+
+  test -d "${FZF_BASE}" && fzf_base="${FZF_BASE}"
+
+  if [[ -z "${fzf_base}" ]]; then
+    fzfdirs=(
+      "${HOME}/.fzf"
+      "${HOME}/.nix-profile/share/fzf"
+      "${XDG_DATA_HOME:-$HOME/.local/share}/fzf"
+      "/usr/local/opt/fzf"
+      "/usr/share/fzf"
+      "/usr/local/share/examples/fzf"
+    )
+    for dir in ${fzfdirs}; do
+      if [[ -d "${dir}" ]]; then
+        fzf_base="${dir}"
+        break
+      fi
+    done
+
+    if [[ -z "${fzf_base}" ]]; then
+      if (( ${+commands[fzf-share]} )) && dir="$(fzf-share)" && [[ -d "${dir}" ]]; then
+        fzf_base="${dir}"
+      elif (( ${+commands[brew]} )) && dir="$(brew --prefix fzf 2>/dev/null)"; then
+        if [[ -d "${dir}" ]]; then
+          fzf_base="${dir}"
+        fi
+      fi
+    fi
+  fi
+
+  if [[ ! -d "${fzf_base}" ]]; then
+    return 1
+  fi
+
+  # Fix fzf shell directory for Arch Linux, NixOS or Void Linux packages
+  if [[ ! -d "${fzf_base}/shell" ]]; then
+    fzf_shell="${fzf_base}"
+  else
+    fzf_shell="${fzf_base}/shell"
+  fi
+
+  # Setup fzf binary path
+  if (( ! ${+commands[fzf]} )) && [[ "$PATH" != *$fzf_base/bin* ]]; then
+    export PATH="$PATH:$fzf_base/bin"
+  fi
+
+  # Auto-completion
+  if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then
+    source "${fzf_shell}/completion.zsh" 2> /dev/null
+  fi
+
+  # Key bindings
+  if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then
+    source "${fzf_shell}/key-bindings.zsh"
+  fi
+}
+
+
+function fzf_setup_using_debian() {
+  if (( ! $+commands[dpkg] )) || ! dpkg -s fzf &>/dev/null; then
+    # Either not a debian based distro, or no fzf installed
+    return 1
+  fi
+
+  # NOTE: There is no need to configure PATH for debian package, all binaries
+  # are installed to /usr/bin by default
+
+  local completions key_bindings
+
+  case $PREFIX in
+    *com.termux*)
+      # Support Termux package
+      completions="${PREFIX}/share/fzf/completion.zsh"
+      key_bindings="${PREFIX}/share/fzf/key-bindings.zsh"
+      ;;
+    *)
+      # Determine completion file path: first bullseye/sid, then buster/stretch
+      completions="/usr/share/doc/fzf/examples/completion.zsh"
+      [[ -f "$completions" ]] || completions="/usr/share/zsh/vendor-completions/_fzf"
+      key_bindings="/usr/share/doc/fzf/examples/key-bindings.zsh"
+      ;;
+  esac
+
+  # Auto-completion
+  if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then
+    source $completions 2> /dev/null
+  fi
+
+  # Key bindings
+  if [[ ! "$DISABLE_FZF_KEY_BINDINGS" == "true" ]]; then
+    source $key_bindings
+  fi
+
+  return 0
+}
+
+function fzf_setup_using_opensuse() {
+  # OpenSUSE installs fzf in /usr/bin/fzf
+  # If the command is not found, the package isn't installed
+  (( $+commands[fzf] )) || return 1
+
+  # The fzf-zsh-completion package installs the auto-completion in
+  local completions="/usr/share/zsh/site-functions/_fzf"
+  # The fzf-zsh-completion package installs the key-bindings file in
+  local key_bindings="/etc/zsh_completion.d/fzf-key-bindings"
+
+  # If these are not found: (1) maybe we're not on OpenSUSE, or
+  # (2) maybe the fzf-zsh-completion package isn't installed.
+  if [[ ! -f "$completions" || ! -f "$key_bindings" ]]; then
+    return 1
+  fi
+
+  # Auto-completion
+  if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then
+    source "$completions" 2>/dev/null
+  fi
+
+  # Key bindings
+  if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then
+    source "$key_bindings" 2>/dev/null
+  fi
+
+  return 0
+}
+
+function fzf_setup_using_openbsd() {
+  # openBSD installs fzf in /usr/local/bin/fzf
+  if [[ "$OSTYPE" != openbsd* ]] || (( ! $+commands[fzf] )); then
+    return 1
+  fi
+
+  # The fzf package installs the auto-completion in
+  local completions="/usr/local/share/zsh/site-functions/_fzf_completion"
+  # The fzf package installs the key-bindings file in
+  local key_bindings="/usr/local/share/zsh/site-functions/_fzf_key_bindings"
+
+  # Auto-completion
+  if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then
+    source "$completions" 2>/dev/null
+  fi
+
+  # Key bindings
+  if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then
+    source "$key_bindings" 2>/dev/null
+  fi
+
+  return 0
+}
+
+function fzf_setup_using_cygwin() {
+  # Cygwin installs fzf in /usr/local/bin/fzf
+  if [[ "$OSTYPE" != cygwin* ]] || (( ! $+commands[fzf] )); then
+    return 1
+  fi
+
+  # The fzf-zsh-completion package installs the auto-completion in
+  local completions="/etc/profile.d/fzf-completion.zsh"
+  # The fzf-zsh package installs the key-bindings file in
+  local key_bindings="/etc/profile.d/fzf.zsh"
+
+  # Auto-completion
+  if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then
+    source "$completions" 2>/dev/null
+  fi
+
+  # Key bindings
+  if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then
+    source "$key_bindings" 2>/dev/null
+  fi
+
+  return 0
+}
+
+function fzf_setup_using_macports() {
+  # If the command is not found, the package isn't installed
+  (( $+commands[fzf] )) || return 1
+
+  # The fzf-zsh-completion package installs the auto-completion in
+  local completions="/opt/local/share/zsh/site-functions/fzf"
+  # The fzf-zsh-completion package installs the key-bindings file in
+  local key_bindings="/opt/local/share/fzf/shell/key-bindings.zsh"
+
+  if [[ ! -f "$completions" || ! -f "$key_bindings" ]]; then
+    return 1
+  fi
+
+  # Auto-completion
+  if [[ -o interactive && "$DISABLE_FZF_AUTO_COMPLETION" != "true" ]]; then
+    source "$completions" 2>/dev/null
+  fi
+
+  # Key bindings
+  if [[ "$DISABLE_FZF_KEY_BINDINGS" != "true" ]]; then
+    source "$key_bindings" 2>/dev/null
+  fi
+
+  return 0
+}
+
+# Indicate to user that fzf installation not found if nothing worked
+function fzf_setup_error() {
+  cat >&2 <<'EOF'
+[oh-my-zsh] fzf plugin: Cannot find fzf installation directory.
+Please add `export FZF_BASE=/path/to/fzf/install/dir` to your .zshrc
+EOF
+}
+
+fzf_setup_using_openbsd \
+  || fzf_setup_using_debian \
+  || fzf_setup_using_opensuse \
+  || fzf_setup_using_cygwin \
+  || fzf_setup_using_macports \
+  || fzf_setup_using_base_dir \
+  || fzf_setup_error
+
+unset -f -m 'fzf_setup_*'
+
+if [[ -z "$FZF_DEFAULT_COMMAND" ]]; then
+  if (( $+commands[fd] )); then
+    export FZF_DEFAULT_COMMAND='fd --type f --hidden --exclude .git'
+  elif (( $+commands[rg] )); then
+    export FZF_DEFAULT_COMMAND='rg --files --hidden --glob "!.git/*"'
+  elif (( $+commands[ag] )); then
+    export FZF_DEFAULT_COMMAND='ag -l --hidden -g "" --ignore .git'
+  fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gas/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gas/README.md
new file mode 100644 (file)
index 0000000..47b3fb9
--- /dev/null
@@ -0,0 +1,10 @@
+# Gas plugin
+
+This plugin adds autocompletion for the [gas](http://walle.github.com/gas) command,
+a utility to manage Git authors.
+
+To use it, add `gas` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... gas)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gas/_gas b/stow/oh-my-zsh/.oh-my-zsh/plugins/gas/_gas
new file mode 100644 (file)
index 0000000..23e6d99
--- /dev/null
@@ -0,0 +1,39 @@
+#compdef gas
+
+local curcontext="$curcontext" state line cmds ret=1
+
+_arguments -C \
+       '(- 1 *)'{-v,--version}'[display version information]' \
+       '(-h|--help)'{-h,--help}'[show help information]' \
+       '1: :->cmds' \
+       '*: :->args' && ret=0
+
+case $state in
+       cmds)
+               cmds=(
+            "version:Prints Gas's version"
+            "use:Uses author"
+            "ssh:Creates a new ssh key for an existing gas author"
+            "show:Shows your current user"
+            "list:Lists your authors"
+            "import:Imports current user to gasconfig"
+            "help:Describe available tasks or one specific task"
+            "delete:Deletes author"
+            "add:Adds author to gasconfig"
+        )
+               _describe -t commands 'gas command' cmds && ret=0
+               ;;
+       args)
+               case $line[1] in
+                       (use|delete)
+        VERSION=$(gas -v)
+        if [[ $VERSION == <1->.*.* ]] || [[ $VERSION == 0.<2->.* ]] || [[ $VERSION == 0.1.<6-> ]] then
+          _values -S , 'authors' $(cat ~/.gas/gas.authors | sed -n -e 's/^.*\[\(.*\)\]/\1/p') && ret=0
+        else
+                                 _values -S , 'authors' $(cat ~/.gas | sed -n -e 's/^\[\(.*\)\]/\1/p') && ret=0
+        fi
+               esac
+               ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gatsby/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gatsby/README.md
new file mode 100644 (file)
index 0000000..36846a2
--- /dev/null
@@ -0,0 +1,7 @@
+# gatsby autocomplete plugin
+
+* Adds autocomplete options for all gatsby commands.
+
+## Requirements
+
+In order to make this work, you will need to have gatsby set up in your path.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gatsby/_gatsby b/stow/oh-my-zsh/.oh-my-zsh/plugins/gatsby/_gatsby
new file mode 100644 (file)
index 0000000..66eb02f
--- /dev/null
@@ -0,0 +1,24 @@
+#compdef gatsby
+#autoload
+
+# in order to make this work, you will need to have gatsby
+# https://www.gatsbyjs.org/
+
+local -a _1st_arguments
+_1st_arguments=(
+'develop:Start development server. Watches files, rebuilds, and hot reloads if something changes'
+'build:Build a Gatsby project.'
+'serve:Serve previously built Gatsby site.'
+'info:Get environment information for debugging and issue reporting'
+'clean:Wipe the local gatsby environment including built assets and cache'
+'repl:Get a node repl with context of Gatsby environment, see (add docs link here)'
+'new: [rootPath] [starter]  Create new Gatsby project.'
+'telemetry:Enable or disable Gatsby anonymous analytics collection.'
+)
+
+_arguments -C '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+    _describe -t commands "gatsby subcommand" _1st_arguments
+    return
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gcloud/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gcloud/README.md
new file mode 100644 (file)
index 0000000..e7ce0e0
--- /dev/null
@@ -0,0 +1,24 @@
+# gcloud
+
+This plugin provides completion support for the
+[Google Cloud SDK CLI](https://cloud.google.com/sdk/gcloud/).
+
+To use it, add `gcloud` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... gcloud)
+```
+
+It relies on you having installed the SDK using one of the supported options
+listed [here](https://cloud.google.com/sdk/install).
+
+## Plugin Options
+
+* Set `CLOUDSDK_HOME` in your `zshrc` file before you load oh-my-zsh if you have
+your GCloud SDK installed in a non-standard location. The plugin will use this
+as the base for your SDK if it finds it set already.
+
+* If you do not have a `python2` in your `PATH` you'll also need to set the
+`CLOUDSDK_PYTHON` environment variable at the end of your `.zshrc`. This is
+used by the SDK to call a compatible interpreter when you run one of the
+SDK commands.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gcloud/gcloud.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gcloud/gcloud.plugin.zsh
new file mode 100644 (file)
index 0000000..9be9d68
--- /dev/null
@@ -0,0 +1,49 @@
+#####################################################
+# gcloud plugin for oh-my-zsh                       #
+# Author: Ian Chesal (github.com/ianchesal)         #
+#####################################################
+
+if [[ -z "${CLOUDSDK_HOME}" ]]; then
+  search_locations=(
+    "$HOME/google-cloud-sdk"
+    "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk"
+    "/opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk"
+    "/usr/share/google-cloud-sdk"
+    "/snap/google-cloud-sdk/current"
+    "/usr/lib/google-cloud-sdk"
+    "/usr/lib64/google-cloud-sdk"
+    "/opt/google-cloud-sdk"
+    "/opt/local/libexec/google-cloud-sdk"
+  )
+
+  for gcloud_sdk_location in $search_locations; do
+    if [[ -d "${gcloud_sdk_location}" ]]; then
+      CLOUDSDK_HOME="${gcloud_sdk_location}"
+      break
+    fi
+  done
+  unset search_locations gcloud_sdk_location
+fi
+
+if (( ${+CLOUDSDK_HOME} )); then
+  # Only source this if gcloud isn't already on the path
+  if (( ! $+commands[gcloud] )); then
+    if [[ -f "${CLOUDSDK_HOME}/path.zsh.inc" ]]; then
+      source "${CLOUDSDK_HOME}/path.zsh.inc"
+    fi
+  fi
+
+  # Look for completion file in different paths
+  for comp_file (
+    "${CLOUDSDK_HOME}/completion.zsh.inc"             # default location
+    "/usr/share/google-cloud-sdk/completion.zsh.inc"  # apt-based location
+  ); do
+    if [[ -f "${comp_file}" ]]; then
+      source "${comp_file}"
+      break
+    fi
+  done
+  unset comp_file
+
+  export CLOUDSDK_HOME
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/README.md
new file mode 100644 (file)
index 0000000..95b3aa7
--- /dev/null
@@ -0,0 +1,10 @@
+# Geeknote plugin
+
+This plugin provides autocompletion for [Geeknote](https://github.com/VitaliyRodnenko/geeknote)
+and an alias for `geeknote` called `gn`.
+
+To use it, add `geeknote` to the plugins array in your zshrc file:
+
+```zsh
+plugins=( ... geeknote ...)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/_geeknote b/stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/_geeknote
new file mode 100644 (file)
index 0000000..a34be59
--- /dev/null
@@ -0,0 +1,157 @@
+#compdef geeknote
+
+# Geeknote Autocomplete plugin for Zsh
+# Requires: Geeknote installed
+# Author : Ján Koščo (@s7anley)
+
+__login() {
+    # no arguments
+}
+
+__logout() {
+    _arguments \
+        '--force[Do not ask about logging out.]'
+}
+
+__settings() {
+    _arguments \
+        "--editor+[Set the editor, which use to edit and create notes.]::"
+}
+
+__create() {
+    _arguments \
+        '--title+[The note title.]::' \
+        '--content+[The note content.]::' \
+        '--tags+[One tag or the list of tags which will be added to the note.]::' \
+        '--notebook+[Set the notebook where to save note.]::' \
+        '--resource+[Add a resource to the note.]::'
+}
+
+__edit() {
+    _arguments \
+        '--note+[The name or ID from the previous search of a note to edit.]::' \
+        '--title+[Set new title of the note.]::' \
+        '--content+[Set new content of the note.]::' \
+        '--tags+[Set new list o tags for the note.]::' \
+        '--notebook+[Assign new notebook for the note.]::' \
+        '--resource+[Add a resource to the note.]::'
+}
+
+__find() {
+    _arguments \
+        '--search+[Text to search.]::' \
+        '--tags+[Notes with which tag/tags to search.]::' \
+        '--notebook+[In which notebook search the note.]::' \
+        '--date+[Set date in format dd.mm.yyyy or date range dd.mm.yyyy-dd.mm.yyyy.]::' \
+        '--count+[How many notes show in the result list.]::' \
+        '--with-url[Add direct url of each note in results to Evernote web-version.]' \
+        '--content-search[Search by content, not by title.]' \
+        '--exact-entry[Search for exact entry of the request.]'
+}
+
+__show() {
+    _arguments \
+        '--note+[The name or ID from the previous search of a note to show.]::' \
+        '--raw[Show the raw note body.]'
+}
+
+__remove() {
+    _arguments \
+        '--note+[The name or ID from the previous search of a note to remove.]::' \
+        '--force[Do not ask about removing.]'
+}
+
+__notebook-list() {
+    # no arguments
+}
+
+__notebook-create() {
+    _arguments \
+        '--title+[Set the title of new notebook.]::'
+}
+
+__notebook-edit() {
+    _arguments \
+        '--title+[Set the title of new notebook.]::' \
+        '--notebook+[The name of a notebook to rename.]::'
+}
+
+__tag-list() {
+    # no arguments
+}
+
+__tag-create() {
+    _arguments \
+        '--title+[Set the title of new tag.]::'
+}
+
+__tag-edit() {
+    _arguments \
+        '--tagname+[The name of a tag to rename.]::' \
+        '--title+[Set the new name of tag.]::'
+}
+
+__user() {
+    _arguments \
+        '--full[Show full information.]'
+}
+
+local -a _1st_arguments
+_1st_arguments=(
+    'login':'Authorize in Evernote.'
+    'logout':'Logout from Evernote.'
+    'settings':'Show and edit current settings.'
+    'create':'Create note in Evernote.'
+    'edit':'Edit note in Evernote.'
+    'find':'Search notes in Evernote.'
+    'show':'Output note in the terminal.'
+    'remove':'Remove note from Evernote.'
+    'notebook-list':'Show the list of existing notebooks in your Evernote.'
+    'notebook-create':'Create new notebook.'
+    'notebook-edit':'Edit/rename notebook.'
+    'tag-list':'Show the list of existing tags in your Evernote.'
+    'tag-create':'Create new tag.'
+    'tag-edit':'Edit/rename tag.'
+    'user':'Show information about active user.'
+)
+
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+    _describe -t commands "geeknote command" _1st_arguments
+    return
+fi
+
+local -a _command_args
+case "$words[1]" in
+    login)
+       __login ;;
+    logout)
+        __logout ;;
+    settings)
+        __settings ;;
+    create)
+        __create ;;
+    edit)
+        __edit ;;
+    find)
+        __find ;;
+    show)
+        __show ;;
+    remove)
+        __remove ;;
+    notebook-list)
+        __notebook-list ;;
+    notebook-create)
+        __notebook-create ;;
+    notebook-edit)
+        __notebook-edit ;;
+    tag-list)
+        __tag-list ;;
+    tag-create)
+        __tag-create ;;
+    tag-edit)
+        __tag-edit ;;
+    user)
+        __user ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/geeknote.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/geeknote/geeknote.plugin.zsh
new file mode 100644 (file)
index 0000000..8126d26
--- /dev/null
@@ -0,0 +1,2 @@
+#Alias
+alias gn='geeknote'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gem/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gem/README.md
new file mode 100644 (file)
index 0000000..decd87b
--- /dev/null
@@ -0,0 +1,17 @@
+# Gem plugin
+
+This plugin adds completions and aliases for [Gem](https://rubygems.org/). The completions include the common `gem` subcommands as well as the installed gems in the current directory.
+
+To use it, add `gem` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... gem)
+```
+
+## Aliases
+
+| Alias                | Command                       | Description                                |
+|----------------------|-------------------------------|--------------------------------------------|
+| gemb                 | `gem build *.gemspec`         | Build a gem from a gemspec                 |
+| gemp                 | `gem push *.gem`              | Push a gem up to the gem server            |
+| gemy [gem] [version] | `gem yank [gem] -v [version]` | Remove a pushed gem version from the index |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gem/_gem b/stow/oh-my-zsh/.oh-my-zsh/plugins/gem/_gem
new file mode 100644 (file)
index 0000000..92feebe
--- /dev/null
@@ -0,0 +1,72 @@
+#compdef gem
+#autoload
+
+# gem zsh completion, based on homebrew completion
+
+_gem_installed() {
+  installed_gems=(${(f)"$(gem list --local --no-versions)"})
+}
+
+local -a _1st_arguments
+
+_1st_arguments=(
+  'build:Build a gem from a gemspec'
+  'cert:Manage RubyGems certificates and signing settings'
+  'check:Check a gem repository for added or missing files'
+  'cleanup:Clean up old versions of installed gems in the local repository'
+  'contents:Display the contents of the installed gems'
+  'dependency:Show the dependencies of an installed gem'
+  'environment:Display information about the RubyGems environment'
+  'fetch:Download a gem and place it in the current directory'
+  'generate_index:Generates the index files for a gem server directory'
+  'help:Provide help on the `gem` command'
+  'install:Install a gem into the local repository'
+  'list:Display gems whose name starts with STRING'
+  'lock:Generate a lockdown list of gems'
+  'mirror:Mirror all gem files (requires rubygems-mirror)'
+  'outdated:Display all gems that need updates'
+  'owner:Manage gem owners on RubyGems.org.'
+  'pristine:Restores installed gems to pristine condition from files located in the gem cache'
+  'push:Push a gem up to RubyGems.org'
+  'query:Query gem information in local or remote repositories'
+  'rdoc:Generates RDoc for pre-installed gems'
+  'search:Display all gems whose name contains STRING'
+  'server:Documentation and gem repository HTTP server'
+  'sources:Manage the sources and cache file RubyGems uses to search for gems'
+  'specification:Display gem specification (in yaml)'
+  'stale:List gems along with access times'
+  'uninstall:Uninstall gems from the local repository'
+  'unpack:Unpack an installed gem to the current directory'
+  'update:Update installed gems to the latest version'
+  'which:Find the location of a library file you can require'
+  'yank:Remove a specific gem version release from RubyGems.org'
+)
+
+local expl
+local -a gems installed_gems
+
+_arguments \
+  '(-v --version)'{-v,--version}'[show version]' \
+  '(-h --help)'{-h,--help}'[show help]' \
+  '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "gem subcommand" _1st_arguments
+  return
+fi
+
+case "$words[1]" in
+  build)
+    _files -g "*.gemspec"
+    ;;
+  install)
+    _files ;;
+  list)
+      if [[ "$state" == forms ]]; then
+        _gem_installed
+        _requested installed_gems expl 'installed gems' compadd -a installed_gems
+      fi ;;
+  uninstall|update)
+    _gem_installed
+    _wanted installed_gems expl 'installed gems' compadd -a installed_gems ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gem/gem.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gem/gem.plugin.zsh
new file mode 100644 (file)
index 0000000..938f5c9
--- /dev/null
@@ -0,0 +1,7 @@
+alias gemb="gem build *.gemspec"
+alias gemp="gem push *.gem"
+
+# gemy GEM 0.0.0 = gem yank GEM -v 0.0.0
+function gemy {
+       gem yank $1 -v $2
+}
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/README.md
new file mode 100644 (file)
index 0000000..a5ff4a8
--- /dev/null
@@ -0,0 +1,66 @@
+# genpass
+
+This plugin provides three unique password generators for ZSH. Each generator
+has at least a 128-bit security margin and generates passwords from the
+cryptographically secure `/dev/urandom`. Each generator can also take an
+optional numeric argument to generate multiple passwords.
+
+To use it from an interactive ZSH, add `genpass` to the plugins array in your
+zshrc file:
+
+    plugins=(... genpass)
+
+You can also invoke password generators directly (they are implemented as
+standalone executable files), which can be handy when you need to generate
+passwords in a script:
+
+    ~/.oh-my-zsh/plugins/genpass/genpass-apple 3
+
+## genpass-apple
+
+Generates a pronounceable pseudoword passphrase of the "cvccvc" consonant/vowel
+syntax, inspired by [Apple's iCloud Keychain password generator][1]. Each
+password has exactly 1 digit placed at the edge of a "word" and exactly 1
+capital letter to satisfy most password security requirements.
+
+    % genpass-apple
+    gelcyv-foqtam-fotqoh-viMleb-lexduv-6ixfuk
+
+    % genpass-apple 3
+    japvyz-qyjti4-kajrod-nubxaW-hukkan-dijcaf
+    vydpig-fucnul-3ukpog-voggom-zygNad-jepgad
+    zocmez-byznis-hegTaj-jecdyq-qiqmiq-5enwom
+
+[1]: https://developer.apple.com/password-rules/
+
+## genpass-monkey
+
+Generates visually unambiguous random meaningless strings using [Crockford's
+base32][2].
+
+    % genpass-monkey
+    xt7gn976e7jj3fstgpy27330x3
+
+    % genpass-monkey 3
+    n1qqwtzgejwgqve9yzf2gxvx4m
+    r2n3f5s6vbqs2yx7xjnmahqewy
+    296w9y9rts3p5r9yay0raek8e5
+
+[2]: https://www.crockford.com/base32.html
+
+## genpass-xkcd
+
+Generates passphrases from `/usr/share/dict/words` inspired by the [famous (and
+slightly misleading) XKCD comic][3]. Each passphrase is prepended with a digit
+showing the number of words in the passphrase to adhere to password security
+requirements that require digits. Each word is 6 characters or less.
+
+    % genpass-xkcd
+    9-eaten-Slav-rife-aired-hill-cordon-splits-welsh-napes
+
+    % genpass-xkcd 3
+    9-worker-Vlad-horde-shrubs-smite-thwart-paw-alters-prawns
+    9-tutors-stink-rhythm-junk-snappy-hooray-barbs-mewl-clomp
+    9-vital-escape-Angkor-Huff-wet-Mayra-abbés-putts-guzzle
+
+[3]: https://xkcd.com/936/
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-apple b/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-apple
new file mode 100755 (executable)
index 0000000..963ab64
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/env zsh
+#
+# Usage: genpass-apple [NUM]
+#
+# Generate a password made of 6 pseudowords of 6 characters each
+# with the security margin of at least 128 bits.
+#
+# Example password: xudmec-4ambyj-tavric-mumpub-mydVop-bypjyp
+#
+# If given a numerical argument, generate that many passwords.
+
+emulate -L zsh -o no_unset -o warn_create_global -o warn_nested_var
+
+if [[ ARGC -gt 1 || ${1-1} != ${~:-<1-$((16#7FFFFFFF))>} ]]; then
+  print -ru2 -- "usage: $0 [NUM]"
+  return 1
+fi
+
+zmodload zsh/system zsh/mathfunc || return
+
+{
+  local -r vowels=aeiouy
+  local -r consonants=bcdfghjklmnpqrstvwxz
+  local -r digits=0123456789
+
+  # Sets REPLY to a uniformly distributed random number in [1, $1].
+  # Requires: $1 <= 256.
+  function -$0-rand() {
+    local c
+    while true; do
+      sysread -s1 c || return
+      # Avoid bias towards smaller numbers.
+      (( #c < 256 / $1 * $1 )) && break
+    done
+    typeset -g REPLY=$((#c % $1 + 1))
+  }
+
+  local REPLY chars
+
+  repeat ${1-1}; do
+    # Generate 6 pseudowords of the form cvccvc where c and v
+    # denote random consonants and vowels respectively.
+    local words=()
+    repeat 6; do
+      words+=('')
+      repeat 2; do
+        for chars in $consonants $vowels $consonants; do
+          -$0-rand $#chars || return
+          words[-1]+=$chars[REPLY]
+        done
+      done
+    done
+
+    local pwd=${(j:-:)words}
+
+    # Replace either the first or the last character in one of
+    # the words with a random digit.
+    -$0-rand $#digits || return
+    local digit=$digits[REPLY]
+    -$0-rand $((2 * $#words)) || return
+    pwd[REPLY/2*7+2*(REPLY%2)-1]=$digit
+
+    # Convert one lower-case character to upper case.
+    while true; do
+      -$0-rand $#pwd || return
+      [[ $vowels$consonants == *$pwd[REPLY]* ]] && break
+    done
+    # NOTE: We aren't using ${(U)c} here because its results are
+    # locale-dependent. For example, when upper-casing 'i' in Turkish
+    # locale we would get 'İ', a.k.a. latin capital letter i with dot
+    # above. We could set LC_CTYPE=C locally but then we would run afoul
+    # of this zsh bug: https://www.zsh.org/mla/workers/2020/msg00588.html.
+    local c=$pwd[REPLY]
+    printf -v c '%o' $((#c - 32))
+    printf "%s\\$c%s\\n" "$pwd[1,REPLY-1]" "$pwd[REPLY+1,-1]" || return
+  done
+} always {
+  unfunction -m -- "-${(b)0}-*"
+} </dev/urandom
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-monkey b/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-monkey
new file mode 100755 (executable)
index 0000000..94ff5e1
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env zsh
+#
+# Usage: genpass-monkey [NUM]
+#
+# Generate a password made of 26 alphanumeric characters
+# with the security margin of at least 128 bits.
+#
+# Example password: nz5ej2kypkvcw0rn5cvhs6qxtm
+#
+# If given a numerical argument, generate that many passwords.
+
+emulate -L zsh -o no_unset -o warn_create_global -o warn_nested_var
+
+if [[ ARGC -gt 1 || ${1-1} != ${~:-<1-$((16#7FFFFFFF))>} ]]; then
+  print -ru2 -- "usage: $0 [NUM]"
+  return 1
+fi
+
+zmodload zsh/system || return
+
+{
+  local -r chars=abcdefghjkmnpqrstvwxyz0123456789
+  local c
+  repeat ${1-1}; do
+    repeat 26; do
+      sysread -s1 c || return
+      # There is uniform because $#chars divides 256.
+      print -rn -- $chars[#c%$#chars+1]
+    done
+    print
+  done
+} </dev/urandom
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-xkcd b/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass-xkcd
new file mode 100755 (executable)
index 0000000..ed03971
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/env zsh
+#
+# Usage: genpass-xkcd [NUM]
+#
+# Generate a password made of words from /usr/share/dict/words
+# with the security margin of at least 128 bits.
+#
+# Example password: 9-mien-flood-Patti-buxom-dozes-ickier-pay-ailed-Foster
+#
+# If given a numerical argument, generate that many passwords.
+#
+# The name of this utility is a reference to https://xkcd.com/936/.
+
+emulate -L zsh -o no_unset -o warn_create_global -o warn_nested_var -o extended_glob
+
+if [[ ARGC -gt 1 || ${1-1} != ${~:-<1-$((16#7FFFFFFF))>} ]]; then
+  print -ru2 -- "usage: $0 [NUM]"
+  return 1
+fi
+
+zmodload zsh/system zsh/mathfunc || return
+
+local -r dict=/usr/share/dict/words
+
+if [[ ! -e $dict ]]; then
+  print -ru2 -- "$0: file not found: $dict"
+  return 1
+fi
+
+# Read all dictionary words and leave only those made of 1-6 characters.
+local -a words
+words=(${(M)${(f)"$(<$dict)"}:#[a-zA-Z](#c1,6)}) || return
+
+if (( $#words < 2 )); then
+  print -ru2 -- "$0: not enough suitable words in $dict"
+  return 1
+fi
+
+if (( $#words > 16#7FFFFFFF )); then
+  print -ru2 -- "$0: too many words in $dict"
+  return 1
+fi
+
+# Figure out how many words we need for 128 bits of security margin.
+# Each word adds log2($#words) bits.
+local -i n=$((ceil(128. / (log($#words) / log(2)))))
+
+{
+  local c
+  repeat ${1-1}; do
+    print -rn -- $n
+    repeat $n; do
+      while true; do
+        # Generate a random number in [0, 2**31).
+        local -i rnd=0
+        repeat 4; do
+          sysread -s1 c || return
+          (( rnd = (~(1 << 23) & rnd) << 8 | #c ))
+        done
+        # Avoid bias towards words in the beginning of the list.
+        (( rnd < 16#7FFFFFFF / $#words * $#words )) || continue
+        print -rn -- -$words[rnd%$#words+1]
+        break
+      done
+    done
+    print
+  done
+} </dev/urandom
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/genpass/genpass.plugin.zsh
new file mode 100644 (file)
index 0000000..a0ea841
--- /dev/null
@@ -0,0 +1 @@
+autoload -Uz genpass-apple genpass-monkey genpass-xkcd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gh/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gh/README.md
new file mode 100644 (file)
index 0000000..54e046a
--- /dev/null
@@ -0,0 +1,23 @@
+# GitHub CLI plugin
+
+This plugin adds completion for the [GitHub CLI](https://cli.github.com/).
+
+To use it, add `gh` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... gh)
+```
+
+This plugin does not add any aliases.
+
+## Cache
+
+This plugin caches the completion script and is automatically updated when the
+plugin is loaded, which is usually when you start up a new terminal emulator.
+
+The cache is stored at:
+
+- `$ZSH/plugins/gh/_gh` completions script
+
+- `$ZSH_CACHE_DIR/gh_version` version of GitHub CLI, used to invalidate
+  the cache.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gh/gh.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gh/gh.plugin.zsh
new file mode 100644 (file)
index 0000000..1d8d84c
--- /dev/null
@@ -0,0 +1,14 @@
+# Autocompletion for the GitHub CLI (gh).
+if (( ! $+commands[gh] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `gh`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_gh" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _gh
+  _comps[gh]=_gh
+fi
+
+gh completion --shell zsh >| "$ZSH_CACHE_DIR/completions/_gh" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-auto-fetch/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-auto-fetch/README.md
new file mode 100644 (file)
index 0000000..e96ab42
--- /dev/null
@@ -0,0 +1,50 @@
+# Git auto-fetch
+
+Automatically fetches all changes from all remotes while you are working in a git-initialized directory.
+
+To use it, add `git-auto-fetch` to the plugins array in your zshrc file:
+
+```shell
+plugins=(... git-auto-fetch)
+```
+
+## Usage
+
+Every time the command prompt is shown all remotes will be fetched in the background. By default,
+`git-auto-fetch` will be triggered only if the last auto-fetch was done at least 60 seconds ago.
+You can change the fetch interval in your .zshrc:
+
+```sh
+GIT_AUTO_FETCH_INTERVAL=1200 # in seconds
+```
+
+A log of `git fetch --all` will be saved in `.git/FETCH_LOG`.
+
+## Toggle auto-fetch per folder
+
+If you are using a mobile connection or for any other reason you can disable git-auto-fetch
+for any folder:
+
+```shell
+$ cd to/your/project
+$ git-auto-fetch
+disabled
+$ git-auto-fetch
+enabled
+```
+
+## Caveats
+
+Automatically fetching all changes defeats the purpose of `git push --force-with-lease`,
+and makes it behave like `git push --force` in some cases. For example:
+
+Consider that you made some changes and possibly rebased some stuff, which means you'll
+need to use `--force-with-lease` to overwrite the remote history of a branch. Between the
+time when you make the changes (maybe do a `git log`) and the time when you `git push`,
+it's possible that someone else updates the branch you're working on.
+
+If `git-auto-fetch` triggers then, you'll have fetched the remote changes without knowing
+it, and even though you're running the push with `--force-with-lease`, git will overwrite
+the recent changes because you already have them in your local repository. The
+[`git push --force-with-lease` docs](https://git-scm.com/docs/git-push) talk about possible
+solutions to this problem.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh
new file mode 100644 (file)
index 0000000..2df34bb
--- /dev/null
@@ -0,0 +1,65 @@
+# Default auto-fetch interval: 60 seconds
+: ${GIT_AUTO_FETCH_INTERVAL:=60}
+
+# Necessary for the git-fetch-all function
+zmodload zsh/datetime
+zmodload -F zsh/stat b:zstat  # only zstat command, not stat command
+
+function git-fetch-all {
+  (
+    # Get git root directory
+    if ! gitdir="$(command git rev-parse --git-dir 2>/dev/null)"; then
+      return 0
+    fi
+
+    # Do nothing if auto-fetch is disabled or don't have permissions
+    if [[ ! -w "$gitdir" || -f "$gitdir/NO_AUTO_FETCH" ]] ||
+       [[ -f "$gitdir/FETCH_LOG" && ! -w "$gitdir/FETCH_LOG" ]]; then
+      return 0
+    fi
+
+    # Get time (seconds) when auto-fetch was last run
+    lastrun="$(zstat +mtime "$gitdir/FETCH_LOG" 2>/dev/null || echo 0)"
+    # Do nothing if not enough time has passed since last auto-fetch
+    if (( EPOCHSECONDS - lastrun < $GIT_AUTO_FETCH_INTERVAL )); then
+      return 0
+    fi
+
+    # Fetch all remotes (avoid ssh passphrase prompt)
+    date -R &>! "$gitdir/FETCH_LOG"
+    GIT_SSH_COMMAND="command ssh -o BatchMode=yes" \
+    GIT_TERMINAL_PROMPT=0 \
+      command git fetch --all 2>/dev/null &>> "$gitdir/FETCH_LOG"
+  ) &|
+}
+
+function git-auto-fetch {
+  # Do nothing if not in a git repository
+  command git rev-parse --is-inside-work-tree &>/dev/null || return 0
+
+  # Remove or create guard file depending on its existence
+  local guard="$(command git rev-parse --git-dir)/NO_AUTO_FETCH"
+  if [[ -f "$guard" ]]; then
+    command rm "$guard" && echo "${fg_bold[green]}enabled${reset_color}"
+  else
+    command touch "$guard" && echo "${fg_bold[red]}disabled${reset_color}"
+  fi
+}
+
+# zle-line-init widget (don't redefine if already defined)
+(( ! ${+functions[_git-auto-fetch_zle-line-init]} )) || return 0
+
+case "$widgets[zle-line-init]" in
+  # Simply define the function if zle-line-init doesn't yet exist
+  builtin|"") function _git-auto-fetch_zle-line-init() {
+      git-fetch-all
+    } ;;
+  # Override the current zle-line-init widget, calling the old one
+  user:*) zle -N _git-auto-fetch_orig_zle-line-init "${widgets[zle-line-init]#user:}"
+    function _git-auto-fetch_zle-line-init() {
+      git-fetch-all
+      zle _git-auto-fetch_orig_zle-line-init -- "$@"
+    } ;;
+esac
+
+zle -N zle-line-init _git-auto-fetch_zle-line-init
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/README.md
new file mode 100644 (file)
index 0000000..7fefed3
--- /dev/null
@@ -0,0 +1,16 @@
+# Git Escape Magic
+
+This plugin is copied from the original at
+https://github.com/knu/zsh-git-escape-magic. All credit for the
+functionality enabled by this plugin should go to @knu.
+
+An excerpt from that project's readme explains its purpose.
+
+> It eliminates the need for manually escaping those meta-characters. The zle function it provides is context aware and recognizes the characteristics of each subcommand of git. Every time you type one of these meta-characters on a git command line, it automatically escapes the meta-character with a backslash as necessary and as appropriate.
+
+## Usage
+
+To use this plugin, add it to your list of plugins in your `.zshrc` file.
+
+**NOTE**: If you use url-quote-magic, it must be included before this
+plugin runs to prevent any conflicts.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/git-escape-magic b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/git-escape-magic
new file mode 100644 (file)
index 0000000..94a8d7b
--- /dev/null
@@ -0,0 +1,135 @@
+# -*- mode: sh -*-
+#
+# git-escape-magic - zle tweak for git command line arguments
+#
+# Copyright (c) 2011, 2012, 2014 Akinori MUSHA
+# Licensed under the 2-clause BSD license.
+#
+# This tweak eliminates the need for manually escaping shell
+# meta-characters such as [~^{}] that are used for specifying a git
+# object (commit or tree).  Every time you type one of these
+# characters on a git command line, it is automatically escaped with a
+# backslash as necessary and as appropriate.
+#
+# If you want to use this with url-quote-magic, make sure to enable it
+# first.
+#
+# Usage:
+#     autoload -Uz git-escape-magic
+#     git-escape-magic
+#
+
+git-escape-magic.self-insert() {
+    emulate -L zsh
+    setopt extendedglob
+    local self_insert_function
+    zstyle -s ':git-escape-magic' self-insert-function self_insert_function
+
+    if [[ "$KEYS" == [{}~^]* ]] && {
+        local qkey="${(q)KEYS}"
+        [[ "$KEYS" != "$qkey" ]]
+    } && {
+        local lbuf="$LBUFFER$qkey"
+        [[ "${(Q)LBUFFER}$KEYS" == "${(Q)lbuf}" ]]
+    } && {
+        local -a words
+        words=("${(@Q)${(z)lbuf}}")
+        [[ "$words[(i)(*/|)git(|-[^/]##)]" -le $#words ]]
+    }
+    then
+        local i
+        i="$words[(I)([;(){\&]|\&[\&\!]|\|\||[=<>]\(*)]"
+        if [[ $i -gt 0 ]]; then
+            shift $((i-1)) words
+            if [[ "$words[1]" == [\=\<\>]\(* ]]; then
+                words[1]="${words[1]#[=<>]\(}"
+            else
+                [[ "$words[1]" == \; && $words[2] == (then|else|elif|do) ]] && shift words
+                shift words
+            fi
+        fi
+        while [[ "$words[1]" == (if|while|until|\!) ]]; do
+            shift words
+        done
+        while [[ "$words[1]" == [A-Za-z_][A-Za-z0-9_]#=* ]]; do
+            shift words
+        done
+        [[ "$words[1]" == (*/|)git(|-[^/]##) ]] && {
+            local subcommand
+            subcommand="${words[1]##*/git-}"
+            if [[ -z "$subcommand" ]]; then
+                shift words
+                subcommand="$words[1]"
+            fi
+            [[ $#words -ge 2 ]]
+        } &&
+        case "$subcommand" in
+            # commands that may take pathspec but never take refspec with [{}~^]
+            (add|rm|am|apply|check-attr|checkout-index|clean|clone|config|diff-files|hash-object|help|index-pack|mailinfo|mailsplit|merge-file|merge-index|mergetool|mktag|mv|pack-objects|pack-redundant|relink|send-email|show-index|show-ref|stage|status|verify-pack)
+                false ;;
+            # commands that may take pathspec but rarely take refspec with [{}~^]
+            (for-each-ref|grep|ls-files|update-index)
+                false ;;
+            (archive|ls-tree)
+                ! [[ $#words -ge 3 &&
+                        "$words[-2]" == [^-]* ]] ;;
+            (diff-tree)
+                ! [[ $#words -ge 4 &&
+                        "$words[-2]" == [^-]* &&
+                        "$words[-3]" == [^-]* ]] ;;
+            (*)
+                [[ $words[(i)--] -gt $#words ]] ;;
+        esac &&
+        case "${words[-1]%%"$KEYS"}" in
+            (*[@^])
+                [[ "$KEYS" == [{~^]* ]] ;;
+            (*[@^]\{[^}]##)
+                [[ "$KEYS" == \}* ]] ;;
+            (?*)
+                [[ "$KEYS" == [~^]* ]] ;;
+            (*)
+                false ;;
+        esac &&
+        LBUFFER="$LBUFFER\\"
+    fi
+
+    zle "$self_insert_function"
+}
+
+git-escape-magic.on() {
+    emulate -L zsh
+    local self_insert_function="${$(zle -lL | awk \
+        '$1=="zle"&&$2=="-N"&&$3=="self-insert"{print $4;exit}'):-.self-insert}"
+
+    [[ "$self_insert_function" == git-escape-magic.self-insert ]] &&
+        return 0
+
+    # For url-quote-magic which does not zle -N itself
+    zle -la "$self_insert_function" || zle -N "$self_insert_function"
+
+    zstyle ':git-escape-magic' self-insert-function "$self_insert_function"
+
+    zle -A git-escape-magic.self-insert self-insert
+    return 0
+}
+
+git-escape-magic.off() {
+    emulate -L zsh
+    local self_insert_function
+    zstyle -s ':git-escape-magic' self-insert-function self_insert_function
+
+    [[ -n "$self_insert_function" ]] &&
+        zle -A "$self_insert_function" self-insert
+    return 0
+}
+
+zle -N git-escape-magic.self-insert
+zle -N git-escape-magic.on
+zle -N git-escape-magic.off
+
+git-escape-magic() {
+        git-escape-magic.on
+}
+
+[[ -o kshautoload ]] || git-escape-magic "$@"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/git-escape-magic.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-escape-magic/git-escape-magic.plugin.zsh
new file mode 100644 (file)
index 0000000..c021ea7
--- /dev/null
@@ -0,0 +1,9 @@
+# Automatically detect and escape zsh globbing meta-characters when used with
+# git refspec characters like `[^~{}]`. NOTE: This must be loaded _after_
+# url-quote-magic.
+#
+# This trick is detailed at https://github.com/knu/zsh-git-escape-magic and is
+# what allowed this plugin to exist.
+
+autoload -Uz git-escape-magic
+git-escape-magic
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-extras/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-extras/README.md
new file mode 100644 (file)
index 0000000..2adc9d4
--- /dev/null
@@ -0,0 +1,17 @@
+# git-extras
+
+This plugin provides completion definitions for some of the commands defined by [git-extras](https://github.com/tj/git-extras).
+
+To use it, add `git-extras` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git-extras)
+```
+
+## Setup notes
+
+The completions work by augmenting the `_git` completion provided by `zsh`. This only works with the `zsh`-provided `_git`, not the `_git` provided by `git` itself. If you have both `zsh` and `git` installed, you need to make sure that the `zsh`-provided `_git` takes precedence.
+
+### OS X Homebrew Setup
+
+**NOTE:** this no longer works on current Homebrew distributions of git. ~~On OS X with Homebrew, you need to install `git` with `brew install git --without-completions`. Otherwise, `git`'s `_git` will take precedence, and you won't see the completions for `git-extras` commands.~~
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-extras/git-extras.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-extras/git-extras.plugin.zsh
new file mode 100644 (file)
index 0000000..b86d7c5
--- /dev/null
@@ -0,0 +1,498 @@
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for git-extras (https://github.com/tj/git-extras).
+#
+#  This depends on and reuses some of the internals of the _git completion
+#  function that ships with zsh itself. It will not work with the _git that ships
+#  with git.
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Alexis GRIMALDI (https://github.com/agrimaldi)
+#  * spacewander (https://github.com/spacewander)
+#
+# ------------------------------------------------------------------------------
+# Inspirations
+# -----------
+#
+#  * git-extras (https://github.com/tj/git-extras)
+#  * git-flow-completion (https://github.com/bobthecow/git-flow-completion)
+#
+# ------------------------------------------------------------------------------
+
+
+# Internal functions
+# These are a lot like their __git_* equivalents inside _git
+
+__gitex_command_successful () {
+  if (( ${#*:#0} > 0 )); then
+    _message 'not a git repository'
+    return 1
+  fi
+  return 0
+}
+
+__gitex_commits() {
+    declare -A commits
+    git log --oneline -15 | sed 's/\([[:alnum:]]\{7\}\) /\1:/' | while read commit
+    do
+        hash=$(echo $commit | cut -d':' -f1)
+        commits[$hash]="$commit"
+    done
+    local ret=1
+    _describe -t commits commit commits && ret=0
+}
+
+__gitex_remote_names() {
+    local expl
+    declare -a remote_names
+    remote_names=(${(f)"$(_call_program remotes git remote 2>/dev/null)"})
+    __git_command_successful || return
+    _wanted remote-names expl remote-name compadd $* - $remote_names
+}
+
+__gitex_tag_names() {
+    local expl
+    declare -a tag_names
+    tag_names=(${${(f)"$(_call_program tags git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/})
+    __git_command_successful || return
+    _wanted tag-names expl tag-name compadd $* - $tag_names
+}
+
+
+__gitex_branch_names() {
+    local expl
+    declare -a branch_names
+    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
+    __git_command_successful || return
+    _wanted branch-names expl branch-name compadd $* - $branch_names
+}
+
+__gitex_specific_branch_names() {
+    local expl
+    declare -a branch_names
+    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/"$1" 2>/dev/null)"}#refs/heads/$1/})
+    __git_command_successful || return
+    _wanted branch-names expl branch-name compadd - $branch_names
+}
+
+__gitex_chore_branch_names() {
+    __gitex_specific_branch_names 'chore'
+}
+
+__gitex_feature_branch_names() {
+    __gitex_specific_branch_names 'feature'
+}
+
+__gitex_refactor_branch_names() {
+    __gitex_specific_branch_names 'refactor'
+}
+
+__gitex_bug_branch_names() {
+    __gitex_specific_branch_names 'bug'
+}
+
+__gitex_submodule_names() {
+    local expl
+    declare -a submodule_names
+    submodule_names=(${(f)"$(_call_program branchrefs git submodule status | awk '{print $2}')"})  # '
+    __git_command_successful || return
+    _wanted submodule-names expl submodule-name compadd $* - $submodule_names
+}
+
+
+__gitex_author_names() {
+    local expl
+    declare -a author_names
+    author_names=(${(f)"$(_call_program branchrefs git log --format='%aN' | sort -u)"})
+    __git_command_successful || return
+    _wanted author-names expl author-name compadd $* - $author_names
+}
+
+# subcommands
+_git-authors() {
+    _arguments  -C \
+        '(--list -l)'{--list,-l}'[show authors]' \
+        '--no-email[without email]' \
+}
+
+_git-bug() {
+    local curcontext=$curcontext state line ret=1
+    declare -A opt_args
+
+    _arguments -C \
+        ': :->command' \
+        '*:: :->option-or-argument' && ret=0
+
+    case $state in
+        (command)
+            declare -a commands
+            commands=(
+                'finish:merge bug into the current branch'
+            )
+            _describe -t commands command commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*}-$line[1]:
+            case $line[1] in
+                (finish)
+                    _arguments -C \
+                        ':branch-name:__gitex_bug_branch_names'
+                    ;;
+                -r|--remote )
+                    _arguments -C \
+                        ':remote-name:__gitex_remote_names'
+                    ;;
+            esac
+            return 0
+    esac
+
+    _arguments \
+        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
+}
+
+
+_git-changelog() {
+    _arguments \
+        '(-l --list)'{-l,--list}'[list commits]' \
+}
+
+_git-chore() {
+    local curcontext=$curcontext state line ret=1
+    declare -A opt_args
+
+    _arguments -C \
+        ': :->command' \
+        '*:: :->option-or-argument' && ret=0
+
+    case $state in
+        (command)
+            declare -a commands
+            commands=(
+                'finish:merge and delete the chore branch'
+            )
+            _describe -t commands command commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*}-$line[1]:
+            case $line[1] in
+                (finish)
+                    _arguments -C \
+                        ':branch-name:__gitex_chore_branch_names'
+                    ;;
+                -r|--remote )
+                    _arguments -C \
+                        ':remote-name:__gitex_remote_names'
+                    ;;
+            esac
+            return 0
+    esac
+
+    _arguments \
+        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
+}
+
+
+_git-contrib() {
+    _arguments \
+        ':author:__gitex_author_names'
+}
+
+
+_git-count() {
+    _arguments \
+        '--all[detailed commit count]'
+}
+
+_git-create-branch() {
+    local curcontext=$curcontext state line
+    _arguments -C \
+        ': :->command' \
+        '*:: :->option-or-argument'
+
+    case "$state" in
+        (command)
+            _arguments \
+                '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*}-$line[1]:
+            case $line[1] in
+                -r|--remote )
+                    _arguments -C \
+                        ':remote-name:__gitex_remote_names'
+                    ;;
+            esac
+    esac
+}
+
+_git-delete-branch() {
+    _arguments \
+        ':branch-name:__gitex_branch_names'
+}
+
+
+_git-delete-submodule() {
+    _arguments \
+        ':submodule-name:__gitex_submodule_names'
+}
+
+
+_git-delete-tag() {
+    _arguments \
+        ':tag-name:__gitex_tag_names'
+}
+
+
+_git-effort() {
+    _arguments \
+        '--above[ignore file with less than x commits]'
+}
+
+
+_git-extras() {
+    local curcontext=$curcontext state line ret=1
+    declare -A opt_args
+
+    _arguments -C \
+        ': :->command' \
+        '*:: :->option-or-argument' && ret=0
+
+    case $state in
+        (command)
+            declare -a commands
+            commands=(
+                'update:update git-extras'
+            )
+            _describe -t commands command commands && ret=0
+            ;;
+    esac
+
+    _arguments \
+        '(-v --version)'{-v,--version}'[show current version]'
+}
+
+
+_git-feature() {
+    local curcontext=$curcontext state line ret=1
+    declare -A opt_args
+
+    _arguments -C \
+        ': :->command' \
+        '*:: :->option-or-argument' && ret=0
+
+    case $state in
+        (command)
+            declare -a commands
+            commands=(
+                'finish:merge feature into the current branch'
+            )
+            _describe -t commands command commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*}-$line[1]:
+            case $line[1] in
+                (finish)
+                    _arguments -C \
+                        ':branch-name:__gitex_feature_branch_names'
+                    ;;
+                -r|--remote )
+                    _arguments -C \
+                        ':remote-name:__gitex_remote_names'
+                    ;;
+            esac
+            return 0
+    esac
+
+    _arguments \
+        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
+}
+
+_git-graft() {
+    _arguments \
+        ':src-branch-name:__gitex_branch_names' \
+        ':dest-branch-name:__gitex_branch_names'
+}
+
+_git-guilt() {
+    _arguments -C \
+        '(--email -e)'{--email,-e}'[display author emails instead of names]' \
+        '(--ignore-whitespace -w)'{--ignore-whitespace,-w}'[ignore whitespace only changes]' \
+        '(--debug -d)'{--debug,-d}'[output debug information]' \
+        '-h[output usage information]'
+}
+
+_git-ignore() {
+    _arguments  -C \
+        '(--local -l)'{--local,-l}'[show local gitignore]' \
+        '(--global -g)'{--global,-g}'[show global gitignore]' \
+        '(--private -p)'{--private,-p}'[show repo gitignore]'
+}
+
+
+_git-ignore() {
+    _arguments  -C \
+        '(--append -a)'{--append,-a}'[append .gitignore]' \
+        '(--replace -r)'{--replace,-r}'[replace .gitignore]' \
+        '(--list-in-table -l)'{--list-in-table,-l}'[print available types in table format]' \
+        '(--list-alphabetically -L)'{--list-alphabetically,-L}'[print available types in alphabetical order]' \
+        '(--search -s)'{--search,-s}'[search word in available types]'
+}
+
+
+_git-merge-into() {
+    _arguments '--ff-only[merge only fast-forward]'
+    _arguments \
+        ':src:__gitex_branch_names' \
+        ':dest:__gitex_branch_names'
+}
+
+_git-missing() {
+    _arguments \
+        ':first-branch-name:__gitex_branch_names' \
+        ':second-branch-name:__gitex_branch_names'
+}
+
+
+_git-refactor() {
+    local curcontext=$curcontext state line ret=1
+    declare -A opt_args
+
+    _arguments -C \
+        ': :->command' \
+        '*:: :->option-or-argument' && ret=0
+
+    case $state in
+        (command)
+            declare -a commands
+            commands=(
+                'finish:merge refactor into the current branch'
+            )
+            _describe -t commands command commands && ret=0
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*}-$line[1]:
+            case $line[1] in
+                (finish)
+                    _arguments -C \
+                        ':branch-name:__gitex_refactor_branch_names'
+                    ;;
+                -r|--remote )
+                    _arguments -C \
+                        ':remote-name:__gitex_remote_names'
+                    ;;
+            esac
+            return 0
+    esac
+
+    _arguments \
+        '(--remote -r)'{--remote,-r}'[setup remote tracking branch]'
+}
+
+
+_git-squash() {
+    _arguments \
+        ':branch-name:__gitex_branch_names'
+}
+
+_git-stamp() {
+    _arguments  -C \
+         '(--replace -r)'{--replace,-r}'[replace stamps with same id]'
+}
+
+_git-standup() {
+    _arguments -C \
+        '-a[Specify the author of commits. Use "all" to specify all authors.]' \
+        '-d[Show history since N days ago]' \
+        '-D[Specify the date format displayed in commit history]' \
+        '-f[Fetch commits before showing history]' \
+        '-g[Display GPG signed info]' \
+        '-h[Display help message]' \
+        '-L[Enable the inclusion of symbolic links]' \
+        '-m[The depth of recursive directory search]'
+}
+
+_git-summary() {
+    _arguments '--line[summarize with lines rather than commits]'
+    __gitex_commits
+}
+
+
+_git-undo(){
+    _arguments  -C \
+        '(--soft -s)'{--soft,-s}'[only rolls back the commit but changes remain un-staged]' \
+        '(--hard -h)'{--hard,-h}'[wipes your commit(s)]'
+}
+
+zstyle -g existing_user_commands ':completion:*:*:git:*' user-commands
+
+zstyle ':completion:*:*:git:*' user-commands $existing_user_commands \
+    alias:'define, search and show aliases' \
+    archive-file:'export the current head of the git repository to an archive' \
+    authors:'generate authors report' \
+    back:'undo and stage latest commits' \
+    bug:'create bug branch' \
+    bulk:'run bulk commands' \
+    changelog:'generate a changelog report' \
+    chore:'create chore branch' \
+    clear-soft:'soft clean up a repository' \
+    clear:'rigorously clean up a repository' \
+    commits-since:'show commit logs since some date' \
+    contrib:'show user contributions' \
+    count:'show commit count' \
+    create-branch:'create branches' \
+    delete-branch:'delete branches' \
+    delete-merged-branches:'delete merged branches' \
+    delete-submodule:'delete submodules' \
+    delete-tag:'delete tags' \
+    delta:'lists changed files' \
+    effort:'show effort statistics on file(s)' \
+    extras:'awesome git utilities' \
+    feature:'create/merge feature branch' \
+    force-clone:'overwrite local repositories with clone' \
+    fork:'fork a repo on GitHub' \
+    fresh-branch:'create fresh branches' \
+    gh-pages:'create the GitHub pages branch' \
+    graft:'merge and destroy a given branch' \
+    guilt:'calculate change between two revisions' \
+    ignore-io:'get sample gitignore file' \
+    ignore:'add .gitignore patterns' \
+    info:'returns information on current repository' \
+    local-commits:'list local commits' \
+    lock:'lock a file excluded from version control' \
+    locked:'ls files that have been locked' \
+    merge-into:'merge one branch into another' \
+    merge-repo:'merge two repo histories' \
+    missing:'show commits missing from another branch' \
+    mr:'checks out a merge request locally' \
+    obliterate:'rewrite past commits to remove some files' \
+    pr:'checks out a pull request locally' \
+    psykorebase:'rebase a branch with a merge commit' \
+    pull-request:'create pull request to GitHub project' \
+    reauthor:'replace the author and/or committer identities in commits and tags' \
+    rebase-patch:'rebases a patch' \
+    refactor:'create refactor branch' \
+    release:'commit, tag and push changes to the repository' \
+    rename-branch:'rename a branch' \
+    rename-tag:'rename a tag' \
+    repl:'git read-eval-print-loop' \
+    reset-file:'reset one file' \
+    root:'show path of root' \
+    scp:'copy files to ssh compatible `git-remote`' \
+    sed:'replace patterns in git-controlled files' \
+    setup:'set up a git repository' \
+    show-merged-branches:'show merged branches' \
+    show-tree:'show branch tree of commit history' \
+    show-unmerged-branches:'show unmerged branches' \
+    squash:'import changes from a branch' \
+    stamp:'stamp the last commit message' \
+    standup:'recall the commit history' \
+    summary:'show repository summary' \
+    sync:'sync local branch with remote branch' \
+    touch:'touch and add file to the index' \
+    undo:'remove latest commits' \
+    unlock:'unlock a file excluded from version control'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow-avh/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow-avh/README.md
new file mode 100644 (file)
index 0000000..0768d93
--- /dev/null
@@ -0,0 +1,19 @@
+# git-flow (AVH Edition) plugin
+
+This plugin adds completion for the [git-flow (AVH Edition)](https://github.com/petervanderdoes/gitflow-avh).
+The AVH Edition of the git extensions that provides high-level repository operations for [Vincent Driessen's branching model](https://nvie.com/posts/a-successful-git-branching-model/).
+
+To use it, add `git-flow-avh` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git-flow-avh)
+```
+
+## Requirements
+
+1. The git-flow tool has to be [installed](https://github.com/petervanderdoes/gitflow-avh#installing-git-flow)
+   separately.
+
+2. You have to use zsh's git completion instead of the git project's git completion. This is typically
+   done by default so you don't need to do anything else. If you installed git with Homebrew you
+   might have to uninstall the git completion it's bundled with.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow-avh/git-flow-avh.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow-avh/git-flow-avh.plugin.zsh
new file mode 100644 (file)
index 0000000..860ca55
--- /dev/null
@@ -0,0 +1,526 @@
+_git-flow ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'init:Initialize a new git repo with support for the branching model.'
+                'feature:Manage your feature branches.'
+                'bugfix:Manage your bugfix branches.'
+                'config:Manage your configuration.'
+                'release:Manage your release branches.'
+                'hotfix:Manage your hotfix branches.'
+                'support:Manage your support branches.'
+                'version:Shows version information.'
+                'finish:Finish the branch you are currently on.'
+                'delete:Delete the branch you are currently on.'
+                'publish:Publish the branch you are currently on.'
+                'rebase:Rebase the branch you are currently on.'
+            )
+            _describe -t commands 'git flow' subcommands
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (init)
+                    _arguments \
+                        -f'[Force setting of gitflow branches, even if already configured]'
+                    ;;
+
+                    (version)
+                    ;;
+
+                    (hotfix)
+                        __git-flow-hotfix
+                    ;;
+
+                    (release)
+                        __git-flow-release
+                    ;;
+
+                    (feature)
+                        __git-flow-feature
+                    ;;
+                    (bugfix)
+                        __git-flow-bugfix
+                    ;;
+
+                    (config)
+                    __git-flow-config
+                    ;;
+
+            esac
+        ;;
+    esac
+}
+
+__git-flow-release ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'start:Start a new release branch.'
+                'finish:Finish a release branch.'
+                'list:List all your release branches. (Alias to `git flow release`)'
+                'publish:Publish release branch to remote.'
+                'track:Checkout remote release branch.'
+                'rebase:Rebase from integration branch.'
+                'delete:Delete a release branch.'
+            )
+            _describe -t commands 'git flow release' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':version:__git_flow_version_list'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -s'[Sign the release tag cryptographically]'\
+                        -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+                        -m'[Use the given tag message]'\
+                        -p'[Push to $ORIGIN after performing finish]'\
+                        ':version:__git_flow_version_list'
+                ;;
+
+                (delete)
+                    _arguments \
+                        -f'[Force deletion]' \
+                        -r'[Delete remote branch]' \
+                        ':version:__git_flow_version_list'
+                ;;
+
+                (publish)
+                    _arguments \
+                        ':version:__git_flow_version_list'
+                ;;
+
+                (track)
+                    _arguments \
+                        ':version:__git_flow_version_list'
+                ;;
+
+                (rebase)
+                    _arguments \
+                        -i'[Do an interactive rebase]' \
+                        ':branch:__git_branch_names'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-flow-hotfix ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'start:Start a new hotfix branch.'
+                'finish:Finish a hotfix branch.'
+                'delete:Delete a hotfix branch.'
+                'rebase:Rebase from integration branch.'
+                'list:List all your hotfix branches. (Alias to `git flow hotfix`)'
+                'rename:Rename a hotfix branch.'
+            )
+            _describe -t commands 'git flow hotfix' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':hotfix:__git_flow_version_list'\
+                        ':branch-name:__git_branch_names'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -s'[Sign the release tag cryptographically]'\
+                        -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+                        -m'[Use the given tag message]'\
+                        -p'[Push to $ORIGIN after performing finish]'\
+                        ':hotfix:__git_flow_hotfix_list'
+                ;;
+
+                (delete)
+                    _arguments \
+                        -f'[Force deletion]' \
+                        -r'[Delete remote branch]' \
+                        ':hotfix:__git_flow_hotfix_list'
+                ;;
+
+                (rebase)
+                    _arguments \
+                        -i'[Do an interactive rebase]' \
+                        ':branch:__git_branch_names'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-flow-feature ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'start:Start a new feature branch.'
+                'finish:Finish a feature branch.'
+                'delete:Delete a feature branch.'
+                'list:List all your feature branches. (Alias to `git flow feature`)'
+                'publish:Publish feature branch to remote.'
+                'track:Checkout remote feature branch.'
+                'diff:Show all changes.'
+                'rebase:Rebase from integration branch.'
+                'checkout:Checkout local feature branch.'
+                'pull:Pull changes from remote.'
+                'rename:Rename a feature branch.'
+            )
+            _describe -t commands 'git flow feature' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':feature:__git_flow_feature_list'\
+                        ':branch-name:__git_branch_names'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -r'[Rebase instead of merge]'\
+                        ':feature:__git_flow_feature_list'
+                ;;
+
+                (delete)
+                    _arguments \
+                        -f'[Force deletion]' \
+                        -r'[Delete remote branch]' \
+                        ':feature:__git_flow_feature_list'
+                ;;
+
+                (publish)
+                    _arguments \
+                        ':feature:__git_flow_feature_list'\
+                ;;
+
+                (track)
+                    _arguments \
+                        ':feature:__git_flow_feature_list'\
+                ;;
+
+                (diff)
+                    _arguments \
+                        ':branch:__git_branch_names'\
+                ;;
+
+                (rebase)
+                    _arguments \
+                        -i'[Do an interactive rebase]' \
+                        ':branch:__git_branch_names'
+                ;;
+
+                (checkout)
+                    _arguments \
+                        ':branch:__git_flow_feature_list'\
+                ;;
+
+                (pull)
+                    _arguments \
+                        ':remote:__git_remotes'\
+                        ':branch:__git_branch_names'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-flow-bugfix ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'start:Start a new bugfix branch.'
+                'finish:Finish a bugfix branch.'
+                'delete:Delete a bugfix branch.'
+                'list:List all your bugfix branches. (Alias to `git flow bugfix`)'
+                'publish:Publish bugfix branch to remote.'
+                'track:Checkout remote bugfix branch.'
+                'diff:Show all changes.'
+                'rebase:Rebase from integration branch.'
+                'checkout:Checkout local bugfix branch.'
+                'pull:Pull changes from remote.'
+                'rename:Rename a bugfix branch.'
+            )
+            _describe -t commands 'git flow bugfix' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':bugfix:__git_flow_bugfix_list'\
+                        ':branch-name:__git_branch_names'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -r'[Rebase instead of merge]'\
+                        ':bugfix:__git_flow_bugfix_list'
+                ;;
+
+                (delete)
+                    _arguments \
+                        -f'[Force deletion]' \
+                        -r'[Delete remote branch]' \
+                        ':bugfix:__git_flow_bugfix_list'
+                ;;
+
+                (publish)
+                    _arguments \
+                        ':bugfix:__git_flow_bugfix_list'\
+                ;;
+
+                (track)
+                    _arguments \
+                        ':bugfix:__git_flow_bugfix_list'\
+                ;;
+
+                (diff)
+                    _arguments \
+                        ':branch:__git_branch_names'\
+                ;;
+
+                (rebase)
+                    _arguments \
+                        -i'[Do an interactive rebase]' \
+                        ':branch:__git_branch_names'
+                ;;
+
+                (checkout)
+                    _arguments \
+                        ':branch:__git_flow_bugfix_list'\
+                ;;
+
+                (pull)
+                    _arguments \
+                        ':remote:__git_remotes'\
+                        ':branch:__git_branch_names'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-flow-config ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'list:List the configuration. (Alias to `git flow config`)'
+                'set:Set the configuration option'
+            )
+            _describe -t commands 'git flow config' subcommands
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (set)
+                    _arguments \
+                        --local'[Use repository config file]' \
+                        --global'[Use global config file]'\
+                        --system'[Use system config file]'\
+                        --file'[Use given config file]'\
+                        ':option:(master develop feature hotfix release support versiontagprefix)'
+                ;;
+
+                *)
+                    _arguments \
+                        --local'[Use repository config file]' \
+                        --global'[Use global config file]'\
+                        --system'[Use system config file]'\
+                        --file'[Use given config file]'
+                ;;
+            esac
+        ;;
+    esac
+}
+__git_flow_version_list ()
+{
+    local expl
+    declare -a versions
+
+    versions=(${${(f)"$(_call_program versions git flow release list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted versions expl 'version' compadd $versions
+}
+
+__git_flow_feature_list ()
+{
+    local expl
+    declare -a features
+
+    features=(${${(f)"$(_call_program features git flow feature list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted features expl 'feature' compadd $features
+}
+
+__git_flow_bugfix_list ()
+{
+    local expl
+    declare -a bugfixes
+
+    bugfixes=(${${(f)"$(_call_program bugfixes git flow bugfix list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted bugfixes expl 'bugfix' compadd $bugfixes
+}
+
+__git_remotes () {
+    local expl gitdir remotes
+
+    gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
+    __git_command_successful || return
+
+    remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
+    __git_command_successful || return
+
+    # TODO: Should combine the two instead of either or.
+    if (( $#remotes > 0 )); then
+        _wanted remotes expl remote compadd $* - $remotes
+    else
+        _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
+    fi
+}
+
+__git_flow_hotfix_list ()
+{
+    local expl
+    declare -a hotfixes
+
+    hotfixes=(${${(f)"$(_call_program hotfixes git flow hotfix list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted hotfixes expl 'hotfix' compadd $hotfixes
+}
+
+__git_branch_names () {
+    local expl
+    declare -a branch_names
+
+    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
+    __git_command_successful || return
+
+    _wanted branch-names expl branch-name compadd $* - $branch_names
+}
+
+__git_command_successful () {
+    if (( ${#pipestatus:#0} > 0 )); then
+        _message 'not a git repository'
+        return 1
+    fi
+    return 0
+}
+
+zstyle ':completion:*:*:git:*' user-commands flow:'provide high-level repository operations'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/README.md
new file mode 100644 (file)
index 0000000..fc8ccf0
--- /dev/null
@@ -0,0 +1,40 @@
+# Git-Flow plugin
+
+This plugin adds completion and aliases for the [`git-flow` command](https://github.com/nvie/gitflow).
+
+To use it, add `git-flow` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git-flow)
+```
+
+## Aliases
+
+| Alias     | Command                                   | Description                                    |
+| --------- | ----------------------------------------- | ---------------------------------------------- |
+| `gcd`     | `git checkout develop`                    | Check out develop branch                       |
+| `gch`     | `git checkout hotfix`                     | Check out hotfix branch                        |
+| `gcr`     | `git checkout release`                    | Check out release branch                       |
+| `gfl`     | `git flow`                                | Git-Flow command                               |
+| `gflf`    | `git flow feature`                        | List existing feature branches                 |
+| `gflff`   | `git flow feature finish`                 | Finish feature: `gflff <name>`                 |
+| `gflffc`  | `gflff ${$(git_current_branch)#feature/}` | Finish current feature                         |
+| `gflfp`   | `git flow feature publish`                | Publish feature: `gflfp <name>`                |
+| `gflfpc`  | `gflfp ${$(git_current_branch)#feature/}` | Publish current feature                        |
+| `gflfpll` | `git flow feature pull`                   | Pull remote feature: `gflfpll <remote> <name>` |
+| `gflfs`   | `git flow feature start`                  | Start a new feature: `gflfs <name>`            |
+| `gflh`    | `git flow hotfix`                         | List existing hotfix branches                  |
+| `gflhf`   | `git flow hotfix finish`                  | Finish hotfix: `gflhf <version>`               |
+| `gflhfc`  | `gflhf ${$(git_current_branch)#hotfix/}`  | Finish current hotfix                          |
+| `gflhp`   | `git flow hotfix publish`                 | Publish hostfix: `gflhp <version>`             |
+| `gflhpc`  | `gflhp ${$(git_current_branch)#hotfix/}`  | Finish current hotfix                          |
+| `gflhs`   | `git flow hotfix start`                   | Start a new hotfix: `gflhs <version>`          |
+| `gfli`    | `git flow init`                           | Initialize git-flow repository                 |
+| `gflr`    | `git flow release`                        | List existing release branches                 |
+| `gflrf`   | `git flow release finish`                 | Finish release: `gflrf <version>`              |
+| `gflrfc`  | `gflrf ${$(git_current_branch)#release/}` | Finish current release                         |
+| `gflrp`   | `git flow release publish`                | Publish release: `gflrp <version>`             |
+| `gflrpc`  | `gflrp ${$(git_current_branch)#release/}` | Publish current release                        |
+| `gflrs`   | `git flow release start`                  | Start a new release: `gflrs <version>`         |
+
+[More information about `git-flow` commands](https://github.com/nvie/gitflow/wiki/Command-Line-Arguments).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/_git-flow b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/_git-flow
new file mode 100644 (file)
index 0000000..eab7127
--- /dev/null
@@ -0,0 +1,327 @@
+#compdef git-flow
+
+_git-flow () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'init:Initialize a new git repo with support for the branching model.'
+        'feature:Manage your feature branches.'
+        'release:Manage your release branches.'
+        'hotfix:Manage your hotfix branches.'
+        'support:Manage your support branches.'
+        'version:Shows version information.'
+      )
+      _describe -t commands 'git flow' subcommands
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (init)
+          _arguments \
+            -f'[Force setting of gitflow branches, even if already configured]'
+          ;;
+
+          (version)
+          ;;
+
+          (hotfix)
+            __git-flow-hotfix
+          ;;
+
+          (release)
+            __git-flow-release
+          ;;
+
+          (feature)
+            __git-flow-feature
+          ;;
+      esac
+    ;;
+  esac
+}
+
+__git-flow-release () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'start:Start a new release branch.'
+        'finish:Finish a release branch.'
+        'list:List all your release branches. (Alias to `git flow release`)'
+        'publish: public'
+        'track: track'
+      )
+      _describe -t commands 'git flow release' subcommands
+      _arguments \
+        -v'[Verbose (more) output]'
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (start)
+          _arguments \
+            -F'[Fetch from origin before performing finish]'\
+            ':version:__git_flow_version_list'
+        ;;
+
+        (finish)
+          _arguments \
+            -F'[Fetch from origin before performing finish]' \
+            -s'[Sign the release tag cryptographically]'\
+            -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+            -m'[Use the given tag message]'\
+            -p'[Push to $ORIGIN after performing finish]'\
+            -k'[Keep branch after performing finish]'\
+            -n"[Don't tag this release]"\
+            ':version:__git_flow_version_list'
+        ;;
+
+        (publish)
+          _arguments \
+            ':version:__git_flow_version_list'\
+        ;;
+
+        (track)
+          _arguments \
+            ':version:__git_flow_version_list'\
+        ;;
+
+        *)
+          _arguments \
+            -v'[Verbose (more) output]'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+__git-flow-hotfix () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'start:Start a new hotfix branch.'
+        'finish:Finish a hotfix branch.'
+        'list:List all your hotfix branches. (Alias to `git flow hotfix`)'
+      )
+      _describe -t commands 'git flow hotfix' subcommands
+      _arguments \
+        -v'[Verbose (more) output]'
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (start)
+          _arguments \
+            -F'[Fetch from origin before performing finish]'\
+            ':hotfix:__git_flow_version_list'\
+            ':branch-name:__git_branch_names'
+        ;;
+
+        (finish)
+          _arguments \
+            -F'[Fetch from origin before performing finish]' \
+            -s'[Sign the release tag cryptographically]'\
+            -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+            -m'[Use the given tag message]'\
+            -p'[Push to $ORIGIN after performing finish]'\
+            -k'[Keep branch after performing finish]'\
+            -n"[Don't tag this release]"\
+            ':hotfix:__git_flow_hotfix_list'
+        ;;
+
+        *)
+          _arguments \
+            -v'[Verbose (more) output]'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+__git-flow-feature () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+  case $state in
+    (command)
+
+      local -a subcommands
+      subcommands=(
+        'start:Start a new feature branch.'
+        'finish:Finish a feature branch.'
+        'list:List all your feature branches. (Alias to `git flow feature`)'
+        'publish: publish'
+        'track: track'
+        'diff: diff'
+        'rebase: rebase'
+        'checkout: checkout'
+        'pull: pull'
+      )
+      _describe -t commands 'git flow feature' subcommands
+      _arguments \
+        -v'[Verbose (more) output]'
+    ;;
+
+    (options)
+      case $line[1] in
+
+        (start)
+          _arguments \
+            -F'[Fetch from origin before performing finish]'\
+            ':feature:__git_flow_feature_list'\
+            ':branch-name:__git_branch_names'
+        ;;
+
+        (finish)
+          _arguments \
+            -F'[Fetch from origin before performing finish]' \
+            -r'[Rebase instead of merge]'\
+            -k'[Keep branch after performing finish]'\
+            ':feature:__git_flow_feature_list'
+        ;;
+
+        (publish)
+          _arguments \
+            ':feature:__git_flow_feature_list'\
+        ;;
+
+        (track)
+          _arguments \
+            ':feature:__git_flow_feature_list'\
+        ;;
+
+        (diff)
+          _arguments \
+            ':branch:__git_flow_feature_list'\
+        ;;
+
+        (rebase)
+          _arguments \
+            -i'[Do an interactive rebase]' \
+            ':branch:__git_flow_feature_list'
+        ;;
+
+        (checkout)
+          _arguments \
+            ':branch:__git_flow_feature_list'\
+        ;;
+
+        (pull)
+          _arguments \
+            ':remote:__git_remotes'\
+            ':branch:__git_flow_feature_list'
+        ;;
+
+        *)
+          _arguments \
+            -v'[Verbose (more) output]'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+__git_flow_version_list () {
+  local expl
+  declare -a versions
+
+  versions=(${${(f)"$(_call_program versions git flow release list 2> /dev/null | tr -d ' |*')"}})
+  __git_command_successful || return
+
+  _wanted versions expl 'version' compadd $versions
+}
+
+__git_flow_feature_list () {
+  local expl
+  declare -a features
+
+  features=(${${(f)"$(_call_program features git flow feature list 2> /dev/null | tr -d ' |*')"}})
+  __git_command_successful || return
+
+  _wanted features expl 'feature' compadd $features
+}
+
+__git_remotes () {
+  local expl gitdir remotes
+
+  gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
+  __git_command_successful || return
+
+  remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
+  __git_command_successful || return
+
+  # TODO: Should combine the two instead of either or.
+  if (( $#remotes > 0 )); then
+    _wanted remotes expl remote compadd $* - $remotes
+  else
+    _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
+  fi
+}
+
+__git_flow_hotfix_list () {
+  local expl
+  declare -a hotfixes
+
+  hotfixes=(${${(f)"$(_call_program hotfixes git flow hotfix list 2> /dev/null | tr -d ' |*')"}})
+  __git_command_successful || return
+
+  _wanted hotfixes expl 'hotfix' compadd $hotfixes
+}
+
+__git_branch_names () {
+  local expl
+  declare -a branch_names
+
+  branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
+  __git_command_successful || return
+
+  _wanted branch-names expl branch-name compadd $* - $branch_names
+}
+
+__git_command_successful () {
+  if (( ${#pipestatus:#0} > 0 )); then
+    _message 'not a git repository'
+    return 1
+  fi
+  return 0
+}
+
+zstyle ':completion:*:*:git:*' user-commands flow:'description for foo'
+
+# Detect if script is sourced or called via autoload
+[[ "$ZSH_EVAL_CONTEXT" != *:file ]] || return
+
+_git-flow "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/git-flow.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-flow/git-flow.plugin.zsh
new file mode 100644 (file)
index 0000000..f842de9
--- /dev/null
@@ -0,0 +1,32 @@
+# Aliases
+alias gcd='git checkout $(git config gitflow.branch.develop)'
+alias gch='git checkout $(git config gitflow.prefix.hotfix)'
+alias gcr='git checkout $(git config gitflow.prefix.release)'
+alias gfl='git flow'
+alias gflf='git flow feature'
+alias gflff='git flow feature finish'
+alias gflffc='git flow feature finish ${$(git_current_branch)#feature/}'
+alias gflfp='git flow feature publish'
+alias gflfpc='git flow feature publish ${$(git_current_branch)#feature/}'
+alias gflfpll='git flow feature pull'
+alias gflfs='git flow feature start'
+alias gflh='git flow hotfix'
+alias gflhf='git flow hotfix finish'
+alias gflhfc='git flow hotfix finish ${$(git_current_branch)#hotfix/}'
+alias gflhp='git flow hotfix publish'
+alias gflhpc='git flow hotfix publish ${$(git_current_branch)#hotfix/}'
+alias gflhs='git flow hotfix start'
+alias gfli='git flow init'
+alias gflr='git flow release'
+alias gflrf='git flow release finish'
+alias gflrfc='git flow release finish ${$(git_current_branch)#release/}'
+alias gflrp='git flow release publish'
+alias gflrpc='git flow release publish ${$(git_current_branch)#release/}'
+alias gflrs='git flow release start'
+
+# Source completion script
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+source "${0:A:h}/_git-flow"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-hubflow/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-hubflow/README.md
new file mode 100644 (file)
index 0000000..dada60d
--- /dev/null
@@ -0,0 +1,24 @@
+# git-hubflow plugin
+
+This plugin adds completion for [HubFlow](https://datasift.github.io/gitflow/) (GitFlow for GitHub), as well as some
+aliases for common commands. HubFlow is a git extension to make it easy to use GitFlow with GitHub. Based on the
+original gitflow extension for git.
+
+The hubflow tool has to be [installed](https://github.com/datasift/gitflow#installation) separately.
+
+To use it, add `git-hubflow` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git-hubflow)
+```
+
+## Aliases
+
+| Alias | Command          | Description                                                      |
+|-------|------------------|------------------------------------------------------------------|
+| ghf   | `git hf`         | Print command overview                                           |
+| ghff  | `git hf feature` | Manage your feature branches                                     |
+| ghfr  | `git hf release` | Manage your release branches                                     |
+| ghfh  | `git hf hotfix`  | Manage your hotfix branches                                      |
+| ghfs  | `git hf support` | Manage your support branches                                     |
+| ghfu  | `git hf update`  | Pull upstream changes down into your master and develop branches |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-hubflow/git-hubflow.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-hubflow/git-hubflow.plugin.zsh
new file mode 100644 (file)
index 0000000..50d7b23
--- /dev/null
@@ -0,0 +1,333 @@
+alias ghf='git hf'
+alias ghff='git hf feature'
+alias ghfr='git hf release'
+alias ghfh='git hf hotfix'
+alias ghfs='git hf support'
+alias ghfu='git hf update'
+
+_git-hf ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'init:Initialize a new git repo with support for the branching model.'
+                'feature:Manage your feature branches.'
+                'release:Manage your release branches.'
+                'hotfix:Manage your hotfix branches.'
+                'support:Manage your support branches.'
+                'update:Pull upstream changes down into your master and develop branches.'
+                'version:Shows version information.'
+            )
+            _describe -t commands 'git hf' subcommands
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (init)
+                    _arguments \
+                        -f'[Force setting of gitflow branches, even if already configured]'
+                ;;
+
+                (version)
+                ;;
+
+                (hotfix)
+                    __git-hf-hotfix
+                ;;
+
+                (release)
+                    __git-hf-release
+                ;;
+
+                (feature)
+                    __git-hf-feature
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-hf-release ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'start:Start a new release branch.'
+                'finish:Finish a release branch.'
+                'list:List all your release branches. (Alias to `git hf release`)'
+                'cancel:Cancel release'
+                'push:Push release to GitHub'
+                'pull:Pull release from GitHub'
+                'track:Track release'
+            )
+            _describe -t commands 'git hf release' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':version:__git_hf_version_list'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -s'[Sign the release tag cryptographically]'\
+                        -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+                        -m'[Use the given tag message]'\
+                        -p'[Push to $ORIGIN after performing finish]'\
+                        -k'[Keep branch after performing finish]'\
+                        -n"[Don't tag this release]"\
+                        ':version:__git_hf_version_list'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-hf-hotfix ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'start:Start a new hotfix branch.'
+                'finish:Finish a hotfix branch.'
+                'list:List all your hotfix branches. (Alias to `git hf hotfix`)'
+                'publish:Publish the hotfix branch.'
+                'track:Track the hotfix branch.'
+                'pull:Pull the hotfix from GitHub.'
+                'push:Push the hotfix to GitHub.'
+                'cancel:Cancel the hotfix.'
+            )
+            _describe -t commands 'git hf hotfix' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':hotfix:__git_hf_version_list'\
+                        ':branch-name:__git_branch_names'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -s'[Sign the release tag cryptographically]'\
+                        -u'[Use the given GPG-key for the digital signature (implies -s)]'\
+                        -m'[Use the given tag message]'\
+                        -p'[Push to $ORIGIN after performing finish]'\
+                        -k'[Keep branch after performing finish]'\
+                        -n"[Don't tag this release]"\
+                        ':hotfix:__git_hf_hotfix_list'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git-hf-feature ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+
+            local -a subcommands
+            subcommands=(
+                'list:List all your feature branches. (Alias to `git hf feature`)'
+                'start:Start a new feature branch'
+                'finish:Finish a feature branch'
+                'submit:submit'
+                'track:track'
+                'diff:Diff'
+                'rebase:Rebase feature branch against develop'
+                'checkout:Checkout feature'
+                'pull:Pull feature branch from GitHub'
+                'push:Push feature branch to GitHub'
+                'cancel:Cancel feature'
+            )
+            _describe -t commands 'git hf feature' subcommands
+            _arguments \
+                -v'[Verbose (more) output]'
+        ;;
+
+        (options)
+            case $line[1] in
+
+                (start)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]'\
+                        ':feature:__git_hf_feature_list'\
+                        ':branch-name:__git_branch_names'
+                ;;
+
+                (finish)
+                    _arguments \
+                        -F'[Fetch from origin before performing finish]' \
+                        -r'[Rebase instead of merge]'\
+                        ':feature:__git_hf_feature_list'
+                ;;
+
+                (publish)
+                    _arguments \
+                        ':feature:__git_hf_feature_list'\
+                ;;
+
+                (track)
+                    _arguments \
+                        ':feature:__git_hf_feature_list'\
+                ;;
+
+                (diff)
+                    _arguments \
+                        ':branch:__git_branch_names'\
+                ;;
+
+                (rebase)
+                    _arguments \
+                        -i'[Do an interactive rebase]' \
+                        ':branch:__git_branch_names'
+                ;;
+
+                (checkout)
+                    _arguments \
+                        ':branch:__git_hf_feature_list'\
+                ;;
+
+                (pull)
+                    _arguments \
+                        ':remote:__git_remotes'\
+                        ':branch:__git_branch_names'
+                ;;
+
+                *)
+                    _arguments \
+                        -v'[Verbose (more) output]'
+                ;;
+            esac
+        ;;
+    esac
+}
+
+__git_hf_version_list ()
+{
+    local expl
+    declare -a versions
+
+    versions=(${${(f)"$(_call_program versions git hf release list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted versions expl 'version' compadd $versions
+}
+
+__git_hf_feature_list ()
+{
+    local expl
+    declare -a features
+
+    features=(${${(f)"$(_call_program features git hf feature list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted features expl 'feature' compadd $features
+}
+
+__git_remotes () {
+    local expl gitdir remotes
+
+    gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
+    __git_command_successful || return
+
+    remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
+    __git_command_successful || return
+
+    # TODO: Should combine the two instead of either or.
+    if (( $#remotes > 0 )); then
+        _wanted remotes expl remote compadd $* - $remotes
+    else
+        _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
+    fi
+}
+
+__git_hf_hotfix_list ()
+{
+    local expl
+    declare -a hotfixes
+
+    hotfixes=(${${(f)"$(_call_program hotfixes git hf hotfix list 2> /dev/null | tr -d ' |*')"}})
+    __git_command_successful || return
+
+    _wanted hotfixes expl 'hotfix' compadd $hotfixes
+}
+
+__git_branch_names () {
+    local expl
+    declare -a branch_names
+
+    branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
+    __git_command_successful || return
+
+    _wanted branch-names expl branch-name compadd $* - $branch_names
+}
+
+__git_command_successful () {
+    if (( ${#pipestatus:#0} > 0 )); then
+        _message 'not a git repository'
+        return 1
+    fi
+    return 0
+}
+
+zstyle ':completion:*:*:git:*' user-commands flow:'description for foo'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-lfs/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-lfs/README.md
new file mode 100644 (file)
index 0000000..1222b27
--- /dev/null
@@ -0,0 +1,24 @@
+# git lfs plugin
+
+The git lfs plugin provides [aliases](#aliases) and [functions](#functions) for [git-lfs](https://github.com/git-lfs/git-lfs).
+
+To use it, add `git-lfs` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git-lfs)
+```
+
+## Aliases
+
+| Alias    | Command                             |
+| :------- | :---------------------------------- |
+| `glfsi`  | `git lfs install`                   |
+| `glfst`  | `git lfs track`                     |
+| `glfsls` | `git lfs ls-files`                  |
+| `glfsmi` | `git lfs migrate import --include=` |
+
+## Functions
+
+| Function | Command                                         |
+| :------- | :---------------------------------------------- |
+| `gplfs`  | `git lfs push origin "$(current_branch)" --all` |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-lfs/git-lfs.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-lfs/git-lfs.plugin.zsh
new file mode 100644 (file)
index 0000000..e7bb676
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Aliases
+#
+
+alias glfsi='git lfs install'
+alias glfst='git lfs track'
+alias glfsls='git lfs ls-files'
+alias glfsmi='git lfs migrate import --include='
+
+#
+# Functions
+#
+
+function gplfs() {
+  local b="$(git_current_branch)"
+  git lfs push origin "$b" --all
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/README.md
new file mode 100644 (file)
index 0000000..8775af8
--- /dev/null
@@ -0,0 +1,66 @@
+# git-prompt plugin
+
+A `zsh` prompt that displays information about the current git repository. In particular:
+the branch name, difference with remote branch, number of files staged or changed, etc.
+
+To use it, add `git-prompt` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git-prompt)
+```
+
+See the [original repository](https://github.com/olivierverdier/zsh-git-prompt).
+
+## Requirements
+
+This plugin uses `python3`, so your host needs to have it installed.
+
+## Examples
+
+The prompt may look like the following:
+
+- `(master↑3|✚1)`: on branch `master`, ahead of remote by 3 commits, 1 file changed but not staged
+- `(status|●2)`: on branch `status`, 2 files staged
+- `(master|✚7…)`: on branch `master`, 7 files changed, some files untracked
+- `(master|✖2✚3)`: on branch `master`, 2 conflicts, 3 files changed
+- `(experimental↓2↑3|✔)`: on branch `experimental`; your branch has diverged by 3 commits, remote by 2 commits; the repository is otherwise clean
+- `(:70c2952|✔)`: not on any branch; parent commit has hash `70c2952`; the repository is otherwise clean
+- `(master|⚑2)`: on branch `master`, there are 2 stashed changes
+
+## Prompt Structure
+
+By default, the general appearance of the prompt is:
+
+```text
+(<branch><branch tracking>|<local status>)
+```
+
+The symbols are as follows:
+
+### Local Status Symbols
+
+| Symbol | Meaning                        |
+|--------|--------------------------------|
+| ✔      | repository clean               |
+| ●n     | there are `n` staged files     |
+| ✖n     | there are `n` unmerged files   |
+| ✚n     | there are `n` unstaged files   |
+| ⚑n     | there are `n` stashed changes  |
+| …      | there are some untracked files |
+
+### Branch Tracking Symbols
+
+| Symbol | Meaning                                                       |
+|--------|---------------------------------------------------------------|
+| ↑n     | ahead of remote by `n` commits                                |
+| ↓n     | behind remote by `n` commits                                  |
+| ↓m↑n   | branches diverged: other by `m` commits, yours by `n` commits |
+
+## Customisation
+
+- Set the variable `ZSH_THEME_GIT_PROMPT_CACHE` to any value in order to enable caching.
+- You may also change a number of variables (whose name start with `ZSH_THEME_GIT_PROMPT_`)
+  to change the appearance of the prompt. Take a look at the bottom of the [plugin file](git-prompt.plugin.zsh)`
+  to see what variables are available.
+
+**Enjoy!**
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/git-prompt.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/git-prompt.plugin.zsh
new file mode 100644 (file)
index 0000000..0485e31
--- /dev/null
@@ -0,0 +1,101 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+__GIT_PROMPT_DIR="${0:A:h}"
+
+## Hook function definitions
+function chpwd_update_git_vars() {
+    update_current_git_vars
+}
+
+function preexec_update_git_vars() {
+    case "$2" in
+        git*|hub*|gh*|stg*)
+        __EXECUTED_GIT_COMMAND=1
+        ;;
+    esac
+}
+
+function precmd_update_git_vars() {
+    if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then
+        update_current_git_vars
+        unset __EXECUTED_GIT_COMMAND
+    fi
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook chpwd chpwd_update_git_vars
+add-zsh-hook precmd precmd_update_git_vars
+add-zsh-hook preexec preexec_update_git_vars
+
+
+## Function definitions
+function update_current_git_vars() {
+    unset __CURRENT_GIT_STATUS
+
+    local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
+    _GIT_STATUS=$(python3 ${gitstatus} 2>/dev/null)
+     __CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}")
+    GIT_BRANCH=$__CURRENT_GIT_STATUS[1]
+    GIT_AHEAD=$__CURRENT_GIT_STATUS[2]
+    GIT_BEHIND=$__CURRENT_GIT_STATUS[3]
+    GIT_STAGED=$__CURRENT_GIT_STATUS[4]
+    GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5]
+    GIT_CHANGED=$__CURRENT_GIT_STATUS[6]
+    GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7]
+    GIT_STASHED=$__CURRENT_GIT_STATUS[8]
+    GIT_CLEAN=$__CURRENT_GIT_STATUS[9]
+}
+
+git_super_status() {
+    precmd_update_git_vars
+    if [ -n "$__CURRENT_GIT_STATUS" ]; then
+      STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}"
+      if [ "$GIT_BEHIND" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}"
+      fi
+      if [ "$GIT_AHEAD" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}"
+      fi
+      STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR"
+      if [ "$GIT_STAGED" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}"
+      fi
+      if [ "$GIT_CONFLICTS" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}"
+      fi
+      if [ "$GIT_CHANGED" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}"
+      fi
+      if [ "$GIT_UNTRACKED" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED$GIT_UNTRACKED%{${reset_color}%}"
+      fi
+      if [ "$GIT_STASHED" -ne "0" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STASHED$GIT_STASHED%{${reset_color}%}"
+      fi
+      if [ "$GIT_CLEAN" -eq "1" ]; then
+          STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN"
+      fi
+      STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX"
+      echo "$STATUS"
+    fi
+}
+
+# Default values for the appearance of the prompt.
+ZSH_THEME_GIT_PROMPT_PREFIX="("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"
+ZSH_THEME_GIT_PROMPT_SEPARATOR="|"
+ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}"
+ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[red]%}%{●%G%}"
+ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg[red]%}%{✖%G%}"
+ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg[blue]%}%{✚%G%}"
+ZSH_THEME_GIT_PROMPT_BEHIND="%{↓%G%}"
+ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%}%{…%G%}"
+ZSH_THEME_GIT_PROMPT_STASHED="%{$fg_bold[blue]%}%{⚑%G%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}"
+
+# Set the prompt.
+RPROMPT='$(git_super_status)'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/gitstatus.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/git-prompt/gitstatus.py
new file mode 100644 (file)
index 0000000..b5c3c9a
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+from __future__ import print_function
+
+import os
+import sys
+import re
+from subprocess import Popen, PIPE, check_output
+
+
+def get_tagname_or_hash():
+    """return tagname if exists else hash"""
+    # get hash
+    hash_cmd = ['git', 'rev-parse', '--short', 'HEAD']
+    hash_ = check_output(hash_cmd).decode('utf-8').strip()
+
+    # get tagname
+    tags_cmd = ['git', 'for-each-ref', '--points-at=HEAD', '--count=2', '--sort=-version:refname', '--format=%(refname:short)', 'refs/tags']
+    tags = check_output(tags_cmd).decode('utf-8').split()
+
+    if tags:
+        return tags[0] + ('+' if len(tags) > 1 else '')
+    elif hash_:
+        return hash_
+    return None
+
+# Re-use method from https://github.com/magicmonty/bash-git-prompt to get stashs count
+def get_stash():
+    cmd = Popen(['git', 'rev-parse', '--git-dir'], stdout=PIPE, stderr=PIPE)
+    so, se = cmd.communicate()
+    stash_file = '%s%s' % (so.decode('utf-8').rstrip(), '/logs/refs/stash')
+
+    try:
+        with open(stash_file) as f:
+            return sum(1 for _ in f)
+    except IOError:
+        return 0
+
+
+# `git status --porcelain --branch` can collect all information
+# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
+po = Popen(['git', 'status', '--porcelain', '--branch'], env=dict(os.environ, LANG="C"), stdout=PIPE, stderr=PIPE)
+stdout, sterr = po.communicate()
+if po.returncode != 0:
+    sys.exit(0)  # Not a git repository
+
+# collect git status information
+untracked, staged, changed, conflicts = [], [], [], []
+ahead, behind = 0, 0
+status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()]
+for st in status:
+    if st[0] == '#' and st[1] == '#':
+        if re.search('Initial commit on', st[2]) or re.search('No commits yet on', st[2]):
+            branch = st[2].split(' ')[-1]
+        elif re.search('no branch', st[2]):  # detached status
+            branch = get_tagname_or_hash()
+        elif len(st[2].strip().split('...')) == 1:
+            branch = st[2].strip()
+        else:
+            # current and remote branch info
+            branch, rest = st[2].strip().split('...')
+            if len(rest.split(' ')) == 1:
+                # remote_branch = rest.split(' ')[0]
+                pass
+            else:
+                # ahead or behind
+                divergence = ' '.join(rest.split(' ')[1:])
+                divergence = divergence.lstrip('[').rstrip(']')
+                for div in divergence.split(', '):
+                    if 'ahead' in div:
+                        ahead = int(div[len('ahead '):].strip())
+                    elif 'behind' in div:
+                        behind = int(div[len('behind '):].strip())
+    elif st[0] == '?' and st[1] == '?':
+        untracked.append(st)
+    else:
+        if st[1] == 'M':
+            changed.append(st)
+        if st[0] == 'U':
+            conflicts.append(st)
+        elif st[0] != ' ':
+            staged.append(st)
+
+stashed = get_stash()
+if not changed and not staged and not conflicts and not untracked:
+    clean = 1
+else:
+    clean = 0
+
+out = ' '.join([
+    branch,
+    str(ahead),
+    str(behind),
+    str(len(staged)),
+    str(len(conflicts)),
+    str(len(changed)),
+    str(len(untracked)),
+    str(stashed),
+    str(clean)
+])
+print(out, end='')
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/git/README.md
new file mode 100644 (file)
index 0000000..050c13d
--- /dev/null
@@ -0,0 +1,248 @@
+# git plugin
+
+The git plugin provides many [aliases](#aliases) and a few useful [functions](#functions).
+
+To use it, add `git` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... git)
+```
+
+## Aliases
+
+| Alias                | Command                                                                                                                          |
+|:---------------------|:---------------------------------------------------------------------------------------------------------------------------------|
+| g                    | git                                                                                                                              |
+| ga                   | git add                                                                                                                          |
+| gaa                  | git add --all                                                                                                                    |
+| gapa                 | git add --patch                                                                                                                  |
+| gau                  | git add --update                                                                                                                 |
+| gav                  | git add --verbose                                                                                                                |
+| gap                  | git apply                                                                                                                        |
+| gapt                 | git apply --3way                                                                                                                 |
+| gb                   | git branch                                                                                                                       |
+| gba                  | git branch -a                                                                                                                    |
+| gbd                  | git branch -d                                                                                                                    |
+| gbda                 | git branch --no-color --merged \| grep -vE "^([+*]\|\s*(<span>$</span>(git_main_branch)\|<span>$</span>(git_develop_branch))\s*<span>$</span>)" \| xargs git branch -d 2>/dev/null |
+| gbD                  | git branch -D                                                                                                                    |
+| gbl                  | git blame -b -w                                                                                                                  |
+| gbnm                 | git branch --no-merged                                                                                                           |
+| gbr                  | git branch --remote                                                                                                              |
+| gbs                  | git bisect                                                                                                                       |
+| gbsb                 | git bisect bad                                                                                                                   |
+| gbsg                 | git bisect good                                                                                                                  |
+| gbsr                 | git bisect reset                                                                                                                 |
+| gbss                 | git bisect start                                                                                                                 |
+| gc                   | git commit -v                                                                                                                    |
+| gc!                  | git commit -v --amend                                                                                                            |
+| gcn!                 | git commit -v --no-edit --amend                                                                                                  |
+| gca                  | git commit -v -a                                                                                                                 |
+| gca!                 | git commit -v -a --amend                                                                                                         |
+| gcan!                | git commit -v -a --no-edit --amend                                                                                               |
+| gcans!               | git commit -v -a -s --no-edit --amend                                                                                            |
+| gcam                 | git commit -a -m                                                                                                                 |
+| gcas                 | git commit -a -s                                                                                                                 |
+| gcasm                | git commit -a -s -m                                                                                                              |
+| gcsm                 | git commit -s -m                                                                                                                 |
+| gcb                  | git checkout -b                                                                                                                  |
+| gcf                  | git config --list                                                                                                                |
+| gcl                  | git clone --recurse-submodules                                                                                                   |
+| gccd                 | git clone --recurse-submodules "<span>$</span>@" && cd "<span>$</span>(basename <span>$</span>_ .git)"                           |
+| gclean               | git clean -id                                                                                                                    |
+| gpristine            | git reset --hard && git clean -dffx                                                                                              |
+| gcm                  | git checkout $(git_main_branch)                                                                                                  |
+| gcd                  | git checkout $(git_develop_branch)                                                                                               |
+| gcmsg                | git commit -m                                                                                                                    |
+| gco                  | git checkout                                                                                                                     |
+| gcor                 | git checkout --recurse-submodules                                                                                                |
+| gcount               | git shortlog -sn                                                                                                                 |
+| gcp                  | git cherry-pick                                                                                                                  |
+| gcpa                 | git cherry-pick --abort                                                                                                          |
+| gcpc                 | git cherry-pick --continue                                                                                                       |
+| gcs                  | git commit -S                                                                                                                    |
+| gd                   | git diff                                                                                                                         |
+| gdca                 | git diff --cached                                                                                                                |
+| gdcw                 | git diff --cached --word-diff                                                                                                    |
+| gdct                 | git describe --tags $(git rev-list --tags --max-count=1)                                                                         |
+| gds                  | git diff --staged                                                                                                                |
+| gdt                  | git diff-tree --no-commit-id --name-only -r                                                                                      |
+| gdnolock             | git diff $@ ":(exclude)package-lock.json" ":(exclude)&ast;.lock"                                                                 |
+| gdup                 | git diff @{upstream}                                                                                                             |
+| gdv                  | git diff -w $@ \| view -                                                                                                         |
+| gdw                  | git diff --word-diff                                                                                                             |
+| gf                   | git fetch                                                                                                                        |
+| gfa                  | git fetch --all --prune                                                                                                          |
+| gfg                  | git ls-files \| grep                                                                                                             |
+| gfo                  | git fetch origin                                                                                                                 |
+| gg                   | git gui citool                                                                                                                   |
+| gga                  | git gui citool --amend                                                                                                           |
+| ggf                  | git push --force origin $(current_branch)                                                                                        |
+| ggfl                 | git push --force-with-lease origin $(current_branch)                                                                             |
+| ggl                  | git pull origin $(current_branch)                                                                                                |
+| ggp                  | git push origin $(current_branch)                                                                                                |
+| ggpnp                | ggl && ggp                                                                                                                       |
+| ggpull               | git pull origin "$(git_current_branch)"                                                                                          |
+| ggpur                | ggu                                                                                                                              |
+| ggpush               | git push origin "$(git_current_branch)"                                                                                          |
+| ggsup                | git branch --set-upstream-to=origin/$(git_current_branch)                                                                        |
+| ggu                  | git pull --rebase origin $(current_branch)                                                                                       |
+| gpsup                | git push --set-upstream origin $(git_current_branch)                                                                             |
+| ghh                  | git help                                                                                                                         |
+| gignore              | git update-index --assume-unchanged                                                                                              |
+| gignored             | git ls-files -v \| grep "^[[:lower:]]"                                                                                           |
+| git-svn-dcommit-push | git svn dcommit && git push github $(git_main_branch):svntrunk                                                                   |
+| gk                   | gitk --all --branches &!                                                                                                          |
+| gke                  | gitk --all $(git log -g --pretty=%h) &!                                                                                           |
+| gl                   | git pull                                                                                                                         |
+| glg                  | git log --stat                                                                                                                   |
+| glgp                 | git log --stat -p                                                                                                                |
+| glgg                 | git log --graph                                                                                                                  |
+| glgga                | git log --graph --decorate --all                                                                                                 |
+| glgm                 | git log --graph --max-count=10                                                                                                   |
+| glo                  | git log --oneline --decorate                                                                                                     |
+| glol                 | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'                           |
+| glols                | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --stat                    |
+| glod                 | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset'                           |
+| glods                | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' --date=short              |
+| glola                | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --all                     |
+| glog                 | git log --oneline --decorate --graph                                                                                             |
+| gloga                | git log --oneline --decorate --graph --all                                                                                       |
+| glp                  | git log --pretty=\<format\>                                                                                                      |
+| gm                   | git merge                                                                                                                        |
+| gmom                 | git merge origin/$(git_main_branch)                                                                                              |
+| gmtl                 | git mergetool --no-prompt                                                                                                        |
+| gmtlvim              | git mergetool --no-prompt --tool=vimdiff                                                                                         |
+| gmum                 | git merge upstream/$(git_main_branch)                                                                                            |
+| gma                  | git merge --abort                                                                                                                |
+| gp                   | git push                                                                                                                         |
+| gpd                  | git push --dry-run                                                                                                               |
+| gpf                  | git push --force-with-lease                                                                                                      |
+| gpf!                 | git push --force                                                                                                                 |
+| gpoat                | git push origin --all && git push origin --tags                                                                                  |
+| gpr                  | git pull --rebase                                                                                                                |
+| gpu                  | git push upstream                                                                                                                |
+| gpv                  | git push -v                                                                                                                      |
+| gr                   | git remote                                                                                                                       |
+| gra                  | git remote add                                                                                                                   |
+| grb                  | git rebase                                                                                                                       |
+| grba                 | git rebase --abort                                                                                                               |
+| grbc                 | git rebase --continue                                                                                                            |
+| grbd                 | git rebase $(git_develop_branch)                                                                                                 |
+| grbi                 | git rebase -i                                                                                                                    |
+| grbm                 | git rebase $(git_main_branch)                                                                                                    |
+| grbom                | git rebase origin/$(git_main_branch)                                                                                             |
+| grbo                 | git rebase --onto                                                                                                                |
+| grbs                 | git rebase --skip                                                                                                                |
+| grev                 | git revert                                                                                                                       |
+| grh                  | git reset                                                                                                                        |
+| grhh                 | git reset --hard                                                                                                                 |
+| groh                 | git reset origin/$(git_current_branch) --hard                                                                                    |
+| grm                  | git rm                                                                                                                           |
+| grmc                 | git rm --cached                                                                                                                  |
+| grmv                 | git remote rename                                                                                                                |
+| grrm                 | git remote remove                                                                                                                |
+| grs                  | git restore                                                                                                                      |
+| grset                | git remote set-url                                                                                                               |
+| grss                 | git restore --source                                                                                                             |
+| grst                 | git restore --staged                                                                                                             |
+| grt                  | cd "$(git rev-parse --show-toplevel \|\| echo .)"                                                                                |
+| gru                  | git reset --                                                                                                                     |
+| grup                 | git remote update                                                                                                                |
+| grv                  | git remote -v                                                                                                                    |
+| gsb                  | git status -sb                                                                                                                   |
+| gsd                  | git svn dcommit                                                                                                                  |
+| gsh                  | git show                                                                                                                         |
+| gsi                  | git submodule init                                                                                                               |
+| gsps                 | git show --pretty=short --show-signature                                                                                         |
+| gsr                  | git svn rebase                                                                                                                   |
+| gss                  | git status -s                                                                                                                    |
+| gst                  | git status                                                                                                                       |
+| gsta                 | git stash push                                                                                                                   |
+| gsta                 | git stash save                                                                                                                   |
+| gstaa                | git stash apply                                                                                                                  |
+| gstc                 | git stash clear                                                                                                                  |
+| gstd                 | git stash drop                                                                                                                   |
+| gstl                 | git stash list                                                                                                                   |
+| gstp                 | git stash pop                                                                                                                    |
+| gsts                 | git stash show --text                                                                                                            |
+| gstu                 | git stash --include-untracked                                                                                                    |
+| gstall               | git stash --all                                                                                                                  |
+| gsu                  | git submodule update                                                                                                             |
+| gsw                  | git switch                                                                                                                       |
+| gswc                 | git switch -c                                                                                                                    |
+| gswm                 | git switch $(git_main_branch)                                                                                                    |
+| gswd                 | git switch $(git_develop_branch)                                                                                                 |
+| gts                  | git tag -s                                                                                                                       |
+| gtv                  | git tag \| sort -V                                                                                                               |
+| gtl                  | gtl(){ git tag --sort=-v:refname -n -l ${1}* }; noglob gtl                                                                       |
+| gunignore            | git update-index --no-assume-unchanged                                                                                           |
+| gunwip               | git log -n 1 \| grep -q -c "\-\-wip\-\-" && git reset HEAD~1                                                                     |
+| gup                  | git pull --rebase                                                                                                                |
+| gupv                 | git pull --rebase -v                                                                                                             |
+| gupa                 | git pull --rebase --autostash                                                                                                    |
+| gupav                | git pull --rebase --autostash -v                                                                                                 |
+| gupom                | git pull --rebase origin $(git_main_branch)                                                                                      |
+| gupomi               | git pull --rebase=interactive origin $(git_main_branch)                                                                          |
+| glum                 | git pull upstream $(git_main_branch)                                                                                             |
+| gluc                 | git pull upstream $(git_current_branch)                                                                                             |
+| gwch                 | git whatchanged -p --abbrev-commit --pretty=medium                                                                               |
+| gwip                 | git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]"           |
+| gam                  | git am                                                                                                                           |
+| gamc                 | git am --continue                                                                                                                |
+| gams                 | git am --skip                                                                                                                    |
+| gama                 | git am --abort                                                                                                                   |
+| gamscp               | git am --show-current-patch                                                                                                      |
+
+### Main branch preference
+
+Following the recent push for removing racially-charged words from our technical vocabulary, the git plugin favors using
+a branch name other than `master`. In this case, we favor the shorter, neutral and descriptive term `main`. This means
+that any aliases and functions that previously used `master`, will use `main` if that branch exists. We do this via the
+function `git_main_branch`.
+
+### Deprecated aliases
+
+These are aliases that have been removed, renamed, or otherwise modified in a way that may, or may not, receive further support.
+
+| Alias  | Command                                                | Modification                                           |
+| :----- | :----------------------------------------------------- | :----------------------------------------------------- |
+| gap    | `git add --patch`                                      | new alias `gapa`                                       |
+| gcl    | `git config --list`                                    | new alias `gcf`                                        |
+| gdc    | `git diff --cached`                                    | new alias `gdca`                                       |
+| gdt    | `git difftool`                                         | no replacement                                         |
+| ggpull | `git pull origin $(current_branch)`                    | new alias `ggl` (`ggpull` still exists for now though) |
+| ggpur  | `git pull --rebase origin $(current_branch)`           | new alias `ggu` (`ggpur` still exists for now though)  |
+| ggpush | `git push origin $(current_branch)`                    | new alias `ggp` (`ggpush` still exists for now though) |
+| gk     | `gitk --all --branches`                                | now aliased to `gitk --all --branches`                 |
+| glg    | `git log --stat --max-count = 10`                      | now aliased to `git log --stat --color`                |
+| glgg   | `git log --graph --max-count = 10`                     | now aliased to `git log --graph --color`               |
+| gwc    | `git whatchanged -p --abbrev-commit --pretty = medium` | new alias `gwch`                                       |
+
+## Functions
+
+### Current
+
+| Command                | Description                                                                                              |
+|:-----------------------|:---------------------------------------------------------------------------------------------------------|
+| `grename <old> <new>`  | Rename `old` branch to `new`, including in origin remote                                                 |
+| current_branch         | Return the name of the current branch                                                                    |
+| git_current_user_name  | Returns the `user.name` config value                                                                     |
+| git_current_user_email | Returns the `user.email` config value                                                                    |
+| git_main_branch        | Returns the name of the main branch: `main` if it exists, `master` otherwise                             |
+| git_develop_branch     | Returns the name of the develop branch: `dev`, `devel`, `development` if they exist, `develop` otherwise |
+
+### Work in Progress (WIP)
+
+These features allow to pause a branch development and switch to another one (_"Work in Progress"_,  or wip). When you want to go back to work, just unwip it.
+
+| Command          | Description                                     |
+|:-----------------|:------------------------------------------------|
+| work_in_progress | Echoes a warning if the current branch is a wip |
+| gwip             | Commit wip branch                               |
+| gunwip           | Uncommit wip branch                             |
+
+### Deprecated functions
+
+| Command                | Description                             | Reason                                                          |
+|:-----------------------|:----------------------------------------|:----------------------------------------------------------------|
+| current_repository     | Return the names of the current remotes | Didn't work properly. Use `git remote -v` instead (`grv` alias) |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/git/git.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/git/git.plugin.zsh
new file mode 100644 (file)
index 0000000..f25453b
--- /dev/null
@@ -0,0 +1,338 @@
+# Git version checking
+autoload -Uz is-at-least
+git_version="${${(As: :)$(git version 2>/dev/null)}[3]}"
+
+#
+# Functions
+#
+
+# The name of the current branch
+# Back-compatibility wrapper for when this function was defined here in
+# the plugin, before being pulled in to core lib/git.zsh as git_current_branch()
+# to fix the core -> git plugin dependency.
+function current_branch() {
+  git_current_branch
+}
+
+# Pretty log messages
+function _git_log_prettily(){
+  if ! [ -z $1 ]; then
+    git log --pretty=$1
+  fi
+}
+compdef _git _git_log_prettily=git-log
+
+# Warn if the current branch is a WIP
+function work_in_progress() {
+  command git -c log.showSignature=false log -n 1 2>/dev/null | grep -q -- "--wip--" && echo "WIP!!"
+}
+
+# Check if main exists and use instead of master
+function git_main_branch() {
+  command git rev-parse --git-dir &>/dev/null || return
+  local ref
+  for ref in refs/{heads,remotes/{origin,upstream}}/{main,trunk}; do
+    if command git show-ref -q --verify $ref; then
+      echo ${ref:t}
+      return
+    fi
+  done
+  echo master
+}
+
+# Check for develop and similarly named branches
+function git_develop_branch() {
+  command git rev-parse --git-dir &>/dev/null || return
+  local branch
+  for branch in dev devel development; do
+    if command git show-ref -q --verify refs/heads/$branch; then
+      echo $branch
+      return
+    fi
+  done
+  echo develop
+}
+
+#
+# Aliases
+# (sorted alphabetically)
+#
+
+alias g='git'
+
+alias ga='git add'
+alias gaa='git add --all'
+alias gapa='git add --patch'
+alias gau='git add --update'
+alias gav='git add --verbose'
+alias gap='git apply'
+alias gapt='git apply --3way'
+
+alias gb='git branch'
+alias gba='git branch -a'
+alias gbd='git branch -d'
+alias gbda='git branch --no-color --merged | command grep -vE "^([+*]|\s*($(git_main_branch)|$(git_develop_branch))\s*$)" | command xargs git branch -d 2>/dev/null'
+alias gbD='git branch -D'
+alias gbl='git blame -b -w'
+alias gbnm='git branch --no-merged'
+alias gbr='git branch --remote'
+alias gbs='git bisect'
+alias gbsb='git bisect bad'
+alias gbsg='git bisect good'
+alias gbsr='git bisect reset'
+alias gbss='git bisect start'
+
+alias gc='git commit -v'
+alias gc!='git commit -v --amend'
+alias gcn!='git commit -v --no-edit --amend'
+alias gca='git commit -v -a'
+alias gca!='git commit -v -a --amend'
+alias gcan!='git commit -v -a --no-edit --amend'
+alias gcans!='git commit -v -a -s --no-edit --amend'
+alias gcam='git commit -a -m'
+alias gcsm='git commit -s -m'
+alias gcas='git commit -a -s'
+alias gcasm='git commit -a -s -m'
+alias gcb='git checkout -b'
+alias gcf='git config --list'
+
+function gccd() {
+  command git clone --recurse-submodules "$@"
+  [[ -d "$_" ]] && cd "$_" || cd "${${_:t}%.git}"
+}
+compdef _git gccd=git-clone
+
+alias gcl='git clone --recurse-submodules'
+alias gclean='git clean -id'
+alias gpristine='git reset --hard && git clean -dffx'
+alias gcm='git checkout $(git_main_branch)'
+alias gcd='git checkout $(git_develop_branch)'
+alias gcmsg='git commit -m'
+alias gco='git checkout'
+alias gcor='git checkout --recurse-submodules'
+alias gcount='git shortlog -sn'
+alias gcp='git cherry-pick'
+alias gcpa='git cherry-pick --abort'
+alias gcpc='git cherry-pick --continue'
+alias gcs='git commit -S'
+alias gcss='git commit -S -s'
+alias gcssm='git commit -S -s -m'
+
+alias gd='git diff'
+alias gdca='git diff --cached'
+alias gdcw='git diff --cached --word-diff'
+alias gdct='git describe --tags $(git rev-list --tags --max-count=1)'
+alias gds='git diff --staged'
+alias gdt='git diff-tree --no-commit-id --name-only -r'
+alias gdup='git diff @{upstream}'
+alias gdw='git diff --word-diff'
+
+function gdnolock() {
+  git diff "$@" ":(exclude)package-lock.json" ":(exclude)*.lock"
+}
+compdef _git gdnolock=git-diff
+
+function gdv() { git diff -w "$@" | view - }
+compdef _git gdv=git-diff
+
+alias gf='git fetch'
+# --jobs=<n> was added in git 2.8
+is-at-least 2.8 "$git_version" \
+  && alias gfa='git fetch --all --prune --jobs=10' \
+  || alias gfa='git fetch --all --prune'
+alias gfo='git fetch origin'
+
+alias gfg='git ls-files | grep'
+
+alias gg='git gui citool'
+alias gga='git gui citool --amend'
+
+function ggf() {
+  [[ "$#" != 1 ]] && local b="$(git_current_branch)"
+  git push --force origin "${b:=$1}"
+}
+compdef _git ggf=git-checkout
+function ggfl() {
+  [[ "$#" != 1 ]] && local b="$(git_current_branch)"
+  git push --force-with-lease origin "${b:=$1}"
+}
+compdef _git ggfl=git-checkout
+
+function ggl() {
+  if [[ "$#" != 0 ]] && [[ "$#" != 1 ]]; then
+    git pull origin "${*}"
+  else
+    [[ "$#" == 0 ]] && local b="$(git_current_branch)"
+    git pull origin "${b:=$1}"
+  fi
+}
+compdef _git ggl=git-checkout
+
+function ggp() {
+  if [[ "$#" != 0 ]] && [[ "$#" != 1 ]]; then
+    git push origin "${*}"
+  else
+    [[ "$#" == 0 ]] && local b="$(git_current_branch)"
+    git push origin "${b:=$1}"
+  fi
+}
+compdef _git ggp=git-checkout
+
+function ggpnp() {
+  if [[ "$#" == 0 ]]; then
+    ggl && ggp
+  else
+    ggl "${*}" && ggp "${*}"
+  fi
+}
+compdef _git ggpnp=git-checkout
+
+function ggu() {
+  [[ "$#" != 1 ]] && local b="$(git_current_branch)"
+  git pull --rebase origin "${b:=$1}"
+}
+compdef _git ggu=git-checkout
+
+alias ggpur='ggu'
+alias ggpull='git pull origin "$(git_current_branch)"'
+alias ggpush='git push origin "$(git_current_branch)"'
+
+alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)'
+alias gpsup='git push --set-upstream origin $(git_current_branch)'
+
+alias ghh='git help'
+
+alias gignore='git update-index --assume-unchanged'
+alias gignored='git ls-files -v | grep "^[[:lower:]]"'
+alias git-svn-dcommit-push='git svn dcommit && git push github $(git_main_branch):svntrunk'
+
+alias gk='\gitk --all --branches &!'
+alias gke='\gitk --all $(git log -g --pretty=%h) &!'
+
+alias gl='git pull'
+alias glg='git log --stat'
+alias glgp='git log --stat -p'
+alias glgg='git log --graph'
+alias glgga='git log --graph --decorate --all'
+alias glgm='git log --graph --max-count=10'
+alias glo='git log --oneline --decorate'
+alias glol="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'"
+alias glols="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --stat"
+alias glod="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset'"
+alias glods="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' --date=short"
+alias glola="git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --all"
+alias glog='git log --oneline --decorate --graph'
+alias gloga='git log --oneline --decorate --graph --all'
+alias glp="_git_log_prettily"
+
+alias gm='git merge'
+alias gmom='git merge origin/$(git_main_branch)'
+alias gmtl='git mergetool --no-prompt'
+alias gmtlvim='git mergetool --no-prompt --tool=vimdiff'
+alias gmum='git merge upstream/$(git_main_branch)'
+alias gma='git merge --abort'
+
+alias gp='git push'
+alias gpd='git push --dry-run'
+alias gpf='git push --force-with-lease'
+alias gpf!='git push --force'
+alias gpoat='git push origin --all && git push origin --tags'
+alias gpr='git pull --rebase'
+alias gpu='git push upstream'
+alias gpv='git push -v'
+
+alias gr='git remote'
+alias gra='git remote add'
+alias grb='git rebase'
+alias grba='git rebase --abort'
+alias grbc='git rebase --continue'
+alias grbd='git rebase $(git_develop_branch)'
+alias grbi='git rebase -i'
+alias grbm='git rebase $(git_main_branch)'
+alias grbom='git rebase origin/$(git_main_branch)'
+alias grbo='git rebase --onto'
+alias grbs='git rebase --skip'
+alias grev='git revert'
+alias grh='git reset'
+alias grhh='git reset --hard'
+alias groh='git reset origin/$(git_current_branch) --hard'
+alias grm='git rm'
+alias grmc='git rm --cached'
+alias grmv='git remote rename'
+alias grrm='git remote remove'
+alias grs='git restore'
+alias grset='git remote set-url'
+alias grss='git restore --source'
+alias grst='git restore --staged'
+alias grt='cd "$(git rev-parse --show-toplevel || echo .)"'
+alias gru='git reset --'
+alias grup='git remote update'
+alias grv='git remote -v'
+
+alias gsb='git status -sb'
+alias gsd='git svn dcommit'
+alias gsh='git show'
+alias gsi='git submodule init'
+alias gsps='git show --pretty=short --show-signature'
+alias gsr='git svn rebase'
+alias gss='git status -s'
+alias gst='git status'
+
+# use the default stash push on git 2.13 and newer
+is-at-least 2.13 "$git_version" \
+  && alias gsta='git stash push' \
+  || alias gsta='git stash save'
+
+alias gstaa='git stash apply'
+alias gstc='git stash clear'
+alias gstd='git stash drop'
+alias gstl='git stash list'
+alias gstp='git stash pop'
+alias gsts='git stash show --text'
+alias gstu='gsta --include-untracked'
+alias gstall='git stash --all'
+alias gsu='git submodule update'
+alias gsw='git switch'
+alias gswc='git switch -c'
+alias gswm='git switch $(git_main_branch)'
+alias gswd='git switch $(git_develop_branch)'
+
+alias gts='git tag -s'
+alias gtv='git tag | sort -V'
+alias gtl='gtl(){ git tag --sort=-v:refname -n -l "${1}*" }; noglob gtl'
+
+alias gunignore='git update-index --no-assume-unchanged'
+alias gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1'
+alias gup='git pull --rebase'
+alias gupv='git pull --rebase -v'
+alias gupa='git pull --rebase --autostash'
+alias gupav='git pull --rebase --autostash -v'
+alias gupom='git pull --rebase origin $(git_main_branch)'
+alias gupomi='git pull --rebase=interactive origin $(git_main_branch)'
+alias glum='git pull upstream $(git_main_branch)'
+alias gluc='git pull upstream $(git_current_branch)'
+
+alias gwch='git whatchanged -p --abbrev-commit --pretty=medium'
+alias gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]"'
+
+alias gam='git am'
+alias gamc='git am --continue'
+alias gams='git am --skip'
+alias gama='git am --abort'
+alias gamscp='git am --show-current-patch'
+
+function grename() {
+  if [[ -z "$1" || -z "$2" ]]; then
+    echo "Usage: $0 old_branch new_branch"
+    return 1
+  fi
+
+  # Rename branch locally
+  git branch -m "$1" "$2"
+  # Rename branch in origin remote
+  if git push origin :"$1"; then
+    git push --set-upstream origin "$2"
+  fi
+}
+
+unset git_version
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/README.md
new file mode 100644 (file)
index 0000000..fed4b12
--- /dev/null
@@ -0,0 +1,15 @@
+# Gitfast plugin
+
+This plugin adds completion for Git, using the zsh completion from git.git folks, which is much faster than the official one from zsh. A lot of zsh-specific features are not supported, like descriptions for every argument, but everything the bash completion has, this one does too (as it is using it behind the scenes). Not only is it faster, it should be more robust, and updated regularly to the latest git upstream version.
+
+To use it, add `gitfast` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... gitfast)
+```
+
+## Aliases
+
+An earlier version of the plugin also loaded the git plugin. If you want to keep those
+aliases enable the [git plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git)
+as well.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/_git b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/_git
new file mode 100644 (file)
index 0000000..31bf88c
--- /dev/null
@@ -0,0 +1,286 @@
+#compdef git gitk
+
+# zsh completion wrapper for git
+#
+# Copyright (c) 2012-2020 Felipe Contreras <felipe.contreras@gmail.com>
+#
+# The recommended way to install this script is to make a copy of it as a
+# file named '_git' inside any directory in your fpath.
+#
+# For example, create a directory '~/.zsh/', copy this file to '~/.zsh/_git',
+# and then add the following to your ~/.zshrc file:
+#
+#  fpath=(~/.zsh $fpath)
+#
+# You need git's bash completion script installed. By default bash-completion's
+# location will be used (e.g. pkg-config --variable=completionsdir bash-completion).
+#
+# If your bash completion script is somewhere else, you can specify the
+# location in your ~/.zshrc:
+#
+#  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
+#
+
+zstyle -T ':completion:*:*:git:*' tag-order && \
+       zstyle ':completion:*:*:git:*' tag-order 'common-commands'
+
+zstyle -s ":completion:*:*:git:*" script script
+if [ -z "$script" ]; then
+       local -a locations
+       local e bash_completion
+
+       bash_completion=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null) ||
+               bash_completion='/usr/share/bash-completion/completions/'
+
+       locations=(
+               "${${funcsourcetrace[1]%:*}:A:h}"/git-completion.bash
+               "$HOME/.local/share/bash-completion/completions/git"
+               '/usr/local/share/bash-completion/completions/git'
+               "$bash_completion/git"
+               '/etc/bash_completion.d/git' # old debian
+               )
+       for e in $locations; do
+               test -f $e && script="$e" && break
+       done
+fi
+
+local old_complete="$functions[complete]"
+functions[complete]=:
+COMP_WORDBREAKS=':'
+GIT_SOURCING_ZSH_COMPLETION=y . "$script"
+functions[complete]="$old_complete"
+
+__gitcompadd ()
+{
+       compadd -p "${2-}" -S "${3- }" -q -- ${=1} && _ret=0
+}
+
+__gitcomp ()
+{
+       emulate -L zsh
+
+       IFS=$' \t\n' __gitcompadd "$1" "${2-}" "${4- }"
+}
+
+__gitcomp_opts ()
+{
+       emulate -L zsh
+
+       local cur_="${3-$cur}"
+
+       [[ "$cur_" == *= ]] && return
+
+       local c IFS=$' \t\n' sfx
+       for c in ${=1}; do
+               if [[ $c == "--" ]]; then
+                       [[ "$cur_" == --no-* ]] && continue
+                       __gitcompadd "--no-..."
+                       break
+               fi
+
+               if [[ -z "${4+set}" ]]; then
+                       case $c in
+                       *=) c="${c%=}"; sfx="=" ;;
+                       *.) sfx="" ;;
+                       *) sfx=" " ;;
+                       esac
+               else
+                       sfx="$4"
+               fi
+               __gitcompadd "$c" "${2-}" "$sfx"
+       done
+}
+
+__gitcomp_nl ()
+{
+       emulate -L zsh
+
+       # words that don't end up in space
+       compadd -p "${2-}" -S "${4- }" -q -- ${${(f)1}:#*\ } && _ret=0
+       # words that end in space
+       compadd -p "${2-}" -S " ${4- }" -q -- ${${(M)${(f)1}:#*\ }% } && _ret=0
+}
+
+__gitcomp_file ()
+{
+       emulate -L zsh
+
+       compadd -f -p "${2-}" -- ${(f)1} && _ret=0
+}
+
+__gitcomp_direct ()
+{
+       __gitcomp_nl "$1" "" "" ""
+}
+
+__gitcomp_file_direct ()
+{
+       __gitcomp_file "$1" ""
+}
+
+__git_complete_command ()
+{
+       emulate -L zsh
+
+       compset -P '*[=:]'
+
+       local command="$1"
+       local completion_func="_git_${command//-/_}"
+       if (( $+functions[$completion_func] )); then
+               emulate ksh -c $completion_func
+               return 0
+       elif emulate ksh -c "__git_support_parseopt_helper $command"; then
+               emulate ksh -c "__git_complete_common $command"
+               return 0
+       else
+               return 1
+       fi
+}
+
+__git_zsh_bash_func ()
+{
+       emulate -L ksh
+
+       local command=$1
+
+       __git_complete_command "$command" && return
+
+       local expansion=$(__git_aliased_command "$command")
+       if [ -n "$expansion" ]; then
+               words[1]=$expansion
+               __git_complete_command "$expansion"
+       fi
+}
+
+__git_zsh_cmd_common ()
+{
+       local -a list
+       list=(
+       add:'add file contents to the index'
+       bisect:'find by binary search the change that introduced a bug'
+       branch:'list, create, or delete branches'
+       checkout:'checkout a branch or paths to the working tree'
+       clone:'clone a repository into a new directory'
+       commit:'record changes to the repository'
+       diff:'show changes between commits, commit and working tree, etc'
+       fetch:'download objects and refs from another repository'
+       grep:'print lines matching a pattern'
+       init:'create an empty Git repository or reinitialize an existing one'
+       log:'show commit logs'
+       merge:'join two or more development histories together'
+       mv:'move or rename a file, a directory, or a symlink'
+       pull:'fetch from and merge with another repository or a local branch'
+       push:'update remote refs along with associated objects'
+       rebase:'forward-port local commits to the updated upstream head'
+       reset:'reset current HEAD to the specified state'
+       restore:'restore working tree files'
+       rm:'remove files from the working tree and from the index'
+       show:'show various types of objects'
+       status:'show the working tree status'
+       switch:'switch branches'
+       tag:'create, list, delete or verify a tag object signed with GPG')
+       _describe -t common-commands 'common commands' list && _ret=0
+}
+
+__git_zsh_cmd_alias ()
+{
+       local -a list
+       list=(${${(0)"$(git config -z --get-regexp '^alias\.*')"}#alias.})
+       list=(${(f)"$(printf "%s:alias for '%s'\n" ${(f@)list})"})
+       _describe -t alias-commands 'aliases' list && _ret=0
+}
+
+__git_zsh_cmd_all ()
+{
+       local -a list
+       emulate ksh -c __git_compute_all_commands
+       list=( ${=__git_all_commands} )
+       _describe -t all-commands 'all commands' list && _ret=0
+}
+
+__git_zsh_main ()
+{
+       local curcontext="$curcontext" state state_descr line
+       typeset -A opt_args
+       local -a __git_C_args
+
+       _arguments -C \
+               '(-p --paginate -P --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \
+               '(-p --paginate -P --no-pager)'{-P,--no-pager}'[do not pipe git output into a pager]' \
+               '(--bare)--git-dir=[set the path to the repository]: :_directories' \
+               '(--git-dir)--bare[treat the repository as a bare repository]' \
+               '(- :)--version[prints the git suite version]' \
+               '--exec-path=[path to where your core git programs are installed]: :_directories' \
+               '(- :)--exec-path[print the path where your core git programs are installed]' \
+               '(- :)--html-path[print the path where git''s HTML documentation is installed]' \
+               '(- :)--info-path[print the path where the Info files are installed]' \
+               '(- :)--man-path[print the manpath (see `man(1)`) for the man pages]' \
+               '--work-tree=[set the path to the working tree]: :_directories' \
+               '--namespace=[set the git namespace]:' \
+               '--no-replace-objects[do not use replacement refs to replace git objects]' \
+               '(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \
+               '*-C[run as if git was started in the given path]: :_directories' \
+               '*-c[pass a configuration parameter to the command]: :->config' \
+               '(-): :->command' \
+               '(-)*:: :->arg' && return
+
+       case $state in
+       (command)
+               _tags common-commands alias-commands all-commands
+               while _tags; do
+                       _requested common-commands && __git_zsh_cmd_common
+                       _requested alias-commands && __git_zsh_cmd_alias
+                       _requested all-commands && __git_zsh_cmd_all
+                       let _ret || break
+               done
+               ;;
+       (config)
+               compset -P '*[=:]'
+               emulate ksh -c __git_complete_config_variable_name_and_value
+               ;;
+       (arg)
+               local command="${words[1]}" __git_dir __git_cmd_idx=1
+
+               if (( $+opt_args[--bare] )); then
+                       __git_dir='.'
+               else
+                       __git_dir=${~opt_args[--git-dir]}
+               fi
+
+               for x in ${(s.:.)opt_args[-C]}; do
+                       __git_C_args+=('-C' ${~x})
+               done
+
+               (( $+opt_args[--help] )) && command='help'
+
+               words=( git ${words[@]} )
+
+               __git_zsh_bash_func $command
+               ;;
+       esac
+}
+
+_git ()
+{
+       local _ret=1
+       local cur cword prev __git_cmd_idx=0
+
+       cur=${words[CURRENT]}
+       prev=${words[CURRENT-1]}
+       let cword=CURRENT-1
+
+       if (( $+functions[__${service}_zsh_main] )); then
+               __${service}_zsh_main
+       elif (( $+functions[__${service}_main] )); then
+               emulate ksh -c __${service}_main
+       elif (( $+functions[_${service}] )); then
+               emulate ksh -c _${service}
+       elif (( $+functions[_${service//-/_}] )); then
+               emulate ksh -c _${service//-/_}
+       fi
+
+       let _ret && _default && _ret=0
+       return _ret
+}
+
+_git
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/git-completion.bash b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/git-completion.bash
new file mode 100644 (file)
index 0000000..dd06b50
--- /dev/null
@@ -0,0 +1,3677 @@
+# bash/zsh completion support for core Git.
+#
+# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
+# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
+# Distributed under the GNU General Public License, version 2.0.
+#
+# The contained completion routines provide support for completing:
+#
+#    *) local and remote branch names
+#    *) local and remote tag names
+#    *) .git/remotes file names
+#    *) git 'subcommands'
+#    *) git email aliases for git-send-email
+#    *) tree paths within 'ref:path/to/file' expressions
+#    *) file paths within current working directory and index
+#    *) common --long-options
+#
+# To use these routines:
+#
+#    1) Copy this file to somewhere (e.g. ~/.git-completion.bash).
+#    2) Add the following line to your .bashrc/.zshrc:
+#        source ~/.git-completion.bash
+#    3) Consider changing your PS1 to also show the current branch,
+#       see git-prompt.sh for details.
+#
+# If you use complex aliases of form '!f() { ... }; f', you can use the null
+# command ':' as the first command in the function body to declare the desired
+# completion style.  For example '!f() { : git commit ; ... }; f' will
+# tell the completion to use commit completion.  This also works with aliases
+# of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".
+#
+# If you have a command that is not part of git, but you would still
+# like completion, you can use __git_complete:
+#
+#   __git_complete gl git_log
+#
+# Or if it's a main command (i.e. git or gitk):
+#
+#   __git_complete gk gitk
+#
+# Compatible with bash 3.2.57.
+#
+# You can set the following environment variables to influence the behavior of
+# the completion routines:
+#
+#   GIT_COMPLETION_CHECKOUT_NO_GUESS
+#
+#     When set to "1", do not include "DWIM" suggestions in git-checkout
+#     and git-switch completion (e.g., completing "foo" when "origin/foo"
+#     exists).
+#
+#   GIT_COMPLETION_SHOW_ALL_COMMANDS
+#
+#     When set to "1" suggest all commands, including plumbing commands
+#     which are hidden by default (e.g. "cat-file" on "git ca<TAB>").
+#
+#   GIT_COMPLETION_SHOW_ALL
+#
+#     When set to "1" suggest all options, including options which are
+#     typically hidden (e.g. '--allow-empty' for 'git commit').
+
+# The following functions are meant to modify COMPREPLY, which should not be
+# modified directly.  The purpose is to localize the modifications so it's
+# easier to emulate it in Zsh. Every time a new __gitcomp* function is added,
+# the corresponding function should be added to Zsh.
+
+__gitcompadd ()
+{
+       local x i=${#COMPREPLY[@]}
+       for x in $1; do
+               if [[ "$x" == "$3"* ]]; then
+                       COMPREPLY[i++]="$2$x$4"
+               fi
+       done
+}
+
+# Creates completion replies.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word (optional).
+__gitcomp ()
+{
+       local IFS=$' \t\n'
+       __gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
+}
+
+# Generates completion reply from newline-separated possible completion words
+# by appending a space to all of them. The result is appended to COMPREPLY.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words, separated by a single newline.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word instead of
+#    the default space (optional).  If specified but empty, nothing is
+#    appended.
+__gitcomp_nl ()
+{
+       local IFS=$'\n'
+       __gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }"
+}
+
+# Appends prefiltered words to COMPREPLY without any additional processing.
+# Callers must take care of providing only words that match the current word
+# to be completed and adding any prefix and/or suffix (trailing space!), if
+# necessary.
+# 1: List of newline-separated matching completion words, complete with
+#    prefix and suffix.
+__gitcomp_direct ()
+{
+       local IFS=$'\n'
+
+       COMPREPLY+=($1)
+}
+
+# Generates completion reply with compgen from newline-separated possible
+# completion filenames.
+# It accepts 1 to 3 arguments:
+# 1: List of possible completion filenames, separated by a single newline.
+# 2: A directory prefix to be added to each possible completion filename
+#    (optional).
+# 3: Generate possible completion matches for this word (optional).
+__gitcomp_file ()
+{
+       local IFS=$'\n'
+
+       # XXX does not work when the directory prefix contains a tilde,
+       # since tilde expansion is not applied.
+       # This means that COMPREPLY will be empty and Bash default
+       # completion will be used.
+       __gitcompadd "$1" "${2-}" "${3-$cur}" ""
+
+       # use a hack to enable file mode in bash < 4
+       compopt -o filenames +o nospace 2>/dev/null ||
+       compgen -f /non-existing-dir/ >/dev/null ||
+       true
+}
+
+# Fills the COMPREPLY array with prefiltered paths without any additional
+# processing.
+# Callers must take care of providing only paths that match the current path
+# to be completed and adding any prefix path components, if necessary.
+# 1: List of newline-separated matching paths, complete with all prefix
+#    path components.
+__gitcomp_file_direct ()
+{
+       local IFS=$'\n'
+
+       COMPREPLY+=($1)
+
+       # use a hack to enable file mode in bash < 4
+       compopt -o filenames +o nospace 2>/dev/null ||
+       compgen -f /non-existing-dir/ >/dev/null ||
+       true
+}
+
+# Creates completion replies, reorganizing options and adding suffixes as needed.
+# It accepts 1 to 4 arguments:
+# 1: List of possible completion words.
+# 2: A prefix to be added to each possible completion word (optional).
+# 3: Generate possible completion matches for this word (optional).
+# 4: A suffix to be appended to each possible completion word (optional).
+__gitcomp_opts ()
+{
+       local cur_="${3-$cur}"
+
+       if [[ "$cur_" == *= ]]; then
+               return
+       fi
+
+       local c i=0 IFS=$' \t\n' sfx
+       for c in $1; do
+               if [[ $c == "--" ]]; then
+                       if [[ "$cur_" == --no-* ]]; then
+                               continue
+                       fi
+
+                       if [[ --no == "$cur_"* ]]; then
+                               COMPREPLY[i++]="--no-... "
+                       fi
+                       break
+               fi
+               if [[ $c == "$cur_"* ]]; then
+                       if [[ -z "${4+set}" ]]; then
+                               case $c in
+                               *=|*.) sfx="" ;;
+                               *) sfx=" " ;;
+                               esac
+                       else
+                               sfx="$4"
+                       fi
+                       COMPREPLY[i++]="${2-}$c$sfx"
+               fi
+       done
+}
+
+# __gitcomp functions end here
+# ==============================================================================
+
+# Discovers the path to the git repository taking any '--git-dir=<path>' and
+# '-C <path>' options into account and stores it in the $__git_repo_path
+# variable.
+__git_find_repo_path ()
+{
+       if [ -n "${__git_repo_path-}" ]; then
+               # we already know where it is
+               return
+       fi
+
+       if [ -n "${__git_C_args-}" ]; then
+               __git_repo_path="$(git "${__git_C_args[@]}" \
+                       ${__git_dir:+--git-dir="$__git_dir"} \
+                       rev-parse --absolute-git-dir 2>/dev/null)"
+       elif [ -n "${__git_dir-}" ]; then
+               test -d "$__git_dir" &&
+               __git_repo_path="$__git_dir"
+       elif [ -n "${GIT_DIR-}" ]; then
+               test -d "$GIT_DIR" &&
+               __git_repo_path="$GIT_DIR"
+       elif [ -d .git ]; then
+               __git_repo_path=.git
+       else
+               __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)"
+       fi
+}
+
+# Deprecated: use __git_find_repo_path() and $__git_repo_path instead
+# __gitdir accepts 0 or 1 arguments (i.e., location)
+# returns location of .git repo
+__gitdir ()
+{
+       if [ -z "${1-}" ]; then
+               __git_find_repo_path || return 1
+               echo "$__git_repo_path"
+       elif [ -d "$1/.git" ]; then
+               echo "$1/.git"
+       else
+               echo "$1"
+       fi
+}
+
+# Runs git with all the options given as argument, respecting any
+# '--git-dir=<path>' and '-C <path>' options present on the command line
+__git ()
+{
+       git ${__git_C_args:+"${__git_C_args[@]}"} \
+               ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null
+}
+
+# Removes backslash escaping, single quotes and double quotes from a word,
+# stores the result in the variable $dequoted_word.
+# 1: The word to dequote.
+__git_dequote ()
+{
+       local rest="$1" len ch
+
+       dequoted_word=""
+
+       while test -n "$rest"; do
+               len=${#dequoted_word}
+               dequoted_word="$dequoted_word${rest%%[\\\'\"]*}"
+               rest="${rest:$((${#dequoted_word}-$len))}"
+
+               case "${rest:0:1}" in
+               \\)
+                       ch="${rest:1:1}"
+                       case "$ch" in
+                       $'\n')
+                               ;;
+                       *)
+                               dequoted_word="$dequoted_word$ch"
+                               ;;
+                       esac
+                       rest="${rest:2}"
+                       ;;
+               \')
+                       rest="${rest:1}"
+                       len=${#dequoted_word}
+                       dequoted_word="$dequoted_word${rest%%\'*}"
+                       rest="${rest:$((${#dequoted_word}-$len+1))}"
+                       ;;
+               \")
+                       rest="${rest:1}"
+                       while test -n "$rest" ; do
+                               len=${#dequoted_word}
+                               dequoted_word="$dequoted_word${rest%%[\\\"]*}"
+                               rest="${rest:$((${#dequoted_word}-$len))}"
+                               case "${rest:0:1}" in
+                               \\)
+                                       ch="${rest:1:1}"
+                                       case "$ch" in
+                                       \"|\\|\$|\`)
+                                               dequoted_word="$dequoted_word$ch"
+                                               ;;
+                                       $'\n')
+                                               ;;
+                                       *)
+                                               dequoted_word="$dequoted_word\\$ch"
+                                               ;;
+                                       esac
+                                       rest="${rest:2}"
+                                       ;;
+                               \")
+                                       rest="${rest:1}"
+                                       break
+                                       ;;
+                               esac
+                       done
+                       ;;
+               esac
+       done
+}
+
+# Clear the variables caching builtins' options when (re-)sourcing
+# the completion script.
+if [[ -n ${ZSH_VERSION-} ]]; then
+       unset ${(M)${(k)parameters[@]}:#__gitcomp_builtin_*} 2>/dev/null
+else
+       unset $(compgen -v __gitcomp_builtin_)
+fi
+
+__gitcomp_builtin_add_default=" --dry-run --verbose --interactive --patch --edit --force --update --renormalize --intent-to-add --all --ignore-removal --refresh --ignore-errors --ignore-missing --sparse --chmod= --pathspec-from-file= --pathspec-file-nul --no-dry-run -- --no-verbose --no-interactive --no-patch --no-edit --no-force --no-update --no-renormalize --no-intent-to-add --no-all --no-ignore-removal --no-refresh --no-ignore-errors --no-ignore-missing --no-sparse --no-chmod --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_am_default=" --interactive --3way --quiet --signoff --utf8 --keep --keep-non-patch --message-id --keep-cr --no-keep-cr --scissors --quoted-cr= --whitespace= --ignore-space-change --ignore-whitespace --directory= --exclude= --include= --patch-format= --reject --resolvemsg= --continue --resolved --skip --abort --quit --show-current-patch --allow-empty --committer-date-is-author-date --ignore-date --rerere-autoupdate --gpg-sign --empty= -- --no-interactive --no-3way --no-quiet --no-signoff --no-utf8 --no-keep --no-keep-non-patch --no-message-id --no-scissors --no-whitespace --no-ignore-space-change --no-ignore-whitespace --no-directory --no-exclude --no-include --no-patch-format --no-reject --no-resolvemsg --no-committer-date-is-author-date --no-ignore-date --no-rerere-autoupdate --no-gpg-sign"
+__gitcomp_builtin_apply_default=" --exclude= --include= --no-add --stat --numstat --summary --check --index --intent-to-add --cached --apply --3way --build-fake-ancestor= --whitespace= --ignore-space-change --ignore-whitespace --reverse --unidiff-zero --reject --allow-overlap --verbose --quiet --inaccurate-eof --recount --directory= --allow-empty --add -- --no-stat --no-numstat --no-summary --no-check --no-index --no-intent-to-add --no-cached --no-apply --no-3way --no-build-fake-ancestor --no-whitespace --no-ignore-space-change --no-ignore-whitespace --no-reverse --no-unidiff-zero --no-reject --no-allow-overlap --no-verbose --no-quiet --no-inaccurate-eof --no-recount --no-directory --no-allow-empty"
+__gitcomp_builtin_archive_default=" --output= --remote= --exec= --no-output -- --no-remote --no-exec"
+__gitcomp_builtin_bisect__helper_default=" --bisect-reset --bisect-next-check --bisect-terms --bisect-start --bisect-next --bisect-state --bisect-log --bisect-replay --bisect-skip --bisect-visualize --bisect-run --no-log --log"
+__gitcomp_builtin_blame_default=" --incremental --root --show-stats --progress --score-debug --show-name --show-number --porcelain --line-porcelain --show-email --ignore-rev= --ignore-revs-file= --color-lines --color-by-age --minimal --contents= --abbrev --no-incremental -- --no-root --no-show-stats --no-progress --no-score-debug --no-show-name --no-show-number --no-porcelain --no-line-porcelain --no-show-email --no-ignore-rev --no-ignore-revs-file --no-color-lines --no-color-by-age --no-minimal --no-contents --no-abbrev"
+__gitcomp_builtin_branch_default=" --verbose --quiet --track --set-upstream-to= --unset-upstream --color --remotes --contains --no-contains --abbrev --all --delete --move --copy --list --show-current --create-reflog --edit-description --merged --no-merged --column --sort= --points-at= --ignore-case --recurse-submodules --format= -- --no-verbose --no-quiet --no-track --no-set-upstream-to --no-unset-upstream --no-color --no-remotes --no-abbrev --no-all --no-delete --no-move --no-copy --no-list --no-show-current --no-create-reflog --no-edit-description --no-column --no-sort --no-points-at --no-ignore-case --no-recurse-submodules --no-format"
+__gitcomp_builtin_bugreport_default=" --output-directory= --suffix= --no-output-directory -- --no-suffix"
+__gitcomp_builtin_cat_file_default=" --allow-unknown-type --batch --batch-check --batch-command --batch-all-objects --buffer --follow-symlinks --unordered --textconv --filters --path= --no-allow-unknown-type -- --no-buffer --no-follow-symlinks --no-unordered --no-path"
+__gitcomp_builtin_check_attr_default=" --all --cached --stdin --no-all -- --no-cached --no-stdin"
+__gitcomp_builtin_check_ignore_default=" --quiet --verbose --stdin --non-matching --no-index --index -- --no-quiet --no-verbose --no-stdin --no-non-matching"
+__gitcomp_builtin_check_mailmap_default=" --stdin --no-stdin"
+__gitcomp_builtin_checkout_default=" --guess --overlay --quiet --recurse-submodules --progress --merge --conflict= --detach --track --orphan= --ignore-other-worktrees --ours --theirs --patch --ignore-skip-worktree-bits --pathspec-from-file= --pathspec-file-nul --no-guess -- --no-overlay --no-quiet --no-recurse-submodules --no-progress --no-merge --no-conflict --no-detach --no-track --no-orphan --no-ignore-other-worktrees --no-patch --no-ignore-skip-worktree-bits --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_checkout__worker_default=" --prefix= --no-prefix"
+__gitcomp_builtin_checkout_index_default=" --all --ignore-skip-worktree-bits --force --quiet --no-create --index --stdin --temp --prefix= --stage= --create -- --no-all --no-ignore-skip-worktree-bits --no-force --no-quiet --no-index --no-stdin --no-temp --no-prefix"
+__gitcomp_builtin_cherry_default=" --abbrev --verbose --no-abbrev -- --no-verbose"
+__gitcomp_builtin_cherry_pick_default=" --quit --continue --abort --skip --cleanup= --no-commit --edit --signoff --mainline= --rerere-autoupdate --strategy= --strategy-option= --gpg-sign --ff --allow-empty --allow-empty-message --keep-redundant-commits --commit -- --no-cleanup --no-edit --no-signoff --no-mainline --no-rerere-autoupdate --no-strategy --no-strategy-option --no-gpg-sign --no-ff --no-allow-empty --no-allow-empty-message --no-keep-redundant-commits"
+__gitcomp_builtin_clean_default=" --quiet --dry-run --interactive --exclude= --no-quiet -- --no-dry-run --no-interactive"
+__gitcomp_builtin_clone_default=" --verbose --quiet --progress --reject-shallow --no-checkout --bare --mirror --local --no-hardlinks --shared --recurse-submodules --jobs= --template= --reference= --reference-if-able= --dissociate --origin= --branch= --upload-pack= --depth= --shallow-since= --shallow-exclude= --single-branch --no-tags --shallow-submodules --separate-git-dir= --config= --server-option= --ipv4 --ipv6 --filter= --also-filter-submodules --remote-submodules --sparse --checkout --hardlinks --tags -- --no-verbose --no-quiet --no-progress --no-reject-shallow --no-bare --no-mirror --no-local --no-shared --no-recurse-submodules --no-recursive --no-jobs --no-template --no-reference --no-reference-if-able --no-dissociate --no-origin --no-branch --no-upload-pack --no-depth --no-shallow-since --no-shallow-exclude --no-single-branch --no-shallow-submodules --no-separate-git-dir --no-config --no-server-option --no-ipv4 --no-ipv6 --no-filter --no-also-filter-submodules --no-remote-submodules --no-sparse"
+__gitcomp_builtin_column_default=" --command= --mode --raw-mode= --width= --indent= --nl= --padding= --no-command -- --no-mode --no-raw-mode --no-width --no-indent --no-nl --no-padding"
+__gitcomp_builtin_commit_default=" --quiet --verbose --file= --author= --date= --message= --reedit-message= --reuse-message= --fixup= --squash= --reset-author --trailer= --signoff --template= --edit --cleanup= --status --gpg-sign --all --include --interactive --patch --only --no-verify --dry-run --short --branch --ahead-behind --porcelain --long --null --amend --no-post-rewrite --untracked-files --pathspec-from-file= --pathspec-file-nul --verify --post-rewrite -- --no-quiet --no-verbose --no-file --no-author --no-date --no-message --no-reedit-message --no-reuse-message --no-fixup --no-squash --no-reset-author --no-signoff --no-template --no-edit --no-cleanup --no-status --no-gpg-sign --no-all --no-include --no-interactive --no-patch --no-only --no-dry-run --no-short --no-branch --no-ahead-behind --no-porcelain --no-long --no-null --no-amend --no-untracked-files --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_commit_graph_default=" --object-dir= --no-object-dir"
+__gitcomp_builtin_config_default=" --global --system --local --worktree --file= --blob= --get --get-all --get-regexp --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section --list --fixed-value --edit --get-color --get-colorbool --type= --bool --int --bool-or-int --bool-or-str --path --expiry-date --null --name-only --includes --show-origin --show-scope --default= --no-global -- --no-system --no-local --no-worktree --no-file --no-blob --no-get --no-get-all --no-get-regexp --no-get-urlmatch --no-replace-all --no-add --no-unset --no-unset-all --no-rename-section --no-remove-section --no-list --no-fixed-value --no-edit --no-get-color --no-get-colorbool --no-type --no-null --no-name-only --no-includes --no-show-origin --no-show-scope --no-default"
+__gitcomp_builtin_count_objects_default=" --verbose --human-readable --no-verbose -- --no-human-readable"
+__gitcomp_builtin_credential_cache_default=" --timeout= --socket= --no-timeout -- --no-socket"
+__gitcomp_builtin_credential_cache__daemon_default=" --debug --no-debug"
+__gitcomp_builtin_credential_store_default=" --file= --no-file"
+__gitcomp_builtin_describe_default=" --contains --debug --all --tags --long --first-parent --abbrev --exact-match --candidates= --match= --exclude= --always --dirty --broken --no-contains -- --no-debug --no-all --no-tags --no-long --no-first-parent --no-abbrev --no-exact-match --no-candidates --no-match --no-exclude --no-always --no-dirty --no-broken"
+__gitcomp_builtin_difftool_default=" --gui --dir-diff --no-prompt --symlinks --tool= --tool-help --trust-exit-code --extcmd= --no-index --index -- --no-gui --no-dir-diff --no-symlinks --no-tool --no-tool-help --no-trust-exit-code --no-extcmd"
+__gitcomp_builtin_env__helper_default=" --type= --default= --exit-code --no-default -- --no-exit-code"
+__gitcomp_builtin_fast_export_default=" --progress= --signed-tags= --tag-of-filtered-object= --reencode= --export-marks= --import-marks= --import-marks-if-exists= --fake-missing-tagger --full-tree --use-done-feature --no-data --refspec= --anonymize --anonymize-map= --reference-excluded-parents --show-original-ids --mark-tags --data -- --no-progress --no-signed-tags --no-tag-of-filtered-object --no-reencode --no-export-marks --no-import-marks --no-import-marks-if-exists --no-fake-missing-tagger --no-full-tree --no-use-done-feature --no-refspec --no-anonymize --no-reference-excluded-parents --no-show-original-ids --no-mark-tags"
+__gitcomp_builtin_fetch_default=" --verbose --quiet --all --set-upstream --append --atomic --upload-pack= --force --multiple --tags --jobs= --prefetch --prune --prune-tags --recurse-submodules --dry-run --write-fetch-head --keep --update-head-ok --progress --depth= --shallow-since= --shallow-exclude= --deepen= --unshallow --refetch --update-shallow --refmap= --server-option= --ipv4 --ipv6 --negotiation-tip= --negotiate-only --filter= --auto-maintenance --auto-gc --show-forced-updates --write-commit-graph --stdin --no-verbose -- --no-quiet --no-all --no-set-upstream --no-append --no-atomic --no-upload-pack --no-force --no-multiple --no-tags --no-jobs --no-prefetch --no-prune --no-prune-tags --no-recurse-submodules --no-dry-run --no-write-fetch-head --no-keep --no-update-head-ok --no-progress --no-depth --no-shallow-since --no-shallow-exclude --no-deepen --no-update-shallow --no-server-option --no-ipv4 --no-ipv6 --no-negotiation-tip --no-negotiate-only --no-filter --no-auto-maintenance --no-auto-gc --no-show-forced-updates --no-write-commit-graph --no-stdin"
+__gitcomp_builtin_fmt_merge_msg_default=" --log --message= --into-name= --file= --no-log -- --no-message --no-into-name --no-file"
+__gitcomp_builtin_for_each_ref_default=" --shell --perl --python --tcl --count= --format= --color --sort= --points-at= --merged --no-merged --contains --no-contains --ignore-case -- --no-shell --no-perl --no-python --no-tcl --no-count --no-format --no-color --no-sort --no-points-at --no-ignore-case"
+__gitcomp_builtin_for_each_repo_default=" --config= --no-config"
+__gitcomp_builtin_format_patch_default=" --numbered --no-numbered --signoff --stdout --cover-letter --numbered-files --suffix= --start-number= --reroll-count= --filename-max-length= --rfc --cover-from-description= --subject-prefix= --output-directory= --keep-subject --no-binary --zero-commit --ignore-if-in-upstream --no-stat --add-header= --to= --cc= --from --in-reply-to= --attach --inline --thread --signature= --base= --signature-file= --quiet --progress --interdiff= --range-diff= --creation-factor= --binary -- --no-numbered --no-signoff --no-stdout --no-cover-letter --no-numbered-files --no-suffix --no-start-number --no-reroll-count --no-filename-max-length --no-cover-from-description --no-zero-commit --no-ignore-if-in-upstream --no-add-header --no-to --no-cc --no-from --no-in-reply-to --no-attach --no-thread --no-signature --no-base --no-signature-file --no-quiet --no-progress --no-interdiff --no-range-diff --no-creation-factor"
+__gitcomp_builtin_fsck_default=" --verbose --unreachable --dangling --tags --root --cache --reflogs --full --connectivity-only --strict --lost-found --progress --name-objects --no-verbose -- --no-unreachable --no-dangling --no-tags --no-root --no-cache --no-reflogs --no-full --no-connectivity-only --no-strict --no-lost-found --no-progress --no-name-objects"
+__gitcomp_builtin_fsck_objects_default=" --verbose --unreachable --dangling --tags --root --cache --reflogs --full --connectivity-only --strict --lost-found --progress --name-objects --no-verbose -- --no-unreachable --no-dangling --no-tags --no-root --no-cache --no-reflogs --no-full --no-connectivity-only --no-strict --no-lost-found --no-progress --no-name-objects"
+__gitcomp_builtin_fsmonitor__daemon_default=""
+__gitcomp_builtin_gc_default=" --quiet --prune --aggressive --keep-largest-pack --no-quiet -- --no-prune --no-aggressive --no-keep-largest-pack"
+__gitcomp_builtin_grep_default=" --cached --no-index --untracked --exclude-standard --recurse-submodules --invert-match --ignore-case --word-regexp --text --textconv --recursive --max-depth= --extended-regexp --basic-regexp --fixed-strings --perl-regexp --line-number --column --full-name --files-with-matches --name-only --files-without-match --only-matching --count --color --break --heading --context= --before-context= --after-context= --threads= --show-function --function-context --and --or --not --quiet --all-match --index -- --no-cached --no-untracked --no-exclude-standard --no-recurse-submodules --no-invert-match --no-ignore-case --no-word-regexp --no-text --no-textconv --no-recursive --no-extended-regexp --no-basic-regexp --no-fixed-strings --no-perl-regexp --no-line-number --no-column --no-full-name --no-files-with-matches --no-name-only --no-files-without-match --no-only-matching --no-count --no-color --no-break --no-heading --no-context --no-before-context --no-after-context --no-threads --no-show-function --no-function-context --no-or --no-quiet --no-all-match"
+__gitcomp_builtin_hash_object_default=" --stdin --stdin-paths --no-filters --literally --path= --filters -- --no-stdin --no-stdin-paths --no-literally --no-path"
+__gitcomp_builtin_help_default=" --all --external-commands --aliases --man --web --info --verbose --guides --config --no-external-commands -- --no-aliases --no-man --no-web --no-info --no-verbose"
+__gitcomp_builtin_hook_default=""
+__gitcomp_builtin_init_default=" --template= --bare --shared --quiet --separate-git-dir= --initial-branch= --object-format= --no-template -- --no-bare --no-quiet --no-separate-git-dir --no-initial-branch --no-object-format"
+__gitcomp_builtin_init_db_default=" --template= --bare --shared --quiet --separate-git-dir= --initial-branch= --object-format= --no-template -- --no-bare --no-quiet --no-separate-git-dir --no-initial-branch --no-object-format"
+__gitcomp_builtin_interpret_trailers_default=" --in-place --trim-empty --where= --if-exists= --if-missing= --only-trailers --only-input --unfold --parse --no-divider --trailer= --divider -- --no-in-place --no-trim-empty --no-where --no-if-exists --no-if-missing --no-only-trailers --no-only-input --no-unfold --no-trailer"
+__gitcomp_builtin_log_default=" --quiet --source --use-mailmap --decorate-refs= --decorate-refs-exclude= --decorate --no-quiet -- --no-source --no-use-mailmap --no-mailmap --no-decorate-refs --no-decorate-refs-exclude --no-decorate"
+__gitcomp_builtin_ls_files_default=" --cached --deleted --modified --others --ignored --stage --killed --directory --eol --empty-directory --unmerged --resolve-undo --exclude= --exclude-from= --exclude-per-directory= --exclude-standard --full-name --recurse-submodules --error-unmatch --with-tree= --abbrev --debug --deduplicate --sparse --no-cached -- --no-deleted --no-modified --no-others --no-ignored --no-stage --no-killed --no-directory --no-eol --no-empty-directory --no-unmerged --no-resolve-undo --no-exclude-per-directory --no-recurse-submodules --no-error-unmatch --no-with-tree --no-abbrev --no-debug --no-deduplicate --no-sparse"
+__gitcomp_builtin_ls_remote_default=" --quiet --upload-pack= --tags --heads --refs --get-url --sort= --symref --server-option= --no-quiet -- --no-upload-pack --no-tags --no-heads --no-refs --no-get-url --no-sort --no-symref --no-server-option"
+__gitcomp_builtin_ls_tree_default=" --long --name-only --name-status --object-only --full-name --full-tree --format= --abbrev --no-full-name -- --no-full-tree --no-abbrev"
+__gitcomp_builtin_merge_default=" --stat --summary --log --squash --commit --edit --cleanup= --ff --ff-only --rerere-autoupdate --verify-signatures --strategy= --strategy-option= --message= --file --into-name= --verbose --quiet --abort --quit --continue --allow-unrelated-histories --progress --gpg-sign --autostash --overwrite-ignore --signoff --no-verify --verify -- --no-stat --no-summary --no-log --no-squash --no-commit --no-edit --no-cleanup --no-ff --no-rerere-autoupdate --no-verify-signatures --no-strategy --no-strategy-option --no-message --no-into-name --no-verbose --no-quiet --no-abort --no-quit --no-continue --no-allow-unrelated-histories --no-progress --no-gpg-sign --no-autostash --no-overwrite-ignore --no-signoff"
+__gitcomp_builtin_merge_base_default=" --all --octopus --independent --is-ancestor --fork-point --no-all"
+__gitcomp_builtin_merge_file_default=" --stdout --diff3 --zdiff3 --ours --theirs --union --marker-size= --quiet --no-stdout -- --no-diff3 --no-zdiff3 --no-ours --no-theirs --no-union --no-marker-size --no-quiet"
+__gitcomp_builtin_mktree_default=" --missing --batch --no-missing -- --no-batch"
+__gitcomp_builtin_multi_pack_index_default=" --object-dir= --no-object-dir"
+__gitcomp_builtin_mv_default=" --verbose --dry-run --sparse --no-verbose -- --no-dry-run --no-sparse"
+__gitcomp_builtin_name_rev_default=" --name-only --tags --refs= --exclude= --all --stdin --annotate-stdin --undefined --always --no-name-only -- --no-tags --no-refs --no-exclude --no-all --no-stdin --no-annotate-stdin --no-undefined --no-always"
+__gitcomp_builtin_notes_default=" --ref= --no-ref"
+__gitcomp_builtin_pack_objects_default=" --quiet --progress --all-progress --all-progress-implied --index-version= --max-pack-size= --local --incremental --window= --window-memory= --depth= --reuse-delta --reuse-object --delta-base-offset --threads= --non-empty --revs --unpacked --all --reflog --indexed-objects --stdin-packs --stdout --include-tag --keep-unreachable --pack-loose-unreachable --unpack-unreachable --sparse --thin --shallow --honor-pack-keep --keep-pack= --compression= --keep-true-parents --use-bitmap-index --write-bitmap-index --filter= --missing= --exclude-promisor-objects --delta-islands --uri-protocol= --no-quiet -- --no-progress --no-all-progress --no-all-progress-implied --no-local --no-incremental --no-window --no-depth --no-reuse-delta --no-reuse-object --no-delta-base-offset --no-threads --no-non-empty --no-revs --no-stdin-packs --no-stdout --no-include-tag --no-keep-unreachable --no-pack-loose-unreachable --no-unpack-unreachable --no-sparse --no-thin --no-shallow --no-honor-pack-keep --no-keep-pack --no-compression --no-keep-true-parents --no-use-bitmap-index --no-write-bitmap-index --no-filter --no-exclude-promisor-objects --no-delta-islands --no-uri-protocol"
+__gitcomp_builtin_pack_refs_default=" --all --prune --no-all -- --no-prune"
+__gitcomp_builtin_pickaxe_default=" --incremental --root --show-stats --progress --score-debug --show-name --show-number --porcelain --line-porcelain --show-email --ignore-rev= --ignore-revs-file= --color-lines --color-by-age --minimal --contents= --abbrev --no-incremental -- --no-root --no-show-stats --no-progress --no-score-debug --no-show-name --no-show-number --no-porcelain --no-line-porcelain --no-show-email --no-ignore-rev --no-ignore-revs-file --no-color-lines --no-color-by-age --no-minimal --no-contents --no-abbrev"
+__gitcomp_builtin_prune_default=" --dry-run --verbose --progress --expire= --exclude-promisor-objects --no-dry-run -- --no-verbose --no-progress --no-expire --no-exclude-promisor-objects"
+__gitcomp_builtin_prune_packed_default=" --dry-run --quiet --no-dry-run -- --no-quiet"
+__gitcomp_builtin_pull_default=" --verbose --quiet --progress --recurse-submodules --rebase --stat --log --signoff --squash --commit --edit --cleanup= --ff --ff-only --verify --verify-signatures --autostash --strategy= --strategy-option= --gpg-sign --allow-unrelated-histories --all --append --upload-pack= --force --tags --prune --jobs --dry-run --keep --depth= --shallow-since= --shallow-exclude= --deepen= --unshallow --update-shallow --refmap= --server-option= --ipv4 --ipv6 --negotiation-tip= --show-forced-updates --set-upstream --no-verbose -- --no-quiet --no-progress --no-recurse-submodules --no-rebase --no-stat --no-log --no-signoff --no-squash --no-commit --no-edit --no-cleanup --no-ff --no-verify --no-verify-signatures --no-autostash --no-strategy --no-strategy-option --no-gpg-sign --no-allow-unrelated-histories --no-all --no-append --no-upload-pack --no-force --no-tags --no-prune --no-jobs --no-dry-run --no-keep --no-depth --no-shallow-since --no-shallow-exclude --no-deepen --no-update-shallow --no-server-option --no-ipv4 --no-ipv6 --no-negotiation-tip --no-show-forced-updates --no-set-upstream"
+__gitcomp_builtin_push_default=" --verbose --quiet --repo= --all --mirror --delete --tags --dry-run --porcelain --force --force-with-lease --force-if-includes --recurse-submodules= --receive-pack= --exec= --set-upstream --progress --prune --no-verify --follow-tags --signed --atomic --push-option= --ipv4 --ipv6 --verify -- --no-verbose --no-quiet --no-repo --no-all --no-mirror --no-delete --no-tags --no-dry-run --no-porcelain --no-force --no-force-with-lease --no-force-if-includes --no-recurse-submodules --no-receive-pack --no-exec --no-set-upstream --no-progress --no-prune --no-follow-tags --no-signed --no-atomic --no-push-option --no-ipv4 --no-ipv6"
+__gitcomp_builtin_range_diff_default=" --creation-factor= --no-dual-color --notes --left-only --right-only --patch --no-patch --unified --function-context --raw --patch-with-raw --patch-with-stat --numstat --shortstat --dirstat --cumulative --dirstat-by-file --check --summary --name-only --name-status --stat --stat-width= --stat-name-width= --stat-graph-width= --stat-count= --compact-summary --binary --full-index --color --ws-error-highlight= --abbrev --src-prefix= --dst-prefix= --line-prefix= --no-prefix --inter-hunk-context= --output-indicator-new= --output-indicator-old= --output-indicator-context= --break-rewrites --find-renames --irreversible-delete --find-copies --find-copies-harder --no-renames --rename-empty --follow --minimal --ignore-all-space --ignore-space-change --ignore-space-at-eol --ignore-cr-at-eol --ignore-blank-lines --ignore-matching-lines= --indent-heuristic --patience --histogram --diff-algorithm= --anchored= --word-diff --word-diff-regex= --color-words --color-moved --color-moved-ws= --relative --text --exit-code --quiet --ext-diff --textconv --ignore-submodules --submodule --ita-invisible-in-index --ita-visible-in-index --pickaxe-all --pickaxe-regex --rotate-to= --skip-to= --find-object= --diff-filter= --output= --dual-color -- --no-creation-factor --no-notes --no-left-only --no-right-only --no-function-context --no-compact-summary --no-full-index --no-color --no-abbrev --no-find-copies-harder --no-rename-empty --no-follow --no-minimal --no-ignore-matching-lines --no-indent-heuristic --no-color-moved --no-color-moved-ws --no-relative --no-text --no-exit-code --no-quiet --no-ext-diff --no-textconv"
+__gitcomp_builtin_read_tree_default=" --index-output= --empty --verbose --trivial --aggressive --reset --prefix= --exclude-per-directory= --dry-run --no-sparse-checkout --debug-unpack --recurse-submodules --quiet --sparse-checkout -- --no-empty --no-verbose --no-trivial --no-aggressive --no-reset --no-dry-run --no-debug-unpack --no-recurse-submodules --no-quiet"
+__gitcomp_builtin_rebase_default=" --onto= --keep-base --no-verify --quiet --verbose --no-stat --signoff --committer-date-is-author-date --reset-author-date --ignore-whitespace --whitespace= --force-rebase --no-ff --continue --skip --abort --quit --edit-todo --show-current-patch --apply --merge --interactive --rerere-autoupdate --empty= --autosquash --gpg-sign --autostash --exec= --rebase-merges --fork-point --strategy= --strategy-option= --root --reschedule-failed-exec --reapply-cherry-picks --verify --stat --ff -- --no-onto --no-keep-base --no-quiet --no-verbose --no-signoff --no-committer-date-is-author-date --no-reset-author-date --no-ignore-whitespace --no-whitespace --no-force-rebase --no-rerere-autoupdate --no-autosquash --no-gpg-sign --no-autostash --no-exec --no-rebase-merges --no-fork-point --no-strategy --no-strategy-option --no-root --no-reschedule-failed-exec --no-reapply-cherry-picks"
+__gitcomp_builtin_receive_pack_default=" --quiet --no-quiet"
+__gitcomp_builtin_reflog_default=""
+__gitcomp_builtin_remote_default=" --verbose --no-verbose"
+__gitcomp_builtin_repack_default=" --quiet --local --write-bitmap-index --delta-islands --unpack-unreachable= --keep-unreachable --window= --window-memory= --depth= --threads= --max-pack-size= --pack-kept-objects --keep-pack= --geometric= --write-midx --no-quiet -- --no-local --no-write-bitmap-index --no-delta-islands --no-unpack-unreachable --no-keep-unreachable --no-window --no-window-memory --no-depth --no-threads --no-max-pack-size --no-pack-kept-objects --no-keep-pack --no-geometric --no-write-midx"
+__gitcomp_builtin_replace_default=" --list --delete --edit --graft --convert-graft-file --raw --format= --no-raw -- --no-format"
+__gitcomp_builtin_rerere_default=" --rerere-autoupdate --no-rerere-autoupdate"
+__gitcomp_builtin_reset_default=" --quiet --no-refresh --mixed --soft --hard --merge --keep --recurse-submodules --patch --intent-to-add --pathspec-from-file= --pathspec-file-nul --refresh -- --no-quiet --no-mixed --no-soft --no-hard --no-merge --no-keep --no-recurse-submodules --no-patch --no-intent-to-add --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_restore_default=" --source= --staged --worktree --ignore-unmerged --overlay --quiet --recurse-submodules --progress --merge --conflict= --ours --theirs --patch --ignore-skip-worktree-bits --pathspec-from-file= --pathspec-file-nul --no-source -- --no-staged --no-worktree --no-ignore-unmerged --no-overlay --no-quiet --no-recurse-submodules --no-progress --no-merge --no-conflict --no-patch --no-ignore-skip-worktree-bits --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_revert_default=" --quit --continue --abort --skip --cleanup= --no-commit --edit --signoff --mainline= --rerere-autoupdate --strategy= --strategy-option= --gpg-sign --commit -- --no-cleanup --no-edit --no-signoff --no-mainline --no-rerere-autoupdate --no-strategy --no-strategy-option --no-gpg-sign"
+__gitcomp_builtin_rm_default=" --dry-run --quiet --cached --ignore-unmatch --sparse --pathspec-from-file= --pathspec-file-nul --no-dry-run -- --no-quiet --no-cached --no-ignore-unmatch --no-sparse --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_send_pack_default=" --verbose --quiet --receive-pack= --exec= --remote= --all --dry-run --mirror --force --signed --push-option= --progress --thin --atomic --stateless-rpc --stdin --helper-status --force-with-lease --force-if-includes --no-verbose -- --no-quiet --no-receive-pack --no-exec --no-remote --no-all --no-dry-run --no-mirror --no-force --no-signed --no-push-option --no-progress --no-thin --no-atomic --no-stateless-rpc --no-stdin --no-helper-status --no-force-with-lease --no-force-if-includes"
+__gitcomp_builtin_shortlog_default=" --committer --numbered --summary --email --group= --no-committer -- --no-numbered --no-summary --no-email --no-group"
+__gitcomp_builtin_show_default=" --quiet --source --use-mailmap --decorate-refs= --decorate-refs-exclude= --decorate --no-quiet -- --no-source --no-use-mailmap --no-mailmap --no-decorate-refs --no-decorate-refs-exclude --no-decorate"
+__gitcomp_builtin_show_branch_default=" --all --remotes --color --more --list --no-name --current --sha1-name --merge-base --independent --topo-order --topics --sparse --date-order --reflog --name -- --no-all --no-remotes --no-color --no-more --no-list --no-current --no-sha1-name --no-merge-base --no-independent --no-topo-order --no-topics --no-sparse --no-date-order"
+__gitcomp_builtin_show_index_default=" --object-format= --no-object-format"
+__gitcomp_builtin_show_ref_default=" --tags --heads --verify --head --dereference --hash --abbrev --quiet --exclude-existing --no-tags -- --no-heads --no-verify --no-head --no-dereference --no-hash --no-abbrev --no-quiet"
+__gitcomp_builtin_sparse_checkout_default=""
+__gitcomp_builtin_stage_default=" --dry-run --verbose --interactive --patch --edit --force --update --renormalize --intent-to-add --all --ignore-removal --refresh --ignore-errors --ignore-missing --sparse --chmod= --pathspec-from-file= --pathspec-file-nul --no-dry-run -- --no-verbose --no-interactive --no-patch --no-edit --no-force --no-update --no-renormalize --no-intent-to-add --no-all --no-ignore-removal --no-refresh --no-ignore-errors --no-ignore-missing --no-sparse --no-chmod --no-pathspec-from-file --no-pathspec-file-nul"
+__gitcomp_builtin_stash_default=""
+__gitcomp_builtin_status_default=" --verbose --short --branch --show-stash --ahead-behind --porcelain --long --null --untracked-files --ignored --ignore-submodules --column --no-renames --find-renames --renames -- --no-verbose --no-short --no-branch --no-show-stash --no-ahead-behind --no-porcelain --no-long --no-null --no-untracked-files --no-ignored --no-ignore-submodules --no-column"
+__gitcomp_builtin_stripspace_default=" --strip-comments --comment-lines"
+__gitcomp_builtin_switch_default=" --create= --force-create= --guess --discard-changes --quiet --recurse-submodules --progress --merge --conflict= --detach --track --orphan= --ignore-other-worktrees --no-create -- --no-force-create --no-guess --no-discard-changes --no-quiet --no-recurse-submodules --no-progress --no-merge --no-conflict --no-detach --no-track --no-orphan --no-ignore-other-worktrees"
+__gitcomp_builtin_symbolic_ref_default=" --quiet --delete --short --no-quiet -- --no-delete --no-short"
+__gitcomp_builtin_tag_default=" --list --delete --verify --annotate --message= --file= --edit --sign --cleanup= --local-user= --force --create-reflog --column --contains --no-contains --merged --no-merged --sort= --points-at --format= --color --ignore-case -- --no-annotate --no-file --no-edit --no-sign --no-cleanup --no-local-user --no-force --no-create-reflog --no-column --no-sort --no-points-at --no-format --no-color --no-ignore-case"
+__gitcomp_builtin_update_index_default=" --ignore-submodules --add --replace --remove --unmerged --refresh --really-refresh --cacheinfo --chmod= --assume-unchanged --no-assume-unchanged --skip-worktree --no-skip-worktree --ignore-skip-worktree-entries --info-only --force-remove --stdin --index-info --unresolve --again --ignore-missing --verbose --clear-resolve-undo --index-version= --split-index --untracked-cache --test-untracked-cache --force-untracked-cache --force-write-index --fsmonitor --fsmonitor-valid --no-fsmonitor-valid -- --no-ignore-submodules --no-add --no-replace --no-remove --no-unmerged --no-ignore-skip-worktree-entries --no-info-only --no-force-remove --no-ignore-missing --no-verbose --no-index-version --no-split-index --no-untracked-cache --no-test-untracked-cache --no-force-untracked-cache --no-force-write-index --no-fsmonitor"
+__gitcomp_builtin_update_ref_default=" --no-deref --stdin --create-reflog --deref -- --no-stdin --no-create-reflog"
+__gitcomp_builtin_update_server_info_default=" --force --no-force"
+__gitcomp_builtin_upload_pack_default=" --stateless-rpc --strict --timeout= --no-stateless-rpc -- --no-strict --no-timeout"
+__gitcomp_builtin_verify_commit_default=" --verbose --raw --no-verbose -- --no-raw"
+__gitcomp_builtin_verify_pack_default=" --verbose --stat-only --object-format= --no-verbose -- --no-stat-only --no-object-format"
+__gitcomp_builtin_verify_tag_default=" --verbose --raw --format= --no-verbose -- --no-raw --no-format"
+__gitcomp_builtin_version_default=" --build-options --no-build-options"
+__gitcomp_builtin_whatchanged_default=" --quiet --source --use-mailmap --decorate-refs= --decorate-refs-exclude= --decorate --no-quiet -- --no-source --no-use-mailmap --no-mailmap --no-decorate-refs --no-decorate-refs-exclude --no-decorate"
+__gitcomp_builtin_write_tree_default=" --missing-ok --prefix= --no-missing-ok -- --no-prefix"
+__gitcomp_builtin_send_email_default="--sender= --from= --smtp-auth= --8bit-encoding= --no-format-patch --no-bcc --no-suppress-from --no-annotate --relogin-delay= --no-cc --no-signed-off-cc --no-signed-off-by-cc --no-chain-reply-to --smtp-debug= --smtp-domain= --chain-reply-to --dry-run --compose --bcc= --smtp-user= --thread --cc-cover --identity= --to= --reply-to= --no-cc-cover --suppress-cc= --to-cmd= --smtp-server= --smtp-ssl-cert-path= --no-thread --smtp-server-option= --quiet --batch-size= --envelope-sender= --smtp-ssl --no-to --validate --format-patch --suppress-from --cc= --compose-encoding= --to-cover --in-reply-to= --annotate --smtp-encryption= --cc-cmd= --smtp-server-port= --smtp-pass= --signed-off-cc --signed-off-by-cc --no-xmailer --subject= --no-to-cover --confirm= --transfer-encoding= --no-smtp-auth --sendmail-cmd= --no-validate --no-identity --dump-aliases --xmailer --force --numbered --no-numbered --signoff --stdout --cover-letter --numbered-files --suffix= --start-number= --reroll-count= --filename-max-length= --rfc --cover-from-description= --subject-prefix= --output-directory= --keep-subject --no-binary --zero-commit --ignore-if-in-upstream --no-stat --add-header= --from --attach --inline --signature= --base= --signature-file= --progress --interdiff= --range-diff= --creation-factor= --binary -- --no-signoff --no-stdout --no-cover-letter --no-numbered-files --no-suffix --no-start-number --no-reroll-count --no-filename-max-length --no-cover-from-description --no-zero-commit --no-ignore-if-in-upstream --no-add-header --no-from --no-in-reply-to --no-attach --no-signature --no-base --no-signature-file --no-quiet --no-progress --no-interdiff --no-range-diff --no-creation-factor"
+
+__gitcomp_builtin_get_default ()
+{
+       eval "test -n \"\$${1}_default\" && echo \"\$${1}_default\""
+}
+
+# This function is equivalent to
+#
+#    __gitcomp_opts "$(git xxx --git-completion-helper) ..."
+#
+# except that the output is cached. Accept 1-3 arguments:
+# 1: the git command to execute, this is also the cache key
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
+__gitcomp_builtin ()
+{
+       # spaces must be replaced with underscore for multi-word
+       # commands, e.g. "git remote add" becomes remote_add.
+       local cmd="$1"
+       local incl="${2-}"
+       local excl="${3-}"
+
+       local var=__gitcomp_builtin_"${cmd//-/_}"
+       local options
+       eval "options=\${$var-}"
+
+       if [ -z "$options" ]; then
+               local completion_helper
+               if [ "${GIT_COMPLETION_SHOW_ALL-}" = "1" ]; then
+                       completion_helper="--git-completion-helper-all"
+               else
+                       completion_helper="--git-completion-helper"
+               fi
+               completion="$(__git ${cmd/_/ } $completion_helper ||
+                       __gitcomp_builtin_get_default $var)" || return
+               # leading and trailing spaces are significant to make
+               # option removal work correctly.
+               options=" $incl $completion "
+
+               for i in $excl; do
+                       options="${options/ $i / }"
+               done
+               eval "$var=\"$options\""
+       fi
+
+       __gitcomp_opts "$options"
+}
+
+# Execute 'git ls-files', unless the --committable option is specified, in
+# which case it runs 'git diff-index' to find out the files that can be
+# committed.  It return paths relative to the directory specified in the first
+# argument, and using the options specified in the second argument.
+__git_ls_files_helper ()
+{
+       if [ "$2" = "--committable" ]; then
+               __git -C "$1" -c core.quotePath=false diff-index \
+                       --name-only --relative HEAD -- "${3//\\/\\\\}*"
+       else
+               # NOTE: $2 is not quoted in order to support multiple options
+               __git -C "$1" -c core.quotePath=false ls-files \
+                       --exclude-standard $2 -- "${3//\\/\\\\}*"
+       fi
+}
+
+
+# __git_index_files accepts 1 or 2 arguments:
+# 1: Options to pass to ls-files (required).
+# 2: A directory path (optional).
+#    If provided, only files within the specified directory are listed.
+#    Sub directories are never recursed.  Path must have a trailing
+#    slash.
+# 3: List only paths matching this path component (optional).
+__git_index_files ()
+{
+       local root="$2" match="$3"
+
+       __git_ls_files_helper "$root" "$1" "${match:-?}" |
+       awk -F / -v pfx="${2//\\/\\\\}" '{
+               paths[$1] = 1
+       }
+       END {
+               for (p in paths) {
+                       if (substr(p, 1, 1) != "\"") {
+                               # No special characters, easy!
+                               print pfx p
+                               continue
+                       }
+
+                       # The path is quoted.
+                       p = dequote(p)
+                       if (p == "")
+                               continue
+
+                       # Even when a directory name itself does not contain
+                       # any special characters, it will still be quoted if
+                       # any of its (stripped) trailing path components do.
+                       # Because of this we may have seen the same directory
+                       # both quoted and unquoted.
+                       if (p in paths)
+                               # We have seen the same directory unquoted,
+                               # skip it.
+                               continue
+                       else
+                               print pfx p
+               }
+       }
+       function dequote(p,    bs_idx, out, esc, esc_idx, dec) {
+               # Skip opening double quote.
+               p = substr(p, 2)
+
+               # Interpret backslash escape sequences.
+               while ((bs_idx = index(p, "\\")) != 0) {
+                       out = out substr(p, 1, bs_idx - 1)
+                       esc = substr(p, bs_idx + 1, 1)
+                       p = substr(p, bs_idx + 2)
+
+                       if ((esc_idx = index("abtvfr\"\\", esc)) != 0) {
+                               # C-style one-character escape sequence.
+                               out = out substr("\a\b\t\v\f\r\"\\",
+                                                esc_idx, 1)
+                       } else if (esc == "n") {
+                               # Uh-oh, a newline character.
+                               # We cannot reliably put a pathname
+                               # containing a newline into COMPREPLY,
+                               # and the newline would create a mess.
+                               # Skip this path.
+                               return ""
+                       } else {
+                               # Must be a \nnn octal value, then.
+                               dec = esc             * 64 + \
+                                     substr(p, 1, 1) * 8  + \
+                                     substr(p, 2, 1)
+                               out = out sprintf("%c", dec)
+                               p = substr(p, 3)
+                       }
+               }
+               # Drop closing double quote, if there is one.
+               # (There is not any if this is a directory, as it was
+               # already stripped with the trailing path components.)
+               if (substr(p, length(p), 1) == "\"")
+                       out = out substr(p, 1, length(p) - 1)
+               else
+                       out = out p
+
+               return out
+       }'
+}
+
+# __git_complete_index_file requires 1 argument:
+# 1: the options to pass to ls-file
+#
+# The exception is --committable, which finds the files appropriate commit.
+__git_complete_index_file ()
+{
+       local dequoted_word pfx="" cur_
+
+       __git_dequote "$cur"
+
+       case "$dequoted_word" in
+       ?*/*)
+               pfx="${dequoted_word%/*}/"
+               cur_="${dequoted_word##*/}"
+               ;;
+       *)
+               cur_="$dequoted_word"
+       esac
+
+       __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
+}
+
+# Lists branches from the local repository.
+# 1: A prefix to be added to each listed branch (optional).
+# 2: List only branches matching this word (optional; list all branches if
+#    unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
+__git_heads ()
+{
+       local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+       __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+                       "refs/heads/$cur_*" "refs/heads/$cur_*/**"
+}
+
+# Lists branches from remote repositories.
+# 1: A prefix to be added to each listed branch (optional).
+# 2: List only branches matching this word (optional; list all branches if
+#    unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
+__git_remote_heads ()
+{
+       local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+       __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+                       "refs/remotes/$cur_*" "refs/remotes/$cur_*/**"
+}
+
+# Lists tags from the local repository.
+# Accepts the same positional parameters as __git_heads() above.
+__git_tags ()
+{
+       local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+       __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+                       "refs/tags/$cur_*" "refs/tags/$cur_*/**"
+}
+
+# List unique branches from refs/remotes used for 'git checkout' and 'git
+# switch' tracking DWIMery.
+# 1: A prefix to be added to each listed branch (optional)
+# 2: List only branches matching this word (optional; list all branches if
+#    unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
+__git_dwim_remote_heads ()
+{
+       local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+       local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
+
+       # employ the heuristic used by git checkout and git switch
+       # Try to find a remote branch that cur_es the completion word
+       # but only output if the branch name is unique
+       __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
+               --sort="refname:strip=3" \
+               "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \
+       uniq -u
+}
+
+# Lists refs from the local (by default) or from a remote repository.
+# It accepts 0, 1 or 2 arguments:
+# 1: The remote to list refs from (optional; ignored, if set but empty).
+#    Can be the name of a configured remote, a path, or a URL.
+# 2: In addition to local refs, list unique branches from refs/remotes/ for
+#    'git checkout's tracking DWIMery (optional; ignored, if set but empty).
+# 3: A prefix to be added to each listed ref (optional).
+# 4: List only refs matching this word (optional; list all refs if unset or
+#    empty).
+# 5: A suffix to be appended to each listed ref (optional; ignored, if set
+#    but empty).
+#
+# Use __git_complete_refs() instead.
+__git_refs ()
+{
+       local i hash dir track="${2-}"
+       local list_refs_from=path remote="${1-}"
+       local format refs
+       local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}"
+       local match="${4-}"
+       local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
+
+       __git_find_repo_path
+       dir="$__git_repo_path"
+
+       if [ -z "$remote" ]; then
+               if [ -z "$dir" ]; then
+                       return
+               fi
+       else
+               if __git_is_configured_remote "$remote"; then
+                       # configured remote takes precedence over a
+                       # local directory with the same name
+                       list_refs_from=remote
+               elif [ -d "$remote/.git" ]; then
+                       dir="$remote/.git"
+               elif [ -d "$remote" ]; then
+                       dir="$remote"
+               else
+                       list_refs_from=url
+               fi
+       fi
+
+       if [ "$list_refs_from" = path ]; then
+               if [[ "$cur_" == ^* ]]; then
+                       pfx="$pfx^"
+                       fer_pfx="$fer_pfx^"
+                       cur_=${cur_#^}
+                       match=${match#^}
+               fi
+               case "$cur_" in
+               refs|refs/*)
+                       format="refname"
+                       refs=("$match*" "$match*/**")
+                       track=""
+                       ;;
+               *)
+                       for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD CHERRY_PICK_HEAD; do
+                               case "$i" in
+                               $match*)
+                                       if [ -e "$dir/$i" ]; then
+                                               echo "$pfx$i$sfx"
+                                       fi
+                                       ;;
+                               esac
+                       done
+                       format="refname:strip=2"
+                       refs=("refs/tags/$match*" "refs/tags/$match*/**"
+                               "refs/heads/$match*" "refs/heads/$match*/**"
+                               "refs/remotes/$match*" "refs/remotes/$match*/**")
+                       ;;
+               esac
+               __git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \
+                       "${refs[@]}"
+               if [ -n "$track" ]; then
+                       __git_dwim_remote_heads "$pfx" "$match" "$sfx"
+               fi
+               return
+       fi
+       case "$cur_" in
+       refs|refs/*)
+               __git ls-remote "$remote" "$match*" | \
+               while read -r hash i; do
+                       case "$i" in
+                       *^{}) ;;
+                       *) echo "$pfx$i$sfx" ;;
+                       esac
+               done
+               ;;
+       *)
+               if [ "$list_refs_from" = remote ]; then
+                       case "HEAD" in
+                       $match*)        echo "${pfx}HEAD$sfx" ;;
+                       esac
+                       __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
+                               "refs/remotes/$remote/$match*" \
+                               "refs/remotes/$remote/$match*/**"
+               else
+                       local query_symref
+                       case "HEAD" in
+                       $match*)        query_symref="HEAD" ;;
+                       esac
+                       __git ls-remote "$remote" $query_symref \
+                               "refs/tags/$match*" "refs/heads/$match*" \
+                               "refs/remotes/$match*" |
+                       while read -r hash i; do
+                               case "$i" in
+                               *^{})   ;;
+                               refs/*) echo "$pfx${i#refs/*/}$sfx" ;;
+                               *)      echo "$pfx$i$sfx" ;;  # symbolic refs
+                               esac
+                       done
+               fi
+               ;;
+       esac
+}
+
+# Completes refs, short and long, local and remote, symbolic and pseudo.
+#
+# Usage: __git_complete_refs [<option>]...
+# --remote=<remote>: The remote to list refs from, can be the name of a
+#                    configured remote, a path, or a URL.
+# --dwim: List unique remote branches for 'git switch's tracking DWIMery.
+# --pfx=<prefix>: A prefix to be added to each ref.
+# --cur=<word>: The current ref to be completed.  Defaults to the current
+#               word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each ref instead of the default
+#                 space.
+# --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to
+#                complete all refs, 'heads' to complete only branches, or
+#                'remote-heads' to complete only remote branches. Note that
+#                --remote is only compatible with --mode=refs.
+__git_complete_refs ()
+{
+       local remote= dwim= pfx= cur_="$cur" sfx=" " mode="refs"
+
+       while test $# != 0; do
+               case "$1" in
+               --remote=*)     remote="${1##--remote=}" ;;
+               --dwim)         dwim="yes" ;;
+               # --track is an old spelling of --dwim
+               --track)        dwim="yes" ;;
+               --pfx=*)        pfx="${1##--pfx=}" ;;
+               --cur=*)        cur_="${1##--cur=}" ;;
+               --sfx=*)        sfx="${1##--sfx=}" ;;
+               --mode=*)       mode="${1##--mode=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       # complete references based on the specified mode
+       case "$mode" in
+               refs)
+                       __gitcomp_direct "$(__git_refs "$remote" "" "$pfx" "$cur_" "$sfx")" ;;
+               heads)
+                       __gitcomp_direct "$(__git_heads "$pfx" "$cur_" "$sfx")" ;;
+               remote-heads)
+                       __gitcomp_direct "$(__git_remote_heads "$pfx" "$cur_" "$sfx")" ;;
+               *)
+                       return 1 ;;
+       esac
+
+       # Append DWIM remote branch names if requested
+       if [ "$dwim" = "yes" ]; then
+               __gitcomp_direct "$(__git_dwim_remote_heads "$pfx" "$cur_" "$sfx")"
+       fi
+}
+
+# __git_refs2 requires 1 argument (to pass to __git_refs)
+# Deprecated: use __git_complete_fetch_refspecs() instead.
+__git_refs2 ()
+{
+       local i
+       for i in $(__git_refs "$1"); do
+               echo "$i:$i"
+       done
+}
+
+# Completes refspecs for fetching from a remote repository.
+# 1: The remote repository.
+# 2: A prefix to be added to each listed refspec (optional).
+# 3: The ref to be completed as a refspec instead of the current word to be
+#    completed (optional)
+# 4: A suffix to be appended to each listed refspec instead of the default
+#    space (optional).
+__git_complete_fetch_refspecs ()
+{
+       local i remote="$1" pfx="${2-}" cur_="${3-$cur}" sfx="${4- }"
+
+       __gitcomp_direct "$(
+               for i in $(__git_refs "$remote" "" "" "$cur_") ; do
+                       echo "$pfx$i:$i$sfx"
+               done
+               )"
+}
+
+# __git_refs_remotes requires 1 argument (to pass to ls-remote)
+__git_refs_remotes ()
+{
+       local i hash
+       __git ls-remote "$1" 'refs/heads/*' | \
+       while read -r hash i; do
+               echo "$i:refs/remotes/$1/${i#refs/heads/}"
+       done
+}
+
+__git_remotes ()
+{
+       __git_find_repo_path
+       test -d "$__git_repo_path/remotes" && ls -1 "$__git_repo_path/remotes"
+       __git remote
+}
+
+# Returns true if $1 matches the name of a configured remote, false otherwise.
+__git_is_configured_remote ()
+{
+       local remote
+       for remote in $(__git_remotes); do
+               if [ "$remote" = "$1" ]; then
+                       return 0
+               fi
+       done
+       return 1
+}
+
+__git_list_merge_strategies ()
+{
+       LANG=C LC_ALL=C git merge -s help 2>&1 |
+       sed -n -e '/[Aa]vailable strategies are: /,/^$/{
+               s/\.$//
+               s/.*://
+               s/^[    ]*//
+               s/[     ]*$//
+               p
+       }'
+}
+
+__git_merge_strategies_default='octopus ours recursive resolve subtree'
+__git_merge_strategies=
+# 'git merge -s help' (and thus detection of the merge strategy
+# list) fails, unfortunately, if run outside of any git working
+# tree.  __git_merge_strategies is set to the empty string in
+# that case, and the detection will be repeated the next time it
+# is needed.
+__git_compute_merge_strategies ()
+{
+       test -n "$__git_merge_strategies" ||
+       { __git_merge_strategies=$(__git_list_merge_strategies);
+               __git_merge_strategies="${__git_merge_strategies:-__git_merge_strategies_default}"; }
+}
+
+__git_merge_strategy_options="ours theirs subtree subtree= patience
+       histogram diff-algorithm= ignore-space-change ignore-all-space
+       ignore-space-at-eol renormalize no-renormalize no-renames
+       find-renames find-renames= rename-threshold="
+
+__git_complete_revlist_file ()
+{
+       local dequoted_word pfx ls ref cur_="$cur"
+       case "$cur_" in
+       *..?*:*)
+               return
+               ;;
+       ?*:*)
+               ref="${cur_%%:*}"
+               cur_="${cur_#*:}"
+
+               __git_dequote "$cur_"
+
+               case "$dequoted_word" in
+               ?*/*)
+                       pfx="${dequoted_word%/*}"
+                       cur_="${dequoted_word##*/}"
+                       ls="$ref:$pfx"
+                       pfx="$pfx/"
+                       ;;
+               *)
+                       cur_="$dequoted_word"
+                       ls="$ref"
+                       ;;
+               esac
+
+               case "$COMP_WORDBREAKS" in
+               *:*) : great ;;
+               *)   pfx="$ref:$pfx" ;;
+               esac
+
+               __gitcomp_file "$(__git ls-tree "$ls" \
+                               | sed 's/^.*    //
+                                      s/$//')" \
+                       "$pfx" "$cur_"
+               ;;
+       *...*)
+               pfx="${cur_%...*}..."
+               cur_="${cur_#*...}"
+               __git_complete_refs --pfx="$pfx" --cur="$cur_"
+               ;;
+       *..*)
+               pfx="${cur_%..*}.."
+               cur_="${cur_#*..}"
+               __git_complete_refs --pfx="$pfx" --cur="$cur_"
+               ;;
+       *)
+               __git_complete_refs
+               ;;
+       esac
+}
+
+__git_complete_file ()
+{
+       __git_complete_revlist_file
+}
+
+__git_complete_revlist ()
+{
+       __git_complete_revlist_file
+}
+
+__git_complete_remote_or_refspec ()
+{
+       local cur_="$cur" cmd="${words[__git_cmd_idx]}"
+       local i c=$((__git_cmd_idx+1)) remote="" pfx="" lhs=1 no_complete_refspec=0
+       if [ "$cmd" = "remote" ]; then
+               ((c++))
+       fi
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
+               case "$i" in
+               --mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
+               -d|--delete) [ "$cmd" = "push" ] && lhs=0 ;;
+               --all)
+                       case "$cmd" in
+                       push) no_complete_refspec=1 ;;
+                       fetch)
+                               return
+                               ;;
+                       *) ;;
+                       esac
+                       ;;
+               --multiple) no_complete_refspec=1; break ;;
+               -*) ;;
+               *) remote="$i"; break ;;
+               esac
+               ((c++))
+       done
+       if [ -z "$remote" ]; then
+               __gitcomp_nl "$(__git_remotes)"
+               return
+       fi
+       if [ $no_complete_refspec = 1 ]; then
+               return
+       fi
+       [ "$remote" = "." ] && remote=
+       case "$cur_" in
+       *:*)
+               case "$COMP_WORDBREAKS" in
+               *:*) : great ;;
+               *)   pfx="${cur_%%:*}:" ;;
+               esac
+               cur_="${cur_#*:}"
+               lhs=0
+               ;;
+       +*)
+               pfx="+"
+               cur_="${cur_#+}"
+               ;;
+       esac
+       case "$cmd" in
+       fetch)
+               if [ $lhs = 1 ]; then
+                       __git_complete_fetch_refspecs "$remote" "$pfx" "$cur_"
+               else
+                       __git_complete_refs --pfx="$pfx" --cur="$cur_"
+               fi
+               ;;
+       pull|remote)
+               if [ $lhs = 1 ]; then
+                       __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
+               else
+                       __git_complete_refs --pfx="$pfx" --cur="$cur_"
+               fi
+               ;;
+       push)
+               if [ $lhs = 1 ]; then
+                       __git_complete_refs --pfx="$pfx" --cur="$cur_"
+               else
+                       __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
+               fi
+               ;;
+       esac
+}
+
+__git_complete_strategy ()
+{
+       __git_compute_merge_strategies
+       case "$prev" in
+       -s|--strategy)
+               __gitcomp "$__git_merge_strategies"
+               return 0
+               ;;
+       -X)
+               __gitcomp_opts "$__git_merge_strategy_options"
+               return 0
+               ;;
+       esac
+       case "$cur" in
+       --strategy=*)
+               __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
+               return 0
+               ;;
+       --strategy-option=*)
+               __gitcomp_opts "$__git_merge_strategy_options" "" "${cur##--strategy-option=}"
+               return 0
+               ;;
+       esac
+       return 1
+}
+
+__git_all_commands=
+__git_compute_all_commands ()
+{
+       test -n "$__git_all_commands" ||
+       __git_all_commands=$(__git --list-cmds=main,others,alias,nohelpers)
+}
+
+# Lists all set config variables starting with the given section prefix,
+# with the prefix removed.
+__git_get_config_variables ()
+{
+       local section="$1" i IFS=$'\n'
+       for i in $(__git config --name-only --get-regexp "^$section\..*"); do
+               echo "${i#$section.}"
+       done
+}
+
+__git_pretty_aliases ()
+{
+       __git_get_config_variables "pretty"
+}
+
+# __git_aliased_command requires 1 argument
+__git_aliased_command ()
+{
+       local cur=$1 last list= word cmdline
+
+       while [[ -n "$cur" ]]; do
+               if [[ "$list" == *" $cur "* ]]; then
+                       # loop detected
+                       return
+               fi
+
+               cmdline=$(__git config --get "alias.$cur")
+               list=" $cur $list"
+               last=$cur
+               cur=
+
+               for word in $cmdline; do
+                       case "$word" in
+                       \!gitk|gitk)
+                               cur="gitk"
+                               break
+                               ;;
+                       \!*)    : shell command alias ;;
+                       -*)     : option ;;
+                       *=*)    : setting env ;;
+                       git)    : git itself ;;
+                       \(\))   : skip parens of shell function definition ;;
+                       {)      : skip start of shell helper function ;;
+                       :)      : skip null command ;;
+                       \'*)    : skip opening quote after sh -c ;;
+                       *)
+                               cur="$word"
+                               break
+                       esac
+               done
+       done
+
+       cur=$last
+       if [[ "$cur" != "$1" ]]; then
+               echo "$cur"
+       fi
+}
+
+# Check whether one of the given words is present on the command line,
+# and print the first word found.
+#
+# Usage: __git_find_on_cmdline [<option>]... "<wordlist>"
+# --show-idx: Optionally show the index of the found word in the $words array.
+__git_find_on_cmdline ()
+{
+       local word c="$__git_cmd_idx" show_idx
+
+       while test $# -gt 1; do
+               case "$1" in
+               --show-idx)     show_idx=y ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+       local wordlist="$1"
+
+       while [ $c -lt $cword ]; do
+               for word in $wordlist; do
+                       if [ "$word" = "${words[c]}" ]; then
+                               if [ -n "${show_idx-}" ]; then
+                                       echo "$c $word"
+                               else
+                                       echo "$word"
+                               fi
+                               return
+                       fi
+               done
+               ((c++))
+       done
+}
+
+# Similar to __git_find_on_cmdline, except that it loops backwards and thus
+# prints the *last* word found. Useful for finding which of two options that
+# supersede each other came last, such as "--guess" and "--no-guess".
+#
+# Usage: __git_find_last_on_cmdline [<option>]... "<wordlist>"
+# --show-idx: Optionally show the index of the found word in the $words array.
+__git_find_last_on_cmdline ()
+{
+       local word c=$cword show_idx
+
+       while test $# -gt 1; do
+               case "$1" in
+               --show-idx)     show_idx=y ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+       local wordlist="$1"
+
+       while [ $c -gt "$__git_cmd_idx" ]; do
+               ((c--))
+               for word in $wordlist; do
+                       if [ "$word" = "${words[c]}" ]; then
+                               if [ -n "$show_idx" ]; then
+                                       echo "$c $word"
+                               else
+                                       echo "$word"
+                               fi
+                               return
+                       fi
+               done
+       done
+}
+
+# Echo the value of an option set on the command line or config
+#
+# $1: short option name
+# $2: long option name including =
+# $3: list of possible values
+# $4: config string (optional)
+#
+# example:
+# result="$(__git_get_option_value "-d" "--do-something=" \
+#     "yes no" "core.doSomething")"
+#
+# result is then either empty (no option set) or "yes" or "no"
+#
+# __git_get_option_value requires 3 arguments
+__git_get_option_value ()
+{
+       local c short_opt long_opt val
+       local result= values config_key word
+
+       short_opt="$1"
+       long_opt="$2"
+       values="$3"
+       config_key="$4"
+
+       ((c = $cword - 1))
+       while [ $c -ge 0 ]; do
+               word="${words[c]}"
+               for val in $values; do
+                       if [ "$short_opt$val" = "$word" ] ||
+                          [ "$long_opt$val"  = "$word" ]; then
+                               result="$val"
+                               break 2
+                       fi
+               done
+               ((c--))
+       done
+
+       if [ -n "$config_key" ] && [ -z "$result" ]; then
+               result="$(__git config "$config_key")"
+       fi
+
+       echo "$result"
+}
+
+__git_has_doubledash ()
+{
+       local c=1
+       while [ $c -lt $cword ]; do
+               if [ "--" = "${words[c]}" ]; then
+                       return 0
+               fi
+               ((c++))
+       done
+       return 1
+}
+
+# Try to count non option arguments passed on the command line for the
+# specified git command.
+# When options are used, it is necessary to use the special -- option to
+# tell the implementation were non option arguments begin.
+# XXX this can not be improved, since options can appear everywhere, as
+# an example:
+#      git mv x -n y
+#
+# __git_count_arguments requires 1 argument: the git command executed.
+__git_count_arguments ()
+{
+       local word i c=0
+
+       # Skip "git" (first argument)
+       for ((i=$__git_cmd_idx; i < ${#words[@]}; i++)); do
+               word="${words[i]}"
+
+               case "$word" in
+                       --)
+                               # Good; we can assume that the following are only non
+                               # option arguments.
+                               ((c = 0))
+                               ;;
+                       "$1")
+                               # Skip the specified git command and discard git
+                               # main options
+                               ((c = 0))
+                               ;;
+                       ?*)
+                               ((c++))
+                               ;;
+               esac
+       done
+
+       printf "%d" $c
+}
+
+__git_whitespacelist="nowarn warn error error-all fix"
+__git_patchformat="mbox stgit stgit-series hg mboxrd"
+__git_showcurrentpatch="diff raw"
+__git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
+__git_quoted_cr="nowarn warn strip"
+
+_git_am ()
+{
+       __git_find_repo_path
+       if [ -d "$__git_repo_path"/rebase-apply ]; then
+               __gitcomp_opts "$__git_am_inprogress_options"
+               return
+       fi
+       case "$cur" in
+       --whitespace=*)
+               __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
+               return
+               ;;
+       --patch-format=*)
+               __gitcomp "$__git_patchformat" "" "${cur##--patch-format=}"
+               return
+               ;;
+       --show-current-patch=*)
+               __gitcomp "$__git_showcurrentpatch" "" "${cur##--show-current-patch=}"
+               return
+               ;;
+       --quoted-cr=*)
+               __gitcomp "$__git_quoted_cr" "" "${cur##--quoted-cr=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin am "" \
+                       "$__git_am_inprogress_options"
+               return
+       esac
+}
+
+_git_apply ()
+{
+       case "$cur" in
+       --whitespace=*)
+               __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin apply
+               return
+       esac
+}
+
+_git_add ()
+{
+       case "$cur" in
+       --chmod=*)
+               __gitcomp "+x -x" "" "${cur##--chmod=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin add
+               return
+       esac
+
+       local complete_opt="--others --modified --directory --no-empty-directory"
+       if test -n "$(__git_find_on_cmdline "-u --update")"
+       then
+               complete_opt="--modified"
+       fi
+       __git_complete_index_file "$complete_opt"
+}
+
+_git_archive ()
+{
+       case "$cur" in
+       --format=*)
+               __gitcomp_nl "$(git archive --list)" "" "${cur##--format=}"
+               return
+               ;;
+       --remote=*)
+               __gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin archive "--format= --list --verbose --prefix= --worktree-attributes"
+               return
+               ;;
+       esac
+       __git_complete_file
+}
+
+_git_bisect ()
+{
+       __git_has_doubledash && return
+
+       local subcommands="start bad good skip reset visualize replay log run"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               __git_find_repo_path
+               if [ -f "$__git_repo_path"/BISECT_START ]; then
+                       __gitcomp "$subcommands"
+               else
+                       __gitcomp "replay start"
+               fi
+               return
+       fi
+
+       case "$subcommand" in
+       bad|good|reset|skip|start)
+               __git_complete_refs
+               ;;
+       *)
+               ;;
+       esac
+}
+
+__git_ref_fieldlist="refname objecttype objectsize objectname upstream push HEAD symref"
+
+_git_branch ()
+{
+       local i c="$__git_cmd_idx" only_local_ref="n" has_r="n"
+
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
+               case "$i" in
+               -d|-D|--delete|-m|-M|--move|-c|-C|--copy)
+                       only_local_ref="y" ;;
+               -r|--remotes)
+                       has_r="y" ;;
+               esac
+               ((c++))
+       done
+
+       case "$cur" in
+       --set-upstream-to=*)
+               __git_complete_refs --cur="${cur##--set-upstream-to=}"
+               ;;
+       --*)
+               __gitcomp_builtin branch
+               ;;
+       *)
+               if [ $only_local_ref = "y" -a $has_r = "n" ]; then
+                       __gitcomp_direct "$(__git_heads "" "$cur" " ")"
+               else
+                       __git_complete_refs
+               fi
+               ;;
+       esac
+}
+
+_git_bundle ()
+{
+       local cmd="${words[__git_cmd_idx+1]}"
+       case "$cword" in
+       $((__git_cmd_idx+1)))
+               __gitcomp "create list-heads verify unbundle"
+               ;;
+       $((__git_cmd_idx+2)))
+               # looking for a file
+               ;;
+       *)
+               case "$cmd" in
+                       create)
+                               __git_complete_revlist
+                       ;;
+               esac
+               ;;
+       esac
+}
+
+# Helper function to decide whether or not we should enable DWIM logic for
+# git-switch and git-checkout.
+#
+# To decide between the following rules in decreasing priority order:
+# - the last provided of "--guess" or "--no-guess" explicitly enable or
+#   disable completion of DWIM logic respectively.
+# - If checkout.guess is false, disable completion of DWIM logic.
+# - If the --no-track option is provided, take this as a hint to disable the
+#   DWIM completion logic
+# - If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion
+#   logic, as requested by the user.
+# - Enable DWIM logic otherwise.
+#
+__git_checkout_default_dwim_mode ()
+{
+       local last_option dwim_opt="--dwim"
+
+       if [ "${GIT_COMPLETION_CHECKOUT_NO_GUESS-}" = "1" ]; then
+               dwim_opt=""
+       fi
+
+       # --no-track disables DWIM, but with lower priority than
+       # --guess/--no-guess/checkout.guess
+       if [ -n "$(__git_find_on_cmdline "--no-track")" ]; then
+               dwim_opt=""
+       fi
+
+       # checkout.guess = false disables DWIM, but with lower priority than
+       # --guess/--no-guess
+       if [ "$(__git config --type=bool checkout.guess)" = "false" ]; then
+               dwim_opt=""
+       fi
+
+       # Find the last provided --guess or --no-guess
+       last_option="$(__git_find_last_on_cmdline "--guess --no-guess")"
+       case "$last_option" in
+               --guess)
+                       dwim_opt="--dwim"
+                       ;;
+               --no-guess)
+                       dwim_opt=""
+                       ;;
+       esac
+
+       echo "$dwim_opt"
+}
+
+_git_checkout ()
+{
+       __git_has_doubledash && return
+
+       local dwim_opt="$(__git_checkout_default_dwim_mode)"
+
+       case "$prev" in
+       -b|-B|--orphan)
+               # Complete local branches (and DWIM branch
+               # remote branch names) for an option argument
+               # specifying a new branch name. This is for
+               # convenience, assuming new branches are
+               # possibly based on pre-existing branch names.
+               __git_complete_refs $dwim_opt --mode="heads"
+               return
+               ;;
+       *)
+               ;;
+       esac
+
+       case "$cur" in
+       --conflict=*)
+               __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
+               ;;
+       --*)
+               __gitcomp_builtin checkout
+               ;;
+       *)
+               # At this point, we've already handled special completion for
+               # the arguments to -b/-B, and --orphan. There are 3 main
+               # things left we can possibly complete:
+               # 1) a start-point for -b/-B, -d/--detach, or --orphan
+               # 2) a remote head, for --track
+               # 3) an arbitrary reference, possibly including DWIM names
+               #
+
+               if [ -n "$(__git_find_on_cmdline "-b -B -d --detach --orphan")" ]; then
+                       __git_complete_refs --mode="refs"
+               elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
+                       __git_complete_refs --mode="remote-heads"
+               else
+                       __git_complete_refs $dwim_opt --mode="refs"
+               fi
+               ;;
+       esac
+}
+
+__git_sequencer_inprogress_options="--continue --quit --abort --skip"
+
+__git_cherry_pick_inprogress_options=$__git_sequencer_inprogress_options
+
+_git_cherry_pick ()
+{
+       __git_find_repo_path
+       if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then
+               __gitcomp_opts "$__git_cherry_pick_inprogress_options"
+               return
+       fi
+
+       __git_complete_strategy && return
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin cherry-pick "" \
+                       "$__git_cherry_pick_inprogress_options"
+               ;;
+       *)
+               __git_complete_refs
+               ;;
+       esac
+}
+
+_git_clean ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin clean
+               return
+               ;;
+       esac
+
+       # XXX should we check for -x option ?
+       __git_complete_index_file "--others --directory"
+}
+
+_git_clone ()
+{
+       case "$prev" in
+       -c|--config)
+               __git_complete_config_variable_name_and_value
+               return
+               ;;
+       esac
+       case "$cur" in
+       --config=*)
+               __git_complete_config_variable_name_and_value \
+                       --cur="${cur##--config=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin clone
+               return
+               ;;
+       esac
+}
+
+__git_untracked_file_modes="all no normal"
+
+_git_commit ()
+{
+       case "$prev" in
+       -c|-C)
+               __git_complete_refs
+               return
+               ;;
+       esac
+
+       case "$cur" in
+       --cleanup=*)
+               __gitcomp "default scissors strip verbatim whitespace
+                       " "" "${cur##--cleanup=}"
+               return
+               ;;
+       --reuse-message=*|--reedit-message=*|\
+       --fixup=*|--squash=*)
+               __git_complete_refs --cur="${cur#*=}"
+               return
+               ;;
+       --untracked-files=*)
+               __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin commit
+               return
+       esac
+
+       if __git rev-parse --verify --quiet HEAD >/dev/null; then
+               __git_complete_index_file "--committable"
+       else
+               # This is the first commit
+               __git_complete_index_file "--cached"
+       fi
+}
+
+_git_describe ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin describe
+               return
+       esac
+       __git_complete_refs
+}
+
+__git_diff_algorithms="myers minimal patience histogram"
+
+__git_diff_submodule_formats="diff log short"
+
+__git_color_moved_opts="no default plain blocks zebra dimmed-zebra"
+
+__git_color_moved_ws_opts="no ignore-space-at-eol ignore-space-change
+                       ignore-all-space allow-indentation-change"
+
+__git_diff_common_options="--stat --numstat --shortstat --summary
+                       --patch-with-stat --name-only --name-status --color
+                       --no-color --color-words --no-renames --check
+                       --color-moved --color-moved= --no-color-moved
+                       --color-moved-ws= --no-color-moved-ws
+                       --full-index --binary --abbrev --diff-filter=
+                       --find-copies-harder --ignore-cr-at-eol
+                       --text --ignore-space-at-eol --ignore-space-change
+                       --ignore-all-space --ignore-blank-lines --exit-code
+                       --quiet --ext-diff --no-ext-diff
+                       --no-prefix --src-prefix= --dst-prefix=
+                       --inter-hunk-context=
+                       --patience --histogram --minimal
+                       --raw --word-diff --word-diff-regex=
+                       --dirstat --dirstat= --dirstat-by-file
+                       --dirstat-by-file= --cumulative
+                       --diff-algorithm=
+                       --submodule --submodule= --ignore-submodules
+                       --indent-heuristic --no-indent-heuristic
+                       --textconv --no-textconv
+                       --patch --no-patch
+                       --anchored=
+"
+
+__git_diff_difftool_options="--cached --staged --pickaxe-all --pickaxe-regex
+                       --base --ours --theirs --no-index --relative --merge-base
+                       $__git_diff_common_options"
+
+_git_diff ()
+{
+       __git_has_doubledash && return
+
+       case "$cur" in
+       --diff-algorithm=*)
+               __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
+               return
+               ;;
+       --submodule=*)
+               __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+               return
+               ;;
+       --color-moved=*)
+               __gitcomp "$__git_color_moved_opts" "" "${cur##--color-moved=}"
+               return
+               ;;
+       --color-moved-ws=*)
+               __gitcomp "$__git_color_moved_ws_opts" "" "${cur##--color-moved-ws=}"
+               return
+               ;;
+       --*)
+               __gitcomp_opts "$__git_diff_difftool_options"
+               return
+               ;;
+       esac
+       __git_complete_revlist_file
+}
+
+__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
+                       tkdiff vimdiff nvimdiff gvimdiff xxdiff araxis p4merge
+                       bc codecompare smerge
+"
+
+_git_difftool ()
+{
+       __git_has_doubledash && return
+
+       case "$cur" in
+       --tool=*)
+               __gitcomp "$__git_mergetools_common kompare" "" "${cur##--tool=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin difftool "$__git_diff_difftool_options"
+               return
+               ;;
+       esac
+       __git_complete_revlist_file
+}
+
+__git_fetch_recurse_submodules="yes on-demand no"
+
+_git_fetch ()
+{
+       case "$cur" in
+       --recurse-submodules=*)
+               __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
+               return
+               ;;
+       --filter=*)
+               __gitcomp "blob:none blob:limit= sparse:oid=" "" "${cur##--filter=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin fetch
+               return
+               ;;
+       esac
+       __git_complete_remote_or_refspec
+}
+
+__git_format_patch_extra_options="
+       --full-index --not --all --no-prefix --src-prefix=
+       --dst-prefix= --notes
+"
+
+_git_format_patch ()
+{
+       case "$cur" in
+       --thread=*)
+               __gitcomp "deep shallow" "" "${cur##--thread=}"
+               return
+               ;;
+       --base=*|--interdiff=*|--range-diff=*)
+               __git_complete_refs --cur="${cur#--*=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin format-patch "$__git_format_patch_extra_options"
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+_git_fsck ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin fsck
+               return
+               ;;
+       esac
+}
+
+_git_gitk ()
+{
+       __gitk_main
+}
+
+# Lists matching symbol names from a tag (as in ctags) file.
+# 1: List symbol names matching this word.
+# 2: The tag file to list symbol names from.
+# 3: A prefix to be added to each listed symbol name (optional).
+# 4: A suffix to be appended to each listed symbol name (optional).
+__git_match_ctag () {
+       awk -v pfx="${3-}" -v sfx="${4-}" "
+               /^${1//\//\\/}/ { print pfx \$1 sfx }
+               " "$2"
+}
+
+# Complete symbol names from a tag file.
+# Usage: __git_complete_symbol [<option>]...
+# --tags=<file>: The tag file to list symbol names from instead of the
+#                default "tags".
+# --pfx=<prefix>: A prefix to be added to each symbol name.
+# --cur=<word>: The current symbol name to be completed.  Defaults to
+#               the current word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each symbol name instead
+#                 of the default space.
+__git_complete_symbol () {
+       local tags=tags pfx="" cur_="${cur-}" sfx=" "
+
+       while test $# != 0; do
+               case "$1" in
+               --tags=*)       tags="${1##--tags=}" ;;
+               --pfx=*)        pfx="${1##--pfx=}" ;;
+               --cur=*)        cur_="${1##--cur=}" ;;
+               --sfx=*)        sfx="${1##--sfx=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       if test -r "$tags"; then
+               __gitcomp_direct "$(__git_match_ctag "$cur_" "$tags" "$pfx" "$sfx")"
+       fi
+}
+
+_git_grep ()
+{
+       __git_has_doubledash && return
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin grep
+               return
+               ;;
+       esac
+
+       case "$cword,$prev" in
+       $((__git_cmd_idx+1)),*|*,-*)
+               __git_complete_symbol && return
+               ;;
+       esac
+
+       __git_complete_refs
+}
+
+_git_help ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin help
+               return
+               ;;
+       esac
+       if test -n "${GIT_TESTING_ALL_COMMAND_LIST-}"
+       then
+               __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(__git --list-cmds=alias,list-guide) gitk"
+       else
+               __gitcomp "$(__git --list-cmds=main,nohelpers,alias,list-guide) gitk"
+       fi
+}
+
+_git_init ()
+{
+       case "$cur" in
+       --shared=*)
+               __gitcomp "
+                       false true umask group all world everybody
+                       " "" "${cur##--shared=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin init
+               return
+               ;;
+       esac
+}
+
+_git_ls_files ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin ls-files
+               return
+               ;;
+       esac
+
+       # XXX ignore options like --modified and always suggest all cached
+       # files.
+       __git_complete_index_file "--cached"
+}
+
+_git_ls_remote ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin ls-remote
+               return
+               ;;
+       esac
+       __gitcomp_nl "$(__git_remotes)"
+}
+
+_git_ls_tree ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin ls-tree
+               return
+               ;;
+       esac
+
+       __git_complete_file
+}
+
+# Options that go well for log, shortlog and gitk
+__git_log_common_options="
+       --not --all
+       --branches --tags --remotes
+       --first-parent --merges --no-merges
+       --max-count=
+       --max-age= --since= --after=
+       --min-age= --until= --before=
+       --min-parents= --max-parents=
+       --no-min-parents --no-max-parents
+"
+# Options that go well for log and gitk (not shortlog)
+__git_log_gitk_options="
+       --dense --sparse --full-history
+       --simplify-merges --simplify-by-decoration
+       --left-right --notes --no-notes
+"
+# Options that go well for log and shortlog (not gitk)
+__git_log_shortlog_options="
+       --author= --committer= --grep=
+       --all-match --invert-grep
+"
+
+__git_log_pretty_formats="oneline short medium full fuller reference email raw format: tformat: mboxrd"
+__git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default human raw unix auto: format:"
+
+_git_log ()
+{
+       __git_has_doubledash && return
+       __git_find_repo_path
+
+       local merge=""
+       if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
+               merge="--merge"
+       fi
+       case "$prev,$cur" in
+       -L,:*:*)
+               return  # fall back to Bash filename completion
+               ;;
+       -L,:*)
+               __git_complete_symbol --cur="${cur#:}" --sfx=":"
+               return
+               ;;
+       -G,*|-S,*)
+               __git_complete_symbol
+               return
+               ;;
+       esac
+       case "$cur" in
+       --pretty=*|--format=*)
+               __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
+                       " "" "${cur#*=}"
+               return
+               ;;
+       --date=*)
+               __gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
+               return
+               ;;
+       --decorate=*)
+               __gitcomp "full short no" "" "${cur##--decorate=}"
+               return
+               ;;
+       --diff-algorithm=*)
+               __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
+               return
+               ;;
+       --submodule=*)
+               __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+               return
+               ;;
+       --no-walk=*)
+               __gitcomp "sorted unsorted" "" "${cur##--no-walk=}"
+               return
+               ;;
+       --*)
+               __gitcomp_opts "
+                       $__git_log_common_options
+                       $__git_log_shortlog_options
+                       $__git_log_gitk_options
+                       --root --topo-order --date-order --reverse
+                       --follow --full-diff
+                       --abbrev-commit --no-abbrev-commit --abbrev=
+                       --relative-date --date=
+                       --pretty= --format= --oneline
+                       --show-signature
+                       --cherry-mark
+                       --cherry-pick
+                       --graph
+                       --decorate --decorate= --no-decorate
+                       --walk-reflogs
+                       --no-walk --no-walk= --do-walk
+                       --parents --children
+                       --expand-tabs --expand-tabs= --no-expand-tabs
+                       $merge
+                       $__git_diff_common_options
+                       --pickaxe-all --pickaxe-regex
+                       "
+               return
+               ;;
+       -L:*:*)
+               return  # fall back to Bash filename completion
+               ;;
+       -L:*)
+               __git_complete_symbol --cur="${cur#-L:}" --sfx=":"
+               return
+               ;;
+       -G*)
+               __git_complete_symbol --pfx="-G" --cur="${cur#-G}"
+               return
+               ;;
+       -S*)
+               __git_complete_symbol --pfx="-S" --cur="${cur#-S}"
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+_git_merge ()
+{
+       __git_complete_strategy && return
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin merge
+               return
+       esac
+       __git_complete_refs
+}
+
+_git_mergetool ()
+{
+       case "$cur" in
+       --tool=*)
+               __gitcomp "$__git_mergetools_common tortoisemerge" "" "${cur##--tool=}"
+               return
+               ;;
+       --*)
+               __gitcomp_opts "--tool= --prompt --no-prompt --gui --no-gui"
+               return
+               ;;
+       esac
+}
+
+_git_merge_base ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin merge-base
+               return
+               ;;
+       esac
+       __git_complete_refs
+}
+
+_git_mv ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin mv
+               return
+               ;;
+       esac
+
+       if [ $(__git_count_arguments "mv") -gt 0 ]; then
+               # We need to show both cached and untracked files (including
+               # empty directories) since this may not be the last argument.
+               __git_complete_index_file "--cached --others --directory"
+       else
+               __git_complete_index_file "--cached"
+       fi
+}
+
+_git_notes ()
+{
+       local subcommands='add append copy edit get-ref list merge prune remove show'
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+
+       case "$subcommand,$cur" in
+       ,--*)
+               __gitcomp_builtin notes
+               ;;
+       ,*)
+               case "$prev" in
+               --ref)
+                       __git_complete_refs
+                       ;;
+               *)
+                       __gitcomp "$subcommands --ref"
+                       ;;
+               esac
+               ;;
+       *,--reuse-message=*|*,--reedit-message=*)
+               __git_complete_refs --cur="${cur#*=}"
+               ;;
+       *,--*)
+               __gitcomp_builtin notes_$subcommand
+               ;;
+       prune,*|get-ref,*)
+               # this command does not take a ref, do not complete it
+               ;;
+       *)
+               case "$prev" in
+               -m|-F)
+                       ;;
+               *)
+                       __git_complete_refs
+                       ;;
+               esac
+               ;;
+       esac
+}
+
+_git_pull ()
+{
+       __git_complete_strategy && return
+
+       case "$cur" in
+       --recurse-submodules=*)
+               __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin pull
+
+               return
+               ;;
+       esac
+       __git_complete_remote_or_refspec
+}
+
+__git_push_recurse_submodules="check on-demand only"
+
+__git_complete_force_with_lease ()
+{
+       local cur_=$1
+
+       case "$cur_" in
+       --*=)
+               ;;
+       *:*)
+               __git_complete_refs --cur="${cur_#*:}"
+               ;;
+       *)
+               __git_complete_refs --cur="$cur_"
+               ;;
+       esac
+}
+
+_git_push ()
+{
+       case "$prev" in
+       --repo)
+               __gitcomp_nl "$(__git_remotes)"
+               return
+               ;;
+       --recurse-submodules)
+               __gitcomp "$__git_push_recurse_submodules"
+               return
+               ;;
+       esac
+       case "$cur" in
+       --repo=*)
+               __gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
+               return
+               ;;
+       --recurse-submodules=*)
+               __gitcomp "$__git_push_recurse_submodules" "" "${cur##--recurse-submodules=}"
+               return
+               ;;
+       --force-with-lease=*)
+               __git_complete_force_with_lease "${cur##--force-with-lease=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin push
+               return
+               ;;
+       esac
+       __git_complete_remote_or_refspec
+}
+
+_git_range_diff ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_opts "
+                       --creation-factor= --no-dual-color
+                       $__git_diff_common_options
+               "
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+__git_rebase_inprogress_options="--continue --skip --abort --quit --show-current-patch"
+__git_rebase_interactive_inprogress_options="$__git_rebase_inprogress_options --edit-todo"
+
+_git_rebase ()
+{
+       __git_find_repo_path
+       if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then
+               __gitcomp_opts "$__git_rebase_interactive_inprogress_options"
+               return
+       elif [ -d "$__git_repo_path"/rebase-apply ] || \
+            [ -d "$__git_repo_path"/rebase-merge ]; then
+               __gitcomp_opts "$__git_rebase_inprogress_options"
+               return
+       fi
+       __git_complete_strategy && return
+       case "$cur" in
+       --whitespace=*)
+               __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
+               return
+               ;;
+       --onto=*)
+               __git_complete_refs --cur="${cur##--onto=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin rebase "" \
+                       "$__git_rebase_interactive_inprogress_options"
+
+               return
+       esac
+       __git_complete_refs
+}
+
+_git_reflog ()
+{
+       local subcommands="show delete expire"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+
+       if [ -z "$subcommand" ]; then
+               __gitcomp "$subcommands"
+       else
+               __git_complete_refs
+       fi
+}
+
+__git_send_email_options="--no-cc-cover --cc= --no-bcc --force --relogin-delay= --to= --suppress-cc= --no-annotate --no-chain-reply-to --sendmail-cmd= --no-identity --transfer-encoding= --validate --no-smtp-auth --confirm= --no-format-patch --reply-to= --smtp-pass= --smtp-server= --annotate --envelope-sender= --no-validate --dry-run --no-thread --smtp-debug= --no-to --thread --no-xmailer --identity= --no-signed-off-cc --no-signed-off-by-cc --smtp-domain= --to-cover --8bit-encoding= --bcc= --smtp-ssl-cert-path= --smtp-user= --cc-cmd= --to-cmd= --no-cc --smtp-server-option= --in-reply-to= --subject= --batch-size= --smtp-auth= --compose --smtp-server-port= --xmailer --no-to-cover --chain-reply-to --smtp-encryption= --dump-aliases --quiet --smtp-ssl --signed-off-cc --signed-off-by-cc --suppress-from --compose-encoding= --no-suppress-from --sender= --from= --format-patch --cc-cover --numbered --no-numbered --signoff --stdout --cover-letter --numbered-files --suffix= --start-number= --reroll-count= --filename-max-length= --rfc --cover-from-description= --subject-prefix= --output-directory= --keep-subject --no-binary --zero-commit --ignore-if-in-upstream --no-stat --add-header= --from --attach --inline --signature= --base= --signature-file= --progress --interdiff= --range-diff= --creation-factor= --binary -- --no-signoff --no-stdout --no-cover-letter --no-numbered-files --no-suffix --no-start-number --no-reroll-count --no-filename-max-length --no-cover-from-description --no-zero-commit --no-ignore-if-in-upstream --no-add-header --no-from --no-in-reply-to --no-attach --no-signature --no-base --no-signature-file --no-quiet --no-progress --no-interdiff --no-range-diff --no-creation-factor"
+__git_send_email_confirm_options="always never auto cc compose"
+__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
+
+_git_send_email ()
+{
+       case "$prev" in
+       --to|--cc|--bcc|--from)
+               __gitcomp_nl "$(__git send-email --dump-aliases)"
+               return
+               ;;
+       esac
+
+       case "$cur" in
+       --confirm=*)
+               __gitcomp "
+                       $__git_send_email_confirm_options
+                       " "" "${cur##--confirm=}"
+               return
+               ;;
+       --suppress-cc=*)
+               __gitcomp "
+                       $__git_send_email_suppresscc_options
+                       " "" "${cur##--suppress-cc=}"
+
+               return
+               ;;
+       --smtp-encryption=*)
+               __gitcomp "ssl tls" "" "${cur##--smtp-encryption=}"
+               return
+               ;;
+       --thread=*)
+               __gitcomp "deep shallow" "" "${cur##--thread=}"
+               return
+               ;;
+       --to=*|--cc=*|--bcc=*|--from=*)
+               __gitcomp "$(__git send-email --dump-aliases)" "" "${cur#--*=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin send-email "$__git_send_email_options $__git_format_patch_extra_options"
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+_git_stage ()
+{
+       _git_add
+}
+
+_git_status ()
+{
+       local complete_opt
+       local untracked_state
+
+       case "$cur" in
+       --ignore-submodules=*)
+               __gitcomp "none untracked dirty all" "" "${cur##--ignore-submodules=}"
+               return
+               ;;
+       --untracked-files=*)
+               __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
+               return
+               ;;
+       --column=*)
+               __gitcomp "
+                       always never auto column row plain dense nodense
+                       " "" "${cur##--column=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin status
+               return
+               ;;
+       esac
+
+       untracked_state="$(__git_get_option_value "-u" "--untracked-files=" \
+               "$__git_untracked_file_modes" "status.showUntrackedFiles")"
+
+       case "$untracked_state" in
+       no)
+               # --ignored option does not matter
+               complete_opt=
+               ;;
+       all|normal|*)
+               complete_opt="--cached --directory --no-empty-directory --others"
+
+               if [ -n "$(__git_find_on_cmdline "--ignored")" ]; then
+                       complete_opt="$complete_opt --ignored --exclude=*"
+               fi
+               ;;
+       esac
+
+       __git_complete_index_file "$complete_opt"
+}
+
+_git_switch ()
+{
+       local dwim_opt="$(__git_checkout_default_dwim_mode)"
+
+       case "$prev" in
+       -c|-C|--orphan)
+               # Complete local branches (and DWIM branch
+               # remote branch names) for an option argument
+               # specifying a new branch name. This is for
+               # convenience, assuming new branches are
+               # possibly based on pre-existing branch names.
+               __git_complete_refs $dwim_opt --mode="heads"
+               return
+               ;;
+       *)
+               ;;
+       esac
+
+       case "$cur" in
+       --conflict=*)
+               __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
+               ;;
+       --*)
+               __gitcomp_builtin switch
+               ;;
+       *)
+               # Unlike in git checkout, git switch --orphan does not take
+               # a start point. Thus we really have nothing to complete after
+               # the branch name.
+               if [ -n "$(__git_find_on_cmdline "--orphan")" ]; then
+                       return
+               fi
+
+               # At this point, we've already handled special completion for
+               # -c/-C, and --orphan. There are 3 main things left to
+               # complete:
+               # 1) a start-point for -c/-C or -d/--detach
+               # 2) a remote head, for --track
+               # 3) a branch name, possibly including DWIM remote branches
+
+               if [ -n "$(__git_find_on_cmdline "-c -C -d --detach")" ]; then
+                       __git_complete_refs --mode="refs"
+               elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
+                       __git_complete_refs --mode="remote-heads"
+               else
+                       __git_complete_refs $dwim_opt --mode="heads"
+               fi
+               ;;
+       esac
+}
+
+__git_config_get_set_variables ()
+{
+       local prevword word config_file= c=$cword
+       while [ $c -gt "$__git_cmd_idx" ]; do
+               word="${words[c]}"
+               case "$word" in
+               --system|--global|--local|--file=*)
+                       config_file="$word"
+                       break
+                       ;;
+               -f|--file)
+                       config_file="$word $prevword"
+                       break
+                       ;;
+               esac
+               prevword=$word
+               c=$((--c))
+       done
+
+       __git config $config_file --name-only --list
+}
+
+__git_config_vars=
+__git_compute_config_vars ()
+{
+       test -n "$__git_config_vars" ||
+       __git_config_vars="$(git help --config-for-completion | sort -u)"
+}
+
+# Completes possible values of various configuration variables.
+#
+# Usage: __git_complete_config_variable_value [<option>]...
+# --varname=<word>: The name of the configuration variable whose value is
+#                   to be completed.  Defaults to the previous word on the
+#                   command line.
+# --cur=<word>: The current value to be completed.  Defaults to the current
+#               word to be completed.
+__git_complete_config_variable_value ()
+{
+       local varname="$prev" cur_="$cur"
+
+       while test $# != 0; do
+               case "$1" in
+               --varname=*)    varname="${1##--varname=}" ;;
+               --cur=*)        cur_="${1##--cur=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       if [ "${BASH_VERSINFO[0]:-0}" -ge 4 ]; then
+               varname="${varname,,}"
+       else
+               varname="$(echo "$varname" |tr A-Z a-z)"
+       fi
+
+       case "$varname" in
+       branch.*.remote|branch.*.pushremote)
+               __gitcomp_nl "$(__git_remotes)" "" "$cur_"
+               return
+               ;;
+       branch.*.merge)
+               __git_complete_refs --cur="$cur_"
+               return
+               ;;
+       branch.*.rebase)
+               __gitcomp "false true merges interactive" "" "$cur_"
+               return
+               ;;
+       remote.pushdefault)
+               __gitcomp_nl "$(__git_remotes)" "" "$cur_"
+               return
+               ;;
+       remote.*.fetch)
+               local remote="${varname#remote.}"
+               remote="${remote%.fetch}"
+               if [ -z "$cur_" ]; then
+                       __gitcomp_nl "refs/heads/" "" "" ""
+                       return
+               fi
+               __gitcomp_nl "$(__git_refs_remotes "$remote")" "" "$cur_"
+               return
+               ;;
+       remote.*.push)
+               local remote="${varname#remote.}"
+               remote="${remote%.push}"
+               __gitcomp_nl "$(__git for-each-ref \
+                       --format='%(refname):%(refname)' refs/heads)" "" "$cur_"
+               return
+               ;;
+       pull.twohead|pull.octopus)
+               __git_compute_merge_strategies
+               __gitcomp "$__git_merge_strategies" "" "$cur_"
+               return
+               ;;
+       color.pager)
+               __gitcomp "false true" "" "$cur_"
+               return
+               ;;
+       color.*.*)
+               __gitcomp "
+                       normal black red green yellow blue magenta cyan white
+                       bold dim ul blink reverse
+                       " "" "$cur_"
+               return
+               ;;
+       color.*)
+               __gitcomp "false true always never auto" "" "$cur_"
+               return
+               ;;
+       diff.submodule)
+               __gitcomp "$__git_diff_submodule_formats" "" "$cur_"
+               return
+               ;;
+       help.format)
+               __gitcomp "man info web html" "" "$cur_"
+               return
+               ;;
+       log.date)
+               __gitcomp "$__git_log_date_formats" "" "$cur_"
+               return
+               ;;
+       sendemail.aliasfiletype)
+               __gitcomp "mutt mailrc pine elm gnus" "" "$cur_"
+               return
+               ;;
+       sendemail.confirm)
+               __gitcomp "$__git_send_email_confirm_options" "" "$cur_"
+               return
+               ;;
+       sendemail.suppresscc)
+               __gitcomp "$__git_send_email_suppresscc_options" "" "$cur_"
+               return
+               ;;
+       sendemail.transferencoding)
+               __gitcomp "7bit 8bit quoted-printable base64" "" "$cur_"
+               return
+               ;;
+       *.*)
+               return
+               ;;
+       esac
+}
+
+# Completes configuration sections, subsections, variable names.
+#
+# Usage: __git_complete_config_variable_name [<option>]...
+# --cur=<word>: The current configuration section/variable name to be
+#               completed.  Defaults to the current word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each fully completed
+#                 configuration variable name (but not to sections or
+#                 subsections) instead of the default space.
+__git_complete_config_variable_name ()
+{
+       local cur_="$cur" sfx=" "
+
+       while test $# != 0; do
+               case "$1" in
+               --cur=*)        cur_="${1##--cur=}" ;;
+               --sfx=*)        sfx="${1##--sfx=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       case "$cur_" in
+       branch.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       branch.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_#*.}"
+               __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
+               __gitcomp "autoSetupMerge autoSetupRebase" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       guitool.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "
+                       argPrompt cmd confirm needsFile noConsole noRescan
+                       prompt revPrompt revUnmerged title
+                       " "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       difftool.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       man.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "cmd path" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       mergetool.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       pager.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_#*.}"
+               __git_compute_all_commands
+               __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       remote.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "
+                       url proxy fetch push mirror skipDefaultUpdate
+                       receivepack uploadpack tagOpt pushurl
+                       " "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       remote.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_#*.}"
+               __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
+               __gitcomp "pushDefault" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       url.*.*)
+               local pfx="${cur_%.*}."
+               cur_="${cur_##*.}"
+               __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx"
+               return
+               ;;
+       *.*)
+               __git_compute_config_vars
+               __gitcomp "$__git_config_vars" "" "$cur_" "$sfx"
+               ;;
+       *)
+               __git_compute_config_vars
+               __gitcomp_nl "$(echo "$__git_config_vars" |
+                               awk -F . '{
+                                       sections[$1] = 1
+                               }
+                               END {
+                                       for (s in sections)
+                                               print s "."
+                               }
+                               ')" "" "$cur_" ""
+               ;;
+       esac
+}
+
+# Completes '='-separated configuration sections/variable names and values
+# for 'git -c section.name=value'.
+#
+# Usage: __git_complete_config_variable_name_and_value [<option>]...
+# --cur=<word>: The current configuration section/variable name/value to be
+#               completed. Defaults to the current word to be completed.
+__git_complete_config_variable_name_and_value ()
+{
+       local cur_="$cur"
+
+       while test $# != 0; do
+               case "$1" in
+               --cur=*)        cur_="${1##--cur=}" ;;
+               *)              return 1 ;;
+               esac
+               shift
+       done
+
+       case "$cur_" in
+       *=*)
+               __git_complete_config_variable_value \
+                       --varname="${cur_%%=*}" --cur="${cur_#*=}"
+               ;;
+       *)
+               __git_complete_config_variable_name --cur="$cur_" --sfx='='
+               ;;
+       esac
+}
+
+_git_config ()
+{
+       case "$prev" in
+       --get|--get-all|--unset|--unset-all)
+               __gitcomp_nl "$(__git_config_get_set_variables)"
+               return
+               ;;
+       *.*)
+               __git_complete_config_variable_value
+               return
+               ;;
+       esac
+       case "$cur" in
+       --*)
+               __gitcomp_builtin config
+               ;;
+       *)
+               __git_complete_config_variable_name
+               ;;
+       esac
+}
+
+_git_remote ()
+{
+       local subcommands="
+               add rename remove set-head set-branches
+               get-url set-url show prune update
+               "
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               case "$cur" in
+               --*)
+                       __gitcomp_builtin remote
+                       ;;
+               *)
+                       __gitcomp "$subcommands"
+                       ;;
+               esac
+               return
+       fi
+
+       case "$subcommand,$cur" in
+       add,--*)
+               __gitcomp_builtin remote_add
+               ;;
+       add,*)
+               ;;
+       set-head,--*)
+               __gitcomp_builtin remote_set-head
+               ;;
+       set-branches,--*)
+               __gitcomp_builtin remote_set-branches
+               ;;
+       set-head,*|set-branches,*)
+               __git_complete_remote_or_refspec
+               ;;
+       update,--*)
+               __gitcomp_builtin remote_update
+               ;;
+       update,*)
+               __gitcomp_nl "$(__git_remotes) $(__git_get_config_variables "remotes")"
+               ;;
+       set-url,--*)
+               __gitcomp_builtin remote_set-url
+               ;;
+       get-url,--*)
+               __gitcomp_builtin remote_get-url
+               ;;
+       prune,--*)
+               __gitcomp_builtin remote_prune
+               ;;
+       *)
+               __gitcomp_nl "$(__git_remotes)"
+               ;;
+       esac
+}
+
+_git_replace ()
+{
+       case "$cur" in
+       --format=*)
+               __gitcomp "short medium long" "" "${cur##--format=}"
+               return
+               ;;
+       --*)
+               __gitcomp_builtin replace
+               return
+               ;;
+       esac
+       __git_complete_refs
+}
+
+_git_rerere ()
+{
+       local subcommands="clear forget diff remaining status gc"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if test -z "$subcommand"
+       then
+               __gitcomp "$subcommands"
+               return
+       fi
+}
+
+_git_reset ()
+{
+       __git_has_doubledash && return
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin reset
+               return
+               ;;
+       esac
+       __git_complete_refs
+}
+
+_git_restore ()
+{
+       case "$prev" in
+       -s)
+               __git_complete_refs
+               return
+               ;;
+       esac
+
+       case "$cur" in
+       --conflict=*)
+               __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
+               ;;
+       --source=*)
+               __git_complete_refs --cur="${cur##--source=}"
+               ;;
+       --*)
+               __gitcomp_builtin restore
+               ;;
+       *)
+               if __git rev-parse --verify --quiet HEAD >/dev/null; then
+                       __git_complete_index_file "--modified"
+               fi
+       esac
+}
+
+__git_revert_inprogress_options=$__git_sequencer_inprogress_options
+
+_git_revert ()
+{
+       __git_find_repo_path
+       if [ -f "$__git_repo_path"/REVERT_HEAD ]; then
+               __gitcomp_opts "$__git_revert_inprogress_options"
+               return
+       fi
+       __git_complete_strategy && return
+       case "$cur" in
+       --*)
+               __gitcomp_builtin revert "" \
+                       "$__git_revert_inprogress_options"
+               return
+               ;;
+       esac
+       __git_complete_refs
+}
+
+_git_rm ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin rm
+               return
+               ;;
+       esac
+
+       __git_complete_index_file "--cached"
+}
+
+_git_shortlog ()
+{
+       __git_has_doubledash && return
+
+       case "$cur" in
+       --*)
+               __gitcomp_opts "
+                       $__git_log_common_options
+                       $__git_log_shortlog_options
+                       --numbered --summary --email
+                       "
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+_git_show ()
+{
+       __git_has_doubledash && return
+
+       case "$cur" in
+       --pretty=*|--format=*)
+               __gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
+                       " "" "${cur#*=}"
+               return
+               ;;
+       --diff-algorithm=*)
+               __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
+               return
+               ;;
+       --submodule=*)
+               __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+               return
+               ;;
+       --color-moved=*)
+               __gitcomp "$__git_color_moved_opts" "" "${cur##--color-moved=}"
+               return
+               ;;
+       --color-moved-ws=*)
+               __gitcomp "$__git_color_moved_ws_opts" "" "${cur##--color-moved-ws=}"
+               return
+               ;;
+       --*)
+               __gitcomp_opts "--pretty= --format= --abbrev-commit --no-abbrev-commit
+                       --oneline --show-signature
+                       --expand-tabs --expand-tabs= --no-expand-tabs
+                       $__git_diff_common_options
+                       "
+               return
+               ;;
+       esac
+       __git_complete_revlist_file
+}
+
+_git_show_branch ()
+{
+       case "$cur" in
+       --*)
+               __gitcomp_builtin show-branch
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+__gitcomp_directories ()
+{
+       local _tmp_dir _tmp_completions _found=0
+
+       # Get the directory of the current token; this differs from dirname
+       # in that it keeps up to the final trailing slash.  If no slash found
+       # that's fine too.
+       [[ "$cur" =~ .*/ ]]
+       _tmp_dir=$BASH_REMATCH
+
+       # Find possible directory completions, adding trailing '/' characters,
+       # de-quoting, and handling unusual characters.
+       while IFS= read -r -d $'\0' c ; do
+               # If there are directory completions, find ones that start
+               # with "$cur", the current token, and put those in COMPREPLY
+               if [[ $c == "$cur"* ]]; then
+                       COMPREPLY+=("$c/")
+                       _found=1
+               fi
+       done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)
+
+       if [[ $_found == 0 ]] && [[ "$cur" =~ /$ ]]; then
+               # No possible further completions any deeper, so assume we're at
+               # a leaf directory and just consider it complete
+               __gitcomp_direct_append "$cur "
+       fi
+}
+
+_git_sparse_checkout ()
+{
+       local subcommands="list init set disable add reapply"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               __gitcomp "$subcommands"
+               return
+       fi
+
+       case "$subcommand,$cur" in
+       *,--*)
+               __gitcomp_builtin sparse-checkout_$subcommand "" "--"
+               ;;
+       set,*|add,*)
+               if [ "$(__git config core.sparseCheckoutCone)" == "true" ] ||
+               [ -n "$(__git_find_on_cmdline --cone)" ]; then
+                       __gitcomp_directories
+               fi
+       esac
+}
+
+_git_stash ()
+{
+       local subcommands='push list show apply clear drop pop create branch'
+       local subcommand="$(__git_find_on_cmdline "$subcommands save")"
+
+       if [ -z "$subcommand" ]; then
+               case "$((cword - __git_cmd_idx)),$cur" in
+               *,--*)
+                       __gitcomp_builtin stash_push
+                       ;;
+               1,sa*)
+                       __gitcomp "save"
+                       ;;
+               1,*)
+                       __gitcomp "$subcommands"
+                       ;;
+               esac
+               return
+       fi
+
+       case "$subcommand,$cur" in
+       list,--*)
+               # NEEDSWORK: can we somehow unify this with the options in _git_log() and _git_show()
+               __gitcomp_builtin stash_list "$__git_log_common_options $__git_diff_common_options"
+               ;;
+       show,--*)
+               __gitcomp_builtin stash_show "$__git_diff_common_options"
+               ;;
+       *,--*)
+               __gitcomp_builtin "stash_$subcommand"
+               ;;
+       branch,*)
+               if [ $cword -eq $((__git_cmd_idx+2)) ]; then
+                       __git_complete_refs
+               else
+                       __gitcomp_nl "$(__git stash list \
+                                       | sed -n -e 's/:.*//p')"
+               fi
+               ;;
+       show,*|apply,*|drop,*|pop,*)
+               __gitcomp_nl "$(__git stash list \
+                               | sed -n -e 's/:.*//p')"
+               ;;
+       esac
+}
+
+_git_submodule ()
+{
+       __git_has_doubledash && return
+
+       local subcommands="add status init deinit update set-branch set-url summary foreach sync absorbgitdirs"
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               case "$cur" in
+               --*)
+                       __gitcomp_opts "--quiet"
+                       ;;
+               *)
+                       __gitcomp "$subcommands"
+                       ;;
+               esac
+               return
+       fi
+
+       case "$subcommand,$cur" in
+       add,--*)
+               __gitcomp_opts "--branch --force --name --reference --depth"
+               ;;
+       status,--*)
+               __gitcomp_opts "--cached --recursive"
+               ;;
+       deinit,--*)
+               __gitcomp_opts "--force --all"
+               ;;
+       update,--*)
+               __gitcomp_opts "
+                       --init --remote --no-fetch
+                       --recommend-shallow --no-recommend-shallow
+                       --force --rebase --merge --reference --depth --recursive --jobs
+               "
+               ;;
+       set-branch,--*)
+               __gitcomp_opts "--default --branch"
+               ;;
+       summary,--*)
+               __gitcomp_opts "--cached --files --summary-limit"
+               ;;
+       foreach,--*|sync,--*)
+               __gitcomp_opts "--recursive"
+               ;;
+       *)
+               ;;
+       esac
+}
+
+_git_svn ()
+{
+       local subcommands="
+               init fetch clone rebase dcommit log find-rev
+               set-tree commit-diff info create-ignore propget
+               proplist show-ignore show-externals branch tag blame
+               migrate mkdirs reset gc
+               "
+       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       if [ -z "$subcommand" ]; then
+               __gitcomp "$subcommands"
+       else
+               local remote_opts="--username= --config-dir= --no-auth-cache"
+               local fc_opts="
+                       --follow-parent --authors-file= --repack=
+                       --no-metadata --use-svm-props --use-svnsync-props
+                       --log-window-size= --no-checkout --quiet
+                       --repack-flags --use-log-author --localtime
+                       --add-author-from
+                       --recursive
+                       --ignore-paths= --include-paths= $remote_opts
+                       "
+               local init_opts="
+                       --template= --shared= --trunk= --tags=
+                       --branches= --stdlayout --minimize-url
+                       --no-metadata --use-svm-props --use-svnsync-props
+                       --rewrite-root= --prefix= $remote_opts
+                       "
+               local cmt_opts="
+                       --edit --rmdir --find-copies-harder --copy-similarity=
+                       "
+
+               case "$subcommand,$cur" in
+               fetch,--*)
+                       __gitcomp_opts "--revision= --fetch-all $fc_opts"
+                       ;;
+               clone,--*)
+                       __gitcomp_opts "--revision= $fc_opts $init_opts"
+                       ;;
+               init,--*)
+                       __gitcomp_opts "$init_opts"
+                       ;;
+               dcommit,--*)
+                       __gitcomp_opts "
+                               --merge --strategy= --verbose --dry-run
+                               --fetch-all --no-rebase --commit-url
+                               --revision --interactive $cmt_opts $fc_opts
+                               "
+                       ;;
+               set-tree,--*)
+                       __gitcomp_opts "--stdin $cmt_opts $fc_opts"
+                       ;;
+               create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
+               show-externals,--*|mkdirs,--*)
+                       __gitcomp_opts "--revision="
+                       ;;
+               log,--*)
+                       __gitcomp_opts "
+                               --limit= --revision= --verbose --incremental
+                               --oneline --show-commit --non-recursive
+                               --authors-file= --color
+                               "
+                       ;;
+               rebase,--*)
+                       __gitcomp_opts "
+                               --merge --verbose --strategy= --local
+                               --fetch-all --dry-run $fc_opts
+                               "
+                       ;;
+               commit-diff,--*)
+                       __gitcomp_opts "--message= --file= --revision= $cmt_opts"
+                       ;;
+               info,--*)
+                       __gitcomp_opts "--url"
+                       ;;
+               branch,--*)
+                       __gitcomp_opts "--dry-run --message --tag"
+                       ;;
+               tag,--*)
+                       __gitcomp_opts "--dry-run --message"
+                       ;;
+               blame,--*)
+                       __gitcomp_opts "--git-format"
+                       ;;
+               migrate,--*)
+                       __gitcomp_opts "
+                               --config-dir= --ignore-paths= --minimize
+                               --no-auth-cache --username=
+                               "
+                       ;;
+               reset,--*)
+                       __gitcomp_opts "--revision= --parent"
+                       ;;
+               *)
+                       ;;
+               esac
+       fi
+}
+
+_git_tag ()
+{
+       local i c="$__git_cmd_idx" f=0
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
+               case "$i" in
+               -d|--delete|-v|--verify)
+                       __gitcomp_direct "$(__git_tags "" "$cur" " ")"
+                       return
+                       ;;
+               -f)
+                       f=1
+                       ;;
+               esac
+               ((c++))
+       done
+
+       case "$prev" in
+       -m|-F)
+               ;;
+       -*|tag)
+               if [ $f = 1 ]; then
+                       __gitcomp_direct "$(__git_tags "" "$cur" " ")"
+               fi
+               ;;
+       *)
+               __git_complete_refs
+               ;;
+       esac
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin tag
+               ;;
+       esac
+}
+
+_git_whatchanged ()
+{
+       _git_log
+}
+
+__git_complete_worktree_paths ()
+{
+       local IFS=$'\n'
+       # Generate completion reply from worktree list skipping the first
+       # entry: it's the path of the main worktree, which can't be moved,
+       # removed, locked, etc.
+       __gitcomp_nl "$(git worktree list --porcelain |
+               sed -n -e '2,$ s/^worktree //p')"
+}
+
+_git_worktree ()
+{
+       local subcommands="add list lock move prune remove unlock"
+       local subcommand subcommand_idx
+
+       subcommand="$(__git_find_on_cmdline --show-idx "$subcommands")"
+       subcommand_idx="${subcommand% *}"
+       subcommand="${subcommand#* }"
+
+       case "$subcommand,$cur" in
+       ,*)
+               __gitcomp "$subcommands"
+               ;;
+       *,--*)
+               __gitcomp_builtin worktree_$subcommand
+               ;;
+       add,*)  # usage: git worktree add [<options>] <path> [<commit-ish>]
+               # Here we are not completing an --option, it's either the
+               # path or a ref.
+               case "$prev" in
+               -b|-B)  # Complete refs for branch to be created/reset.
+                       __git_complete_refs
+                       ;;
+               -*)     # The previous word is an -o|--option without an
+                       # unstuck argument: have to complete the path for
+                       # the new worktree, so don't list anything, but let
+                       # Bash fall back to filename completion.
+                       ;;
+               *)      # The previous word is not an --option, so it must
+                       # be either the 'add' subcommand, the unstuck
+                       # argument of an option (e.g. branch for -b|-B), or
+                       # the path for the new worktree.
+                       if [ $cword -eq $((subcommand_idx+1)) ]; then
+                               # Right after the 'add' subcommand: have to
+                               # complete the path, so fall back to Bash
+                               # filename completion.
+                               :
+                       else
+                               case "${words[cword-2]}" in
+                               -b|-B)  # After '-b <branch>': have to
+                                       # complete the path, so fall back
+                                       # to Bash filename completion.
+                                       ;;
+                               *)      # After the path: have to complete
+                                       # the ref to be checked out.
+                                       __git_complete_refs
+                                       ;;
+                               esac
+                       fi
+                       ;;
+               esac
+               ;;
+       lock,*|remove,*|unlock,*)
+               __git_complete_worktree_paths
+               ;;
+       move,*)
+               if [ $cword -eq $((subcommand_idx+1)) ]; then
+                       # The first parameter must be an existing working
+                       # tree to be moved.
+                       __git_complete_worktree_paths
+               else
+                       # The second parameter is the destination: it could
+                       # be any path, so don't list anything, but let Bash
+                       # fall back to filename completion.
+                       :
+               fi
+               ;;
+       esac
+}
+
+__git_complete_common () {
+       local command="$1"
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin "$command"
+               ;;
+       esac
+}
+
+__git_cmds_with_parseopt_helper=
+__git_support_parseopt_helper () {
+       test -n "$__git_cmds_with_parseopt_helper" ||
+               __git_cmds_with_parseopt_helper="$(__git --list-cmds=parseopt)"
+
+       case " $__git_cmds_with_parseopt_helper " in
+       *" $1 "*)
+               return 0
+               ;;
+       *)
+               return 1
+               ;;
+       esac
+}
+
+__git_have_func () {
+       declare -f -- "$1" >/dev/null 2>&1
+}
+
+__git_complete_command () {
+       local command="$1"
+       local completion_func="_git_${command//-/_}"
+       if ! __git_have_func $completion_func &&
+               __git_have_func _completion_loader
+       then
+               _completion_loader "git-$command"
+       fi
+       if __git_have_func $completion_func
+       then
+               $completion_func
+               return 0
+       elif __git_support_parseopt_helper "$command"
+       then
+               __git_complete_common "$command"
+               return 0
+       else
+               return 1
+       fi
+}
+
+__git_main ()
+{
+       local i c=1 command __git_dir __git_repo_path
+       local __git_C_args C_args_count=0
+       local __git_cmd_idx
+
+       while [ $c -lt $cword ]; do
+               i="${words[c]}"
+               case "$i" in
+               --git-dir=*)
+                       __git_dir="${i#--git-dir=}"
+                       ;;
+               --git-dir)
+                       ((c++))
+                       __git_dir="${words[c]}"
+                       ;;
+               --bare)
+                       __git_dir="."
+                       ;;
+               --help)
+                       command="help"
+                       break
+                       ;;
+               -c|--work-tree|--namespace)
+                       ((c++))
+                       ;;
+               -C)
+                       __git_C_args[C_args_count++]=-C
+                       ((c++))
+                       __git_C_args[C_args_count++]="${words[c]}"
+                       ;;
+               -*)
+                       ;;
+               *)
+                       command="$i"
+                       __git_cmd_idx="$c"
+                       break
+                       ;;
+               esac
+               ((c++))
+       done
+
+       if [ -z "${command-}" ]; then
+               case "$prev" in
+               --git-dir|-C|--work-tree)
+                       # these need a path argument, let's fall back to
+                       # Bash filename completion
+                       return
+                       ;;
+               -c)
+                       __git_complete_config_variable_name_and_value
+                       return
+                       ;;
+               --namespace)
+                       # we don't support completing these options' arguments
+                       return
+                       ;;
+               esac
+               case "$cur" in
+               --*)
+                       __gitcomp_opts "
+                       --paginate
+                       --no-pager
+                       --git-dir=
+                       --bare
+                       --version
+                       --exec-path
+                       --exec-path=
+                       --html-path
+                       --man-path
+                       --info-path
+                       --work-tree=
+                       --namespace=
+                       --no-replace-objects
+                       --help
+                       "
+                       ;;
+               *)
+                       if test -n "${GIT_TESTING_PORCELAIN_COMMAND_LIST-}"
+                       then
+                               __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+                       else
+                               local list_cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config
+
+                               if test "${GIT_COMPLETION_SHOW_ALL_COMMANDS-}" = "1"
+                               then
+                                       list_cmds=builtins,$list_cmds
+                               fi
+                               __gitcomp_nl "$(__git --list-cmds=$list_cmds)"
+                       fi
+                       ;;
+               esac
+               return
+       fi
+
+       __git_complete_command "$command" && return
+
+       local expansion=$(__git_aliased_command "$command")
+       if [ -n "$expansion" ]; then
+               words[1]=$expansion
+               __git_complete_command "$expansion"
+       fi
+}
+
+__gitk_main ()
+{
+       __git_has_doubledash && return
+
+       local __git_repo_path
+       __git_find_repo_path
+
+       local merge=""
+       if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
+               merge="--merge"
+       fi
+       case "$cur" in
+       --*)
+               __gitcomp_opts "
+                       $__git_log_common_options
+                       $__git_log_gitk_options
+                       $merge
+                       "
+               return
+               ;;
+       esac
+       __git_complete_revlist
+}
+
+if [[ -n ${ZSH_VERSION-} && -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
+       echo "ERROR: this script is obsolete, please see git-completion.zsh" 1>&2
+       return
+fi
+
+# The following function is based on code from:
+#
+#   bash_completion - programmable completion functions for bash 3.2+
+#
+#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
+#             © 2009-2010, Bash Completion Maintainers
+#                     <bash-completion-devel@lists.alioth.debian.org>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2, or (at your option)
+#   any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+#   The latest version of this software can be obtained here:
+#
+#   http://bash-completion.alioth.debian.org/
+#
+#   RELEASE: 2.x
+
+# This function reorganizes the words on the command line to be processed by
+# the rest of the script.
+#
+# This is roughly equivalent to going back in time and setting
+# COMP_WORDBREAKS to exclude '=' and ':'.  The intent is to
+# make option types like --date=<type> and <rev>:<path> easy to
+# recognize by treating each shell word as a single token.
+#
+# It is best not to set COMP_WORDBREAKS directly because the value is
+# shared with other completion scripts.  By the time the completion
+# function gets called, COMP_WORDS has already been populated so local
+# changes to COMP_WORDBREAKS have no effect.
+
+if ! type __git_get_comp_words_by_ref >/dev/null 2>&1; then
+__git_get_comp_words_by_ref ()
+{
+       local exclude i j first
+
+       # Which word separators to exclude?
+       exclude="${COMP_WORDBREAKS//[^=:]}"
+       cword=$COMP_CWORD
+       if [ -n "$exclude" ]; then
+               # List of word completion separators has shrunk;
+               # re-assemble words to complete.
+               for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
+                       # Append each nonempty word consisting of just
+                       # word separator characters to the current word.
+                       first=t
+                       while
+                               [ $i -gt 0 ] &&
+                               [ -n "${COMP_WORDS[$i]}" ] &&
+                               # word consists of excluded word separators
+                               [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
+                       do
+                               # Attach to the previous token,
+                               # unless the previous token is the command name.
+                               if [ $j -ge 2 ] && [ -n "$first" ]; then
+                                       ((j--))
+                               fi
+                               first=
+                               words[$j]=${words[j]}${COMP_WORDS[i]}
+                               if [ $i = $COMP_CWORD ]; then
+                                       cword=$j
+                               fi
+                               if (($i < ${#COMP_WORDS[@]} - 1)); then
+                                       ((i++))
+                               else
+                                       # Done.
+                                       break 2
+                               fi
+                       done
+                       words[$j]=${words[j]}${COMP_WORDS[i]}
+                       if [ $i = $COMP_CWORD ]; then
+                               cword=$j
+                       fi
+               done
+       else
+               words=("${COMP_WORDS[@]}")
+       fi
+
+       cur=${words[cword]}
+       prev=${words[cword-1]}
+}
+fi
+
+__git_func_wrap ()
+{
+       local cur words cword prev __git_cmd_idx=0
+       __git_get_comp_words_by_ref
+       $1
+}
+
+___git_complete ()
+{
+       local wrapper="__git_wrap${2}"
+       eval "$wrapper () { __git_func_wrap $2 ; }"
+       complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \
+               || complete -o default -o nospace -F $wrapper $1
+}
+
+# Setup the completion for git commands
+# 1: command or alias
+# 2: function to call (e.g. `git`, `gitk`, `git_fetch`)
+__git_complete ()
+{
+       local func
+
+       if __git_have_func $2; then
+               func=$2
+       elif __git_have_func __$2_main; then
+               func=__$2_main
+       elif __git_have_func _$2; then
+               func=_$2
+       else
+               echo "ERROR: could not find function '$2'" 1>&2
+               return 1
+       fi
+       ___git_complete $1 $func
+}
+
+if ! git --list-cmds=main >/dev/null 2>&1; then
+
+       declare -A __git_cmds
+       __git_cmds[list-complete]="apply blame cherry config difftool fsck help instaweb mergetool prune reflog remote repack replace request-pull send-email show-branch stage whatchanged"
+       __git_cmds[list-guide]="attributes cli core-tutorial credentials cvs-migration diffcore everyday faq glossary hooks ignore mailmap modules namespaces remote-helpers repository-layout revisions submodules tutorial tutorial-2 workflows"
+       __git_cmds[list-mainporcelain]="add am archive bisect branch bundle checkout cherry-pick citool clean clone commit describe diff fetch format-patch gc grep gui init log maintenance merge mv notes pull push range-diff rebase reset restore revert rm shortlog show sparse-checkout stash status submodule switch tag worktree gitk"
+       __git_cmds[main]="add add--interactive am annotate apply archimport archive bisect bisect--helper blame branch bugreport bundle cat-file check-attr check-ignore check-mailmap check-ref-format checkout checkout--worker checkout-index cherry cherry-pick citool clean clone column commit commit-graph commit-tree config count-objects credential credential-cache credential-cache--daemon credential-store cvsexportcommit cvsimport cvsserver daemon describe diff diff-files diff-index diff-tree difftool difftool--helper env--helper fast-export fast-import fetch fetch-pack filter-branch fmt-merge-msg for-each-ref for-each-repo format-patch fsck fsck-objects fsmonitor--daemon gc get-tar-commit-id grep gui gui--askpass hash-object help hook http-backend http-fetch http-push imap-send index-pack init init-db instaweb interpret-trailers legacy-rebase legacy-stash log ls-files ls-remote ls-tree mailinfo mailsplit maintenance merge merge-base merge-file merge-index merge-octopus merge-one-file merge-ours merge-recursive merge-recursive-ours merge-recursive-theirs merge-resolve merge-subtree merge-tree mergetool mktag mktree multi-pack-index mv name-rev notes p4 pack-objects pack-redundant pack-refs patch-id pickaxe prune prune-packed pull push quiltimport range-diff read-tree rebase rebase--helper receive-pack reflog relink remote remote-ext remote-fd remote-ftp remote-ftps remote-http remote-https remote-testsvn repack replace request-pull rerere reset restore rev-list rev-parse revert rm send-email send-pack serve sh-i18n--envsubst shell shortlog show show-branch show-index show-ref sparse-checkout stage stash status stripspace submodule submodule--helper svn switch symbolic-ref tag unpack-file unpack-objects update-index update-ref update-server-info upload-archive upload-archive--writer upload-pack var verify-commit verify-pack verify-tag version web--browse whatchanged worktree write-tree"
+       __git_cmds[others]=""
+       __git_cmds[parseopt]="add am apply archive bisect--helper blame branch bugreport cat-file check-attr check-ignore check-mailmap checkout checkout--worker checkout-index cherry cherry-pick clean clone column commit commit-graph config count-objects credential-cache credential-cache--daemon credential-store describe difftool env--helper fast-export fetch fmt-merge-msg for-each-ref for-each-repo format-patch fsck fsck-objects fsmonitor--daemon gc grep hash-object help hook init init-db interpret-trailers log ls-files ls-remote ls-tree merge merge-base merge-file mktree multi-pack-index mv name-rev notes pack-objects pack-refs pickaxe prune prune-packed pull push range-diff read-tree rebase receive-pack reflog remote repack replace rerere reset restore revert rm send-pack shortlog show show-branch show-index show-ref sparse-checkout stage stash status stripspace switch symbolic-ref tag update-index update-ref update-server-info upload-pack verify-commit verify-pack verify-tag version whatchanged write-tree "
+
+       # Override __git
+       __git ()
+       {
+               case "$1" in
+               --list-cmds=*)
+                       while read -r -d ',' x; do
+                               case "$x" in
+                               nohelpers)
+                                       ;;
+                               alias)
+                                       ;;
+                               config)
+                                       ;;
+                               *)
+                                       echo ${__git_cmds[$x]}
+                                       ;;
+                               esac
+                       done <<< "${1##--list-cmds=},"
+                       return
+                       ;;
+               esac
+               git ${__git_C_args:+"${__git_C_args[@]}"} \
+                       ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null
+       }
+
+fi
+
+___git_complete git __git_main
+___git_complete gitk __gitk_main
+
+# The following are necessary only for Cygwin, and only are needed
+# when the user has tab-completed the executable name and consequently
+# included the '.exe' suffix.
+#
+if [ "$OSTYPE" = cygwin ]; then
+       ___git_complete git.exe __git_main
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/git-prompt.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/git-prompt.sh
new file mode 100644 (file)
index 0000000..1435548
--- /dev/null
@@ -0,0 +1,589 @@
+# bash/zsh git prompt support
+#
+# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
+# Distributed under the GNU General Public License, version 2.0.
+#
+# This script allows you to see repository status in your prompt.
+#
+# To enable:
+#
+#    1) Copy this file to somewhere (e.g. ~/.git-prompt.sh).
+#    2) Add the following line to your .bashrc/.zshrc:
+#        source ~/.git-prompt.sh
+#    3a) Change your PS1 to call __git_ps1 as
+#        command-substitution:
+#        Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
+#        ZSH:  setopt PROMPT_SUBST ; PS1='[%n@%m %c$(__git_ps1 " (%s)")]\$ '
+#        the optional argument will be used as format string.
+#    3b) Alternatively, for a slightly faster prompt, __git_ps1 can
+#        be used for PROMPT_COMMAND in Bash or for precmd() in Zsh
+#        with two parameters, <pre> and <post>, which are strings
+#        you would put in $PS1 before and after the status string
+#        generated by the git-prompt machinery.  e.g.
+#        Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
+#          will show username, at-sign, host, colon, cwd, then
+#          various status string, followed by dollar and SP, as
+#          your prompt.
+#        ZSH:  precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
+#          will show username, pipe, then various status string,
+#          followed by colon, cwd, dollar and SP, as your prompt.
+#        Optionally, you can supply a third argument with a printf
+#        format string to finetune the output of the branch status
+#
+# The repository status will be displayed only if you are currently in a
+# git repository. The %s token is the placeholder for the shown status.
+#
+# The prompt status always includes the current branch name.
+#
+# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty value,
+# unstaged (*) and staged (+) changes will be shown next to the branch
+# name.  You can configure this per-repository with the
+# bash.showDirtyState variable, which defaults to true once
+# GIT_PS1_SHOWDIRTYSTATE is enabled.
+#
+# You can also see if currently something is stashed, by setting
+# GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed,
+# then a '$' will be shown next to the branch name.
+#
+# If you would like to see if there're untracked files, then you can set
+# GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're untracked
+# files, then a '%' will be shown next to the branch name.  You can
+# configure this per-repository with the bash.showUntrackedFiles
+# variable, which defaults to true once GIT_PS1_SHOWUNTRACKEDFILES is
+# enabled.
+#
+# If you would like to see the difference between HEAD and its upstream,
+# set GIT_PS1_SHOWUPSTREAM="auto".  A "<" indicates you are behind, ">"
+# indicates you are ahead, "<>" indicates you have diverged and "="
+# indicates that there is no difference. You can further control
+# behaviour by setting GIT_PS1_SHOWUPSTREAM to a space-separated list
+# of values:
+#
+#     verbose       show number of commits ahead/behind (+/-) upstream
+#     name          if verbose, then also show the upstream abbrev name
+#     legacy        don't use the '--count' option available in recent
+#                   versions of git-rev-list
+#     git           always compare HEAD to @{upstream}
+#     svn           always compare HEAD to your SVN upstream
+#
+# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
+# find one, or @{upstream} otherwise.  Once you have set
+# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
+# setting the bash.showUpstream config variable.
+#
+# You can change the separator between the branch name and the above
+# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
+# is SP.
+#
+# When there is an in-progress operation such as a merge, rebase,
+# revert, cherry-pick, or bisect, the prompt will include information
+# related to the operation, often in the form "|<OPERATION-NAME>".
+#
+# When the repository has a sparse-checkout, a notification of the form
+# "|SPARSE" will be included in the prompt.  This can be shortened to a
+# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted
+# by setting GIT_PS1_OMITSPARSESTATE.
+#
+# If you would like to see more information about the identity of
+# commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE
+# to one of these values:
+#
+#     contains      relative to newer annotated tag (v1.6.3.2~35)
+#     branch        relative to newer tag or branch (master~4)
+#     describe      relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
+#     tag           relative to any older tag (v1.6.3.1-13-gdd42c2f)
+#     default       exactly matching tag
+#
+# If you would like a colored hint about the current dirty state, set
+# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
+# the colored output of "git status -sb" and are available only when
+# using __git_ps1 for PROMPT_COMMAND or precmd in Bash,
+# but always available in Zsh.
+#
+# If you would like __git_ps1 to do nothing in the case when the current
+# directory is set up to be ignored by git, then set
+# GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the
+# repository level by setting bash.hideIfPwdIgnored to "false".
+
+# check whether printf supports -v
+__git_printf_supports_v=
+printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1
+
+# stores the divergence from upstream in $p
+# used by GIT_PS1_SHOWUPSTREAM
+__git_ps1_show_upstream ()
+{
+       local key value
+       local svn_remote svn_url_pattern count n
+       local upstream_type=git legacy="" verbose="" name=""
+
+       svn_remote=()
+       # get some config options from git-config
+       local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
+       while read -r key value; do
+               case "$key" in
+               bash.showupstream)
+                       GIT_PS1_SHOWUPSTREAM="$value"
+                       if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then
+                               p=""
+                               return
+                       fi
+                       ;;
+               svn-remote.*.url)
+                       svn_remote[$((${#svn_remote[@]} + 1))]="$value"
+                       svn_url_pattern="$svn_url_pattern\\|$value"
+                       upstream_type=svn+git # default upstream type is SVN if available, else git
+                       ;;
+               esac
+       done <<< "$output"
+
+       # parse configuration values
+       local option
+       for option in ${GIT_PS1_SHOWUPSTREAM}; do
+               case "$option" in
+               git|svn) upstream_type="$option" ;;
+               verbose) verbose=1 ;;
+               legacy)  legacy=1  ;;
+               name)    name=1 ;;
+               esac
+       done
+
+       # Find our upstream type
+       case "$upstream_type" in
+       git)    upstream_type="@{upstream}" ;;
+       svn*)
+               # get the upstream from the "git-svn-id: ..." in a commit message
+               # (git-svn uses essentially the same procedure internally)
+               local -a svn_upstream
+               svn_upstream=($(git log --first-parent -1 \
+                                       --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
+               if [[ 0 -ne ${#svn_upstream[@]} ]]; then
+                       svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]}
+                       svn_upstream=${svn_upstream%@*}
+                       local n_stop="${#svn_remote[@]}"
+                       for ((n=1; n <= n_stop; n++)); do
+                               svn_upstream=${svn_upstream#${svn_remote[$n]}}
+                       done
+
+                       if [[ -z "$svn_upstream" ]]; then
+                               # default branch name for checkouts with no layout:
+                               upstream_type=${GIT_SVN_ID:-git-svn}
+                       else
+                               upstream_type=${svn_upstream#/}
+                       fi
+               elif [[ "svn+git" = "$upstream_type" ]]; then
+                       upstream_type="@{upstream}"
+               fi
+               ;;
+       esac
+
+       # Find how many commits we are ahead/behind our upstream
+       if [[ -z "$legacy" ]]; then
+               count="$(git rev-list --count --left-right \
+                               "$upstream_type"...HEAD 2>/dev/null)"
+       else
+               # produce equivalent output to --count for older versions of git
+               local commits
+               if commits="$(git rev-list --left-right "$upstream_type"...HEAD 2>/dev/null)"
+               then
+                       local commit behind=0 ahead=0
+                       for commit in $commits
+                       do
+                               case "$commit" in
+                               "<"*) ((behind++)) ;;
+                               *)    ((ahead++))  ;;
+                               esac
+                       done
+                       count="$behind  $ahead"
+               else
+                       count=""
+               fi
+       fi
+
+       # calculate the result
+       if [[ -z "$verbose" ]]; then
+               case "$count" in
+               "") # no upstream
+                       p="" ;;
+               "0      0") # equal to upstream
+                       p="=" ;;
+               "0      "*) # ahead of upstream
+                       p=">" ;;
+               *"      0") # behind upstream
+                       p="<" ;;
+               *)          # diverged from upstream
+                       p="<>" ;;
+               esac
+       else # verbose, set upstream instead of p
+               case "$count" in
+               "") # no upstream
+                       upstream="" ;;
+               "0      0") # equal to upstream
+                       upstream="|u=" ;;
+               "0      "*) # ahead of upstream
+                       upstream="|u+${count#0  }" ;;
+               *"      0") # behind upstream
+                       upstream="|u-${count%   0}" ;;
+               *)          # diverged from upstream
+                       upstream="|u+${count#*  }-${count%      *}" ;;
+               esac
+               if [[ -n "$count" && -n "$name" ]]; then
+                       __git_ps1_upstream_name=$(git rev-parse \
+                               --abbrev-ref "$upstream_type" 2>/dev/null)
+                       if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
+                               upstream="$upstream \${__git_ps1_upstream_name}"
+                       else
+                               upstream="$upstream ${__git_ps1_upstream_name}"
+                               # not needed anymore; keep user's
+                               # environment clean
+                               unset __git_ps1_upstream_name
+                       fi
+               fi
+       fi
+
+}
+
+# Helper function that is meant to be called from __git_ps1.  It
+# injects color codes into the appropriate gitstring variables used
+# to build a gitstring. Colored variables are responsible for clearing
+# their own color.
+__git_ps1_colorize_gitstring ()
+{
+       if [[ -n ${ZSH_VERSION-} ]]; then
+               local c_red='%F{red}'
+               local c_green='%F{green}'
+               local c_lblue='%F{blue}'
+               local c_clear='%f'
+       else
+               # Using \[ and \] around colors is necessary to prevent
+               # issues with command line editing/browsing/completion!
+               local c_red='\[\e[31m\]'
+               local c_green='\[\e[32m\]'
+               local c_lblue='\[\e[1;34m\]'
+               local c_clear='\[\e[0m\]'
+       fi
+       local bad_color=$c_red
+       local ok_color=$c_green
+       local flags_color="$c_lblue"
+
+       local branch_color=""
+       if [ $detached = no ]; then
+               branch_color="$ok_color"
+       else
+               branch_color="$bad_color"
+       fi
+       if [ -n "$c" ]; then
+               c="$branch_color$c$c_clear"
+       fi
+       b="$branch_color$b$c_clear"
+
+       if [ -n "$w" ]; then
+               w="$bad_color$w$c_clear"
+       fi
+       if [ -n "$i" ]; then
+               i="$ok_color$i$c_clear"
+       fi
+       if [ -n "$s" ]; then
+               s="$flags_color$s$c_clear"
+       fi
+       if [ -n "$u" ]; then
+               u="$bad_color$u$c_clear"
+       fi
+}
+
+# Helper function to read the first line of a file into a variable.
+# __git_eread requires 2 arguments, the file path and the name of the
+# variable, in that order.
+__git_eread ()
+{
+       test -r "$1" && IFS=$'\r\n' read "$2" <"$1"
+}
+
+# see if a cherry-pick or revert is in progress, if the user has committed a
+# conflict resolution with 'git commit' in the middle of a sequence of picks or
+# reverts then CHERRY_PICK_HEAD/REVERT_HEAD will not exist so we have to read
+# the todo file.
+__git_sequencer_status ()
+{
+       local todo
+       if test -f "$g/CHERRY_PICK_HEAD"
+       then
+               r="|CHERRY-PICKING"
+               return 0;
+       elif test -f "$g/REVERT_HEAD"
+       then
+               r="|REVERTING"
+               return 0;
+       elif __git_eread "$g/sequencer/todo" todo
+       then
+               case "$todo" in
+               p[\ \   ]|pick[\ \      ]*)
+                       r="|CHERRY-PICKING"
+                       return 0
+               ;;
+               revert[\ \      ]*)
+                       r="|REVERTING"
+                       return 0
+               ;;
+               esac
+       fi
+       return 1
+}
+
+# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
+# when called from PS1 using command substitution
+# in this mode it prints text to add to bash PS1 prompt (includes branch name)
+#
+# __git_ps1 requires 2 or 3 arguments when called from PROMPT_COMMAND (pc)
+# in that case it _sets_ PS1. The arguments are parts of a PS1 string.
+# when two arguments are given, the first is prepended and the second appended
+# to the state string when assigned to PS1.
+# The optional third parameter will be used as printf format string to further
+# customize the output of the git-status string.
+# In this mode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
+__git_ps1 ()
+{
+       # preserve exit status
+       local exit=$?
+       local pcmode=no
+       local detached=no
+       local ps1pc_start='\u@\h:\w '
+       local ps1pc_end='\$ '
+       local printf_format=' (%s)'
+
+       case "$#" in
+               2|3)    pcmode=yes
+                       ps1pc_start="$1"
+                       ps1pc_end="$2"
+                       printf_format="${3:-$printf_format}"
+                       # set PS1 to a plain prompt so that we can
+                       # simply return early if the prompt should not
+                       # be decorated
+                       PS1="$ps1pc_start$ps1pc_end"
+               ;;
+               0|1)    printf_format="${1:-$printf_format}"
+               ;;
+               *)      return $exit
+               ;;
+       esac
+
+       # ps1_expanded:  This variable is set to 'yes' if the shell
+       # subjects the value of PS1 to parameter expansion:
+       #
+       #   * bash does unless the promptvars option is disabled
+       #   * zsh does not unless the PROMPT_SUBST option is set
+       #   * POSIX shells always do
+       #
+       # If the shell would expand the contents of PS1 when drawing
+       # the prompt, a raw ref name must not be included in PS1.
+       # This protects the user from arbitrary code execution via
+       # specially crafted ref names.  For example, a ref named
+       # 'refs/heads/$(IFS=_;cmd=sudo_rm_-rf_/;$cmd)' might cause the
+       # shell to execute 'sudo rm -rf /' when the prompt is drawn.
+       #
+       # Instead, the ref name should be placed in a separate global
+       # variable (in the __git_ps1_* namespace to avoid colliding
+       # with the user's environment) and that variable should be
+       # referenced from PS1.  For example:
+       #
+       #     __git_ps1_foo=$(do_something_to_get_ref_name)
+       #     PS1="...stuff...\${__git_ps1_foo}...stuff..."
+       #
+       # If the shell does not expand the contents of PS1, the raw
+       # ref name must be included in PS1.
+       #
+       # The value of this variable is only relevant when in pcmode.
+       #
+       # Assume that the shell follows the POSIX specification and
+       # expands PS1 unless determined otherwise.  (This is more
+       # likely to be correct if the user has a non-bash, non-zsh
+       # shell and safer than the alternative if the assumption is
+       # incorrect.)
+       #
+       local ps1_expanded=yes
+       [ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
+       [ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
+
+       local repo_info rev_parse_exit_code
+       repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
+               --is-bare-repository --is-inside-work-tree \
+               --short HEAD 2>/dev/null)"
+       rev_parse_exit_code="$?"
+
+       if [ -z "$repo_info" ]; then
+               return $exit
+       fi
+
+       local short_sha=""
+       if [ "$rev_parse_exit_code" = "0" ]; then
+               short_sha="${repo_info##*$'\n'}"
+               repo_info="${repo_info%$'\n'*}"
+       fi
+       local inside_worktree="${repo_info##*$'\n'}"
+       repo_info="${repo_info%$'\n'*}"
+       local bare_repo="${repo_info##*$'\n'}"
+       repo_info="${repo_info%$'\n'*}"
+       local inside_gitdir="${repo_info##*$'\n'}"
+       local g="${repo_info%$'\n'*}"
+
+       if [ "true" = "$inside_worktree" ] &&
+          [ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] &&
+          [ "$(git config --bool bash.hideIfPwdIgnored)" != "false" ] &&
+          git check-ignore -q .
+       then
+               return $exit
+       fi
+
+       local sparse=""
+       if [ -z "${GIT_PS1_COMPRESSSPARSESTATE-}" ] &&
+          [ -z "${GIT_PS1_OMITSPARSESTATE-}" ] &&
+          [ "$(git config --bool core.sparseCheckout)" = "true" ]; then
+               sparse="|SPARSE"
+       fi
+
+       local r=""
+       local b=""
+       local step=""
+       local total=""
+       if [ -d "$g/rebase-merge" ]; then
+               __git_eread "$g/rebase-merge/head-name" b
+               __git_eread "$g/rebase-merge/msgnum" step
+               __git_eread "$g/rebase-merge/end" total
+               r="|REBASE"
+       else
+               if [ -d "$g/rebase-apply" ]; then
+                       __git_eread "$g/rebase-apply/next" step
+                       __git_eread "$g/rebase-apply/last" total
+                       if [ -f "$g/rebase-apply/rebasing" ]; then
+                               __git_eread "$g/rebase-apply/head-name" b
+                               r="|REBASE"
+                       elif [ -f "$g/rebase-apply/applying" ]; then
+                               r="|AM"
+                       else
+                               r="|AM/REBASE"
+                       fi
+               elif [ -f "$g/MERGE_HEAD" ]; then
+                       r="|MERGING"
+               elif __git_sequencer_status; then
+                       :
+               elif [ -f "$g/BISECT_LOG" ]; then
+                       r="|BISECTING"
+               fi
+
+               if [ -n "$b" ]; then
+                       :
+               elif [ -h "$g/HEAD" ]; then
+                       # symlink symbolic ref
+                       b="$(git symbolic-ref HEAD 2>/dev/null)"
+               else
+                       local head=""
+                       if ! __git_eread "$g/HEAD" head; then
+                               return $exit
+                       fi
+                       # is it a symbolic ref?
+                       b="${head#ref: }"
+                       if [ "$head" = "$b" ]; then
+                               detached=yes
+                               b="$(
+                               case "${GIT_PS1_DESCRIBE_STYLE-}" in
+                               (contains)
+                                       git describe --contains HEAD ;;
+                               (branch)
+                                       git describe --contains --all HEAD ;;
+                               (tag)
+                                       git describe --tags HEAD ;;
+                               (describe)
+                                       git describe HEAD ;;
+                               (* | default)
+                                       git describe --tags --exact-match HEAD ;;
+                               esac 2>/dev/null)" ||
+
+                               b="$short_sha..."
+                               b="($b)"
+                       fi
+               fi
+       fi
+
+       if [ -n "$step" ] && [ -n "$total" ]; then
+               r="$r $step/$total"
+       fi
+
+       local w=""
+       local i=""
+       local s=""
+       local u=""
+       local h=""
+       local c=""
+       local p="" # short version of upstream state indicator
+       local upstream="" # verbose version of upstream state indicator
+
+       if [ "true" = "$inside_gitdir" ]; then
+               if [ "true" = "$bare_repo" ]; then
+                       c="BARE:"
+               else
+                       b="GIT_DIR!"
+               fi
+       elif [ "true" = "$inside_worktree" ]; then
+               if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
+                  [ "$(git config --bool bash.showDirtyState)" != "false" ]
+               then
+                       git diff --no-ext-diff --quiet || w="*"
+                       git diff --no-ext-diff --cached --quiet || i="+"
+                       if [ -z "$short_sha" ] && [ -z "$i" ]; then
+                               i="#"
+                       fi
+               fi
+               if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ] &&
+                  git rev-parse --verify --quiet refs/stash >/dev/null
+               then
+                       s="$"
+               fi
+
+               if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ] &&
+                  [ "$(git config --bool bash.showUntrackedFiles)" != "false" ] &&
+                  git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null
+               then
+                       u="%${ZSH_VERSION+%}"
+               fi
+
+               if [ -n "${GIT_PS1_COMPRESSSPARSESTATE-}" ] &&
+                  [ "$(git config --bool core.sparseCheckout)" = "true" ]; then
+                       h="?"
+               fi
+
+               if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
+                       __git_ps1_show_upstream
+               fi
+       fi
+
+       local z="${GIT_PS1_STATESEPARATOR-" "}"
+
+       b=${b##refs/heads/}
+       if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
+               __git_ps1_branch_name=$b
+               b="\${__git_ps1_branch_name}"
+       fi
+
+       # NO color option unless in PROMPT_COMMAND mode or it's Zsh
+       if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+               if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+                       __git_ps1_colorize_gitstring
+               fi
+       fi
+
+       local f="$h$w$i$s$u$p"
+       local gitstring="$c$b${f:+$z$f}${sparse}$r${upstream}"
+
+       if [ $pcmode = yes ]; then
+               if [ "${__git_printf_supports_v-}" != yes ]; then
+                       gitstring=$(printf -- "$printf_format" "$gitstring")
+               else
+                       printf -v gitstring -- "$printf_format" "$gitstring"
+               fi
+               PS1="$ps1pc_start$gitstring$ps1pc_end"
+       else
+               printf -- "$printf_format" "$gitstring"
+       fi
+
+       return $exit
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/gitfast.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/gitfast.plugin.zsh
new file mode 100644 (file)
index 0000000..a6db0c6
--- /dev/null
@@ -0,0 +1,11 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+source "${0:A:h}/git-prompt.sh"
+
+function git_prompt_info() {
+  dirty="$(parse_git_dirty)"
+  __git_ps1 "${ZSH_THEME_GIT_PROMPT_PREFIX//\%/%%}%s${dirty//\%/%%}${ZSH_THEME_GIT_PROMPT_SUFFIX//\%/%%}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/update b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitfast/update
new file mode 100755 (executable)
index 0000000..feb13ff
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+url="https://raw.githubusercontent.com/felipec/git-completion"
+version="1.3.7"
+
+curl -s -o _git "${url}/v${version}/git-completion.zsh" &&
+curl -s -o git-completion.bash "${url}/v${version}/git-completion.bash" &&
+curl -s -o git-prompt.sh "${url}/v${version}/git-prompt.sh"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/github/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/github/README.md
new file mode 100644 (file)
index 0000000..5d8b625
--- /dev/null
@@ -0,0 +1,45 @@
+# github plugin
+
+This plugin supports working with GitHub from the command line. It provides a few things:
+
+* Sets up the `hub` wrapper and completions for the `git` command if you have [`hub`](https://github.com/github/hub) installed.
+* Completion for the [`github` Ruby gem](https://github.com/defunkt/github-gem).
+* Convenience functions for working with repos and URLs.
+
+### Functions
+
+* `empty_gh` - Creates a new empty repo (with a `README.md`) and pushes it to GitHub
+* `new_gh` - Initializes an existing directory as a repo and pushes it to GitHub
+* `exist_gh` - Takes an existing repo and pushes it to GitHub
+
+
+## Installation
+
+[Hub](https://github.com/github/hub) needs to be installed if you want to use it. On OS X with Homebrew, this can be done with `brew install hub`. The `hub` completion definition needs to be added to your `$FPATH` before initializing OMZ.
+
+The [`github` Ruby gem](https://github.com/defunkt/github-gem) needs to be installed if you want to use it.
+
+### Configuration
+
+These settings affect `github`'s behavior.
+
+#### Environment variables
+
+* `$GITHUB_USER`
+* `$GITHUB_PASSWORD`
+
+#### Git configuration options
+
+* `github.user` - GitHub username for repo operations
+
+See `man hub` for more details.
+
+### Homebrew installation note
+
+If you have installed `hub` using Homebrew, its completions may not be on your `$FPATH` if you are using the system `zsh`. Homebrew installs `zsh` completion definitions to `/usr/local/share/zsh/site-functions`, which will be on `$FPATH` for the Homebrew-installed `zsh`, but not for the system `zsh`. If you want it to work with the system `zsh`, add this to your `~/.zshrc` before it sources `oh-my-zsh.sh`.
+
+```zsh
+if (( ! ${fpath[(I)/usr/local/share/zsh/site-functions]} )); then
+  FPATH=/usr/local/share/zsh/site-functions:$FPATH
+fi
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/github/_hub b/stow/oh-my-zsh/.oh-my-zsh/plugins/github/_hub
new file mode 100644 (file)
index 0000000..209a3df
--- /dev/null
@@ -0,0 +1,174 @@
+#compdef hub
+
+# Zsh will source this file when attempting to autoload the "_hub" function,
+# typically on the first attempt to complete the hub command.  We define two new
+# setup helper routines (one for the zsh-distributed version, one for the
+# git-distributed, bash-based version).  Then we redefine the "_hub" function to
+# call "_git" after some other interception.
+#
+# This is pretty fragile, if you think about it.  Any number of implementation
+# changes in the "_git" scripts could cause problems down the road.  It would be
+# better if the stock git completions were just a bit more permissive about how
+# it allowed third-party commands to be added.
+
+(( $+functions[__hub_setup_zsh_fns] )) ||
+__hub_setup_zsh_fns () {
+  (( $+functions[_git-alias] )) ||
+  _git-alias () {
+    _arguments \
+      '-s[output shell script suitable for eval]' \
+      '1::shell:(zsh bash csh)'
+  }
+
+  (( $+functions[_git-browse] )) ||
+  _git-browse () {
+    _arguments \
+      '-u[output the URL]' \
+      '2::subpage:(wiki commits issues)'
+  }
+
+  (( $+functions[_git-compare] )) ||
+  _git-compare () {
+    _arguments \
+      '-u[output the URL]' \
+      ':[start...]end range:'
+  }
+
+  (( $+functions[_git-create] )) ||
+  _git-create () {
+    _arguments \
+      '::name (REPOSITORY or ORGANIZATION/REPOSITORY):' \
+      '-p[make repository private]' \
+      '-d[description]:description' \
+      '-h[home page]:repository home page URL:_urls'
+  }
+
+  (( $+functions[_git-fork] )) ||
+  _git-fork () {
+    _arguments \
+      '--no-remote[do not add a remote for the new fork]'
+  }
+
+  (( $+functions[_git-pull-request] )) ||
+  _git-pull-request () {
+    _arguments \
+      '-f[force (skip check for local commits)]' \
+      '-b[base]:base ("branch", "owner\:branch", "owner/repo\:branch"):' \
+      '-h[head]:head ("branch", "owner\:branch", "owner/repo\:branch"):' \
+      - set1 \
+        '-m[message]' \
+        '-F[file]' \
+        '--no-edit[use first commit message for pull request title/description]' \
+        '-a[user]' \
+        '-M[milestone]' \
+        '-l[labels]' \
+      - set2 \
+        '-i[issue]:issue number:' \
+      - set3 \
+        '::issue-url:_urls'
+  }
+
+  # stash the "real" command for later
+  functions[_hub_orig_git_commands]=$functions[_git_commands]
+
+  # Replace it with our own wrapper.
+  declare -f _git_commands >& /dev/null && unfunction _git_commands
+  _git_commands () {
+    local ret=1
+    # call the original routine
+    _call_function ret _hub_orig_git_commands
+
+    # Effectively "append" our hub commands to the behavior of the original
+    # _git_commands function.  Using this wrapper function approach ensures
+    # that we only offer the user the hub subcommands when the user is
+    # actually trying to complete subcommands.
+    hub_commands=(
+      alias:'show shell instructions for wrapping git'
+      pull-request:'open a pull request on GitHub'
+      pr:'list or checkout a GitHub pull request'
+      issue:'list or create a GitHub issue'
+      release:'list or create a GitHub release'
+      fork:'fork origin repo on GitHub'
+      create:'create new repo on GitHub for the current project'
+      delete:'delete a GitHub repo'
+      browse:'browse the project on GitHub'
+      compare:'open GitHub compare view'
+      ci-status:'show status of GitHub checks for a commit'
+      sync:'update local branches from upstream'
+    )
+    _describe -t hub-commands 'hub command' hub_commands && ret=0
+
+    return ret
+  }
+}
+
+(( $+functions[__hub_setup_bash_fns] )) ||
+__hub_setup_bash_fns () {
+  # TODO more bash-style fns needed here to complete subcommand args.  They take
+  # the form "_git_CMD" where "CMD" is something like "pull-request".
+
+  # Duplicate and rename the 'list_all_commands' function
+  eval "$(declare -f __git_list_all_commands | \
+        sed 's/__git_list_all_commands/__git_list_all_commands_without_hub/')"
+
+  # Wrap the 'list_all_commands' function with extra hub commands
+  __git_list_all_commands() {
+    cat <<-EOF
+alias
+pull-request
+pr
+issue
+release
+fork
+create
+delete
+browse
+compare
+ci-status
+sync
+EOF
+    __git_list_all_commands_without_hub
+  }
+
+  # Ensure cached commands are cleared
+  __git_all_commands=""
+}
+
+# redefine _hub to a much smaller function in the steady state
+_hub () {
+  # only attempt to intercept the normal "_git" helper functions once
+  (( $+__hub_func_replacement_done )) ||
+    () {
+      # At this stage in the shell's execution the "_git" function has not yet
+      # been autoloaded, so the "_git_commands" or "__git_list_all_commands"
+      # functions will not be defined.  Call it now (with a bogus no-op service
+      # to prevent premature completion) so that we can wrap them.
+      if declare -f _git >& /dev/null ; then
+        _hub_noop () { __hub_zsh_provided=1 }       # zsh-provided will call this one
+        __hub_noop_main () { __hub_git_provided=1 } # git-provided will call this one
+        local service=hub_noop
+        _git
+        unfunction _hub_noop
+        unfunction __hub_noop_main
+        service=git
+      fi
+
+      if (( $__hub_zsh_provided )) ; then
+        __hub_setup_zsh_fns
+      elif (( $__hub_git_provided )) ; then
+        __hub_setup_bash_fns
+      fi
+
+      __hub_func_replacement_done=1
+    }
+
+  # Now perform the actual completion, allowing the "_git" function to call our
+  # replacement "_git_commands" function as needed.  Both versions expect
+  # service=git or they will call nonexistent routines or end up in an infinite
+  # loop.
+  service=git
+  declare -f _git >& /dev/null && _git
+}
+
+# make sure we actually attempt to complete on the first "tab" from the user
+_hub
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/github/github.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/github/github.plugin.zsh
new file mode 100644 (file)
index 0000000..79114ff
--- /dev/null
@@ -0,0 +1,77 @@
+# Set up hub wrapper for git, if it is available; https://github.com/github/hub
+if (( $+commands[hub] )); then
+  alias git=hub
+fi
+
+# Functions #################################################################
+
+# Based on https://github.com/dbb/githome/blob/master/.config/zsh/functions
+
+# empty_gh <NAME_OF_REPO>
+#
+# Use this when creating a new repo from scratch.
+# Creates a new repo with a blank README.md in it and pushes it up to GitHub.
+empty_gh() { # [NAME_OF_REPO]
+  emulate -L zsh
+  local repo=$1
+
+  mkdir "$repo"
+  touch "$repo/README.md"
+  new_gh "$repo"
+}
+
+# new_gh [DIRECTORY]
+#
+# Use this when you have a directory that is not yet set up for git.
+# This function will add all non-hidden files to git.
+new_gh() { # [DIRECTORY]
+  emulate -L zsh
+  local repo="$1"
+  cd "$repo" \
+    || return
+
+  git init \
+    || return
+  # add all non-dot files
+  print '.*'"\n"'*~' >> .gitignore
+  git add [^.]* \
+    || return
+  git add -f .gitignore \
+    || return
+  git commit -m 'Initial commit.' \
+    || return
+  hub create \
+    || return
+  git push -u origin master \
+    || return
+}
+
+# exist_gh [DIRECTORY]
+#
+# Use this when you have a git repo that's ready to go and you want to add it
+# to your GitHub.
+exist_gh() { # [DIRECTORY]
+  emulate -L zsh
+  local repo=$1
+  cd "$repo"
+
+  hub create \
+    || return
+  git push -u origin master
+}
+
+# git.io "GitHub URL"
+#
+# Shorten GitHub url, example:
+#   https://github.com/nvogel/dotzsh    >   https://git.io/8nU25w
+# source: https://github.com/nvogel/dotzsh
+# documentation: https://github.com/blog/985-git-io-github-url-shortener
+#
+git.io() {
+  # emulate -L zsh
+  # curl -i -s https://git.io -F "url=$1" | grep "Location" | cut -f 2 -d " "
+  print -u2 ${(%):-"%F{yellow}%BThe \`git.io\` is deprecated.%b\nView the announcement made by GitHub: https://github.blog/changelog/2022-01-11-git-io-no-longer-accepts-new-urls/%f"}
+}
+
+# End Functions #############################################################
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitignore/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitignore/README.md
new file mode 100644 (file)
index 0000000..753dd31
--- /dev/null
@@ -0,0 +1,17 @@
+# gitignore
+
+This plugin enables you the use of [gitignore.io](https://www.gitignore.io/) from the command line. You need an active internet connection.
+
+To use it, add `gitignore` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... gitignore)
+```
+
+## Plugin commands
+
+* `gi list`: List all the currently supported gitignore.io templates.
+
+* `gi [TEMPLATENAME]`: Show git-ignore output on the command line, e.g. `gi java` to exclude class and package files.
+
+* `gi [TEMPLATENAME] >> .gitignore`: Appending programming language settings to your projects .gitignore.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gitignore/gitignore.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gitignore/gitignore.plugin.zsh
new file mode 100644 (file)
index 0000000..a687f5c
--- /dev/null
@@ -0,0 +1,12 @@
+function gi() { curl -fLw '\n' https://www.gitignore.io/api/"${(j:,:)@}" }
+
+_gitignoreio_get_command_list() {
+  curl -sfL https://www.gitignore.io/api/list | tr "," "\n"
+}
+
+_gitignoreio () {
+  compset -P '*,'
+  compadd -S '' `_gitignoreio_get_command_list`
+}
+
+compdef _gitignoreio gi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/README.md
new file mode 100644 (file)
index 0000000..1f4a8be
--- /dev/null
@@ -0,0 +1,9 @@
+# glassfish
+
+The glassfish plugin adds completion for the `asadmin` utility, a command to manage
+[Oracle GlassFish](https://docs.oracle.com/cd/E18930_01/html/821-2416/giobi.html) servers.
+
+To use it, add `glassfish` to the plugins array in your zshrc file:
+```zsh
+plugins=(... glassfish)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/_asadmin b/stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/_asadmin
new file mode 100644 (file)
index 0000000..a6a7af5
--- /dev/null
@@ -0,0 +1,1150 @@
+#compdef asadmin
+#autoload
+
+local -a _1st_arguments
+_1st_arguments=(
+    "add-library:adds one or more library JAR files to GlassFish Server"
+    "add-resources:creates the resources specified in an XML file"
+    "apply-http-lb-changes:applies load balancer configuration changes to the load balancer"
+    "backup-domain:performs a backup on the domain"
+    "change-admin-password:changes the administrator password"
+    "change-master-broker:changes the master broker in a Message Queue cluster providing JMS services for a GlassFish Server cluster."
+    "change-master-password:changes the master password"
+    "collect-log-files:creates a ZIP archive of all available log files"
+    "configure-jms-cluster:configures the Message Queue cluster providing JMS services to a GlassFish Server cluster"
+    "configure-lb-weight:sets load balancing weights for clustered instances"
+    "configure-ldap-for-admin:configures the authentication realm named admin-realm for the given LDAP"
+    "copy-config:copies an existing named configuration to create another configuration"
+    "create-admin-object:adds the administered object with the specified JNDI name for a resource adapter"
+    "create-application-ref:creates a reference to an application"
+    "create-audit-module:adds an audit module"
+    "create-auth-realm:adds the named authentication realm"
+    "create-cluster:creates a GlassFish Server cluster"
+    "create-connector-connection-pool:adds a connection pool with the specified connection pool name"
+    "create-connector-resource:registers the connector resource with the specified JNDI name"
+    "create-connector-security-map:creates a security map for the specified connector connection pool"
+    "create-connector-work-security-map:creates a work security map for the specified resource adapter"
+    "create-custom-resource:creates a custom resource"
+    "create-domain:creates a domain"
+    "create-file-user:creates a new file user"
+    "create-http:sets HTTP parameters for a protocol"
+    "create-http-health-checker:creates a health-checker for a specified load balancer configuration"
+    "create-http-lb:creates a load balancer"
+    "create-http-lb-config:creates a configuration for the load balancer"
+    "create-http-lb-ref:adds an existing cluster or server instance to an existing load balancer configuration or load balancer"
+    "create-http-listener:adds a new HTTP network listener socket"
+    "create-http-redirect:adds a new HTTP redirect"
+    "create-iiop-listener:adds an IIOP listener"
+    "create-instance:creates a GlassFish Server instance"
+    "create-jacc-provider:enables administrators to create a JACC provider that can be used by third-party authorization modules for applications running in GlassFish Server"
+    "create-javamail-resource:creates a JavaMail session resource"
+    "create-jdbc-connection-pool:registers a JDBC connection pool"
+    "create-jdbc-resource:creates a JDBC resource with the specified JNDI name"
+    "create-jms-host:creates a JMS host"
+    "create-jms-resource:creates a JMS resource"
+    "create-jmsdest:creates a JMS physical destination"
+    "create-jndi-resource:registers a JNDI resource"
+    "create-jvm-options:creates options for the Java application launcher"
+    "create-lifecycle-module:creates a lifecycle module"
+    "create-local-instance:creates a GlassFish Server instance on the host where the subcommand is run"
+    "create-message-security-provider:enables administrators to create a message security provider, which specifies how SOAP messages will be secured."
+    "create-network-listener:adds a new network listener socket"
+    "create-node-config:creates a node that is not enabled for remote communication"
+    "create-node-dcom:creates a node that is enabled for com munication over DCOM"
+    "create-node-ssh:creates a node that is enabled for communication over SSH"
+    "create-password-alias:creates a password alias"
+    "create-profiler:creates the profiler element"
+    "create-protocol:adds a new protocol"
+    "create-protocol-filter:adds a new protocol filter"
+    "create-protocol-finder:adds a new protocol finder"
+    "create-resource-adapter-config:creates the configuration information for the connector module"
+    "create-resource-ref:creates a reference to a resource"
+    "create-service:configures the starting of a DAS or a GlassFish Server instance on an unattended boot"
+    "create-ssl:creates and configures the SSL element in the selected HTTP listener, IIOP listener, or IIOP service"
+    "create-system-properties:adds one or more system property elements that can be referenced elsewhere in the configuration."
+    "create-threadpool:adds a thread pool"
+    "create-transport:adds a new transport"
+    "create-virtual-server:creates the named virtual server"
+    "delete-admin-object:removes the administered object with the specified JNDI name."
+    "delete-application-ref:removes a reference to an applica tion"
+    "delete-audit-module:removes the named audit-module"
+    "delete-auth-realm:removes the named authentication realm"
+    "delete-cluster:deletes a GlassFish Server cluster"
+    "delete-config:deletes an existing named configuration"
+    "delete-connector-connection-pool:removes the specified connector connection pool"
+    "delete-connector-resource:removes the connector resource with the specified JNDI name"
+    "delete-connector-security-map:deletes a security map for the specified connector connection pool"
+    "delete-connector-work-security-map:deletes a work security map for the specified resource adapter"
+    "delete-custom-resource:removes a custom resource"
+    "delete-domain:deletes a domain"
+    "delete-file-user:removes the named file user"
+    "delete-http:removes HTTP parameters from a protocol"
+    "delete-http-health-checker:deletes the health-checker for a specified load balancer configuration"
+    "delete-http-lb:deletes a load balancer"
+    "delete-http-lb-config:deletes a load balancer configuration"
+    "delete-http-lb-ref:deletes the cluster or server instance from a load balancer"
+    "delete-http-listener:removes a network listener"
+    "delete-http-redirect:removes an HTTP redirect"
+    "delete-iiop-listener:removes an IIOP listener"
+    "delete-instance:deletes a GlassFish Server instance"
+    "delete-jacc-provider:enables administrators to delete JACC providers defined for a domain"
+    "delete-javamail-resource:removes a JavaMail session resource"
+    "delete-jdbc-connection-pool:removes the specified JDBC connection pool"
+    "delete-jdbc-resource:removes a JDBC resource with the specified JNDI name"
+    "delete-jms-host:removes a JMS host"
+    "delete-jms-resource:removes a JMS resource"
+    "delete-jmsdest:removes a JMS physical destination"
+    "delete-jndi-resource:removes a JNDI resource"
+    "delete-jvm-options:removes one or more options for the Java application launcher"
+    "delete-lifecycle-module:removes the lifecycle module"
+    "delete-local-instance:deletes a GlassFish Server instance on the machine where the subcommand is run"
+    "delete-log-levels:"
+    "delete-message-security-provider:enables administrators to delete a message security provider"
+    "delete-network-listener:removes a network listener"
+    "delete-node-config:deletes a node that is not enabled for remote communication"
+    "delete-node-dcom:deletes a node that is enabled for communication over DCOM"
+    "delete-node-ssh:deletes a node that is enabled for communication over SSH"
+    "delete-password-alias:deletes a password alias"
+    "delete-profiler:removes the profiler element"
+    "delete-protocol:removes a protocol"
+    "delete-protocol-filter:removes a protocol filter"
+    "delete-protocol-finder:removes a protocol finder"
+    "delete-resource-adapter-config:deletes the resource adapter configuration"
+    "delete-resource-ref:removes a reference to a resource"
+    "delete-ssl:deletes the SSL element in the selected HTTP listener, IIOP listener, or IIOP service"
+    "delete-system-property:removes a system property of the domain, configuration, cluster, or server instance, one at a time"
+    "delete-threadpool:removes a thread pool"
+    "delete-transport:removes a transport"
+    "delete-virtual-server:removes a virtual server"
+    "deploy:deploys the specified component"
+    "deploydir:deploys an exploded format of application archive"
+    "environment variable"
+    "disable:disables the component"
+    "disable-http-lb-application:disables an application managed by a load balancer"
+    "disable-http-lb-server:disables a sever or cluster managed by a load balancer"
+    "disable-monitoring:disables monitoring for the server or for specific monitorable modules"
+    "disable-secure-admin:disables secure admin if it is already enabled."
+    "disable-secure-admin-internal-user:Instructs the GlassFish Server DAS and instances to not use the specified admin user to authenticate with each other and to authorize admin operations."
+    "disable-secure-admin-principal:disables the certificate for authorizing access in secure administration."
+    "enable:enables the component"
+    "enable-http-lb-application:enables a previously-disabled application managed by a load balancer"
+    "enable-http-lb-server:enables a previously disabled sever or cluster managed by a load balancer"
+    "enable-monitoring:enables monitoring for the server or for specific monitorable modules"
+    "enable-secure-admin:enables secure admin (if it is not already enabled), optionally changing the alias used for DAS-to-instance admin messages or the alias used for instance-to-DAS admin messages."
+    "enable-secure-admin-internal-user:Instructs the GlassFish Server DAS and instances to use the specified admin user and the password associated with the password alias to authenticate with each other and to authorize admin operations."
+    "enable-secure-admin-principal:Instructs GlassFish Server, when secure admin is enabled, to accept admin requests from clients identified by the specified SSL certificate."
+    "export:marks a variable name for automatic export to the environment of subsequent commands in multimode"
+    "export-http-lb-config:exports the load balancer configuration or load balancer to a file"
+    "export-sync-bundle:exports the configuration data of a cluster or standalone instance to an archive file"
+    "flush-connection-pool:reintializes all connections established in the specified connection pool"
+    "flush-jmsdest:purges messages in a JMS destination."
+    "freeze-transaction-service:freezes the transaction subsystem"
+    "generate-domain-schema:"
+    "generate-jvm-report:shows the JVM machine statistics for a given target instance"
+    "get:gets the values of configurable or monitorable attributes"
+    "get-client-stubs:retrieves the application JAR files needed to launch the application client."
+    "get-health:provides information on the cluster health"
+    "help"
+    "asadmin:utility for performing administrative tasks for Oracle GlassFish Server"
+    "import-sync-bundle:imports the configuration data of a clustered instance or standalone instance from an archive file"
+    "install-node:installs GlassFish Server software on specified SSH-enabled hosts"
+    "install-node-dcom:installs GlassFish Server software on specified DCOM-enabled hosts"
+    "install-node-ssh:installs GlassFish Server software on specified SSH-enabled hosts"
+    "jms-ping:checks if the JMS service is up and running"
+    "list:lists configurable or monitorable elements"
+    "list-admin-objects:gets all the administered objects"
+    "list-application-refs:lists the existing application references"
+    "list-applications:lists deployed applications"
+    "list-audit-modules:gets all audit modules and displays them"
+    "list-auth-realms:lists the authentication realms"
+    "list-backups:lists all backups"
+    "list-clusters:lists existing clusters in a domain"
+    "list-commands:lists available commands"
+    "list-components:lists deployed components"
+    "list-configs:lists named configurations"
+    "list-connector-connection-pools:lists the existing connector connection pools"
+    "list-connector-resources:lists all connector resources"
+    "list-connector-security-maps:lists the security maps belonging to the specified connector connection pool"
+    "list-connector-work-security-maps:lists the work security maps belonging to the specified resource adapter"
+    "list-containers:lists application containers"
+    "list-custom-resources:gets all custom resources"
+    "list-domains:lists the domains in the specified directory"
+    "list-file-groups:lists file groups"
+    "list-file-users:lists the file users"
+    "list-http-lb-configs:lists load balancer configurations"
+    "list-http-lbs:lists load balancers"
+    "list-http-listeners:lists the existing network listeners"
+    "list-iiop-listeners:lists the existing IIOP listeners"
+    "list-instances:lists GlassFish Server instances in a domain"
+    "list-jacc-providers:enables administrators to list JACC providers defined for a domain"
+    "list-javamail-resources:lists the existing JavaMail session resources"
+    "list-jdbc-connection-pools:lists all JDBC connection pools"
+    "list-jdbc-resources:lists all JDBC resources"
+    "list-jms-hosts:lists the existing JMS hosts"
+    "list-jms-resources:lists the JMS resources"
+    "list-jmsdest:lists the existing JMS physical destinations"
+    "list-jndi-entries:browses and queries the JNDI tree"
+    "list-jndi-resources:lists all existing JNDI resources"
+    "list-jvm-options:lists options for the Java application launcher"
+    "list-libraries:lists library JAR files on GlassFish Server"
+    "list-lifecycle-modules:lists the lifecycle modules"
+    "list-log-attributes:lists all logging attributes defined for a specified target in a domain"
+    "list-log-levels:lists the loggers and their log levels"
+    "list-message-security-providers:lists all security message providers for the given message layer"
+    "list-modules:lists GlassFish Server modules"
+    "list-network-listeners:lists the existing network listeners"
+    "list-nodes:lists all GlassFish Server nodes in a domain"
+    "list-nodes-config:lists all GlassFish Server nodes that do not support remote communication in a domain"
+    "list-nodes-dcom:lists all GlassFish Server nodes that support communication over DCOM in a domain"
+    "list-nodes-ssh:lists all GlassFish Server nodes that support communication over SSH in a domain"
+    "list-password-aliases:lists all password aliases"
+    "list-persistence-types:lists registered persistence types for HTTP sessions and SFSB instances"
+    "list-protocol-filters:lists the existing protocol filters"
+    "list-protocol-finders:lists the existing protocol finders"
+    "list-protocols:lists the existing protocols"
+    "list-resource-adapter-configs:lists the names of the current resource adapter configurations"
+    "list-resource-refs:lists existing resource references"
+    "list-secure-admin-internal-users:lists the user names that the GlassFish Server DAS and instances use to authenticate with each other and to authorize admin operations."
+    "list-secure-admin-principals:lists the certificates for which GlassFish Server accepts admin requests from clients."
+    "list-sub-components:lists EJB or servlet components in a deployed module or module of a deployed application"
+    "list-supported-cipher-suites:enables administrators to list the cipher suites that are supported and available to a specified GlassFish Server target"
+    "list-system-properties:lists the system properties of the domain, configuration, cluster, or server instance"
+    "list-threadpools:lists all the thread pools"
+    "list-timers:lists all of the persistent timers owned by server instance(s)"
+    "list-transports:lists the existing transports"
+    "list-virtual-servers:lists the existing virtual servers"
+    "list-web-context-param:lists servlet contextinitialization parameters of a deployed web application or module"
+    "list-web-env-entry:lists environment entries for a deployed web application or module"
+    "login:logs you into a domain"
+    "migrate-timers:moves EJB timers when a clustered instance was stopped or has crashed"
+    "monitor:displays monitoring data for commonly used components and services"
+    "multimode:allows multiple subcommands to be run while preserving environment settings and remaining in the asadmin utility"
+    "ping-connection-pool:tests if a connection pool is usable"
+    "ping-node-dcom:tests if a node that is enabled for communication over DCOM is usable"
+    "ping-node-ssh:tests if a node that is enabled for communication over SSH is usable"
+    "recover-transactions:manually recovers pending transactions"
+    "redeploy:redeploys the specified component"
+    "remove-library:removes one or more library JAR files from GlassFish Server"
+    "restart-domain:restarts the DAS of the specified domain"
+    "restart-instance:restarts a running GlassFish Server instance"
+    "restart-local-instance:restarts a running GlassFish Server instance on the host where the subcommand is run"
+    "restore-domain:restores files from backup"
+    "rollback-transaction:rolls back the named transaction"
+    "rotate-log:rotates the log file"
+    "set:sets the values of configurable attributes"
+    "set-log-attributes:sets the logging attributes for one or more loggers"
+    "set-log-levels:sets the log level for one or more loggers"
+    "set-web-context-param:sets a servlet context initialization parameter of a deployed web application or module"
+    "set-web-env-entry:sets an environment entry for a deployed web application or module"
+    "setup-ssh:sets up an SSH key on specified hosts"
+    "show-component-status:displays the status of the deployed component"
+    "start-cluster:starts a cluster"
+    "start-database:starts the Java DB"
+    "start-domain:starts the DAS of the specified domain"
+    "start-instance:starts a GlassFish Server instance"
+    "start-local-instance:starts a GlassFish Server instance on the host where the subcommand is run"
+    "stop-cluster:stops a GlassFish Server cluster"
+    "stop-database:stops the Java DB"
+    "stop-domain:stops the Domain Administration Server of the specified domain"
+    "stop-instance:stops a running GlassFish Server instance"
+    "stop-local-instance:stops a GlassFish Server instance on the machine where the subcommand is run"
+    "undeploy:removes a deployed component"
+    "unfreeze-transaction-service:resumes all suspended transactions"
+    "uninstall-node:uninstalls GlassFish Server software from specified hosts"
+    "uninstall-node-dcom:uninstalls GlassFish Server software from specified DCOM-enabled hosts"
+    "uninstall-node-ssh:uninstalls GlassFish Server software from specified SSH-enabled hosts"
+    "unset:removes one or more variables from the multimode environment"
+    "unset-web-context-param:unsets a servlet context initialization parameter of a deployed web application or module"
+    "unset-web-env-entry:unsets an environment entry for a deployed web application or module"
+    "update-connector-security-map:modifies a security map for the specified connector connection pool"
+    "update-connector-work-security-map:modifies a work security map for the specified resource adapter"
+    "update-file-user:updates a current file user as specified"
+    "update-node-config:updates the configuration data of anode"
+    "update-node-dcom:updates the configuration data of a node"
+    "update-node-ssh:updates the configuration data of a node"
+    "update-password-alias:updates a password alias"
+    "uptime:returns the length of time that the DAS has been running"
+    "validate-dcom:tests the connection over DCOM to a remote host"
+    "validate-multicast:validates that multicast transport is available for clusters"
+    "verify-domain-xml:verifies the content of the domain.xml file"
+    "version:displays version information forGlassFish Server"
+)
+
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+    _describe -t commands "asadmin command" _1st_arguments
+    return
+fi
+
+local -a _command_args
+case "$words[1]" in
+    add-library)
+        _command_args=('*:directory:_files' '--host+:' '--port+:' '--type+:type:(common ext app)')
+        ;;
+    add-resources)
+        _command_args=('*:directory:_files' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    apply-http-lb-changes)
+        _command_args=('--host+:' '--ping+:' '--port+:')
+        ;;
+    backup-domain)
+        _command_args=('--backupconfig+:' '--backupdir+:' '--description+:' '--domaindir+:' '--long+:long:(true false)')
+        ;;
+    change-admin-password)
+        _command_args=('--domain_name+:' '--domaindir+:')
+        ;;
+    change-master-broker)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    change-master-password)
+        _command_args=('--domaindir+:' '--nodedir+:' '--savemasterpassword+:savemasterpassword:(true false)')
+        ;;
+    collect-log-files)
+        _command_args=('--host+:' '--port+:' '--retrieve+:retrieve:(true false)' '--target+:')
+        ;;
+    configure-jms-cluster)
+        _command_args=('--clustertype+:' '--configstoretype+:' '--dburl+:' '--dbuser+:' '--dbvendor+:' '--host+:' '--jmsdbpassword+:' '--messagestoretype+:' '--port+:' '--property+:')
+        ;;
+    configure-lb-weight)
+        _command_args=('--cluster+:cluster:_asadmin_clusters' '--host+:' '--port+:')
+        ;;
+    configure-ldap-for-admin)
+        _command_args=('--basedn+:' '--host+:' '--ldap-group+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--url+:')
+        ;;
+    copy-config)
+        _command_args=('--host+:' '--port+:' '--systemproperties+:')
+        ;;
+    create-admin-object)
+        _command_args=('--classname+:' '--description+:' '--enabled+:enabled:(true false)' '--host+:' '--port+:' '--property+:' '--raname+:' '--restype+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-application-ref)
+        _command_args=('--enabled+:enabled:(true false)' '--host+:' '--lbenabled+:lbenabled:(true false)' '--port+:' '--target+:target:_asadmin_targets_cluster_das_standalone_instance' '--virtualservers+:')
+        ;;
+    create-audit-module)
+        _command_args=('--classname+:' '--host+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-auth-realm)
+        _command_args=('--classname+:' '--host+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-connector-connection-pool)
+        _command_args=('--associatewiththread+:associatewiththread:(true false)' '--connectiondefinition+:' '--creationretryattempts+:' '--creationretryinterval+:' '--description+:' '--failconnection+:failconnection:(true false)' '--host+:' '--idletimeout+:' '--isconnectvalidatereq+:isconnectvalidatereq:(true false)' '--lazyconnectionassociation+:lazyconnectionassociation:(true false)' '--lazyconnectionenlistment+:lazyconnectionenlistment:(true false)' '--leakreclaim+:leakreclaim:(true false)' '--leaktimeout+:' '--matchconnections+:matchconnections:(true false)' '--maxconnectionusagecount+:' '--maxpoolsize+:' '--maxwait+:' '--ping+:ping:(true false)' '--pooling+:pooling:(true false)' '--poolresize+:' '--port+:' '--property+:' '--raname+:' '--steadypoolsize+:' '--target+:' '--transactionsupport+:transactionsupport:(XATransaction LocalTransaction NoTransaction)' '--validateatmostonceperiod+:')
+        ;;
+    create-connector-resource)
+        _command_args=('--description+:' '--enabled+:enabled:(true false)' '--host+:' '--objecttype+:' '--poolname+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    create-connector-security-map)
+        _command_args=('--host+:' '--mappedpassword+:' '--mappedusername+:' '--poolname+:' '--port+:' '--principals+:' '--target+:' '--usergroups+:')
+        ;;
+    create-connector-work-security-map)
+        _command_args=('--description+:' '--groupsmap+:' '--host+:' '--port+:' '--principalsmap+:' '--raname+:')
+        ;;
+    create-custom-resource)
+        _command_args=('--description+:' '--enabled+:enabled:(true false)' '--factoryclass+:' '--host+:' '--port+:' '--property+:' '--restype+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    create-domain)
+        _command_args=('--adminport+:' '--checkports+:checkports:(true false)' '--domaindir+:' '--domainproperties+:' '--instanceport+:' '--keytooloptions+:' '--nopassword+:nopassword:(true false)' '--portbase+:' '--profile+:' '--savelogin+:savelogin:(true false)' '--savemasterpassword+:savemasterpassword:(true false)' '--template+:' '--usemasterpassword+:usemasterpassword:(true false)')
+        ;;
+    create-file-user)
+        _command_args=('--authrealmname+:' '--groups+:' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--userpassword+:')
+        ;;
+    create-http)
+        _command_args=('--default-virtual-server+:' '--dns-lookup-enabled+:dns-lookup-enabled:(true false)' '--host+:' '--max-connection+:' '--port+:' '--request-timeout-seconds+:' '--servername+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--timeout-seconds+:' '--xpowered+:xpowered:(true false)')
+        ;;
+    create-http-health-checker)
+        _command_args=('--config+:' '--host+:' '--interval+:' '--port+:' '--timeout+:' '--url+:')
+        ;;
+    create-http-lb)
+        _command_args=('--autoapplyenabled+:autoapplyenabled:(true false)' '--devicehost+:' '--deviceport+:' '--healthcheckerinterval+:' '--healthcheckertimeout+:' '--healthcheckerurl+:' '--host+:' '--httpsrouting+:httpsrouting:(true false)' '--lbenableallapplications+:' '--lbenableallinstances+:' '--lbpolicy+:' '--lbpolicymodule+:' '--lbweight+:' '--monitor+:monitor:(true false)' '--port+:' '--property+:' '--reloadinterval+:' '--responsetimeout+:' '--routecookie+:routecookie:(true false)' '--sslproxyhost+:' '--sslproxyport+:' '--target+:target:_asadmin_targets_cluster_standalone_instance')
+        ;;
+    create-http-lb-ref)
+        _command_args=('--config+:' '--healthcheckerinterval+:' '--healthcheckertimeout+:' '--healthcheckerurl+:' '--host+:' '--lbenableallapplications+:' '--lbenableallinstances+:' '--lbname+:' '--lbpolicy+:' '--lbpolicymodule+:' '--lbweight+:' '--port+:')
+        ;;
+    create-http-listener)
+        _command_args=('--acceptorthreads+:' '--default-virtual-server+:' '--defaultvs+:' '--enabled+:enabled:(true false)' '--host+:' '--listeneraddress+:' '--listenerport+:' '--port+:' '--redirectport+:' '--secure+:secure:(true false)' '--securityenabled+:securityenabled:(true false)' '--servername+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--xpowered+:xpowered:(true false)')
+        ;;
+    create-http-redirect)
+        _command_args=('--host+:' '--port+:' '--redirect-port+:' '--secure-redirect+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-iiop-listener)
+        _command_args=('--enabled+:enabled:(true false)' '--host+:' '--iiopport+:' '--listeneraddress+:' '--port+:' '--property+:' '--securityenabled+:securityenabled:(true false)' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-instance)
+        _command_args=('--checkports+:checkports:(true false)' '--cluster+:cluster:_asadmin_clusters' '--config+:' '--host+:' '--lbenabled+:lbenabled:(true false)' '--node+:node:_asadmin_nodes' '--port+:' '--portbase+:' '--systemproperties+:' '--terse+:terse:(true false)')
+        ;;
+    create-jacc-provider)
+        _command_args=('--host+:' '--policyconfigfactoryclass+:' '--policyproviderclass+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-javamail-resource)
+        _command_args=('--debug+:debug:(true false)' '--description+:' '--enabled+:enabled:(true false)' '--fromaddress+:' '--host+:' '--mailhost+:' '--mailuser+:' '--port+:' '--property+:' '--storeprotocol+:' '--storeprotocolclass+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance' '--transprotocol+:' '--transprotocolclass+:')
+        ;;
+    create-jdbc-connection-pool)
+        _command_args=('--allownoncomponentcallers+:allownoncomponentcallers:(true false)' '--associatewiththread+:associatewiththread:(true false)' '--creationretryattempts+:' '--creationretryinterval+:' '--datasourceclassname+:' '--description+:' '--driverclassname+:' '--failconnection+:failconnection:(true false)' '--host+:' '--idletimeout+:' '--initsql+:' '--isconnectvalidatereq+:isconnectvalidatereq:(true false)' '--isisolationguaranteed+:isisolationguaranteed:(true false)' '--isolationlevel+:' '--lazyconnectionassociation+:lazyconnectionassociation:(true false)' '--lazyconnectionenlistment+:lazyconnectionenlistment:(true false)' '--leakreclaim+:leakreclaim:(true false)' '--leaktimeout+:' '--matchconnections+:matchconnections:(true false)' '--maxconnectionusagecount+:' '--maxpoolsize+:' '--maxwait+:' '--nontransactionalconnections+:nontransactionalconnections:(true false)' '--ping+:ping:(true false)' '--pooling+:pooling:(true false)' '--poolresize+:' '--port+:' '--property+:' '--restype+:restype:(javax.sql.DataSource javax.sql.XADataSource javax.sql.ConnectionPoolDataSource java.sql.Driver)' '--sqltracelisteners+:' '--statementcachesize+:' '--statementleakreclaim+:statementleakreclaim:(true false)' '--statementleaktimeout+:' '--statementtimeout+:' '--steadypoolsize+:' '--target+:' '--validateatmostonceperiod+:' '--validationclassname+:' '--validationmethod+:validationmethod:(auto-commit meta-data table custom-validation)' '--validationtable+:' '--wrapjdbcobjects+:wrapjdbcobjects:(true false)')
+        ;;
+    create-jdbc-resource)
+        _command_args=('--connectionpoolid+:' '--description+:' '--enabled+:enabled:(true false)' '--host+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    create-jms-host)
+        _command_args=('--host+:' '--mqhost+:' '--mqpassword+:' '--mqport+:' '--mquser+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-jms-resource)
+        _command_args=('--description+:' '--enabled+:enabled:(true false)' '--host+:' '--port+:' '--property+:' '--restype+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    create-jmsdest)
+        _command_args=('--desttype+:' '--host+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-jndi-resource)
+        _command_args=('--description+:' '--enabled+:enabled:(true false)' '--factoryclass+:' '--host+:' '--jndilookupname+:' '--port+:' '--property+:' '--restype+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    create-jvm-options)
+        _command_args=('--host+:' '--port+:' '--profiler+:profiler:(true false)' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-lifecycle-module)
+        _command_args=('--classname+:' '--classpath+:' '--description+:' '--enabled+:enabled:(true false)' '--failurefatal+:failurefatal:(true false)' '--host+:' '--loadorder+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    create-local-instance)
+        _command_args=('--checkports+:checkports:(true false)' '--cluster+:cluster:_asadmin_clusters' '--config+:' '--lbenabled+:lbenabled:(true false)' '--node+:node:_asadmin_nodes' '--nodedir+:' '--portbase+:' '--savemasterpassword+:savemasterpassword:(true false)' '--systemproperties+:' '--usemasterpassword+:usemasterpassword:(true false)')
+        ;;
+    create-message-security-provider)
+        _command_args=('--classname+:' '--host+:' '--isdefaultprovider+:isdefaultprovider:(true false)' '--layer+:layer:(SOAP HttpServlet)' '--port+:' '--property+:' '--providertype+:providertype:(client server client-server)' '--requestauthrecipient+:' '--requestauthsource+:' '--responseauthrecipient+:' '--responseauthsource+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-network-listener)
+        _command_args=('--address+:' '--enabled+:enabled:(true false)' '--host+:' '--jkenabled+:jkenabled:(true false)' '--listenerport+:' '--port+:' '--protocol+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--threadpool+:' '--transport+:')
+        ;;
+    create-node-config)
+        _command_args=('--host+:' '--installdir+:' '--nodedir+:' '--nodehost+:' '--port+:')
+        ;;
+    create-node-dcom)
+        _command_args=('--archive+:' '--force+:force:(true false)' '--host+:' '--install+:install:(true false)' '--installdir+:' '--nodedir+:' '--nodehost+:' '--port+:' '--windowsdomain+:' '--windowspassword+:' '--windowsuser+:')
+        ;;
+    create-node-ssh)
+        _command_args=('--archive+:' '--force+:force:(true false)' '--host+:' '--install+:install:(true false)' '--installdir+:' '--nodedir+:' '--nodehost+:' '--port+:' '--sshkeyfile+:' '--sshkeypassphrase+:' '--sshpassword+:' '--sshport+:' '--sshuser+:')
+        ;;
+    create-password-alias)
+        _command_args=('--aliaspassword+:' '--host+:' '--port+:')
+        ;;
+    create-profiler)
+        _command_args=('--classpath+:' '--enabled+:enabled:(true false)' '--host+:' '--nativelibrarypath+:' '--port+:' '--property+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-protocol)
+        _command_args=('--host+:' '--port+:' '--securityenabled+:securityenabled:(true false)' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-protocol-filter)
+        _command_args=('--classname+:' '--host+:' '--port+:' '--protocol+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    create-protocol-finder)
+        _command_args=('--classname+:' '--host+:' '--port+:' '--protocol+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--targetprotocol+:')
+        ;;
+    create-resource-adapter-config)
+        _command_args=('--host+:' '--objecttype+:' '--port+:' '--property+:' '--target+:' '--threadpoolid+:')
+        ;;
+    create-resource-ref)
+        _command_args=('--enabled+:enabled:(true false)' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_standalone_instance')
+        ;;
+    create-service)
+        _command_args=('*:instances:_asadmin_instances' '--domaindir+:domaindir:directory:_files' '--dry-run+:dry-run:(true false)' '--force+:force:(true false)' '--name+:' '--node+:node:_asadmin_nodes' '--nodedir+:' '--serviceproperties+:' '--serviceuser+:')
+        ;;
+    create-ssl)
+        _command_args=('--certname+:' '--clientauthenabled+:clientauthenabled:(true false)' '--host+:' '--port+:' '--ssl2ciphers+:' '--ssl2enabled+:ssl2enabled:(true false)' '--ssl3enabled+:ssl3enabled:(true false)' '--ssl3tlsciphers+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--tlsenabled+:tlsenabled:(true false)' '--tlsrollbackenabled+:tlsrollbackenabled:(true false)' '--type+:type:(network-listener http-listener iiop-listener iiop-service jmx-connector)')
+        ;;
+    create-system-properties)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_config_das_domain_standalone_instance')
+        ;;
+    create-threadpool)
+        _command_args=('--host+:' '--idletimeout+:' '--maxqueuesize+:' '--maxthreadpoolsize+:' '--minthreadpoolsize+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--workqueues+:')
+        ;;
+    create-transport)
+        _command_args=('--acceptorthreads+:' '--buffersizebytes+:' '--bytebuffertype+:' '--classname+:' '--displayconfiguration+:displayconfiguration:(true false)' '--enablesnoop+:enablesnoop:(true false)' '--host+:' '--idlekeytimeoutseconds+:' '--maxconnectionscount+:' '--port+:' '--readtimeoutmillis+:' '--selectionkeyhandler+:' '--selectorpolltimeoutmillis+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--tcpnodelay+:tcpnodelay:(true false)' '--writetimeoutmillis+:')
+        ;;
+    create-virtual-server)
+        _command_args=('--defaultwebmodule+:' '--host+:' '--hosts+:' '--httplisteners+:' '--logfile+:' '--networklisteners+:' '--port+:' '--property+:' '--state+:state:(on off disabled)' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-admin-object)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-application-ref)
+        _command_args=('--cascade+:cascade:(true false)' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_standalone_instance')
+        ;;
+    delete-audit-module)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-auth-realm)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-config)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    delete-connector-connection-pool)
+        _command_args=('--cascade+:cascade:(true false)' '--host+:' '--port+:' '--target+:')
+        ;;
+    delete-connector-resource)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-connector-security-map)
+        _command_args=('--host+:' '--poolname+:' '--port+:' '--target+:')
+        ;;
+    delete-connector-work-security-map)
+        _command_args=('--host+:' '--port+:' '--raname+:')
+        ;;
+    delete-custom-resource)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-domain)
+        _command_args=('--domaindir+:')
+        ;;
+    delete-file-user)
+        _command_args=('--authrealmname+:' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-http)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-http-health-checker)
+        _command_args=('--config+:' '--host+:' '--port+:')
+        ;;
+    delete-http-lb-ref)
+        _command_args=('--config+:' '--force+:' '--host+:' '--lbname+:' '--port+:')
+        ;;
+    delete-http-listener)
+        _command_args=('--host+:' '--port+:' '--secure+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-http-redirect)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-iiop-listener)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-instance)
+        _command_args=('*:instances:_asadmin_instances' '--host+:' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    delete-jacc-provider)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-javamail-resource)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-jdbc-connection-pool)
+        _command_args=('--cascade+:cascade:(true false)' '--host+:' '--port+:' '--target+:')
+        ;;
+    delete-jdbc-resource)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-jms-host)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-jms-resource)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-jmsdest)
+        _command_args=('--desttype+:' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-jndi-resource)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-jvm-options)
+        _command_args=('--host+:' '--port+:' '--profiler+:profiler:(true false)' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-lifecycle-module)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    delete-local-instance)
+        _command_args=('*:instances:_asadmin_instances' '--node+:node:_asadmin_nodes' '--nodedir+:')
+        ;;
+    delete-log-levels)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-message-security-provider)
+        _command_args=('--host+:' '--layer+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-network-listener)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-node-config)
+        _command_args=('*:nodes:_asadmin_nodes_config' '--host+:' '--port+:')
+        ;;
+    delete-node-dcom)
+        _command_args=('*:nodes:_asadmin_nodes_dcom' '--force+:force:(true false)' '--host+:' '--port+:' '--uninstall+:uninstall:(true false)')
+        ;;
+    delete-node-ssh)
+        _command_args=('*:nodes:_asadmin_nodes_ssh' '--force+:force:(true false)' '--host+:' '--port+:' '--uninstall+:uninstall:(true false)')
+        ;;
+    delete-password-alias)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    delete-profiler)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-protocol)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-protocol-filter)
+        _command_args=('--host+:' '--port+:' '--protocol+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-protocol-finder)
+        _command_args=('--host+:' '--port+:' '--protocol+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-resource-adapter-config)
+        _command_args=('--host+:' '--port+:' '--target+:')
+        ;;
+    delete-resource-ref)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_standalone_instance')
+        ;;
+    delete-ssl)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--type+:type:(network-listener http-listener iiop-listener iiop-service jmx-connector)')
+        ;;
+    delete-system-property)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_config_das_domain_standalone_instance')
+        ;;
+    delete-threadpool)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-transport)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    delete-virtual-server)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    deploy)
+        _command_args=('*:directory:_files' '--asyncreplication+:asyncreplication:(true false)' '--availabilityenabled+:availabilityenabled:(true false)' '--contextroot+:' '--createtables+:createtables:(true false)' '--dbvendorname+:' '--deploymentplan+:deploymentplan:directory:_files' '--description+:' '--dropandcreatetables+:dropandcreatetables:(true false)' '--enabled+:enabled:(true false)' '--force+:force:(true false)' '--generatermistubs+:generatermistubs:(true false)' '--host+:' '--isredeploy+:isredeploy:(true false)' '--keepfailedstubs+:keepfailedstubs:(true false)' '--keepreposdir+:keepreposdir:(true false)' '--keepstate+:keepstate:(true false)' '--lbenabled+:lbenabled:(true false)' '--libraries+:' '--logreportederrors+:logreportederrors:(true false)' '--name+:' '--port+:' '--precompilejsp+:precompilejsp:(true false)' '--properties+:' '--property+:' '--retrieve+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance' '--type+:' '--uniquetablenames+:uniquetablenames:(true false)' '--verify+:verify:(true false)' '--virtualservers+:')
+        ;;
+    deploydir)
+        _command_args=('*:directory:_files' '--asyncreplication+:asyncreplication:(true false)' '--availabilityenabled+:availabilityenabled:(true false)' '--contextroot+:' '--createtables+:createtables:(true false)' '--dbvendorname+:' '--deploymentplan+:deploymentplan:directory:_files' '--description+:' '--dropandcreatetables+:dropandcreatetables:(true false)' '--enabled+:enabled:(true false)' '--force+:force:(true false)' '--generatermistubs+:generatermistubs:(true false)' '--host+:' '--isredeploy+:isredeploy:(true false)' '--keepfailedstubs+:keepfailedstubs:(true false)' '--keepreposdir+:keepreposdir:(true false)' '--keepstate+:keepstate:(true false)' '--lbenabled+:lbenabled:(true false)' '--libraries+:' '--logreportederrors+:logreportederrors:(true false)' '--name+:' '--port+:' '--precompilejsp+:precompilejsp:(true false)' '--properties+:' '--property+:' '--retrieve+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance' '--type+:' '--uniquetablenames+:uniquetablenames:(true false)' '--verify+:verify:(true false)' '--virtualservers+:')
+        ;;
+    disable)
+        _command_args=('--cascade+:cascade:(true false)' '--droptables+:droptables:(true false)' '--host+:' '--isredeploy+:isredeploy:(true false)' '--isundeploy+:isundeploy:(true false)' '--keepreposdir+:keepreposdir:(true false)' '--keepstate+:keepstate:(true false)' '--port+:' '--properties+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    disable-http-lb-application)
+        _command_args=('--host+:' '--name+:' '--port+:' '--timeout+:')
+        ;;
+    disable-http-lb-server)
+        _command_args=('--host+:' '--port+:' '--timeout+:')
+        ;;
+    disable-monitoring)
+        _command_args=('--host+:' '--modules+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    disable-secure-admin)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    enable)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    enable-http-lb-application)
+        _command_args=('--host+:' '--name+:' '--port+:')
+        ;;
+    enable-http-lb-server)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    enable-monitoring)
+        _command_args=('--dtrace+:dtrace:(true false)' '--host+:' '--mbean+:mbean:(true false)' '--modules+:' '--options+:' '--pid+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    enable-secure-admin)
+        _command_args=('--adminalias+:' '--host+:' '--instancealias+:' '--port+:')
+        ;;
+    export-http-lb-config)
+        _command_args=('--config+:' '--host+:' '--lbname+:' '--lbtargets+:' '--port+:' '--property+:' '--retrievefile+:retrievefile:(true false)')
+        ;;
+    export-sync-bundle)
+        _command_args=('--host+:' '--port+:' '--retrieve+:retrieve:(true false)' '--target+:')
+        ;;
+    flush-connection-pool)
+        _command_args=('--appname+:' '--host+:' '--modulename+:' '--port+:')
+        ;;
+    flush-jmsdest)
+        _command_args=('--desttype+:' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    freeze-transaction-service)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance')
+        ;;
+    generate-domain-schema)
+        _command_args=('--format+:' '--host+:' '--port+:' '--showdeprecated+:showdeprecated:(true false)' '--showsubclasses+:showsubclasses:(true false)')
+        ;;
+    generate-jvm-report)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_clustered_instance_das_standalone_instance' '--type+:type:(summary thread class memory log)')
+        ;;
+    get)
+        _command_args=('--host+:' '--monitor+:monitor:(true false)' '--port+:')
+        ;;
+    get-client-stubs)
+        _command_args=('--appname+:' '--host+:' '--port+:')
+        ;;
+    get-health)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    help)
+        _describe -t help-commands "asadmin help command" _1st_arguments
+    ;;
+    import-sync-bundle)
+        _command_args=('--instance+:' '--node+:node:_asadmin_nodes' '--nodedir+:')
+        ;;
+    install-node)
+        _command_args=('--archive+:' '--create+:create:(true false)' '--force+:force:(true false)' '--installdir+:' '--save+:save:(true false)' '--sshkeyfile+:' '--sshport+:' '--sshuser+:')
+        ;;
+    install-node-dcom)
+        _command_args=('--archive+:' '--create+:create:(true false)' '--force+:force:(true false)' '--installdir+:' '--save+:save:(true false)' '--windowsdomain+:' '--windowsuser+:')
+        ;;
+    install-node-ssh)
+        _command_args=('--archive+:' '--create+:create:(true false)' '--force+:force:(true false)' '--installdir+:' '--save+:save:(true false)' '--sshkeyfile+:' '--sshport+:' '--sshuser+:')
+        ;;
+    jms-ping)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance')
+        ;;
+    list)
+        _command_args=('--host+:' '--monitor+:monitor:(true false)' '--port+:')
+        ;;
+    list-admin-objects)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-application-refs)
+        _command_args=('*:targets:_asadmin_targets_cluster_das_standalone_instance' '--host+:' '--long+:long:(true false)' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    list-applications)
+        _command_args=('*:targets:_asadmin_targets_cluster_das_domain_standalone_instance' '--host+:' '--long+:long:(true false)' '--port+:' '--resources+:resources:(true false)' '--subcomponents+:subcomponents:(true false)' '--terse+:terse:(true false)' '--type+:')
+        ;;
+    list-audit-modules)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-auth-realms)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-backups)
+        _command_args=('--backupconfig+:' '--backupdir+:' '--domaindir+:' '--long+:long:(true false)')
+        ;;
+    list-clusters)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-commands)
+        _command_args=('--localonly+:localonly:(true false)' '--remoteonly+:remoteonly:(true false)')
+        ;;
+    list-components)
+        _command_args=('*:targets:_asadmin_targets_cluster_das_domain_standalone_instance' '--host+:' '--long+:long:(true false)' '--port+:' '--resources+:resources:(true false)' '--subcomponents+:subcomponents:(true false)' '--terse+:terse:(true false)' '--type+:')
+        ;;
+    list-configs)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_domain_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-connector-connection-pools)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-connector-resources)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-connector-security-maps)
+        _command_args=('--host+:' '--long+:long:(true false)' '--port+:' '--securitymap+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    list-connector-work-security-maps)
+        _command_args=('--host+:' '--port+:' '--securitymap+:')
+        ;;
+    list-containers)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-custom-resources)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    list-descriptors)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-domains)
+        _command_args=('--domaindir+:')
+        ;;
+    list-file-groups)
+        _command_args=('--authrealmname+:' '--host+:' '--name+:' '--port+:')
+        ;;
+    list-file-users)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--authrealmname+:' '--host+:' '--port+:')
+        ;;
+    list-http-lb-configs)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-http-listeners)
+        _command_args=('*:targets:_asadmin_targets_cluster_config_das_standalone_instance' '--host+:' '--long+:long:(true false)' '--port+:')
+        ;;
+    list-iiop-listeners)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_domain_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-instances)
+        _command_args=('--host+:' '--long+:long:(true false)' '--nostatus+:nostatus:(true false)' '--port+:' '--standaloneonly+:standaloneonly:(true false)' '--timeoutmsec+:')
+        ;;
+    list-jacc-providers)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-javamail-resources)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    list-jdbc-connection-pools)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-jdbc-resources)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-jms-hosts)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    list-jms-resources)
+        _command_args=('*:targets:_asadmin_targets_cluster_das_domain_standalone_instance' '--host+:' '--port+:' '--restype+:')
+        ;;
+    list-jmsdest)
+        _command_args=('*:targets:_asadmin_targets_cluster_config_das_standalone_instance' '--desttype+:' '--host+:' '--port+:' '--property+:')
+        ;;
+    list-jndi-entries)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance' '--context+:' '--host+:' '--port+:')
+        ;;
+    list-jndi-resources)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    list-jvm-options)
+        _command_args=('--host+:' '--port+:' '--profiler+:profiler:(true false)' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    list-libraries)
+        _command_args=('--host+:' '--port+:' '--type+:type:(common ext app)')
+        ;;
+    list-lifecycle-modules)
+        _command_args=('*:targets:_asadmin_targets_cluster_das_domain_standalone_instance' '--host+:' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    list-log-attributes)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-log-levels)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-message-security-providers)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance' '--host+:' '--layer+:layer:(SOAP HttpServlet)' '--port+:')
+        ;;
+    list-modules)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-network-listeners)
+        _command_args=('*:targets:_asadmin_targets_cluster_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-nodes)
+        _command_args=('--host+:' '--long+:long:(true false)' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    list-nodes-config)
+        _command_args=('--host+:' '--long+:long:(true false)' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    list-nodes-dcom)
+        _command_args=('--host+:' '--long+:long:(true false)' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    list-nodes-ssh)
+        _command_args=('--host+:' '--long+:long:(true false)' '--port+:' '--terse+:terse:(true false)')
+        ;;
+    list-password-aliases)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-persistence-types)
+        _command_args=('--host+:' '--port+:' '--type+:')
+        ;;
+    list-protocol-filters)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    list-protocol-finders)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    list-protocols)
+        _command_args=('*:targets:_asadmin_targets_cluster_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-resource-adapter-configs)
+        _command_args=('--host+:' '--long+:long:(true false)' '--port+:' '--raname+:')
+        ;;
+    list-resource-refs)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-sub-components)
+        _command_args=('--appname+:' '--host+:' '--port+:' '--resources+:resources:(true false)' '--terse+:terse:(true false)' '--type+:')
+        ;;
+    list-supported-cipher-suites)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-system-properties)
+        _command_args=('*:targets:_asadmin_targets_cluster_clustered_instance_config_das_domain_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-threadpools)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    list-timers)
+        _command_args=('*:targets:_asadmin_targets_cluster_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-transports)
+        _command_args=('*:targets:_asadmin_targets_cluster_config_das_standalone_instance' '--host+:' '--port+:')
+        ;;
+    list-virtual-servers)
+        _command_args=('*:targets:_asadmin_targets_cluster_config_das_standalone_instance' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    list-web-context-param)
+        _command_args=('--host+:' '--name+:' '--port+:')
+        ;;
+    list-web-env-entry)
+        _command_args=('--host+:' '--name+:' '--port+:')
+        ;;
+    login)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_das_standalone_instance')
+        ;;
+    migrate-timers)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_clustered_instance_das')
+        ;;
+    monitor)
+        _command_args=('--filename+:filename:directory:_files' '--filter+:' '--interval+:' '--type+:')
+        ;;
+    multimode)
+        _command_args=('--encoding+:' '--file+:file:directory:_files' '--printprompt+:printprompt:(true false)')
+        ;;
+    ping-connection-pool)
+        _command_args=('--appname+:' '--host+:' '--modulename+:' '--port+:' '--target+:')
+        ;;
+    ping-node-dcom)
+        _command_args=('*:nodes:_asadmin_nodes_dcom' '--host+:' '--port+:' '--validate+:validate:(true false)')
+        ;;
+    ping-node-ssh)
+        _command_args=('*:nodes:_asadmin_nodes_ssh' '--host+:' '--port+:' '--validate+:validate:(true false)')
+        ;;
+    recover-transactions)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_clustered_instance_das_standalone_instance' '--transactionlogdir+:')
+        ;;
+    redeploy)
+        _command_args=('*:directory:_files' '--asyncreplication+:asyncreplication:(true false)' '--availabilityenabled+:availabilityenabled:(true false)' '--contextroot+:' '--createtables+:createtables:(true false)' '--dbvendorname+:' '--deploymentplan+:deploymentplan:directory:_files' '--description+:' '--dropandcreatetables+:dropandcreatetables:(true false)' '--enabled+:enabled:(true false)' '--force+:force:(true false)' '--generatermistubs+:generatermistubs:(true false)' '--host+:' '--isredeploy+:isredeploy:(true false)' '--keepfailedstubs+:keepfailedstubs:(true false)' '--keepreposdir+:keepreposdir:(true false)' '--keepstate+:keepstate:(true false)' '--lbenabled+:lbenabled:(true false)' '--libraries+:' '--logreportederrors+:logreportederrors:(true false)' '--name+:' '--port+:' '--precompilejsp+:precompilejsp:(true false)' '--properties+:' '--property+:' '--retrieve+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance' '--type+:' '--uniquetablenames+:uniquetablenames:(true false)' '--verify+:verify:(true false)' '--virtualservers+:')
+        ;;
+    remove-library)
+        _command_args=('*:libraries:_asadmin_libraries' '--host+:' '--port+:' '--type+:type:(common ext app)')
+        ;;
+    restart-domain)
+        _command_args=('--debug+:debug:(true false)' '--domaindir+:' '--force+:force:(true false)' '--kill+:kill:(true false)')
+        ;;
+    restart-instance)
+        _command_args=('*:instances:_asadmin_instances' '--debug+:' '--host+:' '--port+:')
+        ;;
+    restart-local-instance)
+        _command_args=('*:instances:_asadmin_instances' '--debug+:debug:(true false)' '--force+:force:(true false)' '--kill+:kill:(true false)' '--node+:node:_asadmin_nodes' '--nodedir+:')
+        ;;
+    restore-domain)
+        _command_args=('--backupconfig+:' '--backupdir+:' '--description+:' '--domaindir+:' '--filename+:' '--force+:force:(true false)' '--long+:long:(true false)')
+        ;;
+    rollback-transaction)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_clustered_instance_das_standalone_instance' '--transaction_id+:')
+        ;;
+    rotate-log)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_standalone_instance')
+        ;;
+    set)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    set-log-attributes)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    set-log-levels)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance')
+        ;;
+    set-web-context-param)
+        _command_args=('--description+:' '--host+:' '--ignoredescriptoritem+:ignoredescriptoritem:(true false)' '--name+:' '--port+:' '--value+:')
+        ;;
+    set-web-env-entry)
+        _command_args=('--description+:' '--host+:' '--ignoredescriptoritem+:ignoredescriptoritem:(true false)' '--name+:' '--port+:' '--type+:' '--value+:')
+        ;;
+    setup-ssh)
+        _command_args=('--generatekey+:generatekey:(true false)' '--sshkeyfile+:' '--sshport+:' '--sshpublickeyfile+:' '--sshuser+:')
+        ;;
+    show-component-status)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance')
+        ;;
+    start-cluster)
+        _command_args=('*:clusters:_asadmin_clusters' '--autohadboverride+:autohadboverride:(true false)' '--host+:' '--port+:' '--verbose+:verbose:(true false)')
+        ;;
+    start-database)
+        _command_args=('--dbhome+:' '--dbhost+:' '--dbport+:' '--jvmoptions+:')
+        ;;
+    start-domain)
+        _command_args=('--debug+:debug:(true false)' '--domaindir+:' '--upgrade+:upgrade:(true false)' '--verbose+:verbose:(true false)')
+        ;;
+    start-instance)
+        _command_args=('*:instances:_asadmin_instances' '--debug+:debug:(true false)' '--host+:' '--port+:' '--setenv+:' '--sync+:sync:(none normal full)' '--terse+:terse:(true false)')
+        ;;
+    start-local-instance)
+        _command_args=('*:instances:_asadmin_instances' '--debug+:debug:(true false)' '--node+:node:_asadmin_nodes' '--nodedir+:' '--sync+:sync:(none normal full)' '--verbose+:verbose:(true false)')
+        ;;
+    stop-cluster)
+        _command_args=('*:clusters:_asadmin_clusters' '--autohadboverride+:autohadboverride:(true false)' '--host+:' '--kill+:kill:(true false)' '--port+:' '--verbose+:verbose:(true false)')
+        ;;
+    stop-database)
+        _command_args=('--dbhost+:' '--dbport+:' '--dbuser+:')
+        ;;
+    stop-domain)
+        _command_args=('--domaindir+:' '--force+:force:(true false)' '--kill+:kill:(true false)')
+        ;;
+    stop-instance)
+        _command_args=('*:instances:_asadmin_instances' '--force+:force:(true false)' '--host+:' '--kill+:kill:(true false)' '--port+:')
+        ;;
+    stop-local-instance)
+        _command_args=('*:instances:_asadmin_instances' '--force+:force:(true false)' '--kill+:kill:(true false)' '--node+:node:_asadmin_nodes' '--nodedir+:')
+        ;;
+    test-upgrade)
+        _command_args=('--host+:' '--port+:')
+        ;;
+    undeploy)
+        _command_args=('*:applications:_asadmin_applications' '--cascade+:cascade:(true false)' '--droptables+:droptables:(true false)' '--host+:' '--isredeploy+:isredeploy:(true false)' '--keepreposdir+:keepreposdir:(true false)' '--keepstate+:keepstate:(true false)' '--port+:' '--properties+:' '--target+:target:_asadmin_targets_cluster_das_domain_standalone_instance')
+        ;;
+    unfreeze-transaction-service)
+        _command_args=('--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance')
+        ;;
+    uninstall-node)
+        _command_args=('--force+:force:(true false)' '--installdir+:' '--sshkeyfile+:' '--sshport+:' '--sshuser+:')
+        ;;
+    uninstall-node-dcom)
+        _command_args=('--force+:force:(true false)' '--installdir+:' '--windowsdomain+:' '--windowsuser+:')
+        ;;
+    uninstall-node-ssh)
+        _command_args=('--force+:force:(true false)' '--installdir+:' '--sshkeyfile+:' '--sshport+:' '--sshuser+:')
+        ;;
+    unset-web-context-param)
+        _command_args=('--host+:' '--name+:' '--port+:')
+        ;;
+    unset-web-env-entry)
+        _command_args=('--host+:' '--name+:' '--port+:')
+        ;;
+    update-connector-security-map)
+        _command_args=('--addprincipals+:' '--addusergroups+:' '--host+:' '--mappedpassword+:' '--mappedusername+:' '--poolname+:' '--port+:' '--removeprincipals+:' '--removeusergroups+:' '--target+:')
+        ;;
+    update-connector-work-security-map)
+        _command_args=('--addgroups+:' '--addprincipals+:' '--host+:' '--port+:' '--raname+:' '--removegroups+:' '--removeprincipals+:')
+        ;;
+    update-file-user)
+        _command_args=('--authrealmname+:' '--groups+:' '--host+:' '--port+:' '--target+:target:_asadmin_targets_cluster_config_das_standalone_instance' '--userpassword+:')
+        ;;
+    update-node-config)
+        _command_args=('*:nodes:_asadmin_nodes_config' '--host+:' '--installdir+:' '--nodedir+:' '--nodehost+:' '--port+:')
+        ;;
+    update-node-dcom)
+        _command_args=('*:nodes:_asadmin_nodes_dcom' '--force+:force:(true false)' '--host+:' '--installdir+:' '--nodedir+:' '--nodehost+:' '--port+:' '--windowsdomain+:' '--windowspassword+:' '--windowsuser+:')
+        ;;
+    update-node-ssh)
+        _command_args=('*:nodes:_asadmin_nodes_ssh' '--force+:force:(true false)' '--host+:' '--installdir+:' '--nodedir+:' '--nodehost+:' '--port+:' '--sshkeyfile+:' '--sshkeypassphrase+:' '--sshpassword+:' '--sshport+:' '--sshuser+:')
+        ;;
+    update-password-alias)
+        _command_args=('--aliaspassword+:' '--host+:' '--port+:')
+        ;;
+    uptime)
+        _command_args=('--host+:' '--milliseconds+:milliseconds:(true false)' '--port+:')
+        ;;
+    validate-dcom)
+        _command_args=('--host+:' '--port+:' '--remotetestdir+:' '--verbose+:verbose:(true false)' '--windowsdomain+:' '--windowspassword+:' '--windowsuser+:')
+        ;;
+    validate-multicast)
+        _command_args=('--bindaddress+:' '--multicastaddress+:' '--multicastport+:' '--sendperiod+:' '--timeout+:' '--timetolive+:' '--verbose+:verbose:(true false)')
+        ;;
+    verify-domain-xml)
+        _command_args=('--domaindir+:')
+        ;;
+    version)
+        _command_args=('--local+:local:(true false)' '--terse+:terse:(true false)' '--verbose+:verbose:(true false)')
+        ;;
+esac
+
+
+_asadmin_applications() {
+    compadd $(command asadmin list-applications --terse | sed 's/\s.*//')
+}
+
+_asadmin_clusters() {
+    compadd $(command asadmin list-clusters --terse | sed 's/\s.*//')
+}
+
+_asadmin_configs() {
+    compadd $(command asadmin list-configs --terse)
+}
+
+_asadmin_instances() {
+    compadd $(command asadmin list-instances --terse --nostatus domain)
+}
+
+_asadmin_instances_standalone() {
+    compadd $(command asadmin list-instances --terse --standaloneonly --nostatus domain)
+}
+
+_asadmin_libraries() {
+    compadd $(command asadmin list-libraries --terse)
+}
+
+_asadmin_nodes() {
+    compadd $(command asadmin list-nodes --terse)
+}
+
+_asadmin_nodes_config() {
+    compadd $(command asadmin list-nodes-config --terse)
+}
+
+_asadmin_nodes_dcom() {
+    compadd $(command asadmin list-nodes-dcom --terse)
+}
+
+_asadmin_nodes_ssh() {
+    compadd $(command asadmin list-nodes-ssh --terse)
+}
+
+_asadmin_targets() {
+    _asadmin_instances
+    _asadmin_clusters
+    _asadmin_configs
+    compadd domain server
+}
+
+_asadmin_targets_cluster_clustered_instance_config_das_domain_standalone_instance() {
+    _asadmin_instances
+    _asadmin_clusters
+    _asadmin_configs
+    compadd domain server
+}
+
+_asadmin_targets_cluster_clustered_instance_config_das_standalone_instance() {
+    _asadmin_instances
+    _asadmin_clusters
+    _asadmin_configs
+    compadd server
+}
+
+_asadmin_targets_cluster_clustered_instance_das_domain_standalone_instance() {
+    _asadmin_instances
+    _asadmin_clusters
+    compadd domain server
+}
+
+_asadmin_targets_cluster_clustered_instance_das_standalone_instance() {
+    _asadmin_instances
+    _asadmin_clusters
+    _asadmin_configs
+    compadd server
+}
+
+_asadmin_targets_cluster_config_das_standalone_instance() {
+    _asadmin_instances_standalone
+    _asadmin_clusters
+    _asadmin_configs
+    compadd server
+}
+
+_asadmin_targets_cluster_das_domain_standalone_instance() {
+    _asadmin_instances_standalone
+    _asadmin_clusters
+    compadd domain server
+}
+
+_asadmin_targets_cluster_das_standalone_instance() {
+    _asadmin_instances_standalone
+    _asadmin_clusters
+    compadd server
+}
+
+_asadmin_targets_clustered_instance_das() {
+    _asadmin_instances
+    compadd server
+}
+
+_asadmin_targets_clustered_instance_das_standalone_instance() {
+    _asadmin_instances
+    compadd server
+}
+
+_asadmin_targets_cluster_standalone_instance() {
+    _asadmin_clusters
+    _asadmin_instances_standalone
+}
+
+
+compadd '--help'
+_arguments \
+    $_command_args \
+    &&  return 0;
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/glassfish.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/glassfish/glassfish.plugin.zsh
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/globalias/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/globalias/README.md
new file mode 100644 (file)
index 0000000..cd7fc3c
--- /dev/null
@@ -0,0 +1,79 @@
+# Globalias plugin
+
+Expands all glob expressions, subcommands and aliases (including global).
+
+Idea from: https://blog.patshead.com/2012/11/automatically-expaning-zsh-global-aliases---simplified.html.
+
+## Usage
+
+Add `globalias` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... globalias)
+```
+
+Then just press `SPACE` to trigger the expansion of a command you've written.
+
+If you only want to insert a space without expanding the command line, press
+`CTRL`+`SPACE`.
+
+if you would like to filter out any values from expanding set `GLOBALIAS_FILTER_VALUES` to
+an array of said values. See [Filtered values](#filtered-values).
+
+## Examples
+
+#### Glob expressions
+
+```
+$ touch {1..10}<space>
+# expands to
+$ touch 1 2 3 4 5 6 7 8 9 10
+
+$ ls **/*.json<space>
+# expands to
+$ ls folder/file.json anotherfolder/another.json
+```
+
+#### Subcommands
+
+```
+$ mkdir "`date -R`"
+# expands to
+$ mkdir Tue,\ 04\ Oct\ 2016\ 13:54:03\ +0300
+```
+
+#### Aliases
+
+```
+# .zshrc:
+alias -g G="| grep --color=auto -P"
+alias l='ls --color=auto -lah'
+
+$ l<space>G<space>
+# expands to
+$ ls --color=auto -lah | grep --color=auto -P
+```
+
+```
+# .zsrc:
+alias S="sudo systemctl"
+
+$ S<space>
+# expands to:
+$ sudo systemctl
+```
+
+#### Filtered values
+
+```
+# .zshrc
+alias l='ls -lh'
+alias la='ls --color=auto -lah'
+GLOBALIAS_FILTER_VALUES=(l)
+
+$ l<space>
+# does not expand
+$ la<space>
+# expands to:
+$ ls --color=auto -lah
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/globalias/globalias.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/globalias/globalias.plugin.zsh
new file mode 100644 (file)
index 0000000..bd27d58
--- /dev/null
@@ -0,0 +1,23 @@
+globalias() {
+   # Get last word to the left of the cursor:
+   # (z) splits into words using shell parsing
+   # (A) makes it an array even if there's only one element
+   local word=${${(Az)LBUFFER}[-1]}
+   if [[ $GLOBALIAS_FILTER_VALUES[(Ie)$word] -eq 0 ]]; then
+      zle _expand_alias
+      zle expand-word
+   fi
+   zle self-insert
+}
+zle -N globalias
+
+# space expands all aliases, including global
+bindkey -M emacs " " globalias
+bindkey -M viins " " globalias
+
+# control-space to make a normal space
+bindkey -M emacs "^ " magic-space
+bindkey -M viins "^ " magic-space
+
+# normal space during searches
+bindkey -M isearch " " magic-space
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gnu-utils/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gnu-utils/README.md
new file mode 100644 (file)
index 0000000..f5fa81e
--- /dev/null
@@ -0,0 +1,38 @@
+# gnu-utils plugin
+
+This plugin binds GNU coreutils to their default names, so that you don't have
+to call them using their prefixed name, which starts with `g`. This is useful
+in systems which don't have GNU coreutils installed by default, mainly macOS
+or FreeBSD, which use BSD coreutils.
+
+To use it, add `gnu-utils` to the plugins array in your zshrc file:
+```zsh
+plugins=(... gnu-utils)
+```
+
+The plugin works by changing the path that the command hash points to, so
+instead of `ls` pointing to `/bin/ls`, it points to wherever `gls` is
+installed.
+
+Since `hash -rf` or `rehash` refreshes the command hashes, it also wraps
+`hash` and `rehash` so that the coreutils binding is always done again
+after calling these two commands.
+
+Look at the source code of the plugin to see which GNU coreutils are tried
+to rebind. Open an issue if there are some missing.
+
+## Other methods
+
+The plugin also documents two other ways to do this:
+
+1. Using a function wrapper, such that, for example, there exists a function
+named `ls` which calls `gls` instead. Since functions have a higher preference
+than commands, this ends up calling the GNU coreutil. It has also a higher
+preference over shell builtins (`gecho` is called instead of the builtin `echo`).
+
+2. Using an alias. This has an even higher preference than functions, but they
+could be overridden because of a user setting.
+
+## Author
+
+- [Sorin Ionescu](https://github.com/sorin-ionescu).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gnu-utils/gnu-utils.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gnu-utils/gnu-utils.plugin.zsh
new file mode 100644 (file)
index 0000000..9419127
--- /dev/null
@@ -0,0 +1,63 @@
+# ------------------------------------------------------------------------------
+#          FILE:  gnu-utils.plugin.zsh
+#   DESCRIPTION:  oh-my-zsh plugin file.
+#        AUTHOR:  Sorin Ionescu (sorin.ionescu@gmail.com)
+#       VERSION:  1.0.0
+# ------------------------------------------------------------------------------
+
+# Detect if GNU coreutils are installed by looking for gwhoami
+if [[ ! -x "${commands[gwhoami]}" ]]; then
+  return
+fi
+
+__gnu_utils() {
+  local -a gcmds
+  local gcmd
+
+  # coreutils 
+  gcmds=('g[' 'gbase64' 'gbasename' 'gcat' 'gchcon' 'gchgrp' 'gchmod'
+  'gchown' 'gchroot' 'gcksum' 'gcomm' 'gcp' 'gcsplit' 'gcut' 'gdate'
+  'gdd' 'gdf' 'gdir' 'gdircolors' 'gdirname' 'gdu' 'gecho' 'genv' 'gexpand'
+  'gexpr' 'gfactor' 'gfalse' 'gfmt' 'gfold' 'ggroups' 'ghead' 'ghostid'
+  'gid' 'ginstall' 'gjoin' 'gkill' 'glink' 'gln' 'glogname' 'gls' 'gmd5sum'
+  'gmkdir' 'gmkfifo' 'gmknod' 'gmktemp' 'gmv' 'gnice' 'gnl' 'gnohup' 'gnproc'
+  'god' 'gpaste' 'gpathchk' 'gpinky' 'gpr' 'gprintenv' 'gprintf' 'gptx' 'gpwd'
+  'greadlink' 'grm' 'grmdir' 'gruncon' 'gseq' 'gsha1sum' 'gsha224sum'
+  'gsha256sum' 'gsha384sum' 'gsha512sum' 'gshred' 'gshuf' 'gsleep' 'gsort'
+  'gsplit' 'gstat' 'gstty' 'gsum' 'gsync' 'gtac' 'gtail' 'gtee' 'gtest'
+  'gtimeout' 'gtouch' 'gtr' 'gtrue' 'gtruncate' 'gtsort' 'gtty' 'guname'
+  'gunexpand' 'guniq' 'gunlink' 'guptime' 'gusers' 'gvdir' 'gwc' 'gwho'
+  'gwhoami' 'gyes')
+
+  # findutils
+  gcmds+=('gfind' 'gxargs' 'glocate')
+
+  # Not part of either coreutils or findutils, installed separately.
+  gcmds+=('gsed' 'gtar' 'gtime' 'gmake' 'ggrep')
+
+  # can be built optionally
+  gcmds+=('ghostname')
+
+  for gcmd in "${gcmds[@]}"; do
+    # Do nothing if the command isn't found
+    (( ${+commands[$gcmd]} )) || continue
+    
+    # This method allows for builtin commands to be primary but it's
+    # lost if hash -r or rehash is executed, or if $PATH is updated.
+    # Thus, a preexec hook is needed, which will only run if whoami
+    # is not already rehashed.
+    #
+    hash ${gcmd[2,-1]}=${commands[$gcmd]}
+  done
+
+  return 0
+}
+
+__gnu_utils_preexec() {
+  # Run __gnu_utils when the whoami command is not already rehashed.
+  # This acts as a sign that we need to rehash all GNU utils.
+  [[ "${commands[whoami]}" = "${commands[gwhoami]}" ]] || __gnu_utils
+}
+
+autoload -Uz add-zsh-hook
+add-zsh-hook preexec __gnu_utils_preexec
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/README.md
new file mode 100644 (file)
index 0000000..3b7d1e1
--- /dev/null
@@ -0,0 +1,38 @@
+# Golang plugin
+
+This plugin adds completion for the [Go Programming Language](https://golang.org/),
+as well as some aliases for common Golang commands.
+
+To use it, add `golang` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... golang)
+```
+
+## Aliases
+
+| Alias  | Command           | Description                                                   |
+| ------ | ----------------- | ------------------------------------------------------------- |
+| gob    | `go build`        | Build your code                                               |
+| goc    | `go clean`        | Removes object files from package source directories          |
+| god    | `go doc`          | Prints documentation comments                                 |
+| gof    | `go fmt`          | Gofmt formats (aligns and indents) Go programs.               |
+| gofa   | `go fmt ./...`    | Run go fmt for all packages in current directory, recursively |
+| gofx   | `go fix`          | Update packages to use a new API                              |
+| gog    | `go get`          | Downloads packages and then installs them to $GOPATH          |
+| gog    | `go get ./...`    | Installs all dependencies in current directory, recursively   |
+| goi    | `go install`      | Compiles and installs packages to $GOPATH                     |
+| gol    | `go list`         | Lists Go packages                                             |
+| gom    | `go mod`          | Access to operations on modules                               |
+| gopa   | `cd $GOPATH`      | Takes you to `$GOPATH`                                        |
+| gopb   | `cd $GOPATH/bin`  | Takes you to `$GOPATH/bin`                                    |
+| gops   | `cd $GOPATH/src`  | Takes you to `$GOPATH/src`                                    |
+| gor    | `go run`          | Compiles and runs your code                                   |
+| got    | `go test`         | Runs tests                                                    |
+| gota   | `go test ./...`   | Runs tests in all subdirectories                              |
+| goto   | `go tool`         | Prints all the available tools                                |
+| gotoc  | `go tool compile` | Generates object file                                         |
+| gotod  | `go tool dist`    | Utility to bootstrap, build and test go runtime               |
+| gotofx | `go tool fix`     | Fixes an application to use newer features                    |
+| gov    | `go vet`          | Vet examines Go source code and reports suspicious constructs |
+| gow    | `go work`         | Work provides access to operations on workspaces              |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/_golang b/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/_golang
new file mode 100644 (file)
index 0000000..01b976b
--- /dev/null
@@ -0,0 +1,249 @@
+#compdef go
+
+__go_packages() {
+  local gopaths
+  declare -a gopaths
+  gopaths=("${(s/:/)$(go env GOPATH)}")
+  gopaths+=("$(go env GOROOT)")
+  for p in $gopaths; do
+    _path_files -W "$p/src" -/
+  done
+}
+
+__go_identifiers() {
+  local tmpl_path="${functions_source[$0]:h}/templates"
+  compadd $(godoc -templates "$tmpl_path" ${words[-2]} 2> /dev/null)
+}
+
+_go() {
+  typeset -a commands build_flags
+  commands+=(
+    'build[compile packages and dependencies]'
+    'clean[remove object files]'
+    'doc[run godoc on package sources]'
+    'env[print Go environment information]'
+    'fix[run go tool fix on packages]'
+    'fmt[run gofmt on package sources]'
+    'generate[generate Go files by processing source]'
+    'get[download and install packages and dependencies]'
+    'help[display help]'
+    'install[compile and install packages and dependencies]'
+    'list[list packages]'
+    'mod[modules maintenance]'
+    'run[compile and run Go program]'
+    'test[test packages]'
+    'tool[run specified go tool]'
+    'version[print Go version]'
+    'vet[run go tool vet on packages]'
+  )
+  if (( CURRENT == 2 )); then
+    # explain go commands
+    _values 'go tool commands' ${commands[@]}
+    return
+  fi
+  build_flags=(
+    '-a[force reinstallation of packages that are already up to date]'
+    '-n[print the commands but do not run them]'
+    '-p[number of parallel builds]:number'
+    '-race[enable data race detection]'
+    '-x[print the commands]'
+    '-work[print temporary directory name and keep it]'
+    '-ccflags[flags for 5c/6c/8c]:flags'
+    '-gcflags[flags for 5g/6g/8g]:flags'
+    '-ldflags[flags for 5l/6l/8l]:flags'
+    '-gccgoflags[flags for gccgo]:flags'
+    '-compiler[name of compiler to use]:name'
+    '-installsuffix[suffix to add to package directory]:suffix'
+    '-tags[list of build tags to consider satisfied]:tags'
+  )
+
+  case ${words[2]} in
+  doc)
+    _arguments -s -w \
+      "-c[symbol matching honors case (paths not affected)]" \
+      "-cmd[show symbols with package docs even if package is a command]" \
+      "-u[show unexported symbols as well as exported]" \
+      "2:importpaths:__go_packages" \
+      ":next identifiers:__go_identifiers"
+    ;;
+  clean)
+    _arguments -s -w \
+      "-i[remove the corresponding installed archive or binary (what 'go install' would create)]" \
+      "-n[print the remove commands it would execute, but not run them]" \
+      "-r[apply recursively to all the dependencies of the packages named by the import paths]" \
+      "-x[print remove commands as it executes them]" \
+      "*:importpaths:__go_packages"
+    ;;
+  fix|fmt|vet)
+    _alternative ':importpaths:__go_packages' ':files:_path_files -g "*.go"'
+    ;;
+  install)
+    _arguments -s -w : ${build_flags[@]} \
+      "-v[show package names]" \
+      '*:importpaths:__go_packages'
+    ;;
+  get)
+    _arguments -s -w : \
+      ${build_flags[@]}
+    ;;
+  build)
+    _arguments -s -w : \
+      ${build_flags[@]} \
+      "-v[show package names]" \
+      "-o[output file]:file:_files" \
+      "*:args:{ _alternative ':importpaths:__go_packages' ':files:_path_files -g \"*.go\"' }"
+    ;;
+  test)
+    _arguments -s -w : \
+      ${build_flags[@]} \
+      "-c[do not run, compile the test binary]" \
+      "-i[do not run, install dependencies]" \
+      "-v[print test output]" \
+      "-x[print the commands]" \
+      "-short[use short mode]" \
+      "-parallel[number of parallel tests]:number" \
+      "-cpu[values of GOMAXPROCS to use]:number list" \
+      "-run[run tests and examples matching regexp]:regexp" \
+      "-bench[run benchmarks matching regexp]:regexp" \
+      "-benchmem[print memory allocation stats]" \
+      "-benchtime[run each benchmark until taking this long]:duration" \
+      "-blockprofile[write goroutine blocking profile to file]:file" \
+      "-blockprofilerate[set sampling rate of goroutine blocking profile]:number" \
+      "-timeout[kill test after that duration]:duration" \
+      "-cpuprofile[write CPU profile to file]:file:_files" \
+      "-memprofile[write heap profile to file]:file:_files" \
+      "-memprofilerate[set heap profiling rate]:number" \
+      "*:args:{ _alternative ':importpaths:__go_packages' ':files:_path_files -g \"*.go\"' }"
+    ;;
+  list)
+    _arguments -s -w : \
+      "-f[alternative format for the list]:format" \
+      "-json[print data in json format]" \
+      "-compiled[set CompiledGoFiles to the Go source files presented to the compiler]" \
+      "-deps[iterate over not just the named packages but also all their dependencies]" \
+      "-e[change the handling of erroneous packages]" \
+      "-export[set the Export field to the name of a file containing up-to-date export information for the given package]" \
+      "-find[identify the named packages but not resolve their dependencies]" \
+      "-test[report not only the named packages but also their test binaries]" \
+      "-m[list modules instead of packages]" \
+      "-u[adds information about available upgrades]" \
+      "-versions[set the Module's Versions field to a list of all known versions of that module]:number" \
+      "*:importpaths:__go_packages"
+    ;;
+  mod)
+    local -a mod_commands
+    mod_commands+=(
+      'download[download modules to local cache]'
+      'edit[edit go.mod from tools or scripts]'
+      'graph[print module requirement graph]'
+      'init[initialize new module in current directory]'
+      'tidy[add missing and remove unused modules]'
+      'vendor[make vendored copy of dependencies]'
+      'verify[verify dependencies have expected content]'
+      'why[explain why packages or modules are needed]'
+    )
+
+    if (( CURRENT == 3 )); then
+      _values 'go mod commands' ${mod_commands[@]} "help[display help]"
+      return
+    fi
+
+    case ${words[3]} in
+    help)
+      _values 'go mod commands' ${mod_commands[@]}
+      ;;
+    download)
+      _arguments -s -w : \
+        "-json[print a sequence of JSON objects standard output]" \
+        "*:flags"
+      ;;
+    edit)
+      _arguments -s -w : \
+        "-fmt[reformat the go.mod file]" \
+        "-module[change the module's path]" \
+        "-replace[=old{@v}=new{@v} add a replacement of the given module path and version pair]:name" \
+        "-dropreplace[=old{@v}=new{@v} drop a replacement of the given module path and version pair]:name" \
+        "-go[={version} set the expected Go language version]:number" \
+        "-print[print the final go.mod in its text format]" \
+        "-json[print the final go.mod file in JSON format]" \
+        "*:flags"
+      ;;
+    graph)
+      ;;
+    init)
+      ;;
+    tidy)
+      _arguments -s -w : \
+        "-v[print information about removed modules]" \
+        "*:flags"
+      ;;
+    vendor)
+      _arguments -s -w : \
+        "-v[print the names of vendored]" \
+        "*:flags"
+      ;;
+    verify)
+      ;;
+    why)
+      _arguments -s -w : \
+        "-m[treats the arguments as a list of modules and finds a path to any package in each of the modules]" \
+        "-vendor[exclude tests of dependencies]" \
+        "*:importpaths:__go_packages"
+      ;;
+    esac
+    ;;
+  help)
+    _values "${commands[@]}" \
+      'environment[show Go environment variables available]' \
+      'gopath[GOPATH environment variable]' \
+      'packages[description of package lists]' \
+      'remote[remote import path syntax]' \
+      'testflag[description of testing flags]' \
+      'testfunc[description of testing functions]'
+    ;;
+  run)
+    _arguments -s -w : \
+      ${build_flags[@]} \
+      '*:file:_files -g "*.go"'
+    ;;
+  tool)
+    if (( CURRENT == 3 )); then
+        _values "go tool" $(go tool)
+        return
+    fi
+    case ${words[3]} in
+    [568]g)
+        _arguments -s -w : \
+            '-I[search for packages in DIR]:includes:_path_files -/' \
+            '-L[show full path in file:line prints]' \
+            '-S[print the assembly language]' \
+            '-V[print the compiler version]' \
+            '-e[no limit on number of errors printed]' \
+            '-h[panic on an error]' \
+            '-l[disable inlining]' \
+            '-m[print optimization decisions]' \
+            '-o[file specify output file]:file' \
+            '-p[assumed import path for this code]:importpath' \
+            '-u[disable package unsafe]' \
+            "*:file:_files -g '*.go'"
+        ;;
+    [568]l)
+        local O=${words[3]%l}
+        _arguments -s -w : \
+            '-o[file specify output file]:file' \
+            '-L[search for packages in DIR]:includes:_path_files -/' \
+            "*:file:_files -g '*.[ao$O]'"
+        ;;
+    dist)
+        _values "dist tool" banner bootstrap clean env install version
+        ;;
+    *)
+        # use files by default
+        _files
+        ;;
+    esac
+    ;;
+  esac
+}
+
+_go "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/golang.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/golang.plugin.zsh
new file mode 100644 (file)
index 0000000..0dbaab0
--- /dev/null
@@ -0,0 +1,35 @@
+## completion
+compctl -g "*.go" gofmt # standard go tools
+compctl -g "*.go" gccgo # gccgo
+
+# gc
+for p in 5 6 8; do
+  compctl -g "*.${p}" ${p}l
+  compctl -g "*.go" ${p}g
+done
+unset p
+
+## aliases
+alias gob='go build'
+alias goc='go clean'
+alias god='go doc'
+alias gof='go fmt'
+alias gofa='go fmt ./...'
+alias gofx='go fix'
+alias gog='go get'
+alias goga='go get ./...'
+alias goi='go install'
+alias gol='go list'
+alias gom='go mod'
+alias gopa='cd $GOPATH'
+alias gopb='cd $GOPATH/bin'
+alias gops='cd $GOPATH/src'
+alias gor='go run'
+alias got='go test'
+alias gota='go test ./...'
+alias goto='go tool'
+alias gotoc='go tool compile'
+alias gotod='go tool dist'
+alias gotofx='go tool fix'
+alias gov='go vet'
+alias gow='go work'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/templates/package.txt b/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/templates/package.txt
new file mode 100644 (file)
index 0000000..2b75cce
--- /dev/null
@@ -0,0 +1,29 @@
+{{with .PDoc}}{{/*
+
+Constants 
+---------------------------------------
+
+*/}}{{with .Consts}}{{range .}}{{range .Names}}{{.}} {{end}}{{end}}{{end}}{{/*
+
+Variables
+---------------------------------------
+
+*/}}{{with .Vars}}{{range .}}{{range .Names}}{{.}} {{end}}{{end}}{{end}}{{/*
+
+Functions
+---------------------------------------
+
+*/}}{{with .Funcs}}{{range .}}{{ .Name }} {{end}}{{end}}{{/*
+
+Types
+---------------------------------------
+
+*/}}{{with .Types}}{{range .}}{{ $TypeName := .Name }}{{ $TypeName }} {{/*
+
+*/}}{{range .Methods}}{{ $TypeName }}.{{.Name}} {{end}}{{/*
+
+*/}}{{range .Funcs}}{{.Name}} {{end}}{{/*
+
+*/}}{{range .Consts}}{{range .Names}}{{.}} {{end}}{{end}}{{/*
+
+*/}}{{range .Vars}}{{range .Names}}{{.}} {{end}}{{end}}{{end}}{{end}}{{end}}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/templates/search.txt b/stow/oh-my-zsh/.oh-my-zsh/plugins/golang/templates/search.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gpg-agent/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gpg-agent/README.md
new file mode 100644 (file)
index 0000000..8eeb94f
--- /dev/null
@@ -0,0 +1,9 @@
+# gpg-agent
+
+Enables [GPG's gpg-agent](https://www.gnupg.org/documentation/manuals/gnupg/) if it is not running.
+
+To use it, add `gpg-agent` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... gpg-agent)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gpg-agent/gpg-agent.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gpg-agent/gpg-agent.plugin.zsh
new file mode 100644 (file)
index 0000000..1f4be20
--- /dev/null
@@ -0,0 +1,17 @@
+export GPG_TTY=$TTY
+
+# Fix for passphrase prompt on the correct tty
+# See https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html#option-_002d_002denable_002dssh_002dsupport
+function _gpg-agent_update-tty_preexec {
+  gpg-connect-agent updatestartuptty /bye &>/dev/null
+}
+autoload -U add-zsh-hook
+add-zsh-hook preexec _gpg-agent_update-tty_preexec
+
+# If enable-ssh-support is set, fix ssh agent integration
+if [[ $(gpgconf --list-options gpg-agent 2>/dev/null | awk -F: '$1=="enable-ssh-support" {print $10}') = 1 ]]; then
+  unset SSH_AGENT_PID
+  if [[ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]]; then
+    export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
+  fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/README.md
new file mode 100644 (file)
index 0000000..3756db0
--- /dev/null
@@ -0,0 +1,30 @@
+# Gradle plugin
+
+This plugin adds completions and aliases for [Gradle](https://gradle.org/).
+
+To use it, add `gradle` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... gradle)
+```
+
+## Usage
+
+This plugin creates a function called `gradle-or-gradlew`, which is aliased
+to `gradle`, which is used to determine whether the current project directory
+has a gradlew file. If `gradlew` is present it will be used, otherwise `gradle`
+is used instead. Gradle tasks can be executed directly without regard for
+whether it is `gradle` or `gradlew`. It also supports being called from
+any directory inside the root project directory.
+
+Examples:
+
+```zsh
+gradle test
+gradle build
+```
+
+## Completion
+
+This plugin uses [the completion from the Gradle project](https://github.com/gradle/gradle-completion),
+which is distributed under the MIT license.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/_gradle b/stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/_gradle
new file mode 100644 (file)
index 0000000..770723d
--- /dev/null
@@ -0,0 +1,420 @@
+#compdef gradle gradlew gw
+#
+# Taken from https://github.com/gradle/gradle-completion
+# Copyright (c) 2017 Eric Wendelin
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# Terms
+
+__gradle-set-project-root-dir() {
+    local dir=`pwd`
+    project_root_dir=`pwd`
+    while [[ $dir != '/' ]]; do
+        if [[ -f "$dir/settings.gradle" || -f "$dir/settings.gradle.kts" || -f "$dir/gradlew" ]]; then
+            project_root_dir=$dir
+            return 0
+        fi
+        dir="$(dirname "$dir")"
+    done
+    return 1
+}
+
+__gradle-init-cache-dir() {
+    cache_dir="$HOME/.gradle/completion"
+    mkdir -p $cache_dir
+}
+
+__gradle-set-settings-file() {
+    # In order of precedence: --settings-file=filename, settings.gradle, settings.gradle.kts
+
+    local default_gradle_settings_file="$project_root_dir/settings.gradle"
+    if [[ ! -f $default_gradle_settings_file ]]; then
+      default_gradle_settings_file="$project_root_dir/settings.gradle.kts"
+    fi
+    gradle_settings_file=${${(v)opt_args[(i)-c|--settings-file]}:-$default_gradle_settings_file}
+}
+
+__gradle-set-build-file() {
+    __gradle-set-settings-file
+    # In order of precedence: --build-file=filename, rootProject.buildFileName, build.gradle, build.gradle.kts
+
+    local default_gradle_build_file_name="build.gradle"
+    if [[ -r $gradle_settings_file ]]; then
+        default_gradle_build_file_name=${$(grep "^rootProject\.buildFileName" $gradle_settings_file | \
+            sed -n -e "s/rootProject\.buildFileName = [\'\"]\(.*\)[\'\"]/\1/p")}
+
+        default_gradle_build_file_name="${default_gradle_build_file:-build.gradle}"
+    fi
+
+    local default_gradle_build_file="$project_root_dir/$default_gradle_build_file_name"
+    if [[ ! -f $default_gradle_build_file ]]; then
+        default_gradle_build_file="$project_root_dir/build.gradle.kts"
+    fi
+
+    # If a build file is specified after '-b' or '--build-file', use this file.
+    gradle_build_file=${${(v)opt_args[(i)-b|--build-file]}:-$default_gradle_build_file}
+}
+
+__gradle-set-cache-name() {
+    # Cache name is constructed from the absolute path of the build file.
+    cache_name=${${gradle_build_file:a}//[^[:alnum:]]/_}
+}
+
+__gradle-set-files-checksum() {
+    # Cache MD5 sum of all Gradle scripts and modified timestamps
+    if builtin command -v md5 > /dev/null; then
+        gradle_files_checksum=( $(md5 -q -s "$(cat "$cache_dir/$cache_name" | xargs ls -o 2>/dev/null)") )
+    elif builtin command -v md5sum > /dev/null; then
+        gradle_files_checksum=( $(cat "$cache_dir/$cache_name" | xargs ls -o 2>/dev/null | md5sum | awk '{print $1}') )
+    else
+        _message 'Cannot generate completions as neither md5 nor md5sum exist on \$PATH'
+        return 1
+    fi
+}
+
+__gradle-generate-script-cache() {
+    # Invalidate cache after 3 weeks by default
+    local cache_ttl_mins=${$(echo $GRADLE_CACHE_TTL_MINUTES):-30240}
+    local script_exclude_pattern=${$(echo $GRADLE_COMPLETION_EXCLUDE_PATTERN):-"/(.git|build|integTest|samples|templates|smokeTest|testFixtures|out)/"}
+    if [[ ! $(find $cache_dir/$cache_name -mmin -$cache_ttl_mins 2>/dev/null) ]]; then
+        zle -R "Generating Gradle build script cache"
+        # Cache all Gradle scripts
+        local -a gradle_build_scripts
+        gradle_build_scripts=( $(find $project_root_dir -type f -name "*.gradle" -o -name "*.gradle.kts" 2>/dev/null | grep -E -v "$script_exclude_pattern") )
+        printf "%s\n" "${gradle_build_scripts[@]}" >| $cache_dir/$cache_name
+    fi
+}
+
+__gradle-generate-tasks-cache() {
+    __gradle-set-files-checksum
+
+    # Use Gradle wrapper when it exists.
+    local gradle_cmd="gradle"
+    if [[ -x "$project_root_dir/gradlew" ]]; then
+        gradle_cmd="$project_root_dir/gradlew"
+    fi
+
+    zle -R "Generating Gradle task cache from $gradle_build_file"
+
+    # Run gradle to retrieve possible tasks and cache.
+    # Reuse Gradle Daemon if IDLE but don't start a new one.
+    local gradle_tasks_output
+    if [[ ! -z "$($gradle_cmd --status 2>/dev/null | grep IDLE)" ]]; then
+        gradle_tasks_output="$($gradle_cmd --daemon --build-file $gradle_build_file --console plain -q tasks --all 2>/dev/null)"
+    else
+        gradle_tasks_output="$($gradle_cmd --no-daemon --build-file $gradle_build_file --console plain -q tasks --all 2>/dev/null)"
+    fi
+    local gradle_all_tasks="" root_tasks="" subproject_tasks="" output_line
+    local -a match
+    for output_line in ${(f)"$(printf "%s\n" "${gradle_tasks_output[@]}")"}; do
+        if [[ $output_line =~ ^([[:lower:]][[:alnum:][:punct:]]*)([[:space:]]-[[:space:]]([[:print:]]*))? ]]; then
+            local task_name="${match[1]}"
+            local task_description="${match[3]}"
+            # Completion for subproject tasks with ':' prefix
+            if [[ $task_name =~ ^([[:alnum:][:punct:]]+):([[:alnum:]]+) ]]; then
+                gradle_all_tasks+="${task_name//:/\\:}:$task_description\n\\:${task_name//:/\\:}:$task_description\n"
+                subproject_tasks+="${match[2]}\n"
+            else
+                gradle_all_tasks+="${task_name//:/\\:}:$task_description\n"
+                root_tasks+="$task_name\n"
+            fi
+        fi
+    done
+
+    # subproject tasks can be referenced implicitly from root project
+    if [[ $GRADLE_COMPLETION_UNQUALIFIED_TASKS == "true" ]]; then
+        local -a implicit_tasks
+        implicit_tasks=( $(comm -23 <(echo $subproject_tasks | sort) <(echo $root_tasks | sort)) )
+        for task in $(printf "%s\n" "${implicit_tasks[@]}"); do
+            gradle_all_tasks+="$task\n"
+        done
+    fi
+
+    echo $gradle_all_tasks >| $cache_dir/$gradle_files_checksum
+    echo $gradle_files_checksum >| $cache_dir/$cache_name.md5
+}
+
+__gradle-completion-init() {
+    local cache_dir cache_name gradle_build_file gradle_files_checksum project_root_dir
+    __gradle-init-cache-dir
+    __gradle-set-project-root-dir
+    __gradle-set-build-file
+    if [[ -f $gradle_build_file ]]; then
+        __gradle-set-cache-name
+        __gradle-generate-script-cache
+        __gradle-set-files-checksum
+        __gradle-generate-tasks-cache
+    fi
+    return 0
+}
+
+__gradle_tasks() {
+    local cache_dir cache_name gradle_build_file gradle_files_checksum project_root_dir
+
+    __gradle-init-cache-dir
+    __gradle-set-project-root-dir
+    __gradle-set-build-file
+    if [[ -f $gradle_build_file ]]; then
+        __gradle-set-cache-name
+        __gradle-generate-script-cache
+        __gradle-set-files-checksum
+
+        # The cache key is md5 sum of all gradle scripts, so it's valid if it exists.
+        if [[ -f $cache_dir/$cache_name.md5 ]]; then
+            local cached_checksum="$(cat $cache_dir/$cache_name.md5)"
+            local -a cached_tasks
+            if [[ -z $cur ]]; then
+                cached_tasks=(${(f)"$(cat $cache_dir/$cached_checksum)"})
+            else
+                cached_tasks=(${(f)"$(grep "^${cur//:/\\\\:}" $cache_dir/$cached_checksum)"})
+            fi
+            _describe 'all tasks' cached_tasks && ret=0
+        else
+            __gradle-generate-tasks-cache
+        fi
+
+        # Regenerate tasks cache in the background
+        if [[ $gradle_files_checksum != "$(cat $cache_dir/$cache_name.md5)" || ! -f $cache_dir/$gradle_files_checksum || $(wc -c < $cache_dir/$gradle_files_checksum) -le 1 ]]; then
+            $(__gradle-generate-tasks-cache 1>&2 2>/dev/null &)
+        fi
+    else
+        _describe 'built-in tasks' '(
+            "buildEnvironment:Displays all buildscript dependencies declared in root project."
+            "components:Displays the components produced by root project."
+            "dependencies:Displays all dependencies declared in root project."
+            "dependencyInsight:Displays the insight into a specific dependency in root project."
+            "dependentComponents:Displays the dependent components of components in root project."
+            "help:Displays a help message."
+            "init:Initializes a new Gradle build."
+            "model:Displays the configuration model of root project."
+            "projects:Displays the sub-projects of root project."
+            "properties:Displays the properties of root project."
+            "tasks:Displays the tasks runnable from root project."
+            "wrapper:Generates Gradle wrapper files."
+            )' && ret=0
+    fi
+}
+
+__gradle_subcommand() {
+    integer ret=1
+
+    case "$words[1]" in
+        (dependencies)
+            _arguments \
+                '--configuration=[The configuration to generate the report for.]:dependency configuration:_gradle_dependency_configurations' && ret=0
+            ;;
+        (dependencyInsight)
+            _arguments \
+                '--dependency=[Shows the details of given dependency.]' \
+                '--configuration=[Looks for the dependency in given configuration.]:dependency configuration:_gradle_dependency_configurations' && ret=0
+            ;;
+        (help)
+            _arguments \
+                '--task[The task to show help for.]' && ret=0
+            ;;
+        (init)
+            _arguments \
+                '--dsl=[DSL to be used in generated scripts.]:dsl:(groovy kotlin)' \
+                '--package=[Package for the generated source.]' \
+                '--project-name=[Name of the generated project.]' \
+                '--test-framework=[Test framework to be used.]:test framework:(junit kotlintest scalatest spock testng)' \
+                '--type=[Project type to generate.]:project type:(basic cpp-application cpp-library groovy-application groovy-library java-application java-library kotlin-application kotlin-library pom scala-library)' && ret=0
+            ;;
+        (tasks)
+            _arguments \
+                '--all[List all tasks, including subproject tasks.]' \
+                '--group=[Show tasks only from given task group.]' && ret=0
+            ;;
+        (test)
+            _arguments -C \
+                '--debug-jvm[Enable debugging for the test process. The process is started suspended and listening on port 5005. Requires the "java" plugin.]' \
+                '--fail-fast[Stops test execution after the first failed test. Requires the "java" plugin.]' \
+                '--tests=[Sets test class or method name to be included, * is supported. Requires the "java" plugin.]' \
+                '(-)*:: :->task-or-option' && ret=0
+            ;;
+        (wrapper)
+            _arguments \
+                '--distribution-type=[Binary-only or all with docs and sources]:*:distribution type:(bin all)' \
+                '--gradle-version=[Set Gradle version for wrapper]' \
+                '--gradle-distribution-sha256-sum=[SHA-256 checksum]' \
+                '--gradle-distribution-url=[Set Gradle distribution URL]' && ret=0
+            ;;
+        (*)
+            _arguments -C \
+                {-a,--no-rebuild}'[Do not rebuild project dependencies.]' \
+                '(--no-build-cache)--build-cache[Enable the Gradle build cache.]' \
+                {-b,--build-file}'[Specifies the build file.]:build script:_files -g \*.gradle' \
+                {-C,--cache}'[Specifies how compiled build scripts should be cached.]:cache policy:(on rebuild)' \
+                {-c,--settings-file}'[Specifies the settings file.]:settings file:_files -g \*.gradle' \
+                '(--no-configure-on-demand)--configure-on-demand[Only relevant projects are configured in this build run.]' \
+                '--console=[Specifies which type of console output to generate.]:console output type:(plain auto rich verbose)' \
+                '--continue[Continues task execution after a task failure.]' \
+                '-Dorg.gradle.cache.reserved.mb=[Reserve Gradle Daemon memory for operations.]' \
+                '-Dorg.gradle.caching=[Set true to enable Gradle build cache.]:enable build cache:(true false)' \
+                '-Dorg.gradle.console=[Set type of console output to generate.]:console output type:(plain auto rich verbose)' \
+                '-Dorg.gradle.daemon.debug=[Set true to debug Gradle Daemon.]:enable daemon debug:(true false)' \
+                '-Dorg.gradle.daemon.idletimeout=[Kill Gradle Daemon after # idle millis.]' \
+                '-Dorg.gradle.debug=[Set true to debug Gradle Client.]' \
+                '-Dorg.gradle.jvmargs=[Set JVM arguments.]' \
+                '-Dorg.gradle.java.home=[Set JDK home dir.]' \
+                '-Dorg.gradle.logging.level=[Set default Gradle log level.]:log level:(quiet warn lifecycle info debug)' \
+                '-Dorg.gradle.parallel=[Set true to enable parallel project builds.]:enable parallel build:(true false)' \
+                '-Dorg.gradle.priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \
+                '-Dorg.gradle.warning.mode=[Set types of warnings to log.]:warning level:(all summary none)' \
+                '-Dorg.gradle.workers.max=[Set the number of workers Gradle is allowed to use.]' \
+                '(-i --info -w --warn -q --quiet)'{-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \
+                '(--no-daemon)--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
+                '--foreground[Starts the Gradle daemon in the foreground.]' \
+                {-g,--gradle-user-home}'[Specifies the gradle user home directory.]:file:_directories' \
+                \*--include-build'[Includes the specified build in the composite.]:file:_directories' \
+                \*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle' \
+                '(-d --debug -w --warn -q --quiet)'{-i,--info}'[Set log level to info.]' \
+                '--max-workers[Set the maximum number of concurrent workers that Gradle may use.]:number workers' \
+                {-m,--dry-run}'[Runs the builds with all task actions disabled.]' \
+                '--no-color[Do not use color in the console output. (Removed in Gradle 3.0)]' \
+                '(--build-cache)--no-build-cache[Do not use the Gradle build cache.]' \
+                '(--configure-on-demand)--no-configure-on-demand[Disables configuration on demand.]' \
+                '(--daemon)--no-daemon[Do not use the Gradle daemon to run the build.]' \
+                '(--parallel)--no-parallel[Disables parallel execution to build projects.]' \
+                '(--scan)--no-scan[Do not create a build scan.]' \
+                '--offline[The build should operate without accessing network resources.]' \
+                \*{-P+,--project-prop}'[Set project property for the build script (e.g. -Pmyprop=myvalue).]:project property (prop=val):' \
+                {-p,--project-dir}'[Specifies the start directory for Gradle.]:start directory:_directories' \
+                '(--no-parallel)--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
+                '--profile[Profiles build execution time and generates a report in the <build_dir>/reports/profile directory.]' \
+                '--priority[Set priority for Gradle worker processes.]:priority:(low normal)' \
+                '--project-cache-dir[Specifies the project-specific cache directory.]:cache directory:_directories' \
+                '(-d --debug -w --warn -i --info)'{-q,--quiet}'[Log errors only.]' \
+                '--recompile-scripts[Force build script recompiling.]' \
+                '--refresh[Refresh the state of resources of the type(s) specified.]:refresh policy:(dependencies)' \
+                '--refresh-dependencies[Refresh the state of dependencies.]' \
+                '--rerun-tasks[Ignore previously cached task results.]' \
+                '(--no-scan)--scan[Create a build scan.]' \
+                '(-S --full-stacktrace)'{-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \
+                '(-s --stacktrace)'{-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \
+                '--system-prop[system property (prop=val)]' \
+                {-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
+                {-u,--no-search-upward}"[Don't search in parent folders for a settings.gradle file.]" \
+                '(--write-locks)--update-locks[Perform a partial update of the dependency lock.]' \
+                '(-d --debug -q --quiet -i --info)'{-w,--warn}'[Log warnings and errors only.]' \
+                '--warning-mode=[Set types of warnings to log.]:warning mode:(all summary none)' \
+                '(--update-locks)--write-locks[Persists dependency resolution for locked configurations.]' \
+                {-x,--exclude-task}'[Specify a task to be excluded from execution.]' && ret=0
+            ;;
+    esac
+
+    return ret
+}
+
+(( $+functions[_gradle_dependency_configurations] )) ||
+_gradle_dependency_configurations() {
+    local configurations
+    configurations=(
+        'compileClasspath'
+        'runtimeClasspath'
+        'testCompileClasspath'
+        'testRuntimeClasspath'
+    )
+    _describe -t 'dependency configurations' "dependency configuration" configurations
+}
+
+_gradle() {
+    local cur=${words[CURRENT]}
+    local curcontext="$curcontext" state
+    integer ret=1
+    typeset -A opt_args
+
+    _arguments -C \
+        '(-)'{-\?,-h,--help}'[Shows a help message.]' \
+        {-a,--no-rebuild}'[Do not rebuild project dependencies.]' \
+        '(--no-build-cache)--build-cache[Enable the Gradle build cache.]' \
+        {-b,--build-file}'[Specifies the build file.]:build script:_files -g \*.gradle' \
+        {-C,--cache}'[Specifies how compiled build scripts should be cached.]:cache policy:(on rebuild)' \
+        {-c,--settings-file}'[Specifies the settings file.]:settings file:_files -g \*.gradle:->argument-expected' \
+        '(--no-configure-on-demand)--configure-on-demand[Only relevant projects are configured in this build run.]' \
+        '--console=[Specifies which type of console output to generate.]:console output type:(plain auto rich verbose)' \
+        '--continue[Continues task execution after a task failure.]' \
+        '-Dorg.gradle.cache.reserved.mb=[Reserve Gradle Daemon memory for operations.]' \
+        '-Dorg.gradle.caching=[Set true to enable Gradle build cache.]' \
+        '-Dorg.gradle.console=[Set type of console output to generate.]:console output type:(plain auto rich verbose)' \
+        '-Dorg.gradle.daemon.debug=[Set true to debug Gradle Daemon.]' \
+        '-Dorg.gradle.daemon.idletimeout=[Kill Gradle Daemon after # idle millis.]' \
+        '-Dorg.gradle.debug=[Set true to debug Gradle Client.]' \
+        '-Dorg.gradle.jvmargs=[Set JVM arguments.]' \
+        '-Dorg.gradle.java.home=[Set JDK home dir.]' \
+        '-Dorg.gradle.logging.level=[Set default Gradle log level.]:log level:(quiet warn lifecycle info debug)' \
+        '-Dorg.gradle.parallel=[Set true to enable parallel project builds.]:(true false)' \
+        '-Dorg.gradle.priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \
+        '-Dorg.gradle.warning.mode=[Set types of warnings to log.]:warning level:(all summary none)' \
+        '-Dorg.gradle.workers.max=[Set the number of workers Gradle is allowed to use.]' \
+        '(-i --info -w --warn -q --quiet)'{-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \
+        '(--no-daemon)--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
+        '--foreground[Starts the Gradle daemon in the foreground.]' \
+        {-g,--gradle-user-home}'[Specifies the gradle user home directory.]:home directory:_directories:->argument-expected' \
+        '(-)--gui[Launches the Gradle GUI. (Removed in Gradle 4.0)]' \
+        \*--include-build'[Includes the specified build in the composite.]:file:_directories:->argument-expected' \
+        \*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle:->argument-expected' \
+        '(-d --debug -w --warn -q --quiet)'{-i,--info}'[Set log level to info.]' \
+        '--max-workers[Set the maximum number of concurrent workers that Gradle may use.]:number workers:->argument-expected' \
+        {-m,--dry-run}'[Runs the builds with all task actions disabled.]' \
+        '--no-color[Do not use color in the console output. (Removed in Gradle 3.0)]' \
+        '(--build-cache)--no-build-cache[Do not use the Gradle build cache.]' \
+        '(--configure-on-demand)--no-configure-on-demand[Disables configuration on demand.]' \
+        '(--daemon)--no-daemon[Do not use the Gradle daemon to run the build.]' \
+        '(--parallel)--no-parallel[Disables parallel execution to build projects.]' \
+        '(--scan)--no-scan[Do not create a build scan.]' \
+        '--offline[The build should operate without accessing network resources.]' \
+        \*{-P+,--project-prop}'[Set project property for the build script (e.g. -Pmyprop=myvalue).]:project property (prop=val):->argument-expected' \
+        {-p,--project-dir}'[Specifies the start directory for Gradle.]:start directory:_directories:->argument-expected' \
+        '(--no-parallel)--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
+        '--priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \
+        '--profile[Profiles build execution time and generates a report in the <build_dir>/reports/profile directory.]' \
+        '--project-cache-dir=[Specifies the project-specific cache directory.]:cache directory:_directories:->argument-expected' \
+        '(-d --debug -w --warn -i --info)'{-q,--quiet}'[Log errors only.]' \
+        '--recompile-scripts[Force build script recompiling.]' \
+        '--refresh[Refresh the state of resources of the type(s) specified.]:refresh policy:(dependencies)' \
+        '--refresh-dependencies[Refresh the state of dependencies.]' \
+        '--rerun-tasks[Ignore previously cached task results.]' \
+        '(--no-scan)--scan[Create a build scan.]' \
+        '(-S --full-stacktrace)'{-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \
+        '(-s --stacktrace)'{-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \
+        '(-)--status[Shows status of running and recently stopped Gradle Daemons.]' \
+        '(-)--stop[Stops all Gradle daemons.]' \
+        '--system-prop[system property (prop=val)]' \
+        {-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
+        {-u,--no-search-upward}"[Don't search in parent folders for a settings.gradle file.]" \
+        '(--write-locks)--update-locks[Perform a partial update of the dependency lock.]' \
+        '(-)'{-v,--version}'[Print version info.]' \
+        '(-d --debug -q --quiet -i --info)'{-w,--warn}'[Log warnings and errors only.]' \
+        '--warning-mode=[Set types of warnings to log.]:warning mode:(all summary none)' \
+        '(--update-locks)--write-locks[Persists dependency resolution for locked configurations.]' \
+        {-x,--exclude-task}'[Specify a task to be excluded from execution.]' \
+        '(-)*:: :->task-or-option' && ret=0
+
+    if [[ $words[CURRENT] != -* && $state != "argument-expected" ]]; then
+        __gradle_tasks && ret=0
+    else
+        curcontext=${curcontext%:*:*}:gradle-$words[1]:
+        __gradle_subcommand && ret=0
+    fi
+
+    return ret
+}
+
+_gradle "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/gradle.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gradle/gradle.plugin.zsh
new file mode 100644 (file)
index 0000000..5bca364
--- /dev/null
@@ -0,0 +1,26 @@
+# Looks for a gradlew file in the current working directory
+# or any of its parent directories, and executes it if found.
+# Otherwise it will call gradle directly.
+function gradle-or-gradlew() {
+  # find project root
+  # taken from https://github.com/gradle/gradle-completion
+  local dir="$PWD" project_root="$PWD"
+  while [[ "$dir" != / ]]; do
+    if [[ -f "$dir/settings.gradle" || -f "$dir/settings.gradle.kts" || -f "$dir/gradlew" ]]; then
+      project_root="$dir"
+      break
+    fi
+    dir="${dir:h}"
+  done
+
+  # if gradlew found, run it instead of gradle
+  if [[ -f "$project_root/gradlew" ]]; then
+    echo "executing gradlew instead of gradle"
+    "$project_root/gradlew" "$@"
+  else
+    command gradle "$@"
+  fi
+}
+
+alias gradle=gradle-or-gradlew
+compdef _gradle gradle-or-gradlew
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/grails/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/grails/README.md
new file mode 100644 (file)
index 0000000..5d9ebd7
--- /dev/null
@@ -0,0 +1,16 @@
+# Grails plugin
+
+This plugin adds completion for the [Grails 2 CLI](https://grails.github.io/grails2-doc/2.5.x/guide/commandLine.html)
+
+To use it, add `grails` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... grails)
+```
+
+It looks for scripts in the following paths:
+
+- `$GRAILS_HOME/scripts`
+- `~/.grails/scripts`
+- `./scripts`
+- `./plugins/*/scripts`
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/grails/grails.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/grails/grails.plugin.zsh
new file mode 100644 (file)
index 0000000..ddc2574
--- /dev/null
@@ -0,0 +1,60 @@
+_enumerateGrailsScripts() {
+    # Default directories
+    directories=($GRAILS_HOME/scripts ~/.grails/scripts ./scripts)
+
+    # Check all of the plugins directories, if they exist
+    if [ -d plugins ]
+    then
+        directories+=(plugins/*/scripts)
+    fi
+    
+    # Enumerate all of the Groovy files
+    files=()
+    for dir in $directories;
+    do
+        if [ -d $dir ]
+        then
+            files+=($dir/[^_]*.groovy)
+        fi
+    done
+    
+    # Don't try to basename ()
+    if [ ${#files} -eq 0 ];
+    then
+        return
+    fi
+    
+    scripts=()
+    for file in $files
+    do
+        # - Strip the path
+        # - Remove all scripts with a leading '_'
+        # - PackagePlugin_.groovy -> PackagePlugin
+        # - PackagePlugin         -> Package-Plugin
+        # - Package-Plugin        -> package-plugin
+        command=$(basename $file                              \
+            | sed -E  -e 's/^_?([^_]+)_?.groovy/\1/'\
+                      -e 's/([a-z])([A-Z])/\1-\2/g' \
+            | tr "[:upper:]" "[:lower:]"            \
+            | sort                                  \
+            | uniq)
+        scripts+=($command)
+    done
+    echo $scripts
+}
+_grails() {
+    if (( CURRENT == 2 )); then
+        scripts=( $(_enumerateGrailsScripts) )
+        
+        if [ ${#scripts} -ne 0 ];
+        then
+            _multi_parts / scripts
+            return
+        fi
+    fi
+    
+    _files
+}
+compdef _grails grails
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/grc/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/grc/README.md
new file mode 100644 (file)
index 0000000..515e876
--- /dev/null
@@ -0,0 +1,15 @@
+# Generic Colouriser plugin
+
+This plugin adds wrappers for commands supported by [Generic Colouriser](https://github.com/garabik/grc):
+
+To use it, add `grc` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... grc)
+```
+
+## Commands
+
+The plugin sources the bundled alias generator from the installation, available at `/etc/grc.zsh`.
+The complete list of wrapped commands may vary depending on the installed version of `grc`, look
+at the file mentioned above (`/etc/grc.zsh`) to see which commands are wrapped.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/grc/grc.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/grc/grc.plugin.zsh
new file mode 100644 (file)
index 0000000..b709b9e
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env zsh
+
+# common grc.zsh paths
+files=(
+  /etc/grc.zsh            # default
+  /usr/local/etc/grc.zsh  # homebrew
+)
+
+# verify the file is readable and source it
+for file in $files; do
+  if [[ -r "$file" ]]; then
+    source "$file"
+    break
+  fi
+done
+
+unset file files
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/grunt/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/grunt/README.md
new file mode 100644 (file)
index 0000000..a69a9b7
--- /dev/null
@@ -0,0 +1,37 @@
+# grunt plugin
+
+This plugin adds completions for [grunt](https://github.com/gruntjs/grunt).
+
+To use it, add `grunt` to the plugins array of your `.zshrc` file:
+```zsh
+plugins=(... grunt)
+```
+
+## Enable caching
+
+If you want to use the cache, set the following in your `.zshrc`:
+```zsh
+zstyle ':completion:*' use-cache yes
+```
+
+## Settings
+
+* Show grunt file path:
+  ```zsh
+  zstyle ':completion::complete:grunt::options:' show_grunt_path yes
+  ```
+* Cache expiration days (default: 7):
+  ```zsh
+  zstyle ':completion::complete:grunt::options:' expire 1
+  ```
+* Not update options cache if target gruntfile is changed.
+  ```zsh
+  zstyle ':completion::complete:grunt::options:' no_update_options yes
+  ```
+
+Note that if you change the zstyle settings, you should delete the cache file and restart zsh.
+
+```zsh
+$ rm ~/.zcompcache/grunt
+$ exec zsh
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/grunt/grunt.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/grunt/grunt.plugin.zsh
new file mode 100644 (file)
index 0000000..a89469a
--- /dev/null
@@ -0,0 +1,255 @@
+#compdef grunt
+#autoload
+# -----------------------------------------------------------------------------
+#  _grunt
+#
+#  Completion script for grunt.
+#   - https://github.com/gruntjs/grunt
+#   - https://github.com/gruntjs/grunt-cli
+#
+# -----------------------------------------------------------------------------
+#
+#  Version     : 0.1.2
+#  Author      : Yonchu <yuyuchu3333@gmail.com>
+#  License     : MIT License
+#  Repository  : https://github.com/yonchu/grunt-zsh-completion
+#  Last Change : 20 Aug 2014.
+#
+#  Copyright (c) 2013 Yonchu.
+#
+# -----------------------------------------------------------------------------
+# USAGE
+# -----
+#
+# Enable caching:
+#
+#   If you want to use the cache, set the followings in your .zshrc:
+#
+#     zstyle ':completion:*' use-cache yes
+#
+#
+# Settings:
+#
+#  - Show grunt file path:
+#      zstyle ':completion::complete:grunt::options:' show_grunt_path yes
+#
+#  - Cache expiration days (default: 7):
+#      zstyle ':completion::complete:grunt::options:' expire 1
+#
+#  - Not update options cache if target gruntfile is changed.
+#      zstyle ':completion::complete:grunt::options:' no_update_options yes
+#
+#  Note that if you change the zstyle settings,
+#  you should delete the cache file and restart zsh.
+#
+#    $ rm ~/.zcompcache/grunt
+#    $ exec zsh
+#
+# -----------------------------------------------------------------------------
+
+function __grunt() {
+    local curcontext="$curcontext" update_policy state
+    local show_grunt_path update_msg gruntfile opts tasks
+
+    # Setup cache-policy.
+    zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+    if [[ -z $update_policy ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __grunt_caching_policy
+    fi
+
+    # Check show_path option.
+    zstyle -b ":completion:${curcontext}:options:" show_grunt_path show_grunt_path
+
+    # Get current gruntfile.
+    gruntfile=$(__grunt_get_gruntfile)
+
+    # Initialize opts and tasks.
+    opts=()
+    tasks=()
+
+    # Add help options.
+    opts+=('(- 1 *)'{-h,--help}'[Display this help text.]')
+
+    ## Complete without gruntfile.
+    if [[ ! -f $gruntfile ]]; then
+        _arguments "${opts[@]}"
+        return
+    fi
+
+    ## Complete with gruntfile.
+    # Retrieve cache.
+    if ! __grunt_update_cache "$gruntfile"; then
+        update_msg=' (cache updated)'
+    fi
+
+    # Make options completion.
+    if [[ ${#__grunt_opts} -gt 0 ]]; then
+        opts+=("${__grunt_opts[@]}")
+    fi
+
+    # Complete arguments.
+    _arguments \
+        "${opts[@]}" \
+        '*: :->tasks' \
+        && return
+
+    case $state in
+        tasks)
+            if [[ $show_grunt_path == 'yes' ]]; then
+                update_msg="$update_msg: ${${gruntfile/#$HOME/~}%/}"
+            fi
+            # Make tasks completion.
+            if [[ ${#__grunt_tasks} -gt 0 ]]; then
+                tasks+=("${__grunt_tasks[@]}")
+                _describe -t grunt-task "$verbose grunt task$update_msg" tasks || return 1
+            fi
+        ;;
+    esac
+
+    return 0
+}
+
+# Cache policy:
+#   The cache file name: grunt
+#   The cache variable name: __grunt_version __grunt_gruntfile __grunt_opts __grunt_tasks
+function __grunt_update_cache() {
+    # TODO
+    local version='0.1.2'
+    local is_updating=0
+    local gruntfile="$1"
+    local grunt_info no_update_options cache_path
+
+    # Check no_update_options option.
+    zstyle -b ":completion:${curcontext}:options:" no_update_options no_update_options
+
+
+    if ! ( ((  $+__grunt_gruntfile )) \
+        && (( $+__grunt_opts )) \
+        && (( $+__grunt_tasks )) ) \
+        && ! _retrieve_cache 'grunt'; then
+        is_updating=1
+    fi
+
+    if [[ $gruntfile != $__grunt_gruntfile ]]; then
+        # Except for --help options.
+        __grunt_gruntfile=$gruntfile
+        if [[ $no_update_options == 'yes' ]]; then
+            if [[ $PREFIX == ${PREFIX#-} ]]; then
+                # Not options completions.
+                is_updating=1
+            elif [[ ${#__grunt_opts} -lt 2 ]]; then
+                is_updating=1
+            else
+                unset __grunt_gruntfile
+            fi
+        else
+            is_updating=1
+        fi
+    else
+        if [[ $PREFIX != ${PREFIX#-} && ${#__grunt_opts} -gt 1 ]]; then
+            unset __grunt_gruntfile
+        fi
+    fi
+
+    if _cache_invalid 'grunt'; then
+        is_updating=1
+    fi
+
+    # Check _grunt version.
+    if [[ $__grunt_version != $version ]]; then
+        is_updating=1
+    fi
+
+    if [[ $is_updating -ne 0 ]]; then
+        # Update cache.
+        __grunt_version=$version
+        __grunt_gruntfile=$gruntfile
+        is_updating=1
+        grunt_info=$(grunt --help --no-color --gruntfile "$__grunt_gruntfile" 2>/dev/null)
+        __grunt_opts=(${(f)"$(__grunt_get_opts "$grunt_info")"})
+        __grunt_tasks=(${(f)"$(__grunt_get_tasks "$grunt_info")"})
+        _store_cache 'grunt' __grunt_version __grunt_gruntfile __grunt_opts __grunt_tasks
+    fi
+    return $is_updating
+}
+
+function __grunt_get_tasks() {
+    echo -E "$1" \
+        | grep 'Available tasks' -A 100 \
+        | grep '^ ' \
+        | sed -e 's/^[[:blank:]]*//' -e 's/[[:blank:]]*$//' \
+        | sed -e 's/:/\\:/g' \
+        | sed -e 's/  /:/'
+}
+
+function __grunt_get_opts() {
+    local opt_hunk opt_sep opt_num line opt
+    opt_hunk=$(echo -E "$1" \
+        | grep 'Options$' -A 100 \
+        | sed '1 d' \
+        | sed -e 's/[[:blank:]]*$//' \
+    )
+
+    opt_sep=()
+    opt_hunk=(${(f)opt_hunk})
+    opt_num=0
+    for line in "$opt_hunk[@]"; do
+        opt=$(echo -E "$line" | sed -e 's/^[[:blank:]]*//')
+        if [[ $line == $opt ]]; then
+            break
+        fi
+        if [[ $opt != ${opt#-} ]]; then
+            # Start with -
+            (( opt_num++ ))
+            opt=$(echo -E "$opt" | sed 's/^\(\(--[^ ]*\)\(, \(-[^ ]*\)\)*\)  */\2\\t\4\\\t/')
+        fi
+        opt_sep[$opt_num]=("${opt_sep[$opt_num]}${opt}")
+    done
+
+    for line in "$opt_sep[@]"; do
+        opt=(${(s:\t:)line})
+        if [[ ${opt[1]} == '--help' ]]; then
+            continue
+        fi
+        if [[ ${#opt} -eq 2 ]]; then
+            echo -E "(${opt[1]})${opt[1]}[${opt[2]}]"
+        else
+            echo -E "(${opt[1]},${opt[2]})${opt[1]}[${opt[3]}]"
+            echo -E "(${opt[1]},${opt[2]})${opt[2]}[${opt[3]}]"
+        fi
+    done
+}
+
+function __grunt_get_gruntfile() {
+    local gruntfile
+    local curpath="$PWD"
+    while [ "$curpath" ]; do
+        for gruntfile in "$curpath/"{G,g}runtfile.{js,coffee}; do
+            if [[ -e "$gruntfile" ]]; then
+                echo "$gruntfile"
+                return
+            fi
+        done
+        curpath=${curpath%/*}
+    done
+    return 1
+}
+
+function __grunt_caching_policy() {
+    # Returns status zero if the completions cache needs rebuilding.
+
+    # Rebuild if .agignore more recent than cache.
+    if [[ -f $__grunt_gruntfile && $__grunt_gruntfile -nt $1 ]]; then
+        # Invalid cache because gruntfile is old.
+        return 0
+    fi
+
+    local -a oldp
+    local expire
+    zstyle -s ":completion:${curcontext}:options:" expire expire || expire=7
+    # Rebuild if cache is more than $expire days.
+    oldp=( "$1"(Nm+$expire) )
+    (( $#oldp ))
+}
+
+compdef __grunt grunt
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gulp/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/gulp/README.md
new file mode 100644 (file)
index 0000000..4ed2b99
--- /dev/null
@@ -0,0 +1,8 @@
+# gulp plugin
+
+This plugin adds autocompletion for your [`gulp`](https://gulpjs.com/) tasks. It grabs all available tasks from the `gulpfile.js` in the current directory.
+
+To use it, add `gulp` to the plugins array of your `.zshrc` file:
+```
+plugins=(... gulp)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/gulp/gulp.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/gulp/gulp.plugin.zsh
new file mode 100644 (file)
index 0000000..6234302
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/env zsh
+
+#
+# gulp-autocompletion-zsh
+#
+# Autocompletion for your gulp.js tasks
+#
+# Copyright(c) 2014 André König <andre.koenig@posteo.de>
+# MIT Licensed
+#
+
+#
+# André König
+# GitHub: https://github.com/akoenig
+# Twitter: https://twitter.com/caiifr
+#
+
+#
+# Grabs all available tasks from the `gulpfile.js`
+# in the current directory.
+#
+function _gulp_completion {
+    compls=$(gulp --tasks-simple 2>/dev/null)
+
+    completions=(${=compls})
+    compadd -- $completions
+}
+
+compdef _gulp_completion gulp
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hanami/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/hanami/README.md
new file mode 100644 (file)
index 0000000..c9e09f4
--- /dev/null
@@ -0,0 +1,45 @@
+# Hanami Plugin
+
+This plugin adds convenient aliases to work with [Hanami](https://hanamirb.org/) via console.
+It's inspired by Rails plugin, so if you've used it, you'll feel like home.
+
+To use it, add `hanami` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... hanami)
+```
+
+## Usage
+
+For example, type `hc` into your console when you're within Hanami project directory to run
+the application console. Have a look at available shortcuts below. You can read more about
+these commands [on the official website](https://hanamirb.org/guides/command-line/applications/).
+
+## Aliases
+
+| Alias | Command                     | Description                                             |
+|-------|-----------------------------|---------------------------------------------------------|
+| HED\* | `HANAMI_ENV=development`    | Set environment variable HANAMI_ENV to development      |
+| HEP\* | `HANAMI_ENV=production`     | Set environment variable HANAMI_ENV to production       |
+| HET\* | `HANAMI_ENV=test`           | Set environment variable HANAMI_ENV to test             |
+| hc    | `hanami console`            | Run application console                                 |
+| hd    | `hanami destroy`            | Remove specified hanami resource                        |
+| hg    | `hanami generate`           | Create specified hanami resource                        |
+| hgm   | `hanami generate migration` | Create migration file                                   |
+| hs    | `hanami server`             | Launch server with hanami application                   |
+| hsp   | `hanami server -p`          | Launch server with specified port                       |
+| hr    | `hanami routes`             | List application routes                                 |
+| hdc   | `hanami db create`          | Create application database                             |
+| hdd   | `hanami db drop`            | Delete application database                             |
+| hdp   | `hanami db prepare`         | Prepare database for the current environment            |
+| hda   | `hanami db apply`           | Recreates a fresh schema after migrations (destructive) |
+| hdv   | `hanami db version`         | Print current database version                          |
+| hdrs  | `hdd && hdp`                | Drop and recreate application database                  |
+| hdtp  | `HET hdp`                   | Actualize test environment database                     |
+| hrg   | `hr | grep`                 | Grep hanami routes with specified pattern               |
+
+\* You should use these at the beginning of a command, for example:
+
+```console
+$ HED hdd # equivalent to 'HANAMI_ENV=development hanami db drop'
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hanami/hanami.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/hanami/hanami.plugin.zsh
new file mode 100644 (file)
index 0000000..42143b4
--- /dev/null
@@ -0,0 +1,19 @@
+alias HED='HANAMI_ENV=development '
+alias HEP='HANAMI_ENV=production '
+alias HET='HANAMI_ENV=test '
+
+alias hc='hanami console'
+alias hd='hanami destroy'
+alias hg='hanami generate'
+alias hgm='hanami generate migration'
+alias hs='hanami server'
+alias hsp='hanami server -p'
+alias hr='hanami routes'
+alias hdc='hanami db create'
+alias hdd='hanami db drop'
+alias hdp='hanami db prepare'
+alias hda='hanami db apply'
+alias hdv='hanami db version'
+alias hdrs='hdd && hdp'
+alias hdtp='HET hdp'
+alias hrg='hr | grep'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/helm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/helm/README.md
new file mode 100644 (file)
index 0000000..49844c7
--- /dev/null
@@ -0,0 +1,9 @@
+# Helm plugin
+
+This plugin adds completion for [Helm](https://helm.sh/), the Kubernetes package manager.
+
+To use it, add `helm` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... helm)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/helm/helm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/helm/helm.plugin.zsh
new file mode 100644 (file)
index 0000000..151c43d
--- /dev/null
@@ -0,0 +1,13 @@
+if (( ! $+commands[helm] )); then
+  return
+fi
+
+# If the completion file does not exist, generate it and then source it
+# Otherwise, source it and regenerate in the background
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_helm" ]]; then
+  helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null
+  source "$ZSH_CACHE_DIR/completions/_helm"
+else
+  source "$ZSH_CACHE_DIR/completions/_helm"
+  helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null &|
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/heroku/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/heroku/README.md
new file mode 100644 (file)
index 0000000..2bf92c9
--- /dev/null
@@ -0,0 +1,9 @@
+# Heroku
+
+This plugin provides completion for the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli).
+
+To use it add heroku to the plugins array in your zshrc file:
+
+```bash
+plugins=(... heroku)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/heroku/heroku.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/heroku/heroku.plugin.zsh
new file mode 100644 (file)
index 0000000..d22c1bb
--- /dev/null
@@ -0,0 +1,9 @@
+if [[ "$OSTYPE" = darwin* ]]; then
+  cache_dir="${HOME}/Library/Caches"
+else
+  cache_dir="${XDG_CACHE_HOME:-"${HOME}/.cache"}"
+fi
+
+setup_path="${cache_dir}/heroku/autocomplete/zsh_setup"
+[[ -f "$setup_path" ]] && source $setup_path
+unset cache_dir setup_path
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/README.md
new file mode 100644 (file)
index 0000000..6d8b564
--- /dev/null
@@ -0,0 +1,198 @@
+# zsh-history-substring-search
+
+This is a clean-room implementation of the [Fish shell][1]'s history search
+feature, where you can type in any part of any command from history and then
+press chosen keys, such as the UP and DOWN arrows, to cycle through matches.
+
+[1]: http://fishshell.com
+[2]: http://www.zsh.org/mla/users/2009/msg00818.html
+[3]: http://sourceforge.net/projects/fizsh/
+[4]: https://github.com/robbyrussell/oh-my-zsh/pull/215
+[5]: https://github.com/zsh-users/zsh-history-substring-search
+[6]: https://github.com/zsh-users/zsh-syntax-highlighting
+
+
+Requirements
+------------------------------------------------------------------------------
+
+* [ZSH](http://zsh.sourceforge.net) 4.3 or newer
+
+Install
+------------------------------------------------------------------------------
+
+Using the [Homebrew]( https://brew.sh ) package manager:
+
+    brew install zsh-history-substring-search
+    echo 'source /usr/local/share/zsh-history-substring-search/zsh-history-substring-search.zsh' >> ~/.zshrc
+
+Using [Oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh):
+
+1. Clone this repository in oh-my-zsh's plugins directory:
+
+        git clone https://github.com/zsh-users/zsh-history-substring-search ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-history-substring-search
+
+2. Activate the plugin in `~/.zshrc`:
+
+        plugins=( [plugins...] history-substring-search)
+
+3. Source `~/.zshrc`  to take changes into account:
+
+        source ~/.zshrc
+
+Usage
+------------------------------------------------------------------------------
+
+1.  Load this script into your interactive ZSH session:
+
+        % source zsh-history-substring-search.zsh
+
+    If you want to use [zsh-syntax-highlighting][6] along with this script,
+    then make sure that you load it *before* you load this script:
+
+        % source zsh-syntax-highlighting.zsh
+        % source zsh-history-substring-search.zsh
+
+2.  Bind keyboard shortcuts to this script's functions.
+
+    Users typically bind their UP and DOWN arrow keys to this script, thus:
+    * Run `cat -v` in your favorite terminal emulator to observe key codes.
+      (**NOTE:** In some cases, `cat -v` shows the wrong key codes.  If the
+      key codes shown by `cat -v` don't work for you, press `<C-v><UP>` and
+      `<C-v><DOWN>` at your ZSH command line prompt for correct key codes.)
+    * Press the UP arrow key and observe what is printed in your terminal.
+    * Press the DOWN arrow key and observe what is printed in your terminal.
+    * Press the Control and C keys simultaneously to terminate the `cat -v`.
+    * Use your observations from the previous steps to create key bindings.
+      For example, if you observed `^[[A` for UP and `^[[B` for DOWN, then:
+
+          bindkey '^[[A' history-substring-search-up
+          bindkey '^[[B' history-substring-search-down
+
+      However, if the observed values don't work, you can try using terminfo:
+
+          bindkey "$terminfo[kcuu1]" history-substring-search-up
+          bindkey "$terminfo[kcud1]" history-substring-search-down
+
+      You might also want to bind the Control-P/N keys for use in EMACS mode:
+
+          bindkey -M emacs '^P' history-substring-search-up
+          bindkey -M emacs '^N' history-substring-search-down
+
+      You might also want to bind the `k` and `j` keys for use in VI mode:
+
+          bindkey -M vicmd 'k' history-substring-search-up
+          bindkey -M vicmd 'j' history-substring-search-down
+
+3.  Type any part of any previous command and then:
+
+    * Press the `history-substring-search-up` key, which was configured in
+      step 2 above, to select the nearest command that (1) contains your query
+      and (2) is also older than the current command in your command history.
+
+    * Press the `history-substring-search-down` key, which was configured in
+      step 2 above, to select the nearest command that (1) contains your query
+      and (2) is also newer than the current command in your command history.
+
+    * Press `^U` the Control and U keys simultaneously to abort the search.
+
+4.  If a matching command spans more than one line of text, press the LEFT
+    arrow key to move the cursor away from the end of the command, and then:
+
+    * Press the `history-substring-search-up` key, which was configured in
+      step 2 above, to move the cursor to the line above the cursored line.
+      When the cursor reaches the first line of the command, pressing the
+      `history-substring-search-up` key again will cause this script to
+      perform another search.
+
+    * Press the `history-substring-search-down` key, which was configured in
+      step 2 above, to move the cursor to the line below the cursored line.
+      When the cursor reaches the last line of the command, pressing the
+      `history-substring-search-down` key, which was configured in step 2
+      above, again will cause this script to perform another search.
+
+
+Configuration
+------------------------------------------------------------------------------
+
+This script defines the following global variables. You may override their
+default values only after having loaded this script into your ZSH session.
+
+* `HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND` is a global variable that defines
+  how the query should be highlighted inside a matching command. Its default
+  value causes this script to highlight using bold, white text on a magenta
+  background. See the "Character Highlighting" section in the zshzle(1) man
+  page to learn about the kinds of values you may assign to this variable.
+
+* `HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND` is a global variable that
+  defines how the query should be highlighted when no commands in the
+  history match it. Its default value causes this script to highlight using
+  bold, white text on a red background. See the "Character Highlighting"
+  section in the zshzle(1) man page to learn about the kinds of values you
+  may assign to this variable.
+
+* `HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS` is a global variable that defines
+  how the command history will be searched for your query. Its default value
+  causes this script to perform a case-insensitive search. See the "Globbing
+  Flags" section in the zshexpn(1) man page to learn about the kinds of
+  values you may assign to this variable.
+
+* `HISTORY_SUBSTRING_SEARCH_FUZZY` is a global variable that defines
+  how the command history will be searched for your query. If set to a non-empty
+  value, causes this script to perform a fuzzy search by words, matching in
+  given order e.g. `ab c` will match `*ab*c*`
+
+* `HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE` is a global variable that defines
+  whether all search results returned are _unique_. If set to a non-empty
+  value, then only unique search results are presented. This behaviour is off
+  by default. An alternative way to ensure that search results are unique is
+  to use `setopt HIST_IGNORE_ALL_DUPS`. If this configuration variable is off
+  and `setopt HIST_IGNORE_ALL_DUPS` is unset, then `setopt HIST_FIND_NO_DUPS`
+  is still respected and it makes this script skip duplicate _adjacent_ search
+  results as you cycle through them, but this does not guarantee that search
+  results are unique: if your search results were "Dog", "Dog", "HotDog",
+  "Dog", then cycling them gives "Dog", "HotDog", "Dog". Notice that the "Dog"
+  search result appeared twice as you cycled through them. If you wish to
+  receive globally unique search results only once, then use this
+  configuration variable, or use `setopt HIST_IGNORE_ALL_DUPS`.
+
+
+History
+------------------------------------------------------------------------------
+
+* September 2009: [Peter Stephenson][2] originally wrote this script and it
+  published to the zsh-users mailing list.
+
+* January 2011: Guido van Steen (@guidovansteen) revised this script and
+  released it under the 3-clause BSD license as part of [fizsh][3], the
+  Friendly Interactive ZSHell.
+
+* January 2011: Suraj N. Kurapati (@sunaku) extracted this script from
+  [fizsh][3] 1.0.1, refactored it heavily, and finally repackaged it as an
+  [oh-my-zsh plugin][4] and as an independently loadable [ZSH script][5].
+
+* July 2011: Guido van Steen, Suraj N. Kurapati, and Sorin Ionescu
+  (@sorin-ionescu) [further developed it][4] with Vincent Guerci (@vguerci).
+
+* March 2016: Geza Lore (@gezalore) greatly refactored it in pull request #55.
+
+------------------------------------------------------------------------------
+Oh My Zsh Distribution Notes
+------------------------------------------------------------------------------
+
+What you are looking at now is Oh My Zsh's repackaging of zsh-history-substring-search 
+as an OMZ module inside the Oh My Zsh distribution.
+
+The upstream repo, zsh-users/zsh-history-substring-search, can be found on GitHub at 
+https://github.com/zsh-users/zsh-history-substring-search.
+
+This downstream copy was last updated from the following upstream commit:
+
+  SHA:          0f80b8eb3368b46e5e573c1d91ae69eb095db3fb
+  Commit date:  2019-05-12 17:35:54 -0700
+
+Everything above this section is a copy of the original upstream's README, so things
+may differ slightly when you're using this inside OMZ. In particular, you do not
+need to set up key bindings for the up and down arrows yourself in `~/.zshrc`; the OMZ 
+plugin does that for you. You may still want to set up additional emacs- or vi-specific
+bindings as mentioned above.
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/history-substring-search.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/history-substring-search.plugin.zsh
new file mode 100644 (file)
index 0000000..63f0bdd
--- /dev/null
@@ -0,0 +1,19 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+source ${0:A:h}/history-substring-search.zsh
+
+
+# Bind terminal-specific up and down keys
+
+if [[ -n "$terminfo[kcuu1]" ]]; then
+  bindkey -M emacs "$terminfo[kcuu1]" history-substring-search-up
+  bindkey -M viins "$terminfo[kcuu1]" history-substring-search-up
+fi
+if [[ -n "$terminfo[kcud1]" ]]; then
+  bindkey -M emacs "$terminfo[kcud1]" history-substring-search-down
+  bindkey -M viins "$terminfo[kcud1]" history-substring-search-down
+fi
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/history-substring-search.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/history-substring-search.zsh
new file mode 100644 (file)
index 0000000..c326778
--- /dev/null
@@ -0,0 +1,759 @@
+#!/usr/bin/env zsh
+##############################################################################
+#
+# Copyright (c) 2009 Peter Stephenson
+# Copyright (c) 2011 Guido van Steen
+# Copyright (c) 2011 Suraj N. Kurapati
+# Copyright (c) 2011 Sorin Ionescu
+# Copyright (c) 2011 Vincent Guerci
+# Copyright (c) 2016 Geza Lore
+# Copyright (c) 2017 Bengt Brodersen
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#  * Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+#  * Redistributions in binary form must reproduce the above
+#    copyright notice, this list of conditions and the following
+#    disclaimer in the documentation and/or other materials provided
+#    with the distribution.
+#
+#  * Neither the name of the FIZSH nor the names of its contributors
+#    may be used to endorse or promote products derived from this
+#    software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+##############################################################################
+
+#-----------------------------------------------------------------------------
+# declare global configuration variables
+#-----------------------------------------------------------------------------
+
+typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'
+typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'
+typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'
+typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''
+typeset -g HISTORY_SUBSTRING_SEARCH_FUZZY=''
+
+#-----------------------------------------------------------------------------
+# declare internal global variables
+#-----------------------------------------------------------------------------
+
+typeset -g BUFFER MATCH MBEGIN MEND CURSOR
+typeset -g _history_substring_search_refresh_display
+typeset -g _history_substring_search_query_highlight
+typeset -g _history_substring_search_result
+typeset -g _history_substring_search_query
+typeset -g -a _history_substring_search_query_parts
+typeset -g -a _history_substring_search_raw_matches
+typeset -g -i _history_substring_search_raw_match_index
+typeset -g -a _history_substring_search_matches
+typeset -g -i _history_substring_search_match_index
+typeset -g -A _history_substring_search_unique_filter
+
+#-----------------------------------------------------------------------------
+# the main ZLE widgets
+#-----------------------------------------------------------------------------
+
+history-substring-search-up() {
+  _history-substring-search-begin
+
+  _history-substring-search-up-history ||
+  _history-substring-search-up-buffer ||
+  _history-substring-search-up-search
+
+  _history-substring-search-end
+}
+
+history-substring-search-down() {
+  _history-substring-search-begin
+
+  _history-substring-search-down-history ||
+  _history-substring-search-down-buffer ||
+  _history-substring-search-down-search
+
+  _history-substring-search-end
+}
+
+zle -N history-substring-search-up
+zle -N history-substring-search-down
+
+#-----------------------------------------------------------------------------
+# implementation details
+#-----------------------------------------------------------------------------
+
+zmodload -F zsh/parameter
+
+#
+# We have to "override" some keys and widgets if the
+# zsh-syntax-highlighting plugin has not been loaded:
+#
+# https://github.com/nicoulaj/zsh-syntax-highlighting
+#
+if [[ $+functions[_zsh_highlight] -eq 0 ]]; then
+  #
+  # Dummy implementation of _zsh_highlight() that
+  # simply removes any existing highlights when the
+  # user inserts printable characters into $BUFFER.
+  #
+  _zsh_highlight() {
+    if [[ $KEYS == [[:print:]] ]]; then
+      region_highlight=()
+    fi
+  }
+
+  #
+  # The following snippet was taken from the zsh-syntax-highlighting project:
+  #
+  # https://github.com/zsh-users/zsh-syntax-highlighting/blob/56b134f5d62ae3d4e66c7f52bd0cc2595f9b305b/zsh-syntax-highlighting.zsh#L126-161
+  #
+  # Copyright (c) 2010-2011 zsh-syntax-highlighting contributors
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #  * Redistributions of source code must retain the above copyright
+  #    notice, this list of conditions and the following disclaimer.
+  #
+  #  * Redistributions in binary form must reproduce the above copyright
+  #    notice, this list of conditions and the following disclaimer in the
+  #    documentation and/or other materials provided with the distribution.
+  #
+  #  * Neither the name of the zsh-syntax-highlighting contributors nor the
+  #    names of its contributors may be used to endorse or promote products
+  #    derived from this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+  # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  #
+  #--------------8<-------------------8<-------------------8<-----------------
+  # Rebind all ZLE widgets to make them invoke _zsh_highlights.
+  _zsh_highlight_bind_widgets()
+  {
+    # Load ZSH module zsh/zleparameter, needed to override user defined widgets.
+    zmodload zsh/zleparameter 2>/dev/null || {
+      echo 'zsh-syntax-highlighting: failed loading zsh/zleparameter.' >&2
+      return 1
+    }
+
+    # Override ZLE widgets to make them invoke _zsh_highlight.
+    local cur_widget
+    for cur_widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|run-help|which-command|beep|yank*)}; do
+      case $widgets[$cur_widget] in
+
+        # Already rebound event: do nothing.
+        user:$cur_widget|user:_zsh_highlight_widget_*);;
+
+        # User defined widget: override and rebind old one with prefix "orig-".
+        user:*) eval "zle -N orig-$cur_widget ${widgets[$cur_widget]#*:}; \
+                      _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \
+                      zle -N $cur_widget _zsh_highlight_widget_$cur_widget";;
+
+        # Completion widget: override and rebind old one with prefix "orig-".
+        completion:*) eval "zle -C orig-$cur_widget ${${widgets[$cur_widget]#*:}/:/ }; \
+                            _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \
+                            zle -N $cur_widget _zsh_highlight_widget_$cur_widget";;
+
+        # Builtin widget: override and make it call the builtin ".widget".
+        builtin) eval "_zsh_highlight_widget_$cur_widget() { builtin zle .$cur_widget -- \"\$@\" && _zsh_highlight }; \
+                       zle -N $cur_widget _zsh_highlight_widget_$cur_widget";;
+
+        # Default: unhandled case.
+        *) echo "zsh-syntax-highlighting: unhandled ZLE widget '$cur_widget'" >&2 ;;
+      esac
+    done
+  }
+  #-------------->8------------------->8------------------->8-----------------
+
+  _zsh_highlight_bind_widgets
+fi
+
+_history-substring-search-begin() {
+  setopt localoptions extendedglob
+
+  _history_substring_search_refresh_display=
+  _history_substring_search_query_highlight=
+
+  #
+  # If the buffer is the same as the previously displayed history substring
+  # search result, then just keep stepping through the match list. Otherwise
+  # start a new search.
+  #
+  if [[ -n $BUFFER && $BUFFER == ${_history_substring_search_result:-} ]]; then
+    return;
+  fi
+
+  #
+  # Clear the previous result.
+  #
+  _history_substring_search_result=''
+
+  if [[ -z $BUFFER ]]; then
+    #
+    # If the buffer is empty, we will just act like up-history/down-history
+    # in ZSH, so we do not need to actually search the history. This should
+    # speed things up a little.
+    #
+    _history_substring_search_query=
+    _history_substring_search_query_parts=()
+    _history_substring_search_raw_matches=()
+
+  else
+    #
+    # For the purpose of highlighting we keep a copy of the original
+    # query string.
+    #
+    _history_substring_search_query=$BUFFER
+
+    #
+    # compose search pattern
+    #
+    if [[ -n $HISTORY_SUBSTRING_SEARCH_FUZZY ]]; then
+      #
+      # `=` split string in arguments
+      #
+      _history_substring_search_query_parts=(${=_history_substring_search_query})
+    else
+      _history_substring_search_query_parts=(${==_history_substring_search_query})
+    fi
+
+    #
+    # Escape and join query parts with wildcard character '*' as separator
+    # `(j:CHAR:)` join array to string with CHAR as separator
+    #
+    local search_pattern="*${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*"
+
+    #
+    # Find all occurrences of the search pattern in the history file.
+    #
+    # (k) returns the "keys" (history index numbers) instead of the values
+    # (R) returns values in reverse older, so the index of the youngest
+    # matching history entry is at the head of the list.
+    #
+    _history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${search_pattern}]})
+  fi
+
+  #
+  # In order to stay as responsive as possible, we will process the raw
+  # matches lazily (when the user requests the next match) to choose items
+  # that need to be displayed to the user.
+  # _history_substring_search_raw_match_index holds the index of the last
+  # unprocessed entry in _history_substring_search_raw_matches. Any items
+  # that need to be displayed will be added to
+  # _history_substring_search_matches.
+  #
+  # We use an associative array (_history_substring_search_unique_filter) as
+  # a 'set' data structure to ensure uniqueness of the results if desired.
+  # If an entry (key) is in the set (non-empty value), then we have already
+  # added that entry to _history_substring_search_matches.
+  #
+  _history_substring_search_raw_match_index=0
+  _history_substring_search_matches=()
+  _history_substring_search_unique_filter=()
+
+  #
+  # If $_history_substring_search_match_index is equal to
+  # $#_history_substring_search_matches + 1, this indicates that we
+  # are beyond the end of $_history_substring_search_matches and that we
+  # have also processed all entries in
+  # _history_substring_search_raw_matches.
+  #
+  # If $#_history_substring_search_match_index is equal to 0, this indicates
+  # that we are beyond the beginning of $_history_substring_search_matches.
+  #
+  # If we have initially pressed "up" we have to initialize
+  # $_history_substring_search_match_index to 0 so that it will be
+  # incremented to 1.
+  #
+  # If we have initially pressed "down" we have to initialize
+  # $_history_substring_search_match_index to 1 so that it will be
+  # decremented to 0.
+  #
+  if [[ $WIDGET == history-substring-search-down ]]; then
+     _history_substring_search_match_index=1
+  else
+    _history_substring_search_match_index=0
+  fi
+}
+
+_history-substring-search-end() {
+  setopt localoptions extendedglob
+
+  _history_substring_search_result=$BUFFER
+
+  # the search was successful so display the result properly by clearing away
+  # existing highlights and moving the cursor to the end of the result buffer
+  if [[ $_history_substring_search_refresh_display -eq 1 ]]; then
+    region_highlight=()
+    CURSOR=${#BUFFER}
+  fi
+
+  # highlight command line using zsh-syntax-highlighting
+  _zsh_highlight
+
+  # highlight the search query inside the command line
+  if [[ -n $_history_substring_search_query_highlight ]]; then
+    # highlight first matching query parts
+    local highlight_start_index=0
+    local highlight_end_index=0
+    local query_part
+    for query_part in $_history_substring_search_query_parts; do
+      local escaped_query_part=${query_part//(#m)[\][()|\\*?#<>~^]/\\$MATCH}
+      # (i) get index of pattern
+      local query_part_match_index="${${BUFFER:$highlight_start_index}[(i)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${escaped_query_part}]}"
+      if [[ $query_part_match_index -le ${#BUFFER:$highlight_start_index} ]]; then
+        highlight_start_index=$(( $highlight_start_index + $query_part_match_index ))
+        highlight_end_index=$(( $highlight_start_index + ${#query_part} ))
+        region_highlight+=("$(($highlight_start_index - 1)) $(($highlight_end_index - 1)) $_history_substring_search_query_highlight")
+      fi
+    done
+  fi
+
+  # For debugging purposes:
+  # zle -R "mn: "$_history_substring_search_match_index" m#: "${#_history_substring_search_matches}
+  # read -k -t 200 && zle -U $REPLY
+
+  # Exit successfully from the history-substring-search-* widgets.
+  return 0
+}
+
+_history-substring-search-up-buffer() {
+  #
+  # Check if the UP arrow was pressed to move the cursor within a multi-line
+  # buffer. This amounts to three tests:
+  #
+  # 1. $#buflines -gt 1.
+  #
+  # 2. $CURSOR -ne $#BUFFER.
+  #
+  # 3. Check if we are on the first line of the current multi-line buffer.
+  #    If so, pressing UP would amount to leaving the multi-line buffer.
+  #
+  #    We check this by adding an extra "x" to $LBUFFER, which makes
+  #    sure that xlbuflines is always equal to the number of lines
+  #    until $CURSOR (including the line with the cursor on it).
+  #
+  local buflines XLBUFFER xlbuflines
+  buflines=(${(f)BUFFER})
+  XLBUFFER=$LBUFFER"x"
+  xlbuflines=(${(f)XLBUFFER})
+
+  if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xlbuflines -ne 1 ]]; then
+    zle up-line-or-history
+    return 0
+  fi
+
+  return 1
+}
+
+_history-substring-search-down-buffer() {
+  #
+  # Check if the DOWN arrow was pressed to move the cursor within a multi-line
+  # buffer. This amounts to three tests:
+  #
+  # 1. $#buflines -gt 1.
+  #
+  # 2. $CURSOR -ne $#BUFFER.
+  #
+  # 3. Check if we are on the last line of the current multi-line buffer.
+  #    If so, pressing DOWN would amount to leaving the multi-line buffer.
+  #
+  #    We check this by adding an extra "x" to $RBUFFER, which makes
+  #    sure that xrbuflines is always equal to the number of lines
+  #    from $CURSOR (including the line with the cursor on it).
+  #
+  local buflines XRBUFFER xrbuflines
+  buflines=(${(f)BUFFER})
+  XRBUFFER="x"$RBUFFER
+  xrbuflines=(${(f)XRBUFFER})
+
+  if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xrbuflines -ne 1 ]]; then
+    zle down-line-or-history
+    return 0
+  fi
+
+  return 1
+}
+
+_history-substring-search-up-history() {
+  #
+  # Behave like up in ZSH, except clear the $BUFFER
+  # when beginning of history is reached like in Fish.
+  #
+  if [[ -z $_history_substring_search_query ]]; then
+
+    # we have reached the absolute top of history
+    if [[ $HISTNO -eq 1 ]]; then
+      BUFFER=
+
+    # going up from somewhere below the top of history
+    else
+      zle up-line-or-history
+    fi
+
+    return 0
+  fi
+
+  return 1
+}
+
+_history-substring-search-down-history() {
+  #
+  # Behave like down-history in ZSH, except clear the
+  # $BUFFER when end of history is reached like in Fish.
+  #
+  if [[ -z $_history_substring_search_query ]]; then
+
+    # going down from the absolute top of history
+    if [[ $HISTNO -eq 1 && -z $BUFFER ]]; then
+      BUFFER=${history[1]}
+      _history_substring_search_refresh_display=1
+
+    # going down from somewhere above the bottom of history
+    else
+      zle down-line-or-history
+    fi
+
+    return 0
+  fi
+
+  return 1
+}
+
+_history_substring_search_process_raw_matches() {
+  #
+  # Process more outstanding raw matches and append any matches that need to
+  # be displayed to the user to _history_substring_search_matches.
+  # Return whether there were any more results appended.
+  #
+
+  #
+  # While we have more raw matches. Process them to see if there are any more
+  # matches that need to be displayed to the user.
+  #
+  while [[ $_history_substring_search_raw_match_index -lt $#_history_substring_search_raw_matches ]]; do
+    #
+    # Move on to the next raw entry and get its history index.
+    #
+    _history_substring_search_raw_match_index+=1
+    local index=${_history_substring_search_raw_matches[$_history_substring_search_raw_match_index]}
+
+    #
+    # If HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set to a non-empty value,
+    # then ensure that only unique matches are presented to the user.
+    # When HIST_IGNORE_ALL_DUPS is set, ZSH already ensures a unique history,
+    # so in this case we do not need to do anything.
+    #
+    if [[ ! -o HIST_IGNORE_ALL_DUPS && -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then
+      #
+      # Get the actual history entry at the new index, and check if we have
+      # already added it to _history_substring_search_matches.
+      #
+      local entry=${history[$index]}
+
+      if [[ -z ${_history_substring_search_unique_filter[$entry]} ]]; then
+        #
+        # This is a new unique entry. Add it to the filter and append the
+        # index to _history_substring_search_matches.
+        #
+        _history_substring_search_unique_filter[$entry]=1
+        _history_substring_search_matches+=($index)
+
+        #
+        # Indicate that we did find a match.
+        #
+        return 0
+      fi
+
+    else
+      #
+      # Just append the new history index to the processed matches.
+      #
+      _history_substring_search_matches+=($index)
+
+      #
+      # Indicate that we did find a match.
+      #
+      return 0
+    fi
+
+  done
+
+  #
+  # We are beyond the end of the list of raw matches. Indicate that no
+  # more matches are available.
+  #
+  return 1
+}
+
+_history-substring-search-has-next() {
+  #
+  # Predicate function that returns whether any more older matches are
+  # available.
+  #
+
+  if  [[ $_history_substring_search_match_index -lt $#_history_substring_search_matches ]]; then
+    #
+    # We did not reach the end of the processed list, so we do have further
+    # matches.
+    #
+    return 0
+
+  else
+    #
+    # We are at the end of the processed list. Try to process further
+    # unprocessed matches. _history_substring_search_process_raw_matches
+    # returns whether any more matches were available, so just return
+    # that result.
+    #
+    _history_substring_search_process_raw_matches
+    return $?
+  fi
+}
+
+_history-substring-search-has-prev() {
+  #
+  # Predicate function that returns whether any more younger matches are
+  # available.
+  #
+
+  if [[ $_history_substring_search_match_index -gt 1 ]]; then
+    #
+    # We did not reach the beginning of the processed list, so we do have
+    # further matches.
+    #
+    return 0
+
+  else
+    #
+    # We are at the beginning of the processed list. We do not have any more
+    # matches.
+    #
+    return 1
+  fi
+}
+
+_history-substring-search-found() {
+  #
+  # A match is available. The index of the match is held in
+  # $_history_substring_search_match_index
+  #
+  # 1. Make $BUFFER equal to the matching history entry.
+  #
+  # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
+  #    to highlight the current buffer.
+  #
+  BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]]
+  _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND
+}
+
+_history-substring-search-not-found() {
+  #
+  # No more matches are available.
+  #
+  # 1. Make $BUFFER equal to $_history_substring_search_query so the user can
+  #    revise it and search again.
+  #
+  # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND
+  #    to highlight the current buffer.
+  #
+  BUFFER=$_history_substring_search_query
+  _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND
+}
+
+_history-substring-search-up-search() {
+  _history_substring_search_refresh_display=1
+
+  #
+  # Select history entry during history-substring-down-search:
+  #
+  # The following variables have been initialized in
+  # _history-substring-search-up/down-search():
+  #
+  # $_history_substring_search_matches is the current list of matches that
+  # need to be displayed to the user.
+  # $_history_substring_search_match_index is the index of the current match
+  # that is being displayed to the user.
+  #
+  # The range of values that $_history_substring_search_match_index can take
+  # is: [0, $#_history_substring_search_matches + 1].  A value of 0
+  # indicates that we are beyond the beginning of
+  # $_history_substring_search_matches. A value of
+  # $#_history_substring_search_matches + 1 indicates that we are beyond
+  # the end of $_history_substring_search_matches and that we have also
+  # processed all entries in _history_substring_search_raw_matches.
+  #
+  # If $_history_substring_search_match_index equals
+  # $#_history_substring_search_matches and
+  # $_history_substring_search_raw_match_index is not greater than
+  # $#_history_substring_search_raw_matches, then we need to further process
+  # $_history_substring_search_raw_matches to see if there are any more
+  # entries that need to be displayed to the user.
+  #
+  # In _history-substring-search-up-search() the initial value of
+  # $_history_substring_search_match_index is 0. This value is set in
+  # _history-substring-search-begin(). _history-substring-search-up-search()
+  # will initially increment it to 1.
+  #
+
+  if [[ $_history_substring_search_match_index -gt $#_history_substring_search_matches ]]; then
+    #
+    # We are beyond the end of $_history_substring_search_matches. This
+    # can only happen if we have also exhausted the unprocessed matches in
+    # _history_substring_search_raw_matches.
+    #
+    # 1. Update display to indicate search not found.
+    #
+    _history-substring-search-not-found
+    return
+  fi
+
+  if _history-substring-search-has-next; then
+    #
+    # We do have older matches.
+    #
+    # 1. Move index to point to the next match.
+    # 2. Update display to indicate search found.
+    #
+    _history_substring_search_match_index+=1
+    _history-substring-search-found
+
+  else
+    #
+    # We do not have older matches.
+    #
+    # 1. Move the index beyond the end of
+    #    _history_substring_search_matches.
+    # 2. Update display to indicate search not found.
+    #
+    _history_substring_search_match_index+=1
+    _history-substring-search-not-found
+  fi
+
+  #
+  # When HIST_FIND_NO_DUPS is set, meaning that only unique command lines from
+  # history should be matched, make sure the new and old results are different.
+  #
+  # However, if the HIST_IGNORE_ALL_DUPS shell option, or
+  # HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set, then we already have a
+  # unique history, so in this case we do not need to do anything.
+  #
+  if [[ -o HIST_IGNORE_ALL_DUPS || -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then
+    return
+  fi
+
+  if [[ -o HIST_FIND_NO_DUPS && $BUFFER == $_history_substring_search_result ]]; then
+    #
+    # Repeat the current search so that a different (unique) match is found.
+    #
+    _history-substring-search-up-search
+  fi
+}
+
+_history-substring-search-down-search() {
+  _history_substring_search_refresh_display=1
+
+  #
+  # Select history entry during history-substring-down-search:
+  #
+  # The following variables have been initialized in
+  # _history-substring-search-up/down-search():
+  #
+  # $_history_substring_search_matches is the current list of matches that
+  # need to be displayed to the user.
+  # $_history_substring_search_match_index is the index of the current match
+  # that is being displayed to the user.
+  #
+  # The range of values that $_history_substring_search_match_index can take
+  # is: [0, $#_history_substring_search_matches + 1].  A value of 0
+  # indicates that we are beyond the beginning of
+  # $_history_substring_search_matches. A value of
+  # $#_history_substring_search_matches + 1 indicates that we are beyond
+  # the end of $_history_substring_search_matches and that we have also
+  # processed all entries in _history_substring_search_raw_matches.
+  #
+  # In _history-substring-search-down-search() the initial value of
+  # $_history_substring_search_match_index is 1. This value is set in
+  # _history-substring-search-begin(). _history-substring-search-down-search()
+  # will initially decrement it to 0.
+  #
+
+  if [[ $_history_substring_search_match_index -lt 1 ]]; then
+    #
+    # We are beyond the beginning of $_history_substring_search_matches.
+    #
+    # 1. Update display to indicate search not found.
+    #
+    _history-substring-search-not-found
+    return
+  fi
+
+  if _history-substring-search-has-prev; then
+    #
+    # We do have younger matches.
+    #
+    # 1. Move index to point to the previous match.
+    # 2. Update display to indicate search found.
+    #
+    _history_substring_search_match_index+=-1
+    _history-substring-search-found
+
+  else
+    #
+    # We do not have younger matches.
+    #
+    # 1. Move the index beyond the beginning of
+    #    _history_substring_search_matches.
+    # 2. Update display to indicate search not found.
+    #
+    _history_substring_search_match_index+=-1
+    _history-substring-search-not-found
+  fi
+
+  #
+  # When HIST_FIND_NO_DUPS is set, meaning that only unique command lines from
+  # history should be matched, make sure the new and old results are different.
+  #
+  # However, if the HIST_IGNORE_ALL_DUPS shell option, or
+  # HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set, then we already have a
+  # unique history, so in this case we do not need to do anything.
+  #
+  if [[ -o HIST_IGNORE_ALL_DUPS || -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then
+    return
+  fi
+
+  if [[ -o HIST_FIND_NO_DUPS && $BUFFER == $_history_substring_search_result ]]; then
+    #
+    # Repeat the current search so that a different (unique) match is found.
+    #
+    _history-substring-search-down-search
+  fi
+}
+
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/update-from-upstream.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/history-substring-search/update-from-upstream.zsh
new file mode 100755 (executable)
index 0000000..81e1942
--- /dev/null
@@ -0,0 +1,129 @@
+#!/usr/bin/env zsh
+#
+# update-from-upstream.zsh
+#
+# This script updates the Oh My Zsh version of the zsh-history-substring-search
+# plugin from the independent upstream repo. This is to be run by OMZ developers
+# when they want to pull in new changes from upstream to OMZ. It is not run
+# during normal use of the plugin.
+#
+# The official upstream repo is zsh-users/zsh-history-substring-search
+# https://github.com/zsh-users/zsh-history-substring-search
+#
+# This is a zsh script, not a function. Call it with `zsh update-from-upstream.zsh`
+# from the command line, running it from within the plugin directory.
+#
+# You can set the environment variable REPO_PATH to point it at an upstream
+# repo you have already prepared. Otherwise, it will do a clean checkout of
+# upstream's HEAD to a temporary local repo and use that.
+
+
+# Just bail on any error so we don't have to do extra checking.
+# This is a developer-use script, so terse output like that should
+# be fine.
+set -e
+
+
+upstream_basename=zsh-history-substring-search
+plugin_basename=history-substring-search
+UPSTREAM_REPO=zsh-users/$upstream_basename
+need_repo_cleanup=false
+upstream_github_url="https://github.com/$UPSTREAM_REPO"
+
+if [[ -z "$UPSTREAM_REPO_PATH" ]]; then
+  # Do a clean checkout
+  my_tempdir=$(mktemp -d -t omz-update-histsubstrsrch)
+  UPSTREAM_REPO_PATH="$my_tempdir/$upstream_basename"
+  git clone "$upstream_github_url" "$UPSTREAM_REPO_PATH"
+  need_repo_cleanup=true
+  print "Checked out upstream repo to $UPSTREAM_REPO_PATH"
+else
+       print "Using existing $upstream_basename repo at $UPSTREAM_REPO_PATH"
+fi
+
+upstream="$UPSTREAM_REPO_PATH"
+
+# Figure out what we're pulling in
+upstream_sha=$(cd $upstream && git rev-parse HEAD)
+upstream_commit_date=$(cd $upstream && git log  -1 --pretty=format:%ci)
+upstream_just_date=${${=upstream_commit_date}[1]}
+print "upstream SHA:         $upstream_sha"
+print "upstream commit time: $upstream_commit_date"
+print "upstream commit date: $upstream_just_date"
+print
+
+# Copy the files over, using the OMZ plugin's names where needed
+cp -v "$upstream"/* .
+mv -v zsh-history-substring-search.zsh $plugin_basename.zsh
+mv -v zsh-history-substring-search.plugin.zsh $plugin_basename.plugin.zsh
+
+if [[ $need_repo_cleanup == true ]]; then
+       print "Removing temporary repo at $my_tempdir"
+       rm -rf "$my_tempdir"
+fi
+
+# Do OMZ-specific edits
+
+print
+print "Updating files with OMZ-specific stuff"
+print
+
+# OMZ binds the keys as part of the plugin loading
+
+cat >> $plugin_basename.plugin.zsh <<EOF
+
+
+# Bind terminal-specific up and down keys
+
+if [[ -n "\$terminfo[kcuu1]" ]]; then
+  bindkey -M emacs "\$terminfo[kcuu1]" history-substring-search-up
+  bindkey -M viins "\$terminfo[kcuu1]" history-substring-search-up
+fi
+if [[ -n "\$terminfo[kcud1]" ]]; then
+  bindkey -M emacs "\$terminfo[kcud1]" history-substring-search-down
+  bindkey -M viins "\$terminfo[kcud1]" history-substring-search-down
+fi
+
+EOF
+
+# Tack OMZ-specific notes on to readme
+
+thin_line="------------------------------------------------------------------------------"
+cat >> README.md <<EOF
+
+$thin_line
+Oh My Zsh Distribution Notes
+$thin_line
+
+What you are looking at now is Oh My Zsh's repackaging of zsh-history-substring-search 
+as an OMZ module inside the Oh My Zsh distribution.
+
+The upstream repo, $UPSTREAM_REPO, can be found on GitHub at 
+$upstream_github_url.
+
+This downstream copy was last updated from the following upstream commit:
+
+  SHA:          $upstream_sha
+  Commit date:  $upstream_commit_date
+
+Everything above this section is a copy of the original upstream's README, so things
+may differ slightly when you're using this inside OMZ. In particular, you do not
+need to set up key bindings for the up and down arrows yourself in \`~/.zshrc\`; the OMZ 
+plugin does that for you. You may still want to set up additional emacs- or vi-specific
+bindings as mentioned above.
+
+EOF
+
+# Announce success and generate git commit messages
+
+cat <<EOF
+Done OK
+
+Now you can check the results and commit like this:
+
+  git add *
+  git commit -m "history-substring-search: update to upstream version $upstream_just_date" \\
+      -m "Updates OMZ's copy to commit $upstream_sha from $UPSTREAM_REPO"
+
+EOF
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/history/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/history/README.md
new file mode 100644 (file)
index 0000000..a9d480f
--- /dev/null
@@ -0,0 +1,17 @@
+# history plugin
+
+Provides a couple of convenient aliases for using the `history` command to examine your command line history.
+
+To use it, add `history` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... history)
+```
+
+## Aliases
+
+| Alias | Command              | Description                                                      |
+|-------|----------------------|------------------------------------------------------------------|
+| `h`   | `history`            | Prints your command history                                      |
+| `hs`  | `history \| grep`    | Use grep to search your command history                          |
+| `hsi` | `history \| grep -i` | Use grep to do a case-insensitive search of your command history |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/history/history.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/history/history.plugin.zsh
new file mode 100644 (file)
index 0000000..9cee48f
--- /dev/null
@@ -0,0 +1,3 @@
+alias h='history'
+alias hs='history | grep'
+alias hsi='history | grep -i'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/.gitignore b/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/.gitignore
new file mode 100644 (file)
index 0000000..63c2b54
--- /dev/null
@@ -0,0 +1 @@
+fortunes/hitchhiker.dat
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/README.md
new file mode 100644 (file)
index 0000000..d12a1e9
--- /dev/null
@@ -0,0 +1,44 @@
+# hitchhiker
+
+This plugin adds quotes from The Hitchhiker's Guide to the Galaxy, from Douglas Adams.
+
+To use it, add `hitchhiker` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... hitchhiker)
+```
+
+## Aliases
+
+- `hitchhiker`: displays a quote from the book using `fortune`.
+- `hitchhiker_cow`: displays a quote from the book using `cowthink`.
+
+```console
+$ hitchhiker_cow
+ _______________________________________
+( "OK, so ten out of ten for style, but )
+( minus several million for good        )
+( thinking, yeah? "                     )
+ ---------------------------------------
+        o   ^__^
+         o  (oo)\_______
+            (__)\       )\/\
+                ||----w |
+                ||     ||
+```
+
+## Requirements
+
+- `fortune` and `strfile`.
+- `cowthink` if using the `hitchhiker_cow` command.
+
+## Credits
+
+Fortune file: Andreas Gohr <andi@splitbrain.org> ([splitbrain.org](https://www.splitbrain.org/projects/fortunes/hg2g))
+
+Spelling and formatting fixes: grok@resist.ca
+
+Original quotes from:
+
+- https://web.archive.org/web/20120106083254/http://tatooine.fortunecity.com/vonnegut/29/hitch/parhaat.html
+- https://web.archive.org/web/20011112065737/http://www-personal.umd.umich.edu/~nhughes/dna/faqs/quotedir.html
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/fortunes/hitchhiker b/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/fortunes/hitchhiker
new file mode 100644 (file)
index 0000000..825b86c
--- /dev/null
@@ -0,0 +1,275 @@
+"`...You hadn't exactly gone out of your way to call attention to them had you? I mean like actually telling anyone or anything.' `But the plans were on display...' `On display? I eventually had to go down to the cellar to find them.' `That's the display department.' `With a torch.' `Ah, well the lights had probably gone.' `So had the stairs.' `But look you found the notice didn't you?' `Yes,' said Arthur, `yes I did. It was on display in the bottom of a locked filing cabinet stuck in a disused lavatory with a sign on the door saying "Beware of The Leopard".'"
+
+- Arthur singing the praises of the local council planning department.
+%
+"`Time is an illusion. Lunchtime doubly so.' `Very deep,' said Arthur, `you should send that in to the "Reader's Digest". They've got a page for people like you.'"
+
+- Ford convincing Arthur to drink three pints in ten minutes at lunchtime.
+%
+"`This must be Thursday,' said Arthur to himself, sinking low over his beer, `I never could get the hang of Thursdays.'"
+
+- Arthur, on what was to be his last Thursday on Earth.
+%
+"Pages one and two [of Zaphod's presidential speech] had been salvaged by a Damogran Frond Crested Eagle and had already become incorporated into an extraordinary new form of nest which the eagle had invented. It was constructed largely of papier mache and it was virtually impossible for a newly hatched baby eagle to break out of it. The Damogran Frond Crested Eagle had heard of the notion of survival of the species but wanted no truck with it."
+
+- An example of Damogran wildlife.
+%
+"`How do you feel?' he asked him. `Like a military academy,' said Arthur, `bits of me keep passing out.'" .... `We're safe,' he said. `Oh good,' said Arthur. `We're in a small galley cabin,' said Ford, `in one of the spaceships of the Vogon Constructor Fleet.' `Ah,' said Arthur, `this is obviously some strange usage of the word "safe" that I wasn't previously aware of.'
+
+- Arthur after his first ever teleport ride.
+%
+"`The best way to get a drink out of a Vogon is to stick your finger down his throat...'"
+
+- The Book, on one of the Vogon's social inadequacies.
+%
+"`You'd better be prepared for the jump into hyperspace. It's unpleasantly like being drunk.' `What's so unpleasant about being drunk?' `You ask a glass of water.'"
+
+- Arthur getting ready for his first jump into hyperspace.
+%
+"`You know,' said Arthur, `it's at times like this, when I'm trapped in a Vogon airlock with a man from Betelgeuse, and about to die from asphyxiation in deep space that I really wish I'd listened to what my mother told me when I was young.' `Why, what did she tell you?' `I don't know, I didn't listen.'"
+
+- Arthur coping with certain death as best as he could.
+%
+"`Ford, you're turning into a penguin. Stop it.'"
+
+- Arthur experiences the improbability drive at work.
+%
+"`I think you ought to know that I'm feeling very depressed.'" "`Life, don't talk to me about life.'" "`Here I am, brain the size of a planet and they ask me to take you down to the bridge. Call that "job satisfaction"? 'Cos I don't.'" "`I've got this terrible pain in all the diodes down my left side.'"
+
+- Guess who.
+%
+"`If there's anything more important than my ego around, I want it caught and shot now.'"
+
+- Zaphod.
+%
+"`In those days spirits were brave, the stakes were high, men were REAL men, women were REAL women, and small furry creatures from Alpha Centauri were REAL small furry creatures from Aplha Centauri.'"
+
+- The Book getting all nostalgic.
+%
+"`Hey this is terrific!' Zaphod said. `Someone down there is trying to kill us!' `Terrific,' said Arthur. `But don't you see what this means?' `Yes. We are going to die.' `Yes, but apart from that.' `APART from that?' `It means we must be on to something!' `How soon can we get off it?'"
+
+- Zaphod and Arthur in a certain death situation over Magrathea.
+%
+"And wow! Hey! What's this thing coming towards me very fast? Very very fast. So big and flat and round, it needs a big wide sounding word like... ow... ound... round... ground! That's it! That's a good name - ground! I wonder if it will be friends with me?"
+
+- For the sperm whale, it wasn't.
+%
+"Oh no, not again."
+
+- A bowl of petunias on it's way to certain death.
+%
+"`Er, hey Earthman...' `Arthur,' said Arthur. `Yeah, could you just sort of keep this robot with you and guard this end of the passageway. OK?' `Guard?' said Arthur. `What from? You just said there's no one here.' `Yeah, well, just for safety, OK?' said Zaphod. `Whose? Yours or mine?'"
+
+- Arthur drawing the short straw on Magrathea.
+%
+"There are of course many problems connected with life, of which some of the most popular are `Why are people born?' `Why do they die?' `Why do they spend so much of the intervening time wearing digital watches?'"
+
+- The Book.
+%
+"`Right,' said Ford, `I'm going to have a look.' He glanced round at the others. `Is no one going to say, "No you can't possibly, let me go instead"?' They all shook their heads. `Oh well.'"
+
+- Ford attempting to be heroic whilst being seiged by Shooty and Bangbang.
+%
+"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." - The Book just recapping what happened in the last book. "`I am so amazingly cool you could keep a side of meat in me for a month. I am so hip I have difficulty seeing over my pelvis.'"
+
+- Zaphod being cool.
+%
+"`You ARE Zaphod Beeblebrox?' `Yeah,' said Zaphod, `but don't shout it out or they'll all want one.' `THE Zaphod Beeblebrox?' `No, just A Zaphod Bebblebrox, didn't you hear I come in six packs?' `But sir,' it squealed, `I just heard on the sub-ether radio report. It said you were dead...' `Yeah, that's right, I just haven't stopped moving yet.'"
+
+- Zaphod and the Guide's receptionist.
+%
+"The fronting for the eighty-yard-long marble-topped bar had been made by stitching together nearly twenty thousand Antarean Mosaic Lizard skins, despite the fact that the twenty thousand lizards concerned had needed them to keep their insides in."
+
+- The Book decribing Milliways' politically incorrect decor.
+%
+"`...and the Universe,' continued the waiter, determined not to be deflected on his home stretch, `will explode later for your pleasure.' Ford's head swivelled slowly towards him. He spoke with feeling. `Wow,' he said, `What sort of drinks do you serve in this place?' The waiter laughed a polite little waiter's laugh. `Ah,' he said, `I think sir has perhaps misunderstood me.' `Oh, I hope not,' breathed Ford."
+
+- Ford in paradise.
+%
+"Zaphod grinned two manic grins, sauntered over to the bar and bought most of it."
+
+- Zaphod in paradise.
+%
+"`Maybe somebody here tipped off the Galactic Police,' said Trillian. `Everybody saw you come in.' `You mean they want to arrest me over the phone?' said Zaphod, `Could be. I'm a pretty dangerous dude when I'm cornered.' `Yeah,' said a voice from under the table [Ford's now completely rat-arsed at this point], `you go to pieces so fast people get hit by the shrapnel.'"
+
+- Zaphod getting paranoid over a phone call.
+%
+"`Hand me the rap-rod, Plate Captain.' The little waiter's eyebrows wandered about his forehead in confusion. `I beg your pardon, sir?' he said. `The phone, waiter,' said Zaphod, grabbing it off him. `Shee, you guys are so unhip it's a wonder your bums don't fall off.'"
+
+- Zaphod discovers that waiters are the least hip people in the Universe.
+%
+"The main reception foyer was almost empty but Ford nevertheless weaved his way through it."
+
+- Ford making his way out of Milliways whilst under the influence of enough alcohol to make a rhino sing.
+%
+"`The first ten million years were the worst,' said Marvin, `and the second ten million, they were the worst too. The third ten million I didn't enjoy at all. After that I went into a bit of a decline.'"
+
+- Marvin reflecting back on his 576,000,003,579 year career as Milliways' car park attendent.
+%
+"`Incidentally,' he said, `what does teleport mean?' Another moment passed. Slowly, the others turned to face him. `Probably the wrong moment to ask,' said Arthur, `It's just I remember you use the word a short while ago and I only bring it up because...' `Where,' said Ford quietly, `does it say teleport?' `Well, just over here in fact,' said Arthur, pointing at a dark control box in the rear of the cabin, `Just under the word "emergency", above the word "system" and beside the sign saying "out of order".'"
+
+- Arthur finding an escape route from a certain death situation.
+%
+"I teleported home one night With Ron and Sid and Meg. Ron stole Meggie's heart away And I got Sidney's leg."
+
+- A poem about matter transference beams.
+%
+"Anyone who is capable of getting themselves made President should on no account be allowed to do the job."
+
+- Some wisdom from The Book.
+%
+"`We've got to find out what people want from fire, how they relate to it, what sort of image it has for them.' The crowd were tense. They were expecting something wonderful from Ford. `Stick it up your nose,' he said. `Which is precisely the sort of thing we need to know,' insisted the girl, `Do people want fire that can be fitted nasally?'"
+
+- Ford "debating" what to do with fire with a marketing girl.
+%
+"The story goes that I first had the idea for THHGTTG while lying drunk in a field in Innsbruck (or `Spain' as the BBC TV publicity department authoritatively has it, probably because it's easier to spell)." - Foreward by DNA.
+
+FORD   Six pints of bitter. And quickly please, the world's about to   end. BARMAN     Oh yes, sir? Nice weather for it.
+%
+BOOK   Meanwhile, the starship has landed on the surface of Magrathea  and Trillian is about to make one of the most important         statements of her life. Its importance is not immediately       recognised by her companions. TRILL.    Hey, my white mice have escaped. ZAPHOD Nuts to your white mice.
+%
+BOOK   ...Man had always assumed that he was more intelligent than     dolphins because he had achieved so much... the wheel, New York,        wars, and so on, whilst all the dolphins had ever done was muck         about in the water having a good time. But conversely the       dolphins believed themselves to be more intelligent than man for        precisely the same reasons.
+%
+ARTHUR What is an Algolian Zylatburger anyway? FORD    They're a kind of meatburger made from the most unpleasant parts        of a creature well known for its total lack of any pleasant     parts. ARTHUR   So you mean that the Universe does actually end not with a bang         but with a Wimpy?
+
+- Cut dialogue from Fit the Fifth.
+%
+BOOK   There is a theory which states that if ever anyone discovers    exactly what the Universe is for and why it is here, it will    instantly disappear and be replaced by something even more      bizarrely inexplicable.         There is another theory which states that this has already happened.
+
+- Introduction to Fit the Seventh.
+%
+FORD   Tell me Arthur... ARTHUR        Yes? FORD       This boulder we're stuck under, how big would you say it was? Roughly? ARTHUR   Oh, about the size of Coventry Cathedral. FORD  Do you think we could move it? (Arthur doesn't reply) Just asking.
+
+- Ford and Arthur in a tricky situation, Fit the Eighth.
+%
+BOOK   What to do if you find yourself stuck in a crack in the ground  underneath a giant boulder you can't move, with no hope of      rescue. Consider how lucky you are that life has been good to   you so far. Alternatively, if life hasn't been good to you so   far, which given your current circumstances seems more likely,  consider how lucky you are that it won't be troubling you much  longer.
+
+- Comforting advice for Ford and Arthur in this current situation, Fit the Eighth.
+%
+ZAPHOD Hey, this rock... FORD  Marble... ZAPHOD        Marble... FORD  Ice-covered marble... ZAPHOD    Right... it's as slippery as... as... What's the slipperiest    thing you can think of? FORD    At the moment? This marble. ZAPHOD      Right. This marble is as slippery as this marble.
+
+- Zaphod and Ford trying to get a grip on things in Brontitall, Fit the Tenth.
+%
+ARTHUR It's not a question of whose habitat it is, it's a      question of how hard you hit it.
+
+- Arthur pointing out one of the disadvantages of gravity, Fit the Tenth.
+%
+ARTHUR It probably seems a terrible thing to say, but you      know what I sometimes think would be useful in these situations? LINT.  What? ARTHUR    A gun of some sort. LINT.2      Will this help? ARTHUR  What is it? LINT.2      A gun of some sort. ARTHUR      Oh, that'll help. Can you make it fire? LINT.   Er... F/X       DEAFENING ROAR LINT.    Yes.
+
+- Arthur and the Lintillas gaining the upper hand, Fit the Twelfth.
+%
+"He stood up straight and looked the world squarely in the fields and hills. To add weight to his words he stuck the rabbit bone in his hair. He spread his arms out wide. `I will go mad!' he announced."
+
+- Arthur discovering a way of coping with life on Prehistoric Earth.
+%
+"`... then I decided that I was a lemon for a couple of weeks. I kept myself amused all that time jumping in and out of a gin and tonic.' Arthur cleared his throat, and then did it again. `Where,' he said, `did you...?' `Find a gin and tonic?' said Ford brightly. `I found a small lake that thought it was a gin and tonic, and jumped in and out of that. At least, I think it thought it was a gin and tonic.' `I may,' he addded with a grin which would have sent sane men scampering into the trees, `have been imagining it.'"
+
+- Ford updating Arthur about what he's been doing for the past four years.
+%
+"`Eddies,' said Ford, `in the space-time continuum.' `Ah,' nodded Arthur, `is he? Is he?'"
+
+- Arthur failing in his first lesson of galactic physics in four years.
+%
+"Ford grabbed him by the lapels of his dressing gown and spoke to him as slowly and distinctly and patiently as if he were somebody from a telephone company accounts department."
+
+- Ford trying to rectify that situation.
+%
+"...[Arthur] leapt to his feet like an author hearing the phone ring..."
+
+- Who says that the character of Arthur isn't autobiographical?
+%
+"Arthur's consciousness approached his body as from a great distance, and reluctantly. It had had some bad times in there. Slowly, nervously, it entered and settled down into its accustomed position. Arthur sat up. `Where am I?' he said. `Lord's Cricket Ground,' said Ford. `Fine,' said Arthur, and his consciousness stepped out again for a quick breather. His body flopped back on the grass."
+
+- Arthur coping with his return to Earth as best as he could.
+%
+"`A curse,' said Slartibartfast, `which will engulf the Galaxy in fire and destruction, and possibly bring the Universe to a premature doom. I mean it,' he added. `Sounds like a bad time,' said Ford, `with luck I'll be drunk enough not to notice.'"
+
+- Ford ensuring everyone knew where his priorities lay.
+%
+"`My doctor says that I have a malformed public-duty gland and a natural deficiency in moral fibre, and that I am therefore excused from saving Universes.'"
+
+- Ford's last-ditch attempt to get out of helping Slartibartfast.
+%
+"Trillian did a little research in the ship's copy of THHGTTG. It had some advice to offer on drunkenness. `Go to it,' it said, `and good luck.' It was cross-referenced to the entry concerning the size of the Universe and ways of coping with that."
+
+- One of the more preferable pieces of advice contained in the Guide.
+%
+"His eyes seemed to be popping out of his head. He wasn't certain if this was because they were trying to see more clearly, or if they simply wanted to leave at this point."QUOTEHERESTRINGMAGIC1234- Arthur trying to see who had diverted him from going to a party.
+%
+"Arthur yawed wildly as his skin tried to jump one way and his skeleton the other, whilst his brain tried to work out which of his ears it most wanted to crawl out of. `Bet you weren't expecting to see me again,' said the monster, which Arthur couldn't help thinking was a strange remark for it to make, seeing as he had never met the creature before. He could tell that he hadn't met the creature before from the simple fact that he was able to sleep at nights."QUOTEHERESTRINGMAGIC1234- Arthur discovering who had diverted him from going to a party.
+%
+"`That young girl is one of the least benightedly unintelligent organic life forms it has been my profound lack of pleasure not to be able to avoid meeting.'"QUOTEHERESTRINGMAGIC1234- Marvin's first ever compliment about anybody.
+%
+"Arthur hoped and prayed that there wasn't an afterlife. Then he realised there was a contradiction there and merely hoped that there wasn't an afterlife."QUOTEHERESTRINGMAGIC1234- Arthur realising that he's in a certain death situation with a supernova bomb that is shaped like a cricket ball.
+%
+"`Credit?' he said. `Aaaargggh...' These two words are usually coupled together in the Old Pink Dog Bar."QUOTEHERESTRINGMAGIC1234- Ford in a spot of bother.
+%
+"`...we might as well start with where your hand is now.' Arthur said, `So which way do I go?' `Down,' said Fenchurch, `on this occasion.' He moved his hand. `Down,' she said, `is in fact the other way.' `Oh yes.'"QUOTEHERESTRINGMAGIC1234- Arthur trying to discover which part of Fenchurch is wrong.
+%
+"There was a point to this story, but it has temporarily escaped the chronicler's mind."QUOTEHERESTRINGMAGIC1234- This line perhaps best sums up the whole book.
+%
+"The last time anybody made a list of the top hundred character attributes of New Yorkers, common sense snuck in at number 79. .... When it's fall in New York, the air smells as if someone's been frying goats in it, and if you are keen to breathe the best plan is to open a window and stick your head in a building."QUOTEHERESTRINGMAGIC1234- Nuff said??
+%
+"`What's been happening here?' he demanded. `Oh just the nicest things, sir, just the nicest things. can I sit on your lap please?'" "`Colin, I am going to abandon you to your fate.' `I'm so happy.'" "`It will be very, very nasty for you, and that's just too bad. Got it?' `I gurgle with pleasure.'"QUOTEHERESTRINGMAGIC1234- Ford and Colin the robot.
+%
+"What the hell, he thought, you're only young once, and threw himself out of the window. That would at least keep the element of surprise on his side."QUOTEHERESTRINGMAGIC1234- Ford outwitting a Vogon with a rocket launcher by going into another certain death situation.
+%
+"The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong goes wrong it usually turns out to be impossible to get at or repair."QUOTEHERESTRINGMAGIC1234- One of the laws of computers and programming revealed.
+%
+"`You know they've reintroduced the death penalty for insurance company directors?' `Really?' said Arthur. `No I didn't. For what offence?' Trillian frowned. `What do you mean, offence?' `I see.'"QUOTEHERESTRINGMAGIC1234- Evidence that there will be some justice in the Universe eventually.
+%
+"`She hit me on the head with the rock again.' `I think I can confirm that that was my daughter.' `Sweet kid.' `You have to get to know her,' said Arthur. `She eases up does she?' `No,' said Arthur, `but you get a better sense of when to duck.'"QUOTEHERESTRINGMAGIC1234- Ford and Arthur on Random.
+%
+"Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun. "
+%
+"Ah, " said Arthur, "this is obviously some strange usage of the word safe that I wasn't previously aware of. "
+%
+"I don't know, " said the voice on the PA, "apathetic bloody planet, I've no sympathy at all. "
+%
+"Now it is such a bizarrely improbable coincidence that anything so mindboggingly useful could have evolved purely by chance that some thinkers have chosen to see it as the final and clinching proof of the non-existence of God. "The argument goes something like this: `I refuse to prove that I exist,' says God, `for proof denies faith, and without faith I am nothing.' "`But,' says Man, `The Babel fish is a dead giveaway, isn't it? It could not have evolved by chance. It proves you exist, and so therefore, by your own arguments, you don't. QED.'
+%
+"Prostetnic Vogon Jeltz smiled very slowly. This was done not so much for effect as because he was trying to remember the sequence of muscle movements. "
+%
+"OK, so ten out of ten for style, but minus several million for good thinking, yeah? "
+%
+"In those days spirits were brave, the stakes were high, men were real men, women were real women, and small furry creatures from Alpha Centauri were real small furry creatures from Alpha Centauri. "
+%
+"For a moment, nothing happened. Then, after a second or so, nothing continued to happen. "
+%
+(aikamuotojen k�ytt� aikamatkustuksessa) "You can arrive (mayan arivan on-when) for any sitting you like without prior (late fore-when) reservation because you can book retrospectively, as it were when you return to your own time. (you can have on-book haventa forewhen presooning returningwenta retrohome.) "
+%
+"The suit into which the man's body had been stuffed looked as if it's only purpose in life was to demonstrate how difficult it was to get this sort of body into a suit. "
+%
+"He dropped his voice still lower. In the stillness, a fly would not have dared clear its throat. "
+%
+"And finally, " said Max, quieting the audience down and putting on his solemn face, "finally I believe we have with us here tonight, a party of believers, very devout believers, from the Church of the Second Coming of the Great Prophet Zarquon. " ... "There they are, " said Max, "sitting there, patiently. He said he'd come again, and he's kept you waiting a long time, so let's hope he's hurrying fellas, because he's only got eight minutes left! "
+%
+"As he came into the light they could see his black and gold uniform on which the buttons were so highly polished that they shone with an intensity that would have made an approaching motorist flash his lights in annoyance. "
+%
+"You're very sure of your facts, " he said at last, "I couldn't trust the thinking of a man who takes the Universe - if there is one - for granted. "
+%
+"What are you talking about? " "Never mind, eat the fruit. " "You know, this place almost looks like the Garden of Eden. " "Eat the fruit. " "Sounds quite like it too. "
+%
+"Rome wasn't burned in a day. "
+%
+"Does it worry you that you don't talk any kind of sense? "
+%
+"One's never alone with a rubber duck. "
+%
+"Another world, another day, another dawn. "
+%
+"He expanded his chest to make it totally clear that here was the sort of man you only dared to cross if you had a team of Sherpas with you. "
+%
+"It was real. At least, if it wasn't real, it did support them, and as that is what sofas are supposed to do, this, by any test that mattered, was a real sofa. "
+%
+Arthur said, "So which way do I go? " "Down, " said Fenchurch, "on this occasion. " He moved his hand. "Down, " she said, "is in fact the other way. " "Oh yes. "
+%
+"You're one hundred percent positive that the ship which is crashed on the bottom of this ocean is the ship which you said you were one hundred percent positive could one hundred percent positively never crash? "
+%
+"Yes, it's the right planet, all right, " he said again. "Right planet, wrong universe. "
+%
+"Ford had his own code of ethics. It wasn't much of one, but it was his and he stuck by it, more or less. One rule he made was never to buy his own drinks. He wasn't sure if that counted as an ethic, but you have to go with what you've got. "
+%
+"Arthur felt at a bit of a loss. There was a whole Galaxy of stuff out there for him, and he wondered if it was churlish of him to complain to himself that it lacked just two things: the world he was born on and the woman he loved. "
+%
+"What was the self-sacrifice? " "I jettisoned half of a much loved and I think irreplaceable pair of shoes. " "Why was that self-sacrifice? " "Because they were mine! " said Ford crossly. "I think we have different value systems. " "Well mine's better. " "That's according to your... oh never mind. " 
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/hitchhiker.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/hitchhiker/hitchhiker.plugin.zsh
new file mode 100644 (file)
index 0000000..0b1a301
--- /dev/null
@@ -0,0 +1,28 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+HITCHHIKER_DIR="${0:h}/fortunes"
+
+# Aliases
+alias hitchhiker="fortune -a $HITCHHIKER_DIR"
+alias hitchhiker_cow="hitchhiker | cowthink"
+
+() {
+  # Don't generate hitchhiker.dat if it exists and is up-to-date
+  if [[ -f "$HITCHHIKER_DIR/hitchhiker.dat" ]] && ! [[ "$HITCHHIKER_DIR/hitchhiker.dat" -ot "$HITCHHIKER_DIR/hitchhiker" ]]; then
+    return
+  fi
+
+  # If strfile is not found: some systems install strfile in /usr/sbin but it's not in $PATH
+  if ! command -v strfile &>/dev/null && ! [[ -f /usr/sbin/strfile ]]; then
+    echo "[oh-my-zsh] hitchhiker depends on strfile, which is not installed" >&2
+    echo "[oh-my-zsh] strfile is often provided as part of the 'fortune' package" >&2
+    return
+  fi
+
+  "${commands[strfile]:-/usr/sbin/strfile}" "$HITCHHIKER_DIR/hitchhiker" "$HITCHHIKER_DIR/hitchhiker.dat" >/dev/null
+}
+
+unset HITCHHIKER_DIR
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hitokoto/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/hitokoto/README.md
new file mode 100644 (file)
index 0000000..3a8758f
--- /dev/null
@@ -0,0 +1,15 @@
+# hitokoto plugin
+
+Displays a random quote taken from [hitokoto.cn](https://v1.hitokoto.cn/)
+
+Created by [Sinrimin](https://github.com/sinrimin)
+
+## Usage
+
+Add the plugin to the plugins array in your zshrc file and restart zsh:
+
+```zsh
+plugins=(... hitokoto)
+```
+
+Then, run `hitokoto` to get a new random quote.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/hitokoto/hitokoto.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/hitokoto/hitokoto.plugin.zsh
new file mode 100644 (file)
index 0000000..e346d18
--- /dev/null
@@ -0,0 +1,18 @@
+if ! (( $+commands[curl] )); then
+  echo "hitokoto plugin needs curl to work" >&2
+  return
+fi
+
+function hitokoto {
+  setopt localoptions nopromptsubst
+
+  # Get hitokoto data
+  local -a data
+  data=("${(ps:\n:)"$(command curl -s --connect-timeout 2 "https://v1.hitokoto.cn" | command jq -j '.hitokoto+"\n"+.from')"}")
+
+  # Exit if could not fetch hitokoto
+  [[ -n "$data" ]] || return 0
+
+  local quote="${data[1]}" author="${data[2]}"
+  print -P "%F{3}${author}%f: “%F{5}${quote}%f”"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/homestead/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/homestead/README.md
new file mode 100644 (file)
index 0000000..4763023
--- /dev/null
@@ -0,0 +1,9 @@
+# Homestead
+
+This plugin provides completion for [Homestead](https://laravel.com/docs/homestead).
+
+To use it add homestead to the plugins array in your zshrc file.
+
+```bash
+plugins=(... homestead)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/homestead/homestead.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/homestead/homestead.plugin.zsh
new file mode 100644 (file)
index 0000000..ea2803d
--- /dev/null
@@ -0,0 +1,10 @@
+# Homestead basic command completion
+_homestead_get_command_list () {
+  homestead --no-ansi | sed -E "1,/(Available|Common) commands/d" | awk '/^ +[a-z]+/ { print $1 }'
+}
+
+_homestead () {
+  compadd `_homestead_get_command_list`
+}
+
+compdef _homestead homestead
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/httpie/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/httpie/README.md
new file mode 100644 (file)
index 0000000..25bdd0c
--- /dev/null
@@ -0,0 +1,14 @@
+# HTTPie plugin
+
+This plugin adds completion for [HTTPie](https://httpie.org), a command line HTTP
+client, a friendlier cURL replacement.
+
+To use it, add `httpie` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... httpie)
+```
+
+It uses completion from [zsh-completions](https://github.com/zsh-users/zsh-completions).
+
+**Maintainer:** [lululau](https://github.com/lululau)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/httpie/_httpie b/stow/oh-my-zsh/.oh-my-zsh/plugins/httpie/_httpie
new file mode 100644 (file)
index 0000000..4d702ef
--- /dev/null
@@ -0,0 +1,181 @@
+#compdef http
+# ------------------------------------------------------------------------------
+# Copyright (c) 2015 Github zsh-users - http://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for httpie 0.7.2  (http://httpie.org)
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Akira Maeda <https://github.com/glidenote>
+#  * Valodim <https://github.com/Valodim>
+#  * Claus Klingberg <https://github.com/cjk>
+#
+# ------------------------------------------------------------------------------
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+# vim: ft=zsh sw=2 ts=2 et
+# ------------------------------------------------------------------------------
+
+_httpie_params () {
+
+    local ret=1 expl
+
+    # or a url
+    if (( CURRENT <= NORMARG+1 )) && [[ $words[NORMARG] != *:* ]] ; then
+        _httpie_urls && ret=0
+
+    # regular param, if we already have a url
+    elif (( CURRENT > NORMARG )); then
+
+        # if the suffix is precisely : this is shorthand for a header
+        if [[ -prefix ':' ]]; then
+            PREFIX=
+            SUFFIX=:
+        fi
+
+        # if we are in front of a : (possibly due to the PREFIX move before)
+        if [[ -suffix ':' ]]; then
+
+            # this is rather buggy with normal tab behavior :\
+            compstate[insert]=menu
+            _wanted http_header expl 'HTTP Header' \
+                compadd -s ':' -S '' -- Content-Type Cookie && return 0
+        fi
+
+        # ignore all prefix stuff
+        compset -P '(#b)([^:@=]#)'
+        local name=$match[1]
+
+        if compset -P '='; then
+            _message "$name data field value"
+        elif compset -P '@'; then
+            _files
+        elif compset -P ':=@'; then
+            _files
+        elif compset -P ':='; then
+            _message "$name raw json data"
+        elif compset -P '=='; then
+            _message "$name url parameter value"
+        elif compset -P ':'; then
+            _message "$name header content"
+        else
+            typeset -a ops
+            ops=(
+                '=:data field'
+                '\::header'
+                '==:request parameter'
+                '@:data file field'
+                '\:=:raw json field'
+                '\:=@:raw json field file path'
+            )
+            _describe -t httpparams "parameter types" ops -Q -S ''
+        fi
+
+        ret=0
+
+    fi
+
+    # first arg may be a request method
+    (( CURRENT == NORMARG )) &&
+        _wanted http_method expl 'Request Method' \
+            compadd GET POST PUT DELETE HEAD OPTIONS TRACE CONNECT PATCH LINK UNLINK && ret=0
+
+    return $ret
+
+}
+
+_httpie_urls() {
+
+  local ret=1
+
+  if ! [[ -prefix [-+.a-z0-9]#:// ]]; then
+    local expl
+    compset -S '[^:/]*' && compstate[to_end]=''
+    _wanted url-schemas expl 'URL schema' compadd -S '' http:// https:// && ret=0
+  else
+    _urls && ret=0
+  fi
+
+  return $ret
+
+}
+
+_httpie_printflags () {
+
+    local ret=1
+
+    # not sure why this is necessary, but it will complete "-pH" style without it
+    [[ $IPREFIX == "-p" ]] && IPREFIX+=" "
+
+    compset -P '(#b)([a-zA-Z]#)'
+
+    local -a flags
+    [[ $match[1] != *H* ]] && flags+=( "H:request headers" )
+    [[ $match[1] != *B* ]] && flags+=( "B:request body" )
+    [[ $match[1] != *h* ]] && flags+=( "h:response headers" )
+    [[ $match[1] != *b* ]] && flags+=( "b:response body" )
+
+    _describe -t printflags "print flags" flags -S '' && ret=0
+
+    return $ret
+
+}
+
+integer NORMARG
+
+_arguments -n -C -s \
+  '(-j --json -f)'{-j,--json}'[Data items from the command line are serialized as a JSON object.]' \
+  '(-f --form -j)'{-f,--form}'[Data items from the command line are serialized as form fields.]' \
+  '--pretty=[Controls output processing.]:output format:(all colors format none)' \
+  '(-s --style)'{-s,--style}'=[Output coloring style]:STYLE:(autumn borland bw colorful default emacs friendly fruity manni monokai murphy native pastie perldoc ttr solarized tango trac vim vs)' \
+  '(-p --print)'{-p,--print}'=[String specifying what the output should contain]:print flags:_httpie_printflags' \
+  '(-v --verbose)'{-v,--verbose}'[Print the whole request as well as the response.]' \
+  '(-p -h --headers)'{-h,--headers}'[Print only the response headers.]' \
+  '(-p -b --body)'{-b,--body}'[Print only the response body.]' \
+  '(-S --stream)'{-S,--stream}'[Always stream the output by line, i.e., behave like `tail -f`.]' \
+  '(-o --output)'{-o,--output}'=[Save output to FILE.]:output file:_files' \
+  '(-d --download)'{-d,--download}'=[Do not print the response body to stdout.]' \
+  '(-c --continue)'{-c,--continue}'[Resume an interrupted download.]' \
+  '(--session-read-only)--session=[Create, or reuse and update a session.]:session name (or path)' \
+  '(--session)--session-read-only=[Create or read a session without updating it form the request/response exchange.]:session name (or path)' \
+  '(-a --auth)'{-a,--auth}'=[If only the username is provided (-a username)]:USER\:PASS' \
+  '--auth-type=[The authentication mechanism to be used. Defaults to "basic".]:AUTH-TYPE:(basic digest)' \
+  '--proxy=[String mapping protocol to the URL of the proxy.]:PROXY' \
+  '--follow[Allow full redirects.]' \
+  "--verify=[Enable or disable verification of ssl certificates.]:verify certificate:(yes no)" \
+  '--allow-redirects[Set this flag if full redirects are allowed (e.g. re-POST-ing of data at new ``Location``)]' \
+  '--timeout=[Float describes the timeout of the request (Use socket.setdefaulttimeout() as fallback).]:timeout (seconds)' \
+  '--check-status[This flag instructs HTTPie to also check the HTTP status code and exit with an error if the status indicates one.]' \
+  '--ignore-stdin[Do not attempt to read stdin.]' \
+  '(- *)--help[show help message.]' \
+  "(- *)--version[show program's version number and exit.]" \
+  '--traceback[Prints exception traceback should one occur.]' \
+  '--debug[Prints exception traceback should one occur and other information useful for debugging HTTPie itself.]' \
+  '*:args:_httpie_params' && return 0
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/invoke/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/invoke/README.md
new file mode 100644 (file)
index 0000000..3f4b880
--- /dev/null
@@ -0,0 +1,10 @@
+# Invoke plugin
+
+This plugin adds completion for [invoke](https://github.com/pyinvoke/invoke).
+
+To use it, add `invoke` to the plugins array in your `~/.zshrc` file:
+
+```zsh
+plugins=(... invoke)
+```
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/invoke/invoke.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/invoke/invoke.plugin.zsh
new file mode 100644 (file)
index 0000000..8c807de
--- /dev/null
@@ -0,0 +1,5 @@
+# Autocompletion for invoke.
+#
+if [ $commands[invoke] ]; then
+  source <(invoke --print-completion-script=zsh)
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ionic/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ionic/README.md
new file mode 100644 (file)
index 0000000..3ec4fc8
--- /dev/null
@@ -0,0 +1,30 @@
+# Ionic plugin
+
+This plugin adds completion for the [Ionic CLI](https://ionicframework.com/docs/cli),
+as well as some aliases for common Ionic commands.
+
+To use it, add `ionic` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ionic)
+```
+
+## Aliases
+
+| Alias | Command                              | Description                                                      |
+|-------|--------------------------------------|------------------------------------------------------------------|
+| iv    | `ionic --version`                    | Check Ionic version                                              |
+| ih    | `ionic --help`                       | Ionic help command                                               |
+| ist   | `ionic start`                        | Create a new project                                             |
+| ii    | `ionic info`                         | Print system/environment info                                    |
+| is    | `ionic serve`                        | Start a local dev server for app dev/testing                     |
+| icba  | `ionic cordova build android`        | Build web assets and prepare app for android platform targets    |
+| icbi  | `ionic cordova build ios`            | Build web assets and prepare app for ios platform targets        |
+| icra  | `ionic cordova run android`          | Run an Ionic project on a connected android device               |
+| icri  | `ionic cordova run ios`              | Run an Ionic project on a connected ios device                   |
+| icrsa | `ionic cordova resources android`    | Automatically create icon and splash screen resources for android|
+| icrsi | `ionic cordova resources ios`        | Automatically create icon and splash screen resources for ios    |
+| icpaa | `ionic cordova platform add android` | Add Cordova android platform targets                             |
+| icpai | `ionic cordova platform add ios`     | Add Cordova ios platform targets                                 |
+| icpra | `ionic cordova platform rm android`  | Remove Cordova platform targets                                  |
+| icpri | `ionic cordova platform rm ios`      | Remove Cordova platform targets                                  |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ionic/ionic.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ionic/ionic.plugin.zsh
new file mode 100644 (file)
index 0000000..cf388af
--- /dev/null
@@ -0,0 +1,15 @@
+alias iv="ionic --version"
+alias ih="ionic --help"
+alias ist="ionic start"
+alias ii="ionic info"
+alias is="ionic serve"
+alias icba="ionic cordova build android" 
+alias icbi="ionic cordova build ios" 
+alias icra="ionic cordova run android" 
+alias icri="ionic cordova run ios" 
+alias icrsa="ionic cordova resources android" 
+alias icrsi="ionic cordova resources ios"
+alias icpaa="ionic cordova platform add android" 
+alias icpai="ionic cordova platform add ios"
+alias icpra="ionic cordova platform rm android"
+alias icpri="ionic cordova platform rm ios"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/LICENSE b/stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/LICENSE
new file mode 100644 (file)
index 0000000..cf84491
--- /dev/null
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Angel Ramboi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/README.md
new file mode 100644 (file)
index 0000000..0808a26
--- /dev/null
@@ -0,0 +1,17 @@
+# zsh-ipfs
+
+zsh completion plugin for [The InterPlanetary File System (IPFS)][1]
+
+Please submit issues and pull requests to the [main zsh-ipfs repo][2].
+
+### About
+
+[IPFS (InterPlanetary File System)][1] is a peer-to-peer hypermedia protocol
+designed to make the web faster, safer, and more open.
+
+### License
+
+See: https://github.com/hellounicorn/zsh-ipfs/blob/master/LICENSE
+
+[1]: http://ipfs.io/
+[2]: https://github.com/hellounicorn/zsh-ipfs
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/_ipfs b/stow/oh-my-zsh/.oh-my-zsh/plugins/ipfs/_ipfs
new file mode 100644 (file)
index 0000000..8771bc4
--- /dev/null
@@ -0,0 +1,791 @@
+#compdef ipfs
+#autoload
+
+local -a _1st_arguments
+_1st_arguments=(
+  'add:Add a file or directory to ipfs.'
+  'bitswap:Interact with the bitswap agent.'
+  'block:Interact with raw IPFS blocks.'
+  'bootstrap:Show or edit the list of bootstrap peers.'
+  'cat:Show IPFS object data.'
+  'cid:Convert and discover properties of CIDs'
+  'commands:List all available commands.'
+  'config:Get and set ipfs config values.'
+  'daemon:Run a network-connected IPFS node.'
+  'dag:Interact with ipld dag objects. (experimental)'
+  'dht:Issue commands directly through the DHT.'
+  'diag:Generate diagnostic reports.'
+  'dns:Resolve DNS links.'
+  'files:Interact with unixfs files.'
+  'filestore:Interact with filestore objects. (experimental)'
+  'get:Download IPFS objects.'
+  'id:Show ipfs node id info.'
+  'init:Initializes ipfs config file.'
+  'key:Create and list IPNS name keypairs.'
+  'log:Interact with the daemon log output.'
+  'ls:List directory contents for Unix filesystem objects.'
+  'mount:Mounts IPFS to the filesystem (read-only).'
+  'name:Publish and resolve IPNS names.'
+  'object:Interact with IPFS objects.'
+  'p2p:Libp2p stream mounting.'
+  'pin:Pin (and unpin) objects to local storage.'
+  'ping:Send echo request packets to IPFS hosts.'
+  'refs:List links (references) from an object.'
+  'repo:Manipulate the IPFS repo.'
+  'resolve:Resolve the value of names to IPFS.'
+  'stats:Query IPFS statistics.'
+  'swarm:Interact with the swarm.'
+  'tar:Utility functions for tar files in ipfs.'
+  'update:Download and apply go-ipfs updates'
+  'version:Show ipfs version information.'
+)
+
+_ipfs_subcommand(){
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+  _arguments -C ':command:->command' '*::options:->options'
+  case $state in
+    (command)
+      _describe -t commands "ipfs subcommand" $1
+      return
+    ;;
+    (options)
+      case $line[1] in
+        (wantlist)
+          case $MAIN_SUBCOMMAND in
+            (bitswap)
+              _arguments '(-p --peer)'{-p,--peer}'[Specify which peer to show wantlist for. Default: self.]'
+            ;;
+          esac
+        ;;
+        (add)
+          case $MAIN_SUBCOMMAND in
+            (pin)
+              _arguments \
+                '(-r --recursive)'{-r,--recursive}'[Recursively pin the object linked to by the specified object(s). Default: true.]' \
+                '--progress[Show progress.]'
+            ;;
+            (bootstrap)
+              local -a _bootstrap_rm_arguments
+              _bootstrap_rm_arguments=(
+                'default:Add default peers to the bootstrap list.'
+              )
+              _ipfs_subcommand _bootstrap_rm_arguments
+            ;;
+          esac
+        ;;
+        (rm)
+          case $MAIN_SUBCOMMAND in
+            (pin)
+              _arguments '(-r --recursive)'{-r,--recursive}'[Recursively unpin the object linked to by the specified object(s). Default: true.]'
+            ;;
+            (bootstrap)
+              local -a _bootstrap_rm_arguments
+              _bootstrap_rm_arguments=(
+                'all:Remove all peers from the bootstrap list.'
+              )
+              _ipfs_subcommand _bootstrap_rm_arguments
+            ;;
+          esac
+        ;;
+        (ls)
+          case $MAIN_SUBCOMMAND in
+            (pin)
+              _arguments \
+                '(-t --type)'{-t,--type}'[The type of pinned keys to list. Can be "direct", "indirect", "recursive", or "all". Default: all.]' \
+                '(-q --quiet)'{-q,--quiet}'[Write just hashes of objects.]' \
+                '(-s --stream)'{-s,--stream}'[Enable streaming of pins as they are discovered.]'
+            ;;
+            (p2p)
+              _arguments '(-v --headers)'{-v,--headers}'[Print table headers (Protocol, Listen, Target).]'
+            ;;
+          esac
+        ;;
+        (update)
+          case $MAIN_SUBCOMMAND in
+            (pin)
+              _arguments '--unpin[Remove the old pin. Default: true.]'
+            ;;
+          esac
+        ;;
+        (verify)
+          case $MAIN_SUBCOMMAND in
+            (pin)
+              _arguments \
+                '--verbose[Also write the hashes of non-broken pins.]' \
+                '(-q --quiet)'{-q,--quiet}'[Write just hashes of broken pins.]'
+            ;;
+          esac
+        ;;
+        (query|findpeer)
+          case $MAIN_SUBCOMMAND in
+            (dht)
+              _arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
+            ;;
+          esac
+        ;;
+        (get)
+          case $MAIN_SUBCOMMAND in
+            (dht)
+              _arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
+            ;;
+            (object)
+              _arguments '--data-encoding[Encoding type of the data field, either "text" or "base64". Default: text.]'
+            ;;
+          esac
+        ;;
+        (put)
+          case $MAIN_SUBCOMMAND in
+            (dht)
+              _arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
+            ;;
+            (object)
+              _arguments \
+                '--inputenc[Encoding type of input data. One of: {"protobuf", "json"}. Default: json.]' \
+                '--datafieldenc[Encoding type of the data field, either "text" or "base64". Default: text.]' \
+                '--pin[Pin this object when adding.]' \
+                '(-q --quiet)'{-q,--quiet}'[Write minimal output]'
+            ;;
+          esac
+        ;;
+        (findprovs)
+          case $MAIN_SUBCOMMAND in
+            (dht)
+              _arguments \
+                '(-v --verbose)'{-v,--verbose}'[Print extra information.]' \
+                '(-n --num-providers)'{-n,--num-providers}'[The number of providers to find. Default: 20.]'
+            ;;
+          esac
+        ;;
+        (provide)
+          case $MAIN_SUBCOMMAND in
+            (dht)
+              _arguments \
+                '(-v --verbose)'{-v,--verbose}'[Print extra information.]' \
+                '(-r --recursive)'{-r,--recursive}'[Recursively provide entire graph.]'
+            ;;
+          esac
+        ;;
+        (cmds)
+          case $MAIN_SUBCOMMAND in
+            (diag)
+              _arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
+            ;;
+          esac
+        ;;
+        (diff)
+          case $MAIN_SUBCOMMAND in
+            (object)
+              _arguments '(-v --verbose)'{-v,--verbose}'[Print extra information.]'
+            ;;
+          esac
+        ;;
+        (stat)
+          case $MAIN_SUBCOMMAND in
+            (dag)
+              _arguments \
+                '(-p --progress)'{-p,--progress}'[Return progressive data while reading through the DAG. Default: true.]'
+            ;;
+            (object)
+              _arguments '--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
+            ;;
+            (repo)
+              _arguments \
+                '(-s --size-only)'{-s,--size-only}'[Only report RepoSize and StorageMax.]' \
+                '(-H --human)'{-H,--human}'[Print sizes in human readable format (e.g., 1K 234M 2G).]'
+            ;;
+          esac
+        ;;
+        (publish)
+          case $MAIN_SUBCOMMAND in
+            (name)
+              _arguments \
+                '--resolve[Check if the given path can be resolved before publishing. Default: true.]' \
+                '(-t --lifetime)'{-t,--lifetime}'[Time duration that the record will be valid for. Default: 24h.]' \
+                '--allow-offline[When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing.]' \
+                '--ttl[Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental).]' \
+                '(-k --key)'{-k,--key}"[Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'. Default: self.]" \
+                '(-Q --quieter)'{-Q,--quieter}'[Write only final hash.]' \
+                '--ipns-base[Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}. Default: base36.]'
+            ;;
+          esac
+        ;;
+        (pubsub)
+          case $MAIN_SUBCOMMAND in
+            (name)
+              local -a _name_pubsub_arguments
+              _name_pubsub_arguments=(
+                'cancel:Cancel a name subscription'
+                'state:Query the state of IPNS pubsub'
+                'subs:Show current name subscriptions'
+              )
+              _ipfs_subcommand _name_pubsub_arguments
+            ;;
+          esac
+        ;;
+        (resolve)
+          case $MAIN_SUBCOMMAND in
+            (name)
+              _arguments \
+                '(-r --recursive)'{-r,--recursive}'[Resolve until the result is not an IPNS name. Default: true.]' \
+                '(-n --nocache)'{-n,--nocache}'[Do not use cached entries.]' \
+                '(--dhtrc --dht-record-count)'{--dhtrc,--dht-record-count}'[Number of records to request for DHT resolution.]' \
+                '(--dhtt --dht-timeout)'{--dhtt,--dht-timeout}'[Max time to collect values during DHT resolution eg "30s". Pass 0 for no timeout.]' \
+                '(-s --stream)'{-s,--stream}'[Stream entries as they are found.]'
+            ;;
+          esac
+        ;;
+        (patch)
+          case $MAIN_SUBCOMMAND in
+            (object)
+              local -a _object_patch_arguments
+              _object_patch_arguments=(
+                'add-link:Add a link to a given object.'
+                'append-data:Append data to the data segment of a dag node.'
+                'rm-link:Remove a link from a given object.'
+                'set-data:Set the data field of an IPFS object.'
+              )
+              _ipfs_subcommand _object_patch_arguments
+            ;;
+          esac
+        ;;
+        (gc)
+          case $MAIN_SUBCOMMAND in
+            (repo)
+              _arguments \
+                '--stream-errors[Stream errors.]' \
+                '(-q --quiet)'{-q,--quiet}'[Write minimal output.]'
+            ;;
+          esac
+        ;;
+        (bitswap)
+          case $MAIN_SUBCOMMAND in
+            (stats)
+              _arguments \
+                '(-v --verbose)'{-v,--verbose}'[Print extra information.]' \
+                '--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
+            ;;
+          esac
+        ;;
+        (bw)
+          case $MAIN_SUBCOMMAND in
+            (stats)
+              _arguments \
+                '(-p --peer)'{-p,--peer}'[Specify a peer to print bandwidth for.]' \
+                '(-t --proto)'{-t,--proto}'[Specify a protocol to print bandwidth for.]' \
+                '--poll[Print bandwidth at an interval.]' \
+                '(-i --interval)'{-i,--interval}"[Time interval to wait between updating output, if 'poll' is true.]"
+            ;;
+          esac
+        ;;
+        (repo)
+          case $MAIN_SUBCOMMAND in
+            (stats)
+              _arguments \
+                '--size-only[Only report RepoSize and StorageMax.]' \
+                '--human[Print sizes in human readable format (e.g., 1K 234M 2G).]'
+            ;;
+          esac
+        ;;
+        (bases)
+          case $MAIN_SUBCOMMAND in
+            (cid)
+              _arguments \
+                '--prefix[also include the single leter prefixes in addition to the code.]' \
+                '--numeric[also include numeric codes.]'
+            ;;
+          esac
+        ;;
+        (codecs|hashes)
+          case $MAIN_SUBCOMMAND in
+            (cid)
+              _arguments '--numeric[also include numeric codes.]'
+            ;;
+          esac
+        ;;
+        (format)
+          case $MAIN_SUBCOMMAND in
+            (cid)
+              _arguments \
+                '-f[Printf style format string. Default: %s.]' \
+                '-v[CID version to convert to.]' \
+                '--codec[CID codec to convert to.]' \
+                '-b[Multibase to display CID in.]'
+            ;;
+          esac
+        ;;
+        (close)
+          case $MAIN_SUBCOMMAND in
+            (p2p)
+              _arguments \
+                '(-a --all)'{-a,--all}'[Close all listeners.]' \
+                '(-p --protocol)'{-p,--protocol}'[Match protocol name.]' \
+                '(-l --listen-address)'{-l,--listen-address}'[Match listen address.]' \
+                '(-t --target-address)'{-t,--target-address}'[Match target address.]'
+            ;;
+          esac
+        ;;
+        (forward)
+          case $MAIN_SUBCOMMAND in
+            (p2p)
+              _arguments "--allow-custom-protocol[Don't require /x/ prefix.]"
+            ;;
+          esac
+        ;;
+        (listen)
+          case $MAIN_SUBCOMMAND in
+            (p2p)
+              _arguments \
+                "--allow-custom-protocol[Don't require /x/ prefix.]" \
+                '(-r --report-peer-id)'{-r,--report-peer-id}'[Send remote base58 peerid to target when a new connection is established.]'
+            ;;
+          esac
+        ;;
+        (stream)
+          case $MAIN_SUBCOMMAND in
+            (p2p)
+              local -a _p2p_stream_arguments
+              _p2p_stream_arguments=(
+                'close:Close active p2p stream.'
+                'ls:List active p2p streams.'
+              )
+              _ipfs_subcommand _p2p_stream_arguments
+            ;;
+          esac
+        ;;
+        (addrs)
+          case $MAIN_SUBCOMMAND in
+            (swarm)
+              local -a _swarm_addrs_arguments
+              _swarm_addrs_arguments=(
+                'listen:List interface listening addresses.'
+                'local:List local addresses.'
+              )
+              _ipfs_subcommand _swarm_addrs_arguments
+            ;;
+          esac
+        ;;
+        (filters)
+          case $MAIN_SUBCOMMAND in
+            (swarm)
+              local -a _swarm_filters_arguments
+              _swarm_filters_arguments=(
+                'add:Add an address filter.'
+                'rm:Remove an address filter.'
+              )
+              _ipfs_subcommand _swarm_filters_arguments
+            ;;
+          esac
+        ;;
+        (peers)
+          case $MAIN_SUBCOMMAND in
+            (swarm)
+              _arguments \
+                '(-v --verbose)'{-v,--verbose}'[display all extra information.]' \
+                '--streams[Also list information about open streams for each peer.]' \
+                '--latency[Also list information about latency to each peer.]' \
+                '--direction[Also list information about the direction of connection.]'
+            ;;
+          esac
+        ;;
+        (export)
+          case $MAIN_SUBCOMMAND in
+            (dag)
+              _arguments \
+                '(-p --progress)'{-p,--progress}'[Display progress on CLI. Defaults to true when STDERR is a TTY.]'
+            ;;
+            (key)
+              _arguments \
+                '(-o --output)'{-o,--output}'[The path where the output should be stored.]'
+            ;;
+          esac
+        ;;
+        (import)
+          case $MAIN_SUBCOMMAND in
+            (dag)
+              _arguments \
+                '--silent[No output.]' \
+                '--pin-roots[Pin optional roots listed in the .car headers after importing. Default: true.]'
+            ;;
+            (key)
+              _arguments \
+                '--ipns-base[Encoding used for keys: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}. Default: base36.]'
+            ;;
+          esac
+        ;;
+        (remote)
+          case $MAIN_SUBCOMMAND in
+            (pin)
+              local -a _pin_remote_arguments
+              _pin_remote_arguments=(
+                'add:Pin object to remote pinning service.'
+                'ls:List objects pinned to remote pinning service.'
+                'rm:Remove pins from remote pinning service.'
+                'service:Configure remote pinning services.'
+              )
+              _ipfs_subcommand _pin_remote_arguments
+            ;;
+          esac
+        ;;
+      esac
+    ;;
+  esac
+}
+
+local expl
+
+_arguments \
+  '(-c --config)'{-c,--config}'[Path to the configuration file to use.]' \
+  '(-D --debug)'{-D,--debug}'[Operate in debug mode.]' \
+  '(--help)--help[Show the full command help text.]' \
+  '(--h)-h[Show a short version of the command help text.]' \
+  '(-L --local)'{-L,--local}'[Run the command locally, instead of using the daemon. DEPRECATED: use --offline.]' \
+  '(--offline)--offline[Run the command offline.]' \
+  '(--api)--api[Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001).]' \
+  '(--cid-base)--cid-base[Multibase encoding used for version 1 CIDs in output.]' \
+  '(--upgrade-cidv0-in-output)--upgrade-cidv0-in-output[Upgrade version 0 to version 1 CIDs in output.]' \
+  '(--enc --encoding)'{--enc,--encoding}'[The encoding type the output should be encoded with (json, xml, or text). Default: text.]' \
+  '(--stream-channels)--stream-channels[Stream channel output.]' \
+  '(--timeout)--timeout[Set a global timeout on the command.]' \
+  '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "ipfs subcommand" _1st_arguments
+  return
+fi
+
+MAIN_SUBCOMMAND="$words[1]"
+case $MAIN_SUBCOMMAND in
+  (add)
+    _arguments \
+      '(-r --recursive)'{-r,--recursive}'[Add directory paths recursively.]' \
+      '(--dereference-args)--dereference-args[Symlinks supplied in arguments are dereferenced.]' \
+      '(--stdin-name)--stdin-name[Assign a name if the file source is stdin.]' \
+      '(-H --hidden)'{-H,--hidden}'[Include files that are hidden. Only takes effect on recursive add.]' \
+      '(--ignore)--ignore[A rule (.gitignore-stype) defining which file(s) should be ignored (variadic, experimental).]' \
+      '(--ignore-rules-path)--ignore-rules-path[A path to a file with .gitignore-style ignore rules (experimental).]' \
+      '(-q --quiet)'{-q,--quiet}'[Write minimal output.]' \
+      '(-Q --quieter)'{-Q,--quieter}'[Write only final hash.]' \
+      '(--silent)--silent[Write no output.]' \
+      '(-p --progress)'{-p,--progress}'[Stream progress data.]' \
+      '(-t --trickle)'{-t,--trickle}'[Use trickle-dag format for dag generation.]' \
+      '(-n --only-hash)'{-n,--only-hash}'[Only chunk and hash - do not write to disk.]' \
+      '(-w --wrap-with-directory)'{-w,--wrap-with-directory}'[Wrap files with a directory object.]' \
+      '(-s --chunker)'{-s,--chunker}'[Chunking algorithm, size-(bytes) or rabin-(min)-(avg)-(max). Default: size-262144.]' \
+      '(--pin)--pin[Pin this object when adding. Default: true.]' \
+      '(--raw-leaves)--raw-leaves[Use raw blocks for leaf nodes. (experimental).]' \
+      '(--nocopy)--nocopy[Add the file using filestore. Implies raw-leaves. (experimental).]' \
+      '(--fscache)--fscache[Check the filestore for pre-existing blocks. (experimental).]' \
+      '(--cid-version)--cid-version[CID version. Defaults to 0 unless an option that depends on CIDv1 is passed. (experimental).]' \
+      '(--hash)--hash[Hash function to use. Implies CIDv1 if not sha2-256. (experimental). Default: sha2-256.]' \
+      '(--inline)--inline[Inline small blocks into CIDs. (experimental).]' \
+      '(--inline-limit)--inline-limit[Maximum block size to inline. (experimental). Default: 32.]'
+  ;;
+  (bitswap)
+    local -a _bitswap_arguments
+    _bitswap_arguments=(
+      'ledger:Show the current ledger for a peer.'
+      'reprovide:Trigger reprovider.'
+      'stat:Show some diagnostic information on the bitswap agent.'
+      'wantlist:Show blocks currently on the wantlist.'
+    )
+    _ipfs_subcommand _bitswap_arguments
+  ;;
+  (block)
+    local -a _block_arguments
+    _block_arguments=(
+      'get:Get a raw IPFS block.'
+      'put:Store input as an IPFS block.'
+      'rm:Remove IPFS block(s).'
+      'stat:Print information of a raw IPFS block.'
+    )
+    _ipfs_subcommand _block_arguments
+  ;;
+  (bootstrap)
+    local -a _bootstrap_arguments
+    _bootstrap_arguments=(
+      'add:Add peers to the bootstrap list.'
+      'list:Show peers in the bootstrap list.'
+      'rm:Remove peers from the bootstrap list.'
+    )
+    _ipfs_subcommand _bootstrap_arguments
+  ;;
+  (cat)
+    _arguments \
+      '(-o --offset)'{-o,--offset}'[Byte offset to begin reading from.]' \
+      '(-l --length)'{-l,--length}'[Maximum number of bytes to read.]'
+  ;;
+  (cid)
+    local -a _cid_arguments
+    _cid_arguments=(
+      'base32:Convert CIDs to Base32 CID version 1.'
+      'bases:List available multibase encodings.'
+      'codecs:List available CID codecs.'
+      'format:Format and convert a CID in various useful ways.'
+      'hashes:List available multihashes.'
+    )
+    _ipfs_subcommand _cid_arguments
+  ;;
+  (commands)
+    _arguments '(-f --flags)'{-f,--flags}'[Show command flags.]'
+  ;;
+  (config)
+    _arguments \
+      '--bool[Set a boolean value.]' \
+      '--json[Parse stringified JSON.]'
+    local -a _config_arguments
+    _config_arguments=(
+      'edit:Open the config file for editing in $EDITOR.'
+      'profile:Apply profiles to config.'
+      'replace:Replace the config with <file>.'
+      'show:Output config file contents.'
+    )
+    _ipfs_subcommand _config_arguments
+  ;;
+  (daemon)
+    _arguments \
+      '--init[Initialize ipfs with default settings if not already initialized.]' \
+      '--init-config[Path to existing configuration file to be loaded during --init.]' \
+      '--init-profile[Configuration profiles to apply for --init. See ipfs init --help for more.]' \
+      '--routing[Overrides the routing option. Default: default.]' \
+      '--mount[Mounts IPFS to the filesystem.]' \
+      '--writable[Enable writing objects (with POST, PUT and DELETE).]' \
+      '--mount-ipfs[Path to the mountpoint for IPFS (if using --mount). Defaults to config setting.]' \
+      '--mount-ipns[Path to the mountpoint for IPNS (if using --mount). Defaults to config setting.]' \
+      '--unrestricted-api[Allow API access to unlisted hashes.]' \
+      '--disable-transport-encryption[Disable transport encryption (for debugging protocols).]' \
+      '--enable-gc[Enable automatic periodic repo garbage collection.]' \
+      '--manage-fdlimit[Check and raise file descriptor limits if needed. Default: true.]' \
+      '--migrate[If true, assume yes at the migrate prompt. If false, assume no.]' \
+      '--enable-pubsub-experiment[Instantiate the ipfs daemon with the experimental pubsub feature enabled.]' \
+      '--enable-namesys-pubsub[Enable IPNS record distribution through pubsub; enables pubsub.]' \
+      '--enable-mplex-experiment[Add the experimental 'go-multiplex' stream muxer to libp2p on construction. Default: true.]'
+  ;;
+  (dag)
+    local -a _dag_arguments
+    _dag_arguments=(
+      'export:Streams the selected DAG as a .car stream on stdout.'
+      'get:Get a dag node from ipfs.'
+      'import:Import the contents of .car files'
+      'put:Add a dag node to ipfs.'
+      'resolve:Resolve ipld block.'
+      'stat:Gets stats for a DAG'
+    )
+    _ipfs_subcommand _dag_arguments
+  ;;
+  (dht)
+    local -a _dht_arguments
+    _dht_arguments=(
+      'findpeer:Find the multiaddresses associated with a Peer ID.'
+      'findprovs:Find peers that can provide a specific value, given a key.'
+      'get:Given a key, query the routing system for its best value.'
+      'provide:Announce to the network that you are providing given values.'
+      'put:Write a key/value pair to the routing system.'
+      'query:Find the closest Peer IDs to a given Peer ID by querying the DHT.'
+    )
+    _ipfs_subcommand _dht_arguments
+  ;;
+  (diag)
+    local -a _diag_arguments
+    _diag_arguments=(
+      'cmds:List commands run on this IPFS node.'
+      'sys:Print system diagnostic information.'
+    )
+    _ipfs_subcommand _diag_arguments
+  ;;
+  (dns)
+    _arguments '(-r --recursive)'{-r,--recursive}'[Resolve until the result is not a DNS link. Default: true.]'
+  ;;
+  (files)
+    _arguments '(-f --flush)'{-f,--flush}'[Flush target and ancestors after write. Default: true.]'
+    local -a _files_arguments
+    _files_arguments=(
+      'chcid:Change the cid version or hash function of the root node of a given path.'
+      'cp:Copy files into mfs.'
+      "flush:Flush a given path's data to disk."
+      'ls:List directories in the local mutable namespace.'
+      'mkdir:Make directories.'
+      'mv:Move files.'
+      'read:Read a file in a given mfs.'
+      'rm:Remove a file.'
+      'stat:Display file status.'
+      'write:Write to a mutable file in a given filesystem.'
+    )
+    _ipfs_subcommand _files_arguments
+  ;;
+  (filestore)
+    local -a _filestore_arguments
+    _filestore_arguments=(
+      'dups:List blocks that are both in the filestore and standard block storage.'
+      'ls:List objects in filestore.'
+      'verify:Verify objects in filestore.'
+    )
+    _ipfs_subcommand _filestore_arguments
+  ;;
+  (get)
+    _arguments \
+      '(-o --output)'{-o,--output}'[The path where the output should be stored.]'\
+      '(-a --archive)'{-a,--archive}'[Output a TAR archive.]' \
+      '(-C --compress)'{-C,--compress}'[Compress the output with GZIP compression.]' \
+      '(-l --compression-level)'{-l,--compression-level}'[The level of compression (1-9).]'
+  ;;
+  (id)
+    _arguments \
+      '(-f --format)'{-f,--format}'[Optional output format.]' \
+      '--peerid-base[Encoding used for peer IDs: Can either be a multibase encoded CID or a base58btc encoded multihash. Takes {b58mh|base36|k|base32|b...}. Default: b58mh.]'
+  ;;
+  (init)
+    _arguments \
+      '(-a --algorithm)'{-a, --algorithm}'[Cryptographic algorithm to use for key generation. Default: ed25519.]' \
+      '(-b --bits)'{-b,--bits}'[Number of bits to use in the generated RSA private key.]' \
+      '(-e --empty-repo)'{-e,--empty-repo}"[Don't add and pin help files to the local storage.]" \
+      '(-p --profile)'{-p,--profile}"[Apply profile settings to config. Multiple profiles can be separated by ','.]"
+  ;;
+  (key)
+    local -a _key_arguments
+    _key_arguments=(
+      'export:Export a keypair'
+      'gen:Create a new keypair'
+      'import:Import a key and prints imported key id'
+      'list:List all local keypairs'
+      'rename:Rename a keypair'
+      'rm:Remove a keypair'
+      'rotate:Rotates the ipfs identity.'
+    )
+    _ipfs_subcommand _key_arguments
+  ;;
+  (log)
+    local -a _log_arguments
+    _log_arguments=(
+      'level:Change the logging level.'
+      'ls:List the logging subsystems.'
+      'tail:Read the event log.'
+    )
+    _ipfs_subcommand _log_arguments
+  ;;
+  (ls)
+    _arguments \
+      '(-v --headers)'{-v,--headers}'[Print table headers (Hash, Size, Name).]' \
+      '--resolve-type[Resolve linked objects to find out their types. Default: true.]' \
+      '--size[Resolve linked objects to find out their file size. Default: true.]' \
+      '(-s --stream)'{-s,--stream}'[Enable experimental streaming of directory entries as they are traversed.]' \
+  ;;
+  (mount)
+    _arguments \
+      '(-f --ipfs-path)'{-f,--ipfs-path}'[The path where IPFS should be mounted.]' \
+      '(-n --ipns-path)'{-n,--ipns-path}'[The path where IPNS should be mounted.]'
+  ;;
+  (name)
+    local -a _name_arguments
+    _name_arguments=(
+      'publish:Publish IPNS names.'
+      'pubsub:IPNS pubsub management.'
+      'resolve:Resolve IPNS names.'
+    )
+    _ipfs_subcommand _name_arguments
+  ;;
+  (object)
+    local -a _object_arguments
+    _object_arguments=(
+      'data:Output the raw bytes of an IPFS object.'
+      'diff:Display the diff between two ipfs objects.'
+      'get:Get and serialize the DAG node named by <key>.'
+      'links:Output the links pointed to by the specified object.'
+      'new:Create a new object from an ipfs template.'
+      'patch:Create a new merkledag object based on an existing one.'
+      'put:Store input as a DAG object, print its key.'
+      'stat:Get stats for the DAG node named by <key>.'
+    )
+    _ipfs_subcommand _object_arguments
+  ;;
+  (p2p)
+    local -a _p2p_arguments
+    _p2p_arguments=(
+      'close:Stop listening for new connections to forward.'
+      'forward:Forward connections to libp2p service'
+      'listen:Create libp2p service'
+      'ls:List active p2p listeners.'
+      'stream:P2P stream management.'
+    )
+    _ipfs_subcommand _p2p_arguments
+  ;;
+  (pin)
+    local -a _pin_arguments
+    _pin_arguments=(
+      'add:Pin objects to local storage.'
+      'ls:List objects pinned to local storage.'
+      'remote:Pin (and unpin) objects to remote pinning service.'
+      'rm:Remove pinned objects from local storage.'
+      'update:Update a recursive pin'
+      'verify:Verify that recursive pins are complete.'
+    )
+    _ipfs_subcommand _pin_arguments
+  ;;
+  (ping)
+    _arguments '(-n --count)'{-n,--count}'[Number of ping messages to send. Default: 10.]'
+  ;;
+  (refs)
+    _arguments \
+      '--format[Emit edges with given format. Available tokens: <src> <dst> <linkname>. Default: <dst>.]' \
+      '(-e --edges)'{-e,--edges}'[Emit edge format: `<from> -> <to>`.]' \
+      '(-u --unique)'{-u,--unique}'[Omit duplicate refs from output.]' \
+      '(-r --recursive)'{-r,--recursive}'[Recursively list links of child nodes.]' \
+      '--max-depth[Only for recursive refs, limits fetch and listing to the given depth. Default: -1.]'
+    local -a _refs_arguments
+    _refs_arguments='local:List all local references.'
+    _ipfs_subcommand _refs_arguments
+  ;;
+  (repo)
+    local -a _repo_arguments
+    _repo_arguments=(
+      'fsck:Remove repo lockfiles.'
+      'gc:Perform a garbage collection sweep on the repo.'
+      'stat:Get stats for the currently used repo.'
+      'verify:Verify all blocks in repo are not corrupted.'
+      'version:Show the repo version.'
+    )
+    _ipfs_subcommand _repo_arguments
+  ;;
+  (resolve)
+    _arguments \
+      '(-r --recursive)'{-r,--recursive}'[Resolve until the result is an IPFS name. Default: true.]' \
+      '(--dhtrc --dht-record-count)'{--dhtrc,--dht-record-count}'[Number of records to request for DHT resolution.]' \
+      '(--dhtt --dht-timeout)'{--dhtt,--dht-timeout}'[Max time to collect values during DHT resolution eg "30s". Pass 0 for no timeout.]'
+  ;;
+  (stats)
+    local -a _stats_arguments
+    _stats_arguments=(
+      'bitswap:Show some diagnostic information on the bitswap agent.'
+      'bw:Print ipfs bandwidth information.'
+      "dht:Returns statistics about the node's DHT(s)"
+      'repo:Get stats for the currently used repo.'
+    )
+    _ipfs_subcommand _stats_arguments
+  ;;
+  (swarm)
+    local -a _swarm_arguments
+    _swarm_arguments=(
+      'addrs:List known addresses. Useful for debugging.'
+      'connect:Open connection to a given address.'
+      'disconnect:Close connection to a given address.'
+      'filters:Manipulate address filters.'
+      'peers:List peers with open connections.'
+    )
+    _ipfs_subcommand _swarm_arguments
+  ;;
+  (tar)
+    local -a _tar_arguments
+    _tar_arguments=(
+      'add:Import a tar file into ipfs.'
+      'cat:Export a tar file from IPFS.'
+    )
+    _ipfs_subcommand _tar_arguments
+  ;;
+  (version)
+    _arguments \
+      '(-n --number)'{-n,--number}'[Only show the version number.]' \
+      '--commit[Show the commit hash.]' \
+      '--repo[Show repo version.]' \
+      '--all[Show all version information.]'
+  ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/isodate/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/isodate/README.md
new file mode 100644 (file)
index 0000000..1ec75b2
--- /dev/null
@@ -0,0 +1,22 @@
+# Isodate plugin
+
+**Maintainer:** [@Frani](https://github.com/frani)
+
+This plugin adds completion for the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601),
+as well as some aliases for common Date commands.
+
+To use it, add `isodate` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... isodate)
+```
+
+## Aliases
+
+| Alias         | Command                              | Description                                                                |
+|---------------|--------------------------------------|----------------------------------------------------------------------------|
+| isodate       | `date +%Y-%m-%dT%H:%M:%S%z`          | Display the current date with UTC offset and ISO 8601-2 extended format    |
+| isodate_utc   | `date -u +%Y-%m-%dT%H:%M:%SZ`        | Display the current date in UTC and ISO 8601-2 extended format             |
+| isodate_basic | `date -u +%Y%m%dT%H%M%SZ`            | Display the current date in UTC and ISO 8601 basic format                  |
+| unixstamp     | `date +%s`                           | Display the current date as a Unix timestamp (seconds since the Unix epoch)|
+| date_locale   | `date +"%c"`                         | Display the current date using the default locale's format                 |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/isodate/isodate.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/isodate/isodate.plugin.zsh
new file mode 100644 (file)
index 0000000..1a827e7
--- /dev/null
@@ -0,0 +1,7 @@
+# work with date ISO 8601 easy
+
+alias isodate="date +%Y-%m-%dT%H:%M:%S%z"
+alias isodate_utc="date -u +%Y-%m-%dT%H:%M:%SZ"
+alias isodate_basic="date -u +%Y%m%dT%H%M%SZ"
+alias unixstamp="date +%s"
+alias date_locale="date +"%c""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/istioctl/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/istioctl/README.md
new file mode 100644 (file)
index 0000000..afd4d29
--- /dev/null
@@ -0,0 +1,9 @@
+# Istioctl - Istio Command-line Tool
+
+The [istioctl](https://istio.io/latest/docs/ops/diagnostic-tools/istioctl/) tool is a configuration command line utility that allows service operators to debug and diagnose their Istio service mesh deployments.
+
+To use it, add `istioctl` to the plugins array of your zshrc file:
+
+```sh
+plugins=(... istioctl)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/istioctl/istioctl.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/istioctl/istioctl.plugin.zsh
new file mode 100644 (file)
index 0000000..13ead1b
--- /dev/null
@@ -0,0 +1,4 @@
+if [ $commands[istioctl] ]; then
+  source <(istioctl completion zsh)
+  compdef _istioctl istioctl
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/iterm2/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/iterm2/README.md
new file mode 100644 (file)
index 0000000..50cdebf
--- /dev/null
@@ -0,0 +1,29 @@
+# iTerm2 plugin
+
+This plugin adds a few functions that are useful when using [iTerm2](https://www.iterm2.com/).
+
+To use it, add _iterm2_ to the plugins array of your zshrc file:
+```
+plugins=(... iterm2)
+```
+
+## Plugin commands
+
+* `_iterm2_command <iterm2-command>`
+  executes an arbitrary iTerm2 command via an escape code sequence.
+  See https://iterm2.com/documentation-escape-codes.html for all supported commands.
+
+* `iterm2_profile <profile-name>`
+  changes the current terminal window's profile (colors, fonts, settings, etc).
+  `profile-name` is the name of another iTerm2 profile. The profile name can contain spaces.
+
+* `iterm2_tab_color <red> <green> <blue>`
+  changes the color of iTerm2's currently active tab.
+  `red`/`green`/`blue` are on the range 0-255.
+
+* `iterm2_tab_color_reset`
+  resets the color of iTerm2's current tab back to default.
+
+## Contributors
+
+- [Aviv Rosenberg](https://github.com/avivrosenberg)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/iterm2/iterm2.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/iterm2/iterm2.plugin.zsh
new file mode 100644 (file)
index 0000000..9d8e40b
--- /dev/null
@@ -0,0 +1,68 @@
+#####################################################
+# iTerm2 plugin for oh-my-zsh                       #
+# Author: Aviv Rosenberg (github.com/avivrosenberg) #
+#####################################################
+
+###
+# This plugin is only relevant if the terminal is iTerm2 on OSX.
+if [[ "$OSTYPE" == darwin* ]] && [[ -n "$ITERM_SESSION_ID" ]] ; then
+
+  ###
+  # Executes an arbitrary iTerm2 command via an escape code sequence.
+  # See https://iterm2.com/documentation-escape-codes.html for all supported commands.
+  # Example: $ _iterm2_command "1337;StealFocus"
+  function _iterm2_command() {
+    local cmd="$1"
+
+    # Escape codes for wrapping commands for iTerm2.
+    local iterm2_prefix="\x1B]"
+    local iterm2_suffix="\x07"
+
+    # If we're in tmux, a special escape code must be prepended/appended so that
+    # the iTerm2 escape code is passed on into iTerm2.
+    if [[ -n $TMUX ]]; then
+      local tmux_prefix="\x1BPtmux;\x1B"
+      local tmux_suffix="\x1B\\"
+    fi
+
+    echo -n "${tmux_prefix}${iterm2_prefix}${cmd}${iterm2_suffix}${tmux_suffix}"
+  }
+
+  ###
+  # iterm2_profile(): Function for changing the current terminal window's
+  # profile (colors, fonts, settings, etc).
+  # To change the current iTerm2 profile, call this function and pass in a name
+  # of another existing iTerm2 profile (name can contain spaces).
+  function iterm2_profile() {
+    # Desired name of profile
+    local profile="$1"
+
+    # iTerm2 command for changing profile
+    local cmd="1337;SetProfile=$profile"
+
+    # send the sequence
+    _iterm2_command "${cmd}"
+
+    # update shell variable
+    ITERM_PROFILE="$profile"
+  }
+
+  ###
+  # iterm2_tab_color(): Changes the color of iTerm2's currently active tab.
+  # Usage: iterm2_tab_color <red> <green> <blue>
+  #        where red/green/blue are on the range 0-255.
+  function iterm2_tab_color() {
+    _iterm2_command "6;1;bg;red;brightness;$1"
+    _iterm2_command "6;1;bg;green;brightness;$2"
+    _iterm2_command "6;1;bg;blue;brightness;$3"
+  }
+
+
+  ###
+  # iterm2_tab_color_reset(): Resets the color of iTerm2's current tab back to
+  # default.
+  function iterm2_tab_color_reset() {
+    _iterm2_command "6;1;bg;*;default"
+  }
+
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jake-node/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jake-node/README.md
new file mode 100644 (file)
index 0000000..78ca8d8
--- /dev/null
@@ -0,0 +1,9 @@
+# Jake
+
+This plugin provides completion for [Jake](http://jakejs.com/).
+
+To use it add jake-node to the plugins array in your zshrc file.
+
+```bash
+plugins=(... jake-node)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jake-node/jake-node.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jake-node/jake-node.plugin.zsh
new file mode 100644 (file)
index 0000000..c2dad28
--- /dev/null
@@ -0,0 +1,14 @@
+#---oh-my-zsh plugin : task Autocomplete for Jake tool---
+# Jake : https://github.com/mde/jake
+# Warning : Jakefile should have the right case : Jakefile or jakefile
+# Tested on : MacOSX 10.7 (Lion), Ubuntu 11.10
+# Author : Alexandre Lacheze (@al3xstrat)
+# Inspiration : https://weblog.rubyonrails.org/2006/3/9/fast-rake-task-completion-for-zsh
+
+function _jake () {
+  if [ -f Jakefile ] || [ -f jakefile ] || [ -f Jakefile.js ] || [ -f jakefile.js ]; then
+    compadd `jake -T | cut -d " " -f 2 | sed -E "s/.\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"`
+  fi
+}
+
+compdef _jake jake
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jenv/README.md
new file mode 100644 (file)
index 0000000..1487941
--- /dev/null
@@ -0,0 +1,27 @@
+# jenv plugin
+
+[jenv](https://www.jenv.be/) is a Java version manager similar to [rbenv](https://github.com/rbenv/rbenv)
+and [pyenv](https://github.com/yyuu/pyenv).
+
+This plugin initializes jenv and provides the `jenv_prompt_info` function to add Java
+version information to prompts.
+
+To use, add `jenv` to your plugins array in your zshrc file:
+
+```zsh
+plugins=(... jenv)
+```
+
+## Theme example
+
+You can modify your `$PROMPT` or `$RPROMPT` variables to run `jenv_prompt_info`.
+
+For example:
+```
+PROMPT="%~$ "
+RPROMPT='$(jenv_prompt_info)'
+```
+changes your prompt to:
+```
+~/java/project$ ▋                                       oracle64-1.6.0.39
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jenv/jenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jenv/jenv.plugin.zsh
new file mode 100644 (file)
index 0000000..2401026
--- /dev/null
@@ -0,0 +1,36 @@
+jenvdirs=("$HOME/.jenv" "/usr/local/bin/jenv" "/usr/local/jenv" "/opt/jenv")
+
+FOUND_JENV=0
+for jenvdir in $jenvdirs; do
+    if [[ -d "${jenvdir}/bin" ]]; then
+        FOUND_JENV=1
+        break
+    fi
+done
+
+if [[ $FOUND_JENV -eq 0 ]]; then
+    if (( $+commands[brew] )) && jenvdir="$(brew --prefix jenv)"; then
+        [[ -d "${jenvdir}/bin" ]] && FOUND_JENV=1
+    fi
+fi
+
+if [[ $FOUND_JENV -eq 1 ]]; then
+    (( $+commands[jenv] )) || export PATH="${jenvdir}/bin:$PATH"
+    eval "$(jenv init - zsh)"
+
+    function jenv_prompt_info() {
+      local version="$(jenv version-name 2>/dev/null)"
+      echo "${version:gs/%/%%}"
+    }
+
+    if [[ -d "${jenvdir}/versions" ]]; then
+        export JENV_ROOT=$jenvdir
+    fi
+else
+    function jenv_prompt_info() {
+      local version="$(java -version 2>&1 | cut -d' ' -f2)"
+      echo "system: ${version:gs/%/%%}"
+    }
+fi
+
+unset jenvdir jenvdirs FOUND_JENV
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jfrog/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jfrog/README.md
new file mode 100644 (file)
index 0000000..1d85862
--- /dev/null
@@ -0,0 +1,11 @@
+# JFrog CLI
+
+This plugin provides completion for [JFrog CLI](https://github.com/jfrog/jfrog-cli).
+
+JFrog CLI provides a simple interface that automates access to [Artifactory](https://jfrog.com/artifactory), [Xray](https://jfrog.com/xray), [Bintray](https://jfrog.com/bintray) and [Mission Control](https://jfrog.com/mission-control) through their respective REST APIs.
+
+To use it, add `jfrog` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... jfrog)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jfrog/jfrog.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jfrog/jfrog.plugin.zsh
new file mode 100644 (file)
index 0000000..1441bc1
--- /dev/null
@@ -0,0 +1,11 @@
+_jfrog() {
+       local -a opts
+       opts=("${(@f)$(_CLI_ZSH_AUTOCOMPLETE_HACK=1 ${words[@]:0:#words[@]-1} --generate-bash-completion)}")
+       _describe 'values' opts
+       if [[ $compstate[nmatches] -eq 0 && $words[$CURRENT] != -* ]]; then
+               _files
+       fi
+}
+
+compdef _jfrog jfrog
+compdef _jfrog jf
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jhbuild/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jhbuild/README.md
new file mode 100644 (file)
index 0000000..3220e0d
--- /dev/null
@@ -0,0 +1,34 @@
+# JHBuild
+
+This plugin adds some [JHBuild](https://developer.gnome.org/jhbuild/) aliases.
+
+To use it, add `jhbuild` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... jhbuild)
+```
+
+**Maintainer:** [Miguel Vaello](https://github.com/miguxbe)
+
+## Aliases
+
+| Alias   | Command                   |
+|---------|---------------------------|
+| `jh`    | `jhbuild`                 |
+| `jhb`   | `jhbuild build`           |
+| `jhbo`  | `jhbuild buildone`        |
+| `jhckb` | `jhbuild checkbranches`   |
+| `jhckm` | `jhbuild checkmodulesets` |
+| `jhi`   | `jhbuild info`            |
+| `jhl`   | `jhbuild list`            |
+| `jhc`   | `jhbuild clean`           |
+| `jhco`  | `jhbuild cleanone`        |
+| `jhm`   | `jhbuild make`            |
+| `jhr`   | `jhbuild run`             |
+| `jhrd`  | `jhbuild rdepends`        |
+| `jhsd`  | `jhbuild sysdeps`         |
+| `jhu`   | `jhbuild update`          |
+| `jhuo`  | `jhbuild updateone`       |
+| `jhun`  | `jhbuild uninstall`       |
+| `jhsh`  | `jhbuild shell`           |
+| `jht`   | `jhbuild tinderbox`       |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jhbuild/jhbuild.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jhbuild/jhbuild.plugin.zsh
new file mode 100644 (file)
index 0000000..416745d
--- /dev/null
@@ -0,0 +1,32 @@
+# JHBuild Aliases
+
+# Base
+alias jh='jhbuild'
+# Build
+alias jhb='jhbuild build'
+alias jhbo='jhbuild buildone'
+# Checks
+alias jhckb='jhbuild checkbranches'
+alias jhckm='jhbuild checkmodulesets'
+# Info & List
+alias jhi='jhbuild info'
+alias jhl='jhbuild list'
+# Clean
+alias jhc='jhbuild clean'
+alias jhco='jhbuild cleanone'
+# Make
+alias jhm='jhbuild make'
+# Run
+alias jhr='jhbuild run'
+# Depends
+alias jhrd='jhbuild rdepends'
+alias jhsd='jhbuild sysdeps'
+# Update
+alias jhu='jhbuild update'
+alias jhuo='jhbuild updateone'
+# Uninstall
+alias jhun='jhbuild uninstall'
+# Shell
+alias jhsh='jhbuild shell'
+# Tinderbox
+alias jht='jhbuild tinderbox'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jira/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jira/README.md
new file mode 100644 (file)
index 0000000..a5633af
--- /dev/null
@@ -0,0 +1,70 @@
+#  Jira plugin  #
+
+CLI support for JIRA interaction
+
+##  Description  ##
+
+This plugin provides command line tools for interacting with Atlassian's [JIRA](https://www.atlassian.com/software/jira) bug tracking software.
+
+The interaction is all done through the web. No local installation of JIRA is necessary.
+
+In this document, "JIRA" refers to the JIRA issue tracking server, and `jira` refers to the command this plugin supplies.
+
+##  Usage  ##
+
+This plugin supplies one command, `jira`, through which all its features are exposed. Most forms of this command open a JIRA page in your web browser.
+
+```
+jira            # performs the default action
+
+jira new        # opens a new issue
+jira dashboard  # opens your JIRA dashboard
+jira tempo      # opens your JIRA Tempo
+jira reported [username]  # queries for issues reported by a user
+jira assigned [username]  # queries for issues assigned to a user
+jira myissues   # queries for you own issues
+jira branch     # opens an existing issue matching the current branch name
+                # The branch name may have prefixes ending in "/": "feature/MP-1234",
+                # and also suffixes starting with "_": "MP-1234_fix_dashboard"
+                # In both these cases, the issue opened will be "MP-1234"
+jira ABC-123    # opens an existing issue
+jira ABC-123 m  # opens an existing issue for adding a comment
+```
+
+#### Debugging usage  ####
+
+These calling forms are for developers' use, and may change at any time.
+
+```
+jira dumpconfig   # displays the effective configuration
+```
+
+##  Setup  ##
+
+The URL for your JIRA instance is set by `$JIRA_URL` or a `.jira_url` file.
+
+Add a `.jira-url` file in the base of your project. You can also set `$JIRA_URL` in your `~/.zshrc` or put a `.jira-url` in your home directory. A `.jira-url` in the current directory takes precedence, so you can make per-project customizations.
+
+The same goes with `.jira-prefix` and `$JIRA_PREFIX`. These control the prefix added to all issue IDs, which differentiates projects within a JIRA instance.
+
+For example:
+
+```
+cd to/my/project
+echo "https://jira.atlassian.com" >> .jira-url
+```
+
+(Note: The current implementation only looks in the current directory for `.jira-url` and `.jira-prefix`, not up the path, so if you are in a subdirectory of your project, it will fall back to your default JIRA URL. This will probably change in the future though.)
+
+###  Variables  ###
+
+* `$JIRA_URL` - Your JIRA instance's URL
+* `$JIRA_NAME` - Your JIRA username; used as the default user for `assigned`/`reported` searches
+* `$JIRA_PREFIX` - Prefix added to issue ID arguments
+* `$JIRA_RAPID_BOARD` - Set to `true` if you use Rapid Board
+* `$JIRA_DEFAULT_ACTION` - Action to do when `jira` is called with no arguments; defaults to "new"
+
+
+### Browser ###
+
+Your default web browser, as determined by how `open_command` handles `http://` URLs, is used for interacting with the JIRA instance. If you change your system's URL handler associations, it will change the browser that `jira` uses.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jira/_jira b/stow/oh-my-zsh/.oh-my-zsh/plugins/jira/_jira
new file mode 100644 (file)
index 0000000..1ac3eed
--- /dev/null
@@ -0,0 +1,24 @@
+#compdef jira
+#autoload
+
+local -a _1st_arguments
+_1st_arguments=(
+  'new:create a new issue'
+  'dashboard:open the dashboard'
+  'tempo:open the tempo'
+  'reported:search for issues reported by a user'
+  'assigned:search for issues assigned to a user'
+  'branch:open the issue named after the git branch of the current directory'
+  'dumpconfig:display effective jira configuration'
+)
+
+_arguments -C \
+  ':command:->command' \
+  '*::options:->options'
+
+case $state in
+  (command)
+    _describe -t commands "jira subcommand" _1st_arguments
+    return
+   ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jira/jira.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jira/jira.plugin.zsh
new file mode 100644 (file)
index 0000000..22807e0
--- /dev/null
@@ -0,0 +1,133 @@
+# CLI support for JIRA interaction
+#
+# See README.md for details
+
+function jira() {
+  emulate -L zsh
+  local action jira_url jira_prefix
+  if [[ -n "$1" ]]; then
+    action=$1
+  elif [[ -f .jira-default-action ]]; then
+    action=$(cat .jira-default-action)
+  elif [[ -f ~/.jira-default-action ]]; then
+    action=$(cat ~/.jira-default-action)
+  elif [[ -n "${JIRA_DEFAULT_ACTION}" ]]; then
+    action=${JIRA_DEFAULT_ACTION}
+  else
+    action="new"
+  fi
+
+  if [[ -f .jira-url ]]; then
+    jira_url=$(cat .jira-url)
+  elif [[ -f ~/.jira-url ]]; then
+    jira_url=$(cat ~/.jira-url)
+  elif [[ -n "${JIRA_URL}" ]]; then
+    jira_url=${JIRA_URL}
+  else
+    _jira_url_help
+    return 1
+  fi
+
+  if [[ -f .jira-prefix ]]; then
+    jira_prefix=$(cat .jira-prefix)
+  elif [[ -f ~/.jira-prefix ]]; then
+    jira_prefix=$(cat ~/.jira-prefix)
+  elif [[ -n "${JIRA_PREFIX}" ]]; then
+    jira_prefix=${JIRA_PREFIX}
+  else
+    jira_prefix=""
+  fi
+
+
+  if [[ $action == "new" ]]; then
+    echo "Opening new issue"
+    open_command "${jira_url}/secure/CreateIssue!default.jspa"
+  elif [[ "$action" == "assigned" || "$action" == "reported" ]]; then
+    _jira_query ${@:-$action}
+  elif [[ "$action" == "myissues" ]]; then
+    echo "Opening my issues"
+    open_command "${jira_url}/issues/?filter=-1"
+  elif [[ "$action" == "dashboard" ]]; then
+    echo "Opening dashboard"
+    if [[ "$JIRA_RAPID_BOARD" == "true" ]]; then
+      open_command "${jira_url}/secure/RapidBoard.jspa"
+    else
+      open_command "${jira_url}/secure/Dashboard.jspa"
+    fi
+  elif [[ "$action" == "tempo" ]]; then
+    echo "Opening tempo"
+    open_command "${jira_url}/secure/Tempo.jspa"
+  elif [[ "$action" == "dumpconfig" ]]; then
+    echo "JIRA_URL=$jira_url"
+    echo "JIRA_PREFIX=$jira_prefix"
+    echo "JIRA_NAME=$JIRA_NAME"
+    echo "JIRA_RAPID_BOARD=$JIRA_RAPID_BOARD"
+    echo "JIRA_DEFAULT_ACTION=$JIRA_DEFAULT_ACTION"
+  else
+    # Anything that doesn't match a special action is considered an issue name
+    # but `branch` is a special case that will parse the current git branch
+    local issue_arg issue
+    if [[ "$action" == "branch" ]]; then
+      # Get name of the branch
+      issue_arg=$(git rev-parse --abbrev-ref HEAD)
+      # Strip prefixes like feature/ or bugfix/
+      issue_arg=${issue_arg##*/}
+      # Strip suffixes starting with _
+      issue_arg=(${(s:_:)issue_arg})
+      issue_arg=${issue_arg[1]}
+      if [[ "$issue_arg" = ${jira_prefix}* ]]; then
+        issue="${issue_arg}"
+      else
+        issue="${jira_prefix}${issue_arg}"
+      fi
+    else
+      issue_arg=${(U)action}
+      issue="${jira_prefix}${issue_arg}"
+    fi
+
+    local url_fragment
+    if [[ "$2" == "m" ]]; then
+      url_fragment="#add-comment"
+      echo "Add comment to issue #$issue"
+    else
+      echo "Opening issue #$issue"
+    fi
+    open_command "${jira_url}/browse/${issue}${url_fragment}"
+  fi
+}
+
+function _jira_url_help() {
+  cat << EOF
+error: JIRA URL is not specified anywhere.
+
+Valid options, in order of precedence:
+  .jira-url file
+  \$HOME/.jira-url file
+  \$JIRA_URL environment variable
+EOF
+}
+
+function _jira_query() {
+  emulate -L zsh
+  local verb="$1"
+  local jira_name lookup preposition query
+  if [[ "${verb}" == "reported" ]]; then
+    lookup=reporter
+    preposition=by
+  elif [[ "${verb}" == "assigned" ]]; then
+    lookup=assignee
+    preposition=to
+  else
+    echo "error: not a valid lookup: $verb" >&2
+    return 1
+  fi
+  jira_name=${2:=$JIRA_NAME}
+  if [[ -z $jira_name ]]; then
+    echo "error: JIRA_NAME not specified" >&2
+    return 1
+  fi
+
+  echo "Browsing issues ${verb} ${preposition} ${jira_name}"
+  query="${lookup}+%3D+%22${jira_name}%22+AND+resolution+%3D+unresolved+ORDER+BY+priority+DESC%2C+created+ASC"
+  open_command "${jira_url}/secure/IssueNavigator.jspa?reset=true&jqlQuery=${query}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jruby/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jruby/README.md
new file mode 100644 (file)
index 0000000..821a46d
--- /dev/null
@@ -0,0 +1,21 @@
+# JRuby plugin
+
+This plugin adds aliases for [JRuby](https://www.jruby.org/).
+
+To use it, add `jruby` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... jruby)
+```
+
+## Requirements
+
+This plugin assumes you already have jruby installed and available in your [path](https://www.jruby.org/getting-started).
+
+## Aliases
+
+| Alias        | Command                                                          |
+| ------------ | ---------------------------------------------------------------- |
+| `jrspec`     | `jruby --debug -S rspec --debug`                                 |
+| `jprofile`   | `jruby --profile.api -S rspec`                                   |
+| `jexec`      | `jruby -S`                                                       |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jruby/jruby.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jruby/jruby.plugin.zsh
new file mode 100644 (file)
index 0000000..bb7975b
--- /dev/null
@@ -0,0 +1,4 @@
+# Aliases
+alias jrspec='jruby --debug -S rspec --debug'
+alias jprofile='jruby --profile.api -S rspec'
+alias jexec='jruby -S'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jsontools/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jsontools/README.md
new file mode 100644 (file)
index 0000000..6a27400
--- /dev/null
@@ -0,0 +1,79 @@
+# jsontools
+
+Handy command line tools for dealing with json data.
+
+To use it, add `jsontools` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... jsontools)
+```
+
+## Usage
+
+Usage is simple... just take your json data and pipe it into the appropriate jsontool:
+
+- `pp_json`: pretty prints json.
+- `is_json`: returns true if valid json; false otherwise.
+- `urlencode_json`: returns a url encoded string for the given json.
+- `urldecode_json`: returns decoded json for the given url encoded string.
+
+### Supports NDJSON (Newline Delimited JSON)
+
+The plugin also supports [NDJSON](http://ndjson.org/) input, which means all functions
+have an alternative function that reads and processes the input line by line. These
+functions have the same name except using `ndjson` instead of `json`:
+
+> `pp_ndjson`, `is_ndjson`, `urlencode_ndjson`, `urldecode_ndjson`.
+
+### Examples
+
+- **pp_json**:
+
+```console
+# curl json data and pretty print the results
+curl https://coderwall.com/bobwilliams.json | pp_json
+```
+
+- **is_json**:
+
+```console
+# validate if file's content conforms to a valid JSON schema
+$ is_json < data.json
+true
+# shows true / false and returns the proper exit code
+$ echo $?
+0
+```
+
+- **urlencode_json**:
+
+```console
+# json data directly from the command line
+$ echo '{"b":2, "a":1}' | urlencode_json
+%7B%22b%22:2,%20%22a%22:1%7D
+```
+
+- **urldecode_json**:
+
+```console
+# url encoded string to decode
+$ echo '%7B%22b%22:2,%20%22a%22:1%7D' | urldecode_json
+{"b":2, "a":1}
+```
+
+- **pp_ndjson**:
+
+```console
+# echo two separate json objects and pretty print both
+$ echo '{"a": "b"}\n{"c": [1,2,3]}' | pp_ndjson
+{
+    "a": "b"
+}
+{
+    "c": [
+        1,
+        2,
+        3
+    ]
+}
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jsontools/jsontools.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jsontools/jsontools.plugin.zsh
new file mode 100644 (file)
index 0000000..49828d3
--- /dev/null
@@ -0,0 +1,113 @@
+# JSON Tools
+# Adds command line aliases useful for dealing with JSON
+
+# Check that user-defined method is installed
+if [[ -n "$JSONTOOLS_METHOD" ]]; then
+  (( $+commands[$JSONTOOLS_METHOD] )) || unset JSONTOOLS_METHOD
+fi
+
+# If method undefined, find the first one that is installed
+if [[ -z "$JSONTOOLS_METHOD" ]]; then
+  for JSONTOOLS_METHOD in node python3 ruby; do
+    # If method found, break out of loop
+    (( $+commands[$JSONTOOLS_METHOD] )) && break
+    # Otherwise unset the variable
+    unset JSONTOOLS_METHOD
+  done
+
+  # If no methods were found, exit the plugin
+  [[ -n "$JSONTOOLS_METHOD" ]] || return 1
+fi
+
+# Define json tools for each method
+case "$JSONTOOLS_METHOD" in
+  node)
+    # node doesn't make it easy to deal with stdin, so we pass it as an argument with xargs -0
+    function pp_json() {
+      xargs -0 node -e 'console.log(JSON.stringify(JSON.parse(process.argv[1]), null, 4));'
+    }
+    function is_json() {
+      xargs -0 node -e '
+        try {
+          json = JSON.parse(process.argv[1]);
+          console.log("true");
+          process.exit(0);
+        } catch (e) {
+          console.log("false");
+          process.exit(1);
+        }
+      '
+    }
+    function urlencode_json() {
+      xargs -0 node -e "console.log(encodeURIComponent(process.argv[1]))"
+    }
+    function urldecode_json() {
+      xargs -0 node -e "console.log(decodeURIComponent(process.argv[1]))"
+    }
+  ;;
+  python3)
+    function pp_json() {
+      python3 -c 'import sys; del sys.path[0]; import runpy; runpy._run_module_as_main("json.tool")'
+    }
+    function is_json() {
+      python3 -c '
+import sys; del sys.path[0];
+import json
+try:
+  json.loads(sys.stdin.read())
+  print("true"); sys.exit(0)
+except ValueError:
+  print("false"); sys.exit(1)
+      '
+    }
+    function urlencode_json() {
+      python3 -c '
+import sys; del sys.path[0];
+from urllib.parse import quote_plus
+print(quote_plus(sys.stdin.read()))
+      '
+    }
+    function urldecode_json() {
+      python3 -c '
+import sys; del sys.path[0];
+from urllib.parse import unquote_plus
+print(unquote_plus(sys.stdin.read()))
+      '
+    }
+  ;;
+  ruby)
+    function pp_json() {
+      ruby -e '
+        require "json"
+        require "yaml"
+        puts JSON.parse(STDIN.read).to_yaml
+      '
+    }
+    function is_json() {
+      ruby -e '
+        require "json"
+        begin
+          puts !!JSON.parse(STDIN.read); exit(0)
+        rescue JSON::ParserError
+          puts false; exit(1)
+        end
+      '
+    }
+    function urlencode_json() {
+      ruby -e 'require "cgi"; puts CGI.escape(STDIN.read)'
+    }
+    function urldecode_json() {
+      ruby -e 'require "cgi"; puts CGI.unescape(STDIN.read)'
+    }
+  ;;
+esac
+unset JSONTOOLS_METHOD
+
+## Add NDJSON support
+
+function {pp,is,urlencode,urldecode}_ndjson() {
+  local json jsonfunc="${0//ndjson/json}"
+  while read -r json; do
+    $jsonfunc <<< "$json"
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/juju/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/juju/README.md
new file mode 100644 (file)
index 0000000..f0c6530
--- /dev/null
@@ -0,0 +1,130 @@
+# juju plugin
+
+This plugin provides useful aliases and functions for [juju](https://juju.is/) (for TAB completion,
+refer to the [official repo](https://github.com/juju/juju/blob/develop/etc/bash_completion.d/juju)).
+
+To use this plugin, add `juju` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... juju)
+```
+
+## Aliases
+
+Naming convention:
+
+- `!` suffix: `--force --no-wait -y`.
+- `ds` suffix: `--destroy-storage`.
+- `jsh` prefix means `juju show-*`.
+
+### General
+
+| Alias   | Command                                     | Description                                            |
+|---------|---------------------------------------------|--------------------------------------------------------|
+| `j`     | `juju`                                      | The juju command                                       |
+| `jcld`  | `juju clouds`                               | Lists all clouds with registered credentials           |
+| `jclda` | `juju clouds --all`                         | Lists all clouds available to Juju                     |
+| `jdl`   | `juju debug-log --ms`                       | Display log, with millisecond resolution               |
+| `jdlr`  | `juju debug-log --ms --replay`              | Replay entire log                                      |
+| `jh`    | `juju help`                                 | Show help on a command or other topic                  |
+| `jshsl` | `juju show-status-log`                      | Output past statuses for the specified entity          |
+| `jstj`  | `juju status --format=json`                 | Show status in json format (more detailed)             |
+| `jst`   | `juju status --relations --color`           | Show status, including relations, in color             |
+| `jsts`  | `juju status --relations --storage --color` | Show status, including relations and storage, in color |
+
+### Bootstrap
+
+| Alias   | Command                             | Description                                           |
+|---------|-------------------------------------|-------------------------------------------------------|
+| `jb`    | `juju bootstrap`                    | Initializing a Juju cloud environment                 |
+| `jbng`  | `juju bootstrap --no-gui`           | Initializing a Juju cloud environment without GUI     |
+| `jbl`   | `juju bootstrap localhost`          | Initializing an lxd cloud environment                 |
+| `jblng` | `juju bootstrap --no-gui localhost` | Initializing an lxd cloud environment without GUI     |
+| `jbm`   | `juju bootstrap microk8s`           | Initializing a MicroK8s cloud environment             |
+| `jbmng` | `juju bootstrap --no-gui microk8s`  | Initializing a MicroK8s cloud environment without GUI |
+
+### Controller
+
+| Alias    | Command                                                                               | Description                                                       |
+|----------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------|
+| `jctl`   | `juju controllers`                                                                    | List all controllers                                              |
+| `jctlr`  | `juju controllers --refresh`                                                          | List all controllers (download latest details)                    |
+| `jdc`    | `juju destroy-controller --destroy-all-models`                                        | Destroy a controller                                              |
+| `jdc!`   | `juju destroy-controller --destroy-all-models --force --no-wait -y`                   | Destroy a controller                                              |
+| `jdcds`  | `juju destroy-controller --destroy-all-models --destroy-storage`                      | Destroy a controller and associated storage                       |
+| `jdcds!` | `juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y` | Destroy a controller and associated storage                       |
+| `jkc`    | `juju kill-controller -y -t 0`                                                        | Forcibly terminate all associated resources for a Juju controller |
+| `jshc`   | `juju show-controller`                                                                | Shows detailed information of a controller                    |
+| `jsw`    | `juju switch`                                                                         | Select or identify the current controller and model               |
+
+### Model
+
+| Alias    | Command                                                     | Description                                           |
+|----------|-------------------------------------------------------------|-------------------------------------------------------|
+| `jam`    | `juju add-model`                                            | Add a hosted model                                    |
+| `jdm`    | `juju destroy-model`                                        | Non-recoverable, complete removal of a model          |
+| `jdm!`   | `juju destroy-model --force --no-wait -y`                   | Non-recoverable, complete removal of a model          |
+| `jdmds`  | `juju destroy-model --destroy-storage`                      | Non-recoverable, complete removal of a model          |
+| `jdmds!` | `juju destroy-model --destroy-storage --force --no-wait -y` | Non-recoverable, complete removal of a model          |
+| `jmc`    | `juju model-config`                                         | Display or set configuration values on a model        |
+| `jm`     | `juju models`                                               | List models a user can access on a controller         |
+| `jshm`   | `juju show-model`                                           | Show information about the current or specified model |
+| `jsw`    | `juju switch`                                               | Select or identify the current controller and model   |
+
+### Application / unit
+
+| Alias    | Command                                                       | Description                                                               |
+|----------|---------------------------------------------------------------|---------------------------------------------------------------------------|
+| `jc`     | `juju config`                                                 | Get, set, or reset configuration for a deployed application               |
+| `jde`    | `juju deploy --channel=edge`                                  | Deploy a new application or bundle from the edge channel                  |
+| `jd`     | `juju deploy`                                                 | Deploy a new application or bundle                                        |
+| `jra`    | `juju run-action`                                             | Queue an action for execution                                             |
+| `jraw`   | `juju run-action --wait`                                      | Queue an action for execution and wait for results, with optional timeout |
+| `jrm`    | `juju remove-application`                                     | Remove application                                                        |
+| `jrm!`   | `juju remove-application --force --no-wait`                   | Remove application forcefully                                             |
+| `jrmds`  | `juju remove-application --destroy-storage`                   | Remove application and destroy attached storage                           |
+| `jrmds!` | `juju remove-application --destroy-storage --force --no-wait` | Remove application forcefully, destroying attached storage                |
+| `jrp`    | `juju refresh --path`                                         | Upgrade charm from local charm file                                       |
+| `jsa`    | `juju scale-application`                                      | Set the desired number of application units                               |
+| `jssh`   | `juju ssh`                                                    | Initiate an SSH session or execute a command on a Juju target             |
+| `jsshc`  | `juju ssh --container`                                        | Initiate an SSH session or execute a command on a given container         |
+| `jshu`   | `juju show-unit`                                              | Displays information about a unit                                         |
+
+### Storage
+
+| Alias   | Command                       | Description                                     |
+|---------|-------------------------------|-------------------------------------------------|
+| `jrs`   | `juju remove-storage`         | Remove storage                                  |
+| `jrs!`  | `juju remove-storage --force` | Remove storage even if it is currently attached |
+
+### Relation
+
+| Alias     | Command                        | Description                                                       |
+|-----------|--------------------------------|-------------------------------------------------------------------|
+| `jrel`    | `juju relate`                  | Relate two applications                                           |
+| `jrmrel`  | `juju remove-relation`         | Remove an existing relation between two applications.             |
+| `jrmrel!` | `juju remove-relation --force` | Remove an existing relation between two applications, forcefully. |
+
+### Cross-model relation (CMR)
+
+| Alias    | Command            | Description                                                    |
+|----------|--------------------|----------------------------------------------------------------|
+| `jex`    | `juju expose`      | Make an application publicly available over the network        |
+| `jof`    | `juju offer`       | Offer application endpoints for use in other models            |
+| `jcon`   | `juju consume`     | Add a remote offer to the model                                |
+| `jrmsas` | `juju remove-saas` | Remove consumed applications (SAAS) from the model             |
+| `junex`  | `juju unexpose`    | Remove public availability over the network for an application |
+
+### Bundle
+
+| Alias | Command              | Description                                                 |
+|-------|----------------------|-------------------------------------------------------------|
+| `jeb` | `juju export-bundle` | Export the current model configuration as a reusable bundle |
+
+## Functions
+
+- `jaddr <app_name> [unit_num]`: display app or unit IP address.
+- `jreld <relation_name> <app_name> <unit_num>`: display app and unit relation data.
+- `jclean`: destroy all controllers
+- `wjst [interval_secs] [args_for_watch]`: watch juju status, with optional interval
+  (default: 5s); you may pass additional arguments to `watch`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/juju/juju.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/juju/juju.plugin.zsh
new file mode 100644 (file)
index 0000000..be8a2c7
--- /dev/null
@@ -0,0 +1,172 @@
+# ---------------------------------------------------------- #
+# Aliases and functions for juju (https://juju.is)           #
+# ---------------------------------------------------------- #
+
+# Load TAB completions
+# You need juju's bash completion script installed. By default bash-completion's
+# location will be used (i.e. pkg-config --variable=completionsdir bash-completion).
+completion_file="$(pkg-config --variable=completionsdir bash-completion 2>/dev/null)/juju" || \
+  completion_file="/usr/share/bash-completion/completions/juju"
+[[ -f "$completion_file" ]] && source "$completion_file"
+unset completion_file
+
+# ---------------------------------------------------------- #
+# Aliases (in alphabetic order)                              #
+#                                                            #
+# Generally,                                                 #
+#   - `!` means --force --no-wait -y                         #
+#   - `ds` suffix means --destroy-storage                    #
+#   - `jsh` prefix means juju show-*                         #
+# ---------------------------------------------------------- #
+alias j="juju"
+alias jam="juju add-model --config logging-config=\"<root>=WARNING; unit=DEBUG\"\
+ --config update-status-hook-interval=\"60m\""
+alias jb='juju bootstrap'
+alias jbng='juju bootstrap --no-gui'
+alias jbl='juju bootstrap localhost'
+alias jblng='juju bootstrap --no-gui localhost'
+alias jbm='juju bootstrap microk8s'
+alias jbmng='juju bootstrap --no-gui microk8s'
+alias jc='juju config'
+alias jcld='juju clouds'
+alias jclda='juju clouds --all'
+alias jctl='juju controllers'
+alias jctlr='juju controllers --refresh'
+alias jdc='juju destroy-controller --destroy-all-models'
+alias 'jdc!'='juju destroy-controller --destroy-all-models --force --no-wait -y'
+alias jdcds='juju destroy-controller --destroy-all-models --destroy-storage'
+alias 'jdcds!'='juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y'
+alias jdm='juju destroy-model'
+alias 'jdm!'='juju destroy-model --force --no-wait -y'
+alias jdmds='juju destroy-model --destroy-storage'
+alias 'jdmds!'='juju destroy-model --destroy-storage --force --no-wait -y'
+alias jde='juju deploy --channel=edge'
+alias jd='juju deploy'
+alias jdl='juju debug-log --ms'
+alias jdlr='juju debug-log --ms --replay'
+alias jcon='juju consume'
+alias jeb='juju export-bundle'
+alias jex='juju expose'
+alias jh='juju help'
+alias jkc='juju kill-controller -y -t 0'
+alias jm='juju models'
+alias jmc='juju model-config'
+alias jof='juju offer'
+alias jra='juju run-action'
+alias jraw='juju run-action --wait'
+alias jrel='juju relate'
+alias jrm='juju remove-application'
+alias 'jrm!'='juju remove-application --force --no-wait'
+alias jrmds='juju remove-application --destroy-storage'
+alias 'jrmds!'='juju remove-application --destroy-storage --force --no-wait'
+alias jrmrel='juju remove-relation'
+alias 'jrmrel!'='juju remove-relation --force'
+alias jrmsas='juju remove-saas'
+alias jrp='juju refresh --path'
+alias jrs='juju remove-storage'
+alias 'jrs!'='juju remove-storage --force'
+alias jsa='juju scale-application'
+alias jsha='juju show-application'
+alias jshc='juju show-controller'
+alias jshm='juju show-model'
+alias jshsl='juju show-status-log'
+alias jshu='juju show-unit'
+alias jssh='juju ssh'
+alias jsshc='juju ssh --container'
+alias jstj='juju status --format=json'
+alias jst='juju status --relations --color'
+alias jsts='juju status --relations --storage --color'
+alias jsw='juju switch'
+
+# ---------------------------------------------------------- #
+# Functions (in alphabetic order)                            #
+# ---------------------------------------------------------- #
+
+# Get app or unit address
+jaddr() {
+  # $1 = app name
+  # $2 = unit number (optional)
+  if (( ! ${+commands[jq]} )); then
+    echo "jq is required but could not be found." >&2
+    return 1
+  fi
+
+  if [[ $# -eq 1 ]]; then
+    # Get app address
+    juju status "$1" --format=json \
+      | jq -r ".applications.\"$1\".address"
+  elif [[ $# -eq 2 ]]; then
+    # Get unit address
+    juju status "$1/$2" --format=json \
+      | jq -r ".applications.\"$1\".units.\"$1/$2\".address"
+  else
+    echo "Invalid number of arguments."
+    echo "Usage:   jaddr <app-name> [<unit-number>]"
+    echo "Example: jaddr karma"
+    echo "Example: jaddr karma 0"
+    return 1
+  fi
+}
+
+# Destroy all controllers
+jclean() {
+  if (( ! ${+commands[jq]} )); then
+    echo "jq is required but could not be found." >&2
+    return 1
+  fi
+
+  local controllers=$(juju controllers --format=json | jq -r '.controllers | keys[]' 2>/dev/null)
+  if [[ -z "$controllers" ]]; then
+    echo "No controllers registered"
+    return 0
+  fi
+
+  echo "This will forcefully destroy all storages, models and controllers."
+  echo "Controllers to be destroyed:"
+  echo "$controllers"
+
+  if ! read -q '?Are you sure (y/n)? '; then
+    echo
+    echo "Aborted."
+    return 0
+  fi
+
+  echo
+  for controller in ${=controllers}; do
+    timeout 2m juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y $controller
+    timeout 2m juju kill-controller -y -t 0 $controller 2>/dev/null
+    timeout 10s juju unregister $controller 2>/dev/null
+  done
+}
+
+# Display app and unit relation data
+jreld() {
+  # $1 = relation name
+  # $2 = app name
+  # $3 = unit number
+  if [[ $# -ne 3 ]]; then
+    echo "Invalid number of arguments."
+    echo "Usage:   jreld <relation-name> <app-name> <unit-number>"
+    echo "Example: jreld karma-dashboard alertmanager 0"
+    return 1
+  fi
+
+  local relid="$(juju run "relation-ids $1" --unit $2/$3)"
+  if [[ -z "$relid" ]]; then
+    return 1
+  fi
+
+  echo "App data:"
+  juju run "relation-get -r $relid --app - $2" --unit $2/$3
+  echo
+  echo "Unit data:"
+  juju run "relation-get -r $relid - $2" --unit $2/$3
+}
+
+# Watch juju status, with optional interval (default: 5 sec)
+wjst() {
+  local interval="${1:-5}"
+  shift $(( $# > 0 ))
+  watch -n "$interval" --color juju status --relations --color "$@"
+}
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jump/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/jump/README.md
new file mode 100644 (file)
index 0000000..1b0ce68
--- /dev/null
@@ -0,0 +1,31 @@
+# Jump plugin
+
+This plugin allows to easily jump around the file system by manually adding marks.
+Those marks are stored as symbolic links in the directory `$MARKPATH` (default `$HOME/.marks`)
+
+To use it, add `jump` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... jump)
+```
+
+## Commands
+
+| Command              | Description                                                                                     |
+|----------------------|-------------------------------------------------------------------------------------------------|
+| `jump <mark-name>`   | Jump to the given mark                                                                          |
+| `mark [mark-name]`   | Create a mark with the given name or with the name of the current directory if none is provided |
+| `unmark <mark-name>` | Remove the given mark                                                                           |
+| `marks`              | List the existing marks and the directories they point to                                       |
+
+## Key bindings
+
+Pressing `CTRL`+`G` substitutes the written mark name for the full path of the mark.
+For example, with a mark named `mymark` pointing to `/path/to/my/mark`:
+```zsh
+$ cp /tmp/file mymark<C-g>
+```
+will become:
+```zsh
+$ cp /tmp/file /path/to/my/mark
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/jump/jump.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/jump/jump.plugin.zsh
new file mode 100644 (file)
index 0000000..c2da114
--- /dev/null
@@ -0,0 +1,59 @@
+# Easily jump around the file system by manually adding marks
+# marks are stored as symbolic links in the directory $MARKPATH (default $HOME/.marks)
+#
+# jump FOO: jump to a mark named FOO
+# mark FOO: create a mark named FOO
+# unmark FOO: delete a mark
+# marks: lists all marks
+#
+export MARKPATH=$HOME/.marks
+
+jump() {
+       builtin cd -P "$MARKPATH/$1" 2>/dev/null || {echo "No such mark: $1"; return 1}
+}
+
+mark() {
+       if [[ $# -eq 0 || "$1" = "." ]]; then
+               MARK=${PWD:t}
+       else
+               MARK="$1"
+       fi
+       if read -q "?Mark $PWD as ${MARK}? (y/n) "; then
+               command mkdir -p "$MARKPATH"
+               command ln -sfn "$PWD" "$MARKPATH/$MARK"
+       fi
+}
+
+unmark() {
+       LANG= command rm -i "$MARKPATH/$1"
+}
+
+marks() {
+       local link max=0
+       for link in $MARKPATH/{,.}*(@N); do
+               if [[ ${#link:t} -gt $max ]]; then
+                       max=${#link:t}
+               fi
+       done
+       local printf_markname_template="$(printf -- "%%%us " "$max")"
+       for link in $MARKPATH/{,.}*(@N); do
+               local markname="$fg[cyan]${link:t}$reset_color"
+               local markpath="$fg[blue]$(readlink $link)$reset_color"
+               printf -- "$printf_markname_template" "$markname"
+               printf -- "-> %s\n" "$markpath"
+       done
+}
+
+_completemarks() {
+       reply=("${MARKPATH}"/{,.}*(@N:t))
+}
+compctl -K _completemarks jump
+compctl -K _completemarks unmark
+
+_mark_expansion() {
+       setopt localoptions extendedglob
+       autoload -U modify-current-argument
+       modify-current-argument '$(readlink "$MARKPATH/$ARG" || echo "$ARG")'
+}
+zle -N _mark_expansion
+bindkey "^g" _mark_expansion
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kate/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kate/README.md
new file mode 100644 (file)
index 0000000..aa2eaa3
--- /dev/null
@@ -0,0 +1,20 @@
+# Kate plugin
+
+This plugin adds aliases for the [Kate editor](https://kate-editor.org).
+
+To use it, add kate to the plugins array of your zshrc file:
+```
+plugins=(... kate)
+```
+
+## Aliases
+
+| Alias | Command                | Description         |
+|-------|------------------------|---------------------|
+| kate  | `kate >/dev/null 2>&1` | Start kate silently |
+
+## Functions
+
+| Function   | Description                              |
+|------------|------------------------------------------|
+| `kt <dir>` | Change to directory and start kate there |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kate/kate.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/kate/kate.plugin.zsh
new file mode 100644 (file)
index 0000000..eb16522
--- /dev/null
@@ -0,0 +1,9 @@
+
+# Kate
+# Start kate always silent
+alias kate='kate >/dev/null 2>&1'
+
+function kt () {
+  cd $1
+  kate $1
+}
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/keychain/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/keychain/README.md
new file mode 100644 (file)
index 0000000..c603f67
--- /dev/null
@@ -0,0 +1,45 @@
+# keychain plugin
+
+This plugin starts automatically [`keychain`](https://www.funtoo.org/Keychain)
+to set up and load whichever credentials you want for both gpg and ssh
+connections.
+
+To enable it, add `keychain` to your plugins:
+
+```zsh
+plugins=(... keychain)
+```
+
+**NOTE**: It is HIGHLY recommended to also enable the `gpg-agent` plugin.
+
+## Instructions
+
+**IMPORTANT: put these settings _before_ the line that sources oh-my-zsh**
+
+**To adjust the agents** that keychain manages, use the `agents` style as
+shown below. By default, only the `gpg` agent is managed.
+
+```zsh
+zstyle :omz:plugins:keychain agents gpg,ssh
+```
+
+To **load multiple identities** use the `identities` style, For example:
+
+```zsh
+zstyle :omz:plugins:keychain identities id_ed25519 id_github 2C5879C2
+```
+
+**To pass additional options** to the `keychain` program, use the
+`options` style; for example:
+
+```zsh
+zstyle :omz:plugins:keychain options --quiet
+```
+
+## Credits
+
+Based on code from the `ssh-agent` plugin.
+
+## References
+
+- [Keychain](https://www.funtoo.org/Keychain)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/keychain/keychain.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/keychain/keychain.plugin.zsh
new file mode 100644 (file)
index 0000000..f122f79
--- /dev/null
@@ -0,0 +1,32 @@
+(( $+commands[keychain] )) || return
+
+# Define SHORT_HOST if not defined (%m = host name up to first .)
+SHORT_HOST=${SHORT_HOST:-${(%):-%m}}
+
+function {
+       local agents
+       local -a identities
+       local -a options
+       local _keychain_env_sh
+       local _keychain_env_sh_gpg
+
+       # load agents to start.
+       zstyle -s :omz:plugins:keychain agents agents
+
+       # load identities to manage.
+       zstyle -a :omz:plugins:keychain identities identities
+
+       # load additional options
+       zstyle -a :omz:plugins:keychain options options
+
+       # start keychain...
+       keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST
+
+       # Get the filenames to store/lookup the environment from
+       _keychain_env_sh="$HOME/.keychain/$SHORT_HOST-sh"
+       _keychain_env_sh_gpg="$HOME/.keychain/$SHORT_HOST-sh-gpg"
+
+       # Source environment settings.
+       [ -f "$_keychain_env_sh" ]     && . "$_keychain_env_sh"
+       [ -f "$_keychain_env_sh_gpg" ] && . "$_keychain_env_sh_gpg"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kitchen/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kitchen/README.md
new file mode 100644 (file)
index 0000000..89a6d70
--- /dev/null
@@ -0,0 +1,9 @@
+# kitchen plugin
+
+This plugin adds completion support for the [Test Kitchen](https://kitchen.ci).
+
+To use it, add `kitchen` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... kitchen)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kitchen/_kitchen b/stow/oh-my-zsh/.oh-my-zsh/plugins/kitchen/_kitchen
new file mode 100644 (file)
index 0000000..d93d93d
--- /dev/null
@@ -0,0 +1,85 @@
+#compdef kitchen
+# ------------------------------------------------------------------------------
+# Copyright (c) 2014 Github zsh-users - https://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for Test Kitchen (https://kitchen.ci/).
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Peter Eisentraut (https://github.com/petere)
+#
+# ------------------------------------------------------------------------------
+
+
+_kitchen() {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+
+  _arguments '1: :->cmds'\
+             '2: :->args'
+
+  case $state in
+    cmds)
+      _kitchen_commands
+      ;;
+    args)
+      case $line[1] in
+        converge|create|destroy|diagnose|list|setup|test|verify)
+          compadd 'all'
+          _kitchen_instances
+          ;;
+        login)
+          _kitchen_instances
+          ;;
+      esac
+      ;;
+  esac
+}
+
+_kitchen_commands() {
+  local commands
+
+  commands=("${(@f)$(_call_program commands $service help | sed -n 's/^  kitchen \([[:alpha:]]*\) [ A-Z[].*# \(.*\)$/\1:\2/p')}")
+  _describe -t commands 'kitchen commands' commands
+}
+
+_kitchen_instances() {
+  if [[ $_kitchen_instances_cache_dir != $PWD ]]; then
+    unset _kitchen_instances_cache
+  fi
+  if [[ ${+_kitchen_instances_cache} -eq 0 ]]; then
+    _kitchen_instances_cache=(${(f)"$(_call_program instances $service list -b 2>/dev/null)"})
+    _kitchen_instances_cache_dir=$PWD
+  fi
+  _wanted instances expl 'instance' compadd -a _kitchen_instances_cache
+}
+
+_kitchen "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kn/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kn/README.md
new file mode 100644 (file)
index 0000000..d2eb9b3
--- /dev/null
@@ -0,0 +1,17 @@
+# kn - Knative CLI
+
+This plugin provides autocompletion for [kn](https://knative.dev/docs/install/client/install-kn/) operations.
+
+To use it, add `kn` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... kn)
+```
+
+## See Also
+
++ [kn/client](https://github.com/knative/client)
+
+## Contributors
+
++ [btannous](https://github.com/btannous) - Plugin Author
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kn/kn.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/kn/kn.plugin.zsh
new file mode 100644 (file)
index 0000000..f60177d
--- /dev/null
@@ -0,0 +1,8 @@
+# Autocompletion for kn, the command line interface for knative
+#
+# Author: https://github.com/btannous
+
+if [ $commands[kn] ]; then
+  source <(kn completion zsh)
+  compdef _kn kn 
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/knife/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/knife/README.md
new file mode 100644 (file)
index 0000000..b167f16
--- /dev/null
@@ -0,0 +1,25 @@
+# knife plugin
+
+This plugin adds completion for [knife](https://docs.chef.io/knife.html), a command-line tool
+to interact with [Chef](https://chef.io), a platform to automate and manage infrastructure via
+code.
+
+To use it, add `knife` to the plugins array in your zshrc file:
+```zsh
+plugins=(... knife)
+```
+
+## Options
+
+- `KNIFE_RELATIVE_PATH`: if set to `true`, the completion script will look for local cookbooks
+  under the `cookbooks` folder in the chef root directory. It has preference over the other two
+  options below. **Default:** empty.
+
+- `KNIFE_COOKBOOK_PATH`: if set, it points to the folder that contains local cookbooks, for
+   example: `/path/to/my/chef/cookbooks`. **Default:** `cookbook_path` field in `knife.rb`
+   (see below).
+
+- `KNIFE_CONF_PATH`: variable pointing to the `knife.rb` configuration file, for example
+  `/path/to/my/.chef/knife.rb`. Only used if `$KNIFE_COOKBOOK_PATH` isn't set. If it exists,
+  `$PWD/.chef/knife.rb` is used instead. Otherwise, if it's set, its value is used.
+  **Default**: `$HOME/.chef/knife.rb`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/knife/_knife b/stow/oh-my-zsh/.oh-my-zsh/plugins/knife/_knife
new file mode 100644 (file)
index 0000000..09757eb
--- /dev/null
@@ -0,0 +1,257 @@
+#compdef knife
+
+# You can override the path to knife.rb and your cookbooks by setting
+# KNIFE_CONF_PATH=/path/to/my/.chef/knife.rb
+# KNIFE_COOKBOOK_PATH=/path/to/my/chef/cookbooks
+# If you want your local cookbooks path to be calculated relative to where you are then
+# set the below option
+# KNIFE_RELATIVE_PATH=true
+# Read around where these are used for more detail.
+
+# These flags should be available everywhere according to man knife
+knife_general_flags=(--help --server-url --key --config --editor --format --log_level --logfile --no-editor --user --print-after --version --yes)
+
+# knife has a very special syntax, some example calls are:
+# knife status
+# knife cookbook list
+# knife role show ROLENAME
+# knife data bag show DATABAGNAME
+# knife role show ROLENAME --attribute ATTRIBUTENAME
+# knife cookbook show COOKBOOKNAME COOKBOOKVERSION recipes
+
+# The -Q switch in compadd allow for completions of things like "data bag" without having to go through two rounds of completion and avoids zsh inserting a \ for escaping spaces
+_knife() {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+  cloudproviders=(bluebox ec2 rackspace slicehost terremark)
+  _arguments \
+    '1: :->knifecmd' \
+    '2: :->knifesubcmd' \
+    '3: :->knifesubcmd2' \
+    '4: :->knifesubcmd3' \
+    '5: :->knifesubcmd4' \
+    '6: :->knifesubcmd5'
+
+  case $state in
+  knifecmd)
+    compadd -Q "$@" bootstrap client configure cookbook "cookbook site" "data bag" diff exec environment index node recipe role search solo ssh status upload vault windows $cloudproviders
+    ;;
+  knifesubcmd)
+    case $words[2] in
+    bluebox|ec2|rackspace|slicehost|terremark)
+      compadd "$@" server images
+      ;;
+    client)
+      compadd -Q "$@" "bulk delete" list create show delete edit reregister
+      ;;
+    configure)
+      compadd "$@" client
+      ;;
+    cookbook)
+      compadd -Q "$@" test list create download delete "metadata from" show "bulk delete" metadata upload
+      ;;
+    diff)
+      _arguments '*:file or directory:_files -g "*"'
+      ;;
+    environment)
+      compadd -Q "$@" list create delete edit show "from file"
+      ;;
+    node)
+      compadd -Q "$@" "from file" create show edit delete list run_list "bulk delete"
+      ;;
+    recipe)
+      compadd "$@" list
+      ;;
+    role)
+      compadd -Q "$@" "bulk delete" create delete edit "from file" list show
+      ;;
+    solo)
+      compadd "$@" bootstrap clean cook init prepare
+      ;;
+    upload)
+      _arguments '*:file or directory:_files -g "*"'
+      ;;
+    vault)
+      compadd -Q "$@" create decrypt delete edit remove "rotate all keys" "rotate keys" show update
+      ;;
+    windows)
+      compadd "$@" bootstrap
+      ;;
+    *)
+      _arguments '2:Subsubcommands:($(_knife_options1))'
+      ;;
+    esac
+    ;;
+  knifesubcmd2)
+    case $words[3] in
+    server)
+      compadd "$@" list create delete
+      ;;
+    images)
+      compadd "$@" list
+      ;;
+    site)
+      compadd "$@" vendor show share search download list unshare
+      ;;
+    show|delete|edit)
+      _arguments '3:Subsubcommands:($(_chef_$words[2]s_remote))'
+      ;;
+    upload|test)
+      _arguments '3:Subsubcommands:($(_chef_$words[2]s_local) --all)'
+      ;;
+    list)
+      compadd -a "$@" knife_general_flags
+      ;;
+    bag)
+      compadd -Q "$@" show edit list "from file" create delete
+      ;;
+    bootstrap|clean|cook|prepare)
+      compadd "$@" nodes/*.json(N:t:r)
+      ;;
+    init)
+      compadd "$@" ./*(/N:t)
+      ;;
+    *)
+      _arguments '3:Subsubcommands:($(_knife_options2))'
+      ;;
+    esac
+    ;;
+  knifesubcmd3)
+    case $words[3] in
+    show)
+      case $words[2] in
+      cookbook)
+        versioncomp=1
+        _arguments '4:Cookbookversions:($(_cookbook_versions) latest)'
+        ;;
+      node|client|role)
+        compadd "$@" --attribute
+        ;;
+      esac
+      ;;
+    esac
+    case $words[4] in
+    show|edit)
+      _arguments '4:Subsubsubcommands:($(_chef_$words[2]_$words[3]s_remote))'
+      ;;
+    file)
+      case $words[2] in
+      environment)
+        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/environments"'
+        ;;
+      node)
+        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/nodes"'
+        ;;
+      role)
+        _arguments '*:files:_path_files -g "*.(rb|json)" -W "$(_chef_root)/roles"'
+        ;;
+      *)
+        _arguments '*:Subsubcommands:($(_knife_options3))'
+        ;;
+      esac
+      ;;
+    list)
+      compadd -a "$@" knife_general_flags
+      ;;
+    *)
+      _arguments '*:Subsubcommands:($(_knife_options3))'
+      ;;
+    esac
+    ;;
+  knifesubcmd4)
+    if ((versioncomp > 0)); then
+      compadd "$@" attributes definitions files libraries providers recipes resources templates
+    else
+      case $words[5] in
+      file)
+        _arguments '*:directory:_path_files -/ -W "$(_chef_root)/data_bags" -qS \ '
+        ;;
+      *) _arguments '*:Subsubcommands:($(_knife_options2))' ;;
+      esac
+    fi
+    ;;
+  knifesubcmd5)
+    case $words[5] in
+    file)
+      _arguments '*:files:_path_files -g "*.json" -W "$(_chef_root)/data_bags/$words[6]"'
+      ;;
+    *)
+      _arguments '*:Subsubcommands:($(_knife_options3))'
+      ;;
+    esac
+    ;;
+  esac
+}
+
+# Helper functions to provide the argument completion for several depths of commands
+_knife_options1() {
+  (for line in $(knife $words[2] --help | grep -v "^knife"); do echo $line | grep "\-\-"; done)
+}
+
+_knife_options2() {
+  (for line in $(knife $words[2] $words[3] --help | grep -v "^knife"); do echo $line | grep "\-\-"; done)
+}
+
+_knife_options3() {
+  (for line in $(knife $words[2] $words[3] $words[4] --help | grep -v "^knife"); do echo $line | grep "\-\-"; done)
+}
+
+# The chef_x_remote functions use knife to get a list of objects of type x on the server
+_chef_roles_remote() {
+  (knife role list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
+}
+
+_chef_clients_remote() {
+  (knife client list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
+}
+
+_chef_nodes_remote() {
+  (knife node list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
+}
+
+_chef_cookbooks_remote() {
+  (knife cookbook list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
+}
+
+_chef_sitecookbooks_remote() {
+  (knife cookbook site list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
+}
+
+_chef_data_bags_remote() {
+  (knife data bag list --format json | grep \" | awk '{print $1}' | awk -F"," '{print $1}' | awk -F"\"" '{print $2}')
+}
+
+_chef_environments_remote() {
+  (knife environment list | awk '{print $1}')
+}
+
+# The chef_x_local functions use the knife config to find the paths of relevant objects x to be uploaded to the server
+_chef_cookbooks_local() {
+  if [ $KNIFE_RELATIVE_PATH ]; then
+    local cookbook_path="$(_chef_root)/cookbooks"
+  else
+    local knife_rb=${KNIFE_CONF_PATH:-${HOME}/.chef/knife.rb}
+    if [ -f ./.chef/knife.rb ]; then
+      knife_rb="./.chef/knife.rb"
+    fi
+    local cookbook_path=${KNIFE_COOKBOOK_PATH:-$(grep cookbook_path $knife_rb | awk 'BEGIN {FS = "[" }; {print $2}' | sed 's/\,//g' | sed "s/'//g" | sed 's/\(.*\)]/\1/')}
+  fi
+  (for i in $cookbook_path; do ls $i; done)
+}
+
+# This function extracts the available cookbook versions on the chef server
+_cookbook_versions() {
+  (knife cookbook show $words[4] | grep -v $words[4] | grep -v -E '\]|\[|\{|\}' | sed 's/ //g' | sed 's/"//g')
+}
+
+# Searches up from current directory to find the closest folder that has a .chef folder
+# Useful for the knife upload/from file commands
+_chef_root() {
+  directory="$PWD"
+  while [ $directory != '/' ]; do
+    test -e "$directory/.chef" && echo "$directory" && return
+    directory="${directory:h}"
+  done
+}
+
+_knife "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/knife_ssh/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/knife_ssh/README.md
new file mode 100644 (file)
index 0000000..cb836b7
--- /dev/null
@@ -0,0 +1,14 @@
+# knife_ssh plugin
+
+This plugin adds a `knife_ssh` function as well as completion for it, to allow
+connecting via ssh to servers managed with [Chef](https://www.chef.io/).
+
+To use it, add `knife_ssh` to the plugins array in your zshrc file:
+```zsh
+plugins=(... knife_ssh)
+```
+
+The plugin creates a cache of the Chef node list via `knife`, and stores it
+in `$HOME/.knife_comp~`, when first triggering knife_ssh completion.
+
+**Requirements:** `knife` has to be installed.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/knife_ssh/knife_ssh.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/knife_ssh/knife_ssh.plugin.zsh
new file mode 100644 (file)
index 0000000..dc425a3
--- /dev/null
@@ -0,0 +1,18 @@
+function knife_ssh() {
+  grep -q $1 ~/.knife_comp~ 2> /dev/null || rm -f ~/.knife_comp~
+  ssh $(knife node show $1 | awk '/IP:/{print $2}')
+}
+
+_knife_ssh() {
+  if hash knife 2>/dev/null; then
+    if [[ ! -f ~/.knife_comp~ ]]; then
+      echo "\nGenerating ~/.knife_comp~..." >&2
+      knife node list > ~/.knife_comp~
+    fi
+    compadd $(< ~/.knife_comp~)
+  else
+    echo "Could not find knife" >&2
+  fi
+}
+
+compdef _knife_ssh knife_ssh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kops/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kops/README.md
new file mode 100644 (file)
index 0000000..5d9b5f8
--- /dev/null
@@ -0,0 +1,12 @@
+# kops
+
+This plugin provides completion for [kops](https://github.com/kubernetes/kops) (Kubernetes Operations),
+the command line interface to get a production grade Kubernetes cluster up and running.
+
+To use it, add `kops` to the plugins array in your zshrc file.
+
+```
+plugins=(... kops)
+```
+
+**Author:** [@nmrony](https://github.com/nmrony)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kops/kops.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/kops/kops.plugin.zsh
new file mode 100644 (file)
index 0000000..0c38ce2
--- /dev/null
@@ -0,0 +1,3 @@
+if [ $commands[kops] ]; then
+  source <(kops completion zsh)
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kube-ps1/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kube-ps1/README.md
new file mode 100644 (file)
index 0000000..1ed3e44
--- /dev/null
@@ -0,0 +1,241 @@
+kube-ps1: Kubernetes prompt for bash and zsh
+============================================
+
+A script that lets you add the current Kubernetes context and namespace
+configured on `kubectl` to your Bash/Zsh prompt strings (i.e. the `$PS1`).
+
+Inspired by several tools used to simplify usage of `kubectl`.
+
+## Installing
+
+### MacOS
+
+Homebrew package manager:
+
+```
+$ brew update
+$ brew install kube-ps1
+```
+### From Source
+
+1. Clone this repository
+2. Source the kube-ps1.sh in your `~/.zshrc` or your `~/.bashrc`
+
+### Arch Linux
+AUR Package available at [https://aur.archlinux.org/packages/kube-ps1/](https://aur.archlinux.org/packages/kube-ps1/).
+
+#### Zsh
+```sh
+source /path/to/kube-ps1.sh
+PROMPT='$(kube_ps1)'$PROMPT
+```
+#### Bash
+```sh
+source /path/to/kube-ps1.sh
+PS1='[\u@\h \W $(kube_ps1)]\$ '
+```
+
+### Zsh Plugin Managers
+
+#### Using [zplugin](https://github.com/zdharma/zplugin)
+
+Update `.zshrc` with:
+```sh
+zplugin light jonmosco/kube-ps1
+PROMPT='$(kube_ps1)'$PROMPT
+```
+
+## Requirements
+
+The default prompt assumes you have the `kubectl` command line utility installed.
+Official installation instructions and binaries are available:
+
+[Install and Set up kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
+
+If using this with OpenShift, the `oc` tool needs installed.  It can be obtained
+from brew ports:
+
+```
+brew install openshift-cli
+```
+or the source can be downloaded:
+
+[OC Client Tools](https://www.openshift.org/download.html)
+
+Set the binary to `oc` with the following environment variable:
+
+```
+KUBE_PS1_BINARY=oc
+```
+
+If neither binary is available, the prompt will print the following:
+
+```
+(<symbol>|BINARY-N/A:N/A)
+```
+
+## Helper utilities
+
+There are several great tools that make using kubectl very enjoyable:
+
+- [`kubectx` and `kubens`](https://github.com/ahmetb/kubectx) are great for
+fast switching between clusters and namespaces.
+
+## Tmux port
+
+I have begun porting kube-ps1 to tmux as a status line plugin.  If you prefer
+tmux, and like the functionality provided by kube-ps1, checkout the
+[kube-tmux](https://github.com/jonmosco/kube-tmux) project
+
+## Prompt Structure
+
+The default prompt layout is:
+
+```
+(<symbol>|<context>:<namespace>)
+```
+
+If the current-context is not set, kube-ps1 will return the following:
+
+```
+(<symbol>|N/A:N/A)
+```
+
+## Enabling/Disabling
+
+If you want to stop showing Kubernetes status on your prompt string temporarily
+run `kubeoff`. To disable the prompt for all shell sessions, run `kubeoff -g`.
+You can enable it again in the current shell by running `kubeon`, and globally
+with `kubeon -g`.
+
+```
+kubeon     : turn on kube-ps1 status for this shell.  Takes precedence over
+             global setting for current session
+kubeon -g  : turn on kube-ps1 status globally
+kubeoff    : turn off kube-ps1 status for this shell. Takes precedence over
+             global setting for current session
+kubeoff -g : turn off kube-ps1 status globally
+```
+
+## Customization
+
+The default settings can be overridden in `~/.bashrc` or `~/.zshrc` by setting
+the following environment variables:
+
+| Variable | Default | Meaning |
+| :------- | :-----: | ------- |
+| `KUBE_PS1_BINARY` | `kubectl` | Default Kubernetes binary |
+| `KUBE_PS1_NS_ENABLE` | `true` | Display the namespace. If set to `false`, this will also disable `KUBE_PS1_DIVIDER` |
+| `KUBE_PS1_PREFIX` | `(` | Prompt opening character  |
+| `KUBE_PS1_SYMBOL_ENABLE` | `true ` | Display the prompt Symbol. If set to `false`, this will also disable `KUBE_PS1_SEPARATOR` |
+| `KUBE_PS1_SYMBOL_PADDING` | `false` | Adds a space (padding) after the symbol to prevent clobbering prompt characters |
+| `KUBE_PS1_SYMBOL_DEFAULT` | `⎈ ` | Default prompt symbol. Unicode `\u2388` |
+| `KUBE_PS1_SYMBOL_USE_IMG` | `false` | ☸️  ,  Unicode `\u2638` as the prompt symbol |
+| `KUBE_PS1_SEPARATOR` | &#124; | Separator between symbol and context name |
+| `KUBE_PS1_DIVIDER` | `:` | Separator between context and namespace |
+| `KUBE_PS1_SUFFIX` | `)` | Prompt closing character |
+| `KUBE_PS1_CLUSTER_FUNCTION` | No default, must be user supplied | Function to customize how cluster is displayed |
+| `KUBE_PS1_NAMESPACE_FUNCTION` | No default, must be user supplied | Function to customize how namespace is displayed |
+
+For terminals that do not support UTF-8, the symbol will be replaced with the
+string `k8s`.
+
+To disable a feature, set it to an empty string:
+
+```
+KUBE_PS1_SEPARATOR=''
+```
+
+## Colors
+
+The default colors are set with the following environment variables:
+
+| Variable | Default | Meaning |
+| :------- | :-----: | ------- |
+| `KUBE_PS1_PREFIX_COLOR` | `null` | Set default color of the prompt prefix |
+| `KUBE_PS1_SYMBOL_COLOR` | `blue` | Set default color of the Kubernetes symbol |
+| `KUBE_PS1_CTX_COLOR` | `red` | Set default color of the context |
+| `KUBE_PS1_SUFFIX_COLOR` | `null` | Set default color of the prompt suffix |
+| `KUBE_PS1_NS_COLOR` | `cyan` | Set default color of the namespace |
+| `KUBE_PS1_BG_COLOR` | `null` | Set default color of the prompt background |
+
+Blue was used for the default symbol to match the Kubernetes color as closely
+as possible. Red was chosen as the context name to stand out, and cyan for the
+namespace.
+
+Set the variable to an empty string if you do not want color for each
+prompt section:
+
+```
+KUBE_PS1_CTX_COLOR=''
+```
+
+Names are usable for the following colors:
+
+```
+black, red, green, yellow, blue, magenta, cyan
+```
+
+256 colors are available by specifying the numerical value as the variable
+argument.
+
+## Customize display of cluster name and namespace
+
+You can change how the cluster name and namespace are displayed using the
+`KUBE_PS1_CLUSTER_FUNCTION` and `KUBE_PS1_NAMESPACE_FUNCTION` variables
+respectively.
+
+For the following examples let's assume the following:
+
+cluster name: `sandbox.k8s.example.com`
+namespace: `alpha`
+
+If you're using domain style cluster names, your prompt will get quite long
+very quickly. Let's say you only want to display the first portion of the
+cluster name (`sandbox`), you could do that by adding the following:
+
+```sh
+function get_cluster_short() {
+  echo "$1" | cut -d . -f1
+}
+
+KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
+```
+
+The same pattern can be followed to customize the display of the namespace.
+Let's say you would prefer the namespace to be displayed in all uppercase
+(`ALPHA`), here's one way you could do that:
+
+```sh
+function get_namespace_upper() {
+    echo "$1" | tr '[:lower:]' '[:upper:]'
+}
+
+export KUBE_PS1_NAMESPACE_FUNCTION=get_namespace_upper
+```
+
+In both cases, the variable is set to the name of the function, and you must have defined the function in your shell configuration before kube_ps1 is called. The function must accept a single parameter and echo out the final value.
+
+### Bug Reports and shell configuration
+
+Due to the vast ways of customizing the shell, please try the prompt with a
+minimal configuration before submitting a bug report.
+
+This can be done as follows for each shell before loading kube-ps1:
+
+Bash:
+```bash
+bash --norc
+```
+
+Zsh:
+```bash
+zsh -f
+or
+zsh --no-rcs
+```
+
+## Contributors
+
+* [Ahmet Alp Balkan](https://github.com/ahmetb)
+* Jared Yanovich
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kube-ps1/kube-ps1.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/kube-ps1/kube-ps1.plugin.zsh
new file mode 100644 (file)
index 0000000..894e0f7
--- /dev/null
@@ -0,0 +1,386 @@
+#!/usr/bin/env bash
+
+# Kubernetes prompt helper for bash/zsh
+# Displays current context and namespace
+
+# Copyright 2021 Jon Mosco
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Debug
+[[ -n $DEBUG ]] && set -x
+
+# Default values for the prompt
+# Override these values in ~/.zshrc or ~/.bashrc
+KUBE_PS1_BINARY="${KUBE_PS1_BINARY:-kubectl}"
+KUBE_PS1_SYMBOL_ENABLE="${KUBE_PS1_SYMBOL_ENABLE:-true}"
+KUBE_PS1_SYMBOL_DEFAULT=${KUBE_PS1_SYMBOL_DEFAULT:-$'\u2388'}
+KUBE_PS1_SYMBOL_PADDING="${KUBE_PS1_SYMBOL_PADDING:-false}"
+KUBE_PS1_SYMBOL_USE_IMG="${KUBE_PS1_SYMBOL_USE_IMG:-false}"
+KUBE_PS1_NS_ENABLE="${KUBE_PS1_NS_ENABLE:-true}"
+KUBE_PS1_CONTEXT_ENABLE="${KUBE_PS1_CONTEXT_ENABLE:-true}"
+KUBE_PS1_PREFIX="${KUBE_PS1_PREFIX-(}"
+KUBE_PS1_SEPARATOR="${KUBE_PS1_SEPARATOR-|}"
+KUBE_PS1_DIVIDER="${KUBE_PS1_DIVIDER-:}"
+KUBE_PS1_SUFFIX="${KUBE_PS1_SUFFIX-)}"
+
+KUBE_PS1_SYMBOL_COLOR="${KUBE_PS1_SYMBOL_COLOR-blue}"
+KUBE_PS1_CTX_COLOR="${KUBE_PS1_CTX_COLOR-red}"
+KUBE_PS1_NS_COLOR="${KUBE_PS1_NS_COLOR-cyan}"
+KUBE_PS1_BG_COLOR="${KUBE_PS1_BG_COLOR}"
+
+KUBE_PS1_KUBECONFIG_CACHE="${KUBECONFIG}"
+KUBE_PS1_DISABLE_PATH="${HOME}/.kube/kube-ps1/disabled"
+KUBE_PS1_LAST_TIME=0
+KUBE_PS1_CLUSTER_FUNCTION="${KUBE_PS1_CLUSTER_FUNCTION}"
+KUBE_PS1_NAMESPACE_FUNCTION="${KUBE_PS1_NAMESPACE_FUNCTION}"
+
+# Determine our shell
+if [ "${ZSH_VERSION-}" ]; then
+  KUBE_PS1_SHELL="zsh"
+elif [ "${BASH_VERSION-}" ]; then
+  KUBE_PS1_SHELL="bash"
+fi
+
+_kube_ps1_init() {
+  [[ -f "${KUBE_PS1_DISABLE_PATH}" ]] && KUBE_PS1_ENABLED=off
+
+  case "${KUBE_PS1_SHELL}" in
+    "zsh")
+      _KUBE_PS1_OPEN_ESC="%{"
+      _KUBE_PS1_CLOSE_ESC="%}"
+      _KUBE_PS1_DEFAULT_BG="%k"
+      _KUBE_PS1_DEFAULT_FG="%f"
+      setopt PROMPT_SUBST
+      autoload -U add-zsh-hook
+      add-zsh-hook precmd _kube_ps1_update_cache
+      zmodload -F zsh/stat b:zstat
+      zmodload zsh/datetime
+      ;;
+    "bash")
+      _KUBE_PS1_OPEN_ESC=$'\001'
+      _KUBE_PS1_CLOSE_ESC=$'\002'
+      _KUBE_PS1_DEFAULT_BG=$'\033[49m'
+      _KUBE_PS1_DEFAULT_FG=$'\033[39m'
+      [[ $PROMPT_COMMAND =~ _kube_ps1_update_cache ]] || PROMPT_COMMAND="_kube_ps1_update_cache;${PROMPT_COMMAND:-:}"
+      ;;
+  esac
+}
+
+_kube_ps1_color_fg() {
+  local KUBE_PS1_FG_CODE
+  case "${1}" in
+    black) KUBE_PS1_FG_CODE=0;;
+    red) KUBE_PS1_FG_CODE=1;;
+    green) KUBE_PS1_FG_CODE=2;;
+    yellow) KUBE_PS1_FG_CODE=3;;
+    blue) KUBE_PS1_FG_CODE=4;;
+    magenta) KUBE_PS1_FG_CODE=5;;
+    cyan) KUBE_PS1_FG_CODE=6;;
+    white) KUBE_PS1_FG_CODE=7;;
+    # 256
+    [0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-6]) KUBE_PS1_FG_CODE="${1}";;
+    *) KUBE_PS1_FG_CODE=default
+  esac
+
+  if [[ "${KUBE_PS1_FG_CODE}" == "default" ]]; then
+    KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
+    return
+  elif [[ "${KUBE_PS1_SHELL}" == "zsh" ]]; then
+    KUBE_PS1_FG_CODE="%F{$KUBE_PS1_FG_CODE}"
+  elif [[ "${KUBE_PS1_SHELL}" == "bash" ]]; then
+    if tput setaf 1 &> /dev/null; then
+      KUBE_PS1_FG_CODE="$(tput setaf ${KUBE_PS1_FG_CODE})"
+    elif [[ $KUBE_PS1_FG_CODE -ge 0 ]] && [[ $KUBE_PS1_FG_CODE -le 256 ]]; then
+      KUBE_PS1_FG_CODE="\033[38;5;${KUBE_PS1_FG_CODE}m"
+    else
+      KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
+    fi
+  fi
+  echo ${_KUBE_PS1_OPEN_ESC}${KUBE_PS1_FG_CODE}${_KUBE_PS1_CLOSE_ESC}
+}
+
+_kube_ps1_color_bg() {
+  local KUBE_PS1_BG_CODE
+  case "${1}" in
+    black) KUBE_PS1_BG_CODE=0;;
+    red) KUBE_PS1_BG_CODE=1;;
+    green) KUBE_PS1_BG_CODE=2;;
+    yellow) KUBE_PS1_BG_CODE=3;;
+    blue) KUBE_PS1_BG_CODE=4;;
+    magenta) KUBE_PS1_BG_CODE=5;;
+    cyan) KUBE_PS1_BG_CODE=6;;
+    white) KUBE_PS1_BG_CODE=7;;
+    # 256
+    [0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-6]) KUBE_PS1_BG_CODE="${1}";;
+    *) KUBE_PS1_BG_CODE=$'\033[0m';;
+  esac
+
+  if [[ "${KUBE_PS1_BG_CODE}" == "default" ]]; then
+    KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_BG}"
+    return
+  elif [[ "${KUBE_PS1_SHELL}" == "zsh" ]]; then
+    KUBE_PS1_BG_CODE="%K{$KUBE_PS1_BG_CODE}"
+  elif [[ "${KUBE_PS1_SHELL}" == "bash" ]]; then
+    if tput setaf 1 &> /dev/null; then
+      KUBE_PS1_BG_CODE="$(tput setab ${KUBE_PS1_BG_CODE})"
+    elif [[ $KUBE_PS1_BG_CODE -ge 0 ]] && [[ $KUBE_PS1_BG_CODE -le 256 ]]; then
+      KUBE_PS1_BG_CODE="\033[48;5;${KUBE_PS1_BG_CODE}m"
+    else
+      KUBE_PS1_BG_CODE="${DEFAULT_BG}"
+    fi
+  fi
+  echo ${OPEN_ESC}${KUBE_PS1_BG_CODE}${CLOSE_ESC}
+}
+
+_kube_ps1_binary_check() {
+  command -v $1 >/dev/null
+}
+
+_kube_ps1_symbol() {
+  [[ "${KUBE_PS1_SYMBOL_ENABLE}" == false ]] && return
+
+  case "${KUBE_PS1_SHELL}" in
+    bash)
+      if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388' != "\\u2388" ]]; then
+        KUBE_PS1_SYMBOL="${KUBE_PS1_SYMBOL_DEFAULT}"
+        KUBE_PS1_SYMBOL_IMG=$'\u2638\ufe0f'
+      else
+        KUBE_PS1_SYMBOL=$'\xE2\x8E\x88'
+        KUBE_PS1_SYMBOL_IMG=$'\xE2\x98\xB8'
+      fi
+      ;;
+    zsh)
+      KUBE_PS1_SYMBOL="${KUBE_PS1_SYMBOL_DEFAULT}"
+      KUBE_PS1_SYMBOL_IMG="\u2638";;
+    *)
+      KUBE_PS1_SYMBOL="k8s"
+  esac
+
+  if [[ "${KUBE_PS1_SYMBOL_USE_IMG}" == true ]]; then
+    KUBE_PS1_SYMBOL="${KUBE_PS1_SYMBOL_IMG}"
+  fi
+
+  if [[ "${KUBE_PS1_SYMBOL_PADDING}" == true ]]; then
+    echo "${KUBE_PS1_SYMBOL} "
+  else
+    echo "${KUBE_PS1_SYMBOL}"
+  fi
+
+}
+
+_kube_ps1_split() {
+  type setopt >/dev/null 2>&1 && setopt SH_WORD_SPLIT
+  local IFS=$1
+  echo $2
+}
+
+_kube_ps1_file_newer_than() {
+  local mtime
+  local file=$1
+  local check_time=$2
+
+  if [[ "${KUBE_PS1_SHELL}" == "zsh" ]]; then
+    mtime=$(zstat +mtime "${file}")
+  elif stat -c "%s" /dev/null &> /dev/null; then
+    # GNU stat
+    mtime=$(stat -L -c %Y "${file}")
+  else
+    # BSD stat
+    mtime=$(stat -L -f %m "$file")
+  fi
+
+  [[ "${mtime}" -gt "${check_time}" ]]
+}
+
+_kube_ps1_update_cache() {
+  local return_code=$?
+
+  [[ "${KUBE_PS1_ENABLED}" == "off" ]] && return $return_code
+
+  if ! _kube_ps1_binary_check "${KUBE_PS1_BINARY}"; then
+    # No ability to fetch context/namespace; display N/A.
+    KUBE_PS1_CONTEXT="BINARY-N/A"
+    KUBE_PS1_NAMESPACE="N/A"
+    return
+  fi
+
+  if [[ "${KUBECONFIG}" != "${KUBE_PS1_KUBECONFIG_CACHE}" ]]; then
+    # User changed KUBECONFIG; unconditionally refetch.
+    KUBE_PS1_KUBECONFIG_CACHE=${KUBECONFIG}
+    _kube_ps1_get_context_ns
+    return
+  fi
+
+  # kubectl will read the environment variable $KUBECONFIG
+  # otherwise set it to ~/.kube/config
+  local conf
+  for conf in $(_kube_ps1_split : "${KUBECONFIG:-${HOME}/.kube/config}"); do
+    [[ -r "${conf}" ]] || continue
+    if _kube_ps1_file_newer_than "${conf}" "${KUBE_PS1_LAST_TIME}"; then
+      _kube_ps1_get_context_ns
+      return
+    fi
+  done
+
+  return $return_code
+}
+
+_kube_ps1_get_context() {
+  if [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then
+    KUBE_PS1_CONTEXT="$(${KUBE_PS1_BINARY} config current-context 2>/dev/null)"
+    # Set namespace to 'N/A' if it is not defined
+    KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}"
+
+    if [[ ! -z "${KUBE_PS1_CLUSTER_FUNCTION}" ]]; then
+      KUBE_PS1_CONTEXT=$($KUBE_PS1_CLUSTER_FUNCTION $KUBE_PS1_CONTEXT)
+    fi
+  fi
+}
+
+_kube_ps1_get_ns() {
+  if [[ "${KUBE_PS1_NS_ENABLE}" == true ]]; then
+    KUBE_PS1_NAMESPACE="$(${KUBE_PS1_BINARY} config view --minify --output 'jsonpath={..namespace}' 2>/dev/null)"
+    # Set namespace to 'default' if it is not defined
+    KUBE_PS1_NAMESPACE="${KUBE_PS1_NAMESPACE:-default}"
+
+    if [[ ! -z "${KUBE_PS1_NAMESPACE_FUNCTION}" ]]; then
+        KUBE_PS1_NAMESPACE=$($KUBE_PS1_NAMESPACE_FUNCTION $KUBE_PS1_NAMESPACE)
+    fi
+  fi
+}
+
+_kube_ps1_get_context_ns() {
+  # Set the command time
+  if [[ "${KUBE_PS1_SHELL}" == "bash" ]]; then
+    if ((BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 2)); then
+      KUBE_PS1_LAST_TIME=$(printf '%(%s)T')
+    else
+      KUBE_PS1_LAST_TIME=$(date +%s)
+    fi
+  elif [[ "${KUBE_PS1_SHELL}" == "zsh" ]]; then
+    KUBE_PS1_LAST_TIME=$EPOCHSECONDS
+  fi
+
+  _kube_ps1_get_context
+  _kube_ps1_get_ns
+}
+
+# Set kube-ps1 shell defaults
+_kube_ps1_init
+
+_kubeon_usage() {
+  cat <<"EOF"
+Toggle kube-ps1 prompt on
+
+Usage: kubeon [-g | --global] [-h | --help]
+
+With no arguments, turn off kube-ps1 status for this shell instance (default).
+
+  -g --global  turn on kube-ps1 status globally
+  -h --help    print this message
+EOF
+}
+
+_kubeoff_usage() {
+  cat <<"EOF"
+Toggle kube-ps1 prompt off
+
+Usage: kubeoff [-g | --global] [-h | --help]
+
+With no arguments, turn off kube-ps1 status for this shell instance (default).
+
+  -g --global turn off kube-ps1 status globally
+  -h --help   print this message
+EOF
+}
+
+kubeon() {
+  if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
+    _kubeon_usage
+  elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
+    rm -f -- "${KUBE_PS1_DISABLE_PATH}"
+  elif [[ "$#" -ne 0 ]]; then
+    echo -e "error: unrecognized flag ${1}\\n"
+    _kubeon_usage
+    return
+  fi
+
+  KUBE_PS1_ENABLED=on
+}
+
+kubeoff() {
+  if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
+    _kubeoff_usage
+  elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
+    mkdir -p -- "$(dirname "${KUBE_PS1_DISABLE_PATH}")"
+    touch -- "${KUBE_PS1_DISABLE_PATH}"
+  elif [[ $# -ne 0 ]]; then
+    echo "error: unrecognized flag ${1}" >&2
+    _kubeoff_usage
+    return
+  fi
+
+  KUBE_PS1_ENABLED=off
+}
+
+# Build our prompt
+kube_ps1() {
+  [[ "${KUBE_PS1_ENABLED}" == "off" ]] && return
+  [[ -z "${KUBE_PS1_CONTEXT}" ]] && [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]] && return
+
+  local KUBE_PS1
+  local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}"
+
+  # Background Color
+  [[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="$(_kube_ps1_color_bg ${KUBE_PS1_BG_COLOR})"
+
+  # Prefix
+  if [[ -z "${KUBE_PS1_PREFIX_COLOR:-}" ]] && [[ -n "${KUBE_PS1_PREFIX}" ]]; then
+      KUBE_PS1+="${KUBE_PS1_PREFIX}"
+  else
+      KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_PREFIX_COLOR)${KUBE_PS1_PREFIX}${KUBE_PS1_RESET_COLOR}"
+  fi
+
+  # Symbol
+  KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_SYMBOL_COLOR)$(_kube_ps1_symbol)${KUBE_PS1_RESET_COLOR}"
+
+  if [[ -n "${KUBE_PS1_SEPARATOR}" ]] && [[ "${KUBE_PS1_SYMBOL_ENABLE}" == true ]]; then
+    KUBE_PS1+="${KUBE_PS1_SEPARATOR}"
+  fi
+
+  # Context
+  if [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then
+    KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_CTX_COLOR)${KUBE_PS1_CONTEXT}${KUBE_PS1_RESET_COLOR}"
+  fi
+
+  # Namespace
+  if [[ "${KUBE_PS1_NS_ENABLE}" == true ]]; then
+    if [[ -n "${KUBE_PS1_DIVIDER}" ]] && [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then
+      KUBE_PS1+="${KUBE_PS1_DIVIDER}"
+    fi
+    KUBE_PS1+="$(_kube_ps1_color_fg ${KUBE_PS1_NS_COLOR})${KUBE_PS1_NAMESPACE}${KUBE_PS1_RESET_COLOR}"
+  fi
+
+  # Suffix
+  if [[ -z "${KUBE_PS1_SUFFIX_COLOR:-}" ]] && [[ -n "${KUBE_PS1_SUFFIX}" ]]; then
+      KUBE_PS1+="${KUBE_PS1_SUFFIX}"
+  else
+      KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_SUFFIX_COLOR)${KUBE_PS1_SUFFIX}${KUBE_PS1_RESET_COLOR}"
+  fi
+
+  # Close Background color if defined
+  [[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_BG}${_KUBE_PS1_CLOSE_ESC}"
+
+  echo "${KUBE_PS1}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectl/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectl/README.md
new file mode 100644 (file)
index 0000000..579a90b
--- /dev/null
@@ -0,0 +1,137 @@
+# Kubectl plugin
+
+This plugin adds completion for the [Kubernetes cluster manager](https://kubernetes.io/docs/reference/kubectl/kubectl/),
+as well as some aliases for common kubectl commands.
+
+To use it, add `kubectl` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... kubectl)
+```
+
+## Aliases
+
+| Alias   | Command                             | Description                                                                                      |
+|:--------|:------------------------------------|:-------------------------------------------------------------------------------------------------|
+| k       | `kubectl`                           | The kubectl command                                                                              |
+| kca     | `kubectl --all-namespaces`          | The kubectl command targeting all namespaces                                                     |
+| kaf     | `kubectl apply -f`                  | Apply a YML file                                                                                 |
+| keti    | `kubectl exec -ti`                  | Drop into an interactive terminal on a container                                                 |
+|         |                                     | **Manage configuration quickly to switch contexts between local, dev and staging**               |
+| kcuc    | `kubectl config use-context`        | Set the current-context in a kubeconfig file                                                     |
+| kcsc    | `kubectl config set-context`        | Set a context entry in kubeconfig                                                                |
+| kcdc    | `kubectl config delete-context`     | Delete the specified context from the kubeconfig                                                 |
+| kccc    | `kubectl config current-context`    | Display the current-context                                                                      |
+| kcgc    | `kubectl config get-contexts`       | List of contexts available                                                                       |
+|         |                                     | **General aliases**                                                                              |
+| kdel    | `kubectl delete`                    | Delete resources by filenames, stdin, resources and names, or by resources and label selector    |
+| kdelf   | `kubectl delete -f`                 | Delete a pod using the type and name specified in -f argument                                    |
+|         |                                     | **Pod management**                                                                               |
+| kgp     | `kubectl get pods`                  | List all pods in ps output format                                                                |
+| kgpw    | `kgp --watch`                       | After listing/getting the requested object, watch for changes                                    |
+| kgpwide | `kgp -o wide`                       | Output in plain-text format with any additional information. For pods, the node name is included |
+| kep     | `kubectl edit pods`                 | Edit pods from the default editor                                                                |
+| kdp     | `kubectl describe pods`             | Describe all pods                                                                                |
+| kdelp   | `kubectl delete pods`               | Delete all pods matching passed arguments                                                        |
+| kgpl    | `kgp -l`                            | Get pods by label. Example: `kgpl "app=myapp" -n myns`                                           |
+| kgpn    | `kgp -n`                            | Get pods by namespace. Example: `kgpn kube-system`                                               |
+|         |                                     | **Service management**                                                                           |
+| kgs     | `kubectl get svc`                   | List all services in ps output format                                                            |
+| kgsw    | `kgs --watch`                       | After listing all services, watch for changes                                                    |
+| kgswide | `kgs -o wide`                       | After listing all services, output in plain-text format with any additional information          |
+| kes     | `kubectl edit svc`                  | Edit services(svc) from the default editor                                                       |
+| kds     | `kubectl describe svc`              | Describe all services in detail                                                                  |
+| kdels   | `kubectl delete svc`                | Delete all services matching passed argument                                                     |
+|         |                                     | **Ingress management**                                                                           |
+| kgi     | `kubectl get ingress`               | List ingress resources in ps output format                                                       |
+| kei     | `kubectl edit ingress`              | Edit ingress resource from the default editor                                                    |
+| kdi     | `kubectl describe ingress`          | Describe ingress resource in detail                                                              |
+| kdeli   | `kubectl delete ingress`            | Delete ingress resources matching passed argument                                                |
+|         |                                     | **Namespace management**                                                                         |
+| kgns    | `kubectl get namespaces`            | List the current namespaces in a cluster                                                         |
+| kcn     | `kubectl config set-context --current --namespace` | Change current namespace |
+| kens    | `kubectl edit namespace`            | Edit namespace resource from the default editor                                                  |
+| kdns    | `kubectl describe namespace`        | Describe namespace resource in detail                                                            |
+| kdelns  | `kubectl delete namespace`          | Delete the namespace. WARNING! This deletes everything in the namespace                          |
+|         |                                     | **ConfigMap management**                                                                         |
+| kgcm    | `kubectl get configmaps`            | List the configmaps in ps output format                                                          |
+| kecm    | `kubectl edit configmap`            | Edit configmap resource from the default editor                                                  |
+| kdcm    | `kubectl describe configmap`        | Describe configmap resource in detail                                                            |
+| kdelcm  | `kubectl delete configmap`          | Delete the configmap                                                                             |
+|         |                                     | **Secret management**                                                                            |
+| kgsec   | `kubectl get secret`                | Get secret for decoding                                                                          |
+| kdsec   | `kubectl describe secret`           | Describe secret resource in detail                                                               |
+| kdelsec | `kubectl delete secret`             | Delete the secret                                                                                |
+|         |                                     | **Deployment management**                                                                        |
+| kgd     | `kubectl get deployment`            | Get the deployment                                                                               |
+| kgdw    | `kgd --watch`                       | After getting the deployment, watch for changes                                                  |
+| kgdwide | `kgd -o wide`                       | After getting the deployment, output in plain-text format with any additional information        |
+| ked     | `kubectl edit deployment`           | Edit deployment resource from the default editor                                                 |
+| kdd     | `kubectl describe deployment`       | Describe deployment resource in detail                                                           |
+| kdeld   | `kubectl delete deployment`         | Delete the deployment                                                                            |
+| ksd     | `kubectl scale deployment`          | Scale a deployment                                                                               |
+| krsd    | `kubectl rollout status deployment` | Check the rollout status of a deployment                                                         |
+| kres    | `kubectl set env $@ REFRESHED_AT=...` | Recreate all pods in deployment with zero-downtime                                             |
+|         |                                     | **Rollout management**                                                                           |
+| kgrs    | `kubectl get replicaset`            | List all ReplicaSets `rs` created by the deployment                                              |
+| kdrs    | `kubectl describe replicaset`       | Describe ReplicaSet in detail                                                                    |
+| kers    | `kubectl edit replicaset`           | Edit ReplicaSet from the default editor                                                          |
+| krh     | `kubectl rollout history`           | Check the revisions of this deployment                                                           |
+| kru     | `kubectl rollout undo`              | Rollback to the previous revision                                                                |
+|         |                                     | **Port forwarding**                                                                              |
+| kpf     | `kubectl port-forward`              | Forward one or more local ports to a pod                                                         |
+|         |                                     | **Tools for accessing all information**                                                          |
+| kga     | `kubectl get all`                   | List all resources in ps format                                                                  |
+| kgaa    | `kubectl get all --all-namespaces`  | List the requested object(s) across all namespaces                                               |
+|         |                                     | **Logs**                                                                                         |
+| kl      | `kubectl logs`                      | Print the logs for a container or resource                                                       |
+| klf     | `kubectl logs -f`                   | Stream the logs for a container or resource (follow)                                             |
+|         |                                     | **File copy**                                                                                    |
+| kcp     | `kubectl cp`                        | Copy files and directories to and from containers                                                |
+|         |                                     | **Node management**                                                                              |
+| kgno    | `kubectl get nodes`                 | List the nodes in ps output format                                                               |
+| keno    | `kubectl edit node`                 | Edit nodes resource from the default editor                                                      |
+| kdno    | `kubectl describe node`             | Describe node resource in detail                                                                 |
+| kdelno  | `kubectl delete node`               | Delete the node                                                                                  |
+|         |                                     | **Persistent Volume Claim management**                                                           |
+| kgpvc   | `kubectl get pvc`                   | List all PVCs                                                                                    |
+| kgpvcw  | `kgpvc --watch`                     | After listing/getting the requested object, watch for changes                                    |
+| kepvc   | `kubectl edit pvc`                  | Edit pvcs from the default editor                                                                |
+| kdpvc   | `kubectl describe pvc`              | Describe all pvcs                                                                                |
+| kdelpvc | `kubectl delete pvc`                | Delete all pvcs matching passed arguments                                                        |
+|         |                                     | **StatefulSets management**                                                                      |
+| kgss    | `kubectl get statefulset`           | List the statefulsets in ps format                                                               |
+| kgssw   | `kgss --watch`                      | After getting the list of statefulsets, watch for changes                                        |
+| kgsswide| `kgss -o wide`                      | After getting the statefulsets, output in plain-text format with any additional information      |
+| kess    | `kubectl edit statefulset`          | Edit statefulset resource from the default editor                                                |
+| kdss    | `kubectl describe statefulset`      | Describe statefulset resource in detail                                                          |
+| kdelss  | `kubectl delete statefulset`        | Delete the statefulset                                                                           |
+| ksss    | `kubectl scale statefulset`         | Scale a statefulset                                                                              |
+| krsss   | `kubectl rollout status statefulset`| Check the rollout status of a deployment                                                         |
+|         |                                     | **Service Accounts management**                                                                  |
+| kdsa    | `kubectl describe sa`               | Describe a service account in details                                                            |
+| kdelsa  | `kubectl delete sa`                 | Delete the service account                                                                       |
+|         |                                     | **DaemonSet management**                                                                         |
+| kgds    | `kubectl get daemonset`             | List all DaemonSets in ps output format                                                          |
+| kgdsw   | `kgds --watch`                      | After listing all DaemonSets, watch for changes                                                  |
+| keds    | `kubectl edit daemonset`            | Edit DaemonSets from the default editor                                                          |
+| kdds    | `kubectl describe daemonset`        | Describe all DaemonSets in detail                                                                |
+| kdelds  | `kubectl delete daemonset`          | Delete all DaemonSets matching passed argument                                                   |
+|         |                                     | **CronJob management**                                                                           |
+| kgcj    | `kubectl get cronjob`               | List all CronJobs in ps output format                                                            |
+| kecj    | `kubectl edit cronjob`              | Edit CronJob from the default editor                                                             |
+| kdcj    | `kubectl describe cronjob`          | Describe a CronJob in details                                                                    |
+| kdelcj  | `kubectl delete cronjob`            | Delete the CronJob                                                                               |
+|         |                                     | **Job management**                                                                               |
+| kgj     | `kubectl get job`                   | List all Job in ps output format                                                                 |
+| kej     | `kubectl edit job`                  | Edit a Job in details                                                                            |
+| kdj     | `kubectl describe job`              | Describe the Job                                                                                 |
+| kdelj   | `kubectl delete job`                | Delete the Job                                                                                   |
+
+## Wrappers
+
+This plugin provides 3 wrappers to colorize kubectl output in JSON and YAML using various tools (which must be installed):
+
+- `kj`: JSON, colorized with [`jq`](https://stedolan.github.io/jq/).
+- `kjx`: JSON, colorized with [`fx`](https://github.com/antonmedv/fx).
+- `ky`: YAML, colorized with [`yh`](https://github.com/andreazorzetto/yh).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectl/kubectl.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectl/kubectl.plugin.zsh
new file mode 100644 (file)
index 0000000..095d2b3
--- /dev/null
@@ -0,0 +1,189 @@
+if (( $+commands[kubectl] )); then
+  # If the completion file does not exist, generate it and then source it
+  # Otherwise, source it and regenerate in the background
+  if [[ ! -f "$ZSH_CACHE_DIR/completions/_kubectl" ]]; then
+    kubectl completion zsh | tee "$ZSH_CACHE_DIR/completions/_kubectl" >/dev/null
+    source "$ZSH_CACHE_DIR/completions/_kubectl"
+  else
+    source "$ZSH_CACHE_DIR/completions/_kubectl"
+    kubectl completion zsh | tee "$ZSH_CACHE_DIR/completions/_kubectl" >/dev/null &|
+  fi
+fi
+
+# This command is used a LOT both below and in daily life
+alias k=kubectl
+
+# Execute a kubectl command against all namespaces
+alias kca='_kca(){ kubectl "$@" --all-namespaces;  unset -f _kca; }; _kca'
+
+# Apply a YML file
+alias kaf='kubectl apply -f'
+
+# Drop into an interactive terminal on a container
+alias keti='kubectl exec -t -i'
+
+# Manage configuration quickly to switch contexts between local, dev ad staging.
+alias kcuc='kubectl config use-context'
+alias kcsc='kubectl config set-context'
+alias kcdc='kubectl config delete-context'
+alias kccc='kubectl config current-context'
+
+# List all contexts
+alias kcgc='kubectl config get-contexts'
+
+# General aliases
+alias kdel='kubectl delete'
+alias kdelf='kubectl delete -f'
+
+# Pod management.
+alias kgp='kubectl get pods'
+alias kgpa='kubectl get pods --all-namespaces'
+alias kgpw='kgp --watch'
+alias kgpwide='kgp -o wide'
+alias kep='kubectl edit pods'
+alias kdp='kubectl describe pods'
+alias kdelp='kubectl delete pods'
+alias kgpall='kubectl get pods --all-namespaces -o wide'
+
+# get pod by label: kgpl "app=myapp" -n myns
+alias kgpl='kgp -l'
+
+# get pod by namespace: kgpn kube-system"
+alias kgpn='kgp -n'
+
+# Service management.
+alias kgs='kubectl get svc'
+alias kgsa='kubectl get svc --all-namespaces'
+alias kgsw='kgs --watch'
+alias kgswide='kgs -o wide'
+alias kes='kubectl edit svc'
+alias kds='kubectl describe svc'
+alias kdels='kubectl delete svc'
+
+# Ingress management
+alias kgi='kubectl get ingress'
+alias kgia='kubectl get ingress --all-namespaces'
+alias kei='kubectl edit ingress'
+alias kdi='kubectl describe ingress'
+alias kdeli='kubectl delete ingress'
+
+# Namespace management
+alias kgns='kubectl get namespaces'
+alias kens='kubectl edit namespace'
+alias kdns='kubectl describe namespace'
+alias kdelns='kubectl delete namespace'
+alias kcn='kubectl config set-context --current --namespace'
+
+# ConfigMap management
+alias kgcm='kubectl get configmaps'
+alias kgcma='kubectl get configmaps --all-namespaces'
+alias kecm='kubectl edit configmap'
+alias kdcm='kubectl describe configmap'
+alias kdelcm='kubectl delete configmap'
+
+# Secret management
+alias kgsec='kubectl get secret'
+alias kgseca='kubectl get secret --all-namespaces'
+alias kdsec='kubectl describe secret'
+alias kdelsec='kubectl delete secret'
+
+# Deployment management.
+alias kgd='kubectl get deployment'
+alias kgda='kubectl get deployment --all-namespaces'
+alias kgdw='kgd --watch'
+alias kgdwide='kgd -o wide'
+alias ked='kubectl edit deployment'
+alias kdd='kubectl describe deployment'
+alias kdeld='kubectl delete deployment'
+alias ksd='kubectl scale deployment'
+alias krsd='kubectl rollout status deployment'
+
+function kres(){
+  kubectl set env $@ REFRESHED_AT=$(date +%Y%m%d%H%M%S)
+}
+
+# Rollout management.
+alias kgrs='kubectl get replicaset'
+alias kdrs='kubectl describe replicaset'
+alias kers='kubectl edit replicaset'
+alias krh='kubectl rollout history'
+alias kru='kubectl rollout undo'
+
+# Statefulset management.
+alias kgss='kubectl get statefulset'
+alias kgssa='kubectl get statefulset --all-namespaces'
+alias kgssw='kgss --watch'
+alias kgsswide='kgss -o wide'
+alias kess='kubectl edit statefulset'
+alias kdss='kubectl describe statefulset'
+alias kdelss='kubectl delete statefulset'
+alias ksss='kubectl scale statefulset'
+alias krsss='kubectl rollout status statefulset'
+
+# Port forwarding
+alias kpf="kubectl port-forward"
+
+# Tools for accessing all information
+alias kga='kubectl get all'
+alias kgaa='kubectl get all --all-namespaces'
+
+# Logs
+alias kl='kubectl logs'
+alias kl1h='kubectl logs --since 1h'
+alias kl1m='kubectl logs --since 1m'
+alias kl1s='kubectl logs --since 1s'
+alias klf='kubectl logs -f'
+alias klf1h='kubectl logs --since 1h -f'
+alias klf1m='kubectl logs --since 1m -f'
+alias klf1s='kubectl logs --since 1s -f'
+
+# File copy
+alias kcp='kubectl cp'
+
+# Node Management
+alias kgno='kubectl get nodes'
+alias keno='kubectl edit node'
+alias kdno='kubectl describe node'
+alias kdelno='kubectl delete node'
+
+# PVC management.
+alias kgpvc='kubectl get pvc'
+alias kgpvca='kubectl get pvc --all-namespaces'
+alias kgpvcw='kgpvc --watch'
+alias kepvc='kubectl edit pvc'
+alias kdpvc='kubectl describe pvc'
+alias kdelpvc='kubectl delete pvc'
+
+# Service account management.
+alias kdsa="kubectl describe sa"
+alias kdelsa="kubectl delete sa"
+
+# DaemonSet management.
+alias kgds='kubectl get daemonset'
+alias kgdsw='kgds --watch'
+alias keds='kubectl edit daemonset'
+alias kdds='kubectl describe daemonset'
+alias kdelds='kubectl delete daemonset'
+
+# CronJob management.
+alias kgcj='kubectl get cronjob'
+alias kecj='kubectl edit cronjob'
+alias kdcj='kubectl describe cronjob'
+alias kdelcj='kubectl delete cronjob'
+
+# Job management.
+alias kgj='kubectl get job'
+alias kej='kubectl edit job'
+alias kdj='kubectl describe job'
+alias kdelj='kubectl delete job'
+
+# Only run if the user actually has kubectl installed
+if (( ${+_comps[kubectl]} )); then
+  function kj() { kubectl "$@" -o json | jq; }
+  function kjx() { kubectl "$@" -o json | fx; }
+  function ky() { kubectl "$@" -o yaml | yh; }
+
+  compdef kj=kubectl
+  compdef kjx=kubectl
+  compdef ky=kubectl
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/README.md
new file mode 100644 (file)
index 0000000..98f1cf0
--- /dev/null
@@ -0,0 +1,26 @@
+# kubectx - show active kubectl context
+
+This plugins adds ```kubectx_prompt_info()``` function. It shows name of the
+active kubectl context (```kubectl config current-context```).
+
+You can use it to customize prompt and know if You are on prod cluster ;)
+
+_Example_. Add to **.zshrc**:
+
+```
+RPS1='$(kubectx_prompt_info)'
+```
+
+### custom ctx names
+
+One can rename default context name for better readability.
+
+_Example_. Add to **.zshrc**:
+```
+kubectx_mapping[minikube]="mini"
+kubectx_mapping[context_name_from_kubeconfig]="$emoji[wolf_face]"
+kubectx_mapping[production_cluster]="%{$fg[yellow]%}prod!%{$reset_color%}"
+```
+
+![staging](stage.png)
+![production](prod.png)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/kubectx.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/kubectx.plugin.zsh
new file mode 100644 (file)
index 0000000..6096fee
--- /dev/null
@@ -0,0 +1,13 @@
+typeset -g -A kubectx_mapping
+
+function kubectx_prompt_info() {
+  (( $+commands[kubectl] )) || return
+
+  local current_ctx=$(kubectl config current-context 2> /dev/null)
+
+  [[ -n "$current_ctx" ]] || return
+
+  # use value in associative array if it exists
+  # otherwise fall back to the context name
+  echo "${kubectx_mapping[$current_ctx]:-${current_ctx:gs/%/%%}}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/prod.png b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/prod.png
new file mode 100644 (file)
index 0000000..0c194a6
Binary files /dev/null and b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/prod.png differ
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/stage.png b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/stage.png
new file mode 100644 (file)
index 0000000..ac15b39
Binary files /dev/null and b/stow/oh-my-zsh/.oh-my-zsh/plugins/kubectx/stage.png differ
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lando/LICENSE b/stow/oh-my-zsh/.oh-my-zsh/plugins/lando/LICENSE
new file mode 100644 (file)
index 0000000..1d49831
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Joshua Bedford
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lando/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/lando/README.md
new file mode 100644 (file)
index 0000000..928a42b
--- /dev/null
@@ -0,0 +1,37 @@
+# Lando ZSH (lando-zsh)
+
+This plugin adds aliases for using various languages and frameworks with [Lando](https://docs.lando.dev/basics/) for Docker. It will only run within lando-driven project directories.
+
+To use it, add `lando` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... lando)
+```
+
+## ALIASES:
+
+| Alias      | Description      |
+|:----------:|:----------------:|
+| `artisan`  | `lando artisan`  |
+| `composer` | `lando composer` |
+| `drush`    | `lando drush`    |
+| `gulp`     | `lando gulp`     |
+| `npm`      | `lando npm`      |
+| `wp`       | `lando wp`       |
+| `yarn`     | `lando yarn`     |
+
+## How It Works:
+
+This plugin removes the requirement to type `lando` before a command. It utilizes the lando version of supported commands run within directories with the following criteria:
+- The `.lando.yml` file is found in the current directory or any parent directory within `$LANDO_ZSH_SITES_DIRECTORY`.
+- The current directory is within `$LANDO_ZSH_SITES_DIRECTORY` but is not `$LANDO_ZSH_SITES_DIRECTORY` itself.
+
+## Settings:
+
+- `LANDO_ZSH_SITES_DIRECTORY`: The plugin will stop searching through parents for `CONFIG_FILE` once it hits this directory.
+- `LANDO_ZSH_CONFIG_FILE`: The plugin will check to see if this provided file exists to check for presence of Lando.
+
+## Author:
+
+- Author: Joshua Bedford
+- URL: [https://github.com/joshuabedford/lando-zsh](https://github.com/joshuabedford/lando-zsh)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lando/lando.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/lando/lando.plugin.zsh
new file mode 100644 (file)
index 0000000..af53e7e
--- /dev/null
@@ -0,0 +1,41 @@
+# Settings
+: ${LANDO_ZSH_SITES_DIRECTORY:="$HOME/Sites"}
+: ${LANDO_ZSH_CONFIG_FILE:=.lando.yml}
+
+# Enable multiple commands with lando.
+function artisan \
+         composer \
+         drush \
+         gulp \
+         npm \
+         php \
+         wp \
+         yarn {
+  if checkForLandoFile; then
+    lando "$0" "$@"
+  else
+    command "$0" "$@"
+  fi
+}
+
+# Check for the file in the current and parent directories.
+checkForLandoFile() {
+  # Only bother checking for lando within the Sites directory.
+  if [[ "$PWD/" != "$LANDO_ZSH_SITES_DIRECTORY"/* ]]; then
+    # Not within $LANDO_ZSH_SITES_DIRECTORY
+    return 1
+  fi
+
+  local curr_dir="$PWD"
+  # Checking for file: $LANDO_ZSH_CONFIG_FILE within $LANDO_ZSH_SITES_DIRECTORY...
+  while [[ "$curr_dir" != "$LANDO_ZSH_SITES_DIRECTORY" ]]; do
+    if [[ -f "$curr_dir/$LANDO_ZSH_CONFIG_FILE" ]]; then
+      return 0
+    fi
+    curr_dir="${curr_dir:h}"
+  done
+
+  # Could not find $LANDO_ZSH_CONFIG_FILE in the current directory
+  # or in any of its parents up to $LANDO_ZSH_SITES_DIRECTORY.
+  return 1
+}
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/README.md
new file mode 100644 (file)
index 0000000..95f5901
--- /dev/null
@@ -0,0 +1,57 @@
+# Laravel
+
+This plugin adds aliases and autocompletion for Laravel [Artisan](https://laravel.com/docs/artisan) and [Bob](http://daylerees.github.io/laravel-bob/) command-line interfaces.
+
+```
+plugins=(... laravel)
+```
+
+| Alias | Description |
+|:-:|:-:|
+| `artisan`  | `php artisan`  |
+| `pas`  | `php artisan serve` |
+
+## Database
+
+| Alias | Description |
+|:-:|:-:|
+| `pam`  |  `php artisan migrate` |
+| `pamf`  |  `php artisan migrate:fresh` |
+| `pamfs`  |  `php artisan migrate:fresh --seed` |
+| `pamr`  |  `php artisan migrate:rollback` |
+| `pads`  |  `php artisan db:seed` |
+
+## Makers
+
+| Alias | Description |
+|:-:|:-:|
+| `pamm`  |  `php artisan make:model` |
+| `pamc`  |  `php artisan make:controller` |
+| `pams`  |  `php artisan make:seeder` |
+| `pamt`  |  `php artisan make:test` |
+| `pamfa`  |  `php artisan make:factory` |
+| `pamp`  |  `php artisan make:policy` |
+| `pame`  |  `php artisan make:event` |
+| `pamj`  |  `php artisan make:job` |
+| `paml`  |  `php artisan make:listener` |
+| `pamn`  |  `php artisan make:notification` |
+
+## Clears
+
+| Alias | Description |
+|:-:|:-:|
+| `pacac`  |  `php artisan cache:clear` |
+| `pacoc`  |  `php artisan config:clear` |
+| `pavic`  |  `php artisan view:clear` |
+| `paroc`  |  `php artisan route:clear` |
+
+## Queues
+
+| Alias | Description |
+|:-:|:-:|
+| `paqf`  |  `php artisan queue:failed` |
+| `paqft`  |  `php artisan queue:failed-table` |
+| `paql`  |  `php artisan queue:listen` |
+| `paqr`  |  `php artisan queue:retry` |
+| `paqt`  |  `php artisan queue:table` |
+| `paqw`  |  `php artisan queue:work` |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/_artisan b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/_artisan
new file mode 100644 (file)
index 0000000..8637514
--- /dev/null
@@ -0,0 +1,40 @@
+#compdef artisan
+
+# Laravel autocompletion
+# Author: John Hamelink <john@johnhamelink.com>
+#
+# This plugin does the following:
+#  - Adds aliases and autocompletion for artisan
+#  - Adds aliases and autocompletion for bob
+
+local curcontext="$curcontext" state line _opts _bundles ret=1
+_arguments -C \
+    '1: :->cmds' \
+    '*:: :->args' && ret=0
+
+case $state in
+    cmds)
+
+    _values "Artisan command" \
+        'session\:install[Create a session table]' \
+        'migrate[Manage Migrations]' \
+        'test[Run a test]' \
+        'route\:\:call[Call a route in the CLI]' \
+        'key\:\:generate[Generate a key]'
+        ret=0
+        ;;
+    args)
+        case $line[1] in
+            migrate)
+                _values \
+                    'install[Create the Laravel migration table' \
+                    'make[Create a migration]' \
+                    'rollback[Roll back to the last migration operation]' \
+                    'reset[Roll back all migrations that have ever run]'
+                ret=0
+                ;;
+        esac
+        ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/laravel.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel/laravel.plugin.zsh
new file mode 100644 (file)
index 0000000..a8382d3
--- /dev/null
@@ -0,0 +1,41 @@
+#!zsh
+alias artisan='php artisan'
+alias bob='php artisan bob::build'
+
+# Development
+alias pas='php artisan serve'
+
+# Database
+alias pam='php artisan migrate'
+alias pamf='php artisan migrate:fresh'
+alias pamfs='php artisan migrate:fresh --seed'
+alias pamr='php artisan migrate:rollback'
+alias pads='php artisan db:seed'
+
+# Makers
+alias pamm='php artisan make:model'
+alias pamc='php artisan make:controller'
+alias pams='php artisan make:seeder'
+alias pamt='php artisan make:test'
+alias pamfa='php artisan make:factory'
+alias pamp='php artisan make:policy'
+alias pame='php artisan make:event'
+alias pamj='php artisan make:job'
+alias paml='php artisan make:listener'
+alias pamn='php artisan make:notification'
+alias pampp='php artisan make:provider'
+
+
+# Clears
+alias pacac='php artisan cache:clear'
+alias pacoc='php artisan config:clear'
+alias pavic='php artisan view:clear'
+alias paroc='php artisan route:clear'
+
+# queues
+alias paqf='php artisan queue:failed'
+alias paqft='php artisan queue:failed-table'
+alias paql='php artisan queue:listen'
+alias paqr='php artisan queue:retry'
+alias paqt='php artisan queue:table'
+alias paqw='php artisan queue:work'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel4/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel4/README.md
new file mode 100644 (file)
index 0000000..97a6a78
--- /dev/null
@@ -0,0 +1,18 @@
+# Laravel 4 plugin
+
+This plugin adds some aliases for common [Laravel 4](https://laravel.com/docs/4.2) commands.
+
+To use it, add `laravel4` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... laravel4)
+```
+
+## Aliases
+
+| Alias     | Command                     | Description                         |
+|-----------|-----------------------------|-------------------------------------|
+| la4       | `php artisan`               | Main Artisan command                |
+| la4dump   | `php artisan dump-autoload` | Regenerate framework autoload files |
+| la4cache  | `php artisan cache:clear`   | Flush the application cache         |
+| la4routes | `php artisan routes`        | List all registered routes          |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel4/laravel4.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel4/laravel4.plugin.zsh
new file mode 100644 (file)
index 0000000..0edc849
--- /dev/null
@@ -0,0 +1,20 @@
+# Laravel4 basic command completion
+_laravel4_get_command_list () {
+       php artisan --no-ansi | sed "1,/Available commands/d" | awk '/^ +[a-z]+/ { print $1 }'
+}
+
+_laravel4 () {
+  if [ -f artisan ]; then
+    compadd `_laravel4_get_command_list`
+  fi
+}
+
+compdef _laravel4 artisan
+compdef _laravel4 la4
+
+#Alias
+alias la4='php artisan'
+
+alias la4dump='php artisan dump-autoload'
+alias la4cache='php artisan cache:clear'
+alias la4routes='php artisan routes'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel5/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel5/README.md
new file mode 100644 (file)
index 0000000..933342a
--- /dev/null
@@ -0,0 +1,18 @@
+# Laravel 5 plugin
+
+This plugin adds some aliases for common [Laravel 5](https://laravel.com/docs) commands.
+
+To use it, add `laravel5` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... laravel5)
+```
+
+## Aliases
+
+| Alias     | Command                      | Description                                        |
+|-----------|------------------------------|----------------------------------------------------|
+| la5       | `php artisan`                | Main Artisan command                               |
+| la5cache  | `php artisan cache:clear`    | Flush the application cache                        |
+| la5routes | `php artisan route:list`     | List all registered routes                         |
+| la5vendor | `php artisan vendor:publish` | Publish any publishable assets from vendor package |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel5/laravel5.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/laravel5/laravel5.plugin.zsh
new file mode 100644 (file)
index 0000000..70dc4ed
--- /dev/null
@@ -0,0 +1,19 @@
+# Alias
+alias la5='php artisan'
+alias la5cache='php artisan cache:clear'
+alias la5routes='php artisan route:list'
+alias la5vendor='php artisan vendor:publish'
+
+# Laravel5 basic command completion
+_laravel5_get_command_list () {
+  php artisan --raw --no-ansi list | sed "s/[[:space:]].*//g"
+}
+
+_laravel5 () {
+  if [[ -f artisan ]]; then
+    compadd $(_laravel5_get_command_list)
+  fi
+}
+
+compdef _laravel5 artisan
+compdef _laravel5 la5
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/last-working-dir/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/last-working-dir/README.md
new file mode 100644 (file)
index 0000000..b5cc558
--- /dev/null
@@ -0,0 +1,33 @@
+# last-working-dir plugin
+
+Keeps track of the last used working directory and automatically jumps into it
+for new shells, unless the starting directory is not `$HOME`.
+
+Also adds a `lwd` function to jump to the last working directory.
+
+To use it, add `last-working-dir` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... last-working-dir)
+```
+
+## Features
+
+### Use separate last-working-dir files with different SSH keys
+
+If the same user account is used by multiple users connecting via different SSH keys, you can
+configure SSH to map them to different `SSH_USER`s and the plugin will use separate lwd files
+for each one.
+
+Make sure that your SSH server allows environment variables. You can enable this feature
+within the `/etc/sshd/sshd_config` file:
+
+```
+PermitUserEnvironment yes
+```
+
+Then, add `environment="SSH_USER=<SSH_USERNAME>"` before the SSH keys in your `authorized_keys` file:
+
+```
+environment="SSH_USER=a.test@example.com" ssh-ed25519 AAAAC3Nz...
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/last-working-dir/last-working-dir.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/last-working-dir/last-working-dir.plugin.zsh
new file mode 100644 (file)
index 0000000..905a02a
--- /dev/null
@@ -0,0 +1,28 @@
+# Flag indicating if we've previously jumped to last directory
+typeset -g ZSH_LAST_WORKING_DIRECTORY
+
+# Updates the last directory once directory is changed
+autoload -U add-zsh-hook
+add-zsh-hook chpwd chpwd_last_working_dir
+chpwd_last_working_dir() {
+  # Don't run in subshells
+  [[ "$ZSH_SUBSHELL" -eq 0 ]] || return 0
+  # Add ".$SSH_USER" suffix to cache file if $SSH_USER is set and non-empty
+  local cache_file="$ZSH_CACHE_DIR/last-working-dir${SSH_USER:+.$SSH_USER}"
+  pwd >| "$cache_file"
+}
+
+# Changes directory to the last working directory
+lwd() {
+  # Add ".$SSH_USER" suffix to cache file if $SSH_USER is set and non-empty
+  local cache_file="$ZSH_CACHE_DIR/last-working-dir${SSH_USER:+.$SSH_USER}"
+  [[ -r "$cache_file" ]] && cd "$(cat "$cache_file")"
+}
+
+# Jump to last directory automatically unless:
+# - this isn't the first time the plugin is loaded
+# - it's not in $HOME directory
+[[ -n "$ZSH_LAST_WORKING_DIRECTORY" ]] && return
+[[ "$PWD" != "$HOME" ]] && return
+
+lwd 2>/dev/null && ZSH_LAST_WORKING_DIRECTORY=1 || true
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lein/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/lein/README.md
new file mode 100644 (file)
index 0000000..0c41196
--- /dev/null
@@ -0,0 +1,9 @@
+# Leiningen plugin
+
+This plugin adds completions for the [Leiningen](https://leiningen.org/) Clojure build tool.
+
+To use it, add `lein` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... lein)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lein/_lein b/stow/oh-my-zsh/.oh-my-zsh/plugins/lein/_lein
new file mode 100644 (file)
index 0000000..9d022e9
--- /dev/null
@@ -0,0 +1,69 @@
+#compdef lein
+
+# Lein ZSH completion function
+# Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions)
+# and rename it _lein
+
+_lein() {
+  if (( CURRENT > 2 )); then
+    # shift words so _arguments doesn't have to be concerned with second command
+    (( CURRENT-- ))
+    shift words
+    # use _call_function here in case it doesn't exist
+    _call_function 1 _lein_${words[1]}
+  else
+    _values "lein command" \
+      "change[Rewrite project.clj by applying a function.]" \
+      "check[Check syntax and warn on reflection.]" \
+      "classpath[Print the classpath of the current project.]" \
+      "clean[Remove all files from project's target-path.]" \
+      "compile[Compile Clojure source into .class files.]" \
+      "deploy[Build and deploy jar to remote repository.]" \
+      "deps[Download all dependencies.]" \
+      "do[Higher-order task to perform other tasks in succession.]" \
+      "help[Display a list of tasks or help for a given task.]" \
+      "install[Install the current project to the local repository.]" \
+      "jar[Package up all the project's files into a jar file.]" \
+      "javac[Compile Java source files.]" \
+      "new[Generate project scaffolding based on a template.]" \
+      "plugin[DEPRECATED. Please use the :user profile instead.]" \
+      "pom[Write a pom.xml file to disk for Maven interoperability.]" \
+      "release[Perform :release-tasks.]" \
+      "repl[Start a repl session either with the current project or standalone.]" \
+      "retest[Run only the test namespaces which failed last time around.]" \
+      "run[Run a -main function with optional command-line arguments.]" \
+      "search[Search remote maven repositories for matching jars.]" \
+      "show-profiles[List all available profiles or display one if given an argument.]" \
+      "test[Run the project's tests.]" \
+      "trampoline[Run a task without nesting the project's JVM inside Leiningen's.]" \
+      "uberjar[Package up the project files and dependencies into a jar file.]" \
+      "update-in[Perform arbitrary transformations on your project map.]" \
+      "upgrade[Upgrade Leiningen to specified version or latest stable.]" \
+      "vcs[Interact with the version control system.]" \
+      "version[Print version for Leiningen and the current JVM.]" \
+      "with-profile[Apply the given task with the profile(s) specified.]"
+  fi
+}
+
+_lein_plugin() {
+  _values "lein plugin commands" \
+    "install[Download, package, and install plugin jarfile into ~/.lein/plugins]" \
+    "uninstall[Delete the plugin jarfile: \[GROUP/\]ARTIFACT-ID VERSION]"
+}
+
+
+_lein_namespaces() {
+  if [ -f "./project.clj" -a -d "$1" ]; then
+    _values "lein valid namespaces" \
+      $(find "$1" -type f -name "*.clj" -exec awk '/^\(ns */ {gsub("\\)", "", $2); print $2}' '{}' '+')
+  fi
+}
+
+
+_lein_run() {
+  _lein_namespaces "src/"
+}
+
+_lein_test() {
+  _lein_namespaces "test/"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lighthouse/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/lighthouse/README.md
new file mode 100644 (file)
index 0000000..55587b2
--- /dev/null
@@ -0,0 +1,29 @@
+# Lighthouse plugin
+
+This plugin adds commands to manage [Lighthouse](https://lighthouseapp.com/).
+
+To use it, add `lighthouse` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... lighthouse)
+```
+
+## Commands
+
+* `open_lighthouse_ticket <issue>` (alias: `lho`):
+
+  Opens the URL to the issue passed as an argument. To use it, add a `.lighthouse-url`
+  file in your directory with the URL to the individual project.
+
+  Example:
+
+  ```console
+  $ cat .lighthouse-url
+  https://rails.lighthouseapp.com/projects/8994
+
+  $ lho 23
+  Opening ticket #23
+  # The browser goes to https://rails.lighthouseapp.com/projects/8994/tickets/23
+  ```
+
+See a demo: http://screencast.com/t/ZDgwNDUwNT
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lighthouse/lighthouse.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/lighthouse/lighthouse.plugin.zsh
new file mode 100644 (file)
index 0000000..3fca2bf
--- /dev/null
@@ -0,0 +1,12 @@
+open_lighthouse_ticket () {
+  if [ ! -f .lighthouse-url ]; then
+    echo "There is no .lighthouse-url file in the current directory..."
+    return 0
+  fi
+
+  lighthouse_url=$(cat .lighthouse-url)
+  echo "Opening ticket #$1"
+  open_command "$lighthouse_url/tickets/$1"
+}
+
+alias lho='open_lighthouse_ticket'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lol/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/lol/README.md
new file mode 100644 (file)
index 0000000..ea6b0c3
--- /dev/null
@@ -0,0 +1,71 @@
+# lol
+
+Plugin for adding catspeak aliases, because why not.
+
+To use it, add `lol` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... lol)
+```
+
+## Aliases
+
+| Alias        | Command                                                         |
+| ------------ | --------------------------------------------------------------- |
+| `:3`         | `echo`                                                          |
+| `alwayz`     | `tail -f`                                                       |
+| `bringz`     | `git pull`                                                      |
+| `btw`        | `nice`                                                          |
+| `byes`       | `exit`                                                          |
+| `chicken`    | `git add`                                                       |
+| `cya`        | `reboot`                                                        |
+| `donotwant`  | `rm`                                                            |
+| `dowant`     | `cp`                                                            |
+| `gimmeh`     | `touch`                                                         |
+| `gtfo`       | `mv`                                                            |
+| `hackzor`    | `git init`                                                      |
+| `hai`        | `cd`                                                            |
+| `icanhas`    | `mkdir`                                                         |
+| `ihasbucket` | `df -h`                                                         |
+| `iminurbase` | `finger`                                                        |
+| `inur`       | `locate`                                                        |
+| `invisible`  | `cat`                                                           |
+| `iz`         | `ls`                                                            |
+| `kthxbai`    | `halt`                                                          |
+| `letcat`     | `git checkout`                                                  |
+| `moar`       | `more`                                                          |
+| `nomnom`     | `killall`                                                       |
+| `nomz`       | `ps aux`                                                        |
+| `nowai`      | `chmod`                                                         |
+| `oanward`    | `git commit -m`                                                 |
+| `obtw`       | `nohup`                                                         |
+| `onoz`       | `cat /var/log/errors.log`                                       |
+| `ooanward`   | `git commit -am`                                                |
+| `plz`        | `pwd`                                                           |
+| `pwned`      | `ssh`                                                           |
+| `rtfm`       | `man`                                                           |
+| `rulz`       | `git push`                                                      |
+| `tldr`       | `less`                                                          |
+| `violenz`    | `git rebase`                                                    |
+| `visible`    | `echo`                                                          |
+| `wtf`        | `dmesg`                                                         |
+| `yolo`       | `git commit -m "$(curl -s http://whatthecommit.com/index.txt)"` |
+
+## Usage Examples
+
+```sh
+# mkdir new-directory
+icanhas new-directory
+
+# killall firefox
+nomnom firefox
+
+# chmod u=r,go= some.file
+nowai u=r,go= some.file
+
+# ssh root@catserver.org
+pwned root@catserver.org
+
+# git commit -m "$(curl -s http://whatthecommit.com/index.txt)"
+yolo
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lol/lol.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/lol/lol.plugin.zsh
new file mode 100644 (file)
index 0000000..3c30259
--- /dev/null
@@ -0,0 +1,51 @@
+# LOL!!1
+# Source: https://aur.archlinux.org/packages/lolbash/lolbash/lolbash.sh
+
+alias wtf='dmesg'
+alias onoz='cat /var/log/errors.log'
+alias rtfm='man'
+
+alias :3='echo'
+alias visible='echo'
+alias invisible='cat'
+alias moar='more'
+alias tldr='less'
+alias alwayz='tail -f'
+
+alias icanhas='mkdir'
+alias gimmeh='touch'
+alias donotwant='rm'
+alias dowant='cp'
+alias gtfo='mv'
+alias nowai='chmod'
+
+alias hai='cd'
+alias iz='ls'
+alias plz='pwd'
+alias ihasbucket='df -h'
+
+alias inur='locate'
+alias iminurbase='finger'
+
+alias btw='nice'
+alias obtw='nohup'
+
+alias nomz='ps aux'
+alias nomnom='killall'
+
+alias byes='exit'
+alias cya='reboot'
+alias kthxbai='halt'
+
+alias pwned='ssh'
+
+alias hackzor='git init'
+alias rulz='git push'
+alias bringz='git pull'
+alias chicken='git add'
+alias oanward='git commit -m'
+alias ooanward='git commit -am'
+alias yolo='git commit -m "$(curl -s http://whatthecommit.com/index.txt)"'
+alias letcat='git checkout'
+alias violenz='git rebase'
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lpass/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/lpass/README.md
new file mode 100644 (file)
index 0000000..d3923ea
--- /dev/null
@@ -0,0 +1,13 @@
+# lpass (LastPass CLI)
+
+This plugin adds completion for LastPass CLI [`lpass`](https://github.com/lastpass/lastpass-cli).
+
+To use it, add `lpass` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... lpass)
+```
+
+Completion is taken from the `lpass` release [`1.3.3`](https://github.com/lastpass/lastpass-cli/releases/tag/v1.3.3).
+
+Updated on October 9th, 2020.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lpass/_lpass b/stow/oh-my-zsh/.oh-my-zsh/plugins/lpass/_lpass
new file mode 100644 (file)
index 0000000..621a7bc
--- /dev/null
@@ -0,0 +1,169 @@
+#compdef lpass
+
+_lpass() {
+    local cmd has_color has_sync has_interactive
+       if (( CURRENT > 2)); then
+        cmd=${words[2]}
+        # Set the context for the subcommand.
+        curcontext="${curcontext%:*:*}:lpass-$cmd"
+        # Narrow the range of words we are looking at to exclude `lpass'
+        (( CURRENT-- ))
+        shift words
+        # Run the completion for the subcommand
+        case "${cmd}" in
+            login)
+                _arguments : \
+                  '--trust[Cause subsequent logins to not require multifactor authentication.]' \
+                  '--plaintext-key[Save plaintext decryption key to the hard disk]' \
+                  '--force[Do not ask on saving plaintext key]'
+                has_color=1
+            ;;
+
+            logout)
+                _arguments : '--force[Force confirmation]'
+                has_color=1
+            ;;
+            show)
+                _arguments : \
+                  '(-c --clip)'{-c,--clip}'[Copy output to clipboard]' \
+                  '(-x --expand-multi)'{-x,---expand-multi}'[Show the requested information from all of the matching sites]' \
+                  '(--all --username --password --url --notes --field= --id --name --attach=)'{--all,--username,--password,--url,--notes,--field=,--id,--name,--attach=}'[Output the specific field]' \
+                  '(--basic-regexp,--fixed-string)'{-G,--basic-regexp}'[Find a site by substring or regular expression]' \
+                  '--format=[Format output with printf-style placeholders]'
+                _lpass_complete_uniqenames
+                has_color=1
+                has_sync=1
+            ;;
+
+            ls)
+                _arguments : \
+                  '(-l --long)'{-l,--long}'[Also list the last modification time and username]' \
+                  '-u[List username]' \
+                  '-m[List modification time]' \
+                  '--format=[Format output with printf-style placeholders]'
+                                 _lpass_complete_groups
+                has_color=1
+                has_sync=1
+                       ;;
+            mv)
+                _lpass_complete_uniqenames
+                _lpass_complete_groups
+                has_color=1
+            ;;
+            duplicate|rm)
+                _lpass_complete_uniqenames
+                has_color=1
+                has_sync=1
+            ;;
+            add)
+                _arguments : '(--username --password --url --notes --field=)'{--username,--password,--url,--notes,--field=}'[Add field]'
+                _lpass_complete_uniqenames
+                has_color=1
+                has_sync=1
+                has_interactive=1
+            ;;
+            edit)
+                _arguments : '(--name --username --password --url --notes --field=)'{--name,--username,--password,--url,--notes,--field=}'[Update field]'
+                _lpass_complete_uniqenames
+                has_color=1
+                has_sync=1
+                has_interactive=1
+            ;;
+            generate)
+                _arguments : \
+                  '(-c --clip)'{-c,--clip}'[Copy output to clipboard]' \
+                  '--username=[USERNAME]' \
+                  '--url=[URL]' \
+                  '--no-symbols[Do not use symbols]'
+                has_sync=1
+            ;;
+            status)
+               _arguments : '(-q --quiet)'{-q,--quiet}'[Supress output to stdout]'
+                has_color=1
+            ;;
+            sync)
+                _arguments : '(-b --background)'{-b,--background}'[Run sync in background]'
+                has_color=1
+            ;;
+            export)
+                _arguments : '--fields=[Field list]'
+                has_color=1
+                has_sync=1
+            ;;
+            import)
+              if ((CURRENT < 3)); then
+                _files
+              fi
+            ;;
+        esac
+
+        if [ -n "$has_sync" ] || [ -n "$has_color" ] || [ -n "$has_interactive" ]; then
+            local -a generic_options
+            if [ "$has_sync" -eq 1 ]; then
+                generic_options+=('--sync=[Synchronize local cache with server: auto | now | no]')
+            fi
+            if [ "$has_color" -eq 1 ]; then
+                generic_options+=('--color=[Color: auto | never | always]')
+            fi
+            if [ "$has_interactive" -eq 1 ]; then
+                generic_options+=("--non-interactive[Use standard input instead of $EDITOR]")
+            fi
+            _arguments $generic_options
+        fi
+    else
+        local -a subcommands
+        subcommands=(
+          "login:Authenticate with the LastPass server and initialize a local cache"
+          "logout:Remove the local cache and stored encryption keys"
+          "passwd:Change your LastPass password"
+          "show:Display a password or selected field"
+          "ls:List names in groups in a tree structure"
+          "mv:Move the specified entry to a new group"
+          "add:Add a new entry"
+          "edit:Edit the selected field"
+          "generate:Create a randomly generated password"
+          "duplicate:Create a duplicate entry of the one specified"
+          "rm:Remove the specified entry"
+          "status:Show current login status"
+          "sync:Synchronize local cache with server"
+          "export:Dump all account information including passwords as unencrypted csv to stdout"
+          "import:Upload accounts from an unencrypted CSV file to the server"
+          "share:Manipulate shared folders (only enterprise or premium user)"
+        )
+        _describe -t commands 'lpass' subcommands
+        _arguments : \
+          '(-h --help)'{-h,--help}'[show help]' \
+          '(-v --version)'{-v,--version}'[show version]'
+
+    fi
+}
+
+_lpass_complete_uniqenames(){
+  local -a entries
+  while read i;  do
+    if [ -n "$i" ]; then
+      entries+=("$i")
+    fi
+  done < <(lpass ls --sync auto --format "%an" --color=never)
+  compadd -a entries
+}
+
+
+_lpass_complete_groups() {
+  local -a entries
+  while read i;  do
+    if [ -n "$i" ]; then
+      entries+=("$i")
+    fi
+  done < <(lpass ls --sync auto --format "%aN" --color=never | grep -E "\/$")
+  compadd -a entries
+}
+
+_lpass
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lxd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/lxd/README.md
new file mode 100644 (file)
index 0000000..cea45e3
--- /dev/null
@@ -0,0 +1,9 @@
+# lxd
+
+This plugin provides completion for [lxd](https://linuxcontainers.org/lxd/), as well as aliases
+for frequent lxc commands.
+
+To use it add `lxd` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... lxd)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/lxd/lxd.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/lxd/lxd.plugin.zsh
new file mode 100644 (file)
index 0000000..a6a0742
--- /dev/null
@@ -0,0 +1,26 @@
+_lxc_get_command_list () {
+    $_comp_command1 | sed "1,/Available Commands/d" | awk '/^[ \t]*[a-z]+/ { print $1 }'
+}
+
+_lxc_get_subcommand_list () {
+    $_comp_command1 ${words[2]} | sed "1,/Available Commands/d" | awk '/^[ \t]*[a-z]+/ { print $1 }'
+}
+
+_lxc () {
+  local curcontext="$curcontext" state line
+  typeset -A opt_args
+  _arguments \
+    '1: :->command'\
+    '*: :->args'
+
+  case $state in
+    command)
+      compadd $(_lxc_get_command_list)
+      ;;
+    *)
+        compadd $(_lxc_get_subcommand_list)
+      ;;
+  esac
+}
+
+compdef _lxc lxc
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/README.md
new file mode 100644 (file)
index 0000000..1bc4244
--- /dev/null
@@ -0,0 +1,63 @@
+# MacOS plugin
+
+This plugin provides a few utilities to make it more enjoyable on macOS (previously named OSX).
+
+To start using it, add the `macos` plugin to your plugins array in `~/.zshrc`:
+
+```zsh
+plugins=(... macos)
+```
+
+Original author: [Sorin Ionescu](https://github.com/sorin-ionescu)
+
+## Commands
+
+| Command       | Description                                              |
+| :------------ | :------------------------------------------------------- |
+| `tab`         | Open the current directory in a new tab                  |
+| `split_tab`   | Split the current terminal tab horizontally              |
+| `vsplit_tab`  | Split the current terminal tab vertically                |
+| `ofd`         | Open the current directory in a Finder window            |
+| `pfd`         | Return the path of the frontmost Finder window           |
+| `pfs`         | Return the current Finder selection                      |
+| `cdf`         | `cd` to the current Finder directory                     |
+| `pushdf`      | `pushd` to the current Finder directory                  |
+| `pxd`         | Return the current Xcode project directory               |
+| `cdx`         | `cd` to the current Xcode project directory              |
+| `quick-look`  | Quick-Look a specified file                              |
+| `man-preview` | Open a specified man page in Preview app                 |
+| `showfiles`   | Show hidden files in Finder                              |
+| `hidefiles`   | Hide the hidden files in Finder                          |
+| `itunes`      | _DEPRECATED_. Use `music` from macOS Catalina on         |
+| `music`       | Control Apple Music. Use `music -h` for usage details    |
+| `spotify`     | Control Spotify and search by artist, album, track…      |
+| `rmdsstore`   | Remove .DS_Store files recursively in a directory        |
+| `btrestart`   | Restart the Bluetooth daemon                             |
+| `freespace`   | Erases purgeable disk space with 0s on the selected disk |
+
+## Acknowledgements
+
+This application makes use of the following third party scripts:
+
+[shpotify](https://github.com/hnarayanan/shpotify)
+
+Copyright (c) 2012–2019 [Harish Narayanan](https://harishnarayanan.org/).
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/_security b/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/_security
new file mode 100644 (file)
index 0000000..e4ed585
--- /dev/null
@@ -0,0 +1,90 @@
+#compdef security
+
+local -a _1st_arguments
+_1st_arguments=(
+  'help:Show all commands, or show usage for a command'
+  'list-keychains:Display or manipulate the keychain search list'
+  'default-keychain:Display or set the default keychain'
+  'login-keychain:Display or set the login keychain'
+  'create-keychain:Create keychains and add them to the search list'
+  'delete-keychain:Delete keychains and remove them from the search list'
+  'lock-keychain:Lock the specified keychain'
+  'lock-keychain:Unlock the specified keychain'
+  'set-keychain-settings:Set settings for a keychain'
+  'set-keychain-password:Set password for a keychain'
+  'show-keychain-info:Show the settings for keychain'
+  'dump-keychain:Dump the contents of one or more keychains'
+  'create-keypair:Create an asymmetric key pair'
+  'add-generic-password:Add a generic password item'
+  'add-internet-password:Add an internet password item'
+  'add-certificates:Add certificates to a keychain'
+  'find-generic-password:Find a generic password item'
+  'delete-generic-password:Delete a generic password item'
+  'find-internet-password:Find an internet password item'
+  'delete-internet-password:Delete an internet password item'
+  'find-certificate:Find a certificate item'
+  'find-identity:Find an identity certificate + private key'
+  'delete-certificate:Delete a certificate from a keychain'
+  'set-identity-preference:Set the preferred identity to use for a service'
+  'get-identity-preference:Get the preferred identity to use for a service'
+  'create-db:Create a db using the DL'
+  'export:Export items from a keychain'
+  'import:Import items into a keychain'
+  'cms:Encode or decode CMS messages'
+  'install-mds:MDS database'
+  'add-trusted-cert:Add trusted certificates:'
+  'remove-trusted-cert:Remove trusted certificates:'
+  'dump-trust-settings:Display contents of trust settings'
+  'user-trust-settings-enable:Display or manipulate user-level trust settings'
+  'trust-settings-export:Export trust settings'
+  'trust-settings-import:Import trust settings'
+  'verify-cert:Verify certificates:'
+  'authorize:Perform authorization operations'
+  'authorizationdb:Make changes to the authorization policy database'
+  'execute-with-privileges:Execute tool with privileges'
+  'leaks:Run /usr/bin/leaks on this process'
+  'error:Display a descriptive message for the given error codes:'
+  'create-filevaultmaster-keychain:"Create a keychain containing a key pair for FileVault recovery use'
+)
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "security command" _1st_arguments
+  return
+fi
+
+case "$words[1]" in
+  find-(generic|internet)-password)
+    _values \
+      'Usage: find-[internet/generic]-password [-a account] [-s server] [options...] [-g] [keychain...]' \
+      '-a[Match "account" string]' \
+      '-c[Match "creator" (four-character code)]' \
+      '-C[Match "type" (four-character code)]' \
+      '-D[Match "kind" string]' \
+      '-G[Match "value" string (generic attribute)]' \
+      '-j[Match "comment" string]' \
+      '-l[Match "label" string]' \
+      '-s[Match "service" string]' \
+      '-g[Display the password for the item found]' \
+      '-w[Display only the password on stdout]' ;;
+  add-(generic|internet)-password)
+    _values \
+      'Usage: add-[internet/generic]-password [-a account] [-s server] [-w password] [options...] [-A|-T appPath] [keychain]]' \
+      '-a[Specify account name (required)]' \
+      '-c[Specify item creator (optional four-character code)]' \
+      '-C[Specify item type (optional four-character code)]' \
+      '-d[Specify security domain string (optional)]' \
+      '-D[Specify kind (default is "Internet password")]' \
+      '-j[Specify comment string (optional)]' \
+      '-l[Specify label (if omitted, server name is used as default label)]' \
+      '-p[Specify path string (optional)]' \
+      '-P[Specify port number (optional)]' \
+      '-r[Specify protocol (optional four-character SecProtocolType, e.g. "http", "ftp ")]' \
+      '-s[Specify server name (required)]' \
+      '-t[Specify authentication type (as a four-character SecAuthenticationType, default is "dflt")]' \
+      '-w[Specify password to be added]' \
+      '-A[Allow any application to access this item without warning (insecure, not recommended!)]' \
+      '-T[Specify an application which may access this item (multiple -T options are allowed)]' \
+      '-U[Update item if it already exists (if omitted, the item cannot already exist) ]' \
+      'utils)]' ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/macos.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/macos.plugin.zsh
new file mode 100644 (file)
index 0000000..b540eec
--- /dev/null
@@ -0,0 +1,268 @@
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+# Open the current directory in a Finder window
+alias ofd='open_command $PWD'
+
+# Show/hide hidden files in the Finder
+alias showfiles="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder"
+alias hidefiles="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder"
+
+# Bluetooth restart
+function btrestart() {
+  sudo kextunload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport
+  sudo kextload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport
+}
+
+function _omz_macos_get_frontmost_app() {
+  osascript 2>/dev/null <<EOF
+    tell application "System Events"
+      name of first item of (every process whose frontmost is true)
+    end tell
+EOF
+}
+
+function tab() {
+  # Must not have trailing semicolon, for iTerm compatibility
+  local command="cd \\\"$PWD\\\"; clear"
+  (( $# > 0 )) && command="${command}; $*"
+
+  local the_app=$(_omz_macos_get_frontmost_app)
+
+  if [[ "$the_app" == 'Terminal' ]]; then
+    # Discarding stdout to quash "tab N of window id XXX" output
+    osascript >/dev/null <<EOF
+      tell application "System Events"
+        tell process "Terminal" to keystroke "t" using command down
+      end tell
+      tell application "Terminal" to do script "${command}" in front window
+EOF
+  elif [[ "$the_app" == 'iTerm' ]]; then
+    osascript <<EOF
+      tell application "iTerm"
+        set current_terminal to current terminal
+        tell current_terminal
+          launch session "Default Session"
+          set current_session to current session
+          tell current_session
+            write text "${command}"
+          end tell
+        end tell
+      end tell
+EOF
+  elif [[ "$the_app" == 'iTerm2' ]]; then
+    osascript <<EOF
+      tell application "iTerm2"
+        tell current window
+          create tab with default profile
+          tell current session to write text "${command}"
+        end tell
+      end tell
+EOF
+  elif [[ "$the_app" == 'Hyper' ]]; then
+    osascript >/dev/null <<EOF
+      tell application "System Events"
+        tell process "Hyper" to keystroke "t" using command down
+      end tell
+      delay 1
+      tell application "System Events"
+        keystroke "${command}"
+        key code 36  #(presses enter)
+      end tell
+EOF
+  else
+    echo "$0: unsupported terminal app: $the_app" >&2
+    return 1
+  fi
+}
+
+function vsplit_tab() {
+  local command="cd \\\"$PWD\\\"; clear"
+  (( $# > 0 )) && command="${command}; $*"
+
+  local the_app=$(_omz_macos_get_frontmost_app)
+
+  if [[ "$the_app" == 'iTerm' ]]; then
+    osascript <<EOF
+      -- tell application "iTerm" to activate
+      tell application "System Events"
+        tell process "iTerm"
+          tell menu item "Split Vertically With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1
+            click
+          end tell
+        end tell
+        keystroke "${command} \n"
+      end tell
+EOF
+  elif [[ "$the_app" == 'iTerm2' ]]; then
+    osascript <<EOF
+      tell application "iTerm2"
+        tell current session of first window
+          set newSession to (split vertically with same profile)
+          tell newSession
+            write text "${command}"
+            select
+          end tell
+        end tell
+      end tell
+EOF
+  elif [[ "$the_app" == 'Hyper' ]]; then
+    osascript >/dev/null <<EOF
+    tell application "System Events"
+      tell process "Hyper"
+        tell menu item "Split Vertically" of menu "Shell" of menu bar 1
+          click
+        end tell
+      end tell
+      delay 1
+      keystroke "${command} \n"
+    end tell
+EOF
+  else
+    echo "$0: unsupported terminal app: $the_app" >&2
+    return 1
+  fi
+}
+
+function split_tab() {
+  local command="cd \\\"$PWD\\\"; clear"
+  (( $# > 0 )) && command="${command}; $*"
+
+  local the_app=$(_omz_macos_get_frontmost_app)
+
+  if [[ "$the_app" == 'iTerm' ]]; then
+    osascript 2>/dev/null <<EOF
+      tell application "iTerm" to activate
+
+      tell application "System Events"
+        tell process "iTerm"
+          tell menu item "Split Horizontally With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1
+            click
+          end tell
+        end tell
+        keystroke "${command} \n"
+      end tell
+EOF
+  elif [[ "$the_app" == 'iTerm2' ]]; then
+    osascript <<EOF
+      tell application "iTerm2"
+        tell current session of first window
+          set newSession to (split horizontally with same profile)
+          tell newSession
+            write text "${command}"
+            select
+          end tell
+        end tell
+      end tell
+EOF
+  elif [[ "$the_app" == 'Hyper' ]]; then
+    osascript >/dev/null <<EOF
+    tell application "System Events"
+      tell process "Hyper"
+        tell menu item "Split Horizontally" of menu "Shell" of menu bar 1
+          click
+        end tell
+      end tell
+      delay 1
+      keystroke "${command} \n"
+    end tell
+EOF
+  else
+    echo "$0: unsupported terminal app: $the_app" >&2
+    return 1
+  fi
+}
+
+function pfd() {
+  osascript 2>/dev/null <<EOF
+    tell application "Finder"
+      return POSIX path of (insertion location as alias)
+    end tell
+EOF
+}
+
+function pfs() {
+  osascript 2>/dev/null <<EOF
+    set output to ""
+    tell application "Finder" to set the_selection to selection
+    set item_count to count the_selection
+    repeat with item_index from 1 to count the_selection
+      if item_index is less than item_count then set the_delimiter to "\n"
+      if item_index is item_count then set the_delimiter to ""
+      set output to output & ((item item_index of the_selection as alias)'s POSIX path) & the_delimiter
+    end repeat
+EOF
+}
+
+function cdf() {
+  cd "$(pfd)"
+}
+
+function pushdf() {
+  pushd "$(pfd)"
+}
+
+function pxd() {
+  dirname $(osascript 2>/dev/null <<EOF
+    if application "Xcode" is running then
+      tell application "Xcode"
+        return path of active workspace document
+      end tell
+    end if
+EOF
+)
+}
+
+function cdx() {
+  cd "$(pxd)"
+}
+
+function quick-look() {
+  (( $# > 0 )) && qlmanage -p $* &>/dev/null &
+}
+
+function man-preview() {
+  # Don't let Preview.app steal focus if the man page doesn't exist
+  man -w "$@" &>/dev/null && man -t "$@" | open -f -a Preview || man "$@"
+}
+compdef _man man-preview
+
+function vncviewer() {
+  open vnc://$@
+}
+
+# Remove .DS_Store files recursively in a directory, default .
+function rmdsstore() {
+  find "${@:-.}" -type f -name .DS_Store -delete
+}
+
+# Erases purgeable disk space with 0s on the selected disk
+function freespace(){
+  if [[ -z "$1" ]]; then
+    echo "Usage: $0 <disk>"
+    echo "Example: $0 /dev/disk1s1"
+    echo
+    echo "Possible disks:"
+    df -h | awk 'NR == 1 || /^\/dev\/disk/'
+    return 1
+  fi
+
+  echo "Cleaning purgeable files from disk: $1 ...."
+  diskutil secureErase freespace 0 $1
+}
+
+_freespace() {
+  local -a disks
+  disks=("${(@f)"$(df | awk '/^\/dev\/disk/{ printf $1 ":"; for (i=9; i<=NF; i++) printf $i FS; print "" }')"}")
+  _describe disks disks
+}
+
+compdef _freespace freespace
+
+# Music / iTunes control function
+source "${0:h:A}/music"
+
+# Spotify control function
+source "${0:h:A}/spotify"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/music b/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/music
new file mode 100644 (file)
index 0000000..5056679
--- /dev/null
@@ -0,0 +1,170 @@
+#!/usr/bin/env zsh
+
+function music itunes() {
+  local APP_NAME=Music sw_vers=$(sw_vers -productVersion 2>/dev/null)
+
+  autoload is-at-least
+  if [[ -z "$sw_vers" ]] || is-at-least 10.15 $sw_vers; then
+    if [[ $0 = itunes ]]; then
+      echo >&2 The itunes function name is deprecated. Use \'music\' instead.
+      return 1
+    fi
+  else
+    APP_NAME=iTunes
+  fi
+
+  local opt=$1 playlist=$2
+  (( $# > 0 )) && shift
+  case "$opt" in
+    launch|play|pause|stop|rewind|resume|quit)
+      ;;
+    mute)
+      opt="set mute to true"
+      ;;
+    unmute)
+      opt="set mute to false"
+      ;;
+    next|previous)
+      opt="$opt track"
+      ;;
+    vol)
+      local new_volume volume=$(osascript -e "tell application \"$APP_NAME\" to get sound volume")
+      if [[ $# -eq 0 ]]; then
+        echo "Current volume is ${volume}."
+        return 0
+      fi
+      case $1 in
+        up) new_volume=$((volume + 10 < 100 ? volume + 10 : 100)) ;;
+        down) new_volume=$((volume - 10 > 0 ? volume - 10 : 0)) ;;
+        <0-100>) new_volume=$1 ;;
+        *) echo "'$1' is not valid. Expected <0-100>, up or down."
+           return 1 ;;
+      esac
+      opt="set sound volume to ${new_volume}"
+      ;;
+    playlist)
+      # Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f
+      if [[ -n "$playlist" ]]; then
+        osascript 2>/dev/null <<EOF
+          tell application "$APP_NAME"
+            set new_playlist to "$playlist" as string
+            play playlist new_playlist
+          end tell
+EOF
+        if [[ $? -eq 0 ]]; then
+          opt="play"
+        else
+          opt="stop"
+        fi
+      else
+        opt="set allPlaylists to (get name of every playlist)"
+      fi
+      ;;
+    playing|status)
+      local currenttrack currentartist state=$(osascript -e "tell application \"$APP_NAME\" to player state as string")
+      if [[ "$state" = "playing" ]]; then
+        currenttrack=$(osascript -e "tell application \"$APP_NAME\" to name of current track as string")
+        currentartist=$(osascript -e "tell application \"$APP_NAME\" to artist of current track as string")
+        echo -E "Listening to ${fg[yellow]}${currenttrack}${reset_color} by ${fg[yellow]}${currentartist}${reset_color}"
+      else
+        echo "$APP_NAME is $state"
+      fi
+      return 0
+      ;;
+    shuf|shuff|shuffle)
+      # The shuffle property of current playlist can't be changed in iTunes 12,
+      # so this workaround uses AppleScript to simulate user input instead.
+      # Defaults to toggling when no options are given.
+      # The toggle option depends on the shuffle button being visible in the Now playing area.
+      # On and off use the menu bar items.
+      local state=$1
+
+      if [[ -n "$state" && "$state" != (on|off|toggle) ]]; then
+        print "Usage: $0 shuffle [on|off|toggle]. Invalid option."
+        return 1
+      fi
+
+      case "$state" in
+        on|off)
+          # Inspired by: https://stackoverflow.com/a/14675583
+          osascript >/dev/null 2>&1 <<EOF
+            tell application "System Events" to perform action "AXPress" of (menu item "${state}" of menu "Shuffle" of menu item "Shuffle" of menu "Controls" of menu bar item "Controls" of menu bar 1 of application process "iTunes" )
+EOF
+          return 0
+          ;;
+        toggle|*)
+          osascript >/dev/null 2>&1 <<EOF
+            tell application "System Events" to perform action "AXPress" of (button 2 of process "iTunes"'s window "iTunes"'s scroll area 1)
+EOF
+          return 0
+          ;;
+      esac
+      ;;
+    ""|-h|--help)
+      echo "Usage: $0 <option>"
+      echo "option:"
+      echo "\t-h|--help\tShow this message and exit"
+      echo "\tlaunch|play|pause|stop|rewind|resume|quit"
+      echo "\tmute|unmute\tMute or unmute $APP_NAME"
+      echo "\tnext|previous\tPlay next or previous track"
+      echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer."
+      echo "\tvol [0-100|up|down]\tGet or set the volume. 0 to 100 sets the volume. 'up' / 'down' increases / decreases by 10 points. No argument displays current volume."
+      echo "\tplaying|status\tShow what song is currently playing in Music."
+      echo "\tplaylist [playlist name]\t Play specific playlist"
+      return 0
+      ;;
+    *)
+      print "Unknown option: $opt"
+      return 1
+      ;;
+  esac
+  osascript -e "tell application \"$APP_NAME\" to $opt"
+}
+
+function _music() {
+  local app_name
+  case "$words[1]" in
+    itunes) app_name="iTunes" ;;
+    music|*) app_name="Music" ;;
+  esac
+
+  local -a cmds subcmds
+  cmds=(
+    "launch:Launch the ${app_name} app"
+    "play:Play ${app_name}"
+    "pause:Pause ${app_name}"
+    "stop:Stop ${app_name}"
+    "rewind:Rewind ${app_name}"
+    "resume:Resume ${app_name}"
+    "quit:Quit ${app_name}"
+    "mute:Mute the ${app_name} app"
+    "unmute:Unmute the ${app_name} app"
+    "next:Skip to the next song"
+    "previous:Skip to the previous song"
+    "vol:Change the volume"
+    "playlist:Play a specific playlist"
+    {playing,status}":Show what song is currently playing"
+    {shuf,shuff,shuffle}":Set shuffle mode"
+    {-h,--help}":Show usage"
+  )
+
+  if (( CURRENT == 2 )); then
+    _describe 'command' cmds
+  elif (( CURRENT == 3 )); then
+    case "$words[2]" in
+      vol) subcmds=( 'up:Raise the volume' 'down:Lower the volume' )
+        _describe 'command' subcmds ;;
+      shuf|shuff|shuffle) subcmds=('on:Switch on shuffle mode' 'off:Switch off shuffle mode' 'toggle:Toggle shuffle mode (default)')
+        _describe 'command' subcmds ;;
+    esac
+  elif (( CURRENT == 4 )); then
+    case "$words[2]" in
+      playlist) subcmds=('play:Play the playlist (default)' 'stop:Stop the playlist')
+        _describe 'command' subcmds ;;
+    esac
+  fi
+
+  return 0
+}
+
+compdef _music music itunes
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/spotify b/stow/oh-my-zsh/.oh-my-zsh/plugins/macos/spotify
new file mode 100644 (file)
index 0000000..491a606
--- /dev/null
@@ -0,0 +1,478 @@
+#!/usr/bin/env bash
+
+function spotify() {
+# Copyright (c) 2012--2019 Harish Narayanan <mail@harishnarayanan.org>
+#
+# Contains numerous helpful contributions from Jorge Colindres, Thomas
+# Pritchard, iLan Epstein, Gabriele Bonetti, Sean Heller, Eric Martin
+# and Peter Fonseca.
+
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+USER_CONFIG_DEFAULTS="CLIENT_ID=\"\"\nCLIENT_SECRET=\"\"";
+USER_CONFIG_FILE="${HOME}/.shpotify.cfg";
+if ! [[ -f "${USER_CONFIG_FILE}" ]]; then
+    touch "${USER_CONFIG_FILE}";
+    echo -e "${USER_CONFIG_DEFAULTS}" > "${USER_CONFIG_FILE}";
+fi
+source "${USER_CONFIG_FILE}";
+
+showAPIHelp() {
+    echo;
+    echo "Connecting to Spotify's API:";
+    echo;
+    echo "  This command line application needs to connect to Spotify's API in order to";
+    echo "  find music by name. It is very likely you want this feature!";
+    echo;
+    echo "  To get this to work, you need to sign up (or in) and create an 'Application' at:";
+    echo "  https://developer.spotify.com/my-applications/#!/applications/create";
+    echo;
+    echo "  Once you've created an application, find the 'Client ID' and 'Client Secret'";
+    echo "  values, and enter them into your shpotify config file at '${USER_CONFIG_FILE}'";
+    echo;
+    echo "  Be sure to quote your values and don't add any extra spaces!";
+    echo "  When done, it should look like this (but with your own values):";
+    echo '  CLIENT_ID="abc01de2fghijk345lmnop"';
+    echo '  CLIENT_SECRET="qr6stu789vwxyz"';
+}
+
+showHelp () {
+    echo "Usage:";
+    echo;
+    echo "  `basename $0` <command>";
+    echo;
+    echo "Commands:";
+    echo;
+    echo "  play                         # Resumes playback where Spotify last left off.";
+    echo "  play <song name>             # Finds a song by name and plays it.";
+    echo "  play album <album name>      # Finds an album by name and plays it.";
+    echo "  play artist <artist name>    # Finds an artist by name and plays it.";
+    echo "  play list <playlist name>    # Finds a playlist by name and plays it.";
+    echo "  play uri <uri>               # Play songs from specific uri.";
+    echo;
+    echo "  next                         # Skips to the next song in a playlist.";
+    echo "  prev                         # Returns to the previous song in a playlist.";
+    echo "  replay                       # Replays the current track from the beginning.";
+    echo "  pos <time>                   # Jumps to a time (in secs) in the current song.";
+    echo "  pause                        # Pauses (or resumes) Spotify playback.";
+    echo "  stop                         # Stops playback.";
+    echo "  quit                         # Stops playback and quits Spotify.";
+    echo;
+    echo "  vol up                       # Increases the volume by 10%.";
+    echo "  vol down                     # Decreases the volume by 10%.";
+    echo "  vol <amount>                 # Sets the volume to an amount between 0 and 100.";
+    echo "  vol [show]                   # Shows the current Spotify volume.";
+    echo;
+    echo "  status                       # Shows the current player status.";
+    echo "  status artist                # Shows the currently playing artist.";
+    echo "  status album                 # Shows the currently playing album.";
+    echo "  status track                 # Shows the currently playing track.";
+    echo;
+    echo "  share                        # Displays the current song's Spotify URL and URI."
+    echo "  share url                    # Displays the current song's Spotify URL and copies it to the clipboard."
+    echo "  share uri                    # Displays the current song's Spotify URI and copies it to the clipboard."
+    echo;
+    echo "  toggle shuffle               # Toggles shuffle playback mode.";
+    echo "  toggle repeat                # Toggles repeat playback mode.";
+    showAPIHelp
+}
+
+cecho(){
+    bold=$(tput bold);
+    green=$(tput setaf 2);
+    reset=$(tput sgr0);
+    echo $bold$green"$1"$reset;
+}
+
+showArtist() {
+    echo `osascript -e 'tell application "Spotify" to artist of current track as string'`;
+}
+
+showAlbum() {
+    echo `osascript -e 'tell application "Spotify" to album of current track as string'`;
+}
+
+showTrack() {
+    echo `osascript -e 'tell application "Spotify" to name of current track as string'`;
+}
+
+showStatus () {
+    state=`osascript -e 'tell application "Spotify" to player state as string'`;
+    cecho "Spotify is currently $state.";
+    duration=`osascript -e 'tell application "Spotify"
+            set durSec to (duration of current track / 1000) as text
+            set tM to (round (durSec / 60) rounding down) as text
+            if length of ((durSec mod 60 div 1) as text) is greater than 1 then
+                set tS to (durSec mod 60 div 1) as text
+            else
+                set tS to ("0" & (durSec mod 60 div 1)) as text
+            end if
+            set myTime to tM as text & ":" & tS as text
+            end tell
+            return myTime'`;
+    position=`osascript -e 'tell application "Spotify"
+            set pos to player position
+            set nM to (round (pos / 60) rounding down) as text
+            if length of ((round (pos mod 60) rounding down) as text) is greater than 1 then
+                set nS to (round (pos mod 60) rounding down) as text
+            else
+                set nS to ("0" & (round (pos mod 60) rounding down)) as text
+            end if
+            set nowAt to nM as text & ":" & nS as text
+            end tell
+            return nowAt'`;
+
+    echo -e $reset"Artist: $(showArtist)\nAlbum: $(showAlbum)\nTrack: $(showTrack) \nPosition: $position / $duration";
+}
+
+if [ $# = 0 ]; then
+    showHelp;
+else
+       if [ ! -d /Applications/Spotify.app ] && [ ! -d $HOME/Applications/Spotify.app ]; then
+               echo "The Spotify application must be installed."
+               return 1
+       fi
+
+    if [ $(osascript -e 'application "Spotify" is running') = "false" ]; then
+        osascript -e 'tell application "Spotify" to activate' || return 1
+        sleep 2
+    fi
+fi
+while [ $# -gt 0 ]; do
+    arg=$1;
+
+    case $arg in
+        "play"    )
+            if [ $# != 1 ]; then
+                # There are additional arguments, so find out how many
+                array=( $@ );
+                len=${#array[@]};
+                SPOTIFY_SEARCH_API="https://api.spotify.com/v1/search";
+                SPOTIFY_TOKEN_URI="https://accounts.spotify.com/api/token";
+                if [ -z "${CLIENT_ID}" ]; then
+                    cecho "Invalid Client ID, please update ${USER_CONFIG_FILE}";
+                    showAPIHelp;
+                    return 1
+                fi
+                if [ -z "${CLIENT_SECRET}" ]; then
+                    cecho "Invalid Client Secret, please update ${USER_CONFIG_FILE}";
+                    showAPIHelp;
+                    return 1
+                fi
+                SHPOTIFY_CREDENTIALS=$(printf "${CLIENT_ID}:${CLIENT_SECRET}" | base64 | tr -d "\n"|tr -d '\r');
+                SPOTIFY_PLAY_URI="";
+
+                getAccessToken() {
+                    cecho "Connecting to Spotify's API";
+
+                    SPOTIFY_TOKEN_RESPONSE_DATA=$( \
+                        curl "${SPOTIFY_TOKEN_URI}" \
+                            --silent \
+                            -X "POST" \
+                            -H "Authorization: Basic ${SHPOTIFY_CREDENTIALS}" \
+                            -d "grant_type=client_credentials" \
+                    )
+                    if ! [[ "${SPOTIFY_TOKEN_RESPONSE_DATA}" =~ "access_token" ]]; then
+                        cecho "Authorization failed, please check ${USER_CONFG_FILE}"
+                        cecho "${SPOTIFY_TOKEN_RESPONSE_DATA}"
+                        showAPIHelp
+                        return 1
+                    fi
+                    SPOTIFY_ACCESS_TOKEN=$( \
+                        printf "${SPOTIFY_TOKEN_RESPONSE_DATA}" \
+                        | grep -E -o '"access_token":".*",' \
+                        | sed 's/"access_token"://g' \
+                        | sed 's/"//g' \
+                        | sed 's/,.*//g' \
+                    )
+                }
+
+                searchAndPlay() {
+                    type="$1"
+                    Q="$2"
+
+                    getAccessToken;
+
+                    cecho "Searching ${type}s for: $Q";
+
+                    SPOTIFY_PLAY_URI=$( \
+                        curl -s -G $SPOTIFY_SEARCH_API \
+                            -H "Authorization: Bearer ${SPOTIFY_ACCESS_TOKEN}" \
+                            -H "Accept: application/json" \
+                            --data-urlencode "q=$Q" \
+                            -d "type=$type&limit=1&offset=0" \
+                        | grep -E -o "spotify:$type:[a-zA-Z0-9]+" -m 1
+                    )
+                    echo "play uri: ${SPOTIFY_PLAY_URI}"
+                }
+
+                case $2 in
+                    "list"  )
+                        _args=${array[@]:2:$len};
+                        Q=$_args;
+
+                        getAccessToken;
+
+                        cecho "Searching playlists for: $Q";
+
+                        results=$( \
+                            curl -s -G $SPOTIFY_SEARCH_API --data-urlencode "q=$Q" -d "type=playlist&limit=10&offset=0" -H "Accept: application/json" -H "Authorization: Bearer ${SPOTIFY_ACCESS_TOKEN}" \
+                            | grep -E -o "spotify:playlist:[a-zA-Z0-9]+" -m 10 \
+                        )
+
+                        count=$( \
+                            echo "$results" | grep -c "spotify:playlist" \
+                        )
+
+                        if [ "$count" -gt 0 ]; then
+                            random=$(( $RANDOM % $count));
+
+                            SPOTIFY_PLAY_URI=$( \
+                                echo "$results" | awk -v random="$random" '/spotify:playlist:[a-zA-Z0-9]+/{i++}i==random{print; exit}' \
+                            )
+                        fi;;
+
+                    "album" | "artist" | "track"    )
+                        _args=${array[@]:2:$len};
+                        searchAndPlay $2 "$_args";;
+
+                    "uri"  )
+                        SPOTIFY_PLAY_URI=${array[@]:2:$len};;
+
+                    *   )
+                        _args=${array[@]:1:$len};
+                        searchAndPlay track "$_args";;
+                esac
+
+                if [ "$SPOTIFY_PLAY_URI" != "" ]; then
+                    if [ "$2" = "uri" ]; then
+                        cecho "Playing Spotify URI: $SPOTIFY_PLAY_URI";
+                    else
+                        cecho "Playing ($Q Search) -> Spotify URI: $SPOTIFY_PLAY_URI";
+                    fi
+
+                    osascript -e "tell application \"Spotify\" to play track \"$SPOTIFY_PLAY_URI\"";
+
+                else
+                    cecho "No results when searching for $Q";
+                fi
+
+            else
+
+                # play is the only param
+                cecho "Playing Spotify.";
+                osascript -e 'tell application "Spotify" to play';
+            fi
+            break ;;
+
+        "pause"    )
+            state=`osascript -e 'tell application "Spotify" to player state as string'`;
+            if [ $state = "playing" ]; then
+              cecho "Pausing Spotify.";
+            else
+              cecho "Playing Spotify.";
+            fi
+
+            osascript -e 'tell application "Spotify" to playpause';
+            break ;;
+
+        "stop"    )
+            state=`osascript -e 'tell application "Spotify" to player state as string'`;
+            if [ $state = "playing" ]; then
+              cecho "Pausing Spotify.";
+              osascript -e 'tell application "Spotify" to playpause';
+            else
+              cecho "Spotify is already stopped."
+            fi
+
+            break ;;
+
+        "quit"    ) cecho "Quitting Spotify.";
+            osascript -e 'tell application "Spotify" to quit';
+            break ;;
+
+        "next"    ) cecho "Going to next track." ;
+            osascript -e 'tell application "Spotify" to next track';
+            showStatus;
+            break ;;
+
+        "prev"    ) cecho "Going to previous track.";
+            osascript -e '
+            tell application "Spotify"
+                set player position to 0
+                previous track
+            end tell';
+            showStatus;
+            break ;;
+
+        "replay"  ) cecho "Replaying current track.";
+            osascript -e 'tell application "Spotify" to set player position to 0'
+            break ;;
+
+        "vol"    )
+            vol=`osascript -e 'tell application "Spotify" to sound volume as integer'`;
+            if [[ $2 = "" || $2 = "show" ]]; then
+                cecho "Current Spotify volume level is $vol.";
+                break ;
+            elif [ "$2" = "up" ]; then
+                if [ $vol -le 90 ]; then
+                    newvol=$(( vol+10 ));
+                    cecho "Increasing Spotify volume to $newvol.";
+                else
+                    newvol=100;
+                    cecho "Spotify volume level is at max.";
+                fi
+            elif [ "$2" = "down" ]; then
+                if [ $vol -ge 10 ]; then
+                    newvol=$(( vol-10 ));
+                    cecho "Reducing Spotify volume to $newvol.";
+                else
+                    newvol=0;
+                    cecho "Spotify volume level is at min.";
+                fi
+            elif [[ $2 =~ ^[0-9]+$ ]] && [[ $2 -ge 0 && $2 -le 100 ]]; then
+                newvol=$2;
+                cecho "Setting Spotify volume level to $newvol";
+            else
+                echo "Improper use of 'vol' command"
+                echo "The 'vol' command should be used as follows:"
+                echo "  vol up                       # Increases the volume by 10%.";
+                echo "  vol down                     # Decreases the volume by 10%.";
+                echo "  vol [amount]                 # Sets the volume to an amount between 0 and 100.";
+                echo "  vol                          # Shows the current Spotify volume.";
+                return 1
+            fi
+
+            osascript -e "tell application \"Spotify\" to set sound volume to $newvol";
+            break ;;
+
+        "toggle"  )
+            if [ "$2" = "shuffle" ]; then
+                osascript -e 'tell application "Spotify" to set shuffling to not shuffling';
+                curr=`osascript -e 'tell application "Spotify" to shuffling'`;
+                cecho "Spotify shuffling set to $curr";
+            elif [ "$2" = "repeat" ]; then
+                osascript -e 'tell application "Spotify" to set repeating to not repeating';
+                curr=`osascript -e 'tell application "Spotify" to repeating'`;
+                cecho "Spotify repeating set to $curr";
+            fi
+            break ;;
+
+        "status" )
+            if [ $# != 1 ]; then
+                # There are additional arguments, a status subcommand
+                case $2 in
+                    "artist" )
+                        showArtist;
+                        break ;;
+
+                    "album" )
+                        showAlbum;
+                        break ;;
+
+                    "track" )
+                        showTrack;
+                        break ;;
+                esac
+            else
+                # status is the only param
+                showStatus;
+            fi
+            break ;;
+
+        "info" )
+            info=`osascript -e 'tell application "Spotify"
+                set durSec to (duration of current track / 1000)
+                set tM to (round (durSec / 60) rounding down) as text
+                if length of ((durSec mod 60 div 1) as text) is greater than 1 then
+                    set tS to (durSec mod 60 div 1) as text
+                else
+                    set tS to ("0" & (durSec mod 60 div 1)) as text
+                end if
+                set myTime to tM as text & "min " & tS as text & "s"
+                set pos to player position
+                set nM to (round (pos / 60) rounding down) as text
+                if length of ((round (pos mod 60) rounding down) as text) is greater than 1 then
+                    set nS to (round (pos mod 60) rounding down) as text
+                else
+                    set nS to ("0" & (round (pos mod 60) rounding down)) as text
+                end if
+                set nowAt to nM as text & "min " & nS as text & "s"
+                set info to "" & "\nArtist:         " & artist of current track
+                set info to info & "\nTrack:          " & name of current track
+                set info to info & "\nAlbum Artist:   " & album artist of current track
+                set info to info & "\nAlbum:          " & album of current track
+                set info to info & "\nSeconds:        " & durSec
+                set info to info & "\nSeconds played: " & pos
+                set info to info & "\nDuration:       " & mytime
+                set info to info & "\nNow at:         " & nowAt
+                set info to info & "\nPlayed Count:   " & played count of current track
+                set info to info & "\nTrack Number:   " & track number of current track
+                set info to info & "\nPopularity:     " & popularity of current track
+                set info to info & "\nId:             " & id of current track
+                set info to info & "\nSpotify URL:    " & spotify url of current track
+                set info to info & "\nArtwork:        " & artwork url of current track
+                set info to info & "\nPlayer:         " & player state
+                set info to info & "\nVolume:         " & sound volume
+                set info to info & "\nShuffle:        " & shuffling
+                set info to info & "\nRepeating:      " & repeating
+            end tell
+            return info'`
+            cecho "$info";
+            break ;;
+
+        "share"     )
+            uri=`osascript -e 'tell application "Spotify" to spotify url of current track'`;
+            remove='spotify:track:'
+            url=${uri#$remove}
+            url="https://open.spotify.com/track/$url"
+
+            if [ "$2" = "" ]; then
+                cecho "Spotify URL: $url"
+                cecho "Spotify URI: $uri"
+                echo "To copy the URL or URI to your clipboard, use:"
+                echo "\`spotify share url\` or"
+                echo "\`spotify share uri\` respectively."
+            elif [ "$2" = "url" ]; then
+                cecho "Spotify URL: $url";
+                echo -n $url | pbcopy
+            elif [ "$2" = "uri" ]; then
+                cecho "Spotify URI: $uri";
+                echo -n $uri | pbcopy
+            fi
+            break ;;
+
+        "pos"   )
+            cecho "Adjusting Spotify play position."
+            osascript -e "tell application \"Spotify\" to set player position to $2";
+            break ;;
+
+        "help" )
+            showHelp;
+            break ;;
+
+        * )
+            showHelp;
+            return 1 ;;
+
+    esac
+done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macports/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/macports/README.md
new file mode 100644 (file)
index 0000000..09bd42d
--- /dev/null
@@ -0,0 +1,47 @@
+# Macports plugin
+
+This plugin adds completion for the package manager [Macports](https://macports.com/),
+as well as some aliases for common Macports commands.
+
+To use it, add `macports` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... macports)
+```
+
+## Aliases
+
+| Alias | Command                            | Description                                                  |
+|-------|------------------------------------|--------------------------------------------------------------|
+| pc    | `sudo port clean --all installed`  | Clean up intermediate installation files for installed ports |
+| pi    | `sudo port install`                | Install package given as argument                            |
+| pli   | `port livecheck installed`         | Check for updates for installed ports                        |
+| plm   | `port-livecheck-maintainer`        | Check for updates of ports mainained by the specified users  |
+| psu   | `sudo port selfupdate`             | Update ports tree with MacPorts repository                   |
+| puni  | `sudo port uninstall inactive`     | Uninstall inactive ports                                     |
+| puo   | `sudo port upgrade outdated`       | Upgrade ports with newer versions available                  |
+| pup   | `psu && puo`                       | Update ports tree, then upgrade ports to newest versions     |
+
+## Commands
+
+### port-livecheck-maintainer
+
+```text
+Usage:
+  port-livecheck-maintainer
+  port-livecheck-maintainer (maintainer)+
+  port-livecheck-maintainer -h|--help
+
+Check
+
+Options:
+  maintainer  maintainer id
+  -h          print this help message and exit
+```
+
+Checks whether updates are available for ports whose maintainer is the current
+user, or any of a specified list of maintainer expressions.  The current user
+maintainer id is retrieved as follows:
+
+* The value of the `MACPORTS_MAINTAINER` variable, if set and not null.
+* The value of the `USER` variable.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macports/_port b/stow/oh-my-zsh/.oh-my-zsh/plugins/macports/_port
new file mode 100644 (file)
index 0000000..897598a
--- /dev/null
@@ -0,0 +1,92 @@
+#compdef port
+
+local subcmds 
+
+# we cache the list of ports
+# we shall use some cache policy to avoid problems with new ports
+if (( ! $+portlist )); then
+       portlist=($(port echo all; echo "all current active inactive installed uninstalled outdated"))
+fi
+
+subcmds=(
+'activate'
+'archive'
+'build'
+'cat'
+'clean'
+'configure'
+'contents'
+'deactivate'
+'dependents'
+'deps'
+'destroot'
+'dir'
+'distcheck'
+'distclean'
+'dmg'
+'echo'
+'edit'
+'extract'
+'fetch'
+'file'
+'help'
+'info'
+'install' 
+'installed' 
+'list'
+'livecheck'
+'location'
+'mpkg'
+'outdated'
+'patch'
+'pkg'
+'provides'
+'rdependents'
+'rdeps'
+'reclaim'
+'rpmpackage'
+'search'
+'selfupdate'
+'sync'
+'test'
+'unarchive'
+'uninstall'
+'upgrade' 
+'variants'
+'version'
+)
+
+_arguments -C \
+'-v[verbose mode (generate verbose messages)]' \
+'-d[debug mode (generate debugging messages)]' \
+'-q[quiet mode (suppress messages)]' \
+'-D[specify portdir]' \
+'-k[keep mode (do not autoclean after install)]' \
+'-n[dont follow dependencies in upgrade (only for upgrading)]' \
+'-a[upgrade all installed ports (only for upgrading)]' \
+'-u[uninstall non-active ports when upgrading and uninstalling]' \
+'-f[force mode (ignore state file)]' \
+'-s[source-only mode]' \
+'-b[binary-only mode]' \
+'-o[honor state files older than Portfile]' \
+'*::command:->command' \
+&& return 0
+
+case $state in
+       command)
+       if ((CURRENT == 1)); then
+               state=subcommands
+       else
+               state=portname
+       fi
+       ;;
+esac
+
+case $state in
+       subcommands)
+       _describe -t commands 'port commands' subcmds
+       ;;
+       portname)
+       _describe -t commands 'available ports' portlist
+       ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/macports/macports.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/macports/macports.plugin.zsh
new file mode 100644 (file)
index 0000000..d438057
--- /dev/null
@@ -0,0 +1,44 @@
+alias pc="sudo port clean --all installed"
+alias pi="sudo port install"
+alias pli="port livecheck installed"
+alias plm="port-livecheck-maintainer"
+alias psu="sudo port selfupdate"
+alias puni="sudo port uninstall inactive"
+alias puo="sudo port upgrade outdated"
+alias pup="sudo port selfupdate && sudo port upgrade outdated"
+
+port-livecheck-maintainer() {
+  (( ${+commands[port]} == 0 )) || {
+    print -- "port: not found" >&2
+    return 1
+  }
+
+  local -a help_flag
+  zparseopts -D -E h=help_flag -help=help_flag
+
+  (( ${#help_flag} )) && {
+    cat << EOF >&2
+Usage:
+  port-livecheck-maintainer
+  port-livecheck-maintainer (maintainer)+
+  port-livecheck-maintainer -h|--help
+
+Check
+
+Options:
+  maintainer  maintainer id
+  -h          print this help message and exit
+EOF
+    return 1
+  }
+
+  if (( $# == 0 )); then
+    local default=${MACPORTS_MAINTAINER:-${USER}}
+    port livecheck maintainer:${default}
+    return $?
+  fi
+
+  for i in $@; do
+    port livecheck maintainer:${i}
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/magic-enter/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/magic-enter/README.md
new file mode 100644 (file)
index 0000000..78514c6
--- /dev/null
@@ -0,0 +1,17 @@
+## Magic Enter plugin
+
+This plugin makes your enter key magical, by binding commonly used commands to it.
+
+To use it, add `magic-enter` to the plugins array in your zshrc file. You can set the
+commands to be run in your .zshrc, before the line containing plugins. If no command
+is specified in a git directory, `git status` is executed; in other directories, `ls`.
+
+```zsh
+# defaults
+MAGIC_ENTER_GIT_COMMAND='git status -u .'
+MAGIC_ENTER_OTHER_COMMAND='ls -lh .'
+
+plugins=(... magic-enter)
+```
+
+**Maintainer:** [@dufferzafar](https://github.com/dufferzafar)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/magic-enter/magic-enter.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/magic-enter/magic-enter.plugin.zsh
new file mode 100644 (file)
index 0000000..55b8935
--- /dev/null
@@ -0,0 +1,38 @@
+# Default commands
+: ${MAGIC_ENTER_GIT_COMMAND:="git status -u ."} # run when in a git repository
+: ${MAGIC_ENTER_OTHER_COMMAND:="ls -lh ."}      # run anywhere else
+
+magic-enter() {
+  # Only run MAGIC_ENTER commands when in PS1 and command line is empty
+  # http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#User_002dDefined-Widgets
+  if [[ -n "$BUFFER" || "$CONTEXT" != start ]]; then
+    return
+  fi
+
+  if command git rev-parse --is-inside-work-tree &>/dev/null; then
+    BUFFER="$MAGIC_ENTER_GIT_COMMAND"
+  else
+    BUFFER="$MAGIC_ENTER_OTHER_COMMAND"
+  fi
+}
+
+# Wrapper for the accept-line zle widget (run when pressing Enter)
+
+# If the wrapper already exists don't redefine it
+(( ! ${+functions[_magic-enter_accept-line]} )) || return 0
+
+case "$widgets[accept-line]" in
+  # Override the current accept-line widget, calling the old one
+  user:*) zle -N _magic-enter_orig_accept-line "${widgets[accept-line]#user:}"
+    function _magic-enter_accept-line() {
+      magic-enter
+      zle _magic-enter_orig_accept-line -- "$@"
+    } ;;
+  # If no user widget defined, call the original accept-line widget
+  builtin) function _magic-enter_accept-line() {
+      magic-enter
+      zle .accept-line
+    } ;;
+esac
+
+zle -N accept-line _magic-enter_accept-line
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/man/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/man/README.md
new file mode 100644 (file)
index 0000000..4601252
--- /dev/null
@@ -0,0 +1,13 @@
+# Man plugin
+
+This plugin adds a shortcut to insert man before the previous command.
+
+To use it, add `man` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... man)
+```
+# Keyboard Shortcuts
+| Shortcut                          | Description                                                            |
+|-----------------------------------|------------------------------------------------------------------------|
+| <kbd>Esc</kbd> + man              | add man before the previous command to see the manual for this command |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/man/man.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/man/man.plugin.zsh
new file mode 100644 (file)
index 0000000..dcba613
--- /dev/null
@@ -0,0 +1,37 @@
+# ------------------------------------------------------------------------------
+# Author
+# ------
+#
+# * Jerry Ling<jerryling315@gmail.com>
+#
+# ------------------------------------------------------------------------------
+# Usage
+# -----
+#
+# man will be inserted before the command
+#
+# ------------------------------------------------------------------------------
+
+man-command-line() {
+    # if there is no command typed, use the last command
+    [[ -z "$BUFFER" ]] && zle up-history
+
+    # if typed command begins with man, do nothing
+    [[ "$BUFFER" = man\ * ]] && return
+
+    # get command and possible subcommand
+    # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags
+    local -a args
+    args=(${${(Az)BUFFER}[1]} ${${(Az)BUFFER}[2]})
+
+    # check if man page exists for command and first argument
+    if man "${args[1]}-${args[2]}" >/dev/null 2>&1; then
+        BUFFER="man $args"
+    else
+        BUFFER="man ${args[1]}"
+    fi
+}
+
+zle -N man-command-line
+# Defined shortcut keys: [Esc]man
+bindkey "\e"man man-command-line
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/marked2/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/marked2/README.md
new file mode 100644 (file)
index 0000000..101343a
--- /dev/null
@@ -0,0 +1,13 @@
+## marked2
+
+Plugin for Marked 2, a previewer for Markdown files on Mac OS X 
+
+### Requirements
+
+ * [Marked 2](http://marked2app.com)
+
+### Usage
+
+ * If `marked` is called without an argument, open Marked
+
+ * If `marked` is passed a file, open it in Marked
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/marked2/marked2.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/marked2/marked2.plugin.zsh
new file mode 100644 (file)
index 0000000..56863ad
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# If marked is called without an argument, open Marked
+# If marked is passed a file, open it in Marked
+#
+function marked() {
+    if [ "$1" ]
+    then
+        open -a "marked 2.app" "$1"
+    else
+        open -a "marked 2.app"
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mercurial/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mercurial/README.md
new file mode 100644 (file)
index 0000000..19d4a17
--- /dev/null
@@ -0,0 +1,69 @@
+# Mercurial plugin
+
+This plugin adds some handy aliases for using Mercurial as well as a few
+utility and prompt functions that can be used in a theme.
+
+To use it, add `mercurial` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... mercurial)
+```
+
+## Aliases
+
+| Alias   | Command                                     |
+| ------- | ------------------------------------------- |
+| `hga`   | `hg add`                                    |
+| `hgc`   | `hg commit`                                 |
+| `hgca`  | `hg commit --amend`                         |
+| `hgci`  | `hg commit --interactive`                   |
+| `hgb`   | `hg branch`                                 |
+| `hgba`  | `hg branches`                               |
+| `hgbk`  | `hg bookmarks`                              |
+| `hgco`  | `hg checkout`                               |
+| `hgd`   | `hg diff`                                   |
+| `hged`  | `hg diffmerge`                              |
+| `hgp`   | `hg push`                                   |
+| `hgs`   | `hg status`                                 |
+| `hgsl`  | `hg log --limit 20 --template "<template>"` |
+| `hgun`  | `hg resolve --list`                         |
+| `hgi`   | `hg incoming`                               |
+| `hgl`   | `hg pull -u`                                |
+| `hglr`  | `hg pull --rebase`                          |
+| `hgo`   | `hg outgoing`                               |
+| `hglg`  | `hg log --stat -v`                          |
+| `hglgp` | `hg log --stat -p -v`                       |
+
+## Prompt usage
+
+- Switch to a theme which uses `hg_prompt_info`
+
+- Or customize the `$PROMPT` variable of your current theme to contain current folder mercurial repo info.
+  This can be done by putting a custom version of the theme in `$ZSH_CUSTOM` or by changing `$PROMPT` in
+  `.zshrc` after loading the theme.
+
+  For example, for the `robbyrussell` theme you need to modify `$PROMPT` var by adding `$(hg_prompt_info)`
+  after `$(git_prompt_info)`, so it looks like this:
+
+  ```zsh
+  PROMPT='${ret_status}%{$fg_bold[green]%}%p %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)$(hg_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
+  ```
+
+You can also redefine additional vars used in the plugin (after Oh My Zsh is sourced):
+
+```zsh
+ZSH_THEME_HG_PROMPT_PREFIX="%{$fg_bold[magenta]%}hg:(%{$fg[red]%}"
+ZSH_THEME_HG_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_HG_PROMPT_DIRTY="%{$fg[magenta]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_HG_PROMPT_CLEAN="%{$fg[magenta]%})"
+```
+
+### Display repo branch and directory status in prompt
+
+This is the same as git plugin does. **Note**: additional changes to `.zshrc`, or using a theme designed
+to use `hg_prompt_info`, are required in order for this to work.
+
+## Maintainers
+
+- [ptrv](https://github.com/ptrv): original creator
+- [oshybystyi](https://github.com/oshybystyi)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mercurial/mercurial.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/mercurial/mercurial.plugin.zsh
new file mode 100644 (file)
index 0000000..9b85d02
--- /dev/null
@@ -0,0 +1,118 @@
+# aliases
+alias hga='hg add'
+alias hgc='hg commit'
+alias hgca='hg commit --amend'
+alias hgci='hg commit --interactive'
+alias hgb='hg branch'
+alias hgba='hg branches'
+alias hgbk='hg bookmarks'
+alias hgco='hg checkout'
+alias hgd='hg diff'
+alias hged='hg diffmerge'
+alias hgp='hg push'
+alias hgs='hg status'
+alias hgsl='hg log --limit 20 --template "{node|short} | {date|isodatesec} | {author|person}: {desc|strip|firstline}\n" '
+alias hgun='hg resolve --list'
+# pull and update
+alias hgi='hg incoming'
+alias hgl='hg pull -u'
+alias hglr='hg pull --rebase'
+alias hgo='hg outgoing'
+alias hglg='hg log --stat -v'
+alias hglgp='hg log --stat  -p -v'
+
+function hgic() {
+  hg incoming "$@" | grep "changeset" | wc -l
+}
+
+function hgoc() {
+  hg outgoing "$@" | grep "changeset" | wc -l
+}
+
+# functions
+function hg_root() {
+  local dir="$PWD"
+  while [[ "$dir" != "/" ]]; do
+    if [[ -d "$dir/.hg" ]]; then
+      echo "$dir"
+      return 0
+    fi
+    dir="${dir:h}"
+  done
+  return 1
+}
+
+function in_hg() {
+  hg_root >/dev/null
+}
+
+function hg_get_branch_name() {
+  local dir
+  if ! dir=$(hg_root); then
+    return
+  fi
+
+  if [[ ! -f "$dir/.hg/branch" ]]; then
+    echo default
+    return
+  fi
+
+  echo "$(<"$dir/.hg/branch")"
+}
+
+function hg_get_bookmark_name() {
+  local dir
+  if ! dir=$(hg_root); then
+    return
+  fi
+
+  if [[ ! -f "$dir/.hg/bookmarks.current" ]]; then
+    return
+  fi
+
+  echo "$(<"$dir/.hg/bookmarks.current")"
+}
+
+function hg_prompt_info {
+  local dir branch dirty
+  if ! dir=$(hg_root); then
+    return
+  fi
+
+  if [[ ! -f "$dir/.hg/branch" ]]; then
+    branch=default
+  else
+    branch="$(<"$dir/.hg/branch")"
+  fi
+
+  dirty="$(hg_dirty)"
+
+  echo "${ZSH_THEME_HG_PROMPT_PREFIX}${branch:gs/%/%%}${dirty}${ZSH_THEME_HG_PROMPT_SUFFIX}"
+}
+
+function hg_dirty {
+  # Do nothing if clean / dirty settings aren't defined
+  if [[ -z "$ZSH_THEME_HG_PROMPT_DIRTY" && -z "$ZSH_THEME_HG_PROMPT_CLEAN" ]]; then
+    return
+  fi
+
+  # Check if there are modifications
+  local hg_status
+  if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" = true ]]; then
+    if ! hg_status="$(hg status -q 2>/dev/null)"; then
+      return
+    fi
+  else
+    if ! hg_status="$(hg status 2>/dev/null)"; then
+      return
+    fi
+  fi
+
+  # grep exits with 0 when dirty
+  if command grep -Eq '^\s*[ACDIMR!?L].*$' <<< "$hg_status"; then
+    echo $ZSH_THEME_HG_PROMPT_DIRTY
+    return
+  fi
+
+  echo $ZSH_THEME_HG_PROMPT_CLEAN
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/README.md
new file mode 100644 (file)
index 0000000..f7c43b7
--- /dev/null
@@ -0,0 +1,46 @@
+# meteor plugin
+
+The [meteor plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/meteor) provides many
+[useful aliases](#aliases) as well as completion for the `meteor` command.
+
+Enable it by adding `meteor` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... meteor)
+```
+
+## Aliases
+
+| Alias   | Command                    | Description                                                      |
+|---------|----------------------------|------------------------------------------------------------------|
+| `ma`    | `meteor add`               | Add a package to this project                                    |
+| `map`   | `meteor add-platform`      | Add a platform to this project                                   |
+| `mad`   | `meteor admin`             | Administrative commands                                          |
+| `mau`   | `meteor authorized`        | View or change authorized users and organizations for a site     |
+| `mb`    | `meteor build`             | Build this project for all platforms                             |
+| `mcl`   | `meteor claim`             | Claim a site deployed with an old Meteor version                 |
+| `mca`   | `meteor configure-android` | Run the Android configuration tool from Meteor's ADK environment |
+| `mc`    | `meteor create`            | Create a new project                                             |
+| `mdb`   | `meteor debug`             | Run the project, but suspend the server process for debugging    |
+| `mde`   | `meteor deploy`            | Deploy this project to Meteor                                    |
+| `mis`   | `meteor install-sdk`       | Installs SDKs for a platform                                     |
+| `ml`    | `meteor list`              | List the packages explicitly used by your project                |
+| `mlp`   | `meteor list-platforms`    | List the platforms added to your project                         |
+| `mls`   | `meteor list-sites`        | List sites for which you are authorized                          |
+| `mli`   | `meteor login`             | Log in to your Meteor developer account                          |
+| `mlo`   | `meteor logout`            | Log out of your Meteor developer account                         |
+| `mlog`  | `meteor logs`              | Show logs for specified site                                     |
+| `mm`    | `meteor mongo`             | Connect to the Mongo database for the specified site             |
+| `mp`    | `meteor publish`           | Publish a new version of a package to the package server         |
+| `mpa`   | `meteor publish-for-arch`  | Builds an already-published package for a new platform           |
+| `mpr`   | `meteor publish-release`   | Publish a new meteor release to the package server               |
+| `mr`    | `meteor remove`            | Remove a package from this project                               |
+| `mrp`   | `meteor remove-platform`   | Remove a platform from this project                              |
+| `mre`   | `meteor reset`             | Reset the project state. Erases the local database               |
+| `m`     | `meteor run`               | **[default]** Run this project in local development mode         |
+| `ms`    | `meteor search`            | Search through the package server database                       |
+| `msh`   | `meteor shell`             | Launch a Node REPL for interactively evaluating server-side code |
+| `msw`   | `meteor show`              | Show detailed information about a release or package             |
+| `mt`    | `meteor test-packages`     | Test one or more packages                                        |
+| `mu`    | `meteor update`            | Upgrade this project's dependencies to their latest versions     |
+| `mw`    | `meteor whoami`            | Prints the username of your Meteor developer account             |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/_meteor b/stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/_meteor
new file mode 100644 (file)
index 0000000..6a15c4b
--- /dev/null
@@ -0,0 +1,67 @@
+#compdef meteor
+#autoload
+
+# Meteor Autocomplete plugin for Oh-My-Zsh, based on homebrew completion
+# Original author: Dimitri JORGE (https://github.com/jorge-d)
+
+_meteor_all_packages() {
+  packages=(`meteor list | cut -d" " -f1`)
+}
+_meteor_installed_packages() {
+  installed_packages=(`meteor list --using`)
+}
+
+local -a _1st_arguments
+_1st_arguments=(
+  "add-platform:Add a platform to this project."
+  "add:Add a package to this project."
+  "admin:Administrative commands."
+  "authorized:View or change authorized users and organizations for a site."
+  "build:Build this project for all platforms."
+  "claim:Claim a site deployed with an old Meteor version."
+  "configure-android:Run the Android configuration tool from Meteor's ADK environment."
+  "create:Create a new project."
+  "debug:Run the project, but suspend the server process for debugging."
+  "deploy:Deploy this project to Meteor."
+  "install-sdk:Installs SDKs for a platform."
+  "lint:Build this project and run the linters printing all errors and warnings."
+  "list-platforms:List the platforms added to your project."
+  "list-sites:List sites for which you are authorized."
+  "list:List the packages explicitly used by your project."
+  "login:Log in to your Meteor developer account."
+  "logout:Log out of your Meteor developer account."
+  "logs:Show logs for specified site."
+  "mongo:Connect to the Mongo database for the specified site."
+  "publish-for-arch:Builds an already-published package for a new platform."
+  "publish-release:Publish a new meteor release to the package server."
+  "publish:Publish a new version of a package to the package server."
+  "remove-platform:Remove a platform from this project."
+  "remove:Remove a package from this project."
+  "reset:Reset the project state. Erases the local database."
+  "run:[default] Run this project in local development mode."
+  "search:Search through the package server database."
+  "shell:Launch a Node REPL for interactively evaluating server-side code."
+  "show:Show detailed information about a release or package."
+  "test-packages:Test one or more packages."
+  "update:Upgrade this project's dependencies to their latest versions."
+  "whoami:Prints the username of your Meteor developer account."
+)
+
+local expl
+local -a packages installed_packages
+
+if (( CURRENT == 2 )); then
+  _describe -t commands "meteor subcommand" _1st_arguments
+  return
+fi
+
+case "$words[2]" in
+    help)
+      _describe -t commands "meteor subcommand" _1st_arguments ;;
+    remove)
+      _meteor_installed_packages
+      _wanted installed_packages expl 'installed packages' compadd -a installed_packages ;;
+    add)
+      _meteor_all_packages
+      _wanted packages expl 'all packages' compadd -a packages ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/meteor.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/meteor/meteor.plugin.zsh
new file mode 100644 (file)
index 0000000..db55e36
--- /dev/null
@@ -0,0 +1,33 @@
+# Aliases in alphabetical order
+
+alias ma='meteor add'                  # Add a package to this project.
+alias map='meteor add-platform'        # Add a platform to this project.
+alias mad='meteor admin'               # Administrative commands.
+alias mau='meteor authorized'          # View or change authorized users and organizations for a site.
+alias mb='meteor build'                # Build this project for all platforms.
+alias mcl='meteor claim'               # Claim a site deployed with an old Meteor version.
+alias mca='meteor configure-android'   # Run the Android configuration tool from Meteor's ADK environment.
+alias mc='meteor create'               # Create a new project.
+alias mdb='meteor debug'               # Run the project, but suspend the server process for debugging.
+alias mde='meteor deploy'              # Deploy this project to Meteor.
+alias mis='meteor install-sdk'         # Installs SDKs for a platform.
+alias ml='meteor list'                 # List the packages explicitly used by your project.
+alias mlp='meteor list-platforms'      # List the platforms added to your project.
+alias mls='meteor list-sites'          # List sites for which you are authorized.
+alias mli='meteor login'               # Log in to your Meteor developer account.
+alias mlo='meteor logout'              # Log out of your Meteor developer account.
+alias mlog='meteor logs'               # Show logs for specified site.
+alias mm='meteor mongo'                # Connect to the Mongo database for the specified site.
+alias mp='meteor publish'              # Publish a new version of a package to the package server.
+alias mpa='meteor publish-for-arch'    # Builds an already-published package for a new platform.
+alias mpr='meteor publish-release'     # Publish a new meteor release to the package server.
+alias mr='meteor remove'               # Remove a package from this project.
+alias mrp='meteor remove-platform'     # Remove a platform from this project.
+alias mre='meteor reset'               # Reset the project state. Erases the local database.
+alias m='meteor run'                   # [default] Run this project in local development mode.
+alias ms='meteor search'               # Search through the package server database.
+alias msh='meteor shell'               # Launch a Node REPL for interactively evaluating server-side code.
+alias msw='meteor show'                # Show detailed information about a release or package.
+alias mt='meteor test-packages'        # Test one or more packages.
+alias mu='meteor update'               # Upgrade this project's dependencies to their latest versions.
+alias mw='meteor whoami'               # Prints the username of your Meteor developer account.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/microk8s/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/microk8s/README.md
new file mode 100644 (file)
index 0000000..2b4ea20
--- /dev/null
@@ -0,0 +1,24 @@
+# MicroK8s plugin
+
+This plugin provides completion and useful aliases for [MicroK8s](https://microk8s.io/).
+
+To use it, add `microk8s` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... microk8s)
+```
+
+## Aliases
+
+| Alias | Command          | Description                                                                                              |
+|-------|------------------|----------------------------------------------------------------------------------------------------------|
+| mco   | microk8s.config  | Shows the Kubernetes config file.                                                                        |
+| mct   | microk8s.ctr     | Interact with containerd CLI.                                                                            |
+| mdi   | microk8s.disable | Disables an addon.                                                                                       |
+| me    | microk8s.enable  | Enables an addon.                                                                                        |
+| mh    | microk8s.helm    | Interact with Helm CLI.                                                                                  |
+| mis   | microk8s.istio   | Interact with Istio CLI.                                                                                 |
+| mk    | microk8s.kubectl | Interact with Kubernetes CLI.                                                                            |
+| msp   | microk8s.stop    | Stops all Kubernetes services.                                                                           |
+| mst   | microk8s.start   | Starts MicroK8s after it is being stopped.                                                               |
+| msts  | microk8s.status  | Provides an overview of the MicroK8s state (running / not running) as well as the set of enabled addons. |
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/microk8s/microk8s.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/microk8s/microk8s.plugin.zsh
new file mode 100644 (file)
index 0000000..048a9ab
--- /dev/null
@@ -0,0 +1,82 @@
+# ---------------------------------------------------------- #
+# Aliases and Completions for MicroK8s (https://microk8s.io) #
+# Author: Shaun Tabone (https://github.com/xontab)           #
+# ---------------------------------------------------------- #
+
+# Helper function to cache and load completions
+_microk8s_cache_completion() {
+  local cache="${ZSH_CACHE_DIR}/microk8s_$(echo $1)_completion"
+  if [[ ! -f $cache ]]; then
+    $2 $cache
+  fi
+
+  [[ -f $cache ]] && source $cache
+}
+
+# ---------------------------------------------------------- #
+# microk8s.enable                                            #
+# ALIAS: me                                                  #
+# ---------------------------------------------------------- #
+_microk8s_enable_get_command_list() {
+  microk8s.enable --help | tail -n +7 | awk '{$1=$1;print}'
+}
+
+_microk8s_enable() {
+   compadd -X "MicroK8s Addons" $(_microk8s_enable_get_command_list)
+}
+
+compdef _microk8s_enable microk8s.enable
+alias me='microk8s.enable'
+
+# ---------------------------------------------------------- #
+# microk8s.disable                                           #
+# ALIAS: mdi                                                 #
+# ---------------------------------------------------------- #
+_microk8s_disable_get_command_list() {
+  microk8s.disable --help | tail -n +7 | awk '{$1=$1;print}'
+}
+
+_microk8s_disable() {
+  compadd -X "MicroK8s Addons" $(_microk8s_disable_get_command_list)
+}
+
+compdef _microk8s_disable microk8s.disable
+alias mdi='microk8s.disable'
+
+# ---------------------------------------------------------- #
+# microk8s.kubectl                                           #
+# ALIAS: mk                                                  #
+# ---------------------------------------------------------- #
+_microk8s_kubectl_completion() {
+  if [ $commands[microk8s.kubectl] ]; then
+    microk8s.kubectl 2>/dev/null >/dev/null && microk8s.kubectl completion zsh | sed 's/__start_kubectl kubectl/__start_kubectl microk8s.kubectl/g' >$1
+  fi
+}
+
+_microk8s_cache_completion 'kubectl' _microk8s_kubectl_completion
+
+alias mk='microk8s.kubectl'
+
+# ---------------------------------------------------------- #
+# microk8s.helm                                              #
+# ALIAS: mh                                                  #
+# ---------------------------------------------------------- #
+_microk8s_helm_completion() {
+  if [ $commands[microk8s.helm] ]; then
+    microk8s.helm completion zsh | sed 's/__start_helm helm/__start_helm microk8s.helm/g' >$1
+  fi
+}
+
+_microk8s_cache_completion 'helm' _microk8s_helm_completion
+
+alias mh='microk8s.helm'
+
+# ---------------------------------------------------------- #
+# Other Aliases                                              #
+# ---------------------------------------------------------- #
+alias mco='microk8s.config'
+alias mct='microk8s.ctr'
+alias mis='microk8s.istio'
+alias mst='microk8s.start'
+alias msts='microk8s.status'
+alias msp='microk8s.stop'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/minikube/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/minikube/README.md
new file mode 100644 (file)
index 0000000..eb2dd9b
--- /dev/null
@@ -0,0 +1,9 @@
+# minikube
+
+This plugin provides completion for [minikube](https://github.com/kubernetes/minikube).
+
+To use it, add `minikube` to the plugins array in your zshrc file.
+
+```
+plugins=(... minikube)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/minikube/minikube.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/minikube/minikube.plugin.zsh
new file mode 100644 (file)
index 0000000..e87abce
--- /dev/null
@@ -0,0 +1,13 @@
+# Autocompletion for Minikube.
+#
+if (( $+commands[minikube] )); then
+    __MINIKUBE_COMPLETION_FILE="${ZSH_CACHE_DIR}/minikube_completion"
+
+    if [[ ! -f $__MINIKUBE_COMPLETION_FILE ]]; then
+        minikube completion zsh >! $__MINIKUBE_COMPLETION_FILE
+    fi
+
+    [[ -f $__MINIKUBE_COMPLETION_FILE ]] && source $__MINIKUBE_COMPLETION_FILE
+
+    unset __MINIKUBE_COMPLETION_FILE
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mix-fast/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mix-fast/README.md
new file mode 100644 (file)
index 0000000..644f124
--- /dev/null
@@ -0,0 +1,28 @@
+# mix-fast
+
+Fast mix autocompletion plugin.
+
+This script caches the output for later usage and significantly speeds it up.
+It generates a .mix_tasks cache file for current project. Currently if you want
+to update cache you should remove .mix_tasks file
+
+Inspired by and based on rake-fast zsh plugin.
+
+This is entirely based on [this pull request by Ullrich Schäfer](https://github.com/robb/.dotfiles/pull/10/), which is inspired by [this Ruby on Rails trick from 2006](https://weblog.rubyonrails.org/2006/3/9/fast-rake-task-completion-for-zsh/).
+
+
+## Installation
+
+Just add the plugin to your `.zshrc`:
+
+```bash
+plugins=(foo bar mix-fast)
+```
+
+You might consider adding `.mix_tasks` to your [global .gitignore](https://help.github.com/articles/ignoring-files#global-gitignore)
+
+## Usage
+
+`mix`, then press tab
+
+Currently maintained by [styx](https://github.com/styx/)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mix-fast/mix-fast.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/mix-fast/mix-fast.plugin.zsh
new file mode 100644 (file)
index 0000000..564c505
--- /dev/null
@@ -0,0 +1,30 @@
+_mix_refresh () {
+  if [ -f .mix_tasks ]; then
+    rm .mix_tasks
+  fi
+  echo "Generating .mix_tasks..." > /dev/stderr
+  _mix_generate
+  cat .mix_tasks
+}
+
+_mix_does_task_list_need_generating () {
+  [ ! -f .mix_tasks ];
+}
+
+_mix_generate () {
+  mix help | grep '^mix [^ ]' | sed -E "s/mix ([^ ]*) *# (.*)/\1:\2/" > .mix_tasks
+}
+
+_mix () {
+  if [ -f mix.exs ]; then
+    if _mix_does_task_list_need_generating; then
+      echo "\nGenerating .mix_tasks..." > /dev/stderr
+      _mix_generate
+    fi
+    local tasks=(${(f)"$(cat .mix_tasks)"})
+    _describe 'tasks' tasks
+  fi
+}
+
+compdef _mix mix
+alias mix_refresh='_mix_refresh'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mix/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mix/README.md
new file mode 100644 (file)
index 0000000..f0258fe
--- /dev/null
@@ -0,0 +1,19 @@
+# Mix plugin
+
+This plugin adds completions for the [Elixir's Mix build tool](https://hexdocs.pm/mix/Mix.html).
+
+To use it, add `mix` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... mix)
+```
+## Supported Task Types
+
+| Task Type                | Documentation                                            |
+|--------------------------|----------------------------------------------------------|
+| Elixir                   | [Elixir Lang](https://elixir-lang.org/)                  |
+| Phoenix v1.2.1 and below | [Phoenix](https://hexdocs.pm/phoenix/1.2.1/Phoenix.html) |
+| Phoenix v1.3.0 and above | [Phoenix](https://hexdocs.pm/phoenix/Phoenix.html)       |
+| Ecto                     | [Ecto](https://hexdocs.pm/ecto/Ecto.html)                |
+| Hex                      | [Hex](https://hex.pm/)                                   |
+| Nerves                   | [Nerves](https://nerves-project.org/)                    |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mix/_mix b/stow/oh-my-zsh/.oh-my-zsh/plugins/mix/_mix
new file mode 100644 (file)
index 0000000..7940ff1
--- /dev/null
@@ -0,0 +1,156 @@
+#compdef mix
+#autoload
+
+# Elixir mix zsh completion
+
+local -a _1st_arguments
+_1st_arguments=(
+    'app.config:Configures all registered apps'
+    'app.start:Start all registered apps'
+    'app.tree:Prints the application tree'
+    'archive:Lists installed archives'
+    'archive.build:Archive this project into a .ez file'
+    'archive.install:Install an archive locally'
+    'archive.uninstall:Uninstall archives'
+    'clean:Delete generated application files'
+    'cmd:Executes the given command'
+    'compile:Compile source files'
+    'compile.protocols:Consolidates all protocols in all paths'
+    'deps:List dependencies and their status'
+    "deps.clean:Remove the given dependencies' files"
+    'deps.compile:Compile dependencies'
+    'deps.get:Get all out of date dependencies'
+    'deps.tree:Prints the dependency tree'
+    'deps.unlock:Unlock the given dependencies'
+    'deps.update:Update the given dependencies'
+    'do:Executes the tasks separated by comma'
+    'ecto.create:Create Ecto database'
+    'ecto.drop:Drop the storage for the given repository'
+    'ecto.dump:Dumps the current environment’s database structure'
+    'ecto.gen.migration:Generates a migration'
+    'ecto.gen.repo:Generates a new repository'
+    'ecto.load:Loads the current environment’s database structure'
+    'ecto.migrate:Runs Ecto migration'
+    'ecto.migrations:Displays the up / down migration status'
+    'ecto.rollback:Reverts applied migrations'
+    'escript:Lists installed escripts'
+    'escript.build:Builds an escript for the project'
+    'escript.install:Installs an escript locally'
+    'escript.uninstall:Uninstalls escripts'
+    'firmware:Nerves - Build a firmware image for the selected target platform'
+    'firmware.burn:Nerves - Writes the generated firmware image to an attached SDCard or file'
+    'firmware.image:Nerves - Create a firmware image file that can be copied byte-for-byte'
+    'format:Formats the given files and patterns'
+    'help:Print help information for tasks'
+    'hex:Print hex help information'
+    'hex.audit:Shows retired Hex deps for the current project'
+    'hex.build:Builds a new package version locally'
+    'hex.config:Reads, updates or deletes local Hex config'
+    'hex.docs:Fetches or opens documentation of a package'
+    'hex.info:Print hex information'
+    'hex.organization:Manages Hex.pm organizations'
+    'hex.key:Hex API key tasks'
+    'hex.outdated:Shows outdated Hex deps for the current project'
+    'hex.owner:Manages Hex package ownership'
+    'hex.package:Fetches or diffs packages'
+    'hex.publish:Publish a new package version'
+    'hex.registry:Manages local Hex registries'
+    'hex.repo:Manages Hex repositories'
+    'hex.retire:Retires a package version'
+    'hex.search:Search for package names'
+    'hex.sponsor:Show Hex packages accepting sponsorships'
+    'hex.user:Manages your Hex user account'
+    'loadconfig:Loads and persists the given configuration'
+    'local:List local tasks'
+    'local.hex:Install hex locally'
+    'local.phoenix:Updates Phoenix locally'
+    'local.phx:Updates the Phoenix project generator locally'
+    'local.public_keys:Manages public keys'
+    'local.rebar:Install rebar locally'
+    'nerves.artifact:Create an artifact for a specified Nerves package'
+    'nerves.artifact.get:Nerves get artifacts'
+    'nerves.info:Prints Nerves system information'
+    'nerves.new:Create a new Nerves application'
+    'nerves.release.init:Prepare a new Nerves project for use with releases'
+    'new:Create a new Elixir project'
+    'phoenix.digest:Digests and compress static files'
+    'phoenix.gen.channel:Generates a Phoenix channel'
+    'phoenix.gen.html:Generates controller, model and views for an HTML based resource'
+    'phoenix.gen.json:Generates a controller and model for a JSON based resource'
+    'phoenix.gen.model:Generates an Ecto model'
+    'phoenix.gen.secret:Generates a secret'
+    'phoenix.new:Creates a new Phoenix v1.2.1 application'
+    'phoenix.routes:Prints all routes'
+    'phoenix.server:Starts applications and their servers'
+    'phx.digest:Digests and compresses static files'
+    'phx.digest.clean:Removes old versions of static assets.'
+    'phx.gen.auth:Generates authentication logic for a resource'
+    'phx.gen.cert:Generates a self-signed certificate for HTTPS testing'
+    'phx.gen.channel:Generates a Phoenix channel'
+    'phx.gen.context:Generates a context with functions around an Ecto schema'
+    'phx.gen.embedded:Generates an embedded Ecto schema file'
+    'phx.gen.html:Generates controller, views, and context for an HTML resource'
+    'phx.gen.json:Generates controller, views, and context for a JSON resource'
+    'phx.gen.live:Generates LiveView, templates, and context for a resource'
+    'phx.gen.notifier:Generates a notifier that delivers emails by default'
+    'phx.gen.presence:Generates a Presence tracker'
+    'phx.gen.schema:Generates an Ecto schema and migration file'
+    'phx.gen.secret:Generates a secret'
+    'phx.gen.socket:Generates a Phoenix socket handler'
+    'phx.new:Creates a new Phoenix application'
+    'phx.new.ecto:Creates a new Ecto project within an umbrella project'
+    'phx.new.web:Creates a new Phoenix web project within an umbrella project'
+    'phx.routes:Prints all routes'
+    'phx.server:Starts applications and their servers'
+    'profile.cprof:Profiles the given file or expression with cprof'
+    'profile.eprof:Profiles the given file or expression with eprof'
+    'profile.fprof:Profiles the given file or expression with fprof'
+    'release:Assembles a self-contained release'
+    'release.init:Generates sample files for releases'
+    'run:Run the given file or expression'
+    "test:Run a project's tests"
+    'test.coverage:Build report from exported test coverage'
+    'xref:Prints cross reference information'
+    '--help:Describe available tasks'
+    '--version:Prints the Elixir version information'
+)
+
+__task_list ()
+{
+    local expl
+    declare -a tasks
+
+    tasks=(app.config app.start app.tree archive archive.build archive.install archive.uninstall clean cmd compile compile.protocols deps deps.clean deps.compile deps.get deps.tree deps.unlock deps.update do ecto.create ecto.drop ecto.dump ecto.gen.migration ecto.gen.repo ecto.load ecto.migrate ecto.migrations ecto.rollback escript escript.build escript.install escript.uninstall firmware firmware.burn firmware.image format help hex hex.audit hex.build hex.config hex.docs hex.info hex.organization hex.key hex.outdated hex.owner hex.package hex.publish hex.registry hex.repo hex.retire hex.search hex.sponsor hex.user loadconfig local local.hex local.phoenix local.phx local.public_keys local.rebar nerves.artifact nerves.artifact.get nerves.info nerves.new nerves.release.init new phoenix.digest phoenix.gen.channel phoenix.gen.html phoenix.gen.json phoenix.gen.model phoenix.gen.secret phoenix.new phoenix.routes phoenix.server phx.digest phx.digest.clean phx.gen.auth phx.gen.cert phx.gen.channel phx.gen.context phx.gen.embedded phx.gen.html phx.gen.json phx.gen.live phx.gen.notifier phx.gen.presence phx.gen.schema phx.gen.secret phx.gen.socket phx.new phx.new.ecto phx.new.web phx.routes phx.server profile.cprof profile.eprof profile.fprof release release.init run test test.coverage xref)
+
+    _wanted tasks expl 'help' compadd $tasks
+}
+
+local expl
+
+local curcontext="$curcontext" state line
+typeset -A opt_args
+
+_arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+case $state in
+  (command)
+      _describe -t commands "mix subcommand" _1st_arguments
+      return
+  ;;
+
+  (options)
+    case $line[1] in
+      (help)
+         _arguments ':feature:__task_list'
+         ;;
+      (test)
+         _files
+         ;;
+      (run)
+         _files
+         ;;
+    esac
+  ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mongocli/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mongocli/README.md
new file mode 100644 (file)
index 0000000..e245f2a
--- /dev/null
@@ -0,0 +1,19 @@
+# mongocli plugin
+
+The plugin adds several aliases for common [mongocli](https://docs.mongodb.com/mongocli/stable/) commands.
+
+To use it, add `mongocli` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... mongocli)
+```
+
+## Aliases
+
+| Alias    | Command                                                     | Description                                            |
+|----------|-------------------------------------------------------------|--------------------------------------------------------|
+| `ma`     | `mongocli atlas`                                            | Shortcut for mongocli Atlas commands.                  |
+| `mcm`    | `mongocli cloud-manager`                                    | Shortcut for mongocli Cloud Manager commands.          |
+| `mom`    | `mongocli ops-manager`                                      | Shortcut for mongocli Cloud Manager commands.          |
+| `miam`   | `mongocli iam`                                              | Shortcut for mongocli IAM commands.                    |
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mongocli/mongocli.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/mongocli/mongocli.plugin.zsh
new file mode 100644 (file)
index 0000000..0ca877e
--- /dev/null
@@ -0,0 +1,4 @@
+alias ma='mongocli atlas'
+alias mcm='mongocli cloud-manager'
+alias mom='mongocli ops-manager'
+alias miam='mongocli iam'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mosh/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mosh/README.md
new file mode 100644 (file)
index 0000000..4bbecf4
--- /dev/null
@@ -0,0 +1,9 @@
+# Mosh Plugin
+
+This plugin allows SSH tab completion for [mosh](https://mosh.org/) hostnames.
+
+To use it, add `mosh` to the plugins array in your zshrc file:
+
+```
+plugins=(... mosh)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mosh/mosh.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/mosh/mosh.plugin.zsh
new file mode 100644 (file)
index 0000000..ea36b7e
--- /dev/null
@@ -0,0 +1,2 @@
+# Allow SSH tab completion for mosh hostnames
+compdef mosh=ssh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/README.md
new file mode 100644 (file)
index 0000000..f6b2d76
--- /dev/null
@@ -0,0 +1,22 @@
+# multipass
+
+This plugin provides completion for [multipass](https://multipass.run), as well as aliases
+for multipass commands.
+
+To use it, add `multipass` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... multipass)
+```
+
+## Aliases
+
+| Alias  | Command                                                             |
+| ------ | ------------------------------------------------------------------- |
+| `mp`   | `multipass`                                                         |
+| `mpl`  | `multipass list`                                                    |
+| `mpla` | `multipass launch`                                                  |
+| `mpln` | `multipass launch --network en0 --network name=bridge0,mode=manual` |
+| `mps`  | `multipass shell`                                                   |
+| `mpsp` | `multipass stop`                                                    |
+| `mpst` | `multipass start`                                                   |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/_multipass b/stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/_multipass
new file mode 100644 (file)
index 0000000..c742df6
--- /dev/null
@@ -0,0 +1,73 @@
+#compdef multipass
+
+_multipass_get_command_list () {
+  # Sample output:
+  # $ multipass --help
+  # ...
+  # Options:
+  #   -h, --help     Display this help
+  #   -v, --verbose  Increase logging verbosity. Repeat the 'v' in the short option
+  #                  for more detail. Maximum verbosity is obtained with 4 (or more)
+  #                  v's, i.e. -vvvv.
+  # ...
+  # Available commands:
+  #   alias     Create an alias
+  #   aliases   List available aliases
+  #   ...
+  #
+  $_comp_command1 --help | sed '1,/Available commands/d' | awk '/^[ \t]*[a-z]+/ { print $1 }'
+}
+
+_multipass_get_args_list () {
+  # Sample output:
+  # $ multpass help stop
+  # ...
+  # Options:
+  # -h, --help         Display this help
+  # -v, --verbose      Increase logging verbosity. Repeat the 'v' in the short
+  #                     option for more detail. Maximum verbosity is obtained with
+  #                     4 (or more) v's, i.e. -vvvv.
+  # --all              Stop all instances
+  # -t, --time <time>  Time from now, in minutes, to delay shutdown of the
+  #                     instance
+  # -c, --cancel       Cancel a pending delayed shutdown
+  #
+  # Arguments:
+  # name               Names of instances to stop. If omitted, and without the
+  #                     --all option, 'primary' will be assumed.
+  #
+  local arg_name=$($_comp_command1 help ${words[2]} | sed '1,/Arguments/d' | awk '/^[ \t]*[a-z]+/ { print $1; exit }')
+
+  case $arg_name in
+    name)
+      # Sample output:
+      # $ multipass list
+      # Name                    State             IPv4             Image
+      # workable-poacher        Running           10.2.0.28        Ubuntu openHAB Home Appliance
+      #
+      $_comp_command1 list | sed '1d' | awk '/^[ \t]*[^ ]+/ { print $1 }'
+    ;;
+    command)
+      _multipass_get_command_list
+    ;;
+  esac
+}
+
+_multipass () {
+  typeset -A opt_args
+
+  _arguments \
+    '1: :->command'\
+    '*: :->args'
+
+  case $state in
+    command)
+      compadd $(_multipass_get_command_list)
+    ;;
+    *)
+      compadd $(_multipass_get_args_list)
+    ;;
+  esac
+}
+
+_multipass "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/multipass.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/multipass/multipass.plugin.zsh
new file mode 100644 (file)
index 0000000..95025b2
--- /dev/null
@@ -0,0 +1,7 @@
+alias mp="multipass"
+alias mpl="multipass list"
+alias mpla="multipass launch"
+alias mpln="multipass launch --network en0 --network name=bridge0,mode=manual"
+alias mps="multipass shell"
+alias mpsp="multipass stop"
+alias mpst="multipass start"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mvn/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mvn/README.md
new file mode 100644 (file)
index 0000000..815dfd5
--- /dev/null
@@ -0,0 +1,61 @@
+# mvn plugin
+
+The mvn plugin provides many [useful aliases](#aliases) as well as completion for
+the [Apache Maven](https://maven.apache.org/) command (`mvn`).
+
+Enable it by adding `mvn` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... mvn)
+```
+
+## Aliases
+
+The plugin aliases mvn to a function that calls `mvnw` (the [Maven Wrapper](https://github.com/takari/maven-wrapper))
+if it's found, or the mvn command otherwise.
+
+| Alias                | Command                                         |
+|:---------------------|:------------------------------------------------|
+| `mvn!`               | `mvn -f <root>/pom.xml`                         |
+| `mvnag`              | `mvn archetype:generate`                        |
+| `mvnboot`            | `mvn spring-boot:run`                           |
+| `mvnqdev`            | `mvn quarkus:dev`                               |
+| `mvnc`               | `mvn clean`                                     |
+| `mvncd`              | `mvn clean deploy`                              |
+| `mvnce`              | `mvn clean eclipse:clean eclipse:eclipse`       |
+| `mvnci`              | `mvn clean install`                             |
+| `mvncie`             | `mvn clean install eclipse:eclipse`             |
+| `mvncini`            | `mvn clean initialize`                          |
+| `mvncist`            | `mvn clean install -DskipTests`                 |
+| `mvncisto`           | `mvn clean install -DskipTests --offline`       |
+| `mvncom`             | `mvn compile`                                   |
+| `mvncp`              | `mvn clean package`                             |
+| `mvnct`              | `mvn clean test`                                |
+| `mvncv`              | `mvn clean verify`                              |
+| `mvncvst`            | `mvn clean verify -DskipTests`                  |
+| `mvnd`               | `mvn deploy`                                    |
+| `mvndocs`            | `mvn dependency:resolve -Dclassifier=javadoc`   |
+| `mvndt`              | `mvn dependency:tree`                           |
+| `mvne`               | `mvn eclipse:eclipse`                           |
+| `mvnfmt`             | `mvn fmt:format`                                |
+| `mvnjetty`           | `mvn jetty:run`                                 |
+| `mvnp`               | `mvn package`                                   |
+| `mvns`               | `mvn site`                                      |
+| `mvnsrc`             | `mvn dependency:sources`                        |
+| `mvnt`               | `mvn test`                                      |
+| `mvntc`              | `mvn tomcat:run`                                |
+| `mvntc7`             | `mvn tomcat7:run`                               |
+| `mvn-updates`        | `mvn versions:display-dependency-updates`       |
+
+## mvn-color
+
+It's a function that wraps the mvn command to colorize it's output. You can use it in place
+of the `mvn` command. For example: instead of `mvn test`, use `mvn-color test`.
+
+Since [Maven 3.5.0](https://maven.apache.org/docs/3.5.0/release-notes.html) the mvn command
+has colored output, so this function will be soon removed from the plugin.
+
+### Known bugs
+
+It has a bug where it will swallow mvn prompts for user input, _e.g._ when using
+`archetype:generate`. See [#5052](https://github.com/ohmyzsh/ohmyzsh/issues/5052).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mvn/mvn.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/mvn/mvn.plugin.zsh
new file mode 100644 (file)
index 0000000..1b9141f
--- /dev/null
@@ -0,0 +1,342 @@
+# Calls mvnw if found in the current project, otherwise execute the original mvn
+mvn-or-mvnw() {
+  local dir="$PWD"
+  while [[ ! -x "$dir/mvnw" && "$dir" != / ]]; do
+    dir="${dir:h}"
+  done
+
+  if [[ -x "$dir/mvnw" ]]; then
+    echo "Running \`$dir/mvnw\`..." >&2
+    "$dir/mvnw" "$@"
+    return $?
+  fi
+
+  command mvn "$@"
+}
+
+# Wrapper function for Maven's mvn command. Based on https://gist.github.com/1027800
+mvn-color() {
+  local BOLD=$(echoti bold)
+  local TEXT_RED=$(echoti setaf 1)
+  local TEXT_GREEN=$(echoti setaf 2)
+  local TEXT_YELLOW=$(echoti setaf 3)
+  local TEXT_BLUE=$(echoti setaf 4)
+  local TEXT_WHITE=$(echoti setaf 7)
+  local RESET_FORMATTING=$(echoti sgr0)
+
+  (
+    # Filter mvn output using sed. Before filtering set the locale to C, so invalid characters won't break some sed implementations
+    unset LANG
+    LC_CTYPE=C mvn "$@" | sed \
+      -e "s/\(\[INFO\]\)\(.*\)/${TEXT_BLUE}${BOLD}\1${RESET_FORMATTING}\2/g" \
+      -e "s/\(\[DEBUG\]\)\(.*\)/${TEXT_WHITE}${BOLD}\1${RESET_FORMATTING}\2/g" \
+      -e "s/\(\[INFO\]\ BUILD SUCCESSFUL\)/${BOLD}${TEXT_GREEN}\1${RESET_FORMATTING}/g" \
+      -e "s/\(\[WARNING\]\)\(.*\)/${BOLD}${TEXT_YELLOW}\1${RESET_FORMATTING}\2/g" \
+      -e "s/\(\[ERROR\]\)\(.*\)/${BOLD}${TEXT_RED}\1${RESET_FORMATTING}\2/g" \
+      -e "s/Tests run: \([^,]*\), Failures: \([^,]*\), Errors: \([^,]*\), Skipped: \([^,]*\)/${BOLD}${TEXT_GREEN}Tests run: \1${RESET_FORMATTING}, Failures: ${BOLD}${TEXT_RED}\2${RESET_FORMATTING}, Errors: ${BOLD}${TEXT_RED}\3${RESET_FORMATTING}, Skipped: ${BOLD}${TEXT_YELLOW}\4${RESET_FORMATTING}/g"
+
+    # Make sure formatting is reset
+    echo -ne "${RESET_FORMATTING}"
+  )
+}
+
+# either use original mvn or the mvn wrapper
+alias mvn="mvn-or-mvnw"
+
+# Run mvn against the pom found in a project's root directory (assumes a git repo)
+alias 'mvn!'='mvn -f $(git rev-parse --show-toplevel 2>/dev/null || echo ".")/pom.xml'
+
+# aliases
+alias mvnag='mvn archetype:generate'
+alias mvnboot='mvn spring-boot:run'
+alias mvnc='mvn clean'
+alias mvncd='mvn clean deploy'
+alias mvnce='mvn clean eclipse:clean eclipse:eclipse'
+alias mvnci='mvn clean install'
+alias mvncie='mvn clean install eclipse:eclipse'
+alias mvncini='mvn clean initialize'
+alias mvncist='mvn clean install -DskipTests'
+alias mvncisto='mvn clean install -DskipTests --offline'
+alias mvncom='mvn compile'
+alias mvncp='mvn clean package'
+alias mvnct='mvn clean test'
+alias mvncv='mvn clean verify'
+alias mvncvst='mvn clean verify -DskipTests'
+alias mvnd='mvn deploy'
+alias mvndocs='mvn dependency:resolve -Dclassifier=javadoc'
+alias mvndt='mvn dependency:tree'
+alias mvne='mvn eclipse:eclipse'
+alias mvnfmt='mvn fmt:format'
+alias mvnjetty='mvn jetty:run'
+alias mvnp='mvn package'
+alias mvnqdev='mvn quarkus:dev'
+alias mvns='mvn site'
+alias mvnsrc='mvn dependency:sources'
+alias mvnt='mvn test'
+alias mvntc='mvn tomcat:run'
+alias mvntc7='mvn tomcat7:run'
+alias mvn-updates='mvn versions:display-dependency-updates'
+
+
+function listMavenCompletions {
+  local file new_file
+  local -a profiles POM_FILES modules
+
+  # Root POM
+  POM_FILES=(~/.m2/settings.xml)
+
+  # POM in the current directory
+  if [[ -f pom.xml ]]; then
+    local file=pom.xml
+    POM_FILES+=("${file:A}")
+  fi
+
+  # Look for POM files in parent directories
+  while [[ -n "$file" ]] && grep -q "<parent>" "$file"; do
+    # look for a new relativePath for parent pom.xml
+    new_file=$(grep -e "<relativePath>.*</relativePath>" "$file" | sed -e 's/.*<relativePath>\(.*\)<\/relativePath>.*/\1/')
+
+    # if <parent> is present but not defined, assume ../pom.xml
+    if [[ -z "$new_file" ]]; then
+      new_file="../pom.xml"
+    fi
+
+    # if file doesn't exist break
+    file="${file:h}/${new_file}"
+    if ! [[ -e "$file" ]]; then
+      break
+    fi
+
+    POM_FILES+=("${file:A}")
+  done
+
+  # Get profiles from found files
+  for file in $POM_FILES; do
+    [[ -e $file ]] || continue
+    profiles+=($(sed 's/<!--.*-->//' "$file" | sed '/<!--/,/-->/d' | grep -e "<profile>" -A 1 | grep -e "<id>.*</id>" | sed 's?.*<id>\(.*\)<\/id>.*?-P\1?'))
+  done
+
+  # List modules
+  modules=($(print -l **/pom.xml(-.N:h) | grep -v '/target/classes/META-INF/'))
+
+  reply=(
+    # common lifecycle
+    clean initialize process-resources compile process-test-resources test-compile test package verify install deploy site
+
+    # integration testing
+    pre-integration-test integration-test
+
+    # common plugins
+    deploy failsafe install site surefire checkstyle javadoc jxr pmd ant antrun archetype assembly dependency enforcer gpg help release repository source eclipse idea jetty cargo jboss tomcat tomcat6 tomcat7 exec versions war ear ejb android scm buildnumber nexus repository sonar license hibernate3 liquibase flyway gwt
+
+    # deploy
+    deploy:deploy-file
+    # failsafe
+    failsafe:integration-test failsafe:verify
+    # install
+    install:install-file install:help
+    # site
+    site:site site:deploy site:run site:stage site:stage-deploy site:attach-descriptor site:jar site:effective-site
+    # surefire
+    surefire:test
+
+    # checkstyle
+    checkstyle:checkstyle checkstyle:check checkstyle:checkstyle-aggregate
+    # javadoc
+    javadoc:javadoc javadoc:test-javadoc javadoc:javadoc-no-fork javadoc:test-javadoc-no-fork javadoc:aggregate javadoc:test-aggregate javadoc:jar javadoc:test-jar javadoc:aggregate-jar javadoc:test-aggregate-jar javadoc:fix javadoc:test-fix javadoc:resource-bundle javadoc:test-resource-bundle
+    # jxr
+    jxr:jxr jxr:aggregate jxr:test-jxr jxr:test-aggregate
+    # pmd
+    pmd:pmd pmd:cpd pmd:check pmd:cpd-check
+
+    # ant
+    ant:ant ant:clean
+    # antrun
+    antrun:run
+    # archetype
+    archetype:generate archetype:create-from-project archetype:crawl
+    # assembly
+    assembly:single assembly:assembly
+    # dependency
+    dependency:analyze dependency:analyze-dep-mgt dependency:analyze-only dependency:analyze-report dependency:analyze-duplicate dependency:build-classpath dependency:copy dependency:copy-dependencies dependency:display-ancestors dependency:get dependency:go-offline dependency:list dependency:list-repositories dependency:properties dependency:purge-local-repository dependency:resolve dependency:resolve-plugins dependency:sources dependency:tree dependency:unpack dependency:unpack-dependencies
+    # enforcer
+    enforcer:enforce enforcer:display-info
+    # gpg
+    gpg:sign gpg:sign-and-deploy-file
+    # help
+    help:active-profiles help:all-profiles help:describe help:effective-pom help:effective-settings help:evaluate help:expressions help:system
+    # release
+    release:clean release:prepare release:prepare-with-pom release:rollback release:perform release:stage release:branch release:update-versions
+    # jgitflow
+    jgitflow:feature-start jgitflow:feature-finish jgitflow:release-start jgitflow:release-finish jgitflow:hotfix-start jgitflow:hotfix-finish jgitflow:build-number
+    # repository
+    repository:bundle-create repository:bundle-pack
+    # source
+    source:aggregate source:jar source:jar-no-fork source:test-jar source:test-jar-no-fork
+
+    # eclipse
+    eclipse:clean eclipse:eclipse
+    # idea
+    idea:clean idea:idea
+
+    # jetty
+    jetty:run jetty:run-exploded
+    # cargo
+    cargo:start cargo:run cargo:stop cargo:deploy cargo:undeploy cargo:help
+    # jboss
+    jboss:start jboss:stop jboss:deploy jboss:undeploy jboss:redeploy
+    # tomcat
+    tomcat:start tomcat:stop tomcat:deploy tomcat:undeploy tomcat:redeploy
+    # tomcat6
+    tomcat6:run tomcat6:run-war tomcat6:run-war-only tomcat6:stop tomcat6:deploy tomcat6:undeploy
+    # tomcat7
+    tomcat7:run tomcat7:run-war tomcat7:run-war-only tomcat7:deploy
+    # tomee
+    tomee:run tomee:run-war tomee:run-war-only tomee:stop tomee:deploy tomee:undeploy
+    # spring-boot
+    spring-boot:run spring-boot:repackage
+    # quarkus
+    quarkus:dev quarkus:list-extensions quarkus:add-extension quarkus:add-extensions quarkus:generate-config quarkus:help
+    # exec
+    exec:exec exec:java
+    # versions
+    versions:display-dependency-updates versions:display-plugin-updates versions:display-property-updates versions:update-parent versions:update-properties versions:update-child-modules versions:lock-snapshots versions:unlock-snapshots versions:resolve-ranges versions:set versions:use-releases versions:use-next-releases versions:use-latest-releases versions:use-next-snapshots versions:use-latest-snapshots versions:use-next-versions versions:use-latest-versions versions:commit versions:revert
+    # scm
+    scm:add scm:bootstrap scm:branch scm:changelog scm:check-local-modification scm:checkin scm:checkout scm:diff scm:edit scm:export scm:list scm:remove scm:status scm:tag scm:unedit scm:update scm:update-subprojects scm:validate
+    # buildnumber
+    buildnumber:create buildnumber:create-timestamp buildnumber:help buildnumber:hgchangeset
+
+    # war
+    war:war war:exploded war:inplace war:manifest
+    # ear
+    ear:ear ear:generate-application-xml
+    # ejb
+    ejb:ejb
+    # android
+    android:apk android:apklib android:deploy android:deploy-dependencies android:dex android:emulator-start android:emulator-stop android:emulator-stop-all android:generate-sources android:help android:instrument android:manifest-update android:pull android:push android:redeploy android:run android:undeploy android:unpack android:version-update android:zipalign android:devices
+    # nexus
+    nexus:staging-list nexus:staging-close nexus:staging-drop nexus:staging-release nexus:staging-build-promotion nexus:staging-profiles-list nexus:settings-download
+    # repository
+    repository:bundle-create repository:bundle-pack repository:help
+
+    # sonar
+    sonar:sonar
+    # license
+    license:format license:check
+    # hibernate3
+    hibernate3:hbm2ddl hibernate3:help
+    # liquibase
+    liquibase:changelogSync liquibase:changelogSyncSQL liquibase:clearCheckSums liquibase:dbDoc liquibase:diff liquibase:dropAll liquibase:help liquibase:migrate liquibase:listLocks liquibase:migrateSQL liquibase:releaseLocks liquibase:rollback liquibase:rollbackSQL liquibase:status liquibase:tag liquibase:update liquibase:updateSQL liquibase:updateTestingRollback
+    # flyway
+    flyway:clean flyway:history flyway:init flyway:migrate flyway:status flyway:validate
+    # gwt
+    gwt:browser gwt:clean gwt:compile gwt:compile-report gwt:css gwt:debug gwt:eclipse gwt:eclipseTest gwt:generateAsync gwt:help gwt:i18n gwt:mergewebxml gwt:resources gwt:run gwt:sdkInstall gwt:source-jar gwt:soyc gwt:test
+    # asciidoctor
+    asciidoctor:process-asciidoc asciidoctor:auto-refresh asciidoctor:http asciidoctor:zip
+    # compiler
+    compiler:compile compiler:testCompile
+    # resources
+    resources:resources resources:testResources resources:copy-resources
+    # verifier
+    verifier:verify
+    # jar
+    jar:jar jar:test-jar
+    # rar
+    rar:rar
+    # acr
+    acr:acr
+    # shade
+    shade:shade
+    # changelog
+    changelog:changelog changelog:dev-activity changelog:file-activity
+    # changes
+    changes:announcement-mail changes:announcement-generate changes:changes-check changes:changes-validate changes:changes-report changes:jira-report changes:trac-report changes:github-report
+    # doap
+    doap:generate
+    # docck
+    docck:check
+    # jdeps
+    jdeps:jdkinternals jdeps:test-jdkinternals
+    # linkcheck
+    linkcheck:linkcheck
+    # project-info-reports
+    project-info-reports:cim project-info-reports:dependencies project-info-reports:dependency-convergence project-info-reports:dependency-info project-info-reports:dependency-management project-info-reports:distribution-management project-info-reports:help project-info-reports:index project-info-reports:issue-tracking project-info-reports:license project-info-reports:mailing-list project-info-reports:modules project-info-reports:plugin-management project-info-reports:plugins project-info-reports:project-team project-info-reports:scm project-info-reports:summary
+    # surefire-report
+    surefire-report:failsafe-report-only surefire-report:report surefire-report:report-only
+    # invoker
+    invoker:install invoker:integration-test invoker:verify invoker:run
+    # jarsigner
+    jarsigner:sign jarsigner:verify
+    # patch
+    patch:apply
+    # pdf
+    pdf:pdf
+    # plugin
+    plugin:descriptor plugin:report plugin:updateRegistry plugin:addPluginArtifactMetadata plugin:helpmojo
+    # remote-resources
+    remote-resources:bundle remote-resources:process
+    # scm-publish
+    scm-publish:help scm-publish:publish-scm scm-publish:scmpublish
+    # stage
+    stage:copy
+    # toolchain
+    toolchain:toolchain
+    #liberty
+    liberty:clean-server liberty:compile-jsp liberty:configure-arquillian liberty:create-server liberty:debug liberty:debug-server liberty:deploy liberty:dev liberty:display-url liberty:dump-server liberty:install-apps liberty:install-feature liberty:install-server liberty:java-dump-server liberty:package-server liberty:run liberty:run-server liberty:server-status liberty:start liberty:start-server liberty:status liberty:stop liberty:stop-server liberty:test-start-server liberty:test-stop-server liberty:undeploy liberty:uninstall-feature
+
+    # options
+    "-Dmaven.test.skip=true" -DskipTests -DskipITs -Dmaven.surefire.debug -DenableCiProfile "-Dpmd.skip=true" "-Dcheckstyle.skip=true" "-Dtycho.mode=maven" "-Dmaven.test.failure.ignore=true" "-DgroupId=" "-DartifactId=" "-Dversion=" "-Dpackaging=jar" "-Dfile="
+
+    # arguments
+    -am --also-make
+    -amd --also-make-dependents-am
+    -B --batch-mode
+    -b --builder
+    -C --strict-checksums
+    -c --lax-checksums
+    -cpu --check-plugin-updates
+    -D --define
+    -e --errors
+    -emp --encrypt-master-password
+    -ep --encrypt-password
+    -f --file
+    -fae --fail-at-end
+    -ff --fail-fast
+    -fn --fail-never
+    -gs --global-settings
+    -gt --global-toolchains
+    -h --help
+    -l --log-file
+    -llr --legacy-local-repository
+    -N --non-recursive
+    -npr --no-plugin-registry
+    -npu --no-plugin-updates
+    -nsu --no-snapshot-updates
+    -o --offline
+    -P --activate-profiles
+    -pl --projects
+    -q --quiet
+    -rf --resume-from
+    -s --settings
+    -t --toolchains
+    -T --threads
+    -U --update-snapshots
+    -up --update-plugins
+    -v --version
+    -V --show-version
+    -X --debug
+
+    cli:execute cli:execute-phase
+    archetype:generate generate-sources
+    cobertura:cobertura
+    -Dtest=$(if [ -d ./src/test/java ] ; then find ./src/test/java -type f -name '*.java' | grep -v svn | sed 's?.*/\([^/]*\)\..*?-Dtest=\1?' ; fi)
+    -Dit.test=$(if [ -d ./src/test/java ] ; then find ./src/test/java -type f -name '*.java' | grep -v svn | sed 's?.*/\([^/]*\)\..*?-Dit.test=\1?' ; fi)
+
+    $profiles
+    $modules
+  )
+}
+
+compctl -K listMavenCompletions mvn mvnw
+compctl -K listMavenCompletions mvn-color
+compctl -K listMavenCompletions mvn-or-mvnw
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mysql-macports/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/mysql-macports/README.md
new file mode 100644 (file)
index 0000000..ff4fb3a
--- /dev/null
@@ -0,0 +1,20 @@
+# MySQL-Macports plugin
+
+This plugin adds aliases for some of the commonly used [MySQL](https://www.mysql.com/) commands when installed using [MacPorts](https://www.macports.org/) on macOS.
+
+To use it, add `mysql-macports` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... mysql-macports)
+```
+
+For instructions on how to install MySQL using MacPorts, read the [MacPorts wiki](https://trac.macports.org/wiki/howto/MySQL/).
+
+## Aliases
+
+| Alias        | Command                              | Description                                |
+| ------------ | ------------------------------------ | ------------------------------------------ |
+| mysqlstart   | `sudo /path/to/mysql.server start`   | Start the MySQL server.                    |
+| mysqlstop    | `sudo /path/to/mysql.server stop`    | Stop the MySQL server.                     |
+| mysqlrestart | `sudo /path/to/mysql.server restart` | Restart the MySQL server.                  |
+| mysqlstatus  | `mysqladmin5 -u root -p ping`        | Check whether the MySQL server is running. |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/mysql-macports/mysql-macports.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/mysql-macports/mysql-macports.plugin.zsh
new file mode 100644 (file)
index 0000000..c39563f
--- /dev/null
@@ -0,0 +1,8 @@
+# commands to control local mysql-server installation
+# paths are for osx installation via macports
+
+alias mysqlstart='sudo /opt/local/share/mysql5/mysql/mysql.server start'
+alias mysqlstop='sudo /opt/local/share/mysql5/mysql/mysql.server stop'
+alias mysqlrestart='sudo /opt/local/share/mysql5/mysql/mysql.server restart'
+
+alias mysqlstatus='mysqladmin5 -u root -p ping'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/n98-magerun/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/n98-magerun/README.md
new file mode 100644 (file)
index 0000000..b0abe47
--- /dev/null
@@ -0,0 +1,21 @@
+# n98-magerun plugin
+
+The swiss army knife for Magento developers, sysadmins and devops. The tool provides a huge set of well tested command line commands which save hours of work time.
+
+The [n98-magerun plugin](https://github.com/netz98/n98-magerun) provides many
+[useful aliases](#aliases) as well as completion for the `n98-magerun` command.
+
+Enable it by adding `n98-magerun` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... n98-magerun)
+```
+
+## Aliases
+
+| Alias     | Command                                            | Description                                                                       |
+| --------- | -------------------------------------------------- | --------------------------------------------------------------------------------- |
+| n98       | `n98-magerun.phar`                                 | The N98-Magerun phar-file (Version 1)                                             |
+| n98-2     | `n98-magerun2.phar`                                | The N98-Magerun phar-file (Version 2)                                             |
+| mage-get  | `wget https://files.magerun.net/n98-magerun.phar`  | Download the latest stable N98-Magerun phar-file from the file-server (Version 1) |
+| mage2-get | `wget https://files.magerun.net/n98-magerun2.phar` | Download the latest stable N98-Magerun phar-file from the file-server (Version 2) |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/n98-magerun/n98-magerun.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/n98-magerun/n98-magerun.plugin.zsh
new file mode 100644 (file)
index 0000000..d79aee7
--- /dev/null
@@ -0,0 +1,42 @@
+# ------------------------------------------------------------------------------
+# FILE: n98-magerun.plugin.zsh
+# DESCRIPTION: oh-my-zsh n98-magerun plugin file. Adapted from composer plugin 
+# AUTHOR: Andrew Dwyer (andrewrdwyer at gmail dot com)
+# AUTHOR: Jisse Reitsma (jisse at yireo dot com)
+# VERSION: 1.1.0
+# ------------------------------------------------------------------------------
+
+# n98-magerun basic command completion
+_n98_magerun_get_command_list () {
+  $_comp_command1 --no-ansi | sed "1,/Available commands/d" | awk '/^ +[a-z\-:]+/ { print $1 }'
+}
+
+
+_n98_magerun () {
+  _arguments '1: :->command' '*:optional arg:_files'
+
+  case $state in
+    command)
+      compadd $(_n98_magerun_get_command_list)
+      ;;
+    *)
+  esac
+}
+
+compdef _n98_magerun n98-magerun.phar
+compdef _n98_magerun n98-magerun
+compdef _n98_magerun n98-magerun2.phar
+compdef _n98_magerun n98-magerun2
+
+# Aliases
+alias n98='n98-magerun.phar'
+alias mage='n98-magerun.phar'
+alias magerun='n98-magerun.phar'
+
+alias n98-2='n98-magerun2.phar'
+alias mage2='n98-magerun2.phar'
+alias magerun2='n98-magerun2.phar'
+
+# Install n98-magerun into the current directory
+alias mage-get='wget https://files.magerun.net/n98-magerun.phar'
+alias mage2-get='wget https://files.magerun.net/n98-magerun2.phar'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/README.md
new file mode 100644 (file)
index 0000000..d5d437d
--- /dev/null
@@ -0,0 +1,20 @@
+# Nanoc plugin
+
+This plugin adds some aliases and autocompletion for common [Nanoc](https://nanoc.ws) commands.
+
+To use it, add `nanoc` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... nanoc)
+```
+
+## Aliases
+
+| Alias | Command               | Description                                                                       |
+|-------|-----------------------|-----------------------------------------------------------------------------------|
+| n     | `nanoc`               | Main Nanoc command                                                                |
+| nco   | `nanoc compile`       | Compile all items of the current site                                             |
+| ncs   | `nanoc create-site`   | Create a new site at the given path. The site will use the filesystem data source |
+| nd    | `nanoc deploy`        | Deploy the compiled site to the destination (specified with `--target`)           |
+| np    | `nanoc prune`         | Remove files not managed by Nanoc from the output directory                       |
+| nv    | `nanoc view`          | Start the static web server (on port 3000 and all IP addresses, unless specified) |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/_nanoc b/stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/_nanoc
new file mode 100644 (file)
index 0000000..a6a4792
--- /dev/null
@@ -0,0 +1,92 @@
+#compdef nanoc
+#autoload
+
+# requires the 'nanoc' gem to be installed
+
+local -a _1st_arguments
+_1st_arguments=(
+  'check:run issue checks'
+  'compile:compile items of this site'
+  'create-site:create a site'
+  'deploy:deploy the compiled site'
+  'help:show help'
+  'prune:remove files not managed by nanoc from the output directory'
+  'shell:open a shell on the Nanoc environment'
+  'show-data:show data in this site'
+  'show-plugins:show all available plugins'
+  'show-rules:describe the rules for each item'
+  'view:start the web server that serves static files'
+)
+
+local expl
+local -a pkgs installed_pkgs
+
+_arguments \
+  '(--color)--color[enable color]' \
+  '(--debug)--debug[enable debugging]' \
+  '(--env)--env[set environment]' \
+  '(--help)--help[show the help message and quit]' \
+  '(--no-color)--no-color[disable color]' \
+  '(--verbose)--verbose[make output more detailed]' \
+  '(--version)--version[show version information and quit]' \
+  '(--warn)--warn[enable warnings]' \
+  '*:: :->subcmds' && return 0
+
+case "$state" in
+  subcmds)
+    case $words[1] in
+      check)
+        _arguments \
+          '(--preprocess)--preprocess[run preprocessor]'
+      ;;
+
+      compile)
+        _arguments \
+          '(--diff)--diff[generate diff]'
+      ;;
+
+      compile)
+        _arguments \
+          '(--diff)--diff[generate diff]'
+      ;;
+
+      create-site)
+        _arguments \
+          '(--force)--force[force creation of new site]'
+      ;;
+
+      deploy)
+        _arguments \
+          '(--target)--target[specify the location to deploy to (default: `default`)]' \
+          '(--no-check)--no-check[do not run the issue checks marked for deployment]' \
+          '(--list)--list[list available locations to deploy to]' \
+          '(--list-deployers)--list-deployers[list available deployers]' \
+          '(--dry-run)--dry-run[show what would be deployed]'
+      ;;
+
+      prune)
+        _arguments \
+          '(--yes)--yes[confirm deletion]' \
+          '(--dry-run)--dry-run[print files to be deleted instead of actually deleting them]'
+      ;;
+
+      shell)
+        _arguments \
+          '(--preprocess)--preprocess[run preprocessor]'
+      ;;
+
+      view)
+        _arguments \
+          '(--handler)--handler[specify the handler to use (webrick/mongrel/...)]' \
+          '(--host)--host[specify the host to listen on (default: 127.0.0.1)]' \
+          '(--port)--port[specify the port to listen on (default: 3000]' \
+          '(--live-reload)--live-reload[reload on changes]'
+      ;;
+    esac
+  ;;
+esac
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "nanoc subcommand" _1st_arguments
+  return
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/nanoc.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/nanoc/nanoc.plugin.zsh
new file mode 100644 (file)
index 0000000..05272ed
--- /dev/null
@@ -0,0 +1,6 @@
+alias n='nanoc'
+alias nco='nanoc compile'
+alias ncs='nanoc create-site'
+alias nd='nanoc deploy'
+alias np='nanoc prune'
+alias nv='nanoc view'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ng/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ng/README.md
new file mode 100644 (file)
index 0000000..29ac15a
--- /dev/null
@@ -0,0 +1,10 @@
+# ng plugin
+
+This plugin adds autocompletion support for [Angular's CLI](https://github.com/angular/angular-cli)
+(named `ng`).
+
+To use it, add `ng` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... ng)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ng/_ng b/stow/oh-my-zsh/.oh-my-zsh/plugins/ng/_ng
new file mode 100644 (file)
index 0000000..86c6ce1
--- /dev/null
@@ -0,0 +1,56 @@
+#compdef ng
+
+setopt localoptions extendedglob
+
+if (( CURRENT == 2 )); then
+  local -a cmds alias
+  # Sample output (ng help):
+  # Available Commands:
+  #   add Adds support for an external library to your project.
+  for line in ${(@f)"$(ng help 2>/dev/null | sed -n '/^  /p')"}; do
+    if [[ "$line" =~ '^  ([^ ]+) \(([^)]+)\) (.*)$' ]]; then
+      alias=(${match[1]} ${(s:, :)match[2]})
+      cmds+=(${^alias}:"${match[3]//:/}")
+    elif [[ "$line" =~ '^  ([^ ]+) (.*)$' ]]; then
+      cmds+=("${match[1]}:${match[2]//:/}")
+    fi
+  done
+  _describe commands cmds && return 0
+elif (( CURRENT == 3 )); then
+  local -a flags args
+  local section description
+  # Sample output (ng build --help):
+  # --configuration (-c)
+  #   One or more named builder configurations as a comma-separated list as specified in the "configurations" section of angular.json.
+  #   The builder uses the named configurations to run the given target.
+  #   For more information, see https://angular.io/guide/workspace-config#alternate-build-configurations.
+  # Prefix --flags with literal \0, and split on that to get each flag section
+  for section in ${(s:\0:)"$(ng ${words[2]} --help 2>/dev/null | sed -e '1,/^options/ d;s/^  --/\\0--/')"}; do
+    # Split by newline and discard extra description lines (lines > 2)
+    for args description in ${${(@f)section}[1,2]}; do
+      args=(${(s: :)${${args%% #}## #}//[(),]/})
+      description=${${description%% #}## #}
+      flags+=(${^args}":$description")
+    done
+  done
+  _describe flags flags
+
+  case "$words[2]" in
+  b|build|l|lint|t|test)
+    # Sample output (ng config projects):
+    # {
+    #   "angular-project-1": {
+    #     ...
+    #   },
+    #   "angular-project-2": {
+    #     ...
+    #   }
+    # }
+    # In absence of a proper JSON parser, just grab the lines with
+    # a 2-space indentation and only the stuff inside quotes
+    local -a projects
+    projects=(${(@f)"$(ng config projects 2>/dev/null | sed -n 's/^  "\([^"]\+\)".*$/\1/p')"})
+    _describe projects projects
+    ;;
+  esac
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nmap/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/nmap/README.md
new file mode 100644 (file)
index 0000000..0a60068
--- /dev/null
@@ -0,0 +1,27 @@
+# Nmap plugin
+
+Adds some useful aliases for [Nmap](https://nmap.org/) similar to the profiles in zenmap.
+
+To use it, add `nmap` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... nmap)
+```
+
+## Aliases
+
+- `nmap_open_ports`: scan for open ports on target.
+- `nmap_list_interfaces`: list all network interfaces on host where the command runs.
+- `nmap_slow`: slow scan that avoids to spam the targets logs.
+- `nmap_fin`: scan to see if hosts are up with TCP FIN scan.
+- `nmap_full`: aggressive full scan that scans all ports, tries to determine OS and service versions.
+- `nmap_check_for_firewall`: TCP ACK scan to check for firewall existence.
+- `nmap_ping_through_firewall`: host discovery with SYN and ACK probes instead of just pings to avoid firewall restrictions.
+- `nmap_fast`: fast scan of the top 300 popular ports.
+- `nmap_detect_versions`: detects versions of services and OS, runs on all ports.
+- `nmap_check_for_vulns`: uses vulscan script to check target services for vulnerabilities.
+- `nmap_full_udp`: same as full but via UDP.
+- `nmap_traceroute`: try to traceroute using the most common ports.
+- `nmap_full_with_scripts`: same as nmap_full but also runs all the scripts.
+- `nmap_web_safe_osscan`: little "safer" scan for OS version  as connecting to only HTTP and HTTPS ports doesn't look so attacking.
+- `nmap_ping_scan`: ICMP scan for active hosts.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nmap/nmap.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/nmap/nmap.plugin.zsh
new file mode 100644 (file)
index 0000000..406870f
--- /dev/null
@@ -0,0 +1,32 @@
+# Some useful nmap aliases for scan modes
+
+# Nmap options are:
+#  -sS - TCP SYN scan
+#  -v - verbose
+#  -T1 - timing of scan. Options are paranoid (0), sneaky (1), polite (2), normal (3), aggressive (4), and insane (5)
+#  -sF - FIN scan (can sneak through non-stateful firewalls)
+#  -PE - ICMP echo discovery probe
+#  -PP - timestamp discovery probe
+#  -PY - SCTP init ping
+#  -g - use given number as source port
+#  -A - enable OS detection, version detection, script scanning, and traceroute (aggressive)
+#  -O - enable OS detection
+#  -sA - TCP ACK scan
+#  -F - fast scan
+#  --script=vuln - also access vulnerabilities in target
+
+alias nmap_open_ports="nmap --open"
+alias nmap_list_interfaces="nmap --iflist"
+alias nmap_slow="sudo nmap -sS -v -T1"
+alias nmap_fin="sudo nmap -sF -v"
+alias nmap_full="sudo nmap -sS -T4 -PE -PP -PS80,443 -PY -g 53 -A -p1-65535 -v"
+alias nmap_check_for_firewall="sudo nmap -sA -p1-65535 -v -T4"
+alias nmap_ping_through_firewall="nmap -PS -PA"
+alias nmap_fast="nmap -F -T5 --version-light --top-ports 300"
+alias nmap_detect_versions="sudo nmap -sV -p1-65535 -O --osscan-guess -T4 -Pn"
+alias nmap_check_for_vulns="nmap --script=vuln"
+alias nmap_full_udp="sudo nmap -sS -sU -T4 -A -v -PE -PS22,25,80 -PA21,23,80,443,3389 "
+alias nmap_traceroute="sudo nmap -sP -PE -PS22,25,80 -PA21,23,80,3389 -PU -PO --traceroute "
+alias nmap_full_with_scripts="sudo nmap -sS -sU -T4 -A -v -PE -PP -PS21,22,23,25,80,113,31339 -PA80,113,443,10042 -PO --script all " 
+alias nmap_web_safe_osscan="sudo nmap -p 80,443 -O -v --osscan-guess --fuzzy "
+alias nmap_ping_scan="nmap -n -sP"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/node/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/node/README.md
new file mode 100644 (file)
index 0000000..911b669
--- /dev/null
@@ -0,0 +1,19 @@
+# node plugin
+
+This plugin adds `node-docs` function that opens specific section in [Node.js](https://nodejs.org)
+documentation (depending on the installed version).
+
+To use it, add `node` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... node)
+```
+
+## Usage
+
+```zsh
+# Opens https://nodejs.org/docs/latest-v10.x/api/fs.html
+$ node-docs fs
+# Opens https://nodejs.org/docs/latest-v10.x/api/path.html
+$ node-docs path
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/node/node.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/node/node.plugin.zsh
new file mode 100644 (file)
index 0000000..e196662
--- /dev/null
@@ -0,0 +1,6 @@
+# Open the node api for your current version to the optional section.
+# TODO: Make the section part easier to use.
+function node-docs {
+  local section=${1:-all}
+  open_command "https://nodejs.org/docs/$(node --version)/api/$section.html"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nomad/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/nomad/README.md
new file mode 100644 (file)
index 0000000..04b3616
--- /dev/null
@@ -0,0 +1,15 @@
+# Nomad
+
+The `nomad` plugin provides a simple autocompletion for [Nomad](https://nomadproject.io/), a tool from Hashicorp for easily deploy applications at any scale.
+
+## Usage
+
+1. Enable the `nomad` plugin:
+
+   ```zsh
+   plugins=(... nomad)
+   ```
+
+2.  Install [Nomad](https://nomadproject.io/)
+
+3.  Type `nomad` into your prompt and hit `TAB` to see available completion options.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nomad/_nomad b/stow/oh-my-zsh/.oh-my-zsh/plugins/nomad/_nomad
new file mode 100644 (file)
index 0000000..1c935a0
--- /dev/null
@@ -0,0 +1,153 @@
+#compdef nomad
+
+local -a _nomad_cmds
+_nomad_cmds=(
+  'agent:Runs a Nomad agent'
+  'agent-info:Display status information about the local agent'
+  'alloc-status:Display allocation status information and metadata'
+  'client-config:View or modify client configuration details'
+  'eval-status:Display evaluation status and placement failure reasons'
+  'fs:Inspect the contents of an allocation directory'
+  'init:Create an example job file'
+  'inspect:Inspect a submitted job'
+  'logs:Streams the logs of a task.'
+  'node-drain:Toggle drain mode on a given node'
+  'node-status:Display status information about nodes'
+  'plan:Dry-run a job update to determine its effects'
+  'run:Run a new job or update an existing'
+  'server-force-leave:Force a server into the left state'
+  'server-join:Join server nodes together'
+  'server-members:Display a list of known servers and their'
+  'status:Display status information about jobs'
+  'stop:Stop a running job'
+  'validate:Checks if a given job specification is valid'
+  'version:Prints the Nomad version'
+)
+
+__allocstatus() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-short[Display short output. Shows only the most recent task event.]' \
+    '-stats[Display detailed resource usage statistics.]' \
+    '-verbose[Show full information.]' \
+    '-json[Output the allocation in its JSON format.]' \
+    '-t[Format and display allocation using a Go template.]'
+}
+
+__evalstatus() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-monitor[Monitor an outstanding evaluation.]' \
+    '-verbose[Show full information.]' \
+    '-json[Output the allocation in its JSON format.]' \
+    '-t[Format and display allocation using a Go template.]'
+}
+
+__inspect() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-json[Output the allocation in its JSON format.]' \
+    '-t[Format and display allocation using a Go template.]'
+}
+
+__logs() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-stderr[ Display stderr logs.]' \
+    '-job[<job-id> Use a random allocation from the specified job ID.]' \
+    '-verbose[Show full information.]' \
+    '-f[Causes the output to not stop when the end of the logs are reached, but rather to wait for additional output.]' \
+    '-tail[Show the logs contents with offsets relative to the end of the logs. If no offset is given, -n is defaulted to 10.]' \
+    '-n[Sets the tail location in best-efforted number of lines relative to the end of the logs.]' \
+    '-c[Sets the tail location in number of bytes relative to the end of the logs.]'
+}
+
+__nodestatus() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-self[Query the status of the local node.]' \
+    '-allocs[ Display a count of running allocations for each node.]' \
+    '-short[Display short output. Shows only the most recent task event.]' \
+    '-stats[Display detailed resource usage statistics.]' \
+    '-verbose[Show full information.]' \
+    '-json[Output the allocation in its JSON format.]' \
+    '-t[Format and display allocation using a Go template.]'
+}
+
+__plan() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-diff[Determines whether the diff between the remote job and planned job is shown. Defaults to true.]' 
+}
+
+__run() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-check-index[If set, the job is only registered or updated if the the passed job modify index matches the server side version. If a check-index value of zero is passed, the job is only registered if it does not yet exist. If a non-zero value is passed, it ensures that the job is being updated from a known state. The use of this flag is most common in conjunction with plan command.]' \
+    '-detach[Return immediately instead of entering monitor mode. After job submission, the evaluation ID will be printed to the screen, which can be used to examine the evaluation using the eval-status command.]' \
+    '-output[Output the JSON that would be submitted to the HTTP API without submitting the job.]' \
+    '-verbose[Show full information.]'
+}
+
+__status() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-short[Display short output. Shows only the most recent task event.]' \
+    '-evals[Display the evaluations associated with the job.]' \
+    '-verbose[Show full information.]'
+}
+
+__stop() {
+  _arguments \
+    '-address=[(addr) The address of the Nomad server. Overrides the NOMAD_ADDR environment variable if set. Default = http://127.0.0.1:4646]' \
+    '-region=[(region) The region of the Nomad servers to forward commands to. Overrides the NOMAD_REGION environment variable if set. Defaults to the Agent s local region.]' \
+    '-no-color[Disables colored command output.]' \
+    '-detach[Return immediately instead of entering monitor mode. After the deregister command is submitted, a new evaluation ID is printed to the screen, which can be used to examine the evaluation using the eval-status command.]' \
+    '-yes[Automatic yes to prompts.]' \
+    '-verbose[Show full information.]'
+}
+
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "nomad command" _nomad_cmds
+  return
+fi
+
+local -a _command_args
+case "$words[1]" in
+  alloc-status)
+    __allocstatus ;;
+  eval-status)
+    __evalstatus ;;
+  inspect)
+    __inspect ;;
+  logs)
+    __logs ;;
+  node-status)
+    __nodestatus ;;
+  plan)
+    __plan ;;
+  run)
+    __run ;;
+  status)
+    __status ;;
+  stop)
+    __stop ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/npm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/npm/README.md
new file mode 100644 (file)
index 0000000..8eafc6d
--- /dev/null
@@ -0,0 +1,48 @@
+# npm plugin
+
+The npm plugin provides completion as well as adding many useful aliases.
+
+To use it, add npm to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... npm)
+```
+
+## Aliases
+
+| Alias   | Command                      | Description                                                     |
+|:------  |:-----------------------------|:----------------------------------------------------------------|
+| `npmg`  | `npm i -g`                   | Install dependencies globally                                   |
+| `npmS`  | `npm i -S`                   | Install and save to dependencies in your package.json           |
+| `npmD`  | `npm i -D`                   | Install and save to dev-dependencies in your package.json       |
+| `npmF`  | `npm i -f`                   | Force install from remote registries ignoring local cache       |
+| `npmE`  | `PATH="$(npm bin)":"$PATH"`  | Run command from node_modules folder based on current directory |
+| `npmO`  | `npm outdated`               | Check which npm modules are outdated                            |
+| `npmU`  | `npm update`                 | Update all the packages listed to the latest version            |
+| `npmV`  | `npm -v`                     | Check package versions                                          |
+| `npmL`  | `npm list`                   | List installed packages                                         |
+| `npmL0` | `npm ls --depth=0`           | List top-level installed packages                               |
+| `npmst` | `npm start`                  | Run npm start                                                   |
+| `npmt`  | `npm test`                   | Run npm test                                                    |
+| `npmR`  | `npm run`                    | Run npm scripts                                                 |
+| `npmP`  | `npm publish`                | Run npm publish                                                 |
+| `npmI`  | `npm init`                   | Run npm init                                                    |
+| `npmi`  | `npm info`                   | Run npm info                                                    |
+| `npmSe` | `npm search`                 | Run npm search                                                  |
+
+## `npm install` / `npm uninstall` toggle
+
+The plugin adds a function that toggles between `npm install` and `npm uninstall` in
+the current command or the last command, for up to 2 previous commands. **The default
+key binding is pressing <kbd>F2</kbd> twice**.
+
+You can change this key binding by adding the following line to your zshrc file:
+
+```zsh
+bindkey -M emacs '<seq>' npm_toggle_install_uninstall
+bindkey -M vicmd '<seq>' npm_toggle_install_uninstall
+bindkey -M viins '<seq>' npm_toggle_install_uninstall
+```
+
+where `<seq>` is a key sequence obtained by running `cat` and pressing the keyboard
+sequence you want.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/npm/npm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/npm/npm.plugin.zsh
new file mode 100644 (file)
index 0000000..e0dcbf1
--- /dev/null
@@ -0,0 +1,111 @@
+(( $+commands[npm] )) && {
+  command rm -f "${ZSH_CACHE_DIR:-$ZSH/cache}/npm_completion"
+
+  _npm_completion() {
+    local si=$IFS
+    compadd -- $(COMP_CWORD=$((CURRENT-1)) \
+                 COMP_LINE=$BUFFER \
+                 COMP_POINT=0 \
+                 npm completion -- "${words[@]}" \
+                 2>/dev/null)
+    IFS=$si
+  }
+  compdef _npm_completion npm
+}
+
+# Install dependencies globally
+alias npmg="npm i -g "
+
+# npm package names are lowercase
+# Thus, we've used camelCase for the following aliases:
+
+# Install and save to dependencies in your package.json
+# npms is used by https://www.npmjs.com/package/npms
+alias npmS="npm i -S "
+
+# Install and save to dev-dependencies in your package.json
+# npmd is used by https://github.com/dominictarr/npmd
+alias npmD="npm i -D "
+
+# Force npm to fetch remote resources even if a local copy exists on disk.
+alias npmF='npm i -f'
+
+# Execute command from node_modules folder based on current directory
+# i.e npmE gulp
+alias npmE='PATH="$(npm bin)":"$PATH"'
+
+# Check which npm modules are outdated
+alias npmO="npm outdated"
+
+# Update all the packages listed to the latest version
+alias npmU="npm update"
+
+# Check package versions
+alias npmV="npm -v"
+
+# List packages
+alias npmL="npm list"
+
+# List top-level installed packages
+alias npmL0="npm ls --depth=0"
+
+# Run npm start
+alias npmst="npm start"
+
+# Run npm test
+alias npmt="npm test"
+
+# Run npm scripts
+alias npmR="npm run"
+
+# Run npm publish 
+alias npmP="npm publish"
+
+# Run npm init
+alias npmI="npm init"
+
+# Run npm info
+alias npmi="npm info"
+
+# Run npm search
+alias npmSe="npm search"
+
+npm_toggle_install_uninstall() {
+  # Look up to the previous 2 history commands
+  local line
+  for line in "$BUFFER" \
+    "${history[$((HISTCMD-1))]}" \
+    "${history[$((HISTCMD-2))]}"
+  do
+    case "$line" in
+      "npm uninstall"*)
+        BUFFER="${line/npm uninstall/npm install}"
+        (( CURSOR = CURSOR + 2 )) # uninstall -> install: 2 chars removed
+        ;;
+      "npm install"*)
+        BUFFER="${line/npm install/npm uninstall}"
+        (( CURSOR = CURSOR + 2 )) # install -> uninstall: 2 chars added
+        ;;
+      "npm un "*)
+        BUFFER="${line/npm un/npm install}"
+        (( CURSOR = CURSOR + 5 )) # un -> install: 5 chars added
+        ;;
+      "npm i "*)
+        BUFFER="${line/npm i/npm uninstall}"
+        (( CURSOR = CURSOR + 8 )) # i -> uninstall: 8 chars added
+        ;;
+      *) continue ;;
+    esac
+    return 0
+  done
+
+  BUFFER="npm install"
+  CURSOR=${#BUFFER}
+}
+
+zle -N npm_toggle_install_uninstall
+
+# Defined shortcut keys: [F2] [F2]
+bindkey -M emacs '^[OQ^[OQ' npm_toggle_install_uninstall
+bindkey -M vicmd '^[OQ^[OQ' npm_toggle_install_uninstall
+bindkey -M viins '^[OQ^[OQ' npm_toggle_install_uninstall
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/README.md
new file mode 100644 (file)
index 0000000..1acf120
--- /dev/null
@@ -0,0 +1,34 @@
+# nvm plugin
+
+This plugin adds autocompletions for [nvm](https://github.com/nvm-sh/nvm) — a Node.js version manager.
+It also automatically sources nvm, so you don't need to do it manually in your `.zshrc`.
+
+To use it, add `nvm` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... nvm)
+```
+
+## Settings
+
+If you installed nvm in a directory other than `$HOME/.nvm`, set and export `NVM_DIR` to be the directory
+where you installed nvm.
+
+These settings should go in your zshrc file, before Oh My Zsh is sourced:
+
+- **`NVM_HOMEBREW`**: if you installed nvm via Homebrew, in a directory other than `/usr/local/opt/nvm`, you
+  can set `NVM_HOMEBREW` to be the directory where you installed it. For example, on Apple Silicon-based Macs,
+  [Homebrew is installed in `/opt/homebrew`](https://docs.brew.sh/Installation). To get the directory where
+  nvm has been installed, regardless of chip architecture, use `NVM_HOMEBREW=$(brew --prefix nvm)`.
+
+- **`NVM_LAZY`**: if you want the plugin to defer the load of nvm to speed-up the start of your zsh session,
+  set `NVM_LAZY` to `1`. This will source nvm script only when using it, and will create a function for `node`,
+  `npm`, `pnpm`, `yarn`, and the command(s) specified by `NVM_LAZY_CMD`, so when you call either of them,
+  nvm will be loaded and run with default version.
+
+- **`NVM_LAZY_CMD`**: if you want additional command(s) to trigger lazy loading of nvm, set `NVM_LAZY_CMD` to
+  the command or an array of the commands.
+
+- **`NVM_AUTOLOAD`**: if `NVM_AUTOLOAD` is set to `1`, the plugin will automatically load a node version when
+  if finds a [`.nvmrc` file](https://github.com/nvm-sh/nvm#nvmrc) in the current working directory indicating
+  which node version to load.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/_nvm b/stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/_nvm
new file mode 100644 (file)
index 0000000..e292a8d
--- /dev/null
@@ -0,0 +1,34 @@
+#compdef nvm
+#autoload
+
+[[ -f "$NVM_DIR/nvm.sh" ]] || return 0
+
+local -a _1st_arguments
+_1st_arguments=(
+  'help:show help'
+  '--version:print out the latest released version of nvm'
+  'install:download and install a version in <node|iojs|node version number>'
+  'install-latest-npm:download and install the latest npm version'
+  'uninstall:uninstall a version'
+  'use:modify PATH to use <version>. Uses .nvmrc if available'
+  'exec:run <command> on <version>. Uses .nvmrc if available'
+  'run:run `node` on <version> with <args> as arguments. Uses .nvmrc if available'
+  'current:list installed versions'
+  'ls:list installed versions or versions matching a given description'
+  'version:resolve the given description to a single local version'
+  'version-remote:resolve the given description to a single remote version'
+  'ls-remote:list remote versions available for install'
+  'deactivate:undo effects of `nvm` on current shell'
+  'alias:show or set aliases'
+  'unalias:deletes an alias'
+  'reinstall-packages:reinstall global `npm` packages contained in <version> to current version'
+  'unload:unload `nvm` from shell'
+  'which:display path to installed node version. Uses .nvmrc if available'
+)
+
+_arguments -C '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "nvm subcommand" _1st_arguments
+  return
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/nvm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/nvm/nvm.plugin.zsh
new file mode 100644 (file)
index 0000000..1fb4d23
--- /dev/null
@@ -0,0 +1,73 @@
+# See https://github.com/nvm-sh/nvm#installation-and-update
+if [[ -z "$NVM_DIR" ]]; then
+  if [[ -d "$HOME/.nvm" ]]; then
+    export NVM_DIR="$HOME/.nvm"
+  elif [[ -d "${XDG_CONFIG_HOME:-$HOME/.config}/nvm" ]]; then
+    export NVM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/nvm"
+  elif (( $+commands[brew] )); then
+    NVM_HOMEBREW="${NVM_HOMEBREW:-${HOMEBREW_PREFIX:-$(brew --prefix)}/opt/nvm}"
+    if [[ -d "$NVM_HOMEBREW" ]]; then
+      export NVM_DIR="$NVM_HOMEBREW"
+    fi
+  fi
+fi
+
+# Don't try to load nvm if command already available
+# Note: nvm is a function so we need to use `which`
+which nvm &>/dev/null && return
+
+if (( $+NVM_LAZY )); then
+  # Call nvm when first using nvm, node, npm, pnpm, yarn or $NVM_LAZY_CMD
+  function nvm node npm pnpm yarn $NVM_LAZY_CMD {
+    unfunction nvm node npm pnpm yarn $NVM_LAZY_CMD
+    # Load nvm if it exists in $NVM_DIR
+    [[ -f "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh"
+    "$0" "$@"
+  }
+elif [[ -f "$NVM_DIR/nvm.sh" ]]; then
+  # Load nvm if it exists in $NVM_DIR
+  source "$NVM_DIR/nvm.sh"
+else
+  return
+fi
+
+# Autoload nvm when finding a .nvmrc file in the current directory
+# Adapted from: https://github.com/nvm-sh/nvm#zsh
+if (( $+NVM_AUTOLOAD )); then
+  load-nvmrc() {
+    local node_version="$(nvm version)"
+    local nvmrc_path="$(nvm_find_nvmrc)"
+
+    if [[ -n "$nvmrc_path" ]]; then
+      local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
+
+      if [[ "$nvmrc_node_version" = "N/A" ]]; then
+        nvm install
+      elif [[ "$nvmrc_node_version" != "$node_version" ]]; then
+        nvm use
+      fi
+    elif [[ "$node_version" != "$(nvm version default)" ]]; then
+      echo "Reverting to nvm default version"
+      nvm use default
+    fi
+  }
+
+  autoload -U add-zsh-hook
+  add-zsh-hook chpwd load-nvmrc
+
+  load-nvmrc
+fi
+
+# Load nvm bash completion
+for nvm_completion in "$NVM_DIR/bash_completion" "$NVM_HOMEBREW/etc/bash_completion.d/nvm"; do
+  if [[ -f "$nvm_completion" ]]; then
+    # Load bashcompinit
+    autoload -U +X bashcompinit && bashcompinit
+    # Bypass compinit call in nvm bash completion script. See:
+    # https://github.com/nvm-sh/nvm/blob/4436638/bash_completion#L86-L93
+    ZSH_VERSION= source "$nvm_completion"
+    break
+  fi
+done
+
+unset NVM_HOMEBREW NVM_LAZY NVM_AUTOLOAD nvm_completion
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/oc/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/oc/README.md
new file mode 100644 (file)
index 0000000..b7903ea
--- /dev/null
@@ -0,0 +1,13 @@
+# OC - OpenShift CLI
+
+This plugin provides autocompletion for [OC](https://docs.openshift.com/container-platform/latest/cli_reference/openshift_cli/getting-started-cli.html) commands, building, managing and updating operations.
+
+To use it, add `oc` to the plugins array of your zshrc file:
+
+```bash
+plugins=(... oc)
+```
+
+## Contributors
+
++ [kevinkirkup](https://github.com/kevinkirkup) - Plugin Author
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/oc/oc.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/oc/oc.plugin.zsh
new file mode 100644 (file)
index 0000000..f0e2fc3
--- /dev/null
@@ -0,0 +1,8 @@
+# Autocompletion for oc, the command line interface for OpenShift
+#
+# Author: https://github.com/kevinkirkup
+
+if [ $commands[oc] ]; then
+  source <(oc completion zsh)
+  compdef _oc oc
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/octozen/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/octozen/README.md
new file mode 100644 (file)
index 0000000..2051248
--- /dev/null
@@ -0,0 +1,12 @@
+# Octozen plugin
+
+Displays a zen quote from GitHub's Octocat on start up.
+
+To use it, add `octozen` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... octozen)
+```
+
+It defines a `display_octozen` function that fetches a GitHub Octocat zen quote.
+NOTE: Internet connection is required (will time out if not fetched in 2 seconds).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/octozen/octozen.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/octozen/octozen.plugin.zsh
new file mode 100644 (file)
index 0000000..71ee550
--- /dev/null
@@ -0,0 +1,11 @@
+# octozen plugin
+
+# Displays a zen quote from octocat
+function display_octozen() {
+  curl -m 2 -fsL "https://api.github.com/octocat"
+  add-zsh-hook -d precmd display_octozen
+}
+
+# Display the octocat on the first precmd, after the whole starting process has finished
+autoload -Uz add-zsh-hook
+add-zsh-hook precmd display_octozen
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/operator-sdk/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/operator-sdk/README.md
new file mode 100644 (file)
index 0000000..3336e36
--- /dev/null
@@ -0,0 +1,11 @@
+# Operator SDK
+
+[Operator SDK](https://sdk.operatorframework.io/) is a component of the Operator Framework, an open source toolkit to manage Kubernetes native applications, called Operators, in an effective, automated, and scalable way.
+
+To use it, add `operator-sdk` to the plugins array of your zshrc file:
+
+```sh
+plugins=(... operator-sdk)
+```
+
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/operator-sdk/operator-sdk.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/operator-sdk/operator-sdk.plugin.zsh
new file mode 100644 (file)
index 0000000..baeb01a
--- /dev/null
@@ -0,0 +1,4 @@
+if [ $commands[operator-sdk] ]; then
+  source <(operator-sdk completion zsh)
+  compdef _operator-sdk operator-sdk
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/otp/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/otp/README.md
new file mode 100644 (file)
index 0000000..8331fd0
--- /dev/null
@@ -0,0 +1,22 @@
+# otp plugin
+
+This plugin allows you to create one-time passwords using [`oathtool`](https://www.nongnu.org/oath-toolkit/man-oathtool.html),
+able to replace MFA devices. The oathtool key is kept in a GPG-encrypted file so the codes
+can only be generated by a user able to decrypt it.
+
+To use it, add `otp` to the plugins array in your zshrc file:
+```zsh
+plugins=(... otp)
+```
+
+Provided aliases:
+
+- `otp_add_device`: creates a new encrypted storage for an oathtool key and stores it
+  on the disk. For encrypting the key, it will ask for a GPG user ID (your GPG key's
+  email address). Then the OTP key needs to be pasted, followed by a CTRL+D character
+  inserted on an empty line.
+
+- `ot`: generates a MFA code based on the given key and copies it to the clipboard 
+  (on Linux it relies on xsel, on MacOS X it uses pbcopy instead).
+
+The plugin uses `$HOME/.otp` to store its internal files.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/otp/otp.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/otp/otp.plugin.zsh
new file mode 100644 (file)
index 0000000..8be125c
--- /dev/null
@@ -0,0 +1,45 @@
+export OTP_HOME=~/.otp
+mkdir -p $OTP_HOME
+
+function ot () {
+  if ! command -v oathtool > /dev/null 2>&1; then
+    echo "Note: you need to install oathtool or oath-toolkit, depending on your OS or distribution."
+    return 1
+  fi
+
+  if ! command -v gpg > /dev/null 2>&1; then
+    echo "Note: you need to install gpg and create an ID using 'gpg --gen-key', unless you have one already."
+    return 1
+  fi
+
+  COPY_CMD='true'
+
+  if [[ -z "$1" ]]; then
+    echo "usage: $0 <profile.name>"
+    return 1
+  elif [ ! -f $OTP_HOME/$1.otp.asc ]; then
+    echo "missing profile $1, you might need to create it first using otp_add_device"
+    return 1
+  else
+    totpkey=$(gpg --decrypt $OTP_HOME/$1.otp.asc)
+    oathtool --totp --b $totpkey | tee /dev/stderr | clipcopy
+  fi
+}
+
+function otp_add_device () {
+  if [[ "x$1" == "x" ]] then
+    echo "usage: $0 <profile.name>"
+    return 1
+  else
+    echo "Enter an email address attached to your GPG private key, then paste the secret configuration key followed by ^D"
+
+    rm -f $OTP_HOME/$1.otp.asc
+    gpg --armor --encrypt --output $OTP_HOME/$1.otp.asc /dev/stdin
+  fi
+}
+
+function otp_devices () {
+  reply=($(find $OTP_HOME -name \*.otp.asc | xargs basename -s .otp.asc))
+}
+
+compctl -K otp_devices ot
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pass/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pass/README.md
new file mode 100644 (file)
index 0000000..2b07049
--- /dev/null
@@ -0,0 +1,22 @@
+# pass
+
+This plugin provides completion for the [pass](https://www.passwordstore.org/) password manager.
+
+To use it, add `pass` to the plugins array in your zshrc file.
+
+```
+plugins=(... pass)
+```
+
+## Configuration
+
+### Multiple repositories
+
+If you use multiple repositories, you can configure completion like this:
+```zsh
+compdef _pass workpass
+zstyle ':completion::complete:workpass::' prefix "$HOME/work/pass"
+workpass() {
+  PASSWORD_STORE_DIR=$HOME/work/pass pass $@
+}
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pass/_pass b/stow/oh-my-zsh/.oh-my-zsh/plugins/pass/_pass
new file mode 100644 (file)
index 0000000..d911e12
--- /dev/null
@@ -0,0 +1,144 @@
+#compdef pass
+#autoload
+
+# Copyright (C) 2012 - 2014:
+#    Johan Venant <jvenant@invicem.pro>
+#    Brian Mattern <rephorm@rephorm.com>
+#    Jason A. Donenfeld <Jason@zx2c4.com>.
+# All Rights Reserved.
+# This file is licensed under the GPLv2+. Please see COPYING for more information.
+
+
+# If you use multiple repositories, you can configure completion like this:
+#
+# compdef _pass workpass
+# zstyle ':completion::complete:workpass::' prefix "$HOME/work/pass"
+# workpass() {
+#   PASSWORD_STORE_DIR=$HOME/work/pass pass $@
+# }
+
+
+_pass () {
+       local cmd
+       if (( CURRENT > 2)); then
+               cmd=${words[2]}
+               # Set the context for the subcommand.
+               curcontext="${curcontext%:*:*}:pass-$cmd"
+               # Narrow the range of words we are looking at to exclude `pass'
+               (( CURRENT-- ))
+               shift words
+               # Run the completion for the subcommand
+               case "${cmd}" in
+                       init)
+                               _arguments : \
+                                       "-p[gpg-id will only be applied to this subfolder]" \
+                                       "--path[gpg-id will only be applied to this subfolder]"
+                               _pass_complete_keys
+                               ;;
+                       ls|list|edit)
+                               _pass_complete_entries_with_subdirs
+                               ;;
+                       insert)
+                               _arguments : \
+                                       "-e[echo password to console]" \
+                                       "--echo[echo password to console]" \
+                                       "-m[multiline]" \
+                                       "--multiline[multiline]"
+                               _pass_complete_entries_with_subdirs
+                               ;;
+                       generate)
+                               _arguments : \
+                                       "-n[don't include symbols in password]" \
+                                       "--no-symbols[don't include symbols in password]" \
+                                       "-c[copy password to the clipboard]" \
+                                       "--clip[copy password to the clipboard]" \
+                                       "-f[force overwrite]" \
+                                       "--force[force overwrite]" \
+                                       "-i[replace first line]" \
+                                       "--in-place[replace first line]"
+                               _pass_complete_entries_with_subdirs
+                               ;;
+                       cp|copy|mv|rename)
+                               _arguments : \
+                                       "-f[force rename]" \
+                                       "--force[force rename]"
+                                       _pass_complete_entries_with_subdirs
+                               ;;
+                       rm)
+                               _arguments : \
+                                       "-f[force deletion]" \
+                                       "--force[force deletion]" \
+                                       "-r[recursively delete]" \
+                                       "--recursive[recursively delete]"
+                                       _pass_complete_entries_with_subdirs
+                               ;;
+                       git)
+                               local -a subcommands
+                               subcommands=(
+                                       "init:Initialize git repository"
+                                       "push:Push to remote repository"
+                                       "pull:Pull from remote repository"
+                                       "config:Show git config"
+                                       "log:Show git log"
+                                       "reflog:Show git reflog"
+                               )
+                               _describe -t commands 'pass git' subcommands
+                               ;;
+                       show|*)
+                               _pass_cmd_show
+                               ;;
+               esac
+       else
+               local -a subcommands
+               subcommands=(
+                       "init:Initialize new password storage"
+                       "ls:List passwords"
+                       "find:Find password files or directories based on pattern"
+                       "grep:Search inside decrypted password files for matching pattern"
+                       "show:Decrypt and print a password"
+                       "insert:Insert a new password"
+                       "generate:Generate a new password using pwgen"
+                       "edit:Edit a password with \$EDITOR"
+                       "mv:Rename the password"
+                       "cp:Copy the password"
+                       "rm:Remove the password"
+                       "git:Call git on the password store"
+                       "version:Output version information"
+                       "help:Output help message"
+               )
+               _describe -t commands 'pass' subcommands
+               _arguments : \
+                       "--version[Output version information]" \
+                       "--help[Output help message]"
+               _pass_cmd_show
+       fi
+}
+
+_pass_cmd_show () {
+       _arguments : \
+               "-c[put it on the clipboard]" \
+               "--clip[put it on the clipboard]"
+       _pass_complete_entries
+}
+_pass_complete_entries_helper () {
+       local IFS=$'\n'
+       local prefix
+       zstyle -s ":completion:${curcontext}:" prefix prefix || prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
+       _values -C 'passwords' ${$(find -L "$prefix" \( -name .git -o -name .gpg-id \) -prune -o $@ -print 2>/dev/null | sed -e "s#${prefix}/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#g' -e 's#:#\\:#g' | sort):-""}
+}
+
+_pass_complete_entries_with_subdirs () {
+       _pass_complete_entries_helper
+}
+
+_pass_complete_entries () {
+       _pass_complete_entries_helper -type f
+}
+
+_pass_complete_keys () {
+       local IFS=$'\n'
+       # Extract names and email addresses from gpg --list-keys
+       _values 'gpg keys' $(gpg2 --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d')
+}
+
+_pass
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/paver/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/paver/README.md
new file mode 100644 (file)
index 0000000..c38d898
--- /dev/null
@@ -0,0 +1,12 @@
+# Paver
+
+This plugin adds completion for the `paver` command-line tool of [Paver](https://pythonhosted.org/Paver/).
+
+To use it, add `paver` to the plugins array of your zshrc file:
+```zsh
+plugins=(... paver)
+```
+
+The completion function creates a cache of paver tasks with the name `.paver_tasks`,
+in the current working directory. It regenerates that cache when the `pavement.py`
+changes.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/paver/paver.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/paver/paver.plugin.zsh
new file mode 100644 (file)
index 0000000..7e70ea3
--- /dev/null
@@ -0,0 +1,16 @@
+_paver_does_target_list_need_generating () {
+  [ ! -f .paver_targets ] && return 0
+  [ pavement.py -nt .paver_targets ] && return 0
+  return 1
+}
+
+_paver () {
+  if [ -f pavement.py ]; then
+    if _paver_does_target_list_need_generating; then
+      paver --help 2>&1 |grep '-'|grep -v -e '--'|awk -F '-' '{print $1}'|tr -d ' ' > .paver_targets
+    fi
+    compadd `cat .paver_targets`
+  fi
+}
+
+compdef _paver paver
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pep8/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pep8/README.md
new file mode 100644 (file)
index 0000000..a9a4f1c
--- /dev/null
@@ -0,0 +1,8 @@
+# pep8 plugin
+
+This plugin adds completion for [pep8](https://pep8.readthedocs.io/en/release-1.7.x/#), a tool to check your Python code against some of the style conventions in [PEP 8](http://www.python.org/dev/peps/pep-0008/).
+
+To use it, add pep8 to the plugins array of your zshrc file:
+```
+plugins=(... pep8)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pep8/_pep8 b/stow/oh-my-zsh/.oh-my-zsh/plugins/pep8/_pep8
new file mode 100644 (file)
index 0000000..27b7fc5
--- /dev/null
@@ -0,0 +1,34 @@
+#compdef pep8
+#
+# this is zsh completion function file.
+# generated by genzshcomp(ver: 0.5.1)
+#
+
+typeset -A opt_args
+local context state line
+
+_arguments -s -S \
+  "--help[show this help message and exit]:" \
+  "-h[show this help message and exit]:" \
+  "--version[show program's version number and exit]:" \
+  "--verbose[print status messages, or debug with -vv]" \
+  "-v[print status messages, or debug with -vv]" \
+  "--quiet[report only file names, or nothing with -qq]" \
+  "-q[report only file names, or nothing with -qq]" \
+  "--repeat[(obsolete) show all occurrences of the same error]" \
+  "-r[(obsolete) show all occurrences of the same error]" \
+  "--first[show first occurrence of each error]" \
+  "--exclude[exclude files or directories which match these comma separated patterns (default: .svn,CVS,.bzr,.hg,.git,__pycache__)]::patterns:_files" \
+  "--filename[when parsing directories, only check filenames matching these comma separated patterns (default: *.py)]::patterns:_files" \
+  "--select[select errors and warnings (e.g. E,W6)]::errors:_files" \
+  "--ignore[skip errors and warnings (e.g. E4,W)]::errors:_files" \
+  "--show-source[show source code for each error]" \
+  "--show-pep8[show text of PEP 8 for each error (implies --first)]" \
+  "--statistics[count errors and warnings]" \
+  "--count[print total number of errors and warnings to standard error and set exit code to 1 if total is not null]" \
+  "--max-line-length[set maximum allowed line length (default: 79)]::n:_files" \
+  "--format[set the error format \[default|pylint|<custom>\]]::format:_files" \
+  "--diff[report only lines changed according to the unified diff received on STDIN]" \
+  "--benchmark[measure processing speed   are read from the \[pep8\] section of the tox.ini fg file located in any parent folder of the path(s) allowed options are: exclude, filename, select, ngth, count, format, quiet, show-pep8, show-source, .]" \
+  "--config[user config file location (default: /home/gsemet/.config/pep8)]::path:_files" \
+  "*::args:_files"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/README.md
new file mode 100644 (file)
index 0000000..69854aa
--- /dev/null
@@ -0,0 +1,48 @@
+per-directory-history plugin
+----------------------------
+
+This plugin adds per-directory history for zsh, as well as a global history,
+and the ability to toggle between them with a keyboard shortcut. This is a
+bundle of the [official plugin by @jimhester][5].
+
+To use it, add `per-directory-history` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... per-directory-history)
+```
+
+This is an implementation of per-directory history for zsh, some implementations
+of which exist in bash[1][],[2][]. It also implements a toggle-history function
+to change from using the directory history to using the global history. In both
+cases the history is always saved to both the global history and the directory
+history, so the toggle state will not effect the saved histories. Being able to
+switch between global and directory histories on the fly is a novel feature.
+
+## Usage
+
+The default mode is per directory history, interact with your history as normal.
+
+Press ^G (the <kbd>Control</kbd> and <kbd>G</kbd> keys simultaneously) to toggle
+between local and global histories. If you would prefer a different shortcut to
+toggle set the `PER_DIRECTORY_HISTORY_TOGGLE` environment variable.
+
+## Configuration
+
+* `HISTORY_BASE` is a global variable that defines the base directory in which the
+  directory histories are stored (default `$HOME/.directory_history`).
+* `per-directory-history-toggle-history` is the function to toggle between local
+  and global histories.
+* `PER_DIRECTORY_HISTORY_TOGGLE` is the key binding used to run the toggle-history
+  function above (default `^G`)
+
+## History
+
+The idea/inspiration for a per directory history is from [Stewart MacArthur][1]
+and [Dieter][2], the implementation idea is from [Bart Schaefer][3]. The
+implementation is by [Jim Hester][4] in September 2012.
+
+[1]: http://www.compbiome.com/2010/07/bash-per-directory-bash-history.html
+[2]: http://dieter.plaetinck.be/per_directory_bash
+[3]: https://www.zsh.org/mla/users/1997/msg00226.html
+[4]: https://jimhester.com
+[5]: https://github.com/jimhester/per-directory-history
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/per-directory-history.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/per-directory-history.plugin.zsh
new file mode 120000 (symlink)
index 0000000..142d954
--- /dev/null
@@ -0,0 +1 @@
+per-directory-history.zsh
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/per-directory-history.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/per-directory-history/per-directory-history.zsh
new file mode 100644 (file)
index 0000000..7cd673c
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/bin/env zsh
+#
+# This is a implementation of per directory history for zsh, some
+# implementations of which exist in bash[1,2].  It also implements
+# a per-directory-history-toggle-history function to change from using the
+# directory history to using the global history.  In both cases the history is
+# always saved to both the global history and the directory history, so the
+# toggle state will not effect the saved histories.  Being able to switch
+# between global and directory histories on the fly is a novel feature as far
+# as I am aware.
+#
+#-------------------------------------------------------------------------------
+# Configuration
+#-------------------------------------------------------------------------------
+#
+# HISTORY_BASE a global variable that defines the base directory in which the
+# directory histories are stored
+#
+#-------------------------------------------------------------------------------
+# History
+#-------------------------------------------------------------------------------
+#
+# The idea/inspiration for a per directory history is from Stewart MacArthur[1]
+# and Dieter[2], the implementation idea is from Bart Schaefer on the the zsh
+# mailing list[3].  The implementation is by Jim Hester in September 2012.
+#
+# [1]: http://www.compbiome.com/2010/07/bash-per-directory-bash-history.html
+# [2]: http://dieter.plaetinck.be/per_directory_bash
+# [3]: http://www.zsh.org/mla/users/1997/msg00226.html
+#
+################################################################################
+#
+# Copyright (c) 2014 Jim Hester
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not claim
+# that you wrote the original software. If you use this software in a product,
+# an acknowledgment in the product documentation would be appreciated but is
+# not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution..
+#
+################################################################################
+
+#-------------------------------------------------------------------------------
+# configuration, the base under which the directory histories are stored
+#-------------------------------------------------------------------------------
+
+[[ -z $HISTORY_BASE ]] && HISTORY_BASE="$HOME/.directory_history"
+[[ -z $HISTORY_START_WITH_GLOBAL ]] && HISTORY_START_WITH_GLOBAL=false
+[[ -z $PER_DIRECTORY_HISTORY_TOGGLE ]] && PER_DIRECTORY_HISTORY_TOGGLE='^G'
+
+#-------------------------------------------------------------------------------
+# toggle global/directory history used for searching - ctrl-G by default
+#-------------------------------------------------------------------------------
+
+function per-directory-history-toggle-history() {
+  if [[ $_per_directory_history_is_global == true ]]; then
+    _per-directory-history-set-directory-history
+    _per_directory_history_is_global=false
+    print -n "\nusing local history"
+  else
+    _per-directory-history-set-global-history
+    _per_directory_history_is_global=true
+    print -n "\nusing global history"
+  fi
+  zle .push-line
+  zle .accept-line
+}
+
+autoload per-directory-history-toggle-history
+zle -N per-directory-history-toggle-history
+bindkey $PER_DIRECTORY_HISTORY_TOGGLE per-directory-history-toggle-history
+
+#-------------------------------------------------------------------------------
+# implementation details
+#-------------------------------------------------------------------------------
+
+_per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
+
+function _per-directory-history-change-directory() {
+  _per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
+  mkdir -p ${_per_directory_history_directory:h}
+  if [[ $_per_directory_history_is_global == false ]]; then
+    #save to the global history
+    fc -AI $HISTFILE
+    #save history to previous file
+    local prev="$HISTORY_BASE${OLDPWD:A}/history"
+    mkdir -p ${prev:h}
+    fc -AI $prev
+
+    #discard previous directory's history
+    local original_histsize=$HISTSIZE
+    HISTSIZE=0
+    HISTSIZE=$original_histsize
+
+    #read history in new file
+    if [[ -e $_per_directory_history_directory ]]; then
+      fc -R $_per_directory_history_directory
+    fi
+  fi
+}
+
+function _per-directory-history-addhistory() {
+  # respect hist_ignore_space
+  if [[ -o hist_ignore_space ]] && [[ "$1" == \ * ]]; then
+      true
+  else
+      print -Sr -- "${1%%$'\n'}"
+      # instantly write history if set options require it.
+      if [[ -o share_history ]] || \
+         [[ -o inc_append_history ]] || \
+         [[ -o inc_append_history_time ]]; then
+          fc -AI $HISTFILE
+          fc -AI $_per_directory_history_directory
+      fi
+      fc -p $_per_directory_history_directory
+  fi
+}
+
+function _per-directory-history-precmd() {
+  if [[ $_per_directory_history_initialized == false ]]; then
+    _per_directory_history_initialized=true
+
+    if [[ $HISTORY_START_WITH_GLOBAL == true ]]; then
+      _per-directory-history-set-global-history
+      _per_directory_history_is_global=true
+    else
+      _per-directory-history-set-directory-history
+      _per_directory_history_is_global=false
+    fi
+  fi
+}
+
+function _per-directory-history-set-directory-history() {
+  fc -AI $HISTFILE
+  local original_histsize=$HISTSIZE
+  HISTSIZE=0
+  HISTSIZE=$original_histsize
+  if [[ -e "$_per_directory_history_directory" ]]; then
+    fc -R "$_per_directory_history_directory"
+  fi
+}
+
+function _per-directory-history-set-global-history() {
+  fc -AI $_per_directory_history_directory
+  local original_histsize=$HISTSIZE
+  HISTSIZE=0
+  HISTSIZE=$original_histsize
+  if [[ -e "$HISTFILE" ]]; then
+    fc -R "$HISTFILE"
+  fi
+}
+
+mkdir -p ${_per_directory_history_directory:h}
+
+#add functions to the exec list for chpwd and zshaddhistory
+autoload -U add-zsh-hook
+add-zsh-hook chpwd _per-directory-history-change-directory
+add-zsh-hook zshaddhistory _per-directory-history-addhistory
+add-zsh-hook precmd _per-directory-history-precmd
+
+# set initialized flag to false
+_per_directory_history_initialized=false
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/percol/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/percol/README.md
new file mode 100644 (file)
index 0000000..78c881f
--- /dev/null
@@ -0,0 +1,23 @@
+# percol
+
+Provides some useful function to make [percol](https://github.com/mooz/percol) work with zsh history and
+the [jump plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/jump), optionally.
+
+To use it, add `percol` to the plugins array in your zshrc:
+
+```zsh
+plugins=(... percol)
+```
+
+## Requirements
+
+- `percol`: install with `pip install percol`.
+
+- (_Optional_) [`jump`](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/jump) plugin: needs to be
+  enabled before the `percol` plugin.
+
+## Usage
+
+- <kbd>CTRL-R</kbd> (bound to `percol_select_history`): you can use it to grep your history with percol.
+
+- <kbd>CTRL-B</kbd> (bound to `percol_select_marks`): you can use it to grep your jump bookmarks with percol.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/percol/percol.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/percol/percol.plugin.zsh
new file mode 100644 (file)
index 0000000..b78383e
--- /dev/null
@@ -0,0 +1,25 @@
+(( ${+commands[percol]} )) || return
+
+function percol_select_history() {
+  # print history in reverse order (from -1 (latest) to 1 (oldest))
+  BUFFER=$(fc -l -n -1 1 | percol --query "$LBUFFER")
+  CURSOR=$#BUFFER
+  zle -R -c
+}
+zle -N percol_select_history
+bindkey -M emacs '^R' percol_select_history
+bindkey -M viins '^R' percol_select_history
+bindkey -M vicmd '^R' percol_select_history
+
+if (( ${+functions[marks]} )); then
+  function percol_select_marks() {
+    # parse directory from marks output (markname -> path) and quote if necessary
+    BUFFER=${(q)"$(marks | percol --query "$LBUFFER")"##*-> }
+    CURSOR=$#BUFFER
+    zle -R -c
+  }
+  zle -N percol_select_marks
+  bindkey -M emacs '^B' percol_select_marks
+  bindkey -M viins '^B' percol_select_marks
+  bindkey -M vicmd '^B' percol_select_marks
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/perl/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/perl/README.md
new file mode 100644 (file)
index 0000000..dd9b7dc
--- /dev/null
@@ -0,0 +1,37 @@
+# Perl
+
+This plugin adds [perl](https://www.perl.org/) useful aliases/functions.
+
+To use it, add `perl` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... perl)
+```
+
+## Aliases
+
+| Aliases       | Command            |  Description                           |
+| :------------ | :----------------- | :------------------------------------- |
+| pbi           | `perlbrew install` | Install specific perl version          |
+| pbl           | `perlbrew list`    | List all perl version installed        |
+| pbo           | `perlbrew off`     | Go back to the system perl             |
+| pbs           | `perlbrew switch`  | Turn it back on                        |
+| pbu           | `perlbrew use`     | Use specific version of perl           |
+| pd            | `perldoc`          | Show the perl documentation            |
+| ple           | `perl -wlne`       | Use perl like awk/sed                  |
+| latest-perl   | `curl ...`         | Show the latest stable release of Perl |
+
+## Functions
+
+* `newpl`: creates a basic Perl script file and opens it with $EDITOR.
+
+* `pgs`: Perl Global Substitution: `pgs <find_pattern> <replace_pattern> <filename>`
+  Looks for `<find_pattern>` and replaces it with `<replace_pattern>` in `<filename>`.
+
+* `prep`: Perl grep, because 'grep -P' is terrible: `prep <pattern> [<filename>]`
+  Lets you work with pipes or files (if no `<filename>` provided, use stdin).
+
+## Requirements
+
+In order to make this work, you will need to have perl installed.
+More info on the usage and install: https://www.perl.org/get.html
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/perl/perl.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/perl/perl.plugin.zsh
new file mode 100644 (file)
index 0000000..678e88d
--- /dev/null
@@ -0,0 +1,56 @@
+# https://github.com/dbbolton
+#
+# Below are some useful Perl-related aliases/functions that I use with zsh.
+
+
+# Aliases ###################################################################
+
+# perlbrew ########
+alias pbi='perlbrew install'
+alias pbl='perlbrew list'
+alias pbo='perlbrew off'
+alias pbs='perlbrew switch'
+alias pbu='perlbrew use'
+
+# Perl ############
+
+# perldoc`
+alias pd='perldoc'
+
+# use perl like awk/sed
+alias ple='perl -wlne'
+
+# show the latest stable release of Perl
+alias latest-perl='curl -s https://www.perl.org/get.html | perl -wlne '\''if (/perl\-([\d\.]+)\.tar\.gz/) { print $1; exit;}'\'
+
+
+
+# Functions #################################################################
+
+# newpl - creates a basic Perl script file and opens it with $EDITOR
+newpl () {
+       # set $EDITOR to 'vim' if it is undefined
+       [[ -z $EDITOR ]] && EDITOR=vim
+
+       # if the file exists, just open it
+       [[ -e $1 ]] && print "$1 exists; not modifying.\n" && $EDITOR $1
+
+       # if it doesn't, make it, and open it
+       [[ ! -e $1 ]] && print '#!/usr/bin/perl'"\n"'use strict;'"\n"'use warnings;'\
+               "\n\n" > $1 && $EDITOR $1
+}
+
+
+# pgs - Perl Global Substitution
+# find pattern         = 1st arg
+# replace pattern      = 2nd arg
+# filename                     = 3rd arg
+pgs() { # [find] [replace] [filename]
+    perl -i.orig -pe 's/'"$1"'/'"$2"'/g' "$3"
+}
+
+
+# Perl grep, because 'grep -P' is terrible. Lets you work with pipes or files.
+prep() { # [pattern] [filename unless STDOUT]
+    perl -nle 'print if /'"$1"'/;' $2
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/perms/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/perms/README.md
new file mode 100644 (file)
index 0000000..ae7a36b
--- /dev/null
@@ -0,0 +1,15 @@
+# Perms plugin
+
+Plugin to handle some unix filesystem permissions quickly.
+
+To use it, add `perms` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... perms)
+```
+
+## Usage
+
+* `set755` recursively sets all given directories (default to .) to octal 755.
+* `set644` recursively sets all given files (default to .) to octal 644.
+* `fixperms` is a wrapper around `set755` and `set644` applied to a specified directory or the current directory otherwise. It also prompts prior to execution unlike the other two aliases.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/perms/perms.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/perms/perms.plugin.zsh
new file mode 100644 (file)
index 0000000..1a7472c
--- /dev/null
@@ -0,0 +1,82 @@
+# Some useful commands for setting permissions.
+#
+# Rory Hardy [GneatGeek]
+# Andrew Janke [apjanke]
+
+### Aliases
+
+# Set all files' permissions to 644 recursively in a directory
+set644() {
+       find "${@:-.}" -type f ! -perm 644 -print0 | xargs -0 chmod 644
+}
+
+# Set all directories' permissions to 755 recursively in a directory
+set755() {
+       find "${@:-.}" -type d ! -perm 755 -print0 | xargs -0 chmod 755
+}
+
+### Functions
+
+# fixperms - fix permissions on files and directories, with confirmation
+# Returns 0 on success, nonzero if any errors occurred
+fixperms () {
+  local opts confirm target exit_status chmod_opts use_slow_mode
+  zparseopts -E -D -a opts -help -slow v+=chmod_opts
+  if [[ $# > 1 || -n "${opts[(r)--help]}" ]]; then
+    cat <<EOF
+Usage: fixperms [-v] [--help] [--slow] [target]
+
+  target  is the file or directory to change permissions on. If omitted,
+          the current directory is taken to be the target.
+
+  -v      enables verbose output (may be supplied multiple times)
+
+  --slow  will use a slower but more robust mode, which is effective if
+          directories themselves have permissions that forbid you from
+          traversing them.
+
+EOF
+    exit_status=$(( $# > 1 ))
+    return $exit_status
+  fi
+
+  if [[ $# == 0 ]]; then
+    target="."
+  else
+    target="$1"
+  fi
+  if [[ -n ${opts[(r)--slow]} ]]; then use_slow=true; else use_slow=false; fi
+
+  # Because this requires confirmation, bail in noninteractive shells
+  if [[ ! -o interactive ]]; then
+    echo "fixperms: cannot run in noninteractive shell"
+    return 1
+  fi
+
+  echo "Fixing perms on $target?"
+  printf '%s' "Proceed? (y|n) "
+  read confirm
+  if [[ "$confirm" != y ]]; then
+    # User aborted
+    return 1
+  fi
+
+  # This xargs form is faster than -exec chmod <N> {} \; but will encounter
+  # issues if the directories themselves have permissions such that you can't
+  # recurse in to them. If that happens, just rerun this a few times.
+  exit_status=0;
+  if [[ $use_slow == true ]]; then
+    # Process directories first so non-traversable ones are fixed as we go
+    find "$target" -type d ! -perm 755 -exec chmod $chmod_opts 755 {} \;
+    if [[ $? != 0 ]]; then exit_status=$?; fi
+    find "$target" -type f ! -perm 644 -exec chmod $chmod_opts 644 {} \;
+    if [[ $? != 0 ]]; then exit_status=$?; fi
+  else
+    find "$target" -type d ! -perm 755 -print0 | xargs -0 chmod $chmod_opts 755
+    if [[ $? != 0 ]]; then exit_status=$?; fi
+    find "$target" -type f ! -perm 644 -print0 | xargs -0 chmod $chmod_opts 644
+    if [[ $? != 0 ]]; then exit_status=$?; fi
+  fi
+  echo "Complete"
+  return $exit_status
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/phing/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/phing/README.md
new file mode 100644 (file)
index 0000000..84d1d18
--- /dev/null
@@ -0,0 +1,9 @@
+# Phing plugin
+
+This plugin adds autocompletion for [`phing`](https://github.com/phingofficial/phing) targets.
+
+To use it, add `phing` to the plugins array of your `.zshrc` file:
+
+```zsh
+plugins=(... phing)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/phing/phing.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/phing/phing.plugin.zsh
new file mode 100644 (file)
index 0000000..d5a2649
--- /dev/null
@@ -0,0 +1,7 @@
+_phing () {
+  if [ -f build.xml ]; then
+    compadd $(phing -l|grep -v "\[property\]"|grep -v "Buildfile"|sed 1d|grep -v ":$" |grep -v "^\-*$"|grep -v "Warning:"|awk '{print $1}')
+  fi
+}
+
+compdef _phing phing
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pip/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pip/README.md
new file mode 100644 (file)
index 0000000..88d8822
--- /dev/null
@@ -0,0 +1,28 @@
+# pip plugin
+
+This plugin adds completion for [pip](https://pip.pypa.io/en/latest/),
+the Python package manager.
+
+To use it, add `pip` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... pip)
+```
+
+## pip cache
+
+The pip plugin caches the names of available pip packages from the PyPI index.
+To trigger the caching process, try to complete `pip install`,
+or you can run `zsh-pip-cache-packages` directly.
+
+To reset the cache, run `zsh-pip-clear-cache` and it will be rebuilt next
+the next time you autocomplete `pip install`.
+
+## Aliases
+
+| Alias    | Description                                   |
+| :------- | :-------------------------------------------- |
+| pipreq   | Create requirements file                      |
+| pipir    | Install packages from `requirements.txt` file |
+| pipupall | Update all installed packages                 |
+| pipunall | Uninstall all installed packages              |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pip/_pip b/stow/oh-my-zsh/.oh-my-zsh/plugins/pip/_pip
new file mode 100644 (file)
index 0000000..e03be6a
--- /dev/null
@@ -0,0 +1,100 @@
+#compdef pip pip2 pip-2.7 pip3 pip-3.2 pip-3.3 pip-3.4
+#autoload
+
+# pip zsh completion, based on last stable release (pip8)
+# homebrew completion and backwards compatibility
+
+_pip_all() {
+  # we cache the list of packages (originally from the macports plugin)
+  if (( ! $+piplist )); then
+      zsh-pip-cache-packages
+      piplist=($(cat $ZSH_PIP_CACHE_FILE))
+  fi
+}
+
+_pip_installed() {
+  installed_pkgs=($($service freeze | cut -d '=' -f 1))
+}
+
+local -a _1st_arguments
+_1st_arguments=(
+  'install:install packages'
+  'download:download packages'
+  'uninstall:uninstall packages'
+  'freeze:output all currently installed packages (exact versions) to stdout'
+  'list:list installed packages'
+  'show:show information about installed packages'
+  'search:search PyPI'
+  'wheel:build individual wheel archives for your requirements and dependencies'
+  'hash:compute a hash of a local package archive'
+  'help:show available commands'
+  'bundle:create pybundles (archives containing multiple packages)(deprecated)'
+  'unzip:unzip individual packages(deprecated)'
+  'zip:zip individual packages(deprecated)'
+)
+
+local expl
+local -a all_pkgs installed_pkgs
+
+_arguments \
+  '(-h --help)'{-h,--help}'[show help]' \
+  '(--isolated)--isolated[run pip in isolated mode, ignores environment variables and user configuration]' \
+  '(-v --verbose)'{-v,--verbose}'[give more output]' \
+  '(-V --version)'{-V,--version}'[show version number of program and exit]' \
+  '(-q --quiet)'{-q,--quiet}'[give less output]' \
+  '(--log)--log[log file location]' \
+  '(--proxy)--proxy[proxy in form user:passwd@proxy.server:port]' \
+  '(--retries)--retries[max number of retries per connection (default 5 times)]' \
+  '(--timeout)--timeout[socket timeout (default 15s)]' \
+  '(--exists-action)--exists-action[default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup]' \
+  '(--trusted-host)--trusted-host[mark this host as trusted]' \
+  '(--cert)--cert[path to alternate CA bundle]' \
+  '(--client-cert)--client-cert[path to SSL client certificate]' \
+  '(--cache-dir)--cache-dir[store the cache data in specified directory]' \
+  '(--no-cache-dir)--no-cache-dir[disable de cache]' \
+  '(--disable-pip-version-check)--disable-pip-version-check[do not check periodically for new pip version downloads]' \
+  '(-E --environment)'{-E,--environment}'[virtualenv environment to run pip in (deprecated)]' \
+  '(-s --enable-site-packages)'{-s,--enable-site-packages}'[include site-packages in virtualenv (deprecated)]' \
+  '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "pip subcommand" _1st_arguments
+  return
+fi
+
+case "$words[1]" in
+  search)
+    _arguments \
+      '(--index)--index[base URL of Python Package Index]' ;;
+  freeze)
+    _arguments \
+      '(-l --local)'{-l,--local}'[report only virtualenv packages]' ;;
+  install)
+    _arguments \
+      '(-U --upgrade)'{-U,--upgrade}'[upgrade all packages to the newest available version]' \
+      '(--user)--user[install packages to user home]' \
+      '(-f --find-links)'{-f,--find-links}'[URL for finding packages]' \
+      '(-r --requirement)'{-r,--requirement}'[Requirements file for packages to install]:File:_files' \
+      '(--no-deps --no-dependencies)'{--no-deps,--no-dependencies}'[iIgnore package dependencies]' \
+      '(--no-install)--no-install[only download packages]' \
+      '(--no-download)--no-download[only install downloaded packages]' \
+      '(--install-option)--install-option[extra arguments to be supplied to the setup.py]' \
+      '(--single-version-externally-managed)--single-version-externally-managed[do not download/install dependencies. requires --record or --root]'\
+      '(--root)--root[treat this path as a fake chroot, installing into it. implies --single-version-externally-managed]'\
+      '(--record)--record[file to record all installed files to.]'\
+      '(-r --requirement)'{-r,--requirement}'[requirements file]: :_files'\
+      '(-e --editable)'{-e,--editable}'[path of or url to source to link to instead of installing.]: :_files -/'\
+      '1: :->packages' &&  return 0
+
+      if [[ "$state" == packages ]]; then
+        _pip_all
+        _wanted piplist expl 'packages' compadd -a piplist
+        _files -g "*.(tar.gz|whl)"
+      fi ;;
+  uninstall)
+    _pip_installed
+    _wanted installed_pkgs expl 'installed packages' compadd -a installed_pkgs ;;
+  show)
+    _pip_installed
+    _wanted installed_pkgs expl 'installed packages' compadd -a installed_pkgs ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pip/pip.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pip/pip.plugin.zsh
new file mode 100644 (file)
index 0000000..90e39e1
--- /dev/null
@@ -0,0 +1,111 @@
+# Usage:
+# Just add pip to your installed plugins.
+
+# If you would like to change the cheeseshops used for autocomplete set
+# ZSH_PIP_INDEXES in your zshrc. If one of your indexes are bogus you won't get
+# any kind of error message, pip will just not autocomplete from them. Double
+# check!
+#
+# If you would like to clear your cache, go ahead and do a
+# "zsh-pip-clear-cache".
+
+if [[ -d "${XDG_CACHE_HOME:-$HOME/.cache}/pip" ]]; then
+  ZSH_PIP_CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/pip/zsh-cache"
+else
+  ZSH_PIP_CACHE_FILE=~/.pip/zsh-cache
+fi
+ZSH_PIP_INDEXES=(https://pypi.org/simple/)
+
+zsh-pip-clear-cache() {
+  rm $ZSH_PIP_CACHE_FILE
+  unset piplist
+}
+
+zsh-pip-clean-packages() {
+    sed -n '/<a href/ s/.*>\([^<]\{1,\}\).*/\1/p'
+}
+
+zsh-pip-cache-packages() {
+  if [[ ! -d ${ZSH_PIP_CACHE_FILE:h} ]]; then
+      mkdir -p ${ZSH_PIP_CACHE_FILE:h}
+  fi
+
+  if [[ ! -f $ZSH_PIP_CACHE_FILE ]]; then
+      echo -n "(...caching package index...)"
+      tmp_cache=/tmp/zsh_tmp_cache
+      touch $tmp_cache
+      for index in $ZSH_PIP_INDEXES ; do
+          # well... I've already got two problems
+          curl -L $index 2>/dev/null | \
+              zsh-pip-clean-packages \
+               >> $tmp_cache
+      done
+      sort $tmp_cache | uniq | tr '\n' ' ' > $ZSH_PIP_CACHE_FILE
+      rm $tmp_cache
+  fi
+}
+
+# A test function that validates the regex against known forms of the simple
+# index. If you modify the regex to make it work for you, you should add a test
+# case in here and make sure that your changes don't break things for someone
+# else.
+zsh-pip-test-clean-packages() {
+    local expected
+    local actual
+    expected="0x10c-asm
+1009558_nester"
+
+    actual=$(echo -n "<html><head><title>Simple Index</title><meta name=\"api-version\" value=\"2\" /></head><body>
+<a href='0x10c-asm'>0x10c-asm</a><br/>
+<a href='1009558_nester'>1009558_nester</a><br/>
+</body></html>" | zsh-pip-clean-packages)
+
+    if [[ $actual != $expected ]] ; then
+        echo -e "python's simple index is broken:\n$actual\n  !=\n$expected"
+    else
+        echo "python's simple index is fine"
+    fi
+
+    actual=$(echo -n '<html>
+  <head>
+    <title>Simple Package Index</title>
+  </head>
+  <body>
+    <a href="0x10c-asm">0x10c-asm</a><br/>
+    <a href="1009558_nester">1009558_nester</a><br/>
+</body></html>' | zsh-pip-clean-packages)
+
+    if [[ $actual != $expected ]] ; then
+        echo -e "the djangopypi2 index is broken:\n$actual\n  !=\n$expected"
+    else
+        echo "the djangopypi2 index is fine"
+    fi
+}
+
+if (( $+commands[pip3] && !$+commands[pip] )); then
+  alias pip="noglob pip3"
+else
+  alias pip="noglob pip"
+fi
+
+# Create requirements file
+alias pipreq="pip freeze > requirements.txt"
+
+# Install packages from requirements file
+alias pipir="pip install -r requirements.txt"
+
+# Upgrade all installed packages
+function pipupall {
+  # non-GNU xargs does not support nor need `--no-run-if-empty`
+  local xargs="xargs --no-run-if-empty"
+  xargs --version 2>/dev/null | grep -q GNU || xargs="xargs"
+  pip list --outdated | awk 'NR > 2 { print $1 }' | ${=xargs} pip install --upgrade
+}
+
+# Uninstalled all installed packages
+function pipunall {
+  # non-GNU xargs does not support nor need `--no-run-if-empty`
+  local xargs="xargs --no-run-if-empty"
+  xargs --version 2>/dev/null | grep -q GNU || xargs="xargs"
+  pip list --format freeze | cut -d= -f1 | ${=xargs} pip uninstall
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pipenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pipenv/README.md
new file mode 100644 (file)
index 0000000..ab1c1e4
--- /dev/null
@@ -0,0 +1,28 @@
+# Pipenv
+
+## Installation
+In your `.zshrc` file, add `pipenv` to the plugins section
+
+```
+plugins=(... pipenv ...)
+```
+
+## Features
+This plugin provides some features to simplify the use of Pipenv while working on ZSH. 
+- Adds completion for pipenv
+- Auto activates and deactivates pipenv shell
+- Adds short aliases for common pipenv commands
+  - `pch` is aliased to `pipenv check`
+  - `pcl` is aliased to `pipenv clean`
+  - `pgr` is aliased to `pipenv graph`
+  - `pi` is aliased to `pipenv install`
+  - `pidev` is aliased to `pipenv install --dev`
+  - `pl` is aliased to `pipenv lock`
+  - `po` is aliased to `pipenv open`
+  - `prun` is aliased to `pipenv run`
+  - `psh` is aliased to `pipenv shell`
+  - `psy` is aliased to `pipenv sync`
+  - `pu` is aliased to `pipenv uninstall`
+  - `pwh` is aliased to `pipenv --where`
+  - `pvenv` is aliased to `pipenv --venv`
+  - `ppy` is aliased to `pipenv --py`
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pipenv/pipenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pipenv/pipenv.plugin.zsh
new file mode 100644 (file)
index 0000000..4be61a9
--- /dev/null
@@ -0,0 +1,44 @@
+# Pipenv completion
+_pipenv() {
+  eval $(env COMMANDLINE="${words[1,$CURRENT]}" _PIPENV_COMPLETE=complete-zsh pipenv)
+}
+compdef _pipenv pipenv
+
+# Automatic pipenv shell activation/deactivation
+_togglePipenvShell() {
+  # deactivate shell if Pipfile doesn't exist and not in a subdir
+  if [[ ! -f "$PWD/Pipfile" ]]; then
+    if [[ "$PIPENV_ACTIVE" == 1 ]]; then
+      if [[ "$PWD" != "$pipfile_dir"* ]]; then
+        exit
+      fi
+    fi
+  fi
+
+  # activate the shell if Pipfile exists
+  if [[ "$PIPENV_ACTIVE" != 1 ]]; then
+    if [[ -f "$PWD/Pipfile" ]]; then
+      export pipfile_dir="$PWD"
+      pipenv shell
+    fi
+  fi
+}
+autoload -U add-zsh-hook
+add-zsh-hook chpwd _togglePipenvShell
+_togglePipenvShell
+
+# Aliases
+alias pch="pipenv check"
+alias pcl="pipenv clean"
+alias pgr="pipenv graph"
+alias pi="pipenv install"
+alias pidev="pipenv install --dev"
+alias pl="pipenv lock"
+alias po="pipenv open"
+alias prun="pipenv run"
+alias psh="pipenv shell"
+alias psy="pipenv sync"
+alias pu="pipenv uninstall"
+alias pwh="pipenv --where"
+alias pvenv="pipenv --venv"
+alias ppy="pipenv --py"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pj/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pj/README.md
new file mode 100644 (file)
index 0000000..27e5638
--- /dev/null
@@ -0,0 +1,45 @@
+# pj
+
+The `pj` plugin (short for `Project Jump`) allows you to define several
+folders where you store your projects, so that you can jump there directly
+by just using the name of the project directory.
+
+Original idea and code by Jan De Poorter ([@DefV](https://github.com/DefV))
+Source: https://gist.github.com/pjaspers/368394#gistcomment-1016
+
+## Usage
+
+1. Enable the `pj` plugin:
+
+   ```zsh
+   plugins=(... pj)
+   ```
+
+2. Set `$PROJECT_PATHS` in your ~/.zshrc:
+
+   ```zsh
+   PROJECT_PATHS=(~/src ~/work ~/"dir with spaces")
+   ```
+
+You can now use one of the following commands:
+
+##### `pj my-project`:
+
+`cd` to the directory named "my-project" found in one of the `$PROJECT_PATHS`
+directories. If there are several directories named the same, the first one
+to appear in `$PROJECT_PATHS` has preference.
+
+For example:
+```zsh
+PROJECT_PATHS=(~/code ~/work)
+$ ls ~/code    # ~/code/blog ~/code/react
+$ ls ~/work    # ~/work/blog ~/work/project
+$ pj blog      # <-- will cd to ~/code/blog
+```
+
+##### `pjo my-project`
+
+Open the project directory with your defined `$EDITOR`. This follows the same
+directory rules as the `pj` command above.
+
+Note: `pjo` is an alias of `pj open`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pj/pj.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pj/pj.plugin.zsh
new file mode 100644 (file)
index 0000000..431576f
--- /dev/null
@@ -0,0 +1,34 @@
+alias pjo="pj open"
+
+function pj() {
+  local cmd="cd"
+  local project="$1"
+
+  if [[ "open" == "$project" ]]; then
+    shift
+    project=$*
+    cmd=${=EDITOR}
+  else
+    project=$*
+  fi
+
+  for basedir ($PROJECT_PATHS); do
+    if [[ -d "$basedir/$project" ]]; then
+      $cmd "$basedir/$project"
+      return
+    fi
+  done
+
+  echo "No such project '${project}'."
+}
+
+_pj () {
+  local -a projects
+  for basedir ($PROJECT_PATHS); do
+    projects+=(${basedir}/*(/N))
+  done
+
+  compadd ${projects:t}
+}
+
+compdef _pj pj
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/please/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/please/README.md
new file mode 100644 (file)
index 0000000..0a33f89
--- /dev/null
@@ -0,0 +1,26 @@
+# please plugin
+
+[Please](https://please.build) is a cross-language build system with an emphasis on
+high performance, extensibility and reproducibility. It supports a number of popular
+languages and can automate nearly any aspect of your build process.
+
+This plugin adds autocomplete and major aliases for `plz`, the command line tool for
+Please.
+
+To use it, add `please` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... please)
+```
+
+## Aliases
+
+| Alias | Command     |
+|-------|-------------|
+| `pb`  | `plz build` |
+| `pt`  | `plz test`  |
+| `pw`  | `plz watch` |
+
+## Maintainer
+
+[@thought-machine](https://github.com/thought-machine)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/please/please.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/please/please.plugin.zsh
new file mode 100644 (file)
index 0000000..0f58307
--- /dev/null
@@ -0,0 +1,7 @@
+if (( $+commands[plz] )); then
+    source <(plz --completion_script)
+fi
+
+alias pb='plz build'
+alias pt='plz test'
+alias pw='plz watch'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/README.md
new file mode 100644 (file)
index 0000000..5dfd540
--- /dev/null
@@ -0,0 +1,19 @@
+# pm2 plugin
+
+The plugin adds several aliases and completions for common [pm2](http://pm2.keymetrics.io/) commands.
+
+To use it, add `pm2` to the plugins array of your zshrc file:
+```
+plugins=(... pm2)
+```
+
+## Aliases
+
+| Alias  | Command              |
+|--------|----------------------|
+| p2s  | `pm2 start` |
+| p2o  | `pm2 stop` |
+| p2d | `pm2 delete` |
+| p2r   | `pm2 restart` |
+| p2i   | `pm2 list` |
+| p2l   |  `pm2 logs` |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/_pm2 b/stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/_pm2
new file mode 100644 (file)
index 0000000..faa6a34
--- /dev/null
@@ -0,0 +1,168 @@
+#!/bin/zsh -f
+#compdef pm2
+#autoload
+
+local -a _1st_arguments
+
+_1st_arguments=(
+    "start:start and daemonize an app"
+    "trigger:trigger process action"
+    "deploy:deploy your json"
+    "startOrRestart:start or restart JSON file"
+    "startOrReload:start or gracefully reload JSON file"
+    "pid:return pid of [app_name] or all"
+    "stop:stop a process"
+    "restart:restart a process"
+    "scale:scale up/down a process in cluster mode depending on total_number param"
+    "profile\:mem:Sample PM2 heap memory"
+    "profile\:cpu:Profile PM2 cpu"
+    "reload:reload processes (note that its for app using HTTP/HTTPS)"
+    "id:get process id by name"
+    "inspect:inspect a process"
+    "delete:stop and delete a process from pm2 process list"
+    "sendSignal:send a system signal to the target process"
+    "ping:ping pm2 daemon - if not up it will launch it"
+    "updatePM2:update in-memory PM2 with local PM2"
+    "install:install or update a module and run it forever"
+    "module\:update:update a module and run it forever"
+    "module\:generate:Generate a sample module in current folder"
+    "uninstall:stop and uninstall a module"
+    "package:Check & Package TAR type module"
+    "publish:Publish the module you are currently on"
+    "set:sets the specified config <key> <value>"
+    "multiset:multiset eg \"key1 val1 key2 val2\""
+    "get:get value for <key>"
+    "config:get / set module config values"
+    "unset:clears the specified config <key>"
+    "report:give a full pm2 report for https\://github.com/Unitech/pm2/issues"
+    "link:link with the pm2 monitoring dashboard"
+    "unlink:unlink with the pm2 monitoring dashboard"
+    "monitor:monitor target process"
+    "unmonitor:unmonitor target process"
+    "open:open the pm2 monitoring dashboard"
+    "plus:enable pm2 plus"
+    "login:Login to pm2 plus"
+    "logout:Logout from pm2 plus"
+    "web:launch a health API on 0.0.0.0\:9615"
+    "dump:dump all processes for resurrecting them later"
+    "cleardump:Create empty dump file"
+    "send:send stdin to <pm_id>"
+    "attach:attach stdin/stdout to application identified by <pm_id>"
+    "resurrect:resurrect previously dumped processes"
+    "unstartup:disable the pm2 startup hook"
+    "startup:enable the pm2 startup hook"
+    "logrotate:copy default logrotate configuration"
+    "ecosystem:generate a process conf file. (mode = null or simple)"
+    "reset:reset counters for process"
+    "describe:describe all parameters of a process id"
+    "list:list all processes"
+    "jlist:list all processes in JSON format"
+    "prettylist:print json in a prettified JSON"
+    "monit:launch termcaps monitoring"
+    "imonit:launch legacy termcaps monitoring"
+    "dashboard:launch dashboard with monitoring and logs"
+    "flush:flush logs"
+    "reloadLogs:reload all logs"
+    "logs:stream logs file. Default stream all logs"
+    "kill:kill daemon"
+    "pull:updates repository for a given app"
+    "forward:updates repository to the next commit for a given app"
+    "backward:downgrades repository to the previous commit for a given app"
+    "deepUpdate:performs a deep update of PM2"
+    "serve:serve a directory over http via port"
+    "examples:display pm2 usage examples"
+)
+
+local -a id_names
+
+_id_names() {
+    local app_list
+    app_list=`pm2 list -m`
+
+    local -a names ids 
+    names=(`echo $app_list | grep '+---' | awk '{print $2}'`)
+    ids=(`echo $app_list | grep 'pm2 id' | awk '{print $4}'`)
+
+    if (( ${#ids} > 0 )); then
+        for i in {1..${#ids}}; do
+            id_names+=( "${ids[i]}:${names[i]}" )
+        done
+    fi
+}
+
+_arguments \
+    '(-v --version)'{-v,--version}'[output version]' \
+    '(-h --help)'{-h,--help}'[output usage information]' \
+    '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+    _describe "command" _1st_arguments
+    return
+fi
+
+local -a id_comp id_all_comp id_all_files_comp start_options logs_options
+id_comp=('1: :->id_comp')
+id_all_comp=('1: :->id_all_comp')
+id_all_files_comp=('1: :->id_all_files_comp')
+start_options=(
+    '--watch[Watch folder for changes]'
+    '--fresh[Rebuild Dockerfile]'
+    '--daemon[Run container in Daemon mode (debug purposes)]'
+    '--container[Start application in container mode]'
+    '--dist[with --container; change local Dockerfile to containerize all files in current directory]'
+    '--image-name[with --dist; set the exported image name]'
+    '--node-version[with --container, set a specific major Node.js version]'
+    '--dockerdaemon[for debugging purpose]'
+    '(-h --help)'{-h,--help}'[output usage information]'
+    $id_all_files_comp
+)
+logs_options=(
+    '--json[json log output]'
+    '--format[formatted log output]'
+    '--raw[raw output]'
+    '--err[only shows error output]'
+    '--out[only shows standard output]'
+    '--lines[output the last N lines, instead of the last 15 by default]'
+    '--timestamp[add timestamps (default format YYYY-MM-DD-HH:mm:ss)]'
+    '--nostream[print logs without launching the log stream]'
+    '(-h --help)'{-h,--help}'[output usage information]'
+    $id_all_comp
+)
+
+case "$words[1]" in
+    start)
+        _arguments $start_options && return 0
+        ;;
+    logs)
+        _arguments $logs_options && return 0
+        ;;
+    stop|restart|delete|reload|reset)
+        _arguments $id_all_comp && return 0
+        ;;
+    env|inspect|monitor|unmonitor|describe)
+        _arguments $id_comp && return 0
+        ;;
+    deploy|startOrRestart|startOrReload)
+        _files ;;
+esac
+
+case "$state" in
+    id_comp)
+        _id_names
+        _alternative \
+            'args:app args:(($id_names))'
+        ;;
+    id_all_comp)
+        _id_names
+        id_names+=(all)
+        _alternative \
+            'args:app args:(($id_names))'
+        ;;
+    id_all_files_comp)
+        _id_names
+        id_names+=(all)
+        _alternative \
+            'args:app args:(($id_names))' \
+            'files:filename:_files'
+        ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/pm2.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pm2/pm2.plugin.zsh
new file mode 100644 (file)
index 0000000..f05d8db
--- /dev/null
@@ -0,0 +1,6 @@
+alias p2s='pm2 start'
+alias p2o='pm2 stop'
+alias p2d='pm2 delete'
+alias p2r='pm2 restart'
+alias p2i='pm2 list'
+alias p2l='pm2 logs'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pod/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pod/README.md
new file mode 100644 (file)
index 0000000..0a3cc7a
--- /dev/null
@@ -0,0 +1,10 @@
+# pod
+
+This plugin adds completion for [`CocoaPods`](https://cocoapods.org/).
+CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects.
+
+To use it, add `pod` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... pod)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pod/_pod b/stow/oh-my-zsh/.oh-my-zsh/plugins/pod/_pod
new file mode 100644 (file)
index 0000000..80d23da
--- /dev/null
@@ -0,0 +1,682 @@
+#compdef pod
+#autoload
+# setopt XTRACE VERBOSE
+# vim: ft=zsh sw=2 ts=2 et
+
+
+# -----------------------------------------------------------------------------
+#          FILE:  _pod
+#   DESCRIPTION:  Cocoapods (0.33.1) autocomplete plugin for Oh-My-Zsh
+#                 https://cocoapods.org
+#                 Generated with `pod --completion-script
+#        AUTHOR:  Alexandre Joly (alexandre.joly@mekanics.ch)
+#        GITHUB:  https://github.com/mekanics
+#       TWITTER:  @jolyAlexandre
+#       VERSION:  0.0.5
+# -----------------------------------------------------------------------------
+
+local -a _subcommands
+local -a _options
+
+case "$words[2]" in
+  help)
+    case "$words[3]" in
+      *) # pod help
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod help options" _options
+      ;;
+    esac
+  ;;
+  ipc)
+    case "$words[3]" in
+      list)
+        case "$words[4]" in
+          *) # pod ipc list
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod ipc list options" _options
+          ;;
+        esac
+      ;;
+      podfile)
+        case "$words[4]" in
+          *) # pod ipc podfile
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod ipc podfile options" _options
+          ;;
+        esac
+      ;;
+      repl)
+        case "$words[4]" in
+          *) # pod ipc repl
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod ipc repl options" _options
+          ;;
+        esac
+      ;;
+      spec)
+        case "$words[4]" in
+          *) # pod ipc spec
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod ipc spec options" _options
+          ;;
+        esac
+      ;;
+      update-search-index)
+        case "$words[4]" in
+          *) # pod ipc update-search-index
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod ipc update-search-index options" _options
+          ;;
+        esac
+      ;;
+      *) # pod ipc
+        _subcommands=(
+          "list:Lists the specifications known to CocoaPods."
+          "podfile:Converts a Podfile to YAML."
+          "repl:The repl listens to commands on standard input."
+          "spec:Converts a podspec to JSON."
+          "update-search-index:Updates the search index."
+        )
+        _describe -t commands "pod ipc subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod ipc options" _options
+      ;;
+    esac
+  ;;
+  init)
+    case "$words[3]" in
+      *) # pod init
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod init options" _options
+      ;;
+    esac
+  ;;
+  install)
+    case "$words[3]" in
+      *) # pod install
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--no-clean:Leave SCM dirs like \`.git\` and \`.svn\` intact after downloading"
+          "--no-integrate:Skip integration of the Pods libraries in the Xcode project(s)"
+          "--no-repo-update:Skip running \`pod repo update\` before install"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod install options" _options
+      ;;
+    esac
+  ;;
+  lib)
+    case "$words[3]" in
+      create)
+        case "$words[4]" in
+          *) # pod lib create
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod lib create options" _options
+          ;;
+        esac
+      ;;
+      lint)
+        case "$words[4]" in
+          *) # pod lib lint
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--no-clean:Lint leaves the build directory intact for inspection"
+              "--no-subspecs:Lint skips validation of subspecs"
+              "--only-errors:Lint validates even if warnings are present"
+              "--quick:Lint skips checks that would require to download and build the spec"
+              "--silent:Show nothing"
+              "--subspec=NAME:Lint validates only the given subspec"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod lib lint options" _options
+          ;;
+        esac
+      ;;
+      *) # pod lib
+        _subcommands=(
+          "create:Creates a new Pod"
+          "lint:Validates a Pod"
+        )
+        _describe -t commands "pod lib subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod lib options" _options
+      ;;
+    esac
+  ;;
+  list)
+    case "$words[3]" in
+      new)
+        case "$words[4]" in
+          *) # pod list new
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--update:Run \`pod repo update\` before listing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod list new options" _options
+          ;;
+        esac
+      ;;
+      *) # pod list
+        _subcommands=(
+          "new:Lists pods introduced in the master spec-repo since the last check"
+        )
+        _describe -t commands "pod list subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--update:Run \`pod repo update\` before listing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod list options" _options
+      ;;
+    esac
+  ;;
+  outdated)
+    case "$words[3]" in
+      *) # pod outdated
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--no-repo-update:Skip running \`pod repo update\` before install"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod outdated options" _options
+      ;;
+    esac
+  ;;
+  plugins)
+    case "$words[3]" in
+      create)
+        case "$words[4]" in
+          *) # pod plugins create
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod plugins create options" _options
+          ;;
+        esac
+      ;;
+      list)
+        case "$words[4]" in
+          *) # pod plugins list
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod plugins list options" _options
+          ;;
+        esac
+      ;;
+      search)
+        case "$words[4]" in
+          *) # pod plugins search
+            _options=(
+              "--full:Search by name, author, and description"
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod plugins search options" _options
+          ;;
+        esac
+      ;;
+      *) # pod plugins
+        _subcommands=(
+          "create:Creates a new plugin"
+          "list:List all known plugins"
+          "search:Search for known plugins"
+        )
+        _describe -t commands "pod plugins subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod plugins options" _options
+      ;;
+    esac
+  ;;
+  push)
+    case "$words[3]" in
+      *) # pod push
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod push options" _options
+      ;;
+    esac
+  ;;
+  repo)
+    case "$words[3]" in
+      add)
+        case "$words[4]" in
+          *) # pod repo add
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--shallow:Create a shallow clone (fast clone, but no push capabilities)"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod repo add options" _options
+          ;;
+        esac
+      ;;
+      lint)
+        case "$words[4]" in
+          *) # pod repo lint
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--only-errors:Lint presents only the errors"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod repo lint options" _options
+          ;;
+        esac
+      ;;
+      push)
+        case "$words[4]" in
+          *) # pod repo push
+            _options=(
+              "--allow-warnings:Allows pushing even if there are warnings"
+              "--help:Show help banner of specified command"
+              "--local-only:Does not perform the step of pushing REPO to its remote"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod repo push options" _options
+          ;;
+        esac
+      ;;
+      remove)
+        case "$words[4]" in
+          *) # pod repo remove
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod repo remove options" _options
+          ;;
+        esac
+      ;;
+      update)
+        case "$words[4]" in
+          *) # pod repo update
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod repo update options" _options
+          ;;
+        esac
+      ;;
+      *) # pod repo
+        _subcommands=(
+          "add:Add a spec repo."
+          "lint:Validates all specs in a repo."
+          "push:Push new specifications to a spec-repo"
+          "remove:Remove a spec repo"
+          "update:Update a spec repo."
+        )
+        _describe -t commands "pod repo subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod repo options" _options
+      ;;
+    esac
+  ;;
+  search)
+    case "$words[3]" in
+      *) # pod search
+        _options=(
+          "--full:Search by name, summary, and description"
+          "--help:Show help banner of specified command"
+          "--ios:Restricts the search to Pods supported on iOS"
+          "--no-ansi:Show output without ANSI codes"
+          "--osx:Restricts the search to Pods supported on OS X"
+          "--stats:Show additional stats (like GitHub watchers and forks)"
+          "--verbose:Show more debugging information"
+          "--web:Searches on cocoapods.org"
+        )
+        _describe -t options "pod search options" _options
+      ;;
+    esac
+  ;;
+  setup)
+    case "$words[3]" in
+      *) # pod setup
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--no-shallow:Clone full history so push will work"
+          "--push:Use this option to enable push access once granted"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod setup options" _options
+      ;;
+    esac
+  ;;
+  spec)
+    case "$words[3]" in
+      cat)
+        case "$words[4]" in
+          *) # pod spec cat
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--show-all:Pick from all versions of the given podspec"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod spec cat options" _options
+          ;;
+        esac
+      ;;
+      create)
+        case "$words[4]" in
+          *) # pod spec create
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod spec create options" _options
+          ;;
+        esac
+      ;;
+      edit)
+        case "$words[4]" in
+          *) # pod spec edit
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--show-all:Pick which spec to edit from all available versions of the given podspec"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod spec edit options" _options
+          ;;
+        esac
+      ;;
+      lint)
+        case "$words[4]" in
+          *) # pod spec lint
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--no-clean:Lint leaves the build directory intact for inspection"
+              "--no-subspecs:Lint skips validation of subspecs"
+              "--only-errors:Lint validates even if warnings are present"
+              "--quick:Lint skips checks that would require to download and build the spec"
+              "--silent:Show nothing"
+              "--subspec=NAME:Lint validates only the given subspec"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod spec lint options" _options
+          ;;
+        esac
+      ;;
+      which)
+        case "$words[4]" in
+          *) # pod spec which
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--show-all:Print all versions of the given podspec"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod spec which options" _options
+          ;;
+        esac
+      ;;
+      *) # pod spec
+        _subcommands=(
+          "cat:Prints a spec file."
+          "create:Create spec file stub."
+          "edit:Edit a spec file."
+          "lint:Validates a spec file."
+          "which:Prints the path of the given spec."
+        )
+        _describe -t commands "pod spec subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod spec options" _options
+      ;;
+    esac
+  ;;
+  trunk)
+    case "$words[3]" in
+      add-owner)
+        case "$words[4]" in
+          *) # pod trunk add-owner
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod trunk add-owner options" _options
+          ;;
+        esac
+      ;;
+      me)
+        case "$words[4]" in
+          clean-sessions)
+            case "$words[5]" in
+              *) # pod trunk me clean-sessions
+                _options=(
+                  "--all:Removes all your sessions, except for the current one"
+                  "--help:Show help banner of specified command"
+                  "--no-ansi:Show output without ANSI codes"
+                  "--silent:Show nothing"
+                  "--verbose:Show more debugging information"
+                )
+                _describe -t options "pod trunk me clean-sessions options" _options
+              ;;
+            esac
+          ;;
+          *) # pod trunk me
+            _subcommands=(
+              "clean-sessions:Remove sessions"
+            )
+            _describe -t commands "pod trunk me subcommands" _subcommands
+            _options=(
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod trunk me options" _options
+          ;;
+        esac
+      ;;
+      push)
+        case "$words[4]" in
+          *) # pod trunk push
+            _options=(
+              "--allow-warnings:Allows push even if there are lint warnings"
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod trunk push options" _options
+          ;;
+        esac
+      ;;
+      register)
+        case "$words[4]" in
+          *) # pod trunk register
+            _options=(
+              "--description=DESCRIPTION:An arbitrary description to easily identify your session later on."
+              "--help:Show help banner of specified command"
+              "--no-ansi:Show output without ANSI codes"
+              "--silent:Show nothing"
+              "--verbose:Show more debugging information"
+            )
+            _describe -t options "pod trunk register options" _options
+          ;;
+        esac
+      ;;
+      *) # pod trunk
+        _subcommands=(
+          "add-owner:Add an owner to a pod"
+          "me:Display information about your sessions"
+          "push:Publish a podspec"
+          "register:Manage sessions"
+        )
+        _describe -t commands "pod trunk subcommands" _subcommands
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod trunk options" _options
+      ;;
+    esac
+  ;;
+  try)
+    case "$words[3]" in
+      *) # pod try
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod try options" _options
+      ;;
+    esac
+  ;;
+  update)
+    case "$words[3]" in
+      *) # pod update
+        _options=(
+          "--help:Show help banner of specified command"
+          "--no-ansi:Show output without ANSI codes"
+          "--no-clean:Leave SCM dirs like \`.git\` and \`.svn\` intact after downloading"
+          "--no-integrate:Skip integration of the Pods libraries in the Xcode project(s)"
+          "--no-repo-update:Skip running \`pod repo update\` before install"
+          "--silent:Show nothing"
+          "--verbose:Show more debugging information"
+        )
+        _describe -t options "pod update options" _options
+      ;;
+    esac
+  ;;
+  *) # pod
+    _subcommands=(
+      "help:Show help for the given command."
+      "ipc:Inter-process communication"
+      "init:Generate a Podfile for the current directory."
+      "install:Install project dependencies"
+      "lib:Develop pods"
+      "list:List pods"
+      "outdated:Show outdated project dependencies"
+      "plugins:Show available CocoaPods plugins"
+      "push:Temporary alias for the \`pod repo push\` command"
+      "repo:Manage spec-repositories"
+      "search:Searches for pods"
+      "setup:Setup the CocoaPods environment"
+      "spec:Manage pod specs"
+      "trunk:Interact with the CocoaPods API (e.g. publishing new specs)"
+      "try:Try a Pod!"
+      "update:Update outdated project dependencies"
+    )
+    _describe -t commands "pod subcommands" _subcommands
+    _options=(
+      "--completion-script:Print the auto-completion script"
+      "--help:Show help banner of specified command"
+      "--no-ansi:Show output without ANSI codes"
+      "--silent:Show nothing"
+      "--verbose:Show more debugging information"
+      "--version:Show the version of the tool"
+    )
+    _describe -t options "pod options" _options
+  ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/poetry/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/poetry/README.md
new file mode 100644 (file)
index 0000000..51780cb
--- /dev/null
@@ -0,0 +1,9 @@
+# Poetry Plugin
+
+This plugin automatically installs [Poetry](https://python-poetry.org/)'s completions for you, and keeps them up to date as your Poetry version changes.
+
+To use it, add `poetry` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... poetry)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/poetry/poetry.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/poetry/poetry.plugin.zsh
new file mode 100644 (file)
index 0000000..cebcb46
--- /dev/null
@@ -0,0 +1,14 @@
+# Return immediately if poetry is not found
+if (( ! $+commands[poetry] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `poetry`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_poetry" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _poetry
+  _comps[poetry]=_poetry
+fi
+
+poetry completions zsh >| "$ZSH_CACHE_DIR/completions/_poetry" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/postgres/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/postgres/README.md
new file mode 100644 (file)
index 0000000..59445f3
--- /dev/null
@@ -0,0 +1,22 @@
+# Postgres plugin
+
+This plugin adds some aliases for useful Postgres commands.
+
+:warning: this plugin works exclusively with Postgres installed via Homebrew on OSX
+because Postgres paths are hardcoded to `/usr/local/var/postgres`.
+
+To use it, add `postgres` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... postgres)
+```
+
+## Aliases
+
+| Alias       | Command                                                                         | Description                                                 |
+|-------------|---------------------------------------------------------------------------------|-------------------------------------------------------------|
+| startpost   | `pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start` | Start postgres server                                       |
+| stoppost    | `pg_ctl -D /usr/local/var/postgres stop -s -m fast`                             | Stop postgres server                                        |
+| restartpost | `stoppost && sleep 1 && startpost`                                              | Restart (calls stop, then start)                            |
+| reloadpost  | `pg_ctl reload -D /usr/local/var/postgres -s`                                   | Reload postgres configuration (some setting require restart)|
+| statuspost  | `pg_ctl status -D /usr/local/var/postgres -s`                                   | Check startus of postgres server (running, stopped)         |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/postgres/postgres.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/postgres/postgres.plugin.zsh
new file mode 100644 (file)
index 0000000..b6d365d
--- /dev/null
@@ -0,0 +1,13 @@
+# Aliases to control Postgres
+# Paths noted below are for Postgres installed via Homebrew on OSX
+if (( ! $+commands[brew] )); then
+  return
+fi
+
+local PG_BREW_DIR=$(brew --prefix)/var/postgres
+
+alias startpost="pg_ctl -D $PG_BREW_DIR -l $PG_BREW_DIR/server.log start"
+alias stoppost="pg_ctl -D $PG_BREW_DIR stop -s -m fast"
+alias restartpost="stoppost && sleep 1 && startpost"
+alias reloadpost="pg_ctl reload -D $PG_BREW_DIR -s"
+alias statuspost="pg_ctl status -D $PG_BREW_DIR -s"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pow/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pow/README.md
new file mode 100644 (file)
index 0000000..1f8a9d1
--- /dev/null
@@ -0,0 +1,21 @@
+# pow plugin
+
+This plugin adds completion and commands for [pow](http://pow.cx/), a
+zero-configuration Rack server for macOS.
+
+To use it, add pow to the plugins array of your zshrc file:
+
+```sh
+plugins=(... pow)
+```
+
+## Commands
+
+- `kapow` will restart an app.
+
+  ```bash
+  kapow myapp
+  ```
+
+- `kaput` will show the standard output from any pow app.
+- `repow` will restart the pow process.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pow/pow.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pow/pow.plugin.zsh
new file mode 100644 (file)
index 0000000..0b8ccd1
--- /dev/null
@@ -0,0 +1,85 @@
+# Restart a rack app running under pow
+# http://pow.cx/
+#
+# Adds a kapow command that will restart an app
+#
+#   $ kapow myapp
+#
+# Supports command completion.
+#
+# If you are not already using completion you might need to enable it with
+#
+#    autoload -U compinit compinit
+#
+# Changes:
+#
+# Defaults to the current application, and will walk up the tree to find
+# a config.ru file and restart the corresponding app
+#
+# Will Detect if a app does not exist in pow and print a (slightly) helpful
+# error message
+
+rack_root(){
+  setopt chaselinks
+  local orgdir="$PWD"
+  local basedir="$PWD"
+
+  while [[ $basedir != '/' ]]; do
+    test -e "$basedir/config.ru" && break
+    builtin cd ".." 2>/dev/null
+    basedir="$PWD"
+  done
+
+  builtin cd "$orgdir" 2>/dev/null
+  [[ ${basedir} == "/" ]] && return 1
+  echo $basedir
+}
+
+rack_root_detect(){
+  basedir=$(rack_root)
+  echo `basename $basedir | sed -E "s/.(com|net|org)//"`
+}
+
+kapow(){
+  local vhost=$1
+  [ ! -n "$vhost" ] && vhost=$(rack_root_detect)
+  if [ ! -h ~/.pow/$vhost ]
+  then
+    echo "pow: This domain isn’t set up yet. Symlink your application to ${vhost} first."
+    return 1
+  fi
+
+  [ ! -d ~/.pow/${vhost}/tmp ] && mkdir -p ~/.pow/$vhost/tmp
+  touch ~/.pow/$vhost/tmp/restart.txt;
+  [ $? -eq 0 ] &&  echo "pow: restarting $vhost.dev"
+}
+compctl -W ~/.pow -/ kapow
+
+powit(){
+  local basedir="$PWD"
+  local vhost=$1
+  [ ! -n "$vhost" ] && vhost=$(rack_root_detect)
+  if [ ! -h ~/.pow/$vhost ]
+  then
+    echo "pow: Symlinking your app with pow. ${vhost}"
+    [ ! -d ~/.pow/${vhost} ] && ln -s "$basedir" ~/.pow/$vhost
+    return 1
+  fi
+}
+
+powed(){
+  local basedir="$(rack_root)"
+  find ~/.pow/ -type l -lname "*$basedir*" -exec basename {}'.dev' \;
+}
+
+# Restart pow process
+# taken from https://www.matthewratzloff.com
+repow(){
+  lsof | grep 20560 | awk '{print $2}' | xargs kill -9
+  launchctl unload ~/Library/LaunchAgents/cx.pow.powd.plist
+  launchctl load ~/Library/LaunchAgents/cx.pow.powd.plist
+  echo "restarted pow"
+}
+
+# View the standard out (puts) from any pow app
+alias kaput="tail -f ~/Library/Logs/Pow/apps/*"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/powder/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/powder/README.md
new file mode 100644 (file)
index 0000000..a83b1f2
--- /dev/null
@@ -0,0 +1,8 @@
+# Powder
+
+This plugin provides completion for [powder](https://github.com/powder-rb/powder/).
+
+To use it, add powder to the plugins array of your zshrc file:
+```
+plugins=(... powder)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/powder/_powder b/stow/oh-my-zsh/.oh-my-zsh/plugins/powder/_powder
new file mode 100644 (file)
index 0000000..84e260a
--- /dev/null
@@ -0,0 +1,4 @@
+#compdef powder
+#autoload
+
+compadd `powder help | grep powder | cut -d " " -f 4`
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/powify/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/powify/README.md
new file mode 100644 (file)
index 0000000..fd58b86
--- /dev/null
@@ -0,0 +1,10 @@
+# powify plugin
+
+This plugin adds autocompletion for [powify](https://github.com/sethvargo/powify),
+an easy-to-use wrapper for Basecamp's [pow](https://github.com/basecamp/pow).
+
+To use it, add powify to the plugins array of your zshrc file:
+
+```sh
+plugins=(... powify)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/powify/_powify b/stow/oh-my-zsh/.oh-my-zsh/plugins/powify/_powify
new file mode 100644 (file)
index 0000000..57042aa
--- /dev/null
@@ -0,0 +1,55 @@
+#compdef powify
+
+_powify_all_servers() {
+  all_servers=(`ls $HOME/.pow/ 2>/dev/null`)
+}
+
+local -a all_servers
+
+local -a _1st_arguments
+_1st_arguments=(
+  'server:server specific commands'
+  'utils:manage powify'
+  'create:creates a pow app from the current directory (to change the name append name as an argument)'
+  'destroy:destroys the pow app linked to the current directory'
+  'restart:restarts the pow app linked to the current directory'
+  'always_restart:reload the pow app after each request'
+  'always_restart_off:do not reload the pow app after each request'
+  'rename:rename the current pow app to [NAME] or rename [OLD] to [NEW]'
+  'environment:run the this pow app in a different environment (aliased `env`)'
+  'browse:opens and navigates the default browser to this app'
+  'logs:tail the application logs'
+)
+
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "powify command" _1st_arguments
+  return
+fi
+
+case "$words[1]" in
+  server)
+    _values , \
+      'install[install pow server]' \
+      'reinstall[reinstall pow server]' \
+      'update[update pow server]' \
+      'uninstall[uninstall pow server]' \
+      'list[list all pow apps]' \
+      'start[start the pow server]' \
+      'stop[stop the pow server]' \
+      'restart[restart the pow server]' \
+      'host[adds all pow apps to /etc/hosts file]' \
+      'unhost[removes all pow apps from /etc/hosts file]' \
+      'status[print the current server status]' \
+      'config[print the current server configuration]' \
+      'logs[tails the pow server logs]' ;;
+  utils)
+    _values , \
+      'install[install powify.dev server management tool]' \
+      'reinstall[reinstall powify.dev server management tool]' \
+      'uninstall[uninstall powify.dev server management tool]' ;;
+  destroy|restart|always_restart|always_restart_off|rename|browse|logs)
+    _powify_all_servers
+    _wanted all_servers expl 'all pow servers' compadd -a all_servers ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/profiles/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/profiles/README.md
new file mode 100644 (file)
index 0000000..5aa1918
--- /dev/null
@@ -0,0 +1,25 @@
+# profiles plugin
+
+This plugin allows you to create separate configuration files for zsh based
+on your long hostname (including the domain).
+
+To use it, add profiles to the plugins array of your zshrc file:
+
+```sh
+plugins=(... profiles)
+```
+
+It takes your `$HOST` variable and looks for files named according to the
+domain parts in `$ZSH_CUSTOM/profiles/` directory.
+
+For example, for `HOST=host.domain.com`, it will try to load the following files,
+in this order:
+
+```text
+$ZSH_CUSTOM/profiles/com
+$ZSH_CUSTOM/profiles/domain.com
+$ZSH_CUSTOM/profiles/host.domain.com
+```
+
+This means that if there are conflicting settings on those files, the one to take
+precedence will be the last applied, i.e. the one in host.domain.com.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/profiles/profiles.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/profiles/profiles.plugin.zsh
new file mode 100644 (file)
index 0000000..5bc56ce
--- /dev/null
@@ -0,0 +1,12 @@
+# You will probably want to list this plugin as the first in your .zshrc.
+
+# This will look for a custom profile for the local machine and each domain or
+# subdomain it belongs to. (e.g. com, example.com and foo.example.com)
+parts=(${(s:.:)HOST})
+for i in {${#parts}..1}; do
+  profile=${(j:.:)${parts[$i,${#parts}]}}
+  file=$ZSH_CUSTOM/profiles/$profile
+  if [ -f $file ]; then
+    source $file
+  fi
+done
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pyenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pyenv/README.md
new file mode 100644 (file)
index 0000000..b9ee937
--- /dev/null
@@ -0,0 +1,24 @@
+# pyenv
+
+This plugin looks for [pyenv](https://github.com/pyenv/pyenv), a Simple Python version
+management system, and loads it if it's found. It also loads pyenv-virtualenv, a pyenv
+plugin to manage virtualenv, if it's found.
+
+To use it, add `pyenv` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... pyenv)
+```
+
+## Settings
+
+- `ZSH_PYENV_QUIET`: if set to `true`, the plugin will not print any messages if it
+  finds that `pyenv` is not properly configured.
+
+- `ZSH_PYENV_VIRTUALENV`: if set to `false`, the plugin will not load pyenv-virtualenv
+  when it finds it.
+
+## Functions
+
+- `pyenv_prompt_info`: displays the Python version in use by pyenv; or the global Python
+  version, if pyenv wasn't found.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pyenv/pyenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pyenv/pyenv.plugin.zsh
new file mode 100644 (file)
index 0000000..7fbd158
--- /dev/null
@@ -0,0 +1,98 @@
+pyenv_config_warning() {
+  [[ "$ZSH_PYENV_QUIET" != true ]] || return 0
+
+  local reason="$1"
+  local pyenv_root="${PYENV_ROOT/#$HOME/\$HOME}"
+  cat >&2 <<EOF
+Found pyenv, but it is badly configured ($reason). pyenv might not
+work correctly for non-interactive shells (for example, when run from a script).
+${(%):-"%B%F{yellow}"}
+To fix this message, add these lines to the '.profile' and '.zprofile' files
+in your home directory:
+${(%):-"%f"}
+export PYENV_ROOT="$pyenv_root"
+export PATH="\$PYENV_ROOT/bin:\$PATH"
+eval "\$(pyenv init --path)"
+${(%):-"%F{yellow}"}
+You'll need to restart your user session for the changes to take effect.${(%):-%b%f}
+For more information go to https://github.com/pyenv/pyenv/#installation.
+EOF
+}
+
+# This plugin loads pyenv into the current shell and provides prompt info via
+# the 'pyenv_prompt_info' function. Also loads pyenv-virtualenv if available.
+
+# Look for pyenv in $PATH and verify that it's not a part of pyenv-win in WSL
+if ! command -v pyenv &>/dev/null; then
+  FOUND_PYENV=0
+elif [[ "${commands[pyenv]}" = */pyenv-win/* && "$(uname -r)" = *icrosoft* ]]; then
+  FOUND_PYENV=0
+else
+  FOUND_PYENV=1
+fi
+
+# Look for pyenv and try to load it (will only work on interactive shells)
+if [[ $FOUND_PYENV -ne 1 ]]; then
+  pyenvdirs=("$HOME/.pyenv" "/usr/local/pyenv" "/opt/pyenv" "/usr/local/opt/pyenv")
+  for dir in $pyenvdirs; do
+    if [[ -d "$dir/bin" ]]; then
+      FOUND_PYENV=1
+      break
+    fi
+  done
+
+  if [[ $FOUND_PYENV -ne 1 ]]; then
+    if (( $+commands[brew] )) && dir=$(brew --prefix pyenv 2>/dev/null); then
+      if [[ -d "$dir/bin" ]]; then
+        FOUND_PYENV=1
+      fi
+    fi
+  fi
+
+  # If we found pyenv, load it but show a caveat about non-interactive shells
+  if [[ $FOUND_PYENV -eq 1 ]]; then
+    # Configuring in .zshrc only makes pyenv available for interactive shells
+    export PYENV_ROOT="$dir"
+    export PATH="$PYENV_ROOT/bin:$PATH"
+    eval "$(pyenv init --path)"
+
+    # Show warning due to bad pyenv configuration
+    pyenv_config_warning 'pyenv command not found in $PATH'
+  fi
+fi
+
+if [[ $FOUND_PYENV -eq 1 ]]; then
+  if [[ -z "$PYENV_ROOT" ]]; then
+    # This is only for backwards compatibility with users that previously relied
+    # on this plugin exporting it. pyenv itself does not require it to be exported
+    export PYENV_ROOT="$(pyenv root)"
+  fi
+
+  # Add pyenv shims to $PATH if not already added
+  if [[ -z "${path[(Re)$(pyenv root)/shims]}" ]]; then
+    eval "$(pyenv init --path)"
+    pyenv_config_warning 'missing pyenv shims in $PATH'
+  fi
+
+  # Load pyenv
+  eval "$(pyenv init - --no-rehash zsh)"
+
+  # If pyenv-virtualenv exists, load it
+  if [[ "$(pyenv commands)" =~ "virtualenv-init" && "$ZSH_PYENV_VIRTUALENV" != false ]]; then
+    eval "$(pyenv virtualenv-init - zsh)"
+  fi
+
+  function pyenv_prompt_info() {
+    local version="$(pyenv version-name)"
+    echo "${version:gs/%/%%}"
+  }
+else
+  # Fall back to system python
+  function pyenv_prompt_info() {
+    local version="$(python3 -V 2>&1 | cut -d' ' -f2)"
+    echo "system: ${version:gs/%/%%}"
+  }
+fi
+
+unset FOUND_PYENV pyenvdirs dir
+unfunction pyenv_config_warning
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/README.md
new file mode 100644 (file)
index 0000000..31710d8
--- /dev/null
@@ -0,0 +1,16 @@
+# pylint
+
+This plugin adds aliases and autocompletion for [Pylint](https://www.pylint.org/),
+the Python code style checking tool.
+
+To use it, add `pylint` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... pylint)
+```
+
+## Aliases
+
+| Alias        | Command              | Description                                                                                                              |
+| -------------| -------------------- | -------------------------------------------------------------------------------------------------------------------------|
+| pylint-quick | `pylint --reports=n` | Displays a set of reports each one focusing on a particular aspect of the project, default set `no` for multiple reports |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/_pylint b/stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/_pylint
new file mode 100644 (file)
index 0000000..e466d05
--- /dev/null
@@ -0,0 +1,31 @@
+#compdef pylint
+#
+# this is zsh completion function file.
+# generated by genzshcomp(ver: 0.5.1)
+#
+
+typeset -A opt_args
+local context state line
+
+_arguments -s -S \
+  "--help[show this help message and exit]:" \
+  "-h[show this help message and exit]:" \
+  "--version[show program's version number and exit]:" \
+  "--long-help[more verbose help.]" \
+  "--rcfile[Specify a configuration file.]::<file>:_files" \
+  "--errors-only[In error mode, checkers without error messages are disabled and for others, only the ERROR messages are displayed, and no reports are done by default]" \
+  "-E[In error mode, checkers without error messages are disabled and for others, only the ERROR messages are displayed, and no reports are done by default]" \
+  "--ignore[Add files or directories to the blacklist. They should be base names, not paths. \[current: CVS\]]::<file>[,<file>...]:_files" \
+  "--help-msg[Display a help message for the given message id and exit. The value may be a comma separated list of message ids.]::<msg-id>:_files" \
+  "--generate-rcfile[Generate a sample configuration file according to the current configuration. You can put other options before this one to get them in the generated configuration.]" \
+  "--enable[Enable the message, report, category or checker with the given id(s). You can either give multiple identifier separated by comma (,) or put this option multiple time.]::<msg ids>:_files" \
+  "-e[Enable the message, report, category or checker with the given id(s). You can either give multiple identifier separated by comma (,) or put this option multiple time.]::<msg ids>:_files" \
+  "--disable[Disable the message, report, category or checker with the given id(s). You can either give multiple identifier separated by comma (,) or put this option multiple time (only on the command line, not in the configuration file where it should appear only once).]::<msg ids>:_files" \
+  "-d[Disable the message, report, category or checker with the given id(s). You can either give multiple identifier separated by comma (,) or put this option multiple time (only on the command line, not in the configuration file where it should appear only once).]::<msg ids>:_files" \
+  "--output-format[Set the output format. Available formats are text, parseable, colorized, msvs (visual studio) and html \[current: text\]]::<format>:_files" \
+  "-f[Set the output format. Available formats are text, parseable, colorized, msvs (visual studio) and html \[current: text\]]::<format>:_files" \
+  "--include-ids[Include message's id in output \[current: no\]]::<y_or_n>:_files" \
+  "-i[Include message's id in output \[current: no\]]::<y_or_n>:_files" \
+  "--reports[Tells whether to display a full report or only the messages \[current: yes\]]::<y_or_n>:_files" \
+  "-r[Tells whether to display a full report or only the messages \[current: yes\]]::<y_or_n>:_files" \
+  "*::args:_files"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/pylint.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/pylint/pylint.plugin.zsh
new file mode 100644 (file)
index 0000000..14cea5b
--- /dev/null
@@ -0,0 +1 @@
+alias pylint-quick='pylint --reports=n'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/python/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/python/README.md
new file mode 100644 (file)
index 0000000..97c1a34
--- /dev/null
@@ -0,0 +1,29 @@
+# Python plugin
+
+The plugin adds several aliases for useful [Python](https://www.python.org/) commands.
+
+To use it, add `python` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... python)
+```
+
+## Aliases
+
+| Command          | Description                                                                            |
+| ---------------- | -------------------------------------------------------------------------------------- |
+| `py`             | Runs `python3`                                                                         |
+| `ipython`        | Runs the appropriate `ipython` version according to the activated virtualenv           |
+| `pyfind`         | Finds .py files recursively in the current directory                                   |
+| `pyclean [dirs]` | Deletes byte-code and cache files from a list of directories or the current one        |
+| `pygrep <text>`  | Looks for `text` in `*.py` files in the current directory, recursively                 |
+| `pyuserpaths`    | Add user site-packages folders to `PYTHONPATH`, for Python 2 and 3                     |
+| `pyserver`       | Starts an HTTP server on the current directory (use `--directory` for a different one) |
+
+## Virtual environments
+
+The plugin provides two utilities to manage Python venvs:
+
+- `mkv [name]`: make a new virtual environment called `name` (default: `venv`) in current directory.
+
+- `vrun [name]`: activate virtual environment called `name` (default: `venv`) in current directory.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/python/python.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/python/python.plugin.zsh
new file mode 100644 (file)
index 0000000..2fbb595
--- /dev/null
@@ -0,0 +1,83 @@
+# python command
+alias py='python3'
+
+# Find python file
+alias pyfind='find . -name "*.py"'
+
+# Remove python compiled byte-code and mypy/pytest cache in either the current
+# directory or in a list of specified directories (including sub directories).
+function pyclean() {
+  find "${@:-.}" -type f -name "*.py[co]" -delete
+  find "${@:-.}" -type d -name "__pycache__" -delete
+  find "${@:-.}" -depth -type d -name ".mypy_cache" -exec rm -r "{}" +
+  find "${@:-.}" -depth -type d -name ".pytest_cache" -exec rm -r "{}" +
+}
+
+# Add the user installed site-packages paths to PYTHONPATH, only if the
+#   directory exists. Also preserve the current PYTHONPATH value.
+# Feel free to autorun this when .zshrc loads.
+function pyuserpaths() {
+  setopt localoptions extendedglob
+
+  # Check for a non-standard install directory.
+  local user_base="${PYTHONUSERBASE:-"${HOME}/.local"}"
+
+  local python version site_pkgs
+  for python in python2 python3; do
+    # Check if command exists
+    (( ${+commands[$python]} )) || continue
+
+    # Get minor release version.
+    # The patch version is variable length, truncate it.
+    version=${(M)${"$($python -V 2>&1)":7}#[^.]##.[^.]##}
+
+    # Add version specific path, if:
+    # - it exists in the filesystem
+    # - it isn't in $PYTHONPATH already.
+    site_pkgs="${user_base}/lib/python${version}/site-packages"
+    [[ -d "$site_pkgs" && ! "$PYTHONPATH" =~ (^|:)"$site_pkgs"(:|$) ]] || continue
+    export PYTHONPATH="${site_pkgs}${PYTHONPATH+":${PYTHONPATH}"}"
+  done
+}
+
+# Grep among .py files
+alias pygrep='grep -nr --include="*.py"'
+
+# Run proper IPython regarding current virtualenv (if any)
+alias ipython="python3 -c 'import IPython; IPython.terminal.ipapp.launch_new_instance()'"
+
+# Share local directory as a HTTP server
+alias pyserver="python3 -m http.server"
+
+
+## venv utilities
+
+# Activate a the python virtual environment specified.
+# If none specified, use 'venv'.
+function vrun() {
+  local name="${1:-venv}"
+  local venvpath="${name:P}"
+
+  if [[ ! -d "$venvpath" ]]; then
+    echo >&2 "Error: no such venv in current directory: $name"
+    return 1
+  fi
+
+  if [[ ! -f "${venvpath}/bin/activate" ]]; then
+    echo >&2 "Error: '${name}' is not a proper virtual environment"
+    return 1
+  fi
+
+  . "${venvpath}/bin/activate" || return $?
+  echo "Activated virtual environment ${name}"
+}
+
+# Create a new virtual environment, with default name 'venv'.
+function mkv() {
+  local name="${1:-venv}"
+  local venvpath="${name:P}"
+
+  python3 -m venv "${name}" || return
+  echo >&2 "Created venv in '${venvpath}'"
+  vrun "${name}"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rails/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rails/README.md
new file mode 100644 (file)
index 0000000..fa66750
--- /dev/null
@@ -0,0 +1,118 @@
+# Rails
+
+This plugin adds completion for [Ruby On Rails Framework](https://rubyonrails.org/) and
+[Rake](https://ruby.github.io/rake/) commands, as well as some aliases for logs and environment variables.
+
+To use it, add `rails` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rails)
+```
+
+## List of Aliases
+
+### Rails aliases
+
+| Alias   | Command                          | Description                                            |
+| ------- | -------------------------------- | ------------------------------------------------------ |
+| `rc`    | `rails console`                  | Interact with your Rails app from the CLI              |
+| `rcs`   | `rails console --sandbox`        | Test code in a sandbox, without changing any data      |
+| `rd`    | `rails destroy`                  | Undo a generate operation                              |
+| `rdb`   | `rails dbconsole`                | Interact with your db from the console                 |
+| `rdc`   | `rails db:create`                | Create the database                                    |
+| `rdd`   | `rails db:drop`                  | Delete the database                                    |
+| `rdm`   | `rails db:migrate`               | Run pending db migrations                              |
+| `rdmd`  | `rails db:migrate:down`          | Undo specific db migration                             |
+| `rdmr`  | `rails db:migrate:redo`          | Redo specific db migration                             |
+| `rdms`  | `rails db:migrate:status`        | Show current db migration status                       |
+| `rdmtc` | `rails db:migrate db:test:clone` | Run pending migrations and clone db into test database |
+| `rdmu`  | `rails db:migrate:up`            | Run specific db migration                              |
+| `rdr`   | `rails db:rollback`              | Roll back the last migration                           |
+| `rdrs`  | `rails db:reset`                 | Delete the database and set it up again                |
+| `rds`   | `rails db:seed`                  | Seed the database                                      |
+| `rdsl`  | `rails db:schema:load`           | Load the database schema                               |
+| `rdtc`  | `rails db:test:clone`            | Clone the database into the test database              |
+| `rdtp`  | `rails db:test:prepare`          | Duplicate the db schema into your test database        |
+| `rgen`  | `rails generate`                 | Generate boilerplate code                              |
+| `rgm`   | `rails generate migration`       | Generate a db migration                                |
+| `rlc`   | `rails log:clear`                | Clear Rails logs                                       |
+| `rmd`   | `rails middleware`               | Interact with Rails middlewares                        |
+| `rn`    | `rails notes`                    | Search for notes (`FIXME`, `TODO`) in code comments    |
+| `rp`    | `rails plugin`                   | Run a Rails plugin command                             |
+| `rr`    | `rails routes`                   | List all defined routes                                |
+| `rrg`   | `rails routes \| grep`           | List and filter the defined routes                     |
+| `rs`    | `rails server`                   | Launch a web server                                    |
+| `rsb`   | `rails server --bind`            | Launch a web server binding it to a specific IP        |
+| `rsd`   | `rails server --debugger`        | Launch a web server with debugger                      |
+| `rsp`   | `rails server --port`            | Launch a web server and specify the listening port     |
+| `rsts`  | `rails stats`                    | Print code statistics                                  |
+| `rt`    | `rails test`                     | Run Rails tests                                        |
+| `ru`    | `rails runner`                   | Run Ruby code in the context of Rails                  |
+
+### Foreman
+
+| Alias  | Command         | Description                               |
+| ------ | --------------- | ----------------------------------------- |
+| `fmns` | `foreman start` | Interact with your Rails app from the CLI |
+
+### Utility aliases
+
+| Alias     | Command                       | Description                                    |
+| --------- | ----------------------------- | ---------------------------------------------- |
+| `devlog`  | `tail -f log/development.log` | Show and follow changes to the development log |
+| `prodlog` | `tail -f log/production.log`  | Show and follow changes to the production log  |
+| `testlog` | `tail -f log/test.log`        | Show and follow changes to the test log        |
+
+### Environment settings
+
+| Alias | Command                 | Description                     |
+| ----- | ----------------------- | ------------------------------- |
+| `RED` | `RAILS_ENV=development` | Sets `RAILS_ENV` to development |
+| `REP` | `RAILS_ENV=production`  | Sets `RAILS_ENV` to production  |
+| `RET` | `RAILS_ENV=test`        | Sets `RAILS_ENV` to test        |
+
+These are global aliases. Use in combination with a command or just run them
+separately. For example: `REP rake db:migrate` will migrate the production db.
+
+## Legacy
+
+### Rake aliases
+
+The following commands are run [using `rails` instead of `rake` since Rails v5][1], but are preserved under the
+prefix `rk` for backwards compatibility.
+
+[1]: https://guides.rubyonrails.org/v5.2/command_line.html#bin-rails
+
+| Alias    | Command                         | Description                                            |
+| -------- | ------------------------------- | ------------------------------------------------------ |
+| `rkdc`   | `rake db:create`                | Create the database                                    |
+| `rkdd`   | `rake db:drop`                  | Delete the database                                    |
+| `rkdm`   | `rake db:migrate`               | Run pending db migrations                              |
+| `rkdms`  | `rake db:migrate:status`        | Show current db migration status                       |
+| `rkdmtc` | `rake db:migrate db:test:clone` | Run pending migrations and clone db into test database |
+| `rkdr`   | `rake db:rollback`              | Roll back the last migration                           |
+| `rkdrs`  | `rake db:reset`                 | Delete the database and set it up again                |
+| `rkds`   | `rake db:seed`                  | Seed the database                                      |
+| `rkdsl`  | `rake db:schema:load`           | Load the database schema                               |
+| `rkdtc`  | `rake db:test:clone`            | Clone the database into the test database              |
+| `rkdtp`  | `rake db:test:prepare`          | Duplicate the db schema into your test database        |
+| `rklc`   | `rake log:clear`                | Clear Rails logs                                       |
+| `rkmd`   | `rake middleware`               | Interact with Rails middlewares                        |
+| `rkn`    | `rake notes`                    | Search for notes (`FIXME`, `TODO`) in code comments    |
+| `rksts`  | `rake stats`                    | Print code statistics                                  |
+| `rkt`    | `rake test`                     | Run Rails tests                                        |
+
+### Other
+
+| Alias   | Command                            |
+| ------- | ---------------------------------- |
+| `sc`    | `ruby script/console`              |
+| `sd`    | `ruby script/destroy`              |
+| `sd`    | `ruby script/server --debugger`    |
+| `sg`    | `ruby script/generate`             |
+| `sp`    | `ruby script/plugin`               |
+| `sr`    | `ruby script/runner`               |
+| `ssp`   | `ruby script/spec`                 |
+| `sstat` | `thin --stats "/thin/stats" start` |
+
+- `remote_console <server> <directory>`: runs `ruby script/console production` on a remote server.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rails/_rails b/stow/oh-my-zsh/.oh-my-zsh/plugins/rails/_rails
new file mode 100644 (file)
index 0000000..6dc85d4
--- /dev/null
@@ -0,0 +1,624 @@
+#compdef rails
+# ------------------------------------------------------------------------------
+# Copyright (c) 2016 Github zsh-users - http://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for Ruby on Rails (http://rubyonrails.org/).
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Kazuya Takeshima (https://github.com/mitukiii)
+#
+# ------------------------------------------------------------------------------
+
+
+_rails() {
+  local context state line curcontext="$curcontext"
+
+  if (( CURRENT > 2 )); then
+    (( CURRENT-- ))
+    shift words
+    _call_function - "_rails_${words[1]}" || _nothing
+  else
+    __rails_commands
+  fi
+}
+
+__rails_commands() {
+  local context state line curcontext="$curcontext"
+
+  local -a rails_options
+  __rails_setup_rails_options
+
+  _arguments -C \
+    $rails_options \
+    ': :->command'
+
+  case "$state" in
+    command)
+      local -a commands
+      local application_directory
+      __rails_setup_application_directory
+
+      if [ -n "$application_directory" ]; then
+        commands=(
+          {generate,g}'[Generate new code]'
+          {console,c}'[Start the Rails console]'
+          {server,s}'[Start the Rails server]'
+          {dbconsole,db}'[Start a console for the database specified in config/database.yml]'
+          application'[Generate the Rails application code]'
+          {destroy,d}'[Undo code generated with "generate"]'
+          benchmarker'[See how fast a piece of code runs]'
+          profiler'[Get profile information from a piece of code]'
+          plugin'[Install a plugin]'
+          {runner,r}'[Run a piece of code in the application environment]'
+          {test,t}'[Run tests]'
+        )
+      else
+        commands=(
+          new'[Create a new Rails application]'
+        )
+      fi
+
+      _values 'command' $commands
+      ;;
+  esac
+}
+
+__rails_setup_application_directory() {
+  application_directory="$(pwd)"
+
+  while [ -n "$application_directory" ]; do
+    if [ -f "${application_directory}/script/rails" -o -f "${application_directory}/bin/rails" ]; then
+      return
+    fi
+    application_directory="${application_directory%/*}"
+  done
+
+  application_directory=
+}
+
+__rails_setup_rails_options() {
+  rails_options=(
+    {-h,--help}'[Show this help message and quit]'
+    {-v,--version}'[Show Rails version number and quit]'
+  )
+}
+
+__rails_setup_runtime_options() {
+  runtime_options=(
+    '(-f --force)'{-f,--force}'[Overwrite files that already exist]'
+    '(-p --pretend)'{-p,--pretend}'[Run but do not make any changes]'
+    '(-q --quiet)'{-q,--quiet}'[Suppress status output]'
+    '(-s --skip)'{-s,--skip}'[Skip files that already exist]'
+  )
+}
+
+__rails_setup_generators_options() {
+  local -a runtime_options
+  __rails_setup_runtime_options
+
+  generators_options=(
+    $runtime_options
+    --skip-namespace'[Skip namespace (affects only isolated applications)]'
+    --old-style-hash"[Force using old style hash (:foo => 'bar') on Ruby >= 1.9]"
+  )
+}
+
+__rails_setup_model_generators_options() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  model_generators_options=(
+    $generators_options
+    '(-o --orm)'{-o,--orm=}'[Orm to be invoked]:orm'
+  )
+}
+
+__rails_setup_resource_generators_options() {
+  local -a model_generators_options
+  __rails_setup_model_generators_options
+
+  resource_generators_options=(
+    $model_generators_options
+    --force-plural'[Forces the use of a plural ModelName]'
+    --resource-route'[Indicates when to generate resource route]: :__rails_boolean'
+  )
+}
+
+__rails_boolean() {
+  _values 'boolean' 'true' 'false'
+}
+
+__rails_migration_fields() {
+  if compset -P '*:*:'; then
+    _values 'index' 'index' 'uniq'
+  else
+    if compset -P '*:'; then
+      _values -s ':' 'type' 'string' 'text' 'integer' 'float' 'decimal' 'datetime' 'timestamp' 'time' 'date' 'binary' 'boolean' 'references'
+    else
+      _guard '[[:alnum:]_]#' 'field'
+    fi
+  fi
+}
+
+_rails_generate() {
+  local context state line curcontext="$curcontext"
+
+  if (( CURRENT > 2 )); then
+    (( CURRENT-- ))
+    shift words
+    _call_function - "_rails_generate_${words[1]}" || _rails_generate_default
+  else
+    __rails_generate_commands
+  fi
+}
+
+_rails_g() {
+  _rails_generate
+}
+
+__rails_generate_commands() {
+  local context curcontext="$curcontext" update_policy
+
+  zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+  if [ -z "$update_policy" ]; then
+    zstyle ":completion:${curcontext}:" cache-policy _rails_generate_commands_caching_policy
+  fi
+
+  local application_directory
+  __rails_setup_application_directory
+  local cache_name
+  cache_name="rails/${application_directory##*/}/all_generators"
+  if ! _retrieve_cache ${cache_name}; then
+    local -a all_generators
+    all_generators=($(_call_program rails_generators rails generate 2> /dev/null | awk '/^  [a-zA-Z_]+/{ print $1 }'))
+    _store_cache ${cache_name} all_generators
+  fi
+
+  local -a rails_generators
+  rails_generators=(${all_generators:#*:*})
+  _describe -t rails_generators 'rails generator' rails_generators
+
+  local -a -U namespaces
+  local namespace
+  local -a generators
+  namespaces=(${(R)${(M)all_generators:#*:*}%:*})
+  for namespace in $namespaces; do
+    generators=(${${(M)all_generators:#${namespace}:*}/:/\\:})
+    _describe -t ${namespace}_generators "${namespace/_/ } generator" generators
+  done
+}
+
+_rails_generate_commands_caching_policy() {
+  local application_directory
+  __rails_setup_application_directory
+
+  if [ "${application_directory}/Gemfile" -nt "$1" ]; then
+    return 0
+  fi
+
+  local -a oldp
+  oldp=( "$1"(Nmw+1) )
+  (( $#oldp ))
+}
+
+_rails_generate_default() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    '*:argument'
+}
+
+_rails_generate_assets() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    '(-j --javascripts)'{-j,--javascripts}'[Generate JavaScripts]: :__rails_boolean' \
+    '(-y --stylesheets)'{-y,--stylesheets}'[Generate Stylesheets]: :__rails_boolean' \
+    '(-je --javascript-engine)'{-je,--javascript-engine=}'[Engine for JavaScripts]:javascript engine' \
+    '(-se --stylesheet-engine)'{-se,--stylesheet-engine=}'[Engine for Stylesheets]:stylesheet engine' \
+    ': :_guard "^-*" "name"'
+}
+
+_rails_generate_controller() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    '(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:template engine' \
+    '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \
+    --helper'[Indicates when to generate helper]: :__rails_boolean' \
+    --assets'[Indicates when to generate assets]: :__rails_boolean' \
+    ': :_guard "^-*" "name"' \
+    '*: :_guard "^-*" "action"'
+}
+
+_rails_generate_generator() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    --namespace'[Namespace generator under lib/generators/name]: :__rails_boolean' \
+    ': :_guard "^-*" "name"'
+}
+
+_rails_generate_helper() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \
+    ': :_guard "^-*" "name"' \
+}
+
+_rails_generate_integration_test() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    --integration-tool='[Integration tool to be invoke]:integration tool' \
+    ': :_guard "^-*" "name"' \
+}
+
+_rails_generate_jbuilder() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    ': :_guard "^-*" "name"' \
+    '*: :__rails_migration_fields'
+}
+
+_rails_generate_mailer() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    '(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:template engine' \
+    '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \
+    ': :_guard "^-*" "name"' \
+    '*: :_guard "^-*" "method"'
+}
+
+_rails_generate_migration() {
+  local -a modelgenerators_options
+  __rails_setup_model_generators_options
+
+  _arguments \
+    $model_generators_options \
+    ': :_guard "^-*" "name"' \
+    '*: :__rails_migration_fields'
+}
+
+_rails_generate_model() {
+  _rails_generate_migration
+}
+
+_rails_generate_observer() {
+  local -a model_generators_options
+  __rails_setup_model_generators_options
+
+  _arguments \
+    $model_generators_options \
+    ': :_guard "^-*" "name"'
+}
+
+_rails_generate_performance_test() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    --performance-tool='[Performance tool to be invoked]:performance tool' \
+    ': :_guard "^-*" "name"' \
+}
+
+_rails_generate_resource() {
+  local context state line curcontext="$curcontext"
+
+  local -a resource_generators_options
+  __rails_setup_resource_generators_options
+
+  _arguments -C \
+    $resource_generators_options \
+    '(-c --resource-controller)'{-c,--resource-controller=}'[Resource controller to be invoked]:name' \
+    '(-a --actions)'{-a,--actions=}'[Actions for the resource controller]: :->actions' \
+    ': :->name' \
+    '*: :->fields'
+
+  if (( words[(I)(--actions=*|-a)] > 0 && words[(I)(--actions=*|-a)] == words[(I)-*] )); then
+    state=actions
+  fi
+
+  case "$state" in
+    actions)
+      _guard "[[:alnum:]_]#" "actions"
+      ;;
+    name)
+      _guard "^-*" "name"
+      ;;
+    fields)
+      __rails_migration_fields
+      ;;
+  esac
+}
+
+_rails_generate_scaffold() {
+  local -a resource_generators_options
+  __rails_setup_resource_generators_options
+
+  _arguments \
+    $resource_generators_options \
+    '(-y --stylesheets)'{-y,--stylesheets}'[Generate Stylesheets]: :__rails_boolean' \
+    '(-se --stylesheet-engine)'{-se,--stylesheet-engine=}'[Engine for Stylesheets]:stylesheet engine' \
+    '(-c --scaffold-controller)'{-c,--scaffold-controller=}'[Scaffold controller to be invoked]:name' \
+    --assets'[Indicates when to generate assets]:boolean:(true false)' \
+    ': :_guard "^-*" "name"' \
+    '*: :__rails_migration_fields'
+}
+
+_rails_generate_scaffold_controller() {
+  local -a model_generators_options
+  __rails_setup_model_generators_options
+
+  _arguments \
+    $model_generators_options \
+    '(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:template engine' \
+    '(-t --test-framework)'{-t,--test-framework=}'[Test framework to be invoked]:test framework' \
+      --helper'[Indicates when to generate helper]: :__rails_boolean' \
+    ': :_guard "^-*" "name"'
+}
+
+_rails_generate_session_migration() {
+  local -a model_generators_options
+  __rails_setup_model_generators_options
+
+  _arguments \
+    $model_generators_options \
+    ': :_guard "^-*" "name"'
+}
+
+_rails_generate_task() {
+  local -a generators_options
+  __rails_setup_generators_options
+
+  _arguments \
+    $generators_options \
+    ': :_guard "^-*" "name"' \
+    '*: :_guard "^-*" "action"'
+}
+
+_rails_console() {
+  _arguments \
+    '(- *)'{-h,--help}'[Show this help message]' \
+    '(-s --sandbox)'{-s,--sandbox}'[Rollback database modifications on exit]' \
+    --debugger'[Enable ruby-debugging for the console]'
+}
+
+_rails_c() {
+  _rails_console
+}
+
+_rails_server() {
+  _arguments \
+    '(- *)'{-h,--help}'[Show this help message]' \
+    '(-p --port)'{-p,--port=}'[Runs Rails on the specified port]: :_guard "[[\:digit\:]]#" "port"' \
+    '(-b --binding)'{-b,--binding=}'[Binds Rails to the specified ip]:ip:_hosts' \
+    '(-c --config)'{-c,--config=}'[Use custom rackup configuration file]:file:_files -g "*.ru"' \
+    '(-d --daemon)'{-d,--daemon}'[Make server run as a Daemon]' \
+    '(-u --debugger)'{-u,--debugger}'[Enable ruby-debugging for the server]' \
+    '(-e --environment)'{-e,--environment=}'[Specifies the environment to run this server under (test/development/production)]:name:(test development production)' \
+    '(-P --pid)'{-P,--pid=}'[Specifies the PID file]:pid:_files -g "*.pid"'
+}
+
+_rails_s() {
+  _rails_server
+}
+
+_rails_dbconsole() {
+  _arguments \
+    '(- *)'--help'[Show this help message]' \
+    '(-p --include-password)'{-p,--include-password}'[Automatically provide the password from database.yml]' \
+    --mode'[Automatically put the sqlite3 database in the specified mode (html, list, line, column)]:mode:(html list line column)' \
+    --header
+}
+
+_rails_new() {
+  local context state line curcontext="$curcontext"
+
+  local _a rails_options runtime_options
+  __rails_setup_rails_options
+  __rails_setup_runtime_options
+
+  _arguments -C \
+    $rails_options \
+    $runtime_options \
+    '(-r --ruby)'{-r,--ruby=}'[Path to the Ruby binary of your choice]:path' \
+    '(-b --builder)'{-b,--builder=}'[Path to a application builder (can be a filesystem path or URL)]: :->path_or_url' \
+    '(-m --template)'{-m,--template=}'[Path to an application template (can be a filesystem path or URL)]: :->path_or_url' \
+    --skip-gemfile"[Don't create a Gemfile]" \
+    --skip-bundle"[Don't run bundle install]" \
+    '(-G --skip-git)'{-G,--skip-git}'[Skip Git ignores and keeps]' \
+    '(-O --skip-active-record)'{-O,--skip-active-record}'[Skip Active Record files]' \
+    '(-S --skip-sprockets)'{-S,--skip-sprockets}'[Skip Sprockets files]' \
+    '(-d --database)'{-d,--database=}'[Preconfigure for selected database]:database:(mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc)' \
+    '(-j --javascript)'{-j,--javascript=}'[Preconfigure for selected JavaScript library]:javascript' \
+    '(-J --skip-javascript)'{-J,--skip-javascript}'[Skip JavaScript files]' \
+    --dev'[Setup the application with Gemfile pointing to your Rails checkout]' \
+    --edge'[Setup the application with Gemfile pointing to Rails repository]' \
+    '(-T --skip-test-unit)'{-T,--skip-test-unit}'[Skip Test::Unit files]' \
+    --old-style-hash"[Force using old style hash (:foo => 'bar') on Ruby >= 1.9]" \
+    ':app path:_directories'
+
+  case "$state" in
+    path_or_url)
+      _alternative \
+        'files:path:_files -g "*.rb"' \
+        'url:url:_urls'
+      ;;
+  esac
+}
+
+_rails_application() {
+  _rails_new
+}
+
+_rails_db() {
+  _rails_dbconsole
+}
+
+_rails_destroy() {
+  _rails_generate
+}
+
+_rails_d() {
+  _rails_destroy
+}
+
+_rails_benchmarker() {
+  _arguments \
+    '(- *)'{-h,--help}'[Show this help message]' \
+    '(-r --runs)'{-r,--runs}'[Number of runs]: :_guard "[[\:digit\:]]#" "number"' \
+    '(-o --output)'{-o,--output}'[Directory to use when writing the results]:directory:_directories' \
+    '(-m --metrics)'{-m,--metrics}'[Metrics to use]: :_values -s "," "metrics" "wall_time" "memory" "objects" "gc_runs" "gc_time"' \
+    '*: :_guard "^-*" "ruby code"'
+}
+
+_rails_profiler() {
+  _arguments \
+    '(- *)'{-h,--help}'[Show this help message]' \
+    '(-r --runs)'{-r,--runs}'[Number of runs]: :_guard "[[\:digit\:]]#" "number"' \
+    '(-o --output)'{-o,--output}'[Directory to use when writing the results]:directory:_directories' \
+    '(-m --metrics)'{-m,--metrics}'[Metrics to use]: :_values -s "," "metrics" "process_time" "memory" "objects"' \
+    '(-f --formats)'{-f,--formats}'[Formats to output to]: :_values -s "," "formats" "flat" "graph" "html" "call_tree" "call_stack"' \
+    '*: :_guard "^-*" "ruby code"'
+}
+
+_rails_plugin() {
+  local context state line curcontext="$curcontext"
+
+  if (( CURRENT > 2 )); then
+    (( CURRENT-- ))
+    shift words
+    _call_function - "_rails_plugin_${words[1]}" || _nothing
+  else
+    __rails_plugin_commands
+  fi
+}
+
+__rails_plugin_commands() {
+  _values 'plugin command' \
+    install'[Install plugin(s) from known repositories or URLs]' \
+    remove'[Uninstall plugins]' \
+    new
+}
+
+_rails_plugin_install() {
+  _arguments \
+    '(-x --externals)'{-x,--externals}'[Use svn:externals to grab the plugin. Enables plugin updates and plugin versioning]' \
+    '(-o --checkout)'{-o,--checkout}'[Use svn checkout to grab the plugin. Enables updating but does not add a svn:externals entry]' \
+    '(-e --export)'{-e,--export}'[Use svn export to grab the plugin. Exports the plugin, allowing you to check it into your local repository. Does not enable updates or add an svn:externals entry]' \
+    '(-q --quiet)'{-q,--quiet}'[Suppresses the output from installation. Ignored if -v is passed (rails plugin -v install ...)]' \
+    '(-r --revision)'{-r,--revision=}'[Checks out the given revision from subversion or git. Ignored if subversion/git is not used]:revision' \
+    '(-f --force)'{-f,--force}"[Reinstalls a plugin if it's already installed]" \
+    '*:plugin:_urls'
+}
+
+_rails_plugin_remove() {
+  local -a plugins
+
+  plugins=($(_call_program rails_plugins ls -1 vendor/plugins))
+
+  _describe -t plugins 'plugin' plugins
+}
+
+_rails_plugin_new() {
+  _rails_new
+}
+
+_rails_runner() {
+  local context state line curcontext="$curcontext"
+
+  _arguments -C \
+    '(- *)'{-h,--help}'[Show this help message]' \
+    '(-e --environment)'{-e,--environment=}'[Specifies the environment for the runner to operate under (test/development/production)]:name:(test development production)' \
+    ': :->code_or_path'
+
+  case "$state" in
+    code_or_path)
+      _alternative \
+        'files:filename:_files -g "*.rb"' \
+        'codes:ruby code:_guard "^-*" "ruby code"'
+      ;;
+  esac
+}
+
+_rails_r() {
+  _rails_runner
+}
+
+_rails_test() {
+  local context state line curcontext="$curcontext"
+
+  _arguments -C \
+    ': :->path'
+
+  case "$state" in
+    path)
+      _alternative \
+        'files:filename:_files -g "*.rb"'
+      ;;
+  esac
+}
+
+_rails_t() {
+  _rails_test
+}
+
+_rails "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rails/rails.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rails/rails.plugin.zsh
new file mode 100644 (file)
index 0000000..b11cbb5
--- /dev/null
@@ -0,0 +1,116 @@
+# rails command wrapper
+function _rails_command () {
+  if [ -e "bin/stubs/rails" ]; then
+    bin/stubs/rails $@
+  elif [ -e "bin/rails" ]; then
+    bin/rails $@
+  elif [ -e "script/rails" ]; then
+    ruby script/rails $@
+  elif [ -e "script/server" ]; then
+    ruby script/$@
+  else
+    command rails $@
+  fi
+}
+
+alias rails='_rails_command'
+compdef _rails_command=rails
+
+# rake command wrapper
+function _rake_command () {
+  if [ -e "bin/stubs/rake" ]; then
+    bin/stubs/rake $@
+  elif [ -e "bin/rake" ]; then
+    bin/rake $@
+  elif type bundle &> /dev/null && [[ -e "Gemfile" || -e "gems.rb" ]]; then
+    bundle exec rake $@
+  else
+    command rake $@
+  fi
+}
+
+alias rake='_rake_command'
+compdef _rake_command=rake
+
+# Log aliases
+alias devlog='tail -f log/development.log'
+alias prodlog='tail -f log/production.log'
+alias testlog='tail -f log/test.log'
+
+# Environment settings
+alias -g RED='RAILS_ENV=development'
+alias -g REP='RAILS_ENV=production'
+alias -g RET='RAILS_ENV=test'
+
+# Rails aliases
+alias rc='rails console'
+alias rcs='rails console --sandbox'
+alias rd='rails destroy'
+alias rdb='rails dbconsole'
+alias rdc='rails db:create'
+alias rdd='rails db:drop'
+alias rdm='rails db:migrate'
+alias rdmd='rails db:migrate:down'
+alias rdmr='rails db:migrate:redo'
+alias rdms='rails db:migrate:status'
+alias rdmtc='rails db:migrate db:test:clone'
+alias rdmu='rails db:migrate:up'
+alias rdr='rails db:rollback'
+alias rdrs='rails db:reset'
+alias rds='rails db:seed'
+alias rdsl='rails db:schema:load'
+alias rdtc='rails db:test:clone'
+alias rdtp='rails db:test:prepare'
+alias rgen='rails generate'
+alias rgm='rails generate migration'
+alias rlc='rails log:clear'
+alias rmd='rails middleware'
+alias rn='rails notes'
+alias rp='rails plugin'
+alias rr='rails routes'
+alias rrg='rails routes | grep'
+alias rs='rails server'
+alias rsb='rails server --bind'
+alias rsd='rails server --debugger'
+alias rsp='rails server --port'
+alias rsts='rails stats'
+alias rt='rails test'
+alias ru='rails runner'
+
+# Foreman aliases
+alias fmns='foreman start'
+
+# Rake aliases
+alias rkdc='rake db:create'
+alias rkdd='rake db:drop'
+alias rkdm='rake db:migrate'
+alias rkdmd='rake db:migrate:down'
+alias rkdmr='rake db:migrate:redo'
+alias rkdms='rake db:migrate:status'
+alias rkdmtc='rake db:migrate db:test:clone'
+alias rkdmu='rake db:migrate:up'
+alias rkdr='rake db:rollback'
+alias rkdrs='rake db:reset'
+alias rkds='rake db:seed'
+alias rkdsl='rake db:schema:load'
+alias rkdtc='rake db:test:clone'
+alias rkdtp='rake db:test:prepare'
+alias rklc='rake log:clear'
+alias rkmd='rake middleware'
+alias rkn='rake notes'
+alias rksts='rake stats'
+alias rkt='rake test'
+
+# legacy stuff
+alias sc='ruby script/console'
+alias sd='ruby script/destroy'
+alias sd='ruby script/server --debugger'
+alias sg='ruby script/generate'
+alias sp='ruby script/plugin'
+alias sr='ruby script/runner'
+alias ssp='ruby script/spec'
+alias sstat='thin --stats "/thin/stats" start'
+
+function remote_console() {
+  /usr/bin/env ssh $1 "( cd $2 && ruby script/console production )"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rake-fast/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rake-fast/README.md
new file mode 100644 (file)
index 0000000..23cbd80
--- /dev/null
@@ -0,0 +1,35 @@
+# rake-fast
+
+Fast rake autocompletion plugin.
+
+This plugin caches the output for later usage and significantly speeds it up.
+It generates a `.rake_tasks` cache file in parallel to the Rakefile. It also
+checks the file modification time to see if it needs to regenerate the cache
+file.
+
+This is entirely based on [this pull request by Ullrich Schäfer](https://github.com/robb/.dotfiles/pull/10/),
+which is inspired by [this Ruby on Rails trick from 2006](https://weblog.rubyonrails.org/2006/3/9/fast-rake-task-completion-for-zsh/).
+
+Think about that. 2006.
+
+----------
+
+Since August of 2016, it also checks if it's in a Rails project and looks at
+rake files inside `lib/tasks` and their modification time to know if the
+cache file needs to be regenerated.
+
+## Installation
+
+Just add the plugin to your `.zshrc`:
+
+```zsh
+plugins=(... rake-fast)
+```
+
+You might consider adding `.rake_tasks` to your [global .gitignore](https://help.github.com/articles/ignoring-files#global-gitignore)
+
+## Usage
+
+Type `rake`, then press tab.
+
+If you want to force the regeneration of the `.rake_tasks` file, run `rake_refresh`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rake-fast/rake-fast.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rake-fast/rake-fast.plugin.zsh
new file mode 100644 (file)
index 0000000..19dab15
--- /dev/null
@@ -0,0 +1,43 @@
+_rake_does_task_list_need_generating () {
+  [[ ! -f .rake_tasks ]] || [[ Rakefile -nt .rake_tasks ]] || { _is_rails_app && _tasks_changed }
+}
+
+_is_rails_app () {
+  [[ -e "bin/rails" ]] || [[ -e "script/rails" ]]
+}
+
+_tasks_changed () {
+  local -a files
+  files=(lib/tasks lib/tasks/**/*(N))
+
+  for file in $files; do
+    if [[ "$file" -nt .rake_tasks ]]; then
+      return 0
+    fi
+  done
+
+  return 1
+}
+
+_rake_generate () {
+  rake --silent --tasks | cut -d " " -f 2 | sed 's/\[.*\]//g' > .rake_tasks
+}
+
+_rake () {
+  if [[ -f Rakefile ]]; then
+    if _rake_does_task_list_need_generating; then
+      echo "\nGenerating .rake_tasks..." >&2
+      _rake_generate
+    fi
+    compadd $(cat .rake_tasks)
+  fi
+}
+compdef _rake rake
+
+rake_refresh () {
+  [[ -f .rake_tasks ]] && rm -f .rake_tasks
+
+  echo "Generating .rake_tasks..." >&2
+  _rake_generate
+  cat .rake_tasks
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rake/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rake/README.md
new file mode 100644 (file)
index 0000000..72f2a85
--- /dev/null
@@ -0,0 +1,41 @@
+# Rake plugin
+
+This plugin adds support for [rake](https://ruby.github.io/rake/), the Ruby
+build tool or Ruby Make.
+
+To use it, add `rake` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rake)
+```
+
+## Aliases
+
+The plugin aliases the rake command so you can pass arguments when invoking rake tasks
+without having to escape the brackets, i.e., you can run
+
+```sh
+rake namespace:task['argument']
+```
+
+instead of having to do
+
+```sh
+rake namespace:task\['argument'\]
+```
+
+| Alias      | Command                        | Description                                   |
+| ---------- | ------------------------------ | --------------------------------------------- |
+| `rake`     | `noglob rake`                  | Allows unescaped square brackets              |
+| `bin/rake` | `noglob bin/rake`              | Same as above but using rake binstub          |
+| `brake`    | `noglob bundle exec rake`      | Same as above but call rake using bundler     |
+| `srake`    | `noglob sudo rake`             | Same as rake but using sudo                   |
+| `sbrake`   | `noglob sudo bundle exec rake` | Same as above but using both sudo and bundler |
+
+## Jim Weirich
+
+The plugin also aliases `rake` to [`jimweirich`](https://github.com/jimweirich), author of Rake
+and big time contributor to the Ruby open source community. He passed away in 2014:
+
+> Thank you Jim for everything you contributed to the Ruby and open source community
+> over the years. We will miss you dearly. — [**@robbyrussell**](https://github.com/ohmyzsh/ohmyzsh/commit/598a9c6f990756386517d66b6bcf77e53791e905)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rake/rake.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rake/rake.plugin.zsh
new file mode 100644 (file)
index 0000000..0c507e6
--- /dev/null
@@ -0,0 +1,9 @@
+# Thank you Jim for everything you contributed to the Ruby and open source community
+# over the years. We will miss you dearly.
+alias jimweirich='rake'
+
+alias rake='noglob rake'                    # allows square brackts for rake task invocation
+alias 'bin/rake'='noglob bin/rake'          # support use of binstub
+alias brake='noglob bundle exec rake'       # execute the bundled rake gem
+alias srake='noglob sudo rake'              # noglob must come before sudo
+alias sbrake='noglob sudo bundle exec rake' # altogether now ...
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rand-quote/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rand-quote/README.md
new file mode 100644 (file)
index 0000000..c387aaa
--- /dev/null
@@ -0,0 +1,15 @@
+# rand-quote plugin
+
+Displays a random quote taken from [quotationspage.com](http://www.quotationspage.com/random.php)
+
+Created by [Eduardo San Martin Morote, aka Posva](https://posva.github.io)
+
+## Usage
+
+Add the plugin to the plugins array in your zshrc file and restart zsh:
+
+```zsh
+plugins=(... rand-quote)
+```
+
+Then, run `quote` to get a new random quote.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rand-quote/rand-quote.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rand-quote/rand-quote.plugin.zsh
new file mode 100644 (file)
index 0000000..23c21dc
--- /dev/null
@@ -0,0 +1,23 @@
+if ! (( $+commands[curl] )); then
+  echo "rand-quote plugin needs curl to work" >&2
+  return
+fi
+
+function quote {
+  setopt localoptions nopromptsubst
+
+  # Get random quote data
+  local data
+  data="$(command curl -s --connect-timeout 2 "http://www.quotationspage.com/random.php" \
+    | iconv -c -f ISO-8859-1 -t UTF-8 \
+    | command grep -a -m 1 'dt class="quote"')"
+
+  # Exit if could not fetch random quote
+  [[ -n "$data" ]] || return 0
+
+  local quote author
+  quote=$(sed -e 's|</dt>.*||g' -e 's|.*html||g' -e 's|^[^a-zA-Z]*||' -e 's|</a..*$||g' <<< "$data")
+  author=$(sed -e 's|.*/quotes/||g' -e 's|<.*||g' -e 's|.*">||g' <<< "$data")
+
+  print -P "%F{3}${author}%f: “%F{5}${quote}%f”"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rbenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rbenv/README.md
new file mode 100644 (file)
index 0000000..43a2e93
--- /dev/null
@@ -0,0 +1,26 @@
+# rbenv plugin
+
+The primary job of this plugin is to provide `rbenv_prompt_info` which can be added to your theme to include Ruby
+version and gemset information into your prompt.
+
+Some functionality of this plugin will not work unless you also have the rbenv plugin *gemset* installed.
+https://github.com/jf/rbenv-gemset
+
+To use it, add `rbenv` to the plugins array in your zshrc file:
+```zsh
+plugins=(... rbenv)
+```
+
+## Alias
+
+| Alias          | Command             | Description                      |
+|----------------|---------------------|----------------------------------|
+| rubies         | `rbenv versions`    | List the installed Ruby versions |
+| gemsets        | `rbenv gemset list` | List the existing gemsets        |
+
+## Functions
+
+* `current_ruby`: The version of Ruby currently being used.
+* `current_gemset`: The name of the current gemset.
+* `gems`: Lists installed gems with enhanced formatting and color.
+* `rbenv_prompt_info`: For adding information to your prompt. Format: `<ruby version>@<current gemset>`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rbenv/rbenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rbenv/rbenv.plugin.zsh
new file mode 100644 (file)
index 0000000..d758aeb
--- /dev/null
@@ -0,0 +1,68 @@
+# This plugin loads rbenv into the current shell and provides prompt info via
+# the 'rbenv_prompt_info' function.
+
+FOUND_RBENV=$+commands[rbenv]
+
+if [[ $FOUND_RBENV -ne 1 ]]; then
+  rbenvdirs=("$HOME/.rbenv" "/usr/local/rbenv" "/opt/rbenv" "/usr/local/opt/rbenv")
+  for dir in $rbenvdirs; do
+    if [[ -d $dir/bin ]]; then
+      export PATH="$dir/bin:$PATH"
+      FOUND_RBENV=1
+      break
+    fi
+  done
+fi
+
+if [[ $FOUND_RBENV -ne 1 ]]; then
+  if (( $+commands[brew] )) && dir=$(brew --prefix rbenv 2>/dev/null); then
+    if [[ -d $dir/bin ]]; then
+      export PATH="$dir/bin:$PATH"
+      FOUND_RBENV=1
+    fi
+  fi
+fi
+
+if [[ $FOUND_RBENV -eq 1 ]]; then
+  eval "$(rbenv init --no-rehash - zsh)"
+
+  alias rubies="rbenv versions"
+  alias gemsets="rbenv gemset list"
+
+  function current_ruby() {
+    echo "$(rbenv version-name)"
+  }
+
+  function current_gemset() {
+    echo "$(rbenv gemset active 2>/dev/null)" | tr ' ' '+'
+  }
+
+  function gems() {
+    local rbenv_path=$(rbenv prefix)
+    gem list $@ | sed -E \
+      -e "s/\([0-9a-z, \.]+( .+)?\)/$fg[blue]&$reset_color/g" \
+      -e "s|$(echo $rbenv_path)|$fg[magenta]\$rbenv_path$reset_color|g" \
+      -e "s/$current_ruby@global/$fg[yellow]&$reset_color/g" \
+      -e "s/$current_ruby$current_gemset$/$fg[green]&$reset_color/g"
+  }
+
+  function rbenv_prompt_info() {
+    local ruby=${$(current_ruby):gs/%/%%} gemset=${$(current_gemset):gs/%/%%}
+    echo -n "${ZSH_THEME_RUBY_PROMPT_PREFIX}"
+    [[ -n "$gemset" ]] && echo -n "${ruby}@${gemset}" || echo -n "${ruby}"
+    echo "${ZSH_THEME_RUBY_PROMPT_SUFFIX}"
+  }
+else
+  alias rubies="ruby -v"
+  function gemsets() { echo "not supported" }
+  function current_ruby() { echo "not supported" }
+  function current_gemset() { echo "not supported" }
+  function gems() { echo "not supported" }
+  function rbenv_prompt_info() {
+    echo -n "${ZSH_THEME_RUBY_PROMPT_PREFIX}"
+    echo -n "system: $(ruby -v | cut -f-2 -d ' ' | sed 's/%/%%/g')"
+    echo "${ZSH_THEME_RUBY_PROMPT_SUFFIX}"
+  }
+fi
+
+unset FOUND_RBENV rbenvdirs dir
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rbfu/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rbfu/README.md
new file mode 100644 (file)
index 0000000..fbcab64
--- /dev/null
@@ -0,0 +1,18 @@
+# rbfu plugin
+
+This plugin starts [rbfu](https://github.com/hmans/rbfu), a minimal Ruby version
+manager, and adds some useful functions.
+
+To use it, add `rbfu` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rbfu)
+```
+
+**Note: `rbfu` is deprecated and should no longer be used.**
+
+## Functions
+
+- `rbfu-rubies`: lists all installed rubies available to rbfu.
+
+- `rvm_prompt_info`: shows the Ruby version being used with rbfu.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rbfu/rbfu.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rbfu/rbfu.plugin.zsh
new file mode 100644 (file)
index 0000000..27dc3ee
--- /dev/null
@@ -0,0 +1,49 @@
+# Enables rbfu with --auto option, if available.
+#
+# Also provides a command to list all installed/available
+# rubies. To ensure compatibility with themes, creates the
+# rvm_prompt_info function to return the $RBFU_RUBY_VERSION
+# version.
+
+command -v rbfu &>/dev/null || return
+
+eval "$(rbfu --init --auto)"
+
+# Internal: Print ruby version details, if it's currently active, etc.
+function _rbfu_rubies_print() {
+  # 1: path to ruby file
+  # 2: active ruby
+  local rb rb_out
+  rb="${$1:t}"
+  rb_out="$rb"
+
+  # If the ruby is a symlink, add @ to the name.
+  if [[ -h "$1" ]]; then
+    rb_out="${rb_out}${fg[green]}@${reset_color}"
+  fi
+
+  # If the ruby is active, add * to the name and show it in red.
+  if [[ "$rb" = "$2" ]]; then
+    rb_out="${fg[red]}${rb_out} ${fg[red]}*${reset_color}"
+  fi
+
+  echo $rb_out
+}
+
+# Public: Provide a list with all available rubies, this basically depends
+# on ~/.rfbu/rubies. Highlights the currently active ruby version and aliases.
+function rbfu-rubies() {
+  local rbfu_dir active_rb
+  rbfu_dir="${RBFU_RUBIES:-${HOME}/.rbfu/rubies}"
+  active_rb="${RBFU_RUBY_VERSION:-system}"
+
+  _rbfu_rubies_print "${rbfu_dir}/system" "$active_rb"
+  for rb in ${rbfu_dir}/*(N); do
+    _rbfu_rubies_print "$rb" "$active_rb"
+  done
+}
+
+# Public: Create rvm_prompt_info command for themes compatibility, unless
+# it has already been defined.
+(( ${+functions[rvm_prompt_info]} )) || \
+function rvm_prompt_info() { echo "${${RBFU_RUBY_VERSION:=system}:gs/%/%%}" }
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rbw/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rbw/README.md
new file mode 100644 (file)
index 0000000..cae36ce
--- /dev/null
@@ -0,0 +1,22 @@
+# Bitwarden (unofficial) CLI plugin
+
+This plugin adds completion for [rbw](https://github.com/doy/rbw), an unofficial
+CLI for [Bitwarden](https://bitwarden.com).
+
+To use it, add `rbw` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rbw)
+```
+
+## `rbwpw`
+
+The `rbwpw` function is a wrapper around `rbw`. It copies the password in the
+clipboard for the service you ask for and clears the clipboard 20s later.
+The usage is as follows:
+
+```zsh
+rbwpw <service>
+```
+
+This plugin does not add any aliases.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rbw/rbw.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rbw/rbw.plugin.zsh
new file mode 100644 (file)
index 0000000..b6cecf8
--- /dev/null
@@ -0,0 +1,43 @@
+if (( ! $+commands[rbw] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `rbw`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_rbw" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _rbw
+  _comps[rbw]=_rbw
+fi
+
+rbw gen-completions zsh >| "$ZSH_CACHE_DIR/completions/_rbw" &|
+
+# rbwpw function copies the password of a service to the clipboard
+# and clears it after 20 seconds
+function rbwpw {
+  if [[ $# -ne 1 ]]; then
+    echo "usage: rbwpw <service>"
+    return 1
+  fi
+  local service=$1
+  if ! rbw unlock; then
+    echo "rbw is locked"
+    return 1
+  fi
+  local pw=$(rbw get $service 2>/dev/null)
+  if [[ -z $pw ]]; then
+    echo "$service not found"
+    return 1
+  fi
+  echo -n $pw | clipcopy
+  echo "password for $service copied!"
+  {sleep 20 && clipcopy </dev/null 2>/dev/null} &|
+}
+
+function _rbwpw {
+  local -a services
+  services=("${(@f)$(rbw ls 2>/dev/null)}")
+  [[ -n "$services" ]] && compadd -a -- services
+}
+
+compdef _rbwpw rbwpw
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/README.md
new file mode 100644 (file)
index 0000000..807c063
--- /dev/null
@@ -0,0 +1,88 @@
+# React Native plugin
+
+This plugin adds completion for [`react-native`](https://facebook.github.io/react-native/).
+It also defines a few [aliases](#aliases) for the commands more frequently used.
+
+To enable, add `react-native` to your `plugins` array in your zshrc file:
+
+```zsh
+plugins=(... react-native)
+```
+
+## Aliases
+
+| Alias           | React Native command                                                       |
+| :-------------- | :------------------------------------------------------------------------- |
+| **rn**          | `react-native`                                                             |
+| **rns**         | `react-native start`                                                       |
+| **rnlink**      | `react-native link`                                                        |
+| _Logging_       |                                                                            |
+| **rnland**      | `react-native log-android`                                                 |
+| **rnlios**      | `react-native log-ios`                                                     |
+| _App Testing_   |                                                                            |
+| **rnand**       | `react-native run-android`                                                 |
+| **rnios**       | `react-native run-ios`                                                     |
+| _iPhone_        |                                                                            |
+| **rnios4s**     | `react-native run-ios --simulator "iPhone 4s"`                             |
+| **rnios5**      | `react-native run-ios --simulator "iPhone 5"`                              |
+| **rnios5s**     | `react-native run-ios --simulator "iPhone 5s"`                             |
+| **rnios6**      | `react-native run-ios --simulator "iPhone 6"`                              |
+| **rnios6s**     | `react-native run-ios --simulator "iPhone 6s"`                             |
+| **rnios6p**     | `react-native run-ios --simulator "iPhone 6 Plus"`                         |
+| **rnios6sp**    | `react-native run-ios --simulator "iPhone 6s Plus"`                        |
+| **rnios7**      | `react-native run-ios --simulator "iPhone 7"`                              |
+| **rnios7p**     | `react-native run-ios --simulator "iPhone 7 Plus"`                         |
+| **rnios8**      | `react-native run-ios --simulator "iPhone 8"`                              |
+| **rnios8p**     | `react-native run-ios --simulator "iPhone 8 Plus"`                         |
+| **rniosse**     | `react-native run-ios --simulator "iPhone SE"`                             |
+| **rniosx**      | `react-native run-ios --simulator "iPhone X"`                              |
+| **rniosxs**     | `react-native run-ios --simulator "iPhone Xs"`                             |
+| **rniosxsm**    | `react-native run-ios --simulator "iPhone Xs Max"`                         |
+| **rniosxr**     | `react-native run-ios --simulator "iPhone Xʀ"`                             |
+| **rnios11**     | `react-native run-ios --simulator "iPhone 11"`                             |
+| **rnios11p**    | `react-native run-ios --simulator "iPhone 11 Pro"`                         |
+| **rnios11pm**   | `react-native run-ios --simulator "iPhone 11 Pro Max"`                     |
+| **rnios12**     | `react-native run-ios --simulator "iPhone 12"`                             |
+| **rnios12m**    | `react-native run-ios --simulator "iPhone 12 mini"`                        |
+| **rnios12p**    | `react-native run-ios --simulator "iPhone 12 Pro"`                         |
+| **rnios12pm**   | `react-native run-ios --simulator "iPhone 12 Pro Max"`                     |
+| **rnios13**     | `react-native run-ios --simulator "iPhone 13"`                             |
+| **rnios13m**    | `react-native run-ios --simulator "iPhone 13 mini"`                        |
+| **rnios13p**    | `react-native run-ios --simulator "iPhone 13 Pro"`                         |
+| **rnios13pm**   | `react-native run-ios --simulator "iPhone 13 Pro Max"`                     |
+| **rnios14**     | `react-native run-ios --simulator "iPhone 14"`                             |
+| **rnios14pl**   | `react-native run-ios --simulator "iPhone 14 Plus"`                        |
+| **rnios14p**    | `react-native run-ios --simulator "iPhone 14 Pro"`                         |
+| **rnios14pm**   | `react-native run-ios --simulator "iPhone 14 Pro Max"`                     |
+| _iPad_          |                                                                            |
+| **rnipad2**     | `react-native run-ios --simulator "iPad 2"`                                |
+| **rnipad5**     | `react-native run-ios --simulator "iPad (5th generation)"`                 |
+| **rnipad6**     | `react-native run-ios --simulator "iPad (6th generation)"`                 |
+| **rnipadr**     | `react-native run-ios --simulator "iPad Retina"`                           |
+| **rnipada**     | `react-native run-ios --simulator "iPad Air"`                              |
+| **rnipada2**    | `react-native run-ios --simulator "iPad Air 2"`                            |
+| **rnipada3**    | `react-native run-ios --simulator "iPad Air (3rd generation)"`             |
+| **rnipadm2**    | `react-native run-ios --simulator "iPad mini 2"`                           |
+| **rnipadm3**    | `react-native run-ios --simulator "iPad mini 3"`                           |
+| **rnipadm4**    | `react-native run-ios --simulator "iPad mini 4"`                           |
+| **rnipadm5**    | `react-native run-ios --simulator "iPad mini (5th generation)"`            |
+| **rnipadp9**    | `react-native run-ios --simulator "iPad Pro (9.7-inch)"`                   |
+| **rnipadp12**   | `react-native run-ios --simulator "iPad Pro (12.9-inch)"`                  |
+| **rnipadp122**  | `react-native run-ios --simulator "iPad Pro (12.9-inch) (2nd generation)"` |
+| **rnipadp10**   | `react-native run-ios --simulator "iPad Pro (10.5-inch)"`                  |
+| **rnipad11**    | `react-native run-ios --simulator "iPad Pro (11-inch)"`                    |
+| **rnipad123**   | `react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"` |
+| _Apple TV_      |                                                                            |
+| **rnatv**       | `react-native run-ios --simulator "Apple TV"`                              |
+| **rnatv4k**     | `react-native run-ios --simulator "Apple TV 4K"`                           |
+| **rnatv4k1080** | `react-native run-ios --simulator "Apple TV 4K (at 1080p)"`                |
+| **rnipad123**   | `react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"` |
+| _Apple Watch_   |                                                                            |
+| **rnaw38**      | `react-native run-ios --simulator "Apple Watch - 38mm"`                    |
+| **rnaw42**      | `react-native run-ios --simulator "Apple Watch - 42mm"`                    |
+| **rnaws238**    | `react-native run-ios --simulator "Apple Watch Series 2 - 38mm"`           |
+| **rnaws242**    | `react-native run-ios --simulator "Apple Watch Series 2 - 42mm"`           |
+| **rnaws338**    | `react-native run-ios --simulator "Apple Watch Series 3 - 38mm"`           |
+| **rnaws342**    | `react-native run-ios --simulator "Apple Watch Series 3 - 42mm"`           |
+| **rnaws440**    | `react-native run-ios --simulator "Apple Watch Series 4 - 40mm"`           |
+| **rnaws444**    | `react-native run-ios --simulator "Apple Watch Series 4 - 44mm"`           |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/_react-native b/stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/_react-native
new file mode 100644 (file)
index 0000000..893ac04
--- /dev/null
@@ -0,0 +1,32 @@
+#compdef react-native
+#autoload
+
+local -a _1st_arguments
+_1st_arguments=(
+    'init:<ProjectName> generates a new project and installs its dependencies'
+    'android:creates an empty android project'
+    'start:starts the webserver'
+    'run-ios:builds your app and starts it on iOS simulator'
+    'run-android:builds your app and starts it on a connected Android emulator or device'
+    'new-library:generates a native library bridge'
+    'bundle:builds the javascript bundle for offline use'
+    'unbundle:builds javascript as "unbundle" for offline use'
+    'link:[options] <packageName> links all native dependencies'
+    'unlink:[options] <packageName> unlink native dependency'
+    'install:[options] <packageName> install and link native dependencies'
+    'uninstall:[options] <packageName> uninstall and unlink native dependencies'
+    "upgrade:upgrade your app's template files to the latest version; run this after updating the react-native version in your package.json and running npm install"
+    'log-android:starts adb logcat'
+    'log-ios:starts iOS device syslog tail'
+)
+
+
+_arguments \
+    '(--version)--version[show version]' \
+    '(--help)--help[show help]' \
+    '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "react-native subcommand" _1st_arguments
+  return
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/react-native.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/react-native/react-native.plugin.zsh
new file mode 100644 (file)
index 0000000..afeaab4
--- /dev/null
@@ -0,0 +1,75 @@
+# React Native
+alias rn='react-native'
+alias rns='react-native start'
+alias rnlink='react-native link'
+alias rnland='react-native log-android'
+alias rnlios='react-native log-ios'
+alias rnand='react-native run-android'
+alias rnios='react-native run-ios'
+
+# iPhone
+alias rnios4s='react-native run-ios --simulator "iPhone 4s"'
+alias rnios5='react-native run-ios --simulator "iPhone 5"'
+alias rnios5s='react-native run-ios --simulator "iPhone 5s"'
+alias rnios6='react-native run-ios --simulator "iPhone 6"'
+alias rnios6p='react-native run-ios --simulator "iPhone 6 Plus"'
+alias rnios6s='react-native run-ios --simulator "iPhone 6s"'
+alias rnios6sp='react-native run-ios --simulator "iPhone 6s Plus"'
+alias rnios7='react-native run-ios --simulator "iPhone 7"'
+alias rnios7p='react-native run-ios --simulator "iPhone 7 Plus"'
+alias rnios8='react-native run-ios --simulator "iPhone 8"'
+alias rnios8p='react-native run-ios --simulator "iPhone 8 Plus"'
+alias rniosse='react-native run-ios --simulator "iPhone SE"'
+alias rniosx='react-native run-ios --simulator "iPhone X"'
+alias rniosxs='react-native run-ios --simulator "iPhone Xs"'
+alias rniosxsm='react-native run-ios --simulator "iPhone Xs Max"'
+alias rniosxr='react-native run-ios --simulator "iPhone Xʀ"'
+alias rnios11='react-native run-ios --simulator "iPhone 11"'
+alias rnios11p='react-native run-ios --simulator "iPhone 11 Pro"'
+alias rnios11pm='react-native run-ios --simulator "iPhone 11 Pro Max"'
+alias rnios12='react-native run-ios --simulator "iPhone 12"'
+alias rnios12m='react-native run-ios --simulator "iPhone 12 mini"'
+alias rnios12p='react-native run-ios --simulator "iPhone 12 Pro"'
+alias rnios12pm='react-native run-ios --simulator "iPhone 12 Pro Max"'
+alias rnios13='react-native run-ios --simulator "iPhone 13"'
+alias rnios13m='react-native run-ios --simulator "iPhone 13 mini"'
+alias rnios13p='react-native run-ios --simulator "iPhone 13 Pro"'
+alias rnios13pm='react-native run-ios --simulator "iPhone 13 Pro Max"'
+alias rnios14='react-native run-ios --simulator "iPhone 14"'
+alias rnios14pl='react-native run-ios --simulator "iPhone 14 Plus"'
+alias rnios14p='react-native run-ios --simulator "iPhone 14 Pro"'
+alias rnios14pm='react-native run-ios --simulator "iPhone 14 Pro Max"'
+
+# iPad
+alias rnipad2='react-native run-ios --simulator "iPad 2"'
+alias rnipad5='react-native run-ios --simulator "iPad (5th generation)"'
+alias rnipad6='react-native run-ios --simulator "iPad (6th generation)"'
+alias rnipadr='react-native run-ios --simulator "iPad Retina"'
+alias rnipada='react-native run-ios --simulator "iPad Air"'
+alias rnipada2='react-native run-ios --simulator "iPad Air 2"'
+alias rnipada3='react-native run-ios --simulator "iPad Air (3rd generation)"'
+alias rnipadm2='react-native run-ios --simulator "iPad mini 2"'
+alias rnipadm3='react-native run-ios --simulator "iPad mini 3"'
+alias rnipadm4='react-native run-ios --simulator "iPad mini 4"'
+alias rnipadm5='react-native run-ios --simulator "iPad mini (5th generation)"'
+alias rnipadp9='react-native run-ios --simulator "iPad Pro (9.7-inch)"'
+alias rnipadp12='react-native run-ios --simulator "iPad Pro (12.9-inch)"'
+alias rnipadp122='react-native run-ios --simulator "iPad Pro (12.9-inch) (2nd generation)"'
+alias rnipadp10='react-native run-ios --simulator "iPad Pro (10.5-inch)"'
+alias rnipad11='react-native run-ios --simulator "iPad Pro (11-inch)"'
+alias rnipad123='react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"'
+
+# Apple TV
+alias rnatv='react-native run-ios --simulator "Apple TV"'
+alias rnatv4k='react-native run-ios --simulator "Apple TV 4K"'
+alias rnatv4k1080='react-native run-ios --simulator "Apple TV 4K (at 1080p)"'
+
+# Apple Watch
+alias rnaw38='react-native run-ios --simulator "Apple Watch - 38mm"'
+alias rnaw42='react-native run-ios --simulator "Apple Watch - 42mm"'
+alias rnaws238='react-native run-ios --simulator "Apple Watch Series 2 - 38mm"'
+alias rnaws242='react-native run-ios --simulator "Apple Watch Series 2 - 42mm"'
+alias rnaws338='react-native run-ios --simulator "Apple Watch Series 3 - 38mm"'
+alias rnaws342='react-native run-ios --simulator "Apple Watch Series 3 - 42mm"'
+alias rnaws440='react-native run-ios --simulator "Apple Watch Series 4 - 40mm"'
+alias rnaws444='react-native run-ios --simulator "Apple Watch Series 4 - 44mm"'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rebar/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rebar/README.md
new file mode 100644 (file)
index 0000000..456ba45
--- /dev/null
@@ -0,0 +1,9 @@
+# rebar plugin
+
+This plugin adds completions for the [rebar](https://www.rebar3.org/) Erlang build tool.
+
+To use it, add `rebar` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rebar)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rebar/_rebar b/stow/oh-my-zsh/.oh-my-zsh/plugins/rebar/_rebar
new file mode 100644 (file)
index 0000000..ea0d8a6
--- /dev/null
@@ -0,0 +1,79 @@
+#compdef rebar
+
+local curcontext=$curcontext state ret=1
+typeset -ga _rebar_global_opts
+
+_rebar_global_opts=(
+  '(--help -h)'{--help,-h}'[Show the program options]'
+  '(--commands -c)'{--commands,-c}'[Show available commands]'
+  '(--version -V)'{--version,-V}'[Show version information]'
+  '(-vvv -vv -v)'--verbose+'[Verbosity level. Default: 0]:verbosity level:(0 1 2 3)'
+  '(-vvv)-v[Slightly more verbose output]'
+  '(-vvv)-vv[More verbose output]'
+  '(-v -vv)-vvv[Most verbose output]'
+  '(--force -f)'{--force,-f}'[Force]'
+  '-D+[Define compiler macro]'
+  '(--jobs -j)'{--jobs+,-j+}'[Number of concurrent workers a command may use. Default: 3]:workers:(1 2 3 4 5 6 7 8 9)'
+  '(--config -C)'{--config,-C}'[Rebar config file to use]:files:_files'
+  '(--profile -p)'{--profile,-p}'[Profile this run of rebar]'
+  '(--keep-going -k)'{--keep-going,-k}'[Keep running after a command fails]'
+)
+
+_rebar () {
+  _arguments -C $_rebar_global_opts \
+    '*::command and variable:->cmd_and_var' \
+    && return
+
+  case $state in
+    cmd_and_var)
+      _values -S = 'variables' \
+        'clean[Clean]' \
+        'compile[Compile sources]' \
+        'create[Create skel based on template and vars]' \
+        'create-app[Create simple app skel]' \
+        'create-node[Create simple node skel]' \
+        'list-template[List available templates]' \
+        'doc[Generate Erlang program documentation]' \
+        'check-deps[Display to be fetched dependencies]' \
+        'get-deps[Fetch dependencies]' \
+        'update-deps[Update fetched dependencies]' \
+        'delete-deps[Delete fetched dependencies]' \
+        'list-deps[List dependencies]' \
+        'generate[Build release with reltool]' \
+        'overlay[Run reltool overlays only]' \
+        'generate-appups[Generate appup files]' \
+        'generate-upgrade[Build an upgrade package]' \
+        'eunit[Run eunit tests]' \
+        'ct[Run common_test suites]' \
+        'qc[Test QuickCheck properties]' \
+        'xref[Run cross reference analysis]' \
+        'help[Show the program options]' \
+        'version[Show version information]' \
+        'apps[Application names to process]:' \
+        'case[Common Test case]:' \
+        'dump_spec[Dump reltool spec]:' \
+        'jobs[Number of workers]::workers:(0 1 2 3 4 5 6 7 8 9)' \
+        'suites[Common Test suites]::suite name:_path_files -W "(src test)" -g "*.erl(:r)"' \
+        'verbose[Verbosity level]::verbosity level:(0 1 2 3)' \
+        'appid[Application id]:' \
+        'previous_release[Previous release path]:' \
+        'nodeid[Node id]:' \
+        'root_dir[Reltool config root directory]::directory:_files -/' \
+        'skip_deps[Skip deps]::flag:(true false)' \
+        'skip_apps[Application names to not process]::flag:(true false)' \
+        'template[Template name]:' \
+        'template_dir[Template directory]::directory:_files -/' \
+        && ret=0
+      ;;
+  esac
+}
+
+_rebar
+
+# Local variables:
+# mode: shell-script
+# sh-basic-offset: 2
+# sh-indent-comment: t
+# indent-tabs-mode: nil
+# End:
+# ex: sw=2 ts=2 et filetype=sh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/redis-cli/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/redis-cli/README.md
new file mode 100644 (file)
index 0000000..bb6e94a
--- /dev/null
@@ -0,0 +1,15 @@
+# Redis-CLI
+
+This plugin adds [redis-cli](https://redis.io/topics/rediscli) completion, based off of Homebrew completion.
+
+To use it, add `redis-cli` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... redis-cli)
+```
+
+## Requirements
+
+In order to make this work, you will need to have redis installed.
+
+More info on the usage and install: https://redis.io/topics/quickstart
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/redis-cli/_redis-cli b/stow/oh-my-zsh/.oh-my-zsh/plugins/redis-cli/_redis-cli
new file mode 100644 (file)
index 0000000..f936245
--- /dev/null
@@ -0,0 +1,142 @@
+#compdef redis-cli rec
+#autoload
+
+#redis cli completion, based off homebrew completion (ref. 2011-04-14)
+
+local -a _1st_arguments
+_1st_arguments=(
+  'append:append a value to a key'
+  'auth:authenticate to the server'
+  'bgrewriteeaof:asynchronously rewrite the append-only file'
+  'bgsave:asynchronously save the dataset to disk'
+  'blpop:remove and get the first element in a list, or block until one is available'
+  'brpop:remove and get the last element in a list, or block until one is available'
+  'brpoplpush:pop a value from a list, push it to another list and return it; or block until one is available'
+  # 'config get:get the value of a configuration parameter'
+  # 'config set:set a configuration parameter to the given value'
+  # 'config resetstat: reset the stats returned by INFO'
+  'dbsize:return the number of keys in the selected database'
+  # 'debug object:get debugging information about a key'
+  # 'debug segfault:make the server crash'
+  'decr:decrement the integer value of a key by one'
+  'decrby:decrement the integer value of a key by the given number'
+  'del:delete a key'
+  'discard:discard all commands issued after MULTI'
+  'echo:echo the given string'
+  'exec:execute all commands issued after a MULTI'
+  'exists:determine if a key exists'
+  'expire:set the time to live for a key, in seconds'
+  'expireat:set the expiration for a key as a UNIX timestamp'
+  'flushall:remove all keys from all databases'
+  'flushdb:remove all keys from the current database'
+  'get:get the value of a key'
+  'getbit:returns the bit value at offset in the string value stored at key'
+  'getrange:get a substring of the string stored at a key'
+  'getset:set the string value of a key and return its old value'
+  'hdel:delete a hash field'
+  'hexists:determine if a hash field exists'
+  'hget:get the value of a hash field'
+  'hgetall:get all the fields and values in a hash'
+  'hincrby:increment the integer value of a hash field by the given number'
+  'hkeys:get all the fields in a hash'
+  'hlen:get the number of fields in a hash'
+  'hmget:get the values of all the given hash fields'
+  'hmset:set multiple hash fields to multiple values'
+  'hset:set the string value of a hash field'
+  'hsetnx:set the value of a hash field, only if the field does not exist'
+  'hvals:get all the values in a hash'
+  'incr:increment the integer value of a key by one'
+  'incrby:increment the integer value of a key by the given number'
+  'info:get information and statistics about the server'
+  'keys:find all keys matching the given pattern'
+  'lastsave:get the UNIX timestamp of the last successful save to disk'
+  'lindex:get an element from a list by its index'
+  'linsert:insert an element before or after another element in a list'
+  'llen:get the length of a list'
+  'lpop:remove and get the first element in a list'
+  'lpush:prepend a value to a list'
+  'lpushx:prepend a value to a list, only if the list exists'
+  'lrange:get a range of elements from a list'
+  'lrem:remove elements from a list'
+  'lset:set the value of an element in a list by its index'
+  'ltrim:trim a list to the specified range'
+  'mget:get the values of all the given keys'
+  'monitor:listen for all requests received by the server in real time'
+  'move:move a key to another database'
+  'mset:set multiple keys to multiple values'
+  'msetnx:set multiple keys tom ultiple values, only if none of the keys exist'
+  'multi:mark the start of a transaction block'
+  'object:inspect the internals of Redis objects'
+  'persist:remove the expiration from a key'
+  'ping:ping the server'
+  'psubscribe:listen for messages published to channels matching the given patterns'
+  'publish:post a message to a channel'
+  'punsubscribe:stop listening for messages posted to channels matching the given patterns'
+  'quit:close the connection'
+  'randomkey:return a random key from the keyspace'
+  'rename:rename a key'
+  'renamenx:rename a key, only if the new key does not exist'
+  'rpop:remove and get the last element in a list'
+  'rpoplpush:remove the last element in a list, append it to another list and return it'
+  'rpush:append a value to a list'
+  'rpushx:append a value to a list, only if the list exists'
+  'sadd:add a member to a set'
+  'save:synchronously save the dataset to disk'
+  'scard:get the number of members in a set'
+  'sdiff:subtract multiple sets'
+  'sdiffstore:subtract multiple sets and store the resulting set in a key'
+  'select:change the selected database for the current connection'
+  'set:set the string value of a key'
+  'setbit:sets or clears the bit at offset in the string value stored at key'
+  'setex:set the value and expiration of a key'
+  'setnx:set the value of a key, only if the key does not exist'
+  'setrange:overwrite part of a string at key starting at the specified offset'
+  'shutdown:synchronously save the dataset to disk and then shut down the server'
+  'sinter:intersect multiple sets'
+  'sinterstore:intersect multiple sets and store the resulting set in a key'
+  'sismember:determine if a given value is a member of a set'
+  'slaveof:make the server a slave of another instance, or promote it as master'
+  'smembers:get all the members in a set'
+  'smove:move a member from one set to another'
+  'sort:sort the elements in a list, set or sorted set'
+  'spop:remove and return a random member from a set'
+  'srandmember:get a random member from a set'
+  'srem:remove a member from a set'
+  'strlen:get the length of the value stored in a key'
+  'subscribe:listen for messages published to the given channels'
+  'sunion:add multiple sets'
+  'sunionstore:add multiple sets and store the resulting set in a key'
+  'ttl:get the time to live for a key'
+  'type:determine the type stored at key'
+  'unsubscribe:stop listening for messages posted to the given channels'
+  'unwatch:forget about all watched keys'
+  'watch:watch the given keys to determine execution of the MULTI/EXEC block'
+  'zadd:add a member to a sorted set, or update its score if it already exists'
+  'zcard:get the number of members in a sorted set'
+  'zcount:count the members in a sorted set with scores within the given values'
+  'zincrby:increment the score of a member in a sorted set'
+  'zinterstore:intersect multiple sorted sets and store the resulting sorted set in a new key'
+  'zrange:return a range of members in a sorted set, by index'
+  'zrangebyscore:return a range of members in a sorted set, by score'
+  'zrank:determine the index of a member in a sorted set'
+  'zrem:remove a member from a sorted set'
+  'zremrangebyrank:remove all members in a sorted set within the given indexes'
+  'zremrangebyscore:remove all members in a sorted set within the given scores'
+  'zrevrange:return a range of members in a sorted set, by index, with scores ordered from high to low'
+  'zrevrangebyscore:return a range of members in a sorted set, by score, with scores ordered from high to low'
+  'zrevrank:determine the index of a member in a sorted set, with scores ordered from high to low'
+  'zscore:get the score associated with the given member in a sorted set'
+  'zunionstore:add multiple sorted sets and store te resulting sorted set in a new key'
+)
+
+local expl
+
+_arguments \
+  '(-v --version)'{-v,--version}'[show version]' \
+  '(-h --help)'{-h,--help}'[show help]' \
+  '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "redis-cli subcommand" _1st_arguments
+  return
+fi
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/repo/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/repo/README.md
new file mode 100644 (file)
index 0000000..6abd233
--- /dev/null
@@ -0,0 +1,25 @@
+# repo plugin
+
+This plugin mainly adds some aliases and support for automatic completion for
+the [repo command line tool](https://code.google.com/p/git-repo/).
+
+To use it, add `repo` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... repo)
+```
+
+## Aliases
+
+| Alias   | Command                                |
+|---------|----------------------------------------|
+| `r`     | `repo`                                 |
+| `rra`   | `repo rebase --auto-stash`             |
+| `rs`    | `repo sync`                            |
+| `rsrra` | `repo sync ; repo rebase --auto-stash` |
+| `ru`    | `repo upload`                          |
+| `rst`   | `repo status`                          |
+| `rsto`  | `repo status -o`                       |
+| `rfa`   | `repo forall -c`                       |
+| `rfap`  | `repo forall -p -c`                    |
+| `rinf`  | `repo info`                            |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/repo/_repo b/stow/oh-my-zsh/.oh-my-zsh/plugins/repo/_repo
new file mode 100644 (file)
index 0000000..2b1f165
--- /dev/null
@@ -0,0 +1,279 @@
+#compdef repo
+
+__git_apply_whitespace_strategies ()
+{
+  declare -a strategies
+
+  strategies=(
+    'nowarn:turn off the trailing-whitespace warning'
+    'warn:output trailing-whitespace warning, but apply patch'
+    'fix:output trailing-whitespace warning and strip trailing whitespace'
+    'error:output trailing-whitespace warning and refuse to apply patch'
+    'error-all:same as "error", but output warnings for all files')
+
+  _describe -t strategies 'trailing-whitespace resolution strategy' strategies $*
+}
+
+
+_repo()
+{
+  local context state state_descr line curcontext="$curcontext"
+  typeset -A opt_args
+
+  local ret=1
+
+  _arguments -C \
+    '(- 1 *)--help[show usage]'\
+    '1:command:->command'\
+    '*::args:->args' && ret=0
+
+  case $state in
+    (command)
+      repo list  2> /dev/null > /dev/null
+      if [[ $? == 0 ]]; then
+        local commands;
+        commands=(
+          'abandon:Permanently abandon a development branch'
+          'branch:View current topic branches'
+          'branches:View current topic branches'
+          'checkout:Checkout a branch for development'
+          'cherry-pick:Cherry-pick a change.'
+          'diff:Show changes between commit and working tree'
+          'download:Download and checkout a change'
+          'forall:execute command on several project'
+          'grep:Print lines matching a pattern'
+          'help:Display detailed help on a command'
+          'init:Initialize repo in the current directory'
+          'list:List projects and their associated directories'
+          'manifest:Manifest inspection utility'
+          'overview:Display overview of unmerged project branches'
+          'prune:Prune (delete) already merged topics'
+          'rebase:Rebase local branches on upstream branch'
+          'selfupdate:Update repo to the latest version'
+          'smartsync:Update working tree to the latest known good revision'
+          'stage:Stage file(s) for commit'
+          'start:Start a new branch for development'
+          'status:Show the working tree status'
+          'sync:Update working tree to the latest revision'
+          'upload:Upload changes for code review'
+          'version:Display the version of repo'
+        )
+        _describe -t commands 'command' commands && ret=0
+      else
+        local commands;
+        commands=(
+          'init:Install repo in the current working directory'
+          'help:Display detailed help on a command'
+        )
+        _describe -t commands 'command' commands && ret=0
+      fi
+      ;;
+    (args)
+      case $words[1] in
+        (branch | branches)
+          # TODO : list available projects and add them in list to feed compadd with
+          _arguments  : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     ': :__repo_projects' \
+                      && ret=0
+         ;;
+        (abandon)
+          # TODO : list available projects and add them in list to feed compadd with
+          _arguments  : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     ':branch name:__repo_branch' \
+                     ': :__repo_projects'\
+                      && ret=0
+          ;;
+        (checkout)
+          # TODO : list available projects and add them in list to feed compadd with
+          _arguments  : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     ':branch name:__repo_branch' \
+                     ': :__repo_projects'\
+                     && ret=0
+          ;;
+        (init)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-q --quiet)"{-q,--quiet}"[be quiet]" \
+                     "(-u --manifest-url)"{-u,--manifest-url=}"[manifest repository location]":url:__repo_url_prompt \
+                     "(-b --manifest-branch)"{-b,--manifest-branch=}"[manifest branch or revision]":branch:__repo_branch\
+                     "(-m --manifest-name)"{-m,--manifest-name=}"[initial manifest file]":manifest_name:__repo_manifest_name\
+                     "(--mirror)--mirror[mirror the forrest]"\
+                     "(--reference)--reference=[location of mirror directory]":dir:_dirs\
+                     "(--depth)--depth=[create a shallow clone with given depth; see git clone]":depth:__repo_depth_prompt\
+                     "(-g --group=)"{-g,--group=}"[restrict manifest projects to ones with a specified group]":group:_group\
+                     "(-p --platform=)"{-p,--platform=}"[restrict manifest projects to ones with a specified platform group(auto|all|none|linux|darwin|...)]":platform:"(auto all none linux darwin)"\
+                     "(--repo-url)--repo-url=[repo repository location]":url:__repo_url_prompt\
+                     "(--repo-branch)--repo-branch[repo branch or revision]":branch_or_rev:__repo__repo_branch_or_rev\
+                     "(--no-repo-verify)--no-repo-verify[do not verify repo source code]"\
+                     "(--config-name)--config-name[Always prompt for name/e-mail]"\
+                     && ret=0
+          ;;
+        (start)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(--all)--all[begin branch in all projects]"\
+                     "(-r --rev --revision)"{-r,--rev,--revision=}"[point branch at this revision instead of upstream]":branch_or_rev:__repo__repo_branch_or_rev\
+                     "(--head)--head[abbreviation for --rev HEAD]"\
+                    ':branch name:__repo_new__repo_branch_name' \
+                    ':projects:__repo_projects_or_all' \
+                    && ret=0
+          ;;
+        (rebase)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-i --interactive)"{-i,--interactive}"[interactive rebase (single project only)]: :__repo_projects" \
+                     "(-f --force-rebase)"{-f,--force-rebase}"[Pass --force-rebase to git rebase]" \
+                     "(--no-ff)--no-ff=[Pass --no-ff to git rebase]"\
+                     "(-q --quiet)"{-q,--quiet}"[Pass --quiet to git rebase]" \
+                     "(--autosquash)--no-ff[Pass --autosquash to git rebase]"\
+                     "(--whitespace=)--whitespace=[Pass --whitespace to git rebase]: :__git_apply_whitespace_strategies"\
+                     "(--auto-stash)--auto-stash[Stash local modifications before starting]"\
+                     && ret=0
+          ;;
+        (checkout)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                    ':branch name:__git_branch_names' \
+                    ':projects:__repo_projects' \
+                    && ret=0
+          ;;
+        (list)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                    && ret=0
+          ;;
+        (stage)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-i --interactive)"{-i,--interactive}"[use interactive staging]" \
+                    ':projects:__repo_projects' \
+                    && ret=0
+          ;;
+        (status)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-j --jobs)"{-j,--jobs}"[number of projects to check simultaneously]" \
+                    ':projects:__repo_projects' \
+                    && ret=0
+          ;;
+        (sync)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(--no-force-broken)--no-force-broken[stop sync if a project fails to sync (probably because of permissions)]" \
+                     "(-l --local-only)"{-l,--local-only}"[only update working tree, don't fetch]" \
+                     "(-n --network-only)"{-n,--network-branch}"[fetch only, don't update working tree]" \
+                     "(-d --detach)"{-d,--detach}"[detach projects back to manifest revision]" \
+                     "(-c --current-branch)"{-c,--current-branch}"[fetch only current branch from server]" \
+                     "(-q --quiet)"{-q,--quiet}"[be more quiet]" \
+                     "(-j --jobs=)"{-j,--jobs=}"[projects to fetch simultaneously (default 1) (limited to 5)]:projects to fetch simultaneously (default 1) (limited to 5)" \
+                     "(-m --manifest-name=)"{-m,--manifest-name=}"[temporary manifest to use for this sync]:manifest xml file:_files -g *.xml" \
+                     "(--no-clone-bundle)--no-clone-bundle[disable use of /clone.bundle on HTTP/HTTPS]" \
+                     "(-s --smart-sync)"{-s,--smart-sync=}"[smart sync using manifest from a known tag]:tag:" \
+                     '(--no-repo-verify)--no-repo-verify[do not verify repo source code]' \
+                     ': :__repo_projects' \
+                     && ret=0
+          ;;
+        (upload)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-t)-t[Send local branch name to Gerrit Code Review]" \
+                     "(--re= --reviewers=)"{--re=,--reviewers=}"[Request reviews from these people]:Request reviews from these people:" \
+                     "(--cc=)--cc=[Also send email to these email addresses.]:email addresses:_email_addresses" \
+                     "(--br=)--br=[Branch to upload.]:branch:__repo_branch" \
+                     "(--cbr --current-branch)"{--cbr,--current-branch}"[Upload current git branch]" \
+                     "(-d --draft)"{-d,--draft}"[If specified, upload as a draft.]" \
+                     "(--verify --no-verify)--no-verify[Do not run the upload hook.]" \
+                     '(--verify --no-verify)--verify[Run the upload hook without prompting]' \
+                     ': :__repo_projects' \
+                     && ret=0
+          ;;
+        (forall)
+          _arguments : \
+                     "(-h --help)"{-h,--help}"[Show help]" \
+                     "(-v --verbose)"{-v,--verbose}"[Show command error messages]" \
+                     '(-p)-p[Show project headers before output]' \
+                     ': :__repo_projects_mandatory' \
+                     "(-c --command -h --help -v --verbose -p)"{-c,--command}"[Command (and arguments) to execute]" \
+                     && ret=0
+          ;;
+        *)
+          ret=0
+      esac
+      ;;
+  esac
+
+  return $ret
+}
+
+__repo_reviewers()
+{
+ # _message -e url 'reviewers'
+}
+
+__repo_url_prompt()
+{
+  _message -e url 'url'
+}
+
+__repo_manifest_name()
+{
+  _message -e manifest_name 'manifest name'
+}
+
+_group()
+{
+  _message -e group 'group'
+}
+
+__repo_branch()
+{
+  #_message -e branch 'Repo branch'
+  branches=($(repo branches| cut -c4- | grep '|' | cut -d' ' -f1))
+  _describe -t branches 'Select repo branch' branches
+}
+
+__repo__repo_branch_or_rev()
+{
+  _message -e branch_or_rev 'repo branch or revision'
+}
+
+__repo_depth_prompt()
+{
+  _message -e depth 'depth'
+}
+
+__repo_projects()
+{
+  _message -e depth 'Optional option : <projects>...'
+  projects=($(repo list | cut -d' ' -f1))
+  _describe -t projects 'Select projects (keep empty for selecting all projects)' projects
+}
+
+__repo_projects_mandatory()
+{
+  projects=($(repo list | cut -d' ' -f1))
+  #_describe -t projects 'Select projects to apply commands' projects
+  _values -s ' ' "Select projects to apply commands" $projects
+}
+
+__repo_new__repo_branch_name()
+{
+  branches=($(repo branches| cut -c4- | grep '|' | cut -d' ' -f1))
+  _describe "" branches
+  _message -e "branch name" 'Enter new branch name or select an existing repo branch'
+}
+
+__repo_projects_or_all()
+{
+  #_message -e depth '[--all | <project>...]'
+
+  projects=(--all $(repo list | cut -d' ' -f1))
+  _describe -t projects 'Select projects or --all' projects
+  _describe -t --all 'All projects'
+}
+
+_repo "$@"
+return $?
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/repo/repo.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/repo/repo.plugin.zsh
new file mode 100644 (file)
index 0000000..f098993
--- /dev/null
@@ -0,0 +1,10 @@
+alias r='repo'
+alias rra='repo rebase --auto-stash'
+alias rs='repo sync'
+alias rsrra='repo sync ; repo rebase --auto-stash'
+alias ru='repo upload'
+alias rst='repo status'
+alias rsto='repo status -o'
+alias rfa='repo forall -c'
+alias rfap='repo forall -p -c'
+alias rinf='repo info'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ripgrep/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ripgrep/README.md
new file mode 100644 (file)
index 0000000..ab9d041
--- /dev/null
@@ -0,0 +1,9 @@
+# ripgrep
+
+This plugin adds completion for the text search tool [`ripgrep`](https://github.com/BurntSushi/ripgrep), also known as `rg`.
+
+To use it, add `ripgrep` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ripgrep)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ripgrep/_ripgrep b/stow/oh-my-zsh/.oh-my-zsh/plugins/ripgrep/_ripgrep
new file mode 100644 (file)
index 0000000..31bc697
--- /dev/null
@@ -0,0 +1,640 @@
+#compdef rg
+
+##
+# zsh completion function for ripgrep
+#
+# Run ci/test-complete after building to ensure that the options supported by
+# this function stay in synch with the `rg` binary.
+#
+# For convenience, a completion reference guide is included at the bottom of
+# this file.
+#
+# Originally based on code from the zsh-users project — see copyright notice
+# below.
+
+_rg() {
+  local curcontext=$curcontext no='!' descr ret=1
+  local -a context line state state_descr args tmp suf
+  local -A opt_args
+
+  # ripgrep has many options which negate the effect of a more common one — for
+  # example, `--no-column` to negate `--column`, and `--messages` to negate
+  # `--no-messages`. There are so many of these, and they're so infrequently
+  # used, that some users will probably find it irritating if they're completed
+  # indiscriminately, so let's not do that unless either the current prefix
+  # matches one of those negation options or the user has the `complete-all`
+  # style set. Note that this prefix check has to be updated manually to account
+  # for all of the potential negation options listed below!
+  if
+    # We also want to list all of these options during testing
+    [[ $_RG_COMPLETE_LIST_ARGS == (1|t*|y*) ]] ||
+    # (--[imnp]* => --ignore*, --messages, --no-*, --pcre2-unicode)
+    [[ $PREFIX$SUFFIX == --[imnp]* ]] ||
+    zstyle -t ":complete:$curcontext:*" complete-all
+  then
+    no=
+  fi
+
+  # We make heavy use of argument groups here to prevent the option specs from
+  # growing unwieldy. These aren't supported in zsh <5.4, though, so we'll strip
+  # them out below if necessary. This makes the exclusions inaccurate on those
+  # older versions, but oh well — it's not that big a deal
+  args=(
+    + '(exclusive)' # Misc. fully exclusive options
+    '(: * -)'{-h,--help}'[display help information]'
+    '(: * -)'{-V,--version}'[display version information]'
+    '(: * -)'--pcre2-version'[print the version of PCRE2 used by ripgrep, if available]'
+
+    + '(buffered)' # buffering options
+    '--line-buffered[force line buffering]'
+    $no"--no-line-buffered[don't force line buffering]"
+    '--block-buffered[force block buffering]'
+    $no"--no-block-buffered[don't force block buffering]"
+
+    + '(case)' # Case-sensitivity options
+    {-i,--ignore-case}'[search case-insensitively]'
+    {-s,--case-sensitive}'[search case-sensitively]'
+    {-S,--smart-case}'[search case-insensitively if pattern is all lowercase]'
+
+    + '(context-a)' # Context (after) options
+    '(context-c)'{-A+,--after-context=}'[specify lines to show after each match]:number of lines'
+
+    + '(context-b)' # Context (before) options
+    '(context-c)'{-B+,--before-context=}'[specify lines to show before each match]:number of lines'
+
+    + '(context-c)' # Context (combined) options
+    '(context-a context-b)'{-C+,--context=}'[specify lines to show before and after each match]:number of lines'
+
+    + '(column)' # Column options
+    '--column[show column numbers for matches]'
+    $no"--no-column[don't show column numbers for matches]"
+
+    + '(count)' # Counting options
+    {-c,--count}'[only show count of matching lines for each file]'
+    '--count-matches[only show count of individual matches for each file]'
+    '--include-zero[include files with zero matches in summary]'
+
+    + '(encoding)' # Encoding options
+    {-E+,--encoding=}'[specify text encoding of files to search]: :_rg_encodings'
+    $no'--no-encoding[use default text encoding]'
+
+    + '(engine)' # Engine choice options
+    '--engine=[select which regex engine to use]:when:((
+      default\:"use default engine"
+      pcre2\:"identical to --pcre2"
+      auto\:"identical to --auto-hybrid-regex"
+    ))'
+
+    + file # File-input options
+    '(1)*'{-f+,--file=}'[specify file containing patterns to search for]: :_files'
+
+    + '(file-match)' # Files with/without match options
+    '(stats)'{-l,--files-with-matches}'[only show names of files with matches]'
+    '(stats)--files-without-match[only show names of files without matches]'
+
+    + '(file-name)' # File-name options
+    {-H,--with-filename}'[show file name for matches]'
+    {-I,--no-filename}"[don't show file name for matches]"
+
+    + '(file-system)' # File system options
+    "--one-file-system[don't descend into directories on other file systems]"
+    $no'--no-one-file-system[descend into directories on other file systems]'
+
+    + '(fixed)' # Fixed-string options
+    {-F,--fixed-strings}'[treat pattern as literal string instead of regular expression]'
+    $no"--no-fixed-strings[don't treat pattern as literal string]"
+
+    + '(follow)' # Symlink-following options
+    {-L,--follow}'[follow symlinks]'
+    $no"--no-follow[don't follow symlinks]"
+
+    + glob # File-glob options
+    '*'{-g+,--glob=}'[include/exclude files matching specified glob]:glob'
+    '*--iglob=[include/exclude files matching specified case-insensitive glob]:glob'
+
+    + '(glob-case-insensitive)' # File-glob case sensitivity options
+    '--glob-case-insensitive[treat -g/--glob patterns case insensitively]'
+    $no'--no-glob-case-insensitive[treat -g/--glob patterns case sensitively]'
+
+    + '(heading)' # Heading options
+    '(pretty-vimgrep)--heading[show matches grouped by file name]'
+    "(pretty-vimgrep)--no-heading[don't show matches grouped by file name]"
+
+    + '(hidden)' # Hidden-file options
+    {-.,--hidden}'[search hidden files and directories]'
+    $no"--no-hidden[don't search hidden files and directories]"
+
+    + '(hybrid)' # hybrid regex options
+    '--auto-hybrid-regex[dynamically use PCRE2 if necessary]'
+    $no"--no-auto-hybrid-regex[don't dynamically use PCRE2 if necessary]"
+
+    + '(ignore)' # Ignore-file options
+    "(--no-ignore-global --no-ignore-parent --no-ignore-vcs --no-ignore-dot)--no-ignore[don't respect ignore files]"
+    $no'(--ignore-global --ignore-parent --ignore-vcs --ignore-dot)--ignore[respect ignore files]'
+
+    + '(ignore-file-case-insensitive)' # Ignore-file case sensitivity options
+    '--ignore-file-case-insensitive[process ignore files case insensitively]'
+    $no'--no-ignore-file-case-insensitive[process ignore files case sensitively]'
+
+    + '(ignore-exclude)' # Local exclude (ignore)-file options
+    "--no-ignore-exclude[don't respect local exclude (ignore) files]"
+    $no'--ignore-exclude[respect local exclude (ignore) files]'
+
+    + '(ignore-global)' # Global ignore-file options
+    "--no-ignore-global[don't respect global ignore files]"
+    $no'--ignore-global[respect global ignore files]'
+
+    + '(ignore-parent)' # Parent ignore-file options
+    "--no-ignore-parent[don't respect ignore files in parent directories]"
+    $no'--ignore-parent[respect ignore files in parent directories]'
+
+    + '(ignore-vcs)' # VCS ignore-file options
+    "--no-ignore-vcs[don't respect version control ignore files]"
+    $no'--ignore-vcs[respect version control ignore files]'
+
+    + '(require-git)' # git specific settings
+    "--no-require-git[don't require git repository to respect gitignore rules]"
+    $no'--require-git[require git repository to respect gitignore rules]'
+
+    + '(ignore-dot)' # .ignore options
+    "--no-ignore-dot[don't respect .ignore files]"
+    $no'--ignore-dot[respect .ignore files]'
+
+    + '(ignore-files)' # custom global ignore file options
+    "--no-ignore-files[don't respect --ignore-file flags]"
+    $no'--ignore-files[respect --ignore-file files]'
+
+    + '(json)' # JSON options
+    '--json[output results in JSON Lines format]'
+    $no"--no-json[don't output results in JSON Lines format]"
+
+    + '(line-number)' # Line-number options
+    {-n,--line-number}'[show line numbers for matches]'
+    {-N,--no-line-number}"[don't show line numbers for matches]"
+
+    + '(line-terminator)' # Line-terminator options
+    '--crlf[use CRLF as line terminator]'
+    $no"--no-crlf[don't use CRLF as line terminator]"
+    '(text)--null-data[use NUL as line terminator]'
+
+    + '(max-columns-preview)' # max column preview options
+    '--max-columns-preview[show preview for long lines (with -M)]'
+    $no"--no-max-columns-preview[don't show preview for long lines (with -M)]"
+
+    + '(max-depth)' # Directory-depth options
+    '--max-depth=[specify max number of directories to descend]:number of directories'
+    '!--maxdepth=:number of directories'
+
+    + '(messages)' # Error-message options
+    '(--no-ignore-messages)--no-messages[suppress some error messages]'
+    $no"--messages[don't suppress error messages affected by --no-messages]"
+
+    + '(messages-ignore)' # Ignore-error message options
+    "--no-ignore-messages[don't show ignore-file parse error messages]"
+    $no'--ignore-messages[show ignore-file parse error messages]'
+
+    + '(mmap)' # mmap options
+    '--mmap[search using memory maps when possible]'
+    "--no-mmap[don't search using memory maps]"
+
+    + '(multiline)' # Multiline options
+    {-U,--multiline}'[permit matching across multiple lines]'
+    $no'(multiline-dotall)--no-multiline[restrict matches to at most one line each]'
+
+    + '(multiline-dotall)' # Multiline DOTALL options
+    '(--no-multiline)--multiline-dotall[allow "." to match newline (with -U)]'
+    $no"(--no-multiline)--no-multiline-dotall[don't allow \".\" to match newline (with -U)]"
+
+    + '(only)' # Only-match options
+    {-o,--only-matching}'[show only matching part of each line]'
+
+    + '(passthru)' # Pass-through options
+    '(--vimgrep)--passthru[show both matching and non-matching lines]'
+    '!(--vimgrep)--passthrough'
+
+    + '(pcre2)' # PCRE2 options
+    {-P,--pcre2}'[enable matching with PCRE2]'
+    $no'(pcre2-unicode)--no-pcre2[disable matching with PCRE2]'
+
+    + '(pcre2-unicode)' # PCRE2 Unicode options
+    $no'(--no-pcre2 --no-pcre2-unicode)--pcre2-unicode[enable PCRE2 Unicode mode (with -P)]'
+    '(--no-pcre2 --pcre2-unicode)--no-pcre2-unicode[disable PCRE2 Unicode mode (with -P)]'
+
+    + '(pre)' # Preprocessing options
+    '(-z --search-zip)--pre=[specify preprocessor utility]:preprocessor utility:_command_names -e'
+    $no'--no-pre[disable preprocessor utility]'
+
+    + pre-glob # Preprocessing glob options
+    '*--pre-glob[include/exclude files for preprocessing with --pre]'
+
+    + '(pretty-vimgrep)' # Pretty/vimgrep display options
+    '(heading)'{-p,--pretty}'[alias for --color=always --heading -n]'
+    '(heading passthru)--vimgrep[show results in vim-compatible format]'
+
+    + regexp # Explicit pattern options
+    '(1 file)*'{-e+,--regexp=}'[specify pattern]:pattern'
+
+    + '(replace)' # Replacement options
+    {-r+,--replace=}'[specify string used to replace matches]:replace string'
+
+    + '(sort)' # File-sorting options
+    '(threads)--sort=[sort results in ascending order (disables parallelism)]:sort method:((
+      none\:"no sorting"
+      path\:"sort by file path"
+      modified\:"sort by last modified time"
+      accessed\:"sort by last accessed time"
+      created\:"sort by creation time"
+    ))'
+    '(threads)--sortr=[sort results in descending order (disables parallelism)]:sort method:((
+      none\:"no sorting"
+      path\:"sort by file path"
+      modified\:"sort by last modified time"
+      accessed\:"sort by last accessed time"
+      created\:"sort by creation time"
+    ))'
+    '!(threads)--sort-files[sort results by file path (disables parallelism)]'
+
+    + '(stats)' # Statistics options
+    '(--files file-match)--stats[show search statistics]'
+    $no"--no-stats[don't show search statistics]"
+
+    + '(text)' # Binary-search options
+    {-a,--text}'[search binary files as if they were text]'
+    "--binary[search binary files, don't print binary data]"
+    $no"--no-binary[don't search binary files]"
+    $no"(--null-data)--no-text[don't search binary files as if they were text]"
+
+    + '(threads)' # Thread-count options
+    '(sort)'{-j+,--threads=}'[specify approximate number of threads to use]:number of threads'
+
+    + '(trim)' # Trim options
+    '--trim[trim any ASCII whitespace prefix from each line]'
+    $no"--no-trim[don't trim ASCII whitespace prefix from each line]"
+
+    + type # Type options
+    '*'{-t+,--type=}'[only search files matching specified type]: :_rg_types'
+    '*--type-add=[add new glob for specified file type]: :->typespec'
+    '*--type-clear=[clear globs previously defined for specified file type]: :_rg_types'
+    # This should actually be exclusive with everything but other type options
+    '(: *)--type-list[show all supported file types and their associated globs]'
+    '*'{-T+,--type-not=}"[don't search files matching specified file type]: :_rg_types"
+
+    + '(word-line)' # Whole-word/line match options
+    {-w,--word-regexp}'[only show matches surrounded by word boundaries]'
+    {-x,--line-regexp}'[only show matches surrounded by line boundaries]'
+
+    + '(unicode)' # Unicode options
+    $no'--unicode[enable Unicode mode]'
+    '--no-unicode[disable Unicode mode]'
+
+    + '(zip)' # Compression options
+    '(--pre)'{-z,--search-zip}'[search in compressed files]'
+    $no"--no-search-zip[don't search in compressed files]"
+
+    + misc # Other options — no need to separate these at the moment
+    '(-b --byte-offset)'{-b,--byte-offset}'[show 0-based byte offset for each matching line]'
+    '--color=[specify when to use colors in output]:when:((
+      never\:"never use colors"
+      auto\:"use colors or not based on stdout, TERM, etc."
+      always\:"always use colors"
+      ansi\:"always use ANSI colors (even on Windows)"
+    ))'
+    '*--colors=[specify color and style settings]: :->colorspec'
+    '--context-separator=[specify string used to separate non-continuous context lines in output]:separator'
+    $no"--no-context-separator[don't print context separators]"
+    '--debug[show debug messages]'
+    '--field-context-separator[set string to delimit fields in context lines]'
+    '--field-match-separator[set string to delimit fields in matching lines]'
+    '--trace[show more verbose debug messages]'
+    '--dfa-size-limit=[specify upper size limit of generated DFA]:DFA size (bytes)'
+    "(1 stats)--files[show each file that would be searched (but don't search)]"
+    '*--ignore-file=[specify additional ignore file]:ignore file:_files'
+    '(-v --invert-match)'{-v,--invert-match}'[invert matching]'
+    '(-M --max-columns)'{-M+,--max-columns=}'[specify max length of lines to print]:number of bytes'
+    '(-m --max-count)'{-m+,--max-count=}'[specify max number of matches per file]:number of matches'
+    '--max-filesize=[specify size above which files should be ignored]:file size (bytes)'
+    "--no-config[don't load configuration files]"
+    '(-0 --null)'{-0,--null}'[print NUL byte after file names]'
+    '--path-separator=[specify path separator to use when printing file names]:separator'
+    '(-q --quiet)'{-q,--quiet}'[suppress normal output]'
+    '--regex-size-limit=[specify upper size limit of compiled regex]:regex size (bytes)'
+    '*'{-u,--unrestricted}'[reduce level of "smart" searching]'
+
+    + operand # Operands
+    '(--files --type-list file regexp)1: :_guard "^-*" pattern'
+    '(--type-list)*: :_files'
+  )
+
+  # This is used with test-complete to verify that there are no options
+  # listed in the help output that aren't also defined here
+  [[ $_RG_COMPLETE_LIST_ARGS == (1|t*|y*) ]] && {
+    print -rl - $args
+    return 0
+  }
+
+  # Strip out argument groups where unsupported (see above)
+  [[ $ZSH_VERSION == (4|5.<0-3>)(.*)# ]] &&
+  args=( ${(@)args:#(#i)(+|[a-z0-9][a-z0-9_-]#|\([a-z0-9][a-z0-9_-]#\))} )
+
+  _arguments -C -s -S : $args && ret=0
+
+  case $state in
+    colorspec)
+      if [[ ${IPREFIX#--*=}$PREFIX == [^:]# ]]; then
+        suf=( -qS: )
+        tmp=(
+          'column:specify coloring for column numbers'
+          'line:specify coloring for line numbers'
+          'match:specify coloring for match text'
+          'path:specify coloring for file names'
+        )
+        descr='color/style type'
+      elif [[ ${IPREFIX#--*=}$PREFIX == (column|line|match|path):[^:]# ]]; then
+        suf=( -qS: )
+        tmp=(
+          'none:clear color/style for type'
+          'bg:specify background color'
+          'fg:specify foreground color'
+          'style:specify text style'
+        )
+        descr='color/style attribute'
+      elif [[ ${IPREFIX#--*=}$PREFIX == [^:]##:(bg|fg):[^:]# ]]; then
+        tmp=( black blue green red cyan magenta yellow white )
+        descr='color name or r,g,b'
+      elif [[ ${IPREFIX#--*=}$PREFIX == [^:]##:style:[^:]# ]]; then
+        tmp=( {,no}bold {,no}intense {,no}underline )
+        descr='style name'
+      else
+        _message -e colorspec 'no more arguments'
+      fi
+
+      (( $#tmp )) && {
+        compset -P '*:'
+        _describe -t colorspec $descr tmp $suf && ret=0
+      }
+      ;;
+
+    typespec)
+      if compset -P '[^:]##:include:'; then
+        _sequence -s , _rg_types && ret=0
+      # @todo This bit in particular could be better, but it's a little
+      # complex, and attempting to solve it seems to run us up against a crash
+      # bug — zsh # 40362
+      elif compset -P '[^:]##:'; then
+        _message 'glob or include directive' && ret=1
+      elif [[ ! -prefix *:* ]]; then
+        _rg_types -qS : && ret=0
+      fi
+      ;;
+  esac
+
+  return ret
+}
+
+# Complete encodings
+_rg_encodings() {
+  local -a expl
+  local -aU _encodings
+
+  # This is impossible to read, but these encodings rarely if ever change, so it
+  # probably doesn't matter. They are derived from the list given here:
+  # https://encoding.spec.whatwg.org/#concept-encoding-get
+  _encodings=(
+    {{,us-}ascii,arabic,chinese,cyrillic,greek{,8},hebrew,korean}
+    logical visual mac {,cs}macintosh x-mac-{cyrillic,roman,ukrainian}
+    866 ibm{819,866} csibm866
+    big5{,-hkscs} {cn-,cs}big5 x-x-big5
+    cp{819,866,125{0..8}} x-cp125{0..8}
+    csiso2022{jp,kr} csiso8859{6,8}{e,i}
+    csisolatin{{1..6},9} csisolatin{arabic,cyrillic,greek,hebrew}
+    ecma-{114,118} asmo-708 elot_928 sun_eu_greek
+    euc-{jp,kr} x-euc-jp cseuckr cseucpkdfmtjapanese
+    {,x-}gbk csiso58gb231280 gb18030 {,cs}gb2312 gb_2312{,-80} hz-gb-2312
+    iso-2022-{cn,cn-ext,jp,kr}
+    iso8859{,-}{{1..11},13,14,15}
+    iso-8859-{{1..11},{6,8}-{e,i},13,14,15,16} iso_8859-{{1..9},15}
+    iso_8859-{1,2,6,7}:1987 iso_8859-{3,4,5,8}:1988 iso_8859-9:1989
+    iso-ir-{58,100,101,109,110,126,127,138,144,148,149,157}
+    koi{,8,8-r,8-ru,8-u,8_r} cskoi8r
+    ks_c_5601-{1987,1989} ksc{,_}5691 csksc56011987
+    latin{1..6} l{{1..6},9}
+    shift{-,_}jis csshiftjis {,x-}sjis ms_kanji ms932
+    utf{,-}8 utf-16{,be,le} unicode-1-1-utf-8
+    windows-{31j,874,949,125{0..8}} dos-874 tis-620 ansi_x3.4-1968
+    x-user-defined auto none
+  )
+
+  _wanted encodings expl encoding compadd -a "$@" - _encodings
+}
+
+# Complete file types
+_rg_types() {
+  local -a expl
+  local -aU _types
+
+  _types=( ${(@)${(f)"$( _call_program types rg --type-list )"}%%:*} )
+
+  _wanted types expl 'file type' compadd -a "$@" - _types
+}
+
+_rg "$@"
+
+################################################################################
+# ZSH COMPLETION REFERENCE
+#
+# For the convenience of developers who aren't especially familiar with zsh
+# completion functions, a brief reference guide follows. This is in no way
+# comprehensive; it covers just enough of the basic structure, syntax, and
+# conventions to help someone make simple changes like adding new options. For
+# more complete documentation regarding zsh completion functions, please see the
+# following:
+#
+# * http://zsh.sourceforge.net/Doc/Release/Completion-System.html
+# * https://github.com/zsh-users/zsh/blob/master/Etc/completion-style-guide
+#
+# OVERVIEW
+#
+# Most zsh completion functions are defined in terms of `_arguments`, which is a
+# shell function that takes a series of argument specifications. The specs for
+# `rg` are stored in an array, which is common for more complex functions; the
+# elements of the array are passed to `_arguments` on invocation.
+#
+# ARGUMENT-SPECIFICATION SYNTAX
+#
+# The following is a contrived example of the argument specs for a simple tool:
+#
+#   '(: * -)'{-h,--help}'[display help information]'
+#   '(-q -v --quiet --verbose)'{-q,--quiet}'[decrease output verbosity]'
+#   '!(-q -v --quiet --verbose)--silent'
+#   '(-q -v --quiet --verbose)'{-v,--verbose}'[increase output verbosity]'
+#   '--color=[specify when to use colors]:when:(always never auto)'
+#   '*:example file:_files'
+#
+# Although there may appear to be six specs here, there are actually nine; we
+# use brace expansion to combine specs for options that go by multiple names,
+# like `-q` and `--quiet`. This is customary, and ties in with the fact that zsh
+# merges completion possibilities together when they have the same description.
+#
+# The first line defines the option `-h`/`--help`. With most tools, it isn't
+# useful to complete anything after `--help` because it effectively overrides
+# all others; the `(: * -)` at the beginning of the spec tells zsh not to
+# complete any other operands (`:` and `*`) or options (`-`) after this one has
+# been used. The `[...]` at the end associates a description with `-h`/`--help`;
+# as mentioned, zsh will see the identical descriptions and merge these options
+# together when offering completion possibilities.
+#
+# The next line defines `-q`/`--quiet`. Here we don't want to suppress further
+# completions entirely, but we don't want to offer `-q` if `--quiet` has been
+# given (since they do the same thing), nor do we want to offer `-v` (since it
+# doesn't make sense to be quiet and verbose at the same time). We don't need to
+# tell zsh not to offer `--quiet` a second time, since that's the default
+# behaviour, but since this line expands to two specs describing `-q` *and*
+# `--quiet` we do need to explicitly list all of them here.
+#
+# The next line defines a hidden option `--silent` — maybe it's a deprecated
+# synonym for `--quiet`. The leading `!` indicates that zsh shouldn't offer this
+# option during completion. The benefit of providing a spec for an option that
+# shouldn't be completed is that, if someone *does* use it, we can correctly
+# suppress completion of other options afterwards.
+#
+# The next line defines `-v`/`--verbose`; this works just like `-q`/`--quiet`.
+#
+# The next line defines `--color`. In this example, `--color` doesn't have a
+# corresponding short option, so we don't need to use brace expansion. Further,
+# there are no other options it's exclusive with (just itself), so we don't need
+# to define those at the beginning. However, it does take a mandatory argument.
+# The `=` at the end of `--color=` indicates that the argument may appear either
+# like `--color always` or like `--color=always`; this is how most GNU-style
+# command-line tools work. The corresponding short option would normally use `+`
+# — for example, `-c+` would allow either `-c always` or `-calways`. For this
+# option, the arguments are known ahead of time, so we can simply list them in
+# parentheses at the end (`when` is used as the description for the argument).
+#
+# The last line defines an operand (a non-option argument). In this example, the
+# operand can be used any number of times (the leading `*`), and it should be a
+# file path, so we tell zsh to call the `_files` function to complete it. The
+# `example file` in the middle is the description to use for this operand; we
+# could use a space instead to accept the default provided by `_files`.
+#
+# GROUPING ARGUMENT SPECIFICATIONS
+#
+# Newer versions of zsh support grouping argument specs together. All specs
+# following a `+` and then a group name are considered to be members of the
+# named group. Grouping is useful mostly for organisational purposes; it makes
+# the relationship between different options more obvious, and makes it easier
+# to specify exclusions.
+#
+# We could rewrite our example above using grouping as follows:
+#
+#   '(: * -)'{-h,--help}'[display help information]'
+#   '--color=[specify when to use colors]:when:(always never auto)'
+#   '*:example file:_files'
+#   + '(verbosity)'
+#   {-q,--quiet}'[decrease output verbosity]'
+#   '!--silent'
+#   {-v,--verbose}'[increase output verbosity]'
+#
+# Here we take advantage of a useful feature of spec grouping — when the group
+# name is surrounded by parentheses, as in `(verbosity)`, it tells zsh that all
+# of the options in that group are exclusive with each other. As a result, we
+# don't need to manually list out the exclusions at the beginning of each
+# option.
+#
+# Groups can also be referred to by name in other argument specs; for example:
+#
+#   '(xyz)--aaa' '*: :_files'
+#   + xyz --xxx --yyy --zzz
+#
+# Here we use the group name `xyz` to tell zsh that `--xxx`, `--yyy`, and
+# `--zzz` are not to be completed after `--aaa`. This makes the exclusion list
+# much more compact and reusable.
+#
+# CONVENTIONS
+#
+# zsh completion functions generally adhere to the following conventions:
+#
+# * Use two spaces for indentation
+# * Combine specs for options with different names using brace expansion
+# * In combined specs, list the short option first (as in `{-a,--text}`)
+# * Use `+` or `=` as described above for options that take arguments
+# * Provide a description for all options, option-arguments, and operands
+# * Capitalise/punctuate argument descriptions as phrases, not complete
+#   sentences — 'display help information', never 'Display help information.'
+#   (but still capitalise acronyms and proper names)
+# * Write argument descriptions as verb phrases — 'display x', 'enable y',
+#   'use z'
+# * Word descriptions to make it clear when an option expects an argument;
+#   usually this is done with the word 'specify', as in 'specify x' or
+#   'use specified x')
+# * Write argument descriptions as tersely as possible — for example, articles
+#   like 'a' and 'the' should be omitted unless it would be confusing
+#
+# Other conventions currently used by this function:
+#
+# * Order argument specs alphabetically by group name, then option name
+# * Group options that are directly related, mutually exclusive, or frequently
+#   referenced by other argument specs
+# * Use only characters in the set [a-z0-9_-] in group names
+# * Order exclusion lists as follows: short options, long options, groups
+# * Use American English in descriptions
+# * Use 'don't' in descriptions instead of 'do not'
+# * Word descriptions for related options as similarly as possible. For example,
+#   `--foo[enable foo]` and `--no-foo[disable foo]`, or `--foo[use foo]` and
+#   `--no-foo[don't use foo]`
+# * Word descriptions to make it clear when an option only makes sense with
+#   another option, usually by adding '(with -x)' to the end
+# * Don't quote strings or variables unnecessarily. When quotes are required,
+#   prefer single-quotes to double-quotes
+# * Prefix option specs with `$no` when the option serves only to negate the
+#   behaviour of another option that must be provided explicitly by the user.
+#   This prevents rarely used options from cluttering up the completion menu
+################################################################################
+
+# ------------------------------------------------------------------------------
+# Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for ripgrep
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * arcizan <ghostrevery@gmail.com>
+#  * MaskRay <i@maskray.me>
+#
+# ------------------------------------------------------------------------------
+
+# Local Variables:
+# mode: shell-script
+# coding: utf-8-unix
+# indent-tabs-mode: nil
+# sh-indentation: 2
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ros/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ros/README.md
new file mode 100644 (file)
index 0000000..83573e4
--- /dev/null
@@ -0,0 +1,10 @@
+# Roswell Plugin
+
+This plugin adds completions and aliases for [Roswell](https://github.com/roswell/roswell/).
+
+To use it, add `ros` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ros)
+```
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ros/_ros b/stow/oh-my-zsh/.oh-my-zsh/plugins/ros/_ros
new file mode 100644 (file)
index 0000000..6a04d3c
--- /dev/null
@@ -0,0 +1,64 @@
+#compdef ros
+#autoload
+
+# roswell zsh completion, based on gem completion
+
+local -a _1st_arguments
+_1st_arguments=(
+'run: Run repl'
+'install:Install a given implementation or a system for roswell environment'
+'update:Update installed systems.'
+'build:Make executable from script.'
+'use:Change default implementation.'
+'init:a new ros script, optionally based on a template.'
+'fmt:Indent lisp source.'
+'list:Information'
+'template:[WIP] Manage templates'
+'delete:Delete installed implementations'
+'config:Get and set options'
+'version:Show the roswell version information'
+"help:Use \"ros help [command]\" for more information about a command."$'\n\t\t'"Use \"ros help [topic]\" for more information about the topic."
+) 
+
+#local expl
+
+_arguments \
+  '(--version)'--version'[Print version information and quit]' \
+  '(-w --wrap)'{-w,--wrap}'[\[CODE\] Run roswell with a shell wrapper CODE]' \
+  '(-m --image)'{-m,--image}'[\[IMAGE\] continue from Lisp image IMAGE]' \
+  '(-M --module)'{-M,--module}'[\[NAME\] Execute ros script found in ROSWELLPATH. (pythons -m)]' \
+  '(-L --lisp)'{-L,--lisp}'[\[NAME\] Run roswell with a lisp impl NAME\[/VERSION\].]' \
+  '(-l --load)'{-l,--load}'[\[FILE\] load lisp FILE while building]' \
+  '(-S --source-registry)'{-S,--source-registry}'[\[X\] override source registry of asdf systems]' \
+  '(-s --system --load-system)'{-s,--system,--load-system}'[\[SYSTEM\] load asdf SYSTEM while building]' \
+  '(-p --package)'{-p,--package}'[\[PACKAGE\] change current package to \[PACKAGE\]]' \
+  '(-sp --system-package)'{-sp,--system-package}'[\[SP\] combination of -s \[SP\] and -p \[SP\]]' \
+  '(-e --eval)'{-e,--eval}'[\[FORM\] evaluate \[FORM\] while building]' \
+  '--require'--require'[\[MODULE\] require \[MODULE\] while building]' \
+  '(-q --quit)'{-q,--quit}'[quit lisp here]' \
+  '(-r --restart)'{-r,--restart}'[\[FUNC\] restart from build by calling (\[FUNC\])]' \
+  '(-E --entry)'{-E,--entry}'[\[FUNC\] restart from build by calling (\[FUNC\] argv)]' \
+  '(-i --init)'{-i,--init}'[\[FORM\] evaluate \[FORM\] after restart]' \
+  '(-ip --print)'{-ip,--print}'[\[FORM\] evaluate and princ \[FORM\] after restart]' \
+  '(-iw --write)'{-iw,--write}'[\[FORM\] evaluate and write \[FORM\] after restart]' \
+  '(-F --final)'{-F,--final}'[\[FORM\] evaluate \[FORM\] before dumping IMAGE]' \
+  '(\+R --no-rc)'{\+R,--no-rc}'[skip /etc/rosrc, ~/.roswell/init.lisp]' \
+  '(-A --asdf)'{-A,--asdf}'[use new asdf]' \
+  '(\+Q --no-quicklisp)'{\+Q,--no-quicklisp}'[do not use quicklisp]' \
+  '(-v --verbose)'{-v,--verbose}'[be quite noisy while building]' \
+  '--quiet'--quiet'[be quite quiet while building default]' \
+  '--test'--test'[for test purpose]' \
+  '*:: :->subcmds'  && return 0
+
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "ros subcommand" _1st_arguments
+  return
+fi
+
+# _files
+case "$words[1]" in
+  -l|--load)
+    _files
+    ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rsync/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rsync/README.md
new file mode 100644 (file)
index 0000000..032ee7f
--- /dev/null
@@ -0,0 +1,16 @@
+# rsync
+
+This plugin adds aliases for frequent [rsync](https://rsync.samba.org/) commands.
+
+To use it add `rsync` to the plugins array in you zshrc file.
+
+```zsh
+plugins=(... rsync)
+```
+
+| Alias               | Command                                          |
+| ------------------- | ------------------------------------------------ |
+| *rsync-copy*        | `rsync -avz --progress -h`                       |
+| *rsync-move*        | `rsync -avz --progress -h --remove-source-files` |
+| *rsync-update*      | `rsync -avzu --progress -h`                      |
+| *rsync-synchronize* | `rsync -avzu --delete --progress -h`             |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rsync/rsync.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rsync/rsync.plugin.zsh
new file mode 100644 (file)
index 0000000..1a3bb4c
--- /dev/null
@@ -0,0 +1,4 @@
+alias rsync-copy="rsync -avz --progress -h"
+alias rsync-move="rsync -avz --progress -h --remove-source-files"
+alias rsync-update="rsync -avzu --progress -h"
+alias rsync-synchronize="rsync -avzu --delete --progress -h"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ruby/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ruby/README.md
new file mode 100644 (file)
index 0000000..59d839c
--- /dev/null
@@ -0,0 +1,33 @@
+# Ruby plugin
+
+This plugin adds aliases for common commands used in dealing with [Ruby](https://www.ruby-lang.org/en/) and [gem packages](https://rubygems.org/).
+
+To use it, add `ruby` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ruby)
+```
+
+## Aliases
+
+| Alias   | Command                                | Description                                          |
+| ------- | -------------------------------------- | ---------------------------------------------------- |
+| rb      | `ruby`                                 | The Ruby command                                     |
+| sgem    | `sudo gem`                             | Run sudo gem on the system ruby, not the active ruby |
+| rfind   | `find . -name "*.rb" \| xargs grep -n` | Find ruby file                                       |
+| rrun    | `ruby -e`                              | Execute some code: E.g: `rrun "puts 'Hello world!'"` |
+| rserver | `ruby -e httpd . -p 8080`              | Start HTTP Webrick serving local directory/files     |
+| gein    | `gem install`                          | Install a gem into the local repository              |
+| geun    | `gem uninstall`                        | Uninstall gems from the local repository             |
+| geli    | `gem list`                             | Display gems installed locally                       |
+| gei     | `gem info`                             | Show information for the given gem                   |
+| geiall  | `gem info --all`                       | Display all gem versions                             |
+| geca    | `gem cert --add`                       | Add a trusted certificate                            |
+| gecr    | `gem cert --remove`                    | Remove a trusted certificate                         |
+| gecb    | `gem cert --build`                     | Build private key and self-signed certificate        |
+| geclup  | `gem cleanup -n`                       | Do not uninstall gem                                 |
+| gegi    | `gem generate_index`                   | Generate index file for gem server                   |
+| geh     | `gem help`                             | Provide additional help                              |
+| gel     | `gem lock`                             | Generate a lockdown list of gems                     |
+| geo     | `gem open`                             | Open gem source in default editor                    |
+| geoe    | `gem open -e`                          | Open gem sources in preferred editor                 |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ruby/ruby.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ruby/ruby.plugin.zsh
new file mode 100644 (file)
index 0000000..4085121
--- /dev/null
@@ -0,0 +1,26 @@
+# Run sudo gem on the system ruby, not the active ruby
+alias sgem='sudo gem'
+
+# Find ruby file
+alias rfind='find . -name "*.rb" | xargs grep -n'
+
+# Shorthand Ruby
+alias rb="ruby"
+
+# Gem Command Shorthands
+alias gein="gem install"
+alias geun="gem uninstall"
+alias geli="gem list"
+alias gei="gem info"
+alias geiall="gem info --all"
+alias geca="gem cert --add"
+alias gecr="gem cert --remove"
+alias gecb="gem cert --build"
+alias geclup="gem cleanup -n"
+alias gegi="gem generate_index"
+alias geh="gem help"
+alias gel="gem lock"
+alias geo="gem open"
+alias geoe="gem open -e"
+alias rrun="ruby -e"
+alias rserver="ruby -e httpd . -p 8080" # requires webrick
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rust/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rust/README.md
new file mode 100644 (file)
index 0000000..e053644
--- /dev/null
@@ -0,0 +1,9 @@
+# rust
+
+This plugin adds completion for [`rustc`](https://doc.rust-lang.org/rustc/index.html), the compiler for the Rust programming language, as well as for `rustup` and `cargo` if you have the Rust toolchain installed.
+
+To use it, add `rust` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rust)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rust/_rustc b/stow/oh-my-zsh/.oh-my-zsh/plugins/rust/_rustc
new file mode 100644 (file)
index 0000000..6e3f344
--- /dev/null
@@ -0,0 +1,228 @@
+#compdef rustc
+
+local -a _rustc_opts_switches _rustc_opts_lint _rustc_opts_debug
+
+typeset -A opt_args
+
+_rustc_debuginfo_levels=(
+    "0[no debug info]"
+    "1[line-tables only (for stacktraces and breakpoints)]"
+    "2[full debug info with variable and type information (same as -g)]"
+)
+
+_rustc_crate_types=(
+    'bin'
+    'lib'
+    'rlib'
+    'dylib'
+    'cdylib'
+    'staticlib'
+    'proc-macro'
+)
+
+_rustc_emit_types=(
+    'asm'
+    'llvm-bc'
+    'llvm-ir'
+    'obj'
+    'metadata'
+    'link'
+    'dep-info'
+    'mir'
+)
+_rustc_print_types=(
+    'crate-name'
+    'file-names'
+    'sysroot'
+    'cfg'
+    'target-list'
+    'target-cpus'
+    'target-features'
+    'relocation-models'
+    'code-models'
+    'target-spec-json'
+    'native-static-libs'
+)
+_rustc_pretty_types=(
+    'normal[un-annotated source]'
+    'expanded[crates expanded]'
+    'expanded,identified[fully parenthesized, AST nodes with IDs]'
+)
+_rustc_unpretty_types=(
+    'normal[un-annotated source]'
+    'expanded[crates expanded]'
+    'expanded,identified[fully parenthesized, AST nodes with IDs]'
+    'flowgraph=[graphviz formatted flowgraph for node]:NODEID:'
+    'everybody_loops[all function bodies replaced with `loop {}`]'
+    'hir[the HIR]'
+    'hir,identified'
+    'hir,typed[HIR with types for each node]'
+)
+_rustc_color_types=(
+    'auto[colorize, if output goes to a tty (default)]'
+    'always[always colorize output]'
+    'never[never colorize output]'
+)
+_rustc_error_format=(
+    'human'
+    'json'
+)
+
+_rustc_opts_vals=(
+    --cfg='[Configure the compilation environment]:SPEC:'
+    -L'[Add a directory to the library search path]:DIR:_files -/'
+    --crate-name='[Specify the name of the crate being built]'
+    --crate-type='[Comma separated list of types of crates for the compiler to emit]:TYPES:_values -s "," "Crate types"  "$_rustc_crate_types[@]"'
+    --emit='[Comma separated list of types of output for the compiler to emit]:TYPES:_values -s "," "Emit Targets" "$_rustc_emit_types[@]"'
+    --print='[Comma separated list of compiler information to print on stdout]:TYPES:_values -s "," "Printable info" "$_rustc_print_types[@]"'
+    -o'[Write output to <filename>. Ignored if more than one --emit is specified.]:FILENAME:_files'
+    --out-dir='[Write output to compiler-chosen filename in <dir>.  Ignored  if  -o  is  specified. (default the current directory)]:DIR:_files -/'
+    --explain='[Provide a detailed explanation of an error message]:OPT:'
+    --target='[Target triple cpu-manufacturer-kernel\[-os\] to compile]:TRIPLE:'
+    --extern'[Specify where an external rust library is located]:ARG:'
+    --sysroot='[Override the system root]:PATH:_files -/'
+    --error-format='[How errors and other messages are produced]:TYPES:_values "$_rustc_error_format"'
+    --debuginfo='[Emit DWARF debug info to the objects created]:LEVEL:_values "Debug Levels" "$_rustc_debuginfo_levels[@]"'
+    --dep-info='[Output dependency info to <filename> after compiling]::FILE:_files -/'
+    --opt-level='[Optimize with possible levels 0-3]:LEVEL:(0 1 2 3)'
+    --pretty='[Pretty-print the input instead of compiling]::TYPE:_values "TYPES" "$_rustc_pretty_types[@]"'
+    --unpretty='[Present the input source, unstable (and less-pretty)]::TYPE:_values "TYPES" "$_rustc_unpretty_types[@]"'
+    --color='[Configure coloring of output]:CONF:_values "COLORS" "$_rustc_color_types[@]"'
+)
+
+_rustc_opts_switches=(
+    -g'[Equivalent to --debuginfo=2]'
+    -O'[Equivalent to --opt-level=2]'
+    --test'[Build a test harness]'
+    {-v,--verbose}'[Use verbose output]'
+    {-V,--version}'[Print version info and exit]'
+    {-h,--help}'[Display this message]'
+    --no-analysis'[Parse and expand the output, but run no analysis or produce output]'
+    --no-trans'[Run all passes except translation; no output]'
+    --parse-only'[Parse only; do not compile, assemble, or link]'
+    --print-crate-name'[Output the crate name and exit]'
+    --print-file-name'[Output the file(s) that would be written if compilation continued and exit]'
+)
+_rustc_opts_codegen=(
+    'ar=[Path to the archive utility to use when assembling archives.]:BIN:_path_files'
+    'linker=[Path to the linker utility to use when linking libraries, executables, and objects.]:BIN:_path_files'
+    'link-args=[A space-separated list of extra arguments to pass to the linker when the linker is invoked.]:ARGS:'
+    'target-cpu=[Selects a target processor. If the value is "help", then a list of  available  CPUs is printed.]:CPU:'
+    'target-feature=[A space-separated list of features to enable or disable for the target. A preceding "+" enables a feature while a preceding "-" disables it. Available features can be discovered through target-cpu=help.]:FEATURE:'
+    'passes=[A space-separated list of extra LLVM passes to run. A value of "list" will cause rustc to print all known passes and exit. The passes specified are appended at the end of the normal pass manager.]:LIST:'
+    'llvm-args=[A space-separated list of arguments to pass through to LLVM.]:ARGS:'
+    'save-temps[If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated throughout compilation in the output directory.]'
+    'rpath[If specified, then the rpath value for dynamic libraries will be set in either dynamic library or executable outputs.]'
+    'no-prepopulate-passes[Suppresses pre-population of the LLVM pass manager that is run over the module.]'
+    'no-vectorize-loops[Suppresses running the loop vectorization LLVM pass, regardless of optimization level.]'
+    'no-vectorize-slp[Suppresses running the LLVM SLP vectorization pass, regardless of optimization level.]'
+    'soft-float[Generates software floating point library calls instead of hardware instructions.]'
+    'prefer-dynamic[Prefers dynamic linking to static linking.]'
+    "no-integrated-as[Force usage of an external assembler rather than LLVM's integrated one.]"
+    'no-redzone[disable the use of the redzone]'
+    'relocation-model=[The relocation model to use. (default: pic)]:MODEL:(pic static dynamic-no-pic)'
+    'code-model=[choose the code model to use (llc -code-model for details)]:MODEL:'
+    'metadata=[metadata to mangle symbol names with]:VAL:'
+    'extra-filenames=[extra data to put in each output filename]:VAL:'
+    'codegen-units=[divide crate into N units to optimize in parallel]:N:'
+    'help[Show all codegen options]'
+)
+
+_rustc_opts_lint=(
+    'help[Show a list of all lints]'
+    'experimental[detects use of #\[experimental\] items]'
+    'heap-memory[use of any (Box type or @ type) heap memory]'
+    'managed-heap-memory[use of managed (@ type) heap memory]'
+    'missing-doc[detects missing documentation for public members]'
+    'non-uppercase-statics[static constants should have uppercase identifiers]'
+    'owned-heap-memory[use of owned (~ type) heap memory]'
+    'unnecessary-qualification[detects unnecessarily qualified names]'
+    'unsafe-block[usage of an `unsafe` block]'
+    'unstable[detects use of #\[unstable\] items (incl. items with no stability attribute)]'
+    'unused-result[unused result of an expression in a statement]'
+    'variant-size-difference[detects enums with widely varying variant sizes]'
+    'ctypes[proper use of libc types in foreign modules]'
+    'dead-assignment[detect assignments that will never be read]'
+    'dead-code[detect piece of code that will never be used]'
+    'deprecated[detects use of #\[deprecated\] items]'
+    'non-camel-case-types[types, variants and traits should have camel case names]'
+    'non-snake-case[methods, functions, lifetime parameters and modules should have snake case names]'
+    'path-statement[path statements with no effect]'
+    'raw-pointer-deriving[uses of #\[deriving\] with raw pointers are rarely correct]'
+    'type-limits[comparisons made useless by limits of the types involved]'
+    'type-overflow[literal out of range for its type]'
+    'unnecessary-allocation[detects unnecessary allocations that can be eliminated]'
+    'unnecessary-parens[`if`, `match`, `while` and `return` do not need parentheses]'
+    'unreachable-code[detects unreachable code]'
+    'unrecognized-lint[unrecognized lint attribute]'
+    'unsigned-negate[using an unary minus operator on unsigned type]'
+    'unused-attribute[detects attributes that were not used by the compiler]'
+    'unused-imports[imports that are never used]'
+    'unused-must-use[unused result of a type flagged as #\[must_use\]]'
+    "unused-mut[detect mut variables which don't need to be mutable]"
+    'unused-unsafe[unnecessary use of an `unsafe` block]'
+    'unused-variable[detect variables which are not used in any way]'
+    'visible-private-types[detect use of private types in exported type signatures]'
+    'warnings[mass-change the level for lints which produce warnings]'
+    'while-true[suggest using `loop { }` instead of `while true { }`]'
+    'unknown-crate-type[unknown crate type found in #\[crate_type\] directive]'
+    'unknown-features[unknown features found in crate-level #\[feature\] directives]'
+    'bad-style[group of non_camel_case_types, non_snake_case, non_uppercase_statics]'
+    'unused[group of unused_imports, unused_variable, dead_assignment, dead_code, unused_mut, unreachable_code]'
+)
+
+_rustc_opts_debug=(
+    'verbose[in general, enable more debug printouts]'
+    'span-free-formats[when debug-printing compiler state, do not include spans]'
+    "identify-regions[make unnamed regions display as '# (where # is some non-ident unique id)]"
+    'emit-end-regions[emit EndRegion as part of MIR; enable transforms that solely process EndRegion]'
+    'time-passes[measure time of each rustc pass]'
+    'count-llvm-insns[count where LLVM instrs originate]'
+    'time-llvm-passes[measure time of each LLVM pass]'
+    'trans-stats[gather trans statistics]'
+    'asm-comments[generate comments into the assembly (may change behavior)]'
+    'no-verify[skip LLVM verification]'
+    'borrowck-stats[gather borrowck statistics]'
+    'no-landing-pads[omit landing pads for unwinding]'
+    'debug-llvm[enable debug output from LLVM]'
+    'show-span[show spans for compiler debugging]'
+    'count-type-sizes[count the sizes of aggregate types]'
+    'meta-stats[gather metadata statistics]'
+    'no-opt[do not optimize, even if -O is passed]'
+    'print-link-args[Print the arguments passed to the linker]'
+    'gc[Garbage collect shared data (experimental)]'
+    'print-llvm-passes[Prints the llvm optimization passes being run]'
+    'lto[Perform LLVM link-time optimizations]'
+    'ast-json[Print the AST as JSON and halt]'
+    'ast-json-noexpand[Print the pre-expansion AST as JSON and halt]'
+    'ls[List the symbols defined by a library crate]'
+    'save-analysis[Write syntax and type analysis information in addition to normal output]'
+    'flowgraph-print-loans[Include loan analysis data in --pretty flowgraph output]'
+    'flowgraph-print-moves[Include move analysis data in --pretty flowgraph output]'
+    'flowgraph-print-assigns[Include assignment analysis data in --pretty flowgraph output]'
+    'flowgraph-print-all[Include all dataflow analysis data in --pretty flowgraph output]'
+)
+
+_rustc_opts_fun_lint(){
+    _values -s , 'options' \
+        "$_rustc_opts_lint[@]"
+}
+
+_rustc_opts_fun_debug(){
+    _values 'options' "$_rustc_opts_debug[@]"
+}
+
+_rustc_opts_fun_codegen(){
+    _values 'options' "$_rustc_opts_codegen[@]"
+}
+
+_arguments -s :  \
+    '(-W --warn)'{-W,--warn=}'[Set lint warnings]:lint options:_rustc_opts_fun_lint' \
+    '(-A --allow)'{-A,--allow=}'[Set lint allowed]:lint options:_rustc_opts_fun_lint' \
+    '(-D --deny)'{-D,--deny=}'[Set lint denied]:lint options:_rustc_opts_fun_lint' \
+    '(-F --forbid)'{-F,--forbid=}'[Set lint forbidden]:lint options:_rustc_opts_fun_lint' \
+    '*-Z[Set internal debugging options]:debug options:_rustc_opts_fun_debug' \
+    '*-C[Set internal Codegen options]:codegen options:_rustc_opts_fun_codegen' \
+    "$_rustc_opts_switches[@]" \
+    "$_rustc_opts_vals[@]" \
+    '::files:_files -g "*.rs"'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rust/rust.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rust/rust.plugin.zsh
new file mode 100644 (file)
index 0000000..858f141
--- /dev/null
@@ -0,0 +1,26 @@
+if ! (( $+commands[rustup] && $+commands[cargo] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `cargo`. Otherwise, compinit will have already done that
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_cargo" ]]; then
+  autoload -Uz _cargo
+  typeset -g -A _comps
+  _comps[cargo]=_cargo
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `rustup`. Otherwise, compinit will have already done that
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_rustup" ]]; then
+  autoload -Uz _rustup
+  typeset -g -A _comps
+  _comps[rustup]=_rustup
+fi
+
+# Generate completion files in the background
+rustup completions zsh >| "$ZSH_CACHE_DIR/completions/_rustup" &|
+cat >| "$ZSH_CACHE_DIR/completions/_cargo" <<'EOF'
+#compdef cargo
+source "$(rustc +${${(z)$(rustup default)}[1]} --print sysroot)"/share/zsh/site-functions/_cargo
+EOF
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rvm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/rvm/README.md
new file mode 100644 (file)
index 0000000..576b037
--- /dev/null
@@ -0,0 +1,36 @@
+# Ruby Version Manager plugin
+
+This plugin adds some utility functions and completions for [Ruby Version Manager](https://rvm.io/).
+
+To use it, add `rvm` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rvm)
+```
+
+## Aliases
+
+| Alias        | Command              |
+| ------------ | -------------------- |
+| `rb18`       | `rvm use ruby-1.8.7` |
+| `rb19`       | `rvm use ruby-1.9.3` |
+| `rb20`       | `rvm use ruby-2.0.0` |
+| `rb21`       | `rvm use ruby-2.1`   |
+| `rb22`       | `rvm use ruby-2.2`   |
+| `rb23`       | `rvm use ruby-2.3`   |
+| `rb24`       | `rvm use ruby-2.4`   |
+| `rb25`       | `rvm use ruby-2.5`   |
+| `rb26`       | `rvm use ruby-2.6`   |
+| `rb27`       | `rvm use ruby-2.7`   |
+| `rb30`       | `rvm use ruby-3.0`   |
+| `rb31`       | `rvm use ruby-3.1`   |
+| `rvm-update` | `rvm get head`       |
+| `gems`       | `gem list`           |
+| `rvms`       | `rvm gemset`         |
+
+## Deprecated versions
+
+At the time of writing this (2021-12-28), Ruby versions until 2.5 are [EOL][1],
+and will be removed in the future.
+
+[1]: https://endoflife.date/ruby
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/rvm/rvm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/rvm/rvm.plugin.zsh
new file mode 100644 (file)
index 0000000..2a091d0
--- /dev/null
@@ -0,0 +1,55 @@
+# Completion
+fpath+=("${rvm_path}/scripts/zsh/Completion")
+
+typeset -g -A _comps
+autoload -Uz _rvm
+_comps[rvm]=_rvm
+
+# Aliases
+alias rubies='rvm list rubies'
+alias rvms='rvm gemset'
+alias gemsets='rvms list'
+
+
+# rb{version} utilities
+# From `rvm list known`
+typeset -A rubies
+rubies=(
+  18  'ruby-1.8.7'
+  19  'ruby-1.9.3'
+  20  'ruby-2.0.0'
+  21  'ruby-2.1'
+  22  'ruby-2.2'
+  23  'ruby-2.3'
+  24  'ruby-2.4'
+  25  'ruby-2.5'
+  26  'ruby-2.6'
+  27  'ruby-2.7'
+  30  'ruby-3.0'
+  31  'ruby-3.1'
+)
+
+for v in ${(k)rubies}; do
+  version="${rubies[$v]}"
+  functions[rb${v}]="rvm use ${version}\${1+"@\$1"}"
+  functions[_rb${v}]="compadd \$(ls -1 \"\${rvm_path}/gems\" | grep '^${version}@' | sed -e 's/^${version}@//' | awk '{print $1}')"
+  compdef _rb$v rb$v
+done
+unset rubies v version
+
+
+function rvm-update {
+  rvm get head
+}
+
+# TODO: Make this usable w/o rvm.
+function gems {
+  local current_ruby=`rvm-prompt i v p`
+  local current_gemset=`rvm-prompt g`
+
+  gem list $@ | sed -E \
+    -e "s/\([0-9, \.]+( .+)?\)/$fg[blue]&$reset_color/g" \
+    -e "s|$(echo $rvm_path)|$fg[magenta]\$rvm_path$reset_color|g" \
+    -e "s/$current_ruby@global/$fg[yellow]&$reset_color/g" \
+    -e "s/$current_ruby$current_gemset$/$fg[green]&$reset_color/g"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/safe-paste/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/safe-paste/README.md
new file mode 100644 (file)
index 0000000..a2e7ddb
--- /dev/null
@@ -0,0 +1,9 @@
+# safe-paste
+
+Preventing any code from actually running while pasting, so you have a chance to review what was actually pasted before running it.
+
+To use it, add `safe-paste` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... safe-paste)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/safe-paste/safe-paste.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/safe-paste/safe-paste.plugin.zsh
new file mode 100644 (file)
index 0000000..d443ae8
--- /dev/null
@@ -0,0 +1,100 @@
+# A good summary of the zsh 5.1 Bracketed Paste Mode changes is at:
+# https://archive.zhimingwang.org/blog/2015-09-21-zsh-51-and-bracketed-paste.html
+
+# zsh 5.1 (September 2015) introduced built-in support for Bracketed Paste Mode
+# https://github.com/zsh-users/zsh/blob/68405f31a043bdd5bf338eb06688ed3e1f740937/README#L38-L45
+#
+# zsh 5.1 breaks url-quote-magic and other widgets replacing self-insert
+# zsh-users' bracketed-paste-magic resolves these issues:
+# https://github.com/zsh-users/zsh/blob/f702e17b14d75aa21bff014168fa9048124db286/Functions/Zle/bracketed-paste-magic#L9-L12
+
+# Load bracketed-paste-magic if zsh version is >= 5.1
+if [[ ${ZSH_VERSION:0:3} -ge 5.1 ]]; then
+  set zle_bracketed_paste  # Explicitly restore this zsh default
+  autoload -Uz bracketed-paste-magic
+  zle -N bracketed-paste bracketed-paste-magic
+  return  ### The rest of this file is NOT executed on zsh version >= 5.1 ###
+fi
+
+######################################################################
+#    The rest of this file is ONLY executed if zsh version < 5.1
+######################################################################
+
+# Code from Mikael Magnusson: https://www.zsh.org/mla/users/2011/msg00367.html
+#
+# Requires xterm, urxvt, iTerm2 or any other terminal that supports
+# Bracketed Paste Mode as documented:
+# https://www.xfree86.org/current/ctlseqs.html#Bracketed%20Paste%20Mode
+#
+# For tmux, use:   bind ] paste-buffer -p
+#
+# Additional technical details: https://cirw.in/blog/bracketed-paste
+
+# Create a new keymap to use while pasting
+bindkey -N bracketed-paste
+# Make everything in this new keymap enqueue characters for pasting
+bindkey -RM bracketed-paste '\x00-\xFF' bracketed-paste-enqueue
+# These are the codes sent around the pasted text in bracketed paste mode
+bindkey -M main            '^[[200~' _bracketed_paste_begin
+bindkey -M bracketed-paste '^[[201~' _bracketed_paste_end
+# Insert newlines rather than carriage returns when pasting newlines
+bindkey -M bracketed-paste -s '^M' '^J'
+
+zle -N _bracketed_paste_begin
+zle -N _bracketed_paste_end
+zle -N bracketed-paste-enqueue _bracketed_paste_enqueue
+
+# Attempt to not clobber zle_line_{init,finish}
+# Use https://github.com/willghatch/zsh-hooks if available
+if typeset -f hooks-add-hook > /dev/null; then
+  hooks-add-hook zle_line_init_hook   _bracketed_paste_zle_init
+  hooks-add-hook zle_line_finish_hook _bracketed_paste_zle_finish
+else
+  zle -N zle-line-init   _bracketed_paste_zle_init
+  zle -N zle-line-finish _bracketed_paste_zle_finish
+fi
+
+# Switch the active keymap to paste mode
+_bracketed_paste_begin() {
+  # Save the bindkey command to restore the active ("main") keymap
+  # Tokenise the restorative bindkey command into an array
+  _bracketed_paste_restore_keymap=( ${(z)"$(bindkey -lL main)"} )
+  bindkey -A bracketed-paste main
+}
+
+# Go back to our normal keymap, and insert all the pasted text in the
+# command line. This has the nice effect of making the whole paste be
+# a single undo/redo event.
+_bracketed_paste_end() {
+  # Only execute the restore command if it starts with 'bindkey'
+  # Allow for option KSH_ARRAYS being set (indexing starts at 0)
+  if [ ${_bracketed_paste_restore_keymap[@]:0:1} = 'bindkey' ]; then
+    $_bracketed_paste_restore_keymap
+  fi
+  LBUFFER+=$_bracketed_paste_content
+  unset _bracketed_paste_content _bracketed_paste_restore_keymap
+}
+
+# Append a pasted character to the content which is later inserted as a whole
+_bracketed_paste_enqueue() {
+  _bracketed_paste_content+=$KEYS
+}
+
+# Run at zle-line-init
+_bracketed_paste_zle_init() {
+  _bracketed_paste_content=''
+  # Tell terminal to send escape codes around pastes
+  if [[ $TERM =~ '^(rxvt-unicode|xterm(-256color)?|screen(-256color)?)$' ]]; then
+    printf '\e[?2004h'
+  fi
+}
+
+# Run at zle-line-finish
+_bracketed_paste_zle_finish() {
+  # Turn off bracketed paste when we leave ZLE, so pasting in other programs
+  # doesn't get the ^[[200~ codes around the pasted text
+  if [[ $TERM =~ '^(rxvt-unicode|xterm(-256color)?|screen(-256color)?)$' ]]; then
+    printf '\e[?2004l'
+  fi
+}
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/salt/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/salt/README.md
new file mode 100644 (file)
index 0000000..3d224cc
--- /dev/null
@@ -0,0 +1,5 @@
+## Salt autocomplete plugin
+
+A copy of the completion script from the
+[salt](https://github.com/saltstack/salt/blob/develop/pkg/zsh_completion.zsh)
+git repo.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/salt/_salt b/stow/oh-my-zsh/.oh-my-zsh/plugins/salt/_salt
new file mode 100644 (file)
index 0000000..589d21d
--- /dev/null
@@ -0,0 +1,279 @@
+#compdef salt salt-call salt-cp salt-run salt-key
+# The use-cache style is checked in a few places to allow caching minions, modules,
+# or the directory salt is installed in.
+# you can cache those three with:
+# zstyle ':completion:*:salt(|-cp|-call|-run|-key):*' use-cache true
+# and/or selectively:
+# zstyle ':completion::complete:salt-key:set-option-a-1:'             use-cache false
+# zstyle ':completion::complete:salt(|-cp|-call):minions:'            use-cache true
+# zstyle ':completion::complete:salt(|-call):modules:'                use-cache true
+# zstyle ':completion::complete:salt(|-cp|-call|-run|-key):salt_dir:' use-cache true
+#
+# cache validation can be controlled with the style cache-ttl.
+# it expects two arguments: number (days|hours|weeks|months)
+# to invalidate the minion cache after four days:
+# zstyle ':completion::complete:salt(|-cp|-call):minions:'            cache-ttl 4 days
+
+
+local state line curcontext="$curcontext" salt_dir
+
+_modules(){
+    local _funcs expl curcontext=${curcontext%:*}:modules
+
+    if ! zstyle -m ":completion:$curcontext:" cache-policy '*'; then
+        zstyle ":completion:$curcontext:" cache-policy _salt_caching_policy
+    fi
+
+    if _cache_invalid salt/modules || ! _retrieve_cache salt/modules; then
+        _funcs=( ${${(Q)${${(s. .)"$(_call_program salt-call-cmd salt-call --local --log-level error --out txt sys.list_functions)"}%%[],]##}#\[}:#local:} )
+        _store_cache salt/modules _funcs
+    fi
+
+    _wanted modules expl modules _multi_parts "$@" . _funcs
+}
+
+_runners(){
+    local _runs expl curcontext=${curcontext%:*}:runners
+
+    if ! zstyle -m ":completion:$curcontext:" cache-policy '*'; then
+        zstyle ":completion:$curcontext:" cache-policy _salt_caching_policy
+    fi
+
+    if _cache_invalid salt/runners || ! _retrieve_cache salt/runners; then
+        _runs=( ${${(Q)${${(s. .)"$(_call_program salt-call-cmd salt-call --local --log-level error --out txt sys.list_runner_functions)"}%%[],]##}#\[}:#local:} )
+        _store_cache salt/runners _runs
+    fi
+
+    _wanted modules expl runners _multi_parts "$@" . _runs
+}
+
+_minions(){
+    local type requested_type include_all key expl; typeset -A _peons
+
+    # when completing the minion argument for salt and salt-cp, set the argument section
+    # of the context to `minion' not `argument-1'
+    if [[ $service = salt(|-cp) ]]; then
+       curcontext=${curcontext%:*}:minions
+    fi
+
+    # only pass the argument accepted, unaccepted, rejected, denied or all to -t/-T
+    # the argument is used as part of an tag, accepted-minions, rejected-minions, etc.
+    # while un, acc, den, etc will work, you will possibly ignore user customized tags.
+    zparseopts -D -E 't+:=requested_type' 'T+:=include_all'
+
+    if ! zstyle -m ":completion:$curcontext:" cache-policy '*'; then
+        zstyle ":completion:$curcontext:" cache-policy _salt_caching_policy
+    fi
+
+    if _cache_invalid salt/minions || ! _retrieve_cache salt/minions; then
+        # it would be awesome if salt-key could prefix or suffix a word to denote
+        # the key's state. It would remove the need for this loop, calling salt-key N times.
+        for type in accepted unaccepted rejected denied; do
+            salt-key -l $type 2>/dev/null | while read -r key; do
+              [[ $key == *' Keys:' ]] && continue
+              _peons+=( "$key" $type )
+            done
+        done
+        _store_cache salt/minions _peons
+    fi
+
+    # if salt-key's --include-all option isn't on the line, ignore the -T options
+    (( words[(I)--include-all] )) || unset include_all
+
+    if (( requested_type[(I)all] )); then
+        requested_type=( -t accepted -t unaccepted -t rejected -t denied )
+        unset include_all
+    fi
+
+    for type in ${${requested_type:#-t}:-accepted} ${include_all:#-T}; do
+        _wanted $type-minions expl minion compadd "$@" -M 'r:|.=* r:|=*' ${(k)_peons[(R)$~type]}
+    done
+}
+
+(( $+functions[_salt_caching_policy] )) ||
+_salt_caching_policy() {
+    local oldp ttl d t
+    zstyle -a ":completion:$curcontext:" cache-ttl ttl
+
+    if (( $#ttl >= 2 )); then
+      [[ $ttl[1] == <-> ]] && integer t=$ttl[1]
+
+      case $ttl[2] in
+        seconds#)d=s;;
+        months#) d=M;;
+        weeks#)  d=w;;
+        hours#)  d=h;;
+        *)       d=d;;
+      esac
+    fi
+
+    oldp=( "$1"(Nm${d:-d}+${t:-1}) )
+    (( $#oldp ))
+}
+
+local -a _{target,master,logging,minion}_options _{common,out}_opts _target_opt_pat
+_target_opt_pat=(
+    '(-[ELGNRCIS]|--(pcre|list|grain(|-pcre)|nodegroup|range|compound|pillar|ipcidr))'
+    '(-E --pcre -L --list -G --grain --grain-pcre -N --nodegroup -R --range -C --compound -I --pillar -S --ipcidr)'
+)
+
+_target_options=(
+    "$_target_opt_pat[2]"{-E,--pcre}'[use pcre regular expressions]:pcre:'
+    "$_target_opt_pat[2]"{-L,--list}'[take a comma or whitespace delimited list of servers.]:list:'
+    "$_target_opt_pat[2]"{-G,--grain}'[use a grain value to identify targets]:Grains:'
+    "$_target_opt_pat[2]--grain-pcre[use a grain value to identify targets.]:pcre:"
+    "$_target_opt_pat[2]"{-N,--nodegroup}'[use one of the predefined nodegroups to identify a list of targets.]:Nodegroup:'
+    "$_target_opt_pat[2]"{-R,--range}'[use a range expression to identify targets.]:Range:'
+    "$_target_opt_pat[2]"{-C,--compound}'[Use multiple targeting options.]:Compound:'
+    "$_target_opt_pat[2]"{-I,--pillar}'[use a pillar value to identify targets.]:Pillar:'
+    "$_target_opt_pat[2]"{-S,--ipcidr}'[Match based on Subnet (CIDR notation) or IPv4 address.]:Cidr:'
+)
+
+_common_opts=(
+    "--version[show program's version number and exit]"
+    "--versions-report[show program's dependencies version number and exit]"
+    '(-h --help)'{-h,--help}'[show this help message and exit]'
+    '(-c --config-dir)'{-c,--config-dir}'[Pass in an alternative configuration directory.(default: /etc/salt/)]:Config Directory:_files -/'
+    '(-t --timeout)'{-t,--timeout}'[Change the timeout for the running command; default=5]:Timeout (seconds):'
+)
+
+_master_options=(
+    '(-s --static)'{-s,--static}'[Return the data from minions as a group after they all return.]'
+    "--async[Run the salt command but don't wait for a reply]"
+    '(--state-output --state_output)'{--state-output,--state_output}'[Override the configured state_output value for minion output. Default: full]:Outputs:(full terse mixed changes)'
+    '--subset[Execute the routine on a random subset of the targeted minions]:Subset:'
+    '(-v --verbose)'{-v,--verbose}'[Turn on command verbosity, display jid and active job queries]'
+    '--hide-timeout[Hide minions that timeout]'
+    '(-b --batch --batch-size)'{-b,--batch,--batch-size}'[Execute the salt job in batch mode, pass number or percentage to batch.]:Batch Size:'
+    '(-a --auth --eauth --external-auth)'{-a,--auth,--eauth,--external-auth}'[Specify an external authentication system to use.]:eauth:'
+    '(-T --make-token)'{-T,--make-token}'[Generate and save an authentication token for re-use.]'
+    '--return[Set an alternative return method.]:Returners:_path_files -W "$salt_dir/returners" -g "[^_]*.py(\:r)"'
+    '(-d --doc --documentation)'{-d,--doc,--documentation}'[Return the documentation for the specified module]'
+    '--args-separator[Set the special argument used as a delimiter between command arguments of compound commands.]:Arg separator:'
+)
+
+_minion_options=(
+    '--return[Set an alternative return method.]:Returners:_path_files -W "$salt_dir"/returners" -g "[^_]*.py(\:r)"'
+    '(-d --doc --documentation)'{-d,--doc,--documentation}'[Return the documentation for the specified module]'
+    '(-g --grains)'{-g,--grains}'[Return the information generated by the salt grains]'
+    {*-m,*--module-dirs}'[Specify an additional directory to pull modules from.]:Module Dirs:_files -/'
+    '--master[Specify the master to use.]:Master:'
+    '--local[Run salt-call locally, as if there was no master running.]'
+    '--file-root[Set this directory as the base file root.]:File Root:_files -/'
+    '--pillar-root[Set this directory as the base pillar root.]:Pillar Root:_files -/'
+    '--retcode-passthrough[Exit with the salt call retcode and not the salt binary retcode]'
+    '--id[Specify the minion id to use.]:Minion ID:'
+    '--skip-grains[Do not load grains.]'
+    '--refresh-grains-cache[Force a refresh of the grains cache]'
+)
+
+_runner_options=(
+    '--hard-crash[raise any original exception rather than exiting gracefully]'
+    '(-d --doc --documentation)'{-d,--doc,--documentation}'[Return the documentation for the specified module]'
+)
+
+_key_options=(
+    '(-u --user)'{-u+,--user=}'[specify user to run salt-key]:user:_users'
+    '--hard-crash[raise any original exception rather than exiting gracefully]'
+    '(-q --quiet)'{-q,--quiet}'[quiet mode]'
+    '(-y --yes)'{-y,--yes}'[assume yes]'
+    '--rotate-aes-key[prevents the master from refreshing the key session when keys are deleted or rejected]:boolean:(true false)'
+    '--gen-keys=[set a name to generate a keypair for use with salt]:key name'
+    '--gen-keys-dir=[set the directory to save the generated keypair]: : _directories'
+    '--keysize=[set the size for keypair]:key size'
+    '--gen-signature[create a signature file of the masters public-key]'
+    '--priv=[the private-key file to create a signature with]:private key:_files'
+    '--signature-path=[the path where the signature file should be written]: : _directories'
+    '--pub=[the public-key file to create a signature for]:public key:_files'
+    '--auto-create[auto-create a signing key-pair if it does not yet exist]'
+    '--include-all[include non-pending keys when accepting/rejecting]'
+    - '(set)'
+    {-l+,--list=}'[list public keys]:key type:((
+        preaccepted\:"unaccepted/unsigned keys" unaccepted\:"unaccepted/unsigned keys" un\:"unaccepted/unsigned keys"
+        accepted\:"accepted/signed keys" acc\:"accepted/signed keys"
+        rejected\:"rejected keys" rej\:"rejected keys"
+        den\:"denied keys" denied\:"denied keys" all
+      ))'
+    {-a+,--accept=}'[accept key]:key:_minions -t unaccepted -T rejected'
+    {-A,--accept-all}'[accept all keys]'
+    {-r+,--reject=}'[reject key]:key:_minions -t rejected -T accepted'
+    {-p+,--print=}'[print the specified public key]:key:_minions -t all'
+    {-P,--print-all}'[print all public keys]'
+    {-d+,--delete=}'[delete the specified public key]:key:_minions -t all'
+    {-D,--delete-all}'[delete all public keys]'
+    {-f+,--finger=}'[print the specified key'\''s fingerprint]:key:_minions -t all'
+    {-F,--finger-all}'[print the fingerprint of all keys]'
+)
+
+_logging_options=(
+    '(-l --log-level)'{-l,--log-level}'[Console logging log level.(default: warning)]:Log Level:(all garbage trace debug info warning error critical quiet)'
+    '--log-file[Log file path. Default: /var/log/salt/master.]:Log File:_files'
+    '--log-file-level=[Logfile logging log level.Default: warning]:Log Level:(all garbage trace debug info warning error critical quiet)'
+)
+
+_out_opts=(
+    '(--out --output)'{--out,--output}'[Print the output using the specified outputter.]:Outputters:_path_files -W "$salt_dir/output" -g "[^_]*.py(\:r)"'
+    '(--out-indent --output-indent)'{--out-indent,--output-indent}'[Print the output indented by the provided value in spaces.]:Number:'
+    '(--out-file --output-file)'{--out-file,--output-file}'[Write the output to the specified file]:Output File:_files'
+    '(--no-color --no-colour)'{--no-color,--no-colour}'[Disable all colored output]'
+    '(--force-color --force-colour)'{--force-color,--force-colour}'[Force colored output]'
+)
+
+_salt_comp(){
+    case "$service" in
+        salt)
+            _arguments -C \
+                "${words[(r)$_target_opt_pat[1]]+!}:minions:_minions" \
+                ':modules:_modules' \
+                "$_target_options[@]" \
+                "$_common_opts[@]" \
+                "$_master_options[@]" \
+                "$_logging_options[@]" \
+                "$_out_opts[@]"
+            ;;
+        salt-call)
+            _arguments -C \
+                ':modules:_modules' \
+                "$_minion_options[@]" \
+                "$_common_opts[@]" \
+                "$_logging_options[@]" \
+                "$_out_opts[@]"
+            ;;
+        salt-cp)
+            _arguments -C \
+                "${words[(r)$_target_opt_pat[1]]+!}:minions:_minions" \
+                "$_target_options[@]" \
+                "$_common_opts[@]" \
+                "$_logging_options[@]" \
+                ':Source File:_files' \
+                ':Destination File:_files'
+            ;;
+        salt-run)
+            _arguments -C \
+                ":runners:_runners" \
+                "$_runner_options[@]" \
+                "$_common_opts[@]" \
+                "$_logging_options[@]"
+            ;;
+        salt-key)
+            _arguments -C \
+                "$_key_options[@]" \
+                "${_common_opts[@]:#'-t --timeout\)'*}" \
+                "${_logging_options[@]:#'(-l --log-level)'*}"
+            ;;
+    esac
+}
+
+() {
+    local curcontext=${curcontext%:*}:salt_dir
+    if ! zstyle -m ":completion:$curcontext:" cache-policy '*'; then
+        zstyle ":completion:$curcontext:" cache-policy _salt_caching_policy
+    fi
+
+    if _cache_invalid salt/salt_dir || ! _retrieve_cache salt/salt_dir; then
+        salt_dir="${$(python2 -c 'import sys; del sys.path[0]; import salt; print(salt.__file__);')%__init__*}"
+        _store_cache salt/salt_dir salt_dir
+    fi
+}
+
+_salt_comp "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/samtools/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/samtools/README.md
new file mode 100644 (file)
index 0000000..f4baf41
--- /dev/null
@@ -0,0 +1,5 @@
+# Samtools plugin
+
+This plugin adds support for [samtools](http://www.htslib.org/):
+
+* Adds autocomplete options for all samtools sub commands.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/samtools/_samtools b/stow/oh-my-zsh/.oh-my-zsh/plugins/samtools/_samtools
new file mode 100644 (file)
index 0000000..ddb002a
--- /dev/null
@@ -0,0 +1,40 @@
+#compdef samtools
+#autoload
+
+local curcontext="$curcontext" state line ret=1
+local -a _files
+
+_arguments -C \
+  '1: :->cmds' \
+  '2:: :->args' && ret=0
+
+case $state in
+  cmds)
+    _values "samtools command" \
+        "view[SAM<->BAM conversion]" \
+        "sort[sort alignment file]" \
+        "mpileup[multi-way pileup]" \
+        "depth[compute the depth]" \
+        "faidx[index/extract FASTA]" \
+        "tview[text alignment viewer]" \
+        "index[index alignment]" \
+        "idxstats[BAM index stats (r595 or later)]" \
+        "fixmate[fix mate information]" \
+        "flagstat[simple stats]" \
+        "calmd[recalculate MD/NM tags and '=' bases]" \
+        "merge[merge sorted alignments]" \
+        "rmdup[remove PCR duplicates]" \
+        "reheader[replace BAM header]" \
+        "cat[concatenate BAMs]" \
+        "bedcov[read depth per BED region]" \
+        "targetcut[cut fosmid regions (for fosmid pool only)]" \
+        "phase[phase heterozygotes]" \
+        "bamshuf[shuffle and group alignments by name]"
+    ret=0
+    ;;
+  *)
+    _files
+    ;;
+esac
+
+return ret
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/README.md
new file mode 100644 (file)
index 0000000..f020193
--- /dev/null
@@ -0,0 +1,32 @@
+# sbt plugin
+
+This plugin adds completion for the [sbt, the interactive build tool](https://scala-sbt.org/),
+as well as some aliases for common sbt commands.
+
+To use it, add `sbt` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... sbt)
+```
+
+## Aliases
+
+| Alias | Command               | Description                                                  |
+|-------|-----------------------|--------------------------------------------------------------|
+| sbc   | `sbt compile`         | Compiles the main sources                                    |
+| sbcln | `sbt clean`           | Deletes all generated files                                  |
+| sbcc  | `sbt clean compile`   | Deletes generated files, compiles the main sources           |
+| sbco  | `sbt console`         | Starts Scala with the compiled sources and all dependencies  |
+| sbcq  | `sbt consoleQuick`    | Starts Scala with all dependencies                           |
+| sbcp  | `sbt consoleProject`  | Starts Scala with sbt and the build definitions              |
+| sbd   | `sbt doc`             | Generates API documentation for Scala source files           |
+| sbdc  | `sbt dist:clean`      | Deletes the distribution packages                            |
+| sbdi  | `sbt dist`            | Creates the distribution packages                            |
+| sbgi  | `sbt genIdea`         | Create Idea project files                                    |
+| sbp   | `sbt publish`         | Publishes artifacts to the repository                        |
+| sbpl  | `sbt publishLocal`    | Publishes artifacts to the local Ivy repository              |
+| sbr   | `sbt run`             | Runs the main class for the project                          |
+| sbrm  | `sbt runMain`         | Runs the specified main class for the project                |
+| sbu   | `sbt update`          | Resolves and retrieves external dependencies                 |
+| sbx   | `sbt test`            | Compiles and runs all tests                                  |
+| sba   | `sbt assembly`        | Create a fat JAR with all dependencies                       |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/_sbt b/stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/_sbt
new file mode 100644 (file)
index 0000000..2138a72
--- /dev/null
@@ -0,0 +1,56 @@
+#compdef sbt
+#autoload
+
+local -a _sbt_commands
+_sbt_commands=(
+  'clean:delete files produced by the build'
+  'compile:compile sources'
+  'console:start the Scala REPL with project classes on the classpath'
+  'consoleQuick:start the Scala REPL with project deps on the classpath'
+  'consoleProject:start the Scala REPL w/sbt+build-def on the classpath'
+  'dist:generate distribution artifacts'
+  'dist\:clean:clean distribution artifacts'
+  'doc:generate API documentation'
+  'genIdea:generate Intellij Idea project files'
+  'package:produce the main artifact, such as a binary jar'
+  'packageDoc:produce a doc artifact, such as a jar containing API docs'
+  'packageSrc:produce a source artifact, such as a jar containing sources'
+  'publish:publish artifacts to a repository'
+  'publishLocal:publish artifacts to the local repository'
+  'publishM2:publish artifacts to the local Maven 2 repository'
+  'run:run a main class'
+  'runMain:run the main class selected by the first argument'
+  'test:execute all tests'
+  'testOnly:execute the tests provided as arguments'
+  'testQuick:execute previously failed tests'
+  'update:resolve and optionally retrieve dependencies'
+)
+
+local expl
+
+_arguments \
+  '(-help)-h[prints an help message]' \
+  '(-h)-help[prints an help message]' \
+  '(-verbose)-v[this runner is chattier]' \
+  '(-v)-verbose[this runner is chattier]' \
+  '(-debug)-d[set sbt log level to debug]' \
+  '(-d)-debug[set sbt log level to debug]' \
+  '-no-colors[disable ANSI color codes]' \
+  '-sbt-create[start even if current dir contains no sbt project]' \
+  '-sbt-dir[path to global settings/plugins dir (default: ~/.sbt)]' \
+  '-sbt-boot[path to shared boot dir (default: ~/.sbt/boot)]' \
+  '-ivy[path to local Ivy repository (default: ~/.ivy2)]' \
+  '-mem[set memory options]' \
+  '-no-share[use all local caches; no sharing]' \
+  '-no-global[use global caches, but do not use global ~/.sbt dir]' \
+  '-jvm-debug[turn on JVM debugging, open at the given port]' \
+  '-batch[disable interactive mode]' \
+  '-sbt-version[use the specified version of sbt]' \
+  '-sbt-jar[use the specified jar as the sbt launcher]' \
+  '(-sbt-snapshot)-sbt-rc[use an RC version of sbt]' \
+  '(-sbt-rc)-sbt-snapshot[use a snapshot version of sbt]' \
+  '-java-home[alternate JAVA_HOME]' \
+  '*:: :->subcmds' && return 0
+
+_describe -t commands "sbt subcommand" _sbt_commands
+return
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/sbt.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sbt/sbt.plugin.zsh
new file mode 100644 (file)
index 0000000..851302c
--- /dev/null
@@ -0,0 +1,25 @@
+# ------------------------------------------------------------------------------
+#          FILE:  sbt.plugin.zsh
+#   DESCRIPTION:  oh-my-zsh plugin file.
+#        AUTHOR:  Mirko Caserta (mirko.caserta@gmail.com)
+#       VERSION:  1.0.2
+# ------------------------------------------------------------------------------
+# aliases - mnemonic: prefix is 'sb'
+alias sbc='sbt compile'
+alias sbcc='sbt clean compile'
+alias sbco='sbt console'
+alias sbcq='sbt consoleQuick'
+alias sbcln='sbt clean'
+alias sbcp='sbt consoleProject'
+alias sbd='sbt doc'
+alias sbdc='sbt dist:clean'
+alias sbdi='sbt dist'
+alias sbgi='sbt genIdea'
+alias sbp='sbt publish'
+alias sbpl='sbt publishLocal'
+alias sbr='sbt run'
+alias sbrm='sbt runMain'
+alias sbu='sbt update'
+alias sbx='sbt test'
+alias sba='sbt assembly'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scala/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/scala/README.md
new file mode 100644 (file)
index 0000000..91a3221
--- /dev/null
@@ -0,0 +1,16 @@
+# Scala plugin
+
+Completion script for [scala and scalac](https://www.scala-lang.org/) commands.
+
+To use it, add `scala` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... scala)
+```
+
+## Aliases
+
+| Command  | Description                     |
+|----------|---------------------------------|
+| `scala`  | Run code in the Scala language  |
+| `scalac` | Compiler for the Scala language |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scala/_scala b/stow/oh-my-zsh/.oh-my-zsh/plugins/scala/_scala
new file mode 100644 (file)
index 0000000..ba7ac38
--- /dev/null
@@ -0,0 +1,249 @@
+#compdef scala scalac
+# ------------------------------------------------------------------------------
+# Copyright (c) 2012 Github zsh-users - https://github.com/zsh-users
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for scala and scalac (https://www.scala-lang.org/).
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Tony Sloane <inkytonik@gmail.com>
+#
+# ------------------------------------------------------------------------------
+
+typeset -A opt_args
+local context state line
+
+_scala_features () {
+   compadd "postfixOps" "reflectiveCalls" "implicitConversions" "higherKinds" \
+     "existentials" "experimental.macros" "_"
+}
+
+_scala_phases () {
+   compadd "parser" "namer" "packageobjects" "typer" "patmat" "superaccessors" \
+     "extmethods" "pickler" "refchecks" "selectiveanf" "selectivecps" "uncurry" \
+     "tailcalls" "specialize" "explicitouter" "erasure" "posterasure" "lazyvals" \
+     "lambdalift" "constructors" "flatten" "mixin" "cleanup" "icode" "inliner" \
+     "inlineExceptionHandlers" "closelim" "dce" "jvm" "terminal"
+}
+
+local -a shared_opts
+shared_opts=(
+  "-bootclasspath+[Override location of bootstrap class files]:bootstrap class directory:_files -/"
+  "-classpath+[Specify where to find user class files]:directory:_files -/"
+  "-D-[Pass -Dproperty=value directly to the runtime system]"
+  "-d+[Destination for generated classfiles]: directory or jar file:_files"
+  "-dependencyfile+[Set dependency tracking file]:dependency tracking file:_files"
+  "-deprecation[Emit warning and location for usages of deprecated APIs]"
+  "-encoding+[Specify character encoding used by source files]:encoding:"
+  "-explaintypes[Explain type errors in more detail]"
+  "-extdirs+[Override location of installed extensions]:extensions directory:_files -/"
+  "-g\:-[Set level of generated debugging info (default\: vars)]:debugging info level:(none source line vars notailcalls)"
+  "-help[Print a synopsis of standard options]"
+  "-J-[pass argument directly to Java runtime system]:JVM argument:"
+  "-javabootclasspath+[Override java boot classpath]:Java boot class path directory]:_files -/"
+  "-javaextdirs+[Override java extdirs classpath]:Java extdirs directory:_files -/"
+  "-language\:-[Enable one or more language features]:feature:_scala_features"
+  "-no-specialization[Ignore @specialize annotations]"
+  "-nobootcp[Do not use the boot classpath for the scala jars]"
+  "-nowarn[Generate no warnings]"
+  "-optimise[Generate faster bytecode by applying optimisations to the program]"
+  "-P\:-[Pass an option to a plugin (written plugin\:opt)]:plugin option:"
+  "-print[Print program with Scala-specific features removed]"
+  "-sourcepath+[Specify location(s) of source files]:source file directory:_files -/"
+  "-target\:-[Target platform for object files (default\: jvm-1.5)]:platform name:(jvm-1.5 msil)"
+  "-toolcp+[Add to the runner classpath]:directory:_files -/"
+  "-unchecked[Enable detailed unchecked (erasure) warnings]"
+  "-uniqid[Uniquely tag all identifiers in debugging output]"
+  "-usejavacp[Utilize the java.class.path in classpath resolution]"
+  "-verbose[Output messages about what the compiler is doing]"
+  "-version[Print product version and exit]"
+  "-X[Print a synopsis of advanced options]"
+  "-Y[Print a synopsis of private options]"
+)
+
+local -a X_opts
+X_opts=(
+  "-Xcheck-null[Warn upon selection of nullable reference]"
+  "-Xcheckinit[Wrap field accessors to throw an exception on uninitialized access]"
+  "-Xdisable-assertions[Generate no assertions or assumptions]"
+  "-Xelide-below+[Calls to @elidable methods are omitted if method priority is lower than integer argument]"
+  "-Xexperimental[Enable experimental extensions]"
+  "-Xfatal-warnings[Fail the compilation if there are any warnings]"
+  "-Xfull-lubs[Retains pre 2.10 behavior of less aggressive truncation of least upper bounds]"
+  "-Xfuture[Turn on future language features]"
+  "-Xgenerate-phase-graph+[Generate the phase graphs (outputs .dot files) to fileX.dot]:output file:_files"
+  "-Xlint[Enable recommended additional warnings]"
+  "-Xlog-free-terms[Print a message when reification creates a free term]"
+  "-Xlog-free-types[Print a message when reification resorts to generating a free type]"
+  "-Xlog-implicits[Show more detail on why some implicits are not applicable]"
+  "-Xlog-implicit-conversions[Print a message whenever an implicit conversion is inserted]"
+  "-Xlog-reflective-calls[Print a message when a reflective method call is generated]"
+  "-Xmacro-settings\:-[Custom settings for macros]:option"
+  "-Xmain-class+[Class for manifest's Main-Class entry (only useful with -d jar)]:path:"
+  "-Xmax-classfile-name+[Maximum filename length for generated classes]"
+  "-Xmigration[Warn about constructs whose behavior may have changed]"
+  "-Xno-forwarders[Do not generate static forwarders in mirror classes]"
+  "-Xno-patmat-analysis[Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation]"
+  "-Xno-uescape[Disable handling of \u unicode escapes]"
+  "-Xnojline[Do not use JLine for editing]"
+  "-Xoldpatmat[Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10]"
+  "-Xprint\:-[Print out program after <phase>]:phase name:_scala_phases"
+  "-Xprint-icode\:-[Log internal icode to *.icode files after phase (default\: icode)]:phase name:_scala_phases"
+  "-Xprint-pos[Print tree positions, as offsets]"
+  "-Xprint-types[Print tree types (debugging option)]"
+  "-Xprompt[Display a prompt after each error (debugging option)]"
+  "-Xresident[Compiler stays resident: read source filenames from standard input]"
+  "-Xscript+[Treat the source file as a script and wrap it in a main method]:main object name"
+  "-Xshow-class+[Show internal representation of class]:class name"
+  "-Xshow-object+[Show internal representation of object]:object name"
+  "-Xshow-phases[Print a synopsis of compiler phases]"
+  "-Xsource-reader+[Specify a class name for a custom method of reading source files]:class name"
+  "-Xverify[Verify generic signatures in generated bytecode]"
+
+  "-Xassem-extdirs+[List of directories containing assemblies (requires -target:msil) (default\: lib)]:assembly directory:_files -/"
+  "-Xassem-name+[Name of the output assembly (requires -target:msil)]:assembly name:_files"
+  "-Xassem-path+[List of assemblies referenced by the program (requires -target:msil)]:assembly path:_files"
+  "-Xsourcedir+[Mirror source folder structure in output directory (requires -target:msil)]:source directory:_files -/"
+
+  "-Xplugin\:-[Load one or more plugins from file]:plugin file:_files"
+  "-Xpluginsdir+[Path to search compiler plugins]:plugin directory:_files -/"
+  "-Xplugin-list[Print a synopsis of loaded plugins]"
+  "-Xplugin-disable\:-[Disable the given plugin(s)]"
+  "-Xplugin-require\:-[Abort unless the given plugin(s) are available]"
+)
+
+local -a Y_opts
+Y_opts=(
+  "-Y[Print a synopsis of private options]"
+  "-Ybuild-manager-debug[Generate debug information for the Refined Build Manager compiler]"
+  "-Ybuilder-debug\:-[Compile using the specified build manager (default\: none)]:build manager:(none refined simple)"
+  "-Yclosure-elim[Perform closure elimination]"
+  "-Ycompact-trees[Use compact tree printer when displaying trees]"
+  "-Ydead-code[Perform dead code elimination]"
+  "-Ydependent-method-types[Allow dependent method types]"
+  "-Ydump-classes+[Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders)]:output directory:_files -/"
+  "-Yeta-expand-keeps-star[Eta-expand varargs methods to T* rather than Seq[T].  This is a temporary option to ease transition.]"
+  "-Ygen-javap+[Generate a parallel output directory of .javap files]:output directory:_files -/"
+  "-Yinfer-argument-types[Infer types for arguments of overridden methods]"
+  "-Yinline[Perform inlining when possible]"
+  "-Yinline-handlers[Perform exception handler inlining when possible]"
+  "-Yinline-warnings[Emit inlining warnings (normally suppressed due to high volume)]"
+  "-Yinvalidate+[Invalidate classpath entry before run]:classpath entry"
+  "-Ylinearizer\:-[Linearizer to use (default\: rpo)]:linearizer:(normal dfs rpo dump)"
+  "-Ylog-classpath[Output information about what classpath is being applied]"
+  "-Yno-adapted-args[Do not adapt an argument list (either by inserting unit or creating a tuple) to match the receiver]"
+  "-Ymacro-debug-lite[Trace essential macro-related activities]"
+  "-Ymacro-debug-verbose[Trace all macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions]"
+  "-Yno-completion[Disable tab-completion in the REPL]"
+  "-Yno-generic-signatures[Suppress generation of generic signatures for Java]"
+  "-Yno-imports[Compile without any implicit imports]"
+  "-Yno-predef[Compile without importing Predef]"
+  "-Yno-self-type-checks[Suppress check for self-type conformance among inherited members]"
+  "-Yno-squeeze[Disable creation of compact code in matching]"
+  "-Ynotnull[Enable (experimental and incomplete) scala.NotNull]"
+  "-Yoverride-objects[Allow member objects to be overridden]"
+  "-Yoverride-vars[Allow vars to be overridden]"
+  "-Ypmat-naive[Desugar matches as naively as possible]"
+  "-Ypresentation-delay+[Wait number of ms after typing before starting typechecking]"
+  "-Ypresentation-log+[Log presentation compiler events into file]:log file:_files"
+  "-Ypresentation-replay+[Replay presentation compiler events from file]:log file:_files"
+  "-Ypresentation-strict[Do not report type errors in sources with syntax errors]"
+  "-Ypresentation-verbose[Print information about presentation compiler tasks]"
+  "-Yprofile-class+[Specify name of profiler class]:profiler class name"
+  "-Yprofile-memory[Heap snapshot after compiler run (requires jgpagent on JVM -agentpath)]"
+  "-Yrangepos[Use range positions for syntax trees]"
+  "-Yrecursion+[Set recursion depth used when locking symbols]"
+  "-Yreify-copypaste[Dump the reified trees in copypasteable representation]"
+  "-Yrepl-sync[Do not use asynchronous code for REPL startup]"
+  "-Yresolve-term-conflict\:-[Resolve term conflicts (default\: error)]:resolution strategy:(package object error)"
+  "-Yself-in-annots[Include a \"self\" identifier inside of annotations]"
+  "-Yshow\:-[Show after <phase> (requires -Xshow-class or -Xshow-object)]:phase name:_scala_phases"
+  "-Yshow-syms[Print the AST symbol hierarchy after each phase]"
+  "-Yshow-symkinds[Print abbreviated symbol kinds next to symbol names]"
+  "-Yshow-trees[Print detailed ASTs (requires -Xprint\:phase)]"
+  "-Yshow-trees-compact[Print detailed ASTs in compact form (requires -Xprint\:)]"
+  "-Yshow-trees-stringified[Print stringification along with detailed ASTs (requires -Xprint\:)]"
+  "-Ystatistics[Print compiler statistics]"
+  "-Ystruct-dispatch\:-[Structural method dispatch policy (default\: poly-cache)]:policy name:(no-cache mono-cache poly-cache invoke-dynamic)"
+
+  "-Ybrowse\:-[Browse the abstract syntax tree after <phase>]:phase name:_scala_phases"
+  "-Ycheck\:-[Check the tree at the end of <phase>]:phase name:_scala_phases"
+  "-Ylog\:-[Log operations during <phase>]:phase name:_scala_phases"
+  "-Yprofile\:-[Profile CPU usage of given phases (requires jgpagent on JVM -agentpath)]:phase name:_scala_phases"
+  "-Yskip\:-[Skip <phase>]:phase name:_scala_phases"
+  "-Ystop-after\:-[Stop after given phase <phase>]:phase name:_scala_phases"
+  "-Ystop-before\:-[Stop before given phase <phase>]:phase name:_scala_phases"
+
+  "-Ywarn-adapted-args[Warn if an argument list is modified to match the receiver]"
+  "-Ywarn-all[Enable all -Y warnings]"
+  "-Ywarn-dead-code[Warn when dead code is identified]"
+  "-Ywarn-inaccessible[Warn about inaccessible types in method signatures]"
+  "-Ywarn-nullary-override[Warn when non-nullary overrides nullary, e.g. def foo() over def foo]"
+  "-Ywarn-nullary-unit[Warn when nullary methods return Unit]"
+  "-Ywarn-numeric-widen[Warn when numerics are widened]"
+  "-Ywarn-value-discard[Warn when non-Unit expression results are unused]"
+
+  "-Ybuild-manager-debug[Generate debug information for the Refined Build Manager compiler]"
+  "-Ybuilder-debug\:-[Compile using the specified build manager (default\: none)]:manager:(none refined simple)"
+  "-Ycompletion-debug[Trace all tab completion activity]"
+  "-Ydebug[Increase the quantity of debugging output]"
+  "-Ydoc-debug[Trace all scaladoc activity]"
+  "-Yide-debug[Generate, validate and output trees using the interactive compiler]"
+  "-Yinfer-debug[Trace type inference and implicit search]"
+  "-Yissue-debug[Print stack traces when a context issues an error]"
+  "-Ypatmat-debug[Trace pattern matching translation]"
+  "-Ypmat-debug[Trace all pattern matcher activity]"
+  "-Ypos-debug[Trace position validation]"
+  "-Ypresentation-debug[Enable debugging output for the presentation compiler]"
+  "-Yreify-debug[Trace reification]"
+  "-Yrepl-debug[Trace all REPL activity]"
+  "-Ytyper-debug[Trace all type assignments]"
+)
+
+local -a scala_opts
+scala_opts=(
+  "-e+[execute <string> as if entered in the repl]:string" \
+  "-howtorun+[what to run (default\: guess)]:execution mode:(script object jar guess)" \
+  "-i+[preload <file> before starting the repl]:file to preload:_files" \
+  "-nc[no compilation daemon\: do not use the fsc offline compiler]" \
+  "-save[save the compiled script in a jar for future use]"
+)
+
+case $words[$CURRENT] in
+    -X*) _arguments $X_opts;;
+    -Y*) _arguments $Y_opts;;
+      *) case $service in
+           scala)  _arguments $scala_opts $shared_opts "*::filename:_files";;
+           scalac) _arguments $shared_opts "*::filename:_files";;
+         esac
+esac
+
+return 0
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/README.md
new file mode 100644 (file)
index 0000000..d8535f9
--- /dev/null
@@ -0,0 +1,159 @@
+# scd - smart change of directory
+
+Define `scd` shell function for changing to any directory with
+a few keystrokes.
+
+`scd` keeps history of the visited directories, which serves as an index of
+the known paths.  The directory index is updated after every `cd` command in
+the shell and can be also filled manually by running `scd -a`.  To switch to
+some directory, `scd` needs few fragments of the desired path to match with
+the index.  A selection menu is displayed in case of several matches, with a
+preference given to recently visited paths.  `scd` can create permanent
+directory aliases, which appear as named directories in zsh session.
+
+## INSTALLATION NOTES
+
+Besides oh-my-zsh, `scd` can be used with *bash*, *dash* or *tcsh*
+shells and is also available as Vim plugin
+[scd.vim](https://github.com/pavoljuhas/scd.vim) and
+[IPython](https://ipython.org) extension.  For installation details, see
+https://github.com/pavoljuhas/smart-change-directory.
+
+## SYNOPSIS
+
+```sh
+scd [options] [pattern1 pattern2 ...]
+```
+
+## PATTERNS
+
+Patterns may use all zsh [glob operators](
+http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Operators)
+available with *extendedglob* option.  Specified patterns must match
+the absolute path and at least one of them must match in the tail.
+Several special patterns are also recognized as follows:
+
+<dl><dt>
+^PAT</dt><dd>
+  PAT must match at the beginning of the path, for example, "^/home"</dd><dt>
+PAT$</dt><dd>
+  require PAT to match the end of the path, "man$"</dd><dt>
+./</dt><dd>
+  match only subdirectories of the current directory</dd><dt>
+:PAT</dt><dd>
+  require PAT to match over the tail component, ":doc", ":re/doc"</dd>
+</dl>
+
+
+## OPTIONS
+
+<dl><dt>
+-a, --add</dt><dd>
+  add current or specified directories to the directory index.</dd><dt>
+
+--unindex</dt><dd>
+  remove current or specified directories from the index.</dd><dt>
+
+-r, --recursive</dt><dd>
+  apply options <em>--add</em> or <em>--unindex</em> recursively.</dd><dt>
+
+--alias=ALIAS</dt><dd>
+  create alias for the current or specified directory and save it to
+  <em>~/.scdalias.zsh</em>.</dd><dt>
+
+--unalias</dt><dd>
+  remove ALIAS definition for the current or specified directory from
+  <em>~/.scdalias.zsh</em>.  Use "OLD" to purge aliases to non-existent
+  directories.</dd><dt>
+
+-A, --all</dt><dd>
+  display all directories even those excluded by patterns in
+  <em>~/.scdignore</em>.  Disregard the unique matching for a
+  directory alias and filtering of less likely paths.</dd><dt>
+
+-p, --push</dt><dd>
+  use "pushd" to change to the target directory.</dd><dt>
+
+--list</dt><dd>
+  show matching directories and exit.</dd><dt>
+
+-v, --verbose</dt><dd>
+  display directory rank in the selection menu.</dd><dt>
+
+-h, --help</dt><dd>
+  display this options summary and exit.</dd>
+</dl>
+
+
+## Examples
+
+```sh
+# Index recursively some paths for the very first run
+scd -ar ~/Documents/
+
+# Change to a directory path matching "doc"
+scd doc
+
+# Change to a path matching all of "a", "b" and "c"
+scd a b c
+
+# Change to a directory path that ends with "ts"
+scd "ts$"
+
+# Show selection menu and ranking of 20 most likely directories
+scd -v
+
+# Alias current directory as "xray"
+scd --alias=xray
+
+# Jump to a previously defined aliased directory
+scd xray
+```
+
+## FILES
+
+<dl><dt>
+~/.scdhistory</dt><dd>
+    time-stamped index of visited directories.</dd><dt>
+
+~/.scdalias.zsh</dt><dd>
+    scd-generated definitions of directory aliases.</dd><dt>
+
+~/.scdignore</dt><dd>
+    <a href="http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Operators">
+    glob patterns</a> for paths to be ignored in the scd search, for example,
+    <code>/mnt/backup/*</code>.  The patterns are specified one per line
+    and are matched assuming the <em>extendedglob</em> zsh option.  Lines
+    starting with "#" are skipped as comments.  The .scdignore patterns
+    are not applied in the <em>--all</em> mode.</dd>
+</dl>
+
+
+## ENVIRONMENT
+
+<dl><dt>
+SCD_HISTFILE</dt><dd>
+    path to the scd index file (by default ~/.scdhistory).</dd><dt>
+
+SCD_HISTSIZE</dt><dd>
+    maximum number of entries in the index (5000).  Index is trimmed when it
+    exceeds <em>SCD_HISTSIZE</em> by more than 20%.</dd><dt>
+
+SCD_MENUSIZE</dt><dd>
+    maximum number of items for directory selection menu (20).</dd><dt>
+
+SCD_MEANLIFE</dt><dd>
+    mean lifetime in seconds for exponential decay of directory
+    likelihood (86400).</dd><dt>
+
+SCD_THRESHOLD</dt><dd>
+    threshold for cumulative directory likelihood.  Directories with
+    a lower likelihood compared to the best match are excluded (0.005).
+    </dd><dt>
+
+SCD_SCRIPT</dt><dd>
+    command script file where scd writes the final <code>cd</code>
+    command.  This variable must be defined when scd runs in its own
+    process rather than as a shell function.  It is up to the
+    scd caller to use the output in <em>SCD_SCRIPT</em>.</dd>
+</dl>
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/_scd b/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/_scd
new file mode 100644 (file)
index 0000000..39c7fa4
--- /dev/null
@@ -0,0 +1,60 @@
+#compdef scd
+#description smart change directory
+
+local curcontext="$curcontext" state line expl ret=1
+typeset -A opt_args
+
+local -a indexopts myargs
+indexopts=( --add -a --unindex )
+
+myargs=(
+    # common options
+    "(--help -h)"{--help,-h}"[print help and exit]"
+
+    # options for manipulating directory index
+    - index
+    "(--recursive -r)"{--recursive,-r}"[use recursive --add or --unindex]"
+    "($indexopts)"{--add,-a}"[add specified directories to the index]"
+    "($indexopts)--unindex[remove specified directories from the index]"
+    "*:directory:{ (( ${words[(I)-a|--add|--unindex]} )) && _path_files -/ }"
+
+    # define new directory alias
+    - alias
+    "--alias=[create alias for this or given directory]:directory-alias:()"
+    '1:directory:{ (( words[(I)--alias*] )) && _path_files -/ }'
+
+    # remove definition of directory alias
+    - unalias
+    "--unalias[remove definition of directory alias]"
+    "*::directory alias:->scd-alias-target"
+
+    # act on the directory change
+    - scd
+    "(--all -A)"{--all,-A}"[include less likely and ignored paths]"
+    "--list[print matching directories and exit]"
+    "(--verbose -v)"{--verbose,-v}"[show directory ranking and full paths]"
+    "(--push -p)"{--push,-p}"[change directory with 'pushd']"
+    "1::directory alias:->scd-alias-target"
+    "*:patterns:()"
+)
+
+_arguments -S -C $myargs && ret=0
+
+
+if [[ "$state" == scd-alias-target && -s ~/.scdalias.zsh ]]; then
+    local -a scdaliases
+    scdaliases=( )
+    eval "$(setopt extendedglob
+            phome="(#b)(#s)${HOME}(/*)#(#e)"
+            builtin hash -dr
+            source ~/.scdalias.zsh &&
+            for k v in ${(kv)nameddirs}; do
+                scdaliases+=( $k:${v/${~phome}/"~"${match[1]}} )
+            done
+            complete_unalias=${+opt_args[unalias---unalias]}
+            if (( complete_unalias && ! ${+nameddirs[OLD]} )); then
+                scdaliases+=( 'OLD:all aliases to non-existent paths' )
+            fi
+            typeset -p scdaliases )"
+    _describe -t scdaliases scdalias scdaliases
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/scd b/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/scd
new file mode 100755 (executable)
index 0000000..7e9654b
--- /dev/null
@@ -0,0 +1,533 @@
+#!/bin/zsh -f
+
+emulate -L zsh
+
+local RUNNING_AS_COMMAND=
+local EXIT=return
+if [[ $(whence -w $0) == *:' 'command ]]; then
+    RUNNING_AS_COMMAND=1
+    EXIT=exit
+fi
+
+local DOC='scd -- smart change to a recently used directory
+usage: scd [options] [pattern1 pattern2 ...]
+Go to a directory path that matches all patterns.  Prefer recent or
+frequently visited directories as found in the directory index.
+Display a selection menu in case of multiple matches.
+
+Special patterns:
+  ^PAT      match at the path root, "^/home"
+  PAT$      match paths ending with PAT, "man$"
+  ./        match paths under the current directory
+  :PAT      require PAT to span the tail, ":doc", ":re/doc"
+
+Options:
+  -a, --add         add current or specified directories to the index.
+  --unindex         remove current or specified directories from the index.
+  -r, --recursive   apply options --add or --unindex recursively.
+  --alias=ALIAS     create alias for the current or specified directory and
+                    store it in ~/.scdalias.zsh.
+  --unalias         remove ALIAS definition for the current or specified
+                    directory from ~/.scdalias.zsh.
+                    Use "OLD" to purge aliases to non-existent directories.
+  -A, --all         display all directories even those excluded by patterns
+                    in ~/.scdignore.  Disregard unique match for a directory
+                    alias and filtering of less likely paths.
+  -p, --push        use "pushd" to change to the target directory.
+  --list            show matching directories and exit.
+  -v, --verbose     display directory rank in the selection menu.
+  -h, --help        display this message and exit.
+'
+
+local SCD_HISTFILE=${SCD_HISTFILE:-${HOME}/.scdhistory}
+local SCD_HISTSIZE=${SCD_HISTSIZE:-5000}
+local SCD_MENUSIZE=${SCD_MENUSIZE:-20}
+local SCD_MEANLIFE=${SCD_MEANLIFE:-86400}
+local SCD_THRESHOLD=${SCD_THRESHOLD:-0.005}
+local SCD_SCRIPT=${RUNNING_AS_COMMAND:+$SCD_SCRIPT}
+local SCD_ALIAS=~/.scdalias.zsh
+local SCD_IGNORE=~/.scdignore
+
+# Minimum logarithm of probability.  Avoids out of range warning in exp().
+local -r MINLOGPROB=-15
+
+# When false, use case-insensitive globbing to fix PWD capitalization.
+local PWDCASECORRECT=true
+if [[ ${OSTYPE} == darwin* ]]; then
+    PWDCASECORRECT=false
+fi
+
+local a d m p i maxrank threshold
+local opt_help opt_add opt_unindex opt_recursive opt_verbose
+local opt_alias opt_unalias opt_all opt_push opt_list
+local -A drank dalias scdignore
+local dmatching
+local last_directory
+
+setopt extendedglob noautonamedirs brace_ccl
+
+# If SCD_SCRIPT is defined make sure that that file exists and is empty.
+# This removes any old previous commands from the SCD_SCRIPT file.
+[[ -n "$SCD_SCRIPT" ]] && [[ -s $SCD_SCRIPT || ! -f $SCD_SCRIPT ]] && (
+    umask 077
+    : >| $SCD_SCRIPT
+)
+
+# process command line options
+zmodload -i zsh/zutil
+zmodload -i zsh/datetime
+zmodload -i zsh/parameter
+zparseopts -D -E -- a=opt_add -add=opt_add -unindex=opt_unindex \
+    r=opt_recursive -recursive=opt_recursive \
+    -alias:=opt_alias -unalias=opt_unalias \
+    A=opt_all -all=opt_all p=opt_push -push=opt_push -list=opt_list \
+    v=opt_verbose -verbose=opt_verbose h=opt_help -help=opt_help \
+    || $EXIT $?
+
+# remove the first instance of "--" from positional arguments
+argv[(i)--]=( )
+
+if [[ -n $opt_help ]]; then
+    print $DOC
+    $EXIT
+fi
+
+# load directory aliases if they exist
+[[ -r $SCD_ALIAS ]] && source $SCD_ALIAS
+
+# load scd-ignore patterns if available
+if [[ -s $SCD_IGNORE ]]; then
+    setopt noglob
+    <$SCD_IGNORE \
+    while read p; do
+        [[ $p != [\#]* ]] || continue
+        [[ -n $p ]] || continue
+        # expand leading tilde if it has valid expansion
+        if [[ $p == [~]* ]] && ( : ${~p} ) 2>/dev/null; then
+            p=${~p}
+        fi
+        scdignore[$p]=1
+    done
+    setopt glob
+fi
+
+# Private internal functions are prefixed with _scd_Y19oug_.
+# Clean them up when the scd function returns.
+setopt localtraps
+trap 'unfunction -m "_scd_Y19oug_*"' EXIT
+
+# works faster than the (:a) modifier and is compatible with zsh 4.2.6
+_scd_Y19oug_abspath() {
+    set -A $1 ${(ps:\0:)"$(
+        setopt pushdsilent
+        unfunction -m "*"
+        unalias -m "*"
+        unset CDPATH
+        shift
+        for d; do
+            pushd $d || continue
+            $PWDCASECORRECT &&
+                print -Nr -- $PWD ||
+                print -Nr -- (#i)$PWD
+            popd 2>/dev/null
+        done
+        )"}
+}
+
+# define directory alias
+if [[ -n $opt_alias ]]; then
+    if [[ -n $1 && ! -d $1 ]]; then
+        print -u2 "'$1' is not a directory."
+        $EXIT 1
+    fi
+    a=${opt_alias[-1]#=}
+    _scd_Y19oug_abspath d ${1:-$PWD}
+    # alias in the current shell, update alias file if successful
+    hash -d -- $a=$d &&
+    (
+        umask 077
+        hash -dr
+        [[ -r $SCD_ALIAS ]] && source $SCD_ALIAS
+        hash -d -- $a=$d
+        hash -dL >| $SCD_ALIAS
+    )
+    $EXIT $?
+fi
+
+# undefine one or more directory aliases
+if [[ -n $opt_unalias ]]; then
+    local -U uu
+    local ec=0
+    uu=( ${*:-${PWD}} )
+    if (( ${uu[(I)OLD]} && ${+nameddirs[OLD]} == 0 )); then
+        uu=( ${uu:#OLD} ${(ps:\0:)"$(
+            hash -dr
+            if [[ -r $SCD_ALIAS ]]; then
+                source $SCD_ALIAS
+            fi
+            for a d in ${(kv)nameddirs}; do
+                [[ -d $d ]] || print -Nr -- $a
+            done
+            )"}
+        )
+    fi
+    m=( )
+    for p in $uu; do
+        d=$p
+        if [[ ${+nameddirs[$d]} == 0 && -d $d ]]; then
+            _scd_Y19oug_abspath d $d
+        fi
+        a=${(k)nameddirs[$d]:-${(k)nameddirs[(r)$d]}}
+        if [[ -z $a ]]; then
+            ec=1
+            print -u2 "'$p' is neither a directory alias nor an aliased path."
+            continue
+        fi
+        # unalias in the current shell and remember to update the alias file
+        if unhash -d -- $a 2>/dev/null; then
+            m+=( $a )
+        fi
+    done
+    if [[ $#m != 0 && -r $SCD_ALIAS ]]; then
+        (
+            umask 077
+            hash -dr
+            source $SCD_ALIAS
+            for a in $m; do
+                unhash -d -- $a 2>/dev/null
+            done
+            hash -dL >| $SCD_ALIAS
+        ) || ec=$?
+    fi
+    $EXIT $ec
+fi
+
+# The "compress" function collapses repeated directories into
+# a single entry with a time-stamp yielding an equivalent probability.
+_scd_Y19oug_compress() {
+    awk -v epochseconds=$EPOCHSECONDS \
+        -v meanlife=$SCD_MEANLIFE \
+        -v minlogprob=$MINLOGPROB \
+        '
+        BEGIN {
+            FS = "[:;]";
+            pmin = exp(minlogprob);
+        }
+        /^: deleted:0;/ { next; }
+        length($0) < 4096 && $2 > 1000 {
+            df = $0;
+            sub("^[^;]*;", "", df);
+            if (!df)  next;
+            tau = 1.0 * ($2 - epochseconds) / meanlife;
+            prob = (tau < minlogprob) ? pmin : exp(tau);
+            dlist[last[df]] = "";
+            dlist[NR] = df;
+            last[df] = NR;
+            ptot[df] += prob;
+        }
+        END {
+            for (i = 1; i <= NR; ++i) {
+                d = dlist[i];
+                if (d) {
+                    ts = log(ptot[d]) * meanlife + epochseconds;
+                    printf(": %.0f:0;%s\n", ts, d);
+                }
+            }
+        }
+        ' $*
+}
+
+# Rewrite directory index if it is at least 20% oversized.
+local curhistsize
+if [[ -z $opt_unindex && -s $SCD_HISTFILE ]] && \
+curhistsize=$(wc -l <$SCD_HISTFILE) && \
+(( $curhistsize > 1.2 * $SCD_HISTSIZE )); then
+    # Compress repeated entries in a background process.
+    (
+        m=( ${(f)"$(_scd_Y19oug_compress $SCD_HISTFILE)"} )
+        # purge non-existent and ignored directories
+        m=( ${(f)"$(
+            for a in $m; do
+                d=${a#*;}
+                [[ -z ${scdignore[(k)$d]} ]] || continue
+                [[ -d $d ]] || continue
+                $PWDCASECORRECT || d=( (#i)${d} )
+                t=${a%%;*}
+                print -r -- "${t};${d}"
+            done
+            )"}
+        )
+        # cut old entries if still oversized
+        if [[ $#m -gt $SCD_HISTSIZE ]]; then
+            m=( ${m[-$SCD_HISTSIZE,-1]} )
+        fi
+        # Checking existence of many directories could have taken a while.
+        # Append any index entries added in meantime.
+        m+=( ${(f)"$(sed "1,${curhistsize}d" $SCD_HISTFILE)"} )
+        print -lr -- $m >| ${SCD_HISTFILE}
+    ) &|
+fi
+
+# Determine the last recorded directory
+if [[ -s ${SCD_HISTFILE} ]]; then
+    last_directory=${"$(tail -n 1 ${SCD_HISTFILE})"#*;}
+fi
+
+# The "record" function adds its arguments to the directory index.
+_scd_Y19oug_record() {
+    while [[ -n $last_directory && $1 == $last_directory ]]; do
+        shift
+    done
+    if [[ $# -gt 0 ]]; then
+        ( umask 077
+          p=": ${EPOCHSECONDS}:0;"
+          print -lr -- ${p}${^*} >>| $SCD_HISTFILE )
+    fi
+}
+
+if [[ -n $opt_add ]]; then
+    m=( ${^${argv:-$PWD}}(N-/) )
+    _scd_Y19oug_abspath m ${m}
+    _scd_Y19oug_record $m
+    if [[ -n $opt_recursive ]]; then
+        for d in $m; do
+            print -n "scanning ${d} ... "
+            _scd_Y19oug_record ${d}/**/*(-/N)
+            print "[done]"
+        done
+    fi
+    $EXIT
+fi
+
+# take care of removing entries from the directory index
+if [[ -n $opt_unindex ]]; then
+    if [[ ! -s $SCD_HISTFILE ]]; then
+        $EXIT
+    fi
+    argv=( ${argv:-$PWD} )
+    # expand existing directories in the argument list
+    for i in {1..$#}; do
+        if [[ -d ${argv[i]} ]]; then
+            _scd_Y19oug_abspath d ${argv[i]}
+            argv[i]=${d}
+        fi
+    done
+    # strip trailing slashes, but preserve the root path
+    argv=( ${argv/(#m)?\/##(#e)/${MATCH[1]}} )
+    m="$(awk -v recursive=${opt_recursive} '
+        BEGIN {
+            for (i = 2; i < ARGC; ++i) {
+                argset[ARGV[i]] = 1;
+                delete ARGV[i];
+            }
+            unindex_root = ("/" in argset);
+        }
+        1 {
+            d = $0;  sub(/^[^;]*;/, "", d);
+            if (d in argset)  next;
+        }
+        recursive {
+            if (unindex_root)  exit;
+            for (a in argset) {
+                if (substr(d, 1, length(a) + 1) == a"/")  next;
+            }
+        }
+        { print $0 }
+        ' $SCD_HISTFILE $* )" || $EXIT $?
+    : >| ${SCD_HISTFILE}
+    [[ ${#m} == 0 ]] || print -r -- $m >> ${SCD_HISTFILE}
+    $EXIT
+fi
+
+# The "action" function is called when there is just one target directory.
+_scd_Y19oug_action() {
+    local cdcmd=cd
+    [[ -z ${opt_push} ]] || cdcmd=pushd
+    builtin $cdcmd $1 || return $?
+    if [[ -z $SCD_SCRIPT && -n $RUNNING_AS_COMMAND ]]; then
+        print -u2 "Warning: running as command with SCD_SCRIPT undefined."
+    fi
+    if [[ -n $SCD_SCRIPT ]]; then
+        local d=$1
+        if [[ $OSTYPE == cygwin && ${(L)SCD_SCRIPT} == *.bat ]]; then
+            d=$(cygpath -aw .)
+        fi
+        print -r "${cdcmd} ${(qqq)d}" >| $SCD_SCRIPT
+    fi
+}
+
+# Select and order indexed directories by matching command-line patterns.
+# Set global arrays dmatching and drank.
+_scd_Y19oug_match() {
+    ## single argument that is an existing directory or directory alias
+    if [[ -z $opt_all && $# == 1 ]] && \
+        [[ -d ${d::=${nameddirs[$1]}} || -d ${d::=$1} ]] && [[ -x $d ]];
+    then
+        _scd_Y19oug_abspath dmatching $d
+        drank[${dmatching[1]}]=1
+        return
+    fi
+
+    # quote brackets when PWD is /Volumes/[C]/
+    local qpwd=${PWD//(#m)[][]/\\${MATCH}}
+
+    # support "./" as an alias for $PWD to match only subdirectories.
+    argv=( ${argv/(#s).\/(#e)/(#s)${qpwd}(|/*)(#e)} )
+
+    # support "./pat" as an alias for $PWD/pat.
+    argv=( ${argv/(#m)(#s).\/?*/(#s)${qpwd}${MATCH#.}} )
+
+    # support "^" as an anchor for the root directory, e.g., "^$HOME".
+    argv=( ${argv/(#m)(#s)\^?*/(#s)${${~MATCH[2,-1]}}} )
+
+    # support "$" as an anchor at the end of directory name.
+    argv=( ${argv/(#m)?[$](#e)/${MATCH[1]}(#e)} )
+
+    # support prefix ":" to match over the tail component.
+    argv=( ${argv/(#m)(#s):?*/${MATCH[2,-1]}[^/]#(#e)} )
+
+    # calculate rank of all directories in SCD_HISTFILE and store it in drank.
+    # include a dummy entry to avoid issues with splitting an empty string.
+    [[ -s $SCD_HISTFILE ]] && drank=( ${(f)"$(
+        print -l /dev/null -10
+        <$SCD_HISTFILE \
+        awk -v epochseconds=$EPOCHSECONDS \
+            -v meanlife=$SCD_MEANLIFE \
+            -v minlogprob=$MINLOGPROB \
+            '
+            BEGIN {
+                FS = "[:;]";
+                pmin = exp(minlogprob);
+            }
+            /^: deleted:0;/ {
+                df = $0;
+                sub("^[^;]*;", "", df);
+                delete ptot[df];
+                next;
+            }
+            length($0) < 4096 && $2 > 0 {
+                df = $0;
+                sub("^[^;]*;", "", df);
+                if (!df)  next;
+                dp = df;
+                while (!(dp in ptot)) {
+                    ptot[dp] = pmin;
+                    sub("//*[^/]*$", "", dp);
+                    if (!dp)  break;
+                }
+                if ($2 <= 1000)  next;
+                tau = 1.0 * ($2 - epochseconds) / meanlife;
+                prob = (tau < minlogprob) ? pmin : exp(tau);
+                ptot[df] += prob;
+            }
+            END { for (di in ptot)  { print di; print ptot[di]; } }
+            '
+        )"}
+    )
+    unset "drank[/dev/null]"
+
+    # filter drank to the entries that match all arguments
+    for a; do
+        p="(#l)*(${a})*"
+        drank=( ${(kv)drank[(I)${~p}]} )
+    done
+    # require that at least one argument matches in directory tail name.
+    p="(#l)*(${(j:|:)argv})[^/]#"
+    drank=( ${(kv)drank[(I)${~p}]} )
+
+    # discard ignored directories
+    if [[ -z ${opt_all} ]]; then
+        for d in ${(k)drank}; do
+            [[ -z ${scdignore[(k)$d]} ]] || unset "drank[$d]"
+        done
+    fi
+
+    # build a list of matching directories reverse-sorted by their probabilities
+    dmatching=( ${(f)"$(
+        builtin printf "%s %s\n" ${(Oakv)drank} |
+        /usr/bin/sort -grk1 )"}
+    )
+    dmatching=( ${dmatching#*[[:blank:]]} )
+
+    # do not match $HOME or $PWD when run without arguments
+    if [[ $# == 0 ]]; then
+        dmatching=( ${dmatching:#(${HOME}|${PWD})} )
+    fi
+
+    # keep at most SCD_MENUSIZE of matching and valid directories
+    # mark up any deleted entries in the index
+    local -A isdeleted
+    m=( )
+    isdeleted=( )
+    for d in $dmatching; do
+        [[ ${#m} == $SCD_MENUSIZE ]] && break
+        (( ${+isdeleted[$d]} == 0 )) || continue
+        [[ -d $d ]] || { isdeleted[$d]=1; continue }
+        [[ -x $d ]] && m+=$d
+    done
+    dmatching=( $m )
+    if [[ -n ${isdeleted} ]]; then
+        print -lr -- ": deleted:0;"${^${(k)isdeleted}} >> $SCD_HISTFILE
+    fi
+
+    # find the maximum rank
+    maxrank=0.0
+    for d in $dmatching; do
+        [[ ${drank[$d]} -lt maxrank ]] || maxrank=${drank[$d]}
+    done
+
+    # discard all directories below the rank threshold
+    threshold=$(( maxrank * SCD_THRESHOLD ))
+    if [[ -n ${opt_all} ]]; then
+        threshold=0
+    fi
+    dmatching=( ${^dmatching}(Ne:'(( ${drank[$REPLY]} >= threshold ))':) )
+}
+
+_scd_Y19oug_match $*
+
+## process matching directories.
+if [[ ${#dmatching} == 0 ]]; then
+    print -u2 "No matching directory."
+    $EXIT 1
+fi
+
+## build formatted directory aliases for selection menu or list display
+for d in $dmatching; do
+    if [[ -n ${opt_verbose} ]]; then
+        dalias[$d]=$(printf "%.3g %s" ${drank[$d]} $d)
+    else
+        dalias[$d]=$(print -Dr -- $d)
+    fi
+done
+
+## process the --list option
+if [[ -n $opt_list ]]; then
+    for d in $dmatching; do
+        print -r -- "# ${dalias[$d]}"
+        print -r -- $d
+    done
+    $EXIT
+fi
+
+## handle a single matching directory here.
+if [[ ${#dmatching} == 1 ]]; then
+    _scd_Y19oug_action $dmatching
+    $EXIT $?
+fi
+
+## Here we have multiple matches.  Let's use the selection menu.
+a=( {a-z} {A-Z} )
+a=( ${a[1,${#dmatching}]} )
+p=( )
+for i in {1..${#dmatching}}; do
+    [[ -n ${a[i]} ]] || break
+    p+="${a[i]}) ${dalias[${dmatching[i]}]}"
+done
+
+print -c -r -- $p
+
+if read -s -k 1 d && [[ ${i::=${a[(I)$d]}} -gt 0 ]]; then
+    _scd_Y19oug_action ${dmatching[i]}
+    $EXIT $?
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/scd.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/scd/scd.plugin.zsh
new file mode 100644 (file)
index 0000000..1a6c186
--- /dev/null
@@ -0,0 +1,17 @@
+## The scd script should autoload as a shell function.
+autoload -Uz scd
+
+
+## If the scd function exists, define a change-directory-hook function
+## to record visited directories in the scd index.
+if [[ ${+functions[scd]} == 1 ]]; then
+    chpwd_scd() { scd --add $PWD }
+    autoload -Uz add-zsh-hook
+    add-zsh-hook chpwd chpwd_scd
+fi
+
+
+## Load the directory aliases created by scd if any.
+if [[ -s ~/.scdalias.zsh ]]; then
+    source ~/.scdalias.zsh
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/screen/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/screen/README.md
new file mode 100644 (file)
index 0000000..103e172
--- /dev/null
@@ -0,0 +1,10 @@
+# screen
+
+This plugin sets title and hardstatus of the tab window for [screen](https://www.gnu.org/software/screen/),
+the terminal multiplexer.
+
+To use it add `screen` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... screen)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/screen/screen.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/screen/screen.plugin.zsh
new file mode 100644 (file)
index 0000000..c1db8ad
--- /dev/null
@@ -0,0 +1,54 @@
+# if using GNU screen, let the zsh tell screen what the title and hardstatus
+# of the tab window should be.
+if [[ "$TERM" == screen* ]]; then
+  if [[ $_GET_PATH == '' ]]; then
+    _GET_PATH='echo $PWD | sed "s/^\/Users\//~/;s/^\/home\//~/;s/^~$USERNAME/~/"'
+  fi
+  if [[ $_GET_HOST == '' ]]; then
+    _GET_HOST='echo $HOST | sed "s/\..*//"'
+  fi
+
+  # use the current user as the prefix of the current tab title 
+  TAB_TITLE_PREFIX='"`'$_GET_HOST'`:`'$_GET_PATH' | sed "s:..*/::"`$PROMPT_CHAR"'
+  # when at the shell prompt, show a truncated version of the current path (with
+  # standard ~ replacement) as the rest of the title.
+  TAB_TITLE_PROMPT='$SHELL:t'
+  # when running a command, show the title of the command as the rest of the
+  # title (truncate to drop the path to the command)
+  TAB_TITLE_EXEC='$cmd[1]:t'
+
+  # use the current path (with standard ~ replacement) in square brackets as the
+  # prefix of the tab window hardstatus.
+  TAB_HARDSTATUS_PREFIX='"[`'$_GET_PATH'`] "'
+  # when at the shell prompt, use the shell name (truncated to remove the path to
+  # the shell) as the rest of the title
+  TAB_HARDSTATUS_PROMPT='$SHELL:t'
+  # when running a command, show the command name and arguments as the rest of
+  # the title
+  TAB_HARDSTATUS_EXEC='$cmd'
+
+  # tell GNU screen what the tab window title ($1) and the hardstatus($2) should be
+  function screen_set()
+  {
+    # set the tab window title (%t) for screen
+    print -nR $'\033k'$1$'\033'\\\
+
+    # set hardstatus of tab window (%h) for screen
+    print -nR $'\033]0;'$2$'\a'
+  }
+  # called by zsh before executing a command
+  function preexec()
+  {
+    local -a cmd; cmd=(${(z)1}) # the command string
+    eval "tab_title=$TAB_TITLE_PREFIX:$TAB_TITLE_EXEC"
+    eval "tab_hardstatus=$TAB_HARDSTATUS_PREFIX:$TAB_HARDSTATUS_EXEC"
+    screen_set $tab_title $tab_hardstatus
+  }
+  # called by zsh before showing the prompt
+  function precmd()
+  {
+    eval "tab_title=$TAB_TITLE_PREFIX:$TAB_TITLE_PROMPT"
+    eval "tab_hardstatus=$TAB_HARDSTATUS_PREFIX:$TAB_HARDSTATUS_PROMPT"
+    screen_set $tab_title $tab_hardstatus
+  }
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scw/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/scw/README.md
new file mode 100644 (file)
index 0000000..d2312c2
--- /dev/null
@@ -0,0 +1,7 @@
+## Scaleway CLI autocomplete plugin
+
+[scw](https://github.com/scaleway/scaleway-cli): Manage Bare Metal servers from Command Line (as easily as with Docker)
+
+- Adds autocomplete options for all `scw` commands.
+
+Maintainer : Manfred Touron ([@moul](https://github.com/moul))
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/scw/_scw b/stow/oh-my-zsh/.oh-my-zsh/plugins/scw/_scw
new file mode 100644 (file)
index 0000000..0eb125c
--- /dev/null
@@ -0,0 +1,333 @@
+#compdef scw
+#
+# zsh completion for scw (https://www.scaleway.com)
+#
+# Inspired by https://github.com/felixr/docker-zsh-completion
+
+__scw_get_servers() {
+    local expl
+    declare -a servers
+    servers=(${(f)"$(_call_program commands scw _completion servers-names)"})
+    _describe -t servers "servers" servers
+}
+
+__scw_stoppedservers() {
+    __scw_get_servers
+}
+
+__scw_runningservers() {
+    __scw_get_servers
+}
+
+__scw_servers () {
+    __scw_get_servers
+}
+
+__scw_images () {
+    local expl
+    declare -a images
+    images=(${(f)"$(_call_program commands scw _completion images-names)"})
+    _describe -t images "images" images
+}
+
+__scw_images_and_snapshots () {
+    __scw_images
+    __scw_snapshots
+}
+
+__scw_snapshots () {
+    local expl
+    declare -a snapshots
+    snapshots=(${(f)"$(_call_program commands scw _completion --prefix snapshots-names)"})
+    _describe -t snapshots "snapshots" snapshots
+}
+
+__scw_bootscripts () {
+    local expl
+    declare -a bootscripts
+    bootscripts=(${(f)"$(_call_program commands scw _completion bootscripts-names)"})
+    _describe -t bootscripts "bootscripts" bootscripts
+}
+
+__scw_tags() {
+    __scw_images
+}
+
+__scw_repositories_with_tags() {
+    __scw_images
+}
+
+__scw_search() {
+    # declare -a scwsearch
+    local cache_policy
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __scw_caching_policy
+    fi
+
+    local searchterm cachename
+    searchterm="${words[$CURRENT]%/}"
+    cachename=_scw-search-$searchterm
+
+    local expl
+    local -a result
+    if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
+        && ! _retrieve_cache ${cachename#_}; then
+        _message "Searching for ${searchterm}..."
+        result=(${${${(f)"$(_call_program commands scw search ${searchterm})"}%% *}[2,-1]})
+        _store_cache ${cachename#_} result
+    fi
+    _wanted scwsearch expl 'available images' compadd -a result
+}
+
+__scw_caching_policy()
+{
+  oldp=( "$1"(Nmh+1) )     # 1 hour
+  (( $#oldp ))
+}
+
+
+__scw_repositories () {
+    __scw_images
+}
+
+__scw_commands () {
+    # local -a  _scw_subcommands
+    local cache_policy
+
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy __scw_caching_policy
+    fi
+
+    if ( [[ ${+_scw_subcommands} -eq 0 ]] || _cache_invalid scw_subcommands) \
+        && ! _retrieve_cache scw_subcommands;
+    then
+        local -a lines
+        lines=(${(f)"$(_call_program commands scw 2>&1)"})
+        _scw_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I)    *]}]}## #}/ ##/:})
+        _scw_subcommands=($_scw_subcommands 'help:Show help for a command')
+        _store_cache scw_subcommands _scw_subcommands
+    fi
+    _describe -t scw-commands "scw command" _scw_subcommands
+}
+
+__scw_subcommand () {
+    local -a _command_args
+    case "$words[1]" in
+        (attach)
+            _arguments \
+                '--no-stdin[Do not attach stdin]' \
+                ':servers:__scw_runningservers'
+            ;;
+        (commit)
+            _arguments \
+                {-v,--volume=0}'[Volume slot]:volume: ' \
+                ':server:__scw_servers' \
+                ':repository:__scw_repositories_with_tags'
+            ;;
+        (cp)
+            _arguments \
+                ':server:->server' \
+                ':hostpath:_files'
+            case $state in
+                (server)
+                    if compset -P '*:'; then
+                        _files
+                    else
+                        __scw_servers -qS ":"
+                    fi
+                    ;;
+            esac
+            ;;
+        (exec)
+            local state ret
+            _arguments \
+                {-T,--timeout=0}'[Set timeout values to seconds]' \
+                {-w,--wait}'[Wait for SSH to be ready]' \
+                ':servers:__scw_runningservers' \
+                '*::command:->anycommand' && ret=0
+
+            case $state in
+                (anycommand)
+                    shift 1 words
+                    (( CURRENT-- ))
+                    _normal
+                    ;;
+            esac
+
+            return ret
+            ;;
+        (history)
+            _arguments \
+                '--no-trunc[Do not truncate output]' \
+                {-q,--quiet}'[Only show numeric IDs]' \
+                '*:images:__scw_images'
+            ;;
+        (images)
+            _arguments \
+                {-a,--all}'[Show all images]' \
+                '--no-trunc[Do not truncate output]' \
+                {-q,--quiet}'[Only show numeric IDs]' \
+                ':repository:__scw_repositories'
+            ;;
+        (info)
+            ;;
+        (inspect)
+            _arguments \
+                {-f,--format=-}'[Format the output using the given go template]:template: ' \
+                '*:servers:__scw_servers'
+            ;;
+        (kill)
+            _arguments \
+                '*:servers:__scw_runningservers'
+            ;;
+        (login)
+            _arguments \
+                {-o,--organization=-}'[Organization]:organization: ' \
+                {-t,--token=-}'[Token]:token: ' \
+                ':server: '
+            ;;
+        (logout)
+            _arguments \
+                ':server: '
+            ;;
+        (logs)
+            _arguments \
+                '*:servers:__scw_servers'
+            ;;
+        (port)
+            _arguments \
+                '1:servers:__scw_runningservers' \
+                '2:port:_ports'
+            ;;
+        (start)
+            _arguments \
+                {-T,--timeout=0}'[Set timeout values to seconds]' \
+                {-w,--wait}'[Wait for SSH to be ready]' \
+                '*:servers:__scw_stoppedservers'
+            ;;
+        (rm)
+            _arguments \
+                '*:servers:__scw_stoppedservers'
+            ;;
+        (rmi)
+            _arguments \
+                '*:images:__scw_images'
+            ;;
+        (restart)
+            _arguments \
+                '*:servers:__scw_runningservers'
+            ;;
+        (stop)
+            _arguments \
+                {-t,--terminate}'[Stop and trash a server with its volumes]' \
+                {-w,--wait}'[Synchronous stop. Wait for server to be stopped]' \
+                '*:servers:__scw_runningservers'
+            ;;
+        (top)
+            _arguments \
+                '1:servers:__scw_runningservers' \
+                '(-)*:: :->ps-arguments'
+            case $state in
+                (ps-arguments)
+                    _ps
+                    ;;
+            esac
+            ;;
+        (ps)
+            _arguments \
+                {-a,--all}'[Show all servers. Only running servers are shown by default]' \
+                {-l,--latest}'[Show only the latest created server]' \
+                '-n[Show n last created servers, include non-running one]:n:(1 5 10 25 50)' \
+                '--no-trunc[Do not truncate output]' \
+                {-q,--quiet}'[Only show numeric IDs]'
+            ;;
+        (tag)
+            _arguments \
+                {-f,--force}'[force]'\
+                ':image:__scw_images'\
+                ':repository:__scw_repositories_with_tags'
+            ;;
+        (create|run)
+            _arguments \
+                {-a,--attach}'[Attach to stdin, stdout or stderr]' \
+                '*'{-e,--environment=-}'[Set environment variables]:environment variable: ' \
+                '--name=-[Server name]:name: ' \
+                '--bootscript=-[Assign a bootscript]:bootscript:__scw_bootscripts ' \
+                '*-v[Bind mount a volume]:volume: '\
+                '(-):images:__scw_images_and_snapshots' \
+                '(-):command: _command_names -e' \
+                '*::arguments: _normal'
+
+            case $state in
+                (link)
+                    if compset -P '*:'; then
+                        _wanted alias expl 'Alias' compadd -E ""
+                    else
+                        __scw_runningservers -qS ":"
+                    fi
+                    ;;
+            esac
+            ;;
+        (rename)
+            _arguments \
+                ':old name:__scw_servers' \
+                ':new name: '
+            ;;
+        (search)
+            _arguments \
+                '--no-trunc[Do not truncate output]' \
+                ':term: '
+            ;;
+        (wait)
+            _arguments '*:servers:__scw_runningservers'
+            ;;
+        (help)
+            _arguments ':subcommand:__scw_commands'
+            ;;
+        (*)
+            _message 'Unknown sub command'
+    esac
+
+}
+
+_scw () {
+    # Support for subservices, which allows for `compdef _scw scw-shell=_scw_servers`.
+    # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
+    if [[ $service != scw ]]; then
+        _call_function - _$service
+        return
+    fi
+
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+      '-H[tcp://host:port to bind/connect to]:socket: ' \
+         '(-): :->command' \
+         '(-)*:: :->option-or-argument'
+
+    if (( CURRENT == 1 )); then
+
+    fi
+    case $state in
+        (command)
+            __scw_commands
+            ;;
+        (option-or-argument)
+            curcontext=${curcontext%:*:*}:scw-$words[1]:
+            __scw_subcommand
+            ;;
+    esac
+}
+
+_scw "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 4
+# indent-tabs-mode: nil
+# sh-basic-offset: 4
+# End:
+# vim: ft=zsh sw=4 ts=4 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sdk/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sdk/README.md
new file mode 100644 (file)
index 0000000..1eda5d3
--- /dev/null
@@ -0,0 +1,14 @@
+# sdk
+
+Plugin for SDKMAN, a tool for managing parallel versions of multiple Software Development Kits on most Unix based systems.
+Provides autocompletion for all known commands.
+
+To use it, add `sdk` to your plugins array in your zshrc file:
+
+```zsh
+plugins=(... sdk)
+```
+
+## Requirements
+
+* [SDKMAN](http://sdkman.io/)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sdk/sdk.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sdk/sdk.plugin.zsh
new file mode 100644 (file)
index 0000000..441bd6f
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/env zsh
+
+### SDKMAN Autocomplete for Oh My Zsh
+
+_sdk() {
+       case "${CURRENT}" in
+       2)
+               compadd -X $'Commands:\n' -- "${${(Mk)functions[@]:#__sdk_*}[@]#__sdk_}"
+               compadd -n rm
+               ;;
+       3)
+               case "${words[2]}" in
+               l|ls|list|i|install)
+                       compadd -X $'Candidates:\n' -- "${SDKMAN_CANDIDATES[@]}"
+                       ;;
+               ug|upgrade|h|home|c|current|u|use|d|default|rm|uninstall)
+                       compadd -X $'Installed Candidates:\n' -- "${${(u)${(f)$(find -L -- "${SDKMAN_CANDIDATES_DIR}" -mindepth 2 -maxdepth 2 -type d)}[@]:h}[@]:t}"
+                       ;;
+               e|env)
+                       compadd init
+                       ;;
+               offline)
+                       compadd enable disable
+                       ;;
+               selfupdate)
+                       compadd force
+                       ;;
+               flush)
+                       compadd archives broadcast temp version
+                       ;;
+               esac
+               ;;
+       4)
+               case "${words[2]}" in
+               i|install)
+                       setopt localoptions kshglob
+                       if [[ "${words[3]}" == 'java' ]]; then
+                               compadd -X $'Installable Versions of java:\n' -- "${${${${${(f)$(__sdkman_list_versions "${words[3]}")}[@]:5:-4}[@]:#* | (local only|installed ) | *}[@]##* |            | }[@]%%+( )}"
+                       else
+                               compadd -X "Installable Versions of ${words[3]}:"$'\n' -- "${${(z)${(M)${(f)${$(__sdkman_list_versions "${words[3]}")//[*+>]+( )/-}}[@]:# *}[@]}[@]:#-*}"
+                       fi
+                       ;;
+               h|home|u|use|d|default|rm|uninstall)
+                       compadd -X "Installed Versions of ${words[3]}:"$'\n' -- "${${(f)$(find -L -- "${SDKMAN_CANDIDATES_DIR}/${words[3]}" -mindepth 1 -maxdepth 1 -type d -not -name 'current')}[@]:t}"
+                       ;;
+               esac
+               ;;
+       5)
+               case "${words[2]}" in
+               i|install)
+                       _files -X "Path to Local Installation of ${words[3]} ${words[4]}:"$'\n' -/
+                       ;;
+               esac
+               ;;
+       esac
+}
+
+compdef _sdk sdk
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sfdx/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sfdx/README.md
new file mode 100644 (file)
index 0000000..259c17f
--- /dev/null
@@ -0,0 +1,11 @@
+# sfdx plugin
+
+This plugin provides autocompletion for the [Salesforce DX](https://developer.salesforce.com/tools/sfdxcli) CLI.
+
+To use it, add `sfdx` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... sfdx)
+```
+
+Original repository: https://github.com/wadewegner/salesforce-cli-zsh-completion
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sfdx/_sfdx b/stow/oh-my-zsh/.oh-my-zsh/plugins/sfdx/_sfdx
new file mode 100644 (file)
index 0000000..3a441f2
--- /dev/null
@@ -0,0 +1,1110 @@
+#compdef sfdx
+
+# DESCRIPTION: Zsh completion script for the Salesforce CLI
+# AUTHOR: Wade Wegner (@WadeWegner)
+# REPO: https://github.com/wadewegner/salesforce-cli-zsh-completion
+# LICENSE: https://github.com/wadewegner/salesforce-cli-zsh-completion/blob/master/LICENSE
+
+local -a _1st_arguments
+
+_1st_arguments=(
+       "force\:alias\:list":"list username aliases for the Salesforce CLI"
+       "force\:alias\:set":"set username aliases for the Salesforce CLI"
+       "force\:apex\:class\:create":"create an Apex class"
+       "force\:apex\:execute":"execute anonymous Apex code"
+       "force\:apex\:log\:get":"fetch a debug log"
+       "force\:apex\:log\:list":"list debug logs"
+       "force\:apex\:log\:tail":"start debug logging and display logs"
+       "force\:apex\:test\:report":"display test results"
+       "force\:apex\:test\:run":"invoke Apex tests"
+       "force\:apex\:trigger\:create":"create an Apex trigger"
+       "force\:auth\:jwt\:grant":"authorize an org using the JWT flow"
+       "force\:auth\:logout":"log out from authorized orgs"
+       "force\:auth\:sfdxurl\:store":"authorize an org using an SFDX auth URL"
+       "force\:auth\:web\:login":"authorize an org using the web login flow"
+       "force\:config\:get":"get config var values for given names"
+       "force\:config\:list":"list config vars for the Salesforce CLI"
+       "force\:config\:set":"set config vars for the Salesforce CLI"
+       "force\:data\:bulk\:delete":"bulk delete records from a csv file"
+       "force\:data\:bulk\:status":"view the status of a bulk data load job or batch"
+       "force\:data\:bulk\:upsert":"bulk upsert records from a CSV file"
+       "force\:data\:record\:create":"create a record"
+       "force\:data\:record\:delete":"delete a record"
+       "force\:data\:record\:get":"view a record"
+       "force\:data\:record\:update":"update a record"
+       "force\:data\:soql\:query":"execute a SOQL query"
+       "force\:data\:tree\:export":"export data from an org into sObject tree format for force:data:tree:import consumption"
+       "force\:data\:tree\:import":"import data into an org using SObject Tree Save API"
+       "force\:doc\:commands\:display":"display help for force commands"
+       "force\:doc\:commands\:list":"list the force commands"
+       "force\:lightning\:app\:create":"create a Lightning app"
+       "force\:lightning\:component\:create":"create a bundle for an Aura component or a Lightning web component"
+       "force\:lightning\:event\:create":"create a Lightning event"
+       "force\:lightning\:interface\:create":"create a Lightning interface"
+       "force\:lightning\:lint":"analyse (lint) Lightning component code"
+       "force\:lightning\:test\:create":"create a Lightning test"
+       "force\:lightning\:test\:install":"install Lightning Testing Service unmanaged package in your org"
+       "force\:lightning\:test\:run":"invoke Aura component tests"
+       "force\:limits\:api\:display":"display current org’s limits"
+       "force\:mdapi\:convert":"convert metadata from the Metadata API format into the source format"
+       "force\:mdapi\:deploy":"deploy metadata to an org using Metadata API"
+       "force\:mdapi\:deploy\:cancel":"cancel a metadata deployment"
+       "force\:mdapi\:deploy\:report":"check the status of a metadata deployment"
+       "force\:mdapi\:retrieve":"retrieve metadata from an org using Metadata API"
+       "force\:mdapi\:retrieve\:report":"check the status of a metadata retrieval"
+       "force\:org\:create":"create a scratch org"
+       "force\:org\:delete":"mark a scratch org for deletion"
+       "force\:org\:display":"get org description"
+       "force\:org\:list":"list all orgs you’ve created or authenticated to"
+       "force\:org\:open":"open an org in your browser"
+       "force\:org\:shape\:create":"create a snapshot of org edition, features, and licenses"
+       "force\:org\:shape\:delete":"delete all org shapes for a target org"
+       "force\:org\:shape\:list":"list all org shapes you’ve created"
+       "force\:org\:snapshot\:create":"snapshot a scratch org"
+       "force\:org\:snapshot\:delete":"delete a scratch org snapshot"
+       "force\:org\:snapshot\:get":"get details about a scratch org snapshot"
+       "force\:org\:snapshot\:list":"list scratch org snapshots"
+       "force\:package1\:version\:create":"create a first-generation package version in the release org"
+       "force\:package1\:version\:create\:get":"retrieve the status of a package version creation request"
+       "force\:package1\:version\:display":"display details about a first-generation package version"
+       "force\:package1\:version\:list":"list package versions for the specified first-generation package or for the org"
+       "force\:package\:create":"create a package"
+       "force\:package\:hammertest\:list":"list the statuses of running and completed hammer tests"
+       "force\:package\:hammertest\:report":"display the status or results of a hammer test"
+       "force\:package\:hammertest\:run":"run ISV Hammer"
+       "force\:package\:install":"install a package in the target org"
+       "force\:package\:install\:report":"retrieve the status of a package installation request"
+       "force\:package\:installed\:list":"list the org’s installed packages"
+       "force\:package\:list":"list all packages in the Dev Hub org"
+       "force\:package\:uninstall":"uninstall a second-generation package from the target org"
+       "force\:package\:uninstall\:report":"retrieve status of package uninstall request"
+       "force\:package\:update":"update package details"
+       "force\:package\:version\:create":"create a package version"
+       "force\:package\:version\:create\:list":"list package version creation requests"
+       "force\:package\:version\:create\:report":"retrieve details about a package version creation request"
+       "force\:package\:version\:list":"list all package versions in the Dev Hub org"
+       "force\:package\:version\:promote":"promote a package version to released"
+       "force\:package\:version\:report":"retrieve details about a package version in the Dev Hub org"
+       "force\:package\:version\:update":"update a package version"
+       "force\:project\:create":"create a new SFDX project"
+       "force\:project\:upgrade":"update project config files to the latest format"
+       "force\:schema\:sobject\:describe":"describe an object"
+       "force\:schema\:sobject\:list":"list all objects of a specified category"
+       "force\:source\:convert":"convert source into Metadata API format"
+       "force\:source\:delete":"delete source from your project and from a non-source-tracked org"
+       "force\:source\:deploy":"deploy source to a non-source-tracked org"
+       "force\:source\:open":"edit a Lightning Page with Lightning App Builder"
+       "force\:source\:pull":"pull source from the scratch org to the project"
+       "force\:source\:push":"push source to a scratch org from the project"
+       "force\:source\:retrieve":"retrieve source from a non-source-tracked org"
+       "force\:source\:status":"list local changes and/or changes in a scratch org"
+       "force\:user\:create":"create a user for a scratch org"
+       "force\:user\:display":"displays information about a user of a scratch org"
+       "force\:user\:list":"lists all users of a scratch org"
+       "force\:user\:password\:generate":"generate a password for scratch org users"
+       "force\:user\:permset\:assign":"assign a permission set to one or more users of an org"
+       "force\:visualforce\:component\:create":"create a Visualforce component"
+       "force\:visualforce\:page\:create":"create a Visualforce page"
+)
+
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+ _describe -t commands "sfdx command" _1st_arguments
+ return
+fi
+
+local -a _command_args
+case "$words[1]" in
+ force:limits:api:display)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:app:create)
+ _command_args=(
+ '(-n|--appname)'{-n,--appname}'[name of the generated Lightning app]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultLightningApp*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:bulk:delete)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the sObject type of the records you’re deleting]' \
+ '(-f|--csvfile)'{-f,--csvfile}'[the path to the CSV file containing the ids of the records to delete]:file:_files' \
+ '(-w|--wait)'{-w,--wait}'[the number of minutes to wait for the command to complete before displaying the results]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:bulk:status)
+ _command_args=(
+ '(-i|--jobid)'{-i,--jobid}'[the ID of the job you want to view or of the job whose batch you want to view]' \
+ '(-b|--batchid)'{-b,--batchid}'[the ID of the batch whose status you want to view]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:bulk:upsert)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the sObject type of the records you want to upsert]' \
+ '(-f|--csvfile)'{-f,--csvfile}'[the path to the CSV file that defines the records to upsert]:file:_files' \
+ '(-i|--externalid)'{-i,--externalid}'[the column name of the external ID]' \
+ '(-w|--wait)'{-w,--wait}'[the number of minutes to wait for the command to complete before displaying the results]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:class:create)
+ _command_args=(
+ '(-n|--classname)'{-n,--classname}'[name of the generated Apex class]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultApexClass*,ApexException,ApexUnitTest,InboundEmailService)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:doc:commands:display)
+ _command_args=(
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:doc:commands:list)
+ _command_args=(
+ '(-u|--usage)'{-u,--usage}'[list only docopt usage strings]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:visualforce:component:create)
+ _command_args=(
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultVFComponent*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-n|--componentname)'{-n,--componentname}'[name of the generated Visualforce component]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(-l|--label)'{-l,--label}'[Visualforce component label]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:component:create)
+ _command_args=(
+ '(-n|--componentname)'{-n,--componentname}'[name of the generated Lightning component]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultLightningCmp*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(--type)--type[type of the Lightning component (aura*,lwc)]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:mdapi:convert)
+ _command_args=(
+ '(-r|--rootdir)'{-r,--rootdir}'[the root directory containing the Metadata API–formatted metadata]:file:_files' \
+ '(-d|--outputdir)'{-d,--outputdir}'[the output directory to store the source–formatted files]:file:_files' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:source:convert)
+ _command_args=(
+ '(-r|--rootdir)'{-r,--rootdir}'[a source directory other than the default package to convert]:file:_files' \
+ '(-d|--outputdir)'{-d,--outputdir}'[output directory to store the Metadata API–formatted files in]:file:_files' \
+ '(-n|--packagename)'{-n,--packagename}'[name of the package to associate with the metadata-formatted files]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:create)
+ _command_args=(
+ '(-f|--definitionfile)'{-f,--definitionfile}'[path to a scratch org definition file]:file:_files' \
+ '(-j|--definitionjson)'{-j,--definitionjson}'[scratch org definition in json format ]' \
+ '(-n|--nonamespace)'{-n,--nonamespace}'[creates the scratch org with no namespace]' \
+ '(-c|--noancestors)'{-c,--noancestors}'[do not include second-generation package ancestors in the scratch org]' \
+ '(-i|--clientid)'{-i,--clientid}'[connected app consumer key]' \
+ '(-s|--setdefaultusername)'{-s,--setdefaultusername}'[set the created org as the default username]' \
+ '(-a|--setalias)'{-a,--setalias}'[set an alias for for the created scratch org]' \
+ '(-e|--env)'{-e,--env}'[environment where the scratch org is created: \[sandbox*,virtual,prototype\] (sandbox*,virtual,prototype)]' \
+ '(-w|--wait)'{-w,--wait}'[the streaming client socket timeout (in minutes) (default:6, min:2)]' \
+ '(-d|--durationdays)'{-d,--durationdays}'[duration of the scratch org (in days) (default:7, min:1, max:30)]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:create)
+ _command_args=(
+ '(-n|--name)'{-n,--name}'[package name]' \
+ '(-t|--packagetype)'{-t,--packagetype}'[package type (Managed,Unlocked)]' \
+ '(-d|--description)'{-d,--description}'[package description]' \
+ '(-e|--nonamespace)'{-e,--nonamespace}'[creates the package with no namespace; available only for unlocked packages.]' \
+ '(-r|--path)'{-r,--path}'[path to directory that contains the contents of the package]:file:_files' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:user:create)
+ _command_args=(
+ '(-f|--definitionfile)'{-f,--definitionfile}'[file path to a user definition]:file:_files' \
+ '(-a|--setalias)'{-a,--setalias}'[set an alias for the created username to reference within the CLI]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:project:create)
+ _command_args=(
+ '(-n|--projectname)'{-n,--projectname}'[name of the generated project]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (Defaultsfdx-project.json*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-l|--loginurl)'{-l,--loginurl}'[Salesforce instance login URL (https://login.salesforce.com*)]' \
+ '(--sourceapiversion)--sourceapiversion[source API version number (45.0*)]' \
+ '(-s|--namespace)'{-s,--namespace}'[project associated namespace]' \
+ '(-p|--defaultpackagedir)'{-p,--defaultpackagedir}'[default package directory name (force-app*)]' \
+ '(-x|--manifest)'{-x,--manifest}'[generate a manifest (package.xml) for change-set-based development]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:delete)
+ _command_args=(
+ '(-p|--noprompt)'{-p,--noprompt}'[no prompt to confirm deletion]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:source:delete)
+ _command_args=(
+ '(-r|--noprompt)'{-r,--noprompt}'[do not prompt for delete confirmation]' \
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 33) (default:33, min:1)]' \
+ '(-p|--sourcepath)'{-p,--sourcepath}'[comma-separated list of paths to the local metadata to delete]:file:_files' \
+ '(-m|--metadata)'{-m,--metadata}'[comma-separated list of names of metadata components to delete]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:mdapi:deploy)
+ _command_args=(
+ '(-c|--checkonly)'{-c,--checkonly}'[validate deploy but don’t save to the org (default:false)]' \
+ '(-d|--deploydir)'{-d,--deploydir}'[root of directory tree of files to deploy]:file:_files' \
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 0)]' \
+ '(-i|--jobid)'{-i,--jobid}'[(deprecated) job ID of the deployment you want to check; defaults to your most recent CLI deployment if not specified]' \
+ '(-l|--testlevel)'{-l,--testlevel}'[deployment testing level (NoTestRun,RunSpecifiedTests,RunLocalTests,RunAllTestsInOrg)]' \
+ '(-r|--runtests)'{-r,--runtests}'[tests to run if --testlevel RunSpecifiedTests]' \
+ '(-e|--rollbackonerror)'{-e,--rollbackonerror}'[(deprecated) roll back deployment for any failure (default:true)]' \
+ '(-o|--ignoreerrors)'{-o,--ignoreerrors}'[ignore any errors and do not roll back deployment (default:false)]' \
+ '(-g|--ignorewarnings)'{-g,--ignorewarnings}'[whether a warning will allow a deployment to complete successfully (default:false)]' \
+ '(-q|--validateddeployrequestid)'{-q,--validateddeployrequestid}'[request ID of the validated deployment to run a Quick Deploy]' \
+ '(-f|--zipfile)'{-f,--zipfile}'[path to .zip file of metadata to deploy]:file:_files' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[verbose output of deploy results]' \
+ )
+ ;;
+ force:source:deploy)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 33) (default:33, min:1)]' \
+ '(-m|--metadata)'{-m,--metadata}'[comma-separated list of metadata component names]' \
+ '(-p|--sourcepath)'{-p,--sourcepath}'[comma-separated list of paths to the local source files to deploy]:file:_files' \
+ '(-x|--manifest)'{-x,--manifest}'[file path for manifest (package.xml) of components to deploy]:file:_files' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:mdapi:deploy:cancel)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 33) (default:33, min:1)]' \
+ '(-i|--jobid)'{-i,--jobid}'[job ID of the deployment you want to cancel; defaults to your most recent CLI deployment if not specified]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:mdapi:deploy:report)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 0)]' \
+ '(-i|--jobid)'{-i,--jobid}'[job ID of the deployment you want to check; defaults to your most recent CLI deployment if not specified]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[verbose output of deploy results]' \
+ )
+ ;;
+ force:org:display)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[emit additional command output to stdout]' \
+ )
+ ;;
+ force:user:display)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:event:create)
+ _command_args=(
+ '(-n|--eventname)'{-n,--eventname}'[name of the generated Lightning event]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultLightningEvt*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:execute)
+ _command_args=(
+ '(-f|--apexcodefile)'{-f,--apexcodefile}'[path to a local file containing Apex code]:file:_files' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:config:get)
+ _command_args=(
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[emit additional command output to stdout]' \
+ )
+ ;;
+ force:package:hammertest:list)
+ _command_args=(
+ '(-i|--packageversionid)'{-i,--packageversionid}'[ID of the package version to list results for]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:hammertest:report)
+ _command_args=(
+ '(-i|--requestid)'{-i,--requestid}'[ID of the hammer request to report on]' \
+ '(-s|--summary)'{-s,--summary}'[report only a results summary (hide Apex test failures)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:hammertest:run)
+ _command_args=(
+ '(-i|--packageversionid)'{-i,--packageversionid}'[ID of the package version to test]' \
+ '(-s|--subscriberorg)'{-s,--subscriberorg}'[comma-separated list of subscriber orgs IDs]' \
+ '(-f|--subscriberfile)'{-f,--subscriberfile}'[file with list of subscriber orgs IDs, one per line]' \
+ '(-d|--scheduledrundatetime)'{-d,--scheduledrundatetime}'[earliest date/time to run the test]' \
+ '(-p|--preview)'{-p,--preview}'[run the package hammer test in the Salesforce preview version]' \
+ '(-t|--apextests)'{-t,--apextests}'[run the apex tests in the subscriber org]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:install)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[number of minutes to wait for installation status]' \
+ '(-k|--installationkey)'{-k,--installationkey}'[installation key for key-protected package (default: null)]' \
+ '(-b|--publishwait)'{-b,--publishwait}'[number of minutes to wait for subscriber package version ID to become available in the target org ]' \
+ '(-r|--noprompt)'{-r,--noprompt}'[allow Remote Site Settings and Content Security Policy websites to send or receive data without confirmation]' \
+ '(-p|--package)'{-p,--package}'[ID (starts with 04t) or alias of the package version to install]' \
+ '(-s|--securitytype)'{-s,--securitytype}'[security access type for the installed package (AllUsers,AdminsOnly)]' \
+ '(-t|--upgradetype)'{-t,--upgradetype}'[the upgrade type for the package installation (Mixed*,DeprecateOnly)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:install:report)
+ _command_args=(
+ '(-i|--requestid)'{-i,--requestid}'[ID of the package install request you want to check]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:installed:list)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:interface:create)
+ _command_args=(
+ '(-n|--interfacename)'{-n,--interfacename}'[name of the generated Lightning interface]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultLightningIntf*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:auth:jwt:grant)
+ _command_args=(
+ '(-u|--username)'{-u,--username}'[authentication username]' \
+ '(-f|--jwtkeyfile)'{-f,--jwtkeyfile}'[path to a file containing the private key]:file:_files' \
+ '(-i|--clientid)'{-i,--clientid}'[OAuth client ID (sometimes called the consumer key)]' \
+ '(-r|--instanceurl)'{-r,--instanceurl}'[the login URL of the instance the org lives on]' \
+ '(-d|--setdefaultdevhubusername)'{-d,--setdefaultdevhubusername}'[set the authenticated org as the default dev hub org for scratch org creation]' \
+ '(-s|--setdefaultusername)'{-s,--setdefaultusername}'[set the authenticated org as the default username that all commands run against]' \
+ '(-a|--setalias)'{-a,--setalias}'[set an alias for the authenticated org]' \
+ '(-p|--noprompt)'{-p,--noprompt}'[do not prompt for auth confirmation in demo mode]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:lint)
+ _command_args=(
+ '(--ignore)--ignore[pattern used to ignore some folders]' \
+ '(--files)--files[pattern used to include specific files]' \
+ '(--json)--json[format output as JSON]' \
+ '(--config)--config[path to a custom ESLint configuration file]' \
+ '(--verbose)--verbose[report warnings in addition to errors]' \
+ '(--exit)--exit[exit with error code 1 if there are lint issues]' \
+ )
+ ;;
+ force:alias:list)
+ _command_args=(
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:config:list)
+ _command_args=(
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:list)
+ _command_args=(
+ '(--all)--all[include expired, deleted, and unknown-status scratch orgs]' \
+ '(--clean)--clean[remove all local org authorizations for non-active orgs]' \
+ '(-p|--noprompt)'{-p,--noprompt}'[do not prompt for confirmation]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[list more information about each org]' \
+ )
+ ;;
+ force:package:list)
+ _command_args=(
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[display extended package detail]' \
+ )
+ ;;
+ force:user:list)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:log:get)
+ _command_args=(
+ '(-c|--color)'{-c,--color}'[colorize noteworthy log lines]' \
+ '(-i|--logid)'{-i,--logid}'[ID of the log to display]' \
+ '(-n|--number)'{-n,--number}'[number of most recent logs to display (min:1, max:25)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:log:list)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:log:tail)
+ _command_args=(
+ '(-c|--color)'{-c,--color}'[colorize noteworthy log lines]' \
+ '(-d|--debuglevel)'{-d,--debuglevel}'[debug level for trace flag]' \
+ '(-s|--skiptraceflag)'{-s,--skiptraceflag}'[skip trace flag setup]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:auth:logout)
+ _command_args=(
+ '(-a|--all)'{-a,--all}'[include all authenticated orgs]' \
+ '(-p|--noprompt)'{-p,--noprompt}'[do not prompt for confirmation]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:open)
+ _command_args=(
+ '(-p|--path)'{-p,--path}'[navigation URL path]' \
+ '(-r|--urlonly)'{-r,--urlonly}'[display navigation URL, but don’t launch browser]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:source:open)
+ _command_args=(
+ '(-f|--sourcefile)'{-f,--sourcefile}'[file to edit]:file:_files' \
+ '(-r|--urlonly)'{-r,--urlonly}'[generate a navigation URL; don’t launch the editor]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:visualforce:page:create)
+ _command_args=(
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultVFPage*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-n|--pagename)'{-n,--pagename}'[name of the generated Visualforce page]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(-l|--label)'{-l,--label}'[Visualforce page label]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:user:password:generate)
+ _command_args=(
+ '(-o|--onbehalfof)'{-o,--onbehalfof}'[comma-separated list of usernames for which to generate passwords]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:user:permset:assign)
+ _command_args=(
+ '(-n|--permsetname)'{-n,--permsetname}'[the name of the permission set to assign]' \
+ '(-o|--onbehalfof)'{-o,--onbehalfof}'[comma-separated list of usernames or aliases to assign the permission set to]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:source:pull)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 33) (default:33, min:1)]' \
+ '(-f|--forceoverwrite)'{-f,--forceoverwrite}'[ignore conflict warnings and overwrite changes to the project]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:source:push)
+ _command_args=(
+ '(-f|--forceoverwrite)'{-f,--forceoverwrite}'[ignore conflict warnings and overwrite changes to scratch org]' \
+ '(-g|--ignorewarnings)'{-g,--ignorewarnings}'[deploy changes even if warnings are generated]' \
+ '(-r|--replacetokens)'{-r,--replacetokens}'[replace tokens in source files prior to deployment]' \
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 33) (default:33, min:1)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:record:create)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the type of the record you’re creating]' \
+ '(-v|--values)'{-v,--values}'[the <fieldName>=<value> pairs you’re creating]' \
+ '(-t|--usetoolingapi)'{-t,--usetoolingapi}'[create the record with tooling api]' \
+ '(--perflog)--perflog[get API performance data.]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:record:delete)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the type of the record you’re deleting]' \
+ '(-i|--sobjectid)'{-i,--sobjectid}'[the ID of the record you’re deleting]' \
+ '(-w|--where)'{-w,--where}'[a list of <fieldName>=<value> pairs to search for]' \
+ '(-t|--usetoolingapi)'{-t,--usetoolingapi}'[delete the record with Tooling API]' \
+ '(--perflog)--perflog[get API performance data.]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:record:get)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the type of the record you’re retrieving]' \
+ '(-i|--sobjectid)'{-i,--sobjectid}'[the ID of the record you’re retrieving]' \
+ '(-w|--where)'{-w,--where}'[a list of <fieldName>=<value> pairs to search for]' \
+ '(-t|--usetoolingapi)'{-t,--usetoolingapi}'[retrieve the record with Tooling API]' \
+ '(--perflog)--perflog[get API performance data.]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:record:update)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the type of the record you’re updating]' \
+ '(-i|--sobjectid)'{-i,--sobjectid}'[the ID of the record you’re updating]' \
+ '(-w|--where)'{-w,--where}'[a list of <fieldName>=<value> pairs to search for]' \
+ '(-v|--values)'{-v,--values}'[the <fieldName>=<value> pairs you’re updating]' \
+ '(-t|--usetoolingapi)'{-t,--usetoolingapi}'[update the record with Tooling API]' \
+ '(--perflog)--perflog[get API performance data.]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:mdapi:retrieve)
+ _command_args=(
+ '(-a|--apiversion)'{-a,--apiversion}'[target API version for the retrieve (default 45.0)]' \
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: -1 (no limit))]' \
+ '(-r|--retrievetargetdir)'{-r,--retrievetargetdir}'[directory root for the retrieved files]:file:_files' \
+ '(-k|--unpackaged)'{-k,--unpackaged}'[file path of manifest of components to retrieve]:file:_files' \
+ '(-d|--sourcedir)'{-d,--sourcedir}'[source dir to use instead of default manifest sfdx-project.xml]:file:_files' \
+ '(-p|--packagenames)'{-p,--packagenames}'[a comma-separated list of packages to retrieve]' \
+ '(-s|--singlepackage)'{-s,--singlepackage}'[a single-package retrieve (default: false)]' \
+ '(-i|--jobid)'{-i,--jobid}'[(deprecated) job ID of the retrieve you want to check; defaults to your most recent CLI retrieval if not specified]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[verbose output of retrieve result]' \
+ )
+ ;;
+ force:source:retrieve)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: 33) (default:33, min:1)]' \
+ '(-x|--manifest)'{-x,--manifest}'[file path for manifest (package.xml) of components to retrieve]:file:_files' \
+ '(-m|--metadata)'{-m,--metadata}'[comma-separated list of metadata component names]' \
+ '(-p|--sourcepath)'{-p,--sourcepath}'[comma-separated list of source file paths to retrieve]:file:_files' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:mdapi:retrieve:report)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[wait time for command to finish in minutes (default: -1 (no limit))]' \
+ '(-r|--retrievetargetdir)'{-r,--retrievetargetdir}'[directory root for the retrieved files]:file:_files' \
+ '(-i|--jobid)'{-i,--jobid}'[job ID of the retrieve you want to check; defaults to your most recent CLI retrieval if not specified]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[verbose output of retrieve result]' \
+ )
+ ;;
+ force:alias:set)
+ _command_args=(
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:config:set)
+ _command_args=(
+ '(-g|--global)'{-g,--global}'[set config var globally (to be used from any directory)]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:auth:sfdxurl:store)
+ _command_args=(
+ '(-f|--sfdxurlfile)'{-f,--sfdxurlfile}'[path to a file containing the sfdx url]:file:_files' \
+ '(-d|--setdefaultdevhubusername)'{-d,--setdefaultdevhubusername}'[set the authenticated org as the default dev hub org for scratch org creation]' \
+ '(-s|--setdefaultusername)'{-s,--setdefaultusername}'[set the authenticated org as the default username that all commands run against]' \
+ '(-a|--setalias)'{-a,--setalias}'[set an alias for the authenticated org]' \
+ '(-p|--noprompt)'{-p,--noprompt}'[do not prompt for auth confirmation in demo mode]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:shape:create)
+ _command_args=(
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:shape:delete)
+ _command_args=(
+ '(-p|--noprompt)'{-p,--noprompt}'[do not prompt for confirmation]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username for the target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:shape:list)
+ _command_args=(
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[list more information about each org shape]' \
+ )
+ ;;
+ force:org:snapshot:create)
+ _command_args=(
+ '(-o|--sourceorg)'{-o,--sourceorg}'[ID or locally authenticated username or alias of scratch org to snapshot]' \
+ '(-n|--snapshotname)'{-n,--snapshotname}'[unique name of snapshot]' \
+ '(-d|--description)'{-d,--description}'[description of snapshot]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:snapshot:delete)
+ _command_args=(
+ '(-s|--snapshot)'{-s,--snapshot}'[name or ID of snapshot to delete]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:snapshot:get)
+ _command_args=(
+ '(-s|--snapshot)'{-s,--snapshot}'[name or ID of snapshot to retrieve]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:org:snapshot:list)
+ _command_args=(
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:schema:sobject:describe)
+ _command_args=(
+ '(-s|--sobjecttype)'{-s,--sobjecttype}'[the API name of the object to describe]' \
+ '(-t|--usetoolingapi)'{-t,--usetoolingapi}'[execute with Tooling API]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:schema:sobject:list)
+ _command_args=(
+ '(-c|--sobjecttypecategory)'{-c,--sobjecttypecategory}'[the type of objects to list (all|custom|standard)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:soql:query)
+ _command_args=(
+ '(-q|--query)'{-q,--query}'[SOQL query to execute]' \
+ '(-t|--usetoolingapi)'{-t,--usetoolingapi}'[execute query with Tooling API]' \
+ '(-r|--resultformat)'{-r,--resultformat}'[query result format emitted to stdout; --json flag overrides this parameter (human*,csv,json)]' \
+ '(--perflog)--perflog[get API performance data.]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:source:status)
+ _command_args=(
+ '(-a|--all)'{-a,--all}'[list all the changes that have been made]' \
+ '(-l|--local)'{-l,--local}'[list the changes that have been made locally]' \
+ '(-r|--remote)'{-r,--remote}'[list the changes that have been made in the scratch org]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:test:create)
+ _command_args=(
+ '(-n|--testname)'{-n,--testname}'[name of the generated Lightning test]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (DefaultLightningTest*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:lightning:test:install)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[number of minutes to wait for installation status (default:2)]' \
+ '(-r|--releaseversion)'{-r,--releaseversion}'[release version of Lightning Testing Service (default:latest)]' \
+ '(-t|--packagetype)'{-t,--packagetype}'[type of unmanaged package. 'full' option contains both jasmine and mocha, plus examples (full*,jasmine,mocha)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:test:report)
+ _command_args=(
+ '(-i|--testrunid)'{-i,--testrunid}'[ID of test run]' \
+ '(-c|--codecoverage)'{-c,--codecoverage}'[retrieve code coverage results]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[directory to store test run files]:file:_files' \
+ '(-r|--resultformat)'{-r,--resultformat}'[test result format emitted to stdout; --json flag overrides this parameter (human*,tap,junit,json)]' \
+ '(-w|--wait)'{-w,--wait}'[the streaming client socket timeout (in minutes) (default:6, min:2)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[display Apex test processing details]' \
+ )
+ ;;
+ force:apex:test:run)
+ _command_args=(
+ '(-n|--classnames)'{-n,--classnames}'[comma-separated list of Apex test class names to run]' \
+ '(-s|--suitenames)'{-s,--suitenames}'[comma-separated list of Apex test suite names to run]' \
+ '(-t|--tests)'{-t,--tests}'[comma-separated list of Apex test class names or IDs and, if applicable, test methods to run]' \
+ '(-c|--codecoverage)'{-c,--codecoverage}'[retrieve code coverage results]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[directory to store test run files]:file:_files' \
+ '(-l|--testlevel)'{-l,--testlevel}'[testlevel enum value (RunLocalTests,RunAllTestsInOrg,RunSpecifiedTests)]' \
+ '(-r|--resultformat)'{-r,--resultformat}'[test result format emitted to stdout; --json flag overrides this parameter (human*,tap,junit,json)]' \
+ '(-w|--wait)'{-w,--wait}'[the streaming client socket timeout (in minutes) (default:6, min:2)]' \
+ '(--precompilewait)--precompilewait[how long to wait (in minutes) for Apex pre-compilation (default:3, min:3)]' \
+ '(-y|--synchronous)'{-y,--synchronous}'[run tests from a single class synchronously]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[display Apex test processing details]' \
+ )
+ ;;
+ force:lightning:test:run)
+ _command_args=(
+ '(-a|--appname)'{-a,--appname}'[name of your Lightning test application]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[directory path to store test run artifacts: for example, log files and test results]:file:_files' \
+ '(-r|--resultformat)'{-r,--resultformat}'[test result format emitted to stdout; --json flag overrides this parameter (human*,tap,junit,json)]' \
+ '(-f|--configfile)'{-f,--configfile}'[path to config file for the test]:file:_files' \
+ '(-o|--leavebrowseropen)'{-o,--leavebrowseropen}'[leave browser open]' \
+ '(-t|--timeout)'{-t,--timeout}'[time (ms) to wait for results element in dom (default:60000)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:tree:export)
+ _command_args=(
+ '(-q|--query)'{-q,--query}'[soql query, or filepath of file containing a soql query, to retrieve records]' \
+ '(-p|--plan)'{-p,--plan}'[generate multiple sobject tree files and a plan definition file for aggregated import]' \
+ '(-x|--prefix)'{-x,--prefix}'[prefix of generated files]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[directory to store files]:file:_files' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:data:tree:import)
+ _command_args=(
+ '(-f|--sobjecttreefiles)'{-f,--sobjecttreefiles}'[comma-delimited, ordered paths of json files containing collection of record trees to insert]:file:_files' \
+ '(-p|--plan)'{-p,--plan}'[path to plan to insert multiple data files that have master-detail relationships]:file:_files' \
+ '(-c|--contenttype)'{-c,--contenttype}'[if data file extension is not .json, provide content type (applies to all files)]' \
+ '(--confighelp)--confighelp[display schema information for the --plan configuration file to stdout; if you use this option, all other options except --json are ignored]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:apex:trigger:create)
+ _command_args=(
+ '(-n|--triggername)'{-n,--triggername}'[name of the generated Apex trigger]' \
+ '(-t|--template)'{-t,--template}'[template to use for file creation (ApexTrigger*)]' \
+ '(-d|--outputdir)'{-d,--outputdir}'[folder for saving the created files]' \
+ '(-r|--reflect)'{-r,--reflect}'[switch to return flag detailed information]' \
+ '(-a|--apiversion)'{-a,--apiversion}'[API version number (45.0*,44.0)]' \
+ '(-s|--sobject)'{-s,--sobject}'[sObject to create a trigger on (SOBJECT*)]' \
+ '(-e|--triggerevents)'{-e,--triggerevents}'[events that fire the trigger (before insert*,before update,before delete,after insert,after update,after delete,after undelete)]' \
+ '(--json)--json[JSON output]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:uninstall)
+ _command_args=(
+ '(-w|--wait)'{-w,--wait}'[number of minutes to wait for uninstall status]' \
+ '(-p|--package)'{-p,--package}'[ID (starts with 04t) or alias of the package version to uninstall]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:uninstall:report)
+ _command_args=(
+ '(-i|--requestid)'{-i,--requestid}'[ID of the package uninstall request you want to check]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:update)
+ _command_args=(
+ '(-p|--package)'{-p,--package}'[ID (starts with 0Ho) or alias of the package to update]' \
+ '(-n|--name)'{-n,--name}'[new package name]' \
+ '(-d|--description)'{-d,--description}'[new package description]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:project:upgrade)
+ _command_args=(
+ '(-f|--forceupgrade)'{-f,--forceupgrade}'[run all upgrades even if project has already been upgraded]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:version:create)
+ _command_args=(
+ '(-p|--package)'{-p,--package}'[ID (starts with 0Ho) or alias of the package to create a version of]' \
+ '(-d|--path)'{-d,--path}'[path to directory that contains the contents of the package]:file:_files' \
+ '(-f|--definitionfile)'{-f,--definitionfile}'[path to a definition file similar to scratch org definition file that contains the list of features and org preferences that the metadata of the package version depends on]:file:_files' \
+ '(-b|--branch)'{-b,--branch}'[the package version’s branch]' \
+ '(-t|--tag)'{-t,--tag}'[the package version’s tag]' \
+ '(-k|--installationkey)'{-k,--installationkey}'[installation key for key-protected package (either --installationkey or --installationkeybypass is required)]' \
+ '(-x|--installationkeybypass)'{-x,--installationkeybypass}'[bypass the installation key requirement (either --installationkey or --installationkeybypass is required)]' \
+ '(-r|--preserve)'{-r,--preserve}'[temp files are preserved that would otherwise be deleted]' \
+ '(-j|--validateschema)'{-j,--validateschema}'[sfdx-project.json is validated against JSON schema]' \
+ '(-w|--wait)'{-w,--wait}'[minutes to wait for the package version to be created (default:0)]' \
+ '(-s|--buildinstance)'{-s,--buildinstance}'[the instance where the package version will be created——for example, NA50]' \
+ '(-o|--sourceorg)'{-o,--sourceorg}'[the source org ID used to copy the org shape for the build org]' \
+ '(-a|--versionname)'{-a,--versionname}'[the name of the package version to be created]' \
+ '(-n|--versionnumber)'{-n,--versionnumber}'[the version number of the package version to be created]' \
+ '(-e|--versiondescription)'{-e,--versiondescription}'[the description of the package version to be created]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package1:version:create)
+ _command_args=(
+ '(-i|--packageid)'{-i,--packageid}'[ID of the metadata package (starts with 033) of which you’re creating a new version]' \
+ '(-n|--name)'{-n,--name}'[package version name]' \
+ '(-d|--description)'{-d,--description}'[package version description]' \
+ '(-v|--version)'{-v,--version}'[package version in major.minor format, for example, 3.2]' \
+ '(-m|--managedreleased)'{-m,--managedreleased}'[create a managed package version]' \
+ '(-r|--releasenotesurl)'{-r,--releasenotesurl}'[release notes URL]' \
+ '(-p|--postinstallurl)'{-p,--postinstallurl}'[post install URL]' \
+ '(-k|--installationkey)'{-k,--installationkey}'[installation key for key-protected package (default: null)]' \
+ '(-w|--wait)'{-w,--wait}'[minutes to wait for the package version to be created (default: 2 minutes)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package1:version:create:get)
+ _command_args=(
+ '(-i|--requestid)'{-i,--requestid}'[PackageUploadRequest ID]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:version:create:list)
+ _command_args=(
+ '(-c|--createdlastdays)'{-c,--createdlastdays}'[created in the last specified number of days (starting at 00:00:00 of first day to now; 0 for today)]' \
+ '(-s|--status)'{-s,--status}'[filter the list by version creation request status (Queued,InProgress,Success,Error)]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:version:create:report)
+ _command_args=(
+ '(-i|--packagecreaterequestid)'{-i,--packagecreaterequestid}'[package version creation request ID (starts with 08c)]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package1:version:display)
+ _command_args=(
+ '(-i|--packageversionid)'{-i,--packageversionid}'[metadata package version ID (starts with 04t)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:version:list)
+ _command_args=(
+ '(-c|--createdlastdays)'{-c,--createdlastdays}'[created in the last specified number of days (starting at 00:00:00 of first day to now; 0 for today)]' \
+ '(-m|--modifiedlastdays)'{-m,--modifiedlastdays}'[list items modified in the specified last number of days (starting at 00:00:00 of first day to now; 0 for today)]' \
+ '(-p|--packages)'{-p,--packages}'[filter results on specified comma-delimited packages (aliases or 0Ho IDs)]' \
+ '(-r|--released)'{-r,--released}'[display released versions only]' \
+ '(-o|--orderby)'{-o,--orderby}'[order by the specified package version fields]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--concise)--concise[display limited package version details]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[display extended package version details]' \
+ )
+ ;;
+ force:package1:version:list)
+ _command_args=(
+ '(-i|--packageid)'{-i,--packageid}'[metadata package ID (starts with 033)]' \
+ '(-u|--targetusername)'{-u,--targetusername}'[username or alias for the target org; overrides default target org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:version:promote)
+ _command_args=(
+ '(-p|--package)'{-p,--package}'[ID (starts with 04t) or alias of the package version to promote]' \
+ '(-n|--noprompt)'{-n,--noprompt}'[no prompt to confirm setting the package version as released]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:package:version:report)
+ _command_args=(
+ '(-p|--package)'{-p,--package}'[ID (starts with 04t) or alias of the package to retrieve details for]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ '(--verbose)--verbose[displays extended package version details]' \
+ )
+ ;;
+ force:package:version:update)
+ _command_args=(
+ '(-p|--package)'{-p,--package}'[ID (starts with 04t) or alias of the package to update a version of]' \
+ '(-a|--versionname)'{-a,--versionname}'[new package version name]' \
+ '(-e|--versiondescription)'{-e,--versiondescription}'[new package version description]' \
+ '(-b|--branch)'{-b,--branch}'[new package version branch]' \
+ '(-t|--tag)'{-t,--tag}'[new package version tag]' \
+ '(-k|--installationkey)'{-k,--installationkey}'[new installation key for key-protected package (default: null)]' \
+ '(-v|--targetdevhubusername)'{-v,--targetdevhubusername}'[username or alias for the dev hub org; overrides default dev hub org]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ force:auth:web:login)
+ _command_args=(
+ '(-i|--clientid)'{-i,--clientid}'[OAuth client ID (sometimes called the consumer key)]' \
+ '(-r|--instanceurl)'{-r,--instanceurl}'[the login URL of the instance the org lives on]' \
+ '(-d|--setdefaultdevhubusername)'{-d,--setdefaultdevhubusername}'[set the authenticated org as the default dev hub org for scratch org creation]' \
+ '(-s|--setdefaultusername)'{-s,--setdefaultusername}'[set the authenticated org as the default username that all commands run against]' \
+ '(-a|--setalias)'{-a,--setalias}'[set an alias for the authenticated org]' \
+ '(--disablemasking)--disablemasking[disable masking of user input (for use with problematic terminals)]' \
+ '(-p|--noprompt)'{-p,--noprompt}'[do not prompt for auth confirmation in demo mode]' \
+ '(--json)--json[format output as json]' \
+ '(--loglevel)--loglevel[logging level for this command invocation (error*,trace,debug,info,warn,fatal)]' \
+ )
+ ;;
+ esac
+
+_arguments \
+ $_command_args \
+ && return 0
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sfffe/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sfffe/README.md
new file mode 100644 (file)
index 0000000..29044e8
--- /dev/null
@@ -0,0 +1,17 @@
+# "Search files for Front-End"
+
+This plugin adds a few functions for searching files used in Front-End web development.
+
+To use it, add `sfffe` to the plugins array in your zshrc file:
+```zsh
+plugins=(... sfffe)
+```
+
+**Requires:** `ack`
+
+## Functions
+
+- `ajs`: look for string in `.js` files.
+- `acss`: look for string in `.css` files.
+- `fjs`: search for `.js` files under the current working directory.
+- `fcss`: search for `.css` files under the current working directory.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sfffe/sfffe.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sfffe/sfffe.plugin.zsh
new file mode 100644 (file)
index 0000000..177e5fa
--- /dev/null
@@ -0,0 +1,28 @@
+# ------------------------------------------------------------------------------
+#          FILE:  sfffe.plugin.zsh
+#   DESCRIPTION:  search file for FE
+#        AUTHOR:  yleo77 (ylep77@gmail.com)
+#       VERSION:  0.1
+#       REQUIRE:  ack
+# ------------------------------------------------------------------------------
+
+if (( ! $+commands[ack] )); then
+    echo "'ack' is not installed!"
+    return
+fi
+
+ajs() {
+    ack "$@" --type js
+}
+
+acss() {
+    ack "$@" --type css
+}
+
+fjs() {
+    find ./ -name "$@*" -type f | grep '\.js'
+}
+
+fcss() {
+    find ./ -name "$@*" -type f | grep '\.css'
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/.editorconfig b/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/.editorconfig
new file mode 100644 (file)
index 0000000..b7c70d1
--- /dev/null
@@ -0,0 +1,3 @@
+[*.py]
+indent_size = 4
+indent_style = space
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/README.md
new file mode 100644 (file)
index 0000000..b19888c
--- /dev/null
@@ -0,0 +1,62 @@
+# shell-proxy plugin
+
+This a pure user-space program, shell-proxy setter, written in Python3 and Zsh.
+
+To use it, add `shell-proxy` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... shell-proxy)
+```
+
+## Key features
+
+- Supports macOS and Linux (Ubuntu, Archlinux, etc.)
+- Supports git via setting `$GIT_SSH`
+- Supports ssh, sftp, scp, slogin and ssh-copy-id via setting aliases
+- Built-in autocomplete
+
+## Usage
+
+### Method 1
+
+Set `SHELLPROXY_URL` environment variable to the URL of the proxy server:
+
+```sh
+SHELLPROXY_URL="http://127.0.0.1:8123"
+proxy enable
+```
+
+### Method 2
+
+Write a program file in `$HOME/.config/proxy` so that the proxy URL is defined dynamically.
+Note that the program file must be executable.
+
+Example:
+
+```sh
+#!/bin/bash
+
+if [[ "$(uname)" = Darwin ]]; then
+  echo "http://127.0.0.1:6152" # Surge Mac
+else
+  echo "http://127.0.0.1:8123" # polipo
+fi
+```
+
+### Method 3
+
+Use [method 2](#method-2) but define the location of the program file by setting the
+`SHELLPROXY_CONFIG` environment variable:
+
+```sh
+SHELLPROXY_CONFIG="$HOME/.dotfiles/proxy-config"
+```
+
+## Reference
+
+- `$GIT_SSH`: <https://www.git-scm.com/docs/git#Documentation/git.txt-codeGITSSHcode>
+- OpenSSH manual: <https://man.openbsd.org/ssh>
+
+## Maintainer
+
+- [@septs](https://github.com/septs)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/proxy.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/proxy.py
new file mode 100755 (executable)
index 0000000..14f2944
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+import os
+import sys
+from subprocess import check_output, list2cmdline
+
+cwd = os.path.dirname(__file__)
+ssh_agent = os.path.join(cwd, "ssh-agent.py")
+proxy_env = "SHELLPROXY_URL"
+proxy_config = os.environ.get("SHELLPROXY_CONFIG") or os.path.expandvars("$HOME/.config/proxy")
+
+usage="""shell-proxy: no proxy configuration found.
+
+Set `{env}` or create a config file at `{config}`
+See the plugin README for more information.""".format(env=proxy_env, config=proxy_config)
+
+def get_http_proxy():
+    default_proxy = os.environ.get(proxy_env)
+    if default_proxy:
+        return default_proxy
+    if os.path.isfile(proxy_config):
+        return check_output(proxy_config).decode("utf-8").strip()
+    print(usage, file=sys.stderr)
+    sys.exit(1)
+
+
+def make_proxies(url: str):
+    proxies = {"%s_PROXY" % _: url for _ in ("HTTP", "HTTPS", "FTP", "RSYNC", "ALL")}
+    proxies.update({name.lower(): value for (name, value) in proxies.items()})
+    proxies["GIT_SSH"] = ssh_agent
+    return proxies
+
+
+def merge(mapping: dict):
+    return ("%s=%s" % _ for _ in mapping.items())
+
+
+class CommandSet:
+    proxies = make_proxies(get_http_proxy())
+    aliases = {
+        _: "env __SSH_PROGRAM_NAME__=%s %s" % (_, ssh_agent)
+        for _ in ("ssh", "sftp", "scp", "slogin", "ssh-copy-id")
+    }
+
+    def enable(self):
+        cmdline("export", *merge(self.proxies))
+        cmdline("alias", *merge(self.aliases))
+
+    def disable(self):
+        cmdline("unset", *self.proxies.keys())
+        cmdline("unalias", *self.aliases.keys())
+
+    def status(self):
+        proxies = (
+            "%11s = %s" % (name, os.environ[name])
+            for name in self.proxies.keys()
+            if name in os.environ
+        )
+        for _ in proxies:
+            cmdline("echo", _)
+
+    def usage(self):
+        print("usage: proxy {enable,disable,status}", file=sys.stderr)
+
+
+def cmdline(*items):
+    print(list2cmdline(items))
+
+
+def main():
+    command = CommandSet()
+    if len(sys.argv) == 1:
+        command.usage()
+        sys.exit(1)
+    getattr(command, sys.argv[1], command.usage)()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/shell-proxy.plugin.zsh
new file mode 100644 (file)
index 0000000..4fdbe93
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/bash
+# shellcheck disable=SC1090,SC2154
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+eval '
+  proxy() {
+    # deprecate $DEFAULT_PROXY, use SHELLPROXY_URL instead
+    if [[ -n "$DEFAULT_PROXY" && -z "$SHELLPROXY_URL" ]]; then
+      echo >&2 "proxy: DEFAULT_PROXY is deprecated, use SHELLPROXY_URL instead"
+      SHELLPROXY_URL="$DEFAULT_PROXY"
+      unset DEFAULT_PROXY
+    fi
+
+    # deprecate CONFIG_PROXY, use SHELLPROXY_CONFIG instead
+    if [[ -n "$CONFIG_PROXY" && -z "$SHELLPROXY_CONFIG" ]]; then
+      echo >&2 "proxy: CONFIG_PROXY is deprecated, use SHELLPROXY_CONFIG instead"
+      SHELLPROXY_CONFIG="$CONFIG_PROXY"
+      unset CONFIG_PROXY
+    fi
+
+    # the proxy.py script is in the same directory as this function
+    local proxy="'"${0:h}"'/proxy.py"
+
+    # capture the output of the proxy script and bail out if it fails
+    local output
+    output="$(SHELLPROXY_URL="$SHELLPROXY_URL" SHELLPROXY_CONFIG="$SHELLPROXY_CONFIG" "$proxy" "$1")" ||
+      return $?
+
+    # evaluate the output generated by the proxy script
+    source <(echo "$output")
+  }
+'
+
+_proxy() {
+  local -r commands=('enable' 'disable' 'status')
+  compset -P '*,'
+  compadd -S '' "${commands[@]}"
+}
+
+compdef _proxy proxy
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/ssh-agent.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/ssh-agent.py
new file mode 100755 (executable)
index 0000000..4ee24b7
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+import os
+import subprocess
+import sys
+
+ssh_proxy = os.path.join(os.path.dirname(__file__), "ssh-proxy.py")
+
+argv = [
+    os.environ.get("__SSH_PROGRAM_NAME__", "ssh"),
+    "-o",
+    "ProxyCommand={} %h %p".format(ssh_proxy),
+    "-o",
+    "Compression=yes",
+]
+
+subprocess.call(argv + sys.argv[1:], env=os.environ)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/ssh-proxy.py b/stow/oh-my-zsh/.oh-my-zsh/plugins/shell-proxy/ssh-proxy.py
new file mode 100755 (executable)
index 0000000..a498c84
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+import os
+import subprocess
+import sys
+from urllib.parse import urlparse
+
+proxy = next(os.environ[_] for _ in ("HTTP_PROXY", "HTTPS_PROXY") if _ in os.environ)
+
+parsed = urlparse(proxy)
+
+proxy_protocols = {
+    "http": "connect",
+    "https": "connect",
+    "socks": "5",
+    "socks5": "5",
+    "socks4": "4",
+    "socks4a": "4",
+}
+
+if parsed.scheme not in proxy_protocols:
+    raise TypeError('unsupported proxy protocol: "{}"'.format(parsed.scheme))
+
+def make_argv():
+    yield "nc"
+    if sys.platform == 'linux':
+        # caveats: macOS built-in netcat command not supported proxy-type
+        yield "-X" # --proxy-type
+        # Supported protocols are 4 (SOCKS v4), 5 (SOCKS v5) and connect (HTTP proxy).
+        # Default SOCKS v5 is used.
+        yield proxy_protocols[parsed.scheme]
+    yield "-x" # --proxy
+    yield parsed.netloc # proxy-host:proxy-port
+    yield sys.argv[1] # host
+    yield sys.argv[2] # port
+
+subprocess.call(make_argv())
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shrink-path/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/shrink-path/README.md
new file mode 100644 (file)
index 0000000..71a242b
--- /dev/null
@@ -0,0 +1,116 @@
+# shrink-path
+
+A plugin to shrink directory paths for brevity and pretty-printing.
+
+To use it, add `shrink-path` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... shrink-path)
+```
+
+## Examples
+
+For this directory tree:
+```
+/home/
+  me/
+    f o o/     # The prefix f is ambiguous between "f o o" and "f i g".
+      bar/
+        quux/
+      biz/     # The prefix b is ambiguous between bar and biz.
+    f i g/
+      baz/
+```
+here are the results of calling `shrink_path <option> /home/me/foo/bar/quux`:
+```
+Option        Result
+<none>        /h/m/f o/ba/q
+-l|--last     /h/m/f o/ba/q
+-s|--short    /h/m/f/b/q
+-t|--tilde    ~/f o/ba/q
+-f|--fish     ~/f/b/quux
+-g|--glob     /h*/m*/f o*/ba*/q*
+-3            /hom/me/f o/bar/quu
+-e '$' -3     /hom$/me/f o$/bar/quu$
+-q            /h/m/f\ o/ba/q
+-g -q         /h*/m*/f\ o*/ba*/q*
+-x            /home/me/foo/bar/quux
+```
+
+## Usage
+
+For a fish-style working directory in your command prompt, add the following to
+your theme or zshrc:
+
+```zsh
+setopt prompt_subst
+PS1='%n@%m $(shrink_path -f)>'
+```
+
+The following options are available:
+
+```
+    -f, --fish       fish simulation, equivalent to -l -s -t.
+    -g, --glob       Add asterisk to allow globbing of shrunk path (equivalent to -e "*")
+    -l, --last       Print the last directory's full name.
+    -s, --short      Truncate directory names to the number of characters given by -. Without
+                     -s, names are truncated without making them ambiguous.
+    -t, --tilde      Substitute ~ for the home directory.
+    -T, --nameddirs  Substitute named directories as well.
+    -#               Truncate each directly to at least this many characters inclusive of the
+                     ellipsis character(s) (defaulting to 1).
+    -e SYMBOL        Postfix symbol(s) to indicate that a directory name had been truncated.
+    -q, --quote      Quote special characters in the shrunk path
+    -x, --expand     Print the full path. This takes precedence over the other options
+```
+
+The long options can also be set via zstyle, like
+```zsh
+zstyle :prompt:shrink_path fish yes
+```
+
+Note: Directory names containing two or more consecutive spaces are not yet
+supported.
+
+
+## Trick: toggle shrinking with a keyboard shortcut
+
+You can use the `expand` option to disable the path shrinking. You can combine that
+with a key binding widget to toggle path shrinking on and off.
+
+```zsh
+# Toggle off path shrinking
+zstyle ':prompt:shrink_path' expand true
+# Toggle on path shrinking
+zstyle -d ':prompt:shrink_path' expand
+```
+
+Combined with a widget:
+
+```zsh
+# Widget definition
+shrink-path-toggle() {
+  zstyle -t ':prompt:shrink_path' expand \
+    && zstyle -d ':prompt:shrink_path' expand \
+    || zstyle ':prompt:shrink_path' expand true
+  zle reset-prompt
+}
+zle -N shrink-path-toggle
+# Key binding to ALT+SHIFT+S
+bindkey "^[S" shrink-path-toggle
+```
+
+## License
+
+Copyright (C) 2008 by Daniel Friesel <derf@xxxxxxxxxxxxxxxxxx>
+Copyright (C) 2018-2020 by Pavel N. Krivitsky
+
+License: WTFPL <http://www.wtfpl.net>
+
+Ref: https://www.zsh.org/mla/workers/2009/msg00415.html
+     https://www.zsh.org/mla/workers/2009/msg00419.html
+
+
+## Misc
+
+Keywords: prompt directory truncate shrink collapse fish
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/shrink-path/shrink-path.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/shrink-path/shrink-path.plugin.zsh
new file mode 100644 (file)
index 0000000..373fd5b
--- /dev/null
@@ -0,0 +1,182 @@
+# Shrink directory paths, e.g. /home/me/foo/bar/quux -> ~/f/b/quux.
+#
+# For a fish-style working directory in your command prompt, add the following
+# to your theme or zshrc:
+#
+#   setopt prompt_subst
+#   PS1='%n@%m $(shrink_path -f)>'
+#
+# The following options are available:
+#
+#   -f, --fish       fish simulation, equivalent to -l -s -t.
+#   -g, --glob       Add asterisk to allow globbing of shrunk path (equivalent to -e "*")
+#   -l, --last       Print the last directory's full name.
+#   -s, --short      Truncate directory names to the number of characters given by -#. Without
+#                    -s, names are truncated without making them ambiguous.
+#   -t, --tilde      Substitute ~ for the home directory.
+#   -T, --nameddirs  Substitute named directories as well.
+#   -#               Truncate each directly to at least this many characters inclusive of the
+#                    ellipsis character(s) (defaulting to 1).
+#   -e SYMBOL        Postfix symbol(s) to indicate that a directory name had been truncated.
+#   -q, --quote      Quote special characters in the shrunk path
+#
+# The long options can also be set via zstyle, like
+#   zstyle :prompt:shrink_path fish yes
+#
+# Note: Directory names containing two or more consecutive spaces are not yet
+# supported.
+#
+# Keywords: prompt directory truncate shrink collapse fish
+#
+# Copyright (C) 2008 by Daniel Friesel <derf@xxxxxxxxxxxxxxxxxx>
+# License: WTFPL <http://www.wtfpl.net>
+#
+# Ref: https://www.zsh.org/mla/workers/2009/msg00415.html
+#      https://www.zsh.org/mla/workers/2009/msg00419.html
+
+shrink_path () {
+        setopt localoptions
+        setopt rc_quotes null_glob
+
+        typeset -i lastfull=0
+        typeset -i short=0
+        typeset -i tilde=0
+        typeset -i named=0
+        typeset -i length=1
+        typeset ellipsis=""
+        typeset -i quote=0
+        typeset -i expand=0
+
+        if zstyle -t ':prompt:shrink_path' fish; then
+                lastfull=1
+                short=1
+                tilde=1
+        fi
+        if zstyle -t ':prompt:shrink_path' nameddirs; then
+                tilde=1
+                named=1
+        fi
+        zstyle -t ':prompt:shrink_path' last && lastfull=1
+        zstyle -t ':prompt:shrink_path' short && short=1
+        zstyle -t ':prompt:shrink_path' tilde && tilde=1
+        zstyle -t ':prompt:shrink_path' glob && ellipsis='*'
+        zstyle -t ':prompt:shrink_path' quote && quote=1
+        zstyle -t ':prompt:shrink_path' expand && expand=1
+
+        while [[ $1 == -* ]]; do
+                case $1 in
+                        --)
+                                shift
+                                break
+                        ;;
+                        -f|--fish)
+                                lastfull=1
+                                short=1
+                                tilde=1
+                        ;;
+                        -h|--help)
+                                print 'Usage: shrink_path [-f -l -s -t] [directory]'
+                                print ' -f, --fish      fish-simulation, like -l -s -t'
+                                print ' -g, --glob      Add asterisk to allow globbing of shrunk path (equivalent to -e "*")'
+                                print ' -l, --last      Print the last directory''s full name'
+                                print ' -s, --short     Truncate directory names to the number of characters given by -#. Without'
+                                print '                 -s, names are truncated without making them ambiguous.'
+                                print ' -t, --tilde     Substitute ~ for the home directory'
+                                print ' -T, --nameddirs Substitute named directories as well'
+                                print ' -#              Truncate each directly to at least this many characters inclusive of the'
+                                print '                 ellipsis character(s) (defaulting to 1).'
+                                print ' -e SYMBOL       Postfix symbol(s) to indicate that a directory name had been truncated.'
+                                print ' -q, --quote     Quote special characters in the shrunk path'
+                                print ' -x, --expand    Print the full path. This takes precedence over the other options'
+                                print ''
+                                print 'The long options can also be set via zstyle, like'
+                                print '  zstyle :prompt:shrink_path fish yes'
+                                return 0
+                        ;;
+                        -l|--last) lastfull=1 ;;
+                        -s|--short) short=1 ;;
+                        -t|--tilde) tilde=1 ;;
+                        -T|--nameddirs)
+                                tilde=1
+                                named=1
+                        ;;
+                        -[0-9]|-[0-9][0-9])
+                                length=${1/-/}
+                        ;;
+                        -e)
+                                shift
+                                ellipsis="$1"
+                        ;;
+                        -g|--glob)
+                                ellipsis='*'
+                        ;;
+                        -q|--quote)
+                                quote=1
+                        ;;
+                        -x|--expand)
+                                expand=1
+                        ;;
+                esac
+                shift
+        done
+
+        typeset -i elllen=${#ellipsis}
+        typeset -a tree expn
+        typeset result part dir=${1-$PWD}
+        typeset -i i
+
+        [[ -d $dir ]] || return 0
+
+        if (( expand )) {
+                echo "$dir"
+                return 0
+        }
+
+        if (( named )) {
+                for part in ${(k)nameddirs}; {
+                        [[ $dir == ${nameddirs[$part]}(/*|) ]] && dir=${dir/#${nameddirs[$part]}/\~$part}
+                }
+        }
+        (( tilde )) && dir=${dir/#$HOME/\~}
+        tree=(${(s:/:)dir})
+        (
+                if [[ $tree[1] == \~* ]] {
+                        cd -q ${~tree[1]}
+                        result=$tree[1]
+                        shift tree
+                } else {
+                        cd -q /
+                }
+                for dir in $tree; {
+                        if (( lastfull && $#tree == 1 )) {
+                                result+="/$tree"
+                                break
+                        }
+                        expn=(a b)
+                        part=''
+                        i=0
+                        until [[ $i -gt 99 || ( $i -ge $((length - ellen)) || $dir == $part ) && ( (( ${#expn} == 1 )) || $dir = $expn ) ]]; do
+                                (( i++ ))
+                                part+=$dir[$i]
+                                expn=($(echo ${part}*(-/)))
+                                (( short )) && [[ $i -ge $((length - ellen)) ]] && break
+                        done
+
+                        typeset -i dif=$(( ${#dir} - ${#part} - ellen ))
+                        if [[ $dif -gt 0 ]]
+                        then
+                            (( quote )) && part=${(q)part}
+                            part+="$ellipsis"
+                        else
+                            part="$dir"
+                            (( quote )) && part=${(q)part}
+                        fi
+                        result+="/$part"
+                        cd -q $dir
+                        shift tree
+                }
+                echo ${result:-/}
+        )
+}
+
+## vim:ft=zsh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/singlechar/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/singlechar/README.md
new file mode 100644 (file)
index 0000000..d890299
--- /dev/null
@@ -0,0 +1,118 @@
+# Singlechar plugin
+
+This plugin adds single char shortcuts (and combinations) for some commands.
+
+To use it, add `singlechar` to the plugins array of your zshrc file:
+```
+plugins=(... singlechar)
+```
+
+## Aliases
+
+### CAT, GREP, CURL, WGET
+
+| Alias | Command          | Description |
+|-------|------------------|-------------|
+| y     | `grep -Ri`       | Find case-insensitive string in all files and directories, recursively. Follows symlinks. |
+| n     | `grep -Rvi`      | Same as above but only show lines that don't match the string.                            |
+| f     | `grep -Rli`      | Same as 'y' but only print the filenames where the string is found.                       |
+| fn    | `grep -Rlvi`     | Same as above but only show files that don't contain the string.                          |
+| f.    | `find . \| grep` | Grep list of files in current directory                                                   |
+| f:    | `find`           | 'find' command                                                                            |
+| p     | `less`           | 'less' command                                                                            |
+| m     | `man`            | 'man' command                                                                             |
+| d     | `wget`           | 'wget' command                                                                            |
+| u     | `curl`           | 'curl' command                                                                            |
+| c     | `cat`            | 'cat' command                                                                             |
+| w     | `echo >`         | Write arguments to file, overwriting it if it exists.                                     |
+| a     | `echo >>`        | Write arguments to file, appending them if the file exists.                               |
+| w:    | `cat >`          | Write stdin to file, overwriting if it exists.                                            |
+| a:    | `cat >>`         | Write stdin to file, appending it if the file exists.                                     |
+
+### XARGS
+
+These aliases are versions of the aliases above but using xargs. This can be used
+by piping the arguments to the xargs aliases.
+
+| Alias | Command              | Description                     |
+|-------|----------------------|---------------------------------|
+| x     | `xargs`              | 'xargs' command                 |
+| xy    | `xargs grep -Ri`     | Same as 'y' alias using xargs.  |
+| xn    | `xargs grep -Rvi`    | Same as 'n' alias using xargs.  |
+| xf    | `xargs grep -Rli`    | Same as 'f' alias using xargs.  |
+| xfn   | `xargs grep -Rlvi`   | Same as 'fn' alias using xargs. |
+| xf.   | `xargs find \| grep` | Same as 'f.' alias using xargs. |
+| xf:   | `xargs find`         | Same as 'f:' alias using xargs. |
+| xc    | `xargs cat`          | Same as 'c' alias using xargs.  |
+| xp    | `xargs less`         | Same as 'p' alias using xargs.  |
+| xm    | `xargs man`          | Same as 'm' alias using xargs.  |
+| xd    | `xargs wget`         | Same as 'd' alias using xargs.  |
+| xu    | `xargs curl`         | Same as 'u' alias using xargs.  |
+| xw    | `xargs echo >`       | Same as 'w' alias using xargs.  |
+| xa    | `xargs echo >>`      | Same as 'a' alias using xargs.  |
+| xw:   | `xargs cat >`        | Same as 'w:' alias using xargs. |
+| xa:   | `xargs >>`           | Same as 'a:' alias using xargs. |
+
+### SUDO
+
+These aliases are versions of the aliases above in [CAT, GREP, CURL, WGET](#cat-grep-curl-wget)
+but using sudo to run them with root permission.
+
+| Alias | Command               | Description                    |
+|-------|-----------------------|--------------------------------|
+| s     | `sudo`                | 'sudo' command                 |
+| sy    | `sudo grep -Ri`       | Same as 'y' alias using sudo.  |
+| sn    | `sudo grep -Riv`      | Same as 'n' alias using sudo.  |
+| sf    | `sudo grep -Rli`      | Same as 'f' alias using sudo.  |
+| sfn   | `sudo grep -Rlvi`     | Same as 'fn' alias using sudo. |
+| sf.   | `sudo find . \| grep` | Same as 'f.' alias using sudo. |
+| sf:   | `sudo find`           | Same as 'f:' alias using sudo. |
+| sp    | `sudo less`           | Same as 'p' alias using sudo.  |
+| sm    | `sudo man`            | Same as 'm' alias using sudo.  |
+| sd    | `sudo wget`           | Same as 'd' alias using sudo.  |
+| sc    | `sudo cat`            | Same as 'c' alias using sudo.  |
+| sw    | `sudo echo >`         | Same as 'w' alias using sudo.  |
+| sa    | `sudo echo >>`        | Same as 'a' alias using sudo.  |
+| sw:   | `sudo cat >`          | Same as 'w:' alias using sudo. |
+| sa:   | `sudo cat >>`         | Same as 'a:' alias using sudo. |
+
+### SUDO-XARGS
+
+Same as above but using both sudo and xargs.
+
+| Alias | Command                   | Description                     |
+|-------|---------------------------|---------------------------------|
+| sx    | `sudo xargs`              | 'sudo xargs' command            |
+| sxy   | `sudo xargs grep -Ri`     | Same as 'xy' alias using sudo.  |
+| sxn   | `sudo xargs grep -Riv`    | Same as 'xn' alias using sudo.  |
+| sxf   | `sudo xargs grep -li`     | Same as 'xf' alias using sudo.  |
+| sxfn  | `sudo xargs grep -lvi`    | Same as 'xfn' alias using sudo. |
+| sxf.  | `sudo xargs find \| grep` | Same as 'xf.' alias using sudo. |
+| sxf:  | `sudo xargs find`         | Same as 'xf:' alias using sudo. |
+| sxp   | `sudo xargs less`         | Same as 'xp' alias using sudo.  |
+| sxm   | `sudo xargs man`          | Same as 'xm' alias using sudo.  |
+| sxd   | `sudo xargs wget`         | Same as 'xd' alias using sudo.  |
+| sxu   | `sudo xargs curl`         | Same as 'xu' alias using sudo.  |
+| sxc   | `sudo xargs cat`          | Same as 'xc' alias using sudo.  |
+| sxw   | `sudo xargs echo >`       | Same as 'xw' alias using sudo.  |
+| sxa   | `sudo xargs echo >>`      | Same as 'xa' alias using sudo.  |
+| sxw:  | `sudo xargs cat >`        | Same as 'xw:' alias using sudo. |
+| sxa:  | `sudo xargs cat >>`       | Same as 'xa:' alias using sudo. |
+
+## Options
+
+The commands `grep`, `sudo`, `wget`, `curl`, and `less` can be configured to use other commands
+via the setup variables below, before Oh My Zsh is sourced. If they are not set yet, they will
+use their default values:
+
+| Setup variable | Default value |
+|----------------|---------------|
+| GREP           | `grep`        |
+| ROOT           | `sudo`        |
+| WGET           | `wget`        |
+| CURL           | `curl`        |
+| PAGER          | `less`        |
+
+## Author
+
+- [Karolin Varner](https://github.com/koraa)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/singlechar/singlechar.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/singlechar/singlechar.plugin.zsh
new file mode 100644 (file)
index 0000000..d4b0b67
--- /dev/null
@@ -0,0 +1,123 @@
+###########################
+# Settings 
+
+# These can be overwritten any time.
+# If they are not set yet, they will be
+# overwritten with their default values
+
+default GREP grep
+default ROOT sudo
+default WGET wget
+default CURL curl
+
+env_default PAGER less
+
+###########################
+# Alias
+
+# CAT, GREP, CURL, WGET
+
+alias y='"$GREP" -Ri'
+alias n='"$GREP" -Rvi'
+
+alias f.='find . | "$GREP"'
+alias f:='find'
+
+alias f='"$GREP" -Rli'
+alias fn='"$GREP" -Rlvi'
+
+alias w='echo >'
+alias a='echo >>'
+
+alias c='cat'
+alias p='"$PAGER"'
+
+alias m='man'
+
+alias d='"$WGET"'
+alias u='"$CURL"'
+
+# enhanced writing
+
+alias w:='cat >'
+alias a:='cat >>'
+
+# XARGS
+
+alias x='xargs'
+
+alias xy='xargs "$GREP" -Ri'
+alias xn='xargs "$GREP" -Riv'
+
+alias xf.='xargs find | "$GREP"'
+alias xf:='xargs find'
+
+alias xf='xargs "$GREP" -Rli'
+alias xfn='xargs "$GREP" -Rlvi'
+
+alias xw='xargs echo >'
+alias xa='xargs echo >>'
+
+alias xc='xargs cat'
+alias xp='xargs "$PAGER"'
+
+alias xm='xargs man'
+
+alias xd='xargs "$WGET"'
+alias xu='xargs "$CURL"'
+
+alias xw:='xargs cat >'
+alias xa:='xargs >>'
+
+# SUDO
+
+alias s='"$ROOT"'
+
+alias sy='"$ROOT" "$GREP" -Ri'
+alias sn='"$ROOT" "$GREP" -Riv'
+
+alias sf.='"$ROOT" find . | "$GREP"'
+alias sf:='"$ROOT" find'
+
+alias sf='"$ROOT" "$GREP" -Rli'
+alias sfn='"$ROOT" "$GREP" -Rlvi'
+
+alias sw='"$ROOT" echo >'
+alias sa='"$ROOT" echo >>'
+
+alias sc='"$ROOT" cat'
+alias sp='"$ROOT" "$PAGER"'
+
+alias sm='"$ROOT" man'
+
+alias sd='"$ROOT" "$WGET"'
+
+alias sw:='"$ROOT" cat >'
+alias sa:='"$ROOT" cat >>'
+
+# SUDO-XARGS
+
+alias sx='"$ROOT" xargs'
+
+alias sxy='"$ROOT" xargs "$GREP" -Ri'
+alias sxn='"$ROOT" xargs "$GREP" -Riv'
+
+alias sxf.='"$ROOT" xargs find | "$GREP"'
+alias sxf:='"$ROOT" xargs find'
+
+alias sxf='"$ROOT" xargs "$GREP" -li'
+alias sxfn='"$ROOT" xargs "$GREP" -lvi'
+
+alias sxw='"$ROOT" xargs echo >'
+alias sxa='"$ROOT" xargs echo >>'
+
+alias sxc='"$ROOT" xargs cat'
+alias sxp='"$ROOT" xargs "$PAGER"'
+
+alias sxm='"$ROOT" xargs man'
+
+alias sxd='"$ROOT" xargs "$WGET"'
+alias sxu='"$ROOT" xargs "$CURL"'
+
+alias sxw:='"$ROOT" xargs cat >'
+alias sxa:='"$ROOT" xargs cat >>'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/spring/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/spring/README.md
new file mode 100644 (file)
index 0000000..8161813
--- /dev/null
@@ -0,0 +1,25 @@
+# Spring Boot oh-my-zsh plugin
+oh-my-zsh Spring Boot plugin
+
+## Spring Boot autocomplete plugin
+
+- Adds autocomplete options for all spring boot commands.
+
+## Manual Install
+
+     $ cd ~/.oh-my-zsh/plugins
+     $ git clone git@github.com:linux-china/oh-my-zsh-spring-boot-plugin.git spring
+
+Adjust your .zshrc file and add spring to plugins=(...)
+
+## Tips
+
+* Install Spring Cloud plugin: spring install org.springframework.cloud:spring-cloud-cli:1.0.2.RELEASE
+
+## Reference
+
+* Spring Boot: https://spring.io/projects/spring-boot
+* Spring Boot CLI: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#cli
+
+Maintainer : linux_china ([@linux_china](https://twitter.com/linux_china))
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/spring/_spring b/stow/oh-my-zsh/.oh-my-zsh/plugins/spring/_spring
new file mode 100644 (file)
index 0000000..93f1951
--- /dev/null
@@ -0,0 +1,29 @@
+#compdef spring 'spring'
+#autoload
+
+_spring() {
+
+        local cword
+        let cword=CURRENT-1
+
+        local hints
+        hints=()
+
+        local reply
+        while read -r line; do
+                reply=`echo "$line" | awk '{printf $1 ":"; for (i=2; i<NF; i++) printf $i " "; print $NF}'`
+                hints+=("$reply")
+        done < <(spring hint ${cword} ${words[*]})
+
+        if ((cword == 1)) {
+                _describe -t commands 'commands' hints
+                return 0
+        }
+
+        _describe -t options 'options' hints
+        _files
+
+        return 0
+}
+
+_spring "$@"
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sprunge/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sprunge/README.md
new file mode 100644 (file)
index 0000000..80e3b30
--- /dev/null
@@ -0,0 +1,38 @@
+# Sprunge plugin
+
+This plugin uploads data and fetch URL from the pastebin http://sprunge.us
+
+To enable it, add 'sprunge' to your plugins:
+
+```zsh
+plugins=(... sprunge)
+```
+
+## Usage
+
+| Command                      | Description                               |
+|------------------------------|-------------------------------------------|
+| `sprunge filename.txt`       | Uploads filename.txt                      |
+| `sprunge "this is a string"` | Uploads plain text                        |
+| `sprunge < filename.txt`     | Redirects filename.txt content to sprunge |
+| `echo data \| sprunge`       | Any piped data will be uploaded           |
+
+Once sprunge has processed the input it will give you a unique HTTP address:
+
+```console
+$ sprunge "hello"
+http://sprunge.us/XxjnKz
+```
+
+## Notes
+
+- Sprunge accepts piped data, stdin redirection, text strings as input or filenames.
+  Only one of these can be used at a time.
+- Argument precedence goes as follows: stdin > piped input > text strings.
+- If a filename is misspelled or doesn't have the necessary path description, it will NOT
+  generate an error, but instead treat it as a text string.
+
+## Credits
+
+- Original code: [shellperson.net](https://web.archive.org/web/20190910065842/https://www.shellperson.net/sprunge-pastebin-script/).
+- Adapted by: Matt Parnell (@ilikenwf).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sprunge/sprunge.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sprunge/sprunge.plugin.zsh
new file mode 100644 (file)
index 0000000..48dff58
--- /dev/null
@@ -0,0 +1,52 @@
+sprunge() {
+  if [[ "$1" = --help ]]; then
+    fmt -s >&2 << EOF
+
+DESCRIPTION
+  Upload data and fetch URL from the pastebin http://sprunge.us
+
+USAGE
+  $0 filename.txt
+  $0 text string
+  $0 < filename.txt
+  piped_data | $0
+
+NOTES
+  Input Methods:
+  $0 can accept piped data, STDIN redirection [< filename.txt], text strings following the command as arguments, or filenames as arguments. Only one of these methods can be used at a time, so please see the note on precedence. Also, note that using a pipe or STDIN redirection will treat tabs as spaces, or disregard them entirely (if they appear at the beginning of a line). So I suggest using a filename as an argument if tabs are important either to the function or readability of the code.
+
+  Precedence:
+  STDIN redirection has precedence, then piped input, then a filename as an argument, and finally text strings as arguments. For example:
+
+    echo piped | $0 arguments.txt < stdin_redirection.txt
+
+  In this example, the contents of file_as_stdin_redirection.txt would be uploaded. Both the piped_text and the file_as_argument.txt are ignored. If there is piped input and arguments, the arguments will be ignored, and the piped input uploaded.
+
+  Filenames:
+  If a filename is misspelled or doesn't have the necessary path description, it will NOT generate an error, but will instead treat it as a text string and upload it.
+
+EOF
+    return
+  fi
+
+  if [ -t 0 ]; then
+    echo Running interactively, checking for arguments... >&2
+    if [ "$*" ]; then
+      echo Arguments present... >&2
+      if [ -f "$*" ]; then
+        echo Uploading the contents of "$*"... >&2
+        cat "$*"
+      else
+        echo Uploading the text: \""$*"\"... >&2
+        echo "$*"
+      fi | curl -F 'sprunge=<-' http://sprunge.us
+    else
+      echo No arguments found, printing USAGE and exiting. >&2
+      sprunge --help
+      return 1
+    fi
+  else
+    echo Using input from a pipe or STDIN redirection... >&2
+    curl -F 'sprunge=<-' http://sprunge.us
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ssh-agent/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ssh-agent/README.md
new file mode 100644 (file)
index 0000000..fa6a996
--- /dev/null
@@ -0,0 +1,106 @@
+# ssh-agent plugin
+
+This plugin starts automatically `ssh-agent` to set up and load whichever
+credentials you want for ssh connections.
+
+To enable it, add `ssh-agent` to your plugins:
+
+```zsh
+plugins=(... ssh-agent)
+```
+
+## Settings
+
+**IMPORTANT: put these settings _before_ the line that sources oh-my-zsh**
+
+### `agent-forwarding`
+
+To enable **agent forwarding support** add the following to your zshrc file:
+
+```zsh
+zstyle :omz:plugins:ssh-agent agent-forwarding yes
+```
+
+### `helper`
+
+To set an **external helper** to ask for the passwords and possibly store
+them in the system keychain use the `helper` style. For example:
+
+```zsh
+zstyle :omz:plugins:ssh-agent helper ksshaskpass
+```
+
+### `identities`
+
+To **load multiple identities** use the `identities` style (**this has no effect
+if the `lazy` setting is enabled**). For example:
+
+```zsh
+zstyle :omz:plugins:ssh-agent identities id_rsa id_rsa2 id_github
+```
+
+**NOTE:** the identities may be an absolute path if they are somewhere other than
+`~/.ssh`. For example:
+
+```zsh
+zstyle :omz:plugins:ssh-agent identities ~/.config/ssh/id_rsa ~/.config/ssh/id_rsa2 ~/.config/ssh/id_github
+# which can be simplified to
+zstyle :omz:plugins:ssh-agent identities ~/.config/ssh/{id_rsa,id_rsa2,id_github}
+```
+
+### `lazy`
+
+To **NOT load any identities on start** use the `lazy` setting. This is particularly
+useful when combined with the `AddKeysToAgent` setting (available since OpenSSH 7.2),
+since it allows to enter the password only on first use. _NOTE: you can know your
+OpenSSH version with `ssh -V`._
+
+```zsh
+zstyle :omz:plugins:ssh-agent lazy yes
+```
+
+You can enable `AddKeysToAgent` by passing `-o AddKeysToAgent=yes` to the `ssh` command,
+or by adding `AddKeysToAgent yes` to your `~/.ssh/config` file [1].
+See the [OpenSSH 7.2 Release Notes](http://www.openssh.com/txt/release-7.2).
+
+### `lifetime`
+
+To **set the maximum lifetime of the identities**, use the `lifetime` style.
+The lifetime may be specified in seconds or as described in sshd_config(5)
+(see _TIME FORMATS_). If left unspecified, the default lifetime is forever.
+
+```zsh
+zstyle :omz:plugins:ssh-agent lifetime 4h
+```
+
+### `quiet`
+
+To silence the plugin, use the following setting:
+
+```zsh
+zstyle :omz:plugins:ssh-agent quiet yes
+```
+
+### `ssh-add-args`
+
+To **pass arguments to the `ssh-add` command** that adds the identities on startup,
+use the `ssh-add-args` setting. You can pass multiple arguments separated by spaces:
+
+```zsh
+zstyle :omz:plugins:ssh-agent ssh-add-args -K -c -a /run/user/1000/ssh-auth
+```
+
+These will then be passed the the `ssh-add` call as if written directly. The example
+above will turn into:
+
+```zsh
+ssh-add -K -c -a /run/user/1000/ssh-auth <identities>
+```
+
+For valid `ssh-add` arguments run `ssh-add --help` or `man ssh-add`.
+
+## Credits
+
+Based on code from Joseph M. Reagle: https://www.cygwin.com/ml/cygwin/2001-06/msg00537.html
+
+Agent-forwarding support based on ideas from Florent Thoumie and Jonas Pfenniger
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ssh-agent/ssh-agent.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ssh-agent/ssh-agent.plugin.zsh
new file mode 100644 (file)
index 0000000..78ac46b
--- /dev/null
@@ -0,0 +1,108 @@
+# Get the filename to store/lookup the environment from
+ssh_env_cache="$HOME/.ssh/environment-$SHORT_HOST"
+
+function _start_agent() {
+  # Check if ssh-agent is already running
+  if [[ -f "$ssh_env_cache" ]]; then
+    . "$ssh_env_cache" > /dev/null
+
+    # Test if $SSH_AUTH_SOCK is visible
+    zmodload zsh/net/socket
+    if [[ -S "$SSH_AUTH_SOCK" ]] && zsocket "$SSH_AUTH_SOCK" 2>/dev/null; then
+      return 0
+    fi
+  fi
+
+  # Set a maximum lifetime for identities added to ssh-agent
+  local lifetime
+  zstyle -s :omz:plugins:ssh-agent lifetime lifetime
+
+  # start ssh-agent and setup environment
+  zstyle -t :omz:plugins:ssh-agent quiet || echo >&2 "Starting ssh-agent ..."
+  ssh-agent -s ${lifetime:+-t} ${lifetime} | sed '/^echo/d' >! "$ssh_env_cache"
+  chmod 600 "$ssh_env_cache"
+  . "$ssh_env_cache" > /dev/null
+}
+
+function _add_identities() {
+  local id file line sig lines
+  local -a identities loaded_sigs loaded_ids not_loaded
+  zstyle -a :omz:plugins:ssh-agent identities identities
+
+  # check for .ssh folder presence
+  if [[ ! -d "$HOME/.ssh" ]]; then
+    return
+  fi
+
+  # add default keys if no identities were set up via zstyle
+  # this is to mimic the call to ssh-add with no identities
+  if [[ ${#identities} -eq 0 ]]; then
+    # key list found on `ssh-add` man page's DESCRIPTION section
+    for id in id_rsa id_dsa id_ecdsa id_ed25519 identity; do
+      # check if file exists
+      [[ -f "$HOME/.ssh/$id" ]] && identities+=($id)
+    done
+  fi
+
+  # get list of loaded identities' signatures and filenames
+  if lines=$(ssh-add -l); then
+    for line in ${(f)lines}; do
+      loaded_sigs+=${${(z)line}[2]}
+      loaded_ids+=${${(z)line}[3]}
+    done
+  fi
+
+  # add identities if not already loaded
+  for id in $identities; do
+    # if id is an absolute path, make file equal to id
+    [[ "$id" = /* ]] && file="$id" || file="$HOME/.ssh/$id"
+    # check for filename match, otherwise try for signature match
+    if [[ ${loaded_ids[(I)$file]} -le 0 ]]; then
+      sig="$(ssh-keygen -lf "$file" | awk '{print $2}')"
+      [[ ${loaded_sigs[(I)$sig]} -le 0 ]] && not_loaded+=("$file")
+    fi
+  done
+
+  # abort if no identities need to be loaded
+  if [[ ${#not_loaded} -eq 0 ]]; then
+    return
+  fi
+
+  # pass extra arguments to ssh-add
+  local args
+  zstyle -a :omz:plugins:ssh-agent ssh-add-args args
+
+  # if ssh-agent quiet mode, pass -q to ssh-add
+  zstyle -t :omz:plugins:ssh-agent quiet && args=(-q $args)
+
+  # use user specified helper to ask for password (ksshaskpass, etc)
+  local helper
+  zstyle -s :omz:plugins:ssh-agent helper helper
+
+  if [[ -n "$helper" ]]; then
+    if [[ -z "${commands[$helper]}" ]]; then
+      echo >&2 "ssh-agent: the helper '$helper' has not been found."
+    else
+      SSH_ASKPASS="$helper" ssh-add "${args[@]}" ${^not_loaded} < /dev/null
+      return $?
+    fi
+  fi
+
+  ssh-add "${args[@]}" ${^not_loaded}
+}
+
+# Add a nifty symlink for screen/tmux if agent forwarding is enabled
+if zstyle -t :omz:plugins:ssh-agent agent-forwarding \
+   && [[ -n "$SSH_AUTH_SOCK" && ! -L "$SSH_AUTH_SOCK" ]]; then
+  ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen
+else
+  _start_agent
+fi
+
+# Don't add identities if lazy-loading is enabled
+if ! zstyle -t :omz:plugins:ssh-agent lazy; then
+  _add_identities
+fi
+
+unset agent_forwarding ssh_env_cache
+unfunction _start_agent _add_identities
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/stack/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/stack/README.md
new file mode 100644 (file)
index 0000000..da73444
--- /dev/null
@@ -0,0 +1,9 @@
+# Stack
+
+This plugin provides completion for [Stack](https://haskellstack.org).
+
+To use it add stack to the plugins array in your zshrc file.
+
+```bash
+plugins=(... stack)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/stack/stack.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/stack/stack.plugin.zsh
new file mode 100644 (file)
index 0000000..45ef387
--- /dev/null
@@ -0,0 +1,4 @@
+(( $+commands[stack] )) || return
+
+autoload -U +X bashcompinit && bashcompinit
+source <(stack --bash-completion-script stack)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime-merge/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime-merge/README.md
new file mode 100644 (file)
index 0000000..5344791
--- /dev/null
@@ -0,0 +1,17 @@
+## sublime-merge
+
+Plugin for Sublime Merge, a cross platform text and code editor, available for Linux, Mac OS X, and Windows.
+
+### Requirements
+
+ * [Sublime Merge](https://www.sublimemerge.com)
+
+### Usage
+
+ * If `sm` command is called without an argument, launch Sublime Merge
+
+ * If `sm` is passed a directory, `cd` to it and open the existing git repository in Sublime Merge
+
+ * If `smt` command is called, it is equivalent to `sm .`, opening the existing git repository in the current folder in Sublime Merge
+
+ * If `ssm` command is called, it is like `sudo sm`, opening the git repository in Sublime Merge. Useful for editing system protected repositories.
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime-merge/sublime-merge.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime-merge/sublime-merge.plugin.zsh
new file mode 100644 (file)
index 0000000..15452e6
--- /dev/null
@@ -0,0 +1,55 @@
+# Sublime Merge Aliases
+
+() {
+
+       if [[ "$OSTYPE" == linux* ]]; then
+               local _sublime_linux_paths
+               _sublime_linux_paths=(
+                       "$HOME/bin/sublime_merge"
+                       "/opt/sublime_merge/sublime_merge"
+                       "/usr/bin/sublime_merge"
+                       "/usr/local/bin/sublime_merge"
+                       "/usr/bin/sublime_merge"
+                       "/usr/local/bin/smerge"
+                       "/usr/bin/smerge"
+                       )
+               for _sublime_merge_path in $_sublime_linux_paths; do
+                       if [[ -a $_sublime_merge_path ]]; then
+                               sm_run() { $_sublime_merge_path "$@" >/dev/null 2>&1 &| }
+                               ssm_run_sudo() {sudo $_sublime_merge_path "$@" >/dev/null 2>&1}
+                               alias ssm=ssm_run_sudo
+                               alias sm=sm_run
+                               break
+                       fi
+               done
+       elif  [[ "$OSTYPE" = darwin* ]]; then
+               local _sublime_darwin_paths
+               _sublime_darwin_paths=(
+                       "/usr/local/bin/smerge"
+                       "/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge"
+                       "$HOME/Applications/Sublime Merge.app/Contents/SharedSupport/bin/smerge"
+                       )
+               for _sublime_merge_path in $_sublime_darwin_paths; do
+                       if [[ -a $_sublime_merge_path ]]; then
+                               subm () { "$_sublime_merge_path" "$@" }
+                               alias sm=subm
+                               break
+                       fi
+               done
+       elif [[ "$OSTYPE" = 'cygwin' ]]; then
+               local sublime_merge_cygwin_paths
+               sublime_merge_cygwin_paths=(
+                       "$(cygpath $ProgramW6432/Sublime\ Merge)/sublime_merge.exe"
+                       )
+               for _sublime_merge_path in $_sublime_merge_cygwin_paths; do
+                       if [[ -a $_sublime_merge_path ]]; then
+                               subm () { "$_sublime_merge_path" "$@" }
+                               alias sm=subm
+                               break
+                       fi
+               done
+       fi
+
+}
+
+alias smt='sm .'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime/README.md
new file mode 100644 (file)
index 0000000..2299924
--- /dev/null
@@ -0,0 +1,37 @@
+# sublime
+
+Plugin for [Sublime Text](https://www.sublimetext.com/), a cross platform text and code editor,
+available for Linux, macOS, and Windows.
+
+To use the plugin, add `sublime` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... sublime)
+```
+
+Sublime Text has to be installed to use the plugin.
+
+## Usage
+
+The plugin defines several aliases, such as:
+
+- `st`: opens Sublime Text. If passed a file or directory, Sublime Text will open it.
+
+- `stt`: open Sublime Text on the current directory.
+
+- `sst`: if `sudo` is available, `sst` will open Sublime Text with root permissions, so that
+  you can modify any file or directory that you pass it. Useful to edit system files.
+
+There are also a few functions available:
+
+- `find_project` (or `stp` alias): if called, the function will search for a `.sublime-project` file
+  on the current directory or its parents, until it finds none.
+
+  If there is no `.sublime-project` file but the current folder is in a Git repository, it will open
+  Sublime Text on the root directory of the repository.
+
+  If there is no Git repository, it will then open Sublime Text on the current directory.
+
+- `create_project` (or `stn` alias): if called without an argument, create a stub `.sublime-project`
+  file in the current working directory, if one does not already exist. If passed a directory, create
+  a stub `.sublime-project` file in it.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime/sublime.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sublime/sublime.plugin.zsh
new file mode 100644 (file)
index 0000000..dadf375
--- /dev/null
@@ -0,0 +1,124 @@
+# Sublime Text aliases
+
+alias st=subl
+alias stt='subl .'
+
+# Define sst only if sudo exists
+(( $+commands[sudo] )) && alias sst='sudo subl'
+
+alias stp=find_project
+alias stn=create_project
+
+
+# Search for the Sublime Text command if not found
+(( $+commands[subl] )) || {
+  declare -a _sublime_paths
+
+  if [[ "$OSTYPE" == linux* ]]; then
+    if [[ "$(uname -r)" = *icrosoft* ]]; then
+      _sublime_paths=(
+        "$(wslpath -u 'C:\Program Files\Sublime Text\sublime_text.exe' 2>/dev/null)"
+        "$(wslpath -u 'C:\Program Files\Sublime Text 3\subl.exe' 2>/dev/null)"
+        "$(wslpath -u 'C:\Program Files\Sublime Text 2\subl.exe' 2>/dev/null)"
+      )
+    else
+      _sublime_paths=(
+        "$HOME/bin/sublime_text"
+        "/opt/sublime_text/sublime_text"
+        "/opt/sublime_text_3/sublime_text"
+        "/usr/bin/sublime_text"
+        "/usr/local/bin/sublime_text"
+        "/usr/bin/subl"
+        "/usr/bin/subl3"
+        "/snap/bin/subl"
+        "/snap/bin/sublime-text.subl"
+      )
+    fi
+  elif [[ "$OSTYPE" = darwin* ]]; then
+    _sublime_paths=(
+      "/usr/local/bin/subl"
+      "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"
+      "/Applications/Sublime Text 4.app/Contents/SharedSupport/bin/subl"
+      "/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
+      "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"
+      "$HOME/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"
+      "$HOME/Applications/Sublime Text 4.app/Contents/SharedSupport/bin/subl"
+      "$HOME/Applications/Sublime Text 3.app/Contents/SharedSupport/bin/subl"
+      "$HOME/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"
+    )
+  elif [[ "$OSTYPE" = cygwin ]]; then
+    _sublime_paths=(
+      "$(cygpath "$ProgramW6432/Sublime Text 2")/subl.exe"
+      "$(cygpath "$ProgramW6432/Sublime Text 3")/subl.exe"
+    )
+  elif [[ "$OSTYPE" = msys ]]; then
+    _sublime_paths=(
+      "/c/Program Files/Sublime Text/sublime_text.exe"
+      "/c/Program Files/Sublime Text 2/subl.exe"
+      "/c/Program Files/Sublime Text 3/subl.exe"
+    )
+  fi
+
+  for _sublime_path in $_sublime_paths; do
+    if [[ -a $_sublime_path ]]; then
+      alias subl="'$_sublime_path'"
+      (( $+commands[sudo] )) && alias sst="sudo '$_sublime_path'"
+      break
+    fi
+  done
+
+  unset _sublime_paths _sublime_path
+}
+
+function find_project() {
+  local PROJECT_ROOT="${PWD}"
+  local FINAL_DEST="."
+
+  while [[ $PROJECT_ROOT != "/" && ! -d "$PROJECT_ROOT/.git" ]]; do
+    PROJECT_ROOT=$(dirname $PROJECT_ROOT)
+  done
+
+  if [[ $PROJECT_ROOT != "/" ]]; then
+    local PROJECT_NAME="${PROJECT_ROOT##*/}"
+
+    local SUBL_DIR=$PROJECT_ROOT
+    while [[ $SUBL_DIR != "/" && ! -f "$SUBL_DIR/$PROJECT_NAME.sublime-project" ]]; do
+      SUBL_DIR=$(dirname $SUBL_DIR)
+    done
+
+    if [[ $SUBL_DIR != "/" ]]; then
+      FINAL_DEST="$SUBL_DIR/$PROJECT_NAME.sublime-project"
+    else
+      FINAL_DEST=$PROJECT_ROOT
+    fi
+  fi
+
+  subl $FINAL_DEST
+}
+
+function create_project() {
+  local _target=$1
+
+  if [[ "${_target}" == "" ]]; then
+    _target=$(pwd);
+  elif [[ ! -d ${_target} ]]; then
+    echo "${_target} is not a valid directory"
+    return 1
+  fi
+
+  local _sublime_project_file=$_target/$(basename $_target).sublime-project
+
+  if [[ ! -f $_sublime_project_file ]]; then
+    touch $_sublime_project_file
+
+    echo -e "{"                         >> $_sublime_project_file
+    echo -e "\t\"folders\":"            >> $_sublime_project_file
+    echo -e "\t\t[{"                    >> $_sublime_project_file
+    echo -e "\t\t\t\"path\": \".\","    >> $_sublime_project_file
+    echo -e "\t\t\t\"file_exclude_patterns\": []" >> $_sublime_project_file
+    echo -e "\t\t}]"                    >> $_sublime_project_file
+    echo -e "}"                         >> $_sublime_project_file
+
+    echo -e "New Sublime Text project created:\n\t${_sublime_project_file}"
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sudo/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/sudo/README.md
new file mode 100644 (file)
index 0000000..27cd20c
--- /dev/null
@@ -0,0 +1,75 @@
+# sudo
+
+Easily prefix your current or previous commands with `sudo` by pressing <kbd>esc</kbd> twice.
+
+To use it, add `sudo` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... sudo)
+```
+
+## Usage
+
+### Current typed commands
+
+Say you have typed a long command and forgot to add `sudo` in front:
+
+```console
+$ apt-get install build-essential
+```
+
+By pressing the <kbd>esc</kbd> key twice, you will have the same command with `sudo` prefixed without typing:
+
+```console
+$ sudo apt-get install build-essential
+```
+
+The same happens for editing files with your default editor (defined in `$SUDO_EDITOR`, `$VISUAL` or `$EDITOR`, in that order):
+
+If the editor defined were `vim`:
+
+```console
+$ vim /etc/hosts
+```
+
+By pressing the <kbd>esc</kbd> key twice, you will have the same command with `sudo -e` instead of the editor, that would open that editor with root privileges:
+
+```console
+$ sudo -e /etc/hosts
+```
+
+### Previous executed commands
+
+Say you want to delete a system file and denied:
+
+```console
+$ rm some-system-file.txt
+-su: some-system-file.txt: Permission denied
+$
+```
+
+By pressing the <kbd>esc</kbd> key twice, you will have the same command with `sudo` prefixed without typing:
+
+```console
+$ rm some-system-file.txt
+-su: some-system-file.txt: Permission denied
+$ sudo rm some-system-file.txt
+Password:
+$
+```
+
+The same happens for file editing, as told before.
+
+## Key binding
+
+By default, the `sudo` plugin uses <kbd>Esc</kbd><kbd>Esc</kbd> as the trigger.
+If you want to change it, you can use the `bindkey` command to bind it to a different key:
+
+```sh
+bindkey -M emacs '<seq>' sudo-command-line
+bindkey -M vicmd '<seq>' sudo-command-line
+bindkey -M viins '<seq>' sudo-command-line
+```
+
+where `<seq>` is the sequence you want to use. You can find the keyboard sequence
+by running `cat` and pressing the keyboard combination you want to use.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/sudo/sudo.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/sudo/sudo.plugin.zsh
new file mode 100644 (file)
index 0000000..2a0b3bf
--- /dev/null
@@ -0,0 +1,108 @@
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+# sudo or sudo -e (replacement for sudoedit) will be inserted before the command
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+# * Dongweiming <ciici123@gmail.com>
+# * Subhaditya Nath <github.com/subnut>
+# * Marc Cornellà <github.com/mcornella>
+# * Carlo Sala <carlosalag@protonmail.com>
+#
+# ------------------------------------------------------------------------------
+
+__sudo-replace-buffer() {
+  local old=$1 new=$2 space=${2:+ }
+
+  # if the cursor is positioned in the $old part of the text, make
+  # the substitution and leave the cursor after the $new text
+  if [[ $CURSOR -le ${#old} ]]; then
+    BUFFER="${new}${space}${BUFFER#$old }"
+    CURSOR=${#new}
+  # otherwise just replace $old with $new in the text before the cursor
+  else
+    LBUFFER="${new}${space}${LBUFFER#$old }"
+  fi
+}
+
+sudo-command-line() {
+  # If line is empty, get the last run command from history
+  [[ -z $BUFFER ]] && LBUFFER="$(fc -ln -1)"
+
+  # Save beginning space
+  local WHITESPACE=""
+  if [[ ${LBUFFER:0:1} = " " ]]; then
+    WHITESPACE=" "
+    LBUFFER="${LBUFFER:1}"
+  fi
+
+  {
+    # If $SUDO_EDITOR or $VISUAL are defined, then use that as $EDITOR
+    # Else use the default $EDITOR
+    local EDITOR=${SUDO_EDITOR:-${VISUAL:-$EDITOR}}
+
+    # If $EDITOR is not set, just toggle the sudo prefix on and off
+    if [[ -z "$EDITOR" ]]; then
+      case "$BUFFER" in
+        sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "" ;;
+        sudo\ *) __sudo-replace-buffer "sudo" "" ;;
+        *) LBUFFER="sudo $LBUFFER" ;;
+      esac
+      return
+    fi
+
+    # Check if the typed command is really an alias to $EDITOR
+
+    # Get the first part of the typed command
+    local cmd="${${(Az)BUFFER}[1]}"
+    # Get the first part of the alias of the same name as $cmd, or $cmd if no alias matches
+    local realcmd="${${(Az)aliases[$cmd]}[1]:-$cmd}"
+    # Get the first part of the $EDITOR command ($EDITOR may have arguments after it)
+    local editorcmd="${${(Az)EDITOR}[1]}"
+
+    # Note: ${var:c} makes a $PATH search and expands $var to the full path
+    # The if condition is met when:
+    # - $realcmd is '$EDITOR'
+    # - $realcmd is "cmd" and $EDITOR is "cmd"
+    # - $realcmd is "cmd" and $EDITOR is "cmd --with --arguments"
+    # - $realcmd is "/path/to/cmd" and $EDITOR is "cmd"
+    # - $realcmd is "/path/to/cmd" and $EDITOR is "/path/to/cmd"
+    # or
+    # - $realcmd is "cmd" and $EDITOR is "cmd"
+    # - $realcmd is "cmd" and $EDITOR is "/path/to/cmd"
+    # or
+    # - $realcmd is "cmd" and $EDITOR is /alternative/path/to/cmd that appears in $PATH
+    if [[ "$realcmd" = (\$EDITOR|$editorcmd|${editorcmd:c}) \
+      || "${realcmd:c}" = ($editorcmd|${editorcmd:c}) ]] \
+      || builtin which -a "$realcmd" | command grep -Fx -q "$editorcmd"; then
+      __sudo-replace-buffer "$cmd" "sudo -e"
+      return
+    fi
+
+    # Check for editor commands in the typed command and replace accordingly
+    case "$BUFFER" in
+      $editorcmd\ *) __sudo-replace-buffer "$editorcmd" "sudo -e" ;;
+      \$EDITOR\ *) __sudo-replace-buffer '$EDITOR' "sudo -e" ;;
+      sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "$EDITOR" ;;
+      sudo\ *) __sudo-replace-buffer "sudo" "" ;;
+      *) LBUFFER="sudo $LBUFFER" ;;
+    esac
+  } always {
+    # Preserve beginning space
+    LBUFFER="${WHITESPACE}${LBUFFER}"
+
+    # Redisplay edit buffer (compatibility with zsh-syntax-highlighting)
+    zle redisplay
+  }
+}
+
+zle -N sudo-command-line
+
+# Defined shortcut keys: [Esc] [Esc]
+bindkey -M emacs '\e\e' sudo-command-line
+bindkey -M vicmd '\e\e' sudo-command-line
+bindkey -M viins '\e\e' sudo-command-line
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/README.md
new file mode 100644 (file)
index 0000000..a060ff4
--- /dev/null
@@ -0,0 +1,13 @@
+# supervisor plugin
+
+This plugin adds tab-completion for `supervisord`/`supervisorctl` in [Supervisor](http://supervisord.org/).
+Supervisor is a client/server system that allows its users to monitor and control a number
+of processes on UNIX-like operating systems.
+
+To use it, add `supervisor` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... supervisor)
+```
+
+These scripts are from [zshcompfunc4supervisor](https://bitbucket.org/hhatto/zshcompfunc4supervisor).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/_supervisorctl b/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/_supervisorctl
new file mode 100644 (file)
index 0000000..87cffab
--- /dev/null
@@ -0,0 +1,143 @@
+#compdef supervisorctl
+
+typeset -A opt_args
+local context state line
+
+_supervisorctl() {
+    _arguments -s -S \
+        {--configuration,-c}"[configuration file path (default /etc/supervisor.conf)]:FILENAME:_files" \
+        {--help,-h}"[print usage message and exit]:" \
+        {--interactive,-i}"[start an interactive shell after executing commands]" \
+        {--serverurl,-s}"[URL on which supervisord server is listening (default "http://localhost:9001").]" \
+        {--username,-u}"[username to use for authentication with server]:USERNAME:_users" \
+        {--password,-p}"[password to use for authentication with server]:PASSWORD:" \
+        {--history-file,-r}"[keep a readline history (if readline is available)]:FILENAME:_files" \
+        "*::supervisorctl commands:_supervisorctl_command"
+}
+
+(( $+functions[_supervisorctl_command] )) ||
+_supervisorctl_command() {
+    local cmd ret=1
+
+    (( $+supervisorctl_cmds )) || _supervisorctl_cmds=(
+        "add:Activates any updates in config for process/group" \
+        "avail:Display all configured processes" \
+        "clear:Clear process/multiple-process/all-process log files" \
+        "exit:Exit the supervisor shell." \
+        "fg:Connect to a process in foreground mode" \
+        "maintail:tail of supervisor main log file" \
+        "open:Connect to a remote supervisord process. (for UNIX domain socket, use unix:///socket/path)" \
+        "pid:Get the PID of supervisord." \
+        "quit:Exit the supervisor shell." \
+        "reload:Restart the remote supervisord." \
+        "remove:Removes process/group from active config" \
+        "reread:Reload the daemon's configuration files" \
+        "restart:Restart process or group." \
+        "shutdown:Shut the remote supervisord down." \
+        "start:Start process or groups." \
+        "status:Get process status info." \
+        "stop:Stop process or group." \
+        "tail:tail of process stdout" \
+        "update:Reload config and add/remove as necessary" \
+        "version:Show the version of the remote supervisord process" \
+        "help:Show help" \
+        )
+
+    if (( CURRENT == 1 )); then
+        _describe -t commands 'supervisorctl subcommand' _supervisorctl_cmds \
+            || compadd "$@" - ${(s.:.)${(j.:.)_supervisorctl_syns}}
+    else
+        local curcontext="$curcontext"
+
+        cmd="${${_supervisorctl_cmds[(r)$words[1]:*]%%:*}:-${(k)_supervisorctl_syns[(r)(*:|)$words[1](:*|)]}}"
+        if (( $#cmd )); then
+            curcontext="${curcontext%:*:*}:supervisorctl-${cmd}:"
+            _call_function ret _supervisorctl_$cmd || _message 'no more arguments'
+        else
+            _message "unknown supervisorctl command: $words[1]"
+        fi
+        return ret
+    fi
+}
+
+# get supervisor contoroll processes
+(( $+functions[_get_supervisor_procs] )) ||
+_get_supervisor_procs() {
+    local cache_policy
+    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
+    if [[ -z "$cache_policy" ]]; then
+        zstyle ":completion:${curcontext}:" cache-policy _supervisor_procs_caching_policy
+    fi
+
+    if ( [[ ${+_supervisor_procs} -eq 0 ]] || _cache_invalid supervisor_procs ) \
+        && ! _retrieve_cache supervisor_procs; then
+
+        _supervisor_procs=(${${(f)"$(supervisorctl status >/dev/null 2>&1 | awk -F' ' '{print $1}')"}})
+        _store_cache supervisor_procs _supervisor_procs
+    fi
+
+    local expl
+    _wanted supervisor_procs expl 'supervisor processes' compadd -a _supervisor_procs
+}
+
+_supervisor_procs_caching_policy() {
+    local -a oldp
+    oldp=( "$1"(Nmw+1) )
+    (( $#oldp ))
+}
+
+(( $+functions[_supervisorctl_add] )) ||
+_supervisorctl_add() {
+    _arguments -s \
+        "--help[use help system]" \
+        "*::supervisorctl commands:_supervisorctl"
+}
+
+(( $+functions[_supervisorctl_help] )) ||
+_supervisorctl_help() {
+    _arguments -s \
+        "*:supervisorctl commands:_supervisorctl"
+}
+
+(( $+functions[_supervisorctl_maintail] )) ||
+_supervisorctl_maintail() {
+    _arguments -s \
+        '-f[Continuous tail of supervisor main log file (Ctrl-C to exit)]'
+}
+
+(( $+functions[_supervisorctl_start] )) ||
+_supervisorctl_start() {
+    # TODO: add 'all'
+    _arguments -s \
+        '*::supervisor process:_get_supervisor_procs'
+}
+
+(( $+functions[_supervisorctl_restart] )) ||
+_supervisorctl_restart() {
+    # TODO: add 'all'
+    _arguments -s \
+        '*::supervisor process:_get_supervisor_procs'
+}
+
+(( $+functions[_supervisorctl_status] )) ||
+_supervisorctl_status() {
+    _arguments \
+        '*::supervisor process:_get_supervisor_procs'
+}
+
+(( $+functions[_supervisorctl_stop] )) ||
+_supervisorctl_stop() {
+    # TODO: add 'all'
+    _arguments -s \
+        '*::supervisor process:_get_supervisor_procs'
+}
+
+(( $+functions[_supervisorctl_tail] )) ||
+_supervisorctl_tail() {
+    # TODO: add 'stderr'
+    _arguments -s \
+        '-f[Continuous tail of named process stdout Ctrl-C to exit.]' \
+        '*::supervisor process:_get_supervisor_procs'
+}
+
+_supervisorctl "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/_supervisord b/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/_supervisord
new file mode 100644 (file)
index 0000000..e0cb670
--- /dev/null
@@ -0,0 +1,33 @@
+#compdef supervisord
+
+typeset -A opt_args
+local context state line
+
+_arguments \
+    {--configuration,-c}"[configuration file]:FILENAME:_files" \
+    {--nodaemon,-n}"[run in the foreground (same as 'nodaemon true' in config file)]" \
+    {--help,-h}"[print this usage message and exit]:" \
+    {--version,-v}"[print supervisord version number and exit]:" \
+    {--user,-u}"[run supervisord as this user]:USER:_users" \
+    {--umask,-m}"[use this umask for daemon subprocess (default is 022)]" \
+    {--directory,-d}"[directory to chdir to when daemonized]" \
+    {--logfile,-l}"[use FILENAME as logfile path]:FILENAME:_files" \
+    {--logfile_maxbytes,-y}"[use BYTES to limit the max size of logfile]" \
+    {--logfile_backups,-z}"[number of backups to keep when max bytes reached]" \
+    {--loglevel,-e}"[use LEVEL as log level (debug,info,warn,error,critical)]:level:->levels" \
+    {--pidfile,-j}"[write a pid file for the daemon process to FILENAME]:FILENAME:_files" \
+    {--identifier,-i}"[identifier used for this instance of supervisord]" \
+    {--childlogdir,-q}"[the log directory for child process logs]:child log directory:_files -/" \
+    {--nocleanup,-k}"[prevent the process from performing cleanup (removal of old automatic child log files) at startup.]" \
+    {--minfds,-a}"[the minimum number of file descriptors for start success]" \
+    {--strip_ansi,-t}"[strip ansi escape codes from process output]" \
+    "--minprocs[the minimum number of processes available for start success]" \
+    "--profile_options[run supervisord under profiler and output results based on OPTIONS, which is a comma-sep'd list of 'cumulative', 'calls', and/or 'callers', e.g. 'cumulative,callers')]" \
+    "*::args:_gnu_generic"
+
+case $state in
+levels)
+    levels=("debug" "info" "warn" "error" "critical")
+    _describe -t levels 'supervisord levels' levels && return 0
+    ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/supervisor.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/supervisor/supervisor.plugin.zsh
new file mode 100644 (file)
index 0000000..ad54302
--- /dev/null
@@ -0,0 +1,14 @@
+# DECLARATION: This plugin was created by hhatto. What I did is just making a portal from https://bitbucket.org/hhatto/zshcompfunc4supervisor.
+
+alias sup='sudo supervisorctl'
+alias supad='sudo supervisorctl add'
+alias supa='sudo supervisorctl avail'
+alias suprl='sudo supervisorctl reload'
+alias suprm='sudo supervisorctl remove'
+alias suprr='sudo supervisorctl reread'
+alias suprs='sudo supervisorctl restart'
+alias sups='sudo supervisorctl status'
+alias supsr='sudo supervisorctl start'
+alias supso='sudo supervisorctl stop'
+alias supt='sudo supervisorctl tail'
+alias supu='sudo supervisorctl update'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/suse/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/suse/README.md
new file mode 100644 (file)
index 0000000..f37ec16
--- /dev/null
@@ -0,0 +1,96 @@
+# suse
+
+**Maintainer**: [r-darwish](https://github.com/r-darwish)
+
+Alias for Zypper according to the official Zypper's alias
+
+To use it add `suse` to the plugins array in you zshrc file.
+
+```zsh
+plugins=(... suse)
+```
+
+## Main commands
+
+| Alias            | Commands                      | Description                                                    |
+| ---------------- | ----------------------------- | -------------------------------------------------------------- |
+| z                | `sudo zypper`                 | call zypper                                                    |
+| zh               | `zypper -h`                   | print help                                                     |
+| zhse             | `zypper -h se`                | print help for the search command                              |
+| zlicenses        | `zypper licenses`             | prints a report about licenses and EULAs of installed packages |
+| zps              | `sudo zypper ps`              | list process using deleted files                               |
+| zshell           | `sudo zypper shell`           | open a zypper shell session                                    |
+| zsource-download | `sudo zypper source-download` | download source rpms for all installed packages                |
+| ztos             | `zypper tos`                  | shows the ID string of the target operating system             |
+| zvcmp            | `zypper vcmp`                 | tell whether version1 is older or newer than version2          |
+
+## Packages commands
+
+| Alias | Commands          | Description                                                        |
+| ----- | ----------------- | ------------------------------------------------------------------ |
+| zin   | `sudo zypper in`  | install packages                                                   |
+| zinr  | `sudo zypper inr` | install newly added packages recommended by already installed ones |
+| zrm   | `sudo zypper rm`  | remove packages                                                    |
+| zsi   | `sudo zypper si`  | install source of a package                                        |
+| zve   | `sudo zypper ve`  | verify dependencies of installed packages                          |
+
+## Updates commands
+
+| Alias  | Commands            | Description            |
+| ------ | ------------------- | ---------------------- |
+| zdup   | `sudo zypper dup`   | upgrade packages       |
+| zlp    | `zypper lp`         | list necessary patches |
+| zlu    | `zypper lu`         | list updates           |
+| zpchk  | `sudo zypper pchk`  | check for patches      |
+| zup    | `sudo zypper up`    | update packages        |
+| zpatch | `sudo zypper patch` | install patches        |
+
+## Request commands
+
+| Alias         | Commands                   | Description                                          |
+| ------------- | -------------------------- | ---------------------------------------------------- |
+| zif           | `zypper if`                | display info about packages                          |
+| zpa           | `zypper pa`                | list packages                                        |
+| zpatch-info   | `zypper patch-info`        | display info about patches                           |
+| zpattern-info | `zypper pattern-info`      | display info about patterns                          |
+| zproduct-info | `zypper product-info`      | display info about products                          |
+| zpch          | `zypper pch`               | list all patches                                     |
+| zpd           | `zypper pd`                | list products                                        |
+| zpt           | `zypper pt`                | list patterns                                        |
+| zse           | `zypper se`                | search for packages                                  |
+| zwp           | `zypper wp`                | list all packages providing the specified capability |
+
+NOTE: `--no-refresh` is passed to zypper for speeding up the calls and avoid errors due to lack
+of root privileges. If you need to refresh the repositories, call `sudo zypper ref` (`zref` alias)
+before running these aliases.
+
+Related: [#9798](https://github.com/ohmyzsh/ohmyzsh/pull/9798).
+
+## Repositories commands
+
+| Alias | Commands            | Description                              |
+| ----- | ------------------- | ---------------------------------------- |
+| zar   | `sudo zypper ar`    | add a repository                         |
+| zcl   | `sudo zypper clean` | clean cache                              |
+| zlr   | `zypper lr`         | list repositories                        |
+| zmr   | `sudo zypper mr`    | modify repositories                      |
+| znr   | `sudo zypper nr`    | rename repositories (for the alias only) |
+| zref  | `sudo zypper ref`   | refresh repositories                     |
+| zrr   | `sudo zypper rr`    | remove repositories                      |
+
+## Services commands
+| Alias | Commands           | Description                                                    |
+| ----- | ------------------ | -------------------------------------------------------------- |
+| zas   | `sudo zypper as`   | adds a service specified by URI to the system                  |
+| zms   | `sudo zypper ms`   | modify properties of specified services                        |
+| zrefs | `sudo zypper refs` | refreshing a service mean executing the service's special task |
+| zrs   | `sudo zypper rs`   | remove specified repository index service from the system      |
+| zls   | `zypper ls`        | list services defined on the system                            |
+
+## Package Locks Management commands
+| Alias | Commands         | Description                         |
+| ----- | ---------------- | ----------------------------------- |
+| zal   | `sudo zypper al` | add a package lock                  |
+| zcl   | `sudo zypper cl` | remove unused locks                 |
+| zll   | `zypper ll`      | list currently active package locks |
+| zrl   | `sudo zypper rl` | remove specified package lock       |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/suse/suse.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/suse/suse.plugin.zsh
new file mode 100644 (file)
index 0000000..56bc6f1
--- /dev/null
@@ -0,0 +1,59 @@
+#Main commands
+alias z='sudo zypper'
+alias zh='zypper -h'
+alias zhse='zypper -h se'
+alias zlicenses='zypper licenses'
+alias zps='sudo zypper ps'
+alias zshell='sudo zypper shell'
+alias zsource-download='sudo zypper source-download'
+alias ztos='zypper tos'
+alias zvcmp='zypper vcmp'
+
+#Packages commands
+alias zin='sudo zypper in'
+alias zinr='sudo zypper inr'
+alias zrm='sudo zypper rm'
+alias zsi='sudo zypper si'
+alias zve='sudo zypper ve'
+
+#Updates commands
+alias zdup='sudo zypper dup'
+alias zlp='zypper lp'
+alias zlu='zypper lu'
+alias zpchk='sudo zypper pchk'
+alias zup='sudo zypper up'
+alias zpatch='sudo zypper patch'
+
+#Request commands
+alias zif='zypper --no-refresh if'
+alias zpa='zypper --no-refresh pa'
+alias zpatch-info='zypper --no-refresh patch-info'
+alias zpattern-info='zypper --no-refresh pattern-info'
+alias zproduct-info='zypper --no-refresh product-info'
+alias zpch='zypper --no-refresh pch'
+alias zpd='zypper --no-refresh pd'
+alias zpt='zypper --no-refresh pt'
+alias zse='zypper --no-refresh se'
+alias zwp='zypper --no-refresh wp'
+
+#Repositories commands
+alias zar='sudo zypper ar'
+alias zcl='sudo zypper clean'
+alias zlr='zypper lr'
+alias zmr='sudo zypper mr'
+alias znr='sudo zypper nr'
+alias zref='sudo zypper ref'
+alias zrr='sudo zypper rr'
+
+#Services commands
+alias zas='sudo zypper as'
+alias zms='sudo zypper ms'
+alias zrefs='sudo zypper refs'
+alias zrs='sudo zypper rs'
+alias zls='zypper ls'
+
+#Package Locks Management commands
+alias zal='sudo zypper al'
+alias zcl='sudo zypper cl'
+alias zll='zypper ll'
+alias zrl='sudo zypper rl'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/svcat/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/svcat/README.md
new file mode 100644 (file)
index 0000000..0bc60b1
--- /dev/null
@@ -0,0 +1,9 @@
+# svcat
+
+This plugin provides completion for the [Kubernetes service catalog cli](https://github.com/kubernetes-incubator/service-catalog).
+
+To use it, add `svcat` to the plugins array in your zshrc file.
+
+```
+plugins=(... svcat)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/svcat/svcat.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/svcat/svcat.plugin.zsh
new file mode 100644 (file)
index 0000000..f90e7d8
--- /dev/null
@@ -0,0 +1,6 @@
+# Autocompletion for svcat.
+#
+
+if [ $commands[svcat] ]; then
+  source <(svcat completion zsh)
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/svn-fast-info/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/svn-fast-info/README.md
new file mode 100644 (file)
index 0000000..e86ba21
--- /dev/null
@@ -0,0 +1,56 @@
+# svn-fast-info plugin
+
+Faster alternative to the main SVN plugin implementation. Works with svn 1.6 and newer.
+Use as a drop-in replacement to the svn plugin, not as complementary.
+
+To use it, add `svn-fast-info` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... svn-fast-info)
+```
+
+It's faster because it has an efficient use of svn (single svn call) which saves a lot on a huge codebase.
+It displays the current status of the local files (added, deleted, modified, replaced, or else...)
+
+Use `svn_prompt_info` method to display the svn repository status in your theme.
+
+## Functions
+
+- `svn_prompt_info`: displays all the available information regarding the status of the svn repository.
+
+- `svn_repo_need_upgrade`: shows whether the repository needs upgrading. `svn_prompt_info` queries the
+  rest of functions or not based on the result of this function.
+
+- `svn_current_branch_name`: shows the current branch.
+
+- `svn_repo_root_name`: displays the repository root.
+
+- `svn_current_revision`: shows the currently checked-out revision.
+
+- `svn_status_info`: shows a bunch of symbols depending on the status of the files in the repository.
+
+## Options
+
+- `ZSH_THEME_SVN_PROMPT_PREFIX`: sequence displayed at the beginning of the prompt info output.
+
+- `ZSH_THEME_SVN_PROMPT_SUFFIX`: sequence displayed at the end of the prompt info output.
+
+- `ZSH_THEME_SVN_PROMPT_CLEAN`: sequence displayed when the status of the repository is clean.
+
+- `ZSH_THEME_SVN_PROMPT_ADDITIONS`: sequence displayed if there are added files in the repository.
+  **Default:** `+`.
+
+- `ZSH_THEME_SVN_PROMPT_DELETIONS`: sequence displayed if there are deleted files in the repository.
+  **Default:** `✖`.
+
+- `ZSH_THEME_SVN_PROMPT_MODIFICATIONS`: sequence displayed if there are modified files in the repository.
+  **Default:** `✎`.
+
+- `ZSH_THEME_SVN_PROMPT_REPLACEMENTS`: sequence displayed if there are replaced files in the repository.
+  **Default:** `∿`.
+
+- `ZSH_THEME_SVN_PROMPT_UNTRACKED`: sequence displayed if there are untracked files in the repository.
+  **Default:** `?`.
+
+- `ZSH_THEME_SVN_PROMPT_DIRTY`: sequence displayed if the repository is dirty.
+  **Default:** `!`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/svn-fast-info/svn-fast-info.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/svn-fast-info/svn-fast-info.plugin.zsh
new file mode 100644 (file)
index 0000000..46dd5cb
--- /dev/null
@@ -0,0 +1,74 @@
+function svn_prompt_info() {
+  local info
+  info=$(LANG= svn info 2>&1) || return 1 # capture stdout and stderr
+  local repo_need_upgrade=$(svn_repo_need_upgrade $info)
+
+  if [[ -n $repo_need_upgrade ]]; then
+    printf '%s%s%s%s%s%s%s\n' \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      "$ZSH_THEME_SVN_PROMPT_PREFIX" \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      "$repo_need_upgrade" \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      "$ZSH_THEME_SVN_PROMPT_SUFFIX" \
+      "$ZSH_PROMPT_BASE_COLOR"
+  else
+    printf '%s%s%s%s %s%s%s:%s%s%s%s' \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      "$ZSH_THEME_SVN_PROMPT_PREFIX" \
+      "$(svn_status_info $info)" \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      \
+      "$ZSH_THEME_BRANCH_NAME_COLOR" \
+      "${$(svn_current_branch_name $info):gs/%/%%}" \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      \
+      "$(svn_current_revision $info)" \
+      "$ZSH_PROMPT_BASE_COLOR" \
+      "$ZSH_THEME_SVN_PROMPT_SUFFIX" \
+      "$ZSH_PROMPT_BASE_COLOR"
+  fi
+}
+
+function svn_repo_need_upgrade() {
+  command grep -q "E155036" <<< "${1:-$(LANG= svn info 2>/dev/null)}" && \
+    echo "E155036: upgrade repo with svn upgrade"
+}
+
+function svn_current_branch_name() {
+  omz_urldecode "$(
+    command grep '^URL:' <<< "${1:-$(svn info 2>/dev/null)}" | command grep -Eo '(tags|branches)/[^/]+|trunk'
+  )"
+}
+
+function svn_repo_root_name() {
+  command grep '^Repository\ Root:' <<< "${1:-$(LANG= svn info 2>/dev/null)}" | sed 's#.*/##'
+}
+
+function svn_current_revision() {
+  echo "${1:-$(LANG= svn info 2>/dev/null)}" | sed -n 's/Revision: //p'
+}
+
+function svn_status_info() {
+  local svn_status_string="$ZSH_THEME_SVN_PROMPT_CLEAN"
+  local svn_status="$(svn status 2>/dev/null)";
+  if command grep -E '^\s*A' &>/dev/null <<< "$svn_status"; then
+    svn_status_string+="${ZSH_THEME_SVN_PROMPT_ADDITIONS:-+}"
+  fi
+  if command grep -E '^\s*D' &>/dev/null <<< "$svn_status"; then
+    svn_status_string+="${ZSH_THEME_SVN_PROMPT_DELETIONS:-✖}"
+  fi
+  if command grep -E '^\s*M' &>/dev/null <<< "$svn_status"; then
+    svn_status_string+="${ZSH_THEME_SVN_PROMPT_MODIFICATIONS:-✎}"
+  fi
+  if command grep -E '^\s*[R~]' &>/dev/null <<< "$svn_status"; then
+    svn_status_string+="${ZSH_THEME_SVN_PROMPT_REPLACEMENTS:-∿}"
+  fi
+  if command grep -E '^\s*\?' &>/dev/null <<< "$svn_status"; then
+    svn_status_string+="${ZSH_THEME_SVN_PROMPT_UNTRACKED:-?}"
+  fi
+  if command grep -E '^\s*[CI!L]' &>/dev/null <<< "$svn_status"; then
+    svn_status_string+="${ZSH_THEME_SVN_PROMPT_DIRTY:-!}"
+  fi
+  echo $svn_status_string
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/svn/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/svn/README.md
new file mode 100644 (file)
index 0000000..cab166a
--- /dev/null
@@ -0,0 +1,67 @@
+# `svn` plugin
+
+This plugin adds some utility functions to display additional information regarding your current
+svn repository. See https://subversion.apache.org/ for the full svn documentation.
+
+To use it, add `svn` to your plugins array:
+
+```zsh
+plugins=(... svn)
+```
+
+## Functions
+
+| Command               | Description                                 |
+|:----------------------|:--------------------------------------------|
+| `svn_prompt_info`     | Shows svn prompt in themes                  |
+| `in_svn`              | Checks if we're in an svn repository        |
+| `svn_get_repo_name`   | Get repository name                         |
+| `svn_get_branch_name` | Get branch name (see [caveats](#caveats))   |
+| `svn_get_rev_nr`      | Get revision number                         |
+| `svn_dirty`           | Checks if there are changes in the svn repo |
+
+## Caveats
+
+The plugin expects the first directory to be the current branch / tag / trunk. So it returns
+the first path element if you don't use branches.
+
+## Usage on themes
+
+To use this in the `agnoster` theme follow these instructions:
+
+1. Enable the svn plugin
+
+2. Add the following lines to your `zshrc` file:
+
+    ```shell
+    prompt_svn() {
+        local rev branch
+        if in_svn; then
+            rev=$(svn_get_rev_nr)
+            branch=$(svn_get_branch_name)
+            if [[ $(svn_dirty_choose_pwd 1 0) -eq 1 ]]; then
+                prompt_segment yellow black
+                echo -n "$rev@$branch"
+                echo -n "±"
+            else
+                prompt_segment green black
+                echo -n "$rev@$branch"
+            fi
+        fi
+    }
+    ```
+
+3. Override the agnoster `build_prompt()` function:
+
+    ```zsh
+    build_prompt() {
+        RETVAL=$?
+        prompt_status
+        prompt_context
+        prompt_dir
+        prompt_git
+        prompt_svn
+        prompt_end
+    }
+    ```
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/svn/svn.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/svn/svn.plugin.zsh
new file mode 100644 (file)
index 0000000..22b07b4
--- /dev/null
@@ -0,0 +1,89 @@
+svn_prompt_info() {
+  local info display
+  info="$(LANG= svn info 2>/dev/null)" || return 1
+
+  if [[ "$SVN_SHOW_BRANCH" = true ]]; then
+    display="$(svn_get_branch_name "$info")"
+  else
+    display="$(svn_get_repo_name "$info")"
+  fi
+
+  printf '%s%s%s%s%s%s%s%s%s%s' \
+    "$ZSH_PROMPT_BASE_COLOR" \
+    "$ZSH_THEME_SVN_PROMPT_PREFIX" \
+    "$ZSH_THEME_REPO_NAME_COLOR" \
+    "${display:gs/%/%%}" \
+    "$ZSH_PROMPT_BASE_COLOR" \
+    "$ZSH_THEME_SVN_PROMPT_SUFFIX" \
+    "$ZSH_PROMPT_BASE_COLOR" \
+    "$(svn_dirty $info)" \
+    "$(svn_dirty_pwd)" \
+    "$ZSH_PROMPT_BASE_COLOR"
+}
+
+in_svn() {
+  svn info &>/dev/null
+}
+
+svn_get_repo_name() {
+  local info name
+  info="${1:-$(LANG= svn info 2>/dev/null)}"
+  name="$(sed -n 's/^Repository\ Root:\ .*\///p' <<< "$info")"
+  omz_urldecode "$name"
+}
+
+svn_get_branch_name() {
+  local info branch
+  info="${1:-$(LANG= svn info 2>/dev/null)}"
+  branch=$(
+    awk -F/ '/^URL:/ {
+      for (i=0; i<=NF; i++) {
+        if ($i == "branches" || $i == "tags" ) {
+          print $(i+1)
+          break
+        };
+        if ($i == "trunk") {
+          print $i
+          break
+        }
+      }
+    }' <<< "$info"
+  )
+  branch="$(omz_urldecode "$branch")"
+
+  echo "${branch:-$(svn_get_repo_name "$info")}"
+}
+
+svn_get_rev_nr() {
+  sed -n 's/Revision:\ //p' <<<"${1:-$(LANG= svn info 2>/dev/null)}"
+}
+
+svn_dirty() {
+  svn_dirty_choose "${1:-$(LANG= svn info 2>/dev/null)}" $ZSH_THEME_SVN_PROMPT_DIRTY $ZSH_THEME_SVN_PROMPT_CLEAN
+}
+
+svn_dirty_choose() {
+  local root
+  root=$(sed -n 's/^Working Copy Root Path: //p' <<< "${1:-$(LANG= svn info 2>/dev/null)}")
+  if LANG= svn status "$root" 2>/dev/null | command grep -Eq '^\s*[ACDIM!?L]'; then
+    # Grep exits with 0 when "One or more lines were selected", return "dirty".
+    echo $2
+  else
+    # Otherwise, no lines were found, or an error occurred. Return clean.
+    echo $3
+  fi
+}
+
+svn_dirty_pwd () {
+  svn_dirty_choose_pwd $ZSH_THEME_SVN_PROMPT_DIRTY_PWD $ZSH_THEME_SVN_PROMPT_CLEAN_PWD
+}
+
+svn_dirty_choose_pwd () {
+  if LANG= svn status "$PWD" 2>/dev/null | command grep -Eq '^\s*[ACDIM!?L]'; then
+    # Grep exits with 0 when "One or more lines were selected", return "dirty".
+    echo $1
+  else
+    # Otherwise, no lines were found, or an error occurred. Return clean.
+    echo $2
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/README.md
new file mode 100644 (file)
index 0000000..a722c03
--- /dev/null
@@ -0,0 +1,22 @@
+# Swift Package Manager
+
+## Description
+
+This plugin provides a few utilities that make you faster on your daily work with the [Swift Package Manager](https://github.com/apple/swift-package-manager), as well as autocompletion for Swift 5.1.
+
+To start using it, add the `swiftpm` plugin to your `plugins` array in `~/.zshrc`:
+
+```zsh
+plugins=(... swiftpm)
+```
+
+## Aliases
+
+| Alias | Description                         | Command                            |
+|-------|-------------------------------------|------------------------------------|
+| `spi` | Initialize a new package            | `swift package init`               |
+| `spf` | Fetch package dependencies          | `swift package fetch`              |
+| `spu` | Update package dependencies         | `swift package update`             |
+| `spx` | Generates an Xcode project          | `swift package generate-xcodeproj` |
+| `sps` | Print the resolved dependency graph | `swift package show-dependencies`  |
+| `spd` | Print parsed Package.swift as JSON  | `swift package dump-package`       |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/_swift b/stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/_swift
new file mode 100644 (file)
index 0000000..3a92322
--- /dev/null
@@ -0,0 +1,474 @@
+#compdef swift
+local context state state_descr line
+typeset -A opt_args
+
+_swift() {
+    _arguments -C \
+        '(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \
+        '(-): :->command' \
+        '(-)*:: :->arg' && return
+
+    case $state in
+        (command)
+            local tools
+            tools=(
+                'build:build sources into binary products'
+                'run:build and run an executable product'
+                'package:perform operations on Swift packages'
+                'test:build and run tests'
+            )
+            _alternative \
+                'tools:common:{_describe "tool" tools }' \
+                'compiler: :_swift_compiler' && _ret=0
+            ;;
+        (arg)
+            case ${words[1]} in
+                (build)
+                    _swift_build
+                    ;;
+                (run)
+                    _swift_run
+                    ;;
+                (package)
+                    _swift_package
+                    ;;
+                (test)
+                    _swift_test
+                    ;;
+                (*)
+                    _swift_compiler
+                    ;;
+            esac
+            ;;
+    esac
+}
+
+_swift_dependency() {
+    local dependencies
+    dependencies=( $(swift package completion-tool list-dependencies) )
+    _describe '' dependencies
+}
+
+_swift_executable() {
+    local executables
+    executables=( $(swift package completion-tool list-executables) )
+    _describe '' executables
+}
+
+# Generates completions for swift build
+#
+# In the final compdef file, set the following file header:
+#
+#     #compdef _swift_build
+#     local context state state_descr line
+#     typeset -A opt_args
+_swift_build() {
+    arguments=(
+        "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: "
+        "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: "
+        "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: "
+        "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: "
+        "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}"
+        "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files"
+        "(--chdir -C)"{--chdir,-C}"[]: :_files"
+        "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files"
+        "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}"
+        "--disable-prefetching[]"
+        "--skip-update[Skip updating dependencies from their remote during a resolution]"
+        "--disable-sandbox[Disable using the sandbox when executing subprocesses]"
+        "--disable-package-manifest-caching[Disable caching Package.swift manifests]"
+        "--version[]"
+        "--destination[]: :_files"
+        "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]"
+        "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]"
+        "--static-swift-stdlib[Link Swift stdlib statically]"
+        "--force-resolved-versions[]"
+        "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]"
+        "--enable-index-store[Enable indexing-while-building feature]"
+        "--disable-index-store[Disable indexing-while-building feature]"
+        "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]"
+        "--enable-parseable-module-interfaces[]"
+        "--trace-resolver[]"
+        "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: "
+        "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]"
+        "--build-tests[Build both source and test targets]"
+        "--product[Build the specified product]:Build the specified product: "
+        "--target[Build the specified target]:Build the specified target: "
+        "--show-bin-path[Print the binary output path]"
+    )
+    _arguments $arguments && return
+}
+
+# Generates completions for swift run
+#
+# In the final compdef file, set the following file header:
+#
+#     #compdef _swift_run
+#     local context state state_descr line
+#     typeset -A opt_args
+_swift_run() {
+    arguments=(
+        ":The executable to run:_swift_executable"
+        "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: "
+        "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: "
+        "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: "
+        "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: "
+        "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}"
+        "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files"
+        "(--chdir -C)"{--chdir,-C}"[]: :_files"
+        "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files"
+        "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}"
+        "--disable-prefetching[]"
+        "--skip-update[Skip updating dependencies from their remote during a resolution]"
+        "--disable-sandbox[Disable using the sandbox when executing subprocesses]"
+        "--disable-package-manifest-caching[Disable caching Package.swift manifests]"
+        "--version[]"
+        "--destination[]: :_files"
+        "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]"
+        "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]"
+        "--static-swift-stdlib[Link Swift stdlib statically]"
+        "--force-resolved-versions[]"
+        "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]"
+        "--enable-index-store[Enable indexing-while-building feature]"
+        "--disable-index-store[Disable indexing-while-building feature]"
+        "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]"
+        "--enable-parseable-module-interfaces[]"
+        "--trace-resolver[]"
+        "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: "
+        "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]"
+        "--skip-build[Skip building the executable product]"
+        "--build-tests[Build both source and test targets]"
+        "--repl[Launch Swift REPL for the package]"
+    )
+    _arguments $arguments && return
+}
+
+# Generates completions for swift package
+#
+# In the final compdef file, set the following file header:
+#
+#     #compdef _swift_package
+#     local context state state_descr line
+#     typeset -A opt_args
+_swift_package() {
+    arguments=(
+        "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: "
+        "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: "
+        "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: "
+        "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: "
+        "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}"
+        "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files"
+        "(--chdir -C)"{--chdir,-C}"[]: :_files"
+        "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files"
+        "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}"
+        "--disable-prefetching[]"
+        "--skip-update[Skip updating dependencies from their remote during a resolution]"
+        "--disable-sandbox[Disable using the sandbox when executing subprocesses]"
+        "--disable-package-manifest-caching[Disable caching Package.swift manifests]"
+        "--version[]"
+        "--destination[]: :_files"
+        "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]"
+        "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]"
+        "--static-swift-stdlib[Link Swift stdlib statically]"
+        "--force-resolved-versions[]"
+        "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]"
+        "--enable-index-store[Enable indexing-while-building feature]"
+        "--disable-index-store[Disable indexing-while-building feature]"
+        "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]"
+        "--enable-parseable-module-interfaces[]"
+        "--trace-resolver[]"
+        "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: "
+        "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]"
+        '(-): :->command'
+        '(-)*:: :->arg'
+    )
+    _arguments $arguments && return
+    case $state in
+        (command)
+            local modes
+            modes=(
+                'completion-tool:Completion tool (for shell completions)'
+                'dump-package:Print parsed Package.swift as JSON'
+                'describe:Describe the current package'
+                'clean:Delete build artifacts'
+                'show-dependencies:Print the resolved dependency graph'
+                'init:Initialize a new package'
+                'unedit:Remove a package from editable mode'
+                'tools-version:Manipulate tools version of the current package'
+                'fetch:'
+                'resolve:Resolve package dependencies'
+                'reset:Reset the complete cache/build directory'
+                'generate-xcodeproj:Generates an Xcode project'
+                'edit:Put a package in editable mode'
+                'config:Manipulate configuration of the package'
+                'update:Update package dependencies'
+            )
+            _describe "mode" modes
+            ;;
+        (arg)
+            case ${words[1]} in
+                (completion-tool)
+                    _swift_package_completion-tool
+                    ;;
+                (dump-package)
+                    _swift_package_dump-package
+                    ;;
+                (describe)
+                    _swift_package_describe
+                    ;;
+                (clean)
+                    _swift_package_clean
+                    ;;
+                (show-dependencies)
+                    _swift_package_show-dependencies
+                    ;;
+                (init)
+                    _swift_package_init
+                    ;;
+                (unedit)
+                    _swift_package_unedit
+                    ;;
+                (tools-version)
+                    _swift_package_tools-version
+                    ;;
+                (fetch)
+                    _swift_package_fetch
+                    ;;
+                (resolve)
+                    _swift_package_resolve
+                    ;;
+                (reset)
+                    _swift_package_reset
+                    ;;
+                (generate-xcodeproj)
+                    _swift_package_generate-xcodeproj
+                    ;;
+                (edit)
+                    _swift_package_edit
+                    ;;
+                (config)
+                    _swift_package_config
+                    ;;
+                (update)
+                    _swift_package_update
+                    ;;
+            esac
+            ;;
+    esac
+}
+
+_swift_package_completion-tool() {
+    arguments=(
+        ": :{_values '' 'generate-bash-script[generate Bash completion script]' 'generate-zsh-script[generate Bash completion script]' 'list-dependencies[list all dependencies' names]' 'list-executables[list all executables' names]'}"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_dump-package() {
+    arguments=(
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_describe() {
+    arguments=(
+        "--type[json|text]: :{_values '' 'text[describe using text format]' 'json[describe using JSON format]'}"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_clean() {
+    arguments=(
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_show-dependencies() {
+    arguments=(
+        "--format[text|dot|json|flatlist]: :{_values '' 'text[list dependencies using text format]' 'dot[list dependencies using dot format]' 'json[list dependencies using JSON format]'}"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_init() {
+    arguments=(
+        "--type[empty|library|executable|system-module|manifest]: :{_values '' 'empty[generates an empty project]' 'library[generates project for a dynamic library]' 'executable[generates a project for a cli executable]' 'system-module[generates a project for a system module]'}"
+        "--name[Provide custom package name]:Provide custom package name: "
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_unedit() {
+    arguments=(
+        ":The name of the package to unedit:_swift_dependency"
+        "--force[Unedit the package even if it has uncommitted and unpushed changes.]"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_tools-version() {
+    arguments=(
+        "--set[Set tools version of package to the given value]:Set tools version of package to the given value: "
+        "--set-current[Set tools version of package to the current tools version in use]"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_fetch() {
+    arguments=(
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_resolve() {
+    arguments=(
+        ":The name of the package to resolve:_swift_dependency"
+        "--version[The version to resolve at]:The version to resolve at: "
+        "--branch[The branch to resolve at]:The branch to resolve at: "
+        "--revision[The revision to resolve at]:The revision to resolve at: "
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_reset() {
+    arguments=(
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_generate-xcodeproj() {
+    arguments=(
+        "--xcconfig-overrides[Path to xcconfig file]:Path to xcconfig file:_files"
+        "--enable-code-coverage[Enable code coverage in the generated project]"
+        "--output[Path where the Xcode project should be generated]:Path where the Xcode project should be generated:_files"
+        "--legacy-scheme-generator[Use the legacy scheme generator]"
+        "--watch[Watch for changes to the Package manifest to regenerate the Xcode project]"
+        "--skip-extra-files[Do not add file references for extra files to the generated Xcode project]"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_edit() {
+    arguments=(
+        ":The name of the package to edit:_swift_dependency"
+        "--revision[The revision to edit]:The revision to edit: "
+        "--branch[The branch to create]:The branch to create: "
+        "--path[Create or use the checkout at this path]:Create or use the checkout at this path:_files"
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_config() {
+    arguments=(
+        '(-): :->command'
+        '(-)*:: :->arg'
+    )
+    _arguments $arguments && return
+    case $state in
+        (command)
+            local modes
+            modes=(
+                'unset-mirror:Remove an existing mirror'
+                'get-mirror:Print mirror configuration for the given package dependency'
+                'set-mirror:Set a mirror for a dependency'
+            )
+            _describe "mode" modes
+            ;;
+        (arg)
+            case ${words[1]} in
+                (unset-mirror)
+                    _swift_package_config_unset-mirror
+                    ;;
+                (get-mirror)
+                    _swift_package_config_get-mirror
+                    ;;
+                (set-mirror)
+                    _swift_package_config_set-mirror
+                    ;;
+            esac
+            ;;
+    esac
+}
+
+_swift_package_config_unset-mirror() {
+    arguments=(
+        "--package-url[The package dependency url]:The package dependency url: "
+        "--mirror-url[The mirror url]:The mirror url: "
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_config_get-mirror() {
+    arguments=(
+        "--package-url[The package dependency url]:The package dependency url: "
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_config_set-mirror() {
+    arguments=(
+        "--package-url[The package dependency url]:The package dependency url: "
+        "--mirror-url[The mirror url]:The mirror url: "
+    )
+    _arguments $arguments && return
+}
+
+_swift_package_update() {
+    arguments=(
+    )
+    _arguments $arguments && return
+}
+
+# Generates completions for swift test
+#
+# In the final compdef file, set the following file header:
+#
+#     #compdef _swift_test
+#     local context state state_descr line
+#     typeset -A opt_args
+_swift_test() {
+    arguments=(
+        "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: "
+        "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: "
+        "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: "
+        "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: "
+        "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}"
+        "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files"
+        "(--chdir -C)"{--chdir,-C}"[]: :_files"
+        "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files"
+        "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}"
+        "--disable-prefetching[]"
+        "--skip-update[Skip updating dependencies from their remote during a resolution]"
+        "--disable-sandbox[Disable using the sandbox when executing subprocesses]"
+        "--disable-package-manifest-caching[Disable caching Package.swift manifests]"
+        "--version[]"
+        "--destination[]: :_files"
+        "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]"
+        "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]"
+        "--static-swift-stdlib[Link Swift stdlib statically]"
+        "--force-resolved-versions[]"
+        "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]"
+        "--enable-index-store[Enable indexing-while-building feature]"
+        "--disable-index-store[Disable indexing-while-building feature]"
+        "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]"
+        "--enable-parseable-module-interfaces[]"
+        "--trace-resolver[]"
+        "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: "
+        "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]"
+        "--skip-build[Skip building the test target]"
+        "(--list-tests -l)"{--list-tests,-l}"[Lists test methods in specifier format]"
+        "--generate-linuxmain[Generate LinuxMain.swift entries for the package]"
+        "--parallel[Run the tests in parallel.]"
+        "--num-workers[Number of tests to execute in parallel.]:Number of tests to execute in parallel.: "
+        "(--specifier -s)"{--specifier,-s}"[]: : "
+        "--xunit-output[]: :_files"
+        "--filter[Run test cases matching regular expression, Format: <test-target>.<test-case> or <test-target>.<test-case>/<test>]:Run test cases matching regular expression, Format: <test-target>.<test-case> or <test-target>.<test-case>/<test>: "
+        "--enable-code-coverage[Test with code coverage enabled]"
+    )
+    _arguments $arguments && return
+}
+
+_swift_compiler() {
+}
+
+_swift
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/swiftpm.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/swiftpm/swiftpm.plugin.zsh
new file mode 100644 (file)
index 0000000..ef872ea
--- /dev/null
@@ -0,0 +1,8 @@
+# Some aliases to make your life with the Swift Package Manager faster ✌️
+
+alias spi='swift package init'
+alias spf='swift package fetch'
+alias spu='swift package update'
+alias spx='swift package generate-xcodeproj'
+alias sps='swift package show-dependencies'
+alias spd='swift package dump-package'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony/README.md
new file mode 100644 (file)
index 0000000..c58f64f
--- /dev/null
@@ -0,0 +1,9 @@
+# Symfony
+
+This plugin provides completion for [Symfony](https://symfony.com/).
+
+To use it add symfony to the plugins array in your zshrc file.
+
+```bash
+plugins=(... symfony)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony/symfony.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony/symfony.plugin.zsh
new file mode 100644 (file)
index 0000000..f070e9e
--- /dev/null
@@ -0,0 +1,13 @@
+# symfony basic command completion
+
+_symfony_get_command_list () {
+    php symfony | sed "1,/Available tasks/d" | awk 'BEGIN { cat=null; } /^[A-Za-z]+$/ { cat = $1; } /^  :[a-z]+/ { print cat $1; }'
+}
+
+_symfony () {
+  if [ -f symfony ]; then
+    compadd `_symfony_get_command_list`
+  fi
+}
+
+compdef _symfony symfony
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony2/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony2/README.md
new file mode 100644 (file)
index 0000000..7623347
--- /dev/null
@@ -0,0 +1,28 @@
+# Symfony2
+
+This plugin provides completion for [Symfony 2](https://symfony.com/), as well as aliases for frequent Symfony commands.
+
+To use it add symfony2 to the plugins array in your zshrc file.
+
+```bash
+plugins=(... symfony2)
+```
+
+## Aliases
+
+| Alias         | Command                      | Description                   |
+|---------------|------------------------------|-------------------------------|
+| `sf`          | php app/console              | Start the symfony console     |
+| `sfcl`        | sf cache:clear               | Clear the cache               |
+| `sfsr`        | sf server:run                | Run the dev server            |
+| `sfcw`        | sf cache:warmup              | Use the Bundles warmer        |
+| `sfroute`     | sf debug:router              | Show the different routes     |
+| `sfcontainer` | sf debug:container           | List the different services   |
+| `sfgb`        | sf generate:bundle           | Generate a bundle             |
+| `sfgc`        | sf generate:controller       | Generate a controller         |
+| `sfgcom`      | sf generate:command          | Generate a command            |
+| `sfge`        | sf doctrine:generate:entity  | Generate an entity            |
+| `sfsu`        | sf doctrine:schema:update    | Update the schema in Database |
+| `sfdc`        | sf doctrine:database:create  | Create the Database           |
+| `sfdev`       | sf --env=dev                 | Update environment to `dev`   |
+| `sfprod`      | sf --env=prod                | Update environment to `prod`  |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony2/symfony2.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/symfony2/symfony2.plugin.zsh
new file mode 100644 (file)
index 0000000..e23809d
--- /dev/null
@@ -0,0 +1,34 @@
+# Symfony2 basic command completion
+
+_symfony_console () {
+  echo "php $(find . -maxdepth 2 -mindepth 1 -name 'console' -type f | head -n 1)"
+}
+
+_symfony2_get_command_list () {
+   `_symfony_console` --no-ansi --no-debug | sed "1,/Available commands/d" | awk '/^  ?[^ ]+ / { print $1 }'
+}
+
+_symfony2 () {
+   compadd `_symfony2_get_command_list`
+}
+
+compdef _symfony2 '`_symfony_console`'
+compdef _symfony2 'app/console'
+compdef _symfony2 'bin/console'
+compdef _symfony2 sf
+
+#Alias
+alias sf='`_symfony_console`'
+alias sfcl='sf cache:clear'
+alias sfsr='sf server:run -vvv'
+alias sfcw='sf cache:warmup'
+alias sfroute='sf debug:router'
+alias sfcontainer='sf debug:container'
+alias sfgb='sf generate:bundle'
+alias sfgc='sf generate:controller'
+alias sfgcom='sf generate:command'
+alias sfge='sf doctrine:generate:entity'
+alias sfsu='sf doctrine:schema:update'
+alias sfdc='sf doctrine:database:create'
+alias sfdev='sf --env=dev'
+alias sfprod='sf --env=prod'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/systemadmin/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/systemadmin/README.md
new file mode 100644 (file)
index 0000000..3a9d9de
--- /dev/null
@@ -0,0 +1,51 @@
+# Systemadmin plugin
+
+This plugin adds a series of aliases and functions which make a System Administrator's life easier.
+To use it, add `systemadmin` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... systemadmin)
+```
+
+## Aliases
+
+| Alias   | Command                                                                    | Description                                                        |
+|---------|----------------------------------------------------------------------------|--------------------------------------------------------------------|
+| ping    | `ping -c 5`                                                                | Sends only 5 ICMP Messages                                         |
+| clr     | `clear; echo Currently logged in on $TTY, as $USERNAME in directory $PWD.` | Clears the screen and prints the current user, TTY, and directory  |
+| path    | `print -l $path`                                                           | Displays PATH with each entry on a separate line                   |
+| mkdir   | `mkdir -pv`                                                                | Automatically create parent directories and display verbose output |
+| psmem   | `ps -e -orss=,args= \| sort -b -k1 -nr`                                    | Display the processes using the most memory                        |
+| psmem10 | `ps -e -orss=,args= \| sort -b -k1 -nr \| head -n 10`                      | Display the top 10 processes using the most memory                 |
+| pscpu   | `ps -e -o pcpu,cpu,nice,state,cputime,args \|sort -k1 -nr`                 | Display the top processes using the most CPU                       |
+| pscpu10 | `ps -e -o pcpu,cpu,nice,state,cputime,args \|sort -k1 -nr \| head -n 10`   | Display the top 10 processes using the most CPU                    |
+| hist10  | `print -l ${(o)history%% *} \| uniq -c \| sort -nr \| head -n 10`          | Display the top 10 most used commands in the history               |
+
+## Functions
+
+| Function    |  Description                                                                                                          |
+|-------------|-----------------------------------------------------------------------------------------------------------------------|
+| dls         | List only directories in the current directory                                                                        |
+| psgrep      | List all processes that match the pattern input after the command                                                     |
+| killit      | Kills any process that matches a regular expression passed to it                                                      |
+| tree        | List contents of directories in a tree-like format (if tree isn't installed)                                          |
+| sortcons    | Sort connections by state                                                                                             |
+| con80       | View all 80 Port Connections                                                                                          |
+| sortconip   | On the connected IP sorted by the number of connections                                                               |
+| req20       | List the top 20 requests on port 80                                                                                   |
+| http20      | List the top 20 connections to port 80 based on tcpdump data                                                          |
+| timewait20  | List the top 20 time_wait connections                                                                                 |
+| syn20       | List the top 20 SYN connections                                                                                       |
+| port_pro    | Output all processes according to the port number                                                                     |
+| accessip10  | List the top 10 accesses to the ip address in the nginx/access.log file or another log file if specified              |
+| visitpage20 | List the top 20 most visited files or pages in the nginx/access.log file or another log file if specified             |
+| consume100  | List the 100 most time-consuming Page lists (more than 60 seconds) as well as the corresponding number of occurrences |
+| webtraffic  | List website traffic statistics in GB from the nginx/access.log file or another log file if specified                 |
+| c404        | List statistics on 404 connections in the nginx/access.log file or another log file if specified                      |
+| httpstatus  | List statistics based on http status in the nginx/access.log file or another log file if specified                    |
+| d0          | Delete 0 byte files recursively in the current directory or another if specified                                      |
+| geteip      | Gather information regarding an external IP address using [icanhazip.com](https://icanhazip.com)                      |
+| getip       | Determine the local IP Address with `ip addr` or `ifconfig`                                                           |
+| clrz        | Clear zombie processes                                                                                                |
+| conssec     | Show number of concurrent connections per second based on ngnix/access.log file or another log file if specified      |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/systemadmin/systemadmin.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/systemadmin/systemadmin.plugin.zsh
new file mode 100644 (file)
index 0000000..8e5e0af
--- /dev/null
@@ -0,0 +1,155 @@
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+# This is one for the system administrator, operation and maintenance.
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+# * Dongweiming <ciici123@gmail.com>
+#
+# ------------------------------------------------------------------------------
+
+function retlog() {
+    if [[ -z $1 ]];then
+        echo '/var/log/nginx/access.log'
+    else
+        echo $1
+    fi
+}
+
+alias ping='ping -c 5'
+alias clr='clear; echo Currently logged in on $TTY, as $USERNAME in directory $PWD.'
+alias path='print -l $path'
+alias mkdir='mkdir -pv'
+# get top process eating memory
+alias psmem='ps -e -orss=,args= | sort -b -k1 -nr'
+alias psmem10='ps -e -orss=,args= | sort -b -k1 -nr | head -n 10'
+# get top process eating cpu if not work try execute : export LC_ALL='C'
+alias pscpu='ps -e -o pcpu,cpu,nice,state,cputime,args|sort -k1,1n -nr'
+alias pscpu10='ps -e -o pcpu,cpu,nice,state,cputime,args|sort -k1,1n -nr | head -n 10'
+# top10 of the history
+alias hist10='print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
+
+# directory LS
+function dls() {
+    print -l *(/)
+}
+function psgrep() {
+    ps aux | grep "${1:-.}" | grep -v grep
+}
+# Kills any process that matches a regexp passed to it
+function killit() {
+    ps aux | grep -v "grep" | grep "$@" | awk '{print $2}' | xargs sudo kill
+}
+
+# list contents of directories in a tree-like format
+if ! (( $+commands[tree] )); then
+    function tree() {
+        find $@ -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
+    }
+fi
+
+# Sort connection state
+function sortcons() {
+    netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
+}
+
+# View all 80 Port Connections
+function con80() {
+    netstat -nat|grep -i ":80"|wc -l
+}
+
+# On the connected IP sorted by the number of connections
+function sortconip() {
+    netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
+}
+
+# top20 of Find the number of requests on 80 port
+function req20() {
+    netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
+}
+
+# top20 of Using tcpdump port 80 access to view
+function http20() {
+    sudo tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -n 20
+}
+
+# top20 of Find time_wait connection
+function timewait20() {
+    netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20
+}
+
+# top20 of Find SYN connection
+function syn20() {
+    netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr|head -n20
+}
+
+# Printing process according to the port number
+function port_pro() {
+    netstat -ntlp | grep "${1:-.}" | awk '{print $7}' | cut -d/ -f1
+}
+
+# top10 of gain access to the ip address
+function accessip10() {
+    awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}' "$(retlog)"
+}
+
+# top20 of Most Visited file or page
+function visitpage20() {
+    awk '{print $11}' "$(retlog)"|sort|uniq -c|sort -nr|head -n 20
+}
+
+# top100 of Page lists the most time-consuming (more than 60 seconds) as well as the corresponding page number of occurrences
+function consume100() {
+    awk '($NF > 60 && $7~/\.php/){print $7}' "$(retlog)" |sort -n|uniq -c|sort -nr|head -n 100
+    # if django website or other website make by no suffix language
+    # awk '{print $7}' "$(retlog)" |sort -n|uniq -c|sort -nr|head -n 100
+}
+
+# Website traffic statistics (G)
+function webtraffic() {
+    awk "{sum+=$10} END {print sum/1024/1024/1024}" "$(retlog)"
+}
+
+# Statistical connections 404
+function c404() {
+    awk '($9 ~/404/)' "$(retlog)" | awk '{print $9,$7}' | sort
+}
+
+# Statistical http status.
+function httpstatus() {
+    awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}' "$(retlog)"
+}
+
+# Delete 0 byte file
+function d0() {
+    find "${1:-.}" -type f -size 0 -exec rm -rf {} \;
+}
+
+# gather external ip address
+function geteip() {
+    curl -s -S -4 https://icanhazip.com
+    curl -s -S -6 https://icanhazip.com
+}
+
+# determine local IP address(es)
+function getip() {
+    if (( ${+commands[ip]} )); then
+        ip addr | awk '/inet /{print $2}' | command grep -v 127.0.0.1
+    else
+        ifconfig | awk '/inet /{print $2}' | command grep -v 127.0.0.1
+    fi
+}
+
+# Clear zombie processes
+function clrz() {
+    ps -eal | awk '{ if ($2 == "Z") {print $4}}' | kill -9
+}
+
+# Second concurrent
+function conssec() {
+    awk '{if($9~/200|30|404/)COUNT[$4]++}END{for( a in COUNT) print a,COUNT[a]}' "$(retlog)"|sort -k 2 -nr|head -n10
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/systemd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/systemd/README.md
new file mode 100644 (file)
index 0000000..ffa0567
--- /dev/null
@@ -0,0 +1,97 @@
+# Systemd plugin
+
+The systemd plugin provides many useful aliases for systemd.
+
+To use it, add systemd to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... systemd)
+```
+
+## Aliases
+
+| Alias                  | Command                            | Description                                                      |
+|:-----------------------|:-----------------------------------|:-----------------------------------------------------------------|
+| `sc-list-units`        | `systemctl list-units`             | List all units systemd has in memory                             |
+| `sc-is-active`         | `systemctl is-active`              | Show whether a unit is active                                    |
+| `sc-status`            | `systemctl status`                 | Show terse runtime status information about one or more units    |
+| `sc-show`              | `systemctl show`                   | Show properties of units, jobs, or the manager itself            |
+| `sc-help`              | `systemctl help`                   | Show man page of units                                           |
+| `sc-list-unit-files`   | `systemctl list-unit-files`        | List unit files installed on the system                          |
+| `sc-is-enabled`        | `systemctl is-enabled`             | Checks whether any of the specified unit files are enabled       |
+| `sc-list-jobs`         | `systemctl list-jobs`              | List jobs that are in progress                                   |
+| `sc-show-environment`  | `systemctl show-environment`       | Dump the systemd manager environment block                       |
+| `sc-cat`               | `systemctl cat`                    | Show backing files of one or more units                          |
+| `sc-list-timers`       | `systemctl list-timers`            | List timer units currently in memory                             |
+| **Aliases with sudo**                                                                                                        |||
+| `sc-start`             | `sudo systemctl start`             | Start Unit(s)                                                    |
+| `sc-stop`              | `sudo systemctl stop`              | Stop Unit(s)                                                     |
+| `sc-reload`            | `sudo systemctl reload`            | Reload Unit(s)                                                   |
+| `sc-restart`           | `sudo systemctl restart`           | Restart Unit(s)                                                  |
+| `sc-try-restart`       | `sudo systemctl try-restart`       | Restart Unit(s)                                                  |
+| `sc-isolate`           | `sudo systemctl isolate`           | Start a unit and its dependencies and stop all others            |
+| `sc-kill`              | `sudo systemctl kill`              | Kill unit(s)                                                     |
+| `sc-reset-failed`      | `sudo systemctl reset-failed`      | Reset the "failed" state of the specified units,                 |
+| `sc-enable`            | `sudo systemctl enable`            | Enable unit(s)                                                   |
+| `sc-disable`           | `sudo systemctl disable`           | Disable unit(s)                                                  |
+| `sc-reenable`          | `sudo systemctl reenable`          | Reenable unit(s)                                                 |
+| `sc-preset`            | `sudo systemctl preset`            | Reset the enable/disable status one or more unit files           |
+| `sc-mask`              | `sudo systemctl mask`              | Mask unit(s)                                                     |
+| `sc-unmask`            | `sudo systemctl unmask`            | Unmask unit(s)                                                   |
+| `sc-link`              | `sudo systemctl link`              | Link a unit file into the unit file search path                  |
+| `sc-load`              | `sudo systemctl load`              | Load unit(s)                                                     |
+| `sc-cancel`            | `sudo systemctl cancel`            | Cancel job(s)                                                    |
+| `sc-set-environment`   | `sudo systemctl set-environment`   | Set one or more systemd manager environment variables            |
+| `sc-unset-environment` | `sudo systemctl unset-environment` | Unset one or more systemd manager environment variables          |
+| `sc-edit`              | `sudo systemctl edit`              | Edit a drop-in snippet or a whole replacement file with `--full` |
+| `sc-enable-now`        | `sudo systemctl enable --now`      | Enable and start unit(s)                                         |
+| `sc-disable-now`       | `sudo systemctl disable --now`     | Disable and stop unit(s)                                         |
+| `sc-mask-now`          | `sudo systemctl mask --now`        | Mask and stop unit(s)                                            |
+
+### User aliases
+
+You can use the above aliases as `--user` by using the prefix `scu` instead of `sc`.
+For example: `scu-list-units` will be aliased to `systemctl --user list-units`.
+
+### Unit Status Prompt
+
+You can add a token to your prompt in a similar way to the gitfast plugin. To add the token
+to your prompt, drop `$(systemd_prompt_info [unit]...)` into your prompt (more than one unit
+may be specified).
+
+The plugin will add the following to your prompt for each `$unit`.
+
+```text
+<prefix><unit>:<active|notactive><suffix>
+```
+
+You can control these parts with the following variables:
+
+- `<prefix>`: Set `$ZSH_THEME_SYSTEMD_PROMPT_PREFIX`.
+
+- `<suffix>`: Set `$ZSH_THEME_SYSTEMD_PROMPT_SUFFIX`.
+
+- `<unit>`: name passed as parameter to the function. If you want it to be in ALL CAPS,
+  you can set the variable `$ZSH_THEME_SYSTEMD_PROMPT_CAPS` to a non-empty string.
+
+- `<active>`: shown if the systemd unit is active.
+  Set `$ZSH_THEME_SYSTEMD_PROMPT_ACTIVE`.
+
+- `<notactive>`: shown if the systemd unit is *not* active.
+  Set `$ZSH_THEME_SYSTEMD_PROMPT_NOTACTIVE`.
+
+For example, if your prompt contains `PROMPT='$(systemd_prompt_info dhcpd httpd)'` and you set the following variables:
+
+```sh
+ZSH_THEME_SYSTEMD_PROMPT_PREFIX="["
+ZSH_THEME_SYSTEMD_PROMPT_SUFFIX="]"
+ZSH_THEME_SYSTEMD_PROMPT_ACTIVE="+"
+ZSH_THEME_SYSTEMD_PROMPT_NOTACTIVE="X"
+ZSH_THEME_SYSTEMD_PROMPT_CAPS=1
+```
+
+If `dhcpd` is running, and `httpd` is not, then your prompt will look like this:
+
+```text
+[DHCPD: +][HTTPD: X]
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/systemd/systemd.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/systemd/systemd.plugin.zsh
new file mode 100644 (file)
index 0000000..7afd2be
--- /dev/null
@@ -0,0 +1,116 @@
+# systemctl aliases
+user_commands=(
+  cat
+  get-default
+  help
+  is-active
+  is-enabled
+  is-failed
+  is-system-running
+  list-dependencies
+  list-jobs
+  list-sockets
+  list-timers
+  list-unit-files
+  list-units
+  show
+  show-environment
+  status
+)
+
+sudo_commands=(
+  add-requires
+  add-wants
+  cancel
+  daemon-reexec
+  daemon-reload
+  default
+  disable
+  edit
+  emergency
+  enable
+  halt
+  import-environment
+  isolate
+  kexec
+  kill
+  link
+  list-machines
+  load
+  mask
+  preset
+  preset-all
+  reenable
+  reload
+  reload-or-restart
+  reset-failed
+  rescue
+  restart
+  revert
+  set-default
+  set-environment
+  set-property
+  start
+  stop
+  switch-root
+  try-reload-or-restart
+  try-restart
+  unmask
+  unset-environment
+)
+
+power_commands=(
+  hibernate
+  hybrid-sleep
+  poweroff
+  reboot
+  suspend
+)
+
+for c in $user_commands; do
+  alias "sc-$c"="systemctl $c"
+  alias "scu-$c"="systemctl --user $c"
+done
+
+for c in $sudo_commands; do
+  alias "sc-$c"="sudo systemctl $c"
+  alias "scu-$c"="systemctl --user $c"
+done
+
+for c in $power_commands; do
+  alias "sc-$c"="systemctl $c"
+done
+
+unset c user_commands sudo_commands power_commands
+
+
+# --now commands
+alias sc-enable-now="sc-enable --now"
+alias sc-disable-now="sc-disable --now"
+alias sc-mask-now="sc-mask --now"
+
+alias scu-enable-now="scu-enable --now"
+alias scu-disable-now="scu-disable --now"
+alias scu-mask-now="scu-mask --now"
+
+
+function systemd_prompt_info {
+  local unit
+  for unit in "$@"; do
+    echo -n "$ZSH_THEME_SYSTEMD_PROMPT_PREFIX"
+
+    if [[ -n "$ZSH_THEME_SYSTEMD_PROMPT_CAPS" ]]; then
+      echo -n "${(U)unit:gs/%/%%}:"
+    else
+      echo -n "${unit:gs/%/%%}:"
+    fi
+
+    if systemctl is-active "$unit" &>/dev/null; then
+      echo -n "$ZSH_THEME_SYSTEMD_PROMPT_ACTIVE"
+    else
+      echo -n "$ZSH_THEME_SYSTEMD_PROMPT_NOTACTIVE"
+    fi
+
+    echo -n "$ZSH_THEME_SYSTEMD_PROMPT_SUFFIX"
+  done
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/README.md
new file mode 100644 (file)
index 0000000..e77e452
--- /dev/null
@@ -0,0 +1,18 @@
+# taskwarrior
+
+This plugin adds smart tab completion for [TaskWarrior](https://taskwarrior.org/).
+It uses the zsh tab completion script (`_task`) shipped with TaskWarrior for the
+completion definitions.
+
+To use it, add `taskwarrior` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... taskwarrior)
+```
+
+## Examples
+
+Typing `task [TAB]` will give you a list of commands, `task 66[TAB]` shows a
+list of available modifications for that task, etcetera.
+
+The latest version pulled in from the official project is of January 1st, 2015.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/_task b/stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/_task
new file mode 100644 (file)
index 0000000..e0fea17
--- /dev/null
@@ -0,0 +1,285 @@
+#compdef task
+#
+# Copyright 2010 - 2019 Johannes Schlatow
+# Copyright 2009 P.C. Shyamshankar
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# https://www.opensource.org/licenses/mit-license.php
+#
+typeset -g _task_cmds _task_projects _task_tags _task_config _task_modifiers
+_task_projects=(${(f)"$(task _projects)"})
+_task_tags=($(task _tags))
+_task_zshids=( ${(f)"$(task _zshids)"} )
+_task_config=($(task _config))
+_task_columns=($(task _columns))
+_task_modifiers=(
+  'before' \
+  'after' \
+  'none' \
+  'any' \
+  'is' \
+  'isnt' \
+  'has' \
+  'hasnt' \
+  'startswith' \
+  'endswith' \
+  'word' \
+  'noword'
+)
+_task_conjunctions=(
+  'and' \
+  'or' \
+  'xor' \
+  '\)' \
+  '\(' \
+  '<' \
+  '<=' \
+  '=' \
+  '!=' \
+  '>=' \
+  '>'
+)
+_task_cmds=($(task _commands; task _aliases))
+_task_zshcmds=( ${(f)"$(task _zshcommands)"} sentinel:sentinel:sentinel )
+
+_task_aliases=($(task _aliases))
+
+_task() {
+    _arguments -s -S \
+        "*::task default:_task_default"
+    return 0
+}
+
+local -a reply args word
+word=$'[^\0]#\0'
+
+# priorities
+local -a task_priorities
+_regex_words values 'task priorities' \
+  'H:High' \
+  'M:Middle' \
+  'L:Low'
+task_priorities=("$reply[@]")
+
+# projects
+local -a task_projects
+task_projects=(
+  /"$word"/
+  ":values:task projects:compadd -a _task_projects"
+)
+
+local -a _task_dates
+_regex_words values 'task dates' \
+  'tod*ay:Today' \
+  'yes*terday:Yesterday' \
+  'tom*orrow:Tomorrow' \
+  'sow:Start of week' \
+  'soww:Start of work week' \
+  'socw:Start of calendar week' \
+  'som:Start of month' \
+  'soq:Start of quarter' \
+  'soy:Start of year' \
+  'eow:End of week' \
+  'eoww:End of work week' \
+  'eocw:End of calendar week' \
+  'eom:End of month' \
+  'eoq:End of quarter' \
+  'eoy:End of year' \
+  'mon:Monday' \
+  'tue:Tuesday'\
+  'wed:Wednesday' \
+  'thu:Thursday' \
+  'fri:Friday' \
+  'sat:Saturday' \
+  'sun:Sunday' \
+  'good*friday:Good Friday' \
+  'easter:Easter' \
+  'eastermonday:Easter Monday' \
+  'ascension:Ascension' \
+  'pentecost:Pentecost' \
+  'midsommar:Midsommar' \
+  'midsommarafton:Midsommarafton' \
+  'later:Later' \
+  'someday:Some Day'
+_task_dates=("$reply[@]")
+
+local -a _task_reldates
+_regex_words values 'task reldates' \
+  'hrs:n hours' \
+  'day:n days' \
+  '1st:first' \
+  '2nd:second' \
+  '3rd:third' \
+  'th:4th, 5th, etc.' \
+  'wks:weeks'
+_task_reldates=("$reply[@]")
+
+task_dates=(
+  \( "$_task_dates[@]" \|
+    \( /$'[0-9][0-9]#'/- \( "$_task_reldates[@]" \) \)
+  \)
+)
+
+local -a task_zshids
+if (( $#_task_zshids )); then
+  _regex_words values 'task IDs' $_task_zshids
+  task_zshids=("$reply[@]")
+fi
+
+_regex_words values 'task frequencies' \
+  'daily:Every day' \
+  'day:Every day' \
+  'weekdays:Every day skipping weekend days' \
+  'weekly:Every week' \
+  'biweekly:Every two weeks' \
+  'fortnight:Every two weeks' \
+  'monthly:Every month' \
+  'quarterly:Every three months' \
+  'semiannual:Every six months' \
+  'annual:Every year' \
+  'yearly:Every year' \
+  'biannual:Every two years' \
+  'biyearly:Every two years'
+_task_freqs=("$reply[@]")
+
+local -a _task_frequencies
+_regex_words values 'task frequencies' \
+  'd:days' \
+  'w:weeks' \
+  'q:quarters' \
+  'y:years'
+_task_frequencies=("$reply[@]")
+
+task_freqs=(
+  \( "$_task_freqs[@]" \|
+     \( /$'[0-9][0-9]#'/- \( "$_task_frequencies[@]" \) \)
+  \)
+)
+
+# attributes
+local -a task_attributes
+_regex_words -t ':' default 'task attributes' \
+  'des*cription:Task description text' \
+  'status:Status of task - pending, completed, deleted, waiting' \
+  'pro*ject:Project name:$task_projects' \
+  'pri*ority:priority:$task_priorities' \
+  'du*e:Due date:$task_dates' \
+  're*cur:Recurrence frequency:$task_freqs' \
+  'un*til:Expiration date:$task_dates' \
+  'li*mit:Desired number of rows in report' \
+  'wa*it:Date until task becomes pending:$task_dates' \
+  'ent*ry:Date task was created:$task_dates' \
+  'end:Date task was completed/deleted:$task_dates' \
+  'st*art:Date task was started:$task_dates' \
+  'sc*heduled:Date task is scheduled to start:$task_dates' \
+  'dep*ends:Other tasks that this task depends upon:$task_zshids'
+task_attributes=("$reply[@]")
+
+args=(
+  \( "$task_attributes[@]" \|
+  \( /'(project|description|status|entry|end|start|scheduled|depends|due|wait|recur|priority|until|limit).'/- \( /$'[^:]#:'/ ":default:modifiers:compadd -S ':' -a _task_modifiers" \) \) \|
+  \( /'(rc).'/- \( /$'[^:]#:'/ ":arguments:config:compadd -S ':' -a _task_config" \) \) \|
+  \( /'(+|-)'/- \( /"$word"/ ":values:remove tag:compadd -a _task_tags" \) \) \|
+  \( /"$word"/ \)
+  \) \#
+)
+_regex_arguments _task_attributes "${args[@]}"
+
+## task commands
+
+# filter completion
+(( $+functions[_task_filter] )) ||
+_task_filter() {
+  _task_attributes "$@"
+
+  # TODO complete conjunctions only if the previous word is a filter expression, i.e. attribute, ID, any non-command
+  _describe -t default 'task conjunctions' _task_conjunctions
+}
+
+# execute completion
+(( $+functions[_task_execute] )) ||
+_task_execute() {
+  _files
+}
+
+# id-only completion
+(( $+functions[_task_id] )) ||
+_task_id() {
+  _describe -t values 'task IDs' _task_zshids
+}
+
+# subcommand-only function
+(( $+functions[_task_subcommands] )) ||
+_task_subcommands() {
+  local -a subcommands
+  local _zshcmd
+  local cmd category desc
+  local lastcategory=''
+  # The list is sorted by category, in the right order.
+  for _zshcmd in "$_task_zshcmds[@]"; do
+    # Parse out the three fields
+    cmd=${_zshcmd%%:*}
+    category=${${_zshcmd#*:}%%:*}
+    desc=${_zshcmd#*:*:}
+
+    # Present each category as soon as the first entry in the *next* category
+    # is seen.
+    if [[ $category != $lastcategory && -n $lastcategory ]]; then
+      _describe -t ${lastcategory}-commands "task ${lastcategory} command" subcommands
+      subcommands=()
+    fi
+
+    # Log the subcommand; we will process it in some future iteration.
+    subcommands+=( "$cmd:$desc" )
+
+    lastcategory=$category
+  done
+}
+
+## first level completion => task sub-command completion
+(( $+functions[_task_default] )) ||
+_task_default() {
+    local cmd ret=1
+
+  integer i=1
+  while (( i < $#words ))
+  do
+    cmd="${_task_cmds[(r)$words[$i]]}"
+    if (( $#cmd )); then
+      _call_function ret _task_${cmd} ||
+        _call_function ret _task_filter ||
+          _message "No command remaining."
+      return ret
+    fi
+    (( i++ ))
+  done
+
+  # update IDs
+  _task_zshids=( ${(f)"$(task _zshids)"} )
+
+  _task_subcommands
+  _describe -t tasks 'task IDs' _task_zshids
+  _describe -t aliases 'task aliases' _task_aliases
+  _call_function ret _task_filter
+
+  return ret
+}
+
+_task "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/taskwarrior.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/taskwarrior/taskwarrior.plugin.zsh
new file mode 100644 (file)
index 0000000..ab88594
--- /dev/null
@@ -0,0 +1,7 @@
+zstyle ':completion:*:*:task:*' verbose yes
+zstyle ':completion:*:*:task:*:descriptions' format '%U%B%d%b%u'
+
+zstyle ':completion:*:*:task:*' group-name ''
+
+alias t=task
+compdef _task t=task
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/term_tab/README b/stow/oh-my-zsh/.oh-my-zsh/plugins/term_tab/README
new file mode 100644 (file)
index 0000000..316062e
--- /dev/null
@@ -0,0 +1,16 @@
+
+term_tab - 'cwd' for all open zsh sessions
+******************************************
+
+What it does:
+*************
+This plugin allows to complete the 'cwd' of other Zsh sessions. Sounds
+complicated but is rather simple. E.g. if you have three zsh sessions open, in
+each session you are in a different folder, you can hit Ctrl+v in one session
+to show you the current working directory of the other open zsh sessions.
+
+How it works:
+*************
+* It uses 'pidof zsh' to determine all zsh PIDs
+* It reads procfs to get the current working directory of this session
+* Everything is fed into zsh's completion magic
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/term_tab/term_tab.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/term_tab/term_tab.plugin.zsh
new file mode 100644 (file)
index 0000000..1b612df
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 Julian Vetter <death.jester@web.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+function _term_list(){
+  local -a expl
+  local -au dirs
+
+  PREFIX="$IPREFIX$PREFIX"
+  IPREFIX=
+  SUFFIX="$SUFFIX$ISUFFIX"
+  ISUFFIX=
+
+  [[ -o magicequalsubst ]] && compset -P '*='
+
+  case $OSTYPE in
+    solaris*) dirs=( ${(M)${${(f)"$(pgrep -U $UID -x zsh|xargs pwdx)"}:#$$:*}%%/*} ) ;;
+    linux*) dirs=( /proc/${^$(pidof zsh):#$$}/cwd(N:A) ) ;;
+  esac
+  dirs=( ${(D)dirs} )
+
+  compstate[pattern_match]='*'
+  _wanted directories expl 'current directory from other shell' \
+      compadd -Q -M "r:|/=* r:|=*" -f -a dirs
+}
+
+zle -C term_list menu-complete _generic
+bindkey "^v" term_list
+zstyle ':completion:term_list::::' completer _term_list
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/terminitor/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/terminitor/README.md
new file mode 100644 (file)
index 0000000..8c0e021
--- /dev/null
@@ -0,0 +1,9 @@
+# Terminitor plugin
+
+This plugin adds completions for the [Terminitor](https://github.com/achiurizo/terminitor) development workflow setup tool.
+
+To use it, add `terminitor` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... terminitor)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/terminitor/_terminitor b/stow/oh-my-zsh/.oh-my-zsh/plugins/terminitor/_terminitor
new file mode 100644 (file)
index 0000000..3615350
--- /dev/null
@@ -0,0 +1,38 @@
+#compdef terminitor
+#autoload
+
+# terminitor zsh completion
+
+_terminitor_available_scripts() {
+  scripts=(`for SCRIPT in ~/.config/terminitor/*.term ; do basename $SCRIPT .term ; done`)
+}
+
+local -a _1st_arguments
+_1st_arguments=(
+    'create:create a Termfile in directory'
+    'delete:delete terminitor script'
+    'edit:open terminitor script'
+    'fetch:clone the designated repo and run setup'
+    'help:Describe available tasks or one specific task'
+    'init:create initial root terminitor folder'
+    'list:lists all terminitor scripts'
+    'setup:execute setup in the terminitor script'
+    'start:runs the terminitor script'
+    'update:update Terminitor to new global path(.config/.terminitor)'
+)
+
+local expl
+
+_arguments \
+  '*:: :->subcmds' && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "terminitor task" _1st_arguments
+  return
+fi
+
+case "$words[1]" in
+  start|edit|delete|setup)
+    _terminitor_available_scripts
+    _wanted scripts expl 'installed scripts' compadd -a scripts ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/README.md
new file mode 100644 (file)
index 0000000..59c6e7f
--- /dev/null
@@ -0,0 +1,43 @@
+# Terraform plugin
+
+Plugin for Terraform, a tool from Hashicorp for managing infrastructure safely and efficiently.
+It adds completion for `terraform`, as well as aliases and a prompt function.
+
+To use it, add `terraform` to the plugins array of your `~/.zshrc` file:
+
+```shell
+plugins=(... terraform)
+```
+
+## Requirements
+
+* [Terraform](https://terraform.io/)
+
+## Aliases
+
+| Alias | Command              |
+| ----- | -------------------- |
+| `tf`  | `terraform`          |
+| `tfa` | `terraform apply`    |
+| `tfd` | `terraform destroy`  |
+| `tff` | `terraform fmt`      |
+| `tfi` | `terraform init`     |
+| `tfo` | `terraform output`   |
+| `tfp` | `terraform plan`     |
+| `tfv` | `terraform validate` |
+
+## Prompt function
+
+You can add the current Terraform workspace in your prompt by adding `$(tf_prompt_info)`
+to your `PROMPT` or `RPROMPT` variable.
+
+```sh
+RPROMPT='$(tf_prompt_info)'
+```
+
+You can also specify the PREFIX and SUFFIX for the workspace with the following variables:
+
+```sh
+ZSH_THEME_TF_PROMPT_PREFIX="%{$fg[white]%}"
+ZSH_THEME_TF_PROMPT_SUFFIX="%{$reset_color%}"
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/_terraform b/stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/_terraform
new file mode 100644 (file)
index 0000000..6258345
--- /dev/null
@@ -0,0 +1,411 @@
+#compdef terraform
+
+local -a _terraform_cmds opt_args
+_terraform_cmds=(
+    'apply:Builds or changes infrastructure'
+    'console:Interactive console for Terraform interpolations'
+    'destroy:Destroy Terraform-managed infrastructure'
+    'fmt:Rewrites config files to canonical format'
+    'force-unlock:Manually unlock the terraform state'
+    'get:Download and install modules for the configuration'
+    'graph:Create a visual graph of Terraform resources'
+    'import:Import existing infrastructure into Terraform'
+    'init:Initialize a Terraform working directory'
+    'login:Obtain and save credentials for a remote host'
+    'logout:Remove locally-stored credentials for a remote host'
+    'output:Read an output from a state file'
+    'plan:Generate and show an execution plan'
+    'providers:Prints a tree of the providers used in the configuration'
+    'refresh:Update local state file against real resources'
+    'show:Inspect Terraform state or plan'
+    'state:Advanced state management'
+    'taint:Manually mark a resource for recreation'
+    'untaint:Manually unmark a resource as tainted'
+    'validate:Validates the Terraform files'
+    'version:Prints the Terraform version'
+    'workspace:Workspace management'
+    '0.12upgrade:Rewrites pre-0.12 module source code for v0.12'
+    '0.13upgrade:Rewrites pre-0.13 module source code for v0.13'
+)
+
+__012upgrade() {
+  _arguments \
+    '-yes[Skip the initial introduction messages and interactive confirmation. This can be used to run this command in batch from a script.]' \
+    '-force[ Override the heuristic that attempts to detect if a configuration is already written for v0.12 or later.  Some of the transformations made by this command are not idempotent, so re-running against the same module may change the meanings expressions in the module.]'
+}
+
+__013upgrade() {
+  _arguments \
+    '-yes[Skip the initial introduction messages and interactive confirmation. This can be used to run this command in batch from a script.]'
+}
+
+__apply() {
+    _arguments \
+        '-auto-approve[Skip interactive approval of plan before applying.]' \
+        '-backup=[(path) Path to backup the existing state file before modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup.]:backupfile:_files -g "*.backup"' \
+        '-compact-warnings[If Terraform produces any warnings that are not accompanied by errors, show them in a more compact form that includes only the summary messages.]' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-input=[(true) Ask for input for variables if not directly set.]' \
+        '-no-color[If specified, output will be colorless.]' \
+        '-parallelism=[(10) Limit the number of parallel resource operations.]' \
+        '-refresh=[(true) Update state prior to checking for differences. This has no effect if a plan file is given to apply.]' \
+        '-state=[(terraform.tfstate) Path to read and save state (unless state-out is specified).]:statefile:_files -g "*.tfstate"' \
+        '-state-out=[(path) Path to write state to that is different than "-state". This can be used to preserve the old state.]:statefile:_files -g "*.tfstate"' \
+        '*-target=[(resource) Resource to target. Operation will be limited to this resource and its dependencies. This flag can be used multiple times.]:target:__statelist' \
+        '*-var[("foo=bar") Set a variable in the Terraform configuration. This flag can be set multiple times.]' \
+        '*-var-file=[(foo) Set variables in the Terraform configuration from a file. If "terraform.tfvars" or any ".auto.tfvars" files are present, they will be automatically loaded.]:file:_files -g "*.tfvars{,.json}"'
+}
+
+__console() {
+    _arguments \
+        '-state=[(terraform.tfstate) Path to read state.]' \
+        '*-var[("foo=bar") Set a variable in the Terraform configuration. This flag can be set multiple times.]' \
+        '*-var-file=[(foo) Set variables in the Terraform configuration from a file. If "terraform.tfvars" or any ".auto.tfvars" files are present, they will be automatically loaded.]:file:_files -g "*.tfvars{,.json}"'
+}
+
+__destroy() {
+    _arguments \
+        '-backup=[(path) Path to backup the existing state file before modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup.]:backupfile:_files -g "*.backup"' \
+        '-auto-approve[Skip interactive approval before destroying.]' \
+        '-force[Deprecated: same as auto-approve.]' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-no-color[If specified, output will contain no color.]' \
+        '-parallelism=[(10) Limit the number of concurrent operations.]' \
+        '-refresh=[(true) Update state prior to checking for differences. This has no effect if a plan file is given to apply.]' \
+        '-state=[(terraform.tfstate) Path to read and save state (unless state-out is specified).]:statefile:_files -g "*.tfstate"' \
+        '-state-out=[(path) Path to write state to that is different than "-state". This can be used to preserve the old state.]:statefile:_files -g "*.tfstate"' \
+        '*-target=[(resource) Resource to target. Operation will be limited to this resource and its dependencies. This flag can be used multiple times.]:target:__statelist' \
+        '*-var[("foo=bar") Set a variable in the Terraform configuration. This flag can be set multiple times.]' \
+        '*-var-file=[(foo) Set variables in the Terraform configuration from a file. If "terraform.tfvars" or any ".auto.tfvars" files are present, they will be automatically loaded.]:file:_files -g "*.tfvars{,.json}"'
+}
+
+__fmt() {
+    _arguments \
+        '-list=[(true) List files whose formatting differs (always false if using STDIN)]' \
+        '-write=[(true) Write result to source file instead of STDOUT (always false if using STDIN or -check)]' \
+        '-diff=[(false) Display diffs of formatting changes]' \
+        '-check=[(false) Check if the input is formatted. Exit status will be 0 if all input is properly formatted and non-zero otherwise.]' \
+        '-recursive=[(false) Also process files in subdirectories. By default, only the given directory (or current directory) is processed.]'
+}
+
+__force_unlock() {
+    _arguments \
+        "-force[Don't ask for input for unlock confirmation.]"
+}
+
+__get() {
+    _arguments \
+        '-update=[(false) If true, modules already downloaded will be checked for updates and updated if necessary.]' \
+        '-no-color[Disable text coloring in the output.]'
+}
+
+__graph() {
+    _arguments \
+        '-draw-cycles[Highlight any cycles in the graph with colored edges. This helps when diagnosing cycle errors.]' \
+        '-type=[(plan) Type of graph to output. Can be: plan, plan-destroy, apply, validate, input, refresh.]'
+}
+
+__import() {
+    _arguments \
+        '-backup=[(path) Path to backup the existing state file before modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup.]:backupfile:_files -g "*.backup"' \
+        '-config=[(path) Path to a directory of Terraform configuration files to use to configure the provider. Defaults to pwd. If no config files are present, they must be provided via the input prompts or env vars.]' \
+        '-allow-missing-config[Allow import when no resource configuration block exists.]' \
+        '-input=[(true) Ask for input for variables if not directly set.]' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-no-color[If specified, output will contain no color.]' \
+        '-state=[(PATH) Path to the source state file. Defaults to the configured backend, or "terraform.tfstate"]:statefile:_files -g "*.tfstate"' \
+        '-state-out=[(PATH) Path to the destination state file to write to. If this is not specified, the source state file will be used. This can be a new or existing path.]:statefile:_files -g "*.tfstate"' \
+        '*-var[("foo=bar") Set a variable in the Terraform configuration. This flag can be set multiple times. This is only useful with the "-config" flag.]' \
+        '*-var-file=[(foo) Set variables in the Terraform configuration from a file. If "terraform.tfvars" or any ".auto.tfvars" files are present, they will be automatically loaded.]:file:_files -g "*.tfvars{,.json}"'
+}
+
+__init() {
+    _arguments \
+        '-backend=[(true) Configure the backend for this configuration.]' \
+        '-backend-config=[This can be either a path to an HCL file with key/value assignments (same format as terraform.tfvars) or a 'key=value' format. This is merged with what is in the configuration file. This can be specified multiple times. The backend type must be in the configuration itself.]' \
+        '-force-copy[Suppress prompts about copying state data. This is equivalent to providing a "yes" to all confirmation prompts.]' \
+        '-from-module=[(SOURCE) Copy the contents of the given module into the target directory before initialization.]' \
+        '-get=[(true) Download any modules for this configuration.]' \
+        '-get-plugins=[(true) Download any missing plugins for this configuration.]' \
+        '-input=[(true) Ask for input if necessary. If false, will error if input was required.]' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-no-color[If specified, output will contain no color.]' \
+        '-plugin-dir[Directory containing plugin binaries. This overrides all default search paths for plugins, and prevents the automatic installation of plugins. This flag can be used multiple times.]:plugin_dir:_files -/' \
+        '-reconfigure[Reconfigure the backend, ignoring any saved configuration.]' \
+        '-upgrade=[(false) If installing modules (-get) or plugins (-get-plugins), ignore previously-downloaded objects and install the latest version allowed within configured constraints.]' \
+        '-verify-plugins=[(true) Verify the authenticity and integrity of automatically downloaded plugins.]'
+}
+
+__login() {
+    _arguments \
+
+}
+
+__logout() {
+    _arguments \
+
+}
+
+__output() {
+    _arguments \
+        '-state=[(path) Path to the state file to read. Defaults to "terraform.tfstate".]:statefile:_files -g "*.tfstate"' \
+        '-no-color[If specified, output will contain no color.]' \
+        '-json[If specified, machine readable output will be printed in JSON format]'
+}
+
+__plan() {
+    _arguments \
+        '-compact-warnings[If Terraform produces any warnings that are not accompanied by errors, show them in a more compact form that includes only the summary messages.]' \
+        '-destroy[If set, a plan will be generated to destroy all resources managed by the given configuration and state.]' \
+        '-detailed-exitcode[() Return detailed exit codes when the command exits. This will change the meaning of exit codes to: 0 - Succeeded, diff is empty (no changes); 1 - Errored, 2 - Succeeded; there is a diff]' \
+        '-input=[(true) Ask for input for variables if not directly set.]' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-no-color[() If specified, output will contain no color.]' \
+        '-out=[(path) Write a plan file to the given path. This can be used as input to the "apply" command.]' \
+        '-parallelism=[(10) Limit the number of concurrent operations.]' \
+        '-refresh=[(true) Update state prior to checking for differences.]' \
+        '-state=[(statefile) Path to a Terraform state file to use to look up Terraform-managed resources. By default it will use the state "terraform.tfstate" if it exists.]:statefile:_files -g "*.tfstate"' \
+        '*-target=[(resource) Resource to target. Operation will be limited to this resource and its dependencies. This flag can be used multiple times.]:target:__statelist' \
+        '*-var[("foo=bar") Set a variable in the Terraform configuration. This flag can be set multiple times.]' \
+        '*-var-file=[(foo) Set variables in the Terraform configuration from a file. If "terraform.tfvars" or any ".auto.tfvars" files are present, they will be automatically loaded.]:file:_files -g "*.tfvars{,.json}"'
+}
+
+__providers() {
+    local -a __providers_cmds
+    __providers_cmds=(
+      'mirror:Mirrors the provider plugins needed for the current configuration'
+      'schema:Prints the schemas of the providers used in the configuration'
+    )
+    _describe -t providers "providers commands" __providers_cmds
+
+}
+
+__providers_mirror() {
+    _arguments \
+      '-platform=[(os_arch) Choose which target platform to build a mirror for.]' \
+      "*:target_dir:_files -/"
+}
+
+__providers_schema() {
+    _arguments \
+      '-json[]' \
+      '::'
+}
+
+__refresh() {
+    _arguments \
+        '-backup=[(path) Path to backup the existing state file before modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup.]::backupfile:_files -g "*.backup"' \
+        '-compact-warnings[If Terraform produces any warnings that are not accompanied by errors, show them in a more compact form that includes only the summary messages.]' \
+        '-input=[(true) Ask for input for variables if not directly set.]' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-no-color[If specified, output will not contain any color.]' \
+        '-state=[(path) Path to read and save state (unless state-out is specified). Defaults to "terraform.tfstate".]:statefile:_files -g "*.tfstate"' \
+        '-state-out=[(path) Path to write state to that is different than "-state". This can be used to preserve the old state.]:statefile:_files -g "*.tfstate"' \
+        '*-target=[(resource) A Resource Address to target. Operation will be limited to this resource and its dependencies. This flag can be used multiple times.]:target:__statelist' \
+        '*-var[("foo=bar") Set a variable in the Terraform configuration. This flag can be set multiple times.]' \
+        '*-var-file=[(foo) Set variables in the Terraform configuration from a file. If "terraform.tfvars" or any ".auto.tfvars" files are present, they will be automatically loaded.]:file:_files -g "*.tfvars{,.json}"'
+}
+
+__show() {
+    _arguments \
+        '-json[If specified, output the Terraform plan or state in a machine-readable form.]' \
+        '-no-color[If specified, output will not contain any color.]'
+}
+
+__state() {
+    local -a __state_cmds
+    __state_cmds=(
+      'list:List resources in the state'
+      'mv:Move an item in the state'
+      'pull:Pull current state and output to stdout'
+      'push:Update remote state from a local state file'
+      'replace-provider:Replace provider for resources in the Terraform state'
+      'rm:Remove instances from the state' 
+      'show:Show a resource in the state'
+    )
+    _describe -t state "state commands" __state_cmds
+}
+
+__state_list() {
+  _arguments \
+    '-state=[(statefile) Path to a Terraform state file to use to look up Terraform-managed resources. By default, Terraform will consult the state of the currently-selected workspace.]' \
+    '-id=[(id) Filters the results to include only instances whose resource types have an attribute named id whose value equals the given id string.]' \
+    "*:address:__statelist" 
+}
+
+__state_mv() {
+  _arguments \
+    "-dry-run[If set, prints out what would've been moved but doesn't actually move anything.]" \
+    '-backup=[(PATH) Path where Terraform should write the backup for the original state. This can"t be disabled. If not set, Terraform will write it to the same path as the statefile with a ".backup" extension.]:backupfile:_files -g "*.backup"' \
+    '-backup-out=[(PATH) Path where Terraform should write the backup for the destination state. This can"t be disabled. If not set, Terraform will write it to the same path as the destination state file with a backup extension. This only needs to be specified if -state-out is set to a different path than -state.]:backupfile:_files -g "*.backup"' \
+    "-lock=[(true) Lock the state files when locking is supported.]:lock:(true false)" \
+    "-lock-timeout=[(0s) Duration to retry a state lock.]" \
+    '-state=[(path) Path to the source state file. Defaults to the configured backend, or "terraform.tfstate"]:statefile:_files -g "*.tfstate"' \
+    '-state-out=[(path) Path to the destination state file to write to. If this isn"t specified, the source state file will be used. This can be a new or existing path.]:statefile:_files -g "*.tfstate"' \
+    "::" \
+    ":source:__statelist" \
+    ":destination: " 
+}
+
+__state_push() {
+  _arguments \
+    "-force[Write the state even if lineages don't match or the remote serial is higher.]" \
+    '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+    "-lock-timeout=[(0s) Duration to retry a state lock.]" \
+    "::" \
+    ":destination:_files"
+}
+
+__state_replace_provider() {
+  _arguments \
+    '-auto-approve[Skip interactive approval.]' \
+    '-backup=[(PATH) Path where Terraform should write the backup for the state file. This can"t be disabled. If not set, Terraform will write it to the same path as the state file with a ".backup" extension.]:backupfile:_files -g "*.backup"' \
+    "-lock=[(true) Lock the state files when locking is supported.]:lock:(true false)" \
+    "-lock-timeout=[(0s) Duration to retry a state lock.]" \
+    '-state=[(PATH) Path to the source state file. Defaults to the configured backend, or "terraform.tfstate"]:statefile:_files -g "*.tfstate"' \
+    ":from_provider_fqn:" \
+    ":to_provider_fqn:"
+}
+
+__state_rm() {
+  _arguments \
+    "-dry-run[If set, prints out what would've been removed but doesn't actually remove anything.]" \
+    '-backup=[(PATH) Path where Terraform should write the backup for the original state.]::backupfile:_files -g "*.backup"' \
+    "-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)" \
+    "-lock-timeout=[(0s) Duration to retry a state lock.]" \
+    '-state=[(PATH) Path to the state file to update. Defaults to the current workspace state.]:statefile:_files -g "*.tfstate"' \
+    "*:address:__statelist" 
+}
+
+
+__state_show() {
+  _arguments \
+    '-state=[(statefile) Path to a Terraform state file to use to look up Terraform-managed resources. By default it will use the state "terraform.tfstate" if it exists.]:statefile:_files -g "*.tfstate"' \
+    "*:address:__statelist" 
+}
+
+__statelist() {
+  compadd $(terraform state list $opt_args[-state])
+}
+
+__taint() {
+    _arguments \
+        '-allow-missing[If specified, the command will succeed (exit code 0) even if the resource is missing.]' \
+        '-backup=[(path) Path to backup the existing state file before modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup.]:backupfile:_files -g "*.backup"' \
+        '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+        '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+        '-module=[(path)  The module path where the resource lives. By default this will be root. Child modules can be specified by names. Ex. "consul" or "consul.vpc" (nested modules).]' \
+        '-state=[(path) Path to read and save state (unless state-out is  specified). Defaults to "terraform.tfstate".]:statefile:_files -g "*.tfstate"' \
+        '-state-out=[(path) Path to write updated state file. By default, the "-state" path will be used.]:statefile:_files -g "*.tfstate"' \
+        "*:address:__statelist" 
+}
+
+__untaint() {
+    _arguments \
+    '-allow-missing[If specified, the command will succeed (exit code 0) even if the resource is missing.]' \
+    '-backup=[(path) Path to backup the existing state file before modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup.]:backupfile:_files -g "*.backup"' \
+    '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \
+    '-lock-timeout=[(0s) Duration to retry a state lock.]' \
+    '-module=[(path)  The module path where the resource lives. By default this will be root. Child modules can be specified by names. Ex. "consul" or "consul.vpc" (nested modules).]' \
+    '-state=[(path) Path to read and save state (unless state-out is  specified). Defaults to "terraform.tfstate".]:statefile:_files -g "*.tfstate"' \
+    '-state-out=[(path) Path to write updated state file. By default, the "-state" path will be used.]:statefile:_files -g "*.tfstate"'
+}
+
+__validate() {
+    _arguments \
+    '-no-color[If specified, output will not contain any color.]' \
+    '-json[Produce output in a machine-readable JSON format, suitable for use in text editor integrations and other automated systems.]' \
+    ':dir:_files -/'
+}
+
+__version() {
+    _arguments \
+    '-json[Output the version information as a JSON object.]'
+}
+
+__workspace() {
+    local -a __workspace_cmds
+    __workspace_cmds=(
+        'delete:Delete a workspace'
+        'list:List Workspaces'
+        'new:Create a new workspace'
+        'select:Select a workspace'
+        'show:Show the name of the current workspace'
+    )
+    _describe -t workspace "workspace commands" __workspace_cmds
+}
+
+_arguments '*:: :->command'
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "terraform command" _terraform_cmds
+  return
+fi
+
+local -a _command_args
+case "$words[1]" in
+  0.12upgrade)
+    __012upgrade ;;
+  0.13upgrade)
+    __013upgrade ;;
+  apply)
+    __apply ;;
+  console)
+    __console;;
+  destroy)
+    __destroy ;;
+  fmt)
+    __fmt;;
+  force-unlock)
+    __force_unlock;;
+  get)
+    __get ;;
+  graph)
+    __graph ;;
+  import)
+    __import;;
+  init)
+    __init ;;
+  login)
+    __login ;;
+  logout)
+    __logout ;;
+  output)
+    __output ;;
+  plan)
+    __plan ;;
+  providers)
+    test $CURRENT -lt 3 && __providers
+    [[ $words[2] = "mirror" ]] && __providers_mirror
+    [[ $words[2] = "schema" ]] && __providers_schema
+    ;;
+  refresh)
+    __refresh ;;
+  show)
+    __show ;;
+  state)
+    test $CURRENT -lt 3 && __state
+    [[ $words[2] = "list" ]] && __state_list
+    [[ $words[2] = "mv" ]] && __state_mv
+    [[ $words[2] = "push" ]] && __state_push
+    [[ $words[2] = "replace-provider" ]] && __state_replace_provider
+    [[ $words[2] = "rm" ]] && __state_rm
+    [[ $words[2] = "show" ]] && __state_show
+    ;;
+  taint)
+    __taint ;;
+  untaint)
+    __untaint ;;
+  validate)
+    __validate ;;
+  version)
+    __version ;;
+  workspace)
+    test $CURRENT -lt 3 && __workspace ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/terraform.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/terraform/terraform.plugin.zsh
new file mode 100644 (file)
index 0000000..d9e39e6
--- /dev/null
@@ -0,0 +1,18 @@
+function tf_prompt_info() {
+  # dont show 'default' workspace in home dir
+  [[ "$PWD" != ~ ]] || return
+  # check if in terraform dir and file exists
+  [[ -d .terraform && -r .terraform/environment ]] || return
+
+  local workspace="$(< .terraform/environment)"
+  echo "${ZSH_THEME_TF_PROMPT_PREFIX-[}${workspace:gs/%/%%}${ZSH_THEME_TF_PROMPT_SUFFIX-]}"
+}
+
+alias tf='terraform'
+alias tfa='terraform apply'
+alias tfd='terraform destroy'
+alias tff='terraform fmt'
+alias tfi='terraform init'
+alias tfo='terraform output'
+alias tfp='terraform plan'
+alias tfv='terraform validate'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/textastic/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/textastic/README.md
new file mode 100644 (file)
index 0000000..3f3bcea
--- /dev/null
@@ -0,0 +1,15 @@
+## textastic
+
+Plugin for Textastic, a text and code editor for Mac OS X
+
+### Requirements
+
+ * [Textastic](https://www.textasticapp.com/mac.html)
+
+### Usage
+
+ * If `tt` command is called without an argument, launch Textastic
+
+ * If `tt` is passed a directory, cd to it and open it in Textastic
+
+ * If `tt` is passed a file, open it in Textastic
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/textastic/textastic.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/textastic/textastic.plugin.zsh
new file mode 100644 (file)
index 0000000..f5901ea
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# If the tt command is called without an argument, launch Textastic
+# If tt is passed a directory, cd to it and open it in Textastic
+# If tt is passed a file, open it in Textastic
+#
+function tt() {
+    if [[ -z "$1" ]]
+    then
+        open -a "textastic.app"
+    else
+        open -a "textastic.app" "$1"
+        if [[ -d "$1" ]]
+        then
+            cd "$1"
+        fi
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/textmate/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/textmate/README.md
new file mode 100644 (file)
index 0000000..e6c1943
--- /dev/null
@@ -0,0 +1,17 @@
+# TextMate plugin
+
+The plugin adds a function for the [TextMate](https://macromates.com) editor.
+
+To use it, add `textmate` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... textmate)
+```
+
+## Function
+
+The `tm` function provides the following options:
+
+- No arguments: Run `mate` in the current directory.
+- Argument that is a directory: Run `mate` in the given directory and cd to it.
+- Other arguments: Pass all arguments to `mate`. This allows for easy opening of multiple files.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/textmate/textmate.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/textmate/textmate.plugin.zsh
new file mode 100644 (file)
index 0000000..1745110
--- /dev/null
@@ -0,0 +1,14 @@
+# If the tm command is called without an argument, open TextMate in the current directory
+# If tm is passed a directory, cd to it and open it in TextMate
+# If tm is passed anything else (i.e., a list of files and/or options), pass them all along
+#    This allows easy opening of multiple files.
+function tm() {
+       if [[ -z $1 ]]; then
+               mate .
+       elif [[ -d $1 ]]; then
+               mate $1
+               cd $1
+       else
+               mate "$@"
+       fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/thefuck/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/thefuck/README.md
new file mode 100644 (file)
index 0000000..84f7255
--- /dev/null
@@ -0,0 +1,13 @@
+# The Fuck
+
+[The Fuck](https://github.com/nvbn/thefuck) plugin — magnificent app which corrects your previous console command.
+
+To use it, add thefuck to the plugins array of your zshrc file:
+
+plugins=(... thefuck)
+
+## Usage
+Press `ESC` twice to correct previous console command.
+
+## Notes
+`Esc`-`Esc` key binding conflicts with [sudo](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/sudo) plugin.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/thefuck/thefuck.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/thefuck/thefuck.plugin.zsh
new file mode 100644 (file)
index 0000000..2ab4eb6
--- /dev/null
@@ -0,0 +1,21 @@
+if [[ -z $commands[thefuck] ]]; then
+    echo 'thefuck is not installed, you should "pip install thefuck" or "brew install thefuck" first.'
+    echo 'See https://github.com/nvbn/thefuck#installation'
+    return 1
+fi
+
+# Register alias
+[[ ! -a $ZSH_CACHE_DIR/thefuck ]] && thefuck --alias > $ZSH_CACHE_DIR/thefuck
+source $ZSH_CACHE_DIR/thefuck
+
+fuck-command-line() {
+    local FUCK="$(THEFUCK_REQUIRE_CONFIRMATION=0 thefuck $(fc -ln -1 | tail -n 1) 2> /dev/null)"
+    [[ -z $FUCK ]] && echo -n -e "\a" && return
+    BUFFER=$FUCK
+    zle end-of-line
+}
+zle -N fuck-command-line
+# Defined shortcut keys: [Esc] [Esc]
+bindkey -M emacs '\e\e' fuck-command-line
+bindkey -M vicmd '\e\e' fuck-command-line
+bindkey -M viins '\e\e' fuck-command-line
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/themes/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/themes/README.md
new file mode 100644 (file)
index 0000000..408e357
--- /dev/null
@@ -0,0 +1,18 @@
+# Themes Plugin
+
+This plugin allows you to change ZSH theme on the go.
+
+To use it, add `themes` to the plugins array in your zshrc file:
+
+```
+plugins=(... themes)
+```
+
+## Usage
+
+`theme <theme_name>` - Changes the ZSH theme to specified theme.
+
+`theme ` - Changes the ZSH theme to some random theme.
+
+`lstheme ` - Lists installed ZSH themes.
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/themes/themes.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/themes/themes.plugin.zsh
new file mode 100644 (file)
index 0000000..6508562
--- /dev/null
@@ -0,0 +1,35 @@
+function theme {
+    : ${1:=random} # Use random theme if none provided
+
+    if [[ -f "$ZSH_CUSTOM/$1.zsh-theme" ]]; then
+        source "$ZSH_CUSTOM/$1.zsh-theme"
+    elif [[ -f "$ZSH_CUSTOM/themes/$1.zsh-theme" ]]; then
+        source "$ZSH_CUSTOM/themes/$1.zsh-theme"
+    elif [[ -f "$ZSH/themes/$1.zsh-theme" ]]; then
+        source "$ZSH/themes/$1.zsh-theme"
+    else
+        echo "$0: Theme '$1' not found"
+        return 1
+    fi
+}
+
+function _theme {
+    _arguments "1: :($(lstheme))"
+}
+
+compdef _theme theme
+
+function lstheme {
+    # Resources:
+    # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Modifiers
+    # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers
+    {
+        # Show themes inside $ZSH_CUSTOM (in any subfolder)
+        # Strip $ZSH_CUSTOM/themes/ and $ZSH_CUSTOM/ from the name, so that it matches
+        # the value that should be written in $ZSH_THEME to load the theme.
+        print -l "$ZSH_CUSTOM"/**/*.zsh-theme(.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::)
+
+        # Show themes inside $ZSH, stripping the head of the path.
+        print -l "$ZSH"/themes/*.zsh-theme(.N:t:r)
+    } | sort -u | fmt -w $COLUMNS
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/thor/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/thor/README.md
new file mode 100644 (file)
index 0000000..09c705d
--- /dev/null
@@ -0,0 +1,10 @@
+# Thor plugin
+
+This plugin adds completion for [Thor](http://whatisthor.com/), 
+a ruby toolkit for building powerful command-line interfaces.
+
+To use it, add `thor` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... thor)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/thor/_thor b/stow/oh-my-zsh/.oh-my-zsh/plugins/thor/_thor
new file mode 100644 (file)
index 0000000..9f7ed5a
--- /dev/null
@@ -0,0 +1,4 @@
+#compdef thor
+#autoload
+
+compadd `thor list | grep thor | cut -d " " -f 2`
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tig/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/tig/README.md
new file mode 100644 (file)
index 0000000..3323fd0
--- /dev/null
@@ -0,0 +1,16 @@
+# `tig` plugin
+
+This plugin adds some aliases for people who work with [`tig`](https://jonas.github.io/tig/) (text-mode interface for Git) in
+a regular basis. To use it, add `tig` to your plugins array:
+
+```zsh
+plugins=(... tig)
+```
+
+## Features
+
+| Alias | Command        | Description                                     |
+|-------|----------------|-------------------------------------------------|
+| `tis` | `tig status`   | Show git status                                 |
+| `til` | `tig log`      | Show git log                                    |
+| `tib` | `tig blame -C` | `git-blame` a file detecting copies and renames |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tig/tig.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/tig/tig.plugin.zsh
new file mode 100644 (file)
index 0000000..7e0c530
--- /dev/null
@@ -0,0 +1,3 @@
+alias tis='tig status'
+alias til='tig log'
+alias tib='tig blame -C'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/timer/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/timer/README.md
new file mode 100644 (file)
index 0000000..30b0bd0
--- /dev/null
@@ -0,0 +1,18 @@
+This plugin allows to display command's execution time in a very nonintrusive way.
+
+Timer can be tuned by these two variables:
+* `TIMER_PRECISION` allows to control number of decimal places (default `1`)
+* `TIMER_FORMAT` allows to adjust display format (default `'/%d'`)
+* `TIMER_THRESHOLD` allows to set the minimum execution time that causes the timer to be shown (default `0`)
+
+Sample session:
+
+    me@here:~$ sleep 1                                         /1.0s
+    me@here:~$ sleep 73                                     /1m13.0s
+    me@here:~$ TIMER_FORMAT='[%d]'; TIMER_PRECISION=2        [0.00s]
+    me@here:~$ head -c50 < /dev/urandom | hexdump
+    0000000 b2 16 20 f0 29 1f 61 2d 8a 29 20 8c 8c 39 5a ab
+    0000010 21 47 0e f9 ee a4 76 46 71 9e 4f 6b a4 c4 51 cb
+    0000020 f9 1f 7e b9 6f 2c ae dd cf 40 6d 64 a8 fb d3 db
+    0000030 09 37
+    0000032                                                  [0.02s]
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/timer/timer.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/timer/timer.plugin.zsh
new file mode 100644 (file)
index 0000000..b261f71
--- /dev/null
@@ -0,0 +1,35 @@
+zmodload zsh/datetime
+
+__timer_current_time() {
+  zmodload zsh/datetime
+  echo $EPOCHREALTIME
+}
+
+__timer_format_duration() {
+  local mins=$(printf '%.0f' $(($1 / 60)))
+  local secs=$(printf "%.${TIMER_PRECISION:-1}f" $(($1 - 60 * mins)))
+  local duration_str=$(echo "${mins}m${secs}s")
+  local format="${TIMER_FORMAT:-/%d}"
+  echo "${format//\%d/${duration_str#0m}}"
+}
+
+__timer_save_time_preexec() {
+  __timer_cmd_start_time=$(__timer_current_time)
+}
+
+__timer_display_timer_precmd() {
+  if [ -n "${__timer_cmd_start_time}" ]; then
+    local cmd_end_time=$(__timer_current_time)
+    local tdiff=$((cmd_end_time - __timer_cmd_start_time))
+    unset __timer_cmd_start_time
+    if [[ -z "${TIMER_THRESHOLD}" || ${tdiff} -ge "${TIMER_THRESHOLD}" ]]; then
+        local tdiffstr=$(__timer_format_duration ${tdiff})
+        local cols=$((COLUMNS - ${#tdiffstr} - 1))
+        echo -e "\033[1A\033[${cols}C ${tdiffstr}"
+    fi
+  fi
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook preexec __timer_save_time_preexec
+add-zsh-hook precmd __timer_display_timer_precmd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux-cssh/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux-cssh/README.md
new file mode 100644 (file)
index 0000000..4602a50
--- /dev/null
@@ -0,0 +1,10 @@
+# tmux-cssh plugin
+
+This plugin adds autocompletion for [`tmux-cssh`](https://github.com/zinic/tmux-cssh/).
+
+To use it, add `tmux-cssh` to the plugins array in your zshrc file:
+```zsh
+plugins=(... tmux-cssh)
+```
+
+First upstream repo, now disappeared: https://github.com/dennishafemann/tmux-cssh.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux-cssh/_tmux-cssh b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux-cssh/_tmux-cssh
new file mode 100644 (file)
index 0000000..3e81b82
--- /dev/null
@@ -0,0 +1,25 @@
+#compdef tmux-cssh
+
+# tmux-cssh autocompletion for oh-my-zsh
+# Requires: tmux-cssh installed
+# Author: Manfred Touron (@moul)
+
+_arguments \
+  '(-h --help)'{-h,--help}'[This help.]' \
+  '(-u --user)'{-u,--user}'[User to use.]' \
+  '(-c --certificate)'{-c,--certificate}'[Path to ssh-certificate to use.]' \
+  '(-sc --ssh)'{-sc,--ssh}'[SSH-connection-string, multiple.]' \
+  '(-sa --ssh)'{-sa,--ssh}'[SSH connection arguments, used on every session.]' \
+  '(-ts --tmux)'{-ts,--tmux}'[Alternative tmux-session-name, default: tmux-cssh]' \
+  '(-ns --new)'{-ns,--new}'[Initializes a new session, like -ts \[name\].]' \
+  '(-q --quiet)'{-q,--quiet}'[Quiet-mode.]' \
+  '(-f --filename)'{-f,--filename}'[Filename of textfile to get -sc connection-strings from, line separated.]' \
+  '(-cs --config)'{-cs,--config}'[Name of config-settings which should be get from config-file "$HOME/.tmux-cssh". Which can be a grep-regular expression to find the name(s).]' \
+  ':hosts:_hosts' \
+  '*:: :->subcmds' \
+  && return 0
+
+if (( CURRENT == 1 )); then
+  _describe -t commands "tmux-cssh command"
+  return
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/README.md
new file mode 100644 (file)
index 0000000..7348f77
--- /dev/null
@@ -0,0 +1,43 @@
+# tmux
+
+This plugin provides aliases for [tmux](https://tmux.github.io/), the terminal multiplexer.
+To use it add `tmux` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... tmux)
+```
+
+The plugin also supports the following:
+
+- determines if tmux is installed or not, if not, prompts user to install tmux
+- determines if the terminal supports the 256 colors or not, sets the appropriate configuration variable
+- sets the correct local config file to use
+
+## Aliases
+
+| Alias      | Command                    | Description                                              |
+| ---------- | -------------------------- | -------------------------------------------------------- |
+| `ta`       | tmux attach -t             | Attach new tmux session to already running named session |
+| `tad`      | tmux attach -d -t          | Detach named tmux session                                |
+| `ts`       | tmux new-session -s        | Create a new named tmux session                          |
+| `tl`       | tmux list-sessions         | Displays a list of running tmux sessions                 |
+| `tksv`     | tmux kill-server           | Terminate all running tmux sessions                      |
+| `tkss`     | tmux kill-session -t       | Terminate named running tmux session                     |
+| `tmux`     | `_zsh_tmux_plugin_run`     | Start a new tmux session                                 |
+| `tmuxconf` | `$EDITOR $ZSH_TMUX_CONFIG` | Open .tmux.conf file with an editor                      |
+
+## Configuration Variables
+
+| Variable                            | Description                                                                   |
+| ----------------------------------- | ----------------------------------------------------------------------------- |
+| `ZSH_TMUX_AUTOSTART`                | Automatically starts tmux (default: `false`)                                  |
+| `ZSH_TMUX_AUTOSTART_ONCE`           | Autostart only if tmux hasn't been started previously (default: `true`)       |
+| `ZSH_TMUX_AUTOCONNECT`              | Automatically connect to a previous session if it exits (default: `true`)     |
+| `ZSH_TMUX_AUTOQUIT`                 | Automatically closes terminal once tmux exits (default: `ZSH_TMUX_AUTOSTART`) |
+| `ZSH_TMUX_FIXTERM`                  | Sets `$TERM` to 256-color term or not based on current terminal support       |
+| `ZSH_TMUX_ITERM2`                   | Sets the `-CC` option for iTerm2 tmux integration (default: `false`)          |
+| `ZSH_TMUX_FIXTERM_WITHOUT_256COLOR` | `$TERM` to use for non 256-color terminals (default: `screen`)                |
+| `ZSH_TMUX_FIXTERM_WITH_256COLOR`    | `$TERM` to use for 256-color terminals (default: `screen-256color`            |
+| `ZSH_TMUX_CONFIG`                   | Set the configuration path (default: `$HOME/.tmux.conf`)                      |
+| `ZSH_TMUX_UNICODE`                  | Set `tmux -u` option to support unicode                                       |
+| `ZSH_TMUX_DEFAULT_SESSION_NAME`     | Set tmux default session name when autostart is enabled                       |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.extra.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.extra.conf
new file mode 100644 (file)
index 0000000..c4aaad0
--- /dev/null
@@ -0,0 +1,2 @@
+set -g default-terminal $ZSH_TMUX_TERM
+source-file $ZSH_TMUX_CONFIG
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.only.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.only.conf
new file mode 100644 (file)
index 0000000..0734df3
--- /dev/null
@@ -0,0 +1 @@
+set -g default-terminal $ZSH_TMUX_TERM
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmux/tmux.plugin.zsh
new file mode 100644 (file)
index 0000000..b9bb66d
--- /dev/null
@@ -0,0 +1,109 @@
+if ! (( $+commands[tmux] )); then
+  print "zsh tmux plugin: tmux not found. Please install tmux before using this plugin." >&2
+  return 1
+fi
+
+# CONFIGURATION VARIABLES
+# Automatically start tmux
+: ${ZSH_TMUX_AUTOSTART:=false}
+# Only autostart once. If set to false, tmux will attempt to
+# autostart every time your zsh configs are reloaded.
+: ${ZSH_TMUX_AUTOSTART_ONCE:=true}
+# Automatically connect to a previous session if it exists
+: ${ZSH_TMUX_AUTOCONNECT:=true}
+# Automatically close the terminal when tmux exits
+: ${ZSH_TMUX_AUTOQUIT:=$ZSH_TMUX_AUTOSTART}
+# Set term to screen or screen-256color based on current terminal support
+: ${ZSH_TMUX_FIXTERM:=true}
+# Set '-CC' option for iTerm2 tmux integration
+: ${ZSH_TMUX_ITERM2:=false}
+# The TERM to use for non-256 color terminals.
+# Tmux states this should be screen, but you may need to change it on
+# systems without the proper terminfo
+: ${ZSH_TMUX_FIXTERM_WITHOUT_256COLOR:=screen}
+# The TERM to use for 256 color terminals.
+# Tmux states this should be screen-256color, but you may need to change it on
+# systems without the proper terminfo
+: ${ZSH_TMUX_FIXTERM_WITH_256COLOR:=screen-256color}
+# Set the configuration path
+: ${ZSH_TMUX_CONFIG:=$HOME/.tmux.conf}
+# Set -u option to support unicode
+: ${ZSH_TMUX_UNICODE:=false}
+
+# ALIASES
+
+alias ta='tmux attach -t'
+alias tad='tmux attach -d -t'
+alias ts='tmux new-session -s'
+alias tl='tmux list-sessions'
+alias tksv='tmux kill-server'
+alias tkss='tmux kill-session -t'
+alias tmuxconf='$EDITOR $ZSH_TMUX_CONFIG'
+
+# Determine if the terminal supports 256 colors
+if [[ $terminfo[colors] == 256 ]]; then
+  export ZSH_TMUX_TERM=$ZSH_TMUX_FIXTERM_WITH_256COLOR
+else
+  export ZSH_TMUX_TERM=$ZSH_TMUX_FIXTERM_WITHOUT_256COLOR
+fi
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+# Set the correct local config file to use.
+if [[ "$ZSH_TMUX_ITERM2" == "false" && -e "$ZSH_TMUX_CONFIG" ]]; then
+  export ZSH_TMUX_CONFIG
+  export _ZSH_TMUX_FIXED_CONFIG="${0:h:a}/tmux.extra.conf"
+else
+  export _ZSH_TMUX_FIXED_CONFIG="${0:h:a}/tmux.only.conf"
+fi
+
+# Wrapper function for tmux.
+function _zsh_tmux_plugin_run() {
+  if [[ -n "$@" ]]; then
+    command tmux "$@"
+    return $?
+  fi
+
+  local -a tmux_cmd
+  tmux_cmd=(command tmux)
+  [[ "$ZSH_TMUX_ITERM2" == "true" ]] && tmux_cmd+=(-CC)
+  [[ "$ZSH_TMUX_UNICODE" == "true" ]] && tmux_cmd+=(-u)
+
+  # Try to connect to an existing session.
+  [[ "$ZSH_TMUX_AUTOCONNECT" == "true" ]] && $tmux_cmd attach
+
+  # If failed, just run tmux, fixing the TERM variable if requested.
+  if [[ $? -ne 0 ]]; then
+    if [[ "$ZSH_TMUX_FIXTERM" == "true" ]]; then
+      tmux_cmd+=(-f "$_ZSH_TMUX_FIXED_CONFIG")
+    elif [[ -e "$ZSH_TMUX_CONFIG" ]]; then
+      tmux_cmd+=(-f "$ZSH_TMUX_CONFIG")
+    fi
+    if [[ -n "$ZSH_TMUX_DEFAULT_SESSION_NAME" ]]; then
+        $tmux_cmd new-session -s $ZSH_TMUX_DEFAULT_SESSION_NAME
+    else
+        $tmux_cmd new-session
+    fi
+  fi
+
+  if [[ "$ZSH_TMUX_AUTOQUIT" == "true" ]]; then
+    exit
+  fi
+}
+
+# Use the completions for tmux for our function
+compdef _tmux _zsh_tmux_plugin_run
+# Alias tmux to our wrapper function.
+alias tmux=_zsh_tmux_plugin_run
+
+# Autostart if not already in tmux and enabled.
+if [[ -z "$TMUX" && "$ZSH_TMUX_AUTOSTART" == "true" && -z "$INSIDE_EMACS" && -z "$EMACS" && -z "$VIM" ]]; then
+  # Actually don't autostart if we already did and multiple autostarts are disabled.
+  if [[ "$ZSH_TMUX_AUTOSTART_ONCE" == "false" || "$ZSH_TMUX_AUTOSTARTED" != "true" ]]; then
+    export ZSH_TMUX_AUTOSTARTED=true
+    _zsh_tmux_plugin_run
+  fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/README.md
new file mode 100644 (file)
index 0000000..8709204
--- /dev/null
@@ -0,0 +1,19 @@
+# Tmuxinator plugin
+
+This plugin provides completion for [tmuxinator](https://github.com/tmuxinator/tmuxinator),
+as well as aliases for frequent tmuxinator commands.
+
+To use it add `tmuxinator` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... tmuxinator)
+```
+
+## Aliases
+
+| Alias | Command          | Description              |
+| ----- | ---------------- | ------------------------ |
+| `txs` | tmuxinator start | Start Tmuxinator         |
+| `txo` | tmuxinator open  | Open project for editing |
+| `txn` | tmuxinator new   | Create project           |
+| `txl` | tmuxinator list  | List projects            |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/_tmuxinator b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/_tmuxinator
new file mode 100644 (file)
index 0000000..9ae25ac
--- /dev/null
@@ -0,0 +1,23 @@
+#compdef tmuxinator mux
+#autoload
+
+_tmuxinator() {
+  local commands projects
+  commands=(${(f)"$(tmuxinator commands zsh)"})
+  projects=(${(f)"$(tmuxinator completions start)"})
+
+  if (( CURRENT == 2 )); then
+    _describe -t commands "tmuxinator subcommands" commands
+    _describe -t projects "tmuxinator projects" projects
+  elif (( CURRENT == 3)); then
+    case $words[2] in
+      copy|debug|delete|open|start)
+        _arguments '*:projects:($projects)'
+      ;;
+    esac
+  fi
+
+  return
+}
+
+compdef _tmuxinator tmuxinator
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/tmuxinator.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/tmuxinator/tmuxinator.plugin.zsh
new file mode 100644 (file)
index 0000000..166fa98
--- /dev/null
@@ -0,0 +1,5 @@
+# aliases
+alias txs='tmuxinator start'
+alias txo='tmuxinator open'
+alias txn='tmuxinator new'
+alias txl='tmuxinator list'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/toolbox/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/toolbox/README.md
new file mode 100644 (file)
index 0000000..abaca31
--- /dev/null
@@ -0,0 +1,25 @@
+# toolbox plugin
+
+Plugin for [toolbox](https://containertoolbx.org), a tool to use containerized CLI environments.
+
+To use it, add `toolbox` to your plugins array in your `.zshrc` file:
+
+```zsh
+plugins=(... toolbox)
+```
+
+## Prompt function
+
+This plugins adds `toolbox_prompt_info()` function. Using it in your prompt, it will show the toolbox indicator ⬢ (if you are running in a toolbox container), and nothing if not.
+
+You can use it by adding `$(toolbox_prompt_info)` to your `PROMPT` or `RPROMPT` variable:
+
+```zsh
+RPROMPT='$(toolbox_prompt_info)'
+```
+
+## Aliases
+
+| Alias | Command              | Description                            |
+|-------|----------------------|----------------------------------------|
+| tb    | `toolbox enter`      | Enters the toolbox environment         |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/toolbox/toolbox.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/toolbox/toolbox.plugin.zsh
new file mode 100644 (file)
index 0000000..d24d6d3
--- /dev/null
@@ -0,0 +1,5 @@
+function toolbox_prompt_info() {
+  [[ -f /run/.toolboxenv ]] && echo "⬢"
+}
+
+alias tb="toolbox enter"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/torrent/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/torrent/README.md
new file mode 100644 (file)
index 0000000..079aafc
--- /dev/null
@@ -0,0 +1,13 @@
+# torrent
+
+This plugin creates a Torrent file based on a [MagnetURI](https://en.wikipedia.org/wiki/Magnet_URI_scheme).
+
+To use it, add `torrent` to the plugins array in your zshrc file.
+
+```zsh
+plugins=(... torrent)
+```
+
+## Plugin commands
+
+* `magnet_to_torrent <MagnetURI>`: creates Torrent file.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/torrent/torrent.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/torrent/torrent.plugin.zsh
new file mode 100644 (file)
index 0000000..656e337
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Algorithm borrowed from http://wiki.rtorrent.org/MagnetUri and adapted to work with zsh.
+#
+
+function magnet_to_torrent() {
+       [[ "$1" =~ xt=urn:btih:([^\&/]+) ]] || return 1
+
+       hashh=${match[1]}
+
+       if [[ "$1" =~ dn=([^\&/]+) ]];then
+         filename=${match[1]}
+       else
+         filename=$hashh
+       fi
+
+       echo "d10:magnet-uri${#1}:${1}e" > "$filename.torrent"
+}
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/transfer/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/transfer/README.md
new file mode 100644 (file)
index 0000000..825c9a2
--- /dev/null
@@ -0,0 +1,41 @@
+# `transfer` plugin
+
+[`transfer.sh`](https://transfer.sh) is an easy to use file sharing service from the command line
+
+To use it, add `transfer` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... transfer)
+```
+
+## Usage
+
+- Transfer a file: `transfer file.txt`.
+
+- Transfer a whole directory (it will be automatically compressed): `transfer dir`.
+
+### Encryption / Decryption
+
+- Encrypt and upload a file with symmetric cipher and create ASCII armored output:
+
+  ```zsh
+  transfer file -ca
+  ```
+
+- Encrypt and upload directory with symmetric cipher and gpg output:
+
+  ```zsh
+  transfer directory -ca
+  ```
+
+- Decrypt file:
+
+  ```zsh
+  gpg -d file -ca
+  ```
+
+- Decrypt directory:
+
+  ```zsh
+  gpg -d your_archive.tgz.gpg | tar xz
+  ```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/transfer/transfer.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/transfer/transfer.plugin.zsh
new file mode 100644 (file)
index 0000000..b34e115
--- /dev/null
@@ -0,0 +1,97 @@
+# Author:
+#   Remco Verhoef <remco@dutchcoders.io>
+#   https://gist.github.com/nl5887/a511f172d3fb3cd0e42d
+#   Modified to use tar command instead of zip
+#
+
+transfer() {
+  # check arguments
+  if [[ $# -eq 0 ]]; then
+  cat <<EOF
+Error: no arguments specified.
+
+Usage: transfer [file/folder] [options]
+
+Examples:
+  transfer /tmp/test.md
+  transfer /tmp/test.md -ca
+  cat /tmp/test.md | transfer test.md
+  cat /tmp/test.md | transfer test.md -ca
+
+Options:
+  -ca  Encrypt file with symmetric cipher and create ASCII armored output
+EOF
+  return 1
+  fi
+
+  if (( ! $+commands[curl] )); then
+    echo "Error: curl is not installed"
+    return 1
+  fi
+
+  local tmpfile tarfile item basename
+
+  # get temporarily filename, output is written to this file show progress can be showed
+  tmpfile=$(mktemp -t transferXXX)
+
+  # upload stdin or file
+  item="$1"
+
+  # crypt file with symmetric cipher and create ASCII armored output
+  local crypt=0
+  if [[ "$2" = -ca ]]; then
+    crypt=1
+    if (( ! $+commands[gpg] )); then
+      echo "Error: gpg is not installed"
+      return 1
+    fi
+  fi
+
+  if ! tty -s; then
+    # transfer from pipe
+    if (( crypt )); then
+      gpg -aco - | curl -X PUT --progress-bar -T - "https://transfer.sh/$item" >> $tmpfile
+    else
+      curl --progress-bar --upload-file - "https://transfer.sh/$item" >> $tmpfile
+    fi
+  else
+    basename=$(basename "$item" | sed -e 's/[^a-zA-Z0-9._-]/-/g')
+
+    if [[ ! -e $item ]]; then
+      echo "File $item doesn't exist."
+      return 1
+    fi
+
+    if [[ -d $item ]]; then
+      # tar directory and transfer
+      tarfile=$(mktemp -t transferXXX.tar.gz)
+      cd $(dirname $item) || {
+        echo "Error: Could not change to directory $(dirname $item)"
+        return 1
+      }
+
+      tar -czf $tarfile $(basename $item)
+      if (( crypt )); then
+        gpg -cao - "$tarfile" | curl --progress-bar -T "-" "https://transfer.sh/$basename.tar.gz.gpg" >> $tmpfile
+      else
+        curl --progress-bar --upload-file "$tarfile" "https://transfer.sh/$basename.tar.gz" >> $tmpfile
+      fi
+      rm -f $tarfile
+    else
+      # transfer file
+      if (( crypt )); then
+        gpg -cao - "$item" | curl --progress-bar -T "-" "https://transfer.sh/$basename.gpg" >> $tmpfile
+      else
+        curl --progress-bar --upload-file "$item" "https://transfer.sh/$basename" >> $tmpfile
+      fi
+    fi
+  fi
+
+  # cat output link
+  cat $tmpfile
+  # add newline
+  echo
+
+  # cleanup
+  rm -f $tmpfile
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tugboat/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/tugboat/README.md
new file mode 100644 (file)
index 0000000..14f828f
--- /dev/null
@@ -0,0 +1,12 @@
+# Tugboat plugin
+
+This plugin adds autocompletion for Tugboat, a command line tool for interacting with your
+[DigitalOcean droplets](https://www.digitalocean.com/products/droplets/).
+
+To use it, add it to the plugins array in your `~/.zshrc` file:
+
+```zsh
+plugins=(... tugboat)
+```
+
+Further documentation for Tugboat can be found in the [Tugboat repository](https://github.com/petems/tugboat).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/tugboat/_tugboat b/stow/oh-my-zsh/.oh-my-zsh/plugins/tugboat/_tugboat
new file mode 100644 (file)
index 0000000..6bf7369
--- /dev/null
@@ -0,0 +1,106 @@
+#compdef tugboat
+#autoload
+
+# Tugboat zsh autocompletion
+
+
+local -a _commands
+_commands=(
+  'add-key:[NAME] Upload an ssh public key.'
+  'authorize:Authorize a DigitalOcean account with tugboat.'
+  'create:[NAME] Create a droplet.'
+  'destroy:[FUZZY_NAME] Destroy a droplet.'
+  'destroy_image:[FUZZY_NAME] Destroy an image.'
+  'droplets:Retrieve a list of your droplets.'
+  'halt:[FUZZY_NAME] Shutdown a droplet.'
+  'help:[COMMAND] Describe commands or a specific command.'
+  'images:Retrieve a list of your images.'
+  'info:[FUZZY_NAME] [OPTIONS] Show a droplets information.'
+  'info_image:[FUZZY_NAME] [OPTIONS] Show an images information.'
+  'keys:Show available SSH keys.'
+  'password-reset:[FUZZY_NAME] Reset root password.'
+  'rebuild:[FUZZY_NAME] [IMAGE_NAME] Rebuild a droplet.'
+  'regions:Show regions.'
+  'resize:[FUZZY_NAME -s, --size=N] Resize a droplet.'
+  'restart:[FUZZY_NAME] Restart a droplet.'
+  'sizes:Show available droplet sizes.'
+  'snapshot:[SNAPSHOT_NAME] [FUZZY_NAME] [OPTIONS] Queue a snapshot of the droplet.'
+  'ssh:[FUZZY_NAME] SSH into a droplet.'
+  'start:[FUZZY_NAME] Start a droplet.'
+  'verify:Check your DigitalOcean credentials.'
+  'version:Show version.'
+  'wait:[FUZZY_NAME] Wait for a droplet to reach a state.'
+)
+
+local -a _create_arguments
+_create_arguments=(
+  '-s:[--size=N] The size_id of the droplet'
+  '-i:[--image=N] The image_id of the droplet'
+  '-r:[--region=N] The region_id of the droplet'
+  '-k:[--keys=KEYS] A comma separated list of SSH key ids to add to the droplet'
+  '-p:[--private-networking] Enable private networking on the droplet'
+  '-b:[--backups-enabled] Enable backups on the droplet'
+  '-q:[--quiet]'
+)
+
+__task_list ()
+{
+  local expl
+  declare -a tasks
+
+  arguments=(add-key authorize create destroy destroy_image droplets halt help images info info_image keys password-reset rebuild regions resize restart sizes snapshot ssh start verify version wait)
+
+  _wanted tasks expl 'help' compadd $arguments
+}
+
+__droplets_list ()
+{
+    _wanted application expl 'command' compadd $(command tugboat droplets | cut -d " " -f1)
+}
+
+__tugboat-create ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+    case $state in
+        (command)
+            _describe -t commands "gem subcommand" _create_arguments
+            return
+        ;;
+    esac
+}
+
+local curcontext="$curcontext" state line
+typeset -A opt_args
+
+_arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+case $state in
+  (command)
+    _describe -t commands "gem subcommand" _commands
+    return
+  ;;
+
+  (options)
+    case $line[1] in
+      (help)
+        _arguments ':feature:__task_list'
+      ;;
+
+      (ssh)
+        _arguments ':feature:__droplets_list'
+      ;;
+
+      (create)
+        _arguments ':feature:__tugboat-create'
+      ;;
+    esac
+  ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ubuntu/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ubuntu/README.md
new file mode 100644 (file)
index 0000000..20f5c65
--- /dev/null
@@ -0,0 +1,61 @@
+# Ubuntu plugin
+
+This plugin adds completions and aliases for [Ubuntu](https://www.ubuntu.com/).
+
+To use it, add `ubuntu` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ubuntu)
+```
+
+## Aliases
+
+Commands that use `$APT` will use `apt` if installed or defer to `apt-get` otherwise.
+
+| Alias   | Command                                                                  | Description                                                                                       |
+|---------|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
+| age     | `sudo $APT`                                                              | Run apt-get with sudo                                                                             |
+| acs     | `apt-cache search`                                                       | Search the apt-cache with the specified criteria                                                  |
+| acsp    | `apt-cache showpkg`                                                      | Shows information about the listed packages                                                       |
+| acp     | `apt-cache policy`                                                       | Display the package source priorities                                                             |
+| afs     | `apt-file search --regexp`                                               | Perform a regular expression apt-file search                                                      |
+| afu     | `sudo apt-file update`                                                   | Generates or updates the apt-file package database                                                |
+| aga     | `sudo $APT autoclean`                                                    | Clears out the local repository of retrieved package files that can no longer be downloaded       |
+| agb     | `sudo $APT build-dep <source_pkg>`                                       | Installs/Removes packages to satisfy the dependencies of a specified build pkg                    |
+| agc     | `sudo $APT clean`                                                        | Clears out the local repository of retrieved package files leaving everything from the lock files |
+| agd     | `sudo $APT dselect-upgrade`                                              | Follows dselect choices for package installation                                                  |
+| agi     | `sudo $APT install <pkg>`                                                | Install the specified package                                                                     |
+| agli    | `apt list --installed`                                                   | List the installed packages                                                                       |
+| aglu    | `sudo apt-get -u upgrade --assume-no`                                    | Run an apt-get upgrade assuming no to all prompts                                                 |
+| agp     | `sudo $APT purge <pkg>`                                                  | Remove a package including any configuration files                                                |
+| agr     | `sudo $APT remove <pkg>`                                                 | Remove a package                                                                                  |
+| ags     | `$APT source <pkg>`                                                      | Fetch the source for the specified package                                                        |
+| agu     | `sudo $APT update`                                                       | Update package list                                                                               |
+| agud    | `sudo $APT update && sudo $APT dist-upgrade`                             | Update packages list and perform a distribution upgrade                                           |
+| agug    | `sudo $APT upgrade`                                                      | Upgrade available packages                                                                        |
+| agar    | `sudo $APT autoremove`                                                   | Remove automatically installed packages no longer needed                                          |
+| aguu    | `sudo $APT update && sudo $APT upgrade`                                  | Update packages list and upgrade available packages                                               |
+| allpkgs | `dpkg --get-selections \| grep -v deinstall`                             | Print all installed packages                                                                      |
+| kclean  | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` |Remove ALL kernel images and headers EXCEPT the one in use                                         |
+| mydeb   | `time dpkg-buildpackage -rfakeroot -us -uc`                              | Create a basic .deb package                                                                       |
+| ppap    | `sudo ppa-purge <ppa>`                                                   | Remove the specified PPA                                                                          |
+
+
+## Functions
+
+| Function          | Usage                                 |Description                                                               |
+|-------------------|---------------------------------------|--------------------------------------------------------------------------|
+| aar               | `aar ppa:xxxxxx/xxxxxx [packagename]` | apt-add-repository with automatic install/upgrade of the desired package |
+| apt-history       | `apt-history <action>`                | Prints the Apt history of the specified action                           |
+| apt-list-packages | `apt-list-packages`                   | List packages by size                                                    |
+| kerndeb           | `kerndeb`                             | Kernel-package building shortcut                                         |
+
+## Authors:
+
+- [@AlexBio](https://github.com/AlexBio)
+- [@dbb](https://github.com/dbb)
+- [@Mappleconfusers](https://github.com/Mappleconfusers)
+- [@trinaldi](https://github.com/trinaldi)
+- [Nicolas Jonas](https://nextgenthemes.com)
+- [@loctauxphilippe](https://github.com/loctauxphilippe)
+- [@HaraldNordgren](https://github.com/HaraldNordgren)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ubuntu/ubuntu.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/ubuntu/ubuntu.plugin.zsh
new file mode 100644 (file)
index 0000000..7b765a4
--- /dev/null
@@ -0,0 +1,127 @@
+(( $+commands[apt] )) && APT=apt || APT=apt-get
+
+alias acs='apt-cache search'
+
+alias afs='apt-file search --regexp'
+
+# These are apt/apt-get only
+alias ags="$APT source"
+
+alias acp='apt-cache policy'
+
+#List all installed packages
+alias agli='apt list --installed'
+
+# List available updates only
+alias aglu='apt list --upgradable'
+
+alias acsp='apt-cache showpkg'
+compdef _acsp acsp='apt-cache showpkg'
+
+# superuser operations ######################################################
+
+alias afu='sudo apt-file update'
+
+alias ppap='sudo ppa-purge'
+
+alias age="sudo $APT"
+alias aga="sudo $APT autoclean"
+alias agb="sudo $APT build-dep"
+alias agc="sudo $APT clean"
+alias agd="sudo $APT dselect-upgrade"
+alias agi="sudo $APT install"
+alias agp="sudo $APT purge"
+alias agr="sudo $APT remove"
+alias agu="sudo $APT update"
+alias agud="sudo $APT update && sudo $APT dist-upgrade"
+alias agug="sudo $APT upgrade"
+alias aguu="sudo $APT update && sudo $APT upgrade"
+alias agar="sudo $APT autoremove"
+
+
+# Remove ALL kernel images and headers EXCEPT the one in use
+alias kclean='sudo aptitude remove -P ?and(~i~nlinux-(ima|hea) ?not(~n`uname -r`))'
+
+# Misc. #####################################################################
+# print all installed packages
+alias allpkgs='dpkg --get-selections | grep -v deinstall'
+
+# Create a basic .deb package
+alias mydeb='time dpkg-buildpackage -rfakeroot -us -uc'
+
+# apt-add-repository with automatic install/upgrade of the desired package
+# Usage: aar ppa:xxxxxx/xxxxxx [packagename]
+# If packagename is not given as 2nd argument the function will ask for it and guess the default by taking
+# the part after the / from the ppa name which is sometimes the right name for the package you want to install
+function aar() {
+       if [ -n "$2" ]; then
+               PACKAGE=$2
+       else
+               read "PACKAGE?Type in the package name to install/upgrade with this ppa [${1##*/}]: "
+       fi
+
+       if [ -z "$PACKAGE" ]; then
+               PACKAGE=${1##*/}
+       fi
+
+       sudo apt-add-repository $1 && sudo $APT update
+       sudo $APT install $PACKAGE
+}
+
+# Prints apt history
+# Usage:
+#   apt-history install
+#   apt-history upgrade
+#   apt-history remove
+#   apt-history rollback
+#   apt-history list
+# Based On: https://linuxcommando.blogspot.com/2008/08/how-to-show-apt-log-history.html
+function apt-history() {
+  case "$1" in
+    install)
+      zgrep --no-filename 'install ' $(ls -rt /var/log/dpkg*)
+      ;;
+    upgrade|remove)
+      zgrep --no-filename $1 $(ls -rt /var/log/dpkg*)
+      ;;
+    rollback)
+      zgrep --no-filename upgrade $(ls -rt /var/log/dpkg*) | \
+        grep "$2" -A10000000 | \
+        grep "$3" -B10000000 | \
+        awk '{print $4"="$5}'
+      ;;
+    list)
+      zgrep --no-filename '' $(ls -rt /var/log/dpkg*)
+      ;;
+    *)
+      echo "Parameters:"
+      echo " install - Lists all packages that have been installed."
+      echo " upgrade - Lists all packages that have been upgraded."
+      echo " remove - Lists all packages that have been removed."
+      echo " rollback - Lists rollback information."
+      echo " list - Lists all contains of dpkg logs."
+      ;;
+  esac
+}
+
+# Kernel-package building shortcut
+function kerndeb() {
+  # temporarily unset MAKEFLAGS ( '-j3' will fail )
+  MAKEFLAGS=$( print - $MAKEFLAGS | perl -pe 's/-j\s*[\d]+//g' )
+  print '$MAKEFLAGS set to '"'$MAKEFLAGS'"
+  appendage='-custom' # this shows up in $(uname -r)
+  revision=$(date +"%Y%m%d") # this shows up in the .deb file name
+
+  make-kpkg clean
+
+  time fakeroot make-kpkg --append-to-version "$appendage" --revision \
+      "$revision" kernel_image kernel_headers
+}
+
+# List packages by size
+function apt-list-packages {
+  dpkg-query -W --showformat='${Installed-Size} ${Package} ${Status}\n' | \
+  grep -v deinstall | \
+  sort -n | \
+  awk '{print $1" "$2}'
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ufw/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/ufw/README.md
new file mode 100644 (file)
index 0000000..ac377cd
--- /dev/null
@@ -0,0 +1,18 @@
+# UFW plugin
+
+This plugin adds completion for managing everybody's favorite Uncomplicated Firewall (UFW),
+a simple interface for managing iptables. Learn more about [`UFW`](https://wiki.ubuntu.com/UncomplicatedFirewall).
+
+To use it, add ufw to the plugins array of your zshrc file:
+```
+plugins=(... ufw)
+```
+
+Some of the commands include:
+
+* `allow <port>/<optional: protocol>` add an allow rule 
+* `default` set default policy
+* `delete <port>/<optional: protocol>` delete RULE
+* `deny <port>/<optional: protocol>` add deny rule
+* `disable` disables the firewall
+* `enable` enables the firewall
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/ufw/_ufw b/stow/oh-my-zsh/.oh-my-zsh/plugins/ufw/_ufw
new file mode 100644 (file)
index 0000000..f5ad033
--- /dev/null
@@ -0,0 +1,115 @@
+#compdef ufw
+#autoload
+
+typeset -A opt_args
+
+function _ufw_delete_rules {
+  if ufw status &> /dev/null ; then
+    ufw status numbered \
+      | perl -n -e'/\[ +(\d+)\] +([^ ].+)/ && print "\"$1\[$2\]\" "'
+  fi
+}
+
+function _ufw_app_profiles {
+  grep -rhoP "(?<=\[)[^\]]+" /etc/ufw/applications.d/ \
+    | awk '{ print "\""$0"\""}' \
+    | tr '\n' ' '
+}
+
+local -a _1st_arguments
+_1st_arguments=(
+  'allow:add allow rule'
+  'app:Application profile commands'
+  'default:set default policy'
+  'delete:delete RULE'
+  'deny:add deny rule'
+  'disable:disables the firewall'
+  'enable:enables the firewall'
+  'insert:insert RULE at NUM'
+  'limit:add limit rule'
+  'logging:set logging to LEVEL'
+  'reject:add reject rule'
+  'reload:reloads firewall'
+  'reset:reset firewall'
+  'show:show firewall report'
+  'status:show firewall status'
+  'version:display version information'
+)
+
+local context state line curcontext="$curcontext"
+
+_arguments -C \
+  '(--dry-run)--dry-run[dry run]' \
+  '1:: :->cmds' \
+  '2:: :->subcmds' \
+  '3:: :->subsubcmds' \
+&& return 0
+
+local rules
+
+case "$state" in
+  (cmds)
+    _describe -t commands "ufw commands" _1st_arguments
+    return 0
+    ;;
+  (subcmds)
+    case "$line[1]" in
+      (app)
+        _values 'app' \
+          'list[list application profiles]' \
+          'info[show information on PROFILE]' \
+          'update[update PROFILE]' \
+          'default[set default application policy]' \
+        && ret=0
+        ;;
+      (status)
+        _values 'status' \
+          'numbered[show firewall status as numbered list of RULES]' \
+          'verbose[show verbose firewall status]' \
+        && ret=0
+        ;;
+      (logging)
+        _values 'logging' \
+          'on' 'off' 'low' 'medium' 'high' 'full' \
+        && ret=0
+        ;;
+      (default)
+        _values 'default' \
+          'allow' 'deny' 'reject' \
+        && ret=0
+        ;;
+      (show)
+        _values 'show' \
+          'raw' 'builtins' 'before-rules' 'user-rules' 'after-rules' 'logging-rules' 'listening' 'added' \
+        && ret=0
+        ;;
+      (delete)
+        rules="$(_ufw_delete_rules)"
+        if [[ -n "$rules" ]] ; then
+          _values 'delete' \
+            ${(Q)${(z)"$(_ufw_delete_rules)"}} \
+          && ret=0
+        fi
+        ;;
+    esac
+    ;;
+  (subsubcmds)
+    case "$line[1]" in
+      (app)
+        case "$line[2]" in
+          (info|update)
+            _values 'profiles' \
+              ${(Q)${(z)"$(_ufw_app_profiles)"}} \
+            && ret=0
+            ;;
+        esac
+        ;;
+      (default)
+        _values 'default-direction' \
+          'incoming' 'outgoing' \
+        && ret=0
+        ;;
+    esac
+esac
+
+return
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/README.md
new file mode 100644 (file)
index 0000000..93a1bd9
--- /dev/null
@@ -0,0 +1,46 @@
+# universalarchive plugin
+
+Lets you compress files by a command `ua <format> <files>`, supporting various
+compression formats (e.g. 7z, tar.gz, lzma, ...).
+
+To enable it, add `universalarchive` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... universalarchive)
+```
+
+## Usage
+
+Run `ua <format> <files>` to compress `<files>` into an archive file using `<format>`.
+For example:
+
+```sh
+ua xz *.html
+```
+
+this command will compress all `.html` files in directory `folder` into `folder.xz`.
+
+This plugin saves you from having to remember which command line arguments compress a file.
+
+## Supported compression formats
+
+| Extension        | Description                    |
+|:-----------------|:-------------------------------|
+| `7z`             | 7zip file                      |
+| `bz2`            | Bzip2 file                     |
+| `gz`             | Gzip file                      |
+| `lzma`           | LZMA archive                   |
+| `lzo`            | LZO archive                    |
+| `rar`            | WinRAR archive                 |
+| `tar`            | Tarball                        |
+| `tbz`/`tar.bz2`  | Tarball with bzip2 compression |
+| `tgz`/`tar.gz`   | Tarball with gzip compression  |
+| `tlz`/`tar.lzma` | Tarball with lzma compression  |
+| `txz`/`tar.xz`   | Tarball with lzma2 compression |
+| `tZ`/`tar.Z`     | Tarball with LZW compression   |
+| `xz`             | LZMA2 archive                  |
+| `Z`              | Z archive (LZW)                |
+| `zip`            | Zip archive                    |
+| `zst`            | Zstd archive                   |
+
+See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for more information regarding the archive formats.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/_universalarchive b/stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/_universalarchive
new file mode 100644 (file)
index 0000000..17cfd78
--- /dev/null
@@ -0,0 +1,6 @@
+#compdef ua
+
+_arguments \
+  "1:archive format:(7z bz2 gz lzma lzo rar tar tar.bz2 tar.gz tar.lzma tar.xz tar.Z tbz tgz tlz txz tZ xz Z zip zst)" \
+  "*:input files:_files" \
+&& return 0
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/universalarchive.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/universalarchive/universalarchive.plugin.zsh
new file mode 100644 (file)
index 0000000..b287c22
--- /dev/null
@@ -0,0 +1,70 @@
+function ua() {
+  local usage=\
+"Archive files and directories using a given compression algorithm.
+
+Usage:   $0 <format> <files>
+Example: $0 tbz PKGBUILD
+
+Supported archive formats are:
+7z, bz2, gz, lzma, lzo, rar, tar, tbz (tar.bz2), tgz (tar.gz),
+tlz (tar.lzma), txz (tar.xz), tZ (tar.Z), xz, Z, zip, and zst."
+
+  if [[ $# -lt 2 ]]; then
+    print -u2 -- "$usage"
+    return 1
+  fi
+
+  local ext="$1"
+  local input="${2:a}"
+
+  shift
+
+  if [[ ! -e "$input" ]]; then
+    print -u2 -- "$input not found"
+    return 1
+  fi
+
+  # generate output file name
+  local output
+  if [[ $# -gt 1 ]]; then
+    output="${input:h:t}"
+  elif [[ -f "$input" ]]; then
+    output="${input:r:t}"
+  elif [[ -d "$input" ]]; then
+    output="${input:t}"
+  fi
+
+  # if output file exists, generate a random name
+  if [[ -f "${output}.${ext}" ]]; then
+    output=$(mktemp "${output}_XXX") && rm "$output" || return 1
+  fi
+
+  # add extension
+  output="${output}.${ext}"
+
+  # safety check
+  if [[ -f "$output" ]]; then
+    print -u2 -- "output file '$output' already exists. Aborting"
+    return 1
+  fi
+
+  case "$ext" in
+    7z)           7z u                        "${output}"   "${@}" ;;
+    bz2)          bzip2 -vcf                  "${@}" > "${output}" ;;
+    gz)           gzip -vcf                   "${@}" > "${output}" ;;
+    lzma)         lzma -vc -T0                "${@}" > "${output}" ;;
+    lzo)          lzop -vc                    "${@}" > "${output}" ;;
+    rar)          rar a                       "${output}"   "${@}" ;;
+    tar)          tar -cvf                    "${output}"   "${@}" ;;
+    tbz|tar.bz2)  tar -cvjf                   "${output}"   "${@}" ;;
+    tgz|tar.gz)   tar -cvzf                   "${output}"   "${@}" ;;
+    tlz|tar.lzma) XZ_OPT=-T0 tar --lzma -cvf  "${output}"   "${@}" ;;
+    txz|tar.xz)   XZ_OPT=-T0 tar -cvJf        "${output}"   "${@}" ;;
+    tZ|tar.Z)     tar -cvZf                   "${output}"   "${@}" ;;
+    xz)           xz -vc -T0                  "${@}" > "${output}" ;;
+    Z)            compress -vcf               "${@}" > "${output}" ;;
+    zip)          zip -rull                   "${output}"   "${@}" ;;
+    zst)          zstd -c -T0                 "${@}" > "${output}" ;;
+    *) print -u2 -- "$usage"; return 1 ;;
+  esac
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/urltools/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/urltools/README.md
new file mode 100644 (file)
index 0000000..29c3710
--- /dev/null
@@ -0,0 +1,29 @@
+# URLTools plugin
+
+This plugin provides two aliases to URL-encode and URL-decode strings.
+
+To start using it, add the `urltools` plugin to your plugins array in `~/.zshrc`:
+
+```zsh
+plugins=(... urltools)
+```
+
+Original author: [Ian Chesal](https://github.com/ianchesal)
+Original idea and aliases: [Ruslan Spivak](https://ruslanspivak.wordpress.com/2010/06/02/urlencode-and-urldecode-from-a-command-line/)
+
+## Commands
+
+| Command     | Description                  |
+| :---------- | :--------------------------- |
+| `urlencode` | URL-encodes the given string |
+| `urldecode` | URL-decodes the given string |
+
+## Examples
+
+```zsh
+urlencode 'https://github.com/ohmyzsh/ohmyzsh/search?q=urltools&type=Code'
+# returns https%3A%2F%2Fgithub.com%2Fohmyzsh%2Fohmyzsh%2Fsearch%3Fq%3Durltools%26type%3DCode
+
+urldecode 'https%3A%2F%2Fgithub.com%2Fohmyzsh%2Fohmyzsh%2Fsearch%3Fq%3Durltools%26type%3DCode'
+# returns https://github.com/ohmyzsh/ohmyzsh/search?q=urltools&type=Code
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/urltools/urltools.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/urltools/urltools.plugin.zsh
new file mode 100644 (file)
index 0000000..b443e50
--- /dev/null
@@ -0,0 +1,42 @@
+# URL Tools
+# Adds handy command line aliases useful for dealing with URLs
+#
+# Taken from:
+# https://ruslanspivak.com/2010/06/02/urlencode-and-urldecode-from-a-command-line/
+
+if [[ $(whence $URLTOOLS_METHOD) = "" ]]; then
+    URLTOOLS_METHOD=""
+fi
+
+if [[ $(whence node) != "" && ( "x$URLTOOLS_METHOD" = "x"  || "x$URLTOOLS_METHOD" = "xnode" ) ]]; then
+    alias urlencode='node -e "console.log(encodeURIComponent(process.argv[1]))"'
+    alias urldecode='node -e "console.log(decodeURIComponent(process.argv[1]))"'
+elif [[ $(whence python3) != "" && ( "x$URLTOOLS_METHOD" = "x" || "x$URLTOOLS_METHOD" = "xpython" ) ]]; then
+    alias urlencode='python3 -c "import sys; del sys.path[0]; import urllib.parse as up; print(up.quote_plus(sys.argv[1]))"'
+    alias urldecode='python3 -c "import sys; del sys.path[0]; import urllib.parse as up; print(up.unquote_plus(sys.argv[1]))"'
+elif [[ $(whence python2) != "" && ( "x$URLTOOLS_METHOD" = "x" || "x$URLTOOLS_METHOD" = "xpython" ) ]]; then
+    alias urlencode='python2 -c "import sys; del sys.path[0]; import urllib as ul; print ul.quote_plus(sys.argv[1])"'
+    alias urldecode='python2 -c "import sys; del sys.path[0]; import urllib as ul; print ul.unquote_plus(sys.argv[1])"'
+elif [[ $(whence xxd) != "" && ( "x$URLTOOLS_METHOD" = "x" || "x$URLTOOLS_METHOD" = "xshell" ) ]]; then
+    function urlencode() {echo $@ | tr -d "\n" | xxd -plain | sed "s/\(..\)/%\1/g"}
+    function urldecode() {printf $(echo -n $@ | sed 's/\\/\\\\/g;s/\(%\)\([0-9a-fA-F][0-9a-fA-F]\)/\\x\2/g')"\n"}
+elif [[ $(whence ruby) != "" && ( "x$URLTOOLS_METHOD" = "x" || "x$URLTOOLS_METHOD" = "xruby" ) ]]; then
+    alias urlencode='ruby -r cgi -e "puts CGI.escape(ARGV[0])"'
+    alias urldecode='ruby -r cgi -e "puts CGI.unescape(ARGV[0])"'
+elif [[ $(whence php) != "" && ( "x$URLTOOLS_METHOD" = "x" || "x$URLTOOLS_METHOD" = "xphp" ) ]]; then
+    alias urlencode='php -r "echo rawurlencode(\$argv[1]); echo \"\n\";"'
+    alias urldecode='php -r "echo rawurldecode(\$argv[1]); echo \"\\n\";"'
+elif [[ $(whence perl) != "" && ( "x$URLTOOLS_METHOD" = "x" || "x$URLTOOLS_METHOD" = "xperl" ) ]]; then
+    if perl -MURI::Encode -e 1&> /dev/null; then
+        alias urlencode='perl -MURI::Encode -ep "uri_encode($ARGV[0]);"'
+        alias urldecode='perl -MURI::Encode -ep "uri_decode($ARGV[0]);"'
+    elif perl -MURI::Escape -e 1 &> /dev/null; then
+        alias urlencode='perl -MURI::Escape -ep "uri_escape($ARGV[0]);"'
+        alias urldecode='perl -MURI::Escape -ep "uri_unescape($ARGV[0]);"'
+    else
+        alias urlencode="perl -e '\$new=\$ARGV[0]; \$new =~ s/([^A-Za-z0-9])/sprintf(\"%%%02X\", ord(\$1))/seg; print \"\$new\n\";'"
+        alias urldecode="perl -e '\$new=\$ARGV[0]; \$new =~ s/\%([A-Fa-f0-9]{2})/pack(\"C\", hex(\$1))/seg; print \"\$new\n\";'"
+    fi
+fi
+
+unset URLTOOLS_METHOD
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant-prompt/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant-prompt/README.md
new file mode 100644 (file)
index 0000000..c5bc55d
--- /dev/null
@@ -0,0 +1,6 @@
+This plugin prompts the status of the Vagrant VMs. It supports single-host and
+multi-host configurations as well.
+
+Look inside the source for documentation about custom variables. 
+
+Alberto Re <alberto.re@gmail.com>
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh
new file mode 100644 (file)
index 0000000..d7c76c3
--- /dev/null
@@ -0,0 +1,33 @@
+# vim:ft=zsh ts=2 sw=2 sts=2
+#
+# To display Vagrant infos on your prompt add the vagrant_prompt_info to the
+# $PROMPT variable in your theme. Example:
+#
+# PROMPT='%{$fg[$NCOLOR]%}%B%n%b%{$reset_color%}:%{$fg[blue]%}%B%c/%b%{$reset_color%} $(vagrant_prompt_info)$(svn_prompt_info)$(git_prompt_info)%(!.#.$) '
+#
+# `vagrant_prompt_info` makes use of some custom variables. This is an example
+# definition:
+#
+# ZSH_THEME_VAGRANT_PROMPT_PREFIX="%{$fg_bold[blue]%}["
+# ZSH_THEME_VAGRANT_PROMPT_SUFFIX="%{$fg_bold[blue]%}]%{$reset_color%} "
+# ZSH_THEME_VAGRANT_PROMPT_RUNNING="%{$fg_no_bold[green]%}●"
+# ZSH_THEME_VAGRANT_PROMPT_POWEROFF="%{$fg_no_bold[red]%}●"
+# ZSH_THEME_VAGRANT_PROMPT_SUSPENDED="%{$fg_no_bold[yellow]%}●"
+# ZSH_THEME_VAGRANT_PROMPT_NOT_CREATED="%{$fg_no_bold[white]%}○"
+
+function vagrant_prompt_info() {
+  local vm_states vm_state
+  if [[ -d .vagrant && -f Vagrantfile ]]; then
+    vm_states=(${(f)"$(vagrant status 2> /dev/null | sed -nE 's/^.*(saved|poweroff|running|not created) \([[:alnum:]_]+\)$/\1/p')"})
+    printf '%s' $ZSH_THEME_VAGRANT_PROMPT_PREFIX
+    for vm_state in $vm_states; do
+      case "$vm_state" in
+        saved) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_SUSPENDED ;;
+        running) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_RUNNING ;;
+        poweroff) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_POWEROFF ;;
+        "not created") printf '%s' $ZSH_THEME_VAGRANT_PROMPT_NOT_CREATED ;;
+      esac
+    done
+    printf '%s' $ZSH_THEME_VAGRANT_PROMPT_SUFFIX
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/README.md
new file mode 100644 (file)
index 0000000..331bfa1
--- /dev/null
@@ -0,0 +1,40 @@
+# Vagrant plugin
+
+This plugin adds autocompletion for [Vagrant](https://www.vagrantup.com/) commands, task names, box names and built-in handy documentation.
+
+To use it, add `vagrant` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... vagrant)
+```
+
+## Aliases
+
+| Alias   | Command                      |
+|---------|------------------------------|
+| `vgi`   | `vagrant init`               |
+| `vup`   | `vagrant up`                 |
+| `vd`    | `vagrant destroy`            |
+| `vdf`   | `vagrant destroy -f`         |
+| `vssh`  | `vagrant ssh`                |
+| `vsshc` | `vagrant ssh-config`         |
+| `vrdp`  | `vagrant rdp`                |
+| `vh`    | `vagrant halt`               |
+| `vssp`  | `vagrant suspend`            |
+| `vst`   | `vagrant status`             |
+| `vre`   | `vagrant resume`             |
+| `vgs`   | `vagrant global-status`      |
+| `vpr`   | `vagrant provision`          |
+| `vr`    | `vagrant reload`             |
+| `vrp`   | `vagrant reload --provision` |
+| `vp`    | `vagrant push`               |
+| `vsh`   | `vagrant share`              |
+| `vba`   | `vagrant box add`            |
+| `vbr`   | `vagrant box remove`         |
+| `vbl`   | `vagrant box list`           |
+| `vbo`   | `vagrant box outdated`       |
+| `vbu`   | `vagrant box update`         |
+| `vpli`  | `vagrant plugin install`     |
+| `vpll`  | `vagrant plugin list`        |
+| `vplun` | `vagrant plugin uninstall`   |
+| `vplu`  | `vagrant plugin update`      |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/_vagrant b/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/_vagrant
new file mode 100644 (file)
index 0000000..e888355
--- /dev/null
@@ -0,0 +1,133 @@
+#compdef vagrant
+#autoload
+
+# vagrant zsh completion
+
+local -a _1st_arguments
+_1st_arguments=(
+    'box:Box commands'
+    'cloud:Manages everything related to Vagrant Cloud'
+    'connect:Connects to a remotely shared Vagrant environment'
+    'destroy:Destroys the vagrant environment'
+    'docker-logs:Outputs the logs from the Docker container'
+    'docker-run:Run a one-off command in the context of a container'
+    'global-status:Reports the status of all active Vagrant environments on the system'
+    'halt:Halts the currently running vagrant environment'
+    'help:Shows the help for a subcommand'
+    'init:[box_name] [box_url] Initializes current folder for Vagrant usage'
+    'list-commands:Outputs all available Vagrant subcommands, even non-primary ones'
+    'login:Authenticates against a Vagrant Cloud server to access protected boxes'
+    'package:Packages a vagrant environment for distribution'
+    'plugin:Plugin commands'
+    'port:Displays information about guest port mappings'
+    'provision:Run the provisioner'
+    'push:Deploys code in this environment to a configured destination'
+    'rdp:Connects to machine via RDP'
+    'reload:Reload the vagrant environment'
+    'resume:Resumes a suspended vagrant environment'
+    'rsync:Syncs rsync synced folders to remote machine'
+    'rsync-auto:Syncs rsync synced folders automatically when files change'
+    'share:Shares your Vagrant environment with anyone in the world'
+    'snapshot:Manage snapshots with the guest machine'
+    'ssh:SSH into the currently running environment'
+    'ssh-config:Outputs .ssh/config valid syntax for connecting to this environment via ssh'
+    'status:Shows the status of the current Vagrant environment'
+    'suspend:Suspends the currently running vagrant environment'
+    'snapshot:Used to manage snapshots with the guest machine'
+    'up:Creates the vagrant environment'
+    'validate:Validates the Vagrantfile'
+    'version:Prints current and latest Vagrant version'
+    '--help:[TASK] Describe available tasks or one specific task'
+    '--version:Prints the Vagrant version information'
+)
+
+local -a _box_arguments
+_box_arguments=(
+    'add:ADDRESS Adds a box to the system'
+    'help:COMMAND List subcommands'
+    'list:Lists all installed boxes'
+    'outdated:Checks if a box has newer version'
+    'remove:NAME Removes a box from the system'
+    'repackage:NAME PROVIDER VERSION Repackages an installed box into a `.box` file'
+    'update:Updates box to a newer version, if available'
+)
+
+__task_list ()
+{
+    local expl
+    declare -a tasks
+
+    tasks=(box destroy halt init package port provision reload resume ssh ssh_config status suspend up version)
+
+    _wanted tasks expl 'help' compadd $tasks
+}
+
+__box_list ()
+{
+    _wanted application expl 'command' compadd $(command vagrant box list | sed -e 's/  *(.*)//g;s/ /\\ /g')
+}
+
+__vm_list ()
+{
+    _wanted application expl 'command' compadd $(command grep "${VAGRANT_CWD:-.}/Vagrantfile" -oe '^[^#]*\.vm\.define *[:"]\([a-zA-Z0-9\._-]\+\)' 2>/dev/null | awk '{print substr($2, 2)}')
+    _wanted application expl 'command' compadd $(command ls "${VAGRANT_CWD:-.}/.vagrant/machines/" 2>/dev/null)
+}
+
+__vagrant-box ()
+{
+    local curcontext="$curcontext" state line
+    typeset -A opt_args
+
+    _arguments -C \
+        ':command:->command' \
+        '*::options:->options'
+
+   case $state in
+       (command)
+           _describe -t commands "vagrant subcommand" _box_arguments
+           return
+       ;;
+
+       (options)
+           case $line[1] in
+               (repackage|remove)
+                   _arguments ':feature:__box_list'
+               ;;
+           esac
+       ;;
+    esac
+}
+
+
+
+
+local expl
+local -a boxes installed_boxes
+
+local curcontext="$curcontext" state line
+typeset -A opt_args
+
+_arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+case $state in
+  (command)
+      _describe -t commands "vagrant subcommand" _1st_arguments
+      return
+  ;;
+
+  (options)
+    case $line[1] in
+      (help)
+         _arguments ':feature:__task_list'
+      ;;
+
+      (box)
+          __vagrant-box
+      ;;
+      (up|provision|port|package|destroy|reload|ssh|ssh-config|halt|resume|status)
+      _arguments ':feature:__vm_list'
+    esac
+  ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/vagrant.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/vagrant/vagrant.plugin.zsh
new file mode 100644 (file)
index 0000000..a4e9b06
--- /dev/null
@@ -0,0 +1,33 @@
+alias vgi="vagrant init"
+
+alias vup="vagrant up"
+alias vd="vagrant destroy"
+alias vdf="vagrant destroy -f"
+
+alias vssh="vagrant ssh"
+alias vsshc="vagrant ssh-config"
+alias vrdp="vagrant rdp"
+
+alias vh="vagrant halt"
+alias vssp="vagrant suspend"
+alias vst="vagrant status"
+alias vre="vagrant resume"
+alias vgs="vagrant global-status"
+
+alias vpr="vagrant provision"
+alias vr="vagrant reload"
+alias vrp="vagrant reload --provision"
+
+alias vp="vagrant push"
+alias vsh="vagrant share"
+
+alias vba="vagrant box add"
+alias vbr="vagrant box remove"
+alias vbl="vagrant box list"
+alias vbo="vagrant box outdated"
+alias vbu="vagrant box update"
+
+alias vpli="vagrant plugin install"
+alias vpll="vagrant plugin list"
+alias vplun="vagrant plugin uninstall"
+alias vplu="vagrant plugin update"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vault/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vault/README.md
new file mode 100644 (file)
index 0000000..69051d2
--- /dev/null
@@ -0,0 +1,15 @@
+# Vault plugin
+
+Note: this plugin is deprecated. Use the [official autocompletion](https://www.vaultproject.io/docs/commands/index.html#autocompletion) instead.
+
+-------
+
+Adds autocomplete options for all [vault](https://www.vaultproject.io) commands.
+
+To use it, add `vault` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... vault)
+```
+
+Crafted with <3 by Valentin Bud ([@valentinbud](https://twitter.com/valentinbud))
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vault/_vault b/stow/oh-my-zsh/.oh-my-zsh/plugins/vault/_vault
new file mode 100644 (file)
index 0000000..f6bd351
--- /dev/null
@@ -0,0 +1,400 @@
+#compdef vault
+
+typeset -a main_args
+main_args=(
+    '(-version)-version[Prints the Vault version]'
+    '(-help)-help[Prints Vault Help]'
+)
+
+typeset -a general_args
+general_args=(
+    '(-help)-help[Prints Help]'
+    '(-address)-address=-[The address of the Vault server. Overrides the VAULT_ADDR environment variable if set.]:address:'
+    '(-ca-cert)-ca-cert=-[Path to a PEM encoded CA cert file to use to verify the Vault server SSL certificate. Overrides the VAULT_CACERT environment variable if set.]:file:_files -g "*.pem"'
+    '(-ca-path)-ca-path=-[Path to a directory of PEM encoded CA cert files to verify the Vault server SSL certificate. If both -ca-cert and -ca-path are specified, -ca-path is used.Overrides the VAULT_CAPATH environment variable if set.]:directory:_directories'
+    '(-client-cert)-client-cert=-[Path to a PEM encoded client certificate for TLS authentication to the Vault server. Must also specify -client-key. Overrides the VAULT_CLIENT_CERT environment variable if set.]:file:_files -g "*.pem"'
+    '(-client-key)-client-key=-[Path to an unencrypted PEM encoded private key matching the client certificate from -client-cert. Overrides the VAULT_CLIENT_KEY environment variable if set.]:file:_files -g "*.pem"'
+    '(-tls-skip-verify)-tls-skip-verify[Do not verify TLS certificate. This is highly not recommended. Verification will also be skipped if VAULT_SKIP_VERIFY is set.]'
+)
+
+typeset -a audit_enable_args
+audit_enable_args=(
+    '(-description)-description=-[A human-friendly description for the backend. This shows up only when querying the enabled backends.]:description:'
+    '(-id)-id=-[Specify a unique ID for this audit backend. This is purely for referencing this audit backend. By default this will be the backend type.]:id:'
+)
+
+typeset -a auth_args
+auth_args=(
+    '(-method)-method=-[Outputs help for the authentication method with the given name for the remote server. If this authentication method is not available, exit with code 1.]:method:(cert ldap github userpass app-id)'
+    '(-method-help)-method-help[If set, the help for the selected method will be shown.]'
+    '(-methods)-methods[List the available auth methods.]'
+    '(-no-verify)-no-verify[Do not verify the token after creation; avoids a use count]'
+)
+
+typeset -a auth_enable_args
+auth_enable_args=(
+    '(-description)-description=-[Human-friendly description of the purpose for the auth provider. This shows up in the auth-list command.]:description:'
+    '(-path)-path=-[Mount point for the auth provider. This defaults to the type of the mount. This will make the auth provider available at "/auth/<path>"]:path:'
+)
+
+typeset -a init_args
+init_args=(
+    '(-key-shares)-key-shares=-[(default: 5) The number of key shares to split the master key into.]:keyshares:'
+    '(-key-threshold)-key-threshold=-[(default: 3) The number of key shares required to reconstruct the master key.]:keythreshold:'
+    '(-pgp-keys)-pgp-keys[If provided, must be a comma-separated list of files on disk containing binary- or base64-format public PGP keys. The number of files must match "key-shares". The output unseal keys will encrypted and hex-encoded, in order, with the given public keys. If you want to use them with the "vault unseal" command, you will need to hex decode and decrypt; this will be the plaintext unseal key.]:pgpkeys:_files'
+)
+
+typeset -a mount_tune_args
+mount_tune_args=(
+    '(-default-lease-ttl)-default-lease-ttl=-[Default lease time-to-live for this backend. If not specified, uses the system default, or the previously set value. Set to "system" to explicitly set it to use the system default.]:defaultleasettl:'
+    '(-max-lease-ttl)-max-lease-ttl=-[Max lease time-to-live for this backend. If not specified, uses the system default, or the previously set value. Set to "system" to explicitly set it to use the system default.]:maxleasettl:'
+)
+
+typeset -a mount_args
+mount_args=(
+    $mount_tune_args
+    '(-path)-path=-[Mount point for the logical backend. This defaults to the type of the mount.]:path:'
+    '(-description)-description=-[Human-friendly description of the purpose for the mount. This shows up in the mounts command.]:description:'
+)
+
+typeset -a rekey_args
+rekey_args=(
+    $init_args
+    '(-init)-init[Initialize the rekey operation by setting the desired number of shares and the key threshold. This can only be done if no rekey is already initiated.]:init:'
+    '(-cancel)-cancel[Reset the rekey process by throwing away prior keys and the rekey configuration.]:cancel:'
+    '(-status)-status[Prints the status of the current rekey operation. This can be used to see the status without attempting to provide an unseal key.]:status:'
+)
+
+typeset -a ssh_args
+ssh_args=(
+    '(-role)-role[Role to be used to create the key. ]:role:'
+    '(-no-exec)-no-exec[Shows the credentials but does not establish connection.]:noexec:'
+    '(-mount-point)-mount-point[Mount point of SSH backend. If the backend is mounted at "ssh", which is the default as well, this parameter can be skipped.]:mountpoint:'
+    '(-format)-format[If no-exec option is enabled, then the credentials will be printed out and SSH connection will not be established. The format of the output can be "json" or "table". JSON output is useful when writing scripts. Default is "table".]:format:(json table)'
+)
+
+typeset -a token_create_args
+token_create_args=(
+    '(-id)-id=-[The token value that clients will use to authenticate with vault. If not provided this defaults to a 36 character UUID. A root token is required to specify the ID of a token.]:id:'
+    '(-display-name)-display-name=-[A display name to associate with this token. This is a non-security sensitive value used to help identify created secrets, i.e. prefixes.]:displayname:'
+    '(-ttl)-ttl=-[TTL to associate with the token. This option enables the tokens to be renewable.]:ttl:'
+    '*-metadata=-[Metadata to associate with the token. This shows up in the audit log. This can be specified multiple times.]:metadata:'
+    '(-orphan)-orphan[If specified, the token will have no parent. Only root tokens can create orphan tokens. This prevents the new token from being revoked with your token.]:orphan:'
+    '(-no-default-policy)-no-default-policy[If specified, the token will not have the "default" policy included in its policy set.]:nodefaultpolicy:'
+    '*-policy=-[Policy to associate with this token. This can be specified multiple times.]:policy:__vault_policies'
+    '(-use-limit)-use-limit=-[The number of times this token can be used until it is automatically revoked.]:uselimit:'
+    '(-format)-format=-[The format for output. By default it is a whitespace-delimited table. This can also be json.]:format:(json table)'
+)
+
+typeset -a server_args
+server_args=(
+    '*-config=-[Path to the configuration file or directory. This can be specified multiple times. If it is a directory, all files with a ".hcl" or ".json" suffix will be loaded.]:config:_files'
+    '-dev[Enables Dev mode. In this mode, Vault is completely in-memory and unsealed. Do not run the Dev server in production!]:dev:'
+    '-log-level=-[Log verbosity. Defaults to "info", will be outputtedto stderr. Supported values: "trace", "debug", "info", "warn", "err"]:loglevel:(trace debug info warn err)'
+)
+
+_vault_audit-list() {
+    _arguments : \
+        ${general_args[@]} && ret=0
+}
+
+_vault_audit-disable() {
+    # vault audit-list doesn't print the backend id so for now
+    # no *smart* autocompletion for this subcommand.
+    _arguments : \
+        ${general_args[@]} \
+        ':::(file syslog)' && ret=0
+}
+
+_vault_audit-enable() {
+    _arguments : \
+        ${general_args[@]} \
+        ${audit_enable_args[@]} \
+        ': :->backends' \
+        '*:: :->backendconfig' && ret=0
+
+    case $state in
+        backends)
+            local -a backends
+            backends=(
+                'file:The "file" audit backend writes audit logs to a file.'
+                'syslog:The "syslog" audit backend writes audit logs to syslog.'
+            )
+            _describe -t backends 'vault audit backends' backends && ret=0
+            ;;
+        backendconfig)
+            case ${line[1]} in
+                file)
+                    _values -w "Audit Backend File" \
+                        'path[(required) - The path to where the file will be written. If this path exists, the audit backend will append to it.]:file:_files' \
+                        'log_raw[(optional) Should security sensitive information be logged raw. Defaults to "false".]:log_raw:(true false)' && ret=0
+                    ;;
+                syslog)
+                    _values -w "Audit Backend Syslog" \
+                        'facility[(optional) - The syslog facility to use. Defaults to "AUTH".]:facility:(kern user mail daemon auth syslog lpr news uucp authpriv ftp cron local0 local1 local2 local3 local4 local5 local6 local7)' \
+                        'tag[(optional) - The syslog tag to use. Defaults to "vault".]:tag:' \
+                        'log_raw[(optional) Should security sensitive information be logged raw.]:log_raw:(true false)' && ret=0
+                            ;;
+            esac
+            ;;
+    esac
+}
+
+_vault_auth() {
+    _arguments : \
+        ${general_args[@]} \
+        ${auth_args[@]} && ret=0
+}
+
+_vault_auth-enable() {
+    _arguments : \
+        ${general_args[@]} \
+        ${auth_enable_args[@]} \
+        ':::(cert ldap github userpass app-id)' && ret=0
+}
+
+__vault_auth_methods() {
+    local -a authmethods
+    authmethods=($(vault auth -methods | awk 'NR>1{split ($1,a,"/"); print a[1]":["$2"]"}'))
+    _describe -t authmethods 'authmethods' authmethods && ret=0
+}
+
+_vault_auth-disable() {
+    _arguments : \
+        ${general_args[@]} \
+        ':::__vault_auth_methods' && ret=0
+
+}
+
+_vault_init() {
+    _arguments : \
+        ${general_args[@]} \
+        ${init_args[@]} && ret=0
+}
+
+_vault_key-status() {
+    _arguments : \
+        ${general_args[@]} && ret=0
+}
+
+__vault_mounts() {
+    local -a mounts
+    mounts=($(vault mounts | awk 'NR>1{split ($1,a,"/"); print a[1]":["$2"]"}'))
+    _describe -t mounts 'mounts' mounts && ret=0
+}
+
+_vault_mounts() {
+    _arguments : \
+        ${general_args[@]} && ret=0
+}
+
+_vault_mount() {
+    # to find out how many types of backends are there
+    _arguments : \
+        ${general_args[@]} \
+        ${mount_args[@]} \
+        ':::(generic ssh)' && ret=0
+}
+
+_vault_mount-tune() {
+    _arguments : \
+        ${general_args[@]} \
+        ${mount_tune_args[@]} \
+        ':::__vault_mounts' && ret=0
+}
+
+_vault_unmount() {
+    _arguments : \
+        ${general_args[@]} \
+        ':::__vault_mounts' && ret=0
+}
+
+_vault_remount() {
+    _arguments : \
+        ${general_args[@]} \
+        ':::__vault_mounts' \
+        ':::'  && ret=0
+}
+
+__vault_policies() {
+    local -a policies
+    policies=($(vault policies | awk '{print $1":["$1"]"}'))
+    _describe -t policies 'policies' policies && ret=0
+}
+
+_vault_policies() {
+    _arguments : \
+        ${general_args[@]} \
+        ':::__vault_policies' && ret=0
+}
+
+_vault_policy-delete() {
+    _arguments : \
+        ${general_args[@]} \
+        ':::__vault_policies' && ret=0
+}
+
+_vault_policy-write() {
+    _arguments : \
+        ${general_args[@]} \
+        ': ::' \
+        '::policy:_files' && ret=0
+}
+
+_vault_status() {
+    _arguments : \
+        ${general_args[@]} && ret=0
+}
+
+_vault_rekey() {
+    _arguments : \
+        ${general_args[@]} \
+        ${rekey_args[@]} \
+        ': ::' && ret=0
+}
+
+_vault_rotate() {
+    _arguments : \
+        ${general_args[@]} && ret=0
+}
+
+_vault_seal() {
+    _arguments : \
+        ${general_args[@]} && ret=0
+}
+
+_vault_ssh() {
+    _arguments : \
+        ${general_args[@]} \
+        ${ssh_args[@]} \
+        ': ::' && ret=0
+}
+
+_vault_token-create() {
+    _arguments : \
+        ${general_args[@]} \
+        ${token_create_args[@]} && ret=0
+}
+
+_vault_token-renew() {
+    _arguments : \
+        ${general_args[@]} \
+        '(-format)-format=-[The format for output. By default it is a whitespace-delimited table. This can also be json.]:format:(json table)' \
+        ': ::' \
+        ': ::' && ret=0
+}
+
+_vault_token-revoke() {
+    _arguments : \
+        ${general_args[@]} \
+        '(-mode)-mode=-[The type of revocation to do. See the documentation above for more information.]:mode:(  orphan path)' \
+        ': ::' && ret=0
+}
+
+_vault_unseal() {
+    _arguments : \
+        ${general_args[@]} \
+        '(-reset)-reset[Reset the unsealing process by throwing away prior keys in process to unseal the vault.]:reset:' \
+        ': ::' && ret=0
+}
+
+_vault_version() {
+    # no args
+}
+
+_vault_delete() {
+    _arguments : \
+        ${general_args[@]} \
+        ': ::' && ret=0
+}
+
+_vault_path-help() {
+    _arguments : \
+        ${general_args[@]} \
+        ': ::' && ret=0
+}
+
+_vault_revoke() {
+    _arguments : \
+        ${general_args[@]} \
+        '(-format)-format=-[The format for output. By default it is a whitespace-delimited table. This can also be json.]:format:(json table)' \
+        ': ::' \
+        ': ::' && ret=0
+}
+
+_vault_server() {
+    _arguments : \
+        ${server_args[@]} && ret=0
+
+}
+
+_vault_write() {
+    _arguments : \
+        ${general_args[@]} \
+        '(-f -force)'{-f,-force}'[Force the write to continue without any data values specified. This allows writing to keys that do not need or expect any fields to be specified.]:force:' \
+        ': ::' \
+        ': ::' && ret=0
+}
+
+_vault_read() {
+    _arguments : \
+        ${general_args[@]} \
+        '(-format)-format=-[The format for output. By default it is a whitespace-delimited table. This can also be json.]:format:(json table)' \
+        '(-field)-field=-[If included, the raw value of the specified field will be output raw to stdout.]:field:' \
+        ': ::' && ret=0
+}
+
+_vault_commands() {
+    local -a commands
+
+    commands=(
+        "delete":"Delete operation on secrets in Vault"
+        "path-help":"Look up the help for a path"
+        "read":"Read data or secrets from Vault"
+        "renew":"Renew the lease of a secret"
+        "revoke":"Revoke a secret"
+        "server":"Start a Vault server"
+        "status":"Outputs status of whether Vault is sealed and if HA mode is enabled"
+        "write":"Write secrets or configuration into Vault"
+        "audit-disable":"Disable an audit backend"
+        "audit-enable":"Enable an audit backend"
+        "audit-list":"Lists enabled audit backends in Vault"
+        "auth":"Prints information about how to authenticate with Vault"
+        "auth-disable":"Disable an auth provider"
+        "auth-enable":"Enable a new auth provider"
+        "init":"Initialize a new Vault server"
+        "key-status":"Provides information about the active encryption key"
+        "mount":"Mount a logical backend"
+        "mount-tune":"Tune mount configuration parameters"
+        "mounts":"Lists mounted backends in Vault"
+        "policies":"List the policies on the server"
+        "policy-delete":"Delete a policy from the server"
+        "policy-write":"Write a policy to the server"
+        "rekey":"Rekeys Vault to generate new unseal keys"
+        "remount":"Remount a secret backend to a new path"
+        "rotate":"Rotates the backend encryption key used to persist data"
+        "seal":"Seals the vault server"
+        "ssh":"Initiate a SSH session"
+        "token-create":"Create a new auth token"
+        "token-renew":"Renew an auth token if there is an associated lease"
+        "token-revoke":"Revoke one or more auth tokens"
+        "unmount":"Unmount a secret backend"
+        "unseal":"Unseals the vault server"
+        "version":"Prints the Vault version"
+    )
+
+    _describe -t commands 'vault command' commands && ret=0
+}
+
+local curcontext=$curcontext ret=1
+_arguments : \
+    ${main_args[@]} \
+    '*:: :->subcommands' && ret=0
+if ((CURRENT == 1 )); then
+    _vault_commands && ret=0
+fi
+if [[ $state == subcommands ]]; then
+    # (( CURRENT -- ))
+    curcontext="${curcontext%:*:*}:vault-$words[1]:"
+    _call_function ret _vault_$words[1]
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vi-mode/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vi-mode/README.md
new file mode 100644 (file)
index 0000000..476666b
--- /dev/null
@@ -0,0 +1,132 @@
+# vi-mode plugin
+
+This plugin increase `vi-like` zsh functionality.
+
+To use it, add `vi-mode` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... vi-mode)
+```
+
+## Settings
+
+- `VI_MODE_RESET_PROMPT_ON_MODE_CHANGE`: controls whether the prompt is redrawn when
+  switching to a different input mode. If this is unset, the mode indicator will not
+  be updated when changing to a different mode.
+  Set it to `true` to enable it. For example:
+
+  ```zsh
+  VI_MODE_RESET_PROMPT_ON_MODE_CHANGE=true
+  ```
+
+  The default value is unset, unless `vi_mode_prompt_info` is used, in which case it'll
+  automatically be set to `true`.
+
+- `VI_MODE_SET_CURSOR`: controls whether the cursor style is changed when switching
+  to a different input mode. Set it to `true` to enable it (default: unset):
+
+  ```zsh
+  VI_MODE_SET_CURSOR=true
+  ```
+
+- `MODE_INDICATOR`: controls the string displayed when the shell is in normal mode.
+  See [Mode indicators](#mode-indicators) for details.
+
+- `INSERT_MODE_INDICATOR`: controls the string displayed when the shell is in insert mode.
+  See [Mode indicators](#mode-indicators) for details.
+
+## Mode indicators
+
+*Normal mode* is indicated with a red `<<<` mark at the right prompt, when it
+hasn't been defined by theme, *Insert mode* is not displayed by default.
+
+You can change these indicators by setting the `MODE_INDICATOR` (*Normal mode*) and
+`INSERT_MODE_INDICATORS` (*Insert mode*) variables.
+This settings support Prompt Expansion sequences. For example:
+
+```zsh
+MODE_INDICATOR="%F{white}+%f"
+INSERT_MODE_INDICATOR="%F{yellow}+%f"
+```
+
+You can also use the `vi_mode_prompt_info` function in your prompt, which will display
+this mode indicator.
+
+## Key bindings
+
+Use `ESC` or `CTRL-[` to enter `Normal mode`.
+
+NOTE: some of these key bindings are set by zsh by default when using a vi-mode keymap.
+
+### History
+
+- `ctrl-p` : Previous command in history
+- `ctrl-n` : Next command in history
+- `/`      : Search backward in history
+- `n`      : Repeat the last `/`
+
+### Vim edition
+
+- `vv`     : Edit current command line in Vim
+
+NOTE: this used to be bound to `v`. That is now the default (`visual-mode`).
+
+### Movement
+
+- `$`   : To the end of the line
+- `^`   : To the first non-blank character of the line
+- `0`   : To the first character of the line
+- `w`   : [count] words forward
+- `W`   : [count] WORDS forward
+- `e`   : Forward to the end of word [count] inclusive
+- `E`   : Forward to the end of WORD [count] inclusive
+- `b`   : [count] words backward
+- `B`   : [count] WORDS backward
+- `t{char}`   : Till before [count]'th occurrence of {char} to the right
+- `T{char}`   : Till before [count]'th occurrence of {char} to the left
+- `f{char}`   : To [count]'th occurrence of {char} to the right
+- `F{char}`   : To [count]'th occurrence of {char} to the left
+- `;`   : Repeat latest f, t, F or T [count] times
+- `,`   : Repeat latest f, t, F or T in opposite direction
+
+### Insertion
+
+- `i`   : Insert text before the cursor
+- `I`   : Insert text before the first character in the line
+- `a`   : Append text after the cursor
+- `A`   : Append text at the end of the line
+- `o`   : Insert new command line below the current one
+- `O`   : Insert new command line above the current one
+
+### Delete and Insert
+
+- `ctrl-h`      : While in *Insert mode*: delete character before the cursor
+- `ctrl-w`      : While in *Insert mode*: delete word before the cursor
+- `d{motion}`   : Delete text that {motion} moves over
+- `dd`          : Delete line
+- `D`           : Delete characters under the cursor until the end of the line
+- `c{motion}`   : Delete {motion} text and start insert
+- `cc`          : Delete line and start insert
+- `C`           : Delete to the end of the line and start insert
+- `r{char}`     : Replace the character under the cursor with {char}
+- `R`           : Enter replace mode: Each character replaces existing one
+- `x`           : Delete `count` characters under and after the cursor
+- `X`           : Delete `count` characters before the cursor
+
+## Known issues
+
+### Low `$KEYTIMEOUT`
+
+A low `$KEYTIMEOUT` value (< 15) means that key bindings that need multiple characters,
+like `vv`, will be very difficult to trigger. `$KEYTIMEOUT` controls the number of
+milliseconds that must pass before a key press is read and the appropriate key binding
+is triggered. For multi-character key bindings, the key presses need to happen before
+the timeout is reached, so on low timeouts the key press happens too slow, and therefore
+another key binding is triggered.
+
+We recommend either setting `$KEYTIMEOUT` to a higher value, or remapping the key bindings
+that you want to trigger to a keyboard sequence. For example:
+
+```zsh
+bindkey -M vicmd 'V' edit-command-line # this remaps `vv` to `V` (but overrides `visual-mode`)
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vi-mode/vi-mode.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/vi-mode/vi-mode.plugin.zsh
new file mode 100644 (file)
index 0000000..149d6bb
--- /dev/null
@@ -0,0 +1,145 @@
+# Control whether to force a redraw on each mode change.
+#
+# Resetting the prompt on every mode change can cause lag when switching modes.
+# This is especially true if the prompt does things like checking git status.
+#
+# Set to "true" to force the prompt to reset on each mode change.
+# Unset or set to any other value to do the opposite.
+#
+# The default is not to reset, unless we're showing the mode in RPS1.
+typeset -g VI_MODE_RESET_PROMPT_ON_MODE_CHANGE
+# Control whether to change the cursor style on mode change.
+#
+# Set to "true" to change the cursor on each mode change.
+# Unset or set to any other value to do the opposite.
+typeset -g VI_MODE_SET_CURSOR
+
+typeset -g VI_KEYMAP=main
+
+function _vi-mode-set-cursor-shape-for-keymap() {
+  [[ "$VI_MODE_SET_CURSOR" = true ]] || return
+
+  # https://vt100.net/docs/vt510-rm/DECSCUSR
+  local _shape=0
+  case "${1:-${VI_KEYMAP:-main}}" in
+    main)    _shape=6 ;; # vi insert: line
+    viins)   _shape=6 ;; # vi insert: line
+    isearch) _shape=6 ;; # inc search: line
+    command) _shape=6 ;; # read a command name
+    vicmd)   _shape=2 ;; # vi cmd: block
+    visual)  _shape=2 ;; # vi visual mode: block
+    viopp)   _shape=0 ;; # vi operation pending: blinking block
+    *)       _shape=0 ;;
+  esac
+  printf $'\e[%d q' "${_shape}"
+}
+
+# Updates editor information when the keymap changes.
+function zle-keymap-select() {
+  # update keymap variable for the prompt
+  typeset -g VI_KEYMAP=$KEYMAP
+
+  if [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" = true ]]; then
+    zle reset-prompt
+    zle -R
+  fi
+  _vi-mode-set-cursor-shape-for-keymap "${VI_KEYMAP}"
+}
+zle -N zle-keymap-select
+
+# These "echoti" statements were originally set in lib/key-bindings.zsh
+# Not sure the best way to extend without overriding.
+function zle-line-init() {
+  local prev_vi_keymap
+  prev_vi_keymap="${VI_KEYMAP:-}"
+  typeset -g VI_KEYMAP=main
+  [[ "$prev_vi_keymap" != 'main' ]] && [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" = true ]] && zle reset-prompt
+  (( ! ${+terminfo[smkx]} )) || echoti smkx
+  _vi-mode-set-cursor-shape-for-keymap "${VI_KEYMAP}"
+}
+zle -N zle-line-init
+
+function zle-line-finish() {
+  typeset -g VI_KEYMAP=main
+  (( ! ${+terminfo[rmkx]} )) || echoti rmkx
+  _vi-mode-set-cursor-shape-for-keymap default
+}
+zle -N zle-line-finish
+
+bindkey -v
+
+# allow vv to edit the command line (standard behaviour)
+autoload -Uz edit-command-line
+zle -N edit-command-line
+bindkey -M vicmd 'vv' edit-command-line
+
+# allow ctrl-p, ctrl-n for navigate history (standard behaviour)
+bindkey '^P' up-history
+bindkey '^N' down-history
+
+# allow ctrl-h, ctrl-w, ctrl-? for char and word deletion (standard behaviour)
+bindkey '^?' backward-delete-char
+bindkey '^h' backward-delete-char
+bindkey '^w' backward-kill-word
+
+# allow ctrl-r and ctrl-s to search the history
+bindkey '^r' history-incremental-search-backward
+bindkey '^s' history-incremental-search-forward
+
+# allow ctrl-a and ctrl-e to move to beginning/end of line
+bindkey '^a' beginning-of-line
+bindkey '^e' end-of-line
+
+function wrap_clipboard_widgets() {
+  # NB: Assume we are the first wrapper and that we only wrap native widgets
+  # See zsh-autosuggestions.zsh for a more generic and more robust wrapper
+  local verb="$1"
+  shift
+
+  local widget
+  local wrapped_name
+  for widget in "$@"; do
+    wrapped_name="_zsh-vi-${verb}-${widget}"
+    if [ "${verb}" = copy ]; then
+      eval "
+        function ${wrapped_name}() {
+          zle .${widget}
+          printf %s \"\${CUTBUFFER}\" | clipcopy 2>/dev/null || true
+        }
+      "
+    else
+      eval "
+        function ${wrapped_name}() {
+          CUTBUFFER=\"\$(clippaste 2>/dev/null || echo \$CUTBUFFER)\"
+          zle .${widget}
+        }
+      "
+    fi
+    zle -N "${widget}" "${wrapped_name}"
+  done
+}
+
+wrap_clipboard_widgets copy vi-yank vi-yank-eol vi-backward-kill-word vi-change-whole-line vi-delete vi-delete-char
+wrap_clipboard_widgets paste vi-put-{before,after}
+unfunction wrap_clipboard_widgets
+
+# if mode indicator wasn't setup by theme, define default, we'll leave INSERT_MODE_INDICATOR empty by default
+if [[ -z "$MODE_INDICATOR" ]]; then
+  MODE_INDICATOR='%B%F{red}<%b<<%f'
+fi
+
+function vi_mode_prompt_info() {
+  # If we're using the prompt to display mode info, and we haven't explicitly
+  # disabled "reset prompt on mode change", then set it here.
+  #
+  # We do that here instead of the `if` statement below because the user may
+  # set RPS1/RPROMPT to something else in their custom config.
+  : "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:=true}"
+
+  echo "${${VI_KEYMAP/vicmd/$MODE_INDICATOR}/(main|viins)/$INSERT_MODE_INDICATOR}"
+}
+
+# define right prompt, if it wasn't defined by a theme
+if [[ -z "$RPS1" && -z "$RPROMPT" ]]; then
+  RPS1='$(vi_mode_prompt_info)'
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vim-interaction/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vim-interaction/README.md
new file mode 100644 (file)
index 0000000..6816480
--- /dev/null
@@ -0,0 +1,82 @@
+# Vim Interaction #
+
+The plugin presents a function called `callvim` whose usage is:
+
+    usage: callvim [-b cmd] [-a cmd] [file ... fileN]
+    
+      -b cmd     Run this command in GVIM before editing the first file
+      -a cmd     Run this command in GVIM after editing the first file
+      file       The file to edit
+      ... fileN  The other files to add to the argslist
+
+## Rationale ##
+
+The idea for this script is to give you some decent interaction with a running
+GVim session.  Normally you'll be running around your filesystem doing any
+number of amazing things and you'll need to load some files into GVim for
+editing, inspecting, destruction, or other bits of mayhem.  This script lets you
+do that.
+
+## Aliases ##
+
+There are a few aliases presented as well:
+
+* `v` A shorthand for `callvim`
+* `vvsp` Edits the passed in file but first makes a vertical split
+* `vhsp` Edits the passed in file but first makes a horizontal split
+
+## Post Callout ##
+
+At the end of the `callvim` function we invoke the `postCallVim` function if it
+exists.  If you're using MacVim, for example, you could define a function that
+brings window focus to it after the file is loaded:
+
+    function postCallVim
+    {
+      osascript -e 'tell application "MacVim" to activate'
+    }
+
+This'll be different depending on your OS / Window Manager.
+
+## Examples ##
+
+This will load `/tmp/myfile.scala` into the running GVim session:
+
+    > v /tmp/myfile.scala
+
+This will load it after first doing a vertical split:
+
+    > vvsp /tmp/myfile.scala
+    or
+    > v -b':vsp' /tmp/myfile.scala
+
+This will load it after doing a horizontal split, then moving to the bottom of
+the file:
+
+    > vhsp -aG /tmp/myfile.scala
+    or
+    > v -b':sp' -aG /tmp/myfile.scala
+
+This will load the file and then copy the first line to the end (Why you would
+ever want to do this... I dunno):
+
+    > v -a':1t$' /tmp/myfile.scala
+
+And this will load all of the `*.txt` files into the args list:
+
+    > v *.txt
+
+If you want to load files into areas that are already split, use one of the
+aliases for that:
+
+    # Do a ':wincmd h' first
+    > vh /tmp/myfile.scala
+
+    # Do a ':wincmd j' first
+    > vj /tmp/myfile.scala
+
+    # Do a ':wincmd k' first
+    > vk /tmp/myfile.scala
+
+    # Do a ':wincmd l' first
+    > vl /tmp/myfile.scala
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vim-interaction/vim-interaction.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/vim-interaction/vim-interaction.plugin.zsh
new file mode 100644 (file)
index 0000000..b73f9b4
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# See README.md
+#
+# Derek Wyatt (derek@{myfirstnamemylastname}.org
+# 
+
+function callvim {
+  if [[ $# == 0 ]]; then
+    cat <<EOH
+usage: callvim [-b cmd] [-a cmd] [-n name] [file ... fileN]
+
+  -b cmd     Run this command in GVIM before editing the first file
+  -a cmd     Run this command in GVIM after editing the first file
+  -n name    Name of the GVIM server to connect to
+  file       The file to edit
+  ... fileN  The other files to add to the argslist
+EOH
+    return 0
+  fi
+
+  # Look up the newest instance or start one
+  local name="$(gvim --serverlist | tail -n 1)"
+  [[ -n "$name" ]] || {
+    # run gvim or exit if it fails
+    gvim || return $?
+
+    # wait for gvim instance to fully load
+    while name=$(gvim --serverlist) && [[ -z "$name" ]]; do
+      sleep 0.1
+    done
+  }
+
+  local before="<esc>" files after cmd
+
+  while getopts ":b:a:n:" option
+  do
+    case $option in
+      a) after="$OPTARG"
+         ;;
+      b) before="$OPTARG"
+         ;;
+      n) name="$OPTARG"
+         ;;
+    esac
+  done
+  shift $((OPTIND-1))
+
+  # If before or after commands begin with : and don't end with <cr>, append it
+  [[ ${after}  = :* && ${after}  != *\<cr\> ]] && after+="<cr>"
+  [[ ${before} = :* && ${before} != *\<cr\> ]] && before+="<cr>"
+  # Open files passed (:A means abs path resolving symlinks, :q means quoting special chars)
+  [[ $# -gt 0 ]] && files=':args! '"${@:A:q}<cr>"
+  # Pass the built vim command to gvim
+  cmd="$before$files$after"
+
+  # Run the gvim command
+  gvim --servername "$name" --remote-send "$cmd" || return $?
+
+  # Run postCallVim if defined (maybe to bring focus to gvim, see README)
+  (( ! $+functions[postCallVim] )) || postCallVim
+}
+
+alias v=callvim
+alias vvsp="callvim -b':vsp'"
+alias vhsp="callvim -b':sp'"
+alias vk="callvim -b':wincmd k'"
+alias vj="callvim -b':wincmd j'"
+alias vl="callvim -b':wincmd l'"
+alias vh="callvim -b':wincmd h'"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenv/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenv/README.md
new file mode 100644 (file)
index 0000000..e0b8c2c
--- /dev/null
@@ -0,0 +1,15 @@
+# virtualenv
+
+The plugin displays information of the created virtual container and allows background theming.
+
+To use it, add `virtualenv` to the plugins array of your zshrc file:
+```
+plugins=(... virtualenv)
+```
+
+The plugin creates a `virtualenv_prompt_info` function that you can use in your theme, which displays
+the basename of the current `$VIRTUAL_ENV`. It uses two variables to control how that is shown:
+
+- `ZSH_THEME_VIRTUALENV_PREFIX`: sets the prefix of the VIRTUAL_ENV. Defaults to `[`.
+
+- `ZSH_THEME_VIRTUALENV_SUFFIX`: sets the suffix of the VIRTUAL_ENV. Defaults to `]`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenv/virtualenv.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenv/virtualenv.plugin.zsh
new file mode 100644 (file)
index 0000000..56707bb
--- /dev/null
@@ -0,0 +1,7 @@
+function virtualenv_prompt_info(){
+  [[ -n ${VIRTUAL_ENV} ]] || return
+  echo "${ZSH_THEME_VIRTUALENV_PREFIX=[}${VIRTUAL_ENV:t:gs/%/%%}${ZSH_THEME_VIRTUALENV_SUFFIX=]}"
+}
+
+# disables prompt mangling in virtual_env/bin/activate
+export VIRTUAL_ENV_DISABLE_PROMPT=1
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenvwrapper/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenvwrapper/README.md
new file mode 100644 (file)
index 0000000..63eb585
--- /dev/null
@@ -0,0 +1,38 @@
+# Virtualenvwrapper plugin
+
+This plugin loads Python's [virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/) shell tools.
+
+To use it, add `virtualenvwrapper` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... virtualenvwrapper)
+```
+
+## Usage
+
+The plugin allows to automatically activate virtualenvs on cd into git repositories with a matching name:
+
+```
+➜  github $ cd ansible
+(ansible) ➜  ansible git:(devel) $ cd docs
+(ansible) ➜  docs git:(devel) $ cd ..
+(ansible) ➜  ansible git:(devel) $ cd ..
+➜  github $
+```
+
+We can override this by having a `.venv` file in the directory containing a differently named virtualenv:
+
+```
+➜  github $ cat ansible/.venv
+myvirtualenv
+➜  github $ cd ansible
+(myvirtualenv) ➜  ansible git:(devel) $ cd ..
+➜  github $
+```
+
+We can disable this behaviour by setting `DISABLE_VENV_CD=1` before Oh My Zsh is sourced:
+```zsh
+DISABLE_VENV_CD=1
+plugins=(... virtualenvwrapper)
+source $ZSH/oh-my-zsh.sh
+```
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/virtualenvwrapper/virtualenvwrapper.plugin.zsh
new file mode 100644 (file)
index 0000000..d359e0c
--- /dev/null
@@ -0,0 +1,91 @@
+function {
+    # search in these locations for the init script:
+    for virtualenvwrapper in $commands[virtualenvwrapper_lazy.sh] \
+      $commands[virtualenvwrapper.sh] \
+      /usr/share/virtualenvwrapper/virtualenvwrapper{_lazy,}.sh \
+      /usr/local/bin/virtualenvwrapper{_lazy,}.sh \
+      /etc/bash_completion.d/virtualenvwrapper \
+      /usr/share/bash-completion/completions/virtualenvwrapper \
+      $HOME/.local/bin/virtualenvwrapper.sh
+    do
+        if [[ -f "$virtualenvwrapper" ]]; then
+            source "$virtualenvwrapper"
+            return
+        fi
+    done
+    print "[oh-my-zsh] virtualenvwrapper plugin: Cannot find virtualenvwrapper.sh.\n"\
+          "Please install with \`pip install virtualenvwrapper\`" >&2
+    return 1
+}
+
+if [[ $? -eq 0 ]] && ! type workon &>/dev/null; then
+  print "[oh-my-zsh] virtualenvwrapper plugin: shell function 'workon' not defined.\n"\
+        "Please check ${virtualenvwrapper}" >&2
+  return
+fi
+
+if [[ -z "$WORKON_HOME" ]]; then
+  WORKON_HOME="$HOME/.virtualenvs"
+fi
+
+if [[ ! $DISABLE_VENV_CD -eq 1 ]]; then
+  # Automatically activate Git projects or other customized virtualenvwrapper projects based on the
+  # directory name of the project. Virtual environment name can be overridden
+  # by placing a .venv file in the project root with a virtualenv name in it.
+  function workon_cwd {
+    if [[ -z "$WORKON_CWD" ]]; then
+      local WORKON_CWD=1
+      # Get absolute path, resolving symlinks
+      local PROJECT_ROOT="${PWD:A}"
+      while [[ "$PROJECT_ROOT" != "/" && ! -e "$PROJECT_ROOT/.venv" \
+          && ! -d "$PROJECT_ROOT/.git" ]]; do
+        PROJECT_ROOT="${PROJECT_ROOT:h}"
+      done
+
+      # Check for virtualenv name override
+      if [[ -f "$PROJECT_ROOT/.venv" ]]; then
+        ENV_NAME="$(cat "$PROJECT_ROOT/.venv")"
+      elif [[ -f "$PROJECT_ROOT/.venv/bin/activate" ]];then
+        ENV_NAME="$PROJECT_ROOT/.venv"
+      elif [[ "$PROJECT_ROOT" != "/" ]]; then
+        ENV_NAME="${PROJECT_ROOT:t}"
+      else
+        ENV_NAME=""
+      fi
+      
+      if [[ -n $CD_VIRTUAL_ENV && "$ENV_NAME" != "$CD_VIRTUAL_ENV" ]]; then
+        # We've just left the repo, deactivate the environment
+        # Note: this only happens if the virtualenv was activated automatically
+        if [[ -n "$VIRTUAL_ENV" ]]; then
+          # Only deactivate if VIRTUAL_ENV was set
+          # User may have deactivated manually or via another mechanism
+          deactivate
+        fi
+        # clean up regardless
+        unset CD_VIRTUAL_ENV
+      fi
+      if [[ "$ENV_NAME" != "" ]]; then
+        # Activate the environment only if it is not already active
+        if [[ ! "$VIRTUAL_ENV" -ef "$WORKON_HOME/$ENV_NAME" ]]; then
+          if [[ -e "$WORKON_HOME/$ENV_NAME/bin/activate" ]]; then
+            workon "$ENV_NAME" && export CD_VIRTUAL_ENV="$ENV_NAME"
+          elif [[ -e "$ENV_NAME/bin/activate" ]]; then
+            source $ENV_NAME/bin/activate && export CD_VIRTUAL_ENV="$ENV_NAME"
+          else
+            ENV_NAME=""
+          fi
+        fi
+      fi
+      if [[ "$ENV_NAME" == "" && -n $CD_VIRTUAL_ENV && -n $VIRTUAL_ENV ]]; then
+        # We've just left the repo, deactivate the environment
+        # Note: this only happens if the virtualenv was activated automatically
+        deactivate && unset CD_VIRTUAL_ENV
+      fi
+    fi
+  }
+
+  # Append workon_cwd to the chpwd_functions array, so it will be called on cd
+  # http://zsh.sourceforge.net/Doc/Release/Functions.html
+  autoload -U add-zsh-hook
+  add-zsh-hook chpwd workon_cwd
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/volta/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/volta/README.md
new file mode 100644 (file)
index 0000000..d5972d5
--- /dev/null
@@ -0,0 +1,11 @@
+# Volta
+
+This plugin provides completion for [Volta](https://volta.sh/).
+
+To use it add volta to the plugins array in your zshrc file.
+
+```bash
+plugins=(... volta)
+```
+
+This plugin installs no aliases.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/volta/volta.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/volta/volta.plugin.zsh
new file mode 100644 (file)
index 0000000..ab05ed5
--- /dev/null
@@ -0,0 +1,14 @@
+# COMPLETION FUNCTION
+if (( ! $+commands[volta] )); then
+  return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `deno`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_volta" ]]; then
+  typeset -g -A _comps
+  autoload -Uz _volta
+  _comps[volta]=_volta
+fi
+
+volta completions zsh >| "$ZSH_CACHE_DIR/completions/_volta" &|
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vscode/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vscode/README.md
new file mode 100644 (file)
index 0000000..e95ed5d
--- /dev/null
@@ -0,0 +1,78 @@
+# VS Code
+
+This plugin provides useful aliases to simplify the interaction between the command line and VS Code or VSCodium editor.
+
+To start using it, add the `vscode` plugin to your `plugins` array in `~/.zshrc`:
+
+```zsh
+plugins=(... vscode)
+```
+
+## Requirements
+
+This plugin requires to have a flavour of VS Code installed and it's executable available in PATH.
+
+You can install either:
+
+* VS Code (code)
+* VS Code Insiders (code-insiders)
+* VSCodium (codium)
+
+### MacOS
+While Linux installations will add the executable to PATH, MacOS users might still have to do this manually:
+
+[For VS Code and VS Code Insiders](https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line), open
+the Command Palette via (F1 or ⇧⌘P) and type shell command to find the Shell Command:
+> Shell Command: Install 'code' command in PATH
+
+[For VSCodium](https://github.com/VSCodium/vscodium/blob/master/DOCS.md#how-do-i-open-vscodium-from-the-terminal), open
+the Command Palette via (F1 or ⇧⌘P) and type shell command to find the Shell Command:
+> Shell Command: Install 'codium' command in PATH
+
+## Using multiple flavours
+
+If for any reason, you ever require to use multiple flavours of VS Code i.e. VS Code (stable) and VS Code Insiders, you can 
+manually specify the flavour's executable. Add the following line to the .zshrc file (between the `ZSH_THEME` and the `plugins=()` lines).
+This will make the plugin use your manually defined executable.
+
+```zsh
+ZSH_THEME=...
+
+# Choose between one [code, code-insiders or codium]
+# The following line will make the plugin to open VS Code Insiders
+# Invalid entries will be ignored, no aliases will be added
+VSCODE=code-insiders
+
+plugins=(... vscode)
+
+source $ZSH/oh-my-zsh.sh
+```
+
+## Common aliases
+
+| Alias                   | Command                        | Description                                                                                                 |
+| ----------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
+| vsc                     | code .                         | Open the current folder in VS code                                                                          |
+| vsca `dir`              | code --add `dir`               | Add folder(s) to the last active window                                                                     |
+| vscd `file` `file`      | code --diff `file` `file`      | Compare two files with each other.                                                                          |
+| vscg `file:line[:char]` | code --goto `file:line[:char]` | Open a file at the path on the specified line and character position.                                       |
+| vscn                    | code --new-window              | Force to open a new window.                                                                                 |
+| vscr                    | code --reuse-window            | Force to open a file or folder in the last active window.                                                   |
+| vscw                    | code --wait                    | Wait for the files to be closed before returning.                                                           |
+| vscu `dir`              | code --user-data-dir `dir`     | Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code. |
+
+## Extensions aliases
+
+| Alias                   | Command                                                          | Description                       |
+| ----------------------- | ---------------------------------------------------------------- | --------------------------------- |
+| vsced `dir`             | code --extensions-dir `dir`                                      | Set the root path for extensions. |
+| vscie `id or vsix-path` | code --install-extension `extension-id> or <extension-vsix-path` | Installs an extension.            |
+| vscue `id or vsix-path` | code --uninstall-extension `id or vsix-path`                     | Uninstalls an extension.          |
+
+## Other options:
+
+| Alias        | Command                   | Description                                                                                                           |
+| ------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------- |
+| vscv         | code --verbose            | Print verbose output (implies --wait).                                                                                |
+| vscl `level` | code --log `level`        | Log level to use. Default is 'info'. Allowed values are 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'. |
+| vscde        | code --disable-extensions | Disable all installed extensions.                                                                                     |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vscode/vscode.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/vscode/vscode.plugin.zsh
new file mode 100644 (file)
index 0000000..48d9043
--- /dev/null
@@ -0,0 +1,41 @@
+# VS Code (stable / insiders) / VSCodium zsh plugin
+# Authors:
+#   https://github.com/MarsiBarsi (original author)
+#   https://github.com/babakks
+#   https://github.com/SteelShot
+
+# Verify if any manual user choice of VS Code exists first.
+if [[ -n "$VSCODE" ]] && ! which $VSCODE &>/dev/null; then
+  echo "'$VSCODE' flavour of VS Code not detected."
+  unset VSCODE
+fi
+
+# Otherwise, try to detect a flavour of VS Code.
+if [[ -z "$VSCODE" ]]; then
+  if which code &>/dev/null; then
+    VSCODE=code
+  elif which code-insiders &>/dev/null; then
+    VSCODE=code-insiders
+  elif which codium &>/dev/null; then
+    VSCODE=codium
+  else
+    return
+  fi
+fi
+
+alias vsc="$VSCODE ."
+alias vsca="$VSCODE --add"
+alias vscd="$VSCODE --diff"
+alias vscg="$VSCODE --goto"
+alias vscn="$VSCODE --new-window"
+alias vscr="$VSCODE --reuse-window"
+alias vscw="$VSCODE --wait"
+alias vscu="$VSCODE --user-data-dir"
+
+alias vsced="$VSCODE --extensions-dir"
+alias vscie="$VSCODE --install-extension"
+alias vscue="$VSCODE --uninstall-extension"
+
+alias vscv="$VSCODE --verbose"
+alias vscl="$VSCODE --log"
+alias vscde="$VSCODE --disable-extensions"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vundle/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/vundle/README.md
new file mode 100644 (file)
index 0000000..4990385
--- /dev/null
@@ -0,0 +1,19 @@
+# Vundle plugin
+
+This plugin adds functions to control [vundle](https://github.com/VundleVim/Vundle.vim) plug-in manager for vim.
+
+To use it, add `vundle` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... vundle)
+```
+
+## Functions
+
+| Function      | Usage           | Description                                                                |
+|---------------|-----------------|----------------------------------------------------------------------------|
+| vundle-init   | `vundle-init`   | Install vundle by cloning git repository into ~/.vim folder                |
+| vundle        | `vundle`        | Install plugins set in .vimrc (equals `:PluginInstall`)                    |
+| vundle-update | `vundle-update` | Update plugins set in .vimrc (equals `:PluginInstall!`)                    |
+| vundle-clean  | `vundle-clean`  | Delete plugins that have been removed from .vimrc (equals `:PluginClean!`) |
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/vundle/vundle.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/vundle/vundle.plugin.zsh
new file mode 100644 (file)
index 0000000..c84cacd
--- /dev/null
@@ -0,0 +1,27 @@
+function vundle-init () {
+  if [ ! -d ~/.vim/bundle/Vundle.vim/ ]
+  then
+    mkdir -p ~/.vim/bundle/Vundle.vim/
+  fi
+
+  if [ ! -d ~/.vim/bundle/Vundle.vim/.git ] && [ ! -f ~/.vim/bundle/Vundle.vim/.git ]
+  then
+    git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
+    echo "\n\tRead about vim configuration for vundle at https://github.com/VundleVim/Vundle.vim\n"
+  fi
+}
+
+function vundle () {
+  vundle-init
+  vim -c "execute \"PluginInstall\" | qa"
+}
+
+function vundle-update () {
+  vundle-init
+  vim -c "execute \"PluginInstall!\" | qa"
+}
+
+function vundle-clean () {
+  vundle-init
+  vim -c "execute \"PluginClean!\" | qa"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/README.md
new file mode 100644 (file)
index 0000000..3fcb6d7
--- /dev/null
@@ -0,0 +1,43 @@
+# wakeonlan
+
+This plugin provides a wrapper around the "wakeonlan" tool available from most
+distributions' package repositories, or from [the following website](https://github.com/jpoliv/wakeonlan).
+
+To use it, add `wakeonlan` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... wakeonlan)
+```
+
+## Usage
+
+In order to use this wrapper, create the `~/.wakeonlan` directory, and place in
+that directory one file for each device you would like to be able to wake. Give
+the file a name that describes the device, such as its hostname. Each file
+should contain a line with the mac address of the target device and the network
+broadcast address.
+
+For instance, there might be a file ~/.wakeonlan/leto with the following
+contents:
+
+```
+00:11:22:33:44:55:66 192.168.0.255
+```
+
+To wake that device, use the following command:
+
+```console
+$ wake leto
+```
+
+The available device names will be autocompleted, so:
+
+```console
+$ wake <tab>
+```
+
+...will suggest "leto", along with any other configuration files that were
+placed in the ~/.wakeonlan directory.
+
+For more information regarding the configuration file format, check the
+wakeonlan man page.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/_wake b/stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/_wake
new file mode 100644 (file)
index 0000000..4ab10d3
--- /dev/null
@@ -0,0 +1,4 @@
+#compdef wake
+#autoload
+
+_arguments "1:device to wake:_files -W '$HOME/.wakeonlan'" && return 0
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/wakeonlan.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/wakeonlan/wakeonlan.plugin.zsh
new file mode 100644 (file)
index 0000000..6cef7d4
--- /dev/null
@@ -0,0 +1,14 @@
+function wake() {
+  local config_file="$HOME/.wakeonlan/$1"
+  if [[ ! -f "$config_file" ]]; then
+    echo "ERROR: There is no configuration file at \"$config_file\"."
+    return 1
+  fi
+
+  if (( ! $+commands[wakeonlan] )); then
+    echo "ERROR: Can't find \"wakeonlan\".  Are you sure it's installed?"
+    return 1
+  fi
+
+  wakeonlan -f "$config_file"
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/LICENSE b/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/LICENSE
new file mode 100644 (file)
index 0000000..8caa6c6
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Markus Færevaag
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/README.md
new file mode 100644 (file)
index 0000000..8791f9f
--- /dev/null
@@ -0,0 +1,260 @@
+# wd
+
+[![Build Status](https://travis-ci.org/mfaerevaag/wd.png?branch=master)](https://travis-ci.org/mfaerevaag/wd)
+
+`wd` (*warp directory*) lets you jump to custom directories in zsh, without using `cd`.
+Why?
+Because `cd` seems inefficient when the folder is frequently visited or has a long path.
+
+![tty.gif](https://raw.githubusercontent.com/mfaerevaag/wd/master/tty.gif)
+
+## Setup
+
+### [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh)
+
+`wd` comes bundled with oh-my-zsh!
+
+Just add the plugin in your `.zshrc` file:
+
+```zsh
+plugins=(... wd)
+```
+
+### [Antigen](https://github.com/zsh-users/antigen)
+
+In your `.zshrc`:
+
+```zsh
+antigen bundle mfaerevaag/wd
+```
+
+### [Antibody](https://github.com/getantibody/antibody)
+
+In your `.zshrc`:
+
+```zsh
+antibody bundle mfaerevaag/wd
+```
+
+### Arch ([AUR](https://aur.archlinux.org/packages/zsh-plugin-wd-git/))
+
+1. Install from the AUR
+
+```zsh
+yay -S zsh-plugin-wd-git
+# or use any other AUR helper
+```
+
+2. Then add to your `.zshrc`:
+
+```zsh
+wd() {
+    . /usr/share/wd/wd.sh
+}
+```
+
+### [zplug](https://github.com/zplug/zplug)
+
+```zsh
+zplug "mfaerevaag/wd", as:command, use:"wd.sh", hook-load:"wd() { . $ZPLUG_REPOS/mfaerevaag/wd/wd.sh }"
+```
+
+### Automatic
+
+_Note: automatic install does not provide the manpage. It is also poor security practice to run remote code without first reviewing it, so you ought to look [here](https://github.com/mfaerevaag/wd/blob/master/install.sh)_
+
+Run either command in your terminal:
+
+```zsh
+curl -L https://github.com/mfaerevaag/wd/raw/master/install.sh | sh
+```
+
+or
+
+```zsh
+wget --no-check-certificate https://github.com/mfaerevaag/wd/raw/master/install.sh -O - | sh
+```
+
+### Manual
+
+1. Clone this repository on your local machine in a sensible location (if you know what you're doing of course all of this is up to you):
+
+```zsh
+git clone git@github.com:mfaerevaag/wd.git ~/.local/wd --depth 1
+```
+
+2. Add `wd` function to `.zshrc` (or `.profile` etc.):
+
+```zsh
+wd() {
+    . ~/.local/wd/wd.sh
+}
+```
+
+3. Install manpage (optional):
+
+```zsh
+sudo cp ~/.local/wd/wd.1 /usr/share/man/man1/wd.1
+sudo chmod 644 /usr/share/man/man1/wd.1
+```
+
+**Note:** when pulling and updating `wd`, you'll need to repeat step 3 should the manpage change
+
+## Completion
+
+If you're NOT using [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) and you want to utilize the zsh-completion feature, you will also need to add the path to your `wd` installation (`~/bin/wd` if you used the automatic installer) to your `fpath`.
+E.g. in your `~/.zshrc`:
+
+```zsh
+fpath=(~/path/to/wd $fpath)
+```
+
+Also, you may have to force a rebuild of `zcompdump` by running:
+
+```zsh
+rm -f ~/.zcompdump; compinit
+```
+
+## Usage
+
+* Add warp point to current working directory:
+
+```zsh
+wd add foo
+```
+
+If a warp point with the same name exists, use `wd add foo --force` to overwrite it.
+
+**Note:** a warp point cannot contain colons, or consist of only spaces and dots.
+The first will conflict in how `wd` stores the warp points, and the second will conflict with other features, as below.
+
+You can omit point name to automatically use the current directory's name instead.
+
+* From any directory, warp to `foo` with:
+
+```zsh
+wd foo
+```
+
+* You can also warp to a directory within `foo`, with autocompletion:
+
+```zsh
+wd foo some/inner/path
+```
+
+* You can warp back to previous directory and higher, with this dot syntax:
+
+```zsh
+wd ..
+wd ...
+```
+
+This is a wrapper for the zsh's `dirs` function.  
+_You might need to add `setopt AUTO_PUSHD` to your `.zshrc` if you are not using [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh)._
+
+* Remove warp point:
+
+```zsh
+wd rm foo
+```
+
+You can omit point name to use the current directory's name instead.
+
+* List all warp points (stored in `~/.warprc` by default):
+
+```zsh
+wd list
+```
+
+* List files in given warp point:
+
+```zsh
+wd ls foo
+```
+
+* Show path of given warp point:
+
+```zsh
+wd path foo
+```
+
+* List warp points to current directory, or optionally, path to given warp point:
+
+```zsh
+wd show
+```
+
+* Remove warp points to non-existent directories.
+
+```zsh
+wd clean
+```
+
+Use `wd clean --force` to not be prompted with confirmation.
+
+* Print usage info:
+
+```zsh
+wd help
+```
+
+The usage will be printed also if you call `wd` with no command
+
+* Print the running version of `wd`:
+
+```zsh
+wd --version
+```
+
+* Specifically set the config file (default being `~/.warprc`), which is useful for testing:
+
+```zsh
+wd --config ./file <command>
+```
+
+* Force `exit` with return code after running. This is not default, as it will *exit your terminal*, though required for testing/debugging.
+
+```zsh
+wd --debug <command>
+```
+
+* Silence all output:
+
+```zsh
+wd --quiet <command>
+```
+
+## Configuration
+
+You can configure `wd` with the following environment variables:
+
+### `WD_CONFIG`
+
+Defines the path where warp points get stored. Defaults to `$HOME/.warprc`.
+
+## Testing
+
+`wd` comes with a small test suite, run with [shunit2](https://github.com/kward/shunit2). This can be used to confirm that things are working as they should on your setup, or to demonstrate an issue.
+
+To run, simply `cd` into the `test` directory and run the `tests.sh`.
+
+```zsh
+cd ./test
+./tests.sh
+```
+
+## Maintainers
+
+Following @mfaerevaag stepping away from active maintainership of this repository, the following users now are also maintainers of the repo:
+
+* @alpha-tango-kilo
+
+* @MattLewin
+
+Anyone else contributing is greatly appreciated and will be mentioned in the release notes!
+
+---
+
+Credit to [altschuler](https://github.com/altschuler) for an awesome idea.
+
+Hope you enjoy!
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/_wd.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/_wd.sh
new file mode 100644 (file)
index 0000000..8d5cf15
--- /dev/null
@@ -0,0 +1,98 @@
+#compdef wd
+
+zstyle ':completion::complete:wd:*:descriptions' format '%B%d%b'
+zstyle ':completion::complete:wd:*:commands' group-name commands
+zstyle ':completion::complete:wd:*:warp_points' group-name warp_points
+zstyle ':completion::complete:wd::' list-grouped
+
+zmodload zsh/mapfile
+
+function _wd() {
+  local WD_CONFIG=${WD_CONFIG:-$HOME/.warprc}
+  local ret=1
+
+  local -a commands
+  local -a warp_points
+
+  warp_points=( "${(f)mapfile[$WD_CONFIG]//$HOME/~}" )
+
+  typeset -A points
+  while read -r line
+  do
+    arr=(${(s,:,)line})
+    name=${arr[1]}
+    target_path=${arr[2]}
+
+    # replace ~ from path to fix completion (#17)
+    target_path=${target_path/#\~/$HOME}
+
+    points[$name]=$target_path
+  done < $WD_CONFIG
+
+  commands=(
+    'add:Adds the current working directory to your warp points'
+    'add!:Overwrites existing warp point'
+    'export:Export warp points as static named directories'
+    'rm:Removes the given warp point'
+    'list:Outputs all stored warp points'
+    'ls:Show files from given warp point'
+    'path:Show path to given warp point'
+    'show:Outputs all warp points that point to the current directory or shows a specific target directory for a point'
+    'help:Show this extremely helpful text'
+    'clean:Remove points warping to nonexistent directories'
+    'clean!:Remove nonexistent directories without confirmation'
+    '..:Go back to last directory'
+  )
+
+  _arguments -C \
+    '1: :->first_arg' \
+    '2: :->second_arg' && ret=0
+
+  local target=$words[2]
+
+  case $state in
+    first_arg)
+      _describe -t warp_points "Warp points" warp_points && ret=0
+      _describe -t commands "Commands" commands && ret=0
+      ;;
+    second_arg)
+      case $target in
+        add\!|rm)
+          _describe -t points "Warp points" warp_points && ret=0
+          ;;
+        add)
+          _message 'Write the name of your warp point' && ret=0
+          ;;
+        show)
+          _describe -t points "Warp points" warp_points && ret=0
+          ;;
+        ls)
+          _describe -t points "Warp points" warp_points && ret=0
+          ;;
+        path)
+          _describe -t points "Warp points" warp_points && ret=0
+          ;;
+        *)
+          if [[ -v points[$target] ]]; then
+            # complete sub directories from the warp point
+            _path_files -W "(${points[$target]})" -/ && ret=0
+          fi
+          
+          # don't complete anything if warp point is not valid
+          ;;
+      esac
+      ;;
+  esac
+
+  return $ret
+}
+
+_wd "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/wd.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/wd.plugin.zsh
new file mode 100644 (file)
index 0000000..ca2ca7c
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/zsh
+
+# WARP DIRECTORY
+# ==============
+# Jump to custom directories in terminal
+# because `cd` takes too long...
+#
+# @github.com/mfaerevaag/wd
+
+# Handle $0 according to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+eval "wd() { source '${0:A:h}/wd.sh' }"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/wd.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/wd/wd.sh
new file mode 100644 (file)
index 0000000..9085c5b
--- /dev/null
@@ -0,0 +1,501 @@
+#!/bin/zsh
+
+# WARP DIRECTORY
+# ==============
+# Jump to custom directories in terminal
+# because `cd` takes too long...
+#
+# @github.com/mfaerevaag/wd
+
+# version
+readonly WD_VERSION=0.5.0
+
+# colors
+readonly WD_BLUE="\033[96m"
+readonly WD_GREEN="\033[92m"
+readonly WD_YELLOW="\033[93m"
+readonly WD_RED="\033[91m"
+readonly WD_NOC="\033[m"
+
+## functions
+
+# helpers
+wd_yesorno()
+{
+    # variables
+    local question="${1}"
+    local prompt="${question} "
+    local yes_RETVAL="0"
+    local no_RETVAL="3"
+    local RETVAL=""
+    local answer=""
+
+    # read-eval loop
+    while true ; do
+        printf $prompt
+        read -r answer
+
+        case ${answer:=${default}} in
+            "Y"|"y"|"YES"|"yes"|"Yes" )
+                RETVAL=${yes_RETVAL} && \
+                    break
+                ;;
+            "N"|"n"|"NO"|"no"|"No" )
+                RETVAL=${no_RETVAL} && \
+                    break
+                ;;
+            * )
+                echo "Please provide a valid answer (y or n)"
+                ;;
+        esac
+    done
+
+    return ${RETVAL}
+}
+
+wd_print_msg()
+{
+    if [[ -z $wd_quiet_mode ]]
+    then
+        local color=$1
+        local msg=$2
+
+        if [[ $color == "" || $msg == "" ]]
+        then
+            print " ${WD_RED}*${WD_NOC} Could not print message. Sorry!"
+        else
+            print " ${color}*${WD_NOC} ${msg}"
+        fi
+    fi
+}
+
+wd_print_usage()
+{
+    command cat <<- EOF
+Usage: wd [command] [point]
+
+Commands:
+    <point>         Warps to the directory specified by the warp point
+    <point> <path>  Warps to the directory specified by the warp point with path appended
+    add <point>     Adds the current working directory to your warp points
+    add             Adds the current working directory to your warp points with current directory's name
+    rm <point>      Removes the given warp point
+    rm              Removes the given warp point with current directory's name
+    show <point>    Print path to given warp point
+    show            Print warp points to current directory
+    list            Print all stored warp points
+    ls  <point>     Show files from given warp point (ls)
+    path <point>    Show the path to given warp point (pwd)
+    clean           Remove points warping to nonexistent directories (will prompt unless --force is used)
+
+    -v | --version  Print version
+    -d | --debug    Exit after execution with exit codes (for testing)
+    -c | --config   Specify config file (default ~/.warprc)
+    -q | --quiet    Suppress all output
+    -f | --force    Allows overwriting without warning (for add & clean)
+
+    help            Show this extremely helpful text
+EOF
+}
+
+wd_exit_fail()
+{
+    local msg=$1
+
+    wd_print_msg "$WD_RED" "$msg"
+    WD_EXIT_CODE=1
+}
+
+wd_exit_warn()
+{
+    local msg=$1
+
+    wd_print_msg "$WD_YELLOW" "$msg"
+    WD_EXIT_CODE=1
+}
+
+wd_getdir()
+{
+    local name_arg=$1
+
+    point=$(wd_show "$name_arg")
+    dir=${point:28+$#name_arg+7}
+
+    if [[ -z $name_arg ]]; then
+        wd_exit_fail "You must enter a warp point"
+        break
+    elif [[ -z $dir ]]; then
+        wd_exit_fail "Unknown warp point '${name_arg}'"
+        break
+    fi
+}
+
+# core
+
+wd_warp()
+{
+    local point=$1
+    local sub=$2
+
+    if [[ $point =~ "^\.+$" ]]
+    then
+        if [[ $#1 < 2 ]]
+        then
+            wd_exit_warn "Warping to current directory?"
+        else
+            (( n = $#1 - 1 ))
+            cd -$n > /dev/null
+        fi
+    elif [[ ${points[$point]} != "" ]]
+    then
+        if [[ $sub != "" ]]
+        then
+            cd ${points[$point]/#\~/$HOME}/$sub
+        else
+            cd ${points[$point]/#\~/$HOME}
+        fi
+    else
+        wd_exit_fail "Unknown warp point '${point}'"
+    fi
+}
+
+wd_add()
+{
+    local point=$1
+    local force=$2
+
+    if [[ $point == "" ]]
+    then
+        point=$(basename "$PWD")
+    fi
+
+    if [[ $point =~ "^[\.]+$" ]]
+    then
+        wd_exit_fail "Warp point cannot be just dots"
+    elif [[ $point =~ "[[:space:]]+" ]]
+    then
+        wd_exit_fail "Warp point should not contain whitespace"
+    elif [[ $point =~ : ]] || [[ $point =~ / ]]
+    then
+        wd_exit_fail "Warp point contains illegal character (:/)"
+    elif [[ ${points[$point]} == "" ]] || [ ! -z "$force" ]
+    then
+        wd_remove "$point" > /dev/null
+        printf "%q:%s\n" "${point}" "${PWD/#$HOME/~}" >> "$WD_CONFIG"
+        if (whence sort >/dev/null); then
+            local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
+            # use 'cat' below to ensure we respect $WD_CONFIG as a symlink
+            command sort -o "${config_tmp}" "$WD_CONFIG" && command cat "${config_tmp}" > "$WD_CONFIG" && command rm "${config_tmp}"
+        fi
+
+        wd_export_static_named_directories
+
+        wd_print_msg "$WD_GREEN" "Warp point added"
+
+        # override exit code in case wd_remove did not remove any points
+        # TODO: we should handle this kind of logic better
+        WD_EXIT_CODE=0
+    else
+        wd_exit_warn "Warp point '${point}' already exists. Use 'add --force' to overwrite."
+    fi
+}
+
+wd_remove()
+{
+    local point_list=$1
+
+    if [[ "$point_list" == "" ]]
+    then
+        point_list=$(basename "$PWD")
+    fi
+
+    for point_name in $point_list ; do
+        if [[ ${points[$point_name]} != "" ]]
+        then
+            local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
+            # Copy and delete in two steps in order to preserve symlinks
+            if sed -n "/^${point_name}:.*$/!p" "$WD_CONFIG" > "$config_tmp" && command cp "$config_tmp" "$WD_CONFIG" && command rm "$config_tmp"
+            then
+                wd_print_msg "$WD_GREEN" "Warp point removed"
+            else
+                wd_exit_fail "Something bad happened! Sorry."
+            fi
+        else
+            wd_exit_fail "Warp point was not found"
+        fi
+    done
+}
+
+wd_list_all()
+{
+    wd_print_msg "$WD_BLUE" "All warp points:"
+
+    entries=$(sed "s:${HOME}:~:g" "$WD_CONFIG")
+
+    max_warp_point_length=0
+    while IFS= read -r line
+    do
+        arr=(${(s,:,)line})
+        key=${arr[1]}
+
+        length=${#key}
+        if [[ length -gt max_warp_point_length ]]
+        then
+            max_warp_point_length=$length
+        fi
+    done <<< "$entries"
+
+    while IFS= read -r line
+    do
+        if [[ $line != "" ]]
+        then
+            arr=(${(s,:,)line})
+            key=${arr[1]}
+            val=${arr[2]}
+
+            if [[ -z $wd_quiet_mode ]]
+            then
+                printf "%${max_warp_point_length}s  ->  %s\n" "$key" "$val"
+            fi
+        fi
+    done <<< "$entries"
+}
+
+wd_ls()
+{
+    wd_getdir "$1"
+    ls "${dir/#\~/$HOME}"
+}
+
+wd_path()
+{
+    wd_getdir "$1"
+    echo "$(echo "$dir" | sed "s:~:${HOME}:g")"
+}
+
+wd_show()
+{
+    local name_arg=$1
+    # if there's an argument we look up the value
+    if [[ -n $name_arg ]]
+    then
+        if [[ -z $points[$name_arg] ]]
+        then
+            wd_print_msg "$WD_BLUE" "No warp point named $name_arg"
+        else
+            wd_print_msg "$WD_GREEN" "Warp point: ${WD_GREEN}$name_arg${WD_NOC} -> $points[$name_arg]"
+        fi
+    else
+        # hax to create a local empty array
+        local wd_matches
+        wd_matches=()
+        # do a reverse lookup to check whether PWD is in $points
+        PWD="${PWD/$HOME/~}"
+        if [[ ${points[(r)$PWD]} == "$PWD" ]]
+        then
+            for name in ${(k)points}
+            do
+                if [[ $points[$name] == "$PWD" ]]
+                then
+                    wd_matches[$(($#wd_matches+1))]=$name
+                fi
+            done
+
+            wd_print_msg "$WD_BLUE" "$#wd_matches warp point(s) to current directory: ${WD_GREEN}$wd_matches${WD_NOC}"
+        else
+            wd_print_msg "$WD_YELLOW" "No warp point to $(echo "$PWD" | sed "s:$HOME:~:")"
+        fi
+    fi
+}
+
+wd_clean() {
+    local force=$1
+    local count=0
+    local wd_tmp=""
+
+    while read -r line
+    do
+        if [[ $line != "" ]]
+        then
+            arr=(${(s,:,)line})
+            key=${arr[1]}
+            val=${arr[2]}
+
+            if [ -d "${val/#\~/$HOME}" ]
+            then
+                wd_tmp=$wd_tmp"\n"`echo "$line"`
+            else
+                wd_print_msg "$WD_YELLOW" "Nonexistent directory: ${key} -> ${val}"
+                count=$((count+1))
+            fi
+        fi
+    done < "$WD_CONFIG"
+
+    if [[ $count -eq 0 ]]
+    then
+        wd_print_msg "$WD_BLUE" "No warp points to clean, carry on!"
+    else
+        if [ ! -z "$force" ] || wd_yesorno "Removing ${count} warp points. Continue? (y/n)"
+        then
+            echo "$wd_tmp" >! "$WD_CONFIG"
+            wd_print_msg "$WD_GREEN" "Cleanup complete. ${count} warp point(s) removed"
+        else
+            wd_print_msg "$WD_BLUE" "Cleanup aborted"
+        fi
+    fi
+}
+
+wd_export_static_named_directories() {
+  if [[ ! -z $WD_EXPORT ]]
+  then
+    command grep '^[0-9a-zA-Z_-]\+:' "$WD_CONFIG" | sed -e "s,~,$HOME," -e 's/:/=/' | while read -r warpdir ; do
+        hash -d "$warpdir"
+    done
+  fi
+}
+
+local WD_CONFIG=${WD_CONFIG:-$HOME/.warprc}
+local WD_QUIET=0
+local WD_EXIT_CODE=0
+local WD_DEBUG=0
+
+# Parse 'meta' options first to avoid the need to have them before
+# other commands. The `-D` flag consumes recognized options so that
+# the actual command parsing won't be affected.
+
+zparseopts -D -E \
+    c:=wd_alt_config -config:=wd_alt_config \
+    q=wd_quiet_mode -quiet=wd_quiet_mode \
+    v=wd_print_version -version=wd_print_version \
+    d=wd_debug_mode -debug=wd_debug_mode \
+    f=wd_force_mode -force=wd_force_mode
+
+if [[ ! -z $wd_print_version ]]
+then
+    echo "wd version $WD_VERSION"
+fi
+
+if [[ ! -z $wd_alt_config ]]
+then
+    WD_CONFIG=$wd_alt_config[2]
+fi
+
+# check if config file exists
+if [ ! -e "$WD_CONFIG" ]
+then
+    # if not, create config file
+    touch "$WD_CONFIG"
+else
+    wd_export_static_named_directories
+fi
+
+# load warp points
+typeset -A points
+while read -r line
+do
+    arr=(${(s,:,)line})
+    key=${arr[1]}
+    # join the rest, in case the path contains colons
+    val=${(j,:,)arr[2,-1]}
+
+    points[$key]=$val
+done < "$WD_CONFIG"
+
+# get opts
+args=$(getopt -o a:r:c:lhs -l add:,rm:,clean,list,ls:,path:,help,show -- $*)
+
+# check if no arguments were given, and that version is not set
+if [[ ($? -ne 0 || $#* -eq 0) && -z $wd_print_version ]]
+then
+    wd_print_usage
+
+# check if config file is writeable
+elif [ ! -w "$WD_CONFIG" ]
+then
+    # do nothing
+    # can't run `exit`, as this would exit the executing shell
+    wd_exit_fail "\'$WD_CONFIG\' is not writeable."
+
+else
+    # parse rest of options
+    local wd_o
+    for wd_o
+    do
+        case "$wd_o"
+            in
+            "-a"|"--add"|"add")
+                wd_add "$2" "$wd_force_mode"
+                break
+                ;;
+            "-e"|"export")
+                wd_export_static_named_directories
+                break
+                ;;
+            "-r"|"--remove"|"rm")
+                # Passes all the arguments as a single string separated by whitespace to wd_remove
+                wd_remove "${@:2}"
+                break
+                ;;
+            "-l"|"list")
+                wd_list_all
+                break
+                ;;
+            "-ls"|"ls")
+                wd_ls "$2"
+                break
+                ;;
+            "-p"|"--path"|"path")
+                wd_path "$2"
+                break
+                ;;
+            "-h"|"--help"|"help")
+                wd_print_usage
+                break
+                ;;
+            "-s"|"--show"|"show")
+                wd_show "$2"
+                break
+                ;;
+            "-c"|"--clean"|"clean")
+                wd_clean "$wd_force_mode"
+                break
+                ;;
+            *)
+                wd_warp "$wd_o" "$2"
+                break
+                ;;
+            --)
+                break
+                ;;
+        esac
+    done
+fi
+
+## garbage collection
+# if not, next time warp will pick up variables from this run
+# remember, there's no sub shell
+
+unset wd_warp
+unset wd_add
+unset wd_remove
+unset wd_show
+unset wd_list_all
+unset wd_print_msg
+unset wd_yesorno
+unset wd_print_usage
+unset wd_alt_config
+unset wd_quiet_mode
+unset wd_print_version
+unset wd_export_static_named_directories
+unset wd_o
+
+unset args
+unset points
+unset val &> /dev/null # fixes issue #1
+
+if [[ -n $wd_debug_mode ]]
+then
+    exit $WD_EXIT_CODE
+else
+    unset wd_debug_mode
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/web-search/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/web-search/README.md
new file mode 100644 (file)
index 0000000..54232a9
--- /dev/null
@@ -0,0 +1,80 @@
+# web-search plugin
+
+This plugin adds aliases for searching with Google, Wiki, Bing, YouTube and other popular services.
+
+Open your `~/.zshrc` file and enable the `web-search` plugin:
+
+```zsh
+plugins=( ... web-search)
+```
+
+## Usage
+
+You can use the `web-search` plugin in these two forms:
+
+* `web_search <context> <term> [more terms if you want]`
+* `<context> <term> [more terms if you want]`
+
+For example, these two are equivalent:
+
+```zsh
+$ web_search google oh-my-zsh
+$ google oh-my-zsh
+```
+
+Available search contexts are:
+
+| Context               | URL                                      |
+| --------------------- | ---------------------------------------- |
+| `bing`                | `https://www.bing.com/search?q=`         |
+| `google`              | `https://www.google.com/search?q=`       |
+| `brs` or `brave`      | `https://search.brave.com/search?q=`     |
+| `yahoo`               | `https://search.yahoo.com/search?p=`     |
+| `ddg` or `duckduckgo` | `https://www.duckduckgo.com/?q=`         |
+| `sp` or `startpage`   | `https://www.startpage.com/do/search?q=` |
+| `yandex`              | `https://yandex.ru/yandsearch?text=`     |
+| `github`              | `https://github.com/search?q=`           |
+| `baidu`               | `https://www.baidu.com/s?wd=`            |
+| `ecosia`              | `https://www.ecosia.org/search?q=`       |
+| `goodreads`           | `https://www.goodreads.com/search?q=`    |
+| `qwant`               | `https://www.qwant.com/?q=`              |
+| `givero`              | `https://www.givero.com/search?q=`       |
+| `stackoverflow`       | `https://stackoverflow.com/search?q=`    |
+| `wolframalpha`        | `https://wolframalpha.com/input?i=`      |
+| `archive`             | `https://web.archive.org/web/*/`         |
+| `scholar`             | `https://scholar.google.com/scholar?q=`  |
+
+Also there are aliases for bang-searching DuckDuckGo:
+
+| Context   | Bang  |
+|-----------|-------|
+| `wiki`    | `!w`  |
+| `news`    | `!n`  |
+| `youtube` | `!yt` |
+| `map`     | `!m`  |
+| `image`   | `!i`  |
+| `ducky`   | `!`   |
+
+### Custom search engines
+
+If you want to add other search contexts to the plugin, you can use the
+`$ZSH_WEB_SEARCH_ENGINES` variable. Set it before Oh My Zsh is sourced,
+with the following format:
+
+```zsh
+ZSH_WEB_SEARCH_ENGINES=(
+    <context> <URL>
+    <context> <URL>
+)
+```
+
+where `<context>` is the name of the search context, and `<URL>` a URL of
+the same type as the search contexts above. For example, to add `reddit`,
+you'd do:
+
+```zsh
+ZSH_WEB_SEARCH_ENGINES=(reddit "https://www.reddit.com/search/?q=")
+```
+
+These custom search engines will also be turned to aliases, so you can
+both do `web_search reddit <query>` or `reddit <query>`.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/web-search/web-search.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/web-search/web-search.plugin.zsh
new file mode 100644 (file)
index 0000000..d8b4a7f
--- /dev/null
@@ -0,0 +1,84 @@
+# web_search from terminal
+
+function web_search() {
+  emulate -L zsh
+
+  # define search engine URLS
+  typeset -A urls
+  urls=(
+    $ZSH_WEB_SEARCH_ENGINES
+    google          "https://www.google.com/search?q="
+    bing            "https://www.bing.com/search?q="
+    brave           "https://search.brave.com/search?q="
+    yahoo           "https://search.yahoo.com/search?p="
+    duckduckgo      "https://www.duckduckgo.com/?q="
+    startpage       "https://www.startpage.com/do/search?q="
+    yandex          "https://yandex.ru/yandsearch?text="
+    github          "https://github.com/search?q="
+    baidu           "https://www.baidu.com/s?wd="
+    ecosia          "https://www.ecosia.org/search?q="
+    goodreads       "https://www.goodreads.com/search?q="
+    qwant           "https://www.qwant.com/?q="
+    givero          "https://www.givero.com/search?q="
+    stackoverflow   "https://stackoverflow.com/search?q="
+    wolframalpha    "https://www.wolframalpha.com/input/?i="
+    archive         "https://web.archive.org/web/*/"
+    scholar         "https://scholar.google.com/scholar?q="
+  )
+
+  # check whether the search engine is supported
+  if [[ -z "$urls[$1]" ]]; then
+    echo "Search engine '$1' not supported."
+    return 1
+  fi
+
+  # search or go to main page depending on number of arguments passed
+  if [[ $# -gt 1 ]]; then
+    # build search url:
+    # join arguments passed with '+', then append to search engine URL
+    url="${urls[$1]}$(omz_urlencode ${@[2,-1]})"
+  else
+    # build main page url:
+    # split by '/', then rejoin protocol (1) and domain (2) parts with '//'
+    url="${(j://:)${(s:/:)urls[$1]}[1,2]}"
+  fi
+
+  open_command "$url"
+}
+
+
+alias bing='web_search bing'
+alias brs='web_search brave'
+alias google='web_search google'
+alias yahoo='web_search yahoo'
+alias ddg='web_search duckduckgo'
+alias sp='web_search startpage'
+alias yandex='web_search yandex'
+alias github='web_search github'
+alias baidu='web_search baidu'
+alias ecosia='web_search ecosia'
+alias goodreads='web_search goodreads'
+alias qwant='web_search qwant'
+alias givero='web_search givero'
+alias stackoverflow='web_search stackoverflow'
+alias wolframalpha='web_search wolframalpha'
+alias archive='web_search archive'
+alias scholar='web_search scholar'
+
+#add your own !bang searches here
+alias wiki='web_search duckduckgo \!w'
+alias news='web_search duckduckgo \!n'
+alias youtube='web_search duckduckgo \!yt'
+alias map='web_search duckduckgo \!m'
+alias image='web_search duckduckgo \!i'
+alias ducky='web_search duckduckgo \!'
+
+# other search engine aliases
+if [[ ${#ZSH_WEB_SEARCH_ENGINES} -gt 0 ]]; then
+  typeset -A engines
+  engines=($ZSH_WEB_SEARCH_ENGINES)
+  for key in ${(k)engines}; do
+    alias "$key"="web_search $key"
+  done
+  unset engines key
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wp-cli/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/wp-cli/README.md
new file mode 100644 (file)
index 0000000..c4993ab
--- /dev/null
@@ -0,0 +1,109 @@
+# WP-CLI
+
+The [WordPress CLI](https://wp-cli.org/) is a command-line tool for managing WordPress installations. You can update plugins, set up multisite installs and much more, without using a web browser.
+
+This plugin adds [tab completion](https://wp-cli.org/#tab-completions) for `wp-cli` as well as several aliases for commonly used commands.
+
+To use it, add `wp-cli` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... wp-cli)
+```
+
+**Maintainer:** [joshmedeski](https://github.com/joshmedeski)
+
+## Aliases
+
+The entire list of `wp-cli` commands can be found here: https://developer.wordpress.org/cli/commands/
+
+| Alias     | Command                     |
+|-----------|-----------------------------|
+| **Core**                                |
+| `wpcc`    | `wp core config`            |
+| `wpcd`    | `wp core download`          |
+| `wpci`    | `wp core install`           |
+| `wpcii`   | `wp core is-installed`      |
+| `wpcmc`   | `wp core multisite-convert` |
+| `wpcmi`   | `wp core multisite-install` |
+| `wpcu`    | `wp core update`            |
+| `wpcudb`  | `wp core update-db`         |
+| `wpcvc`   | `wp core verify-checksums`  |
+| **Cron**                                |
+| `wpcre`   | `wp cron event`             |
+| `wpcrs`   | `wp cron schedule`          |
+| `wpcrt`   | `wp cron test`              |
+| **Database**                            |
+| `wpdbe`   | `wp db export`              |
+| `wpdbi`   | `wp db import`              |
+| `wpdbcr`  | `wp db create`              |
+| `wpdbs`   | `wp db search`              |
+| `wpdbch`  | `wp db check`               |
+| `wpdbr`   | `wp db repair`              |
+| **Menu**                                |
+| `wpmc`    | `wp menu create`            |
+| `wpmd`    | `wp menu delete`            |
+| `wpmi`    | `wp menu item`              |
+| `wpml`    | `wp menu list`              |
+| `wpmlo`   | `wp menu location`          |
+| **Plugin**                              |
+| `wppa`    | `wp plugin activate`        |
+| `wppda`   | `wp plugin deactivate`      |
+| `wppd`    | `wp plugin delete`          |
+| `wppg`    | `wp plugin get`             |
+| `wppi`    | `wp plugin install`         |
+| `wppis`   | `wp plugin is-installed`    |
+| `wppl`    | `wp plugin list`            |
+| `wppp`    | `wp plugin path`            |
+| `wpps`    | `wp plugin search`          |
+| `wppst`   | `wp plugin status`          |
+| `wppt`    | `wp plugin toggle`          |
+| `wppun`   | `wp plugin uninstall`       |
+| `wppu`    | `wp plugin update`          |
+| **Post**                                |
+| `wppoc`   | `wp post create`            |
+| `wppod`   | `wp post delete`            |
+| `wppoe`   | `wp post edit`              |
+| `wppogen` | `wp post generate`          |
+| `wppog`   | `wp post get`               |
+| `wppol`   | `wp post list`              |
+| `wppom`   | `wp post meta`              |
+| `wppou`   | `wp post update`            |
+| `wppourl` | `wp post url`               |
+| **Sidebar**                             |
+| `wpsbl`   | `wp sidebar list`           |
+| **Theme**                               |
+| `wpta`    | `wp theme activate`         |
+| `wptd`    | `wp theme delete`           |
+| `wptdis`  | `wp theme disable`          |
+| `wpte`    | `wp theme enable`           |
+| `wptg`    | `wp theme get`              |
+| `wpti`    | `wp theme install`          |
+| `wptis`   | `wp theme is-installed`     |
+| `wptl`    | `wp theme list`             |
+| `wptm`    | `wp theme mod`              |
+| `wptp`    | `wp theme path`             |
+| `wpts`    | `wp theme search`           |
+| `wptst`   | `wp theme status`           |
+| `wptu`    | `wp theme update`           |
+| **User**                                |
+| `wpuac`   | `wp user add-cap`           |
+| `wpuar`   | `wp user add-role`          |
+| `wpuc`    | `wp user create`            |
+| `wpud`    | `wp user delete`            |
+| `wpugen`  | `wp user generate`          |
+| `wpug`    | `wp user get`               |
+| `wpui`    | `wp user import-csv`        |
+| `wpul`    | `wp user list`              |
+| `wpulc`   | `wp user list-caps`         |
+| `wpum`    | `wp user meta`              |
+| `wpurc`   | `wp user remove-cap`        |
+| `wpurr`   | `wp user remove-role`       |
+| `wpusr`   | `wp user set-role`          |
+| `wpuu`    | `wp user update`            |
+| **Widget**                              |
+| `wpwa`    | `wp widget add`             |
+| `wpwda`   | `wp widget deactivate`      |
+| `wpwd`    | `wp widget delete`          |
+| `wpwl`    | `wp widget list`            |
+| `wpwm`    | `wp widget move`            |
+| `wpwu`    | `wp widget update`          |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/wp-cli/wp-cli.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/wp-cli/wp-cli.plugin.zsh
new file mode 100644 (file)
index 0000000..09bdf32
--- /dev/null
@@ -0,0 +1,123 @@
+# WP-CLI
+# A command line interface for WordPress
+# https://wp-cli.org/
+
+# Core
+alias wpcc='wp core config'
+alias wpcd='wp core download'
+alias wpci='wp core install'
+alias wpcii='wp core is-installed'
+alias wpcmc='wp core multisite-convert'
+alias wpcmi='wp core multisite-install'
+alias wpcu='wp core update'
+alias wpcudb='wp core update-db'
+alias wpcvc='wp core verify-checksums'
+
+# Cron
+alias wpcre='wp cron event'
+alias wpcrs='wp cron schedule'
+alias wpcrt='wp cron test'
+
+# Db
+alias wpdbe='wp db export'
+alias wpdbi='wp db import'
+alias wpdbcr='wp db create'
+alias wpdbs='wp db search'
+alias wpdbch='wp db check'
+alias wpdbr='wp db repair'
+
+# Menu
+alias wpmc='wp menu create'
+alias wpmd='wp menu delete'
+alias wpmi='wp menu item'
+alias wpml='wp menu list'
+alias wpmlo='wp menu location'
+
+# Plugin
+alias wppa='wp plugin activate'
+alias wppda='wp plugin deactivate'
+alias wppd='wp plugin delete'
+alias wppg='wp plugin get'
+alias wppi='wp plugin install'
+alias wppis='wp plugin is-installed'
+alias wppl='wp plugin list'
+alias wppp='wp plugin path'
+alias wpps='wp plugin search'
+alias wppst='wp plugin status'
+alias wppt='wp plugin toggle'
+alias wppun='wp plugin uninstall'
+alias wppu='wp plugin update'
+
+# Post
+alias wppoc='wp post create'
+alias wppod='wp post delete'
+alias wppoe='wp post edit'
+alias wppogen='wp post generate'
+alias wppog='wp post get'
+alias wppol='wp post list'
+alias wppom='wp post meta'
+alias wppou='wp post update'
+alias wppourl='wp post url'
+
+# Sidebar
+alias wpsbl='wp sidebar list'
+
+# Theme
+alias wpta='wp theme activate'
+alias wptd='wp theme delete'
+alias wptdis='wp theme disable'
+alias wpte='wp theme enable'
+alias wptg='wp theme get'
+alias wpti='wp theme install'
+alias wptis='wp theme is-installed'
+alias wptl='wp theme list'
+alias wptm='wp theme mod'
+alias wptp='wp theme path'
+alias wpts='wp theme search'
+alias wptst='wp theme status'
+alias wptu='wp theme update'
+
+# User
+alias wpuac='wp user add-cap'
+alias wpuar='wp user add-role'
+alias wpuc='wp user create'
+alias wpud='wp user delete'
+alias wpugen='wp user generate'
+alias wpug='wp user get'
+alias wpui='wp user import-csv'
+alias wpul='wp user list'
+alias wpulc='wp user list-caps'
+alias wpum='wp user meta'
+alias wpurc='wp user remove-cap'
+alias wpurr='wp user remove-role'
+alias wpusr='wp user set-role'
+alias wpuu='wp user update'
+
+# Widget
+alias wpwa='wp widget add'
+alias wpwda='wp widget deactivate'
+alias wpwd='wp widget delete'
+alias wpwl='wp widget list'
+alias wpwm='wp widget move'
+alias wpwu='wp widget update'
+
+
+# Completion for wp
+autoload -U +X bashcompinit && bashcompinit
+_wp_complete() {
+       local cur=${COMP_WORDS[COMP_CWORD]}
+
+       IFS=$'\n';  # want to preserve spaces at the end
+       local opts="$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT")"
+
+       if [[ "$opts" =~ \<file\>\s* ]]
+       then
+               COMPREPLY=( $(compgen -f -- $cur) )
+       elif [[ $opts = "" ]]
+       then
+               COMPREPLY=( $(compgen -f -- $cur) )
+       else
+               COMPREPLY=( ${opts[*]} )
+       fi
+}
+complete -o nospace -F _wp_complete wp
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/README.md
new file mode 100644 (file)
index 0000000..27d6a22
--- /dev/null
@@ -0,0 +1,88 @@
+# Xcode
+
+## Description
+
+This plugin provides a few utilities that can help you on your daily use of Xcode and iOS development.
+
+To start using it, add the `xcode` plugin to your `plugins` array in `~/.zshrc`:
+
+```zsh
+plugins=(... xcode)
+```
+
+
+## Aliases
+
+| Alias | Description                              | Command                                        |
+|-------|------------------------------------------|------------------------------------------------|
+| xcb   | Build Xcode projects and workspaces      | xcodebuild                                     |
+| xcdd  | Purge all temporary build information    | rm -rf ~/Library/Developer/Xcode/DerivedData/* |
+| xcp   | Show currently selected Xcode directory  | xcode-select --print-path                      |
+| xcsel | Select different Xcode directory by path | sudo xcode-select --switch                     |
+| xx    | Opens the files listed in Xcode          | open -a "Xcode.app"                            |
+
+
+## Functions
+
+###  `xc`
+
+Opens the current directory in Xcode as an Xcode project or a Swift package. This will open one of the `.xcworkspace`, `.xcodeproj`, `.swiftpm` and `Package.swift` files that it can find in the current working directory. You can also specify a directory to look in for the Xcode files.
+Returns 1 if it didn't find any relevant files.
+
+###  `xx`
+
+Opens the files listed in Xcode, multiple files are opened in a multi-file browser.
+
+###  `simulator`
+
+Opens the iOS Simulator from your command line, dependent on whichever is the active developer directory for Xcode. (That is, it respects the `xcsel` setting.)
+
+### `xcselv`
+
+Selects different Xcode installations by version name. This is like `xcsel`, except it takes just a version name as an argument instead of the full path to the Xcode installation. Uses the naming conventions described below.
+
+* `xcselv <version>` selects a version
+ * Example: `xcselv 6.2`
+* `xcselv default` selects the default unversioned `Applications/Xcode.app`
+* `xcselv` with no argument lists the available Xcode versions in a human-readable format
+* `xcselv -l` lists the installed Xcode versions
+* `xcselv -L` lists the installed Xcode versions in a short version-name-only format
+* `xcselv -p` prints info about the active Xcode version
+* `xcselv -h` prints a help message
+
+The option parsing for `xcselv` is naive. Options may not be combined, and only the first option is recognized.
+
+## Multiple Xcode Versions
+
+The `xcselv` command provides support for switching between different Xcode installations using just a version number. Different Xcode versions are identified by file naming conventions.
+
+### Versioned Xcode Naming Conventions
+
+Apple does not seem to explicitly define or provide tooling support for a naming convention or other organizational mechanism for managing versioned Xcode installations. Apple seems to have released beta versions with both `Xcode<version>.app` and `Xcode-<version>.app` style names in the past, and both styles show up in forum and blog discussions.
+
+We've adopted the following naming convention:
+
+* Versioned Xcode installations are identified by the name `Xcode-<version>` or `Xcode<version>`.
+* The `-` separating `"Xcode"` and the version name is optional, and may be replaced by a space.
+* The versioned name may be applied to the `Xcode.app` itself, or a subdirectory underneath `Applications/` containing it.
+* You cannot version both the `Xcode.app` filename itself and the containing subfolder.
+* Thus, all of the following are equivalent.
+ * `Applications/Xcode-<version>.app`
+ * `Applications/Xcode-<version>/Xcode.app`
+ * `Applications/Xcode<version>.app`
+ * `Applications/Xcode <version>.app`
+ * `Applications/Xcode <version>/Xcode.app`
+* Both the system `/Applications/` and user `$HOME/Applications/` directories are searched.
+ * The user's `$HOME/Applications/` takes precedence over `/Applications` for a given version.
+ * If multiple naming variants within the same `Applications/` folder indicate the same version (for example, `Xcode-3.2.1.app`, `Xcode3.2.1.app`, and `Xcode-3.2.1/Xcode.app`), the precedence order is unspecified and implementation-dependent.
+* The `<version>` may be any string that is valid in a filename.
+* The special version name `"default"` refers to the "default" unversioned Xcode at `Applications/Xcode.app` (in either `/Applications/` or `$HOME/Applications/`).
+* Version names may not start with ``"-"`` or whitespace.
+
+The restrictions on the naming convention may need to be tightened in the future. In particular, if there are other well-known applications whose names begin with the string `"Xcode"`, the strings allowed for `<version>` may need to be restricted to avoid colliding with other applications. If there's evidence that one of these naming techniques is strongly favored either in practice or by Apple, we may tighten the naming convention to favor it.
+
+## Caveats
+
+Using `xcsel` or `xcselv` to select an Xcode that is installed under your `$HOME` may break things for other users, depending on your system setup. We let you do this anyway because some people run OS X as effectively single-user, or have open permissions so this will work. You could also use `$DEVELOPER_DIR` as an alternative to `xcsel` that is scoped to the current user or session, instead of a global setting.
+
+This does not verify that the version name in the Xcode filename matches the actual version of that binary. It is the user's responsibility to get the names right.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/_xcselv b/stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/_xcselv
new file mode 100644 (file)
index 0000000..f9861d5
--- /dev/null
@@ -0,0 +1,19 @@
+#compdef xcselv
+#autoload
+
+function _xcselv_compl_list_versions() {
+  _omz_xcode_list_versions short
+}
+
+_arguments \
+  '(-l -L -p)-h[prints a help message]' \
+  '(-L -p -h)-l[lists installed Xcode versions]' \
+  '(-l -p -h)-L[lists installed Xcode versions (long form)]' \
+  '(-h -l -L)-p[prints active Xcode version]' \
+  && ret=0
+
+local _xcode_versions
+_xcode_versions=($(_xcselv_compl_list_versions))
+_describe -t _xcode_versions 'version' _xcode_versions
+
+return 1
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/xcode.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/xcode/xcode.plugin.zsh
new file mode 100644 (file)
index 0000000..3bd12cd
--- /dev/null
@@ -0,0 +1,201 @@
+alias xcb='xcodebuild'
+alias xcdd='rm -rf ~/Library/Developer/Xcode/DerivedData/*'
+alias xcp='xcode-select --print-path'
+alias xcsel='sudo xcode-select --switch'
+
+# original author: @subdigital
+# source: https://gist.github.com/subdigital/5420709
+function xc {
+  local xcode_files
+  xcode_files=(${1:-.}/{*.{xcworkspace,xcodeproj,swiftpm},Package.swift}(N))
+
+  if [[ ${#xcode_files} -eq 0 ]]; then
+    echo "No Xcode files found in ${1:-the current directory}." >&2
+    return 1
+  fi
+
+  local active_path
+  active_path=${"$(xcode-select -p)"%%/Contents/Developer*}
+  echo "Found ${xcode_files[1]}. Opening with ${active_path}"
+  open -a "$active_path" "${xcode_files[1]}"
+}
+
+# Opens a file or files in the Xcode IDE. Multiple files are opened in multi-file browser
+# original author: @possen
+function xx {
+  if [[ $# == 0 ]]; then
+    echo "Specify file(s) to open in xcode."
+    return 1
+  fi
+  echo "${xcode_files}"
+  open -a "Xcode.app" "$@"
+}
+
+# "XCode-SELect by Version" - select Xcode by just version number
+# Uses naming convention:
+#  - different versions of Xcode are named Xcode-<version>.app or stored
+#     in a folder named Xcode-<version>
+#  - the special version name "default" refers to the "default" Xcode.app with no suffix
+function xcselv {
+  emulate -L zsh
+  if [[ $# == 0 ]]; then
+    echo "xcselv: error: no option or argument given" >&2
+    echo "xcselv: see 'xcselv -h' for help" >&2
+    return 1
+  elif [[ $1 == "-p" ]]; then
+    _omz_xcode_print_active_version
+    return
+  elif [[ $1 == "-l" ]]; then
+    _omz_xcode_list_versions
+    return
+  elif [[ $1 == "-L" ]]; then
+    _omz_xcode_list_versions short
+    return
+  elif [[ $1 == "-h" ]]; then
+    _omz_xcode_print_xcselv_usage
+    return 0
+  elif [[ $1 == -* && $1 != "-" ]]; then
+    echo "xcselv: error: unrecognized option: $1" >&2
+    echo "xcselv: see 'xcselv -h' for help" >&2
+    return 1
+  fi
+  # Main case: "xcselv <version>" to select a version
+  local version=$1
+  local -A xcode_versions
+  _omz_xcode_locate_versions
+  if [[ -z ${xcode_versions[$version]} ]]; then
+    echo "xcselv: error: Xcode version '$version' not found" >&2
+    return 1
+  fi
+  app="${xcode_versions[$version]}"
+  echo "selecting Xcode $version: $app"
+  xcsel "$app"
+}
+
+function _omz_xcode_print_xcselv_usage {
+  cat << EOF >&2
+Usage:
+  xcselv <version>
+  xcselv [options]
+
+Options:
+  <version> set the active Xcode version
+  -h        print this help message and exit
+  -p        print the active Xcode version
+  -l        list installed Xcode versions (long human-readable form)
+  -L        list installed Xcode versions (short form, version names only)
+EOF
+}
+
+# Parses the Xcode version from a filename based on our conventions
+# Only meaningful when called from other _omz_xcode functions
+function _omz_xcode_parse_versioned_file {
+  local file=$1
+  local basename=${app:t}
+  local dir=${app:h}
+  local parent=${dir:t}
+  #echo "parent=$parent basename=$basename verstr=$verstr ver=$ver" >&2
+  local verstr
+  if [[ $parent == Xcode* ]]; then
+    if [[ $basename == "Xcode.app" ]]; then
+      # "Xcode-<version>/Xcode.app" format
+      verstr=$parent
+    else
+      # Both file and parent dir are versioned. Reject.
+      return 1;
+    fi
+  elif [[ $basename == Xcode*.app ]]; then
+    # "Xcode-<version>.app" format
+    verstr=${basename:r}
+  else
+    # Invalid naming pattern
+    return 1;
+  fi
+
+  local ver=${verstr#Xcode}
+  ver=${ver#[- ]}
+  if [[ -z $ver ]]; then
+    # Unversioned "default" installation location
+    ver="default"
+  fi
+  print -- "$ver"
+}
+
+# Print the active version, using xcselv's notion of versions
+function _omz_xcode_print_active_version {
+  emulate -L zsh
+  local -A xcode_versions
+  local versions version active_path
+  _omz_xcode_locate_versions
+  active_path=$(xcode-select -p)
+  active_path=${active_path%%/Contents/Developer*}
+  versions=(${(kni)xcode_versions})
+  for version ($versions); do
+    if [[ "${xcode_versions[$version]}" == $active_path ]]; then
+      printf "%s (%s)\n" $version $active_path
+      return
+    fi
+  done
+  printf "%s (%s)\n" "<unknown>" $active_path
+}
+
+# Locates all the installed versions of Xcode on this system, for this
+# plugin's internal use.
+# Populates the $xcode_versions associative array variable
+# Caller should local-ize $xcode_versions with `local -A xcode_versions`
+function _omz_xcode_locate_versions {
+  emulate -L zsh
+  local -a app_dirs
+  local app_dir apps app xcode_ver
+  # In increasing precedence order:
+  app_dirs=(/Applications $HOME/Applications)
+  for app_dir ($app_dirs); do
+    apps=( $app_dir/Xcode*.app(N) $app_dir/Xcode*/Xcode.app(N) )
+    for app ($apps); do
+      xcode_ver=$(_omz_xcode_parse_versioned_file $app)
+      if [[ $? != 0 ]]; then
+        continue
+      fi
+      xcode_versions[$xcode_ver]=$app
+    done
+  done
+}
+
+function _omz_xcode_list_versions {
+  emulate -L zsh
+  local -A xcode_versions
+  _omz_xcode_locate_versions
+  local width=1 width_i versions do_short=0
+  if [[ $1 == "short" ]]; then
+    do_short=1
+  fi
+  versions=(${(kni)xcode_versions})
+  for version ($versions); do
+    if [[ $#version > $width ]]; then
+      width=$#version;
+    fi
+  done
+  for version ($versions); do
+    if [[ $do_short == 1 ]]; then
+      printf "%s\n" $version
+    else
+      printf "%-${width}s -> %s\n" "$version" "${xcode_versions[$version]}"
+    fi
+  done
+}
+
+function simulator {
+  local devfolder
+  devfolder="$(xcode-select -p)"
+
+  # Xcode ≤ 5.x
+  if [[ -d "${devfolder}/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app" ]]; then
+    open "${devfolder}/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app"
+  # Xcode ≥ 6.x
+  elif [[ -d "${devfolder}/Applications/iOS Simulator.app" ]]; then
+    open "${devfolder}/Applications/iOS Simulator.app"
+  # Xcode ≥ 7.x
+  else
+    open "${devfolder}/Applications/Simulator.app"
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/README.md
new file mode 100644 (file)
index 0000000..9c16ff2
--- /dev/null
@@ -0,0 +1,56 @@
+# Yarn plugin
+
+This plugin adds completion for the [Yarn package manager](https://yarnpkg.com/en/),
+as well as some aliases for common Yarn commands.
+
+To use it, add `yarn` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... yarn)
+```
+
+## Global scripts directory
+
+It also adds `yarn` global scripts dir (commonly `~/.yarn/bin`) to the `$PATH`.
+To disable this feature, set the following style in your `.zshrc`:
+
+```zsh
+zstyle ':omz:plugins:yarn' global-path false
+```
+
+## Aliases
+
+| Alias | Command                                   | Description                                                                   |
+| ----- | ----------------------------------------- | ----------------------------------------------------------------------------- |
+| y     | `yarn`                                    | The Yarn command                                                              |
+| ya    | `yarn add`                                | Install a package in dependencies (`package.json`)                            |
+| yad   | `yarn add --dev`                          | Install a package in devDependencies (`package.json`)                         |
+| yap   | `yarn add --peer`                         | Install a package in peerDependencies (`package.json`)                        |
+| yb    | `yarn build`                              | Run the build script defined in `package.json`                                |
+| ycc   | `yarn cache clean`                        | Clean yarn's global cache of packages                                         |
+| yd    | `yarn dev`                                | Run the dev script defined in `package.json`                                  |
+| yga   | `yarn global add`                         | Install packages globally on your operating system                            |
+| ygls  | `yarn global list`                        | Lists global installed packages                                               |
+| ygrm  | `yarn global remove`                      | Remove global installed packages from your OS                                 |
+| ygu   | `yarn global upgrade`                     | Upgrade packages installed globally to their latest version                   |
+| yh    | `yarn help`                               | Show help for a yarn command                                                  |
+| yi    | `yarn init`                               | Interactively creates or updates a package.json file                          |
+| yin   | `yarn install`                            | Install dependencies defined in `package.json`                                |
+| yln   | `yarn lint`                               | Run the lint script defined in `package.json`                                 |
+| ylnf  | `yarn lint --fix`                         | Run the lint script defined in `package.json`to automatically fix problems    |
+| yls   | `yarn list`                               | List installed packages                                                       |
+| yout  | `yarn outdated`                           | Check for outdated package dependencies                                       |
+| yp    | `yarn pack`                               | Create a compressed gzip archive of package dependencies                      |
+| yrm   | `yarn remove`                             | Remove installed packages                                                     |
+| yrun  | `yarn run`                                | Run a defined package script                                                  |
+| ys    | `yarn serve`                              | Start the dev server                                                          |
+| yst   | `yarn start`                              | Run the start script defined in `package.json`                                |
+| yt    | `yarn test`                               | Run the test script defined in `package.json`                                 |
+| ytc   | `yarn test --coverage`                    | Run the test script defined in `package.json` with coverage                   |
+| yuc   | `yarn global upgrade && yarn cache clean` | Upgrade global packages and clean yarn's global cache                         |
+| yui   | `yarn upgrade-interactive`                | Prompt for which outdated packages to upgrade                                 |
+| yuil  | `yarn upgrade-interactive --latest`       | Prompt for which outdated packages to upgrade to the latest available version |
+| yup   | `yarn upgrade`                            | Upgrade packages to their latest version                                      |
+| yv    | `yarn version`                            | Update the version of your package                                            |
+| yw    | `yarn workspace`                          | Run a command within a single workspace.                                      |
+| yws   | `yarn workspaces`                         | Run a command within all defined workspaces.                                  |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/_yarn b/stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/_yarn
new file mode 100644 (file)
index 0000000..1237ba6
--- /dev/null
@@ -0,0 +1,502 @@
+#compdef yarn
+# ------------------------------------------------------------------------------
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the zsh-users nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+#  Completion script for yarn (https://yarnpkg.com/)
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+#  * Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
+#  * Shohei YOSHIDA <syohex@gmail.com>
+#
+# ------------------------------------------------------------------------------
+
+declare -g _yarn_run_cwd
+
+_commands=(
+  'access'
+  'audit:Checks for known security issues with the installed packages'
+  'autoclean:Clean and remove unnecessary files from package dependencies'
+  'cache:List or clean every cached package'
+  "check:Verify package dependencies against yarn's lock file"
+  'config:Manages the yarn configuration files'
+  'create:Creates new projects from any create-* starter kits'
+  'exec'
+  'generate-lock-entry:Generates a lock file entry'
+  'global:Install packages globally on your operating system'
+  'help:Show information about a command'
+  'import:Generate yarn.lock from an existing npm-installed node_modules folder'
+  'info:Show information about a package'
+  'init:Interactively creates or updates a package.json file'
+  'install:Install all the dependencies listed within package.json'
+  'licenses:List licenses for installed packages'
+  'link:Symlink a package folder during development'
+  'login:Store registry username and email'
+  'logout:Clear registry username and email'
+  'node:Runs Node with the same version that the one used by Yarn itself'
+  'outdated:Check for outdated package dependencies'
+  'owner:Manage package owners'
+  'pack:Create a compressed gzip archive of package dependencies'
+  'policies:Defines project-wide policies for your project'
+  'publish:Publish a package to the npm registry'
+  'run:Run a defined package script'
+  'tag:Add, remove, or list tags on a package'
+  'team:Maintain team memberships'
+  'unlink:Unlink a previously created symlink for a package'
+  'unplug:Temporarily copies a package outside of the global cache for debugging purposes'
+  'version:Update the package version'
+  'versions:Display version information of currently installed Yarn, Node.js, and its dependencies'
+  'why:Show information about why a package is installed'
+  'workspace'
+  'workspaces:Show information about your workspaces'
+)
+
+_global_commands=(
+  'add:Installs a package and any packages that it depends on'
+  'bin:Displays the location of the yarn bin folder'
+  'list:List installed packages'
+  'remove:Remove installed package from dependencies updating package.json'
+  'upgrade:Upgrades packages to their latest version based on the specified range'
+  'upgrade-interactive:Interactively upgrade packages'
+)
+
+_yarn_find_package_json() {
+  local dir=$(cd "$1" && pwd)
+
+  while true
+  do
+    if [[ -e "${dir}/package.json" ]]; then
+      echo "${dir}/package.json"
+      return
+    fi
+
+    if [[ $dir == '/' ]]; then
+      break
+    fi
+
+    dir=$(dirname $dir)
+  done
+}
+
+_yarn_commands_scripts() {
+  local -a scripts binaries
+  local packageJson
+
+  if [[ -n $opt_args[--cwd] ]]; then
+    packageJson=$(_yarn_find_package_json $opt_args[--cwd])
+    binaries=($(cd $opt_args[--cwd] && echo node_modules/.bin/*(x:t)))
+  else
+    packageJson=$(_yarn_find_package_json $pwd)
+    binaries=($(echo node_modules/.bin/*(x:t)))
+  fi
+
+  if [[ -n $packageJson ]]; then
+    scripts=($(cat "$packageJson" | perl -0777 -MJSON::PP -n -E '$r=decode_json($_); do{($k=$_)=~s/:/\\:/g;say $k}for sort keys %{$r->{scripts}}'))
+  fi
+
+  _describe 'command or script' _commands -- _global_commands -- scripts -- binaries
+}
+
+_yarn_scripts() {
+  local -a binaries scripts
+  local -a commands
+  local packageJson
+
+  if [[ -n $_yarn_run_cwd ]]; then
+    packageJson=$(_yarn_find_package_json $_yarn_run_cwd)
+    if [[ -d "${_yarn_run_cwd}/node_modules" ]]; then
+      binaries=($(cd $_yarn_run_cwd && echo node_modules/.bin/*(x:t)))
+    else
+      binaries=($(cd $_yarn_run_cwd && yarn bin | perl -wln -e 'm{^[^:]+: (\S+)$} and print $1'))
+    fi
+  else
+    packageJson=$(_yarn_find_package_json $pwd)
+    if [[ -d node_modules ]]; then
+      binaries=($(echo node_modules/.bin/*(x:t)))
+    else
+      binaries=($(yarn bin | perl -wln -e 'm{^[^:]+: (\S+)$} and print $1'))
+    fi
+  fi
+
+  if [[ -n $packageJson ]]; then
+    scripts=("${(@f)$(cat ${packageJson} | perl -0777 -MJSON::PP -n -E '%r=%{decode_json($_)->{scripts}}; do{$k=$_;($e=$k)=~s/:/\\:/g; printf "$e:$r{$k}\n"} for sort keys %r')}")
+  fi
+
+  commands=('env' $scripts $binaries)
+  _describe 'command' commands
+}
+
+_yarn_global_commands() {
+  local -a cmds
+  cmds=('ls:List installed packages')
+  _describe 'command' _global_commands
+}
+
+_yarn_commands() {
+  _describe 'command' _commands -- _global_commands
+}
+
+_yarn_add_files() {
+  if compset -P "(file|link):"; then
+    _files
+  fi
+}
+
+_yarn_workspaces() {
+  local version=$(yarn --version |sed -n 's|\([0-9]*\).*|\1|p')
+  local -a workspaces
+  if [[ $version == "1" ]]; then
+    workspaces=(${(@f)$(yarn workspaces info |sed -n -e 's/^  "\([^"]*\)": {/\1/p')})
+  else
+    workspaces=(${(@f)$(yarn workspaces list --json | sed -n 's|.*"name":"\([^"]*\)"}|\1|p')})
+  fi
+  _describe 'workspace' workspaces
+}
+
+_yarn() {
+  local context state state_descr line
+  typeset -A opt_args
+
+  _arguments \
+    '(-h --help)'{-h,--help}'[output usage information]' \
+    '(-V --version)'{-V,--version}'[output the version number]' \
+    '--verbose[output verbose messages on internal operations]' \
+    '--cache-folder=[specify a custom folder to store the yarn cache]:folder:_files -/' \
+    '--check-files[install will verify file tree of packages for consistency]' \
+    '--cwd=[working directory to use]:path:_files -/' \
+    "(--enable-pnp --pnp)--disable-pnp[disable the Plug'n'Play installation]" \
+    '(--no-emoji)--emoji=[enable emoji in output(default: false)]:enabled:(true false)' \
+    '(--emoji)--no-emoji[disable emoji in output]' \
+    '(--disable-pnp)'{--enable-pnp,--pnp}"[enable the Plug'n'Play installation]" \
+    '--flat[only allow one version of a package]' \
+    '--focus[Focus on a single workspace by installing remote copies of its sibling workspaces]' \
+    '--force[install and build packages even if they were built before, overwrite lockfile]' \
+    "--frozen-lockfile[don't generate a lockfile and fail if an update is needed]" \
+    '--global-folder=[modules folder]:folder:_files -/' \
+    '--har[save HAR output of network traffic]' \
+    '--https-proxy=[HTTPS proxy]:host:_hosts' \
+    '--ignore-engines[ignore engines check]' \
+    "--ignore-scripts[don't run lifecycle scripts]" \
+    '--ignore-optional[ignore optional dependencies]' \
+    '--ignore-platform[ignore platform checks]' \
+    '--json[format Yarn log messages as lines of JSON]' \
+    '--link-duplicates[create hardlinks to the repeated modules in node_modules]' \
+    '--link-folder=[specify a custom folder to store global links]' \
+    '--modules-folder=[rather than installing modules into the node_modules folder relative to the cwd, output them here]:folder:_files -/' \
+    '--mutex=[use a mutex to ensure only one yarn instance is executing]:type[\:specifier]' \
+    '--network-concurrency=[maximum number of concurrent network requests]:number' \
+    '--network-timeout=[TCP timeout for network requests]:milliseconds' \
+    "--no-bin-links[don't generate bin links when setting up packages]" \
+    '--no-default-rc[prevent Yarn from automatically detecting yarnrc and npmrc files]' \
+    "--no-lockfile[don't read or generate a lockfile]" \
+    '--non-interactive[do not show interactive prompts]' \
+    '--no-node-version-check[do not warn when using a potentially unsupported Node version]' \
+    '--no-progress[disable progress bar]' \
+    '--offline[trigger an error if any required dependencies are not available in local cache]' \
+    '--otp=[one-time password for two factor authentication]:otpcode' \
+    '--prefer-offline[use network only if dependencies are not available in local cache]' \
+    '--preferred-cache-folder=[specify a custom folder to store the yarn cache if possible]:folder:_files -/' \
+    '(--prod --production)'{--prod,--production}'[install only production dependencies]' \
+    '--proxy=[HTTP proxy]:host:_hosts' \
+    "--pure-lockfile[don't generate a lockfile]" \
+    '--registry=[override configuration registry]:url:_urls' \
+    '(-s --silent)'{-s,--silent}'[skip Yarn console logs, other types of logs (script output) will be printed]' \
+    '--scripts-prepend-node-path=[prepend the node executable dir to the PATH in scripts]:bool:(true false)' \
+    '--skip-integrity-check[run install without checking if node_modules is installed]' \
+    "--strict-semver[don't compare semver loosely]" \
+    '--update-checksum[update package checksums from current repository]' \
+    '--use-yarnrc=[specifies a yarnrc that Yarn should use]:yarnrc:_files' \
+    '1: :_yarn_commands_scripts' \
+    '*:: :->command_args'
+
+
+  case $state in
+    command_args)
+      case $words[1] in
+        help)
+          _arguments \
+            '1: :_yarn_commands' \
+        ;;
+
+        access)
+          _arguments \
+            '1: :(public restricted grant revoke ls-packages ls-collaborators edit)'
+        ;;
+
+        add)
+          _arguments \
+            '(-D --dev)'{-D,--dev}'[install packages in devDependencies]' \
+            '(-P --peer)'{-P,--peer}'[install packages in peerDependencies]' \
+            '(-O --optional)'{-O,--optional}'[install packages in optionalDependencies]' \
+            '(-E --exact)'{-E,--exact}'[install packages as exact versions]' \
+            '(-T --tilde)'{-T,--tilde}'[install the most recent release of the packages that have the same minor version]' \
+            '(--ignore-workspace-root-check -W)'{--ignore-workspace-root-check,-W}'[allows a package to be installed at the workspaces root]' \
+            '--audit[checks for known security issues with the installed packages]' \
+            '*:package-name:_yarn_add_files'
+        ;;
+
+        audit)
+          _arguments \
+            '--verbose[output verbose message]' \
+            '--json[format Yarn log messages as lines of JSON]' \
+            '--level=[only print advisories with severity greater than or equal to]:level:(info low moderate high critical)' \
+            '--groups=[only audit dependencies from listed groups]:groups:->groups_args'
+        ;;
+
+        cache)
+          _arguments \
+            '1: :(list dir clean)' \
+            '*:: :->cache_args'
+        ;;
+
+        check)
+          _arguments \
+            '--integrity[Verifies that versions and hashed values of the package contents in package.json]' \
+            '--verify-tree[Recursively verifies that the dependencies in package.json are present in node_modules]'
+        ;;
+
+        config)
+          _arguments \
+            '1: :(set get delete list)' \
+            '*:: :->config_args'
+        ;;
+
+        global)
+          _arguments \
+            '--prefix=[bin prefix to use to install binaries]' \
+            '1: :_yarn_global_commands' \
+            '*:: :->command_args'
+        ;;
+
+        info)
+          _arguments \
+            '1:package:' \
+            '2:field'
+        ;;
+
+        init)
+          _arguments \
+            '(-y --yes)'{-y,--yes}'[install packages in devDependencies]'
+        ;;
+
+        licenses)
+          _arguments \
+            '1: :(ls generate-disclaimer)' \
+        ;;
+
+        link|unlink|outdated)
+          _arguments \
+            '1:package' \
+        ;;
+
+        list)
+          _arguments \
+            '--depth=[Limit the depth of the shown dependencies]:depth' \
+            '--pattern=[filter the list of dependencies by the pattern]'
+        ;;
+
+        owner)
+          _arguments \
+            '1: :(list add rm)' \
+            '*:: :->owner_args'
+        ;;
+
+        pack)
+          _arguments \
+            '(-f --filename)'{-f,--filename}':filename:_files'
+        ;;
+
+        publish)
+          _arguments \
+            '--new-version:version:' \
+            '--message:message:' \
+            '--no-git-tag-version' \
+            '--access:access:' \
+            '--tag:tag:' \
+            '1: :_files'
+        ;;
+
+        policies)
+          _arguments \
+            '1: :(set-version)'
+        ;;
+
+        remove|upgrade)
+          _arguments \
+            '*:package:'
+        ;;
+
+        run)
+          if [[ -n $opt_args[--cwd] ]]; then
+            _yarn_run_cwd=$opt_args[--cwd]
+          else
+            _yarn_run_cwd=''
+          fi
+          _arguments \
+            '1: :_yarn_scripts' \
+            '*:: :_default'
+        ;;
+
+        tag)
+          _arguments \
+            '1: :(lists add rm)' \
+            '*:: :->tag_args'
+        ;;
+
+        team)
+          _arguments \
+            '1: :(create destroy add rm list)' \
+            '*:: :->team_args'
+        ;;
+
+        upgrade-interactive)
+          _arguments \
+            '--latest[use the version tagged latest in the registry]'
+        ;;
+
+        version)
+          _arguments \
+            '--new-version[create a new version using an interactive session to prompt you]:version:' \
+            '--major[creates a new version by incrementing the major version]' \
+            '--minor[creates a new version by incrementing the minor version]' \
+            '--patch[creates a new version by incrementing the patch version]' \
+            '--premajor[creates a new prerelease version by incrementing the major version]' \
+            '--preminor[creates a new prerelease version by incrementing the minor version]' \
+            '--prepatch[creates a new prerelease version by incrementing the patch version]' \
+            '--prerelease[increments the prerelease version number keeping the main version]' \
+            '--no-git-tag-version[creates a new version without creating a git tag]' \
+            '--no-commit-hooks[bypasses running commit hooks when committing the new version]'
+        ;;
+
+        why)
+          _arguments \
+            '1:query:_files'
+        ;;
+
+        workspace)
+          _arguments \
+            '1:workspace:_yarn_workspaces' \
+            '*:: :_yarn_global_commands'
+        ;;
+
+        workspaces)
+          _arguments \
+            '--json[format Yarn log messages as lines of JSON]' \
+            '1:commands:(info run)'
+        ;;
+
+        *)
+          _default
+        ;;
+      esac
+    ;;
+  esac
+
+  case $state in
+    cache_args)
+      if [[ $words[1] == "list" ]]; then
+        _arguments \
+          '--pattern=[print out every cached package that matches the pattern]:pattern:'
+      fi
+    ;;
+    config_args)
+      case $words[1] in
+        get|delete)
+          _arguments \
+            '1:key:'
+        ;;
+
+        set)
+          _arguments \
+            '(-g --global)'{-g,--global} \
+            '1:key:' \
+            '2:value:'
+        ;;
+      esac
+    ;;
+    groups_args)
+      local dependency_groups=(devDependencies dependencies optionalDependencies peerDependencies bundledDependencies)
+      _values -s ',' 'groups' $dependency_groups
+    ;;
+
+    owner_args)
+      case $words[1] in
+        ls)
+          _arguments \
+            '1:package:'
+        ;;
+
+        add|rm)
+          _arguments \
+            '1:user:' \
+            '2:package:'
+        ;;
+      esac
+    ;;
+
+    tag_args)
+      case $words[1] in
+        ls)
+          _arguments \
+            '1:package'
+        ;;
+
+        add|rm)
+          _arguments \
+            '1:package:' \
+            '2:tag:'
+        ;;
+      esac
+    ;;
+
+    team_args)
+      case $words[1] in
+        create|destroy|ls)
+          _arguments \
+            '1:scope\:team:'
+        ;;
+
+        add|rm)
+          _arguments \
+            '1:scope\:team:' \
+            '2:user:'
+        ;;
+      esac
+    ;;
+  esac
+}
+
+_yarn "$@"
+
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/yarn.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/yarn/yarn.plugin.zsh
new file mode 100644 (file)
index 0000000..bcb8661
--- /dev/null
@@ -0,0 +1,44 @@
+if zstyle -T ':omz:plugins:yarn' global-path; then
+  # Skip yarn call if default global bin dir exists
+  [[ -d "$HOME/.yarn/bin" ]] && bindir="$HOME/.yarn/bin" || bindir="$(yarn global bin 2>/dev/null)"
+
+  # Add yarn bin directory to $PATH if it exists and not already in $PATH
+  [[ $? -eq 0 ]] \
+    && [[ -d "$bindir" ]] \
+    && (( ! ${path[(Ie)$bindir]} )) \
+    && path+=("$bindir")
+  unset bindir
+fi
+
+alias y="yarn"
+alias ya="yarn add"
+alias yad="yarn add --dev"
+alias yap="yarn add --peer"
+alias yb="yarn build"
+alias ycc="yarn cache clean"
+alias yd="yarn dev"
+alias yga="yarn global add"
+alias ygls="yarn global list"
+alias ygrm="yarn global remove"
+alias ygu="yarn global upgrade"
+alias yh="yarn help"
+alias yi="yarn init"
+alias yin="yarn install"
+alias yln="yarn lint"
+alias ylnf="yarn lint --fix"
+alias yls="yarn list"
+alias yout="yarn outdated"
+alias yp="yarn pack"
+alias yrm="yarn remove"
+alias yrun="yarn run"
+alias ys="yarn serve"
+alias yst="yarn start"
+alias yt="yarn test"
+alias ytc="yarn test --coverage"
+alias yuc="yarn global upgrade && yarn cache clean"
+alias yui="yarn upgrade-interactive"
+alias yuil="yarn upgrade-interactive --latest"
+alias yup="yarn upgrade"
+alias yv="yarn version"
+alias yw="yarn workspace"
+alias yws="yarn workspaces"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yii/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/yii/README.md
new file mode 100644 (file)
index 0000000..9636149
--- /dev/null
@@ -0,0 +1,15 @@
+# Yii plugin
+
+The plugin adds autocomplete commands and subcommands for [yii](https://www.yiiframework.com/).
+
+To use it, add `yii` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... yii)
+```
+
+## Aliases
+
+| Alias  | Command              |
+|--------|----------------------|
+| yiic   | `protected/yiic`     |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yii/yii.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/yii/yii.plugin.zsh
new file mode 100644 (file)
index 0000000..b816160
--- /dev/null
@@ -0,0 +1,17 @@
+# Yii basic command completion
+
+_yii_get_command_list () {
+       protected/yiic | awk '/^ - [a-z]+/ { print $2 }'
+}
+
+_yii () {
+  if [ -f protected/yiic ]; then
+    compadd `_yii_get_command_list`
+  fi
+}
+
+compdef _yii protected/yiic
+compdef _yii yiic
+
+# Aliases
+alias yiic='protected/yiic'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yii2/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/yii2/README.md
new file mode 100644 (file)
index 0000000..345b66e
--- /dev/null
@@ -0,0 +1,7 @@
+# Yii2 autocomplete plugin
+
+* Adds autocomplete commands and subcommands for yii.
+
+## Requirements
+
+Autocomplete works from directory where your `yii` file contains.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yii2/yii2.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/yii2/yii2.plugin.zsh
new file mode 100644 (file)
index 0000000..713f2ef
--- /dev/null
@@ -0,0 +1,29 @@
+# Yii2 command completion
+
+_yii2_format_command () {
+  awk '/^- [a-z]+/ { sub(":", "", $2); print $2 }'
+}
+
+_yii2 () {
+  if [ -f ./yii ]; then
+    _arguments \
+      '1: :->command'\
+      '*: :->params'
+
+    case $state in
+      command)
+
+      local -a commands
+      local -a name
+
+      if [[ $words[2] == *\/ ]]; then
+        name=$words[2]
+      fi
+
+      commands=(${(f)"$(./yii help $name --color=0 | _yii2_format_command)"})
+      compadd -Q -S '' -a -- commands
+    esac
+  fi
+}
+
+compdef _yii2 yii
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yum/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/yum/README.md
new file mode 100644 (file)
index 0000000..fec5849
--- /dev/null
@@ -0,0 +1,27 @@
+# Yum plugin
+
+This plugin adds useful aliases for common [Yum](http://yum.baseurl.org/) commands.
+
+To use it, add `yum` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... yum)
+```
+
+## Aliases
+
+| Alias | Command                           | Description                  |
+|-------|-----------------------------------|------------------------------|
+| ys    | `yum search`                      | Search package               |
+| yp    | `yum info`                        | Show package info            |
+| yl    | `yum list`                        | List packages                |
+| ygl   | `yum grouplist`                   | List package groups          |
+| yli   | `yum list installed`              | Print all installed packages |
+| ymc   | `yum makecache`                   | Rebuild the yum package list |
+| yu    | `sudo yum update`                 | Upgrade packages             |
+| yi    | `sudo yum install`                | Install package              |
+| ygi   | `sudo yum groupinstall`           | Install package group        |
+| yr    | `sudo yum remove`                 | Remove package               |
+| ygr   | `sudo yum groupremove`            | Remove pagage group          |
+| yrl   | `sudo yum remove --remove-leaves` | Remove package and leaves    |
+| yc    | `sudo yum clean all`              | Clean yum cache              |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/yum/yum.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/yum/yum.plugin.zsh
new file mode 100644 (file)
index 0000000..d365711
--- /dev/null
@@ -0,0 +1,16 @@
+## Aliases
+
+alias ys="yum search"                       # search package
+alias yp="yum info"                         # show package info
+alias yl="yum list"                         # list packages
+alias ygl="yum grouplist"                   # list package groups
+alias yli="yum list installed"              # print all installed packages
+alias ymc="yum makecache"                   # rebuilds the yum package list
+
+alias yu="sudo yum update"                  # upgrade packages
+alias yi="sudo yum install"                 # install package
+alias ygi="sudo yum groupinstall"           # install package group
+alias yr="sudo yum remove"                  # remove package
+alias ygr="sudo yum groupremove"            # remove pagage group
+alias yrl="sudo yum remove --remove-leaves" # remove package and leaves
+alias yc="sudo yum clean all"               # clean cache
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/z/LICENSE b/stow/oh-my-zsh/.oh-my-zsh/plugins/z/LICENSE
new file mode 100644 (file)
index 0000000..d1cca7a
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018-2022 Alexandros Kozak
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/z/MANUAL.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/z/MANUAL.md
new file mode 100644 (file)
index 0000000..dcca3c4
--- /dev/null
@@ -0,0 +1,343 @@
+# Zsh-z
+
+Zsh-z is a command line tool that allows you to jump quickly to directories that you have visited frequently in the past, or recently -- but most often a combination of the two (a concept known as ["frecency"](https://en.wikipedia.org/wiki/Frecency)). It works by keeping track of when you go to directories and how much time you spend in them. It is then in the position to guess where you want to go when you type a partial string, e.g., `z src` might take you to `~/src/zsh`. `z zsh` might also get you there, and `z c/z` might prove to be even more specific -- it all depends on your habits and how much time you have been using Zsh-z to build up a database. After using Zsh-z for a little while, you will get to where you want to be by typing considerably less than you would need if you were using `cd`.
+
+Zsh-z is a native Zsh port of [rupa/z](https://github.com/rupa/z), a tool written for `bash` and Zsh that uses embedded `awk` scripts to do the heavy lifting. It was quite possibly my most used command line tool for a couple of years. I decided to translate it, `awk` parts and all, into pure Zsh script, to see if by eliminating calls to external tools (`awk`, `sort`, `date`, `sed`, `mv`, `rm`, and `chown`) and reducing forking through subshells I could make it faster. The performance increase is impressive, particularly on systems where forking is slow, such as Cygwin, MSYS2, and WSL. I have found that, in those environments, switching directories using Zsh-z can be over 100% faster than it is using `rupa/z`.
+
+There is a noteworthy stability increase as well. Race conditions have always been a problem with `rupa/z`, and users of that utility will occasionally lose their `.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code that works on `bash` as well), I have been able to implement a `zsh/system`-based file-locking mechanism similar to [the one @mafredri once proposed for `rupa/z`](https://github.com/rupa/z/pull/199). It is now nearly impossible to crash the database, even through extreme testing.
+
+There are other, smaller improvements which I try to document in [Improvements and Fixes](#improvements-and-fixes). These include the new default behavior of sorting your tab completions by frecency rather than just letting Zsh sort the raw results alphabetically (a behavior which can be restored if you like it -- [see below](#settings)).
+
+Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same database (`~/.z`), so you can go on using `rupa/z` when you launch `bash`.
+
+## Table of Contents
+- [News](#news)
+- [Installation](#installation)
+- [Command Line Options](#command-line-options)
+- [Settings](#settings)
+- [Case Sensitivity](#case-sensitivity)
+- [`ZSHZ_UNCOMMON`](#zshz_uncommon)
+- [Making `--add` work for you](#making---add-work-for-you)
+- [Other Improvements and Fixes](#other-improvements-and-fixes)
+- [Migrating from Other Tools](#migrating-from-other-tools)
+- [`COMPLETE_ALIASES`](#complete_aliases)
+- [Known Bugs](#known-bugs)
+
+## News
+
+<details>
+    <summary>Here are the latest features and updates.</summary>
+
+- June 29, 2022
+    + Zsh-z is less likely to leave temporary files sitting around (props @mafredri).
+- June 27, 2022
+    + A bug was fixed which was preventing paths with spaces in them from being updated ([#61](https://github.com/agkozak/zsh-z/issues/61)).
+    + If writing to the temporary database file fails, the database will not be clobbered (props @mafredri).
+- December 19, 2021
+    + ZSH-z will now display tildes for `HOME` during completion when `ZSHZ_TILDE=1` has been set.
+- November 11, 2021
+    + A bug was fixed which was preventing ranks from being incremented.
+    + `--add` has been made to work with relative paths and has been documented for the user.
+- October 14, 2021
+    + Completions were being sorted alphabetically, rather than by rank; this error has been fixed.
+- September 25, 2021
+    + Orthographical change: "Zsh," not "ZSH."
+- September 23, 2021
+    + `z -xR` will now remove a directory *and its subdirectories* from the database.
+    + `z -x` and `z -xR` can now take an argument; without one, `PWD` is assumed.
+- September 7, 2021
+    + Fixed the unload function so that it removes the `$ZSHZ_CMD` alias (default: `z`).
+- August 27, 2021
+    + Using `print -v ... -f` instead of `print -v` to work around longstanding bug in Zsh involving `print -v` and multibyte strings.
+- August 13, 2021
+    + Fixed the explanation string printed during completion so that it may be formatted with `zstyle`.
+    + Zsh-z now declares `ZSHZ_EXCLUDE_DIRS` as an array with unique elements so that you do not have to.
+- July 29, 2021
+    + Temporarily disabling use of `print -v`, which seems to be mangling CJK multibyte strings.
+- July 27, 2021
+    + Internal escaping of path names now works with older versions of ZSH.
+    + Zsh-z now detects and discards any incomplete or incorrectly formattted database entries.
+- July 10, 2021
+    + Setting `ZSHZ_TRAILING_SLASH=1` makes it so that a search pattern ending in `/` can match the end of a path; e.g. `z foo/` can match `/path/to/foo`.
+- June 25, 2021
+    + Setting `ZSHZ_TILDE=1` displays the `HOME` directory as `~`.
+- May 7, 2021
+    + Setting `ZSHZ_ECHO=1` will cause Zsh-z to display the new path when you change directories.
+    + Better escaping of path names to deal paths containing the characters ``\`()[]``.
+- February 15, 2021
+    + Ranks are displayed the way `rupa/z` now displays them, i.e. as large integers. This should help Zsh-z to integrate with other tools.
+- January 31, 2021
+    + Zsh-z is now efficient enough that, on MSYS2 and Cygwin, it is faster to run it in the foreground than it is to fork a subshell for it.
+    + `_zshz_precmd` simply returns if `PWD` is `HOME` or in `ZSH_EXCLUDE_DIRS`, rather than waiting for `zshz` to do that.
+- January 17, 2021
+    + Made sure that the `PUSHD_IGNORE_DUPS` option is respected.
+- January 14, 2021
+    + The `z -h` help text now breaks at spaces.
+    + `z -l` was not working for Zsh version < 5.
+- January 11, 2021
+    + Major refactoring of the code.
+    + `z -lr` and `z -lt` work as expected.
+    + `EXTENDED_GLOB` has been disabled within the plugin to accomodate old-fashioned Windows directories with names such as `Progra~1`.
+    + Removed `zshelldoc` documentation.
+- January 6, 2021
+    + I have corrected the frecency routine so that it matches `rupa/z`'s math, but for the present, Zsh-z will continue to display ranks as 1/10000th of what they are in `rupa/z` -- [they had to multiply theirs by 10000](https://github.com/rupa/z/commit/f1f113d9bae9effaef6b1e15853b5eeb445e0712) to work around `bash`'s inadequacies at dealing with decimal fractions.
+- January 5, 2021
+    + If you try `z foo`, and `foo` is not in the database but `${PWD}/foo` is a valid directory, Zsh-z will `cd` to it.
+- December 22, 2020
+    + `ZSHZ_CASE`: when set to `ignore`, pattern matching is case-insensitive; when set to `smart`, patterns are matched case-insensitively when they are all lowercase and case-sensitively when they have uppercase characters in them (a behavior very much like Vim's `smartcase` setting).
+    + `ZSHZ_KEEP_DIRS` is an array of directory names that should not be removed from the database, even if they are not currently available (useful when a drive is not always mounted).
+    + Symlinked datafiles were having their symlinks overwritten; this bug has been fixed.
+
+</details>
+
+## Installation
+
+### General observations
+
+This script can be installed simply by downloading it and sourcing it from your `.zshrc`:
+
+    source /path/to/zsh-z.plugin.zsh
+
+For tab completion to work, you will want to have loaded `compinit`. The frameworks handle this themselves. If you are not using a framework, put
+
+    autoload -U compinit && compinit
+
+in your .zshrc somewhere below where you source `zsh-z.plugin.zsh`.
+
+If you add
+
+    zstyle ':completion:*' menu select
+
+to your `.zshrc`, your completion menus will look very nice. This `zstyle` invocation should work with any of the frameworks below as well.
+
+### For [antigen](https://github.com/zsh-users/antigen) users
+
+Add the line
+
+    antigen bundle agkozak/zsh-z
+
+to your `.zshrc`, somewhere above the line that says `antigen apply`.
+
+### For [oh-my-zsh](http://ohmyz.sh/) users
+
+Execute the following command:
+
+    git clone https://github.com/agkozak/zsh-z ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-z
+
+and add `zsh-z` to the line of your `.zshrc` that specifies `plugins=()`, e.g., `plugins=( git zsh-z )`.
+
+### For [prezto](https://github.com/sorin-ionescu/prezto) users
+
+Execute the following command:
+
+    git clone https://github.com/agkozak/zsh-z.git ~/.zprezto-contrib/zsh-z
+
+Then edit your `~/.zpreztorc` file. Make sure the line that says
+
+    zstyle ':prezto:load' pmodule-dirs $HOME/.zprezto-contrib
+
+is uncommented. Then find the section that specifies which modules are to be loaded; it should look something like this:
+
+    zstyle ':prezto:load' pmodule \
+        'environment' \
+        'terminal' \
+        'editor' \
+        'history' \
+        'directory' \
+        'spectrum' \
+        'utility' \
+        'completion' \
+        'prompt'
+
+Add a backslash to the end of the last line add `'zsh-z'` to the list, e.g.,
+
+    zstyle ':prezto:load' pmodule \
+        'environment' \
+        'terminal' \
+        'editor' \
+        'history' \
+        'directory' \
+        'spectrum' \
+        'utility' \
+        'completion' \
+        'prompt' \
+        'zsh-z'
+
+Then relaunch `zsh`.
+
+### For [zcomet](https://github.com/agkozak/zcomet) users
+        
+Simply add
+
+    zcomet load agkozak/zsh-z
+
+to your `.zshrc` (below where you source `zcomet.zsh` and above where you run `zcomet compinit`).
+
+### For [zgen](https://github.com/tarjoilija/zgen) users
+
+Add the line
+
+    zgen load agkozak/zsh-z
+
+somewhere above the line that says `zgen save`. Then run
+
+    zgen reset
+    zsh
+
+to refresh your init script.
+
+### For [Zim](https://github.com/zimfw/zimfw)
+
+Add the following line to your `.zimrc`:
+
+    zmodule https://github.com/agkozak/zsh-z
+
+Then run
+
+    zimfw install
+
+and restart your shell.
+
+### For [Zinit](https://github.com/zdharma-continuum/zinit) users
+
+Add the line
+
+    zinit load agkozak/zsh-z
+
+to your `.zshrc`.
+
+`zsh-z` supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zshz` to restore the shell to its state before `zsh-z` was loaded.
+
+### For [Znap](https://github.com/marlonrichert/zsh-snap) users
+
+Add the line
+
+    znap source agkozak/zsh-z
+
+somewhere below the line where you `source` Znap itself.
+
+### For [zplug](https://github.com/zplug/zplug) users
+
+Add the line
+
+    zplug "agkozak/zsh-z"
+
+somewhere above the line that says `zplug load`. Then run
+
+    zplug install
+    zplug load
+
+to install `zsh-z`.
+
+## Command Line Options
+
+- `--add` Add a directory to the database
+- `-c`    Only match subdirectories of the current directory
+- `-e`    Echo the best match without going to it
+- `-h`    Display help
+- `-l`    List all matches without going to them
+- `-r`    Match by rank (i.e. how much time you spend in directories)
+- `-t`    Time -- match by how recently you have been to directories
+- `-x`    Remove a directory (by default, the current directory) from the database
+- `-xR`   Remove a directory (by default, the current directory) and its subdirectories from the database
+
+# Settings
+
+Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its behavior if you set them; you can also keep your old ones if you have been using `rupa/z` (they begin with `_Z_`).
+
+* `ZSHZ_CMD` changes the command name (default: `z`)
+* `ZSHZ_COMPLETION` can be `'frecent'` (default) or `'legacy'`, depending on whether you want your completion results sorted according to frecency or simply sorted alphabetically
+* `ZSHZ_DATA` changes the database file (default: `~/.z`)
+* `ZSHZ_ECHO` displays the new path name when changing directories (default: `0`)
+* `ZSHZ_EXCLUDE_DIRS` is an array of directories to keep out of the database (default: empty)
+* `ZSHZ_KEEP_DIRS` is an array of directories that should not be removed from the database, even if they are not currently available (useful when a drive is not always mounted) (default: empty)
+* `ZSHZ_MAX_SCORE` is the maximum combined score the database entries can have before they begin to age and potentially drop out of the database (default: 9000)
+* `ZSHZ_NO_RESOLVE_SYMLINKS` prevents symlink resolution (default: `0`)
+* `ZSHZ_OWNER` allows usage when in `sudo -s` mode (default: empty)
+* `ZSHZ_TILDE` displays the name of the `HOME` directory as a `~` (default: `0`)
+* `ZSHZ_TRAILING_SLASH` makes it so that a search pattern ending in `/` can match the final element in a path; e.g., `z foo/` can match `/path/to/foo` (default: `0`)
+* `ZSHZ_UNCOMMON` changes the logic used to calculate the directory jumped to; [see below](#zshz_uncommon`) (default: `0`)
+
+## Case sensitivity
+
+The default behavior of Zsh-z is to try to find a case-sensitive match. If there is none, then Zsh-z tries to find a case-insensitive match.
+
+Some users prefer simple case-insensitivity; this behavior can be enabled by setting
+
+    ZSHZ_CASE=ignore
+
+If you like Vim's `smartcase` setting, where lowercase patterns are case-insensitive while patterns with any uppercase characters are treated case-sensitively, try setting
+
+    ZSHZ_CASE=smart
+
+## `ZSHZ_UNCOMMON`
+
+A common complaint about the default behavior of `rupa/z` and Zsh-z involves "common prefixes." If you type `z code` and the best matches, in increasing order, are
+
+    /home/me/code/foo
+    /home/me/code/bar
+    /home/me/code/bat
+
+Zsh-z will see that all possible matches share a common prefix and will send you to that directory -- `/home/me/code` -- which is often a desirable result. But if the possible matches are
+
+    /home/me/.vscode/foo
+    /home/me/code/foo
+    /home/me/code/bar
+    /home/me/code/bat
+
+then there is no common prefix. In this case, `z code` will simply send you to the highest-ranking match, `/home/me/code/bat`.
+
+You may enable an alternate, experimental behavior by setting `ZSHZ_UNCOMMON=1`. If you do that, Zsh-z will not jump to a common prefix, even if one exists. Instead, it chooses the highest-ranking match -- but it drops any subdirectories that do not include the search term. So if you type `z bat` and `/home/me/code/bat` is the best match, that is exactly where you will end up. If, however, you had typed `z code` and the best match was also `/home/me/code/bat`, you would have ended up in `/home/me/code` (because `code` was what you had searched for). This feature is still in development, and feedback is welcome.
+
+## Making `--add` Work for You
+
+Zsh-z internally uses the `--add` option to add paths to its database. @zachriggle pointed out to me that users might want to use `--add` themselves, so I have altered it a little to make it more user-friendly.
+
+A good example might involve a directory tree that has Git repositories within it. The working directories could be added to the Zsh-z database as a batch with
+
+    for i in $(find $PWD -maxdepth 3 -name .git -type d); do
+      z --add ${i:h}
+    done
+
+(As a Zsh user, I tend to use `**` instead of `find`, but it is good to see how deep your directory trees go before doing that.)
+
+
+## Other Improvements and Fixes
+
+* `z -x` works, with the help of `chpwd_functions`.
+* Zsh-z works on Solaris.
+* Zsh-z uses the "new" `zshcompsys` completion system instead of the old `compctl` one.
+* There is no error message when the database file has not yet been created.
+* There is support for special characters (e.g., `[`) in directory names.
+* If `z -l` only returns one match, a common root is not printed.
+* Exit status codes increasingly make sense.
+* Completions work with options `-c`, `-r`, and `-t`.
+* If `~/foo` and `~/foob` are matches, `~/foo` is *not* the common root. Only a common parent directory can be a common root.
+* `z -x` and the new, recursive `z -xR` can take an argument so that you can remove directories other than `PWD` from the database.
+
+## Migrating from Other Tools
+
+Zsh-z's database format is identical to that of `rupa/z`. You may switch freely between the two tools (I still use `rupa/z` for `bash`). `fasd` also uses that database format, but it stores it by default in `~/.fasd`, so you will have to `cp ~/.fasd ~/.z` if you want to use your old directory history.
+
+If you are coming to Zsh-z (or even to the original `rupa/z`, for that matter) from `autojump`, try using my [`jumpstart-z`](https://github.com/agkozak/jumpstart-z/blob/master/jumpstart-z) tool to convert your old database to the Zsh-z format, or simply run
+
+    awk -F "\t" '{printf("%s|%0.f|%s\n", $2, $1, '"$(date +%s)"')}' < /path/to/autojump.txt > ~/.z
+
+## `COMPLETE_ALIASES`
+
+`z`, or any alternative you set up using `$ZSH_CMD` or `$_Z_CMD`, is an alias. `setopt COMPLETE_ALIASES` divorces the tab completion for aliases from the underlying commands they invoke, so if you enable `COMPLETE_ALIASES`, tab completion for Zsh-z will be broken. You can get it working again, however, by adding under
+
+    setopt COMPLETE_ALIASES
+
+the line
+
+    compdef _zshz ${ZSHZ_CMD:-${_Z_CMD:-z}}
+
+That will re-bind `z` or the command of your choice to the underlying Zsh-z function.
+
+## Known Bugs
+It is possible to run a completion on a string with spaces in it, e.g., `z us bi<TAB>` might take you to `/usr/local/bin`. This works, but as things stand, after the completion the command line reads
+
+    z us /usr/local/bin.
+
+You get where you want to go, but the detritus on the command line is annoying. This is also a problem in `rupa/z`, but I am keen on eventually eliminating this glitch. Advice is welcome.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/z/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/z/README.md
new file mode 100644 (file)
index 0000000..5b7d6f6
--- /dev/null
@@ -0,0 +1,24 @@
+# z - jump around
+
+This plugin defines the [z command](https://github.com/agkozak/zsh-z) that tracks your most visited directories and allows you to access them with very few keystrokes.
+
+### Example
+
+Assume that you have previously visited directory `~/.oh-my-zsh/plugins`. From any folder in your command line, you can quickly access it by using a regex match to this folder:
+
+```bash
+/usr/bin$ z plug  # Even 'z p' might suffice
+~/.oh-my-zsh/plugins$
+```
+
+### Setup
+
+To enable z, add `z` to your `plugins` array in your zshrc file:
+
+```zsh
+plugins=(... z)
+```
+
+### Further reading
+
+For advanced usage and details of z, see [MANUAL](./MANUAL.md) (copied from [agkozak/zsh-z](https://github.com/agkozak/zsh-z)).
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/z/_z b/stow/oh-my-zsh/.oh-my-zsh/plugins/z/_z
new file mode 100644 (file)
index 0000000..9891a52
--- /dev/null
@@ -0,0 +1,82 @@
+#compdef zshz ${ZSHZ_CMD:-${_Z_CMD:-z}}
+#
+# Zsh-z - jump around with Zsh - A native Zsh version of z without awk, sort,
+# date, or sed
+#
+# https://github.com/agkozak/zsh-z
+#
+# Copyright (c) 2018-2022 Alexandros Kozak
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# z (https://github.com/rupa/z) is copyright (c) 2009 rupa deadwyler and
+# licensed under the WTFPL license, Version 2.a
+#
+# shellcheck shell=ksh
+
+############################################################
+# Zsh-z COMPLETIONS
+############################################################
+emulate -L zsh
+(( ZSHZ_DEBUG )) &&
+  setopt LOCAL_OPTIONS WARN_CREATE_GLOBAL NO_WARN_NESTED_VAR 2> /dev/null
+
+# TODO: This routine currently reproduces z's feature of allowing spaces to be
+# used as wildcards in completions, so that
+#
+#   z us lo bi
+#
+# can expand to
+#
+#   z /usr/local/bin
+#
+# but it also reproduces z's buggy display on the commandline, viz.
+#
+#   z us lo /usr/local/bin
+#
+# Address.
+
+local completions expl completion
+local -a completion_list
+
+completions=$(zshz --complete ${(@)words:1})
+[[ -z $completions ]] && return 1
+
+for completion in ${(f)completions[@]}; do
+  if (( ZSHZ_TILDE )) && [[ $completion == ${HOME}* ]]; then
+    completion="~${(q)${completion#${HOME}}}"
+  else
+    completion="${(q)completion}"
+  fi
+  completion_list+=( $completion )
+done
+
+_description -V completion_list expl 'directories'
+
+if [[ $ZSHZ_COMPLETION == 'legacy' ]]; then
+  compadd "${expl[@]}" -QU -- "${completion_list[@]}"
+else
+  compadd "${expl[@]}" -QU -V zsh-z -- "${completion_list[@]}"
+fi
+
+compstate[insert]=menu
+
+return 0
+
+# vim: ft=zsh:fdm=indent:ts=2:et:sts=2:sw=2:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/z/z.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/z/z.plugin.zsh
new file mode 100644 (file)
index 0000000..209edfe
--- /dev/null
@@ -0,0 +1,968 @@
+################################################################################
+# Zsh-z - jump around with Zsh - A native Zsh version of z without awk, sort,
+# date, or sed
+#
+# https://github.com/agkozak/zsh-z
+#
+# Copyright (c) 2018-2022 Alexandros Kozak
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# z (https://github.com/rupa/z) is copyright (c) 2009 rupa deadwyler and
+# licensed under the WTFPL license, Version 2.
+#
+# Zsh-z maintains a jump-list of the directories you actually use.
+#
+# INSTALL:
+#   * put something like this in your .zshrc:
+#       source /path/to/zsh-z.plugin.zsh
+#   * cd around for a while to build up the database
+#
+# USAGE:
+#   * z foo       cd to the most frecent directory matching foo
+#   * z foo bar   cd to the most frecent directory matching both foo and bar
+#                   (e.g. /foo/bat/bar/quux)
+#   * z -r foo    cd to the highest ranked directory matching foo
+#   * z -t foo    cd to most recently accessed directory matching foo
+#   * z -l foo    List matches instead of changing directories
+#   * z -e foo    Echo the best match without changing directories
+#   * z -c foo    Restrict matches to subdirectories of PWD
+#   * z -x        Remove a directory (default: PWD) from the database
+#   * z -xR       Remove a directory (default: PWD) and its subdirectories from
+#                   the database
+#
+# ENVIRONMENT VARIABLES:
+#
+#   ZSHZ_CASE -> if `ignore', pattern matching is case-insensitive; if `smart',
+#     pattern matching is case-insensitive only when the pattern is all
+#     lowercase
+#   ZSHZ_CMD -> name of command (default: z)
+#   ZSHZ_COMPLETION -> completion method (default: 'frecent'; 'legacy' for
+#     alphabetic sorting)
+#   ZSHZ_DATA -> name of datafile (default: ~/.z)
+#   ZSHZ_EXCLUDE_DIRS -> array of directories to exclude from your database
+#     (default: empty)
+#   ZSHZ_KEEP_DIRS -> array of directories that should not be removed from the
+#     database, even if they are not currently available (default: empty)
+#   ZSHZ_MAX_SCORE -> maximum combined score the database entries can have
+#     before beginning to age (default: 9000)
+#   ZSHZ_NO_RESOLVE_SYMLINKS -> '1' prevents symlink resolution
+#   ZSHZ_OWNER -> your username (if you want use Zsh-z while using sudo -s)
+#   ZSHZ_UNCOMMON -> if 1, do not jump to "common directories," but rather drop
+#     subdirectories based on what the search string was (default: 0)
+################################################################################
+
+autoload -U is-at-least
+
+if ! is-at-least 4.3.11; then
+  print "Zsh-z requires Zsh v4.3.11 or higher." >&2 && exit
+fi
+
+############################################################
+# The help message
+#
+# Globals:
+#   ZSHZ_CMD
+############################################################
+_zshz_usage() {
+  print "Usage: ${ZSHZ_CMD:-${_Z_CMD:-z}} [OPTION]... [ARGUMENT]
+Jump to a directory that you have visited frequently or recently, or a bit of both, based on the partial string ARGUMENT.
+
+With no ARGUMENT, list the directory history in ascending rank.
+
+  --add Add a directory to the database
+  -c    Only match subdirectories of the current directory
+  -e    Echo the best match without going to it
+  -h    Display this help and exit
+  -l    List all matches without going to them
+  -r    Match by rank
+  -t    Match by recent access
+  -x    Remove a directory from the database (by default, the current directory)
+  -xR   Remove a directory and its subdirectories from the database (by default, the current directory)" |
+    fold -s -w $COLUMNS >&2
+}
+
+# Load zsh/datetime module, if necessary
+(( $+EPOCHSECONDS )) || zmodload zsh/datetime
+
+# Load zsh/files, if necessary
+[[ ${builtins[zf_chown]} == 'defined' &&
+   ${builtins[zf_mv]}    == 'defined' &&
+   ${builtins[zf_rm]}    == 'defined' ]] ||
+  zmodload -F zsh/files b:zf_chown b:zf_mv b:zf_rm
+
+# Load zsh/system, if necessary
+[[ ${modules[zsh/system]} == 'loaded' ]] || zmodload zsh/system &> /dev/null
+
+# Global associative array for internal use
+typeset -gA ZSHZ
+
+# Make sure ZSHZ_EXCLUDE_DIRS has been declared so that other scripts can
+# simply append to it
+(( ${+ZSHZ_EXCLUDE_DIRS} )) || typeset -gUa ZSHZ_EXCLUDE_DIRS
+
+# Determine if zsystem flock is available
+zsystem supports flock &> /dev/null && ZSHZ[USE_FLOCK]=1
+
+# Determine if `print -v' is supported
+is-at-least 5.3.0 && ZSHZ[PRINTV]=1
+
+############################################################
+# The Zsh-z Command
+#
+# Globals:
+#   ZSHZ
+#   ZSHZ_CASE
+#   ZSHZ_COMPLETION
+#   ZSHZ_DATA
+#   ZSHZ_DEBUG
+#   ZSHZ_EXCLUDE_DIRS
+#   ZSHZ_KEEP_DIRS
+#   ZSHZ_MAX_SCORE
+#   ZSHZ_OWNER
+#
+# Arguments:
+#   $* Command options and arguments
+############################################################
+zshz() {
+
+  # Don't use `emulate -L zsh' - it breaks PUSHD_IGNORE_DUPS
+  setopt LOCAL_OPTIONS NO_KSH_ARRAYS NO_SH_WORD_SPLIT EXTENDED_GLOB
+  (( ZSHZ_DEBUG )) && setopt LOCAL_OPTIONS WARN_CREATE_GLOBAL
+
+  local REPLY
+  local -a lines
+
+  # Allow the user to specify the datafile name in $ZSHZ_DATA (default: ~/.z)
+  # If the datafile is a symlink, it gets dereferenced
+  local datafile=${${ZSHZ_DATA:-${_Z_DATA:-${HOME}/.z}}:A}
+
+  # If the datafile is a directory, print a warning and exit
+  if [[ -d $datafile ]]; then
+    print "ERROR: Zsh-z's datafile (${datafile}) is a directory." >&2
+    exit
+  fi
+
+  # Make sure that the datafile exists before attempting to read it or lock it
+  # for writing
+  [[ -f $datafile ]] || touch "$datafile"
+
+  # Bail if we don't own the datafile and $ZSHZ_OWNER is not set
+  [[ -z ${ZSHZ_OWNER:-${_Z_OWNER}} && -f $datafile && ! -O $datafile ]] &&
+    return
+
+  # Load the datafile into an array and parse it
+  lines=( ${(f)"$(< $datafile)"} )
+  # Discard entries that are incomplete or incorrectly formatted
+  lines=( ${(M)lines:#/*\|[[:digit:]]##[.,]#[[:digit:]]#\|[[:digit:]]##} )
+
+  ############################################################
+  # Add a path to or remove one from the datafile
+  #
+  # Globals:
+  #   ZSHZ
+  #   ZSHZ_EXCLUDE_DIRS
+  #   ZSHZ_OWNER
+  #
+  # Arguments:
+  #   $1 Which action to perform (--add/--remove)
+  #   $2 The path to add
+  ############################################################
+  _zshz_add_or_remove_path() {
+    local action=${1}
+    shift
+
+    if [[ $action == '--add' ]]; then
+
+      # TODO: The following tasks are now handled by _agkozak_precmd. Dead code?
+
+      # Don't add $HOME
+      [[ $* == $HOME ]] && return
+
+      # Don't track directory trees excluded in ZSHZ_EXCLUDE_DIRS
+      local exclude
+      for exclude in ${(@)ZSHZ_EXCLUDE_DIRS:-${(@)_Z_EXCLUDE_DIRS}}; do
+        case $* in
+          ${exclude}|${exclude}/*) return ;;
+        esac
+      done
+    fi
+
+    # A temporary file that gets copied over the datafile if all goes well
+    local tempfile="${datafile}.${RANDOM}"
+
+    # See https://github.com/rupa/z/pull/199/commits/ed6eeed9b70d27c1582e3dd050e72ebfe246341c
+    if (( ZSHZ[USE_FLOCK] )); then
+
+      local lockfd
+
+      # Grab exclusive lock (released when function exits)
+      zsystem flock -f lockfd "$datafile" 2> /dev/null || return
+
+    fi
+
+    integer tmpfd
+    case $action in
+      --add)
+        exec {tmpfd}>|"$tempfile"  # Open up tempfile for writing
+        _zshz_update_datafile $tmpfd "$*"
+        local ret=$?
+        ;;
+      --remove)
+        local xdir  # Directory to be removed
+
+        if (( ${ZSHZ_NO_RESOLVE_SYMLINKS:-${_Z_NO_RESOLVE_SYMLINKS}} )); then
+          [[ -d ${${*:-${PWD}}:a} ]] && xdir=${${*:-${PWD}}:a}
+        else
+          [[ -d ${${*:-${PWD}}:A} ]] && xdir=${${*:-${PWD}}:a}
+        fi
+
+        local -a lines_to_keep
+        if (( ${+opts[-R]} )); then
+          # Prompt user before deleting entire database
+          if [[ $xdir == '/' ]] && ! read -q "?Delete entire Zsh-z database? "; then
+            print && return 1
+          fi
+          # All of the lines that don't match the directory to be deleted
+          lines_to_keep=( ${lines:#${xdir}\|*} )
+          # Or its subdirectories
+          lines_to_keep=( ${lines_to_keep:#${xdir%/}/**} )
+        else
+          # All of the lines that don't match the directory to be deleted
+          lines_to_keep=( ${lines:#${xdir}\|*} )
+        fi
+        if [[ $lines != "$lines_to_keep" ]]; then
+          lines=( $lines_to_keep )
+        else
+          return 1  # The $PWD isn't in the datafile
+        fi
+        exec {tmpfd}>|"$tempfile"  # Open up tempfile for writing
+        print -u $tmpfd -l -- $lines
+        local ret=$?
+        ;;
+    esac
+
+    if (( tmpfd != 0 )); then
+      # Close tempfile
+      exec {tmpfd}>&-
+    fi
+
+    if (( ret != 0 )); then
+      # Avoid clobbering the datafile if the write to tempfile failed
+      zf_rm -f "$tempfile"
+      return $ret
+    fi
+
+    local owner
+    owner=${ZSHZ_OWNER:-${_Z_OWNER}}
+
+    if (( ZSHZ[USE_FLOCK] )); then
+      zf_mv "$tempfile" "$datafile" 2> /dev/null || zf_rm -f "$tempfile"
+
+      if [[ -n $owner ]]; then
+        zf_chown ${owner}:"$(id -ng ${owner})" "$datafile"
+      fi
+    else
+      if [[ -n $owner ]]; then
+        zf_chown "${owner}":"$(id -ng "${owner}")" "$tempfile"
+      fi
+      zf_mv -f "$tempfile" "$datafile" 2> /dev/null || zf_rm -f "$tempfile"
+    fi
+
+    # In order to make z -x work, we have to disable zsh-z's adding
+    # to the database until the user changes directory and the
+    # chpwd_functions are run
+    if [[ $action == '--remove' ]]; then
+      ZSHZ[DIRECTORY_REMOVED]=1
+    fi
+  }
+
+  ############################################################
+  # Read the curent datafile contents, update them, "age" them
+  # when the total rank gets high enough, and print the new
+  # contents to STDOUT.
+  #
+  # Globals:
+  #   ZSHZ_KEEP_DIRS
+  #   ZSHZ_MAX_SCORE
+  #
+  # Arguments:
+  #   $1 File descriptor linked to tempfile
+  #   $2 Path to be added to datafile
+  ############################################################
+  _zshz_update_datafile() {
+
+    integer fd=$1
+    local -A rank time
+
+    # Characters special to the shell (such as '[]') are quoted with backslashes
+    # See https://github.com/rupa/z/issues/246
+    local add_path=${(q)2}
+
+    local -a existing_paths
+    local now=$EPOCHSECONDS line dir
+    local path_field rank_field time_field count x
+
+    rank[$add_path]=1
+    time[$add_path]=$now
+
+    # Remove paths from database if they no longer exist
+    for line in $lines; do
+      if [[ ! -d ${line%%\|*} ]]; then
+        for dir in ${(@)ZSHZ_KEEP_DIRS}; do
+          if [[ ${line%%\|*} == ${dir}/* ||
+                ${line%%\|*} == $dir     ||
+                $dir == '/' ]]; then
+            existing_paths+=( $line )
+          fi
+        done
+      else
+        existing_paths+=( $line )
+      fi
+    done
+    lines=( $existing_paths )
+
+    for line in $lines; do
+      path_field=${(q)line%%\|*}
+      rank_field=${${line%\|*}#*\|}
+      time_field=${line##*\|}
+
+      # When a rank drops below 1, drop the path from the database
+      (( rank_field < 1 )) && continue
+
+      if [[ $path_field == $add_path ]]; then
+        rank[$path_field]=$rank_field
+        (( rank[$path_field]++ ))
+        time[$path_field]=$now
+      else
+        rank[$path_field]=$rank_field
+        time[$path_field]=$time_field
+      fi
+      (( count += rank_field ))
+    done
+    if (( count > ${ZSHZ_MAX_SCORE:-${_Z_MAX_SCORE:-9000}} )); then
+      # Aging
+      for x in ${(k)rank}; do
+        print -u $fd -- "$x|$(( 0.99 * rank[$x] ))|${time[$x]}" || return 1
+      done
+    else
+      for x in ${(k)rank}; do
+        print -u $fd -- "$x|${rank[$x]}|${time[$x]}" || return 1
+      done
+    fi
+  }
+
+  ############################################################
+  # The original tab completion method
+  #
+  # String processing is smartcase -- case-insensitive if the
+  # search string is lowercase, case-sensitive if there are
+  # any uppercase letters. Spaces in the search string are
+  # treated as *'s in globbing. Read the contents of the
+  # datafile and print matches to STDOUT.
+  #
+  # Arguments:
+  #   $1 The string to be completed
+  ############################################################
+  _zshz_legacy_complete() {
+
+    local line path_field path_field_normalized
+
+    # Replace spaces in the search string with asterisks for globbing
+    1=${1//[[:space:]]/*}
+
+    for line in $lines; do
+
+      path_field=${line%%\|*}
+
+      path_field_normalized=$path_field
+      if (( ZSHZ_TRAILING_SLASH )); then
+        path_field_normalized=${path_field%/}/
+      fi
+
+      # If the search string is all lowercase, the search will be case-insensitive
+      if [[ $1 == "${1:l}" && ${path_field_normalized:l} == *${~1}* ]]; then
+        print -- $path_field
+      # Otherwise, case-sensitive
+      elif [[ $path_field_normalized == *${~1}* ]]; then
+        print -- $path_field
+      fi
+
+    done
+    # TODO: Search strings with spaces in them are currently treated case-
+    # insensitively.
+  }
+
+  ############################################################
+  # `print' or `printf' to REPLY
+  #
+  # Variable assignment through command substitution, of the
+  # form
+  #
+  #   foo=$( bar )
+  #
+  # requires forking a subshell; on Cygwin/MSYS2/WSL1 that can
+  # be surprisingly slow. Zsh-z avoids doing that by printing
+  # values to the variable REPLY. Since Zsh v5.3.0 that has
+  # been possible with `print -v'; for earlier versions of the
+  # shell, the values are placed on the editing buffer stack
+  # and then `read' into REPLY.
+  #
+  # Globals:
+  #   ZSHZ
+  #
+  # Arguments:
+  #   Options and parameters for `print'
+  ############################################################
+  _zshz_printv() {
+    # NOTE: For a long time, ZSH's `print -v' had a tendency
+    # to mangle multibyte strings:
+    #
+    #   https://www.zsh.org/mla/workers/2020/msg00307.html
+    #
+    # The bug was fixed in late 2020:
+    #
+    #   https://github.com/zsh-users/zsh/commit/b6ba74cd4eaec2b6cb515748cf1b74a19133d4a4#diff-32bbef18e126b837c87b06f11bfc61fafdaa0ed99fcb009ec53f4767e246b129
+    #
+    # In order to support shells with the bug, we must use a form of `printf`,
+    # which does not exhibit the undesired behavior. See
+    #
+    #   https://www.zsh.org/mla/workers/2020/msg00308.html
+
+    if (( ZSHZ[PRINTV] )); then
+      builtin print -v REPLY -f %s $@
+    else
+      builtin print -z $@
+      builtin read -rz REPLY
+    fi
+  }
+
+  ############################################################
+  # If matches share a common root, find it, and put it in
+  # REPLY for _zshz_output to use.
+  #
+  # Arguments:
+  #   $1 Name of associative array of matches and ranks
+  ############################################################
+  _zshz_find_common_root() {
+    local -a common_matches
+    local x short
+
+    common_matches=( ${(@Pk)1} )
+
+    for x in ${(@)common_matches}; do
+      if [[ -z $short ]] || (( $#x < $#short )) || [[ $x != ${short}/* ]]; then
+        short=$x
+      fi
+    done
+
+    [[ $short == '/' ]] && return
+
+    for x in ${(@)common_matches}; do
+      [[ $x != $short* ]] && return
+    done
+
+    _zshz_printv -- $short
+  }
+
+  ############################################################
+  # Calculate a common root, if there is one. Then do one of
+  # the following:
+  #
+  #   1) Print a list of completions in frecent order;
+  #   2) List them (z -l) to STDOUT; or
+  #   3) Put a common root or best match into REPLY
+  #
+  # Globals:
+  #   ZSHZ_UNCOMMON
+  #
+  # Arguments:
+  #   $1 Name of an associative array of matches and ranks
+  #   $2 The best match or best case-insensitive match
+  #   $3 Whether to produce a completion, a list, or a root or
+  #        match
+  ############################################################
+  _zshz_output() {
+
+    local match_array=$1 match=$2 format=$3
+    local common k x
+    local -a descending_list output
+    local -A output_matches
+
+    output_matches=( ${(Pkv)match_array} )
+
+    _zshz_find_common_root $match_array
+    common=$REPLY
+
+    case $format in
+
+      completion)
+        for k in ${(@k)output_matches}; do
+          _zshz_printv -f "%.2f|%s" ${output_matches[$k]} $k
+          descending_list+=( ${(f)REPLY} )
+          REPLY=''
+        done
+        descending_list=( ${${(@On)descending_list}#*\|} )
+        print -l $descending_list
+        ;;
+
+      list)
+        local path_to_display
+        for x in ${(k)output_matches}; do
+          if (( ${output_matches[$x]} )); then
+            path_to_display=$x
+            (( ZSHZ_TILDE )) &&
+              path_to_display=${path_to_display/#${HOME}/\~}
+            _zshz_printv -f "%-10d %s\n" ${output_matches[$x]} $path_to_display
+            output+=( ${(f)REPLY} )
+            REPLY=''
+          fi
+        done
+        if [[ -n $common ]]; then
+          (( ZSHZ_TILDE )) && common=${common/#${HOME}/\~}
+          (( $#output > 1 )) && printf "%-10s %s\n" 'common:' $common
+        fi
+        # -lt
+        if (( $+opts[-t] )); then
+          for x in ${(@On)output}; do
+            print -- $x
+          done
+        # -lr
+        elif (( $+opts[-r] )); then
+          for x in ${(@on)output}; do
+            print -- $x
+          done
+        # -l
+        else
+          for x in ${(@on)output}; do
+            print $x
+          done
+        fi
+        ;;
+
+      *)
+        if (( ! ZSHZ_UNCOMMON )) && [[ -n $common ]]; then
+          _zshz_printv -- $common
+        else
+          _zshz_printv -- ${(P)match}
+        fi
+        ;;
+    esac
+  }
+
+  ############################################################
+  # Match a pattern by rank, time, or a combination of the
+  # two, and output the results as completions, a list, or a
+  # best match.
+  #
+  # Globals:
+  #   ZSHZ
+  #   ZSHZ_CASE
+  #   ZSHZ_KEEP_DIRS
+  #   ZSHZ_OWNER
+  #
+  # Arguments:
+  #   #1 Pattern to match
+  #   $2 Matching method (rank, time, or [default] frecency)
+  #   $3 Output format (completion, list, or [default] store
+  #     in REPLY
+  ############################################################
+  _zshz_find_matches() {
+    setopt LOCAL_OPTIONS NO_EXTENDED_GLOB
+
+    local fnd=$1 method=$2 format=$3
+
+    local -a existing_paths
+    local line dir path_field rank_field time_field rank dx escaped_path_field
+    local -A matches imatches
+    local best_match ibest_match hi_rank=-9999999999 ihi_rank=-9999999999
+
+    # Remove paths from database if they no longer exist
+    for line in $lines; do
+      if [[ ! -d ${line%%\|*} ]]; then
+        for dir in ${(@)ZSHZ_KEEP_DIRS}; do
+          if [[ ${line%%\|*} == ${dir}/* ||
+                ${line%%\|*} == $dir     ||
+                $dir == '/' ]]; then
+            existing_paths+=( $line )
+          fi
+        done
+      else
+        existing_paths+=( $line )
+      fi
+    done
+    lines=( $existing_paths )
+
+    for line in $lines; do
+      path_field=${line%%\|*}
+      rank_field=${${line%\|*}#*\|}
+      time_field=${line##*\|}
+
+      case $method in
+        rank) rank=$rank_field ;;
+        time) (( rank = time_field - EPOCHSECONDS )) ;;
+        *)
+          # Frecency routine
+          (( dx = EPOCHSECONDS - time_field ))
+          rank=$(( 10000 * rank_field * (3.75/((0.0001 * dx + 1) + 0.25)) ))
+          ;;
+      esac
+
+      # Use spaces as wildcards
+      local q=${fnd//[[:space:]]/\*}
+
+      # If $ZSHZ_TRAILING_SLASH is set, use path_field with a trailing slash for matching.
+      local path_field_normalized=$path_field
+      if (( ZSHZ_TRAILING_SLASH )); then
+        path_field_normalized=${path_field%/}/
+      fi
+
+      # If $ZSHZ_CASE is 'ignore', be case-insensitive.
+      #
+      # If it's 'smart', be case-insensitive unless the string to be matched
+      # includes capital letters.
+      #
+      # Otherwise, the default behavior of Zsh-z is to match case-sensitively if
+      # possible, then to fall back on a case-insensitive match if possible.
+      if [[ $ZSHZ_CASE == 'smart' && ${1:l} == $1 &&
+            ${path_field_normalized:l} == ${~q:l} ]]; then
+        imatches[$path_field]=$rank
+      elif [[ $ZSHZ_CASE != 'ignore' && $path_field_normalized == ${~q} ]]; then
+        matches[$path_field]=$rank
+      elif [[ $ZSHZ_CASE != 'smart' && ${path_field_normalized:l} == ${~q:l} ]]; then
+        imatches[$path_field]=$rank
+      fi
+
+      # Escape characters that would cause "invalid subscript" errors
+      # when accessing the associative array.
+      escaped_path_field=${path_field//'\'/'\\'}
+      escaped_path_field=${escaped_path_field//'`'/'\`'}
+      escaped_path_field=${escaped_path_field//'('/'\('}
+      escaped_path_field=${escaped_path_field//')'/'\)'}
+      escaped_path_field=${escaped_path_field//'['/'\['}
+      escaped_path_field=${escaped_path_field//']'/'\]'}
+
+      if (( matches[$escaped_path_field] )) &&
+         (( matches[$escaped_path_field] > hi_rank )); then
+        best_match=$path_field
+        hi_rank=${matches[$escaped_path_field]}
+      elif (( imatches[$escaped_path_field] )) &&
+           (( imatches[$escaped_path_field] > ihi_rank )); then
+        ibest_match=$path_field
+        ihi_rank=${imatches[$escaped_path_field]}
+        ZSHZ[CASE_INSENSITIVE]=1
+      fi
+    done
+
+    # Return 1 when there are no matches
+    [[ -z $best_match && -z $ibest_match ]] && return 1
+
+    if [[ -n $best_match ]]; then
+      _zshz_output matches best_match $format
+    elif [[ -n $ibest_match ]]; then
+      _zshz_output imatches ibest_match $format
+    fi
+  }
+
+  # THE MAIN ROUTINE
+
+  local -A opts
+
+  zparseopts -E -D -A opts -- \
+    -add \
+    -complete \
+    c \
+    e \
+    h \
+    -help \
+    l \
+    r \
+    R \
+    t \
+    x
+
+  if [[ $1 == '--' ]]; then
+    shift
+  elif [[ -n ${(M)@:#-*} && -z $compstate ]]; then
+    print "Improper option(s) given."
+    _zshz_usage
+    return 1
+  fi
+
+  local opt output_format method='frecency' fnd prefix req
+
+  for opt in ${(k)opts}; do
+    case $opt in
+      --add)
+        [[ ! -d $* ]] && return 1
+        local dir
+        # Cygwin and MSYS2 have a hard time with relative paths expressed from /
+        if [[ $OSTYPE == (cygwin|msys) && $PWD == '/' && $* != /* ]]; then
+          set -- "/$*"
+        fi
+        if (( ${ZSHZ_NO_RESOLVE_SYMLINKS:-${_Z_NO_RESOLVE_SYMLINKS}} )); then
+          dir=${*:a}
+        else
+          dir=${*:A}
+        fi
+        _zshz_add_or_remove_path --add "$dir"
+        return
+        ;;
+      --complete)
+        if [[ -s $datafile && ${ZSHZ_COMPLETION:-frecent} == 'legacy' ]]; then
+          _zshz_legacy_complete "$1"
+          return
+        fi
+        output_format='completion'
+        ;;
+      -c) [[ $* == ${PWD}/* || $PWD == '/' ]] || prefix="$PWD " ;;
+      -h|--help)
+        _zshz_usage
+        return
+        ;;
+      -l) output_format='list' ;;
+      -r) method='rank' ;;
+      -t) method='time' ;;
+      -x)
+        # Cygwin and MSYS2 have a hard time with relative paths expressed from /
+        if [[ $OSTYPE == (cygwin|msys) && $PWD == '/' && $* != /* ]]; then
+          set -- "/$*"
+        fi
+        _zshz_add_or_remove_path --remove $*
+        return
+        ;;
+    esac
+  done
+  req="$*"
+  fnd="$prefix$*"
+
+  [[ -n $fnd && $fnd != "$PWD " ]] || {
+    [[ $output_format != 'completion' ]] && output_format='list'
+  }
+
+  #########################################################
+  # If $ZSHZ_ECHO == 1, display paths as you jump to them.
+  # If it is also the case that $ZSHZ_TILDE == 1, display
+  # the home directory as a tilde.
+  #########################################################
+  _zshz_echo() {
+    if (( ZSHZ_ECHO )); then
+      if (( ZSHZ_TILDE )); then
+        print ${PWD/#${HOME}/\~}
+      else
+        print $PWD
+      fi
+    fi
+  }
+
+  if [[ ${@: -1} == /* ]] && (( ! $+opts[-e] && ! $+opts[-l] )); then
+    # cd if possible; echo the new path if $ZSHZ_ECHO == 1
+    [[ -d ${@: -1} ]] && builtin cd ${@: -1} && _zshz_echo && return
+  fi
+
+  # With option -c, make sure query string matches beginning of matches;
+  # otherwise look for matches anywhere in paths
+
+  # zpm-zsh/colors has a global $c, so we'll avoid math expressions here
+  if [[ ! -z ${(tP)opts[-c]} ]]; then
+    _zshz_find_matches "$fnd*" $method $output_format
+  else
+    _zshz_find_matches "*$fnd*" $method $output_format
+  fi
+
+  local ret2=$?
+
+  local cd
+  cd=$REPLY
+
+  # New experimental "uncommon" behavior
+  #
+  # If the best choice at this point is something like /foo/bar/foo/bar, and the  # search pattern is `bar', go to /foo/bar/foo/bar; but if the search pattern
+  # is `foo', go to /foo/bar/foo
+  if (( ZSHZ_UNCOMMON )) && [[ -n $cd ]]; then
+    if [[ -n $cd ]]; then
+
+      # In the search pattern, replace spaces with *
+      local q=${fnd//[[:space:]]/\*}
+      q=${q%/} # Trailing slash has to be removed
+
+      # As long as the best match is not case-insensitive
+      if (( ! ZSHZ[CASE_INSENSITIVE] )); then
+        # Count the number of characters in $cd that $q matches
+        local q_chars=$(( ${#cd} - ${#${cd//${~q}/}} ))
+        # Try dropping directory elements from the right; stop when it affects
+        # how many times the search pattern appears
+        until (( ( ${#cd:h} - ${#${${cd:h}//${~q}/}} ) != q_chars )); do
+          cd=${cd:h}
+        done
+
+      # If the best match is case-insensitive
+      else
+        local q_chars=$(( ${#cd} - ${#${${cd:l}//${~${q:l}}/}} ))
+        until (( ( ${#cd:h} - ${#${${${cd:h}:l}//${~${q:l}}/}} ) != q_chars )); do
+          cd=${cd:h}
+        done
+      fi
+
+      ZSHZ[CASE_INSENSITIVE]=0
+    fi
+  fi
+
+  if (( ret2 == 0 )) && [[ -n $cd ]]; then
+    if (( $+opts[-e] )); then               # echo
+      (( ZSHZ_TILDE )) && cd=${cd/#${HOME}/\~}
+      print -- "$cd"
+    else
+      # cd if possible; echo the new path if $ZSHZ_ECHO == 1
+      [[ -d $cd ]] && builtin cd "$cd" && _zshz_echo
+    fi
+  else
+    # if $req is a valid path, cd to it; echo the new path if $ZSHZ_ECHO == 1
+    if ! (( $+opts[-e] || $+opts[-l] )) && [[ -d $req ]]; then
+      builtin cd "$req" && _zshz_echo
+    else
+      return $ret2
+    fi
+  fi
+}
+
+alias ${ZSHZ_CMD:-${_Z_CMD:-z}}='zshz 2>&1'
+
+############################################################
+# precmd - add path to datafile unless `z -x' has just been
+#   run
+#
+# Globals:
+#   ZSHZ
+############################################################
+_zshz_precmd() {
+  # Do not add PWD to datafile when in HOME directory, or
+  # if `z -x' has just been run
+  [[ $PWD == "$HOME" ]] || (( ZSHZ[DIRECTORY_REMOVED] )) && return
+
+  # Don't track directory trees excluded in ZSHZ_EXCLUDE_DIRS
+  local exclude
+  for exclude in ${(@)ZSHZ_EXCLUDE_DIRS:-${(@)_Z_EXCLUDE_DIRS}}; do
+    case $PWD in
+      ${exclude}|${exclude}/*) return ;;
+    esac
+  done
+
+  # It appears that forking a subshell is so slow in Windows that it is better
+  # just to add the PWD to the datafile in the foreground
+  if [[ $OSTYPE == (cygwin|msys) ]]; then
+      zshz --add "$PWD"
+  else
+      (zshz --add "$PWD" &)
+  fi
+
+  # See https://github.com/rupa/z/pull/247/commits/081406117ea42ccb8d159f7630cfc7658db054b6
+  : $RANDOM
+}
+
+############################################################
+# chpwd
+#
+# When the $PWD is removed from the datafile with `z -x',
+# Zsh-z refrains from adding it again until the user has
+# left the directory.
+#
+# Globals:
+#   ZSHZ
+############################################################
+_zshz_chpwd() {
+  ZSHZ[DIRECTORY_REMOVED]=0
+}
+
+autoload -Uz add-zsh-hook
+
+add-zsh-hook precmd _zshz_precmd
+add-zsh-hook chpwd _zshz_chpwd
+
+############################################################
+# Completion
+############################################################
+
+# Standarized $0 handling
+# (See https://github.com/agkozak/Zsh-100-Commits-Club/blob/master/Zsh-Plugin-Standard.adoc)
+0=${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}
+0=${${(M)0:#/*}:-$PWD/$0}
+
+(( ${fpath[(ie)${0:A:h}]} <= ${#fpath} )) || fpath=( "${0:A:h}" "${fpath[@]}" )
+
+############################################################
+# zsh-z functions
+############################################################
+ZSHZ[FUNCTIONS]='_zshz_usage
+                 _zshz_add_or_remove_path
+                 _zshz_update_datafile
+                 _zshz_legacy_complete
+                 _zshz_printv
+                 _zshz_find_common_root
+                 _zshz_output
+                 _zshz_find_matches
+                 zshz
+                 _zshz_precmd
+                 _zshz_chpwd
+                 _zshz'
+
+############################################################
+# Enable WARN_NESTED_VAR for functions listed in
+#   ZSHZ[FUNCTIONS]
+############################################################
+(( ZSHZ_DEBUG )) && () {
+  if is-at-least 5.4.0; then
+    local x
+    for x in ${=ZSHZ[FUNCTIONS]}; do
+      functions -W $x
+    done
+  fi
+}
+
+############################################################
+# Unload function
+#
+# See https://github.com/agkozak/Zsh-100-Commits-Club/blob/master/Zsh-Plugin-Standard.adoc#unload-fun
+#
+# Globals:
+#   ZSHZ
+#   ZSHZ_CMD
+############################################################
+zsh-z_plugin_unload() {
+  emulate -L zsh
+
+  add-zsh-hook -D precmd _zshz_precmd
+  add-zsh-hook -d chpwd _zshz_chpwd
+
+  local x
+  for x in ${=ZSHZ[FUNCTIONS]}; do
+    (( ${+functions[$x]} )) && unfunction $x
+  done
+
+  unset ZSHZ
+
+  fpath=( "${(@)fpath:#${0:A:h}}" )
+
+  (( ${+aliases[${ZSHZ_CMD:-${_Z_CMD:-z}}]} )) &&
+    unalias ${ZSHZ_CMD:-${_Z_CMD:-z}}
+
+  unfunction $0
+}
+
+# vim: fdm=indent:ts=2:et:sts=2:sw=2:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zbell/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/zbell/README.md
new file mode 100644 (file)
index 0000000..eb87699
--- /dev/null
@@ -0,0 +1,33 @@
+# zbell plugin
+
+This plugin prints a bell character when a command finishes if it has been
+running for longer than a specified duration.
+
+To use it, add `zbell` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... zbell)
+```
+
+## Settings
+
+These settings need to be set in your zshrc file, before Oh My Zsh is sourced.
+
+- `zbell_duration`: duration in seconds after which to consider notifying
+  the end of a command. Default: 15 seconds.
+
+- `zbell_ignore`: if there are programs that you know run long that you
+  don't want to bell after, then add them to the `zbell_ignore` array.
+  By default, `$EDITOR` and `$PAGER` are ignored:
+
+  ```zsh
+  zbell_ignore=($EDITOR $PAGER)
+  ```
+
+- `zbell_use_notify_send`: If set to `true`, `notify-send` tool is used -- if
+  available -- to display a popup on the screen. Default: `true` (enabled).
+
+## Author
+
+Adapted from an original version by [Jean-Philippe Ouellet](https://github.com/jpouellet).
+Made available under the ISC license.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zbell/zbell.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zbell/zbell.plugin.zsh
new file mode 100644 (file)
index 0000000..8e37402
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/env zsh
+
+# This script prints a bell character when a command finishes
+# if it has been running for longer than $zbell_duration seconds.
+# If there are programs that you know run long that you don't
+# want to bell after, then add them to $zbell_ignore.
+#
+# This script uses only zsh builtins so its fast, there's no needless
+# forking, and its only dependency is zsh and its standard modules
+#
+# Written by Jean-Philippe Ouellet <jpo@vt.edu>
+# Made available under the ISC license.
+
+# only do this if we're in an interactive shell
+[[ -o interactive ]] || return
+
+# get $EPOCHSECONDS. builtins are faster than date(1)
+zmodload zsh/datetime || return
+
+# make sure we can register hooks
+autoload -Uz add-zsh-hook || return
+
+# make sure we can do regexp replace
+autoload -Uz regexp-replace || return
+
+# initialize zbell_duration if not set
+(( ${+zbell_duration} )) || zbell_duration=15
+
+# initialize zbell_ignore if not set
+(( ${+zbell_ignore} )) || zbell_ignore=($EDITOR $PAGER)
+
+# initialize zbell_use_notify_send if not set
+(( ${+zbell_use_notify_send} )) || zbell_use_notify_send=true
+
+# initialize it because otherwise we compare a date and an empty string
+# the first time we see the prompt. it's fine to have lastcmd empty on the
+# initial run because it evaluates to an empty string, and splitting an
+# empty string just results in an empty array.
+zbell_timestamp=$EPOCHSECONDS
+
+# UI notification function
+# $1: command
+# $2: duration in seconds
+zbell_ui_notify() {
+       [[ $zbell_use_notify_send != "true" ]] && return
+
+       if type notify-send > /dev/null; then
+               notify-send -i terminal "Command completed in ${2}s:" $1
+       fi
+}
+
+# default notification function
+# $1: command
+# $2: duration in seconds
+zbell_notify() {
+       zbell_ui_notify "${@}"
+       print -n "\a"
+}
+
+# right before we begin to execute something, store the time it started at
+zbell_begin() {
+       zbell_timestamp=$EPOCHSECONDS
+       zbell_lastcmd=$1
+}
+
+# when it finishes, if it's been running longer than $zbell_duration,
+# and we dont have an ignored command in the line, then print a bell.
+zbell_end() {
+       local cmd_duration=$(( $EPOCHSECONDS - $zbell_timestamp ))
+       local ran_long=$(( $cmd_duration >= $zbell_duration ))
+
+       local zbell_lastcmd_tmp="$zbell_lastcmd"
+       regexp-replace zbell_lastcmd_tmp '^sudo ' ''
+
+       [[ $zbell_last_timestamp == $zbell_timestamp ]] && return
+
+       [[ $zbell_lastcmd_tmp == "" ]] && return
+
+       zbell_last_timestamp=$zbell_timestamp
+
+       local has_ignored_cmd=0
+       for cmd in ${(s:;:)zbell_lastcmd_tmp//|/;}; do
+               words=(${(z)cmd})
+               util=${words[1]}
+               if (( ${zbell_ignore[(i)$util]} <= ${#zbell_ignore} )); then
+                       has_ignored_cmd=1
+                       break
+               fi
+       done
+
+       (( ! $has_ignored_cmd && ran_long )) && zbell_notify $zbell_lastcmd $cmd_duration
+}
+
+# register the functions as hooks
+add-zsh-hook preexec zbell_begin
+add-zsh-hook precmd zbell_end
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/README.md
new file mode 100644 (file)
index 0000000..0131f70
--- /dev/null
@@ -0,0 +1,50 @@
+# zeus plugin
+
+[Zeus](https://github.com/burke/zeus) preloads your Rails environment and forks that
+process whenever needed. This effectively speeds up Rails' boot process to under 1 sec.
+This plugin adds autocompletion for zeus and aliases for common usage.
+
+To use it, add `zeus` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... zeus)
+```
+
+You also need to have the `zeus` gem installed.
+
+| Alias        | Command                                                            |
+|:-------------|:-------------------------------------------------------------------|
+| _zi_         | `zeus init`                                                        |
+| _zinit_      | `zeus init`                                                        |
+| _zs_         | `zeus start`                                                       |
+| _ztart_      | `zeus start`                                                       |
+| _zc_         | `zeus console`                                                     |
+| _zonsole_    | `zeus console`                                                     |
+| _zsr_        | `zeus server`                                                      |
+| _zerver_     | `zeus server`                                                      |
+| _zr_         | `noglob zeus rake`                                                 |
+| _zake_       | `noglob zeus rake`                                                 |
+| _zg_         | `zeus generate`                                                    |
+| _zenerate_   | `zeus generate`                                                    |
+| _zrn_        | `zeus runner`                                                      |
+| _zunner_     | `zeus runner`                                                      |
+| _zcu_        | `zeus cucumber`                                                    |
+| _zucumber_   | `zeus cucumber`                                                    |
+| _zwip_       | `zeus cucumber --profile wip`                                      |
+| _zspec_      | `zeus rspec`                                                       |
+| _zt_         | `zeus test`                                                        |
+| _zest_       | `zeus test`                                                        |
+| _zu_         | `zeus test test/unit/*`                                            |
+| _zunits_     | `zeus test test/unit/*`                                            |
+| _zf_         | `zeus test test/functional/*`                                      |
+| _zunctional_ | `zeus test test/functional/*`                                      |
+| _za_         | `zeus test test/unit/*; zeus test test/functional/; zeus cucumber` |
+| _zall_       | `zeus test test/unit/*; zeus test test/functional/; zeus cucumber` |
+| _zsw_        | `rm .zeus.sock`                                                    |
+| _zweep_      | `rm .zeus.sock`                                                    |
+| _zdbr_       | `zeus rake db:reset db:test:prepare`                               |
+| _zdbreset_   | `zeus rake db:reset db:test:prepare`                               |
+| _zdbm_       | `zeus rake db:migrate db:test:prepare`                             |
+| _zdbmigrate_ | `zeus rake db:migrate db:test:prepare`                             |
+| _zdbc_       | `zeus rake db:create`                                              |
+| _zdbcm_      | `zeus rake db:create db:migrate db:test:prepare`                   |
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/_zeus b/stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/_zeus
new file mode 100644 (file)
index 0000000..78f0c54
--- /dev/null
@@ -0,0 +1,98 @@
+#compdef zeus
+#autoload
+
+# in order to make this work, you will need to have the gem zeus installed
+# zeus zsh completion
+
+local -a _1st_arguments
+if [[ -e .zeus.sock ]]; then
+  _1st_arguments=(
+  'console:Lets you interact with your Rails application from the command line. (alias = c)'
+  'cucumber:Runs cucumber.'
+  'dbconsole:Figures out which database you are using and drops you into whichever command line interface.'
+  'destroy:Figures out what generate did, and undoes it. (alias = d)'
+  'generate:Uses templates to create a whole lot of things. (alias = g)'
+  'rake:Execute rake tasks.'
+  'runner:Runs Ruby code in the context of Rails non-interactively. (alias = r)'
+  'server:Launches a small web server named WEBrick which comes bundled with Ruby. (alias = s)'
+  'test:Runs RSpec tests. (alias = rspec, testrb)'
+  'version:Shows the version number.'
+  )
+else
+  _1st_arguments=(
+  'start:Preloads the zeus environment'
+  'init:Generate a zeus.json file'
+  )
+fi
+
+_rails_generate_arguments() {
+    generate_arguments=(
+      controller
+      generator
+      helper
+      integration_test
+      mailer
+      migration
+      model
+      observer
+      performance_test
+      plugin
+      resource
+      scaffold
+      scaffold_controller
+      session_migration
+      stylesheets
+    )
+}
+
+_rake_does_task_list_need_generating () {
+  if [ ! -f .rake_tasks ]; then return 0;
+  else
+    accurate=$(stat -f%m .rake_tasks)
+    changed=$(stat -f%m Rakefile)
+    return $(expr $accurate '>=' $changed)
+  fi
+}
+
+_zrake ()
+{
+    local expl
+    declare -a tasks
+
+    if [ -f Rakefile ]; then
+      if _rake_does_task_list_need_generating; then
+        echo "\nGenerating .rake_tasks..." > /dev/stderr
+        rake --silent --tasks | cut -d " " -f 2 > .rake_tasks
+      fi
+      tasks=(`cat .rake_tasks`)
+      _wanted tasks expl 'rake' compadd $tasks
+    fi
+}
+
+local expl
+local curcontext="$curcontext" state line
+typeset -A opt_args
+
+_arguments -C \
+    ':command:->command' \
+    '*::options:->options'
+
+
+case $state in
+  (command)
+    _describe -t commands "zeus subcommand" _1st_arguments
+    return
+  ;;
+
+  (options)
+    case $line[1] in
+      (rake)
+        _zrake
+      ;;
+      (generate|g|destroy|d)
+        _rails_generate_arguments
+        _wanted generate_arguments expl 'all generate' compadd -a generate_arguments
+      ;;
+    esac
+  ;;
+esac
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/zeus.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zeus/zeus.plugin.zsh
new file mode 100644 (file)
index 0000000..5dec1a4
--- /dev/null
@@ -0,0 +1,70 @@
+# Some aliases for zeus. (See: https://github.com/burke/zeus)
+# Zeus preloads your Rails environment and forks that process whenever
+# needed. This effectively speeds up Rails' boot process to under 1 sec.
+
+# Init
+alias zi='zeus init'
+alias zinit='zeus init'
+
+# Start
+alias zs='zeus start'
+alias ztart='zeus start'
+
+# Console
+alias zc='zeus console'
+alias zonsole='zeus console'
+
+# Server
+alias zsr='zeus server'
+alias zerver='zeus server'
+
+# Rake
+alias zr='noglob zeus rake'
+alias zake='noglob zeus rake'
+
+# Generate
+alias zg='zeus generate'
+alias zenerate='zeus generate'
+
+# Runner
+alias zrn='zeus runner'
+alias zunner='zeus runner'
+
+# Cucumber
+alias zcu='zeus cucumber'
+alias zucumber='zeus cucumber'
+alias zwip='zeus cucumber --profile wip'
+
+# Rspec
+alias zspec='zeus rspec'
+
+# Test
+alias zt='zeus test'
+alias zest='zeus test'
+
+alias zu='zeus test test/unit/*'
+alias zunits='zeus test test/unit/*'
+
+alias zf='zeus test test/functional/*'
+alias zunctional='zeus test test/functional/*'
+
+alias za='zeus test test/unit/*; zeus test test/functional/; zeus cucumber'
+alias zall='zeus test test/unit/*; zeus test test/functional/; zeus cucumber'
+
+# Clean up crashed zeus instances.
+alias zsw='rm .zeus.sock'
+alias zweep='rm .zeus.sock'
+
+# Reset database
+alias zdbr='zeus rake db:reset db:test:prepare'
+alias zdbreset='zeus rake db:reset db:test:prepare'
+
+# Migrate and prepare database
+alias zdbm='zeus rake db:migrate db:test:prepare'
+alias zdbmigrate='zeus rake db:migrate db:test:prepare'
+
+# Create database
+alias zdbc='zeus rake db:create'
+
+# Create, migrate and prepare database
+alias zdbcm='zeus rake db:create db:migrate db:test:prepare'
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zoxide/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/zoxide/README.md
new file mode 100644 (file)
index 0000000..f326eff
--- /dev/null
@@ -0,0 +1,14 @@
+# zoxide plugin
+
+Initializes [zoxide](https://github.com/ajeetdsouza/zoxide), a smarter cd
+command for your terminal.
+
+![Tutorial](https://raw.githubusercontent.com/ajeetdsouza/zoxide/97dc08347d9dbf5b5a4516b79e0ac27366b962ce/contrib/tutorial.webp)
+
+To use it, add `zoxide` to the plugins array in your `.zshrc` file:
+
+```zsh
+plugins=(... zoxide)
+```
+
+**Note:** you have to [install zoxide](https://github.com/ajeetdsouza/zoxide#step-1-install-zoxide) first.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zoxide/zoxide.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zoxide/zoxide.plugin.zsh
new file mode 100644 (file)
index 0000000..e5658b8
--- /dev/null
@@ -0,0 +1,5 @@
+if (( $+commands[zoxide] )); then
+  eval "$(zoxide init zsh)"
+else
+  echo '[oh-my-zsh] zoxide not found, please install it from https://github.com/ajeetdsouza/zoxide'
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-interactive-cd/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-interactive-cd/README.md
new file mode 100644 (file)
index 0000000..c8337fb
--- /dev/null
@@ -0,0 +1,23 @@
+# zsh-interactive-cd
+
+This plugin adds a fish-like interactive tab completion for the `cd` command.
+
+To use it, add `zsh-interactive-cd` to the plugins array of your zshrc file:
+```zsh
+plugins=(... zsh-interactive-cd)
+```
+
+![demo](https://user-images.githubusercontent.com/1441704/74360670-cb202900-4dc5-11ea-9734-f60caf726e85.gif)
+
+## Usage
+
+Press tab for completion as usual, it'll launch fzf automatically. Check fzf’s [readme](https://github.com/junegunn/fzf#search-syntax) for more search syntax usage.
+
+## Requirements
+
+This plugin requires [fzf](https://github.com/junegunn/fzf). Install it by following
+its [installation instructions](https://github.com/junegunn/fzf#installation).
+
+## Author
+
+[Henry Chang](https://github.com/changyuheng)
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh
new file mode 100644 (file)
index 0000000..b0520c2
--- /dev/null
@@ -0,0 +1,148 @@
+# Copyright (c) 2017 Henry Chang
+
+__zic_fzf_prog() {
+  [ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] \
+    && echo "fzf-tmux -d${FZF_TMUX_HEIGHT:-40%}" || echo "fzf"
+}
+
+__zic_matched_subdir_list() {
+  local dir length seg starts_with_dir
+  if [[ "$1" == */ ]]; then
+    dir="$1"
+    if [[ "$dir" != / ]]; then
+      dir="${dir: : -1}"
+    fi
+    length=$(echo -n "$dir" | wc -c)
+    if [ "$dir" = "/" ]; then
+      length=0
+    fi
+    find -L "$dir" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \
+        | cut -b $(( ${length} + 2 ))- | sed '/^$/d' | while read -r line; do
+      if [[ "${line[1]}" == "." ]]; then
+        continue
+      fi
+      echo "$line"
+    done
+  else
+    dir=$(dirname -- "$1")
+    length=$(echo -n "$dir" | wc -c)
+    if [ "$dir" = "/" ]; then
+      length=0
+    fi
+    seg=$(basename -- "$1")
+    starts_with_dir=$( \
+      find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
+          2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \
+          | while read -r line; do
+        if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
+          continue
+        fi
+        if [[ "$line" == "$seg"* ]]; then
+          echo "$line"
+        fi
+      done
+    )
+    if [ -n "$starts_with_dir" ]; then
+      echo "$starts_with_dir"
+    else
+      find -L "$dir" -mindepth 1 -maxdepth 1 -type d \
+          2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \
+          | while read -r line; do
+        if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then
+          continue
+        fi
+        if [[ "$line" == *"$seg"* ]]; then
+          echo "$line"
+        fi
+      done
+    fi
+  fi
+}
+
+_zic_list_generator() {
+  __zic_matched_subdir_list "${(Q)@[-1]}" | sort
+}
+
+_zic_complete() {
+  setopt localoptions nonomatch
+  local l matches fzf tokens base
+
+  l=$(_zic_list_generator $@)
+
+  if [ -z "$l" ]; then
+    zle ${__zic_default_completion:-expand-or-complete}
+    return
+  fi
+
+  fzf=$(__zic_fzf_prog)
+
+  if [ $(echo $l | wc -l) -eq 1 ]; then
+    matches=${(q)l}
+  else
+    matches=$(echo $l \
+        | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} \
+          --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS \
+          --bind 'shift-tab:up,tab:down'" ${=fzf} \
+        | while read -r item; do
+      echo -n "${(q)item} "
+    done)
+  fi
+
+  matches=${matches% }
+  if [ -n "$matches" ]; then
+    tokens=(${(z)LBUFFER})
+    base="${(Q)@[-1]}"
+    if [[ "$base" != */ ]]; then
+      if [[ "$base" == */* ]]; then
+        base="$(dirname -- "$base")"
+        if [[ ${base[-1]} != / ]]; then
+          base="$base/"
+        fi
+      else
+        base=""
+      fi
+    fi
+    LBUFFER="${tokens[1]} "
+    if [ -n "$base" ]; then
+      base="${(q)base}"
+      if [ "${tokens[2][1]}" = "~" ]; then
+        base="${base/#$HOME/~}"
+      fi
+      LBUFFER="${LBUFFER}${base}"
+    fi
+    LBUFFER="${LBUFFER}${matches}/"
+  fi
+  zle redisplay
+  typeset -f zle-line-init >/dev/null && zle zle-line-init
+}
+
+zic-completion() {
+  setopt localoptions noshwordsplit noksh_arrays noposixbuiltins
+  local tokens cmd
+
+  tokens=(${(z)LBUFFER})
+  cmd=${tokens[1]}
+
+  if [[ "$LBUFFER" =~ "^\ *cd$" ]]; then
+    zle ${__zic_default_completion:-expand-or-complete}
+  elif [ "$cmd" = cd ]; then
+    _zic_complete ${tokens[2,${#tokens}]/#\~/$HOME}
+  else
+    zle ${__zic_default_completion:-expand-or-complete}
+  fi
+}
+
+[ -z "$__zic_default_completion" ] && {
+  binding=$(bindkey '^I')
+  # $binding[(s: :w)2]
+  # The command substitution and following word splitting to determine the
+  # default zle widget for ^I formerly only works if the IFS parameter contains
+  # a space via $binding[(w)2]. Now it specifically splits at spaces, regardless
+  # of IFS.
+  [[ $binding =~ 'undefined-key' ]] || __zic_default_completion=$binding[(s: :w)2]
+  unset binding
+}
+
+zle -N zic-completion
+bindkey -M emacs '^I' zic-completion
+bindkey -M viins '^I' zic-completion
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-aliases.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-aliases.conf
new file mode 100644 (file)
index 0000000..047b017
--- /dev/null
@@ -0,0 +1,33 @@
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_aliases_active_text
+active_text=${znt_aliases_active_text:-$active_text}
+
+# 2. znt_aliases_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_aliases_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 3. znt_aliases_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_aliases_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 4. znt_aliases_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_aliases_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 5. znt_aliases_keywords (array)
+if (( ${+znt_aliases_keywords} )); then
+    keywords=( "${znt_aliases_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-cd.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-cd.conf
new file mode 100644 (file)
index 0000000..8271e5d
--- /dev/null
@@ -0,0 +1,68 @@
+# Hotlist
+# Can use e.g. $ZSH_VERSION, e.g. /usr/share/zsh/$ZSH_VERSION/functions
+local -a hotlist
+hotlist=(
+    ~/.config/znt
+    /usr/share/zsh/site-functions
+    /usr/share/zsh
+    /usr/local/share/zsh/site-functions
+    /usr/local/share/zsh
+    /usr/local/bin
+    /usr/lib
+)
+
+# Suppress adding (to directory stack) directories visited by n-cd
+# Value 0 is the default (directories will be added to dirstack)
+local NCD_DONT_PUSHD=0
+
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+# Colorize last segments of the paths
+# (#s) is ^, (#e) is $, # is *, ## is + (comparing to regex)
+local NLIST_COLORING_PATTERN="[a-zA-Z0-9 ._-]##/#(#e)"
+local NLIST_COLORING_COLOR=$'\x1b[00;33m'
+
+# Search keywords, iterated with F2 or Ctrl-X or Ctrl-/
+local -a keywords
+keywords=( "zsh" "local" "git" )
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_cd_hotlist (array)
+if (( ${+znt_cd_hotlist} )); then
+    hotlist=( "${znt_cd_hotlist[@]}" )
+fi
+
+# 2. znt_cd_dont_pushd
+NCD_DONT_PUSHD=${znt_cd_dont_pushd:-$NCD_DONT_PUSHD}
+
+# 3. znt_cd_active_text
+active_text=${znt_cd_active_text:-$active_text}
+
+# 4. znt_cd_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_cd_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 5. znt_cd_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_cd_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 6. znt_cd_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_cd_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 7. znt_cd_keywords (array)
+if (( ${+znt_cd_keywords} )); then
+    keywords=( "${znt_cd_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-env.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-env.conf
new file mode 100644 (file)
index 0000000..85dda05
--- /dev/null
@@ -0,0 +1,38 @@
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+# (#s) is ^, (#e) is $, # is *, ## is + (comparing to regex)
+local NLIST_COLORING_PATTERN="[a-zA-Z0-9_]##"
+local NLIST_COLORING_MATCH_MULTIPLE=0
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_env_active_text
+active_text=${znt_env_active_text:-$active_text}
+
+# 2. znt_env_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_env_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 3. znt_env_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_env_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 4. znt_env_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_env_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 5. znt_env_keywords (array)
+if (( ${+znt_env_keywords} )); then
+    keywords=( "${znt_env_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-functions.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-functions.conf
new file mode 100644 (file)
index 0000000..d032e27
--- /dev/null
@@ -0,0 +1,41 @@
+# Which editor to use, zed or vared
+# vared is the default
+local feditor="zed"
+# local feditor="vared"
+
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_functions_feditor
+feditor=${znt_functions_feditor:-$feditor}
+
+# 2. znt_functions_active_text
+active_text=${znt_functions_active_text:-$active_text}
+
+# 3. znt_functions_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_functions_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 4. znt_functions_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_functions_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 5. znt_functions_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_functions_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 6. znt_functions_keywords (array)
+if (( ${+znt_functions_keywords} )); then
+    keywords=( "${znt_functions_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-history.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-history.conf
new file mode 100644 (file)
index 0000000..d7c69e1
--- /dev/null
@@ -0,0 +1,43 @@
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=underline
+
+# Highlight a few keywords
+local NLIST_COLORING_PATTERN="(while|for |sudo|make|(#s)git|vim(#e)|vim |emacs(#e)|emacs )"
+local NLIST_COLORING_COLOR=$'\x1b[00;33m'
+local NLIST_COLORING_MATCH_MULTIPLE=1
+
+# Search keywords, iterated with F2 or Ctrl-X or Ctrl-/
+local -a keywords
+keywords=( "git" "vim" "mplayer" )
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_history_active_text
+active_text=${znt_history_active_text:-$active_text}
+
+# 2. znt_history_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_history_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 3. znt_history_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_history_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 4. znt_history_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_history_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 5. znt_history_keywords (array)
+if (( ${+znt_history_keywords} )); then
+    keywords=( "${znt_history_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-kill.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-kill.conf
new file mode 100644 (file)
index 0000000..59807b2
--- /dev/null
@@ -0,0 +1,46 @@
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+# Colorize first number column and last path segment
+# This doesn't cover scripts named "[0-9]## *", which should be very rare
+# (#s) is ^, (#e) is $, # is *, ## is + (comparing to regex)
+# | is alternative, but only in ()
+local NLIST_COLORING_PATTERN="((#s) #[0-9]## |[[][^]]#](#e)|[^ 0-9/?\\\\][^/\\\\]#(#e))"
+local NLIST_COLORING_COLOR=$'\x1b[00;33m'
+local NLIST_COLORING_MATCH_MULTIPLE=1
+
+# Search keywords, iterated with F2 or Ctrl-X or Ctrl-/
+local -a keywords
+keywords=( "vim" "git" "git commit" "firefox" "mplayer" )
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_kill_active_text
+active_text=${znt_kill_active_text:-$active_text}
+
+# 2. znt_kill_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_kill_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 3. znt_kill_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_kill_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 4. znt_kill_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_kill_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 5. znt_kill_keywords (array)
+if (( ${+znt_kill_keywords} )); then
+    keywords=( "${znt_kill_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-list.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-list.conf
new file mode 100644 (file)
index 0000000..096104d
--- /dev/null
@@ -0,0 +1,55 @@
+# Should the list (text, borders) be drawn in bold
+# Value 1 is the default
+local bold=0
+
+# Main color pair (foreground/background)
+local colorpair="white/black"
+
+# Should draw the border?
+local border=0
+
+# Combinations of colors to try out with Ctrl-T and Ctrl-G
+# The last number is the bold option, 0 or 1
+local -a themes
+themes=( "white/black/1" "green/black/0" "green/black/1" "white/blue/0" "white/blue/1"
+         "magenta/black/0" "magenta/black/1" )
+
+# Uncomment when using new (>5.2) Zsh version that supports 256 colors in zcurses
+#themes=( "white/17/0" "10/17/1" "white/24/1" "white/22/0" "white/22/1" "white/25/0" "white/25/1"
+#         "white/59/0" "white/59/1" "white/60/0" "white/60/1" "white/61/0" "white/61/1" "black/65/0"
+#         "black/244/0"  )
+
+# When 1, pressing enter when in search mode will not
+# only leave the mode, but also do selection and leave
+# n-history
+local NLIST_INSTANT_SELECT=0
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_list_bold
+bold=${znt_list_bold:-$bold}
+
+# 2. znt_list_colorpair
+colorpair=${znt_list_colorpair:-$colorpair}
+
+# 3. znt_list_border
+border=${znt_list_border:-$border}
+
+# 4. znt_list_themes (array)
+if (( ${+znt_list_themes} )); then
+    themes=( "${znt_list_themes[@]}" )
+fi
+
+# 5. znt_list_instant_select
+NLIST_INSTANT_SELECT=${znt_list_instant_select:-$NLIST_INSTANT_SELECT}
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-options.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-options.conf
new file mode 100644 (file)
index 0000000..29c5e08
--- /dev/null
@@ -0,0 +1,34 @@
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_options_active_text
+active_text=${znt_options_active_text:-$active_text}
+
+# 2. znt_options_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_options_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 3. znt_options_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_options_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 4. znt_options_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_options_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 5. znt_options_keywords (array)
+if (( ${+znt_options_keywords} )); then
+    keywords=( "${znt_options_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-panelize.conf b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/.config/znt/n-panelize.conf
new file mode 100644 (file)
index 0000000..58ce1b6
--- /dev/null
@@ -0,0 +1,34 @@
+# How should be current element of the list drawn. Possible values: reverse,
+# underline.
+# On Linux virtual terminal this will be enforced to reverse (because of poor
+# underline support on that terminal). The same for screen/tmux.
+local active_text=reverse
+
+
+
+
+
+
+
+#
+# Zshrc integration. All below variables can
+# be set in zshrc and will have precedence
+# over config files
+#
+
+# 1. znt_panelize_active_text
+active_text=${znt_panelize_active_text:-$active_text}
+
+# 2. znt_panelize_nlist_coloring_pattern
+NLIST_COLORING_PATTERN=${znt_panelize_nlist_coloring_pattern:-$NLIST_COLORING_PATTERN}
+
+# 3. znt_panelize_nlist_coloring_color
+NLIST_COLORING_COLOR=${znt_panelize_nlist_coloring_color:-$NLIST_COLORING_COLOR}
+
+# 4. znt_panelize_nlist_coloring_match_multiple
+NLIST_COLORING_MATCH_MULTIPLE=${znt_panelize_nlist_coloring_match_multiple:-$NLIST_COLORING_MATCH_MULTIPLE}
+
+# 5. znt_panelize_keywords (array)
+if (( ${+znt_panelize_keywords} )); then
+    keywords=( "${znt_panelize_keywords[@]}" )
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/LICENSE b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/LICENSE
new file mode 100644 (file)
index 0000000..075c80c
--- /dev/null
@@ -0,0 +1,700 @@
+This software is dual-licensed under MIT and GPLv3.
+
+MIT License
+-----------
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+GPLv3  License
+--------------
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/Makefile b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/Makefile
new file mode 100644 (file)
index 0000000..f34af0c
--- /dev/null
@@ -0,0 +1,35 @@
+NAME=zsh-navigation-tools
+
+INSTALL?=install -c
+PREFIX?=/usr/local
+SHARE_DIR?=$(DESTDIR)$(PREFIX)/share/$(NAME)
+DOC_DIR?=$(DESTDIR)$(PREFIX)/share/doc/$(NAME)
+
+all:
+
+install:
+       $(INSTALL) -d $(SHARE_DIR)
+       $(INSTALL) -d $(SHARE_DIR)/.config
+       $(INSTALL) -d $(SHARE_DIR)/.config/znt
+       $(INSTALL) -d $(DOC_DIR)
+       cp zsh-navigation-tools.plugin.zsh _n-kill doc/znt-tmux.zsh $(SHARE_DIR)
+       cp README.md NEWS LICENSE doc/img/n-history2.png $(DOC_DIR)
+       if [ x"true" = x"`git rev-parse --is-inside-work-tree 2>/dev/null`" ]; then \
+               git rev-parse HEAD; \
+       else \
+               cat .revision-hash; \
+       fi > $(SHARE_DIR)/.revision-hash
+       :
+       for fname in n-*; do cp "$$fname" $(SHARE_DIR); done; \
+       for fname in znt-*; do cp "$$fname" $(SHARE_DIR); done; \
+       for fname in .config/znt/n-*; do cp "$$fname" $(SHARE_DIR)/.config/znt; done;
+
+uninstall:
+       rm -f $(SHARE_DIR)/.revision-hash $(SHARE_DIR)/_* $(SHARE_DIR)/zsh-* $(SHARE_DIR)/n-* $(SHARE_DIR)/znt-* $(SHARE_DIR)/.config/znt/n-*
+       [ -d $(SHARE_DIR)/.config/znt ] && rmdir $(SHARE_DIR)/.config/znt || true
+       [ -d $(SHARE_DIR)/.config ] && rmdir $(SHARE_DIR)/.config || true
+       [ -d $(SHARE_DIR) ] && rmdir $(SHARE_DIR) || true
+       rm -f $(DOC_DIR)/README.md $(DOC_DIR)/LICENSE $(DOC_DIR)/n-history2.png 
+       [ -d $(DOC_DIR) ] && rmdir $(DOC_DIR) || true
+
+.PHONY: all install uninstall
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/NEWS b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/NEWS
new file mode 100644 (file)
index 0000000..acd9f2e
--- /dev/null
@@ -0,0 +1,17 @@
+-------------------------------------
+CHANGES FROM PREVIOUS VERSIONS OF ZNT
+-------------------------------------
+
+Changes from 2.2.1 to 2.2.7
+---------------------------
+
+Tmux integration has been added – bind file znt-tmux.zsh in Tmux as
+described in README.md and e.g. run local history on remote hosts. Tmux
+opens new window with n-history, and pastes selected history entry into
+immediate previous window (e.g. a remote session). Fixed plugin.zsh file
+to not use (outer scope) positional parameters. This fixes problem with
+Grlm's Zsh configuration. The file now doesn't use "test" builtin (but
+[[ instead), because it can be shadowed by alias or command. Private
+history has been fixed to not overwrite its history file with the same
+content. This improves performance when switching to private history
+view.
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/README.md b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/README.md
new file mode 100644 (file)
index 0000000..4dc9cdb
--- /dev/null
@@ -0,0 +1,259 @@
+[![License (GPL version 3)](https://img.shields.io/badge/license-GNU%20GPL%20version%203-blue.svg?style=flat-square)](./LICENSE)
+[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](./LICENSE)
+![ZSH 5.0.0](https://img.shields.io/badge/zsh-v5.0.0-orange.svg?style=flat-square)
+[![Gitter][gitter-image]][gitter-link]
+
+![znt logo](https://imageshack.com/a/img905/2629/WK9qjN.png)
+
+# Zsh Navigation Tools
+
+Set of tools like `n-history` – multi-word history searcher, `n-cd` – directory
+bookmark manager, `n-kill` – `htop` like kill utility, and more. Based on
+`n-list`, a tool generating selectable curses-based list of elements that has
+access to current `Zsh` session, i.e. has broad capabilities to work together
+with it. Feature highlights include incremental multi-word searching, approximate
+matching, ANSI coloring, themes, unique mode, horizontal scroll, grepping, advanced
+history management and various integrations with `Zsh`.
+
+To use it, add `zsh-navigation-tools` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... zsh-navigation-tools)
+```
+
+Also check out [![ZCA](https://imageshack.com/a/img911/8084/qSpO8a.png) Zsh Command Architect](https://github.com/zdharma-continuum/zsh-cmd-architect)
+and [Zconvey](https://github.com/zdharma-continuum/zconvey)
+
+
+
+Videos:
+- [https://youtu.be/QwZ8IJEgXRE](https://youtu.be/QwZ8IJEgXRE)
+- [https://youtu.be/DN9QqssAYB8](https://youtu.be/DN9QqssAYB8)
+
+Screenshots:
+
+![n-history](https://imageshack.com/a/img921/5046/bqr0mk.png)
+
+![n-history](https://imageshack.com/a/img633/9905/WzfSdl.gif)
+
+
+## History Widget
+
+To have `n-history` as the incremental searcher bound to `Ctrl-R` copy `znt-*`
+files into the `*/site-functions` dir (unless you do single file install) and
+add:
+
+```zsh
+autoload znt-history-widget
+zle -N znt-history-widget
+bindkey "^R" znt-history-widget
+```
+
+to `.zshrc`. This is done automatically when using the installer, zgen, antigen
+or single file install. Two other widgets exist, `znt-cd-widget` and
+`znt-kill-widget`, they too can be assigned to key combinations (`autoload` is done
+in `.zshrc` so no need of it):
+
+```zsh
+zle -N znt-cd-widget
+bindkey "^B" znt-cd-widget
+zle -N znt-kill-widget
+bindkey "^Y" znt-kill-widget
+```
+
+## Introduction
+
+The tools are:
+
+- `n-aliases` - browses aliases, relegates editing to `vared`
+- `n-cd` - browses dirstack and bookmarked directories, allows to enter selected directory
+- `n-functions` - browses functions, relegates editing to `zed` or `vared`
+- `n-history` - browses history, allows to edit and run commands from it
+- `n-kill` - browses processes list, allows to send signal to selected process
+- `n-env` - browses environment, relegates editing to `vared`
+- `n-options` - browses options, allows to toggle their state
+- `n-panelize` - loads output of given command into the list for browsing
+
+All tools support horizontal scroll with `<`,`>`, `{`,`}`, `h`,`l` or left and right cursors. Other keys are:
+
+- `H`, `?` (from n-history) - run n-help
+- `Ctrl-R` - start n-history, the incremental, multi-keyword history searcher (Zsh binding)
+- `Ctrl-A` - rotate entered words (1+2+3 -> 3+1+2)
+- `Ctrl-F` - fix mode (approximate matching)
+- `Ctrl-L` - redraw of whole display
+- `Ctrl-T` - browse themes (next theme)
+- `Ctrl-G` - browse themes (previous theme)
+- `Ctrl-U` - half page up
+- `Ctrl-D` - half page down
+- `Ctrl-P` - previous element (also done with vim's k)
+- `Ctrl-N` - next element (also done with vim's j)
+- `[`, `]` - jump directory bookmarks in n-cd and typical signals in n-kill
+- `g`, `G` - beginning and end of the list
+- `/` - show incremental search
+- `F3` - show/hide incremental search
+- `Esc` - exit incremental search, clearing filter
+- `Ctrl-W` (in incremental search) - delete whole word
+- `Ctrl-K` (in incremental search) - delete whole line
+- `Ctrl-O`, `o` - enter uniq mode (no duplicate lines)
+- `Ctrl-E`, `e` - edit private history (when in private history view)
+- `F1` - (in n-history) - switch view
+- `F2`, `Ctrl-X`, `Ctrl-/` - search predefined keywords (defined in config files)
+
+## Configuration
+
+`ZNT` has configuration files located in `~/.config/znt`. The files are:
+
+```
+n-aliases.conf
+n-cd.conf
+n-env.conf
+n-functions.conf
+n-history.conf
+n-kill.conf
+n-list.conf
+n-options.conf
+n-panelize.conf
+```
+
+`n-list.conf` contains main configuration variables:
+
+```zsh
+# Should the list (text, borders) be drawn in bold
+local bold=0
+
+# Main color pair (foreground/background)
+local colorpair="white/black"
+
+# Should draw the border?
+local border=1
+
+# Combinations of colors to try out with Ctrl-T and Ctrl-G
+# The last number is the bold option, 0 or 1
+local -a themes
+themes=( "white/black/1" "green/black/0" "green/black/1" "white/blue/0" "white/blue/1"
+         "magenta/black/0" "magenta/black/1" )
+```
+
+Read remaining configuration files to see what's in them. Nevertheless, configuration
+can be also set from `zshrc`. There are `5` standard `zshrc` configuration variables:
+
+```
+znt_history_active_text - underline or reverse - how should be active element highlighted
+znt_history_nlist_coloring_pattern - pattern that can be used to colorize elements
+znt_history_nlist_coloring_color - color with which to colorize
+znt_history_nlist_coloring_match_multiple - should multiple matches be colorized (0 or 1)
+znt_history_keywords (array) - search keywords activated with `Ctrl-X`, `F2` or `Ctrl-/`, e.g. ( "git" "vim" )
+```
+
+Above variables will work for `n-history` tool. For other tools, change `_history_` to
+e.g. `_cd_`, for the `n-cd` tool. The same works for all `8` tools.
+
+Common configuration of the tools uses variables with `_list_` in them:
+
+```
+znt_list_bold - should draw text in bold (0 or 1)
+znt_list_colorpair - main pair of colors to be used, e.g "green/black"
+znt_list_border - should draw borders around windows (0 or 1)
+znt_list_themes (array) - list of themes to try out with Ctrl-T, e.g. ( "white/black/1" "green/black/0" )
+znt_list_instant_select - should pressing enter in search mode leave tool (0 or 1)
+```
+
+If you used `ZNT` before `v2.1.12`, remove old configuration files `~/.config/znt/*.conf` so that `ZNT`
+can update them to the latest versions that support integration with `Zshrc`. If you used installer
+then run it again (after the remove of configuration files).
+
+## Programming
+
+The function `n-list` is used as follows:
+
+```zsh
+n-list {element1} [element2] ... [elementN]
+```
+
+This is all that is needed to be done to have the features like ANSI coloring,
+incremental multi-word search, unique mode, horizontal scroll, non-selectable
+elements (grepping is done outside `n-list`, see the tools for how it can be
+done). To set up non-selectable entries add their indices into array
+`NLIST_NONSELECTABLE_ELEMENTS`:
+
+```zsh
+typeset -a NLIST_NONSELECTABLE_ELEMENTS
+NLIST_NONSELECTABLE_ELEMENTS=( 1 )
+```
+
+Result is stored as `$reply[REPLY]` (`$` isn't needed before `REPLY` because
+of arithmetic context inside `[]`). The returned array might be different from
+input arguments as `n-list` can process them via incremental search or uniq
+mode. `$REPLY` is the index in that possibly processed array. If `$REPLY`
+equals `-1` it means that no selection have been made (user quitted via `q`
+key).
+
+To set up entries that can be jumped to with `[`,`]` keys add their indices to
+`NLIST_HOP_INDEXES` array:
+
+```zsh
+typeset -a NLIST_HOP_INDEXES
+NLIST_HOP_INDEXES=( 1 10 )
+```
+
+`n-list` can automatically colorize entries according to a `Zsh` pattern.
+Following example will colorize all numbers with blue:
+
+```zsh
+local NLIST_COLORING_PATTERN="[0-9]##"
+local NLIST_COLORING_COLOR=$'\x1b[00;34m'
+local NLIST_COLORING_END_COLOR=$'\x1b[0m'
+local NLIST_COLORING_MATCH_MULTIPLE=1
+
+n-list "This is a number 123" "This line too has a number: 456"
+```
+
+Blue is the default color, it doesn't have to be set. See `zshexpn` man page
+for more information on `Zsh` patterns. Briefly, comparing to regular
+expressions, `(#s)` is `^`, `(#e)` is `$`, `#` is `*`, `##` is `+`. Alternative
+will work when in parenthesis, i.e. `(a|b)`. BTW by using this method you can
+colorize output of the tools, via their config files (check out e.g. n-cd.conf,
+it is using this).
+
+## Performance
+
+`ZNT` are fastest with `Zsh` before `5.0.6` and starting from `5.2`
+
+## A tip
+
+Zsh plugins may look scary, as they seem to have some "architecture". In fact, what a plugin really is, is that:
+
+1. It has its directory added to `fpath`
+2. It has any first `*.plugin.zsh` file sourced
+
+That's it. When one contributes to Oh-My-Zsh or creates a plugin for any plugin manager, they only need to account for this.
+The same with doing any non-typical Zsh Navigation Tools installation.
+
+## More
+
+- be aware of [this](https://github.com/zdharma-continuum/zsh-navigation-tools/blob/f49f910d239ae5bc6e1a5bb34930307b4f4e3ffe/zsh-navigation-tools.plugin.zsh#L35-L49)
+
+# Fixing tmux, screen and linux vt
+
+If `TERM=screen-256color` (often a case for `tmux` and `screen` sessions) then
+`ncv` terminfo capability will have `2`nd bit set.  This in general means that
+underline won't work. To fix this by creating your own `ncv=0`-equipped
+terminfo file, run:
+
+```zsh
+{ infocmp -x screen-256color; printf '\t%s\n' 'ncv@,'; } > /tmp/t && tic -x /tmp/t
+```
+
+A file will be created in directory `~/.terminfo` and will be automatically
+used, `tmux` and `screen` will work. Similar is for Linux virtual terminal:
+
+```zsh
+{ infocmp -x linux; printf '\t%s\n' 'ncv@,'; } > /tmp/t && tic -x /tmp/t
+```
+
+It will not display underline properly, but will instead highlight by a color,
+which is quite nice. The same will not work for FreeBSD's vt, `ZNT` will detect
+if that vt is used and will revert to highlighting elements via `reverse` mode.
+
+[gitter-image]: https://badges.gitter.im/zdharma-continuum/community.svg
+[gitter-link]: https://gitter.im/zdharma-continuum/community
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/_n-kill b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/_n-kill
new file mode 100644 (file)
index 0000000..9da68b9
--- /dev/null
@@ -0,0 +1,41 @@
+#compdef n-kill
+
+local context ret=1
+
+typeset -a list linewords
+typeset -aU words wordbits
+local line word
+integer cygwin=0
+
+local IFS="
+"
+
+case "$(uname)" in
+    CYGWIN*) list=( `command ps -Wa` ); cygwin=1 ;;
+    *) list=( `command ps -o pid,uid,command -A` ) ;;
+esac
+
+shift list
+
+IFS=" "
+for line in "${list[@]}"; do
+    linewords=( $=line )
+    if [ "$cygwin" = "1" ]; then
+        linewords=( "${(@)linewords[8,-1]}" )
+    else
+        linewords=( "${(@)linewords[3,-1]}" )
+    fi
+    for word in "${linewords[@]}"; do
+        if [ "$cygwin" = "1" ]; then
+            wordbits=( "${(@s:\:)word}" )
+        else
+            wordbits=( "${(@s:/:)word}" )
+        fi
+        words+=( "${wordbits[@]}" )
+    done
+done
+
+_wanted bits expl "Processes' name bits" \
+    compadd -M 'm:{a-z}={A-Z}' "$@" -a - words && ret=0
+
+return "$ret"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/generate_single_file b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/generate_single_file
new file mode 100755 (executable)
index 0000000..d3d3938
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/zsh
+
+local PLUGIN_FILE="doc/zshnavigationtools.plugin.zsh"
+
+[ -d doc ] || cd ..
+
+rm -vf "$PLUGIN_FILE"
+echo "# The preamble comments apply when using ZNT as autoload functions" >>"$PLUGIN_FILE"
+echo "# https://github.com/psprint/zsh-navigation-tools" >>"$PLUGIN_FILE"
+echo "# License is GPLv3 and MIT" >>"$PLUGIN_FILE"
+echo -n "# " >>"$PLUGIN_FILE"
+git show-ref master | head -1 >>"$PLUGIN_FILE"
+echo >>"$PLUGIN_FILE"
+
+for i in n-*(on); do
+    echo "$i() {" >>"$PLUGIN_FILE"
+    cat "$i" >>"$PLUGIN_FILE"
+    echo "}" >>"$PLUGIN_FILE"
+    echo "alias n${i#n-}=$i" >>"$PLUGIN_FILE"
+    echo >>"$PLUGIN_FILE"
+done
+
+# Append znt-* files
+for i in znt-*(on); do
+    echo "$i() {" >>"$PLUGIN_FILE"
+    cat "$i" >>"$PLUGIN_FILE"
+    echo "}" >>"$PLUGIN_FILE"
+    echo >>"$PLUGIN_FILE"
+done
+
+# Append ^R bind
+echo "zle -N znt-history-widget" >>"$PLUGIN_FILE"
+echo "bindkey '^R' znt-history-widget" >>"$PLUGIN_FILE"
+echo "setopt AUTO_PUSHD HIST_IGNORE_DUPS PUSHD_IGNORE_DUPS" >>"$PLUGIN_FILE"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/img/n-history2.png b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/img/n-history2.png
new file mode 100644 (file)
index 0000000..fa23de0
Binary files /dev/null and b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/img/n-history2.png differ
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/install.sh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/install.sh
new file mode 100755 (executable)
index 0000000..2b71aa3
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+if ! type git 2>/dev/null 1>&2; then
+    echo "Please install GIT first"
+    echo "Exiting"
+    exit 1
+fi
+
+#
+# Clone or pull
+#
+
+if ! test -d "$HOME/.config"; then
+    mkdir "$HOME/.config"
+fi
+
+if ! test -d "$HOME/.config/znt"; then
+    mkdir "$HOME/.config/znt"
+fi
+
+echo ">>> Downloading zsh-navigation-tools to ~/.config/znt"
+if test -d ~/.config/znt/zsh-navigation-tools; then
+    cd ~/.config/znt/zsh-navigation-tools
+    git pull origin master
+else
+    cd ~/.config/znt
+    git clone https://github.com/psprint/zsh-navigation-tools.git zsh-navigation-tools
+fi
+echo ">>> Done"
+
+#
+# Copy configs
+#
+
+echo ">>> Copying config files"
+
+cd ~/.config/znt
+
+set n-aliases.conf n-env.conf n-history.conf n-list.conf n-panelize.conf n-cd.conf n-functions.conf n-kill.conf n-options.conf
+
+for i; do
+    if ! test -f "$i"; then
+        cp -v zsh-navigation-tools/.config/znt/$i .
+    fi
+done
+
+echo ">>> Done"
+
+#
+# Modify .zshrc
+#
+
+echo ">>> Updating .zshrc"
+if ! grep zsh-navigation-tools ~/.zshrc >/dev/null 2>&1; then
+    echo >> ~/.zshrc
+    echo "### ZNT's installer added snippet ###" >> ~/.zshrc
+    echo "fpath=( \"\$fpath[@]\" \"\$HOME/.config/znt/zsh-navigation-tools\" )" >> ~/.zshrc
+    echo "autoload n-aliases n-cd n-env n-functions n-history n-kill n-list n-list-draw n-list-input n-options n-panelize n-help" >> ~/.zshrc
+    echo "autoload znt-usetty-wrapper znt-history-widget znt-cd-widget znt-kill-widget" >> ~/.zshrc
+    echo "alias naliases=n-aliases ncd=n-cd nenv=n-env nfunctions=n-functions nhistory=n-history" >> ~/.zshrc
+    echo "alias nkill=n-kill noptions=n-options npanelize=n-panelize nhelp=n-help" >> ~/.zshrc
+    echo "zle -N znt-history-widget" >> ~/.zshrc
+    echo "bindkey '^R' znt-history-widget" >> ~/.zshrc
+    echo "setopt AUTO_PUSHD HIST_IGNORE_DUPS PUSHD_IGNORE_DUPS" >> ~/.zshrc
+    echo "zstyle ':completion::complete:n-kill::bits' matcher 'r:|=** l:|=*'" >> ~/.zshrc
+    echo "### END ###" >> ~/.zshrc
+    echo ">>> Done"
+else
+    echo ">>> .zshrc already updated, not making changes"
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/n-preview b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/n-preview
new file mode 100644 (file)
index 0000000..2d8eea3
--- /dev/null
@@ -0,0 +1,224 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-preview` to .zshrc
+#
+# This is partially a test if n-list-draw and n-list-input can be
+# used multiple times to create multiple lists. It might become
+# more usable if someone adds more features like previewing of
+# archive contents.
+
+emulate -L zsh
+
+zmodload zsh/curses
+
+setopt typesetsilent extendedglob
+trap "return" TERM INT QUIT
+trap "_vpreview_exit" EXIT
+
+local IFS="
+"
+
+[ -f ~/.config/znt/n-list.conf ] && . ~/.config/znt/n-list.conf
+
+[[ "$colorpair" = "" ]] && colorpair="white/black"
+local background="${colorpair#*/}"
+
+# Drawing and input
+autoload n-list-draw n-list-input
+
+# Cleanup before any exit
+_vpreview_exit() {
+    zcurses 2>/dev/null delwin files
+    zcurses 2>/dev/null delwin body 
+    zcurses 2>/dev/null delwin status
+    zcurses 2>/dev/null refresh
+    zcurses end
+}
+
+# Outputs a message in the bottom of the screen
+_vpreview_status_msg() {
+    zcurses move status 1 2
+    zcurses clear status eol
+    zcurses string status "$1"
+}
+
+# Prefer tput, then module terminfo
+_nlist_cursor_visibility() {
+    if type tput 2>/dev/null 1>&2; then
+        [ "$1" = "1" ] && tput cvvis
+        [ "$1" = "0" ] && tput civis
+    elif [ "$has_termcap" = "1" ]; then
+        [ "$1" = "1" ] && [ -n $terminfo[cvvis] ] && echo -n $terminfo[cvvis]
+        [ "$1" = "0" ] && [ -n $terminfo[civis] ] && echo -n $terminfo[civis]
+    fi 
+}
+
+#
+# Main code
+#
+
+integer term_height="$LINES"
+integer term_width="$COLUMNS"
+if [[ "$term_height" -lt 1 || "$term_width" -lt 1 ]]; then
+    local stty_out=$( stty size )
+    term_height="${stty_out% *}"
+    term_width="${stty_out#* }"
+fi
+
+integer status_height=3
+integer status_width=term_width
+integer status_page_height=1
+integer status_page_width=term_width-2
+
+integer files_height=term_height-status_height
+integer files_width=term_width/5
+integer files_page_height=files_height-2
+integer files_page_width=files_width-2
+
+integer body_height=term_height-status_height
+integer body_width=term_width-files_width
+integer body_page_height=body_height-2
+integer body_page_width=body_width
+
+integer _from_what_idx_list_is_shown_1=1
+integer current_1=1
+
+integer _from_what_idx_list_is_shown_2=1
+integer current_2=1
+integer hscroll_2=0
+
+integer active_window=0
+
+local ansi_mode="ansi"
+[ -f ~/.config/znt/n-preview.conf ] && . ~/.config/znt/n-preview.conf
+typeset -a hcmd
+#if type pygmentize 2>/dev/null 1>&2; then
+#    hcmd=( pygmentize -g )
+if type highlight 2>/dev/null 1>&2; then
+    hcmd=( highlight -q --force -O ansi )
+elif type source-highlight 2>/dev/null 1>&2; then
+    # Warning: source-highlight can have problems
+    hcmd=( source-highlight --failsafe -fesc -o STDOUT -i )
+else
+    ansi_mode="noansi"
+fi
+
+zcurses init
+zcurses addwin status "$status_height" "$status_width" $(( term_height - status_height )) 0
+zcurses addwin files "$files_height" "$files_width" 0 0
+zcurses addwin body "$body_height" "$body_width" 0 "$files_width"
+zcurses bg status white/black
+zcurses bg files white/black
+zcurses bg body white/black
+
+#
+# Listening for input
+#
+
+local key keypad
+
+# Clear input buffer
+zcurses timeout status 0
+zcurses input status key keypad
+zcurses timeout status -1
+key=""
+keypad=""
+
+typeset -a filenames
+integer last_element_1
+
+typeset -a body
+integer last_element_2
+
+filenames=( *(N) )
+filenames=( "${(@M)filenames:#(#i)*$1*}" )
+
+local NLIST_GREP_STRING="$1"
+
+integer last_element_1="$#filenames"
+integer last_element_2=0
+
+local selection action final_key
+
+while (( 1 )); do
+    # Output the lists
+    integer end_idx=$(( _from_what_idx_list_is_shown_1 + files_page_height - 1 ))
+    [ "$end_idx" -gt "$last_element_1" ] && end_idx=last_element_1
+
+    n-list-draw "$(( (current_1 -1) % files_page_height + 1 ))" \
+                    "$files_page_height" "$files_page_width" 1 2 0 files \
+                    "${(@)filenames[_from_what_idx_list_is_shown_1, end_idx]}"
+
+    if [ "$#body" -ge 1 ]; then
+        end_idx=$(( _from_what_idx_list_is_shown_2 + body_page_height - 1 ))
+        [ "$end_idx" -gt "$last_element_2" ] && end_idx=last_element_2
+
+        n-list-draw "$(( (current_2 -1) % body_page_height + 1 ))" \
+                        "$body_page_height" "$body_page_width" 1 0 "$hscroll_2" body \
+                        "${(@)body[_from_what_idx_list_is_shown_2, end_idx]}"
+    fi
+
+    [[ "$active_window" -eq 0 ]] && zcurses border files
+    zcurses border status
+    zcurses refresh files body status 
+
+    # Wait for input
+    zcurses input status key keypad
+
+    # Get the special (i.e. "keypad") key or regular key
+    if [ -n "$key" ]; then
+        final_key="$key" 
+    elif [ -n "$keypad" ]; then
+        final_key="$keypad"
+    else
+        _vpreview_status_msg "Inproper input detected"
+        zcurses refresh status 
+    fi
+
+    if [ "$active_window" -eq 0 ]; then
+        zcurses clear files
+        n-list-input "$current_1" "$_from_what_idx_list_is_shown_1" "$files_page_height" \
+            "$files_page_width" "$last_element_1" 0 "$final_key"
+
+        selection="$reply[1]"
+        action="$reply[2]"
+        current_1="$reply[3]"
+        _from_what_idx_list_is_shown_1="$reply[4]"
+
+        if [ "$action" = "SELECT" ]; then
+            # Load new file and refresh the displaying window
+            local filename="$filenames[$selection]"
+            if [ "$ansi_mode" = "ansi" ]; then
+                body=( "${(@f)"$( "$hcmd[@]" "$filename" )"}" )
+            else
+                body=( "${(@f)"$(<$filename)"}" )
+            fi
+            last_element_2="$#body"
+            current_2=1
+            _from_what_idx_list_is_shown_2=1
+            zcurses clear body
+        fi
+    elif [ "$active_window" -eq 1 ]; then
+        zcurses clear body
+        n-list-input "$current_2" "$_from_what_idx_list_is_shown_2" "$body_page_height" \
+            "$body_page_width" "$last_element_2" "$hscroll_2" "$final_key"
+
+        selection="$reply[1]"
+        action="$reply[2]"
+        current_2="$reply[3]"
+        _from_what_idx_list_is_shown_2="$reply[4]"
+        hscroll_2="$reply[5]"
+
+    fi
+
+    if [ "$action" = "LEAVE" ]; then
+        active_window=1-active_window
+    elif [ "$action" = "QUIT" ]; then
+            break
+    elif [ "$action" = "REDRAW" ]; then
+        zcurses clear files redraw
+        zcurses clear body redraw
+        zcurses clear status redraw
+    fi
+done
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/znt-tmux.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/doc/znt-tmux.zsh
new file mode 100755 (executable)
index 0000000..309c11a
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env zsh
+
+# Copyright (c) 2016, Zsolt Lengyel
+# Modifications copyright (c) 2016, Sebastian Gniazdowski
+
+#
+# This script opens a new, temporary tmux pane and runs n-history. When
+# a selection is made, the result (history entry) is pasted back into
+# original tmux pane, and the temporary pane is closed. This allows to
+# use local history on remote machines.
+#
+# To use, put this line to your ~/.tmux.conf. The tool is invoked with:
+# Ctrl+b h
+#
+# bind h run-shell -b "$ZNT_REPO_DIR/doc/znt-tmux.zsh"
+#
+
+# get and save the current active tmux pane id
+active_pane=$(tmux display -p -F ':#{session_id}:#I:#P:#{pane_active}:#{window_active}:#{session_attached}' )
+a_active_pane=("${(@s/:/)active_pane}")
+
+active_session=${a_active_pane[2]//$}
+active_window=$a_active_pane[3]
+active_pane=$a_active_pane[4]
+
+# set variables for upcoming window
+tmux setenv -t $active_session:$active_window.$active_pane "ZNT_TMUX_MODE" 1
+tmux setenv -t $active_session:$active_window.$active_pane "ZNT_TMUX_ORIGIN_SESSION" "$active_session"
+tmux setenv -t $active_session:$active_window.$active_pane "ZNT_TMUX_ORIGIN_WINDOW" "$active_window"
+tmux setenv -t $active_session:$active_window.$active_pane "ZNT_TMUX_ORIGIN_PANE" "$active_pane"
+
+# create a new window in the active session and call it znt-hist
+tmux new-window -t $active_session: -n znt-hist
+
+# unset the variables, so only above single window has them
+tmux setenv -u -t $active_session:$active_window.$active_pane "ZNT_TMUX_MODE"
+tmux setenv -u -t $active_session:$active_window.$active_pane "ZNT_TMUX_ORIGIN_SESSION"
+tmux setenv -u -t $active_session:$active_window.$active_pane "ZNT_TMUX_ORIGIN_WINDOW"
+tmux setenv -u -t $active_session:$active_window.$active_pane "ZNT_TMUX_ORIGIN_PANE"
+
+# znt's session id
+znt_active_pane=$(tmux display -p -F ':#{session_id}:#I:#P:#{pane_active}:#{window_active}:#{session_attached}' )
+znt_a_active_pane=("${(@s/:/)znt_active_pane}")
+
+znt_active_session=${znt_a_active_pane[2]//$}
+znt_active_window=$znt_a_active_pane[3]
+znt_active_pane=$znt_a_active_pane[4]
+
+# call znt
+tmux send -t "$znt_active_session:$znt_active_window.$znt_active_pane" n-history ENTER
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-aliases b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-aliases
new file mode 100644 (file)
index 0000000..f8c1c37
--- /dev/null
@@ -0,0 +1,47 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-aliases` to .zshrc
+#
+# This function allows to choose an alias for edition with vared
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob
+zmodload zsh/curses
+zmodload zsh/parameter
+
+local IFS="
+"
+
+unset NLIST_COLORING_PATTERN
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-aliases.conf ] && builtin source ~/.config/znt/n-aliases.conf
+
+local list
+local selected
+
+NLIST_REMEMBER_STATE=0
+
+list=( "${(@k)aliases}" )
+list=( "${(@M)list:#(#i)*$1*}" )
+
+local NLIST_GREP_STRING="$1"
+
+if [ "$#list" -eq 0 ]; then
+    echo "No matching aliases"
+    return 1
+fi
+
+list=( "${(@i)list}" )
+n-list "$list[@]"
+
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+    echo "Editing \`$selected':"
+    print -rs "vared aliases\\[$selected\\]"
+    vared aliases\[$selected\]
+fi
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-cd b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-cd
new file mode 100644 (file)
index 0000000..48c6dbf
--- /dev/null
@@ -0,0 +1,71 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-cd` to .zshrc
+#
+# This function allows to choose a directory from pushd stack
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob pushdignoredups
+
+zmodload zsh/curses
+local IFS="
+"
+
+# Unset before configuration is read
+unset NLIST_COLORING_PATTERN
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-cd.conf ] && builtin source ~/.config/znt/n-cd.conf
+
+local list
+local selected
+
+NLIST_REMEMBER_STATE=0
+
+list=( `dirs -p` )
+list=( "${(@M)list:#(#i)*$1*}" )
+
+local NLIST_GREP_STRING="$1"
+
+[ "$#list" -eq 0 ] && echo "No matching directories"
+
+if [ "$#hotlist" -ge 1 ]; then
+    typeset -a NLIST_NONSELECTABLE_ELEMENTS NLIST_HOP_INDEXES
+    local tmp_list_size="$#list"
+    NLIST_NONSELECTABLE_ELEMENTS=( $(( tmp_list_size+1 )) $(( tmp_list_size+2 )) )
+    list=( "$list[@]" "" $'\x1b[00;31m'"Hotlist"$'\x1b[00;00m': "$hotlist[@]" )
+    (( tmp_list_size+=3 ))
+    local middle_hop=$(( (tmp_list_size+$#list) / 2 ))
+    [[ "$middle_hop" -eq $tmp_list_size || "$middle_hop" -eq $#list ]] && middle_hop=""
+    [ "$tmp_list_size" -eq $#list ] && tmp_list_size=""
+    NLIST_HOP_INDEXES=( 1 $tmp_list_size $middle_hop $#list )
+else
+    [ "$#list" -eq 0 ] && return 1
+fi
+
+n-list "${list[@]}"
+
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+    selected="${selected/#\~/$HOME}"
+
+    (( NCD_DONT_PUSHD )) && setopt NO_AUTO_PUSHD
+    cd "$selected"
+    local code=$?
+    (( NCD_DONT_PUSHD )) && setopt AUTO_PUSHD
+
+    if [ "$code" -eq "0" ]; then
+        # ZLE?
+        if [ "${(t)CURSOR}" = "integer-local-special" ]; then
+            zle -M "You have selected $selected"
+        else
+            echo "You have selected $selected"
+        fi
+    fi
+else
+    [ "${(t)CURSOR}" = "integer-local-special" ] && zle redisplay
+fi
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-env b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-env
new file mode 100644 (file)
index 0000000..c003b63
--- /dev/null
@@ -0,0 +1,47 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-env` to .zshrc
+#
+# This function allows to choose an environment variable
+# for edition with vared
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob
+unsetopt equals
+zmodload zsh/curses
+
+local IFS="
+"
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-env.conf ] && builtin source ~/.config/znt/n-env.conf
+
+local list
+local selected
+
+NLIST_REMEMBER_STATE=0
+
+list=( `env` )
+list=( "${(@M)list:#(#i)*$1*}" )
+
+local NLIST_GREP_STRING="$1"
+
+if [ "$#list" -eq 0 ]; then
+    echo "No matching variables"
+    return 1
+fi
+
+list=( "${(@i)list}" )
+n-list "$list[@]"
+
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+    selected="${selected%%=*}"
+    echo "Editing \`$selected':"
+    print -rs "vared \"$selected\""
+    vared "$selected"
+fi
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-functions b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-functions
new file mode 100644 (file)
index 0000000..1748cbc
--- /dev/null
@@ -0,0 +1,54 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-functions` to .zshrc
+#
+# This function allows to choose a function for edition with vared
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob
+zmodload zsh/curses
+zmodload zsh/parameter
+
+local IFS="
+"
+
+unset NLIST_COLORING_PATTERN
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-functions.conf ] && builtin source ~/.config/znt/n-functions.conf
+
+local list
+local selected
+
+NLIST_REMEMBER_STATE=0
+
+list=( "${(@k)functions}" )
+list=( "${(@M)list:#(#i)*$1*}" )
+
+local NLIST_GREP_STRING="$1"
+
+if [ "$#list" -eq 0 ]; then
+    echo "No matching functions"
+    return 1
+fi
+
+list=( "${(@i)list}" )
+n-list "$list[@]"
+
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+    if [ "$feditor" = "zed" ]; then
+        echo "Editing \`$selected' (ESC ZZ or Ctrl-x-w to finish):"
+        autoload zed
+        print -rs "zed -f -- \"$selected\""
+        zed -f -- "$selected"
+    else
+        echo "Editing \`$selected':"
+        print -rs "vared functions\\[$selected\\]"
+        vared functions\[$selected\]
+    fi
+fi
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-help b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-help
new file mode 100644 (file)
index 0000000..c7f6328
--- /dev/null
@@ -0,0 +1,135 @@
+autoload colors
+colors
+
+local h1="$fg_bold[magenta]"
+local h2="$fg_bold[green]"
+local h3="$fg_bold[blue]"
+local h4="$fg_bold[yellow]"
+local h5="$fg_bold[cyan]"
+local rst="$reset_color"
+
+LESS="-iRc" less <<<"
+${h1}Key Bindings${rst}
+
+${h2}H${rst}, ${h2}?${rst} (from n-history) - run n-help
+${h2}Ctrl-A${rst} - rotate entered words (1+2+3 -> 3+1+2)
+${h2}Ctrl-F${rst} - fix mode (approximate matching)
+${h2}Ctrl-L${rst} - redraw of whole display
+${h2}Ctrl-T${rst} - browse themes (next theme)
+${h2}Ctrl-G${rst} - browse themes (previous theme)
+${h2}Ctrl-U${rst} - half page up
+${h2}Ctrl-D${rst} - half page down
+${h2}Ctrl-P${rst} - previous element (also done with vim's k)
+${h2}Ctrl-N${rst} - next element (also done with vim's j)
+${h2}[${rst}, ${h2}]${rst} - jump directory bookmarks in n-cd and typical signals in n-kill
+${h2}g, ${h2}G${rst} - beginning and end of the list
+${h2}/${rst} - show incremental search
+${h2}F3${rst} - show/hide incremental search
+${h2}Esc${rst} - exit incremental search, clearing filter
+${h2}Ctrl-W${rst} (in incremental search) - delete whole word
+${h2}Ctrl-K${rst} (in incremental search) - delete whole line
+${h2}Ctrl-O, ${h2}o${rst} - enter uniq mode (no duplicate lines)
+${h2}Ctrl-E, ${h2}e${rst} - edit private history (when in private history view)
+${h2}F1${rst} - (in n-history) - switch view
+${h2}F2${rst}, ${h2}Ctrl-X${rst}, ${h2}Ctrl-/${rst} - search predefined keywords (defined in config files)
+
+${h1}Configuration files${rst}
+
+Location of the files is ${h3}~/.config/znt${rst}. Skeletons are copied there
+when using ${h3}zsh-navigation-tools.plugin.zsh${rst} file (sourcing it or using
+a plugin manager). There's a main config file ${h3}n-list.conf${rst} and files
+for each tool.
+
+To have a skeleton copied again into ${h3}~/.config/znt${rst}, delete it from
+there and restart Zsh a few times (3-7 or so; there's a random check
+that optimizes startup time).
+
+${h1}Predefined search keywords${rst}
+
+Following block of code in e.g. ${h3}~/.config/znt/n-history.conf${rst} defines
+set of keywords that can be invoked (i.e. searched for) via ${h2}F2${rst}, ${h2}Ctrl-X${rst}
+or ${h2}Ctrl-/${rst}:
+
+    ${h4}# Search keywords, iterated with F2 or Ctrl-X or Ctrl-/${rst}
+    ${h2}local${rst} -a keywords
+    keywords=( ${h2}\"git\" \"vim\" \"mplayer\"${rst} )
+
+${h1}Search query rotation${rst}
+
+When searching, after pressing ${h2}Ctrl-A${rst}, words 1 2 3 will become 3 1 2, etc.
+This can be used to edit some not-last word.
+
+${h1}Fix mode${rst}
+
+Approximate matching - pressing ${h2}f${rst} or ${h2}Ctrl-F${rst} will enter "FIX" mode, in which
+1 or 2 errors are allowed in what's searched. This utilizes original Zsh
+approximate matching features and is intended to be used after entering
+search query, when a typo is discovered.
+
+${h1}Color themes${rst}
+
+Following block of code in ${h3}~/.config/znt/n-list.conf${rst} defines set of
+themes that can be browsed with ${h2}Ctrl-T${rst} and ${h2}Ctrl-G${rst}:
+
+    ${h4}# Combinations of colors to try out with Ctrl-T and Ctrl-G
+    # The last number is the bold option, 0 or 1${rst}
+    ${h2}local${rst} -a themes
+    themes=( ${h2}\"white/black/1\" \"green/black/0\" \"green/black/1\"${rst}
+             ${h2}\"white/blue/0\" \"white/blue/1\" \"magenta/black/0\"${rst}
+             ${h2}\"magenta/black/1\"${rst} )
+
+It's \"foreground/background/bold\". There's support for 256-color themes
+for Zsh > 5.2, defined like e.g.: 
+
+    themes=( ${h2}\"white/17/0\" \"10/17/1\" \"white/24/1\"${rst} )
+
+i.e. with use of numbers, from 0 to 254.
+
+${h1}Private history${rst}
+
+N-history stores what's selected in its own history file. It can be
+edited. Use ${h2}e${rst} or ${h2}Ctrl-E${rst} for that when in n-history. Your \$EDITOR will
+start. This is a way to have handy set of bookmarks prepared in private
+history's file.
+
+Private history is instantly shared among sessions.
+
+${h1}Zshrc integration${rst}
+
+There are 5 standard configuration variables that can be set in zshrc:
+
+${h4}znt_history_active_text${rst}
+\"underline\" or \"reverse\" - how should be active element highlighted
+${h4}znt_history_nlist_coloring_pattern${rst}
+Pattern that can be used to colorize elements
+${h4}znt_history_nlist_coloring_color${rst}
+Color with which to colorize via the pattern
+${h4}znt_history_nlist_coloring_match_multiple${rst}
+Should multiple matches be colorized (${h2}\"0\"${rst} or ${h2}\"1\"${rst})
+${h4}znt_history_keywords ${h2}(array)${rst}
+Search keywords activated with Ctrl-X, F2, Ctrl-/, e.g. ( ${h2}\"git\"${rst} ${h2}\"vim\"${rst} )
+
+Above variables will work for n-history tool. For other tools, change
+\"_history_\" to e.g. \"_cd_\", for the n-cd tool. The same works for
+all 8 tools.
+
+Common configuration of the tools uses variables with \"_list_\" in them:
+
+${h4}znt_list_bold${rst}
+Should draw text in bold (${h2}\"0\"${rst} or ${h2}\"1\"${rst})
+${h4}znt_list_colorpair${rst}
+Main pair of colors to be used, e.g ${h2}\"green/black\"${rst}
+${h4}znt_list_border${rst}
+Should draw borders around windows (${h2}\"0\"${rst} or ${h2}\"1\"${rst})
+${h4}znt_list_themes ${h2}(array)${rst}
+List of themes to try out with Ctrl-T, e.g. ( ${h2}\"white/black/1\"${rst}
+${h2}\"green/black/0\"${rst} )
+${h4}znt_list_instant_select${rst}
+Should pressing enter in search mode leave tool (${h2}\"0\"${rst} or ${h2}\"1\"${rst})
+
+If you used ZNT before v2.1.12 then remove old configuration files
+${h3}~/.config/znt/*.conf${rst} so that ZNT can update them to the latest versions
+that support integration with Zshrc. If you used installer then run it
+again (after the remove of configuration files), that is not needed when
+using as plugin.
+"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-history b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-history
new file mode 100644 (file)
index 0000000..b425ecd
--- /dev/null
@@ -0,0 +1,371 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-history` to .zshrc
+#
+# This function allows to browse Z shell's history and use the
+# entries
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob
+zmodload zsh/curses
+zmodload zsh/parameter
+
+local IFS="
+"
+
+# Variables to save list's state when switching views
+# The views are: history and "most frequent history words"
+local one_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+local one_NLIST_CURRENT_IDX
+local one_NLIST_IS_SEARCH_MODE
+local one_NLIST_SEARCH_BUFFER
+local one_NLIST_TEXT_OFFSET
+local one_NLIST_IS_UNIQ_MODE
+local one_NLIST_IS_F_MODE
+local one_NLIST_GREP_STRING
+local one_NLIST_NONSELECTABLE_ELEMENTS
+local one_NLIST_REMEMBER_STATE
+local one_NLIST_ENABLED_EVENTS
+
+local two_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+local two_NLIST_CURRENT_IDX
+local two_NLIST_IS_SEARCH_MODE
+local two_NLIST_SEARCH_BUFFER
+local two_NLIST_TEXT_OFFSET
+local two_NLIST_IS_UNIQ_MODE
+local two_NLIST_IS_F_MODE
+local two_NLIST_GREP_STRING
+local two_NLIST_NONSELECTABLE_ELEMENTS
+local two_NLIST_REMEMBER_STATE
+local two_NLIST_ENABLED_EVENTS
+
+local three_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+local three_NLIST_CURRENT_IDX
+local three_NLIST_IS_SEARCH_MODE
+local three_NLIST_SEARCH_BUFFER
+local three_NLIST_TEXT_OFFSET
+local three_NLIST_IS_UNIQ_MODE
+local three_NLIST_IS_F_MODE
+local three_NLIST_GREP_STRING
+local three_NLIST_NONSELECTABLE_ELEMENTS
+local three_NLIST_REMEMBER_STATE
+local three_NLIST_ENABLED_EVENTS
+
+# history view
+integer active_view=0
+
+# Lists are "0", "1", "2" - 1st, 2nd, 3rd
+# Switching is done in cyclic manner
+# i.e. 0 -> 1, 1 -> 2, 2 -> 0
+_nhistory_switch_lists_states() {
+    # First argument is current, newly selected list, i.e. $active_view
+    # This implies that we are switching from previous view
+   
+    if [ "$1" = "0" ]; then
+        # Switched to 1st list, save 3rd list's state
+        three_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+        three_NLIST_CURRENT_IDX=$NLIST_CURRENT_IDX
+        three_NLIST_IS_SEARCH_MODE=$NLIST_IS_SEARCH_MODE
+        three_NLIST_SEARCH_BUFFER=$NLIST_SEARCH_BUFFER
+        three_NLIST_TEXT_OFFSET=$NLIST_TEXT_OFFSET
+        three_NLIST_IS_UNIQ_MODE=$NLIST_IS_UNIQ_MODE
+        three_NLIST_IS_F_MODE=$NLIST_IS_F_MODE
+        three_NLIST_GREP_STRING=$NLIST_GREP_STRING
+        three_NLIST_NONSELECTABLE_ELEMENTS=( ${NLIST_NONSELECTABLE_ELEMENTS[@]} )
+        three_NLIST_REMEMBER_STATE=$NLIST_REMEMBER_STATE
+        three_NLIST_ENABLED_EVENTS=( ${NLIST_ENABLED_EVENTS[@]} )
+
+        # ..and restore 1st list's state
+        NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=$one_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+        NLIST_CURRENT_IDX=$one_NLIST_CURRENT_IDX
+        NLIST_IS_SEARCH_MODE=$one_NLIST_IS_SEARCH_MODE
+        NLIST_SEARCH_BUFFER=$one_NLIST_SEARCH_BUFFER
+        NLIST_TEXT_OFFSET=$one_NLIST_TEXT_OFFSET
+        NLIST_IS_UNIQ_MODE=$one_NLIST_IS_UNIQ_MODE
+        NLIST_IS_F_MODE=$one_NLIST_IS_F_MODE
+        NLIST_GREP_STRING=$one_NLIST_GREP_STRING
+        NLIST_NONSELECTABLE_ELEMENTS=( ${one_NLIST_NONSELECTABLE_ELEMENTS[@]} )
+        NLIST_REMEMBER_STATE=$one_NLIST_REMEMBER_STATE
+        NLIST_ENABLED_EVENTS=( ${one_NLIST_ENABLED_EVENTS[@]} )
+    elif [ "$1" = "1" ]; then
+        # Switched to 2nd list, save 1st list's state
+        one_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+        one_NLIST_CURRENT_IDX=$NLIST_CURRENT_IDX
+        one_NLIST_IS_SEARCH_MODE=$NLIST_IS_SEARCH_MODE
+        one_NLIST_SEARCH_BUFFER=$NLIST_SEARCH_BUFFER
+        one_NLIST_TEXT_OFFSET=$NLIST_TEXT_OFFSET
+        one_NLIST_IS_UNIQ_MODE=$NLIST_IS_UNIQ_MODE
+        one_NLIST_IS_F_MODE=$NLIST_IS_F_MODE
+        one_NLIST_GREP_STRING=$NLIST_GREP_STRING
+        one_NLIST_NONSELECTABLE_ELEMENTS=( ${NLIST_NONSELECTABLE_ELEMENTS[@]} )
+        one_NLIST_REMEMBER_STATE=$NLIST_REMEMBER_STATE
+        one_NLIST_ENABLED_EVENTS=( ${NLIST_ENABLED_EVENTS[@]} )
+
+        # ..and restore 2nd list's state
+        NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=$two_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+        NLIST_CURRENT_IDX=$two_NLIST_CURRENT_IDX
+        NLIST_IS_SEARCH_MODE=$two_NLIST_IS_SEARCH_MODE
+        NLIST_SEARCH_BUFFER=$two_NLIST_SEARCH_BUFFER
+        NLIST_TEXT_OFFSET=$two_NLIST_TEXT_OFFSET
+        NLIST_IS_UNIQ_MODE=$two_NLIST_IS_UNIQ_MODE
+        NLIST_IS_F_MODE=$two_NLIST_IS_F_MODE
+        NLIST_GREP_STRING=$two_NLIST_GREP_STRING
+        NLIST_NONSELECTABLE_ELEMENTS=( ${two_NLIST_NONSELECTABLE_ELEMENTS[@]} )
+        NLIST_REMEMBER_STATE=$two_NLIST_REMEMBER_STATE
+        NLIST_ENABLED_EVENTS=( ${two_NLIST_ENABLED_EVENTS[@]} )
+    elif [ "$1" = "2" ]; then
+        # Switched to 3rd list, save 2nd list's state
+        two_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+        two_NLIST_CURRENT_IDX=$NLIST_CURRENT_IDX
+        two_NLIST_IS_SEARCH_MODE=$NLIST_IS_SEARCH_MODE
+        two_NLIST_SEARCH_BUFFER=$NLIST_SEARCH_BUFFER
+        two_NLIST_TEXT_OFFSET=$NLIST_TEXT_OFFSET
+        two_NLIST_IS_UNIQ_MODE=$NLIST_IS_UNIQ_MODE
+        two_NLIST_IS_F_MODE=$NLIST_IS_F_MODE
+        two_NLIST_GREP_STRING=$NLIST_GREP_STRING
+        two_NLIST_NONSELECTABLE_ELEMENTS=( ${NLIST_NONSELECTABLE_ELEMENTS[@]} )
+        two_NLIST_REMEMBER_STATE=$NLIST_REMEMBER_STATE
+        two_NLIST_ENABLED_EVENTS=( ${NLIST_ENABLED_EVENTS[@]} )
+
+        # ..and restore 3rd list's state
+        NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=$three_NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN
+        NLIST_CURRENT_IDX=$three_NLIST_CURRENT_IDX
+        NLIST_IS_SEARCH_MODE=$three_NLIST_IS_SEARCH_MODE
+        NLIST_SEARCH_BUFFER=$three_NLIST_SEARCH_BUFFER
+        NLIST_TEXT_OFFSET=$three_NLIST_TEXT_OFFSET
+        NLIST_IS_UNIQ_MODE=$three_NLIST_IS_UNIQ_MODE
+        NLIST_IS_F_MODE=$three_NLIST_IS_F_MODE
+        NLIST_GREP_STRING=$three_NLIST_GREP_STRING
+        NLIST_NONSELECTABLE_ELEMENTS=( ${three_NLIST_NONSELECTABLE_ELEMENTS[@]} )
+        NLIST_REMEMBER_STATE=$three_NLIST_REMEMBER_STATE
+        NLIST_ENABLED_EVENTS=( ${three_NLIST_ENABLED_EVENTS[@]} )
+    fi
+}
+
+local most_frequent_db="$HOME/.config/znt/mostfrequent.db"
+_nhistory_generate_most_frequent() {
+    local title=$'\x1b[00;31m'"Most frequent history words:"$'\x1b[00;00m\0'
+
+    typeset -A uniq
+    for k in "${historywords[@]}"; do
+        uniq[$k]=$(( ${uniq[$k]:-0} + 1 ))
+    done
+    vk=()
+    for k v in ${(kv)uniq}; do
+        vk+="$v"$'\t'"$k"
+    done
+
+    print -rl -- "$title" "${(On)vk[@]}" > "$most_frequent_db"
+}
+
+# Load configuration
+unset NLIST_COLORING_PATTERN
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-history.conf ] && builtin source ~/.config/znt/n-history.conf
+
+local list
+local selected
+local private_history_db="$HOME/.config/znt/privhist.db"
+
+local NLIST_GREP_STRING="$1"
+# 2 is: init once, then remember
+local NLIST_REMEMBER_STATE=2
+two_NLIST_REMEMBER_STATE=2
+three_NLIST_REMEMBER_STATE=2
+
+# Only Private history has EDIT
+local -a NLIST_ENABLED_EVENTS
+NLIST_ENABLED_EVENTS=( "F1" "HELP" )
+two_NLIST_ENABLED_EVENTS=( "F1" "EDIT" "HELP" )
+three_NLIST_ENABLED_EVENTS=( "F1" "HELP" )
+
+# All view should attempt to replace new lines with \n
+local NLIST_REPLACE_NEWLINES="1"
+two_NLIST_REPLACE_NEWLINES="1"
+three_NLIST_REPLACE_NEWLINES="1"
+
+# Only second and third view has non-selectable first entry
+local -a NLIST_NONSELECTABLE_ELEMENTS
+NLIST_NONSELECTABLE_ELEMENTS=( )
+two_NLIST_NONSELECTABLE_ELEMENTS=( 1 )
+three_NLIST_NONSELECTABLE_ELEMENTS=( 1 )
+
+while (( 1 )); do
+
+    #
+    # View 1 - history
+    #
+    if [ "$active_view" = "0" ]; then
+        list=( "$history[@]" )
+        list=( "${(@M)list:#(#i)*$NLIST_GREP_STRING*}" )
+
+        if [ "$#list" -eq 0 ]; then
+            echo "No matching history entries"
+            return 1
+        fi
+
+        n-list "${list[@]}"
+
+        # Selection or quit?
+        if [[ "$REPLY" = -(#c0,1)[0-9]## && ("$REPLY" -lt 0 || "$REPLY" -gt 0) ]]; then
+            break
+        fi
+
+        # View change?
+        if [ "$REPLY" = "F1" ]; then
+            # Target view: 2
+            active_view=1
+            _nhistory_switch_lists_states "1"
+        elif [ "$REPLY" = "HELP" ]; then
+            n-help
+        fi
+
+    #
+    # View 3 - most frequent words in history
+    #
+    elif [ "$active_view" = "2" ]; then
+        local -a dbfile
+        dbfile=( $most_frequent_db(Nm+1) )
+
+        # Compute most frequent history words
+        if [[ "${#NHISTORY_WORDS}" -eq "0" || "${#dbfile}" -ne "0" ]]; then
+            # Read the list if it's there
+            local -a list
+            list=()
+            [ -s "$most_frequent_db" ] && list=( ${(f)"$(<$most_frequent_db)"} )
+
+            # Will wait for the data?
+            local message=0
+            if [[ "${#list}" -eq 0 ]]; then
+                message=1
+                _nlist_alternate_screen 1
+                zcurses init
+                zcurses delwin info 2>/dev/null
+                zcurses addwin info "$term_height" "$term_width" 0 0
+                zcurses bg info white/black
+                zcurses string info "Computing most frequent history words..."$'\n'
+                zcurses string info "(This is done once per day, from now on transparently)"$'\n'
+                zcurses refresh info
+                sleep 3
+            fi
+
+            # Start periodic list regeneration?
+            if [[ "${#list}" -eq 0 || "${#dbfile}" -ne "0" ]]; then
+                # Mark the file with current time, to prevent double
+                # regeneration (on quick double change of view)
+                print >> "$most_frequent_db"
+                (_nhistory_generate_most_frequent &) &> /dev/null
+            fi
+
+            # Ensure we got the list, wait for it if needed
+            while [[ "${#list}" -eq 0 ]]; do
+                zcurses string info "."
+                zcurses refresh info
+                LANG=C sleep 0.5
+                [ -s "$most_frequent_db" ] && list=( ${(f)"$(<$most_frequent_db)"} )
+            done
+
+            NHISTORY_WORDS=( "${list[@]}" )
+
+            if [ "$message" -eq "1" ]; then
+                zcurses delwin info 2>/dev/null
+                zcurses refresh
+                zcurses end
+                _nlist_alternate_screen 0
+            fi
+        else
+            # Reuse most frequent history words
+            local -a list
+            list=( "${NHISTORY_WORDS[@]}" )
+        fi
+
+        n-list "${list[@]}"
+
+        if [ "$REPLY" = "F1" ]; then
+            # Target view: 1
+            active_view=0
+            _nhistory_switch_lists_states "0"
+        elif [[ "$REPLY" = -(#c0,1)[0-9]## && "$REPLY" -lt 0 ]]; then
+            break
+        elif [[ "$REPLY" = -(#c0,1)[0-9]## && "$REPLY" -gt 0 ]]; then
+            local word="${reply[REPLY]#(#s) #[0-9]##$'\t'}"
+            one_NLIST_SEARCH_BUFFER="$word"
+            one_NLIST_SEARCH_BUFFER="${one_NLIST_SEARCH_BUFFER## ##}"
+
+            # Target view: 1
+            active_view=0
+            _nhistory_switch_lists_states "0"
+        elif [ "$REPLY" = "HELP" ]; then
+            n-help
+        fi
+
+    #
+    # View 2 - private history
+    #
+    elif [ "$active_view" = "1" ]; then
+        if [ -s "$private_history_db" ]; then
+            local title=$'\x1b[00;32m'"Private history:"$'\x1b[00;00m\0'
+            () { fc -Rap "$private_history_db" 20000 0; list=( "$title" ${history[@]} ) }
+        else
+            list=( "Private history - history entries selected via this tool will be put here" )
+        fi
+
+        n-list "${list[@]}"
+
+        # Selection or quit?
+        if [[ "$REPLY" = -(#c0,1)[0-9]## && ("$REPLY" -lt 0 || "$REPLY" -gt 0) ]]; then
+            break
+        fi
+
+        # View change?
+        if [ "$REPLY" = "F1" ]; then
+            # Target view: 3
+            active_view=2
+            _nhistory_switch_lists_states "2"
+        # Edit of the history?
+        elif [ "$REPLY" = "EDIT" ]; then
+            "${EDITOR:-vim}" "$private_history_db"
+        elif [ "$REPLY" = "HELP" ]; then
+            n-help
+        fi
+    fi
+done
+
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+
+    # Append to private history
+    if [[ "$active_view" = "0" ]]; then
+        local newline=$'\n'
+        local selected_ph="${selected//$newline/\\$newline}"
+        print -r -- "$selected_ph" >> "$private_history_db"
+    fi
+
+    # TMUX?
+    if [[ "$ZNT_TMUX_MODE" = "1" ]]; then
+        tmux send -t "$ZNT_TMUX_ORIGIN_SESSION:$ZNT_TMUX_ORIGIN_WINDOW.$ZNT_TMUX_ORIGIN_PANE" "$selected"
+        tmux kill-window
+        return 0
+    # ZLE?
+    elif [ "${(t)CURSOR}" = "integer-local-special" ]; then
+        zle .redisplay
+        zle .kill-buffer
+        LBUFFER+="$selected"
+    else
+        print -zr -- "$selected"
+    fi
+else
+    # TMUX?
+    if [[ "$ZNT_TMUX_MODE" = "1" ]]; then
+        tmux kill-window
+    # ZLE?
+    elif [[ "${(t)CURSOR}" = "integer-local-special" ]]; then
+        zle redisplay
+    fi
+fi
+
+return 0
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-kill b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-kill
new file mode 100644 (file)
index 0000000..0d10565
--- /dev/null
@@ -0,0 +1,96 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-kill` to .zshrc
+#
+# This function allows to choose a process and a signal to send to it
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob
+zmodload zsh/curses
+
+local IFS="
+"
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-kill.conf ] && builtin source ~/.config/znt/n-kill.conf
+
+typeset -A signals
+signals=(
+     1       "1  - HUP"
+     2       "2  - INT"
+     3       "3  - QUIT"
+     6       "6  - ABRT"
+     9       "9  - KILL"
+     14      "14 - ALRM"
+     15      "15 - TERM"
+     17      "17 - STOP"
+     19      "19 - CONT"
+)
+
+local list
+local selected
+local signal
+local -a signal_names
+local title
+
+NLIST_REMEMBER_STATE=0
+
+typeset -a NLIST_NONSELECTABLE_ELEMENTS
+NLIST_NONSELECTABLE_ELEMENTS=( 1 )
+
+type ps 2>/dev/null 1>&2 || { echo >&2 "Error: \`ps' not found"; return 1 }
+
+case "$(uname)" in
+    CYGWIN*) list=( `command ps -Wa` )  ;;
+    *) list=( `command ps -o pid,uid,command -A` ) ;;
+esac
+
+# Ask of PID
+title=$'\x1b[00;31m'"${list[1]}"$'\x1b[00;00m\0'
+shift list
+list=( "$title" "${(@M)list:#(#i)*$1*}" )
+
+local NLIST_GREP_STRING="$1"
+
+if [ "$#list" -eq 1 ]; then
+    echo "No matching processes"
+    return 1
+fi
+
+n-list "$list[@]"
+
+# Got answer? (could be Ctrl-C or 'q')
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+    selected="${selected## #}"
+    pid="${selected%% *}"
+
+    # Now ask of signal
+    signal_names=( ${(vin)signals} )
+    typeset -a NLIST_HOP_INDEXES
+    NLIST_HOP_INDEXES=( 3 6 8 )
+    unset NLIST_COLORING_PATTERN
+    n-list $'\x1b[00;31mSelect signal:\x1b[00;00m' "$signal_names[@]"
+
+    if [ "$REPLY" -gt 0 ]; then
+        selected="$reply[REPLY]"
+        signal="${(k)signals[(r)$selected]}"
+
+        # ZLE?
+        if [ "${(t)CURSOR}" = "integer-local-special" ]; then
+            zle redisplay
+            zle kill-whole-line
+            zle -U "kill -$signal $pid"
+        else
+            print -zr "kill -$signal $pid"
+        fi
+    else
+        [ "${(t)CURSOR}" = "integer-local-special" ] && zle redisplay
+    fi
+else
+    [ "${(t)CURSOR}" = "integer-local-special" ] && zle redisplay
+fi
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list
new file mode 100644 (file)
index 0000000..f25db8f
--- /dev/null
@@ -0,0 +1,517 @@
+# $1, $2, ... - elements of the list
+# $NLIST_NONSELECTABLE_ELEMENTS - array of indexes (1-based) that cannot be selected
+# $REPLY is the output variable - contains index (1-based) or -1 when no selection
+# $reply (array) is the second part of the output - use the index (REPLY) to get selected element
+#
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-list` to .zshrc
+#
+# This function outputs a list of elements that can be
+# navigated with keyboard. Uses curses library
+
+emulate -LR zsh
+
+setopt typesetsilent extendedglob noshortloops
+
+_nlist_has_terminfo=0
+
+zmodload zsh/curses
+zmodload zsh/terminfo 2>/dev/null && _nlist_has_terminfo=1
+
+trap "REPLY=-2; reply=(); return" TERM INT QUIT
+trap "_nlist_exit" EXIT
+
+# Drawing and input
+autoload n-list-draw n-list-input
+
+# Cleanup before any exit
+_nlist_exit() {
+    setopt localoptions
+    setopt extendedglob
+
+    [[ "$REPLY" = -(#c0,1)[0-9]## || "$REPLY" = F<-> || "$REPLY" = "EDIT" || "$REPLY" = "HELP" ]] || REPLY="-1"
+    zcurses 2>/dev/null delwin inner
+    zcurses 2>/dev/null delwin main
+    zcurses 2>/dev/null refresh
+    zcurses end
+    _nlist_alternate_screen 0
+    _nlist_cursor_visibility 1
+    unset _nlist_has_terminfo
+}
+
+# Outputs a message in the bottom of the screen
+_nlist_status_msg() {
+    # -1 for border, -1 for 0-based indexing
+    zcurses move main $(( term_height - 1 - 1 )) 2
+    zcurses clear main eol
+    zcurses string main "$1"
+    #status_msg_strlen is localized in caller
+    status_msg_strlen=$#1
+}
+
+# Prefer tput, then module terminfo
+_nlist_cursor_visibility() {
+    if type tput 2>/dev/null 1>&2; then
+        [ "$1" = "1" ] && { tput cvvis; tput cnorm }
+        [ "$1" = "0" ] && tput civis
+    elif [ "$_nlist_has_terminfo" = "1" ]; then
+        [ "$1" = "1" ] && { [ -n $terminfo[cvvis] ] && echo -n $terminfo[cvvis];
+                           [ -n $terminfo[cnorm] ] && echo -n $terminfo[cnorm] }
+        [ "$1" = "0" ] && [ -n $terminfo[civis] ] && echo -n $terminfo[civis]
+    fi 
+}
+
+# Reason for this function is that on some systems
+# smcup and rmcup are not knowing why left empty
+_nlist_alternate_screen() {
+    [ "$_nlist_has_terminfo" -ne "1" ] && return
+    [[ "$1" = "1" && -n "$terminfo[smcup]" ]] && return
+    [[ "$1" = "0" && -n "$terminfo[rmcup]" ]] && return
+
+    case "$TERM" in
+        *rxvt*)
+            [ "$1" = "1" ] && echo -n $'\x1b7\x1b[?47h'
+            [ "$1" = "0" ] && echo -n $'\x1b[2J\x1b[?47l\x1b8'
+            ;;
+        *)
+            [ "$1" = "1" ] && echo -n $'\x1b[?1049h'
+            [ "$1" = "0" ] && echo -n $'\x1b[?1049l'
+            # just to remember two other that work: $'\x1b7\x1b[r\x1b[?47h', $'\x1b[?47l\x1b8'
+            ;;
+    esac
+}
+
+_nlist_compute_user_vars_difference() {
+        if [[ "${(t)NLIST_NONSELECTABLE_ELEMENTS}" != "array" &&
+                "${(t)NLIST_NONSELECTABLE_ELEMENTS}" != "array-local" ]]
+        then
+            last_element_difference=0
+            current_difference=0
+        else
+            last_element_difference=$#NLIST_NONSELECTABLE_ELEMENTS
+            current_difference=0
+            local idx
+            for idx in "${(n)NLIST_NONSELECTABLE_ELEMENTS[@]}"; do
+                [ "$idx" -le "$NLIST_CURRENT_IDX" ] && current_difference+=1 || break
+            done
+        fi
+}
+
+# List was processed, check if variables aren't off range
+_nlist_verify_vars() {
+    [ "$NLIST_CURRENT_IDX" -gt "$last_element" ] && NLIST_CURRENT_IDX="$last_element"
+    [[ "$NLIST_CURRENT_IDX" -eq 0 && "$last_element" -ne 0 ]] && NLIST_CURRENT_IDX=1
+    (( NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=0+((NLIST_CURRENT_IDX-1)/page_height)*page_height+1 ))
+}
+
+# Compute the variables which are shown to the user
+_nlist_setup_user_vars() {
+    if [ "$1" = "1" ]; then
+        # Basic values when there are no non-selectables
+        NLIST_USER_CURRENT_IDX="$NLIST_CURRENT_IDX"
+        NLIST_USER_LAST_ELEMENT="$last_element"
+    else
+        _nlist_compute_user_vars_difference
+        NLIST_USER_CURRENT_IDX=$(( NLIST_CURRENT_IDX - current_difference ))
+        NLIST_USER_LAST_ELEMENT=$(( last_element - last_element_difference ))
+    fi
+}
+
+_nlist_colorify_disp_list() {
+    local col=$'\x1b[00;34m' reset=$'\x1b[0m'
+    [ -n "$NLIST_COLORING_COLOR" ] && col="$NLIST_COLORING_COLOR"
+    [ -n "$NLIST_COLORING_END_COLOR" ] && reset="$NLIST_COLORING_END_COLOR"
+
+    if [ "$NLIST_COLORING_MATCH_MULTIPLE" -eq 1 ]; then
+        disp_list=( "${(@)disp_list//(#mi)$~NLIST_COLORING_PATTERN/$col${MATCH}$reset}" )
+    else
+        disp_list=( "${(@)disp_list/(#mi)$~NLIST_COLORING_PATTERN/$col${MATCH}$reset}" )
+    fi
+}
+
+#
+# Main code
+#
+
+# Check if there is proper input
+if [ "$#" -lt 1 ]; then
+    echo "Usage: n-list element_1 ..."
+    return 1
+fi
+
+REPLY="-1"
+typeset -ga reply
+reply=()
+
+integer term_height="$LINES"
+integer term_width="$COLUMNS"
+if [[ "$term_height" -lt 1 || "$term_width" -lt 1 ]]; then
+    local stty_out=$( stty size )
+    term_height="${stty_out% *}"
+    term_width="${stty_out#* }"
+fi
+integer inner_height=term_height-3
+integer inner_width=term_width-3
+integer page_height=inner_height
+integer page_width=inner_width
+
+typeset -a list disp_list
+integer last_element=$#
+local action
+local final_key
+integer selection
+integer last_element_difference=0
+integer current_difference=0
+local prev_search_buffer=""
+integer prev_uniq_mode=0
+integer prev_start_idx=-1
+local MBEGIN MEND MATCH mbegin mend match
+
+# Iteration over predefined keywords
+integer curkeyword nkeywords
+local keywordisfresh="0"
+if [[ "${(t)keywords}" != *array* ]]; then
+    local -a keywords
+    keywords=()
+fi
+curkeyword=0
+nkeywords=${#keywords}
+
+# Iteration over themes
+integer curtheme nthemes
+local themeisfresh="0"
+if [[ "${(t)themes}" != *array* ]]; then
+    local -a themes
+    themes=()
+fi
+curtheme=0
+nthemes=${#themes}
+
+# Ability to remember the list between calls
+if [[ -z "$NLIST_REMEMBER_STATE" || "$NLIST_REMEMBER_STATE" -eq 0 || "$NLIST_REMEMBER_STATE" -eq 2 ]]; then
+    NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN=1
+    NLIST_CURRENT_IDX=1
+    NLIST_IS_SEARCH_MODE=0
+    NLIST_SEARCH_BUFFER=""
+    NLIST_TEXT_OFFSET=0
+    NLIST_IS_UNIQ_MODE=0
+    NLIST_IS_F_MODE=0
+
+    # Zero - because it isn't known, unless we
+    # confirm that first element is selectable
+    NLIST_USER_CURRENT_IDX=0
+    [[ ${NLIST_NONSELECTABLE_ELEMENTS[(r)1]} != 1 ]] && NLIST_USER_CURRENT_IDX=1
+    NLIST_USER_LAST_ELEMENT=$(( last_element - $#NLIST_NONSELECTABLE_ELEMENTS ))
+
+    # 2 is init once, then remember
+    [ "$NLIST_REMEMBER_STATE" -eq 2 ] && NLIST_REMEMBER_STATE=1
+fi
+
+if [ "$NLIST_START_IN_SEARCH_MODE" -eq 1 ]; then
+    NLIST_START_IN_SEARCH_MODE=0
+    NLIST_IS_SEARCH_MODE=1
+fi
+
+if [ -n "$NLIST_SET_SEARCH_TO" ]; then
+    NLIST_SEARCH_BUFFER="$NLIST_SET_SEARCH_TO"
+    NLIST_SET_SEARCH_TO=""
+fi
+
+if [ "$NLIST_START_IN_UNIQ_MODE" -eq 1 ]; then
+    NLIST_START_IN_UNIQ_MODE=0
+    NLIST_IS_UNIQ_MODE=1
+fi
+
+_nlist_alternate_screen 1
+zcurses init
+zcurses delwin main 2>/dev/null
+zcurses delwin inner 2>/dev/null
+zcurses addwin main "$term_height" "$term_width" 0 0
+zcurses addwin inner "$inner_height" "$inner_width" 1 2
+# From n-list.conf
+[ "$colorpair" = "" ] && colorpair="white/black"
+[ "$border" = "0" ] || border="1"
+local background="${colorpair#*/}"
+local backuptheme="$colorpair/$bold"
+zcurses bg main "$colorpair"
+zcurses bg inner "$colorpair"
+if [ "$NLIST_IS_SEARCH_MODE" -ne 1 ]; then
+    _nlist_cursor_visibility 0
+fi
+
+zcurses refresh
+
+#
+# Listening for input
+#
+
+local key keypad
+
+# Clear input buffer
+zcurses timeout main 0
+zcurses input main key keypad
+zcurses timeout main -1
+key=""
+keypad=""
+
+# This loop makes script faster on some Zsh's (e.g. 5.0.8)
+repeat 1; do
+    list=( "$@" )
+done
+
+last_element="$#list"
+
+zcurses clear main redraw
+zcurses clear inner redraw
+while (( 1 )); do
+    # Do searching (filtering with string)
+    if [ -n "$NLIST_SEARCH_BUFFER" ]; then
+        # Compute new list?
+        if [[ "$NLIST_SEARCH_BUFFER" != "$prev_search_buffer" || "$NLIST_IS_UNIQ_MODE" -ne "$prev_uniq_mode"
+                || "$NLIST_IS_F_MODE" -ne "$prev_f_mode" ]]
+        then
+            prev_search_buffer="$NLIST_SEARCH_BUFFER"
+            prev_uniq_mode="$NLIST_IS_UNIQ_MODE"
+            prev_f_mode="$NLIST_IS_F_MODE"
+            # regenerating list -> regenerating disp_list
+            prev_start_idx=-1
+
+            # Take all elements, including duplicates and non-selectables
+            typeset +U list
+            repeat 1; do
+                list=( "$@" )
+            done
+
+            # Remove non-selectable elements
+            [ "$#NLIST_NONSELECTABLE_ELEMENTS" -gt 0 ] && for i in "${(nO)NLIST_NONSELECTABLE_ELEMENTS[@]}"; do
+                if [[ "$i" = <-> ]]; then
+                    list[$i]=()
+                fi
+            done
+
+            # Remove duplicates
+            [ "$NLIST_IS_UNIQ_MODE" -eq 1 ] && typeset -U list
+
+            last_element="$#list"
+
+            # Next do the filtering
+            local search_buffer="${NLIST_SEARCH_BUFFER%% ##}"
+            search_buffer="${search_buffer## ##}"
+            search_buffer="${search_buffer//(#m)[][*?|#~^()><\\]/\\$MATCH}"
+            local search_pattern=""
+            local colsearch_pattern=""
+            if [ -n "$search_buffer" ]; then
+                # The repeat will make the matching work on a fresh heap
+                repeat 1; do
+                    if [ "$NLIST_IS_F_MODE" -eq "1" ]; then
+                        search_pattern="${search_buffer// ##/*~^(#a1)*}"
+                        colsearch_pattern="${search_buffer// ##/|(#a1)}"
+                        list=( "${(@M)list:#(#ia1)*$~search_pattern*}" )
+                    elif [ "$NLIST_IS_F_MODE" -eq "2" ]; then
+                        search_pattern="${search_buffer// ##/*~^(#a2)*}"
+                        colsearch_pattern="${search_buffer// ##/|(#a2)}"
+                        list=( "${(@M)list:#(#ia2)*$~search_pattern*}" )
+                    else
+                        # Pattern will be *foo*~^*bar* (inventor: Mikael Magnusson)
+                        search_pattern="${search_buffer// ##/*~^*}"
+                        # Pattern will be (foo|bar)
+                        colsearch_pattern="${search_buffer// ##/|}"
+                        list=( "${(@M)list:#(#i)*$~search_pattern*}" )
+                    fi
+                done
+
+                last_element="$#list"
+            fi
+
+            # Called after processing list
+            _nlist_verify_vars
+        fi
+
+        _nlist_setup_user_vars 1
+
+        integer end_idx=$(( NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN + page_height - 1 ))
+        [ "$end_idx" -gt "$last_element" ] && end_idx=last_element
+
+        if [ "$prev_start_idx" -ne "$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN" ]; then
+            prev_start_idx="$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN"
+            disp_list=( "${(@)list[NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN, end_idx]}" )
+
+            if [ -n "$colsearch_pattern" ]; then
+                local red=$'\x1b[00;31m' reset=$'\x1b[00;00m'
+                # The repeat will make the matching work on a fresh heap
+                repeat 1; do
+                    if [ "$NLIST_IS_F_MODE" -eq "1" ]; then
+                        disp_list=( "${(@)disp_list//(#mia1)($~colsearch_pattern)/$red${MATCH}$reset}" )
+                    elif [ "$NLIST_IS_F_MODE" -eq "2" ]; then
+                        disp_list=( "${(@)disp_list//(#mia2)($~colsearch_pattern)/$red${MATCH}$reset}" )
+                    else
+                        disp_list=( "${(@)disp_list//(#mi)($~colsearch_pattern)/$red${MATCH}$reset}" )
+                    fi
+                done
+            fi
+
+            # We have display list, lets replace newlines with "\n" when needed (1/2)
+            [ "$NLIST_REPLACE_NEWLINES" -eq 1 ] && disp_list=( "${(@)disp_list//$'\n'/\\n}" )
+        fi
+
+        # Output colored list
+        zcurses clear inner
+        n-list-draw "$(( (NLIST_CURRENT_IDX-1) % page_height + 1 ))" \
+            "$page_height" "$page_width" 0 0 "$NLIST_TEXT_OFFSET" inner \
+            "$disp_list[@]"
+    else
+        # There is no search, but there was in previous loop
+        # OR
+        # Uniq mode was entered or left out
+        # -> compute new list
+        if [[ -n "$prev_search_buffer" || "$NLIST_IS_UNIQ_MODE" -ne "$prev_uniq_mode" ]]; then
+            prev_search_buffer=""
+            prev_uniq_mode="$NLIST_IS_UNIQ_MODE"
+            # regenerating list -> regenerating disp_list
+            prev_start_idx=-1
+
+            # Take all elements, including duplicates and non-selectables
+            typeset +U list
+            repeat 1; do
+                list=( "$@" )
+            done
+
+            # Remove non-selectable elements only when in uniq mode
+            [ "$NLIST_IS_UNIQ_MODE" -eq 1 ] && [ "$#NLIST_NONSELECTABLE_ELEMENTS" -gt 0 ] &&
+            for i in "${(nO)NLIST_NONSELECTABLE_ELEMENTS[@]}"; do
+                if [[ "$i" = <-> ]]; then
+                    list[$i]=()
+                fi
+            done
+
+            # Remove duplicates when in uniq mode
+            [ "$NLIST_IS_UNIQ_MODE" -eq 1 ] && typeset -U list
+
+            last_element="$#list"
+            # Called after processing list
+            _nlist_verify_vars
+        fi
+
+        # "1" - shouldn't bother with non-selectables
+        _nlist_setup_user_vars "$NLIST_IS_UNIQ_MODE"
+
+        integer end_idx=$(( NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN + page_height - 1 ))
+        [ "$end_idx" -gt "$last_element" ] && end_idx=last_element
+
+        if [ "$prev_start_idx" -ne "$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN" ]; then
+            prev_start_idx="$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN"
+            disp_list=( "${(@)list[NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN, end_idx]}" )
+
+            [ -n "$NLIST_COLORING_PATTERN" ] && _nlist_colorify_disp_list
+
+            # We have display list, lets replace newlines with "\n" when needed (2/2)
+            [ "$NLIST_REPLACE_NEWLINES" -eq 1 ] && disp_list=( "${(@)disp_list//$'\n'/\\n}" )
+        fi
+
+        # Output the list
+        zcurses clear inner
+        n-list-draw "$(( (NLIST_CURRENT_IDX-1) % page_height + 1 ))" \
+            "$page_height" "$page_width" 0 0 "$NLIST_TEXT_OFFSET" inner \
+            "$disp_list[@]"
+    fi
+
+    local status_msg_strlen
+    local keywordmsg=""
+    if [ "$keywordisfresh" = "1" ]; then
+        keywordmsg="($curkeyword/$nkeywords) "
+        keywordisfresh="0"
+    fi
+
+    local thememsg=""
+    if [ "$themeisfresh" = "1" ]; then
+        local theme="$backuptheme"
+        [ "$curtheme" -gt 0 ] && theme="${themes[curtheme]}"
+        thememsg="($curtheme/$nthemes $theme) "
+        themeisfresh="0"
+    fi
+
+    local _txt2="" _txt3=""
+    [ "$NLIST_IS_UNIQ_MODE" -eq 1 ] && _txt2="[-UNIQ-] "
+    [ "$NLIST_IS_F_MODE" -eq 1 ] && _txt3="[-FIX-] "
+    [ "$NLIST_IS_F_MODE" -eq 2 ] && _txt3="[-FIX2-] "
+
+    if [ "$NLIST_IS_SEARCH_MODE" = "1" ]; then
+        _nlist_status_msg "${_txt2}${_txt3}${keywordmsg}${thememsg}Filtering with: ${NLIST_SEARCH_BUFFER// /+}"
+    elif [[ ${NLIST_NONSELECTABLE_ELEMENTS[(r)$NLIST_CURRENT_IDX]} != $NLIST_CURRENT_IDX ||
+            -n "$NLIST_SEARCH_BUFFER" || "$NLIST_IS_UNIQ_MODE" -eq 1 ]]; then
+        local _txt=""
+        [ -n "$NLIST_GREP_STRING" ] && _txt=" [$NLIST_GREP_STRING]"
+        _nlist_status_msg "${_txt2}${_txt3}${keywordmsg}${thememsg}Current #$NLIST_USER_CURRENT_IDX (of #$NLIST_USER_LAST_ELEMENT entries)$_txt"
+    else
+        _nlist_status_msg "${keywordmsg}${thememsg}"
+    fi
+
+    [ "$border" = "1" ] && zcurses border main
+
+    local top_msg=" ${(C)ZSH_NAME} $ZSH_VERSION, shell level $SHLVL "
+    if [[ "${NLIST_ENABLED_EVENTS[(r)F1]}" = "F1" ]]; then
+        top_msg=" F1-change view,$top_msg"
+    fi
+    zcurses move main 0 $(( term_width / 2 - $#top_msg / 2 ))
+    zcurses string main $top_msg
+
+    zcurses refresh main inner
+    zcurses move main $(( term_height - 1 - 1 )) $(( status_msg_strlen + 2 ))
+
+    # Wait for input
+    zcurses input main key keypad
+
+    # Get the special (i.e. "keypad") key or regular key
+    if [ -n "$key" ]; then
+        final_key="$key"
+    elif [ -n "$keypad" ]; then
+        final_key="$keypad"
+    else
+        _nlist_status_msg "Inproper input detected"
+        zcurses refresh main inner
+    fi
+
+    n-list-input "$NLIST_CURRENT_IDX" "$NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN" \
+                    "$page_height" "$page_width" "$last_element" "$NLIST_TEXT_OFFSET" \
+                    "$final_key" "$NLIST_IS_SEARCH_MODE" "$NLIST_SEARCH_BUFFER" \
+                    "$NLIST_IS_UNIQ_MODE" "$NLIST_IS_F_MODE"
+
+    selection="$reply[1]"
+    action="$reply[2]"
+    NLIST_CURRENT_IDX="$reply[3]"
+    NLIST_FROM_WHAT_IDX_LIST_IS_SHOWN="$reply[4]"
+    NLIST_TEXT_OFFSET="$reply[5]"
+    NLIST_IS_SEARCH_MODE="$reply[6]"
+    NLIST_SEARCH_BUFFER="$reply[7]"
+    NLIST_IS_UNIQ_MODE="$reply[8]"
+    NLIST_IS_F_MODE="$reply[9]"
+
+    if [ -z "$action" ]; then
+        continue
+    elif [ "$action" = "SELECT" ]; then
+        REPLY="$selection"
+        reply=( "$list[@]" )
+        break
+    elif [ "$action" = "QUIT" ]; then
+        REPLY=-1
+        reply=( "$list[@]" )
+        break
+    elif [ "$action" = "REDRAW" ]; then
+        zcurses clear main redraw
+        zcurses clear inner redraw
+    elif [[ "$action" = F<-> ]]; then
+        REPLY="$action"
+        reply=( "$list[@]" )
+        break
+    elif [[ "$action" = "EDIT" ]]; then
+        REPLY="EDIT"
+        reply=( "$list[@]" )
+        break
+    elif [[ "$action" = "HELP" ]]; then
+        REPLY="HELP"
+        reply=( "$list[@]" )
+        break
+    fi
+done
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list-draw b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list-draw
new file mode 100644 (file)
index 0000000..ae1e011
--- /dev/null
@@ -0,0 +1,133 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-list-draw` to .zshrc
+#
+# This is an internal function not for direct use
+
+emulate -L zsh
+
+zmodload zsh/curses
+
+setopt typesetsilent extendedglob
+
+_nlist_print_with_ansi() {
+    local win="$1" text="$2" out col chunk Xout
+    integer text_offset="$3" max_text_len="$4" text_len=0 no_match=0 nochunk_text_len to_skip_from_chunk to_chop_off_from_chunk before_len
+
+    # 1 - non-escaped text, 2 - first number in the escaped text, with ;
+    # 3 - second number, 4 - text after whole escape text
+
+    typeset -a c
+    c=( black red green yellow blue magenta cyan white )
+
+    while [[ -n "$text" && "$no_match" -eq 0 ]]; do
+        if [[ "$text" = (#b)([^$'\x1b']#)$'\x1b'\[([0-9](#c0,2))(#B)(\;|)(#b)([0-9](#c0,2))m(*) ]]; then
+            # Text for further processing
+            text="$match[4]"
+            # Text chunk to output now
+            out="$match[1]"
+            # Save color
+            col="$match[2]"
+            (( match[3] >= 30 && match[3] <= 37 )) && col="$match[3]"
+        else
+            out="$text"
+            no_match=1
+        fi
+
+        if [ -n "$out" ]; then
+################ Expand tabs ################
+            chunk="$out"
+            before_len="$text_len"
+            Xout=""
+
+            while [ -n "$chunk" ]; do
+                [[ "$chunk" = (#b)([^$'\t']#)$'\t'(*) ]] && {
+                    (( all_text_len=((before_len+${#match[1]})/8+1)*8 ))
+
+                    Xout+="${(r:all_text_len-before_len:: :)match[1]}"
+
+                    before_len+=all_text_len-before_len
+                    chunk="$match[2]"
+                } || {
+                    Xout+="$chunk"
+                    break
+                }
+            done
+#############################################
+
+            # Input text length without the current chunk
+            nochunk_text_len=text_len
+            # Input text length up to current chunk
+            text_len+="$#Xout"
+
+            # Should start displaying with this chunk?
+            # I.e. stop skipping left part of the input text?
+            if (( text_len > text_offset )); then
+                to_skip_from_chunk=text_offset-nochunk_text_len
+
+                # LEFT - is chunk off the left skip boundary? +1 for 1-based index in string
+                (( to_skip_from_chunk > 0 )) && Xout="${Xout[to_skip_from_chunk+1,-1]}"
+
+                # RIGHT - is text off the screen?
+                if (( text_len-text_offset > max_text_len )); then
+                    to_chop_off_from_chunk=0+(text_len-text_offset)-max_text_len
+                    Xout="${Xout[1,-to_chop_off_from_chunk-1]}"
+                fi
+                
+                [ -n "$Xout" ] && zcurses string "$win" "$Xout"
+            fi
+        fi
+
+        if (( no_match == 0 )); then
+            if (( col >= 30 && col <= 37 )); then
+                zcurses attr "$win" $c[col-29]/"$background"
+            elif [[ "$col" -eq 0 ]]; then
+                zcurses attr "$win" "$colorpair"
+            fi
+        fi
+    done
+}
+
+integer highlight="$1"
+integer page_height="$2"
+integer page_width="$3"
+local y_offset="$4"
+local x_offset="$5"
+local text_offset="$6"
+local win="$7"
+shift 7
+integer max_text_len=page_width-x_offset
+
+[[ "$bold" = "0" || "$bold" = "-bold" ]] && bold="-bold" || bold="+bold"
+[[ "$active_text" = "underline" || "$active_text" = "reverse" ]] || local active_text="reverse"
+# Linux has ncv 18, screen* has ncv 3 - underline won't work properly
+(( ${terminfo[ncv]:-0} & 2 )) && active_text="reverse"
+# FreeBSD uses TERM=xterm for newcons but doesn't actually support underline
+[[ "$TERM" = "xterm" && -z "$DISPLAY" ]] && active_text="reverse"
+
+integer max_idx=page_height
+integer end_idx=max_idx
+[ "$end_idx" -gt "$#" ] && end_idx="$#"
+integer y=y_offset
+
+zcurses attr "$win" "$bold" "$colorpair"
+
+integer i text_len
+local text
+for (( i=1; i<=end_idx; i++ )); do
+    zcurses move "$win" $y "$x_offset"
+
+    [ "$i" = "$highlight" ] && zcurses attr "$win" +"$active_text"
+    _nlist_print_with_ansi "$win" "$@[i]" "$text_offset" "$max_text_len"
+    zcurses clear "$win" eol
+    [ "$i" = "$highlight" ] && zcurses attr "$win" -"$active_text"
+
+    y+=1
+done
+
+if [ "$end_idx" -lt "$max_idx" ]; then
+    zcurses move "$win" $y "$x_offset"
+    zcurses clear "$win" eol
+fi
+
+zcurses attr "$win" white/black
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list-input b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-list-input
new file mode 100644 (file)
index 0000000..9bafc51
--- /dev/null
@@ -0,0 +1,377 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-list-input` to .zshrc
+#
+# This is an internal function not for direct use
+
+emulate -L zsh
+
+zmodload zsh/curses
+
+setopt typesetsilent
+
+# Compute first to show index
+_nlist_compute_first_to_show_idx() {
+    from_what_idx_list_is_shown=0+((current_idx-1)/page_height)*page_height+1
+}
+
+_nlist_update_from_keywords() {
+    keywordisfresh="1"
+    if [ "$nkeywords" -gt 0 ]; then
+        curkeyword=$(( (curkeyword+1) % (nkeywords+1) ))
+        if [ "$curkeyword" -eq "0" ]; then
+            buffer=""
+        else
+            buffer="${keywords[curkeyword]}"
+        fi
+    fi
+}
+
+_nlist_iterate_theme() {
+    themeisfresh="1"
+    if [ "$1" = "1" ]; then
+        curtheme=$(( (curtheme+1) % (nthemes+1) ))
+    else
+        curtheme=curtheme-1
+        [ "$curtheme" -lt 0 ] && curtheme=nthemes
+    fi
+
+    if [ "$nthemes" -gt 0 ]; then
+        local theme=${themes[curtheme]}
+        [ "$curtheme" -eq "0" ] && theme="$backuptheme"
+
+        colorpair="${theme%/*}"
+        bold="${theme##*/}"
+        background="${colorpair#*/}"
+        zcurses bg main "$colorpair"
+        zcurses bg inner "$colorpair"
+    fi
+}
+
+_nlist_rotate_buffer() {
+    setopt localoptions noglob
+
+    local -a words
+    words=( ${(s: :)buffer} )
+    words=( ${words[-1]} ${words[1,-2]} )
+
+    local space=""
+    [ "${buffer[-1]}" = " " ] && space=" "
+
+    buffer="${(j: :)words}$space"
+}
+
+typeset -ga reply
+reply=( -1 '' )
+integer current_idx="$1"
+integer from_what_idx_list_is_shown="$2"
+integer page_height="$3"
+integer page_width="$4"
+integer last_element="$5"
+integer hscroll="$6"
+local key="$7"
+integer search="$8"
+local buffer="$9"
+integer uniq_mode="$10"
+integer f_mode="$11"
+
+#
+# Listening for input
+#
+
+if [ "$search" = "0" ]; then
+
+case "$key" in
+    (UP|k|$'\C-P')
+        # Are there any elements before the current one?
+        [ "$current_idx" -gt 1 ] && current_idx=current_idx-1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (DOWN|j|$'\C-N')
+        # Are there any elements after the current one?
+        [ "$current_idx" -lt "$last_element" ] && current_idx=current_idx+1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (PPAGE|$'\b'|$'\C-?'|BACKSPACE)
+        current_idx=current_idx-page_height
+        [ "$current_idx" -lt 1 ] && current_idx=1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (NPAGE|" ")
+        current_idx=current_idx+page_height
+        [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
+        _nlist_compute_first_to_show_idx
+        ;;
+    ($'\C-U')
+        current_idx=current_idx-page_height/2
+        [ "$current_idx" -lt 1 ] && current_idx=1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    ($'\C-D')
+        current_idx=current_idx+page_height/2
+        [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (HOME|g)
+        current_idx=1
+        _nlist_compute_first_to_show_idx
+        ;;
+    (END|G)
+        current_idx=last_element
+        _nlist_compute_first_to_show_idx
+        ;;
+    ($'\n'|ENTER)
+        # Is that element selectable?
+        # Check for this only when there is no search
+        if [[ "$NLIST_SEARCH_BUFFER" != "" || "$NLIST_IS_UNIQ_MODE" -eq 1 ||
+            ${NLIST_NONSELECTABLE_ELEMENTS[(r)$current_idx]} != $current_idx ]]
+        then
+            # Save current element in the result variable
+            reply=( $current_idx "SELECT" )
+        fi
+        ;;
+    (H|'?')
+        # This event needs to be enabled
+        if [[ "${NLIST_ENABLED_EVENTS[(r)HELP]}" = "HELP" ]]; then
+            reply=( -1 "HELP" )
+        fi
+        ;;
+    (F1)
+        # This event needs to be enabled
+        if [[ "${NLIST_ENABLED_EVENTS[(r)F1]}" = "F1" ]]; then
+            reply=( -1 "$key" )
+        fi
+        ;;
+    (F4|F5|F6|F7|F8|F9|F10|DC)
+        # ignore; F2, F3 are used below
+        ;;
+    (q)
+        reply=( -1 "QUIT" )
+        ;;
+    (/)
+        search=1
+        _nlist_cursor_visibility 1
+        ;;
+    ($'\t')
+        reply=( $current_idx "LEAVE" )
+        ;;
+    ($'\C-L')
+        reply=( -1 "REDRAW" )
+        ;;
+    (\])
+        [[ "${(t)NLIST_HOP_INDEXES}" = "array" || "${(t)NLIST_HOP_INDEXES}" = "array-local" ]] &&
+        [ -z "$NLIST_SEARCH_BUFFER" ] && [ "$NLIST_IS_UNIQ_MODE" -eq 0 ] &&
+        for idx in "${(n)NLIST_HOP_INDEXES[@]}"; do
+            if [ "$idx" -gt "$current_idx" ]; then
+                current_idx=$idx
+                _nlist_compute_first_to_show_idx
+                break
+            fi
+        done
+        ;;
+    (\[)
+        [[ "${(t)NLIST_HOP_INDEXES}" = "array" || "${(t)NLIST_HOP_INDEXES}" = "array-local" ]] &&
+        [ -z "$NLIST_SEARCH_BUFFER" ] && [ "$NLIST_IS_UNIQ_MODE" -eq 0 ] &&
+        for idx in "${(nO)NLIST_HOP_INDEXES[@]}"; do
+            if [ "$idx" -lt "$current_idx" ]; then
+                current_idx=$idx
+                _nlist_compute_first_to_show_idx
+                break
+            fi
+        done
+        ;;
+    ('<'|'{'|LEFT|'h')
+        hscroll=hscroll-7
+        [ "$hscroll" -lt 0 ] && hscroll=0
+        ;;
+    ('>'|'}'|RIGHT|'l')
+        hscroll+=7
+        ;;
+    ($'\E')
+        buffer=""
+        ;;
+    (F3)
+        if [ "$search" = "1" ]; then
+            search=0
+            _nlist_cursor_visibility 0
+        else
+            search=1
+            _nlist_cursor_visibility 1
+        fi
+        ;;
+    (o|$'\C-O')
+        uniq_mode=1-uniq_mode
+        ;;
+    (f|$'\C-F')
+        (( f_mode=(f_mode+1) % 3 ))
+        ;;
+    ($'\x1F'|F2|$'\C-X')
+        search=1
+        _nlist_cursor_visibility 1
+        _nlist_update_from_keywords
+        ;;
+    ($'\C-T')
+        _nlist_iterate_theme 1
+        ;;
+    ($'\C-G')
+        _nlist_iterate_theme 0
+        ;;
+    ($'\C-E'|e)
+        # This event needs to be enabled
+        if [[ "${NLIST_ENABLED_EVENTS[(r)EDIT]}" = "EDIT" ]]; then
+            reply=( -1 "EDIT" )
+        fi
+        ;;
+    ($'\C-A')
+        _nlist_rotate_buffer
+        ;;
+    (*)
+        ;;
+esac
+
+else
+
+case "$key" in
+    ($'\n'|ENTER)
+        if [ "$NLIST_INSTANT_SELECT" = "1" ]; then
+            if [[ "$NLIST_SEARCH_BUFFER" != "" || "$NLIST_IS_UNIQ_MODE" -eq 1 ||
+                ${NLIST_NONSELECTABLE_ELEMENTS[(r)$current_idx]} != $current_idx ]]
+            then
+                reply=( $current_idx "SELECT" )
+            fi
+        else
+            search=0
+            _nlist_cursor_visibility 0
+        fi
+        ;;
+    ($'\C-L')
+        reply=( -1 "REDRAW" )
+        ;;
+
+    #
+    # Slightly limited navigation
+    #
+
+    (UP|$'\C-P')
+        [ "$current_idx" -gt 1 ] && current_idx=current_idx-1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (DOWN|$'\C-N')
+        [ "$current_idx" -lt "$last_element" ] && current_idx=current_idx+1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (PPAGE)
+        current_idx=current_idx-page_height
+        [ "$current_idx" -lt 1 ] && current_idx=1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (NPAGE)
+        current_idx=current_idx+page_height
+        [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
+        _nlist_compute_first_to_show_idx
+        ;;
+    ($'\C-U')
+        current_idx=current_idx-page_height/2
+        [ "$current_idx" -lt 1 ] && current_idx=1;
+        _nlist_compute_first_to_show_idx
+        ;;
+    ($'\C-D')
+        current_idx=current_idx+page_height/2
+        [ "$current_idx" -gt "$last_element" ] && current_idx=last_element;
+        _nlist_compute_first_to_show_idx
+        ;;
+    (HOME)
+        current_idx=1
+        _nlist_compute_first_to_show_idx
+        ;;
+    (END)
+        current_idx=last_element
+        _nlist_compute_first_to_show_idx
+        ;;
+    (LEFT)
+        hscroll=hscroll-7
+        [ "$hscroll" -lt 0 ] && hscroll=0
+        ;;
+    (RIGHT)
+        hscroll+=7
+        ;;
+    (F1)
+        # This event needs to be enabled
+        if [[ "${NLIST_ENABLED_EVENTS[(r)F1]}" = "F1" ]]; then
+            reply=( -1 "$key" )
+        fi
+        ;;
+    (F4|F5|F6|F7|F8|F9|F10|DC)
+        # ignore; F2, F3 are used below
+        ;;
+
+    #
+    # The input
+    #
+
+    ($'\b'|$'\C-?'|BACKSPACE)
+        buffer="${buffer%?}"
+        ;;
+    ($'\C-W')
+        [ "$buffer" = "${buffer% *}" ] && buffer="" || buffer="${buffer% *}"
+        ;;
+    ($'\C-K')
+        buffer=""
+        ;;
+    ($'\E')
+        buffer=""
+        search=0
+        _nlist_cursor_visibility 0
+        ;;
+    (F3)
+        if [ "$search" = "1" ]; then
+            search=0
+            _nlist_cursor_visibility 0
+        else
+            search=1
+            _nlist_cursor_visibility 1
+        fi
+        ;;
+    ($'\C-O')
+        uniq_mode=1-uniq_mode
+        ;;
+    ($'\C-F')
+        (( f_mode=(f_mode+1) % 3 ))
+        ;;
+    ($'\x1F'|F2|$'\C-X')
+        _nlist_update_from_keywords
+        ;;
+    ($'\C-T')
+        _nlist_iterate_theme 1
+        ;;
+    ($'\C-G')
+        _nlist_iterate_theme 0
+        ;;
+    ($'\C-E')
+        # This event needs to be enabled
+        if [[ "${NLIST_ENABLED_EVENTS[(r)EDIT]}" = "EDIT" ]]; then
+            reply=( -1 "EDIT" )
+        fi
+        ;;
+    ($'\C-A')
+        _nlist_rotate_buffer
+        ;;
+    (*)
+        if [[ $#key == 1 && $((#key)) -lt 31 ]]; then
+            # ignore all other control keys
+        else
+            buffer+="$key"
+        fi
+        ;;
+esac
+
+fi
+
+reply[3]="$current_idx"
+reply[4]="$from_what_idx_list_is_shown"
+reply[5]="$hscroll"
+reply[6]="$search"
+reply[7]="$buffer"
+reply[8]="$uniq_mode"
+reply[9]="$f_mode"
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-options b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-options
new file mode 100644 (file)
index 0000000..b1a9340
--- /dev/null
@@ -0,0 +1,84 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-options` to .zshrc
+#
+# This function allows to browse and toggle shell's options
+#
+# Uses n-list
+
+#emulate -L zsh
+
+zmodload zsh/curses
+
+local IFS="
+"
+
+unset NLIST_COLORING_PATTERN
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-options.conf ] && builtin source ~/.config/znt/n-options.conf
+
+# TODO restore options
+unsetopt localoptions
+
+integer kshoptionprint=0
+[[ -o kshoptionprint ]] && kshoptionprint=1
+setopt kshoptionprint
+
+local list
+local selected
+local option
+local state
+
+# 0 - don't remember, 1 - remember, 2 - init once, then remember
+NLIST_REMEMBER_STATE=2
+
+local NLIST_GREP_STRING="${1:=}"
+
+while (( 1 )); do
+    list=( `setopt` )
+    list=( "${(M)list[@]:#*${1:=}*}" )
+    list=( "${list[@]:#kshoptionprint*}" )
+
+    if [ "$#list" -eq 0 ]; then
+        echo "No matching options"
+        break
+    fi
+
+    local red=$'\x1b[00;31m' green=$'\x1b[00;32m' reset=$'\x1b[00;00m'
+    list=( "${list[@]/ off/${red} off$reset}" )
+    #list=( "${list[@]/ on/${green} on$reset}" )
+    list=( "${(i)list[@]}" )
+
+    n-list "${list[@]}"
+
+    if [ "$REPLY" -gt 0 ]; then
+        [[ -o ksharrays ]] && selected="${reply[$(( REPLY - 1 ))]}" || selected="${reply[$REPLY]}"
+        option="${selected%% *}"
+        state="${selected##* }"
+
+        if [[ -o globsubst ]]; then
+            unsetopt globsubst
+            state="${state%$reset}"
+            setopt globsubst
+        else
+            state="${state%$reset}"
+        fi
+
+        # Toggle the option
+        if [ "$state" = "on" ]; then
+            echo "Setting |$option| to off"
+            unsetopt "$option"
+        else
+            echo "Setting |$option| to on"
+            setopt "$option"
+        fi
+    else
+        break
+    fi
+done
+
+NLIST_REMEMBER_STATE=0
+
+[[ "$kshoptionprint" -eq 0 ]] && unsetopt kshoptionprint
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-panelize b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/n-panelize
new file mode 100644 (file)
index 0000000..e2b567f
--- /dev/null
@@ -0,0 +1,68 @@
+# Copy this file into /usr/share/zsh/site-functions/
+# and add 'autoload n-panelize` to .zshrc
+#
+# This function somewhat reminds the panelize feature from Midnight Commander
+# It allows browsing output of arbitrary command. Example usage:
+# v-panelize ls /usr/local/bin
+#
+# Uses n-list
+
+emulate -L zsh
+
+setopt extendedglob
+zmodload zsh/curses
+
+local IFS="
+"
+
+unset NLIST_COLORING_PATTERN
+
+[ -f ~/.config/znt/n-list.conf ] && builtin source ~/.config/znt/n-list.conf
+[ -f ~/.config/znt/n-panelize.conf ] && builtin source ~/.config/znt/n-panelize.conf
+
+local list
+local selected
+
+NLIST_REMEMBER_STATE=0
+
+if [ -t 0 ]; then
+    # Check if there is proper input
+    if [ "$#" -lt 1 ]; then
+        echo "Usage: n-panelize {command} [option|argument] ... or command | n-panelize"
+        return 1
+    fi
+
+    # This loop makes script faster on some Zsh's (e.g. 5.0.8)
+    repeat 1; do
+        list=( `"$@"` )
+    done
+
+    # TODO: $? doesn't reach user
+    [ "$?" -eq 127 ] && return $?
+else
+    # Check if can reattach to terminal
+    if [[ ! -c /dev/tty && ! -t 2 ]]; then
+        echo "No terminal available (no /dev/tty)"
+        return 1
+    fi
+
+    # This loop makes script faster on some Zsh's (e.g. 5.0.8)
+    repeat 1; do
+        list=( "${(@f)"$(<&0)"}" )
+    done
+
+    if [[ ! -c /dev/tty ]]; then
+        exec <&2
+    else
+        exec </dev/tty
+    fi
+fi
+
+n-list "${list[@]}"
+
+if [ "$REPLY" -gt 0 ]; then
+    selected="$reply[REPLY]"
+    print -zr "# $selected"
+fi
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-cd-widget b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-cd-widget
new file mode 100644 (file)
index 0000000..6d1be6b
--- /dev/null
@@ -0,0 +1,8 @@
+autoload znt-usetty-wrapper n-cd
+local NLIST_START_IN_SEARCH_MODE=0
+local NLIST_START_IN_UNIQ_MODE=0
+
+znt-usetty-wrapper n-cd "$@"
+
+unset NLIST_START_IN_SEARCH_MODE
+unset NLIST_START_IN_UNIQ_MODE
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-history-widget b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-history-widget
new file mode 100644 (file)
index 0000000..479c221
--- /dev/null
@@ -0,0 +1,22 @@
+autoload znt-usetty-wrapper n-history
+local NLIST_START_IN_SEARCH_MODE=1
+local NLIST_START_IN_UNIQ_MODE=1
+
+# Only if current $BUFFER doesn't come from history
+if [ "$HISTCMD" = "$HISTNO" ]; then
+    () {
+        setopt localoptions extendedglob
+        local -a match mbegin mend
+        local MATCH; integer MBEGIN MEND
+
+        [ -n "$BUFFER" ] && BUFFER="${BUFFER%% ##} "
+    }
+
+    local NLIST_SET_SEARCH_TO="$BUFFER"
+fi
+
+znt-usetty-wrapper n-history "$@"
+
+unset NLIST_START_IN_SEARCH_MODE
+unset NLIST_START_IN_UNIQ_MODE
+unset NLIST_SET_SEARCH_TO
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-kill-widget b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-kill-widget
new file mode 100644 (file)
index 0000000..1aff7bb
--- /dev/null
@@ -0,0 +1,8 @@
+autoload znt-usetty-wrapper n-kill
+local NLIST_START_IN_SEARCH_MODE=0
+local NLIST_START_IN_UNIQ_MODE=0
+
+znt-usetty-wrapper n-kill "$@"
+
+unset NLIST_START_IN_SEARCH_MODE
+unset NLIST_START_IN_UNIQ_MODE
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-usetty-wrapper b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/znt-usetty-wrapper
new file mode 100644 (file)
index 0000000..19c5ac8
--- /dev/null
@@ -0,0 +1,40 @@
+emulate -L zsh
+
+zmodload zsh/curses
+
+test_fd0() {
+    true <&0
+}
+
+local restore=0 FD
+
+# Reattach to terminal
+if [ ! -t 0 ]; then
+    # Check if can reattach to terminal in any way
+    if [[ ! -c /dev/tty && ! -t 2 ]]; then
+        echo "No terminal available (no /dev/tty and no terminal at stderr)"
+        return 1
+    fi
+
+    if test_fd0 2>/dev/null; then
+        exec {FD}<&0
+        restore=2
+    else
+        restore=1
+    fi
+
+    if [[ ! -c /dev/tty ]]; then
+        exec <&2
+    else
+        exec </dev/tty
+    fi
+fi
+
+# Run the command
+"$@"
+
+# Restore FD state
+(( restore == 1 )) && exec <&-
+(( restore == 2 )) && exec <&$FD && exec {FD}<&-
+
+# vim: set filetype=zsh:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/zsh-navigation-tools.plugin.zsh b/stow/oh-my-zsh/.oh-my-zsh/plugins/zsh-navigation-tools/zsh-navigation-tools.plugin.zsh
new file mode 100644 (file)
index 0000000..54c8198
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/env zsh
+
+#
+# No plugin manager is needed to use this file. All that is needed is adding:
+#   source {where-znt-is}/zsh-navigation-tools.plugin.zsh
+#
+# to ~/.zshrc.
+#
+
+# According to the standard:
+# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+
+export ZNT_REPO_DIR="${0:h}"
+export ZNT_CONFIG_DIR="$HOME/.config/znt"
+
+#
+# Update FPATH if:
+# 1. Not loading with a plugin manager
+# 2. Not having fpath already updated
+#
+
+if [[ ${zsh_loaded_plugins[-1]} != */zsh-navigation-tools && -z ${fpath[(r)${0:h}]} ]]
+then
+    fpath+=( "${0:h}" )
+fi
+
+#
+# Copy configs
+#
+
+if [[ ! -d "$HOME/.config" ]]; then
+    command mkdir "$HOME/.config"
+fi
+
+if [[ ! -d "$ZNT_CONFIG_DIR" ]]; then
+    command mkdir "$ZNT_CONFIG_DIR"
+fi
+
+# 9 files
+unset __ZNT_CONFIG_FILES
+typeset -ga __ZNT_CONFIG_FILES
+set +A __ZNT_CONFIG_FILES n-aliases.conf n-env.conf n-history.conf n-list.conf n-panelize.conf n-cd.conf n-functions.conf n-kill.conf n-options.conf
+
+# Check for random 2 files if they exist
+# This will shift 0 - 7 elements
+shift $(( RANDOM % 8 )) __ZNT_CONFIG_FILES
+if [[ ! -f "$ZNT_CONFIG_DIR/${__ZNT_CONFIG_FILES[1]}" || ! -f "$ZNT_CONFIG_DIR/${__ZNT_CONFIG_FILES[2]}" ]]; then
+    # Something changed - examine every file
+    set +A __ZNT_CONFIG_FILES n-aliases.conf n-env.conf n-history.conf n-list.conf n-panelize.conf n-cd.conf n-functions.conf n-kill.conf n-options.conf
+    unset __ZNT_CONFIG_FILE
+    typeset -g __ZNT_CONFIG_FILE
+    for __ZNT_CONFIG_FILE in "${__ZNT_CONFIG_FILES[@]}"; do
+        if [[ ! -f "$ZNT_CONFIG_DIR/$__ZNT_CONFIG_FILE" ]]; then
+            command cp "$ZNT_REPO_DIR/.config/znt/$__ZNT_CONFIG_FILE" "$ZNT_CONFIG_DIR"
+        fi
+    done
+    unset __ZNT_CONFIG_FILE
+fi
+
+unset __ZNT_CONFIG_FILES
+
+#
+# Load functions
+#
+
+autoload n-aliases n-cd n-env n-functions n-history n-kill n-list n-list-draw n-list-input n-options n-panelize n-help
+autoload znt-usetty-wrapper znt-history-widget znt-cd-widget znt-kill-widget
+alias naliases=n-aliases ncd=n-cd nenv=n-env nfunctions=n-functions nhistory=n-history
+alias nkill=n-kill noptions=n-options npanelize=n-panelize nhelp=n-help
+
+zle -N znt-history-widget
+bindkey '^R' znt-history-widget
+setopt AUTO_PUSHD HIST_IGNORE_DUPS PUSHD_IGNORE_DUPS
+zstyle ':completion::complete:n-kill::bits' matcher 'r:|=** l:|=*'
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/templates/zshrc.zsh-template b/stow/oh-my-zsh/.oh-my-zsh/templates/zshrc.zsh-template
new file mode 100644 (file)
index 0000000..7e1c799
--- /dev/null
@@ -0,0 +1,101 @@
+# If you come from bash you might have to change your $PATH.
+# export PATH=$HOME/bin:/usr/local/bin:$PATH
+
+# Path to your oh-my-zsh installation.
+export ZSH=$HOME/.oh-my-zsh
+
+# Set name of the theme to load --- if set to "random", it will
+# load a random theme each time oh-my-zsh is loaded, in which case,
+# to know which specific one was loaded, run: echo $RANDOM_THEME
+# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
+ZSH_THEME="robbyrussell"
+
+# Set list of themes to pick from when loading at random
+# Setting this variable when ZSH_THEME=random will cause zsh to load
+# a theme from this variable instead of looking in $ZSH/themes/
+# If set to an empty array, this variable will have no effect.
+# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
+
+# Uncomment the following line to use case-sensitive completion.
+# CASE_SENSITIVE="true"
+
+# Uncomment the following line to use hyphen-insensitive completion.
+# Case-sensitive completion must be off. _ and - will be interchangeable.
+# HYPHEN_INSENSITIVE="true"
+
+# Uncomment one of the following lines to change the auto-update behavior
+# zstyle ':omz:update' mode disabled  # disable automatic updates
+# zstyle ':omz:update' mode auto      # update automatically without asking
+# zstyle ':omz:update' mode reminder  # just remind me to update when it's time
+
+# Uncomment the following line to change how often to auto-update (in days).
+# zstyle ':omz:update' frequency 13
+
+# Uncomment the following line if pasting URLs and other text is messed up.
+# DISABLE_MAGIC_FUNCTIONS="true"
+
+# Uncomment the following line to disable colors in ls.
+# DISABLE_LS_COLORS="true"
+
+# Uncomment the following line to disable auto-setting terminal title.
+# DISABLE_AUTO_TITLE="true"
+
+# Uncomment the following line to enable command auto-correction.
+# ENABLE_CORRECTION="true"
+
+# Uncomment the following line to display red dots whilst waiting for completion.
+# You can also set it to another string to have that shown instead of the default red dots.
+# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
+# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
+# COMPLETION_WAITING_DOTS="true"
+
+# Uncomment the following line if you want to disable marking untracked files
+# under VCS as dirty. This makes repository status check for large repositories
+# much, much faster.
+# DISABLE_UNTRACKED_FILES_DIRTY="true"
+
+# Uncomment the following line if you want to change the command execution time
+# stamp shown in the history command output.
+# You can set one of the optional three formats:
+# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
+# or set a custom format using the strftime function format specifications,
+# see 'man strftime' for details.
+# HIST_STAMPS="mm/dd/yyyy"
+
+# Would you like to use another custom folder than $ZSH/custom?
+# ZSH_CUSTOM=/path/to/new-custom-folder
+
+# Which plugins would you like to load?
+# Standard plugins can be found in $ZSH/plugins/
+# Custom plugins may be added to $ZSH_CUSTOM/plugins/
+# Example format: plugins=(rails git textmate ruby lighthouse)
+# Add wisely, as too many plugins slow down shell startup.
+plugins=(git)
+
+source $ZSH/oh-my-zsh.sh
+
+# User configuration
+
+# export MANPATH="/usr/local/man:$MANPATH"
+
+# You may need to manually set your language environment
+# export LANG=en_US.UTF-8
+
+# Preferred editor for local and remote sessions
+# if [[ -n $SSH_CONNECTION ]]; then
+#   export EDITOR='vim'
+# else
+#   export EDITOR='mvim'
+# fi
+
+# Compilation flags
+# export ARCHFLAGS="-arch x86_64"
+
+# Set personal aliases, overriding those provided by oh-my-zsh libs,
+# plugins, and themes. Aliases can be placed here, though oh-my-zsh
+# users are encouraged to define aliases within the ZSH_CUSTOM folder.
+# For a full list of active aliases, run `alias`.
+#
+# Example aliases
+# alias zshconfig="mate ~/.zshrc"
+# alias ohmyzsh="mate ~/.oh-my-zsh"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/3den.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/3den.zsh-theme
new file mode 100644 (file)
index 0000000..ae3a886
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT=$'%{$fg[white]%}$(ruby_prompt_info) %{$fg_bold[cyan]%}%~%{$reset_color%}$(git_prompt_info) %{$fg[cyan]%}%D{[%I:%M:%S]}\
+%{$fg_bold[green]%}%n$%{$reset_color%} '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[white]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="*"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/Soliah.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/Soliah.zsh-theme
new file mode 100644 (file)
index 0000000..c3dd6af
--- /dev/null
@@ -0,0 +1,85 @@
+PROMPT='%{$fg[blue]%}%n%{$reset_color%} on %{$fg[red]%}%M%{$reset_color%} in %{$fg[blue]%}%~%b%{$reset_color%}$(git_time_since_commit)$(check_git_prompt_info)
+$ '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[white]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%})"
+
+# Text to display if the branch is dirty
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}*%{$reset_color%}" 
+
+# Text to display if the branch is clean
+ZSH_THEME_GIT_PROMPT_CLEAN="" 
+
+# Colors vary depending on time lapsed.
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}"
+ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[cyan]%}"
+
+
+# Git sometimes goes into a detached head state. git_prompt_info doesn't
+# return anything in this case. So wrap it in another function and check
+# for an empty string.
+function check_git_prompt_info() {
+    if git rev-parse --git-dir > /dev/null 2>&1; then
+        if [[ -z $(git_prompt_info) ]]; then
+            echo "%{$fg[magenta]%}detached-head%{$reset_color%})"
+        else
+            echo "$(git_prompt_info)"
+        fi
+    fi
+}
+
+# Determine if we are using a gemset.
+function rvm_gemset() {
+    if hash rvm 2>/dev/null; then
+        GEMSET=`rvm gemset list | grep '=>' | cut -b4-`
+        if [[ -n $GEMSET ]]; then
+            echo "%{$fg[yellow]%}$GEMSET%{$reset_color%}|"
+        fi 
+    fi
+}
+
+# Determine the time since last commit. If branch is clean,
+# use a neutral color, otherwise colors will vary according to time.
+function git_time_since_commit() {
+    if git rev-parse --git-dir > /dev/null 2>&1; then
+        # Only proceed if there is actually a commit.
+        if last_commit=`git -c log.showSignature=false log --pretty=format:'%at' -1 2> /dev/null`; then
+            now=`date +%s`
+            seconds_since_last_commit=$((now-last_commit))
+
+            # Totals
+            MINUTES=$((seconds_since_last_commit / 60))
+            HOURS=$((seconds_since_last_commit/3600))
+           
+            # Sub-hours and sub-minutes
+            DAYS=$((seconds_since_last_commit / 86400))
+            SUB_HOURS=$((HOURS % 24))
+            SUB_MINUTES=$((MINUTES % 60))
+            
+            if [[ -n $(git status -s 2> /dev/null) ]]; then
+                if [ "$MINUTES" -gt 30 ]; then
+                    COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG"
+                elif [ "$MINUTES" -gt 10 ]; then
+                    COLOR="$ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM"
+                else
+                    COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT"
+                fi
+            else
+                COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+            fi
+
+            if [ "$HOURS" -gt 24 ]; then
+                echo "($(rvm_gemset)$COLOR${DAYS}d${SUB_HOURS}h${SUB_MINUTES}m%{$reset_color%}|"
+            elif [ "$MINUTES" -gt 60 ]; then
+                echo "($(rvm_gemset)$COLOR${HOURS}h${SUB_MINUTES}m%{$reset_color%}|"
+            else
+                echo "($(rvm_gemset)$COLOR${MINUTES}m%{$reset_color%}|"
+            fi
+        else
+            COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+            echo "($(rvm_gemset)$COLOR~|"
+        fi
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/adben.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/adben.zsh-theme
new file mode 100644 (file)
index 0000000..c2fdbed
--- /dev/null
@@ -0,0 +1,118 @@
+#!/usr/bin/env zsh
+# #
+# # #README
+# #
+# # This theme provides two customizable header functionalities:
+# # a) displaying a pseudo-random message from a database of quotations
+# # (https://en.wikipedia.org/wiki/Fortune_%28Unix%29)
+# # b) displaying randomly command line tips from The command line fu
+# # (https://www.commandlinefu.com) community: in order to make use of this functionality
+# # you will need Internet connection.
+# # This theme provides as well information for the current user's context, like;
+# # branch and status for the current version control system (git and svn currently
+# # supported) and time, presented to the user in a non invasive volatile way.
+# #
+# # #REQUIREMENTS
+# # This theme requires wget::
+# # -Homebrew-osx- brew install wget
+# # -Debian/Ubuntu- apt-get install wget
+# # and fortune ::
+# # -Homebrew-osx- brew install fortune
+# # -Debian/Ubuntu- apt-get install fortune
+# #
+# # optionally:
+# # -Oh-myzsh vcs plug-ins git and svn.
+# # -Solarized theme (https://github.com/altercation/solarized/)
+# # -OS X: iTerm 2 (https://iterm2.com/)
+# # -font Source code pro (https://github.com/adobe/source-code-pro)
+# #
+# # This theme's look and feel is based on the Aaron Toponce's zsh theme, more info:
+# # https://pthree.org/2008/11/23/727/
+# # enjoy!
+
+########## COLOR ###########
+for COLOR in CYAN WHITE YELLOW MAGENTA BLACK BLUE RED DEFAULT GREEN GREY; do
+  typeset -g PR_$COLOR="%b%{$fg[${(L)COLOR}]%}"
+  typeset -g PR_BRIGHT_$COLOR="%B%{$fg[${(L)COLOR}]%}"
+done
+PR_RESET="%{$reset_color%}"
+
+RED_START="${PR_GREY}<${PR_RED}<${PR_BRIGHT_RED}<${PR_RESET} "
+RED_END="${PR_BRIGHT_RED}>${PR_RED}>${PR_GREY}>${PR_RESET} "
+GREEN_START="${PR_GREY}>${PR_GREEN}>${PR_BRIGHT_GREEN}>${PR_RESET}"
+GREEN_END="${PR_BRIGHT_GREEN}>${PR_GREEN}>${PR_GREY}>${PR_RESET} "
+
+########## VCS ###########
+VCS_DIRTY_COLOR="${PR_YELLOW}"
+VCS_CLEAN_COLOR="${PR_GREEN}"
+VCS_SUFFIX_COLOR="${PR_RED}› ${PR_RESET}"
+
+########## SVN ###########
+ZSH_THEME_SVN_PROMPT_PREFIX="${PR_RED}‹svn:"
+ZSH_THEME_SVN_PROMPT_SUFFIX="${VCS_SUFFIX_COLOR}"
+ZSH_THEME_SVN_PROMPT_DIRTY="${VCS_DIRTY_COLOR} ✘"
+ZSH_THEME_SVN_PROMPT_CLEAN="${VCS_CLEAN_COLOR} ✔"
+
+########## GIT ###########
+ZSH_THEME_GIT_PROMPT_PREFIX="${PR_RED}‹git:"
+ZSH_THEME_GIT_PROMPT_SUFFIX="${VCS_SUFFIX_COLOR}"
+ZSH_THEME_GIT_PROMPT_DIRTY="${VCS_DIRTY_COLOR} ✘"
+ZSH_THEME_GIT_PROMPT_CLEAN="${VCS_CLEAN_COLOR} ✔"
+ZSH_THEME_GIT_PROMPT_ADDED="${PR_YELLOW} ✚"
+ZSH_THEME_GIT_PROMPT_MODIFIED="${PR_YELLOW} ✹"
+ZSH_THEME_GIT_PROMPT_DELETED="${PR_YELLOW} ✖"
+ZSH_THEME_GIT_PROMPT_RENAMED="${PR_YELLOW} ➜"
+ZSH_THEME_GIT_PROMPT_UNMERGED="${PR_YELLOW} ═"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="${PR_YELLOW} ✭"
+
+# Get a fortune quote
+ps1_fortune() {
+  if (( ${+commands[fortune]} )); then
+    fortune
+  fi
+}
+
+# Obtain a command tip
+ps1_command_tip() {
+  {
+    if (( ${+commands[wget]} )); then
+      command wget -qO- https://www.commandlinefu.com/commands/random/plaintext
+    elif (( ${+commands[curl]} )); then
+      command curl -fsL https://www.commandlinefu.com/commands/random/plaintext
+    fi 
+  } | sed '1d;/^$/d'
+}
+
+# Show prompt header (fortune / command tip)
+prompt_header() {
+  local header=$(
+    case "${ENABLE_COMMAND_TIP:-}" in
+    true) ps1_command_tip ;;
+    *) ps1_fortune ;;
+    esac
+  )
+
+  # Make sure to quote % so that they're not expanded by the prompt
+  echo -n "${header:gs/%/%%}"
+}
+
+# Context: user@directory or just directory
+prompt_context() {
+  if [[ "$USERNAME" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
+    echo -n "${PR_RESET}${PR_RED}%n@%m"
+  fi
+}
+
+########## SETUP ###########
+
+# Required for the prompt
+setopt prompt_subst
+
+# Prompt: header, context (user@host), directory
+PROMPT="${RED_START}${PR_YELLOW}\$(prompt_header)${PR_RESET}
+${RED_START}\$(prompt_context)${PR_BRIGHT_YELLOW}%~${PR_RESET}
+${GREEN_START} "
+# Right prompt: vcs status + time
+RPROMPT="\$(git_prompt_info)\$(svn_prompt_info)${PR_YELLOW}%D{%R.%S %a %b %d %Y} ${GREEN_END}"
+# Matching continuation prompt
+PROMPT2="${GREEN_START} %_ ${GREEN_START} "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/af-magic.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/af-magic.zsh-theme
new file mode 100644 (file)
index 0000000..2ef9b02
--- /dev/null
@@ -0,0 +1,46 @@
+# af-magic.zsh-theme
+#
+# Author: Andy Fleming
+# URL: http://andyfleming.com/
+
+# dashed separator size
+function afmagic_dashes {
+  # check either virtualenv or condaenv variables
+  local python_env="${VIRTUAL_ENV:-$CONDA_DEFAULT_ENV}"
+
+  # if there is a python virtual environment and it is displayed in
+  # the prompt, account for it when returning the number of dashes
+  if [[ -n "$python_env" && "$PS1" = \(* ]]; then
+    echo $(( COLUMNS - ${#python_env} - 3 ))
+  else
+    echo $COLUMNS
+  fi
+}
+
+# primary prompt: dashed separator, directory and vcs info
+PS1="${FG[237]}\${(l.\$(afmagic_dashes)..-.)}%{$reset_color%}
+${FG[032]}%~\$(git_prompt_info)\$(hg_prompt_info) ${FG[105]}%(!.#.»)%{$reset_color%} "
+PS2="%{$fg[red]%}\ %{$reset_color%}"
+
+# right prompt: return code, virtualenv and context (user@host)
+RPS1="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+if (( $+functions[virtualenv_prompt_info] )); then
+  RPS1+='$(virtualenv_prompt_info)'
+fi
+RPS1+=" ${FG[237]}%n@%m%{$reset_color%}"
+
+# git settings
+ZSH_THEME_GIT_PROMPT_PREFIX=" ${FG[075]}(${FG[078]}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="${FG[214]}*%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="${FG[075]})%{$reset_color%}"
+
+# hg settings
+ZSH_THEME_HG_PROMPT_PREFIX=" ${FG[075]}(${FG[078]}"
+ZSH_THEME_HG_PROMPT_CLEAN=""
+ZSH_THEME_HG_PROMPT_DIRTY="${FG[214]}*%{$reset_color%}"
+ZSH_THEME_HG_PROMPT_SUFFIX="${FG[075]})%{$reset_color%}"
+
+# virtualenv settings
+ZSH_THEME_VIRTUALENV_PREFIX=" ${FG[075]}["
+ZSH_THEME_VIRTUALENV_SUFFIX="]%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/afowler.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/afowler.zsh-theme
new file mode 100644 (file)
index 0000000..f6d3ef8
--- /dev/null
@@ -0,0 +1,10 @@
+PROMPT='%m %B%F{blue}:: %b%F{green}%3~ $(hg_prompt_info)$(git_prompt_info)%B%(!.%F{red}.%F{blue})»%f%b '
+RPS1='%(?..%F{red}%? ↵%f)'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
+
+ZSH_THEME_HG_PROMPT_PREFIX="%{$fg[magenta]%}hg:‹%{$fg[yellow]%}"
+ZSH_THEME_HG_PROMPT_SUFFIX="%{$fg[magenta]%}› %{$reset_color%}"
+ZSH_THEME_HG_PROMPT_DIRTY=" %{$fg[red]%}✗"
+ZSH_THEME_HG_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/agnoster.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/agnoster.zsh-theme
new file mode 100644 (file)
index 0000000..5f4efe8
--- /dev/null
@@ -0,0 +1,258 @@
+# vim:ft=zsh ts=2 sw=2 sts=2
+#
+# agnoster's Theme - https://gist.github.com/3712874
+# A Powerline-inspired theme for ZSH
+#
+# # README
+#
+# In order for this theme to render correctly, you will need a
+# [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts).
+# Make sure you have a recent version: the code points that Powerline
+# uses changed in 2012, and older versions will display incorrectly,
+# in confusing ways.
+#
+# In addition, I recommend the
+# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
+# using it on Mac OS X, [iTerm 2](https://iterm2.com/) over Terminal.app -
+# it has significantly better color fidelity.
+#
+# If using with "light" variant of the Solarized color schema, set
+# SOLARIZED_THEME variable to "light". If you don't specify, we'll assume
+# you're using the "dark" variant.
+#
+# # Goals
+#
+# The aim of this theme is to only show you *relevant* information. Like most
+# prompts, it will only show git information when in a git working directory.
+# However, it goes a step further: everything from the current user and
+# hostname to whether the last call exited with an error to whether background
+# jobs are running in this shell will all be displayed automatically when
+# appropriate.
+
+### Segment drawing
+# A few utility functions to make it easy and re-usable to draw segmented prompts
+
+CURRENT_BG='NONE'
+
+case ${SOLARIZED_THEME:-dark} in
+    light) CURRENT_FG='white';;
+    *)     CURRENT_FG='black';;
+esac
+
+# Special Powerline characters
+
+() {
+  local LC_ALL="" LC_CTYPE="en_US.UTF-8"
+  # NOTE: This segment separator character is correct.  In 2012, Powerline changed
+  # the code points they use for their special characters. This is the new code point.
+  # If this is not working for you, you probably have an old version of the
+  # Powerline-patched fonts installed. Download and install the new version.
+  # Do not submit PRs to change this unless you have reviewed the Powerline code point
+  # history and have new information.
+  # This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of
+  # what font the user is viewing this source code in. Do not replace the
+  # escape sequence with a single literal character.
+  # Do not change this! Do not make it '\u2b80'; that is the old, wrong code point.
+  SEGMENT_SEPARATOR=$'\ue0b0'
+}
+
+# Begin a segment
+# Takes two arguments, background and foreground. Both can be omitted,
+# rendering default background/foreground.
+prompt_segment() {
+  local bg fg
+  [[ -n $1 ]] && bg="%K{$1}" || bg="%k"
+  [[ -n $2 ]] && fg="%F{$2}" || fg="%f"
+  if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
+    echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
+  else
+    echo -n "%{$bg%}%{$fg%} "
+  fi
+  CURRENT_BG=$1
+  [[ -n $3 ]] && echo -n $3
+}
+
+# End the prompt, closing any open segments
+prompt_end() {
+  if [[ -n $CURRENT_BG ]]; then
+    echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR"
+  else
+    echo -n "%{%k%}"
+  fi
+  echo -n "%{%f%}"
+  CURRENT_BG=''
+}
+
+### Prompt components
+# Each component will draw itself, and hide itself if no information needs to be shown
+
+# Context: user@hostname (who am I and where am I)
+prompt_context() {
+  if [[ "$USERNAME" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
+    prompt_segment black default "%(!.%{%F{yellow}%}.)%n@%m"
+  fi
+}
+
+# Git: branch/detached head, dirty status
+prompt_git() {
+  (( $+commands[git] )) || return
+  if [[ "$(git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]]; then
+    return
+  fi
+  local PL_BRANCH_CHAR
+  () {
+    local LC_ALL="" LC_CTYPE="en_US.UTF-8"
+    PL_BRANCH_CHAR=$'\ue0a0'         # 
+  }
+  local ref dirty mode repo_path
+
+   if [[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]]; then
+    repo_path=$(git rev-parse --git-dir 2>/dev/null)
+    dirty=$(parse_git_dirty)
+    ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git rev-parse --short HEAD 2> /dev/null)"
+    if [[ -n $dirty ]]; then
+      prompt_segment yellow black
+    else
+      prompt_segment green $CURRENT_FG
+    fi
+
+    if [[ -e "${repo_path}/BISECT_LOG" ]]; then
+      mode=" <B>"
+    elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then
+      mode=" >M<"
+    elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then
+      mode=" >R>"
+    fi
+
+    setopt promptsubst
+    autoload -Uz vcs_info
+
+    zstyle ':vcs_info:*' enable git
+    zstyle ':vcs_info:*' get-revision true
+    zstyle ':vcs_info:*' check-for-changes true
+    zstyle ':vcs_info:*' stagedstr '✚'
+    zstyle ':vcs_info:*' unstagedstr '±'
+    zstyle ':vcs_info:*' formats ' %u%c'
+    zstyle ':vcs_info:*' actionformats ' %u%c'
+    vcs_info
+    echo -n "${${ref:gs/%/%%}/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}"
+  fi
+}
+
+prompt_bzr() {
+  (( $+commands[bzr] )) || return
+
+  # Test if bzr repository in directory hierarchy
+  local dir="$PWD"
+  while [[ ! -d "$dir/.bzr" ]]; do
+    [[ "$dir" = "/" ]] && return
+    dir="${dir:h}"
+  done
+
+  local bzr_status status_mod status_all revision
+  if bzr_status=$(bzr status 2>&1); then
+    status_mod=$(echo -n "$bzr_status" | head -n1 | grep "modified" | wc -m)
+    status_all=$(echo -n "$bzr_status" | head -n1 | wc -m)
+    revision=${$(bzr log -r-1 --log-format line | cut -d: -f1):gs/%/%%}
+    if [[ $status_mod -gt 0 ]] ; then
+      prompt_segment yellow black "bzr@$revision ✚"
+    else
+      if [[ $status_all -gt 0 ]] ; then
+        prompt_segment yellow black "bzr@$revision"
+      else
+        prompt_segment green black "bzr@$revision"
+      fi
+    fi
+  fi
+}
+
+prompt_hg() {
+  (( $+commands[hg] )) || return
+  local rev st branch
+  if $(hg id >/dev/null 2>&1); then
+    if $(hg prompt >/dev/null 2>&1); then
+      if [[ $(hg prompt "{status|unknown}") = "?" ]]; then
+        # if files are not added
+        prompt_segment red white
+        st='±'
+      elif [[ -n $(hg prompt "{status|modified}") ]]; then
+        # if any modification
+        prompt_segment yellow black
+        st='±'
+      else
+        # if working copy is clean
+        prompt_segment green $CURRENT_FG
+      fi
+      echo -n ${$(hg prompt "☿ {rev}@{branch}"):gs/%/%%} $st
+    else
+      st=""
+      rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
+      branch=$(hg id -b 2>/dev/null)
+      if `hg st | grep -q "^\?"`; then
+        prompt_segment red black
+        st='±'
+      elif `hg st | grep -q "^[MA]"`; then
+        prompt_segment yellow black
+        st='±'
+      else
+        prompt_segment green $CURRENT_FG
+      fi
+      echo -n "☿ ${rev:gs/%/%%}@${branch:gs/%/%%}" $st
+    fi
+  fi
+}
+
+# Dir: current working directory
+prompt_dir() {
+  prompt_segment blue $CURRENT_FG '%~'
+}
+
+# Virtualenv: current working virtualenv
+prompt_virtualenv() {
+  if [[ -n "$VIRTUAL_ENV" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
+    prompt_segment blue black "(${VIRTUAL_ENV:t:gs/%/%%})"
+  fi
+}
+
+# Status:
+# - was there an error
+# - am I root
+# - are there background jobs?
+prompt_status() {
+  local -a symbols
+
+  [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘"
+  [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡"
+  [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"
+
+  [[ -n "$symbols" ]] && prompt_segment black default "$symbols"
+}
+
+#AWS Profile:
+# - display current AWS_PROFILE name
+# - displays yellow on red if profile name contains 'production' or
+#   ends in '-prod'
+# - displays black on green otherwise
+prompt_aws() {
+  [[ -z "$AWS_PROFILE" || "$SHOW_AWS_PROMPT" = false ]] && return
+  case "$AWS_PROFILE" in
+    *-prod|*production*) prompt_segment red yellow  "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
+    *) prompt_segment green black "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
+  esac
+}
+
+## Main prompt
+build_prompt() {
+  RETVAL=$?
+  prompt_status
+  prompt_virtualenv
+  prompt_aws
+  prompt_context
+  prompt_dir
+  prompt_git
+  prompt_bzr
+  prompt_hg
+  prompt_end
+}
+
+PROMPT='%{%f%b%k%}$(build_prompt) '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/alanpeabody.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/alanpeabody.zsh-theme
new file mode 100644 (file)
index 0000000..1de90e5
--- /dev/null
@@ -0,0 +1,24 @@
+
+local user='%{$fg[magenta]%}%n@%{$fg[magenta]%}%m%{$reset_color%}'
+local pwd='%{$fg[blue]%}%~%{$reset_color%}'
+local return_code='%(?..%{$fg[red]%}%? ↵%{$reset_color%})'
+local git_branch='$(git_prompt_status)%{$reset_color%}$(git_prompt_info)%{$reset_color%}'
+
+ZSH_THEME_RVM_PROMPT_OPTIONS="i v g"
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%} ✚"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[blue]%} ✹"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✖"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[magenta]%} ➜"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[yellow]%} ═"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ✭"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[green]%}‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="›%{$reset_color%}"
+
+PROMPT="${user} ${pwd}$ "
+RPROMPT="${return_code} ${git_branch} \$(ruby_prompt_info)"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/amuse.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/amuse.zsh-theme
new file mode 100644 (file)
index 0000000..3f7ec0b
--- /dev/null
@@ -0,0 +1,18 @@
+# vim:ft=zsh ts=2 sw=2 sts=2
+
+# Must use Powerline font, for \uE0A0 to render.
+ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[magenta]%}\uE0A0 "
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}!"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[green]%}?"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg_bold[red]%}‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="›%{$reset_color%}"
+
+PROMPT='
+%{$fg_bold[green]%}%~%{$reset_color%}$(git_prompt_info) ⌚ %{$fg_bold[red]%}%*%{$reset_color%}
+$ '
+
+RPROMPT='$(ruby_prompt_info)'
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/apple.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/apple.zsh-theme
new file mode 100644 (file)
index 0000000..0c18325
--- /dev/null
@@ -0,0 +1,24 @@
+function toon {
+  echo -n ""
+}
+
+autoload -Uz vcs_info
+zstyle ':vcs_info:*' check-for-changes true
+zstyle ':vcs_info:*' unstagedstr '%F{red}*'   # display this when there are unstaged changes
+zstyle ':vcs_info:*' stagedstr '%F{yellow}+'  # display this when there are staged changes
+zstyle ':vcs_info:*' actionformats '%F{5}[%F{2}%b%F{3}|%F{1}%a%c%u%F{5}]%f '
+zstyle ':vcs_info:*' formats '%F{5}[%F{2}%b%c%u%F{5}]%f '
+zstyle ':vcs_info:svn:*' branchformat '%b'
+zstyle ':vcs_info:svn:*' actionformats '%F{5}[%F{2}%b%F{1}:%F{3}%i%F{3}|%F{1}%a%c%u%F{5}]%f '
+zstyle ':vcs_info:svn:*' formats '%F{5}[%F{2}%b%F{1}:%F{3}%i%c%u%F{5}]%f '
+zstyle ':vcs_info:*' enable git cvs svn
+
+theme_precmd () {
+  vcs_info
+}
+
+setopt prompt_subst
+PROMPT='%{$fg[magenta]%}$(toon)%{$reset_color%} %~/ %{$reset_color%}${vcs_info_msg_0_}%{$reset_color%}'
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd theme_precmd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/arrow.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/arrow.zsh-theme
new file mode 100644 (file)
index 0000000..76c031f
--- /dev/null
@@ -0,0 +1,14 @@
+if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="yellow"; fi
+
+PROMPT='%{$fg[$NCOLOR]%}%c ➤ %{$reset_color%}'
+RPROMPT='%{$fg[$NCOLOR]%} $(git_prompt_info)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:"
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY="*"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+# See https://geoff.greer.fm/lscolors/
+export LSCOLORS="exfxcxdxbxbxbxbxbxbxbx"
+export LS_COLORS="di=34;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=31;40:cd=31;40:su=31;40:sg=31;40:tw=31;40:ow=31;40:"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/aussiegeek.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/aussiegeek.zsh-theme
new file mode 100644 (file)
index 0000000..2ded5c1
--- /dev/null
@@ -0,0 +1,8 @@
+
+PROMPT='$fg_bold[blue][ $fg[red]%t $fg_bold[blue]] $fg_bold[blue] [ $fg[red]%n@%m:%~$(git_prompt_info)$fg[yellow]$(ruby_prompt_info)$fg_bold[blue] ]$reset_color
+ $ '
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="$fg_bold[green]("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"
+ZSH_THEME_GIT_PROMPT_CLEAN="✔"
+ZSH_THEME_GIT_PROMPT_DIRTY="✗"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/avit.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/avit.zsh-theme
new file mode 100644 (file)
index 0000000..f90ba33
--- /dev/null
@@ -0,0 +1,85 @@
+# AVIT ZSH Theme
+
+# settings
+typeset +H _current_dir="%{$fg_bold[blue]%}%3~%{$reset_color%} "
+typeset +H _return_status="%{$fg_bold[red]%}%(?..⍉)%{$reset_color%}"
+typeset +H _hist_no="%{$fg[grey]%}%h%{$reset_color%}"
+
+PROMPT='
+$(_user_host)${_current_dir} $(git_prompt_info) $(ruby_prompt_info)
+%{%(!.${fg[red]}.${fg[white]})%}▶%{$reset_color%} '
+
+PROMPT2='%{%(!.${fg[red]}.${fg[white]})%}◀%{$reset_color%} '
+
+RPROMPT='$(vi_mode_prompt_info)%{$(echotc UP 1)%}$(_git_time_since_commit) $(git_prompt_status) ${_return_status}%{$(echotc DO 1)%}'
+
+function _user_host() {
+  local me
+  if [[ -n $SSH_CONNECTION ]]; then
+    me="%n@%m"
+  elif [[ $LOGNAME != $USERNAME ]]; then
+    me="%n"
+  fi
+  if [[ -n $me ]]; then
+    echo "%{$fg[cyan]%}$me%{$reset_color%}:"
+  fi
+}
+
+# Determine the time since last commit. If branch is clean,
+# use a neutral color, otherwise colors will vary according to time.
+function _git_time_since_commit() {
+  local last_commit now seconds_since_last_commit
+  local minutes hours days years commit_age
+  # Only proceed if there is actually a commit.
+  if last_commit=$(command git -c log.showSignature=false log --format='%at' -1 2>/dev/null); then
+    now=$(date +%s)
+    seconds_since_last_commit=$((now-last_commit))
+
+    # Totals
+    minutes=$((seconds_since_last_commit / 60))
+    hours=$((minutes / 60))
+    days=$((hours / 24))
+    years=$((days / 365))
+
+    if [[ $years -gt 0 ]]; then
+      commit_age="${years}y$((days % 365 ))d"
+    elif [[ $days -gt 0 ]]; then
+      commit_age="${days}d$((hours % 24))h"
+    elif [[ $hours -gt 0 ]]; then
+      commit_age+="${hours}h$(( minutes % 60 ))m"
+    else
+      commit_age="${minutes}m"
+    fi
+
+    echo "${ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL}${commit_age}%{$reset_color%}"
+  fi
+}
+
+MODE_INDICATOR="%{$fg_bold[yellow]%}❮%{$reset_color%}%{$fg[yellow]%}❮❮%{$reset_color%}"
+
+# Git prompt settings
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%}✚ "
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%}⚑ "
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%}✖ "
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%}▴ "
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[cyan]%}§ "
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[white]%}◒ "
+
+# Ruby prompt settings
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[grey]%}"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$reset_color%}"
+
+# Colors vary depending on time lapsed.
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}"
+ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[white]%}"
+
+# LS colors, made with https://geoff.greer.fm/lscolors/
+export LSCOLORS="exfxcxdxbxegedabagacad"
+export LS_COLORS='di=34;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;43:'
+export GREP_COLOR='1;33'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/awesomepanda.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/awesomepanda.zsh-theme
new file mode 100644 (file)
index 0000000..85036e4
--- /dev/null
@@ -0,0 +1,16 @@
+# the svn plugin has to be activated for this to work.
+local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ %s)"
+PROMPT='${ret_status}%{$fg_bold[green]%} %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}$(svn_prompt_info)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%})%{$fg[yellow]%} ✗ %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%}) "
+
+ZSH_PROMPT_BASE_COLOR="%{$fg_bold[blue]%}"
+ZSH_THEME_REPO_NAME_COLOR="%{$fg_bold[red]%}"
+
+ZSH_THEME_SVN_PROMPT_PREFIX="svn:("
+ZSH_THEME_SVN_PROMPT_SUFFIX=")"
+ZSH_THEME_SVN_PROMPT_DIRTY="%{$fg[red]%} ✘ %{$reset_color%}"
+ZSH_THEME_SVN_PROMPT_CLEAN=" "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/bira.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/bira.zsh-theme
new file mode 100644 (file)
index 0000000..42a70a0
--- /dev/null
@@ -0,0 +1,32 @@
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+local user_host="%B%(!.%{$fg[red]%}.%{$fg[green]%})%n@%m%{$reset_color%} "
+local user_symbol='%(!.#.$)'
+local current_dir="%B%{$fg[blue]%}%~ %{$reset_color%}"
+
+local vcs_branch='$(git_prompt_info)$(hg_prompt_info)'
+local rvm_ruby='$(ruby_prompt_info)'
+local venv_prompt='$(virtualenv_prompt_info)'
+
+ZSH_THEME_RVM_PROMPT_OPTIONS="i v g"
+
+PROMPT="╭─${user_host}${current_dir}${rvm_ruby}${vcs_branch}${venv_prompt}
+╰─%B${user_symbol}%b "
+RPROMPT="%B${return_code}%b"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}●%{$fg[yellow]%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[yellow]%}"
+
+ZSH_THEME_HG_PROMPT_PREFIX="$ZSH_THEME_GIT_PROMPT_PREFIX"
+ZSH_THEME_HG_PROMPT_SUFFIX="$ZSH_THEME_GIT_PROMPT_SUFFIX"
+ZSH_THEME_HG_PROMPT_DIRTY="$ZSH_THEME_GIT_PROMPT_DIRTY"
+ZSH_THEME_HG_PROMPT_CLEAN="$ZSH_THEME_GIT_PROMPT_CLEAN"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="› %{$reset_color%}"
+
+ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX="%{$fg[green]%}‹"
+ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX="› %{$reset_color%}"
+ZSH_THEME_VIRTUALENV_PREFIX="$ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX"
+ZSH_THEME_VIRTUALENV_SUFFIX="$ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/blinks.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/blinks.zsh-theme
new file mode 100644 (file)
index 0000000..ddb32f7
--- /dev/null
@@ -0,0 +1,30 @@
+# https://github.com/blinks zsh theme
+
+function _prompt_char() {
+  if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
+    echo "%{%F{blue}%}±%{%f%k%b%}"
+  else
+    echo ' '
+  fi
+}
+
+# This theme works with both the "dark" and "light" variants of the
+# Solarized color schema.  Set the SOLARIZED_THEME variable to one of
+# these two values to choose.  If you don't specify, we'll assume you're
+# using the "dark" variant.
+
+case ${SOLARIZED_THEME:-dark} in
+    light) bkg=white;;
+    *)     bkg=black;;
+esac
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" [%{%B%F{blue}%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{%f%k%b%K{${bkg}}%B%F{green}%}]"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{%F{red}%}*%{%f%k%b%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+PROMPT='%{%f%k%b%}
+%{%K{${bkg}}%B%F{green}%}%n%{%B%F{blue}%}@%{%B%F{cyan}%}%m%{%B%F{green}%} %{%b%F{yellow}%K{${bkg}}%}%~%{%B%F{green}%}$(git_prompt_info)%E%{%f%k%b%}
+%{%K{${bkg}}%}$(_prompt_char)%{%K{${bkg}}%} %#%{%f%k%b%} '
+
+RPROMPT='!%{%B%F{cyan}%}%!%{%f%k%b%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/bureau.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/bureau.zsh-theme
new file mode 100644 (file)
index 0000000..698aa2f
--- /dev/null
@@ -0,0 +1,126 @@
+# oh-my-zsh Bureau Theme
+
+### NVM
+
+ZSH_THEME_NVM_PROMPT_PREFIX="%B⬡%b "
+ZSH_THEME_NVM_PROMPT_SUFFIX=""
+
+### Git [±master ▾●]
+
+ZSH_THEME_GIT_PROMPT_PREFIX="[%{$fg_bold[green]%}±%{$reset_color%}%{$fg_bold[white]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}]"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}✓%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_AHEAD="%{$fg[cyan]%}▴%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_BEHIND="%{$fg[magenta]%}▾%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_STAGED="%{$fg_bold[green]%}●%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNSTAGED="%{$fg_bold[yellow]%}●%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg_bold[red]%}●%{$reset_color%}"
+
+bureau_git_info () {
+  local ref
+  ref=$(command git symbolic-ref HEAD 2> /dev/null) || \
+  ref=$(command git rev-parse --short HEAD 2> /dev/null) || return
+  echo "${ref#refs/heads/}"
+}
+
+bureau_git_status() {
+  local result gitstatus
+  gitstatus="$(command git status --porcelain -b 2>/dev/null)"
+
+  # check status of files
+  local gitfiles="$(tail -n +2 <<< "$gitstatus")"
+  if [[ -n "$gitfiles" ]]; then
+    if [[ "$gitfiles" =~ $'(^|\n)[AMRD]. ' ]]; then
+      result+="$ZSH_THEME_GIT_PROMPT_STAGED"
+    fi
+    if [[ "$gitfiles" =~ $'(^|\n).[MTD] ' ]]; then
+      result+="$ZSH_THEME_GIT_PROMPT_UNSTAGED"
+    fi
+    if [[ "$gitfiles" =~ $'(^|\n)\\?\\? ' ]]; then
+      result+="$ZSH_THEME_GIT_PROMPT_UNTRACKED"
+    fi
+    if [[ "$gitfiles" =~ $'(^|\n)UU ' ]]; then
+      result+="$ZSH_THEME_GIT_PROMPT_UNMERGED"
+    fi
+  else
+    result+="$ZSH_THEME_GIT_PROMPT_CLEAN"
+  fi
+
+  # check status of local repository
+  local gitbranch="$(head -n 1 <<< "$gitstatus")"
+  if [[ "$gitbranch" =~ '^## .*ahead' ]]; then
+    result+="$ZSH_THEME_GIT_PROMPT_AHEAD"
+  fi
+  if [[ "$gitbranch" =~ '^## .*behind' ]]; then
+    result+="$ZSH_THEME_GIT_PROMPT_BEHIND"
+  fi
+  if [[ "$gitbranch" =~ '^## .*diverged' ]]; then
+    result+="$ZSH_THEME_GIT_PROMPT_DIVERGED"
+  fi
+
+  # check if there are stashed changes
+  if command git rev-parse --verify refs/stash &> /dev/null; then
+    result+="$ZSH_THEME_GIT_PROMPT_STASHED"
+  fi
+
+  echo $result
+}
+
+bureau_git_prompt() {
+  # check git information
+  local gitinfo=$(bureau_git_info)
+  if [[ -z "$gitinfo" ]]; then
+    return
+  fi
+
+  # quote % in git information
+  local output="${gitinfo:gs/%/%%}"
+
+  # check git status
+  local gitstatus=$(bureau_git_status)
+  if [[ -n "$gitstatus" ]]; then
+    output+=" $gitstatus"
+  fi
+
+  echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${output}${ZSH_THEME_GIT_PROMPT_SUFFIX}"
+}
+
+
+_PATH="%{$fg_bold[white]%}%~%{$reset_color%}"
+
+if [[ $EUID -eq 0 ]]; then
+  _USERNAME="%{$fg_bold[red]%}%n"
+  _LIBERTY="%{$fg[red]%}#"
+else
+  _USERNAME="%{$fg_bold[white]%}%n"
+  _LIBERTY="%{$fg[green]%}$"
+fi
+_USERNAME="$_USERNAME%{$reset_color%}@%m"
+_LIBERTY="$_LIBERTY%{$reset_color%}"
+
+
+get_space () {
+  local STR=$1$2
+  local zero='%([BSUbfksu]|([FB]|){*})'
+  local LENGTH=${#${(S%%)STR//$~zero/}}
+  local SPACES=$(( COLUMNS - LENGTH - ${ZLE_RPROMPT_INDENT:-1} ))
+
+  (( SPACES > 0 )) || return
+  printf ' %.0s' {1..$SPACES}
+}
+
+_1LEFT="$_USERNAME $_PATH"
+_1RIGHT="[%*]"
+
+bureau_precmd () {
+  _1SPACES=`get_space $_1LEFT $_1RIGHT`
+  print
+  print -rP "$_1LEFT$_1SPACES$_1RIGHT"
+}
+
+setopt prompt_subst
+PROMPT='> $_LIBERTY '
+RPROMPT='$(nvm_prompt_info) $(bureau_git_prompt)'
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd bureau_precmd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/candy-kingdom.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/candy-kingdom.zsh-theme
new file mode 100644 (file)
index 0000000..31e63df
--- /dev/null
@@ -0,0 +1,34 @@
+if ! hg prompt 2>/dev/null; then
+    function hg_prompt_info { }
+else
+    function hg_prompt_info {
+        hg prompt --angle-brackets "\
+< on %{$fg[magenta]%}<branch>%{$reset_color%}>\
+< at %{$fg[yellow]%}<tags|%{$reset_color%}, %{$fg[yellow]%}>%{$reset_color%}>\
+%{$fg[green]%}<status|modified|unknown><update>%{$reset_color%}<
+patches: <patches|join( → )|pre_applied(%{$fg[yellow]%})|post_applied(%{$reset_color%})|pre_unapplied(%{$fg_bold[black]%})|post_unapplied(%{$reset_color%})>>" 2>/dev/null
+    }
+fi
+
+function box_name {
+  local box="${SHORT_HOST:-$HOST}"
+  [[ -f ~/.box-name ]] && box="$(< ~/.box-name)"
+  echo "${box:gs/%/%%}"
+}
+
+PROMPT='
+%{$fg[magenta]%}%n%{$reset_color%}@%{$fg[yellow]%}$(box_name)%{$reset_color%}:%{$fg_bold[green]%}%~%{$reset_color%}$(hg_prompt_info)$(git_prompt_info)
+%(?,,%{${fg_bold[white]}%}[%?]%{$reset_color%} )$ '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" (%{$fg[magenta]%}branch: "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[red]%}?"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[orange]%}!"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%})"
+
+RPROMPT='%{$fg[red]%}%(?..✘)%{$reset_color%}'
+
+# Add battery status if the battery plugin is enabled
+if (( $+functions[battery_pct_prompt] )); then
+    RPROMPT+='$(battery_time_remaining) $(battery_pct_prompt)%{$reset_color%}'
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/candy.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/candy.zsh-theme
new file mode 100644 (file)
index 0000000..40e6d41
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT=$'%{$fg_bold[green]%}%n@%m %{$fg[blue]%}%D{[%X]} %{$reset_color%}%{$fg[white]%}[%~]%{$reset_color%} $(git_prompt_info)\
+%{$fg[blue]%}->%{$fg_bold[blue]%} %#%{$reset_color%} '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}*%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/clean.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/clean.zsh-theme
new file mode 100644 (file)
index 0000000..5c96e47
--- /dev/null
@@ -0,0 +1,14 @@
+if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="white"; fi
+
+PROMPT='%{$fg[$NCOLOR]%}%B%n%b%{$reset_color%}:%{$fg[blue]%}%B%c/%b%{$reset_color%} $(git_prompt_info)%(!.#.$) '
+RPROMPT='[%*]'
+
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}(%{$fg_no_bold[yellow]%}%B"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%b%{$fg_bold[blue]%})%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%}✗"
+
+# LS colors, made with https://geoff.greer.fm/lscolors/
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/cloud.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/cloud.zsh-theme
new file mode 100644 (file)
index 0000000..e26f786
--- /dev/null
@@ -0,0 +1,10 @@
+if [[ -z $ZSH_THEME_CLOUD_PREFIX ]]; then
+    ZSH_THEME_CLOUD_PREFIX='☁'
+fi
+
+PROMPT='%{$fg_bold[cyan]%}$ZSH_THEME_CLOUD_PREFIX %{$fg_bold[green]%} %{$fg[green]%}%c %{$fg_bold[cyan]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}[%{$fg[cyan]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%}] %{$fg[yellow]%}⚡ %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%}]"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/crcandy.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/crcandy.zsh-theme
new file mode 100644 (file)
index 0000000..5b9cd42
--- /dev/null
@@ -0,0 +1,8 @@
+PROMPT=$'
+%{$fg_bold[green]%}%n@%m %{$fg[blue]%}%D{[%H:%M:%S]} %{$reset_color%}%{$fg[white]%}[%~]%{$reset_color%} $(git_prompt_info)\
+%{$fg[blue]%}->%{$fg_bold[blue]%} %#%{$reset_color%} '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}*%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/crunch.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/crunch.zsh-theme
new file mode 100644 (file)
index 0000000..8278661
--- /dev/null
@@ -0,0 +1,39 @@
+# CRUNCH - created from Steve Eley's cat waxing.
+# Initially hacked from the Dallas theme. Thanks, Dallas Reedy.
+#
+# This theme assumes you do most of your oh-my-zsh'ed "colorful" work at a single machine, 
+# and eschews the standard space-consuming user and hostname info.  Instead, only the 
+# things that vary in my own workflow are shown:
+#
+# * The time (not the date)
+# * The RVM version and gemset (omitting the 'ruby' name if it's MRI)
+# * The current directory
+# * The Git branch and its 'dirty' state
+# 
+# Colors are at the top so you can mess with those separately if you like.
+# For the most part I stuck with Dallas's.
+
+CRUNCH_BRACKET_COLOR="%{$fg[white]%}"
+CRUNCH_TIME_COLOR="%{$fg[yellow]%}"
+CRUNCH_RVM_COLOR="%{$fg[magenta]%}"
+CRUNCH_DIR_COLOR="%{$fg[cyan]%}"
+CRUNCH_GIT_BRANCH_COLOR="%{$fg[green]%}"
+CRUNCH_GIT_CLEAN_COLOR="%{$fg[green]%}"
+CRUNCH_GIT_DIRTY_COLOR="%{$fg[red]%}"
+
+# These Git variables are used by the oh-my-zsh git_prompt_info helper:
+ZSH_THEME_GIT_PROMPT_PREFIX="$CRUNCH_BRACKET_COLOR:$CRUNCH_GIT_BRANCH_COLOR"
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_CLEAN=" $CRUNCH_GIT_CLEAN_COLOR✓"
+ZSH_THEME_GIT_PROMPT_DIRTY=" $CRUNCH_GIT_DIRTY_COLOR✗"
+
+# Our elements:
+CRUNCH_TIME_="$CRUNCH_BRACKET_COLOR{$CRUNCH_TIME_COLOR%T$CRUNCH_BRACKET_COLOR}%{$reset_color%}"
+ZSH_THEME_RUBY_PROMPT_PREFIX="$CRUNCH_BRACKET_COLOR"["$CRUNCH_RVM_COLOR"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="$CRUNCH_BRACKET_COLOR"]"%{$reset_color%}"
+CRUNCH_RVM_='$(ruby_prompt_info)'
+CRUNCH_DIR_="$CRUNCH_DIR_COLOR%~\$(git_prompt_info) "
+CRUNCH_PROMPT="$CRUNCH_BRACKET_COLOR➭ "
+
+# Put it all together!
+PROMPT="$CRUNCH_TIME_$CRUNCH_RVM_$CRUNCH_DIR_$CRUNCH_PROMPT%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/cypher.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/cypher.zsh-theme
new file mode 100644 (file)
index 0000000..6e6b78e
--- /dev/null
@@ -0,0 +1,4 @@
+# Based on evan's prompt
+# Shows the exit status of the last command if non-zero
+# Uses "#" instead of "»" when running with elevated privileges
+PROMPT="%m %{${fg_bold[red]}%}:: %{${fg[green]}%}%3~%(0?. . %{${fg[red]}%}%? )%{${fg[blue]}%}»%{${reset_color}%} "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/dallas.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/dallas.zsh-theme
new file mode 100644 (file)
index 0000000..4f8be20
--- /dev/null
@@ -0,0 +1,27 @@
+# Personalized!
+
+# Grab the current date (%D) and time (%T) wrapped in {}: {%D %T}
+DALLAS_CURRENT_TIME_="%{$fg[white]%}{%{$fg[yellow]%}%D %T%{$fg[white]%}}%{$reset_color%}"
+# Grab the current machine name: muscato
+DALLAS_CURRENT_MACH_="%{$fg[green]%}%m%{$fg[white]%}:%{$reset_color%}"
+# Grab the current filepath, use shortcuts: ~/Desktop
+# Append the current git branch, if in a git repository: ~aw@master
+DALLAS_CURRENT_LOCA_="%{$fg[cyan]%}%~\$(git_prompt_info)%{$reset_color%}\$(parse_git_dirty)"
+# Grab the current username: dallas
+DALLAS_CURRENT_USER_="%{$fg[red]%}%n%{$reset_color%}"
+# Use a % for normal users and a # for privileged (root) users.
+DALLAS_PROMPT_CHAR_="%{$fg[white]%}%(!.#.%%)%{$reset_color%}"
+# For the git prompt, use a white @ and blue text for the branch name
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[white]%}@%{$fg[blue]%}"
+# Close it all off by resetting the color and styles.
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+# Do nothing if the branch is clean (no changes).
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+# Add 3 cyan ✗s if this branch is diiirrrty! Dirty branch!
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[cyan]%}✗✗✗"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[white]%}[%{$fg[magenta]%}"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$fg[white]%}]%{$reset_color%}"
+
+# Put it all together!
+PROMPT="$DALLAS_CURRENT_TIME_\$(ruby_prompt_info)$DALLAS_CURRENT_MACH_$DALLAS_CURRENT_LOCA_ $DALLAS_CURRENT_USER_$DALLAS_PROMPT_CHAR_ "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/darkblood.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/darkblood.zsh-theme
new file mode 100644 (file)
index 0000000..33508fb
--- /dev/null
@@ -0,0 +1,9 @@
+# meh. Dark Blood Rewind, a new beginning.
+
+PROMPT=$'%{$fg[red]%}┌[%{$fg_bold[white]%}%n%{$reset_color%}%{$fg[red]%}@%{$fg_bold[white]%}%m%{$reset_color%}%{$fg[red]%}] [%{$fg_bold[white]%}/dev/%y%{$reset_color%}%{$fg[red]%}] %{$(git_prompt_info)%}%(?,,%{$fg[red]%}[%{$fg_bold[white]%}%?%{$reset_color%}%{$fg[red]%}])
+%{$fg[red]%}└[%{$fg_bold[white]%}%~%{$reset_color%}%{$fg[red]%}]>%{$reset_color%} '
+PS2=$' %{$fg[red]%}|>%{$reset_color%} '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[red]%}[%{$fg_bold[white]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}%{$fg[red]%}] "
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}⚡%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/daveverwer.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/daveverwer.zsh-theme
new file mode 100644 (file)
index 0000000..89aef92
--- /dev/null
@@ -0,0 +1,7 @@
+# Copied and modified from the oh-my-zsh theme from geoffgarside
+# Red server name, green cwd, blue git status
+
+PROMPT='%{$fg[red]%}%m%{$reset_color%}:%{$fg[green]%}%c%{$reset_color%}$(git_prompt_info) %(!.#.$) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[blue]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/dieter.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/dieter.zsh-theme
new file mode 100644 (file)
index 0000000..83f2dcc
--- /dev/null
@@ -0,0 +1,56 @@
+# the idea of this theme is to contain a lot of info in a small string, by
+# compressing some parts and colorcoding, which bring useful visual cues,
+# while limiting the amount of colors and such to keep it easy on the eyes.
+# When a command exited >0, the timestamp will be in red and the exit code
+# will be on the right edge.
+# The exit code visual cues will only display once.
+# (i.e. they will be reset, even if you hit enter a few times on empty command prompts)
+
+typeset -g -A host_repr
+
+# translate hostnames into shortened, colorcoded strings
+host_repr=('dieter-ws-a7n8x-arch' "%{$fg_bold[green]%}ws" 'dieter-p4sci-arch' "%{$fg_bold[blue]%}p4")
+
+# local time, color coded by last return code
+time_enabled="%(?.%{$fg[green]%}.%{$fg[red]%})%*%{$reset_color%}"
+time_disabled="%{$fg[green]%}%*%{$reset_color%}"
+time=$time_enabled
+
+# user part, color coded by privileges
+local user="%(!.%{$fg[blue]%}.%{$fg[blue]%})%n%{$reset_color%}"
+
+# Hostname part.  compressed and colorcoded per host_repr array
+# if not found, regular hostname in default color
+local host="@${host_repr[$HOST]:-$HOST}%{$reset_color%}"
+
+# Compacted $PWD
+local pwd="%{$fg[blue]%}%c%{$reset_color%}"
+
+PROMPT='${time} ${user}${host} ${pwd} $(git_prompt_info)'
+
+# i would prefer 1 icon that shows the "most drastic" deviation from HEAD,
+# but lets see how this works out
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%} %{$fg[yellow]%}?%{$fg[green]%}%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%}"
+
+# elaborate exitcode on the right when >0
+return_code_enabled="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+return_code_disabled=
+return_code=$return_code_enabled
+
+RPS1='${return_code}'
+
+function accept-line-or-clear-warning () {
+       if [[ -z $BUFFER ]]; then
+               time=$time_disabled
+               return_code=$return_code_disabled
+       else
+               time=$time_enabled
+               return_code=$return_code_enabled
+       fi
+       zle accept-line
+}
+zle -N accept-line-or-clear-warning
+bindkey '^M' accept-line-or-clear-warning
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/dogenpunk.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/dogenpunk.zsh-theme
new file mode 100644 (file)
index 0000000..923ca74
--- /dev/null
@@ -0,0 +1,77 @@
+# dogenpunk.zsh-theme
+
+MODE_INDICATOR="%{$fg_bold[red]%}❮%{$reset_color%}%{$fg[red]%}❮❮%{$reset_color%}"
+local return_status="%{$fg[red]%}%(?..⏎)%{$reset_color%}"
+
+PROMPT='%{$fg[blue]%}%m%{$reset_color%}%{$fg_bold[white]%} ॐ  %{$reset_color%}%{$fg[cyan]%}%~:%{$reset_color%}$(git_time_since_commit)$(git_prompt_info)
+%{$fg[red]%}%!%{$reset_color%} $(prompt_char) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[green]%}git%{$reset_color%}@%{$bg[white]%}%{$fg[black]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%})"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}!%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+RPROMPT='${return_status}$(git_prompt_status)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%} ✚"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[blue]%} ✹"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✖"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[magenta]%} ➜"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[yellow]%} ═"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ✭"
+
+function prompt_char() {
+  git branch >/dev/null 2>/dev/null && echo "%{$fg[green]%}±%{$reset_color%}" && return
+  hg root >/dev/null 2>/dev/null && echo "%{$fg_bold[red]%}☿%{$reset_color%}" && return
+  echo "%{$fg[cyan]%}◯ %{$reset_color%}"
+}
+
+# Colors vary depending on time lapsed.
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}"
+ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[cyan]%}"
+
+# Determine the time since last commit. If branch is clean,
+# use a neutral color, otherwise colors will vary according to time.
+function git_time_since_commit() {
+    if git rev-parse --git-dir > /dev/null 2>&1; then
+        # Only proceed if there is actually a commit.
+        if last_commit=`git -c log.showSignature=false log --pretty=format:'%at' -1 2> /dev/null`; then
+            now=`date +%s`
+            seconds_since_last_commit=$((now-last_commit))
+
+            # Totals
+            MINUTES=$((seconds_since_last_commit / 60))
+            HOURS=$((seconds_since_last_commit/3600))
+
+            # Sub-hours and sub-minutes
+            DAYS=$((seconds_since_last_commit / 86400))
+            SUB_HOURS=$((HOURS % 24))
+            SUB_MINUTES=$((MINUTES % 60))
+
+            if [[ -n $(git status -s 2> /dev/null) ]]; then
+                if [ "$MINUTES" -gt 30 ]; then
+                    COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG"
+                elif [ "$MINUTES" -gt 10 ]; then
+                    COLOR="$ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM"
+                else
+                    COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT"
+                fi
+            else
+                COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+            fi
+
+            if [ "$HOURS" -gt 24 ]; then
+                echo "($COLOR${DAYS}d${SUB_HOURS}h${SUB_MINUTES}m%{$reset_color%}|"
+            elif [ "$MINUTES" -gt 60 ]; then
+                echo "($COLOR${HOURS}h${SUB_MINUTES}m%{$reset_color%}|"
+            else
+                echo "($COLOR${MINUTES}m%{$reset_color%}|"
+            fi
+        else
+            COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+            echo "($COLOR~|"
+        fi
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/dpoggi.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/dpoggi.zsh-theme
new file mode 100644 (file)
index 0000000..6469a20
--- /dev/null
@@ -0,0 +1,14 @@
+if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="green"; fi
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+PROMPT='%{$fg[$NCOLOR]%}%n%{$reset_color%}@%{$fg[cyan]%}%m\
+%{$reset_color%}:%{$fg[magenta]%}%~\
+$(git_prompt_info) \
+%{$fg[red]%}%(!.#.»)%{$reset_color%} '
+PROMPT2='%{$fg[red]%}\ %{$reset_color%}'
+RPS1='${return_code}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}("
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%}○%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}⚡%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg[yellow]%})%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/dst.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/dst.zsh-theme
new file mode 100644 (file)
index 0000000..6b2f876
--- /dev/null
@@ -0,0 +1,16 @@
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}!"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+function prompt_char {
+       if [ $UID -eq 0 ]; then echo "%{$fg[red]%}#%{$reset_color%}"; else echo $; fi
+}
+
+PROMPT='%(?, ,%{$fg[red]%}FAIL%{$reset_color%}
+)
+%{$fg[magenta]%}%n%{$reset_color%}@%{$fg[yellow]%}%m%{$reset_color%}: %{$fg_bold[blue]%}%~%{$reset_color%}$(git_prompt_info)
+$(prompt_char) '
+
+RPROMPT='%{$fg[green]%}[%*]%{$reset_color%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/dstufft.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/dstufft.zsh-theme
new file mode 100644 (file)
index 0000000..39ce698
--- /dev/null
@@ -0,0 +1,19 @@
+function prompt_char {
+    git branch >/dev/null 2>/dev/null && echo '±' && return
+    hg root >/dev/null 2>/dev/null && echo 'Hg' && return
+    echo '○'
+}
+
+function virtualenv_info {
+    [ $VIRTUAL_ENV ] && echo '('`basename $VIRTUAL_ENV`') '
+}
+
+PROMPT='
+%{$fg[magenta]%}%n%{$reset_color%} at %{$fg[yellow]%}%m%{$reset_color%} in %{$fg_bold[green]%}%~%{$reset_color%}$(git_prompt_info)
+$(virtualenv_info)$(prompt_char) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[magenta]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%}!"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[green]%}?"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/duellj.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/duellj.zsh-theme
new file mode 100644 (file)
index 0000000..f70b39b
--- /dev/null
@@ -0,0 +1,7 @@
+# user, host, full path, and time/date
+# on two lines for easier vgrepping
+# entry in a nice long thread on the Arch Linux forums: https://bbs.archlinux.org/viewtopic.php?pid=521888#p521888
+PROMPT=$'%{\e[0;34m%}%B┌─[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;34m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}%!%{\e[0;34m%}%B]%b%{\e[0m%}
+%{\e[0;34m%}%B└─%B[%{\e[1;35m%}$%{\e[0;34m%}%B]%{\e[0m%}%b '
+RPROMPT='[%*]'
+PS2=$' \e[0;34m%}%B>%{\e[0m%}%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/eastwood.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/eastwood.zsh-theme
new file mode 100644 (file)
index 0000000..88134f8
--- /dev/null
@@ -0,0 +1,23 @@
+# RVM settings
+if [[ -s ~/.rvm/scripts/rvm ]] ; then 
+  RPS1="%{$fg[yellow]%}rvm:%{$reset_color%}%{$fg[red]%}\$(~/.rvm/bin/rvm-prompt)%{$reset_color%} $EPS1"
+else
+  if which rbenv &> /dev/null; then
+    RPS1="%{$fg[yellow]%}rbenv:%{$reset_color%}%{$fg[red]%}\$(rbenv version | sed -e 's/ (set.*$//')%{$reset_color%} $EPS1"
+  fi
+fi
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[green]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}*%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+# Customized git status, oh-my-zsh currently does not allow render dirty status before branch
+git_custom_status() {
+  local cb=$(git_current_branch)
+  if [ -n "$cb" ]; then
+    echo "$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_PREFIX$(git_current_branch)$ZSH_THEME_GIT_PROMPT_SUFFIX"
+  fi
+}
+
+PROMPT='$(git_custom_status)%{$fg[cyan]%}[%~% ]%{$reset_color%}%B$%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/edvardm.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/edvardm.zsh-theme
new file mode 100644 (file)
index 0000000..d41dd44
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%} %{$fg_bold[white]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/emotty.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/emotty.zsh-theme
new file mode 100644 (file)
index 0000000..ba08409
--- /dev/null
@@ -0,0 +1,113 @@
+#!/usr/bin/env zsh
+# ------------------------------------------------------------------------------
+#          FILE: emotty.zsh-theme
+#   DESCRIPTION: A varying emoji based theme
+#        AUTHOR: Alexis Hildebrandt (afh[at]surryhill.net)
+#       VERSION: 1.0.0
+#       DEPENDS: emotty plugin
+#    RECOMMENDS: Hasklig font
+#
+# This theme shows a different emoji for each tty at the main prompt.
+#
+# There are pre-defined different emoji sets to choose from, e.g.:
+# emoji, stellar, floral, zodiac, love (see emotty plugin).
+# 
+# To choose a different emotty set than the default (emoji)
+# % export emotty_set=nature
+#
+# For the superuser (root) this theme shows a designated indicator
+# and switches the foreground color to red
+# (see root_prompt variable, default: skull).
+# But you are using sudo (8) instead of designated a root shell, right‽
+#
+# When logged in via SSH the main prompt also shows the user- and hostname.
+#
+# The exit status of the last failed command is displayed in the window title
+# along with an indicator (see warn_glyph variable, default: collision symbol).
+# To clear it just run: $NULL, true or :
+#
+# The right prompt shows the current working directory (3 levels up) in cyan.
+#
+# When in a git repository the main prompt shows the current branch name
+# with a branch indicator in yellow
+# (see vcs_branch_glyph variable, default: Hasklig branch glyph).
+#
+# If there are modified files the prompt switches to red and shows an unstaged
+# indicator (see vcs_unstaged_glyph variable, default: circled letter M).
+#
+# If there are staged files the prompt switches to green and shows an staged
+# indicator (see vcs_staged_glyph variable, default: high voltage sign).
+#
+# In a git repository the right prompt shows the repository name in bold and
+# prepends the current working directory subpath within the repository.
+#
+# When git currently performs an action such as merge or rebase, the action is
+# displayed in red instead of the branch name and a special action indicator
+# is shown (see vcs_action_glyph variable, default: chevron).
+# ------------------------------------------------------------------------------
+
+(( ${+functions[emotty]} )) || {
+  echo "error: the emotty theme requires the emotty plugin" >&2
+  return 1
+}
+
+(( ${+emoji} )) || {
+  echo "error: the emotty theme requires the emoji plugin" >&2
+  return 1
+}
+
+user_prompt="$(emotty)"
+root_prompt="$emoji[skull]"
+warn_prompt="$emoji[collision_symbol]"
+
+vcs_unstaged_glyph="%{$emoji[circled_latin_capital_letter_m]$emoji2[emoji_style] %2G%}"
+vcs_staged_glyph="%{$emoji[high_voltage_sign]%2G%}"
+vcs_branch_glyph=$'\Ue0a0' # 
+vcs_action_glyph=$'\U276f' # ❯
+
+red="$FG[001]"
+yellow="$FG[003]"
+green="$FG[002]"
+cyan="$FG[014]"
+
+prompt_glyph="%{%(#.${root_prompt}.${user_prompt}) %2G%}"
+
+# Uncomment the next line if you also like to see the warn_prompt in the prompt on the right.
+#last_command_failed="%(?.. %F{red}%1{${warn_prompt} %1G%}%?%f)"
+
+
+setopt promptsubst
+
+# Workaround for zsh 5.2 release (kudos to @timothybasanov)
+autoload +X VCS_INFO_nvcsformats
+functions[VCS_INFO_nvcsformats]=${functions[VCS_INFO_nvcsformats]/local -a msgs/}
+
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+zstyle ':vcs_info:*' enable git #hg svn cvs
+zstyle ':vcs_info:*' get-revision false
+zstyle ':vcs_info:*' check-for-changes true
+zstyle ':vcs_info:git:*' unstagedstr "${red}${vcs_unstaged_glyph}"
+zstyle ':vcs_info:*' stagedstr "${green}${vcs_staged_glyph}"
+
+# %(K|F){color} set (back|fore)ground color
+# %(k|f) reset (back|fore)ground color
+zstyle ':vcs_info:*' max-exports 3
+zstyle ':vcs_info:*' nvcsformats "${prompt_glyph}" '%3~' ''
+zstyle ':vcs_info:*' formats "${yellow}%u%c%b${vcs_branch_glyph}%f" '%S|' "$FX[bold]%r$FX[no-bold]" 
+zstyle ':vcs_info:*' actionformats "${red}%K{white}%a${vcs_action_glyph}%k%f" '%S|' "$FX[bold]%r$FX[no-bold]"
+
+red_if_root="%(!.%F{red}.)"
+sshuser_on_host="${SSH_TTY:+%(!.$red.$yellow)%n@%m$reset_color}"
+
+PROMPT='${sshuser_on_host}${vcs_info_msg_0_}${red_if_root} '
+RPROMPT='${cyan}${vcs_info_msg_1_##.|}${vcs_info_msg_2_}%f${last_command_failed}'
+
+emotty_title() {
+  title "${${?/[^0]*/$warn_prompt $?}/0/${prompt_glyph}}"
+}
+add-zsh-hook precmd emotty_title
+add-zsh-hook precmd vcs_info
+
+# vim:ft=zsh ts=2 sw=2 sts=2
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/essembeh.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/essembeh.zsh-theme
new file mode 100644 (file)
index 0000000..43d4093
--- /dev/null
@@ -0,0 +1,50 @@
+# My custom theme:
+#   - single line
+#   - quite simple by default: user@host:$PWD
+#   - green for local shell as non root
+#   - red for ssh shell as non root
+#   - magenta for root sessions
+#   - prefix with remote address for ssh shells
+#   - prefix to detect docker containers or chroot
+#   - git plugin to display current branch and status
+
+# git plugin 
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[cyan]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=") %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%%"
+ZSH_THEME_GIT_PROMPT_ADDED="+"
+ZSH_THEME_GIT_PROMPT_MODIFIED="*"
+ZSH_THEME_GIT_PROMPT_RENAMED="~"
+ZSH_THEME_GIT_PROMPT_DELETED="!"
+ZSH_THEME_GIT_PROMPT_UNMERGED="?"
+
+function zsh_essembeh_gitstatus {
+       ref=$(git symbolic-ref HEAD 2> /dev/null) || return
+       GIT_STATUS=$(git_prompt_status)
+       if [[ -n $GIT_STATUS ]]; then
+               GIT_STATUS=" $GIT_STATUS"
+       fi
+       echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$GIT_STATUS$ZSH_THEME_GIT_PROMPT_SUFFIX"
+}
+
+# by default, use green for user@host and no prefix
+local ZSH_ESSEMBEH_COLOR="green"
+local ZSH_ESSEMBEH_PREFIX=""
+if [[ -n "$SSH_CONNECTION" ]]; then
+       # display the source address if connected via ssh
+       ZSH_ESSEMBEH_PREFIX="%{$fg[yellow]%}[$(echo $SSH_CONNECTION | awk '{print $1}')]%{$reset_color%} "
+       # use red color to highlight a remote connection
+       ZSH_ESSEMBEH_COLOR="red"
+elif [[ -r /etc/debian_chroot ]]; then 
+       # prefix prompt in case of chroot
+       ZSH_ESSEMBEH_PREFIX="%{$fg[yellow]%}[chroot:$(cat /etc/debian_chroot)]%{$reset_color%} "
+elif [[ -r /.dockerenv ]]; then
+       # also prefix prompt inside a docker container
+       ZSH_ESSEMBEH_PREFIX="%{$fg[yellow]%}[docker]%{$reset_color%} "
+fi
+if [[ $UID = 0 ]]; then
+       # always use magenta for root sessions, even in ssh
+       ZSH_ESSEMBEH_COLOR="magenta"
+fi
+PROMPT='${ZSH_ESSEMBEH_PREFIX}%{$fg[$ZSH_ESSEMBEH_COLOR]%}%n@%M%{$reset_color%}:%{%B$fg[yellow]%}%~%{$reset_color%b%} $(zsh_essembeh_gitstatus)%(!.#.$) '
+RPROMPT="%(?..%{$fg[red]%}%?%{$reset_color%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/evan.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/evan.zsh-theme
new file mode 100644 (file)
index 0000000..02ca22d
--- /dev/null
@@ -0,0 +1,2 @@
+# Evan's minimal prompt
+PROMPT='%m :: %2~ %B»%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/fino-time.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/fino-time.zsh-theme
new file mode 100644 (file)
index 0000000..c7e2d96
--- /dev/null
@@ -0,0 +1,37 @@
+# fino-time.zsh-theme
+
+# Use with a dark background and 256-color terminal!
+# Meant for people with RVM and git. Tested only on OS X 10.7.
+
+# You can set your computer name in the ~/.box-name file if you want.
+
+# Borrowing shamelessly from these oh-my-zsh themes:
+#   bira
+#   robbyrussell
+#
+# Also borrowing from http://stevelosh.com/blog/2010/02/my-extravagant-zsh-prompt/
+
+function virtualenv_info {
+    [ $VIRTUAL_ENV ] && echo '('`basename $VIRTUAL_ENV`') '
+}
+
+function prompt_char {
+    git branch >/dev/null 2>/dev/null && echo '⠠⠵' && return
+    echo '○'
+}
+
+function box_name {
+  local box="${SHORT_HOST:-$HOST}"
+  [[ -f ~/.box-name ]] && box="$(< ~/.box-name)"
+  echo "${box:gs/%/%%}"
+}
+
+PROMPT="╭─%{$FG[040]%}%n%{$reset_color%} %{$FG[239]%}at%{$reset_color%} %{$FG[033]%}$(box_name)%{$reset_color%} %{$FG[239]%}in%{$reset_color%} %{$terminfo[bold]$FG[226]%}%~%{$reset_color%}\$(git_prompt_info)\$(ruby_prompt_info) %D - %*
+╰─\$(virtualenv_info)\$(prompt_char) "
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$FG[239]%}on%{$reset_color%} %{$fg[255]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$FG[202]%}✘✘✘"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$FG[040]%}✔"
+ZSH_THEME_RUBY_PROMPT_PREFIX=" %{$FG[239]%}using%{$FG[243]%} ‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="›%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/fino.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/fino.zsh-theme
new file mode 100644 (file)
index 0000000..9365a3c
--- /dev/null
@@ -0,0 +1,47 @@
+# fino.zsh-theme
+
+# Use with a dark background and 256-color terminal!
+# Meant for people with rbenv and git. Tested only on OS X 10.7.
+
+# You can set your computer name in the ~/.box-name file if you want.
+
+# Borrowing shamelessly from these oh-my-zsh themes:
+#   bira
+#   robbyrussell
+#
+# Also borrowing from http://stevelosh.com/blog/2010/02/my-extravagant-zsh-prompt/
+
+function virtualenv_prompt_info {
+  [[ -n ${VIRTUAL_ENV} ]] || return
+  echo "${ZSH_THEME_VIRTUALENV_PREFIX:=[}${VIRTUAL_ENV:t}${ZSH_THEME_VIRTUALENV_SUFFIX:=]}"
+}
+
+function prompt_char {
+  command git branch &>/dev/null && echo "±" || echo '○'
+}
+
+function box_name {
+  local box="${SHORT_HOST:-$HOST}"
+  [[ -f ~/.box-name ]] && box="$(< ~/.box-name)"
+  echo "${box:gs/%/%%}"
+}
+
+local ruby_env='$(ruby_prompt_info)'
+local git_info='$(git_prompt_info)'
+local virtualenv_info='$(virtualenv_prompt_info)'
+local prompt_char='$(prompt_char)'
+
+PROMPT="╭─${FG[040]}%n ${FG[239]}at ${FG[033]}$(box_name) ${FG[239]}in %B${FG[226]}%~%b${git_info}${ruby_env}${virtualenv_info}
+╰─${prompt_char}%{$reset_color%} "
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" ${FG[239]}on%{$reset_color%} ${FG[255]}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="${FG[202]}✘✘✘"
+ZSH_THEME_GIT_PROMPT_CLEAN="${FG[040]}✔"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX=" ${FG[239]}using${FG[243]} ‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="›%{$reset_color%}"
+
+export VIRTUAL_ENV_DISABLE_PROMPT=1
+ZSH_THEME_VIRTUALENV_PREFIX=" ${FG[239]}using${FG[243]} «"
+ZSH_THEME_VIRTUALENV_SUFFIX="»%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/fishy.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/fishy.zsh-theme
new file mode 100644 (file)
index 0000000..2b8d559
--- /dev/null
@@ -0,0 +1,35 @@
+# ZSH Theme emulating the Fish shell's default prompt.
+
+_fishy_collapsed_wd() {
+  local i pwd
+  pwd=("${(s:/:)PWD/#$HOME/~}")
+  if (( $#pwd > 1 )); then
+    for i in {1..$(($#pwd-1))}; do
+      if [[ "$pwd[$i]" = .* ]]; then
+        pwd[$i]="${${pwd[$i]}[1,2]}"
+      else
+        pwd[$i]="${${pwd[$i]}[1]}"
+      fi
+    done
+  fi
+  echo "${(j:/:)pwd}"
+}
+
+local user_color='green'; [ $UID -eq 0 ] && user_color='red'
+PROMPT='%n@%m %{$fg[$user_color]%}$(_fishy_collapsed_wd)%{$reset_color%}%(!.#.>) '
+PROMPT2='%{$fg[red]%}\ %{$reset_color%}'
+
+local return_status="%{$fg_bold[red]%}%(?..%?)%{$reset_color%}"
+RPROMPT="${RPROMPT}"'${return_status}$(git_prompt_info)$(git_prompt_status)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" "
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg_bold[green]%}+"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg_bold[blue]%}!"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg_bold[red]%}-"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg_bold[magenta]%}>"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg_bold[yellow]%}#"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg_bold[cyan]%}?"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/flazz.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/flazz.zsh-theme
new file mode 100644 (file)
index 0000000..e21b52e
--- /dev/null
@@ -0,0 +1,19 @@
+if [ "$USERNAME" = "root" ]
+then CARETCOLOR="red"
+else CARETCOLOR="blue"
+fi
+
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+PROMPT='%m%{${fg_bold[magenta]}%} :: %{$reset_color%}%{${fg[green]}%}%3~ $(git_prompt_info)%{${fg_bold[$CARETCOLOR]}%}%#%{${reset_color}%} '
+
+RPS1='$(vi_mode_prompt_info) ${return_code}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[cyan]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
+
+MODE_INDICATOR="%{$fg_bold[magenta]%}<%{$reset_color%}%{$fg[magenta]%}<<%{$reset_color%}"
+
+# TODO use 265 colors
+#MODE_INDICATOR="$FX[bold]$FG[020]<$FX[no_bold]%{$fg[blue]%}<<%{$reset_color%}"
+# TODO use two lines if git
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/fletcherm.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/fletcherm.zsh-theme
new file mode 100644 (file)
index 0000000..e961885
--- /dev/null
@@ -0,0 +1,12 @@
+# Copied from old version of tonotdo's theme. LSCOLORS modified.
+PROMPT='%{$fg_no_bold[cyan]%}%n%{$fg_no_bold[magenta]%}•%{$fg_no_bold[green]%}%3~$(git_prompt_info)%{$reset_color%}» '
+RPROMPT='[%*]'
+
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}(%{$fg_no_bold[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[blue]%})"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[yellow]%}⚡%{$fg_bold[blue]%})"
+
+export LSCOLORS="exfxcxdxbxegedabagacad"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/fox.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/fox.zsh-theme
new file mode 100644 (file)
index 0000000..3ecd4e2
--- /dev/null
@@ -0,0 +1,9 @@
+# fox.zsh-theme
+
+PROMPT='%{$fg[cyan]%}┌[%{$fg_bold[white]%}%n%{$reset_color%}%{$fg[cyan]%}☮%{$fg_bold[white]%}%M%{$reset_color%}%{$fg[cyan]%}]%{$fg[white]%}-%{$fg[cyan]%}(%{$fg_bold[white]%}%~%{$reset_color%}%{$fg[cyan]%})$(git_prompt_info)
+└> % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="-[%{$reset_color%}%{$fg[white]%}git://%{$fg_bold[white]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}%{$fg[cyan]%}]-"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/frisk.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/frisk.zsh-theme
new file mode 100644 (file)
index 0000000..f4f934d
--- /dev/null
@@ -0,0 +1,12 @@
+PROMPT=$'
+%{$fg[blue]%}%/%{$reset_color%} $(git_prompt_info)$(bzr_prompt_info)%{$fg[white]%}[%n@%m]%{$reset_color%} %{$fg[white]%}[%T]%{$reset_color%}
+%{$fg_bold[black]%}>%{$reset_color%} '
+
+PROMPT2="%{$fg_bold[black]%}%_> %{$reset_color%}"
+
+GIT_CB="git::"
+ZSH_THEME_SCM_PROMPT_PREFIX="%{$fg[green]%}["
+ZSH_THEME_GIT_PROMPT_PREFIX=$ZSH_THEME_SCM_PROMPT_PREFIX$GIT_CB
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}*%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/frontcube.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/frontcube.zsh-theme
new file mode 100644 (file)
index 0000000..de63483
--- /dev/null
@@ -0,0 +1,13 @@
+
+PROMPT='
+%{$fg_bold[gray]%}%~%{$fg_bold[blue]%}%{$fg_bold[blue]%} % %{$reset_color%}
+%{$fg[green]%}➞  %{$reset_color%}'
+
+RPROMPT='$(git_prompt_info) $(ruby_prompt_info)'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}[git:"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}] %{$fg[red]%}✖ %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%}] %{$fg[green]%}✔%{$reset_color%}"
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[green]%}["
+ZSH_THEME_RUBY_PROMPT_SUFFIX="]%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/funky.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/funky.zsh-theme
new file mode 100644 (file)
index 0000000..574538f
--- /dev/null
@@ -0,0 +1,14 @@
+# Taken from Tassilo's Blog
+# https://tsdh.wordpress.com/2007/12/06/my-funky-zsh-prompt/
+
+local blue_op="%{$fg[blue]%}[%{$reset_color%}"
+local blue_cp="%{$fg[blue]%}]%{$reset_color%}"
+local path_p="${blue_op}%~${blue_cp}"
+local user_host="${blue_op}%n@%m${blue_cp}"
+local ret_status="${blue_op}%?${blue_cp}"
+local hist_no="${blue_op}%h${blue_cp}"
+local smiley="%(?,%{$fg[green]%}:%)%{$reset_color%},%{$fg[red]%}:(%{$reset_color%})"
+PROMPT="╭─${path_p}─${user_host}─${ret_status}─${hist_no}
+╰─${blue_op}${smiley}${blue_cp} %# "
+local cur_cmd="${blue_op}%_${blue_cp}"
+PROMPT2="${cur_cmd}> "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/fwalch.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/fwalch.zsh-theme
new file mode 100644 (file)
index 0000000..33f851c
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg_bold[green]%} %{$fg[cyan]%}%c%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" (%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/gallifrey.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/gallifrey.zsh-theme
new file mode 100644 (file)
index 0000000..47b057f
--- /dev/null
@@ -0,0 +1,11 @@
+# ZSH Theme - Preview: https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#gallifrey
+return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+host_color="%(!.%{$fg[red]%}.%{$fg[green]%})"
+
+PROMPT="${host_color}%m%{$reset_color%} %2~ \$(git_prompt_info)%{$reset_color%}%B»%b "
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
+
+unset return_code host_color
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/gallois.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/gallois.zsh-theme
new file mode 100644 (file)
index 0000000..bb97bfb
--- /dev/null
@@ -0,0 +1,24 @@
+# Depends on the git plugin for work_in_progress()
+(( $+functions[work_in_progress] )) || work_in_progress() {}
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[green]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}*%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+# Customized git status, oh-my-zsh currently does not allow render dirty status before branch
+git_custom_status() {
+  local branch=$(git_current_branch)
+  [[ -n "$branch" ]] || return 0
+  echo "$(parse_git_dirty)\
+%{${fg_bold[yellow]}%}$(work_in_progress)%{$reset_color%}\
+${ZSH_THEME_GIT_PROMPT_PREFIX}${branch}${ZSH_THEME_GIT_PROMPT_SUFFIX}"
+}
+
+# RVM component of prompt
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}["
+ZSH_THEME_RUBY_PROMPT_SUFFIX="]%{$reset_color%}"
+
+# Combine it all into a final right-side prompt
+RPS1="\$(git_custom_status)\$(ruby_prompt_info)${RPS1:+ $RPS1}"
+PROMPT='%{$fg[cyan]%}[%~% ]%(?.%{$fg[green]%}.%{$fg[red]%})%B$%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/garyblessington.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/garyblessington.zsh-theme
new file mode 100644 (file)
index 0000000..b4f84a7
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg[cyan]%}%c%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}% %{$reset_color%}: '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="(%{$fg[blue]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[red]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/gentoo.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/gentoo.zsh-theme
new file mode 100644 (file)
index 0000000..b1aef21
--- /dev/null
@@ -0,0 +1,30 @@
+autoload -Uz colors && colors
+
+autoload -Uz vcs_info
+zstyle ':vcs_info:*' check-for-changes true
+zstyle ':vcs_info:*' unstagedstr '%F{red}*'   # display this when there are unstaged changes
+zstyle ':vcs_info:*' stagedstr '%F{yellow}+'  # display this when there are staged changes
+zstyle ':vcs_info:*' actionformats '%F{5}(%F{2}%b%F{3}|%F{1}%a%c%u%m%F{5})%f '
+zstyle ':vcs_info:*' formats '%F{5}(%F{2}%b%c%u%m%F{5})%f '
+zstyle ':vcs_info:svn:*' branchformat '%b'
+zstyle ':vcs_info:svn:*' actionformats '%F{5}(%F{2}%b%F{1}:%{3}%i%F{3}|%F{1}%a%c%u%m%F{5})%f '
+zstyle ':vcs_info:svn:*' formats '%F{5}(%F{2}%b%F{1}:%F{3}%i%c%u%m%F{5})%f '
+zstyle ':vcs_info:*' enable git cvs svn
+zstyle ':vcs_info:git*+set-message:*' hooks untracked-git
+
++vi-untracked-git() {
+  if command git status --porcelain 2>/dev/null | command grep -q '??'; then
+    hook_com[misc]='%F{red}?'
+  else
+    hook_com[misc]=''
+  fi
+}
+
+gentoo_precmd() {
+  vcs_info
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd gentoo_precmd
+
+PROMPT='%(!.%B%F{red}.%B%F{green}%n@)%m %F{blue}%(!.%1~.%~) ${vcs_info_msg_0_}%F{blue}%(!.#.$)%k%b%f '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/geoffgarside.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/geoffgarside.zsh-theme
new file mode 100644 (file)
index 0000000..675ec72
--- /dev/null
@@ -0,0 +1,5 @@
+# PROMPT="[%*] %n:%c $(git_prompt_info)%(!.#.$) "
+PROMPT='[%*] %{$fg[cyan]%}%n%{$reset_color%}:%{$fg[green]%}%c%{$reset_color%}$(git_prompt_info) %(!.#.$) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[yellow]%}git:("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/gianu.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/gianu.zsh-theme
new file mode 100644 (file)
index 0000000..faa8021
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='[%{$fg_bold[white]%}%n%{$reset_color%}@%{$fg_bold[red]%}%m%{$reset_color%} %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)%{$reset_color%}]$ '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="(%{$fg_bold[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%} %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/gnzh.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/gnzh.zsh-theme
new file mode 100644 (file)
index 0000000..1e6c4e9
--- /dev/null
@@ -0,0 +1,43 @@
+# Based on bira theme
+
+setopt prompt_subst
+
+() {
+
+local PR_USER PR_USER_OP PR_PROMPT PR_HOST
+
+# Check the UID
+if [[ $UID -ne 0 ]]; then # normal user
+  PR_USER='%F{green}%n%f'
+  PR_USER_OP='%F{green}%#%f'
+  PR_PROMPT='%f➤ %f'
+else # root
+  PR_USER='%F{red}%n%f'
+  PR_USER_OP='%F{red}%#%f'
+  PR_PROMPT='%F{red}➤ %f'
+fi
+
+# Check if we are on SSH or not
+if [[ -n "$SSH_CLIENT"  ||  -n "$SSH2_CLIENT" ]]; then
+  PR_HOST='%F{red}%M%f' # SSH
+else
+  PR_HOST='%F{green}%M%f' # no SSH
+fi
+
+
+local return_code="%(?..%F{red}%? ↵%f)"
+
+local user_host="${PR_USER}%F{cyan}@${PR_HOST}"
+local current_dir="%B%F{blue}%~%f%b"
+local git_branch='$(git_prompt_info)'
+
+PROMPT="╭─${user_host} ${current_dir} \$(ruby_prompt_info) ${git_branch}
+╰─$PR_PROMPT "
+RPROMPT="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%F{yellow}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %f"
+ZSH_THEME_RUBY_PROMPT_PREFIX="%F{red}‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="›%f"
+
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/gozilla.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/gozilla.zsh-theme
new file mode 100644 (file)
index 0000000..593b8ec
--- /dev/null
@@ -0,0 +1,15 @@
+PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%} %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+RPROMPT='$(git_prompt_status)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[cyan]%} ✈"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%} ✭"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✗"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%} ➦"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[magenta]%} ✂"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[grey]%} ✱"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/half-life.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/half-life.zsh-theme
new file mode 100644 (file)
index 0000000..c4d7851
--- /dev/null
@@ -0,0 +1,93 @@
+# prompt style and colors based on Steve Losh's Prose theme:
+# https://github.com/sjl/oh-my-zsh/blob/master/themes/prose.zsh-theme
+#
+# vcs_info modifications from Bart Trojanowski's zsh prompt:
+# http://www.jukie.net/bart/blog/pimping-out-zsh-prompt
+#
+# git untracked files modification from Brian Carper:
+# https://briancarper.net/blog/570/git-info-in-your-zsh-prompt
+
+#use extended color palette if available
+if [[ $TERM = (*256color|*rxvt*) ]]; then
+  turquoise="%{${(%):-"%F{81}"}%}"
+  orange="%{${(%):-"%F{166}"}%}"
+  purple="%{${(%):-"%F{135}"}%}"
+  hotpink="%{${(%):-"%F{161}"}%}"
+  limegreen="%{${(%):-"%F{118}"}%}"
+else
+  turquoise="%{${(%):-"%F{cyan}"}%}"
+  orange="%{${(%):-"%F{yellow}"}%}"
+  purple="%{${(%):-"%F{magenta}"}%}"
+  hotpink="%{${(%):-"%F{red}"}%}"
+  limegreen="%{${(%):-"%F{green}"}%}"
+fi
+
+autoload -Uz vcs_info
+# enable VCS systems you use
+zstyle ':vcs_info:*' enable git svn
+
+# check-for-changes can be really slow.
+# you should disable it, if you work with large repositories
+zstyle ':vcs_info:*:prompt:*' check-for-changes true
+
+# set formats
+# %b - branchname
+# %u - unstagedstr (see below)
+# %c - stagedstr (see below)
+# %a - action (e.g. rebase-i)
+# %R - repository path
+# %S - path in the repository
+PR_RST="%{${reset_color}%}"
+FMT_BRANCH=" on ${turquoise}%b%u%c${PR_RST}"
+FMT_ACTION=" performing a ${limegreen}%a${PR_RST}"
+FMT_UNSTAGED="${orange} ●"
+FMT_STAGED="${limegreen} ●"
+
+zstyle ':vcs_info:*:prompt:*' unstagedstr   "${FMT_UNSTAGED}"
+zstyle ':vcs_info:*:prompt:*' stagedstr     "${FMT_STAGED}"
+zstyle ':vcs_info:*:prompt:*' actionformats "${FMT_BRANCH}${FMT_ACTION}"
+zstyle ':vcs_info:*:prompt:*' formats       "${FMT_BRANCH}"
+zstyle ':vcs_info:*:prompt:*' nvcsformats   ""
+
+
+function steeef_chpwd {
+  PR_GIT_UPDATE=1
+}
+
+function steeef_preexec {
+  case "$2" in
+  *git*|*svn*) PR_GIT_UPDATE=1 ;;
+  esac
+}
+
+function steeef_precmd {
+  (( PR_GIT_UPDATE )) || return
+
+  # check for untracked files or updated submodules, since vcs_info doesn't
+  if [[ -n "$(git ls-files --other --exclude-standard 2>/dev/null)" ]]; then
+    PR_GIT_UPDATE=1
+    FMT_BRANCH="${PM_RST} on ${turquoise}%b%u%c${hotpink} ●${PR_RST}"
+  else
+    FMT_BRANCH="${PM_RST} on ${turquoise}%b%u%c${PR_RST}"
+  fi
+  zstyle ':vcs_info:*:prompt:*' formats       "${FMT_BRANCH}"
+
+  vcs_info 'prompt'
+  PR_GIT_UPDATE=
+}
+
+# vcs_info running hooks
+PR_GIT_UPDATE=1
+
+autoload -U add-zsh-hook
+add-zsh-hook chpwd steeef_chpwd
+add-zsh-hook precmd steeef_precmd
+add-zsh-hook preexec steeef_preexec
+
+# ruby prompt settings
+ZSH_THEME_RUBY_PROMPT_PREFIX="with%F{red} "
+ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_RVM_PROMPT_OPTIONS="v g"
+
+setopt prompt_subst
+PROMPT="${purple}%n%{$reset_color%} in ${limegreen}%~%{$reset_color%}\$(ruby_prompt_info)\$vcs_info_msg_0_${orange} λ%{$reset_color%} "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/humza.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/humza.zsh-theme
new file mode 100644 (file)
index 0000000..1078862
--- /dev/null
@@ -0,0 +1,26 @@
+# ZSH THEME Preview: https://skitch.com/huyy/rk979/humza.zshtheme
+
+let TotalBytes=0
+for Bytes in $(ls -l | grep "^-" | awk '{ print $5 }')
+do
+   let TotalBytes=$TotalBytes+$Bytes
+done
+               # should it say b, kb, Mb, or Gb
+if [ $TotalBytes -lt 1024 ]; then
+   TotalSize=$(echo -e "scale=3 \n$TotalBytes \nquit" | bc)
+   suffix="b"
+elif [ $TotalBytes -lt 1048576 ]; then
+   TotalSize=$(echo -e "scale=3 \n$TotalBytes/1024 \nquit" | bc)
+   suffix="kb"
+elif [ $TotalBytes -lt 1073741824 ]; then
+   TotalSize=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
+   suffix="Mb"
+else
+   TotalSize=$(echo -e "scale=3 \n$TotalBytes/1073741824 \nquit" | bc)
+   suffix="Gb"
+fi
+
+PROMPT='%{$reset_color%}%n %{$fg[green]%}{%{$reset_color%}%~%{$fg[green]%}}%{$reset_color%}$(git_prompt_info) greetings, earthling %{$fg[green]%}[%{$reset_color%}%{$TotalSize%}%{$suffix%}%{$fg[green]%}]%{$fg[red]%}$%{$reset_color%} ☞ '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[red]%}±("
+ZSH_THEME_GIT_PROMPT_SUFFIX=");%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/imajes.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/imajes.zsh-theme
new file mode 100644 (file)
index 0000000..88c35b6
--- /dev/null
@@ -0,0 +1,5 @@
+# Found on the ZshWiki
+#  http://zshwiki.org/home/config/prompt
+#
+
+PROMPT="%{$fg[red]%}%%%{$reset_color%} "
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/intheloop.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/intheloop.zsh-theme
new file mode 100644 (file)
index 0000000..7a98db2
--- /dev/null
@@ -0,0 +1,23 @@
+# A multiline prompt with username, hostname, full path, return status, git branch, git dirty status, git remote status
+
+local return_status="%{$fg[red]%}%(?..⏎)%{$reset_color%}"
+
+local host_color="green"
+if [ -n "$SSH_CLIENT" ]; then
+  local host_color="red"
+fi
+
+PROMPT='
+%{$fg_bold[grey]%}[%{$reset_color%}%{$fg_bold[${host_color}]%}%n@%m%{$reset_color%}%{$fg_bold[grey]%}]%{$reset_color%} %{$fg_bold[blue]%}%10c%{$reset_color%} $(git_prompt_info) $(git_remote_status)
+%{$fg_bold[cyan]%}❯%{$reset_color%} '
+
+
+RPROMPT='${return_status}%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[grey]%}(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[grey]%}) %{$fg[yellow]%}⚡%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[grey]%})"
+ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE="%{$fg_bold[magenta]%}↓%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE="%{$fg_bold[magenta]%}↑%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE="%{$fg_bold[magenta]%}↕%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/itchy.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/itchy.zsh-theme
new file mode 100644 (file)
index 0000000..41a42e8
--- /dev/null
@@ -0,0 +1,18 @@
+local smiley="%(?,%{$fg[green]%}☺%{$reset_color%},%{$fg[red]%}☹%{$reset_color%})"
+
+local user="%{$fg[cyan]%}%n%{$reset_color%}"
+local host="%{$fg[cyan]%}@%m%{$reset_color%}"
+local pwd="%{$fg[yellow]%}%~%{$reset_color%}"
+
+PROMPT='${user}${host} ${pwd}
+${smiley}  '
+
+RPROMPT='$(ruby_prompt_info) %{$fg[white]%}$(git_prompt_info)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX=""
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%} ✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%} ✔%{$reset_color%}"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX=""
+ZSH_THEME_RUBY_PROMPT_SUFFIX=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jaischeema.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jaischeema.zsh-theme
new file mode 100644 (file)
index 0000000..50d2bc4
--- /dev/null
@@ -0,0 +1,12 @@
+# jaischeema.zsh-theme
+
+PROMPT='%{$fg_bold[magenta]%}%m%{$reset_color%} at %{$fg_bold[green]%}%~%{$reset_color%} %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}% %{$reset_color%}%{$fg[red]%}❯%{$reset_color%} '
+RPROMPT='$(ruby_prompt_info)'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="±(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%}) "
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jbergantine.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jbergantine.zsh-theme
new file mode 100644 (file)
index 0000000..8e9a8ee
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%} %{$fg[cyan]%}%c %{$fg_bold[white]%}$(git_prompt_info)%{$fg_bold[white]%} % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[white]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[white]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jispwoso.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jispwoso.zsh-theme
new file mode 100644 (file)
index 0000000..7484305
--- /dev/null
@@ -0,0 +1,10 @@
+local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ %s)"
+PROMPT=$'%{$fg[green]%}%n@%m: %{$reset_color%}%{$fg[blue]%}%/ %{$reset_color%}%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}
+${ret_status} %{$reset_color%} '
+
+PROMPT2="%{$fg_blod[black]%}%_> %{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jnrowe.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jnrowe.zsh-theme
new file mode 100644 (file)
index 0000000..5a5ab34
--- /dev/null
@@ -0,0 +1,37 @@
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+zstyle ':vcs_info:*' actionformats \
+       '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '
+zstyle ':vcs_info:*' formats '%F{2}%s%F{7}:%F{2}(%F{1}%b%F{2})%f '
+zstyle ':vcs_info:*' enable git
+
+add-zsh-hook precmd prompt_vcs
+
+prompt_vcs () {
+    vcs_info
+
+    if [ "${vcs_info_msg_0_}" = "" ]; then
+        dir_status="%F{2}→%f"
+    elif [[ $(git diff --cached --name-status 2>/dev/null ) != "" ]]; then
+        dir_status="%F{1}▶%f"
+    elif [[ $(git diff --name-status 2>/dev/null ) != "" ]]; then
+        dir_status="%F{3}▶%f"
+    else
+        dir_status="%F{2}▶%f"
+    fi
+}
+
+function {
+    if [[ -n "$SSH_CLIENT" ]]; then
+        PROMPT_HOST=" ($HOST)"
+    else
+        PROMPT_HOST=''
+    fi
+}
+
+local ret_status="%(?:%{$fg_bold[green]%}Ξ:%{$fg_bold[red]%}%S↑%s%?)"
+
+PROMPT='${ret_status}%{$fg[blue]%}${PROMPT_HOST}%{$fg_bold[green]%} %{$fg_bold[yellow]%}%2~ ${vcs_info_msg_0_}${dir_status}%{$reset_color%} '
+
+#  vim: set ft=zsh ts=4 sw=4 et:
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jonathan.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jonathan.zsh-theme
new file mode 100644 (file)
index 0000000..e8c4908
--- /dev/null
@@ -0,0 +1,124 @@
+function theme_precmd {
+  local TERMWIDTH=$(( COLUMNS - ${ZLE_RPROMPT_INDENT:-1} ))
+
+  PR_FILLBAR=""
+  PR_PWDLEN=""
+
+  local promptsize=${#${(%):---(%n@%m:%l)---()--}}
+  local rubypromptsize=${#${(%)$(ruby_prompt_info)}}
+  local pwdsize=${#${(%):-%~}}
+
+  # Truncate the path if it's too long.
+  if (( promptsize + rubypromptsize + pwdsize > TERMWIDTH )); then
+    (( PR_PWDLEN = TERMWIDTH - promptsize ))
+  elif [[ "${langinfo[CODESET]}" = UTF-8 ]]; then
+    PR_FILLBAR="\${(l:$(( TERMWIDTH - (promptsize + rubypromptsize + pwdsize) ))::${PR_HBAR}:)}"
+  else
+    PR_FILLBAR="${PR_SHIFT_IN}\${(l:$(( TERMWIDTH - (promptsize + rubypromptsize + pwdsize) ))::${altchar[q]:--}:)}${PR_SHIFT_OUT}"
+  fi
+}
+
+function theme_preexec {
+  setopt local_options extended_glob
+  if [[ "$TERM" = "screen" ]]; then
+    local CMD=${1[(wr)^(*=*|sudo|-*)]}
+    echo -n "\ek$CMD\e\\"
+  fi
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd  theme_precmd
+add-zsh-hook preexec theme_preexec
+
+
+# Set the prompt
+
+# Need this so the prompt will work.
+setopt prompt_subst
+
+# See if we can use colors.
+autoload zsh/terminfo
+for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE GREY; do
+  typeset -g PR_$color="%{$terminfo[bold]$fg[${(L)color}]%}"
+  typeset -g PR_LIGHT_$color="%{$fg[${(L)color}]%}"
+done
+PR_NO_COLOUR="%{$terminfo[sgr0]%}"
+
+# Modify Git prompt
+ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%} %{%G✚%}"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[blue]%} %{%G✹%}"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} %{%G✖%}"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[magenta]%} %{%G➜%}"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[yellow]%} %{%G═%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} %{%G✭%}"
+
+# Use extended characters to look nicer if supported.
+if [[ "${langinfo[CODESET]}" = UTF-8 ]]; then
+  PR_SET_CHARSET=""
+  PR_HBAR="─"
+  PR_ULCORNER="┌"
+  PR_LLCORNER="└"
+  PR_LRCORNER="┘"
+  PR_URCORNER="┐"
+else
+  typeset -g -A altchar
+  set -A altchar ${(s..)terminfo[acsc]}
+  # Some stuff to help us draw nice lines
+  PR_SET_CHARSET="%{$terminfo[enacs]%}"
+  PR_SHIFT_IN="%{$terminfo[smacs]%}"
+  PR_SHIFT_OUT="%{$terminfo[rmacs]%}"
+  PR_HBAR="${PR_SHIFT_IN}${altchar[q]:--}${PR_SHIFT_OUT}"
+  PR_ULCORNER="${PR_SHIFT_IN}${altchar[l]:--}${PR_SHIFT_OUT}"
+  PR_LLCORNER="${PR_SHIFT_IN}${altchar[m]:--}${PR_SHIFT_OUT}"
+  PR_LRCORNER="${PR_SHIFT_IN}${altchar[j]:--}${PR_SHIFT_OUT}"
+  PR_URCORNER="${PR_SHIFT_IN}${altchar[k]:--}${PR_SHIFT_OUT}"
+fi
+
+# Decide if we need to set titlebar text.
+case $TERM in
+  xterm*)
+    PR_TITLEBAR=$'%{\e]0;%(!.-=*[ROOT]*=- | .)%n@%m:%~ | ${COLUMNS}x${LINES} | %y\a%}'
+    ;;
+  screen)
+    PR_TITLEBAR=$'%{\e_screen \005 (\005t) | %(!.-=[ROOT]=- | .)%n@%m:%~ | ${COLUMNS}x${LINES} | %y\e\\%}'
+    ;;
+  *)
+    PR_TITLEBAR=""
+    ;;
+esac
+
+# Decide whether to set a screen title
+if [[ "$TERM" = "screen" ]]; then
+  PR_STITLE=$'%{\ekzsh\e\\%}'
+else
+  PR_STITLE=""
+fi
+
+# Finally, the prompt.
+PROMPT='${PR_SET_CHARSET}${PR_STITLE}${(e)PR_TITLEBAR}\
+${PR_CYAN}${PR_ULCORNER}${PR_HBAR}${PR_GREY}(\
+${PR_GREEN}%${PR_PWDLEN}<...<%~%<<\
+${PR_GREY})$(ruby_prompt_info)${PR_CYAN}${PR_HBAR}${PR_HBAR}${(e)PR_FILLBAR}${PR_HBAR}${PR_GREY}(\
+${PR_CYAN}%(!.%SROOT%s.%n)${PR_GREY}@${PR_GREEN}%m:%l\
+${PR_GREY})${PR_CYAN}${PR_HBAR}${PR_URCORNER}\
+
+${PR_CYAN}${PR_LLCORNER}${PR_BLUE}${PR_HBAR}(\
+${PR_YELLOW}%D{%H:%M:%S}\
+${PR_LIGHT_BLUE}%{$reset_color%}$(git_prompt_info)$(git_prompt_status)${PR_BLUE})${PR_CYAN}${PR_HBAR}\
+${PR_HBAR}\
+>${PR_NO_COLOUR} '
+
+# display exitcode on the right when > 0
+return_code="%(?..%{$fg[red]%}%? ↵ %{$reset_color%})"
+RPROMPT=' $return_code${PR_CYAN}${PR_HBAR}${PR_BLUE}${PR_HBAR}\
+(${PR_YELLOW}%D{%a,%b%d}${PR_BLUE})${PR_HBAR}${PR_CYAN}${PR_LRCORNER}${PR_NO_COLOUR}'
+
+PS2='${PR_CYAN}${PR_HBAR}\
+${PR_BLUE}${PR_HBAR}(\
+${PR_LIGHT_GREEN}%_${PR_BLUE})${PR_HBAR}\
+${PR_CYAN}${PR_HBAR}${PR_NO_COLOUR} '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/josh.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/josh.zsh-theme
new file mode 100644 (file)
index 0000000..ea051c5
--- /dev/null
@@ -0,0 +1,43 @@
+grey='\e[0;90m'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$grey%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$grey%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$grey%})"
+
+function josh_prompt {
+  (( spare_width = ${COLUMNS} ))
+  prompt=" "
+
+  branch=$(git_current_branch)
+  ruby_version=$(ruby_prompt_info)
+  path_size=${#PWD}
+  branch_size=${#branch}
+  ruby_size=${#ruby_version}
+  user_machine_size=${#${(%):-%n@%m-}}
+  
+  if [[ ${#branch} -eq 0 ]]
+    then (( ruby_size = ruby_size + 1 ))
+  else
+    (( branch_size = branch_size + 4 ))
+    if [[ -n $(git status -s 2> /dev/null) ]]; then
+      (( branch_size = branch_size + 2 ))
+    fi
+  fi
+  
+  (( spare_width = ${spare_width} - (${user_machine_size} + ${path_size} + ${branch_size} + ${ruby_size}) ))
+
+  while [ ${#prompt} -lt $spare_width ]; do
+    prompt=" $prompt"
+  done
+  
+  prompt="%{%F{green}%}$PWD$prompt%{%F{red}%}$(ruby_prompt_info)%{$reset_color%} $(git_current_branch)"
+  
+  echo $prompt
+}
+
+setopt prompt_subst
+
+PROMPT='
+%n@%m $(josh_prompt)
+%(?,%{%F{green}%},%{%F{red}%})⚡%{$reset_color%} '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jreese.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jreese.zsh-theme
new file mode 100644 (file)
index 0000000..de42a10
--- /dev/null
@@ -0,0 +1,14 @@
+if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="green"; fi
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+PROMPT='%{$fg[$NCOLOR]%}%n%{$fg[green]%}@%m%{$reset_color%} %~ \
+$(git_prompt_info)\
+%{$fg[red]%}%(!.#.»)%{$reset_color%} '
+PROMPT2='%{$fg[red]%}\ %{$reset_color%}'
+RPS1='${return_code}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}±%{$fg[yellow]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="⚡"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/jtriley.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/jtriley.zsh-theme
new file mode 100644 (file)
index 0000000..0f5b16f
--- /dev/null
@@ -0,0 +1,2 @@
+PROMPT="%{$fg_bold[cyan]%}%T%{$fg_bold[green]%} %{$fg_bold[white]%}%n%{$fg[magenta]%}@%{$fg_bold[white]%}%m %{$fg_bold[green]%}%d
+%{$fg_bold[yellow]%}%% %{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/juanghurtado.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/juanghurtado.zsh-theme
new file mode 100644 (file)
index 0000000..dbdfde7
--- /dev/null
@@ -0,0 +1,41 @@
+# Color shortcuts
+RED=$fg[red]
+YELLOW=$fg[yellow]
+GREEN=$fg[green]
+WHITE=$fg[white]
+BLUE=$fg[blue]
+RED_BOLD=$fg_bold[red]
+YELLOW_BOLD=$fg_bold[yellow]
+GREEN_BOLD=$fg_bold[green]
+WHITE_BOLD=$fg_bold[white]
+BLUE_BOLD=$fg_bold[blue]
+RESET_COLOR=$reset_color
+
+# Format for git_prompt_info()
+ZSH_THEME_GIT_PROMPT_PREFIX=""
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+
+# Format for parse_git_dirty()
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$RED%}(*)"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+# Format for git_prompt_status()
+ZSH_THEME_GIT_PROMPT_UNMERGED=" %{$RED%}unmerged"
+ZSH_THEME_GIT_PROMPT_DELETED=" %{$RED%}deleted"
+ZSH_THEME_GIT_PROMPT_RENAMED=" %{$YELLOW%}renamed"
+ZSH_THEME_GIT_PROMPT_MODIFIED=" %{$YELLOW%}modified"
+ZSH_THEME_GIT_PROMPT_ADDED=" %{$GREEN%}added"
+ZSH_THEME_GIT_PROMPT_UNTRACKED=" %{$WHITE%}untracked"
+
+# Format for git_prompt_ahead()
+ZSH_THEME_GIT_PROMPT_AHEAD=" %{$RED%}(!)"
+
+# Format for git_prompt_long_sha() and git_prompt_short_sha()
+ZSH_THEME_GIT_PROMPT_SHA_BEFORE=" %{$WHITE%}[%{$YELLOW%}"
+ZSH_THEME_GIT_PROMPT_SHA_AFTER="%{$WHITE%}]"
+
+# Prompt format
+PROMPT='
+%{$GREEN_BOLD%}%n@%m%{$WHITE%}:%{$YELLOW%}%~%u$(parse_git_dirty)$(git_prompt_ahead)%{$RESET_COLOR%}
+%{$BLUE%}>%{$RESET_COLOR%} '
+RPROMPT='%{$GREEN_BOLD%}$(git_current_branch)$(git_prompt_short_sha)$(git_prompt_status)%{$RESET_COLOR%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/junkfood.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/junkfood.zsh-theme
new file mode 100644 (file)
index 0000000..01fae4b
--- /dev/null
@@ -0,0 +1,30 @@
+# Totally ripped off Dallas theme
+
+# Grab the current date (%W) and time (%t):
+JUNKFOOD_TIME_="%{$fg_bold[red]%}#%{$fg_bold[white]%}( %{$fg_bold[yellow]%}%W%{$reset_color%}@%{$fg_bold[white]%}%t )( %{$reset_color%}"
+
+# Grab the current machine name 
+JUNKFOOD_MACHINE_="%{$fg_bold[blue]%}%m%{$fg[white]%} ):%{$reset_color%}"
+
+# Grab the current username 
+JUNKFOOD_CURRENT_USER_="%{$fg_bold[green]%}%n%{$reset_color%}"
+
+# Grab the current filepath, use shortcuts: ~/Desktop
+# Append the current git branch, if in a git repository: ~aw@master
+JUNKFOOD_LOCA_="%{$fg[cyan]%}%~\$(git_prompt_info)%{$reset_color%}"
+
+# For the git prompt, use a white @ and blue text for the branch name
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[white]%}@%{$fg_bold[white]%}"
+
+# Close it all off by resetting the color and styles.
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+
+# Do nothing if the branch is clean (no changes).
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}✔"
+
+# Add 3 cyan ✗s if this branch is diiirrrty! Dirty branch!
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%}✗✗✗"
+
+# Put it all together!
+PROMPT="$JUNKFOOD_TIME_$JUNKFOOD_CURRENT_USER_@$JUNKFOOD_MACHINE_$JUNKFOOD_LOCA_
+   "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/kafeitu.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/kafeitu.zsh-theme
new file mode 100644 (file)
index 0000000..af96f5e
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%}%n%{$fg[cyan]%}@%{$fg_bold[green]%}%m %{$fg_bold[green]%} %{$fg[cyan]%}%~ %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/kardan.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/kardan.zsh-theme
new file mode 100644 (file)
index 0000000..9a3d591
--- /dev/null
@@ -0,0 +1,12 @@
+# Simple theme based on my old zsh settings.
+
+function get_host {
+       echo '@'$HOST
+}
+
+PROMPT='> '
+RPROMPT='%~$(git_prompt_info)$(get_host)'
+
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_PREFIX="("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")"
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/kennethreitz.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/kennethreitz.zsh-theme
new file mode 100644 (file)
index 0000000..b255a8d
--- /dev/null
@@ -0,0 +1,15 @@
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+PROMPT='$(virtualenv_prompt_info)%{\e[03m%}%{$fg[green]%}%c \
+$(git_prompt_info)\
+\
+%{$fg[red]%}%(!.#.»)%{$reset_color%} '
+PROMPT2='%{$fg[red]%}\ %{$reset_color%}'
+RPS1='%{$fg[blue]%}%~%{$reset_color%} ${return_code} '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[yellow]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}*%{$fg[yellow]%}"
+ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX="%{$reset_color%}%{\e[03m%}%{$fg[blue]%}"
+ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX="!%{$reset_color%} "
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/kiwi.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/kiwi.zsh-theme
new file mode 100644 (file)
index 0000000..94f0ffc
--- /dev/null
@@ -0,0 +1,10 @@
+(( $+functions[battery_pct_prompt] )) || function battery_pct_prompt { }
+
+PROMPT='%{$fg_bold[green]%}┌[%{$fg_bold[cyan]%}kiwish-4.2%{$fg_bold[green]%}]-(%{$fg_bold[white]%}%2~%{$fg_bold[green]%})-$(git_prompt_info)$(svn_prompt_info)$(battery_pct_prompt)
+└> % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="[%{$reset_color%}%{$fg[white]%}git:%{$fg_bold[white]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg_bold[green]%}]-"
+
+ZSH_THEME_SVN_PROMPT_PREFIX="[%{$reset_color%}%{$fg[white]%}svn:%{$fg_bold[white]%}/"
+ZSH_THEME_SVN_PROMPT_SUFFIX="%{$fg_bold[green]%}]-"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/kolo.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/kolo.zsh-theme
new file mode 100644 (file)
index 0000000..e07be75
--- /dev/null
@@ -0,0 +1,24 @@
+autoload -Uz vcs_info
+
+zstyle ':vcs_info:*' stagedstr '%F{green}●'
+zstyle ':vcs_info:*' unstagedstr '%F{yellow}●'
+zstyle ':vcs_info:*' check-for-changes true
+zstyle ':vcs_info:svn:*' branchformat '%b'
+zstyle ':vcs_info:svn:*' formats ' [%b%F{1}:%F{11}%i%c%u%B%F{green}]'
+zstyle ':vcs_info:*' enable git svn
+
+theme_precmd () {
+  if [[ -z $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then
+    zstyle ':vcs_info:git:*' formats ' [%b%c%u%B%F{green}]'
+  else
+    zstyle ':vcs_info:git:*' formats ' [%b%c%u%B%F{red}●%F{green}]'
+  fi
+
+  vcs_info
+}
+
+setopt prompt_subst
+PROMPT='%B%F{magenta}%c%B%F{green}${vcs_info_msg_0_}%B%F{magenta} %{$reset_color%}%% '
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd  theme_precmd
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/kphoen.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/kphoen.zsh-theme
new file mode 100644 (file)
index 0000000..8e8894a
--- /dev/null
@@ -0,0 +1,43 @@
+# kphoen.zsh-theme
+
+if [[ "$TERM" != "dumb" ]] && [[ "$DISABLE_LS_COLORS" != "true" ]]; then
+    PROMPT='[%{$fg[red]%}%n%{$reset_color%}@%{$fg[magenta]%}%m%{$reset_color%}:%{$fg[blue]%}%~%{$reset_color%}$(git_prompt_info)]
+%# '
+
+    ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[green]%}"
+    ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+    ZSH_THEME_GIT_PROMPT_DIRTY=""
+    ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+    # display exitcode on the right when >0
+    return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+    RPROMPT='${return_code}$(git_prompt_status)%{$reset_color%}'
+
+    ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%} ✚"
+    ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[blue]%} ✹"
+    ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✖"
+    ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[magenta]%} ➜"
+    ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[yellow]%} ═"
+    ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ✭"
+else
+    PROMPT='[%n@%m:%~$(git_prompt_info)]
+%# '
+
+    ZSH_THEME_GIT_PROMPT_PREFIX=" on"
+    ZSH_THEME_GIT_PROMPT_SUFFIX=""
+    ZSH_THEME_GIT_PROMPT_DIRTY=""
+    ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+    # display exitcode on the right when >0
+    return_code="%(?..%? ↵)"
+
+    RPROMPT='${return_code}$(git_prompt_status)'
+
+    ZSH_THEME_GIT_PROMPT_ADDED=" ✚"
+    ZSH_THEME_GIT_PROMPT_MODIFIED=" ✹"
+    ZSH_THEME_GIT_PROMPT_DELETED=" ✖"
+    ZSH_THEME_GIT_PROMPT_RENAMED=" ➜"
+    ZSH_THEME_GIT_PROMPT_UNMERGED=" ═"
+    ZSH_THEME_GIT_PROMPT_UNTRACKED=" ✭"
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/lambda.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/lambda.zsh-theme
new file mode 100644 (file)
index 0000000..6e67773
--- /dev/null
@@ -0,0 +1,4 @@
+PROMPT='λ %~/ $(git_prompt_info)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/linuxonly.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/linuxonly.zsh-theme
new file mode 100644 (file)
index 0000000..98572b9
--- /dev/null
@@ -0,0 +1,58 @@
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+local c0=$(printf "\033[0m")
+local c1=$(printf "\033[38;5;215m")
+local c2=$(printf "\033[38;5;209m")
+local c3=$(printf "\033[38;5;203m")
+local c4=$(printf "\033[33;4m")
+local c5=$(printf "\033[38;5;137m")
+local c6=$(printf "\033[38;5;240m")
+local c7=$(printf "\033[38;5;149m")
+local c8=$(printf "\033[38;5;126m")
+local c9=$(printf "\033[38;5;162m")
+
+if [ "$TERM" = "linux" ]; then
+    c1=$(printf "\033[34;1m")
+    c2=$(printf "\033[35m")
+    c3=$(printf "\033[31m")
+    c4=$(printf "\033[31;1m")
+    c5=$(printf "\033[32m")
+    c6=$(printf "\033[32;1m")
+    c7=$(printf "\033[33m")
+    c8=$(printf "\033[33;1m")
+    c9=$(printf "\033[34m")
+fi
+
+zstyle ':vcs_info:*' actionformats \
+    '%{$c8%}(%f%s)%{$c7%}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '
+zstyle ':vcs_info:*' formats \
+    "%{$c8%}%s%{$c7%}:%{$c7%}(%{$c9%}%b%{$c7%})%f "
+zstyle ':vcs_info:*' enable git
+
+add-zsh-hook precmd prompt_jnrowe_precmd
+
+prompt_jnrowe_precmd () {
+    vcs_info
+
+    if [ "${vcs_info_msg_0_}" = "" ]; then
+        dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$c4%}%/ %{$c0%}(%{$c5%}%?%{$c0%})"
+        PROMPT='${dir_status} ${ret_status}%{$reset_color%}
+> '
+    elif [[ $(git diff --cached --name-status 2>/dev/null ) != "" ]]; then
+        dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$c4%}%/ %{$c0%}(%{$c5%}%?%{$c0%})"
+        PROMPT='${vcs_info_msg_0_}
+${dir_status} ${vcs_info_msg_0_}%{$reset_color%}
+> '
+    elif [[ $(git diff --name-status 2>/dev/null ) != "" ]]; then
+        dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$c4%}%/ %{$c0%}(%{$c5%}%?%{$c0%})"
+        PROMPT='${vcs_info_msg_0_}
+${dir_status}%{$reset_color%}
+%{$c9%}·>%{$c0%} '
+    else
+        dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$c4%}%/ %{$c0%}(%{$c5%}%?%{$c0%})"
+        PROMPT='${vcs_info_msg_0_}
+${dir_status} ${vcs_info_msg_0_}%{$reset_color%}
+> '
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/lukerandall.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/lukerandall.zsh-theme
new file mode 100644 (file)
index 0000000..cdecd28
--- /dev/null
@@ -0,0 +1,24 @@
+# ZSH Theme - Preview: https://cl.ly/f701d00760f8059e06dc
+# Thanks to gallifrey, upon whose theme this is based
+
+local return_code="%(?..%{$fg_bold[red]%}%? ↵%{$reset_color%})"
+
+function my_git_prompt_info() {
+  ref=$(git symbolic-ref HEAD 2> /dev/null) || return
+  GIT_STATUS=$(git_prompt_status)
+  [[ -n $GIT_STATUS ]] && GIT_STATUS=" $GIT_STATUS"
+  echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$GIT_STATUS$ZSH_THEME_GIT_PROMPT_SUFFIX"
+}
+
+PROMPT='%{$fg_bold[green]%}%n@%m%{$reset_color%} %{$fg_bold[blue]%}%2~%{$reset_color%} $(my_git_prompt_info)%{$reset_color%}%B»%b '
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=") %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%%"
+ZSH_THEME_GIT_PROMPT_ADDED="+"
+ZSH_THEME_GIT_PROMPT_MODIFIED="*"
+ZSH_THEME_GIT_PROMPT_RENAMED="~"
+ZSH_THEME_GIT_PROMPT_DELETED="!"
+ZSH_THEME_GIT_PROMPT_UNMERGED="?"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/macovsky-ruby.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/macovsky-ruby.zsh-theme
new file mode 120000 (symlink)
index 0000000..d3ee200
--- /dev/null
@@ -0,0 +1 @@
+macovsky.zsh-theme
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/macovsky.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/macovsky.zsh-theme
new file mode 100644 (file)
index 0000000..f527e58
--- /dev/null
@@ -0,0 +1,12 @@
+# ZSH Theme - Preview: https://i.gyazo.com/8becc8a7ed5ab54a0262a470555c3eed.png
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+PROMPT='%{$fg[green]%}%~%{$reset_color%} $(ruby_prompt_info) $(git_prompt_info)%{$reset_color%}%B$%b '
+RPROMPT="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
+
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="› %{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/maran.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/maran.zsh-theme
new file mode 100644 (file)
index 0000000..fddb7bc
--- /dev/null
@@ -0,0 +1,6 @@
+# Theme with full path names and hostname
+# Handy if you work on different servers all the time;
+PROMPT='%{$fg[cyan]%}%n%{$reset_color%}@%{$fg[yellow]%}%M:%{$fg[green]%}%/%{$reset_color%}$(git_prompt_info) %(!.#.$) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[cyan]%}git:("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mgutz.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mgutz.zsh-theme
new file mode 100644 (file)
index 0000000..dcf3270
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg_bold[magenta]%}%1~$(git_prompt_info) %{$fg_bold[magenta]%}%# %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[yellow]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="*]"
+ZSH_THEME_GIT_PROMPT_CLEAN="]"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mh.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mh.zsh-theme
new file mode 100644 (file)
index 0000000..2b2cc9b
--- /dev/null
@@ -0,0 +1,24 @@
+# mh theme
+# preview: https://cl.ly/1y2x0W0E3t2C0F29043z
+
+# features:
+# path is autoshortened to ~30 characters
+# displays git status (if applicable in current folder)
+# turns username green if superuser, otherwise it is white
+
+# if superuser make the username green
+if [ $UID -eq 0 ]; then NCOLOR="green"; else NCOLOR="white"; fi
+
+# prompt
+PROMPT='[%{$fg[$NCOLOR]%}%B%n%b%{$reset_color%}:%{$fg[red]%}%30<...<%~%<<%{$reset_color%}]%(!.#.$) '
+RPROMPT='$(git_prompt_info)'
+
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[gray]%}(%{$fg_no_bold[yellow]%}%B"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%b%{$fg_bold[gray]%})%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%}✱"
+
+# LS colors, made with https://geoff.greer.fm/lscolors/
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/michelebologna.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/michelebologna.zsh-theme
new file mode 100644 (file)
index 0000000..bb86d68
--- /dev/null
@@ -0,0 +1,79 @@
+# Michele Bologna's theme
+# https://www.michelebologna.net
+#
+# This a theme for oh-my-zsh. Features a colored prompt with:
+# * username@host: [jobs] [git] workdir %
+# * hostname color is based on hostname characters. When using as root, the
+# prompt shows only the hostname in red color.
+# * [jobs], if applicable, counts the number of suspended jobs tty
+# * [git], if applicable, represents the status of your git repo (more on that
+# later)
+# * '%' prompt will be green if last command return value is 0, yellow otherwise.
+#
+# git prompt is inspired by official git contrib prompt:
+# https://github.com/git/git/tree/master/contrib/completion/git-prompt.sh
+# and it adds:
+# * the current branch
+# * '%' if there are untracked files
+# * '$' if there are stashed changes
+# * '*' if there are modified files
+# * '+' if there are added files
+# * '<' if local repo is behind remote repo
+# * '>' if local repo is ahead remote repo
+# * '=' if local repo is equal to remote repo (in sync)
+# * '<>' if local repo is diverged
+
+local green="%{$fg_bold[green]%}"
+local red="%{$fg_bold[red]%}"
+local cyan="%{$fg_bold[cyan]%}"
+local yellow="%{$fg_bold[yellow]%}"
+local blue="%{$fg_bold[blue]%}"
+local magenta="%{$fg_bold[magenta]%}"
+local white="%{$fg_bold[white]%}"
+local reset="%{$reset_color%}"
+
+local -a color_array
+color_array=($green $red $cyan $yellow $blue $magenta $white)
+
+local username_color=$white
+local hostname_color=$color_array[$[((#HOST))%7+1]] # choose hostname color based on first character
+local current_dir_color=$blue
+
+local username="%n"
+local hostname="%m"
+local current_dir="%~"
+
+local username_output="%(!..${username_color}${username}${reset}@)"
+local hostname_output="${hostname_color}${hostname}${reset}"
+local current_dir_output="${current_dir_color}${current_dir}${reset}"
+local jobs_bg="${red}fg: %j$reset"
+local last_command_output="%(?.%(!.$red.$green).$yellow)"
+
+ZSH_THEME_GIT_PROMPT_PREFIX=""
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_UNTRACKED="$blue%%"
+ZSH_THEME_GIT_PROMPT_MODIFIED="$red*"
+ZSH_THEME_GIT_PROMPT_ADDED="$green+"
+ZSH_THEME_GIT_PROMPT_STASHED="$blue$"
+ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE="$green="
+ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE=">"
+ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE="<"
+ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE="$red<>"
+
+function michelebologna_git_prompt {
+  local out=$(git_prompt_info)$(git_prompt_status)$(git_remote_status)
+  [[ -n $out ]] || return
+  printf " %s(%s%s%s)%s" \
+    "%{$fg_bold[white]%}" \
+    "%{$fg_bold[green]%}" \
+    "$out" \
+    "%{$fg_bold[white]%}" \
+    "%{$reset_color%}"
+}
+
+PROMPT="$username_output$hostname_output:$current_dir_output%1(j. [$jobs_bg].)"
+PROMPT+='$(michelebologna_git_prompt)'
+PROMPT+=" $last_command_output%#$reset "
+RPROMPT=''
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mikeh.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mikeh.zsh-theme
new file mode 100644 (file)
index 0000000..f231b91
--- /dev/null
@@ -0,0 +1,21 @@
+setopt prompt_subst
+
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+# check-for-changes can be really slow.
+# you should disable it, if you work with large repositories
+zstyle ':vcs_info:*:prompt:*' check-for-changes true
+
+add-zsh-hook precmd mikeh_precmd
+
+mikeh_precmd() {
+    vcs_info
+}
+
+# user, host, full path, and time/date
+# on two lines for easier vgrepping
+# entry in a nice long thread on the Arch Linux forums: https://bbs.archlinux.org/viewtopic.php?pid=521888#p521888
+PROMPT=$'%{\e[0;34m%}%B..[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;30m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}'%D{"%a %b %d, %I:%M"}%b$'%{\e[0;34m%}%B]%b%{\e[0m%}
+%{\e[0;34m%}%B..%B[%{\e[1;35m%}$%{\e[0;34m%}%B] <($vcs_info_msg_0_)>%{\e[0m%}%b '
+PS2=$' \e[0;34m%}%B>%{\e[0m%}%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/miloshadzic.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/miloshadzic.zsh-theme
new file mode 100644 (file)
index 0000000..ad53944
--- /dev/null
@@ -0,0 +1,8 @@
+# Yay! High voltage and arrows!
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%}⚡%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+PROMPT='%{$fg[cyan]%}%1~%{$reset_color%}%{$fg[red]%}|%{$reset_color%}$(git_prompt_info)%{$fg[cyan]%}⇒%{$reset_color%} '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/minimal.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/minimal.zsh-theme
new file mode 100644 (file)
index 0000000..588ab69
--- /dev/null
@@ -0,0 +1,26 @@
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[white]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}●%{$fg[white]%}]%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN="]%{$reset_color%} "
+
+ZSH_THEME_SVN_PROMPT_PREFIX="$ZSH_THEME_GIT_PROMPT_PREFIX"
+ZSH_THEME_SVN_PROMPT_SUFFIX="$ZSH_THEME_GIT_PROMPT_SUFFIX"
+ZSH_THEME_SVN_PROMPT_DIRTY="$ZSH_THEME_GIT_PROMPT_DIRTY"
+ZSH_THEME_SVN_PROMPT_CLEAN="$ZSH_THEME_GIT_PROMPT_CLEAN"
+
+ZSH_THEME_HG_PROMPT_PREFIX="$ZSH_THEME_GIT_PROMPT_PREFIX"
+ZSH_THEME_HG_PROMPT_SUFFIX="$ZSH_THEME_GIT_PROMPT_SUFFIX"
+ZSH_THEME_HG_PROMPT_DIRTY="$ZSH_THEME_GIT_PROMPT_DIRTY"
+ZSH_THEME_HG_PROMPT_CLEAN="$ZSH_THEME_GIT_PROMPT_CLEAN"
+
+vcs_status() {
+  if (( ${+functions[in_svn]} )) && in_svn; then
+    svn_prompt_info
+  elif (( ${+functions[in_hg]} )) && in_hg; then
+    hg_prompt_info
+  else
+    git_prompt_info
+  fi
+}
+
+PROMPT='%2~ $(vcs_status)»%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mira.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mira.zsh-theme
new file mode 100644 (file)
index 0000000..a7c6035
--- /dev/null
@@ -0,0 +1,23 @@
+# Based on bira zsh theme with nvm, rvm and jenv support
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+local user_host='%{$terminfo[bold]$fg[green]%}%n@%m%{$reset_color%}'
+local current_dir='%{$terminfo[bold]$fg[blue]%} %~%{$reset_color%}'
+
+local nvm_node='%{$fg[green]%}‹node-$(nvm_prompt_info)›%{$reset_color%}'
+
+local jenv_java='%{$fg[blue]%}‹$(jenv_prompt_info)›%{$reset_color%}'
+
+local git_branch='$(git_prompt_info)'
+
+local rvm_ruby='$(ruby_prompt_info)'
+
+PROMPT="╭─${user_host} ${current_dir} ${nvm_node} ${rvm_ruby} ${jenv_java} ${git_branch}
+╰─%B$%b "
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=") %{$reset_color%}"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}‹"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="›%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mlh.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mlh.zsh-theme
new file mode 100644 (file)
index 0000000..baff3fb
--- /dev/null
@@ -0,0 +1,97 @@
+# The Official Theme of Major League Hacking
+
+##     ## ##       ##     ##
+###   ### ##       ##     ##
+#### #### ##       ##     ##
+## ### ## ##       #########
+##     ## ##       ##     ##
+##     ## ##       ##     ##
+##     ## ######## ##     ##
+
+# # # # # # # # # # # # # # # # # #
+# # # Feel free to customize! # # #
+# # # # # # # # # # # # # # # # # #
+
+# To customize symbols (e.g MLH_AT_SYMBOL), simply set them as environment variables
+# for example in your ~/.zshrc file, like this:
+# MLH_AT_SYMBOL=" at "
+# 
+# Settings *must* be set before sourcing oh-my-zsh.sh the .zshrc file.
+#
+# To easily discover colors and their codes, type `spectrum_ls` in the terminal
+
+# right prompt default settings
+if [ -z "$MLH_PRINT_EXIT_CODE" ]; then
+  MLH_PRINT_EXIT_CODE=true
+fi
+
+if [ -z "$MLH_PRINT_TIME" ]; then
+  MLH_PRINT_TIME=false
+fi
+
+# left prompt symbols default settings
+
+if [ -z "$MLH_AT_SYMBOL" ]; then
+  MLH_AT_SYMBOL="@"
+fi
+
+if [ -z "$MLH_IN_SYMBOL" ]; then
+  MLH_IN_SYMBOL=" in "
+fi
+
+if [ -z "$MLH_ON_SYMBOL" ]; then
+  MLH_ON_SYMBOL=" on "
+fi
+
+if [ -z "$MLH_SHELL_SYMBOL" ]; then
+  MLH_SHELL_SYMBOL="$ "
+fi
+
+# colors
+USER_COLOR="%F{001}"
+DEVICE_COLOR="%F{033}"
+DIR_COLOR="%F{220}"
+BRANCH_COLOR="%F{001}"
+TIME_COLOR="%F{033}"
+
+username() {
+  echo "$USER_COLOR%n%f"
+}
+
+# Prints device name
+device() {
+  echo "$DEVICE_COLOR%m%f"
+}
+
+# Prints the current directory
+directory() {
+  echo "$DIR_COLOR%1~%f"
+}
+
+# Prints current time
+current_time() {
+  if [ "$MLH_PRINT_TIME" = true ]; then
+    echo " $TIME_COLOR%*%f"
+  fi
+}
+
+# Prints exit code of the last executed command
+exit_code() {
+  if [ "$MLH_PRINT_EXIT_CODE" = true ]; then
+    echo "%(?..%F{001}exit %?)%f"
+  fi
+}
+
+prompt_end() {
+  printf "\n$MLH_SHELL_SYMBOL"
+}
+
+# Set git_prompt_info text
+ZSH_THEME_GIT_PROMPT_PREFIX="${MLH_ON_SYMBOL}${BRANCH_COLOR}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%f"
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+# %B and %b make the text bold
+PROMPT='%b$(username)$MLH_AT_SYMBOL$(device)$MLH_IN_SYMBOL$(directory)$(git_prompt_info)%b$(prompt_end)'
+RPROMPT="$(exit_code)$(current_time)"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mortalscumbag.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mortalscumbag.zsh-theme
new file mode 100644 (file)
index 0000000..d81a7ca
--- /dev/null
@@ -0,0 +1,65 @@
+function my_git_prompt() {
+  tester=$(git rev-parse --git-dir 2> /dev/null) || return
+  
+  INDEX=$(git status --porcelain 2> /dev/null)
+  STATUS=""
+
+  # is branch ahead?
+  if $(echo "$(git log origin/$(git_current_branch)..HEAD 2> /dev/null)" | grep '^commit' &> /dev/null); then
+    STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD"
+  fi
+
+  # is branch behind?
+  if $(echo "$(git log HEAD..origin/$(git_current_branch) 2> /dev/null)" | grep '^commit' &> /dev/null); then
+    STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND"
+  fi
+
+  # is anything staged?
+  if $(echo "$INDEX" | command grep -E -e '^(D[ M]|[MARC][ MD]) ' &> /dev/null); then
+    STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED"
+  fi
+
+  # is anything unstaged?
+  if $(echo "$INDEX" | command grep -E -e '^[ MARC][MD] ' &> /dev/null); then
+    STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNSTAGED"
+  fi
+
+  # is anything untracked?
+  if $(echo "$INDEX" | grep '^?? ' &> /dev/null); then
+    STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED"
+  fi
+
+  # is anything unmerged?
+  if $(echo "$INDEX" | command grep -E -e '^(A[AU]|D[DU]|U[ADU]) ' &> /dev/null); then
+    STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNMERGED"
+  fi
+
+  if [[ -n $STATUS ]]; then
+    STATUS=" $STATUS"
+  fi
+
+  echo "$ZSH_THEME_GIT_PROMPT_PREFIX$(my_current_branch)$STATUS$ZSH_THEME_GIT_PROMPT_SUFFIX"
+}
+
+function my_current_branch() {
+  echo $(git_current_branch || echo "(no branch)")
+}
+
+function ssh_connection() {
+  if [[ -n $SSH_CONNECTION ]]; then
+    echo "%{$fg_bold[red]%}(ssh) "
+  fi
+}
+
+local ret_status="%(?:%{$fg_bold[green]%}:%{$fg_bold[red]%})%?%{$reset_color%}"
+PROMPT=$'\n$(ssh_connection)%{$fg_bold[green]%}%n@%m%{$reset_color%}$(my_git_prompt) : %~\n[${ret_status}] %# '
+
+ZSH_THEME_PROMPT_RETURNCODE_PREFIX="%{$fg_bold[red]%}"
+ZSH_THEME_GIT_PROMPT_PREFIX=" $fg[white]‹ %{$fg_bold[yellow]%}"
+ZSH_THEME_GIT_PROMPT_AHEAD="%{$fg_bold[magenta]%}↑"
+ZSH_THEME_GIT_PROMPT_BEHIND="%{$fg_bold[green]%}↓"
+ZSH_THEME_GIT_PROMPT_STAGED="%{$fg_bold[green]%}●"
+ZSH_THEME_GIT_PROMPT_UNSTAGED="%{$fg_bold[red]%}●"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg_bold[white]%}●"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg_bold[red]%}✕"
+ZSH_THEME_GIT_PROMPT_SUFFIX=" $fg_bold[white]›%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/mrtazz.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/mrtazz.zsh-theme
new file mode 100644 (file)
index 0000000..214ba5a
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT='%{$fg_bold[red]%}%m%{$reset_color%}:%{$fg[cyan]%}%c%{$reset_color%}:%# '
+RPROMPT='%{$fg_bold[green]%}$(git_prompt_info)%{$reset_color%}% '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="<%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%} %{$fg[yellow]%}✗%{$fg[green]%}>%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%}>"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/murilasso.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/murilasso.zsh-theme
new file mode 100644 (file)
index 0000000..d46874c
--- /dev/null
@@ -0,0 +1,14 @@
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+local user_host='%{$terminfo[bold]$fg[green]%}%n@%m%{$reset_color%}'
+local current_dir='%{$terminfo[bold]$fg[blue]%}%~%{$reset_color%}'
+local rvm_ruby='%{$fg[red]%}$(ruby_prompt_info)%{$reset_color%}'
+local git_branch='%{$fg[blue]%}$(git_prompt_info)%{$reset_color%}'
+
+PROMPT="${user_host}:${current_dir} ${rvm_ruby}
+${git_branch} %B$%b "
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX=""
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/muse.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/muse.zsh-theme
new file mode 100644 (file)
index 0000000..84bee52
--- /dev/null
@@ -0,0 +1,16 @@
+PROMPT="${FG[117]}%~%{$reset_color%}\$(git_prompt_info)\$(virtualenv_prompt_info)${FG[133]}\$(git_prompt_status) ${FG[077]}ᐅ%{$reset_color%} "
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" ${FG[012]}("
+ZSH_THEME_GIT_PROMPT_SUFFIX="${FG[012]})%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" ${FG[133]}✘"
+ZSH_THEME_GIT_PROMPT_CLEAN=" ${FG[118]}✔"
+
+ZSH_THEME_GIT_PROMPT_ADDED="${FG[082]}✚%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_MODIFIED="${FG[166]}✹%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DELETED="${FG[160]}✖%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_RENAMED="${FG[220]}➜%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNMERGED="${FG[082]}═%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="${FG[190]}✭%{$reset_color%}"
+
+ZSH_THEME_VIRTUALENV_PREFIX=" ["
+ZSH_THEME_VIRTUALENV_SUFFIX="]"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/nanotech.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/nanotech.zsh-theme
new file mode 100644 (file)
index 0000000..5d33316
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT='%F{green}%2c%F{blue} [%f '
+RPROMPT='$(git_prompt_info) %F{blue}] %F{green}%D{%L:%M} %F{yellow}%D{%p}%f'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%F{yellow}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%f"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %F{red}*%f"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/nebirhos.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/nebirhos.zsh-theme
new file mode 100644 (file)
index 0000000..fc05e79
--- /dev/null
@@ -0,0 +1,21 @@
+# Based on robbyrussell's theme, with host and rvm indicators. Example:
+# @host ➜ currentdir rvm:(rubyversion@gemset) git:(branchname)
+
+# Get the current ruby version in use with RVM:
+if [ -e ~/.rvm/bin/rvm-prompt ]; then
+    RUBY_PROMPT_="%{$fg_bold[blue]%}rvm:(%{$fg[green]%}\$(~/.rvm/bin/rvm-prompt s i v g)%{$fg_bold[blue]%})%{$reset_color%} "
+else
+  if which rbenv &> /dev/null; then
+    RUBY_PROMPT_="%{$fg_bold[blue]%}rbenv:(%{$fg[green]%}\$(rbenv version | sed -e 's/ (set.*$//')%{$fg_bold[blue]%})%{$reset_color%} "
+  fi
+fi
+
+# Get the host name (first 4 chars)
+HOST_PROMPT_="%{$fg_bold[red]%}@%m ➜ %{$fg_bold[cyan]%}%c "
+GIT_PROMPT="%{$fg_bold[blue]%}\$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}"
+PROMPT="$HOST_PROMPT_$RUBY_PROMPT_$GIT_PROMPT"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/nicoulaj.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/nicoulaj.zsh-theme
new file mode 100644 (file)
index 0000000..685cd1a
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env zsh
+# ------------------------------------------------------------------------------
+# Prompt for the Zsh shell:
+#   * One line.
+#   * VCS info on the right prompt.
+#   * Only shows the path on the left prompt by default.
+#   * Crops the path to a defined length and only shows the path relative to
+#     the current VCS repository root.
+#   * Wears a different color whether the last command succeeded/failed.
+#   * Shows user@hostname if connected through SSH.
+#   * Shows if logged in as root or not.
+# ------------------------------------------------------------------------------
+
+# Customizable parameters.
+PROMPT_PATH_MAX_LENGTH=30
+PROMPT_DEFAULT_END=❯
+PROMPT_ROOT_END=❯❯❯
+PROMPT_SUCCESS_COLOR=$FG[071]
+PROMPT_FAILURE_COLOR=$FG[124]
+PROMPT_VCS_INFO_COLOR=$FG[242]
+
+# Set required options.
+setopt promptsubst
+
+# Load required modules.
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+# Add hook for calling vcs_info before each command.
+add-zsh-hook precmd vcs_info
+
+# Set vcs_info parameters.
+zstyle ':vcs_info:*' enable hg bzr git
+zstyle ':vcs_info:*:*' check-for-changes true # Can be slow on big repos.
+zstyle ':vcs_info:*:*' unstagedstr '!'
+zstyle ':vcs_info:*:*' stagedstr '+'
+zstyle ':vcs_info:*:*' actionformats "%S" "%r/%s/%b %u%c (%a)"
+zstyle ':vcs_info:*:*' formats "%S" "%r/%s/%b %u%c"
+zstyle ':vcs_info:*:*' nvcsformats "%~" ""
+
+# Define prompts.
+PROMPT="%(0?.%{$PROMPT_SUCCESS_COLOR%}.%{$PROMPT_FAILURE_COLOR%})${SSH_TTY:+[%n@%m]}%{$FX[bold]%}%$PROMPT_PATH_MAX_LENGTH<..<"'${vcs_info_msg_0_%%.}'"%<<%(!.$PROMPT_ROOT_END.$PROMPT_DEFAULT_END)%{$FX[no-bold]%}%{$FX[reset]%} "
+RPROMPT="%{$PROMPT_VCS_INFO_COLOR%}"'$vcs_info_msg_1_'"%{$FX[reset]%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/norm.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/norm.zsh-theme
new file mode 100644 (file)
index 0000000..bd7ca56
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT='%{$fg[yellow]%}λ %m %{$fg[green]%}%c %{$fg[yellow]%}→ $(git_prompt_info)$(hg_prompt_info)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="λ %{$fg[blue]%}git %{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg[yellow]%} → %{$reset_color%}"
+ZSH_THEME_HG_PROMPT_PREFIX="λ %{$fg[blue]%}hg %{$fg[red]%}"
+ZSH_THEME_HG_PROMPT_SUFFIX="%{$fg[yellow]%} → %{$reset_color%}"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/obraun.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/obraun.zsh-theme
new file mode 100644 (file)
index 0000000..c64362b
--- /dev/null
@@ -0,0 +1,10 @@
+if [ "$USERNAME" = "root" ]; then CARETCOLOR="red"; else CARETCOLOR="blue"; fi
+
+local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+PROMPT='%{$fg[green]%}[%D{%H:%M:%S}]%{$reset_color%} %{$fg_no_bold[cyan]%}%n %{${fg_bold[blue]}%}::%{$reset_color%} %{$fg[yellow]%}%m%{$reset_color%} %{$fg_no_bold[magenta]%} ➜ %{$reset_color%} %{${fg[green]}%}%3~ $(git_prompt_info)%{${fg_bold[$CARETCOLOR]}%}»%{${reset_color}%} '
+
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[red]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/peepcode.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/peepcode.zsh-theme
new file mode 100644 (file)
index 0000000..0445346
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Based on Geoffrey Grosenbach's peepcode zsh theme from
+# https://github.com/topfunky/zsh-simple
+#
+
+git_repo_path() {
+  command git rev-parse --git-dir 2>/dev/null
+}
+
+git_commit_id() {
+  command git rev-parse --short HEAD 2>/dev/null
+}
+
+git_mode() {
+  if [[ -e "$repo_path/BISECT_LOG" ]]; then
+    echo "+bisect"
+  elif [[ -e "$repo_path/MERGE_HEAD" ]]; then
+    echo "+merge"
+  elif [[ -e "$repo_path/rebase" || -e "$repo_path/rebase-apply" || -e "$repo_path/rebase-merge" || -e "$repo_path/../.dotest" ]]; then
+    echo "+rebase"
+  fi
+}
+
+git_dirty() {
+  if [[ "$repo_path" != '.' && -n "$(command git ls-files -m)" ]]; then
+    echo " %{$fg_bold[grey]%}✗%{$reset_color%}"
+  fi
+}
+
+git_prompt() {
+  local cb=$(git_current_branch)
+  if [[ -n "$cb" ]]; then
+    local repo_path=$(git_repo_path)
+    echo " %{$fg_bold[grey]%}$cb %{$fg[white]%}$(git_commit_id)%{$reset_color%}$(git_mode)$(git_dirty)"
+  fi
+}
+
+local smiley='%(?.%F{green}☺%f.%F{red}☹%f)'
+
+PROMPT='
+${VIRTUAL_ENV:+"($VIRTUAL_ENV) "}%~
+${smiley}  '
+
+RPROMPT='%F{white} $(ruby_prompt_info)$(git_prompt)%{$reset_color%}'
+
+# Disable automatic virtualenv prompt change
+export VIRTUAL_ENV_DISABLE_PROMPT=1
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/philips.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/philips.zsh-theme
new file mode 100644 (file)
index 0000000..fec734b
--- /dev/null
@@ -0,0 +1,14 @@
+if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="green"; fi
+
+PROMPT='%{$fg[$NCOLOR]%}%B%n%b%{$reset_color%}:%{$fg[blue]%}%B%c/%b%{$reset_color%} $(git_prompt_info)%(!.#.$) '
+RPROMPT='[%*]'
+
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}(%{$fg_no_bold[red]%}%B"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%b%{$fg_bold[blue]%})%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="*"
+
+# LS colors, made with https://geoff.greer.fm/lscolors/
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:*.patch=00;34:*.o=00;32:*.so=01;35:*.ko=01;31:*.la=00;33'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/pmcgee.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/pmcgee.zsh-theme
new file mode 100644 (file)
index 0000000..58a9b8b
--- /dev/null
@@ -0,0 +1,16 @@
+if [ $UID -eq 0 ]; then NCOLOR="red"; else NCOLOR="green"; fi
+
+PROMPT='
+%{$fg[$NCOLOR]%}%B%n@%m%b%{$reset_color%} %{$fg[white]%}%B${PWD/#$HOME/~}%b%{$reset_color%}
+$(git_prompt_info)%(!.#.$) '
+RPROMPT='[%*]'
+
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_no_bold[yellow]%}%B"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%}*"
+
+# LS colors, made with https://geoff.greer.fm/lscolors/
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/pygmalion-virtualenv.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/pygmalion-virtualenv.zsh-theme
new file mode 100644 (file)
index 0000000..c2ab7f4
--- /dev/null
@@ -0,0 +1,54 @@
+# Yay! High voltage and arrows!
+
+
+function _virtualenv_prompt_info {
+    if [[ -n "$(whence virtualenv_prompt_info)" ]]; then
+        if [ -n "$(whence pyenv_prompt_info)" ]; then
+            if [ "$1" = "inline" ]; then
+                ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX=%{$fg[blue]%}"::%{$fg[red]%}"
+                ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX=""
+                virtualenv_prompt_info
+            fi
+            [ "$(pyenv_prompt_info)" = "${PYENV_PROMPT_DEFAULT_VERSION}" ] && virtualenv_prompt_info
+        else
+            virtualenv_prompt_info
+        fi
+    fi
+}
+
+prompt_setup_pygmalion(){
+  setopt localoptions extendedglob
+
+  ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[green]%}"
+  ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+  ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%}⚡%{$reset_color%}"
+  ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+  base_prompt='$(_virtualenv_prompt_info)%{$fg[magenta]%}%n%{$reset_color%}%{$fg[cyan]%}@%{$reset_color%}%{$fg[yellow]%}%m%{$reset_color%}%{$fg[red]%}:%{$reset_color%}%{$fg[cyan]%}%0~%{$reset_color%}%{$fg[red]%}|%{$reset_color%}'
+  post_prompt='%{$fg[cyan]%}⇒%{$reset_color%}  '
+
+  base_prompt_nocolor=${base_prompt//\%\{[^\}]##\}}
+  post_prompt_nocolor=${post_prompt//\%\{[^\}]##\}}
+
+  autoload -U add-zsh-hook
+  add-zsh-hook precmd prompt_pygmalion_precmd
+}
+
+prompt_pygmalion_precmd(){
+  setopt localoptions nopromptsubst extendedglob
+
+  local gitinfo=$(git_prompt_info)
+  local gitinfo_nocolor=${gitinfo//\%\{[^\}]##\}}
+  local exp_nocolor="$(print -P \"${base_prompt_nocolor}${gitinfo_nocolor}${post_prompt_nocolor}\")"
+  local prompt_length=${#exp_nocolor}
+
+  # add new line on prompt longer than 40 characters
+  local nl=""
+  if [[ $prompt_length -gt 40 ]]; then
+    nl=$'\n%{\r%}'
+  fi
+
+  PROMPT="${base_prompt}\$(git_prompt_info)${nl}${post_prompt}"
+}
+
+prompt_setup_pygmalion
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/pygmalion.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/pygmalion.zsh-theme
new file mode 100644 (file)
index 0000000..be9ca38
--- /dev/null
@@ -0,0 +1,32 @@
+# Yay! High voltage and arrows!
+
+prompt_setup_pygmalion(){
+  setopt localoptions extendedglob
+
+  ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[green]%}"
+  ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+  ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%}⚡%{$reset_color%}"
+  ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+  base_prompt='%{$fg[magenta]%}%n%{$reset_color%}%{$fg[cyan]%}@%{$reset_color%}%{$fg[yellow]%}%m%{$reset_color%}%{$fg[red]%}:%{$reset_color%}%{$fg[cyan]%}%0~%{$reset_color%}%{$fg[red]%}|%{$reset_color%}'
+  post_prompt='%{$fg[cyan]%}⇒%{$reset_color%}  '
+
+  base_prompt_nocolor=${base_prompt//\%\{[^\}]##\}}
+  post_prompt_nocolor=${post_prompt//\%\{[^\}]##\}}
+
+  autoload -U add-zsh-hook
+  add-zsh-hook precmd prompt_pygmalion_precmd
+}
+
+prompt_pygmalion_precmd(){
+  setopt localoptions nopromptsubst extendedglob
+
+  local gitinfo=$(git_prompt_info)
+  local gitinfo_nocolor=${gitinfo//\%\{[^\}]##\}}
+  local exp_nocolor="$(print -P \"${base_prompt_nocolor}${gitinfo_nocolor}${post_prompt_nocolor}\")"
+  local prompt_length=${#exp_nocolor}
+
+  PROMPT="${base_prompt}\$(git_prompt_info)${post_prompt}"
+}
+
+prompt_setup_pygmalion
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/random.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/random.zsh-theme
new file mode 100644 (file)
index 0000000..28af84e
--- /dev/null
@@ -0,0 +1,47 @@
+# Deprecate ZSH_THEME_RANDOM_BLACKLIST
+if [[ -n "$ZSH_THEME_RANDOM_BLACKLIST" ]]; then
+  echo '[oh-my-zsh] ZSH_THEME_RANDOM_BLACKLIST is deprecated. Use `ZSH_THEME_RANDOM_IGNORED` instead.'
+  ZSH_THEME_RANDOM_IGNORED=($ZSH_THEME_RANDOM_BLACKLIST)
+  unset ZSH_THEME_RANDOM_BLACKLIST
+fi
+
+# Make themes a unique array
+typeset -Ua themes
+
+if [[ "${(t)ZSH_THEME_RANDOM_CANDIDATES}" = array && ${#ZSH_THEME_RANDOM_CANDIDATES[@]} -gt 0 ]]; then
+  # Use ZSH_THEME_RANDOM_CANDIDATES if properly defined
+  themes=(${(@)ZSH_THEME_RANDOM_CANDIDATES:#random})
+else
+  # Look for themes in $ZSH_CUSTOM and $ZSH and add only the theme name
+  themes=(
+    "$ZSH_CUSTOM"/*.zsh-theme(N:t:r)
+    "$ZSH_CUSTOM"/themes/*.zsh-theme(N:t:r)
+    "$ZSH"/themes/*.zsh-theme(N:t:r)
+  )
+  # Remove ignored themes from the list
+  for theme in random ${ZSH_THEME_RANDOM_IGNORED[@]}; do
+    themes=("${(@)themes:#$theme}")
+  done
+fi
+
+# Choose a theme out of the pool of candidates
+N=${#themes[@]}
+(( N = (RANDOM%N) + 1 ))
+RANDOM_THEME="${themes[$N]}"
+unset N themes theme
+
+# Source theme
+if [[ -f "$ZSH_CUSTOM/$RANDOM_THEME.zsh-theme" ]]; then
+  source "$ZSH_CUSTOM/$RANDOM_THEME.zsh-theme"
+elif [[ -f "$ZSH_CUSTOM/themes/$RANDOM_THEME.zsh-theme" ]]; then
+  source "$ZSH_CUSTOM/themes/$RANDOM_THEME.zsh-theme"
+elif [[ -f "$ZSH/themes/$RANDOM_THEME.zsh-theme" ]]; then
+  source "$ZSH/themes/$RANDOM_THEME.zsh-theme"
+else
+  echo "[oh-my-zsh] Random theme '${RANDOM_THEME}' not found"
+  return 1
+fi
+
+if [[ "$ZSH_THEME_RANDOM_QUIET" != true ]]; then
+  echo "[oh-my-zsh] Random theme '${RANDOM_THEME}' loaded"
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/re5et.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/re5et.zsh-theme
new file mode 100644 (file)
index 0000000..bdf342f
--- /dev/null
@@ -0,0 +1,15 @@
+if [ "$USERNAME" = "root" ]; then CARETCOLOR="red"; else CARETCOLOR="magenta"; fi
+
+local return_code="%(?..%{$fg_bold[red]%}:( %?%{$reset_color%})"
+
+PROMPT='
+%{$fg_bold[cyan]%}%n%{$reset_color%}%{$fg[yellow]%}@%{$reset_color%}%{$fg_bold[blue]%}%m%{$reset_color%}:%{${fg_bold[green]}%}%~%{$reset_color%}$(git_prompt_info)
+%{${fg[$CARETCOLOR]}%}%# %{${reset_color}%}'
+
+RPS1='${return_code} %D - %*'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[magenta]%}^%{$reset_color%}%{$fg_bold[yellow]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%} ±"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ?"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[red]%} ♥"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/refined.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/refined.zsh-theme
new file mode 100644 (file)
index 0000000..5e2de7a
--- /dev/null
@@ -0,0 +1,108 @@
+#!/usr/bin/env zsh
+
+# ------------------------------------------------------------------------------
+#
+# Pure - A minimal and beautiful theme for oh-my-zsh
+#
+# Based on the custom Zsh-prompt of the same name by Sindre Sorhus. A huge
+# thanks goes out to him for designing the fantastic Pure prompt in the first
+# place! I'd also like to thank Julien Nicoulaud for his "nicoulaj" theme from
+# which I've borrowed both some ideas and some actual code. You can find out
+# more about both of these fantastic two people here:
+#
+# Sindre Sorhus
+#   Github:   https://github.com/sindresorhus
+#   Twitter:  https://twitter.com/sindresorhus
+#
+# Julien Nicoulaud
+#   Github:   https://github.com/nicoulaj
+#   Twitter:  https://twitter.com/nicoulaj
+#
+# ------------------------------------------------------------------------------
+
+# Set required options
+#
+setopt prompt_subst
+
+# Load required modules
+#
+autoload -Uz vcs_info
+
+# Set vcs_info parameters
+#
+zstyle ':vcs_info:*' enable hg bzr git
+zstyle ':vcs_info:*:*' unstagedstr '!'
+zstyle ':vcs_info:*:*' stagedstr '+'
+zstyle ':vcs_info:*:*' formats "$FX[bold]%r$FX[no-bold]/%S" "%s:%b" "%%u%c"
+zstyle ':vcs_info:*:*' actionformats "$FX[bold]%r$FX[no-bold]/%S" "%s:%b" "%u%c (%a)"
+zstyle ':vcs_info:*:*' nvcsformats "%~" "" ""
+
+# Fastest possible way to check if repo is dirty
+#
+git_dirty() {
+    # Check if we're in a git repo
+    command git rev-parse --is-inside-work-tree &>/dev/null || return
+    # Check if it's dirty
+    command git diff --quiet --ignore-submodules HEAD &>/dev/null; [ $? -eq 1 ] && echo "*"
+}
+
+# Display information about the current repository
+#
+repo_information() {
+    echo "%F{blue}${vcs_info_msg_0_%%/.} %F{8}$vcs_info_msg_1_`git_dirty` $vcs_info_msg_2_%f"
+}
+
+# Displays the exec time of the last command if set threshold was exceeded
+#
+cmd_exec_time() {
+    local stop=`date +%s`
+    local start=${cmd_timestamp:-$stop}
+    let local elapsed=$stop-$start
+    [ $elapsed -gt 5 ] && echo ${elapsed}s
+}
+
+# Get the initial timestamp for cmd_exec_time
+#
+preexec() {
+    cmd_timestamp=`date +%s`
+}
+
+# Output additional information about paths, repos and exec time
+#
+precmd() {
+    setopt localoptions nopromptsubst
+    vcs_info # Get version control info before we start outputting stuff
+    print -P "\n$(repo_information) %F{yellow}$(cmd_exec_time)%f"
+    unset cmd_timestamp #Reset cmd exec time.
+}
+
+# Define prompts
+#
+PROMPT="%(?.%F{magenta}.%F{red})❯%f " # Display a red prompt char on failure
+RPROMPT="%F{8}${SSH_TTY:+%n@%m}%f"    # Display username if connected via SSH
+
+# ------------------------------------------------------------------------------
+#
+# List of vcs_info format strings:
+#
+# %b => current branch
+# %a => current action (rebase/merge)
+# %s => current version control system
+# %r => name of the root directory of the repository
+# %S => current path relative to the repository root directory
+# %m => in case of Git, show information about stashes
+# %u => show unstaged changes in the repository
+# %c => show staged changes in the repository
+#
+# List of prompt format strings:
+#
+# prompt:
+# %F => color dict
+# %f => reset color
+# %~ => current path
+# %* => time
+# %n => username
+# %m => shortname host
+# %(?..) => prompt conditional - %(condition.true.false)
+#
+# ------------------------------------------------------------------------------
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/rgm.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/rgm.zsh-theme
new file mode 100644 (file)
index 0000000..9452a8b
--- /dev/null
@@ -0,0 +1,8 @@
+PROMPT='
+%n@%m %{$fg[cyan]%}%~
+%? $(git_prompt_info)%{$fg_bold[blue]%}%% %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/risto.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/risto.zsh-theme
new file mode 100644 (file)
index 0000000..cb773a6
--- /dev/null
@@ -0,0 +1,6 @@
+# -*- sh -*- vim:set ft=sh ai et sw=4 sts=4:
+# It might be bash like, but I can't have my co-workers knowing I use zsh
+PROMPT='%{$fg[green]%}%n@%m:%{$fg_bold[blue]%}%2~ $(git_prompt_info)%{$reset_color%}%(!.#.$) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[red]%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="›%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/rixius.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/rixius.zsh-theme
new file mode 100644 (file)
index 0000000..b33f23e
--- /dev/null
@@ -0,0 +1,21 @@
+# name in folder (github)
+# ± if in github repo, or ≥ if otherwise Time in 24-hour format is on right.
+function collapse_pwd {
+    echo $(pwd | sed -e "s,^$HOME,~,")
+}
+function prompt_char {
+    echo -n "%{$bg[white]%}%{$fg[red]%}"
+    git branch >/dev/null 2>/dev/null && echo "±%{$reset_color%}" && return
+    echo "≥%{$reset_color%}"
+}
+RIXIUS_PRE="%{$bg[white]%}%{$fg[red]%}"
+
+PROMPT='
+%{$RIXIUS_PRE%}%n%{$reset_color%} in %{$fg_bold[green]%}$(collapse_pwd)%{$reset_color%}$(git_prompt_info)
+$(prompt_char) '
+RPROMPT='%{$RIXIUS_PRE%}%T%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[magenta]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$RIXIUS_PRE%}!%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$RIXIUS_PRE%}√%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/rkj-repos.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/rkj-repos.zsh-theme
new file mode 100644 (file)
index 0000000..3cb4523
--- /dev/null
@@ -0,0 +1,35 @@
+# user, host, full path, and time/date on two lines for easier vgrepping
+
+function hg_prompt_info {
+  if (( $+commands[hg] )) && grep -q "prompt" ~/.hgrc; then
+    hg prompt --angle-brackets "\
+<hg:%{$fg[magenta]%}<branch>%{$reset_color%}><:%{$fg[magenta]%}<bookmark>%{$reset_color%}>\
+</%{$fg[yellow]%}<tags|%{$reset_color%}, %{$fg[yellow]%}>%{$reset_color%}>\
+%{$fg[red]%}<status|modified|unknown><update>%{$reset_color%}<
+patches: <patches|join( → )|pre_applied(%{$fg[yellow]%})|post_applied(%{$reset_color%})|pre_unapplied(%{$fg_bold[black]%})|post_unapplied(%{$reset_color%})>>" 2>/dev/null
+  fi
+}
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[cyan]%}+"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%}✱"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%}✗"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%}➦"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[magenta]%}✂"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[blue]%}✈"
+ZSH_THEME_GIT_PROMPT_SHA_BEFORE=" %{$fg[blue]%}"
+ZSH_THEME_GIT_PROMPT_SHA_AFTER="%{$reset_color%}"
+
+function mygit() {
+  if [[ "$(git config --get oh-my-zsh.hide-status)" != "1" ]]; then
+    ref=$(command git symbolic-ref HEAD 2> /dev/null) || \
+    ref=$(command git rev-parse --short HEAD 2> /dev/null) || return
+    echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(git_prompt_short_sha)$(git_prompt_status)%{$fg_bold[blue]%}$ZSH_THEME_GIT_PROMPT_SUFFIX "
+  fi
+}
+
+function retcode() {}
+
+# alternate prompt with git & hg
+PROMPT=$'%{$fg_bold[blue]%}┌─[%{$fg_bold[green]%}%n%b%{$fg[black]%}@%{$fg[cyan]%}%m%{$fg_bold[blue]%}]%{$reset_color%} - %{$fg_bold[blue]%}[%{$fg_bold[default]%}%~%{$fg_bold[blue]%}]%{$reset_color%} - %{$fg_bold[blue]%}[%b%{$fg[yellow]%}'%D{"%Y-%m-%d %I:%M:%S"}%b$'%{$fg_bold[blue]%}]
+%{$fg_bold[blue]%}└─[%{$fg_bold[magenta]%}%?$(retcode)%{$fg_bold[blue]%}] <$(mygit)$(hg_prompt_info)>%{$reset_color%} '
+PS2=$' \e[0;34m%}%B>%{\e[0m%}%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/rkj.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/rkj.zsh-theme
new file mode 100644 (file)
index 0000000..d7c9314
--- /dev/null
@@ -0,0 +1,9 @@
+# user, host, full path, and time/date
+# on two lines for easier vgrepping
+# entry in a nice long thread on the Arch Linux forums: https://bbs.archlinux.org/viewtopic.php?pid=521888#p521888
+
+function retcode() {}
+
+PROMPT=$'%{\e[0;34m%}%B┌─[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;30m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}'%D{"%Y-%m-%d %I:%M:%S"}%b$'%{\e[0;34m%}%B]%b%{\e[0m%}
+%{\e[0;34m%}%B└─%B[%{\e[1;35m%}%?$(retcode)%{\e[0;34m%}%B]%{\e[0m%}%b '
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/robbyrussell.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/robbyrussell.zsh-theme
new file mode 100644 (file)
index 0000000..2fd5f2c
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ )"
+PROMPT+=' %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/sammy.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/sammy.zsh-theme
new file mode 100644 (file)
index 0000000..52e6e4b
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%{$fg[white]%}%c$(git_prompt_info)$ % %{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="("
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY="*)"
+ZSH_THEME_GIT_PROMPT_CLEAN=")"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/simonoff.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/simonoff.zsh-theme
new file mode 100644 (file)
index 0000000..287781d
--- /dev/null
@@ -0,0 +1,99 @@
+function theme_precmd {
+  PR_FILLBAR=""
+  PR_PWDLEN=""
+
+  local promptsize=${#${(%):--(%n@%M:)--(%l)-}}
+  local pwdsize=${#${(%):-%~}}
+  local gitbranchsize="${#${(%)$(git_prompt_info)}:-}"
+  local rvmpromptsize="${#${(%)$(ruby_prompt_info):-}}"
+
+  # Truncate the path if it's too long.
+  if (( promptsize + pwdsize + rvmpromptsize + gitbranchsize > COLUMNS )); then
+    (( PR_PWDLEN = COLUMNS - promptsize ))
+  else
+    PR_FILLBAR="\${(l.$(( COLUMNS - (promptsize + pwdsize + rvmpromptsize + gitbranchsize) ))..${PR_SPACE}.)}"
+  fi
+}
+
+function theme_preexec {
+  setopt local_options extended_glob
+  if [[ "$TERM" == "screen" ]]; then
+    local CMD=${1[(wr)^(*=*|sudo|-*)]}
+    echo -n "\ek$CMD\e\\"
+  fi
+
+  if [[ "$TERM" == "xterm" ]]; then
+    print -Pn "\e]0;$1\a"
+  fi
+
+  if [[ "$TERM" == "rxvt" ]]; then
+    print -Pn "\e]0;$1\a"
+  fi
+
+}
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd  theme_precmd
+add-zsh-hook preexec theme_preexec
+
+
+# Set the prompt
+
+# Need this so the prompt will work.
+setopt prompt_subst
+
+# See if we can use colors.
+autoload zsh/terminfo
+for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE GREY; do
+  typeset -g PR_$color="%{$terminfo[bold]$fg[${(L)color}]%}"
+  typeset -g PR_LIGHT_$color="%{$fg[${(L)color}]%}"
+done
+PR_NO_COLOUR="%{$terminfo[sgr0]%}"
+
+# Use extended characters to look nicer
+PR_HBAR="-"
+PR_ULCORNER="-"
+PR_LLCORNER="-"
+PR_LRCORNER="-"
+PR_URCORNER="-"
+
+# Modify Git prompt
+ZSH_THEME_GIT_PROMPT_PREFIX=" ["
+ZSH_THEME_GIT_PROMPT_SUFFIX="]"
+
+# Modify RVM prompt
+ZSH_THEME_RUBY_PROMPT_PREFIX=" ["
+ZSH_THEME_RUBY_PROMPT_SUFFIX="]"
+
+# Decide if we need to set titlebar text.
+case $TERM in
+  xterm*|*rxvt*)
+    PR_TITLEBAR=$'%{\e]0;%(!.-=*[ROOT]*=- | .)%n@%M:%~ $(git_prompt_info) $(ruby_prompt_info) | ${COLUMNS}x${LINES} | %y\a%}'
+    ;;
+  screen)
+    PR_TITLEBAR=$'%{\e_screen \005 (\005t) | %(!.-=[ROOT]=- | .)%n@%m:%~ | ${COLUMNS}x${LINES} | %y\e\\%}'
+    ;;
+  *)
+    PR_TITLEBAR=""
+    ;;
+esac
+
+# Decide whether to set a screen title
+if [[ "$TERM" == "screen" ]]; then
+  PR_STITLE=$'%{\ekzsh\e\\%}'
+else
+  PR_STITLE=""
+fi
+
+# Finally, the prompt.
+PROMPT='$PR_SET_CHARSET$PR_STITLE${(e)PR_TITLEBAR}\
+$PR_RED$PR_HBAR<\
+$PR_BLUE%(!.$PR_RED%SROOT%s.%n)$PR_GREEN@$PR_BLUE%M:$PR_GREEN%$PR_PWDLEN<...<%~$PR_CYAN$(git_prompt_info)$(ruby_prompt_info)\
+$PR_RED>$PR_HBAR${(e)PR_FILLBAR}\
+$PR_RED$PR_HBAR<\
+$PR_GREEN%l$PR_RED>$PR_HBAR\
+
+$PR_RED$PR_HBAR<\
+%(?..$PR_LIGHT_RED%?$PR_BLUE:)\
+$PR_LIGHT_BLUE%(!.$PR_RED.$PR_WHITE)%#$PR_RED>$PR_HBAR\
+$PR_NO_COLOUR '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/simple.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/simple.zsh-theme
new file mode 100644 (file)
index 0000000..bcdecc1
--- /dev/null
@@ -0,0 +1,6 @@
+PROMPT='%(!.%{$fg[red]%}.%{$fg[green]%})%~$(git_prompt_info)%{$reset_color%} '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg_bold[blue]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg_bold[blue]%})"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}✗"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/skaro.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/skaro.zsh-theme
new file mode 100644 (file)
index 0000000..84b7b11
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT='%{$fg_bold[green]%}%h %{$fg[cyan]%}%2~ %{$fg_bold[blue]%}$(git_prompt_info) %{$reset_color%}» '
+
+ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/smt.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/smt.zsh-theme
new file mode 100644 (file)
index 0000000..52e6d9a
--- /dev/null
@@ -0,0 +1,83 @@
+# smt.zsh-theme, based on dogenpunk by Matthew Nelson.
+
+MODE_INDICATOR="%{$fg_bold[red]%}❮%{$reset_color%}%{$fg[red]%}❮❮%{$reset_color%}"
+local return_status="%{$fg[red]%}%(?..⏎)%{$reset_color%} "
+
+ZSH_THEME_GIT_PROMPT_PREFIX="|"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%}⚡%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_AHEAD="%{$fg_bold[red]%}!%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}✓%{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%} ✚"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[blue]%} ✹"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✖"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[magenta]%} ➜"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[yellow]%} ═"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ✭"
+
+# Format for git_prompt_long_sha() and git_prompt_short_sha()
+ZSH_THEME_GIT_PROMPT_SHA_BEFORE="➤ %{$fg_bold[yellow]%}"
+ZSH_THEME_GIT_PROMPT_SHA_AFTER="%{$reset_color%}"
+
+function prompt_char() {
+  command git branch &>/dev/null && echo "%{$fg[green]%}±%{$reset_color%}" && return
+  command hg root &>/dev/null && echo "%{$fg_bold[red]%}☿%{$reset_color%}" && return
+  command darcs show repo &>/dev/null && echo "%{$fg_bold[green]%}❉%{$reset_color%}" && return
+  echo "%{$fg[cyan]%}◯%{$reset_color%}"
+}
+
+# Colors vary depending on time lapsed.
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT="%{$fg[green]%}"
+ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM="%{$fg[yellow]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG="%{$fg[red]%}"
+ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[cyan]%}"
+
+# Determine the time since last commit. If branch is clean,
+# use a neutral color, otherwise colors will vary according to time.
+function git_time_since_commit() {
+    local COLOR MINUTES HOURS DAYS SUB_HOURS SUB_MINUTES
+    local last_commit seconds_since_last_commit
+
+    # Only proceed if there is actually a commit
+    if ! last_commit=$(command git -c log.showSignature=false log --pretty=format:'%at' -1 2>/dev/null); then
+        echo "[$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL~%{$reset_color%}]"
+        return
+    fi
+
+    # Totals
+    seconds_since_last_commit=$(( EPOCHSECONDS - last_commit ))
+    MINUTES=$(( seconds_since_last_commit / 60 ))
+    HOURS=$(( MINUTES / 60 ))
+
+    # Sub-hours and sub-minutes
+    DAYS=$(( HOURS / 24 ))
+    SUB_HOURS=$(( HOURS % 24 ))
+    SUB_MINUTES=$(( MINUTES % 60 ))
+
+    if [[ -z "$(command git status -s 2>/dev/null)" ]]; then
+        COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+    else
+        if [[ "$MINUTES" -gt 30 ]]; then
+            COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG"
+        elif [[ "$MINUTES" -gt 10 ]]; then
+            COLOR="$ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM"
+        else
+            COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT"
+        fi
+    fi
+
+    if [[ "$HOURS" -gt 24 ]]; then
+        echo "[${COLOR}${DAYS}d${SUB_HOURS}h${SUB_MINUTES}m%{$reset_color%}]"
+    elif [[ "$MINUTES" -gt 60 ]]; then
+        echo "[${COLOR}${HOURS}h${SUB_MINUTES}m%{$reset_color%}]"
+    else
+        echo "[${COLOR}${MINUTES}m%{$reset_color%}]"
+    fi
+}
+
+PROMPT='
+%{$fg[blue]%}%m%{$reset_color%} 福 %{$fg[cyan]%}%~ %{$reset_color%}$(git_prompt_short_sha)$(git_prompt_info)
+%{$fg[red]%}%!%{$reset_color%} $(prompt_char) : '
+
+RPROMPT='${return_status}$(git_time_since_commit)$(git_prompt_status)%{$reset_color%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/sonicradish.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/sonicradish.zsh-theme
new file mode 100644 (file)
index 0000000..5086118
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env zsh 
+#local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
+
+setopt promptsubst
+
+autoload -U add-zsh-hook
+ROOT_ICON_COLOR=$FG[111]
+MACHINE_NAME_COLOR=$FG[208]
+PROMPT_SUCCESS_COLOR=$FG[103]
+PROMPT_FAILURE_COLOR=$FG[124]
+PROMPT_VCS_INFO_COLOR=$FG[242]
+PROMPT_PROMPT=$FG[208]
+GIT_DIRTY_COLOR=$FG[124]
+GIT_CLEAN_COLOR=$FG[148]
+GIT_PROMPT_INFO=$FG[148]
+
+# Hash
+ROOT_ICON="# "
+if [[ $EUID -ne 0 ]] ; then
+       ROOT_ICON=""
+fi
+
+PROMPT='%{$ROOT_ICON_COLOR%}$ROOT_ICON%{$reset_color%}%{$MACHINE_NAME_COLOR%}%m➜  %{$reset_color%}%{$PROMPT_SUCCESS_COLOR%}%c%{$reset_color%} %{$GIT_PROMPT_INFO%}$(git_prompt_info)%{$GIT_DIRTY_COLOR%}$(git_prompt_status) %{$reset_color%}%{$PROMPT_PROMPT%}ᐅ %{$reset_color%} '
+
+#RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX=": "
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$GIT_PROMPT_INFO%} :"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$GIT_DIRTY_COLOR%}✘"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$GIT_CLEAN_COLOR%}✔"
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$FG[103]%}✚%{$rset_color%}"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$FG[103]%}✹%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$FG[103]%}✖%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$FG[103]%}➜%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$FG[103]%}═%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$FG[103]%}✭%{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/sorin.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/sorin.zsh-theme
new file mode 100644 (file)
index 0000000..e478d26
--- /dev/null
@@ -0,0 +1,42 @@
+# sorin.zsh-theme
+# screenshot: https://i.imgur.com/aipDQ.png
+
+if [[ "$TERM" != "dumb" ]] && [[ "$DISABLE_LS_COLORS" != "true" ]]; then
+  MODE_INDICATOR="%{$fg_bold[red]%}❮%{$reset_color%}%{$fg[red]%}❮❮%{$reset_color%}"
+  local return_status="%{$fg[red]%}%(?..⏎)%{$reset_color%}"
+
+  PROMPT='%{$fg[cyan]%}%c$(git_prompt_info) %(!.%{$fg_bold[red]%}#.%{$fg_bold[green]%}❯)%{$reset_color%} '
+
+  ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[blue]%}git%{$reset_color%}:%{$fg[red]%}"
+  ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+  ZSH_THEME_GIT_PROMPT_DIRTY=""
+  ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+  RPROMPT='${return_status}$(git_prompt_status)%{$reset_color%}'
+
+  ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%} ✚"
+  ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[blue]%} ✹"
+  ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✖"
+  ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[magenta]%} ➜"
+  ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[yellow]%} ═"
+  ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ✭"
+else
+  MODE_INDICATOR="❮❮❮"
+  local return_status="%(?::⏎)"
+
+  PROMPT='%c$(git_prompt_info) %(!.#.❯) '
+
+  ZSH_THEME_GIT_PROMPT_PREFIX=" git:"
+  ZSH_THEME_GIT_PROMPT_SUFFIX=""
+  ZSH_THEME_GIT_PROMPT_DIRTY=""
+  ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+  RPROMPT='${return_status}$(git_prompt_status)'
+
+  ZSH_THEME_GIT_PROMPT_ADDED=" ✚"
+  ZSH_THEME_GIT_PROMPT_MODIFIED=" ✹"
+  ZSH_THEME_GIT_PROMPT_DELETED=" ✖"
+  ZSH_THEME_GIT_PROMPT_RENAMED=" ➜"
+  ZSH_THEME_GIT_PROMPT_UNMERGED=" ═"
+  ZSH_THEME_GIT_PROMPT_UNTRACKED=" ✭"
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/sporty_256.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/sporty_256.zsh-theme
new file mode 100644 (file)
index 0000000..e008a86
--- /dev/null
@@ -0,0 +1,13 @@
+# zsh theme requires 256 color enabled terminal
+# i.e TERM=xterm-256color
+# Preview - https://www.flickr.com/photos/adelcampo/4556482563/sizes/o/
+# based on robbyrussell's shell but louder!
+
+PROMPT='%{$fg_bold[blue]%}$(git_prompt_info) %F{208}%c%f
+%{$fg_bold[white]%}%# %{$reset_color%}'
+RPROMPT='%B%F{208}%n%f%{$fg_bold[white]%}@%F{039}%m%f%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%F{154}±|%f%F{124}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}%B✘%b%F{154}|%f%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=" %{$fg[green]%}✔%F{154}|"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/steeef.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/steeef.zsh-theme
new file mode 100644 (file)
index 0000000..3532d3b
--- /dev/null
@@ -0,0 +1,103 @@
+# prompt style and colors based on Steve Losh's Prose theme:
+# https://github.com/sjl/oh-my-zsh/blob/master/themes/prose.zsh-theme
+#
+# vcs_info modifications from Bart Trojanowski's zsh prompt:
+# http://www.jukie.net/bart/blog/pimping-out-zsh-prompt
+#
+# git untracked files modification from Brian Carper:
+# https://briancarper.net/blog/570/git-info-in-your-zsh-prompt
+
+export VIRTUAL_ENV_DISABLE_PROMPT=1
+
+function virtualenv_info {
+    [ $VIRTUAL_ENV ] && echo '('%F{blue}`basename $VIRTUAL_ENV`%f') '
+}
+PR_GIT_UPDATE=1
+
+setopt prompt_subst
+
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+#use extended color palette if available
+if [[ $terminfo[colors] -ge 256 ]]; then
+    turquoise="%F{81}"
+    orange="%F{166}"
+    purple="%F{135}"
+    hotpink="%F{161}"
+    limegreen="%F{118}"
+else
+    turquoise="%F{cyan}"
+    orange="%F{yellow}"
+    purple="%F{magenta}"
+    hotpink="%F{red}"
+    limegreen="%F{green}"
+fi
+
+# enable VCS systems you use
+zstyle ':vcs_info:*' enable git svn
+
+# check-for-changes can be really slow.
+# you should disable it, if you work with large repositories
+zstyle ':vcs_info:*:prompt:*' check-for-changes true
+
+# set formats
+# %b - branchname
+# %u - unstagedstr (see below)
+# %c - stagedstr (see below)
+# %a - action (e.g. rebase-i)
+# %R - repository path
+# %S - path in the repository
+PR_RST="%f"
+FMT_BRANCH="(%{$turquoise%}%b%u%c${PR_RST})"
+FMT_ACTION="(%{$limegreen%}%a${PR_RST})"
+FMT_UNSTAGED="%{$orange%}●"
+FMT_STAGED="%{$limegreen%}●"
+
+zstyle ':vcs_info:*:prompt:*' unstagedstr   "${FMT_UNSTAGED}"
+zstyle ':vcs_info:*:prompt:*' stagedstr     "${FMT_STAGED}"
+zstyle ':vcs_info:*:prompt:*' actionformats "${FMT_BRANCH}${FMT_ACTION}"
+zstyle ':vcs_info:*:prompt:*' formats       "${FMT_BRANCH}"
+zstyle ':vcs_info:*:prompt:*' nvcsformats   ""
+
+
+function steeef_preexec {
+    case "$2" in
+        *git*)
+            PR_GIT_UPDATE=1
+            ;;
+        *hub*)
+            PR_GIT_UPDATE=1
+            ;;
+        *svn*)
+            PR_GIT_UPDATE=1
+            ;;
+    esac
+}
+add-zsh-hook preexec steeef_preexec
+
+function steeef_chpwd {
+    PR_GIT_UPDATE=1
+}
+add-zsh-hook chpwd steeef_chpwd
+
+function steeef_precmd {
+    if [[ -n "$PR_GIT_UPDATE" ]] ; then
+        # check for untracked files or updated submodules, since vcs_info doesn't
+        if git ls-files --other --exclude-standard 2> /dev/null | grep -q "."; then
+            PR_GIT_UPDATE=1
+            FMT_BRANCH="(%{$turquoise%}%b%u%c%{$hotpink%}●${PR_RST})"
+        else
+            FMT_BRANCH="(%{$turquoise%}%b%u%c${PR_RST})"
+        fi
+        zstyle ':vcs_info:*:prompt:*' formats "${FMT_BRANCH} "
+
+        vcs_info 'prompt'
+        PR_GIT_UPDATE=
+    fi
+}
+add-zsh-hook precmd steeef_precmd
+
+PROMPT=$'
+%{$purple%}%n${PR_RST} at %{$orange%}%m${PR_RST} in %{$limegreen%}%~${PR_RST} $vcs_info_msg_0_$(virtualenv_info)
+$ '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/strug.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/strug.zsh-theme
new file mode 100644 (file)
index 0000000..89b56b0
--- /dev/null
@@ -0,0 +1,25 @@
+# terminal coloring
+export CLICOLOR=1
+export LSCOLORS=dxFxCxDxBxegedabagacad
+
+local git_branch='$(git_prompt_info)%{$reset_color%}$(git_remote_status)'
+
+PROMPT="%{$fg[green]%}╭─%n@%m %{$reset_color%}%{$fg[yellow]%}in %~ %{$reset_color%}${git_branch}
+%{$fg[green]%}╰\$ %{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[yellow]%}on "
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$reset_color%}%{$fg[red]%} ✘ %{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%} ✔ %{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED=true
+ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX="%{$fg[yellow]%}("
+ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX="%{$fg[yellow]%})%{$reset_color%}"
+
+ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE=" +"
+ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR=%{$fg[green]%}
+
+ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE=" -"
+ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR=%{$fg[red]%}
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/sunaku.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/sunaku.zsh-theme
new file mode 100644 (file)
index 0000000..77f3acc
--- /dev/null
@@ -0,0 +1,25 @@
+# Git-centric variation of the "fishy" theme.
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[green]%}+"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[magenta]%}!"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%}-"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%}>"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[cyan]%}#"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[yellow]%}?"
+
+ZSH_THEME_GIT_PROMPT_PREFIX=""
+ZSH_THEME_GIT_PROMPT_SUFFIX=" "
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+local user_color='green'
+test $UID -eq 0 && user_color='red'
+
+PROMPT='%(?..%{$fg_bold[red]%}exit %?
+%{$reset_color%})'\
+'%{$bold_color%}$(git_prompt_status)%{$reset_color%}'\
+'$(git_prompt_info)'\
+'%{$fg[$user_color]%}%~%{$reset_color%}'\
+'%(!.#.>) '
+
+PROMPT2='%{$fg[red]%}\ %{$reset_color%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/sunrise.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/sunrise.zsh-theme
new file mode 100644 (file)
index 0000000..11f6af1
--- /dev/null
@@ -0,0 +1,93 @@
+# Sunrise theme for oh-my-zsh
+# Intended to be used with Solarized: https://ethanschoonover.com/solarized
+
+# Color shortcuts
+R=$fg_no_bold[red]
+G=$fg_no_bold[green]
+M=$fg_no_bold[magenta]
+Y=$fg_no_bold[yellow]
+B=$fg_no_bold[blue]
+RESET=$reset_color
+
+if [ "$USERNAME" = "root" ]; then
+    PROMPTCOLOR="%{$R%}" PROMPTPREFIX="-!-";
+else
+    PROMPTCOLOR="" PROMPTPREFIX="---";
+fi
+
+local return_code="%(?..%{$R%}%? ↵%{$RESET%})"
+
+# Get the status of the working tree (copied and modified from git.zsh)
+custom_git_prompt_status() {
+  INDEX=$(git status --porcelain 2> /dev/null)
+  STATUS=""
+  # Non-staged
+  if $(echo "$INDEX" | grep '^?? ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS"
+  fi
+  if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS"
+  fi
+  if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
+  fi
+  if $(echo "$INDEX" | grep '^.M ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
+  elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
+  elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
+  fi
+  # Staged
+  if $(echo "$INDEX" | grep '^D  ' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_DELETED$STATUS"
+  fi
+  if $(echo "$INDEX" | grep '^R' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_RENAMED$STATUS"
+  fi
+  if $(echo "$INDEX" | grep '^M' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_MODIFIED$STATUS"
+  fi
+  if $(echo "$INDEX" | grep '^A' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_ADDED$STATUS"
+  fi
+
+  if $(echo -n "$STATUS" | grep '.*' &> /dev/null); then
+    STATUS="$ZSH_THEME_GIT_STATUS_PREFIX$STATUS"
+  fi
+
+  echo $STATUS
+}
+
+# get the name of the branch we are on (copied and modified from git.zsh)
+function custom_git_prompt() {
+  ref=$(git symbolic-ref HEAD 2> /dev/null) || return
+  echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$(git_prompt_ahead)$(custom_git_prompt_status)$ZSH_THEME_GIT_PROMPT_SUFFIX"
+}
+
+# %B sets bold text
+PROMPT='%B$PROMPTPREFIX %2~ $(custom_git_prompt)%{$M%}%B»%b%{$RESET%} '
+RPS1="${return_code}"
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$Y%}‹"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$Y%}›%{$RESET%} "
+
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$R%}*"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+ZSH_THEME_GIT_PROMPT_AHEAD="%{$B%}➔"
+
+
+ZSH_THEME_GIT_STATUS_PREFIX=" "
+
+# Staged
+ZSH_THEME_GIT_PROMPT_STAGED_ADDED="%{$G%}A"
+ZSH_THEME_GIT_PROMPT_STAGED_MODIFIED="%{$G%}M"
+ZSH_THEME_GIT_PROMPT_STAGED_RENAMED="%{$G%}R"
+ZSH_THEME_GIT_PROMPT_STAGED_DELETED="%{$G%}D"
+
+# Not-staged
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$R%}?"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$R%}M"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$R%}D"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$R%}UU"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/superjarin.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/superjarin.zsh-theme
new file mode 100644 (file)
index 0000000..86fa9c7
--- /dev/null
@@ -0,0 +1,18 @@
+# Grab the current version of ruby in use: [ruby-1.8.7]
+JARIN_CURRENT_RUBY_="%{$fg[white]%}[%{$fg[red]%}\$(ruby_prompt_info)%{$fg[white]%}]%{$reset_color%}"
+
+# Grab the current filepath, use shortcuts: ~/Desktop
+# Append the current git branch, if in a git repository
+JARIN_CURRENT_LOCA_="%{$fg_bold[cyan]%}%~\$(git_prompt_info)%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[white]%} <%{$fg[magenta]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$fg[white]%}"
+
+# Do nothing if the branch is clean (no changes).
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[white]%}>"
+
+# Add a yellow ✗ if the branch is dirty
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[white]%}> %{$fg[yellow]%}✗"
+
+# Put it all together!
+PROMPT="$JARIN_CURRENT_RUBY_ $JARIN_CURRENT_LOCA_ "
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/suvash.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/suvash.zsh-theme
new file mode 100644 (file)
index 0000000..850476c
--- /dev/null
@@ -0,0 +1,21 @@
+function prompt_char {
+    git branch >/dev/null 2>/dev/null && echo '±' && return
+    hg root >/dev/null 2>/dev/null && echo 'Hg' && return
+    echo '○'
+}
+
+function virtualenv_info {
+    [[ -n "$VIRTUAL_ENV" ]] && echo '('${VIRTUAL_ENV:t}') '
+}
+
+PROMPT='%F{magenta}%n%f at %F{yellow}%m%f in %B%F{green}%~%f%b$(git_prompt_info)$(ruby_prompt_info)
+$(virtualenv_info) $(prompt_char) '
+
+ZSH_THEME_GIT_PROMPT_PREFIX=' on %F{magenta}'
+ZSH_THEME_GIT_PROMPT_SUFFIX='%f'
+ZSH_THEME_GIT_PROMPT_DIRTY='%F{green}!'
+ZSH_THEME_GIT_PROMPT_UNTRACKED='%F{green}?'
+ZSH_THEME_GIT_PROMPT_CLEAN=''
+
+ZSH_THEME_RUBY_PROMPT_PREFIX=' using %F{red}'
+ZSH_THEME_RUBY_PROMPT_SUFFIX='%f'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/takashiyoshida.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/takashiyoshida.zsh-theme
new file mode 100644 (file)
index 0000000..419a8cf
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# PROMPT
+#
+PROMPT_BRACKET_BEGIN='%{$fg_bold[white]%}['
+PROMPT_HOST='%{$fg_bold[cyan]%}%m'
+PROMPT_SEPARATOR='%{$reset_color%}:'
+PROMPT_DIR='%{$fg_bold[yellow]%}%c'
+PROMPT_BRACKET_END='%{$fg_bold[white]%}]'
+
+PROMPT_USER='%{$fg_bold[white]%}%n'
+PROMPT_SIGN='%{$reset_color%}%#'
+
+GIT_PROMPT_INFO='$(git_prompt_info)'
+
+# My current prompt looks like:
+# [host:current_dir] (git_prompt_info)
+# [username]%
+PROMPT="${PROMPT_BRACKET_BEGIN}${PROMPT_HOST}${PROMPT_SEPARATOR}${PROMPT_DIR}${PROMPT_BRACKET_END}${GIT_PROMPT_INFO}
+${PROMPT_BRACKET_BEGIN}${PROMPT_USER}${PROMPT_BRACKET_END}${PROMPT_SIGN} "
+
+#
+# Git repository
+#
+ZSH_THEME_GIT_PROMPT_PREFIX=" on %{$fg[magenta]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[green]%}!"
+ZSH_THEME_GIT_PROMPT_CLEAN=''
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/terminalparty.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/terminalparty.zsh-theme
new file mode 100644 (file)
index 0000000..cd7370b
--- /dev/null
@@ -0,0 +1,8 @@
+PROMPT='%(?,%{$fg[green]%},%{$fg[red]%}) %% '
+# RPS1='%{$fg[blue]%}%~%{$reset_color%} '
+RPS1='%{$fg[white]%}%2~$(git_prompt_info) %{$fg_bold[blue]%}%m%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[yellow]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%} ⚡%{$fg[yellow]%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/theunraveler.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/theunraveler.zsh-theme
new file mode 100644 (file)
index 0000000..e4bfb79
--- /dev/null
@@ -0,0 +1,16 @@
+# Comment
+
+PROMPT='%{$fg[magenta]%}[%c] %{$reset_color%}'
+
+RPROMPT='%{$fg[magenta]%}$(git_prompt_info)%{$reset_color%} $(git_prompt_status)%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX=""
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_DIRTY=""
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[cyan]%} ✈"
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%} ✭"
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✗"
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%} ➦"
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[magenta]%} ✂"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[grey]%} ✱"
\ No newline at end of file
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/tjkirch.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/tjkirch.zsh-theme
new file mode 100644 (file)
index 0000000..c516098
--- /dev/null
@@ -0,0 +1,15 @@
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}⚡"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+function prompt_char {
+       if [ $UID -eq 0 ]; then echo "%{$fg[red]%}#%{$reset_color%}"; else echo $; fi
+}
+
+PROMPT='%(?, ,%{$fg[red]%}FAIL: $?%{$reset_color%}
+)
+%{$fg[magenta]%}%n%{$reset_color%}@%{$fg[yellow]%}%m%{$reset_color%}: %{$fg_bold[blue]%}%~%{$reset_color%}$(git_prompt_info)
+$(prompt_char) '
+
+RPROMPT='%{$fg[green]%}[%*]%{$reset_color%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/tjkirch_mod.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/tjkirch_mod.zsh-theme
new file mode 100644 (file)
index 0000000..2dd060e
--- /dev/null
@@ -0,0 +1,13 @@
+ZSH_THEME_GIT_PROMPT_PREFIX=" %{$fg[green]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg[red]%}⚡"
+ZSH_THEME_GIT_PROMPT_CLEAN=""
+
+function prompt_char {
+       if [ $UID -eq 0 ]; then echo "%{$fg[red]%}#%{$reset_color%}"; else echo $; fi
+}
+
+PROMPT='%(?,,%{$fg[red]%}FAIL: $?%{$reset_color%}
+)%{$fg[magenta]%}%n%{$reset_color%}@%{$fg[yellow]%}%m%{$reset_color%}: %{$fg_bold[blue]%}%~%{$reset_color%}$(git_prompt_info) $(prompt_char) '
+
+RPROMPT='%{$fg[green]%}[%*]%{$reset_color%}'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/tonotdo.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/tonotdo.zsh-theme
new file mode 100644 (file)
index 0000000..426e2bf
--- /dev/null
@@ -0,0 +1,12 @@
+PROMPT='%{$fg_no_bold[cyan]%}%n%{$fg_no_bold[magenta]%}➜%{$fg_no_bold[green]%}%3~$(git_prompt_info)%{$reset_color%}» '
+RPROMPT='[%*]'
+
+# git theming
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}(%{$fg_no_bold[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX=""
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[blue]%})"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[yellow]%}✗%{$fg_bold[blue]%})"
+
+# LS colors, made with https://geoff.greer.fm/lscolors/
+export LSCOLORS="Gxfxcxdxbxegedabagacad"
+export LS_COLORS='no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:'
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/trapd00r.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/trapd00r.zsh-theme
new file mode 100644 (file)
index 0000000..260c9e7
--- /dev/null
@@ -0,0 +1,132 @@
+# trapd00r.zsh-theme
+#
+# This theme needs a terminal supporting 256 colors as well as unicode.
+# In order to avoid external dependencies, it also has a zsh version of
+# the previously used perl script https://github.com/trapd00r/utils/blob/master/zsh_path,
+# which splits up the current path and makes it fancy.
+#
+# By default it spans over two lines like so:
+#
+# scp1@shiva:pts/9-> /home » scp1 (0)
+# >
+#
+# that's  user@host:pts/-> splitted path (return status)
+#
+# If the current directory is a git repository, we span 3 lines;
+#
+# git❨ master ❩ DIRTY
+# scp1@shiva:pts/4-> /home » scp1 » dev » utils (0)
+# >
+
+autoload -U add-zsh-hook
+autoload -Uz vcs_info
+
+local c0=$'\e[m'
+local c1=$'\e[38;5;245m'
+local c2=$'\e[38;5;250m'
+local c3=$'\e[38;5;242m'
+local c4=$'\e[38;5;197m'
+local c5=$'\e[38;5;225m'
+local c6=$'\e[38;5;240m'
+local c7=$'\e[38;5;242m'
+local c8=$'\e[38;5;244m'
+local c9=$'\e[38;5;162m'
+local c10=$'\e[1m'
+local c11=$'\e[38;5;208m\e[1m'
+local c12=$'\e[38;5;142m\e[1m'
+local c13=$'\e[38;5;196m\e[1m'
+
+
+zsh_path() {
+  setopt localoptions nopromptsubst
+
+  local colors
+  colors=$(echoti colors)
+
+  local -A yellow
+  yellow=(
+    1  '%F{228}'   2  '%F{222}'   3  '%F{192}'   4  '%F{186}'
+    5  '%F{227}'   6  '%F{221}'   7  '%F{191}'   8  '%F{185}'
+    9  '%F{226}'   10  '%F{220}'   11  '%F{190}'   12  '%F{184}'
+    13  '%F{214}'   14  '%F{178}'  15  '%F{208}'   16  '%F{172}'
+    17  '%F{202}'   18  '%F{166}'
+  )
+
+  local dir i=1
+  for dir (${(s:/:)PWD}); do
+    if [[ $i -eq 1 ]]; then
+      if [[ $colors -ge 256 ]]; then
+        print -Pn "%F{065}%B /%b"
+      else
+        print -Pn "\e[31;1m /"
+      fi
+    else
+      if [[ $colors -ge 256 ]]; then
+        print -Pn "${yellow[$i]:-%f} » "
+      else
+        print -Pn "%F{yellow} > "
+      fi
+    fi
+
+    (( i++ ))
+
+    if [[ $colors -ge 256 ]]; then
+      print -Pn "%F{065}$dir"
+    else
+      print -Pn "%F{blue}$dir"
+    fi
+  done
+  print -Pn "%f"
+}
+
+
+# We don't want to use the extended colorset in the TTY / VC.
+if [ "$TERM" = linux ]; then
+  c1=$'\e[34;1m'
+  c2=$'\e[35m'
+  c3=$'\e[31m'
+  c4=$'\e[31;1m'
+  c5=$'\e[32m'
+  c6=$'\e[32;1m'
+  c7=$'\e[33m'
+  c8=$'\e[33;1m'
+  c9=$'\e[34m'
+  c11=$'\e[35;1m'
+  c12=$'\e[36m'
+  c13=$'\e[31;1m'
+fi
+
+zstyle ':vcs_info:*' actionformats \
+    '%{$c8%}(%f%s)%{$c7%}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '
+
+zstyle ':vcs_info:*' formats \
+    "%{$c8%}%s%%{$c7%}❨ %{$c9%}%{$c11%}%b%{$c7%} ❩%{$reset_color%}%f "
+
+zstyle ':vcs_info:*' enable git
+
+add-zsh-hook precmd prompt_jnrowe_precmd
+
+prompt_jnrowe_precmd () {
+  vcs_info
+  if [ "${vcs_info_msg_0_}" = "" ]; then
+    dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})"
+    PROMPT='${dir_status} ${ret_status}%{$reset_color%}
+> '
+  # modified, to be committed
+  elif [[ $(git diff --cached --name-status 2>/dev/null ) != "" ]]; then
+    dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})"
+    PROMPT='${vcs_info_msg_0_}%{$30%} %{$bg_bold[red]%}%{$fg_bold[cyan]%}C%{$fg_bold[black]%}OMMIT%{$reset_color%}
+${dir_status}%{$reset_color%}
+> '
+  elif [[ $(git diff --name-status 2>/dev/null ) != "" ]]; then
+    dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})"
+    PROMPT='${vcs_info_msg_0_}%{$bg_bold[red]%}%{$fg_bold[blue]%}D%{$fg_bold[black]%}IRTY%{$reset_color%}
+${dir_status}%{$reset_color%}
+%{$c13%}>%{$c0%} '
+  else
+    dir_status="%{$c1%}%n%{$c4%}@%{$c2%}%m%{$c0%}:%{$c3%}%l%{$c6%}->%{$(zsh_path)%} %{$c0%}(%{$c5%}%?%{$c0%})"
+    PROMPT='${vcs_info_msg_0_}
+${dir_status}%{$reset_color%}
+> '
+  fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/wedisagree.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/wedisagree.zsh-theme
new file mode 100644 (file)
index 0000000..e9e9d6e
--- /dev/null
@@ -0,0 +1,109 @@
+# On a mac with snow leopard, for nicer terminal colours:
+
+# - Install SIMBL: http://www.culater.net/software/SIMBL/SIMBL.php
+# - Download'Terminal-Colours': http://bwaht.net/code/TerminalColours.bundle.zip
+# - Place that bundle in ~/Library/Application\ Support/SIMBL/Plugins (create that folder if it doesn't exist)
+# - Open Terminal preferences. Go to Settings -> Text -> More
+# - Change default colours to your liking.
+# 
+# Here are the colours from Textmate's Monokai theme:
+# 
+# Black: 0, 0, 0
+# Red: 229, 34, 34
+# Green: 166, 227, 45
+# Yellow: 252, 149, 30
+# Blue: 196, 141, 255
+# Magenta: 250, 37, 115
+# Cyan: 103, 217, 240
+# White: 242, 242, 242
+
+# Thanks to Steve Losh: http://stevelosh.com/blog/2009/03/candy-colored-terminal/
+
+# The prompt
+
+PROMPT='%{$fg[magenta]%}[%c] %{$reset_color%}'
+
+# The right-hand prompt
+
+RPROMPT='${time} %{$fg[magenta]%}$(git_prompt_info)%{$reset_color%}$(git_prompt_status)%{$reset_color%}$(git_prompt_ahead)%{$reset_color%}'
+
+# Add this at the start of RPROMPT to include rvm info showing ruby-version@gemset-name
+# $(ruby_prompt_info) 
+
+# local time, color coded by last return code
+time_enabled="%(?.%{$fg[green]%}.%{$fg[red]%})%*%{$reset_color%}"
+time_disabled="%{$fg[green]%}%*%{$reset_color%}"
+time=$time_enabled
+
+ZSH_THEME_GIT_PROMPT_PREFIX=" ☁  %{$fg[red]%}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%} ☂" # Ⓓ
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%} ✭" # ⓣ
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%} ☀" # Ⓞ
+
+ZSH_THEME_GIT_PROMPT_ADDED="%{$fg[cyan]%} ✚" # ⓐ ⑃
+ZSH_THEME_GIT_PROMPT_MODIFIED="%{$fg[yellow]%} ⚡"  # ⓜ ⑁
+ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[red]%} ✖" # ⓧ ⑂
+ZSH_THEME_GIT_PROMPT_RENAMED="%{$fg[blue]%} ➜" # ⓡ ⑄
+ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[magenta]%} ♒" # ⓤ ⑊
+ZSH_THEME_GIT_PROMPT_AHEAD="%{$fg[blue]%} 𝝙"
+
+ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[yellow]%}"
+ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$reset_color%}"
+
+# More symbols to choose from:
+# ☀ ✹ ☄ ♆ ♀ ♁ ♐ ♇ ♈ ♉ ♚ ♛ ♜ ♝ ♞ ♟ ♠ ♣ ⚢ ⚲ ⚳ ⚴ ⚥ ⚤ ⚦ ⚒ ⚑ ⚐ ♺ ♻ ♼ ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷
+# ✡ ✔ ✖ ✚ ✱ ✤ ✦ ❤ ➜ ➟ ➼ ✂ ✎ ✐ ⨀ ⨁ ⨂ ⨍ ⨎ ⨏ ⨷ ⩚ ⩛ ⩡ ⩱ ⩲ ⩵  ⩶ ⨠ 
+# ⬅ ⬆ ⬇ ⬈ ⬉ ⬊ ⬋ ⬒ ⬓ ⬔ ⬕ ⬖ ⬗ ⬘ ⬙ ⬟  ⬤ 〒 ǀ ǁ ǂ ĭ Ť Ŧ
+
+# Determine if we are using a gemset.
+function rvm_gemset() {
+    GEMSET=`rvm gemset list | grep '=>' | cut -b4-`
+    if [[ -n $GEMSET ]]; then
+        echo "%{$fg[yellow]%}$GEMSET%{$reset_color%}|"
+    fi 
+}
+
+# Determine the time since last commit. If branch is clean,
+# use a neutral color, otherwise colors will vary according to time.
+function git_time_since_commit() {
+    if git rev-parse --git-dir > /dev/null 2>&1; then
+        # Only proceed if there is actually a commit.
+        if last_commit=`git -c log.showSignature=false log --pretty=format:'%at' -1 2> /dev/null`; then
+            now=`date +%s`
+            seconds_since_last_commit=$((now-last_commit))
+
+            # Totals
+            MINUTES=$((seconds_since_last_commit / 60))
+            HOURS=$((seconds_since_last_commit/3600))
+           
+            # Sub-hours and sub-minutes
+            DAYS=$((seconds_since_last_commit / 86400))
+            SUB_HOURS=$((HOURS % 24))
+            SUB_MINUTES=$((MINUTES % 60))
+            
+            if [[ -n $(git status -s 2> /dev/null) ]]; then
+                if [ "$MINUTES" -gt 30 ]; then
+                    COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_LONG"
+                elif [ "$MINUTES" -gt 10 ]; then
+                    COLOR="$ZSH_THEME_GIT_TIME_SHORT_COMMIT_MEDIUM"
+                else
+                    COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_SHORT"
+                fi
+            else
+                COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+            fi
+
+            if [ "$HOURS" -gt 24 ]; then
+                echo "($(rvm_gemset)$COLOR${DAYS}d${SUB_HOURS}h${SUB_MINUTES}m%{$reset_color%}|"
+            elif [ "$MINUTES" -gt 60 ]; then
+                echo "($(rvm_gemset)$COLOR${HOURS}h${SUB_MINUTES}m%{$reset_color%}|"
+            else
+                echo "($(rvm_gemset)$COLOR${MINUTES}m%{$reset_color%}|"
+            fi
+        else
+            COLOR="$ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL"
+            echo "($(rvm_gemset)$COLOR~|"
+        fi
+    fi
+}
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/wezm+.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/wezm+.zsh-theme
new file mode 100644 (file)
index 0000000..fee3eb0
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT='%{${fg_bold[yellow]}%}%n%{$reset_color%}%{${fg[yellow]}%}@%m%{$reset_color%} $(git_prompt_info)%(?,,%{${fg_bold[white]}%}[%?]%{$reset_color%} )%{$fg[yellow]%}%#%{$reset_color%} '
+RPROMPT='%{$fg[green]%}%~%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[blue]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%})%{$fg[red]%}✗%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/wezm.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/wezm.zsh-theme
new file mode 100644 (file)
index 0000000..1881343
--- /dev/null
@@ -0,0 +1,7 @@
+PROMPT='$(git_prompt_info)%(?,,%{${fg_bold[white]}%}[%?]%{$reset_color%} )%{$fg[yellow]%}%#%{$reset_color%} '
+RPROMPT='%{$fg[green]%}%~%{$reset_color%}'
+
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[blue]%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%})%{$fg[red]%}⚡%{$reset_color%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/wuffers.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/wuffers.zsh-theme
new file mode 100644 (file)
index 0000000..4019d0a
--- /dev/null
@@ -0,0 +1,5 @@
+ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}["
+ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%} "
+ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%} x%{$fg_bold[blue]%}"
+
+PROMPT='%{$(git_prompt_info)%}%{$fg_bold[green]%}{%{$(rvm current 2>/dev/null || rbenv version-name 2>/dev/null)%}}%{$reset_color%} %{$fg[cyan]%}%c%{$reset_color%} '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/xiong-chiamiov-plus.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/xiong-chiamiov-plus.zsh-theme
new file mode 100644 (file)
index 0000000..aa6ef74
--- /dev/null
@@ -0,0 +1,6 @@
+# user, host, full path, and time/date
+# on two lines for easier vgrepping
+# entry in a nice long thread on the Arch Linux forums: https://bbs.archlinux.org/viewtopic.php?pid=521888#p521888
+PROMPT=$'%{\e[0;34m%}%B┌─[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;30m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}'%D{"%a %b %d, %H:%M"}%b$'%{\e[0;34m%}%B]%b%{\e[0m%}
+%{\e[0;34m%}%B└─%B[%{\e[1;35m%}$%{\e[0;34m%}%B] <$(git_prompt_info)>%{\e[0m%}%b '
+PS2=$' \e[0;34m%}%B>%{\e[0m%}%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/xiong-chiamiov.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/xiong-chiamiov.zsh-theme
new file mode 100644 (file)
index 0000000..b67d994
--- /dev/null
@@ -0,0 +1,6 @@
+# user, host, full path, and time/date
+# on two lines for easier vgrepping
+# entry in a nice long thread on the Arch Linux forums: https://bbs.archlinux.org/viewtopic.php?pid=521888#p521888
+PROMPT=$'%{\e[0;34m%}%B┌─[%b%{\e[0m%}%{\e[1;32m%}%n%{\e[1;30m%}@%{\e[0m%}%{\e[0;36m%}%m%{\e[0;34m%}%B]%b%{\e[0m%} - %b%{\e[0;34m%}%B[%b%{\e[1;37m%}%~%{\e[0;34m%}%B]%b%{\e[0m%} - %{\e[0;34m%}%B[%b%{\e[0;33m%}'%D{"%a %b %d, %H:%M"}%b$'%{\e[0;34m%}%B]%b%{\e[0m%}
+%{\e[0;34m%}%B└─%B[%{\e[1;35m%}$%{\e[0;34m%}%B]>%{\e[0m%}%b '
+PS2=$' \e[0;34m%}%B>%{\e[0m%}%b '
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/ys.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/ys.zsh-theme
new file mode 100644 (file)
index 0000000..4c3c56f
--- /dev/null
@@ -0,0 +1,80 @@
+# Clean, simple, compatible and meaningful.
+# Tested on Linux, Unix and Windows under ANSI colors.
+# It is recommended to use with a dark background.
+# Colors: black, red, green, yellow, *blue, magenta, cyan, and white.
+#
+# Mar 2013 Yad Smood
+
+# VCS
+YS_VCS_PROMPT_PREFIX1=" %{$reset_color%}on%{$fg[blue]%} "
+YS_VCS_PROMPT_PREFIX2=":%{$fg[cyan]%}"
+YS_VCS_PROMPT_SUFFIX="%{$reset_color%}"
+YS_VCS_PROMPT_DIRTY=" %{$fg[red]%}x"
+YS_VCS_PROMPT_CLEAN=" %{$fg[green]%}o"
+
+# Git info
+local git_info='$(git_prompt_info)'
+ZSH_THEME_GIT_PROMPT_PREFIX="${YS_VCS_PROMPT_PREFIX1}git${YS_VCS_PROMPT_PREFIX2}"
+ZSH_THEME_GIT_PROMPT_SUFFIX="$YS_VCS_PROMPT_SUFFIX"
+ZSH_THEME_GIT_PROMPT_DIRTY="$YS_VCS_PROMPT_DIRTY"
+ZSH_THEME_GIT_PROMPT_CLEAN="$YS_VCS_PROMPT_CLEAN"
+
+# SVN info
+local svn_info='$(svn_prompt_info)'
+ZSH_THEME_SVN_PROMPT_PREFIX="${YS_VCS_PROMPT_PREFIX1}svn${YS_VCS_PROMPT_PREFIX2}"
+ZSH_THEME_SVN_PROMPT_SUFFIX="$YS_VCS_PROMPT_SUFFIX"
+ZSH_THEME_SVN_PROMPT_DIRTY="$YS_VCS_PROMPT_DIRTY"
+ZSH_THEME_SVN_PROMPT_CLEAN="$YS_VCS_PROMPT_CLEAN"
+
+# HG info
+local hg_info='$(ys_hg_prompt_info)'
+ys_hg_prompt_info() {
+       # make sure this is a hg dir
+       if [ -d '.hg' ]; then
+               echo -n "${YS_VCS_PROMPT_PREFIX1}hg${YS_VCS_PROMPT_PREFIX2}"
+               echo -n $(hg branch 2>/dev/null)
+               if [[ "$(hg config oh-my-zsh.hide-dirty 2>/dev/null)" != "1" ]]; then
+                       if [ -n "$(hg status 2>/dev/null)" ]; then
+                               echo -n "$YS_VCS_PROMPT_DIRTY"
+                       else
+                               echo -n "$YS_VCS_PROMPT_CLEAN"
+                       fi
+               fi
+               echo -n "$YS_VCS_PROMPT_SUFFIX"
+       fi
+}
+
+# Virtualenv
+local venv_info='$(virtenv_prompt)'
+YS_THEME_VIRTUALENV_PROMPT_PREFIX=" %{$fg[green]%}"
+YS_THEME_VIRTUALENV_PROMPT_SUFFIX=" %{$reset_color%}%"
+virtenv_prompt() {
+       [[ -n "${VIRTUAL_ENV:-}" ]] || return
+       echo "${YS_THEME_VIRTUALENV_PROMPT_PREFIX}${VIRTUAL_ENV:t}${YS_THEME_VIRTUALENV_PROMPT_SUFFIX}"
+}
+
+local exit_code="%(?,,C:%{$fg[red]%}%?%{$reset_color%})"
+
+# Prompt format:
+#
+# PRIVILEGES USER @ MACHINE in DIRECTORY on git:BRANCH STATE [TIME] C:LAST_EXIT_CODE
+# $ COMMAND
+#
+# For example:
+#
+# % ys @ ys-mbp in ~/.oh-my-zsh on git:master x [21:47:42] C:0
+# $
+PROMPT="
+%{$terminfo[bold]$fg[blue]%}#%{$reset_color%} \
+%(#,%{$bg[yellow]%}%{$fg[black]%}%n%{$reset_color%},%{$fg[cyan]%}%n) \
+%{$reset_color%}@ \
+%{$fg[green]%}%m \
+%{$reset_color%}in \
+%{$terminfo[bold]$fg[yellow]%}%~%{$reset_color%}\
+${hg_info}\
+${git_info}\
+${svn_info}\
+${venv_info}\
+ \
+[%*] $exit_code
+%{$terminfo[bold]$fg[red]%}$ %{$reset_color%}"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/themes/zhann.zsh-theme b/stow/oh-my-zsh/.oh-my-zsh/themes/zhann.zsh-theme
new file mode 100644 (file)
index 0000000..a00650a
--- /dev/null
@@ -0,0 +1,25 @@
+autoload -Uz vcs_info
+
+zstyle ':vcs_info:*' stagedstr '%F{green}●'
+zstyle ':vcs_info:*' unstagedstr '%F{yellow}●'
+zstyle ':vcs_info:*' check-for-changes true
+zstyle ':vcs_info:svn:*' branchformat '%b'
+zstyle ':vcs_info:svn:*' formats ' [%b%F{1}:%F{11}%i%c%u%B%F{green}]'
+zstyle ':vcs_info:*' enable git svn
+
+theme_precmd () {
+  if [[ -z $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then
+    zstyle ':vcs_info:git:*' formats ' [%b%c%u%B%F{green}]'
+  else
+    zstyle ':vcs_info:git:*' formats ' [%b%c%u%B%F{red}●%F{green}]'
+  fi
+
+  vcs_info
+}
+
+setopt prompt_subst
+PROMPT='%B%F{blue}%c%B%F{green}${vcs_info_msg_0_}%B%F{magenta} %{$reset_color%}% '
+
+autoload -U add-zsh-hook
+add-zsh-hook precmd  theme_precmd
+
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/changelog.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/changelog.sh
new file mode 100755 (executable)
index 0000000..6489a3c
--- /dev/null
@@ -0,0 +1,476 @@
+#!/usr/bin/env zsh
+
+cd "$ZSH"
+setopt extendedglob
+
+##############################
+# CHANGELOG SCRIPT CONSTANTS #
+##############################
+
+#* Holds the list of valid types recognized in a commit subject
+#* and the display string of such type
+local -A TYPES
+TYPES=(
+  build     "Build system"
+  chore     "Chore"
+  ci        "CI"
+  docs      "Documentation"
+  feat      "Features"
+  fix       "Bug fixes"
+  perf      "Performance"
+  refactor  "Refactor"
+  style     "Style"
+  test      "Testing"
+)
+
+#* Types that will be displayed in their own section, in the order specified here.
+local -a MAIN_TYPES
+MAIN_TYPES=(feat fix perf docs)
+
+#* Types that will be displayed under the category of other changes
+local -a OTHER_TYPES
+OTHER_TYPES=(refactor style other)
+
+#* Commit types that don't appear in $MAIN_TYPES nor $OTHER_TYPES
+#* will not be displayed and will simply be ignored.
+local -a IGNORED_TYPES
+IGNORED_TYPES=(${${${(@k)TYPES}:|MAIN_TYPES}:|OTHER_TYPES})
+
+############################
+# COMMIT PARSING UTILITIES #
+############################
+
+function parse-commit {
+
+  # This function uses the following globals as output: commits (A),
+  # subjects (A), scopes (A) and breaking (A). All associative arrays (A)
+  # have $hash as the key.
+  # - commits holds the commit type
+  # - subjects holds the commit subject
+  # - scopes holds the scope of a commit
+  # - breaking holds the breaking change warning if a commit does
+  #   make a breaking change
+
+  function commit:type {
+    local type
+
+    # Parse commit type from the subject
+    if [[ "$1" =~ '^([a-zA-Z_\-]+)(\(.+\))?!?: .+$' ]]; then
+      type="${match[1]}"
+    fi
+
+    # If $type doesn't appear in $TYPES array mark it as 'other'
+    if [[ -n "$type" && -n "${(k)TYPES[(i)$type]}" ]]; then
+      echo $type
+    else
+      echo other
+    fi
+  }
+
+  function commit:scope {
+    local scope
+
+    # Try to find scope in "type(<scope>):" format
+    if [[ "$1" =~ '^[a-zA-Z_\-]+\((.+)\)!?: .+$' ]]; then
+      echo "${match[1]}"
+      return
+    fi
+
+    # If no scope found, try to find it in "<scope>:" format
+    if [[ "$1" =~ '^([a-zA-Z_\-]+): .+$' ]]; then
+      scope="${match[1]}"
+      # Make sure it's not a type before printing it
+      if [[ -z "${(k)TYPES[(i)$scope]}" ]]; then
+        echo "$scope"
+      fi
+    fi
+  }
+
+  function commit:subject {
+    # Only display the relevant part of the commit, i.e. if it has the format
+    # type[(scope)!]: subject, where the part between [] is optional, only
+    # displays subject. If it doesn't match the format, returns the whole string.
+    if [[ "$1" =~ '^[a-zA-Z_\-]+(\(.+\))?!?: (.+)$' ]]; then
+      echo "${match[2]}"
+    else
+      echo "$1"
+    fi
+  }
+
+  # Return subject if the body or subject match the breaking change format
+  function commit:is-breaking {
+    local subject="$1" body="$2" message
+
+    if [[ "$body" =~ "BREAKING CHANGE: (.*)" || \
+      "$subject" =~ '^[^ :\)]+\)?!: (.*)$' ]]; then
+      message="${match[1]}"
+      # remove CR characters (might be inserted in GitHub UI commit description form)
+      message="${message//$'\r'/}"
+      # skip next paragraphs (separated by two newlines or more)
+      message="${message%%$'\n\n'*}"
+      # ... and replace newlines with spaces
+      echo "${message//$'\n'/ }"
+    else
+      return 1
+    fi
+  }
+
+  # Return truncated hash of the reverted commit
+  function commit:is-revert {
+    local subject="$1" body="$2"
+
+    if [[ "$subject" = Revert* && \
+      "$body" =~ "This reverts commit ([^.]+)\." ]]; then
+      echo "${match[1]:0:7}"
+    else
+      return 1
+    fi
+  }
+
+  # Parse commit with hash $1
+  local hash="$1" subject="$2" body="$3" warning rhash
+
+  # Commits following Conventional Commits (https://www.conventionalcommits.org/)
+  # have the following format, where parts between [] are optional:
+  #
+  #  type[(scope)][!]: subject
+  #
+  #  commit body
+  #  [BREAKING CHANGE: warning]
+
+  # commits holds the commit type
+  types[$hash]="$(commit:type "$subject")"
+  # scopes holds the commit scope
+  scopes[$hash]="$(commit:scope "$subject")"
+  # subjects holds the commit subject
+  subjects[$hash]="$(commit:subject "$subject")"
+
+  # breaking holds whether a commit has breaking changes
+  # and its warning message if it does
+  if warning=$(commit:is-breaking "$subject" "$body"); then
+    breaking[$hash]="$warning"
+  fi
+
+  # reverts holds commits reverted in the same release
+  if rhash=$(commit:is-revert "$subject" "$body"); then
+    reverts[$hash]=$rhash
+  fi
+}
+
+#############################
+# RELEASE CHANGELOG DISPLAY #
+#############################
+
+function display-release {
+
+  # This function uses the following globals: output, version,
+  # types (A), subjects (A), scopes (A), breaking (A) and reverts (A).
+  #
+  # - output is the output format to use when formatting (raw|text|md)
+  # - version is the version in which the commits are made
+  # - types, subjects, scopes, breaking, and reverts are associative arrays
+  #   with commit hashes as keys
+
+  # Remove commits that were reverted
+  local hash rhash
+  for hash rhash in ${(kv)reverts}; do
+    if (( ${+types[$rhash]} )); then
+      # Remove revert commit
+      unset "types[$hash]" "subjects[$hash]" "scopes[$hash]" "breaking[$hash]"
+      # Remove reverted commit
+      unset "types[$rhash]" "subjects[$rhash]" "scopes[$rhash]" "breaking[$rhash]"
+    fi
+  done
+
+  # Remove commits from ignored types unless it has breaking change information
+  for hash in ${(k)types[(R)${(j:|:)IGNORED_TYPES}]}; do
+    (( ! ${+breaking[$hash]} )) || continue
+    unset "types[$hash]" "subjects[$hash]" "scopes[$hash]"
+  done
+
+  # If no commits left skip displaying the release
+  if (( $#types == 0 )); then
+    return
+  fi
+
+  # Get length of longest scope for padding
+  local max_scope=0
+  for hash in ${(k)scopes}; do
+    max_scope=$(( max_scope < ${#scopes[$hash]} ? ${#scopes[$hash]} : max_scope ))
+  done
+
+  ##* Formatting functions
+
+  # Format the hash according to output format
+  # If no parameter is passed, assume it comes from `$hash`
+  function fmt:hash {
+    #* Uses $hash from outer scope
+    local hash="${1:-$hash}"
+    case "$output" in
+    raw) printf '%s' "$hash" ;;
+    text) printf '\e[33m%s\e[0m' "$hash" ;; # red
+    md) printf '[`%s`](https://github.com/ohmyzsh/ohmyzsh/commit/%s)' "$hash" ;;
+    esac
+  }
+
+  # Format headers according to output format
+  # Levels 1 to 2 are considered special, the rest are formatted
+  # the same, except in md output format.
+  function fmt:header {
+    local header="$1" level="$2"
+    case "$output" in
+    raw)
+      case "$level" in
+      1) printf '%s\n%s\n\n' "$header" "$(printf '%.0s=' {1..${#header}})" ;;
+      2) printf '%s\n%s\n\n' "$header" "$(printf '%.0s-' {1..${#header}})" ;;
+      *) printf '%s:\n\n' "$header" ;;
+      esac ;;
+    text)
+      case "$level" in
+      1|2) printf '\e[1;4m%s\e[0m\n\n' "$header" ;; # bold, underlined
+      *) printf '\e[1m%s:\e[0m\n\n' "$header" ;; # bold
+      esac ;;
+    md) printf '%s %s\n\n' "$(printf '%.0s#' {1..${level}})" "$header" ;;
+    esac
+  }
+
+  function fmt:scope {
+    #* Uses $scopes (A) and $hash from outer scope
+    local scope="${1:-${scopes[$hash]}}"
+
+    # If no scopes, exit the function
+    if [[ $max_scope -eq 0 ]]; then
+      return
+    fi
+
+    # Get how much padding is required for this scope
+    local padding=0
+    padding=$(( max_scope < ${#scope} ? 0 : max_scope - ${#scope} ))
+    padding="${(r:$padding:: :):-}"
+
+    # If no scope, print padding and 3 spaces (equivalent to "[] ")
+    if [[ -z "$scope" ]]; then
+      printf "${padding}   "
+      return
+    fi
+
+    # Print [scope]
+    case "$output" in
+    raw|md) printf '[%s]%s ' "$scope" "$padding";;
+    text) printf '[\e[38;5;9m%s\e[0m]%s ' "$scope" "$padding";; # red 9
+    esac
+  }
+
+  # If no parameter is passed, assume it comes from `$subjects[$hash]`
+  function fmt:subject {
+    #* Uses $subjects (A) and $hash from outer scope
+    local subject="${1:-${subjects[$hash]}}"
+
+    # Capitalize first letter of the subject
+    subject="${(U)subject:0:1}${subject:1}"
+
+    case "$output" in
+    raw) printf '%s' "$subject" ;;
+    # In text mode, highlight (#<issue>) and dim text between `backticks`
+    text) sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" ;;
+    # In markdown mode, link to (#<issue>) issues
+    md) sed -E 's|#([0-9]+)|[#\1](https://github.com/ohmyzsh/ohmyzsh/issues/\1)|g' <<< "$subject" ;;
+    esac
+  }
+
+  function fmt:type {
+    #* Uses $type from outer scope
+    local type="${1:-${TYPES[$type]:-${(C)type}}}"
+    [[ -z "$type" ]] && return 0
+    case "$output" in
+    raw|md) printf '%s: ' "$type" ;;
+    text) printf '\e[4m%s\e[24m: ' "$type" ;; # underlined
+    esac
+  }
+
+  ##* Section functions
+
+  function display:version {
+    fmt:header "$version" 2
+  }
+
+  function display:breaking {
+    (( $#breaking != 0 )) || return 0
+
+    case "$output" in
+    text) printf '\e[31m'; fmt:header "BREAKING CHANGES" 3 ;;
+    raw) fmt:header "BREAKING CHANGES" 3 ;;
+    md) fmt:header "BREAKING CHANGES ⚠" 3 ;;
+    esac
+
+    local hash message
+    local wrap_width=$(( (COLUMNS < 100 ? COLUMNS : 100) - 3 ))
+    for hash message in ${(kv)breaking}; do
+      # Format the BREAKING CHANGE message by word-wrapping it at maximum 100
+      # characters (use $COLUMNS if smaller than 100)
+      message="$(fmt -w $wrap_width <<< "$message")"
+      # Display hash and scope in their own line, and then the full message with
+      # blank lines as separators and a 3-space left padding
+      echo " - $(fmt:hash) $(fmt:scope)\n\n$(fmt:subject "$message" | sed 's/^/   /')\n"
+    done
+  }
+
+  function display:type {
+    local hash type="$1"
+
+    local -a hashes
+    hashes=(${(k)types[(R)$type]})
+
+    # If no commits found of type $type, go to next type
+    (( $#hashes != 0 )) || return 0
+
+    fmt:header "${TYPES[$type]}" 3
+    for hash in $hashes; do
+      echo " - $(fmt:hash) $(fmt:scope)$(fmt:subject)"
+    done | sort -k3 # sort by scope
+    echo
+  }
+
+  function display:others {
+    local hash type
+
+    # Commits made under types considered other changes
+    local -A changes
+    changes=(${(kv)types[(R)${(j:|:)OTHER_TYPES}]})
+
+    # If no commits found under "other" types, don't display anything
+    (( $#changes != 0 )) || return 0
+
+    fmt:header "Other changes" 3
+    for hash type in ${(kv)changes}; do
+      case "$type" in
+      other) echo " - $(fmt:hash) $(fmt:scope)$(fmt:subject)" ;;
+      *) echo " - $(fmt:hash) $(fmt:scope)$(fmt:type)$(fmt:subject)" ;;
+      esac
+    done | sort -k3 # sort by scope
+    echo
+  }
+
+  ##* Release sections order
+
+  # Display version header
+  display:version
+
+  # Display breaking changes first
+  display:breaking
+
+  # Display changes for commit types in the order specified
+  for type in $MAIN_TYPES; do
+    display:type "$type"
+  done
+
+  # Display other changes
+  display:others
+}
+
+function main {
+  # $1 = until commit, $2 = since commit
+  local until="$1" since="$2"
+
+  # $3 = output format (--text|--raw|--md)
+  # --md:   uses markdown formatting
+  # --raw:  outputs without style
+  # --text: uses ANSI escape codes to style the output
+  local output=${${3:-"--text"}#--*}
+
+  if [[ -z "$until" ]]; then
+    until=HEAD
+  fi
+
+  if [[ -z "$since" ]]; then
+    # If $since is not specified:
+    # 1) try to find the version used before updating
+    # 2) try to find the first version tag before $until
+    since=$(command git config --get oh-my-zsh.lastVersion 2>/dev/null) || \
+    since=$(command git describe --abbrev=0 --tags "$until^" 2>/dev/null) || \
+    unset since
+  elif [[ "$since" = --all ]]; then
+    unset since
+  fi
+
+  # Commit classification arrays
+  local -A types subjects scopes breaking reverts
+  local truncate=0 read_commits=0
+  local version tag
+  local hash refs subject body
+
+  # Get the first version name:
+  # 1) try tag-like version, or
+  # 2) try branch name, or
+  # 3) try name-rev, or
+  # 4) try short hash
+  version=$(command git describe --tags $until 2>/dev/null) \
+    || version=$(command git symbolic-ref --quiet --short $until 2>/dev/null) \
+    || version=$(command git name-rev --no-undefined --name-only --exclude="remotes/*" $until 2>/dev/null) \
+    || version=$(command git rev-parse --short $until 2>/dev/null)
+
+  # Get commit list from $until commit until $since commit, or until root commit if $since is unset
+  local range=${since:+$since..}$until
+
+  # Git log options
+  # -z:             commits are delimited by null bytes
+  # --format:       [7-char hash]<field sep>[ref names]<field sep>[subject]<field sep>[body]
+  # --abbrev=7:     force commit hashes to be 7 characters long
+  # --no-merges:    merge commits are omitted
+  # --first-parent: commits from merged branches are omitted
+  local SEP="0mZmAgIcSeP"
+  local -a raw_commits
+  raw_commits=(${(0)"$(command git -c log.showSignature=false log -z \
+    --format="%h${SEP}%D${SEP}%s${SEP}%b" --abbrev=7 \
+    --no-merges --first-parent $range)"})
+
+  local raw_commit
+  local -a raw_fields
+  for raw_commit in $raw_commits; do
+    # Truncate list on versions with a lot of commits
+    if [[ -z "$since" ]] && (( ++read_commits > 35 )); then
+      truncate=1
+      break
+    fi
+
+    # Read the commit fields (@ is needed to keep empty values)
+    eval "raw_fields=(\"\${(@ps:$SEP:)raw_commit}\")"
+    hash="${raw_fields[1]}"
+    refs="${raw_fields[2]}"
+    subject="${raw_fields[3]}"
+    body="${raw_fields[4]}"
+
+    # If we find a new release (exact tag)
+    if [[ "$refs" = *tag:\ * ]]; then
+      # Parse tag name (needs: setopt extendedglob)
+      tag="${${refs##*tag: }%%,# *}"
+      # Output previous release
+      display-release
+      # Reinitialize commit storage
+      types=()
+      subjects=()
+      scopes=()
+      breaking=()
+      reverts=()
+      # Start work on next release
+      version="$tag"
+      read_commits=1
+    fi
+
+    parse-commit "$hash" "$subject" "$body"
+  done
+
+  display-release
+
+  if (( truncate )); then
+    echo " ...more commits omitted"
+    echo
+  fi
+}
+
+# Use raw output if stdout is not a tty
+if [[ ! -t 1 && -z "$3" ]]; then
+  main "$1" "$2" --raw
+else
+  main "$@"
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/check_for_upgrade.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/check_for_upgrade.sh
new file mode 100644 (file)
index 0000000..cc527e7
--- /dev/null
@@ -0,0 +1,209 @@
+# Migrate .zsh-update file to $ZSH_CACHE_DIR
+if [[ -f ~/.zsh-update && ! -f "${ZSH_CACHE_DIR}/.zsh-update" ]]; then
+  mv ~/.zsh-update "${ZSH_CACHE_DIR}/.zsh-update"
+fi
+
+# Get user's update preferences
+#
+# Supported update modes:
+# - prompt (default): the user is asked before updating when it's time to update
+# - auto: the update is performed automatically when it's time
+# - reminder: a reminder is shown to the user when it's time to update
+# - disabled: automatic update is turned off
+zstyle -s ':omz:update' mode update_mode || {
+  update_mode=prompt
+
+  # If the mode zstyle setting is not set, support old-style settings
+  [[ "$DISABLE_UPDATE_PROMPT" != true ]] || update_mode=auto
+  [[ "$DISABLE_AUTO_UPDATE" != true ]] || update_mode=disabled
+}
+
+# Cancel update if:
+# - the automatic update is disabled.
+# - the current user doesn't have write permissions nor owns the $ZSH directory.
+# - git is unavailable on the system.
+if [[ "$update_mode" = disabled ]] \
+   || [[ ! -w "$ZSH" || ! -O "$ZSH" ]] \
+   || ! command -v git &>/dev/null; then
+  unset update_mode
+  return
+fi
+
+function current_epoch() {
+  zmodload zsh/datetime
+  echo $(( EPOCHSECONDS / 60 / 60 / 24 ))
+}
+
+function is_update_available() {
+  local branch
+  branch=${"$(builtin cd -q "$ZSH"; git config --local oh-my-zsh.branch)":-master}
+
+  local remote remote_url remote_repo
+  remote=${"$(builtin cd -q "$ZSH"; git config --local oh-my-zsh.remote)":-origin}
+  remote_url=$(builtin cd -q "$ZSH"; git config remote.$remote.url)
+
+  local repo
+  case "$remote_url" in
+  https://github.com/*) repo=${${remote_url#https://github.com/}%.git} ;;
+  git@github.com:*) repo=${${remote_url#git@github.com:}%.git} ;;
+  *)
+    # If the remote is not using GitHub we can't check for updates
+    # Let's assume there are updates
+    return 0 ;;
+  esac
+
+  # If the remote repo is not the official one, let's assume there are updates available
+  [[ "$repo" = ohmyzsh/ohmyzsh ]] || return 0
+  local api_url="https://api.github.com/repos/${repo}/commits/${branch}"
+
+  # Get local HEAD. If this fails assume there are updates
+  local local_head
+  local_head=$(builtin cd -q "$ZSH"; git rev-parse $branch 2>/dev/null) || return 0
+
+  # Get remote HEAD. If no suitable command is found assume there are updates
+  # On any other error, skip the update (connection may be down)
+  local remote_head
+  remote_head=$(
+    if (( ${+commands[curl]} )); then
+      curl --connect-timeout 2 -fsSL -H 'Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null
+    elif (( ${+commands[wget]} )); then
+      wget -T 2 -O- --header='Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null
+    elif (( ${+commands[fetch]} )); then
+      HTTP_ACCEPT='Accept: application/vnd.github.v3.sha' fetch -T 2 -o - $api_url 2>/dev/null
+    else
+      exit 0
+    fi
+  ) || return 1
+
+  # Compare local and remote HEADs (if they're equal there are no updates)
+  [[ "$local_head" != "$remote_head" ]] || return 1
+
+  # If local and remote HEADs don't match, check if there's a common ancestor
+  # If the merge-base call fails, $remote_head might not be downloaded so assume there are updates
+  local base
+  base=$(builtin cd -q "$ZSH"; git merge-base $local_head $remote_head 2>/dev/null) || return 0
+
+  # If the common ancestor ($base) is not $remote_head,
+  # the local HEAD is older than the remote HEAD
+  [[ $base != $remote_head ]]
+}
+
+function update_last_updated_file() {
+  echo "LAST_EPOCH=$(current_epoch)" >! "${ZSH_CACHE_DIR}/.zsh-update"
+}
+
+function update_ohmyzsh() {
+  if ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" --interactive; then
+    update_last_updated_file
+  fi
+}
+
+function has_typed_input() {
+  # Created by Philippe Troin <phil@fifi.org>
+  # https://zsh.org/mla/users/2022/msg00062.html
+  emulate -L zsh
+  zmodload zsh/zselect
+
+  # Back up stty settings prior to disabling canonical mode
+  # Consider that no input can be typed if stty fails
+  # (this might happen if stdin is not a terminal)
+  local termios
+  termios=$(stty --save 2>/dev/null) || return 1
+  {
+    # Disable canonical mode so that typed input counts
+    # regardless of whether Enter was pressed
+    stty -icanon
+
+    # Poll stdin (fd 0) for data ready to be read
+    zselect -t 0 -r 0
+    return $?
+  } always {
+    # Restore stty settings
+    stty $termios
+  }
+}
+
+() {
+  emulate -L zsh
+
+  local epoch_target mtime option LAST_EPOCH
+
+  # Remove lock directory if older than a day
+  zmodload zsh/datetime
+  zmodload -F zsh/stat b:zstat
+  if mtime=$(zstat +mtime "$ZSH/log/update.lock" 2>/dev/null); then
+    if (( (mtime + 3600 * 24) < EPOCHSECONDS )); then
+      command rm -rf "$ZSH/log/update.lock"
+    fi
+  fi
+
+  # Check for lock directory
+  if ! command mkdir "$ZSH/log/update.lock" 2>/dev/null; then
+    return
+  fi
+
+  # Remove lock directory on exit. `return $ret` is important for when trapping a SIGINT:
+  #  The return status from the function is handled specially. If it is zero, the signal is
+  #  assumed to have been handled, and execution continues normally. Otherwise, the shell
+  #  will behave as interrupted except that the return status of the trap is retained.
+  #  This means that for a CTRL+C, the trap needs to return the same exit status so that
+  #  the shell actually exits what it's running.
+  trap "
+    ret=\$?
+    unset update_mode
+    unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh 2>/dev/null
+    command rm -rf '$ZSH/log/update.lock'
+    return \$ret
+  " EXIT INT QUIT
+
+  # Create or update .zsh-update file if missing or malformed
+  if ! source "${ZSH_CACHE_DIR}/.zsh-update" 2>/dev/null || [[ -z "$LAST_EPOCH" ]]; then
+    update_last_updated_file
+    return
+  fi
+
+  # Number of days before trying to update again
+  zstyle -s ':omz:update' frequency epoch_target || epoch_target=${UPDATE_ZSH_DAYS:-13}
+  # Test if enough time has passed until the next update
+  if (( ( $(current_epoch) - $LAST_EPOCH ) < $epoch_target )); then
+    return
+  fi
+
+  # Test if Oh My Zsh directory is a git repository
+  if ! (builtin cd -q "$ZSH" && LANG= git rev-parse &>/dev/null); then
+    echo >&2 "[oh-my-zsh] Can't update: not a git repository."
+    return
+  fi
+
+  # Check if there are updates available before proceeding
+  if ! is_update_available; then
+    return
+  fi
+
+  # If in reminder mode or user has typed input, show reminder and exit
+  if [[ "$update_mode" = reminder ]] || has_typed_input; then
+    printf '\r\e[0K' # move cursor to first column and clear whole line
+    echo "[oh-my-zsh] It's time to update! You can do that by running \`omz update\`"
+    return 0
+  fi
+
+  # Don't ask for confirmation before updating if in auto mode
+  if [[ "$update_mode" = auto ]]; then
+    update_ohmyzsh
+    return $?
+  fi
+
+  # Ask for confirmation and only update on 'y', 'Y' or Enter
+  # Otherwise just show a reminder for how to update
+  echo -n "[oh-my-zsh] Would you like to update? [Y/n] "
+  read -r -k 1 option
+  [[ "$option" = $'\n' ]] || echo
+  case "$option" in
+    [yY$'\n']) update_ohmyzsh ;;
+    [nN]) update_last_updated_file ;&
+    *) echo "[oh-my-zsh] You can update manually by running \`omz update\`" ;;
+  esac
+}
+
+unset update_mode
+unset -f current_epoch is_update_available update_last_updated_file update_ohmyzsh
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/install.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/install.sh
new file mode 100755 (executable)
index 0000000..a6538f9
--- /dev/null
@@ -0,0 +1,523 @@
+#!/bin/sh
+#
+# This script should be run via curl:
+#   sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
+# or via wget:
+#   sh -c "$(wget -qO- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
+# or via fetch:
+#   sh -c "$(fetch -o - https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
+#
+# As an alternative, you can first download the install script and run it afterwards:
+#   wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
+#   sh install.sh
+#
+# You can tweak the install behavior by setting variables when running the script. For
+# example, to change the path to the Oh My Zsh repository:
+#   ZSH=~/.zsh sh install.sh
+#
+# Respects the following environment variables:
+#   ZSH     - path to the Oh My Zsh repository folder (default: $HOME/.oh-my-zsh)
+#   REPO    - name of the GitHub repo to install from (default: ohmyzsh/ohmyzsh)
+#   REMOTE  - full remote URL of the git repo to install (default: GitHub via HTTPS)
+#   BRANCH  - branch to check out immediately after install (default: master)
+#
+# Other options:
+#   CHSH       - 'no' means the installer will not change the default shell (default: yes)
+#   RUNZSH     - 'no' means the installer will not run zsh after the install (default: yes)
+#   KEEP_ZSHRC - 'yes' means the installer will not replace an existing .zshrc (default: no)
+#
+# You can also pass some arguments to the install script to set some these options:
+#   --skip-chsh: has the same behavior as setting CHSH to 'no'
+#   --unattended: sets both CHSH and RUNZSH to 'no'
+#   --keep-zshrc: sets KEEP_ZSHRC to 'yes'
+# For example:
+#   sh install.sh --unattended
+# or:
+#   sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
+#
+set -e
+
+# Make sure important variables exist if not already defined
+#
+# $USER is defined by login(1) which is not always executed (e.g. containers)
+# POSIX: https://pubs.opengroup.org/onlinepubs/009695299/utilities/id.html
+USER=${USER:-$(id -u -n)}
+# $HOME is defined at the time of login, but it could be unset. If it is unset,
+# a tilde by itself (~) will not be expanded to the current user's home directory.
+# POSIX: https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap08.html#tag_08_03
+HOME="${HOME:-$(getent passwd $USER 2>/dev/null | cut -d: -f6)}"
+# macOS does not have getent, but this works even if $HOME is unset
+HOME="${HOME:-$(eval echo ~$USER)}"
+
+
+# Track if $ZSH was provided
+custom_zsh=${ZSH:+yes}
+
+# Default settings
+ZSH="${ZSH:-$HOME/.oh-my-zsh}"
+REPO=${REPO:-ohmyzsh/ohmyzsh}
+REMOTE=${REMOTE:-https://github.com/${REPO}.git}
+BRANCH=${BRANCH:-master}
+
+# Other options
+CHSH=${CHSH:-yes}
+RUNZSH=${RUNZSH:-yes}
+KEEP_ZSHRC=${KEEP_ZSHRC:-no}
+
+
+command_exists() {
+  command -v "$@" >/dev/null 2>&1
+}
+
+user_can_sudo() {
+  # Check if sudo is installed
+  command_exists sudo || return 1
+  # The following command has 3 parts:
+  #
+  # 1. Run `sudo` with `-v`. Does the following:
+  #    • with privilege: asks for a password immediately.
+  #    • without privilege: exits with error code 1 and prints the message:
+  #      Sorry, user <username> may not run sudo on <hostname>
+  #
+  # 2. Pass `-n` to `sudo` to tell it to not ask for a password. If the
+  #    password is not required, the command will finish with exit code 0.
+  #    If one is required, sudo will exit with error code 1 and print the
+  #    message:
+  #    sudo: a password is required
+  #
+  # 3. Check for the words "may not run sudo" in the output to really tell
+  #    whether the user has privileges or not. For that we have to make sure
+  #    to run `sudo` in the default locale (with `LANG=`) so that the message
+  #    stays consistent regardless of the user's locale.
+  #
+  ! LANG= sudo -n -v 2>&1 | grep -q "may not run sudo"
+}
+
+# The [ -t 1 ] check only works when the function is not called from
+# a subshell (like in `$(...)` or `(...)`, so this hack redefines the
+# function at the top level to always return false when stdout is not
+# a tty.
+if [ -t 1 ]; then
+  is_tty() {
+    true
+  }
+else
+  is_tty() {
+    false
+  }
+fi
+
+# This function uses the logic from supports-hyperlinks[1][2], which is
+# made by Kat Marchán (@zkat) and licensed under the Apache License 2.0.
+# [1] https://github.com/zkat/supports-hyperlinks
+# [2] https://crates.io/crates/supports-hyperlinks
+#
+# Copyright (c) 2021 Kat Marchán
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+supports_hyperlinks() {
+  # $FORCE_HYPERLINK must be set and be non-zero (this acts as a logic bypass)
+  if [ -n "$FORCE_HYPERLINK" ]; then
+    [ "$FORCE_HYPERLINK" != 0 ]
+    return $?
+  fi
+
+  # If stdout is not a tty, it doesn't support hyperlinks
+  is_tty || return 1
+
+  # DomTerm terminal emulator (domterm.org)
+  if [ -n "$DOMTERM" ]; then
+    return 0
+  fi
+
+  # VTE-based terminals above v0.50 (Gnome Terminal, Guake, ROXTerm, etc)
+  if [ -n "$VTE_VERSION" ]; then
+    [ $VTE_VERSION -ge 5000 ]
+    return $?
+  fi
+
+  # If $TERM_PROGRAM is set, these terminals support hyperlinks
+  case "$TERM_PROGRAM" in
+  Hyper|iTerm.app|terminology|WezTerm) return 0 ;;
+  esac
+
+  # kitty supports hyperlinks
+  if [ "$TERM" = xterm-kitty ]; then
+    return 0
+  fi
+
+  # Windows Terminal also supports hyperlinks
+  if [ -n "$WT_SESSION" ]; then
+    return 0
+  fi
+
+  # Konsole supports hyperlinks, but it's an opt-in setting that can't be detected
+  # https://github.com/ohmyzsh/ohmyzsh/issues/10964
+  # if [ -n "$KONSOLE_VERSION" ]; then
+  #   return 0
+  # fi
+
+  return 1
+}
+
+# Adapted from code and information by Anton Kochkov (@XVilka)
+# Source: https://gist.github.com/XVilka/8346728
+supports_truecolor() {
+  case "$COLORTERM" in
+  truecolor|24bit) return 0 ;;
+  esac
+
+  case "$TERM" in
+  iterm           |\
+  tmux-truecolor  |\
+  linux-truecolor |\
+  xterm-truecolor |\
+  screen-truecolor) return 0 ;;
+  esac
+
+  return 1
+}
+
+fmt_link() {
+  # $1: text, $2: url, $3: fallback mode
+  if supports_hyperlinks; then
+    printf '\033]8;;%s\033\\%s\033]8;;\033\\\n' "$2" "$1"
+    return
+  fi
+
+  case "$3" in
+  --text) printf '%s\n' "$1" ;;
+  --url|*) fmt_underline "$2" ;;
+  esac
+}
+
+fmt_underline() {
+  is_tty && printf '\033[4m%s\033[24m\n' "$*" || printf '%s\n' "$*"
+}
+
+# shellcheck disable=SC2016 # backtick in single-quote
+fmt_code() {
+  is_tty && printf '`\033[2m%s\033[22m`\n' "$*" || printf '`%s`\n' "$*"
+}
+
+fmt_error() {
+  printf '%sError: %s%s\n' "${FMT_BOLD}${FMT_RED}" "$*" "$FMT_RESET" >&2
+}
+
+setup_color() {
+  # Only use colors if connected to a terminal
+  if ! is_tty; then
+    FMT_RAINBOW=""
+    FMT_RED=""
+    FMT_GREEN=""
+    FMT_YELLOW=""
+    FMT_BLUE=""
+    FMT_BOLD=""
+    FMT_RESET=""
+    return
+  fi
+
+  if supports_truecolor; then
+    FMT_RAINBOW="
+      $(printf '\033[38;2;255;0;0m')
+      $(printf '\033[38;2;255;97;0m')
+      $(printf '\033[38;2;247;255;0m')
+      $(printf '\033[38;2;0;255;30m')
+      $(printf '\033[38;2;77;0;255m')
+      $(printf '\033[38;2;168;0;255m')
+      $(printf '\033[38;2;245;0;172m')
+    "
+  else
+    FMT_RAINBOW="
+      $(printf '\033[38;5;196m')
+      $(printf '\033[38;5;202m')
+      $(printf '\033[38;5;226m')
+      $(printf '\033[38;5;082m')
+      $(printf '\033[38;5;021m')
+      $(printf '\033[38;5;093m')
+      $(printf '\033[38;5;163m')
+    "
+  fi
+
+  FMT_RED=$(printf '\033[31m')
+  FMT_GREEN=$(printf '\033[32m')
+  FMT_YELLOW=$(printf '\033[33m')
+  FMT_BLUE=$(printf '\033[34m')
+  FMT_BOLD=$(printf '\033[1m')
+  FMT_RESET=$(printf '\033[0m')
+}
+
+setup_ohmyzsh() {
+  # Prevent the cloned repository from having insecure permissions. Failing to do
+  # so causes compinit() calls to fail with "command not found: compdef" errors
+  # for users with insecure umasks (e.g., "002", allowing group writability). Note
+  # that this will be ignored under Cygwin by default, as Windows ACLs take
+  # precedence over umasks except for filesystems mounted with option "noacl".
+  umask g-w,o-w
+
+  echo "${FMT_BLUE}Cloning Oh My Zsh...${FMT_RESET}"
+
+  command_exists git || {
+    fmt_error "git is not installed"
+    exit 1
+  }
+
+  ostype=$(uname)
+  if [ -z "${ostype%CYGWIN*}" ] && git --version | grep -Eq 'msysgit|windows'; then
+    fmt_error "Windows/MSYS Git is not supported on Cygwin"
+    fmt_error "Make sure the Cygwin git package is installed and is first on the \$PATH"
+    exit 1
+  fi
+
+  # Manual clone with git config options to support git < v1.7.2
+  git init --quiet "$ZSH" && cd "$ZSH" \
+  && git config core.eol lf \
+  && git config core.autocrlf false \
+  && git config fsck.zeroPaddedFilemode ignore \
+  && git config fetch.fsck.zeroPaddedFilemode ignore \
+  && git config receive.fsck.zeroPaddedFilemode ignore \
+  && git config oh-my-zsh.remote origin \
+  && git config oh-my-zsh.branch "$BRANCH" \
+  && git remote add origin "$REMOTE" \
+  && git fetch --depth=1 origin \
+  && git checkout -b "$BRANCH" "origin/$BRANCH" || {
+    [ ! -d "$ZSH" ] || {
+      cd -
+      rm -rf "$ZSH" 2>/dev/null
+    }
+    fmt_error "git clone of oh-my-zsh repo failed"
+    exit 1
+  }
+  # Exit installation directory
+  cd -
+
+  echo
+}
+
+setup_zshrc() {
+  # Keep most recent old .zshrc at .zshrc.pre-oh-my-zsh, and older ones
+  # with datestamp of installation that moved them aside, so we never actually
+  # destroy a user's original zshrc
+  echo "${FMT_BLUE}Looking for an existing zsh config...${FMT_RESET}"
+
+  # Must use this exact name so uninstall.sh can find it
+  OLD_ZSHRC=~/.zshrc.pre-oh-my-zsh
+  if [ -f ~/.zshrc ] || [ -h ~/.zshrc ]; then
+    # Skip this if the user doesn't want to replace an existing .zshrc
+    if [ "$KEEP_ZSHRC" = yes ]; then
+      echo "${FMT_YELLOW}Found ~/.zshrc.${FMT_RESET} ${FMT_GREEN}Keeping...${FMT_RESET}"
+      return
+    fi
+    if [ -e "$OLD_ZSHRC" ]; then
+      OLD_OLD_ZSHRC="${OLD_ZSHRC}-$(date +%Y-%m-%d_%H-%M-%S)"
+      if [ -e "$OLD_OLD_ZSHRC" ]; then
+        fmt_error "$OLD_OLD_ZSHRC exists. Can't back up ${OLD_ZSHRC}"
+        fmt_error "re-run the installer again in a couple of seconds"
+        exit 1
+      fi
+      mv "$OLD_ZSHRC" "${OLD_OLD_ZSHRC}"
+
+      echo "${FMT_YELLOW}Found old ~/.zshrc.pre-oh-my-zsh." \
+        "${FMT_GREEN}Backing up to ${OLD_OLD_ZSHRC}${FMT_RESET}"
+    fi
+    echo "${FMT_YELLOW}Found ~/.zshrc.${FMT_RESET} ${FMT_GREEN}Backing up to ${OLD_ZSHRC}${FMT_RESET}"
+    mv ~/.zshrc "$OLD_ZSHRC"
+  fi
+
+  echo "${FMT_GREEN}Using the Oh My Zsh template file and adding it to ~/.zshrc.${FMT_RESET}"
+
+  # Replace $HOME path with '$HOME' in $ZSH variable in .zshrc file
+  omz=$(echo "$ZSH" | sed "s|^$HOME/|\$HOME/|")
+  sed "s|^export ZSH=.*$|export ZSH=\"${omz}\"|" "$ZSH/templates/zshrc.zsh-template" > ~/.zshrc-omztemp
+  mv -f ~/.zshrc-omztemp ~/.zshrc
+
+  echo
+}
+
+setup_shell() {
+  # Skip setup if the user wants or stdin is closed (not running interactively).
+  if [ "$CHSH" = no ]; then
+    return
+  fi
+
+  # If this user's login shell is already "zsh", do not attempt to switch.
+  if [ "$(basename -- "$SHELL")" = "zsh" ]; then
+    return
+  fi
+
+  # If this platform doesn't provide a "chsh" command, bail out.
+  if ! command_exists chsh; then
+    cat <<EOF
+I can't change your shell automatically because this system does not have chsh.
+${FMT_BLUE}Please manually change your default shell to zsh${FMT_RESET}
+EOF
+    return
+  fi
+
+  echo "${FMT_BLUE}Time to change your default shell to zsh:${FMT_RESET}"
+
+  # Prompt for user choice on changing the default login shell
+  printf '%sDo you want to change your default shell to zsh? [Y/n]%s ' \
+    "$FMT_YELLOW" "$FMT_RESET"
+  read -r opt
+  case $opt in
+    y*|Y*|"") ;;
+    n*|N*) echo "Shell change skipped."; return ;;
+    *) echo "Invalid choice. Shell change skipped."; return ;;
+  esac
+
+  # Check if we're running on Termux
+  case "$PREFIX" in
+    *com.termux*) termux=true; zsh=zsh ;;
+    *) termux=false ;;
+  esac
+
+  if [ "$termux" != true ]; then
+    # Test for the right location of the "shells" file
+    if [ -f /etc/shells ]; then
+      shells_file=/etc/shells
+    elif [ -f /usr/share/defaults/etc/shells ]; then # Solus OS
+      shells_file=/usr/share/defaults/etc/shells
+    else
+      fmt_error "could not find /etc/shells file. Change your default shell manually."
+      return
+    fi
+
+    # Get the path to the right zsh binary
+    # 1. Use the most preceding one based on $PATH, then check that it's in the shells file
+    # 2. If that fails, get a zsh path from the shells file, then check it actually exists
+    if ! zsh=$(command -v zsh) || ! grep -qx "$zsh" "$shells_file"; then
+      if ! zsh=$(grep '^/.*/zsh$' "$shells_file" | tail -n 1) || [ ! -f "$zsh" ]; then
+        fmt_error "no zsh binary found or not present in '$shells_file'"
+        fmt_error "change your default shell manually."
+        return
+      fi
+    fi
+  fi
+
+  # We're going to change the default shell, so back up the current one
+  if [ -n "$SHELL" ]; then
+    echo "$SHELL" > ~/.shell.pre-oh-my-zsh
+  else
+    grep "^$USER:" /etc/passwd | awk -F: '{print $7}' > ~/.shell.pre-oh-my-zsh
+  fi
+
+  echo "Changing your shell to $zsh..."
+
+  # Check if user has sudo privileges to run `chsh` with or without `sudo`
+  #
+  # This allows the call to succeed without password on systems where the
+  # user does not have a password but does have sudo privileges, like in
+  # Google Cloud Shell.
+  #
+  # On systems that don't have a user with passwordless sudo, the user will
+  # be prompted for the password either way, so this shouldn't cause any issues.
+  #
+  if user_can_sudo; then
+    sudo -k chsh -s "$zsh" "$USER"  # -k forces the password prompt
+  else
+    chsh -s "$zsh" "$USER"          # run chsh normally
+  fi
+
+  # Check if the shell change was successful
+  if [ $? -ne 0 ]; then
+    fmt_error "chsh command unsuccessful. Change your default shell manually."
+  else
+    export SHELL="$zsh"
+    echo "${FMT_GREEN}Shell successfully changed to '$zsh'.${FMT_RESET}"
+  fi
+
+  echo
+}
+
+# shellcheck disable=SC2183  # printf string has more %s than arguments ($FMT_RAINBOW expands to multiple arguments)
+print_success() {
+  printf '%s         %s__      %s           %s        %s       %s     %s__   %s\n'      $FMT_RAINBOW $FMT_RESET
+  printf '%s  ____  %s/ /_    %s ____ ___  %s__  __  %s ____  %s_____%s/ /_  %s\n'      $FMT_RAINBOW $FMT_RESET
+  printf '%s / __ \\%s/ __ \\  %s / __ `__ \\%s/ / / / %s /_  / %s/ ___/%s __ \\ %s\n'  $FMT_RAINBOW $FMT_RESET
+  printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s   / /_%s(__  )%s / / / %s\n'      $FMT_RAINBOW $FMT_RESET
+  printf '%s\\____/%s_/ /_/ %s /_/ /_/ /_/%s\\__, / %s   /___/%s____/%s_/ /_/  %s\n'    $FMT_RAINBOW $FMT_RESET
+  printf '%s    %s        %s           %s /____/ %s       %s     %s          %s....is now installed!%s\n' $FMT_RAINBOW $FMT_GREEN $FMT_RESET
+  printf '\n'
+  printf '\n'
+  printf "%s %s %s\n" "Before you scream ${FMT_BOLD}${FMT_YELLOW}Oh My Zsh!${FMT_RESET} look over the" \
+    "$(fmt_code "$(fmt_link ".zshrc" "file://$HOME/.zshrc" --text)")" \
+    "file to select plugins, themes, and options."
+  printf '\n'
+  printf '%s\n' "• Follow us on Twitter: $(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)"
+  printf '%s\n' "• Join our Discord community: $(fmt_link "Discord server" https://discord.gg/ohmyzsh)"
+  printf '%s\n' "• Get stickers, t-shirts, coffee mugs and more: $(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)"
+  printf '%s\n' $FMT_RESET
+}
+
+main() {
+  # Run as unattended if stdin is not a tty
+  if [ ! -t 0 ]; then
+    RUNZSH=no
+    CHSH=no
+  fi
+
+  # Parse arguments
+  while [ $# -gt 0 ]; do
+    case $1 in
+      --unattended) RUNZSH=no; CHSH=no ;;
+      --skip-chsh) CHSH=no ;;
+      --keep-zshrc) KEEP_ZSHRC=yes ;;
+    esac
+    shift
+  done
+
+  setup_color
+
+  if ! command_exists zsh; then
+    echo "${FMT_YELLOW}Zsh is not installed.${FMT_RESET} Please install zsh first."
+    exit 1
+  fi
+
+  if [ -d "$ZSH" ]; then
+    echo "${FMT_YELLOW}The \$ZSH folder already exists ($ZSH).${FMT_RESET}"
+    if [ "$custom_zsh" = yes ]; then
+      cat <<EOF
+
+You ran the installer with the \$ZSH setting or the \$ZSH variable is
+exported. You have 3 options:
+
+1. Unset the ZSH variable when calling the installer:
+   $(fmt_code "ZSH= sh install.sh")
+2. Install Oh My Zsh to a directory that doesn't exist yet:
+   $(fmt_code "ZSH=path/to/new/ohmyzsh/folder sh install.sh")
+3. (Caution) If the folder doesn't contain important information,
+   you can just remove it with $(fmt_code "rm -r $ZSH")
+
+EOF
+    else
+      echo "You'll need to remove it if you want to reinstall."
+    fi
+    exit 1
+  fi
+
+  setup_ohmyzsh
+  setup_zshrc
+  setup_shell
+
+  print_success
+
+  if [ $RUNZSH = no ]; then
+    echo "${FMT_YELLOW}Run zsh to try it out.${FMT_RESET}"
+    exit
+  fi
+
+  exec zsh -l
+}
+
+main "$@"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/require_tool.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/require_tool.sh
new file mode 100755 (executable)
index 0000000..19c5f6f
--- /dev/null
@@ -0,0 +1,161 @@
+__require_tool_version_compare ()
+{
+  (
+    # Locally ignore failures, otherwise we'll exit whenever $1 and $2
+    # are not equal!
+    set +e
+
+awk_strverscmp='
+  # Use only awk features that work with 7th edition Unix awk (1978).
+  # My, what an old awk you have, Mr. Solaris!
+  END {
+    while (length(v1) || length(v2)) {
+      # Set d1 to be the next thing to compare from v1, and likewise for d2.
+      # Normally this is a single character, but if v1 and v2 contain digits,
+      # compare them as integers and fractions as strverscmp does.
+      if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) {
+       # Split v1 and v2 into their leading digit string components d1 and d2,
+       # and advance v1 and v2 past the leading digit strings.
+       for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue
+       for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue
+       d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1)
+       d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1)
+       if (d1 ~ /^0/) {
+         if (d2 ~ /^0/) {
+           # Compare two fractions.
+           while (d1 ~ /^0/ && d2 ~ /^0/) {
+             d1 = substr(d1, 2); len1--
+             d2 = substr(d2, 2); len2--
+           }
+           if (len1 != len2 && ! (len1 && len2 && substr(d1, 1, 1) == substr(d2, 1, 1))) {
+             # The two components differ in length, and the common prefix
+             # contains only leading zeros.  Consider the longer to be less.
+             d1 = -len1
+             d2 = -len2
+           } else {
+             # Otherwise, compare as strings.
+             d1 = "x" d1
+             d2 = "x" d2
+           }
+         } else {
+           # A fraction is less than an integer.
+           exit 1
+         }
+       } else {
+         if (d2 ~ /^0/) {
+           # An integer is greater than a fraction.
+           exit 2
+         } else {
+           # Compare two integers.
+           d1 += 0
+           d2 += 0
+         }
+       }
+      } else {
+       # The normal case, without worrying about digits.
+       if (v1 == "") d1 = v1; else { d1 = substr(v1, 1, 1); v1 = substr(v1,2) }
+       if (v2 == "") d2 = v2; else { d2 = substr(v2, 1, 1); v2 = substr(v2,2) }
+      }
+      if (d1 < d2) exit 1
+      if (d1 > d2) exit 2
+    }
+  }
+'
+    awk "$awk_strverscmp" v1="$1" v2="$2" /dev/null
+    case $? in
+      1)  echo '<';;
+      0)  echo '=';;
+      2)  echo '>';;
+    esac
+  )
+}
+
+
+__require_tool_fatal ()
+{
+    echo $@ >/dev/stderr
+    return 1
+}
+
+# Usage: require_tool program version
+# Returns: 0 if $1 version if greater equals than $2, 1 otherwise.
+# In case of error, message is written on error output.
+#
+# Example: require_tool gcc 4.6
+# Use GCC environment variable if defined instead of lookup for the tool
+# in the environment.
+require_tool ()
+{
+  envvar_name=$(echo $1 | tr '[:lower:]' '[:upper:]')
+  tool=$(printenv $envvar_name || echo $1)
+  local version=$($tool --version 2>/dev/null| \
+    sed -n 's/.*[^0-9.]\([0-9]*\.[0-9.]*\).*/\1/p;q')
+  if test x"$version" = x ; then
+      echo "$tool is required" >/dev/stderr
+      return 1
+  fi
+  case $(__require_tool_version_compare "$2" "$version") in
+    '>')
+         echo "$1 $2 or better is required: this is $tool $version" >/dev/stderr
+         return 1
+         ;;
+  esac
+}
+
+usage() {
+    cat <<EOF
+NAME
+    require_tool.sh - Ensure version of a tool is greater than the one expected
+
+SYNOPSIS
+    require_tool.sh [ -h ]
+                    [ --help ]
+                    [ TOOL MIN_VERSION ]
+
+DESCRIPTION
+    TOOL is the name or path of the program to check. If the name is specified, its
+    path is deduced from PATH environment variable. If environment variable TOOL
+    (in upper-case characters) is defined, considers its value as path to the tool.
+
+    MIN_VERSION is a string representing the minimum required version.
+
+BEHAVIOR
+    * locate path to the program.
+    * execute $ TOOL_PATH --version
+    * extract version from standard output.
+    * compare this version to the expected one.
+
+OPTIONS
+    -h --help
+        Display this message and exit 0
+
+ERRORS
+    if program is not found or its version is prior to expected version,
+    a message is written to error output.
+
+EXIT VALUE
+    returns 0 if program version if greater equals than expected version,
+    returns 1 otherwise.
+
+EXAMPLE
+    $ require_tool.sh emacs 23
+    $ CC=g++ require_tool.sh cc 4.6
+    $ require_tool.sh zsh 4.5
+
+EOF
+}
+
+for arg in $@; do
+    case $arg in
+        -h|--help)
+            usage
+            exit 0
+            ;;
+    esac
+done
+if [ $# -gt 2 ] ; then
+    echo "ERROR: expecting 2 parameters. Please see option --help"
+    exit 1
+fi
+
+require_tool $@
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/theme_chooser.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/theme_chooser.sh
new file mode 100755 (executable)
index 0000000..3883f1d
--- /dev/null
@@ -0,0 +1,98 @@
+#!/bin/zsh
+
+# Zsh Theme Chooser by fox (fox91 at anche dot no)
+# This program is free software. It comes without any warranty, to
+# the extent permitted by applicable law. You can redistribute it
+# and/or modify it under the terms of the Do What The Fuck You Want
+# To Public License, Version 2, as published by Sam Hocevar. See
+# http://www.wtfpl.net/txt/copying/ for more details.
+
+THEMES_DIR="$ZSH/themes"
+FAVLIST="${HOME}/.zsh_favlist"
+source $ZSH/oh-my-zsh.sh
+
+function noyes() {
+    read "a?$1 [y/N] "
+    if [[ $a == "N" || $a == "n" || $a = "" ]]; then
+        return 0
+    fi
+    return 1
+}
+
+function theme_preview() {
+    THEME=$1
+    THEME_NAME=`echo $THEME | sed s/\.zsh-theme$//`
+    print "$fg[blue]${(l.((${COLUMNS}-${#THEME_NAME}-5))..─.)}$reset_color $THEME_NAME $fg[blue]───$reset_color"
+    source "$THEMES_DIR/$THEME"
+    cols=$(tput cols)
+    (exit 1)
+    print -P "$PROMPT                                                                                      $RPROMPT"
+}
+
+function banner() {
+    echo
+    echo "\e[0;1;35;95m╺━\e[0;1;31;91m┓┏\e[0;1;33;93m━┓\e[0;1;32;92m╻\e[0m \e[0;1;36;96m╻\e[0m   \e[0;1;35;95m╺┳\e[0;1;31;91m╸╻\e[0m \e[0;1;33;93m╻\e[0;1;32;92m┏━\e[0;1;36;96m╸┏\e[0;1;34;94m┳┓\e[0;1;35;95m┏━\e[0;1;31;91m╸\e[0m   \e[0;1;32;92m┏━\e[0;1;36;96m╸╻\e[0m \e[0;1;34;94m╻\e[0;1;35;95m┏━\e[0;1;31;91m┓┏\e[0;1;33;93m━┓\e[0;1;32;92m┏━\e[0;1;36;96m┓┏\e[0;1;34;94m━╸\e[0;1;35;95m┏━\e[0;1;31;91m┓\e[0m"
+    echo "\e[0;1;31;91m┏━\e[0;1;33;93m┛┗\e[0;1;32;92m━┓\e[0;1;36;96m┣━\e[0;1;34;94m┫\e[0m    \e[0;1;31;91m┃\e[0m \e[0;1;33;93m┣\e[0;1;32;92m━┫\e[0;1;36;96m┣╸\e[0m \e[0;1;34;94m┃\e[0;1;35;95m┃┃\e[0;1;31;91m┣╸\e[0m    \e[0;1;36;96m┃\e[0m  \e[0;1;34;94m┣\e[0;1;35;95m━┫\e[0;1;31;91m┃\e[0m \e[0;1;33;93m┃┃\e[0m \e[0;1;32;92m┃\e[0;1;36;96m┗━\e[0;1;34;94m┓┣\e[0;1;35;95m╸\e[0m \e[0;1;31;91m┣┳\e[0;1;33;93m┛\e[0m"
+    echo "\e[0;1;33;93m┗━\e[0;1;32;92m╸┗\e[0;1;36;96m━┛\e[0;1;34;94m╹\e[0m \e[0;1;35;95m╹\e[0m    \e[0;1;33;93m╹\e[0m \e[0;1;32;92m╹\e[0m \e[0;1;36;96m╹\e[0;1;34;94m┗━\e[0;1;35;95m╸╹\e[0m \e[0;1;31;91m╹\e[0;1;33;93m┗━\e[0;1;32;92m╸\e[0m   \e[0;1;34;94m┗━\e[0;1;35;95m╸╹\e[0m \e[0;1;31;91m╹\e[0;1;33;93m┗━\e[0;1;32;92m┛┗\e[0;1;36;96m━┛\e[0;1;34;94m┗━\e[0;1;35;95m┛┗\e[0;1;31;91m━╸\e[0;1;33;93m╹┗\e[0;1;32;92m╸\e[0m"
+    echo
+}
+
+function usage() {
+    echo "Usage: $0 [options] [theme]"
+    echo
+    echo "Options"
+    echo "  -l   List available themes"
+    echo "  -s   Show all themes"
+    echo "  -h   Get this help message"
+    exit 1
+}
+
+function list_themes() {
+    for THEME in $(ls $THEMES_DIR); do
+        THEME_NAME=`echo $THEME | sed s/\.zsh-theme$//`
+        echo $THEME_NAME
+    done
+}
+
+function insert_favlist() {
+    if grep -q "$THEME_NAME" $FAVLIST 2> /dev/null ; then
+        echo "Already in favlist"
+    else
+        echo $THEME_NAME >> $FAVLIST
+        echo "Saved to favlist"
+    fi
+
+}
+
+function theme_chooser() {
+    for THEME in $(ls $THEMES_DIR); do
+        echo
+        theme_preview $THEME
+        echo
+        if [[ -z $1 ]]; then
+            noyes "Do you want to add it to your favourite list ($FAVLIST)?" || \
+                  insert_favlist $THEME_NAME
+            echo
+        fi
+    done
+}
+
+while getopts ":lhs" Option
+do
+  case $Option in
+    l ) list_themes ;;
+    s ) theme_chooser 0 ;;
+    h ) usage ;;
+    * ) usage ;; # Default.
+  esac
+done
+
+if [[ -z $Option ]]; then
+    if [[ -z $1 ]]; then
+        banner
+        echo
+        theme_chooser
+    else
+        theme_preview $1".zsh-theme"
+    fi
+fi
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/uninstall.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/uninstall.sh
new file mode 100644 (file)
index 0000000..6a0e7b4
--- /dev/null
@@ -0,0 +1,40 @@
+read -r -p "Are you sure you want to remove Oh My Zsh? [y/N] " confirmation
+if [ "$confirmation" != y ] && [ "$confirmation" != Y ]; then
+  echo "Uninstall cancelled"
+  exit
+fi
+
+echo "Removing ~/.oh-my-zsh"
+if [ -d ~/.oh-my-zsh ]; then
+  rm -rf ~/.oh-my-zsh
+fi
+
+if [ -e ~/.zshrc ]; then
+  ZSHRC_SAVE=~/.zshrc.omz-uninstalled-$(date +%Y-%m-%d_%H-%M-%S)
+  echo "Found ~/.zshrc -- Renaming to ${ZSHRC_SAVE}"
+  mv ~/.zshrc "${ZSHRC_SAVE}"
+fi
+
+echo "Looking for original zsh config..."
+ZSHRC_ORIG=~/.zshrc.pre-oh-my-zsh
+if [ -e "$ZSHRC_ORIG" ]; then
+  echo "Found $ZSHRC_ORIG -- Restoring to ~/.zshrc"
+  mv "$ZSHRC_ORIG" ~/.zshrc
+  echo "Your original zsh config was restored."
+else
+  echo "No original zsh config found"
+fi
+
+if hash chsh >/dev/null 2>&1 && [ -f ~/.shell.pre-oh-my-zsh ]; then
+  old_shell=$(cat ~/.shell.pre-oh-my-zsh)
+  echo "Switching your shell back to '$old_shell':"
+  if chsh -s "$old_shell"; then
+    rm -f ~/.shell.pre-oh-my-zsh
+  else
+    echo "Could not change default shell. Change it manually by running chsh"
+    echo "or editing the /etc/passwd file."
+  fi
+fi
+
+echo "Thanks for trying out Oh My Zsh. It's been uninstalled."
+echo "Don't forget to restart your terminal!"
diff --git a/stow/oh-my-zsh/.oh-my-zsh/tools/upgrade.sh b/stow/oh-my-zsh/.oh-my-zsh/tools/upgrade.sh
new file mode 100755 (executable)
index 0000000..596a593
--- /dev/null
@@ -0,0 +1,251 @@
+#!/usr/bin/env zsh
+
+# Protect against running with shells other than zsh
+if [ -z "$ZSH_VERSION" ]; then
+  exec zsh "$0" "$@"
+fi
+
+# Protect against unwanted sourcing
+case "$ZSH_EVAL_CONTEXT" in
+  *:file) echo "error: this file should not be sourced" && return ;;
+esac
+
+cd "$ZSH"
+
+# Use colors, but only if connected to a terminal
+# and that terminal supports them.
+
+# The [ -t 1 ] check only works when the function is not called from
+# a subshell (like in `$(...)` or `(...)`, so this hack redefines the
+# function at the top level to always return false when stdout is not
+# a tty.
+if [ -t 1 ]; then
+  is_tty() {
+    true
+  }
+else
+  is_tty() {
+    false
+  }
+fi
+
+# This function uses the logic from supports-hyperlinks[1][2], which is
+# made by Kat Marchán (@zkat) and licensed under the Apache License 2.0.
+# [1] https://github.com/zkat/supports-hyperlinks
+# [2] https://crates.io/crates/supports-hyperlinks
+#
+# Copyright (c) 2021 Kat Marchán
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+supports_hyperlinks() {
+  # $FORCE_HYPERLINK must be set and be non-zero (this acts as a logic bypass)
+  if [ -n "$FORCE_HYPERLINK" ]; then
+    [ "$FORCE_HYPERLINK" != 0 ]
+    return $?
+  fi
+
+  # If stdout is not a tty, it doesn't support hyperlinks
+  is_tty || return 1
+
+  # DomTerm terminal emulator (domterm.org)
+  if [ -n "$DOMTERM" ]; then
+    return 0
+  fi
+
+  # VTE-based terminals above v0.50 (Gnome Terminal, Guake, ROXTerm, etc)
+  if [ -n "$VTE_VERSION" ]; then
+    [ $VTE_VERSION -ge 5000 ]
+    return $?
+  fi
+
+  # If $TERM_PROGRAM is set, these terminals support hyperlinks
+  case "$TERM_PROGRAM" in
+  Hyper|iTerm.app|terminology|WezTerm) return 0 ;;
+  esac
+
+  # kitty supports hyperlinks
+  if [ "$TERM" = xterm-kitty ]; then
+    return 0
+  fi
+
+  # Windows Terminal also supports hyperlinks
+  if [ -n "$WT_SESSION" ]; then
+    return 0
+  fi
+
+  # Konsole supports hyperlinks, but it's an opt-in setting that can't be detected
+  # https://github.com/ohmyzsh/ohmyzsh/issues/10964
+  # if [ -n "$KONSOLE_VERSION" ]; then
+  #   return 0
+  # fi
+
+  return 1
+}
+
+# Adapted from code and information by Anton Kochkov (@XVilka)
+# Source: https://gist.github.com/XVilka/8346728
+supports_truecolor() {
+  case "$COLORTERM" in
+  truecolor|24bit) return 0 ;;
+  esac
+
+  case "$TERM" in
+  iterm           |\
+  tmux-truecolor  |\
+  linux-truecolor |\
+  xterm-truecolor |\
+  screen-truecolor) return 0 ;;
+  esac
+
+  return 1
+}
+
+fmt_link() {
+  # $1: text, $2: url, $3: fallback mode
+  if supports_hyperlinks; then
+    printf '\033]8;;%s\033\\%s\033]8;;\033\\\n' "$2" "$1"
+    return
+  fi
+
+  case "$3" in
+  --text) printf '%s\n' "$1" ;;
+  --url|*) fmt_underline "$2" ;;
+  esac
+}
+
+fmt_underline() {
+  is_tty && printf '\033[4m%s\033[24m\n' "$*" || printf '%s\n' "$*"
+}
+
+setopt typeset_silent
+typeset -a RAINBOW
+
+if is_tty; then
+  if supports_truecolor; then
+    RAINBOW=(
+      "$(printf '\033[38;2;255;0;0m')"
+      "$(printf '\033[38;2;255;97;0m')"
+      "$(printf '\033[38;2;247;255;0m')"
+      "$(printf '\033[38;2;0;255;30m')"
+      "$(printf '\033[38;2;77;0;255m')"
+      "$(printf '\033[38;2;168;0;255m')"
+      "$(printf '\033[38;2;245;0;172m')"
+    )
+  else
+    RAINBOW=(
+      "$(printf '\033[38;5;196m')"
+      "$(printf '\033[38;5;202m')"
+      "$(printf '\033[38;5;226m')"
+      "$(printf '\033[38;5;082m')"
+      "$(printf '\033[38;5;021m')"
+      "$(printf '\033[38;5;093m')"
+      "$(printf '\033[38;5;163m')"
+    )
+  fi
+
+  RED=$(printf '\033[31m')
+  GREEN=$(printf '\033[32m')
+  YELLOW=$(printf '\033[33m')
+  BLUE=$(printf '\033[34m')
+  BOLD=$(printf '\033[1m')
+  RESET=$(printf '\033[0m')
+fi
+
+# Update upstream remote to ohmyzsh org
+git remote -v | while read remote url extra; do
+  case "$url" in
+  https://github.com/robbyrussell/oh-my-zsh(|.git))
+    git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git"
+    break ;;
+  git@github.com:robbyrussell/oh-my-zsh(|.git))
+    git remote set-url "$remote" "git@github.com:ohmyzsh/ohmyzsh.git"
+    break ;;
+  # Update out-of-date "unauthenticated git protocol on port 9418" to https
+  git://github.com/robbyrussell/oh-my-zsh(|.git))
+    git remote set-url "$remote" "https://github.com/ohmyzsh/ohmyzsh.git"
+    break ;;
+  esac
+done
+
+# Set git-config values known to fix git errors
+# Line endings (#4069)
+git config core.eol lf
+git config core.autocrlf false
+# zeroPaddedFilemode fsck errors (#4963)
+git config fsck.zeroPaddedFilemode ignore
+git config fetch.fsck.zeroPaddedFilemode ignore
+git config receive.fsck.zeroPaddedFilemode ignore
+# autostash on rebase (#7172)
+resetAutoStash=$(git config --bool rebase.autoStash 2>/dev/null)
+git config rebase.autoStash true
+
+local ret=0
+
+# repository settings
+remote=${"$(git config --local oh-my-zsh.remote)":-origin}
+branch=${"$(git config --local oh-my-zsh.branch)":-master}
+
+# repository state
+last_head=$(git symbolic-ref --quiet --short HEAD || git rev-parse HEAD)
+# checkout update branch
+git checkout -q "$branch" -- || exit 1
+# branch commit before update (used in changelog)
+last_commit=$(git rev-parse "$branch")
+
+# Update Oh My Zsh
+printf "${BLUE}%s${RESET}\n" "Updating Oh My Zsh"
+if LANG= git pull --quiet --rebase $remote $branch; then
+  # Check if it was really updated or not
+  if [[ "$(git rev-parse HEAD)" = "$last_commit" ]]; then
+    message="Oh My Zsh is already at the latest version."
+  else
+    message="Hooray! Oh My Zsh has been updated!"
+
+    # Save the commit prior to updating
+    git config oh-my-zsh.lastVersion "$last_commit"
+
+    # Print changelog to the terminal
+    if [[ "$1" = --interactive ]]; then
+      "$ZSH/tools/changelog.sh" HEAD "$last_commit"
+    fi
+
+    printf "${BLUE}%s \`${BOLD}%s${RESET}${BLUE}\`${RESET}\n" "You can see the changelog with" "omz changelog"
+  fi
+
+  printf '%s         %s__      %s           %s        %s       %s     %s__   %s\n'      $RAINBOW $RESET
+  printf '%s  ____  %s/ /_    %s ____ ___  %s__  __  %s ____  %s_____%s/ /_  %s\n'      $RAINBOW $RESET
+  printf '%s / __ \\%s/ __ \\  %s / __ `__ \\%s/ / / / %s /_  / %s/ ___/%s __ \\ %s\n'  $RAINBOW $RESET
+  printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s   / /_%s(__  )%s / / / %s\n'      $RAINBOW $RESET
+  printf '%s\\____/%s_/ /_/ %s /_/ /_/ /_/%s\\__, / %s   /___/%s____/%s_/ /_/  %s\n'    $RAINBOW $RESET
+  printf '%s    %s        %s           %s /____/ %s       %s     %s          %s\n'      $RAINBOW $RESET
+  printf '\n'
+  printf "${BLUE}%s${RESET}\n\n" "$message"
+  printf "${BLUE}${BOLD}%s %s${RESET}\n" "To keep up with the latest news and updates, follow us on Twitter:" "$(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)"
+  printf "${BLUE}${BOLD}%s %s${RESET}\n" "Want to get involved in the community? Join our Discord:" "$(fmt_link "Discord server" https://discord.gg/ohmyzsh)"
+  printf "${BLUE}${BOLD}%s %s${RESET}\n" "Get your Oh My Zsh swag at:" "$(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)"
+else
+  ret=$?
+  printf "${RED}%s${RESET}\n" 'There was an error updating. Try again later?'
+fi
+
+# go back to HEAD previous to update
+git checkout -q "$last_head" --
+
+# Unset git-config values set just for the upgrade
+case "$resetAutoStash" in
+  "") git config --unset rebase.autoStash ;;
+  *) git config rebase.autoStash "$resetAutoStash" ;;
+esac
+
+# Exit with `1` if the update failed
+exit $ret
diff --git a/stow/tmux/.tmux.conf b/stow/tmux/.tmux.conf
new file mode 100755 (executable)
index 0000000..fc0515c
--- /dev/null
@@ -0,0 +1,62 @@
+set -g mouse on
+set -g history-limit 10000
+#set -g default-terminal "screen-256color"
+#set -g default-terminal "xterm"
+
+set -g default-terminal "tmux-256color"
+#set-option -ga terminal-overrides ",256col:Tc"
+
+# use vimmode
+setw -g mode-keys vi
+
+# key bindings for horizontal and vertical panes
+unbind %
+bind | split-window -h
+bind - split-window -v
+
+# move between panes like vim does:
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+
+bind S set synchronize-panes
+#
+#urxvt tab like window switching (-n: no prior escape seq)
+bind -n C-S-down new-window
+bind -n C-S-left prev
+bind -n C-S-right next
+bind -n C-left swap-window -t -1
+bind -n C-right swap-window -t +1
+
+# enable window titles
+set -g set-titles on
+
+# bind to reload config
+bind r source-file ~/.tmux.conf
+
+# Notifying if other windows has activities
+setw -g monitor-activity on
+set -g visual-activity on
+
+# das verhindert irgendwie, das die shelleingabe kaputt geht 
+# nachdem "t /var/log/irgendwas" mit Ctrl-C abgrebrochen wurde
+set -g default-command "${SHELL}"
+
+set-option -g detach-on-destroy off
+
+# panes
+set -g pane-border-style        'bg=colour235 fg=colour241'
+set -g pane-active-border-style 'bg=colour235 fg=green'
+
+# statusbar
+set -g status-position bottom
+set -g status-justify left
+
+setw -g status-style "default"
+setw -g status-style "bg=colour239 fg=white"
+set -g status-left ' '
+set -g window-status-separator " "
+set -g status-right '#[fg=black,bg=white] %d.%m.%Y %H:%M:%S '
+set -g window-status-format                                '[#I: #T/#W]'
+set -g window-status-current-format '#[fg=black,bg=green] 👉[#I: #T/#W]👈 '
diff --git a/stow/vim/.vim/README.md b/stow/vim/.vim/README.md
new file mode 100644 (file)
index 0000000..2da8195
--- /dev/null
@@ -0,0 +1,7 @@
+# Install
+
+    git clone http://src.twobees.de/git/dotvim ~/.vim
+    ~/.vim/init.sh
+
+# Update
+    ~/.vim/init.sh
diff --git a/stow/vim/.vim/filetype.vim b/stow/vim/.vim/filetype.vim
new file mode 100644 (file)
index 0000000..d9506cd
--- /dev/null
@@ -0,0 +1,8 @@
+if exists("did_load_filetypes")
+    finish
+endif
+
+augroup filetypedetect
+    au! BufRead,BufNewFile *_[FS]*.log setfiletype hub
+    au! BufNewFile,BufRead *.xaml      setfiletype xml
+augroup END
diff --git a/stow/vim/.vim/ftplugin/go.vim b/stow/vim/.vim/ftplugin/go.vim
new file mode 100644 (file)
index 0000000..6f5fe3d
--- /dev/null
@@ -0,0 +1 @@
+setlocal nolist
diff --git a/stow/vim/.vim/ftplugin/hub.vim b/stow/vim/.vim/ftplugin/hub.vim
new file mode 100644 (file)
index 0000000..f5a1036
--- /dev/null
@@ -0,0 +1,17 @@
+setlocal buftype=nofile
+setlocal nomodifiable
+setlocal syntax=hub
+setlocal  nowrap
+if has('gui_running')
+    set guifont=DejaVu_Sans_Mono:h9:cANSI:qDRAFT
+    setlocal  guioptions+=b
+    silent simalt ~x
+endif
+setlocal nolist
+setlocal noswapfile
+setlocal nobackup
+setlocal noundofile
+setlocal foldmethod=manual
+setlocal colorcolumn="0"
+let b:qs_local_disable=1
+match Ignore /\r$/
diff --git a/stow/vim/.vim/ftplugin/perl.vim b/stow/vim/.vim/ftplugin/perl.vim
new file mode 100644 (file)
index 0000000..9763f3b
--- /dev/null
@@ -0,0 +1,16 @@
+"define :Tidy command to run perltidy on visual selection || entire buffer"
+command! -range=% -nargs=* Tidy <line1>,<line2>!perltidy
+
+"run :Tidy on entire buffer and return cursor to (approximate) original position"
+fun! DoTidy()
+    let l = line(".")
+    let c = col(".")
+    :Tidy
+    call cursor(l, c)
+endfun
+
+"shortcut for normal mode to run on entire buffer then return to current line"
+noremap <F2> :call DoTidy()<CR>
+
+"shortcut for visual mode to run on the the current visual selection"
+vnoremap <F2> :Tidy<CR>
diff --git a/stow/vim/.vim/init.sh b/stow/vim/.vim/init.sh
new file mode 100755 (executable)
index 0000000..a12b355
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+cd $HOME/.vim &>/dev/null
+if [ $? -ne "0" ];then
+    cd $HOME/vimfiles &>/dev/null
+    if [ $? -ne "0" ];then
+        echo "could not change to vim configuration dir";
+        exit 1;
+    fi
+fi
+echo "vim configuration dir: " `pwd`
+
+if [ -d bundle/Vundle.vim ];then
+    cd bundle/Vundle.vim;
+    echo "Update Vundle:"
+    git pull
+    cd -
+else
+    git clone https://github.com/VundleVim/Vundle.vim.git bundle/Vundle.vim
+fi
+vim +PluginClean! +PluginInstall! +qall
+stty sane
diff --git a/stow/vim/.vim/plugins.vundel.vim b/stow/vim/.vim/plugins.vundel.vim
new file mode 100644 (file)
index 0000000..6757eec
--- /dev/null
@@ -0,0 +1,44 @@
+set nocompatible
+filetype off
+
+exec 'set rtp+='.b:vim_conf_dir.'/bundle/Vundle.vim/'
+call vundle#rc(b:vim_conf_dir.'/bundle/')
+
+call vundle#begin()
+Plugin 'VundleVim/Vundle.vim'
+Plugin 'chrisbra/vim-diff-enhanced'
+Plugin 'tpope/vim-repeat'
+Plugin 'tpope/vim-fugitive'
+Plugin 'tpope/vim-surround'
+Plugin 'tpope/vim-unimpaired'
+Plugin 'godlygeek/tabular'
+"Plugin 'w0rp/ale'
+"Plugin 'vimwiki/vimwiki'
+if ! has("win32")
+    Plugin '4Evergreen4/vim-hardy'
+endif
+Plugin 'jlanzarotta/bufexplorer'
+Plugin 'mileszs/ack.vim'
+Plugin 'JamshedVesuna/vim-markdown-preview'
+Plugin 'blueyed/smarty.vim'
+Plugin 'vim-scripts/nginx.vim'
+"Plugin 'vim-scripts/CycleColor'
+Plugin 'c9s/perlomni.vim'
+Plugin 'morhetz/gruvbox'
+Plugin 'junegunn/fzf.vim'
+Plugin 'unblevable/quick-scope'
+if has('nvim')
+    Plugin 'glacambre/firenvim', { 'do': { _ -> firenvim#install(0) } }
+endif
+
+" platformio dev:
+Plugin 'prabirshrestha/asyncomplete.vim'
+Plugin 'prabirshrestha/vim-lsp'
+Plugin 'mattn/vim-lsp-settings'
+Plugin 'prabirshrestha/asyncomplete-lsp.vim'
+Plugin 'pangloss/vim-javascript'
+Plugin 'thirtythreeforty/lessspace.vim'
+Plugin 'fatih/vim-go'
+call vundle#end()
+filetype on
+filetype plugin indent on
diff --git a/stow/vim/.vim/syntax/hub.vim b/stow/vim/.vim/syntax/hub.vim
new file mode 100644 (file)
index 0000000..dd9cc60
--- /dev/null
@@ -0,0 +1,68 @@
+" Vim syntax file
+" file type: log files
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+  finish
+endif
+
+
+syn match logdate /^\d\{2}\.\d\{2}/ nextgroup=logtime skipwhite
+syn match logtime /\d\{2}:\d\{2}:\d\{2}:\d\{4}/
+
+syn match cri ".* CRITIC.*"
+syn match err ".* ERROR.*"
+syn match war ".* WARNIN.*"
+syn match inf ".* INFO.*"
+syn match trace1 ".* TRACE1.*" contains=@calls
+syn match trace2 ".* TRACE2.*" contains=@calls
+syn match trace3 ".* TRACE3.*" contains=@calls
+
+syn keyword callcontrol Setup Connect DemandTx CeaseTx contained
+syn keyword callnotification NotifyCallOngoing NotifyProceeding NotifyConnected NotifyTxGranted NotifyTxCeased notifyDisconnected contained
+
+syn cluster calls contains=callcontrol,callnotification
+
+" Highlight colors for log levels.
+":hi crit ctermfg=Red
+":hi error ctermfg=Red
+":hi warn ctermfg=Red
+":hi info ctermfg=Black
+":hi trace ctermfg=Gray
+
+
+if &background == "light"
+       hi logdate guifg=RoyalBlue4
+       hi logtime guifg=RoyalBlue4
+
+       hi cri guifg=red1
+       hi err guifg=red2
+       hi war guifg=red3
+       hi trace1 guifg=gray33
+       hi trace2 guifg=gray43
+       hi trace3 guifg=gray63
+       hi inf guifg=black
+
+       hi link callcontrol calls
+       hi link callnotification calls
+       hi calls gui=bold
+else
+       hi logdate guifg=RoyalBlue4
+       hi logtime guifg=RoyalBlue4
+
+       hi cri guifg=red1
+       hi err guifg=red2
+       hi war guifg=red3
+       hi trace1 guifg=gray63
+       hi trace2 guifg=gray43
+       hi trace3 guifg=gray33
+       hi inf guifg=white
+
+       hi link callcontrol calls
+       hi link callnotification calls
+       hi calls gui=bold
+
+endif
+
+
+let b:current_syntax = "hub"
diff --git a/stow/vim/.vim/syntax/iptables.vim b/stow/vim/.vim/syntax/iptables.vim
new file mode 100644 (file)
index 0000000..5812432
--- /dev/null
@@ -0,0 +1,379 @@
+"============================================================================
+"
+" iptables-save/restore syntax highlighter
+"
+" Language:       iptables-save/restore file
+" Version:     Not Specified
+" Date:        07-Jun-2014
+" Maintainer:  Eric Haarbauer <ehaar70{AT}gmail{DOT}com>
+" License:     This file is placed in the public domain.
+"
+"============================================================================
+" Section:  Notes  {{{1
+"============================================================================
+"
+" This vim syntax script highlights files used by Harald Welte's iptables-save
+" and iptables-restore utilities.  Both utilities are part of the iptables
+" application (http://www.netfilter.org/projects/iptables).
+" 
+" Features:
+"
+"   * Distinguishes commands, options, modules, targets and chains.
+"   * Distinguishes numeric IP addresses from net masks.
+"   * Highlights tokens that occur only in hand-edited files; for example,
+"     "--append" and "destination-unreachable".
+"   * Special handling for module names; for example, the tcp module is
+"     colored differently from the tcp protocol.
+"
+" Options:
+"
+"   Customize the behavior of this script by setting values for the following
+"   options in your .vimrc file.  (Type ":h vimrc" in vim for more information
+"   on the .vimrc file.)
+"
+"   g:Iptables_SpecialDelimiters
+"     This variable, if set to a non-zero value, distinguishes numeric
+"     delimiters, including the dots in IP addresses, the slash that separates
+"     an IP address from a netmask, and the colon that separates the ends of a
+"     port range.  If not set, this option defaults to off.
+"
+" Known Issues:
+"
+"   * Some special argument tokens are highlighted whether or not they are
+"     used with the correct option.  For example, "destination-unreachable"
+"     gets special highlighting whether or not is used as an argument to the
+"     --icmp-type option.  In practice, this is rarely a problem.
+"
+" Reporting Issues:
+"
+"   If you discover an iptables file that this script highlights incorrectly,
+"   please email the author (address at the top of the script) with the
+"   following information:
+"
+"     * Problem iptables file WITH ANY SENSITIVE INFORMATION REMOVED
+"     * The release version of this script (see top of the script)
+"     * If possible, a patch to fix the problem
+"
+" Design Notes:
+"
+"   Part of this script is autogenerated from the output of the iptables man
+"   page.  The source code for generating the script is available from the
+"   author on request (see email address at the top of the script).  The
+"   script should build from source on most Linux systems with iptables
+"   installed.
+"
+"   The build system that generates this script strips special CVS tokens
+"   (like "Id:") so that CVS no longer recognizes them.  This allows users to
+"   place the script in their own version control system without losing
+"   information.  The author encourages other vim script developers to adopt a
+"   similar approach in their own scripts.
+"
+" Installation:
+"
+"   Put this file in your user runtime syntax directory, usually ~/.vim/syntax
+"   in *NIX or C:\Program Files\vim\vimfiles\syntax in Windows.  Type ":h
+"   syn-files" from within vim for more information.
+"
+"   The iptables-save and iptables-restore applications do not specify a
+"   naming standard for the files they use.  However, iptables-save places a
+"   comment in the first line of its output.  Other applications, such as
+"   Fedora's system-config-securitylevel uses the iptables-save/restore
+"   format, but with a different leading comment.  We can use these leading
+"   comments to identify the filetype by placing the following code in the
+"   scripts.vim file in your user runtime directory:
+"   
+"      if getline(1) =~ "^# Generated by iptables-save" ||
+"       \ getline(1) =~ "^# Firewall configuration written by"
+"          setfiletype iptables
+"          set commentstring=#%s
+"          finish
+"      endif
+"
+"   Setting the commentstring on line 4 allows Meikel Brandmeyer's
+"   EnhancedCommentify script (vimscript #23) to work with iptables files.
+"   (Advanced users may want to set the commentstring option in an ftplugin
+"   file or in autocommands defined in .vimrc.)
+"
+"============================================================================
+" Source File: Id: iptables.src.vim 43 2014-06-08 03:21:32Z ehaar 
+"============================================================================
+" Section:  Initialization  {{{1
+"============================================================================
+
+" For version 5.x: Clear all syntax items
+" For version 6.x: Quit when a syntax file was already loaded
+if !exists("main_syntax")
+  if version < 600
+    syntax clear
+  elseif exists("b:current_syntax")
+    finish
+  endif
+  let main_syntax = 'iptables'
+endif
+
+" Don't use standard HiLink, it will not work with included syntax files
+if version < 508
+  command! -nargs=+ IptablesHiLink highlight link <args>
+else
+  command! -nargs=+ IptablesHiLink highlight default link <args>
+endif
+
+syntax case match
+
+if version < 600
+    set iskeyword+=-
+else
+    setlocal iskeyword+=-
+endif
+
+" Initialize global public variables:  {{{2
+
+" Support deprecated variable name used prior to release 1.07.
+if exists("g:iptablesSpecialDelimiters") &&
+\ !exists("g:Iptables_SpecialDelimiters")
+
+    let   g:Iptables_SpecialDelimiters = g:iptablesSpecialDelimiters
+    unlet g:iptablesSpecialDelimiters
+    " echohl WarningMsg | echo "Warning:" | echohl None
+    " echo "The g:iptablesSpecialDelimiters variable is deprecated."
+    " echo "Please use g:Iptables_SpecialDelimiters in your .vimrc instead"
+
+endif
+
+if exists("g:Iptables_SpecialDelimiters")
+    let s:Iptables_SpecialDelimiters = g:Iptables_SpecialDelimiters
+else
+    let s:Iptables_SpecialDelimiters = 0
+endif
+
+"============================================================================
+" Section:  Group Definitions  {{{1
+"============================================================================
+
+syntax keyword iptablesSaveDirective COMMIT
+syntax match   iptablesSaveOperation "^[:*]"
+
+syntax keyword iptablesTable filter nat mangle raw
+
+syntax keyword iptablesTarget
+    \ ACCEPT DROP QUEUE RETURN BALANCE CLASSIFY CLUSTERIP CONNMARK
+    \ CONNSECMARK CONNTRACK DNAT DSCP ECN IPMARK IPV4OPSSTRIP LOG
+    \ MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT
+    \ ROUTE SAME SECMARK SET SNAT TARPIT TCPMSS TOS TRACE TTL ULOG XOR
+
+syntax keyword iptablesBuiltinChain
+    \ INPUT OUTPUT FORWARD PREROUTING POSTROUTING
+
+syntax keyword iptablesCommand -A -D -I -R -L -F -Z -N -X -P -E
+    \ --append --delete --insert --replace --list --flush --zero
+    \ --new-chain --delete-chain --policy --rename-chain
+
+syntax keyword iptablesParam   -p -s -d -j -i -o -f -c -t
+
+syntax match iptablesOperator "\s\zs!\ze\s"
+
+syntax keyword iptablesModuleName contained
+    \ account addrtype ah childlevel comment condition connbytes connlimit
+    \ connmark connrate conntrack dccp dscp dstlimit ecn esp fuzzy hashlimit
+    \ helper icmp iprange ipv4options length limit mac mark mport multiport
+    \ nth osf owner physdev pkttype policy psd quota random realm recent
+    \ sctp set state string tcp tcpmss time tos ttl u32 udp unclean
+
+syntax keyword iptablesModuleType
+    \ UNSPEC UNICAST LOCAL BROADCAST ANYCAST MULTICAST BLACKHOLE UNREACHABLE
+    \ PROHIBIT THROW NAT XRESOLVE INVALID ESTABLISHED NEW RELATED SYN ACK FIN
+    \ RST URG PSH ALL NONE
+
+" From --reject-with option
+syntax keyword iptablesModuleType
+    \ icmp-net-unreachable
+    \ icmp-host-unreachable
+    \ icmp-port-unreachable
+    \ icmp-proto-unreachable
+    \ icmp-net-prohibited
+    \ icmp-host-prohibited
+    \ icmp-admin-prohibited
+
+" From --icmp-type option
+syntax keyword iptablesModuleType
+    \ any
+    \ echo-reply
+    \ destination-unreachable
+    \    network-unreachable
+    \    host-unreachable
+    \    protocol-unreachable
+    \    port-unreachable
+    \    fragmentation-needed
+    \    source-route-failed
+    \    network-unknown
+    \    host-unknown
+    \    network-prohibited
+    \    host-prohibited
+    \    TOS-network-unreachable
+    \    TOS-host-unreachable
+    \    communication-prohibited
+    \    host-precedence-violation
+    \    precedence-cutoff
+    \ source-quench
+    \ redirect
+    \    network-redirect
+    \    host-redirect
+    \    TOS-network-redirect
+    \    TOS-host-redirect
+    \ echo-request
+    \ router-advertisement
+    \ router-solicitation
+    \ time-exceeded
+    \    ttl-zero-during-transit
+    \    ttl-zero-during-reassembly
+    \ parameter-problem
+    \    ip-header-bad
+    \    required-option-missing
+    \ timestamp-request
+    \ timestamp-reply
+    \ address-mask-request
+    \ address-mask-reply
+
+" If we used a keyword for this, port names would be colored the same
+" as modules with the same name (e.g. tcp, udp, icmp).
+syntax keyword iptablesParam -m --match skipwhite nextgroup=iptablesModuleName
+
+syntax region iptablesString start=+"+ skip=+\\"+ end=+"+ oneline
+
+syntax match  iptablesComment    "^#.*" contains=iptablesTodo
+syntax match  iptablesBadComment "^\s\+\zs#.*" " Pound must be in first column
+
+syntax keyword iptablesTodo contained TODO FIXME XXX NOT NOTE
+
+" Special Delimiters: {{{2
+
+if s:Iptables_SpecialDelimiters != 0
+    syntax match iptablesNumber    "\<[0-9./:]\+\>"
+        \ contains=iptablesMask,iptablesDelimiter
+    syntax match iptablesDelimiter "[./:]"     contained
+    syntax match iptablesMask      "/[0-9.]\+" contained 
+        \ contains=iptablesDelimiter
+else " s:Iptables_SpecialDelimiters == 0
+    syntax match iptablesNumber    "\<[0-9./]\+\>"
+        \ contains=iptablesMask,iptablesDelimiter
+    syntax match iptablesDelimiter "/"         contained
+    syntax match iptablesMask      "/[0-9.]\+" contained 
+        \ contains=iptablesDelimiter
+endif
+
+"============================================================================
+" Section:  Autogenerated Groups  {{{2
+"============================================================================
+
+" Begin autogenerated section.
+" iptables2vim: "iptables2vim 43 2014-06-08 03:21:32Z ehaar"
+" iptables:     "iptables v1.4.19.1"
+
+syntax keyword iptablesLongParam
+   \ --zone --xor-tos --xor-mark --weekdays --vproto --vportctl --vport 
+   \ --vmethod --verbose --vdir --validmark --vaddr --update 
+   \ --ulog-qthreshold --ulog-prefix --ulog-nlgroup --ulog-cprange 
+   \ --uid-owner --u --type --tunnel-src --tunnel-dst --ttl-set --ttl-lt 
+   \ --ttl-inc --ttl-gt --ttl-eq --ttl-dec --ttl --transparent --tproxy-mark 
+   \ --total-nodes --tos --to-source --to-ports --to-port --to-destination 
+   \ --to --timestop --timestart --timeout --tcp-option --tcp-flags --table 
+   \ --syn --strip-options --string --strict --state --src-type --src-range 
+   \ --src-pfx --src-group --src --sports --sport --spi --source-ports 
+   \ --source-port --source --soft --socket-exists --set-xmark --set-tos 
+   \ --set-mss --set-mark --set-dscp-class --set-dscp --set-counters 
+   \ --set-class --set --selctx --seconds --save-mark --save --rttl --rt-type 
+   \ --rt-segsleft --rt-len --rt- --rsource --return--nomatch --restore-mark 
+   \ --restore --reqid --remove --reject-with --reap --realm --rdest --rcheck 
+   \ --rateest-pps --rateest-name --rateest-lt --rateest-interval 
+   \ --rateest-gt --rateest-ewmalog --rateest-eq --rateest-delta 
+   \ --rateest-bps --rateest --random --quota --queue-num --queue-bypass 
+   \ --queue-balance --protocol --proto --probability --ports --pol 
+   \ --pkt-type --physdev-out --physdev-is-out --physdev-is-in 
+   \ --physdev-is-bridged --physdev-in --persistent --packet --out-interface 
+   \ --or-tos --or-mark --on-port --on-ip --numeric --notrack --nodst 
+   \ --nflog-threshold --nflog-range --nflog-prefix --nflog-group 
+   \ --nfacct-name --next --new --name --mss --monthdays --modprobe --mode 
+   \ --mh-type --mask --mark --mangle-mac-d --mac-source --loose --log-uid 
+   \ --log-tcp-sequence --log-tcp-options --log-prefix --log-level 
+   \ --log-ip-options --log --local-node --line-numbers --limit-iface-out 
+   \ --limit-iface-in --limit-burst --limit --length --led-trigger-id 
+   \ --led-delay --led-always-blink --label --kerneltz --jump --ipvs --ipv 
+   \ --invert --in-interface --icmpv --icmp-type --hmark-tuple 
+   \ --hmark-src-prefix --hmark-sport-mask --hmark-spi-mask --hmark-rnd 
+   \ --hmark-proto-mask --hmark-offset --hmark-mod --hmark-dst-prefix 
+   \ --hmark-dport-mask --hl-set --hl-lt --hl-inc --hl-gt --hl-eq --hl-dec 
+   \ --hitcount --hex-string --helper --help --header --hbh-opts --hbh-len 
+   \ --hashmode --hashlimit-upto --hashlimit-srcmask --hashlimit-src 
+   \ --hashlimit-name --hashlimit-mode --hashlimit-mask 
+   \ --hashlimit-htable-size --hashlimit-htable-max 
+   \ --hashlimit-htable-gcinterval --hashlimit-htable-expire 
+   \ --hashlimit-dstmask --hashlimit-burst --hashlimit-above --hashlimit 
+   \ --hash-init --h-length --goto --gid-owner --genre --gateway --from 
+   \ --fragres --fragmore --fragment --fraglen --fraglast --fragid 
+   \ --fragfirst --expevents --exist --exact --every --espspi 
+   \ --ecn-tcp-remove --ecn-tcp-ece --ecn-tcp-cwr --ecn-ip-ect --dst-type 
+   \ --dst-range --dst-pfx --dst-opts --dst-len --dst-group --dst 
+   \ --dscp-class --dscp --dports --dport --dir --destination-ports 
+   \ --destination-port --destination --del-set --dccp-types --dccp-option 
+   \ --datestop --datestart --ctstatus --ctstate --ctreplsrcport --ctreplsrc 
+   \ --ctrepldstport --ctrepldst --ctproto --ctorigsrcport --ctorigsrc 
+   \ --ctorigdstport --ctorigdst --ctexpire --ctevents --ctdir --cpu 
+   \ --contiguous --connlimit-upto --connlimit-saddr --connlimit-mask 
+   \ --connlimit-daddr --connlimit-above --connbytes-mode --connbytes-dir 
+   \ --connbytes --comment --clustermac --cluster-total-nodes 
+   \ --cluster-local-nodemask --cluster-local-node --cluster-hash-seed --clus 
+   \ --clamp-mss-to-pmtu --chunk-types --checksum-fill --check --bytecode 
+   \ --and-tos --and-mark --algo --ahspi --ahres --ahlen --add-set 
+   \ --accept-local
+" End autogenerated section.
+
+"============================================================================
+" Section:  Group Linking  {{{1
+"============================================================================
+
+IptablesHiLink iptablesSaveDirective PreProc
+IptablesHiLink iptablesSaveOperation PreProc
+
+IptablesHiLink iptablesTable         Statement
+IptablesHiLink iptablesTarget        Statement
+IptablesHiLink iptablesBuiltinChain  Type
+
+IptablesHiLink iptablesCommand       Operator
+
+IptablesHiLink iptablesModuleName    Type
+IptablesHiLink iptablesModuleType    Type
+
+IptablesHiLink iptablesOperator      Operator
+IptablesHiLink iptablesParam         Identifier
+IptablesHiLink iptablesLongParam     Identifier
+
+IptablesHiLink iptablesNumber        Constant
+
+if s:Iptables_SpecialDelimiters != 0
+    IptablesHiLink iptablesMask      PreProc
+    IptablesHiLink iptablesDelimiter Delimiter
+else " s:Iptables_SpecialDelimiters == 0 
+    IptablesHiLink iptablesMask      Special
+    IptablesHiLink iptablesDelimiter None
+endif
+
+IptablesHiLink iptablesString        Constant
+
+IptablesHiLink iptablesComment       Comment
+IptablesHiLink iptablesBadComment    Error
+IptablesHiLink iptablesTodo          Todo   
+
+"============================================================================
+" Section:  Clean Up    {{{1
+"============================================================================
+
+delcommand IptablesHiLink
+
+let b:current_syntax = "iptables"
+
+if main_syntax == 'iptables'
+  unlet main_syntax
+endif
+
+" Autoconfigure vim indentation settings
+" vim:ts=4:sw=4:sts=4:fdm=marker:iskeyword+=-
diff --git a/stow/vim/.vim/vimrc b/stow/vim/.vim/vimrc
new file mode 100644 (file)
index 0000000..254f0ef
--- /dev/null
@@ -0,0 +1,624 @@
+"set vim config dir
+let b:vim_conf_dir = $HOME.'/.vim'
+if has("win32")
+    let b:vim_conf_dir = $HOME.'\vimfiles'
+endif
+set nocompatible
+
+if has('nvim')
+    if isdirectory( b:vim_conf_dir . '/tmpnvim/') == 0
+        call mkdir(b:vim_conf_dir.'/tmpnvim/', 'p', 0700)
+    endif
+else
+    if isdirectory( b:vim_conf_dir . '/tmp/') == 0
+        call mkdir(b:vim_conf_dir.'/tmp/', 'p', 0700)
+    endif
+endif
+
+let g:qs_highlight_on_keys = ['f', 'F', 't', 'T']
+augroup qs_colors
+  autocmd!
+  autocmd ColorScheme * highlight QuickScopePrimary guifg='#afff5f' gui=underline ctermfg=155 cterm=underline
+  autocmd ColorScheme * highlight QuickScopeSecondary guifg='#5fffff' gui=underline ctermfg=81 cterm=underline
+augroup END
+
+
+"load plugins
+if filereadable(b:vim_conf_dir . '/plugins.vundel.vim')
+    exec 'source ' . b:vim_conf_dir . '/plugins.vundel.vim'
+endif
+"
+" auskommentiert, macht in screen das nix gut aussieht..
+"set termguicolors
+set background=dark
+set t_Co=256
+try
+    let g:gruvbox_contrast_dark = 'hard'
+    let g:gruvbox_italicize_comments = 0
+    colorscheme gruvbox
+catch /^Vim\%((\a\+)\)\=:E185/
+    "  wird evtl rest instlliert... E185 heißt nicht gefunden..
+endtry
+
+
+set backspace=indent,eol,start
+set relativenumber
+set number
+set lazyredraw
+
+set expandtab
+set tabstop=4
+set softtabstop=4
+set shiftwidth=4
+
+set pastetoggle=<F3>
+
+set encoding=utf-8
+set modeline
+
+set history=50
+set noerrorbells
+set visualbell t_vb=
+set hidden
+set nojoinspaces
+set nrformats=
+if ! has ('nvim')
+    set ttymouse=xterm2
+endif
+set mouse=a
+
+" Tab-completion in command-line mode
+set path+=**
+set wildmode=full
+set wildmenu
+set wildignore=*.pdf,*.fo,
+set title
+
+" Appearance
+set ruler
+set showmode
+set showcmd
+set laststatus=2
+set hlsearch
+set incsearch
+set ignorecase
+set smartcase
+
+" remove =, thus 'gf' works whit filepath asignemens like myvar=/path/tofile
+set isfname-==
+
+let perl_include_pod = 1
+augroup PerlSettings
+    autocmd!
+    autocmd FileType perl setlocal complete-=i
+augroup END
+
+let mapleader = ","
+
+nnoremap <F5> :wa<CR>:!./%
+nnoremap <F8> ]s
+nnoremap <S-F8> [s
+nnoremap Z Y
+
+nnoremap <leader>- i• 
+inoremap <leader>- • 
+
+" Window switching
+nnoremap <C-k> <C-W>k
+nnoremap <C-j> <C-W>j
+nnoremap <C-h> <C-W>h
+nnoremap <C-l> <C-W>l
+
+nnoremap <Leader>i a'" <<  << "' <Esc>6hi
+nnoremap <Leader>a a'{}' <Esc>2hi
+nnoremap <Leader>A a'"+  +"' <Esc>4hi
+autocmd FileType cpp nnoremap <Leader>a a'"<<  <<"' <Esc>5hi
+
+" see :h restore-position
+nnoremap <Leader>= msgg=G`s
+
+inoremap kj <Esc>
+inoremap jk <Esc>
+inoremap ts<tab> // TODOts: <Esc>=$A
+inoremap obs<tab> //TODOObsolete: kann nach der Abspaltung von XXXX entfernt werden<Esc>=$0fXviw
+
+inoremap no<tab> <Esc>0i <nodoc /><Esc>0i///<Esc>=$
+inoremap td<tab> <Esc>0i//TODOts: doku<CR><summary> </summary><Esc>0i/// <Esc>kVj=$
+
+autocmd InsertEnter * set timeoutlen=500
+autocmd InsertLeave * set timeoutlen=1000
+
+inoremap in<tab> <Esc>0i<inheritdoc /><Esc>0i///<Esc>V=
+
+" do not use ex mode
+map Q <Nop>
+
+nnoremap <C-p> :bprev<CR>
+nnoremap <C-n> :bnext<CR>
+
+nnoremap <leader>e :tabedit $MYVIMRC<CR>
+
+nnoremap  ZZ :wqall<CR>
+nnoremap  <F6> :wa<CR>:make -j 8<CR><CR>
+inoremap  <F6> <esc>:wa<CR>:make -j 8<CR><CR>
+
+nnoremap <Leader>x :wa\|!./%<CR>
+inoremap <Leader>x <esc>:wa\|!./%<CR>
+
+nnoremap <C-l> <C-W>l
+
+" Copy paste to/from system clipboard
+vnoremap <leader>c "*y
+noremap  <leader>v "*p
+inoremap <leader>v <esc>"*p
+vnoremap <leader>v "*p
+
+"nnoremap <Leader>= mzgg=G`z<CR>
+nnoremap <F2> :call FormatDocument()<CR>
+" write using sudo.
+cmap w!! w !sudo tee > /dev/null %
+
+"move lines up/down visually selected
+inoremap <S-Up> <Esc>:m .-2<CR>==gi
+nnoremap <S-Up> :m .-2<CR>==
+vnoremap <S-Up> :m '<-2<CR>gv=gv
+inoremap <S-Down> <Esc>:m .+1<CR>==gi
+nnoremap <S-Down> :m .+1<CR>==
+vnoremap <S-Down> :m '>+1<CR>gv=gv
+
+nnoremap <S-Right> >>
+vnoremap <S-Right> :><CR>gv
+vnoremap <S-Left>  :<<CR>gv
+nnoremap <S-Left> <<
+
+" repeat lS-ast command on all selected:
+vnoremap . :normal.<CR>
+
+vnoremap <leader>tt :Tabular /^[^-+=]*\zs\S*=/l1l1<cr>
+vnoremap <leader>t, :Tabular /,\zs/l1l1<cr>
+vnoremap <leader>t<space>  :Tabular /\s\+\zs/l1l0<cr>
+vnoremap <leader>t:        :Tabular /:\zs/l1l0<cr>
+vnoremap <leader>t(  :Tabular /(/l1l0<cr>
+"
+" append word under cursor with 'or' to current search pattern
+nnoremap <Leader>s yiw/<C-R>/\\|<C-R>"<cr>
+" append selection with 'or' to current search pattern
+vnoremap <Leader>s y/<C-R>/\\|<C-R>"<cr>
+
+cmap w!! w !sudo tee % >/dev/null
+nnoremap <Leader>mh :wa<CR>:silent !mhsend -run reload code<CR>:redraw!<CR>
+nnoremap <Leader>ll iprint_log("");<Esc>V=0f(la
+
+if has('win32')
+    nnoremap <Leader>r :source ~/vimfiles/vimrc<CR>
+else
+    nnoremap <Leader>r :source ~/.vim/vimrc<CR>
+endif
+
+filetype plugin indent on
+syntax enable
+set autoindent
+
+" ack seems to have vanished from artfull, thus use silversearchger-ag
+" for ack.vim:
+if executable('ag')
+    let g:ackprg = 'ag --vimgrep'
+endif
+
+set list listchars=tab:→\ ,trail:·
+
+hi Visual  guifg=White guibg=Blue gui=bold
+
+set diffopt+=vertical
+"set diffopt+=iwhite
+set diffopt+=algorithm:patience
+"jump to next diff and center line
+noremap <leader>n ]cz.
+noremap <leader>p [cz.
+if has ('win32')
+    set guifont=DejaVu_Sans_Mono:h9:cANSI:qDRAFT
+endif
+if &diff
+    " ignore whitespace
+    set diffopt+=vertical
+    "set diffopt+=iwhite
+    set diffopt+=algorithm:patience
+
+    syntax off
+    highlight DiffText term=reverse cterm=reverse ctermfg=214 ctermbg=234 gui=reverse guifg=lightgreen guibg=DarkGreen
+    " go fullscreen:
+    if has ('win32')
+        autocmd GuiEnter * simalt ~x
+        set guifont=DejaVu_Sans_Mono:h8:cANSI:qDRAFT
+    endif
+    " make all diff windows the same size
+    autocmd VimResized * wincmd =
+    autocmd VimEnter *  2wincmd w
+    autocmd VimEnter *  syntax off
+    autocmd VimEnter * set guioptions+=b
+    set relativenumber!
+    set number
+else
+    if has("gui_running")
+        set lines=999 columns=120
+    endif
+    " from /etc/vim/vimrc (restore last editing position)
+    if has("autocmd")
+        au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
+    endif
+
+    set textwidth=120
+
+endif
+
+
+" remove currently unused fugitive buffers:
+autocmd BufReadPost fugitive://* set bufhidden=delete
+
+" reset terminal colors after vim leaves
+"if !has("gui_running")
+"    au VimLeave * !echo -ne "\033[0m"
+"endif
+
+" macht dass auch in screen auf dem server der vollstaendige hintergund gmalt
+" wird.
+set t_ut=
+
+if has ('win32') || has('win32unix')
+    let g:vimwiki_list = [
+                \{
+                \   'path':'~/vimwiki',
+                \   'path_html':'~/vimwiki/html/',
+                \   'syntax': 'markdown',
+                \   'ext': '.md'
+                \ }
+                \ ]
+else
+    let g:vimwiki_list = [
+                \ {
+                \   'path':'~/p/wiki',
+                \   'path_html':'~/p/wiki/html/',
+                \   'syntax': 'markdown',
+                \   'ext': '.md'
+                \ }
+                \ ]
+endif
+
+if has('nvim')
+    "" tmp files:
+    if isdirectory( b:vim_conf_dir . '/tmpnvim/backup') == 0
+        call mkdir(b:vim_conf_dir.'/tmpnvim/backup', 'p', 0700)
+    endif
+    exec 'set backupdir='. b:vim_conf_dir.'/tmpnvim/backup//'
+    set backup
+
+    " delete old swap dirs and disable swap files
+    if isdirectory( b:vim_conf_dir . '/tmpnvim/swap') == 1
+        call delete(b:vim_conf_dir.'/tmpnvim/swap', 'rf')
+    endif
+    set noswapfile
+
+    " viminfo stores the the state of your previous editing session
+    if has('win32')
+        set viminfo+=n~/vimfiles/tmpnvim/viminfo
+    else
+        set viminfo+=n~/.vim/tmpnvim/viminfo
+    endif
+
+    " letzte suche beim öffnen einer Datei sofort wieder anzeigen
+    set viminfo-=h
+
+    if exists("+undofile")
+        " undofile - This allows you to use undos after exiting and restarting
+        " This, like swap and backups, uses .vim-undo first, then ~/.vim/undo
+        " :help undo-persistence
+        " This is only present in 7.3+
+        if isdirectory( b:vim_conf_dir . '/tmpnvim/undo') == 0
+            call mkdir(b:vim_conf_dir.'/tmpnvim/undo', 'p', 0700)
+        endif
+        exec 'set undodir='. b:vim_conf_dir.'/tmpnvim/undo'
+        set undofile
+    endif
+else
+    "" tmp files:
+    if isdirectory( b:vim_conf_dir . '/tmp/backup') == 0
+        call mkdir(b:vim_conf_dir.'/tmp/backup', 'p', 0700)
+    endif
+    exec 'set backupdir='. b:vim_conf_dir.'/tmp/backup//'
+    set backup
+
+    " delete old swap dirs and disable swap files
+    if isdirectory( b:vim_conf_dir . '/tmp/swap') == 1
+        call delete(b:vim_conf_dir.'/tmp/swap', 'rf')
+    endif
+    set noswapfile
+
+    " viminfo stores the the state of your previous editing session
+    if has('win32')
+        set viminfo+=n~/vimfiles/tmp/viminfo
+    else
+        set viminfo+=n~/.vim/tmp/viminfo
+    endif
+
+    " letzte suche beim öffnen einer Datei sofort wieder anzeigen
+    set viminfo-=h
+
+    if exists("+undofile")
+        " undofile - This allows you to use undos after exiting and restarting
+        " This, like swap and backups, uses .vim-undo first, then ~/.vim/undo
+        " :help undo-persistence
+        " This is only present in 7.3+
+        if isdirectory( b:vim_conf_dir . '/tmp/undo') == 0
+            call mkdir(b:vim_conf_dir.'/tmp/undo', 'p', 0700)
+        endif
+        exec 'set undodir='. b:vim_conf_dir.'/tmp/undo'
+        set undofile
+    endif
+endif
+
+" format document
+function! FormatDocument()
+    let save_pos = getpos(".")
+    normal gg=G
+    call setpos('.', save_pos)
+    echom "formatiert.."
+endfunction
+
+" reformat xml stuff
+function! XmlPretty()
+    let save_pos = getpos(".")
+    :silent! %s/&lt;/</g
+    :silent! %s/&gt;/>/g
+    :silent! %s/></>\r</g
+    :set ft=xml
+    :normal mzgg=G`z
+    call setpos('.', save_pos)
+endfunction
+
+" fix logger stuff to use the newer api call
+" remove #regions and whitspaces
+" use {var} instead of " + var + "
+command! -range FixCsharp call FixCsharp(<line1>, <line2>)
+
+function! FixCsharp(l1,l2) range
+    let save_pos = getpos(".")
+    let r = a:l1. ','. a:l2
+    echo 'fixing range: '. r
+    " regions entfernen;
+    :silent! exec r . 'g/^\s*#\(end\)\{0,1\}region/d'
+    :silent! exec r . 'g/\.WriteException(/normal 0df,$^iLog.Exception(\eV='
+    :silent! exec r . 'g/\.WriteMessage(/normal 0f(ldf."ayiw0P0xlveu0iLog.\eelcf,(\eld0$^PV='
+
+    " '+ varname +' durch '{varname}' ersetzen
+    :silent! exec r . 's/"\s*+\s*\(.\{-\}\)\s*+\s*"/{\1}/g'
+    :silent! exec r . 's/"\s*+\s*\(.\{-\}\)\s*+\s*$/{\1}" +/g'
+    :silent! exec r . 's/"\s*+\s*\(.\{-\}\)\s*);/{\1}");/g'
+    "
+    "ersetze 'Zeilenanfang "'
+    :silent! exec r . 's/\(^\s*\)\("[^"]*{\)/\1$\2/g'
+    :silent! exec r . 's/[^$]\(".*{\)/ $\1/g'
+
+    " mehrere leerzeilen durch eine einzelne ersetzen:
+    :silent! exec r . 's/\s\+$//e'
+    :silent! exec r . 's/\n\{3,}/\r\r/e'
+    :noh
+    call setpos('.', save_pos)
+endfunction
+
+function! FixWhitespace()
+    " convert tabs to spaces
+    :retab
+    " remove trailing whitespace
+    :silent! %s/\s\+$//e
+    :silent! g/\s*<!--\**-->\s*/d
+
+    " remov '//******' and '//#####'
+    :silent! g/\/\/\(\*\|#\)*\s*$/d
+    " remove excessive newlines
+    :silent! %s/\n\n\n\+/\r\r/
+    :noh
+endfunction
+
+function! UndoCSharStringInterpolation()
+    silent! s/\$"/"/g
+    silent! s/{\(.\{-}\)}/" + \1 + "/g
+endfunction
+
+let g:ale_linters = {
+            \   'cpp': ['gcc', 'cppcheck', 'clang'],
+            \   'perl': ['perl', 'perlcritic'],
+            \}
+let b:ale_warn_about_trailing_whitespace = 1
+let g:ale_sign_column_always = 1
+let g:ale_cpp_clang_options =
+            \  '-std=c++14 -Wall -pedantic -fPIC
+            \   -I/usr/include/x86_64-linux-gnu/qt5
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtPrintSupport
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtWidgets
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtGui
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtCore
+            \   -I/usr/include/libdrm
+            \   -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g+
+            \'
+
+let g:ale_cpp_gcc_options =
+            \  '-std=c++14 -Wall -pedantic -fPIC
+            \   -I/usr/include/x86_64-linux-gnu/qt5
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtPrintSupport
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtWidgets
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtGui
+            \   -I/usr/include/x86_64-linux-gnu/qt5/QtCore
+            \   -I/usr/include/libdrm
+            \   -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g+
+            \'
+
+"""" ALE end """"
+
+if has("patch-7.4.354")
+    " Indents word-wrapped lines as much as the 'parent' line
+    set breakindent
+    " Ensures word-wrap does not split words
+    set formatoptions=l
+    set lbr
+endif
+
+hi CursorLineNr  ctermbg=black guibg=black
+hi CursorLine    ctermbg=black guibg=black
+augroup CursorLine
+    au!
+    au VimEnter,WinEnter,BufWinEnter * setlocal cursorline
+    au WinLeave * setlocal nocursorline
+augroup END
+
+packadd! matchit
+
+let g:acp_enableAtStartup = 1
+let g:acp_behaviorPerlOmniLength = 0
+let g:acp_behaviorPhpOmniLength = 0
+let g:acp_completeoptPreview = 1
+let g:acp_behaviorPythonOmniLength = 0
+let g:acp_behaviorXmlOmniLength = 0
+let g:acp_behaviorHtmlOmniLength = 0
+let g:acp_behaviorCssOmniPropertyLength = 1
+let g:acp_behaviorCssOmniValueLength = 0
+
+highlight ExtraWhitespace ctermfg=red guifg=red ctermbg=white guibg=DarkGrey
+
+" keine trailing whitespaces in hub log files anzeigen
+match ExtraWhitespace /\s\+$/
+
+let g:ale_python_flake8_options = "--max-line-length=120"
+
+if has("win32")
+    function! CopyFormatted(line1, line2)
+        let prev_number = &number
+        let prev_relativenumber = &relativenumber
+        let prev_background = &background
+        let prev_ft = &ft
+        setlocal number!
+        setlocal relativenumber!
+        setlocal background=light
+        " wenn ft manuel gesetzt war wird das von set background zurueckgesetzt, deswegen gleich wieder setzen
+        exe 'setlocal ft='.expand(prev_ft)
+
+        execute a:line1 . "," . a:line2 . "TOhtml"
+        %yank *
+        !start /min powershell -noprofile "gcb | scb -as"
+        bwipeout!
+
+        if (prev_number)
+            set number
+        endif
+        if (prev_relativenumber)
+            set relativenumber
+        endif
+        exe 'setlocal background='.expand(prev_background)
+        exe 'setlocal ft='.expand(prev_ft)
+    endfunction
+
+    command! -range=% HtmlClip silent call CopyFormatted(<line1>,<line2>)
+endif
+
+augroup logfilesgroup
+    autocmd!
+    au! BufRead,BufNewFile *.log    setlocal nowrap |
+                \ setlocal textwidth=0 |
+                \ let &colorcolumn=""
+augroup END
+
+set suffixes+=.mhp,.backup1,.backup2,.backup3
+
+" firenvim config
+let g:firenvim_config = {
+    \ 'globalSettings': {
+        \ 'alt': 'all',
+    \  },
+    \ 'localSettings': {
+        \ '.*': {
+            \ 'cmdline': 'neovim',
+            \ 'content': 'text',
+            \ 'priority': 0,
+            \ 'selector': 'textarea',
+            \ 'takeover': 'never',
+        \ },
+    \ }
+\ }
+let fc = g:firenvim_config['localSettings']
+
+
+" lsp
+let g:lsp_diagnostics_echo_cursor = 1
+" Register ccls C++ lanuage server.
+if executable('ccls')
+   au User lsp_setup call lsp#register_server({
+      \ 'name': 'ccls',
+      \ 'cmd': {server_info->['ccls']},
+      \ 'root_uri': {server_info->lsp#utils#path_to_uri(
+      \     lsp#utils#find_nearest_parent_file_directory(
+      \             lsp#utils#get_buffer_path(),
+      \                 ['compile_commands.json']
+      \     ))},
+      \ 'initialization_options': {
+          \ 'cache': {'directory': expand('~/.cache/ccls') },
+          \},
+      \ 'allowlist': ['ino', 'c', 'cpp', 'objc', 'objcpp', 'cc'],
+      \ })
+endif
+
+if executable('typescript-language-server')
+    au User lsp_setup call lsp#register_server({
+                \ 'name': 'javascript support using typescript-language-server',
+                \ 'cmd': { server_info->[&shell, &shellcmdflag, 'typescript-language-server --stdio']},
+                \ 'root_uri': { server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_directory(lsp#utils#get_buffer_path(), '.git/..'))},
+                \ 'whitelist': ['javascript', 'javascript.jsx', 'javascriptreact']
+                \ })
+endif
+
+
+"" if executable('pls')
+""     au User lsp_setup call lsp#register_server({
+""                 \ 'name': 'pls',
+""                 \ 'cmd': {server_info->['pls']},
+""                 \ 'settings': { 'perl': {
+""                 \                    'cwd': getcwd(),
+""                 \                    'perlcritic': { 'enabled': 'true' },
+""                 \                    'syntax': { 'enabled': 'true' },
+""                 \               } },
+""                 \ 'allowlist': ['perl'],
+""                 \ })
+"" endif
+
+function! s:on_lsp_buffer_enabled() abort
+    setlocal omnifunc=lsp#complete
+    setlocal signcolumn=yes
+    nmap <buffer> gd <plug>(lsp-definition)
+    nmap <buffer> gs <plug>(lsp-document-symbol-search)
+    nmap <buffer> gS <plug>(lsp-workspace-symbol-search)
+    nmap <buffer> gr <plug>(lsp-references)
+    nmap <buffer> gi <plug>(lsp-implementation)
+    nmap <buffer> gt <plug>(lsp-type-definition)
+    nmap <buffer> <leader>rn <plug>(lsp-rename)
+    nmap <buffer> <f2> <plug>(lsp-rename)
+    nmap <buffer> [g <plug>(lsp-previous-diagnostic)
+    nmap <buffer> ]g <plug>(lsp-next-diagnostic)
+    nmap <buffer> K <plug>(lsp-hover)
+endfunction
+
+augroup lsp_install
+    au!
+    autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
+augroup END
+
+let g:lsp_diagnostics_highlights_enabled = 1
+
+highlight lspReference cterm=underline guifg=red guibg=green
+
+
+" asyncomplete tabcompletion
+inoremap <expr> <Tab>   pumvisible() ? "\<C-n>" : "\<Tab>"
+inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
+inoremap <expr> <cr>    pumvisible() ? asyncomplete#close_popup() : "\<cr>"
+
+" netrw
+inoremap <F4> :Explore<CR>
+nnoremap <F4> <Esc>:Explore<CR>
diff --git a/stow/vsvim/_vsvimrc b/stow/vsvim/_vsvimrc
new file mode 100644 (file)
index 0000000..e6fbac9
--- /dev/null
@@ -0,0 +1,69 @@
+set relativenumber
+set number
+
+" Appearance
+set hlsearch
+set incsearch
+set ignorecase
+set smartcase
+set visualbell
+let mapleader = " "
+
+nnoremap <Leader>i a'" <<  << "' <Esc>6hi
+nnoremap <Leader>a a'{}' <Esc>2hi
+nnoremap <Leader>A a'"+  +"' <Esc>4hi
+autocmd FileType cpp nnoremap <Leader>a a'"<<  <<"' <Esc>5hi
+
+nnoremap <F2> msgg=G`szz
+
+inoremap kj <Esc>
+inoremap jk <Esc>
+nnoremap <leader>ts O// TODOts: <Esc>=$A
+nnoremap <leader>td O//TODOts: doku<CR><summary> </summary><Esc>0i/// <Esc>kVj=$
+nnoremap <leader>in O<Esc>0I// <inheritdoc/><Esc>0I/<Esc>=lj
+nnoremap <leader>no O<Esc>0I// <nodoc /><Esc>0I/<Esc>=lj
+
+" Copy paste to/from system clipboard
+vnoremap <leader>c "*y
+noremap  <leader>v "*p
+vnoremap <leader>v "*p
+
+"move lines up/down visually selected
+nnoremap <S-Up> :m .-2<CR>==
+inoremap <S-Up> <Esc>:m .-2<CR>==gi
+vnoremap <S-Up> :m '<-2<CR>gv=gv
+inoremap <S-Down> <Esc>:m .+1<CR>==gi
+nnoremap <S-Down> :m .+1<CR>==
+vnoremap <S-Down> :m '>+1<CR>gv=gv
+
+nnoremap <S-Right> >>
+vnoremap <S-Right> :><CR>gv
+vnoremap <S-Left>  :<<CR>gv
+nnoremap <S-Left> <<
+
+" repeat lS-ast command on all selected:
+vnoremap . :normal.<CR>
+
+noremap <leader>n ]cz.
+noremap <leader>p [cz.
+
+
+nmap <C-]> :vsc Edit.GoToDefinition<CR>
+nmap gd :vsc Edit.GoToDefinition<CR>
+nmap gi :vsc Edit.GoToImplementation<CR>
+nmap gf :vsc Edit.FindAllReferences<CR>
+nmap dj :vsc Edit.GoToNextLocation<CR>
+nmap dk :vsc Edit.GoToPrevLocation<CR>
+nmap <leader>e :vsc View.ErrorList<CR>
+
+nmap <C-o> :vsc View.NavigateBackward<CR>
+nmap <C-i> :vsc View.NavigateForward<CR>
+nmap br :vsc Debug.Start<CR>
+nmap bf :vsc Debug.Restart<CR>
+nmap bs :vsc Build.BuildSolution<CR>
+
+nmap <leader>j :vsc Window.NextTab<CR>
+nmap <leader>k :vsc Window.PreviousTab<CR>
+
+
+set scrolloff=8
diff --git a/stow/zsh/.zshrc b/stow/zsh/.zshrc
new file mode 100644 (file)
index 0000000..605f82d
--- /dev/null
@@ -0,0 +1,117 @@
+# If you come from bash you might have to change your $PATH.
+# export PATH=$HOME/bin:/usr/local/bin:$PATH
+
+# Path to your oh-my-zsh installation.
+export ZSH="$HOME/.oh-my-zsh"
+
+# Set name of the theme to load --- if set to "random", it will
+# load a random theme each time oh-my-zsh is loaded, in which case,
+# to know which specific one was loaded, run: echo $RANDOM_THEME
+# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
+ZSH_THEME="dpoggi"
+
+# Set list of themes to pick from when loading at random
+# Setting this variable when ZSH_THEME=random will cause zsh to load
+# a theme from this variable instead of looking in $ZSH/themes/
+# If set to an empty array, this variable will have no effect.
+# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
+
+# Uncomment the following line to use case-sensitive completion.
+# CASE_SENSITIVE="true"
+
+# Uncomment the following line to use hyphen-insensitive completion.
+# Case-sensitive completion must be off. _ and - will be interchangeable.
+# HYPHEN_INSENSITIVE="true"
+
+# Uncomment one of the following lines to change the auto-update behavior
+# zstyle ':omz:update' mode disabled  # disable automatic updates
+zstyle ':omz:update' mode auto      # update automatically without asking
+# zstyle ':omz:update' mode reminder  # just remind me to update when it's time
+
+# Uncomment the following line to change how often to auto-update (in days).
+zstyle ':omz:update' frequency 13
+
+# Uncomment the following line if pasting URLs and other text is messed up.
+# DISABLE_MAGIC_FUNCTIONS="true"
+
+# Uncomment the following line to disable colors in ls.
+# DISABLE_LS_COLORS="true"
+
+# Uncomment the following line to disable auto-setting terminal title.
+# DISABLE_AUTO_TITLE="true"
+
+# Uncomment the following line to enable command auto-correction.
+# ENABLE_CORRECTION="true"
+
+# Uncomment the following line to display red dots whilst waiting for completion.
+# You can also set it to another string to have that shown instead of the default red dots.
+# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
+# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
+COMPLETION_WAITING_DOTS="true"
+
+# Uncomment the following line if you want to disable marking untracked files
+# under VCS as dirty. This makes repository status check for large repositories
+# much, much faster.
+# DISABLE_UNTRACKED_FILES_DIRTY="true"
+
+# Uncomment the following line if you want to change the command execution time
+# stamp shown in the history command output.
+# You can set one of the optional three formats:
+# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
+# or set a custom format using the strftime function format specifications,
+# see 'man strftime' for details.
+HIST_STAMPS="yyyy-mm-dd"
+
+# Would you like to use another custom folder than $ZSH/custom?
+# ZSH_CUSTOM=/path/to/new-custom-folder
+
+# Which plugins would you like to load?
+# Standard plugins can be found in $ZSH/plugins/
+# Custom plugins may be added to $ZSH_CUSTOM/plugins/
+# Example format: plugins=(rails git textmate ruby lighthouse)
+# Add wisely, as too many plugins slow down shell startup.
+plugins=(git fzf)
+
+source $ZSH/oh-my-zsh.sh
+
+# User configuration
+
+# export MANPATH="/usr/local/man:$MANPATH"
+
+# You may need to manually set your language environment
+# export LANG=en_US.UTF-8
+
+# Preferred editor for local and remote sessions
+# if [[ -n $SSH_CONNECTION ]]; then
+#   export EDITOR='vim'
+# else
+#   export EDITOR='mvim'
+# fi
+
+if [[ -e /snap/bin/nvim ]]; then
+    export EDITOR='/snap/bin/nvim'
+elif [ `which nvim` != "" ]; then
+    export EDITOR=`which nvim`
+else 
+    echo "nvim not installed?"
+    export EDITOR=vim
+fi
+
+alias vi=$EDITOR
+alias vim=$EDITOR
+alias ll='ls -lah'
+alias t='tail -F -n 40'
+
+# Compilation flags
+# export ARCHFLAGS="-arch x86_64"
+
+# Set personal aliases, overriding those provided by oh-my-zsh libs,
+# plugins, and themes. Aliases can be placed here, though oh-my-zsh
+# users are encouraged to define aliases within the ZSH_CUSTOM folder.
+# For a full list of active aliases, run `alias`.
+#
+# Example aliases
+# alias zshconfig="mate ~/.zshrc"
+# alias ohmyzsh="mate ~/.oh-my-zsh"
+
+export PATH=$PATH:~/bin:~/.bin:/snap/bin