Compare commits

...

9 Commits

Author SHA1 Message Date
Marc Cornellà 85c4941492
fix(cli)!: remove harmful `--unattended` flag for `omz update` (#12935)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2025-01-23 21:06:00 +01:00
shun095 d2e79501b2
fix(timer): minutes calculation logic (#12857) 2025-01-23 21:04:45 +01:00
fossdd 69410e7020
feat(foot): add foot plugin (#12849) 2025-01-23 20:43:27 +01:00
Marc Cornellà 4e29c670a4
fix(changelog): show if there are no changes (#12934) 2025-01-23 20:38:12 +01:00
Thomas Boyer 1bae199736
fix(direnv): warn user if command not found (#12840)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2025-01-23 20:37:00 +01:00
Keith Bennett bd0a5b2598
docs(chucknorris): add useful note (#12822) 2025-01-23 20:28:44 +01:00
jamesrtnz 9a0e22c184
feat(perl): add `perlbrew` auto activation (#12814)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2025-01-23 20:24:43 +01:00
Marc Cornellà 501f29f90c
fix(tailscale): fix completion binding for alias to `Tailscale` (#12928)
Fixes #12928
2025-01-23 20:14:47 +01:00
Marc Cornellà cca4043238
feat(python): support multiple venvs via `$PYTHON_VENV_NAMES` (#12932) 2025-01-23 19:54:50 +01:00
13 changed files with 190 additions and 39 deletions

View File

@ -487,6 +487,17 @@ wait a week?) you just need to run:
omz update 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! 🎉 Magic! 🎉
## Uninstalling Oh My Zsh ## Uninstalling Oh My Zsh

View File

@ -823,6 +823,13 @@ function _omz::update {
return 1 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) local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)
[[ $? -eq 0 ]] || { [[ $? -eq 0 ]] || {
_omz::log error "\`$ZSH\` is not a git directory. Aborting..." _omz::log error "\`$ZSH\` is not a git directory. Aborting..."
@ -831,11 +838,7 @@ function _omz::update {
# Run update script # Run update script
zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default 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 $?
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
# Update last updated file # Update last updated file
zmodload zsh/datetime zmodload zsh/datetime
@ -844,7 +847,7 @@ function _omz::update {
command rm -rf "$ZSH/log/update.lock" command rm -rf "$ZSH/log/update.lock"
# Restart the zsh session if there were changes # 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 # Old zsh versions don't have ZSH_ARGZERO
local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}" local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}"
# Check whether to run a login shell # Check whether to run a login shell

View File

@ -36,3 +36,10 @@ Last login: Fri Jan 30 23:12:26 on ttys001
- `cowsay` if using `chuck_cow` - `cowsay` if using `chuck_cow`
Available via homebrew, apt, ... 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.

View File

@ -1,5 +1,8 @@
# Don't continue if direnv is not found # If direnv is not found, don't continue and print a warning
command -v direnv &>/dev/null || return 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() { _direnv_hook() {
trap -- '' SIGINT; trap -- '' SIGINT;

35
plugins/foot/README.md Normal file
View File

@ -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.

View File

@ -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\\"
}

View File

@ -8,30 +8,36 @@ To use it, add `perl` to the plugins array in your zshrc file:
plugins=(... perl) 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
| Aliases | Command | Description | | Aliases | Command | Description |
| :------------ | :----------------- | :------------------------------------- | | :---------- | :----------------- | :------------------------------------- |
| pbi | `perlbrew install` | Install specific perl version | | pbi | `perlbrew install` | Install specific perl version |
| pbl | `perlbrew list` | List all perl version installed | | pbl | `perlbrew list` | List all perl version installed |
| pbo | `perlbrew off` | Go back to the system perl | | pbo | `perlbrew off` | Go back to the system perl |
| pbs | `perlbrew switch` | Turn it back on | | pbs | `perlbrew switch` | Turn it back on |
| pbu | `perlbrew use` | Use specific version of perl | | pbu | `perlbrew use` | Use specific version of perl |
| pd | `perldoc` | Show the perl documentation | | pd | `perldoc` | Show the perl documentation |
| ple | `perl -wlne` | Use perl like awk/sed | | ple | `perl -wlne` | Use perl like awk/sed |
| latest-perl | `curl ...` | Show the latest stable release of Perl | | latest-perl | `curl ...` | Show the latest stable release of Perl |
## Functions ## 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>` - `pgs`: Perl Global Substitution: `pgs <find_pattern> <replace_pattern> <filename>` Looks for
Looks for `<find_pattern>` and replaces it with `<replace_pattern>` in `<filename>`. `<find_pattern>` and replaces it with `<replace_pattern>` in `<filename>`.
* `prep`: Perl grep, because 'grep -P' is terrible: `prep <pattern> [<filename>]` - `prep`: Perl grep, because 'grep -P' is terrible: `prep <pattern> [<filename>]` Lets you work with pipes or
Lets you work with pipes or files (if no `<filename>` provided, use stdin). files (if no `<filename>` provided, use stdin).
## Requirements ## Requirements
In order to make this work, you will need to have perl installed. In order to make this work, you will need to have perl installed. More info on the usage and install:
More info on the usage and install: https://www.perl.org/get.html https://www.perl.org/get.html

View File

@ -54,3 +54,12 @@ pgs() { # [find] [replace] [filename]
prep() { # [pattern] [filename unless STDOUT] prep() { # [pattern] [filename unless STDOUT]
perl -nle 'print if /'"$1"'/;' $2 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

View File

@ -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) The plugin provides three utilities to manage Python 3.3+ [venv](https://docs.python.org/3/library/venv.html)
virtual environments: virtual environments:
- `mkv [name]`: make a new virtual environment called `name` (default: if set `$PYTHON_VENV_NAME`, else - `mkv [name]`: make a new virtual environment called `name` in the current directory.
`venv`) 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 - `vrun [name]`: activate the virtual environment called `name` in the current directory.
`venv`) 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 `<venv-name>/bin/activate`, and automatically deactivate it when navigating out of it (keeps venv activated
in subdirectories). in subdirectories).
- To enable the feature, set `export PYTHON_AUTO_VRUN=true` before sourcing oh-my-zsh. - To enable the feature, set `PYTHON_AUTO_VRUN=true` before sourcing oh-my-zsh.
- Plugin activates first virtual environment in lexicographic order whose name begins with `<venv-name>`. - 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 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.

View File

@ -47,12 +47,29 @@ alias pygrep='grep -nr --include="*.py"'
alias pyserver="python3 -m http.server" alias pyserver="python3 -m http.server"
## venv utilities ## venv settings
: ${PYTHON_VENV_NAME:=venv} : ${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. # 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() { 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 name="${1:-$PYTHON_VENV_NAME}"
local venvpath="${name:P}" local venvpath="${name:P}"
@ -91,10 +108,11 @@ if [[ "$PYTHON_AUTO_VRUN" == "true" ]]; then
fi fi
if [[ $PWD != ${VIRTUAL_ENV:h} ]]; then 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 # make sure we're not in a venv already
(( $+functions[deactivate] )) && deactivate > /dev/null 2>&1 (( $+functions[deactivate] )) && deactivate > /dev/null 2>&1
source $_file > /dev/null 2>&1 source $file > /dev/null 2>&1
break break
done done
fi fi

View File

@ -15,4 +15,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_tailscale" ]]; then
fi fi
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" &| tailscale completion zsh >| "$ZSH_CACHE_DIR/completions/_tailscale" &|

View File

@ -6,7 +6,7 @@ __timer_current_time() {
} }
__timer_format_duration() { __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 secs=$(printf "%.${TIMER_PRECISION:-1}f" $(($1 - 60 * mins)))
local duration_str=$(echo "${mins}m${secs}s") local duration_str=$(echo "${mins}m${secs}s")
local format="${TIMER_FORMAT:-/%d}" local format="${TIMER_FORMAT:-/%d}"

View File

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