diff --git a/.github/dependencies.yml b/.github/dependencies.yml index 603bf7566..02995d6cd 100644 --- a/.github/dependencies.yml +++ b/.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 @@ -36,7 +38,7 @@ dependencies: plugins/z: branch: master repo: agkozak/zsh-z - version: afaf2965b41fdc6ca66066e09382726aa0b6aa04 + version: dd94ef04acc41748ba171eb219971cb455e0040b precopy: | set -e test -e README.md && mv -f README.md MANUAL.md diff --git a/.github/workflows/dependencies/requirements.txt b/.github/workflows/dependencies/requirements.txt index ed0d129b3..d8149743c 100644 --- a/.github/workflows/dependencies/requirements.txt +++ b/.github/workflows/dependencies/requirements.txt @@ -1,7 +1,7 @@ -certifi==2024.8.30 -charset-normalizer==3.4.0 +certifi==2024.12.14 +charset-normalizer==3.4.1 idna==3.10 PyYAML==6.0.2 requests==2.32.3 -semver==3.0.2 -urllib3==2.2.3 +semver==3.0.3 +urllib3==2.3.0 diff --git a/.gitignore b/.gitignore index 10bd4bebc..a53da3b3e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ log/ # editor configs .vscode .idea + +# zcompile cached files +*.zwc diff --git a/README.md b/README.md index 58828cf7f..f7455228a 100644 --- a/README.md +++ b/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 diff --git a/lib/cli.zsh b/lib/cli.zsh index 38a84840c..aed86e758 100644 --- a/lib/cli.zsh +++ b/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 diff --git a/plugins/chucknorris/README.md b/plugins/chucknorris/README.md index 0562b3b59..655e7cf11 100644 --- a/plugins/chucknorris/README.md +++ b/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. diff --git a/plugins/direnv/direnv.plugin.zsh b/plugins/direnv/direnv.plugin.zsh index 0a33194dd..c026dbe76 100644 --- a/plugins/direnv/direnv.plugin.zsh +++ b/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; diff --git a/plugins/eza/README.md b/plugins/eza/README.md index 90e549994..bec1f85cb 100644 --- a/plugins/eza/README.md +++ b/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 diff --git a/plugins/eza/eza.plugin.zsh b/plugins/eza/eza.plugin.zsh index f25f1c30b..60ed1eb27 100644 --- a/plugins/eza/eza.plugin.zsh +++ b/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'") diff --git a/plugins/foot/README.md b/plugins/foot/README.md new file mode 100644 index 000000000..67777d9fa --- /dev/null +++ b/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. + diff --git a/plugins/foot/foot.plugin.zsh b/plugins/foot/foot.plugin.zsh new file mode 100644 index 000000000..c1d077e26 --- /dev/null +++ b/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\\" +} diff --git a/plugins/git-auto-fetch/README.md b/plugins/git-auto-fetch/README.md index e96ab42a3..0d7431bba 100644 --- a/plugins/git-auto-fetch/README.md +++ b/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 diff --git a/plugins/gitfast/MANUAL.adoc b/plugins/gitfast/MANUAL.adoc new file mode 100644 index 000000000..5333f5a2c --- /dev/null +++ b/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]. diff --git a/plugins/gitfast/_git b/plugins/gitfast/_git index 31bf88c1c..1283c713e 100644 --- a/plugins/gitfast/_git +++ b/plugins/gitfast/_git @@ -2,23 +2,11 @@ # zsh completion wrapper for git # -# Copyright (c) 2012-2020 Felipe Contreras +# Copyright (c) 2012-2024 Felipe Contreras # -# 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 && \ diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash index 9a2045f26..8a790ca69 100644 --- a/plugins/gitfast/git-completion.bash +++ b/plugins/gitfast/git-completion.bash @@ -1,6 +1,8 @@ # bash/zsh completion support for core Git. # # Copyright (C) 2006,2007 Shawn O. Pearce +# Copyright (c) 2012-2024 Felipe Contreras +# # Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). # Distributed under the GNU General Public License, version 2.0. # diff --git a/plugins/grc/grc.plugin.zsh b/plugins/grc/grc.plugin.zsh index 55ffc1a1e..fc6ecc8ac 100644 --- a/plugins/grc/grc.plugin.zsh +++ b/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) ) diff --git a/plugins/jira/README.md b/plugins/jira/README.md index 7cfb81b19..19266e7f0 100644 --- a/plugins/jira/README.md +++ b/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 diff --git a/plugins/jira/jira.plugin.zsh b/plugins/jira/jira.plugin.zsh index 9bcf4cc7b..22e0c82c7 100644 --- a/plugins/jira/jira.plugin.zsh +++ b/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}" diff --git a/plugins/per-directory-history/README.md b/plugins/per-directory-history/README.md index 2816c11ba..c7d062a0c 100644 --- a/plugins/per-directory-history/README.md +++ b/plugins/per-directory-history/README.md @@ -35,6 +35,7 @@ toggle set the `PER_DIRECTORY_HISTORY_TOGGLE` environment variable. function above (default `^G`) * `PER_DIRECTORY_HISTORY_PRINT_MODE_CHANGE` is a variable which toggles whether the current mode is printed to the screen following a mode change (default `true`) +* `HISTORY_START_WITH_GLOBAL` is a global variable that defines how to start the plugin: global or local (default `false`) ## History diff --git a/plugins/perl/README.md b/plugins/perl/README.md index dd9b7dc75..a387455c1 100644 --- a/plugins/perl/README.md +++ b/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 ` - Looks for `` and replaces it with `` in ``. +- `pgs`: Perl Global Substitution: `pgs ` Looks for + `` and replaces it with `` in ``. -* `prep`: Perl grep, because 'grep -P' is terrible: `prep []` - Lets you work with pipes or files (if no `` provided, use stdin). +- `prep`: Perl grep, because 'grep -P' is terrible: `prep []` Lets you work with pipes or + files (if no `` 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 diff --git a/plugins/perl/perl.plugin.zsh b/plugins/perl/perl.plugin.zsh index 678e88d97..137fa252a 100644 --- a/plugins/perl/perl.plugin.zsh +++ b/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 diff --git a/plugins/python/README.md b/plugins/python/README.md index 8014992de..490cf88f1 100644 --- a/plugins/python/README.md +++ b/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 `/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 ``. + - 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=`. For example: `export PYTHON_VENV_NAME=".venv"` + `PYTHON_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. + diff --git a/plugins/python/python.plugin.zsh b/plugins/python/python.plugin.zsh index 63733e1de..2b139ddf0 100644 --- a/plugins/python/python.plugin.zsh +++ b/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 diff --git a/plugins/rust/rust.plugin.zsh b/plugins/rust/rust.plugin.zsh index 858f14126..567cebc64 100644 --- a/plugins/rust/rust.plugin.zsh +++ b/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 diff --git a/plugins/tailscale/tailscale.plugin.zsh b/plugins/tailscale/tailscale.plugin.zsh index e0e011196..8b4e1e34d 100644 --- a/plugins/tailscale/tailscale.plugin.zsh +++ b/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" &| diff --git a/plugins/timer/timer.plugin.zsh b/plugins/timer/timer.plugin.zsh index d21d59989..6baf1f681 100644 --- a/plugins/timer/timer.plugin.zsh +++ b/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}" diff --git a/plugins/web-search/README.md b/plugins/web-search/README.md index ad3741fc9..d0b03dff2 100644 --- a/plugins/web-search/README.md +++ b/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: diff --git a/plugins/web-search/web-search.plugin.zsh b/plugins/web-search/web-search.plugin.zsh index b97e33a0b..ff77faed7 100644 --- a/plugins/web-search/web-search.plugin.zsh +++ b/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' diff --git a/plugins/z/LICENSE b/plugins/z/LICENSE index 6af13b9e0..162cba8d1 100644 --- a/plugins/z/LICENSE +++ b/plugins/z/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2023 Alexandros Kozak +Copyright (c) 2018-2024 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 diff --git a/plugins/z/MANUAL.md b/plugins/z/MANUAL.md index 106d8c107..eddf787dd 100644 --- a/plugins/z/MANUAL.md +++ b/plugins/z/MANUAL.md @@ -6,15 +6,15 @@ ![Zsh-z demo](img/demo.gif) -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 command-line tool that allows you to jump quickly to directories that you have visited frequently 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. Based on this data, it predicts where you want to go when you type a partial string. For example, `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 long 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 to 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`. +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. `rupa/z` was 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 is also a significant stability improvement. Race conditions have always been a problem with `rupa/z`, and users of that utility occasionally lose their `~/.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code standard 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. -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)). +There are other, smaller improvements which I document below in [Improvements and Fixes](#improvements-and-fixes). For instance, tab completions are now sorted by frecency by default rather than alphabetically (the latter behavior 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`. +Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same database (`~/.z`, or whatever database file you specify), so you can go on using `rupa/z` when you launch `bash`. ## Table of Contents - [News](#news) @@ -37,13 +37,13 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d - August 24, 2023 + Zsh-z will now run when `setopt NO_UNSET` has been enabled (props @ntninja). - August 23, 2023 - + Better logic for loading `zsh/files` (props @z0rc) + + Better logic for loading `zsh/files` (props @z0rc). - August 2, 2023 - + Zsh-z still uses the `zsh/files` module when possible, but will fall back on the standard `chown`, `mv`, and `rm` commands in its absence. + + Zsh-z still uses the `zsh/files` module when possible but will fall back on the standard `chown`, `mv`, and `rm` commands in its absence. - April 27, 2023 + Zsh-z now allows the user to specify the directory-changing command using the `ZSHZ_CD` environment variable (default: `builtin cd`; props @basnijholt). - January 27, 2023 - + If the datafile directory specified by `ZSHZ_DATA` or `_Z_DATA` does not already exist, create it (props @mattmc3). + + If the database file directory specified by `ZSHZ_DATA` or `_Z_DATA` does not already exist, create it (props @mattmc3). - June 29, 2022 + Zsh-z is less likely to leave temporary files sitting around (props @mafredri). - June 27, 2022 @@ -69,7 +69,7 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d + 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. + + Temporarily disabling the use of `print -v`, which was 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 formatted database entries. @@ -102,7 +102,7 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d - 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. + + Symlinked database files were having their symlinks overwritten; this bug has been fixed. @@ -118,7 +118,7 @@ For tab completion to work, `_zshz` *must* be in the same directory as `zsh-z.pl autoload -U compinit; compinit -in your .zshrc somewhere below where you source `zsh-z.plugin.zsh`. +in your `.zshrc` somewhere below where you source `zsh-z.plugin.zsh`. If you add @@ -188,7 +188,7 @@ Add a backslash to the end of the last line add `'zsh-z'` to the list, e.g., Then relaunch `zsh`. ### For [zcomet](https://github.com/agkozak/zcomet) users - + Simply add zcomet load agkozak/zsh-z @@ -228,7 +228,7 @@ Add the line 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. +Zsh-z supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zsh-z` to restore the shell to its state before Zsh-z was loaded. ### For [Znap](https://github.com/marlonrichert/zsh-snap) users @@ -249,7 +249,7 @@ somewhere above the line that says `zplug load`. Then run zplug install zplug load -to install `zsh-z`. +to install Zsh-z. ## Command Line Options @@ -263,9 +263,9 @@ to install `zsh-z`. - `-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 +## 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_`). +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` (whose environment variables begin with `_Z_`). * `ZSHZ_CMD` changes the command name (default: `z`) * `ZSHZ_CD` specifies the default directory-changing command (default: `builtin cd`) @@ -324,19 +324,18 @@ A good example might involve a directory tree that has Git repositories within i (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 is compatible with 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. +* No error message is displayed when the database file has not yet been created. +* Special characters (e.g., `[`) in directory names are now supported. +* If `z -l` returns only one match, a common root is not printed. +* Exit status codes are more logical. +* Completions now work with options `-c`, `-r`, and `-t`. +* If `~/foo` and `~/foob` are matches, `~/foo` is no longer considered the common root. Only a common parent directory can be a common root. +* `z -x` and the new, recursive `z -xR` can now accept an argument so that you can remove directories other than `PWD` from the database. ## Migrating from Other Tools @@ -358,7 +357,7 @@ the line That will re-bind `z` or the command of your choice to the underlying Zsh-z function. -## Known Bugs +## Known Bug It is possible to run a completion on a string with spaces in it, e.g., `z us bi` 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. diff --git a/plugins/z/z.plugin.zsh b/plugins/z/z.plugin.zsh index a41a4ae25..bf15b01de 100644 --- a/plugins/z/z.plugin.zsh +++ b/plugins/z/z.plugin.zsh @@ -4,7 +4,7 @@ # # https://github.com/agkozak/zsh-z # -# Copyright (c) 2018-2023 Alexandros Kozak +# Copyright (c) 2018-2024 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 @@ -120,7 +120,6 @@ fi [[ ${builtins[zf_mv]-} == 'defined' ]] && ZSHZ[MV]='zf_mv' [[ ${builtins[zf_rm]-} == 'defined' ]] && ZSHZ[RM]='zf_rm' - # Load zsh/system, if necessary [[ ${modules[zsh/system]-} == 'loaded' ]] || zmodload zsh/system &> /dev/null diff --git a/themes/af-magic.zsh-theme b/themes/af-magic.zsh-theme index 70549d01f..668c4e5de 100644 --- a/themes/af-magic.zsh-theme +++ b/themes/af-magic.zsh-theme @@ -13,6 +13,8 @@ function afmagic_dashes { # the prompt, account for it when returning the number of dashes if [[ -n "$python_env" && "$PS1" = *\(${python_env}\)* ]]; then echo $(( COLUMNS - ${#python_env} - 3 )) + elif [[ -n "$VIRTUAL_ENV_PROMPT" && "$PS1" = *${VIRTUAL_ENV_PROMPT}* ]]; then + echo $(( COLUMNS - ${#VIRTUAL_ENV_PROMPT} )) else echo $COLUMNS fi diff --git a/themes/sonicradish.zsh-theme b/themes/sonicradish.zsh-theme index db6170969..11d66a27e 100644 --- a/themes/sonicradish.zsh-theme +++ b/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%}" diff --git a/tools/changelog.sh b/tools/changelog.sh index c4b26079e..ff409115f 100755 --- a/tools/changelog.sh +++ b/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