diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..b883403 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,15 @@ +name: Lint + +on: + pull_request: + branches: [main, master] + push: + branches: [main, master] + tags: ["v*.*.*"] + workflow_dispatch: + +jobs: + commit: + uses: zdharma-continuum/.github/.github/workflows/commit-job.yml@main + lint: + uses: zdharma-continuum/.github/.github/workflows/lint-job.yml@main diff --git a/:za-lb-atclone-handler b/:za-lb-atclone-handler index 94edf67..d576944 100644 --- a/:za-lb-atclone-handler +++ b/:za-lb-atclone-handler @@ -1,119 +1,90 @@ +# +#!/usr/bin/env zsh # Original work Copyright (c) 2019-2020 Sebastian Gniazdowski # Modified work Copyright (c) 2020-2021 Nicholas Serrano -# License MIT - -emulate -RL zsh -setopt extendedglob warncreateglobal typesetsilent noshortloops nullglob - -if [[ "$1" = plugin ]] { - local type="$1" user="$2" plugin="$3" id_as="$4" dir="${5#%}" hook="$6" -} else { - local type="$1" url="$2" id_as="$3" dir="${4#%}" hook="$5" -} - -# -# lbin'' ice – creation of links +# Modified work Copyright (c) 2022 zdharma-continuum and contributors # -if (( ${+ICE[lbin]} )) { - (( ${+ICE[sbin]} )) && { - (( !OPTS[opt_-q,--quiet] )) && \ - +zinit-message "{pre}linkbin annex: {ice}sbin{warn} ice detected, not doing anything...{rst}" - return; - } - local -a lbins srcdst - lbins=( ${(s.;.)ICE[lbin]} ) +emulate -LR zsh +setopt extendedglob warncreateglobal typesetsilent noshortloops - local lbin sym="-P" +if [[ "$1" = plugin ]]; then + local type="$1" user="$2" plugin="$3" id_as="$4" dir="${5#%}" hook="$6" +else + local type="$1" url="$2" id_as="$3" dir="${4#%}" hook="$5" +fi +if (( ${+ICE[lbin]} )); then + if (( ${+ICE[sbin]} )); then + +zi-log "{m} {b}linkbin{rst}: {ice}sbin{rst} ice detected, not doing anything" + return 0 + fi ( - # CD for the globbing through eval + local lbin sym="-P" + local -a lbins srcdst + lbins=(${(s.;.)ICE[lbin]}) builtin cd -q "$dir" || return - - for lbin ( $lbins "" ) { - [[ ${lbin[1]} = "!" ]] && sym="-s" - - if [[ -z $lbin && ${#lbins} -eq 0 ]] || [[ $lbin = "!" && ${#lbins} -eq 1 ]] { + for lbin in $lbins ""; do + [[ ${lbin[1]} = "!" ]] && sym="-s" + if [[ -z $lbin && ${#lbins} -eq 0 ]] || [[ $lbin = "!" && ${#lbins} -eq 1 ]]; then local -a files - integer i=0 - while [[ ! -f $files[1] && $i -lt 9 ]]; do + integer i=0 + while [[ ! -f $files[1] && $i -lt 10 ]]; do ((i++)) case $i in - 1) - files=( $dir/${id_as:t}(Nnon.) ) - ;; - 2) - [[ -n $plugin ]] && files=( $dir/$plugin(Nnon.) ) - ;; - 3) - [[ -n $url ]] && files=( $dir/${url:t}(Nnon.) ) - ;; - 4) - files=( $dir/*(*Nnon.:t) ) - ;; - 5) - files=( $dir/**/${id_as:t} ) - ;; - 6) - [[ -n $plugin ]] && files=( $dir/**/$plugin(Nnon.) ) - ;; - 7) - [[ -n $url ]] && files=( $dir/**/${url:t}(Nnon.) ) - ;; - 8) - files=( $dir/**/*(*Nnon.:t) ) - ;; - 9) - +zinit-message "{pre}linkbin annex: {error}The automatic-empty {ice}lbin{error} ice didn't find any executable files{rst}" - ;; + (1) files=($dir/${id_as:t}(Nnon.)) ;; + (2) [[ -n $plugin ]] && files=($dir/$plugin(Nnon.)) ;; + (3) [[ -n $url ]] && files=($dir/${url:t}(Nnon.)) ;; + (4) files=($dir/*/*(*Nnon.:t)) ;; + (5) files=($dir/**/*(*Nnon.:t)) ;; + (6) files=($dir/**/${id_as:t}(Nnon.)) ;; + (7) [[ -n $plugin ]] && files=($dir/**/$plugin(Nnon.)) ;; + (8) [[ -n $url ]] && files=($dir/**/${url:t}(Nnon.)) ;; + (9) files=($dir/**/*(*Nnon.:t)) ;; + (10) +zi-log "{e} {b}linkbin{rst}: {ice}lbin{rst} ice did not detect any executable files" ;; esac done - [[ $i -gt 8 ]] && break - lbin=$files[1] - } else { - lbin=${lbin#!} + [[ $i -gt 9 ]] && break + lbin=$files[1] + else + lbin=${lbin#!} [[ -z $lbin ]] && continue - } - srcdst=( ${(@s.->.)lbin} ) - srcdst=( "${srcdst[@]//((#s)[[:space:]]##|[[:space:]]##(#e))/}" ) - - # Substitute the standard keywords and param''-s - @zinit-substitute 'srcdst[1]' 'srcdst[2]' - + fi + srcdst=(${(@s.->.)lbin}) + srcdst=("${srcdst[@]//((#s)[[:space:]]##|[[:space:]]##(#e))/}") + @zinit-substitute "srcdst[1]" "srcdst[2]" local -a fnames local fname - eval "fnames=( ${srcdst[1]}(Nnon.) )" - - if (( !${#fnames} )) { - +zinit-message "{pre}linkbin annex: {error}The {ice}lbin{error} ice (\`{glob}$lbin{error}')didn't match any files{rst}" + if [[ $srcdst[1] != /* ]]; then + eval "fnames=(**/${srcdst[1]}(Nnon-.))" + else + eval "fnames=(${srcdst[1]}(Nnon-.))" + fi + if (( !${#fnames} )); then + +zi-log "{e} {b}linkbin{rst}: {ice}lbin{rst} ice ({glob}$lbin{rst}) did not match any files" continue - } - - for fname ( $fnames ) { - srcdst[1]="$fname" - - local target_binary="${${(M)srcdst[1]:#/*}:-$dir/${srcdst[1]}}" \ - fnam="${srcdst[2]:-${srcdst[1]:t}}" - local file="$ZPFX/bin/$fnam" - + fi + for fname in $fnames; do + srcdst[1]="$fname" + local target_binary="${${(M)srcdst[1]:#/*}:-$dir/${srcdst[1]}}" + local fnam="${srcdst[2]:-${srcdst[1]:t}}" + local file="$ZPFX/bin/$fnam" command chmod +x "$target_binary" command ln -f "$sym" "$target_binary" "$file" - if [[ -x $file ]]; then - (( !OPTS[opt_-q,--quiet] )) && \ - if [[ -x $target_binary ]]; then - if [[ $hook == atclone-<-> || $ZINIT[annex-multi-flag:pull-active] -ge 2 ]] { - +zinit-message "{pre}linkbin annex: {msg}${${${hook:#*atclone-<->}:+Re-c}:-C}reated the {obj}$fnam{data2} ${${${sym#-P}:+soft}:-hard}{msg} link and set +x on the {obj}${target_binary:t}{msg} binary{rst}" - } - else - +zinit-message "{pre}linkbin annex: {error}${${${hook:#*atclone-<->}:+Re-c}:-C}reated the {obj}$fnam{data2} ${${${sym#-P}:+soft}:-hard}{error} link however the {obj}${target_binary:t}{error} binary does not exist or failed to set +x on it{rst}" + if [[ -x $target_binary ]]; then + if (( !OPTS[opt_-q,--quiet] )) && [[ $hook == atclone-<-> || $ZINIT[annex-multi-flag:pull-active] -ge 1 ]]; then + +zi-log "{m} {b}linkbin{rst}: ${${${hook:#*atclone-<->}:+Re-c}:-C}reated {file}$fnam{rst} ${${${sym#-P}:+soft}:-hard} link & set +x on the {file}${target_binary:t}{rst} binary" fi + else + +zi-log "{m} {b}linkbin{rst}: ${${${hook:#*atclone-<->}:+Re-c}:-C}reated {file}$fnam{rst} ${${${sym#-P}:+soft}:-hard} link, but {file}${target_binary:t}{rst} binary does not exist or failed to set +x on it" + fi else - +zinit-message "{pre}linkbin annex: {error}Something went wrong creating the {obj}$fnam{error} link{rst}" + +zi-log "{e} {b}linkbin{rst}: Failed to create {file}$fnam{rst} link" fi - } - } + done + done ) -} +fi -# vim:ft=zsh:sw=4:sts=4:et +# vim: set expandtab filetype=zsh shiftwidth=4 softtabstop=4 tabstop=4: diff --git a/:za-lb-atdelete-handler b/:za-lb-atdelete-handler index 76b28e3..bffa20a 100644 --- a/:za-lb-atdelete-handler +++ b/:za-lb-atdelete-handler @@ -1,114 +1,89 @@ +#!/usr/bin/env zsh +# # Original work Copyright (c) 2019-2020 Sebastian Gniazdowski # Modified work Copyright (c) 2020-2021 Nicholas Serrano -# License MIT - -emulate -RL zsh -setopt extendedglob warncreateglobal typesetsilent noshortloops nullglob +# Modified work Copyright (c) 2022 zdharma-continuum and contributors -if [[ "$1" = plugin ]] { - local type="$1" user="$2" plugin="$3" id_as="$4" dir="${5#%}" hook="$6" -} else { - local type="$1" url="$2" id_as="$3" dir="${4#%}" hook="$5" -} +emulate -LR zsh +setopt extendedglob warncreateglobal typesetsilent noshortloops -# -# lbin'' ice – creation of links -# +if [[ "$1" = plugin ]]; then + local type="$1" user="$2" plugin="$3" id_as="$4" dir="${5#%}" hook="$6" +else + local type="$1" url="$2" id_as="$3" dir="${4#%}" hook="$5" +fi -if (( ${+ICE[lbin]} )) { - (( ${+ICE[sbin]} )) && { - (( !OPTS[opt_-q,--quiet] )) && \ - +zinit-message "{pre}linkbin annex: {ice}sbin{warn} ice detected, not doing anything...{rst}" - return; - } +if (( ${+ICE[lbin]} )); then + # if (( ${+ICE[sbin]} || ${+ZINIT_ICE[sbin]} )); then + # +zi-log "{m} {b}linkbin{rst}: {ice}sbin{rst} ice detected, not doing anything" + # return + # fi + if (( ${+ICE[sbin]} )); then + +zi-log "{m} {b}linkbin{rst}: {ice}sbin{rst} ice detected, not doing anything" + return 0 + fi local -a lbins srcdst - lbins=( ${(s.;.)ICE2[lbin]} ) - - local lbin sym="-P" - + lbins=(${(s.;.)ICE2[lbin]}) + local lbin sym="-P" ( - # CD for the globbing through eval builtin cd -q "$dir" || return - - for lbin ( $lbins "" ) { - [[ ${lbin[1]} = "!" ]] && sym="-s" - - if [[ -z $lbin && ${#lbins} -eq 0 ]] || [[ $lbin = "!" && ${#lbins} -eq 1 ]] { + for lbin in $lbins ""; do + [[ ${lbin[1]} = "!" ]] && sym="-s" + if [[ -z $lbin && ${#lbins} -eq 0 ]] || [[ $lbin = "!" && ${#lbins} -eq 1 ]]; then local -a files - integer i=0 - while [[ ! -f $files[1] && $i -lt 9 ]]; do + integer i=0 + while [[ ! -f $files[1] && $i -lt 10 ]]; do ((i++)) case $i in - 1) - files=( $dir/${id_as:t}(Nnon.) ) - ;; - 2) - [[ -n $plugin ]] && files=( $dir/$plugin(Nnon.) ) - ;; - 3) - [[ -n $url ]] && files=( $dir/${url:t}(Nnon.) ) - ;; - 4) - files=( $dir/*(*Nnon.:t) ) - ;; - 5) - files=( $dir/**/${id_as:t} ) - ;; - 6) - [[ -n $plugin ]] && files=( $dir/**/$plugin(Nnon.) ) - ;; - 7) - [[ -n $url ]] && files=( $dir/**/${url:t}(Nnon.) ) - ;; - 8) - files=( $dir/**/*(*Nnon.:t) ) - ;; - 9) - +zinit-message "{pre}linkbin annex: {error}The automatic-empty {ice}lbin{error} ice didn't find any executable files{rst}" - ;; + (1) files=($dir/${id_as:t}(Nnon.)) ;; + (2) [[ -n $plugin ]] && files=($dir/$plugin(Nnon.)) ;; + (3) [[ -n $url ]] && files=($dir/${url:t}(Nnon.)) ;; + (4) files=($dir/*/*(*Nnon.:t)) ;; + (5) files=($dir/**/*(*Nnon.:t)) ;; + (6) files=($dir/**/${id_as:t}(Nnon.)) ;; + (7) [[ -n $plugin ]] && files=($dir/**/$plugin(Nnon.)) ;; + (8) [[ -n $url ]] && files=($dir/**/${url:t}(Nnon.)) ;; + (9) files=($dir/**/*(*Nnon.:t)) ;; + (10) +zi-log "{e} {b}linkbin{rst}: {ice}lbin{rst} ice did not detect any executable files" ;; esac done - [[ $i -gt 8 ]] && break - lbin=$files[1] - } else { - lbin=${lbin#!} + [[ $i -gt 9 ]] && break + lbin=$files[1] + else + lbin=${lbin#!} [[ -z $lbin ]] && continue - } - srcdst=( ${(@s.->.)lbin} ) - srcdst=( "${srcdst[@]//((#s)[[:space:]]##|[[:space:]]##(#e))/}" ) - - # Substitute the standard keywords and param''-s - @zinit-substitute 'srcdst[1]' 'srcdst[2]' - + fi + srcdst=(${(@s.->.)lbin}) + srcdst=("${srcdst[@]//((#s)[[:space:]]##|[[:space:]]##(#e))/}") + @zinit-substitute "srcdst[1]" "srcdst[2]" local -a fnames local fname - eval "fnames=( ${srcdst[1]}(Nnon.) )" - - if (( !${#fnames} )) { - +zinit-message "{pre}linkbin annex: {error}The {ice}lbin{error} ice (\`{glob}$lbin{error}')didn't match any files{rst}" + if [[ ${srcdst[1]} != /* ]]; then + eval "fnames=(**/${srcdst[1]}(Nnon-.))" + else + eval "fnames=(${srcdst[1]}(Nnon-.))" + fi + if (( !${#fnames} )); then + +zi-log "{e} {b}linkbin{rst}: The {ice}lbin{rst} ice ({glob}$lbin{rst}) did not match any files" continue - } - - for fname ( $fnames ) { - srcdst[1]="$fname" - - local fnam="${srcdst[2]:-${srcdst[1]:t}}" - local file="$ZPFX/bin/$fnam" - - if [[ -f $file ]] { + fi + for fname in $fnames; do + srcdst[1]="$fname" + local fnam="${srcdst[2]:-${srcdst[1]:t}}" + local file="$ZPFX/bin/$fnam" + if [[ -f $file ]]; then command rm "$file" if ! [[ -f $file ]]; then - (( !OPTS[opt_-q,--quiet] )) && \ - +zinit-message "{pre}linkbin annex: {msg}Removed {obj}$fnam{data2} ${${${sym#-P}:+soft}:-hard}{msg} link{rst}" + (( !OPTS[opt_-q,--quiet] )) && +zi-log "{m} {b}linkbin{rst}: Deleted {file}$fnam{rst} ${${${sym#-P}:+soft}:-hard} link" else - +zinit-message "{pre}linkbin annex: {error}Something went wrong deleting the {obj}$fnam{error} link{rst}" + +zi-log "{e} {b}linkbin{rst}: Failed to delete {file}$fnam{rst} link" fi - } else { - +zinit-message "{pre}linkbin annex: {error}The {obj}$fnam{data2} ${${${sym#-P}:+soft}:-hard}{error} link didn't exist in \$ZPFX/bin (or isn't a regular file){rst}" - } - } - } + else + +zi-log "{w} {b}linkbin{rst}: {file}$fnam{rst} ${${${sym#-P}:+soft}:-hard} link not found in \$ZPFX/bin" + fi + done + done ) -} +fi -# vim:ft=zsh:sw=4:sts=4:et +# vim: set expandtab filetype=zsh shiftwidth=4 softtabstop=4 tabstop=4: diff --git a/README.md b/README.md index 750084f..e288f1d 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,47 @@ - - -**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* +# zinit-annex-binary-symlink -- [z-a-linkbin](#z-a-linkbin) - - [Introduction](#introduction) - - [Installation](#installation) - - [How it works](#how-it-works) - - [The Ice Modifiers Provided By The Annex](#the-ice-modifiers-provided-by-the-annex) - - [1. **`lbin'[!]{path-to-binary}[ -> {name-of-the-script}]; …'`**](#1-lbinpath-to-binary---name-of-the-script-) + - +- [Installation](#installation) +- [How it works](#how-it-works) +- [The Ice Modifiers Provided By The Annex](#the-ice-modifiers-provided-by-the-annex) + - [`lbin'[!]{path-to-binary}[ -> {name-of-the-script}]'`](#lbinpath-to-binary---name-of-the-script) -# z-a-linkbin + -## Introduction +A Zsh-Zinit annex (i.e. an extension) that provides functionality, which allows to: -A Zsh-Zinit annex (i.e. an extension) that provides functionality, which -allows to: +1. Run programs and scripts without adding anything to `$PATH` via the automatic creation of **links** in `$ZPFX/bin` - 1. Run programs and scripts without adding anything to `$PATH` via - the automatic creation of **links** in `$ZPFX/bin` - -## Installation +## Installation Simply load like a regular plugin, i.e.: ```zsh -zinit light NICHOLAS85/z-a-linkbin +zinit light zdharma-continuum/zinit-annex-binary-symlink ``` -After executing this command you can then use the new ice-mods provided by -the annex. +After executing this command you can then use the new ice-mods provided by the annex. -## How it works +## How it works -Exposing a binary program without modifying `$PATH` – `z-a-linkbin` will -automatically create a hard or soft link to the binary in `$ZPFX/bin` -exposing the program to the command line as if it were being placed in `$PATH`. +Exposing a binary program without modifying `$PATH` – `zinit-annex-binary-symlink` will automatically create a hard or +soft link to the binary in `$ZPFX/bin` exposing the program to the command line as if it were being placed in `$PATH`. -The command can then be accessed normally – not only in the live -Zsh session, but also from any Zsh script. +The command can then be accessed normally – not only in the live Zsh session, but also from any Zsh script. -## The Ice Modifiers Provided By The Annex +## The Ice Modifiers Provided By The Annex There is 1 ice-modifier provided and handled by this annex. They are: - 1. `lbin''` – creates `links` for binaries and scripts. -**The ice-modifier in detail:** +1. `lbin''` – creates `links` for binaries and scripts. ---- +**The ice-modifier in detail:** -## 1. **`lbin'[!]{path-to-binary}[ -> {name-of-the-script}]; …'`** +### `lbin'[!]{path-to-binary}[ -> {name-of-the-script}]'` -It creates the `link` that calls the actual binary. The link is -created always under the same, standard and single `$PATH` entry: -`$ZPFX/bin` (which is `~/.zinit/polaris/bin` by default). +It creates the `link` that calls the actual binary. The link is created always under the same, standard and single +`$PATH` entry: `$ZPFX/bin` (which is `~/.zinit/polaris/bin` by default). The optional preceding `!` flag means create a soft link instead of a hard link. @@ -69,6 +56,7 @@ fzf -> /home/sg/.zinit/plugins/junegunn---fzf-bin/fzf % fzf --version 0.23.1 (fc7630a) ``` + **The ice can contain globs**. It will expand these when searching for the binary. Example: @@ -85,13 +73,11 @@ myfzf **The ice can be empty**. It will then try to create the link for: -- trailing component of the `id_as` ice, e.g.: `id_as'exts/git-my'` → it'll - check if a file `git-my` exists and if yes, create the link `git-my`, -- the plugin name, e.g.: for `paulirish/git-open` it'll check if a file - `git-open` exists and if yes, create the link `git-open`, +- trailing component of the `id_as` ice, e.g.: `id_as'exts/git-my'` → it'll check if a file `git-my` exists and if yes, + create the link `git-my`, +- the plugin name, e.g.: for `paulirish/git-open` it'll check if a file `git-open` exists and if yes, create the link + `git-open`, - trailing component of the snippet URL, - for any alphabetically first executable file. -Above also applies if just `!` were passed. - - +> **Note**: The above also applies if only `!` is passed. diff --git a/z-a-binary-symlink.plugin.zsh b/z-a-binary-symlink.plugin.zsh new file mode 100644 index 0000000..e971104 --- /dev/null +++ b/z-a-binary-symlink.plugin.zsh @@ -0,0 +1,36 @@ +#!/usr/bin/env zsh +# -*- mode: sh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# +# Original work Copyright (c) 2019-2020 Sebastian Gniazdowski +# Modified work Copyright (c) 2020-2021 Nicholas Serrano +# Modified work Copyright (c) 2022 zdharma-continuum and contributors + +# According to the Zsh Plugin Standard: +# http://zdharma.org/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html + +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" + +[[ -d $ZPFX/bin ]] || command mkdir -p "$ZPFX/bin" + +autoload :za-lb-atclone-handler :za-lb-atdelete-handler + +# An empty stub to fill the help handler fields +:za-lb-null-handler() { :; } + +@zinit-register-annex "z-a-linkbin" \ + hook:atclone-50 \ + :za-lb-atclone-handler \ + :za-lb-null-handler \ + "lbin|lbin''" # also register new ices + +@zinit-register-annex "z-a-linkbin" \ + hook:\%atpull-50 \ + :za-lb-atclone-handler \ + :za-lb-null-handler + +@zinit-register-annex "z-a-linkbin" \ + hook:atdelete-50 \ + :za-lb-atdelete-handler \ + :za-lb-null-handler + diff --git a/z-a-linkbin.plugin.zsh b/z-a-linkbin.plugin.zsh deleted file mode 100644 index 45b18cf..0000000 --- a/z-a-linkbin.plugin.zsh +++ /dev/null @@ -1,37 +0,0 @@ -# Original work Copyright (c) 2019-2020 Sebastian Gniazdowski -# Modified work Copyright (c) 2020 Nicholas Serrano -# License MIT - -# According to the Zsh Plugin Standard: -# http://zdharma.org/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html - -0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" -0="${${(M)0:#/*}:-$PWD/$0}" - -autoload :za-lb-atclone-handler :za-lb-atdelete-handler - -# An empty stub to fill the help handler fields -:za-lb-null-handler() { :; } - -#@zinit-register-annex "z-a-linkbin" \ -# subcommand:link-list \ -# :za-lb-list \ -# :za-lb-help-handler - - -@zinit-register-annex "z-a-linkbin" \ - hook:atclone-50 \ - :za-lb-atclone-handler \ - :za-lb-null-handler \ - "lbin|lbin''" # also register new ices - -@zinit-register-annex "z-a-linkbin" \ - hook:\%atpull-50 \ - :za-lb-atclone-handler \ - :za-lb-null-handler - -@zinit-register-annex "z-a-linkbin" \ - hook:atdelete-50 \ - :za-lb-atdelete-handler \ - :za-lb-null-handler -