34 次代码提交 d82669199b ... 6e7ac0544e

作者 SHA1 备注 提交日期
  tuzi3040 6e7ac0544e fix(agnoster): print white text over black for light theme only (#12983) 1 月之前
  Adrien Plazas 92da3108b5 fix(agnoster): print white text over black (#12525) 2 月之前
  Marc Cornellà 7d32e7fc3f fix(updater): detect p10k instant prompt (#12971) 2 月之前
  Stephen Gelman 0e99f402cd feat(agnoster): add color config and add some git stuff (#12505) 2 月之前
  Dennis Dashkevich 8074eb8b46 fix(chruby): update brew sourcing for Apple Silicon (#12941) 2 月之前
  Carlo Sala 4d9d346718 feat(asdf): support asdf v0.16 ahead 2 月之前
  Daniel Mensinger db32c6ccce fix(mvn): handle directories in `<relativePath>` (#12957) 2 月之前
  dependabot[bot] 2b547d113b chore(deps): bump certifi in /.github/workflows/dependencies (#12955) 2 月之前
  ohmyzsh[bot] 2343ad517d feat(wd): update to v0.9.3 (#12954) 2 月之前
  soemiran 1c34b0e67d feat(terraform): support `TF_DATA_DIR` in `tf_prompt_info` (#12949) 2 月之前
  Guspan Tanadi 33d4db7fee docs(ember-cli): fix typo (#12945) 2 月之前
  Carlo Sala ce9a4a0196 feat(dnf): add `dnf5` completion 2 月之前
  dependabot[bot] 9ffc14c3e1 chore(deps): bump semver from 3.0.3 to 3.0.4 in /.github/workflows/dependencies (#12938) 2 月之前
  Marcus Voltolim cc9259d6ad docs(git-auto-fetch): fix typo (#12937) 2 月之前
  Eduardo Roberto 3bd48b12c8 chore: ignore `.zwc` files (#12936) 2 月之前
  Ken van der Eerden 5fd2059e5e feat(jira): allow branch name customization (#12850) 2 月之前
  Marc Cornellà 85c4941492 fix(cli)!: remove harmful `--unattended` flag for `omz update` (#12935) 2 月之前
  shun095 d2e79501b2 fix(timer): minutes calculation logic (#12857) 2 月之前
  fossdd 69410e7020 feat(foot): add foot plugin (#12849) 2 月之前
  Marc Cornellà 4e29c670a4 fix(changelog): show if there are no changes (#12934) 2 月之前
  Thomas Boyer 1bae199736 fix(direnv): warn user if command not found (#12840) 2 月之前
  Keith Bennett bd0a5b2598 docs(chucknorris): add useful note (#12822) 2 月之前
  jamesrtnz 9a0e22c184 feat(perl): add `perlbrew` auto activation (#12814) 2 月之前
  Marc Cornellà 501f29f90c fix(tailscale): fix completion binding for alias to `Tailscale` (#12928) 2 月之前
  Marc Cornellà cca4043238 feat(python): support multiple venvs via `$PYTHON_VENV_NAMES` (#12932) 2 月之前
  dependabot[bot] 6e9cda3d30 chore(deps): bump semver in /.github/workflows/dependencies (#12924) 3 月之前
  ohmyzsh[bot] d689aa289e feat(gitfast): update to version v2.2 (#12923) 3 月之前
  Felipe Contreras 8c5b71b2f4 ci(deps): update `gitfast` to its new structure (#12922) 3 月之前
  Abhijeet Vashistha 028d653632 fix(sonicradish): reset color typo (#12912) 3 月之前
  Nico Just 04cba220f7 feat(eza): add color-scale options (#12841) 3 月之前
  Michele Bologna 7a3695aadf fix(grc): add linuxbrew path (#12903) 3 月之前
  Thomas cae2e45193 fix(rust): call `rustc` through `rustup run` (#12901) 3 月之前
  Carlo Sala 276e540eed fix(cli): ensure `ksharrays` is unset 3 月之前
  Bhanu 5c17bcd21f feat(web-search): add perplexity.ai (#12815) 3 月之前

+ 6 - 4
.github/dependencies.yml

@@ -2,11 +2,13 @@ dependencies:
   plugins/gitfast:
     repo: felipec/git-completion
     branch: master
-    version: tag:v2.1
+    version: tag:v2.2
     postcopy: |
       set -e
-      rm -rf git-completion.plugin.zsh Makefile README.adoc t tools
-      test -e git-completion.zsh && mv -f git-completion.zsh _git
+      rm -rf git-completion.plugin.zsh Makefile t tools
+      mv README.adoc MANUAL.adoc
+      mv -f src/* .
+      rmdir src
   plugins/gradle:
     repo: gradle/gradle-completion
     branch: master
@@ -28,7 +30,7 @@ dependencies:
   plugins/wd:
     repo: mfaerevaag/wd
     branch: master
-    version: tag:v0.9.2
+    version: tag:v0.9.3
     precopy: |
       set -e
       rm -r test

+ 2 - 2
.github/workflows/dependencies/requirements.txt

@@ -1,7 +1,7 @@
-certifi==2024.12.14
+certifi==2025.1.31
 charset-normalizer==3.4.1
 idna==3.10
 PyYAML==6.0.2
 requests==2.32.3
-semver==3.0.2
+semver==3.0.4
 urllib3==2.3.0

+ 3 - 0
.gitignore

@@ -10,3 +10,6 @@ log/
 # editor configs
 .vscode
 .idea
+
+# zcompile cached files
+*.zwc

+ 11 - 0
README.md

@@ -487,6 +487,17 @@ wait a week?) you just need to run:
 omz update
 ```
 
+> [!NOTE]
+> If you want to automate this process in a script, you should call directly the `upgrade` script, like this:
+>
+> ```sh
+> $ZSH/tools/upgrade.sh
+> ```
+>
+> See more options in the [FAQ: How do I update Oh My Zsh?](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#how-do-i-update-oh-my-zsh).
+>
+> **USE OF `omz update --unattended` HAS BEEN REMOVED, AS IT HAS SIDE EFFECTS**.
+
 Magic! 🎉
 
 ## Uninstalling Oh My Zsh

+ 10 - 6
lib/cli.zsh

@@ -1,6 +1,7 @@
 #!/usr/bin/env zsh
 
 function omz {
+  setopt localoptions noksharrays
   [[ $# -gt 0 ]] || {
     _omz::help
     return 1
@@ -822,6 +823,13 @@ function _omz::update {
     return 1
   }
 
+  # Check if --unattended was passed
+  [[ "$1" != --unattended ]] || {
+    _omz::log error "the \`\e[2m--unattended\e[0m\` flag is no longer supported, use the \`\e[2mupgrade.sh\e[0m\` script instead."
+    _omz::log error "for more information see https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#how-do-i-update-oh-my-zsh"
+    return 1
+  }
+
   local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)
   [[ $? -eq 0 ]] || {
     _omz::log error "\`$ZSH\` is not a git directory. Aborting..."
@@ -830,11 +838,7 @@ function _omz::update {
 
   # Run update script
   zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
-  if [[ "$1" != --unattended ]]; then
-    ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
-  else
-    ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -v $verbose_mode || return $?
-  fi
+  ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
 
   # Update last updated file
   zmodload zsh/datetime
@@ -843,7 +847,7 @@ function _omz::update {
   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
+  if [[ "$(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

+ 18 - 0
plugins/asdf/asdf.plugin.zsh

@@ -1,3 +1,21 @@
+if (( $+commands[asdf] )); then
+  export ASDF_DATA_DIR="${ASDF_DATA_DIR:-$HOME/.asdf}"
+  path=("$ASDF_DATA_DIR/shims" $path)
+
+  # If the completion file doesn't exist yet, we need to autoload it and
+  # bind it to `asdf`. Otherwise, compinit will have already done that.
+  if [[ ! -f "$ZSH_CACHE_DIR/completions/_asdf" ]]; then
+    typeset -g -A _comps
+    autoload -Uz _asdf
+    _comps[asdf]=_asdf
+  fi
+  asdf completion zsh >| "$ZSH_CACHE_DIR/completions/_asdf" &|
+
+  return
+fi
+
+# TODO:(2025-02-12): remove deprecated asdf <0.16 code
+
 # Find where asdf should be installed
 ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
 ASDF_COMPLETIONS="$ASDF_DIR/completions"

+ 2 - 0
plugins/chruby/chruby.plugin.zsh

@@ -22,6 +22,8 @@ _source-from-homebrew() {
   # check default brew prefix
   if [[ -h /usr/local/opt/chruby ]];then
     _brew_prefix="/usr/local/opt/chruby"
+  elif [[ -h /opt/homebrew/opt/chruby ]]; then
+    _brew_prefix="/opt/homebrew/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

+ 7 - 0
plugins/chucknorris/README.md

@@ -36,3 +36,10 @@ Last login: Fri Jan 30 23:12:26 on ttys001
 - `cowsay` if using `chuck_cow`
 
 Available via homebrew, apt, ...
+
+> [!NOTE]  
+> In addition to installing `fortune`, it may be necessary to run:
+> 
+> `strfile $ZSH/plugins/chucknorris/fortunes/chucknorris\n`
+> 
+> (include the "\n" literally) to write the fortune data to the proper directory.

+ 5 - 2
plugins/direnv/direnv.plugin.zsh

@@ -1,5 +1,8 @@
-# Don't continue if direnv is not found
-command -v direnv &>/dev/null || return
+# If direnv is not found, don't continue and print a warning
+if (( ! $+commands[direnv] )); then
+  echo "Warning: direnv not found. Please install direnv and ensure it's in your PATH before using this plugin."
+  return
+fi
 
 _direnv_hook() {
   trap -- '' SIGINT;

+ 570 - 0
plugins/dnf/_dnf5

@@ -0,0 +1,570 @@
+#compdef dnf5
+# based on dnf-5.2.6.2
+
+# utility functions
+
+_dnf5_helper() {
+  _call_program specs $service "${(q-)@}" "${(q-)PREFIX}\*" \
+        -qC --assumeno --nogpgcheck 2>/dev/null </dev/null
+}
+
+_dnf5_repositories() {
+  # required option: -T (all|disabled|enabled)
+  local selected expl
+  zparseopts -D -E - T:=selected
+  selected=$selected[2]
+  _wanted $selected-repositories expl "$selected repository" \
+    compadd "$@" - "${(@)${(f)$(_dnf5_helper repo list --$selected)}[2,-1]%% *}"
+}
+
+_dnf5_packages() {
+  # required option: -T (all|available|installed|upgradable)
+  local selected opt expl
+  zparseopts -D -E - T:=selected
+  selected=$selected[2]
+  case $selected in
+    all)        opt='' ;;   # option --all does not exist
+    upgradable) opt='--upgrades' ;;
+    *)          opt="--$selected" ;;
+  esac
+  _wanted $selected-packages expl "$selected package" \
+    compadd "$@" - $(_dnf5_helper repoquery $opt --qf='%{name} ')
+}
+
+_dnf5_rpm_files() {
+  local expl
+  _wanted rpm-files expl 'rpm file' _files -g '(#i)*.rpm(-.)'
+}
+
+_dnf5_packages_or_rpms() {
+  if [[ "$words[CURRENT]" = (*/*|\~*) ]]; then # if looks like a path name
+    _dnf_rpm_files
+  else
+    _dnf5_packages "$@"
+  fi
+}
+
+_dnf5_groups() {
+  # optional option: -T (available|installed)
+  local update_policy selected line pat groups
+  zparseopts -D -E - T:=selected
+  selected=$selected[2]
+  if [[ -z $selected ]]; then
+    selected=all
+    opt=  # option --all does not exist
+  else
+    opt=--$selected
+  fi
+  # XXX hidden groups are not included
+  for line in ${${(f)"$(_dnf5_helper group list $opt)"}[2,-1]}; do
+    line=( ${(z)line} )
+    groups+=( "$line[1]:$line[2,-2]" )
+  done
+  _describe -t $selected-groups "$selected group" groups
+}
+
+_dnf5_environments() {
+  local line envs
+  for line in ${${(f)"$(_dnf5_helper environment list)"}[2,-1]}; do
+    line=( ${(z)line} )
+    envs+=( "$line[1]:$line[2,-2]" )
+  done
+  _describe -t environments 'environment' envs
+}
+
+# completers for (several) dnf commands
+
+_dnf5-advisory () {
+  _arguments : \
+    $advisory_opts \
+    '--contains-pkgs=[only show advisories containing specified packages]: : _sequence _dnf5_packages -T installed' \
+    + '(with)' \
+    '--with-cve[show only advisories referencing CVE ticket]' \
+    '--with-bz[show only advisories referencing Bugzilla ticket]' \
+    + '(type)' \
+    '--all[show all advisories]' \
+    '--available[show advisories containing newer versions of installed packages (default)]' \
+    '--installed[show advisories containing equal and older version of installed packages]' \
+    '--updates[show advisories containing upgradable packages]' \
+    + args \
+    ':subcommand:(list info summary)' '*:advisory spec:'
+}
+
+_dnf5-group() {
+  local -a tmp
+  if (( CURRENT == 2 )); then
+    tmp=(
+      'list:list all matching groups'
+      'info:print detailed information about groups'
+      'install:install packages from specified groups'
+      'remove:remove removable packages in specified groups'
+      'upgrade:upgrade specified groups and packages in them'
+    )
+    _describe -t subcommands 'subcommand' tmp
+  else
+    case $words[2] in
+      list|info)
+        tmp=(
+          '(--installed)--available[show only available groups]'
+          '(--available)--installed[show only installed groups]'
+          '--hidden[show also hidden groups]'
+          '--contains-pkgs=[show only groups containing specified packages]: : _sequence _dnf5_packages -T all'
+          '*: : _dnf5_groups'
+        )
+        ;;
+      install)
+        tmp=( $common_opts
+              '--with-optional[include optional packages from the groups]'
+              '*: : _dnf5_groups -T available' )
+        ;|
+      upgrade)
+        tmp=( ${common_opts:#--skip-broken*}
+              '*: : _dnf5_groups -T installed' )
+        ;|
+      remove)
+        tmp=( $offline_opts
+              '*: : _dnf5_groups -T installed' )
+        ;|
+      install|remove)
+        tmp+=( '--no-packages[operate on groups only, not manipulate any packages]' )
+        ;|
+      install|upgrade)
+        tmp+=( $downgrade_opts )
+        ;;
+    esac
+    _arguments : $tmp
+  fi
+}
+
+_dnf5-history() {
+  local -a tmp
+  if (( CURRENT == 2 )); then
+    tmp=(
+      'list:list info about recorded transactions'
+      'info:print detailed about specific transactions'
+      'undo:revert all actions from the specified transaction'
+      'redo:repeat the specified transaction'
+      'rollback:undo all transactions performed after the specified transaction'
+      'store:store the transaction into a directory'
+    )
+    _describe -t subcommands 'subcommand' tmp
+  else
+    case $words[2] in
+      list|info)
+        tmp=( '--reverse[reverse the order of transactions in output]' )
+        ;;
+      undo|rollback|redo)
+        tmp=( '--skip-unavailable[allow skipping impossible actions]' )
+        ;|
+      undo|rollback)
+        tmp+=( $replay_opts )
+        ;;
+      store)
+        tmp=( {-o,--output=}'[directory for storing the transaction (default ./transaction)]: : _directories')
+    esac
+    _arguments : $tmp '2:transaction:( )'
+  fi
+}
+
+_dnf5-mark() {
+  local -a tmp
+  if (( CURRENT == 2 )); then
+    tmp=(
+      'user:mark the package as user-installed'
+      'dependency:mark the package as a dependency'
+      'weak:mark the package as a weak dependency'
+      'group:mark the package as installed by the specified group'
+    )
+    _describe -t subcommands 'subcommand' tmp
+  else
+    tmp=(
+      '--skip-unavailable[skip packages not installed on the system]'
+      '--store=[store the transaction in specified directory]: : _directories'
+    )
+    if [[ $words[2] = group ]]; then
+        tmp+=( '2:group-id: _dnf5_groups -T installed' )
+    fi
+    _arguments : $tmp '*: : _dnf5_packages -T installed'
+  fi
+}
+
+_dnf5-module() {
+  local -a tmp
+  if (( CURRENT == 2 )); then
+    tmp=(
+      'list:list module streams'
+      'info:print details about module streams'
+      'enable:enable module streams'
+      'disable:disable modules including all their streams'
+      "reset:reset module state so it's no longer enabled or disabled"
+    )
+    _describe -t subcommands 'subcommand' tmp
+  elif (( CURRENT == 3 )) && [[ $cur = -* ]]; then
+    case $words[2] in
+      list|info) tmp=( --enabled --disabled ) ;;
+      enable)    tmp=( --skip-broken --skip-unavailable ) ;;
+      *)         tmp=( --skip-unavailable ) ;;
+    esac
+    _wanted options expl 'option' compadd -a tmp
+  else
+    _message 'module spec'
+  fi
+}
+
+_dnf5-offline() {  # also used by the 'system-upgrade' command
+  local -a tmp
+  if (( CURRENT == 2 )); then
+    tmp=(
+      'clean:remove any stored offline transactions and cached packages'
+      'log:list boots during which offline transaction was attempted'
+      'reboot:prepare the system for offline transaction and reboot'
+    )
+    if [[ $cmd = offline ]]; then
+      tmp+=( 'status:show status of the current offline transaction' )
+    else
+      tmp+=( 'download:download all packages needed for upgrade' )
+    fi
+    _describe -t subcommands 'subcommand' tmp && ret=0
+  else
+    case $words[2] in
+      download)
+        _arguments : \
+          '--releasever=[the version to upgrade to]:version number:' \
+          '--no-downgrade:do not install packages older than currently installed' '*: :' && ret=0
+        ;;
+      log)
+        _arguments : \
+          '--number=[show log of transaction specified by number]:transaction number:' '*: :' && ret=0
+        ;;
+      reboot)
+        _wanted options expl 'option' compadd -- --poweroff && ret=0
+        ;;
+    esac
+  fi
+}
+
+_dnf5-repoquery() {
+  local v
+  local -a opts=(
+    $advisory_opts
+    '--arch=[limit results to specified architectures]:list of archs: '
+    '--available[limit results to available packages]'
+    '--disable-modular-filtering[include packages of inactive module streams]'
+    '--duplicates[limit to installed duplicate packages]'
+    '--exactdeps[limit to packages that require capability specified by ==what{requires,depends}]'
+    '--extras[limit to installed packages that are not present in any available repository]'
+    '--file=[limit results to packages which own specified file]:list of files: _sequence _files'
+    '--installed[query installed packages]'
+    '--installonly[limit to installed installonly packages]'
+    '--latest-limit=[limit to latest packages of specified number]:number:'
+    '--leaves[limit to groups of installed packages not required by other installed packages]'
+    '--providers-of=[select packages that provide specified attribute]:attribute:(conflicts depends enhances obsoletes provides recommends requires requires_pre suggests supplement)'
+    '--recent[limit to only recently changed packages]'
+    '--recursive[make --whatrequires/--providers-of work recursively]'
+    '--security[limit to packages in security advisories]'
+    '--srpm[use the corresponding source RPM]'
+    '--unneeded[limit to unneeded installed packages]'
+    '--upgrades[limit to available packages that provide upgrade for installed packages]'
+    '--userinstalled[limit to packages that are not installed as dependencies]'
+    '--whatdepends=[limit to packages that require, enhance, recommend, suggest of supplement specified capability]:list of capability:'
+    '--whatconflicts=[limit to packages that conflicts with specified capabilities]:list of capability: '
+  )
+  for v in enhance obsolete provide recommend require suggest supplement; do
+    opts+=( "--what${v}s=[limit to packages that $v specified capabilities]:list of capability: ")
+  done
+  # mutually exclusive formating options
+  opts+=(
+    + '(format)'
+    '--conflicts[display capabilities that the package conflicts with]'
+    '--depends[display capabilities that the package depends on, enables, recommends, suggests or supplements]'
+    '--files[show files in the package]'
+    '--requires-pre[display capabilities required to run pre/post scripts of the package]'
+    '--sourcerpm[display source RPM of the package]'
+    '--location[display location of the package]'
+    '--info[show detailed information about the package]'
+    '--changelogs[print the package changelogs]'
+    '(- *)--querytags[list tags recognized by --queryformat]'
+    '--queryformat=[specify output format]:format:'
+  )
+  for v in enhance obsolete provide recommend require suggest supplement; do
+    opts+=( "--${v}s[display capabilities ${v}ed by the package]" )
+  done
+
+  _arguments : '*: : _dnf5_packages -T all' $opts
+}
+
+# dnf commands
+
+_dnf5_commands() {
+  local -a dnf_cmds=(
+    'advisory:manage advisories'
+    'autoremove:remove unneeded packages'
+    'check:check for problems in package database'
+    'check-upgrade:check for available package upgrades'
+    'clean:remove or invalidate cached data'
+    'distro-sync:up/downgrade installed packages to the latest available'
+    'downgrade:downgrade packages'
+    'download:download packages'
+    'environment:manage comps environments'
+    'group:manage comps groups'
+    'history:manage transaction history'
+    'info:provide detailed information about packages'
+    'install:install packages'
+    'leaves:list groups of leaf packages'
+    'list:list installed or available packages'
+    'makecache:generate the metadata cache'
+    'mark:change the reason of an installed package'
+    'module:manage modules'
+    'offline:manage offline transactions'
+    'provides:find what package provides the given value'
+    'reinstall:reinstall packages'
+    'remove:remove packages'
+    'replay:replay stored transactions'
+    'repo:manage repositories'
+    'repoquery:search for packages in repositories'
+    'search:search for packages using keywords'
+    'swap:remove software and install another in the single transaction'
+    'system-upgrade:upgrade the system to a new major release'
+    'upgrade:upgrade packages'
+    'versionlock:protect packages from updates to newer versions'
+  )
+  _describe -t dnf-commands 'dnf command' dnf_cmds
+}
+
+# subcommands and options
+
+_dnf5_subcmds_opts() {
+  local cur=$words[CURRENT] cmd=$words[1] expl ret=1
+  local -a tmp
+  # common options
+  local -a offline_opts=(
+    '(--store)--offline[store the transaction to be performed offline]'
+    '(--offline)--store=[store the transaction in specified directory]: : _directories'
+  )
+  local -a common_opts=(
+    $offline_opts
+    '--allowerasing[allow erasing of installed packages]'
+    '--skip-broken[resolve dependency problems by skipping problematic packages]'
+    "--skip-unavailable[skip packages that can't be synchronized]"
+    '--downloadonly[download packages without executing transaction]'
+  )
+  local -a advisory_opts=(
+    '--advisories=[consider only specified advisories]:list of advisories:'
+    '--advisory-severities=[limit to advisories with specified severity]:severity:_sequence compadd - critical important moderate low none'
+    '--bzs=[limit to advisories that fix specified Bugzilla ID]:list of Bugzilla ID:'
+    '--cves=[limit to advisories that fix specified CVE ID]:list of CVD ID]:'
+    '--security[limit to security advisories]'
+    '--bugfix[limit to bugfix advisories]'
+    '--enhancement[limit to enhancement advisories]'
+    '--newpackage[limit to newpackage advisories]'
+  )
+  local -a downgrade_opts=(
+    '(--no-allow-downgrade)--allow-downgrade[enable downgrade of dependencies]'
+    '(--allow-downgrade)--no-allow-downgrade[disable downgrade of dependencies]'
+  )
+  local -a replay_opts=(
+    '--ignore-extras[not consider extra packages]'
+    '--ignore-installed[mismatches between installed and stored transaction are not errors]'
+  )
+  # Deal with some aliases (not comprehensive)
+  case $cmd in
+    check-updgrade) cmd=check-update;;
+    dg) cmd=downgrade;;
+    dsync) cmd=distro-sync;;
+    grp) cmd=group;;
+    if) cmd=info;;
+    in) cmd=install;;
+    ls) cmd=list;;
+    mc) cmd=makecache;;
+    rei) cmd=reinstall;;
+    rm) cmd=remove ;;
+    rq) cmd=repoquery;;
+    se) cmd=search;;
+    update|up) cmd=upgrade;;
+  esac
+  local curcontext="${curcontext%:*:*}:dnf-${cmd}:"
+
+  case $cmd in
+    advisory|group|history|mark|module|offline|repoquery)
+      _dnf5-$cmd && ret=0
+      ;;
+    system-upgrade)
+      _dnf5-offline && ret=0
+      ;;
+    autoremove)
+      _arguments : $offline_opts && ret=0
+      ;;
+    check)
+      _arguments : \
+        '--dependencies[show missing dependencies and conflicts]' \
+        '--duplicates[show duplicated packages]' \
+        '--obsoleted[show obsoleted packages]' && ret=0
+      ;;
+    check-upgrade)
+      _arguments : \
+        $advisory_opts \
+        '--changelogs[print package changelogs]' \
+        '--minimal[reports the lowest versions of packages that fix advisories]' \
+        '*: : _dnf5_packages -T installed' && ret=0
+      ;;
+    clean)
+      tmp=(
+        'dbcache:remove cache files generated from the repository metadata'
+        'expire-cache:mark the repository metadata expired'
+        'metadata:remove the repository metadata'
+        'packages:remove any cached packages'
+        'all:clean all'
+      )
+      _describe -t cache-types 'cache type' tmp && ret=0
+      ;;
+    distro-sync)
+      _arguments : $common_opts '*: : _dnf5_packages -T installed' && ret=0
+      ;;
+    downgrade)
+      _arguments : \
+        $common_opts $downgrade_opts \
+        '*: : _dnf5_packages -T installed' && ret=0
+      ;;
+    download)
+      _arguments : \
+        '--arch=[limit to packages of specified architecture]:list of architectures:' \
+        '--resolve[resolve and download needed dependencies]' \
+        '--alldeps[with --resolve, also download already installed dependencies]' \
+        '--destdir=[download to the specified directory]: : _directories' \
+        '--srpm[download the source rpm]' \
+        '--url[print the list of URLs where the rpms can be downloaded]' \
+        '*--urlprotocol=[with --url, limit to specified protocols]:protocol:_sequence compadd - http https ftp file' \
+        '*: : _dnf5_packages -T all' && ret=0
+      ;;
+    environment)
+      _arguments : \
+        '--available[show only available environments]' \
+        '--installed[show only installed environments]' \
+        ':subcommand:(list info)' \
+        '*: : _dnf5_environments' && ret=0
+      ;;
+    info|list)
+      _arguments : \
+        '--showduplicates[show all versions of the packages]' \
+        '*: : _dnf5_packages -T all' \
+        + '(type)' \
+        '--installed[list only installed packages]:*: : _dnf5_packages -T installed' \
+        '--available[list only available packages]:*: : _dnf5_packages -T available' \
+        '--extras[list only extras]' \
+        '--obsoletes[list only installed but obsoleted packages]:*: : _dnf5_packages -T installed' \
+        '--recent[list only recently added packages]' \
+        '--upgrades[list only available upgrades of installed packages]:*: : _dnf5_packages -T upgradable' \
+        '--autoremove[list only packages that will be autoremoved]:*: : _dnf5_packages -T installed' &&ret=0
+      ;;
+    install)
+      _arguments : \
+        $common_opts $downgrade_opts $advisory_opts \
+        '*: : _dnf5_packages_or_rpms -T available' && ret=0
+      ;;
+    leaves|makecache)
+      # nothing to complete
+      ;;
+    provides)
+      _files && ret=0
+      ;;
+    reinstall)
+      _arguments : \
+        $common_opts $downgrade_opts \
+        '*: : _dnf5_packages_or_rpms -T installed' && ret=0
+      ;;
+    remove)
+      _arguments : \
+        $offline_opts \
+        '--no-autoremove[not remove dependencies that are no longer used]' \
+        '*: : _dnf5_packages -T installed' && ret=0
+      ;;
+    replay)
+      _arguments : \
+        $replay_opts \
+        ':transaction path:_directories' && ret=0
+      ;;
+    repo)
+      _arguments : \
+        '--all[show info about all repositories]' \
+        '--enabled[show info only about enabled repositories]' \
+        '--disabled[show info only about disabled repositories]' \
+        ':subcommand:(list info)' && ret=0
+      ;;
+    search)
+      _arguments : \
+        '--all[search patterns also inside description and URL fields]' \
+        '--showduplicates[show all versions of packages, not only the latest ones]' \
+        '*:search pattern:' && ret=0
+      ;;
+    swap)
+      _arguments : \
+        $offline_opts \
+        '--allowerasing[allow erasing of installed packages]' \
+        ': : _dnf5_packages -T installed' \
+        ': : _dnf5_packages -T available' && ret=0
+      ;;
+    upgrade)
+      _arguments : \
+        ${common_opts:#--skip-broken*} $downgrade_opts $advisory_opts \
+        '--minimal[upgrade only to the lowest available versions that fix advisories]' \
+        '--destdir=[specify directory into which downloading packages]: : _directories' \
+      '*: : _dnf5_packages_or_rpms -T upgradable' && ret=0
+      ;;
+    versionlock)
+      _arguments : \
+        ':subcommand:(add exclude clear delete list)' \
+        '*: : _dnf5_packages -T all' && ret=0
+      ;;
+  esac
+  return ret
+}
+
+# main completer
+
+_dnf5() {
+  local curcontext="$curcontext" state state_descr line ret=1
+  typeset -A opt_args
+  local -a opts=(
+    '(-y --assumeyes)--assumeno[answer no for all questions]'
+    '--best[try the best available package version]'
+    '(-C --cacheonly)'{-C,--cacheonly}"[run entirely from system cache, don't update cache]"
+    '--comment=[add comment to transaction history]:comment:'
+    '(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files'
+    '--debugsolver[dump detailed solving results in file ./debugdata]'
+    '*--disable-plugin=[disable specified plugins]:list of plugin names:'
+    '(--repo)*--disable-repo=[disable specified repos]: : _sequence _dnf5_repositories -T enabled'
+    '--dump-main-config[print main configuration values to stdout]'
+    '*--dump-repo-config=[print repository configuration values to stdout]:repi id'
+    '--dump-variables[print variable values to stdout]'
+    '*--enable-plugin=[enable specified plugins]:list of plugin names:'
+    '*--enable-repo=[enable additional repos]: : _sequence _dnf5_repositories -T disabled'
+    '--forcearch=[force the use of the specified arch]:arch:'
+    '(-)'{-h,--help}'[show the help message]'
+    '--installroot=[set install root]: : _directories'
+    '--no-best[do not limit transactions to best candidates]'
+    '--no-docs[do not install documentation]'
+    '--no-gpgcheck[skip checking GPG signatures on packages]'
+    '--no-plugins[disable all plugins]'
+    '(-q --quiet)'{-q,--quiet}'[show just the relevant content]'
+    '--refresh[force refreshing metadata before running the command]'
+    '--releasever=[override distribution release in config files]:release ver:'
+    '(--disablerepo)*--repo=[enable just the specified repo]: : _sequence _dnf5_repositories -T all'
+    '*--repofrompath=[specify additional repos]:repository_label,path_or_url: '
+    '*--setopt=[override option in config file]:repoid.option=value:'
+    '*--setvar=[override DNF5 variable value]'
+    '--show-new-leaves[show newly installed leaf packages]'
+    '--use-host-config[use config files and variables from host system]'
+    '(- *)--version[show dnf version]'
+    '(-y --assumeyes --assumeno)'{-y,--assumeyes}'[answer yes for all questions]'
+    '*'{-x+,--exclude=}'[exclude specified packages from transaction]: : _sequence _dnf5_packages -T all'
+  )
+  _arguments -C -s : $opts ': :->command' '*:: :->cmd_args' && ret=0
+
+  case $state in
+    command) _dnf5_commands && ret=0 ;;
+    cmd_args) _dnf5_subcmds_opts && ret=0 ;;
+  esac
+  return ret
+}
+
+_dnf5 "$@"

+ 1 - 1
plugins/ember-cli/README.md

@@ -29,5 +29,5 @@ plugins=(... ember-cli)
 
 - [BilalBudhani](https://github.com/BilalBudhani)
 - [eubenesa](https://github.com/eubenesa)
-- [scottkidder](https://github.com/scottkidder]
+- [scottkidder](https://github.com/scottkidder)
 - [t-sauer](https://www.github.com/t-sauer)

+ 23 - 0
plugins/eza/README.md

@@ -65,6 +65,29 @@ If `yes`, sets the `--icons` option of `eza`, adding icons for files and folders
 
 Default: `no`
 
+### `color-scale`
+
+```zsh
+zstyle ':omz:plugins:eza' 'color-scale' all|age|size
+```
+
+Highlight levels of field(s) distinctly. Use comma(,) separated list of `all`, `age`, `size`
+
+Default: `none`
+
+### `color-scale-mode`
+
+```zsh
+zstyle ':omz:plugins:eza' 'color-scale-mode' gradient|fixed
+```
+
+Choose the mode for highlighting:
+
+- `gradient` (default) -- gradient coloring
+- `fixed` -- fixed coloring
+
+Default: `gradient`
+
 ### `size-prefix`
 
 ```zsh

+ 8 - 0
plugins/eza/eza.plugin.zsh

@@ -34,6 +34,14 @@ function _configure_eza() {
   if zstyle -t ':omz:plugins:eza' 'icons'; then
     _EZA_TAIL+=("--icons=auto")
   fi
+  zstyle -s ':omz:plugins:eza' 'color-scale' _val
+  if [[ $_val ]]; then
+    _EZA_TAIL+=("--color-scale=$_val")
+  fi
+  zstyle -s ':omz:plugins:eza' 'color-scale-mode' _val
+  if [[ $_val == (gradient|fixed) ]]; then
+    _EZA_TAIL+=("--color-scale-mode=$_val")
+  fi
   zstyle -s ':omz:plugins:eza' 'time-style' _val
   if [[ $_val ]]; then
     _EZA_TAIL+=("--time-style='$_val'")

+ 35 - 0
plugins/foot/README.md

@@ -0,0 +1,35 @@
+# foot
+
+This plugin adds shell integration for [foot, a fast, lightweight and
+minimalistic Wayland terminal emulator](https://codeberg.org/dnkl/foot).
+
+To use, add `foot` to the list of plugins in your `.zshrc` file:
+
+```zsh
+plugins=(... foot)
+```
+
+## Spawning new terminal instances in the current working directory
+
+When spawning a new terminal instance (with `ctrl+shift+n` by default), the new
+instance will start in the current working directory.
+
+## Jumping between prompts
+
+Foot can move the current viewport to focus prompts of already executed
+commands (bound to ctrl+shift+z/x by default).
+
+## Piping last command's output
+
+The key binding `pipe-command-output` can pipe the last command's output to an
+application of your choice (similar to the other `pipe-*` key bindings):
+
+```
+[key-bindings]
+pipe-command-output=[sh -c "f=$(mktemp); cat - > $f; footclient emacsclient -nw $f; rm $f"] Control+Shift+g
+```
+
+When pressing ctrl+shift+g, the last command's output is written to a
+temporary file, then an emacsclient is started in a new footclient instance.
+The temporary file is removed after the footclient instance has closed.
+

+ 10 - 0
plugins/foot/foot.plugin.zsh

@@ -0,0 +1,10 @@
+function precmd {
+  print -Pn "\e]133;A\e\\"
+  if ! builtin zle; then
+    print -n "\e]133;D\e\\"
+  fi
+}
+
+function preexec {
+  print -n "\e]133;C\e\\"
+}

+ 1 - 1
plugins/git-auto-fetch/README.md

@@ -18,7 +18,7 @@ You can change the fetch interval in your .zshrc:
 GIT_AUTO_FETCH_INTERVAL=1200 # in seconds
 ```
 
-A log of `git fetch --all` will be saved in `.git/FETCH_LOG`.
+A log of `git-fetch-all` will be saved in `.git/FETCH_LOG`.
 
 ## Toggle auto-fetch per folder
 

+ 40 - 0
plugins/gitfast/MANUAL.adoc

@@ -0,0 +1,40 @@
+This project is a friendly fork of the official Git completion
+(`contrib/completion`) and prompt scripts for Bash, Zsh, and possibly other
+shells.
+
+Most Git developers use the Bash shell, for which the completion scripts work
+rather well, however, Zsh is typically neglected. I've sent many patches to fix
+the issues, many have been merged, but many have been ignored, thus the need for
+a canonical location of a good, working Zsh completion.
+
+There are advantages for Bash users too. Currently the scripts under `contrib` are tied to the
+specific Git version, for example the completion scripts of version v2.40
+(https://git.kernel.org/pub/scm/git/git.git/plain/contrib/completion/git-completion.bash?h=v2.40.0[git-completion.bash])
+have issues with older versions of Git (e.g. v2.33); the ones in
+this project don't.
+
+With `git-completion` you can be sure you are using the latest completion that
+works in both shells, and any Git version.
+
+This is a sister project of the
+https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/gitfast[Oh My Zsh
+gitfast] plugin (that I also maintain), which has similar needs.
+
+== Installation ==
+
+* https://github.com/felipec/git-completion/wiki/Bash[Bash instructions]
+* https://github.com/felipec/git-completion/wiki/Zsh[Zsh instructions]
+
+== Improvements from upstream ==
+
+This is a short list of the benefits you get:
+
+* Easier installation
+* Tons of bug fixes
+* Works with older versions of git
+* Zsh: much more options
+* Zsh: quoting works properly
+* Zsh: automatic suffix removal
+
+For a full list of all the patches on top of upstream git check
+https://github.com/felipec/git-completion/wiki/Patches[Patches].

+ 3 - 15
plugins/gitfast/_git

@@ -2,23 +2,11 @@
 
 # zsh completion wrapper for git
 #
-# Copyright (c) 2012-2020 Felipe Contreras <felipe.contreras@gmail.com>
+# Copyright (c) 2012-2024 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.
+# The recommended way to use this script is to prepend its location to 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
+#  fpath=($git_completion_srcdir $fpath)
 #
 
 zstyle -T ':completion:*:*:git:*' tag-order && \

+ 2 - 0
plugins/gitfast/git-completion.bash

@@ -1,6 +1,8 @@
 # bash/zsh completion support for core Git.
 #
 # Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
+# Copyright (c) 2012-2024 Felipe Contreras <felipe.contreras@gmail.com>
+#
 # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
 # Distributed under the GNU General Public License, version 2.0.
 #

+ 1 - 0
plugins/grc/grc.plugin.zsh

@@ -5,6 +5,7 @@ files=(
   /etc/grc.zsh               # default
   /usr/local/etc/grc.zsh     # homebrew darwin-x64
   /opt/homebrew/etc/grc.zsh  # homebrew darwin-arm64
+  /home/linuxbrew/.linuxbrew/etc/grc.zsh # linuxbrew 
   /usr/share/grc/grc.zsh     # Gentoo Linux (app-misc/grc)
 )
 

+ 16 - 0
plugins/jira/README.md

@@ -43,6 +43,22 @@ starting with "_": "MP-1234_fix_dashboard". In both these cases, the issue opene
 This is also checks if the prefix is in the name, and adds it if not, so: "MP-1234" opens the issue "MP-1234",
 "mp-1234" opens the issue "mp-1234", and "1234" opens the issue "MP-1234".
 
+If your branch naming convention deviates, you can overwrite the jira_branch function to determine and echo the Jira issue key yourself.
+Define a function `jira_branch` after sourcing `oh-my-zsh.sh` in your `.zshrc`.
+Example:
+```zsh
+# Determine branch name from naming convention 'type/KEY-123/description'.
+function jira_branch() {
+  # 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 like /some-branch-description
+  issue_arg=${issue_arg%%/*}
+  # Return the value
+  echo $issue_arg
+}
+```
 
 
 #### Debugging usage

+ 25 - 18
plugins/jira/jira.plugin.zsh

@@ -17,6 +17,30 @@ jira branch                     Opens an existing issue matching the current bra
 EOF
 }
 
+# If your branch naming convention deviates, you can partially override this plugin function
+# to determine the jira issue key based on your formatting.
+# See https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#partially-overriding-an-existing-plugin
+function jira_branch() {
+  # 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})
+  # If there is only one part, it means that there is a different delimiter. Try with -
+  if [[ ${#issue_arg[@]} = 1 && ${issue_arg} == *-* ]]; then
+    issue_arg=(${(s:-:)issue_arg})
+    issue_arg="${issue_arg[1]}-${issue_arg[2]}"
+  else
+    issue_arg=${issue_arg[1]}
+  fi
+  if [[ "${issue_arg:l}" = ${jira_prefix:l}* ]]; then
+    echo "${issue_arg}"
+  else
+    echo "${jira_prefix}${issue_arg}"
+  fi
+}
+
 function jira() {
   emulate -L zsh
   local action jira_url jira_prefix
@@ -91,24 +115,7 @@ function jira() {
     # 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})
-      # If there is only one part, it means that there is a different delimiter. Try with -
-      if [[ ${#issue_arg[@]} = 1 && ${issue_arg} == *-* ]]; then
-        issue_arg=(${(s:-:)issue_arg})
-        issue_arg="${issue_arg[1]}-${issue_arg[2]}"
-      else
-        issue_arg=${issue_arg[1]}
-      fi
-      if [[ "${issue_arg:l}" = ${jira_prefix:l}* ]]; then
-        issue="${issue_arg}"
-      else
-        issue="${jira_prefix}${issue_arg}"
-      fi
+      issue=$(jira_branch)
     else
       issue_arg=${(U)action}
       issue="${jira_prefix}${issue_arg}"

+ 7 - 1
plugins/mvn/mvn.plugin.zsh

@@ -101,8 +101,14 @@ function listMavenCompletions {
       new_file="../pom.xml"
     fi
 
-    # if file doesn't exist break
     file="${file:h}/${new_file}"
+
+    # if the file points to a directory, assume it is a pom.xml in that directory
+    if [[ -d "$file" ]]; then
+      file="${file}/pom.xml"
+    fi
+
+    # if file doesn't exist break
     if ! [[ -e "$file" ]]; then
       break
     fi

+ 23 - 17
plugins/perl/README.md

@@ -8,30 +8,36 @@ To use it, add `perl` to the plugins array in your zshrc file:
 plugins=(... perl)
 ```
 
+## Perlbrew activation
+
+If the plugin detects that `perlbrew` hasn't been activated, yet there is an installation of it in
+`$PERLBREW_ROOT`, it'll initialize by default. To avoid this behaviour, set `ZSH_PERLBREW_ACTIVATE=false`
+before `source oh-my-zsh.sh` in your zshrc.
+
 ## 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 |
+| 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.
+- `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>`.
+- `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).
+- `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
+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

+ 9 - 0
plugins/perl/perl.plugin.zsh

@@ -54,3 +54,12 @@ pgs() { # [find] [replace] [filename]
 prep() { # [pattern] [filename unless STDOUT]
     perl -nle 'print if /'"$1"'/;' $2
 }
+
+# If the 'perlbrew' function isn't defined, perlbrew isn't setup.
+if [[ $ZSH_PERLBREW_ACTIVATE != false ]] && (( ! $+functions[perlbrew] )); then
+  local _perlbrew="${PERLBREW_ROOT:-${HOME}/perl5/perlbrew}"
+  if [[ -f "${_perlbrew}/etc/bashrc" ]]; then
+    source "${_perlbrew}/etc/bashrc"
+  fi
+  unset _perlbrew
+fi

+ 37 - 8
plugins/python/README.md

@@ -24,16 +24,45 @@ plugins=(... python)
 The plugin provides three utilities to manage Python 3.3+ [venv](https://docs.python.org/3/library/venv.html)
 virtual environments:
 
-- `mkv [name]`: make a new virtual environment called `name` (default: if set `$PYTHON_VENV_NAME`, else
-  `venv`) in the current directory.
+- `mkv [name]`: make a new virtual environment called `name` in the current directory.
+  **Default**: `$PYTHON_VENV_NAME` if set, otherwise `venv`.
 
-- `vrun [name]`: Activate the virtual environment called `name` (default: if set `$PYTHON_VENV_NAME`, else
-  `venv`) in the current directory.
+- `vrun [name]`: activate the virtual environment called `name` in the current directory.
+  **Default**: the first existing in `$PYTHON_VENV_NAMES`.
 
-- `auto_vrun`: Automatically activate the venv virtual environment when entering a directory containing
+- `auto_vrun`: automatically activate the venv virtual environment when entering a directory containing
   `<venv-name>/bin/activate`, and automatically deactivate it when navigating out of it (keeps venv activated
   in subdirectories).
-  - To enable the feature, set `export PYTHON_AUTO_VRUN=true` before sourcing oh-my-zsh.
-  - Plugin activates first virtual environment in lexicographic order whose name begins with `<venv-name>`.
+  - To enable the feature, set `PYTHON_AUTO_VRUN=true` before sourcing oh-my-zsh.
+  - The plugin activates the first existing virtual environment, in order, appearing in `$PYTON_VENV_NAMES`.
     The default virtual environment name is `venv`. To use a different name, set
-    `export PYTHON_VENV_NAME=<venv-name>`. For example: `export PYTHON_VENV_NAME=".venv"`
+    `PYTHON_VENV_NAME=<venv-name>`. For example: `PYTHON_VENV_NAME=".venv"`
+
+### Settings
+
+You can set these variables in your `.zshrc` file, before Oh My Zsh is sourced.
+For example:
+
+```sh
+PYTHON_VENV_NAME=".venv"
+PYTHON_VENV_NAMES=($PYTHON_VENV_NAME venv)
+...
+plugins=(... python)
+source "$ZSH/oh-my-zsh.sh"
+```
+
+
+## `$PYTHON_VENV_NAME`
+
+**Default**: `venv`.
+
+Preferred name for virtual environments, for example when creating via `mkv`.
+
+## `$PYTHON_VENV_NAMES`
+
+**Default**: `$PYTHON_VENV_NAME venv .venv`.
+
+Array of virtual environment names to be checked, in order, by `vrun` and `auto_vrun`.
+This means these functions will load the first existing virtual environment in this list.
+Duplicate names are ignored.
+

+ 22 - 4
plugins/python/python.plugin.zsh

@@ -47,12 +47,29 @@ alias pygrep='grep -nr --include="*.py"'
 alias pyserver="python3 -m http.server"
 
 
-## venv utilities
+## venv settings
 : ${PYTHON_VENV_NAME:=venv}
 
+# Array of possible virtual environment names to look for, in order
+# -U for removing duplicates
+typeset -gaU PYTHON_VENV_NAMES
+[[ -n "$PYTHON_VENV_NAMES" ]] || PYTHON_VENV_NAMES=($PYTHON_VENV_NAME venv .venv)
+
 # Activate a the python virtual environment specified.
-# If none specified, use $PYTHON_VENV_NAME, else 'venv'.
+# If none specified, use the first existing in $PYTHON_VENV_NAMES.
 function vrun() {
+  if [[ -z "$1" ]]; then
+    local name
+    for name in $PYTHON_VENV_NAMES; do
+      local venvpath="${name:P}"
+      if [[ -d "$venvpath" ]]; then
+        vrun "$name"
+        return $?
+      fi
+    done
+    echo >&2 "Error: no virtual environment found in current directory"
+  fi
+
   local name="${1:-$PYTHON_VENV_NAME}"
   local venvpath="${name:P}"
 
@@ -91,10 +108,11 @@ if [[ "$PYTHON_AUTO_VRUN" == "true" ]]; then
     fi
 
     if [[ $PWD != ${VIRTUAL_ENV:h} ]]; then
-      for _file in "${PYTHON_VENV_NAME}"*/bin/activate(N.); do
+      local file
+      for file in "${^PYTHON_VENV_NAMES[@]}"/bin/activate(N.); do
         # make sure we're not in a venv already
         (( $+functions[deactivate] )) && deactivate > /dev/null 2>&1
-        source $_file > /dev/null 2>&1
+        source $file > /dev/null 2>&1
         break
       done
     fi

+ 1 - 1
plugins/rust/rust.plugin.zsh

@@ -22,5 +22,5 @@ fi
 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
+source "$(rustup run ${${(z)$(rustup default)}[1]} rustc --print sysroot)"/share/zsh/site-functions/_cargo
 EOF

+ 7 - 0
plugins/tailscale/tailscale.plugin.zsh

@@ -15,4 +15,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_tailscale" ]]; then
   fi
 fi
 
+# If using the alias, let's make sure that the aliased executable is also bound
+# in case the alias points to "Tailscale" instead of "tailscale".
+# See https://github.com/ohmyzsh/ohmyzsh/discussions/12928
+if (( $+aliases[tailscale] )); then
+  _comps[${aliases[tailscale]:t}]=_tailscale
+fi
+
 tailscale completion zsh >| "$ZSH_CACHE_DIR/completions/_tailscale" &|

+ 2 - 2
plugins/terraform/terraform.plugin.zsh

@@ -2,9 +2,9 @@ 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
+  [[ -d "${TF_DATA_DIR:-.terraform}" && -r "${TF_DATA_DIR:-.terraform}/environment" ]] || return
 
-  local workspace="$(< .terraform/environment)"
+  local workspace="$(< "${TF_DATA_DIR:-.terraform}/environment")"
   echo "${ZSH_THEME_TF_PROMPT_PREFIX-[}${workspace:gs/%/%%}${ZSH_THEME_TF_PROMPT_SUFFIX-]}"
 }
 

+ 1 - 1
plugins/timer/timer.plugin.zsh

@@ -6,7 +6,7 @@ __timer_current_time() {
 }
 
 __timer_format_duration() {
-  local mins=$(printf '%.0f' $(($1 / 60)))
+  local mins=$(printf '%.0f' $(($(IFS='.' read int dec <<< "$1"; echo $int) / 60)))
   local secs=$(printf "%.${TIMER_PRECISION:-1}f" $(($1 - 60 * mins)))
   local duration_str=$(echo "${mins}m${secs}s")
   local format="${TIMER_FORMAT:-/%d}"

+ 46 - 7
plugins/wd/wd.sh

@@ -8,7 +8,7 @@
 # @github.com/mfaerevaag/wd
 
 # version
-readonly WD_VERSION=0.9.2
+readonly WD_VERSION=0.9.3
 
 # colors
 readonly WD_BLUE="\033[96m"
@@ -256,20 +256,47 @@ wd_remove()
 }
 
 wd_browse() {
+    # Check if fzf is installed
     if ! command -v fzf >/dev/null; then
-        echo "This functionality requires fzf. Please install fzf first."
+        wd_print_msg "$WD_RED" "This functionality requires fzf. Please install fzf first."
         return 1
     fi
+
+    # Ensure wd_config_file is properly set
+    if [[ -z $wd_config_file ]]; then
+        wd_config_file="${WD_CONFIG:-$HOME/.warprc}"
+    fi
+
+    # Check if config file exists
+    if [[ ! -f $wd_config_file ]]; then
+        wd_print_msg "$WD_RED" "Config file $wd_config_file does not exist. Please create it first."
+        return 1
+    fi
+
+    # Read entries from the config file
     local entries=("${(@f)$(sed "s:${HOME}:~:g" "$wd_config_file" | awk -F ':' '{print $1 " -> " $2}')}")
+    if [[ -z $entries ]]; then
+        wd_print_msg "$WD_YELLOW" "You don't have any warp points to browse"
+        return 1
+    fi
+
+    # Temp file for remove operations
     local script_path="${${(%):-%x}:h}"
     local wd_remove_output=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
+
+    # Create fzf bindings
     entries=("All warp points:" "Press enter to select. Press delete to remove" "${entries[@]}")
-    local fzf_bind="delete:execute(echo {} | awk -F ' -> ' '{print \$1}' | xargs -I {} "$script_path/wd.sh" rm {} > "$wd_remove_output")+abort"
+    local fzf_bind="delete:execute(echo {} | awk -F ' -> ' '{print \$1}' | xargs -I {} \"$script_path/wd.sh\" rm {} > \"$wd_remove_output\")+abort"
+
+    # Run fzf
     local selected_entry=$(printf '%s\n' "${entries[@]}" | fzf --height 100% --reverse --header-lines=2 --bind="$fzf_bind")
+
+    # Handle selection
     if [[ -e $wd_remove_output ]]; then
         cat "$wd_remove_output"
-        rm "$wd_remove_output"
+        rm -f "$wd_remove_output"
     fi
+
     if [[ -n $selected_entry ]]; then
         local selected_point="${selected_entry%% ->*}"
         selected_point=$(echo "$selected_point" | xargs)
@@ -278,14 +305,26 @@ wd_browse() {
 }
 
 wd_browse_widget() {
-  if [[ -e $wd_config_file ]]; then
+    # Ensure wd_config_file is properly set
+    if [[ -z $wd_config_file ]]; then
+        wd_config_file="${WD_CONFIG:-$HOME/.warprc}"
+    fi
+
+    # Check if config file exists
+    if [[ ! -f $wd_config_file ]]; then
+        wd_print_msg "$WD_RED" "Config file $wd_config_file does not exist. Please create it first."
+        return 1
+    fi
+
+    # Call wd_browse to handle the selection
     wd_browse
+
+    # Restore the zsh buffer and cursor after running wd_browse
     saved_buffer=$BUFFER
     saved_cursor=$CURSOR
     BUFFER=
     zle redisplay
     zle accept-line
-  fi
 }
 
 wd_restore_buffer() {
@@ -578,7 +617,7 @@ unset wd_print_msg
 unset wd_yesorno
 unset wd_print_usage
 unset wd_alt_config
-unset wd_config_file
+#unset wd_config_file do not unset this - breaks keybind
 unset wd_quiet_mode
 unset wd_print_version
 unset wd_force_mode

+ 1 - 0
plugins/web-search/README.md

@@ -52,6 +52,7 @@ Available search contexts are:
 | `gopkg`               | `https://pkg.go.dev/search?m=package&q=`        |
 | `chatgpt`             | `https://chatgpt.com/?q=`                       |
 | `reddit`              | `https://www.reddit.com/search/?q=`             |
+| `ppai`                | `https://www.perplexity.ai/search/new?q=`       |
 
 Also there are aliases for bang-searching DuckDuckGo:
 

+ 2 - 0
plugins/web-search/web-search.plugin.zsh

@@ -33,6 +33,7 @@ function web_search() {
     gopkg           "https://pkg.go.dev/search?m=package&q="
     chatgpt         "https://chatgpt.com/?q="
     reddit          "https://www.reddit.com/search/?q="
+    ppai            "https://www.perplexity.ai/search/new?q="
   )
 
   # check whether the search engine is supported
@@ -87,6 +88,7 @@ alias packagist='web_search packagist'
 alias gopkg='web_search gopkg'
 alias chatgpt='web_search chatgpt'
 alias reddit='web_search reddit'
+alias ppai='web_search ppai'
 
 #add your own !bang searches here
 alias wiki='web_search duckduckgo \!w'

+ 127 - 31
themes/agnoster.zsh-theme

@@ -35,10 +35,74 @@
 CURRENT_BG='NONE'
 
 case ${SOLARIZED_THEME:-dark} in
-    light) CURRENT_FG='white';;
-    *)     CURRENT_FG='black';;
+    light)
+      CURRENT_FG='white'
+      CURRENT_DEFAULT_FG='white'
+      ;;
+    *)
+      CURRENT_FG='black'
+      CURRENT_DEFAULT_FG='default'
+      ;;
 esac
 
+### Theme Configuration Initialization
+#
+# Override these settings in your ~/.zshrc
+
+# Current working directory
+: ${AGNOSTER_DIR_FG:=${CURRENT_FG}}
+: ${AGNOSTER_DIR_BG:=blue}
+
+# user@host
+: ${AGNOSTER_CONTEXT_FG:=${CURRENT_DEFAULT_FG}}
+: ${AGNOSTER_CONTEXT_BG:=black}
+
+# Git related
+: ${AGNOSTER_GIT_CLEAN_FG:=${CURRENT_FG}}
+: ${AGNOSTER_GIT_CLEAN_BG:=green}
+: ${AGNOSTER_GIT_DIRTY_FG:=black}
+: ${AGNOSTER_GIT_DIRTY_BG:=yellow}
+
+# Bazaar related
+: ${AGNOSTER_BZR_CLEAN_FG:=${CURRENT_FG}}
+: ${AGNOSTER_BZR_CLEAN_BG:=green}
+: ${AGNOSTER_BZR_DIRTY_FG:=black}
+: ${AGNOSTER_BZR_DIRTY_BG:=yellow}
+
+# Mercurial related
+: ${AGNOSTER_HG_NEWFILE_FG:=white}
+: ${AGNOSTER_HG_NEWFILE_BG:=red}
+: ${AGNOSTER_HG_CHANGED_FG:=black}
+: ${AGNOSTER_HG_CHANGED_BG:=yellow}
+: ${AGNOSTER_HG_CLEAN_FG:=${CURRENT_FG}}
+: ${AGNOSTER_HG_CLEAN_BG:=green}
+
+# VirtualEnv colors
+: ${AGNOSTER_VENV_FG:=black}
+: ${AGNOSTER_VENV_BG:=blue}
+
+# AWS Profile colors
+: ${AGNOSTER_AWS_PROD_FG:=yellow}
+: ${AGNOSTER_AWS_PROD_BG:=red}
+: ${AGNOSTER_AWS_FG:=black}
+: ${AGNOSTER_AWS_BG:=green}
+
+# Status symbols
+: ${AGNOSTER_STATUS_RETVAL_FG:=red}
+: ${AGNOSTER_STATUS_ROOT_FG:=yellow}
+: ${AGNOSTER_STATUS_JOB_FG:=cyan}
+: ${AGNOSTER_STATUS_FG:=${CURRENT_DEFAULT_FG}}
+: ${AGNOSTER_STATUS_BG:=black}
+
+## Non-Color settings - set to 'true' to enable
+# Show the actual numeric return value rather than a cross symbol.
+: ${AGNOSTER_STATUS_RETVAL_NUMERIC:=false}
+# Show git working dir in the style "/git/root   master  relative/dir" instead of "/git/root/relative/dir   master"
+: ${AGNOSTER_GIT_INLINE:=false}
+# Show the git branch status in the prompt rather than the generic branch symbol
+: ${AGNOSTER_GIT_BRANCH_STATUS:=true}
+
+
 # Special Powerline characters
 
 () {
@@ -83,16 +147,36 @@ prompt_end() {
   CURRENT_BG=''
 }
 
+git_toplevel() {
+	local repo_root=$(git rev-parse --show-toplevel)
+	if [[ $repo_root = '' ]]; then
+		# We are in a bare repo. Use git dir as root
+		repo_root=$(git rev-parse --git-dir)
+		if [[ $repo_root = '.' ]]; then
+			repo_root=$PWD
+		fi
+	fi
+	echo -n $repo_root
+}
+
 ### 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"
+    prompt_segment "$AGNOSTER_CONTEXT_BG" "$AGNOSTER_CONTEXT_FG" "%(!.%{%F{$AGNOSTER_STATUS_ROOT_FG}%}.)%n@%m"
   fi
 }
 
+prompt_git_relative() {
+  local repo_root=$(git_toplevel)
+  local path_in_repo=$(pwd | sed "s/^$(echo "$repo_root" | sed 's:/:\\/:g;s/\$/\\$/g')//;s:^/::;s:/$::;")
+  if [[ $path_in_repo != '' ]]; then
+    prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" "$path_in_repo"
+  fi;
+}
+
 # Git: branch/detached head, dirty status
 prompt_git() {
   (( $+commands[git] )) || return
@@ -113,20 +197,22 @@ prompt_git() {
     ref="◈ $(command git describe --exact-match --tags HEAD 2> /dev/null)" || \
     ref="➦ $(command git rev-parse --short HEAD 2> /dev/null)"
     if [[ -n $dirty ]]; then
-      prompt_segment yellow black
+      prompt_segment "$AGNOSTER_GIT_DIRTY_BG" "$AGNOSTER_GIT_DIRTY_FG"
     else
-      prompt_segment green $CURRENT_FG
+      prompt_segment "$AGNOSTER_GIT_CLEAN_BG" "$AGNOSTER_GIT_CLEAN_FG"
     fi
 
-    local ahead behind
-    ahead=$(command git log --oneline @{upstream}.. 2>/dev/null)
-    behind=$(command git log --oneline ..@{upstream} 2>/dev/null)
-    if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then
-      PL_BRANCH_CHAR=$'\u21c5'
-    elif [[ -n "$ahead" ]]; then
-      PL_BRANCH_CHAR=$'\u21b1'
-    elif [[ -n "$behind" ]]; then
-      PL_BRANCH_CHAR=$'\u21b0'
+    if [[ $AGNOSTER_GIT_BRANCH_STATUS == 'true' ]]; then
+      local ahead behind
+      ahead=$(command git log --oneline @{upstream}.. 2>/dev/null)
+      behind=$(command git log --oneline ..@{upstream} 2>/dev/null)
+      if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then
+        PL_BRANCH_CHAR=$'\u21c5'
+      elif [[ -n "$ahead" ]]; then
+        PL_BRANCH_CHAR=$'\u21b1'
+      elif [[ -n "$behind" ]]; then
+        PL_BRANCH_CHAR=$'\u21b0'
+      fi
     fi
 
     if [[ -e "${repo_path}/BISECT_LOG" ]]; then
@@ -149,6 +235,7 @@ prompt_git() {
     zstyle ':vcs_info:*' actionformats ' %u%c'
     vcs_info
     echo -n "${${ref:gs/%/%%}/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}"
+    [[ $AGNOSTER_GIT_INLINE == 'true' ]] && prompt_git_relative
   fi
 }
 
@@ -168,12 +255,12 @@ prompt_bzr() {
     status_all=$(echo -n "$bzr_status" | head -n1 | wc -m)
     revision=${$(command bzr log -r-1 --log-format line | cut -d: -f1):gs/%/%%}
     if [[ $status_mod -gt 0 ]] ; then
-      prompt_segment yellow black "bzr@$revision ✚"
+      prompt_segment "$AGNOSTER_BZR_DIRTY_BG" "$AGNOSTER_BZR_DIRTY_FG" "bzr@$revision ✚"
     else
       if [[ $status_all -gt 0 ]] ; then
-        prompt_segment yellow black "bzr@$revision"
+        prompt_segment "$AGNOSTER_BZR_DIRTY_BG" "$AGNOSTER_BZR_DIRTY_FG" "bzr@$revision"
       else
-        prompt_segment green black "bzr@$revision"
+        prompt_segment "$AGNOSTER_BZR_CLEAN_BG" "$AGNOSTER_BZR_CLEAN_FG" "bzr@$revision"
       fi
     fi
   fi
@@ -186,15 +273,15 @@ prompt_hg() {
     if $(command hg prompt >/dev/null 2>&1); then
       if [[ $(command hg prompt "{status|unknown}") = "?" ]]; then
         # if files are not added
-        prompt_segment red white
+        prompt_segment "$AGNOSTER_HG_NEWFILE_BG" "$AGNOSTER_HG_NEWFILE_FG"
         st='±'
       elif [[ -n $(command hg prompt "{status|modified}") ]]; then
         # if any modification
-        prompt_segment yellow black
+        prompt_segment "$AGNOSTER_HG_CHANGED_BG" "$AGNOSTER_HG_CHANGED_FG"
         st='±'
       else
         # if working copy is clean
-        prompt_segment green $CURRENT_FG
+        prompt_segment "$AGNOSTER_HG_CLEAN_BG" "$AGNOSTER_HG_CLEAN_FG"
       fi
       echo -n ${$(command hg prompt "☿ {rev}@{branch}"):gs/%/%%} $st
     else
@@ -202,13 +289,13 @@ prompt_hg() {
       rev=$(command hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
       branch=$(command hg id -b 2>/dev/null)
       if command hg st | command grep -q "^\?"; then
-        prompt_segment red black
+        prompt_segment "$AGNOSTER_HG_NEWFILE_BG" "$AGNOSTER_HG_NEWFILE_FG"
         st='±'
       elif command hg st | command grep -q "^[MA]"; then
-        prompt_segment yellow black
+        prompt_segment "$AGNOSTER_HG_CHANGED_BG" "$AGNOSTER_HG_CHANGED_FG"
         st='±'
       else
-        prompt_segment green $CURRENT_FG
+        prompt_segment "$AGNOSTER_HG_CLEAN_BG" "$AGNOSTER_HG_CLEAN_FG"
       fi
       echo -n "☿ ${rev:gs/%/%%}@${branch:gs/%/%%}" $st
     fi
@@ -217,13 +304,18 @@ prompt_hg() {
 
 # Dir: current working directory
 prompt_dir() {
-  prompt_segment blue $CURRENT_FG '%~'
+  if [[ $AGNOSTER_GIT_INLINE == 'true' ]] && $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
+    # Git repo and inline path enabled, hence only show the git root
+    prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" "$(git_toplevel | sed "s:^$HOME:~:")"
+  else
+    prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" '%~'
+  fi
 }
 
 # Virtualenv: current working virtualenv
 prompt_virtualenv() {
   if [[ -n "$VIRTUAL_ENV" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
-    prompt_segment blue black "(${VIRTUAL_ENV:t:gs/%/%%})"
+    prompt_segment "$AGNOSTER_VENV_BG" "$AGNOSTER_VENV_FG" "(${VIRTUAL_ENV:t:gs/%/%%})"
   fi
 }
 
@@ -234,11 +326,15 @@ prompt_virtualenv() {
 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}%}⚙"
+  if [[ $AGNOSTER_STATUS_RETVAL_NUMERIC == 'true' ]]; then
+    [[ $RETVAL -ne 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_RETVAL_FG}%}$RETVAL"
+  else
+    [[ $RETVAL -ne 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_RETVAL_FG}%}✘"
+  fi
+  [[ $UID -eq 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_ROOT_FG}%}⚡"
+  [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_JOB_FG}%}⚙"
 
-  [[ -n "$symbols" ]] && prompt_segment black default "$symbols"
+  [[ -n "$symbols" ]] && prompt_segment "$AGNOSTER_STATUS_BG" "$AGNOSTER_STATUS_FG" "$symbols"
 }
 
 #AWS Profile:
@@ -249,8 +345,8 @@ prompt_status() {
 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/%/%%}" ;;
+    *-prod|*production*) prompt_segment "$AGNOSTER_AWS_PROD_BG" "$AGNOSTER_AWS_PROD_FG"  "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
+    *) prompt_segment "$AGNOSTER_AWS_BG" "$AGNOSTER_AWS_FG" "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
   esac
 }
 

+ 1 - 1
themes/sonicradish.zsh-theme

@@ -29,7 +29,7 @@ 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_ADDED="%{$FG[103]%}✚%{$reset_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%}"

+ 14 - 1
tools/changelog.sh

@@ -400,6 +400,9 @@ function display-release {
   function display:breaking {
     (( $#breaking != 0 )) || return 0
 
+    # If we reach here we have shown commits, set flag
+    shown_commits=1
+
     case "$output" in
     text) printf '\e[31m'; fmt:header "BREAKING CHANGES" 3 ;;
     raw) fmt:header "BREAKING CHANGES" 3 ;;
@@ -427,6 +430,9 @@ function display-release {
     # If no commits found of type $type, go to next type
     (( $#hashes != 0 )) || return 0
 
+    # If we reach here we have shown commits, set flag
+    shown_commits=1
+
     fmt:header "${TYPES[$type]}" 3
     for hash in $hashes; do
       echo " - $(fmt:hash) $(fmt:scope)$(fmt:subject)"
@@ -444,6 +450,9 @@ function display-release {
     # If no commits found under "other" types, don't display anything
     (( $#changes != 0 )) || return 0
 
+    # If we reach here we have shown commits, set flag
+    shown_commits=1
+
     fmt:header "Other changes" 3
     for hash type in ${(kv)changes}; do
       case "$type" in
@@ -498,7 +507,7 @@ function main {
 
   # Commit classification arrays
   local -A types subjects scopes breaking reverts
-  local truncate=0 read_commits=0
+  local truncate=0 read_commits=0 shown_commits=0
   local version tag
   local hash refs subject body
 
@@ -569,6 +578,10 @@ function main {
     echo " ...more commits omitted"
     echo
   fi
+
+  if (( ! shown_commits )); then
+    echo "No changes to mention."
+  fi
 }
 
 # Use raw output if stdout is not a tty

+ 6 - 1
tools/check_for_upgrade.sh

@@ -27,7 +27,7 @@ zstyle -s ':omz:update' mode update_mode || {
 # - $ZSH is not a git repository
 if [[ "$update_mode" = disabled ]] \
    || [[ ! -w "$ZSH" || ! -O "$ZSH" ]] \
-   || [[ ! -t 1 ]] \
+   || [[ ! -t 1 && ${POWERLEVEL9K_INSTANT_PROMPT:-off} == off ]] \
    || ! command git --version 2>&1 >/dev/null \
    || (builtin cd -q "$ZSH"; ! command git rev-parse --is-inside-work-tree &>/dev/null); then
   unset update_mode
@@ -112,6 +112,11 @@ function update_ohmyzsh() {
   local verbose_mode
   zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
 
+  # Force verbose mode to silent if p10k instant prompt is enabled
+  if [[ ${POWERLEVEL9K_INSTANT_PROMPT:-off} != "off" ]]; then
+    verbose_mode=silent
+  fi
+
   if [[ "$update_mode" != background-alpha ]] \
     && LANG= ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode; then
     update_last_updated_file