diff --git a/.gitignore b/.gitignore index 5b4da2c7..ea480374 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,26 @@ -.DS_Store -**/.DS_Store -.ignore +# zplug bin/* !bin/zplug-env +repos/* +.cache +.gitignore.d/* + +# zsh zcompdump **/zcompdump +zcompdump.zwc **/zcompdump.zwc -**/*~ -**/*.swp -.cache -repos + +# a2x (man page) *.xml **/*.xml + +# vim +*~ +**/*~ +*.swp +**/*.swp + +# OS X +.DS_Store +**/.DS_Store diff --git a/.travis.yml b/.travis.yml index b08f9b40..ae502797 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ sudo: false before_script: - zsh --version script: -- make test +- TEST_TARGET=test/all.t make test notifications: slack: secure: t60Xlx634DaOWN1VRaIFPfXTAUb5188pR1IFrvIoYWqBMY0vP8AihxQP80fwnaOQGaIcbjDLjlU6CV8R2J/uXw4QKOsF0VF93X1NdNyuu3wRC/Kqe/FERYTwhMy2/b9Sf2fWe5eEE4fcpnX2GtJnDzzGoesLe5GvRL+mqJLN+sgAnszQp9++aybktZ0lkpaEMYWu0V96sZOdKqsxxOF4wpMt4Z3hBPi0mA3OgwxIh+0sg55czIcMl7ZLtAtm4fCSDHKojQvbaBUSfsRR6LjTb6a5b6hQBtL9n5xRzHN3J82T5noPLlj2zg+EWlLIwD5pGdkSpPAfQUb+/pNHALGijEXXDfosPGOJWI4EU1EhC1/H7zzkOPcPzEX6X+s3vx8ruObg3vvVsOYU3hqNcxz63zgw0NDLVVVnOV4+VusIDI5rxKUaVtFBH7nJf5cLu9+AF6RjVgZyuozlHvsecinl3YdyenD3saYkqRMJn3mQaWND1c2PnZWtNoclJbRwcilf3OFkl+LGskq39HluYZ8VTVE95FkfuGtN9P1v/C7XPSD1/VPKY+3hWbMpfKFQpNgy2D67mVuuiRtHAszTw80qq0IPEcdX1nYtJrzNclUb9FTXpy6etUHyQbkND8B9brw580sYgdJfavgaaKLF7usZrUlOcayzMd6j6eEPmN7b1QY= diff --git a/Makefile b/Makefile index 4adef441..ba9487ea 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,26 @@ ZPLUG_ROOT := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) -ZSPEC := $(ZPLUG_ROOT)/bin/zspec -ZSPEC_URL := https://raw.githubusercontent.com/b4b4r07/zspec/master/bin/zspec -MANPAGE := $(ZPLUG_ROOT)/doc/man/man1/zplug.1 -MANPATH := /usr/local/share/man/man1 -LICENSE_URL := http://b4b4r07.mit-license.org -LICENSE_TXT := $(ZPLUG_ROOT)/doc/LICENSE-MIT.txt +SHOVE_URL := https://github.com/key-amb/shove +SHOVE_DIR := $(ZPLUG_ROOT)/.gitignore.d/shove +TEST_TARGET ?= test -SKIP_FILES := __clone__ __releases__ __install__ __update__ __load__ -TEST_FILES := $(shell find $(ZPLUG_ROOT)/test -name *_test.zsh | sort) -SKIP_TESTS := $(foreach f, $(SKIP_FILES), $(shell find $(ZPLUG_ROOT)/test -name $(f)_test.zsh)) -MINI_TESTS := $(filter-out $(SKIP_TESTS), $(TEST_FILES)) +.DEFAULT_GOAL := help -.PHONY: all install man zspec minitest test license +.PHONY: all install shove test license help all: -install: man license - @cat $(LICENSE_TXT) +install: ## Install zplug to your machine -man: - @test -f $(MANPATH)/zplug.1 || cp -v -f $(MANPAGE) $(MANPATH) +shove: # Grab shove from GitHub and grant execution + @if [ ! -d $(SHOVE_DIR) ]; then \ + git clone $(SHOVE_URL) $(SHOVE_DIR); \ + chmod 755 $(SHOVE_DIR)/bin/shove; \ + fi -zspec: - @test -f $(ZSPEC) || curl -L $(ZSPEC_URL) -o $(ZSPEC) - @test -x $(ZSPEC) || chmod 755 $(ZSPEC) +test: shove ## Unit test for zplug + ZPLUG_ROOT=$(ZPLUG_ROOT) $(SHOVE_DIR)/bin/shove -r $(TEST_TARGET) -s zsh -minitest: zspec - @ZPLUG_ROOT=$(ZPLUG_ROOT) $(ZSPEC) $(MINI_TESTS) - -test: zspec - @ZPLUG_ROOT=$(ZPLUG_ROOT) $(ZSPEC) $(TEST_FILES) - -license: - @curl -fsSL -o $(LICENSE_TXT) $(LICENSE_URL) +help: ## Self-documented Makefile + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ + | sort \ + | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/README.md b/README.md index 18f66ef3..16871e8b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +:us: [:jp:](./doc/guide/README.ja.md) + > Zsh Plugin Manager [![Travis][travis-badge]][travis-link] @@ -62,9 +64,9 @@ $ git clone https://github.com/zplug/zplug $ZPLUG_HOME ## Requirements -- `zsh` version 4.3.9 or higher -- `git` version 1.7 or higher -- `awk` An AWK variant that's **not** `mawk` +- `zsh`: version 4.3.9 or higher +- `git`: version 1.7 or higher +- `awk`: An AWK variant that's **not** `mawk` ## Usage @@ -172,10 +174,10 @@ Finally, use `zplug install` to install your plugins and reload `.zshrc`. | Command | Description | Options | |-----------|-------------|---------| -| `install` | Install packages in parallel | `--verbose`,`--select` | +| `install` | Install packages in parallel | (None) | | `load` | Source installed plugins and add installed commands to `$PATH` | `--verbose` | | `list` | List installed packages (more specifically, view the associative array `$zplugs`) | `--select` | -| `update` | Update installed packages in parallel | `--self`,`--select` | +| `update` | Update installed packages in parallel | `--self`,`--select`,`--force` | | `check` | Return true if all packages are installed, false otherwise | `--verbose` | | `status` | Check if the remote repositories are up to date | `--select` | | `clean` | Remove repositories which are no longer managed | `--force`,`--select` | @@ -333,6 +335,7 @@ Defaults to `$ZPLUG_HOME/.cache`. You can change where the cache file is saved, Defaults to `$ZPLUG_HOME/repos`. You can change where the repositories are cloned in case you want to manage them separately. ### External commands + zplug, like `git(1)`, supports external commands. These are executable scripts that reside somewhere in the PATH, named `zplug-cmdname`, which can be invoked with `zplug cmdname`. diff --git a/autoload/autoload.zsh b/autoload/autoload.zsh deleted file mode 100644 index 8874e575..00000000 --- a/autoload/autoload.zsh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "job/polling" - -local cmd -local -a autoload_dirs autoload_files - -__zplug::core::core::get_autoload_dirs; autoload_dirs=( "${reply[@]}" ) -__zplug::core::core::get_autoload_files; autoload_files=( "${reply[@]}" ) - -if (( $+functions[${autoload_files[$(($RANDOM % $#autoload_files + 1))]}] )); then - return 0 -fi - -fpath=( -"${autoload_dirs[@]}" -$fpath -) - -for cmd in "${autoload_files[@]}" -do - autoload -Uz "$cmd" -done diff --git a/autoload/commands/__check__ b/autoload/commands/__check__ index 582d0bd0..b8d55f9e 100644 --- a/autoload/commands/__check__ +++ b/autoload/commands/__check__ @@ -1,13 +1,11 @@ #!/usr/bin/env zsh +# Description: +# Return true if all packages are installed, false otherwise -__import "core/core" -__import "print/print" -__import "job/spinner" - -local is_verbose=false -local arg line -local -a args fail -local -A zspec +local is_verbose=false +local arg repo +local -aU repos not_installed_repos +local -A tags while (( $# > 0 )) do @@ -17,46 +15,64 @@ do is_verbose=true ;; -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid return 1 ;; + */*) + repos+=( "${arg:gs:@::}" ) + ;; *) - args+=("$arg") + return 1 ;; esac shift done -for line in ${${args[@]:-${(k)zplugs[@]}}:gs:@::} -do - __parser__ "$line" - zspec=( "${reply[@]}" ) - if [[ $zspec[from] == local ]]; then - continue - fi +if (( $#repos == 0 )); then + repos=( "${(k)zplugs[@]:gs:@::}" ) +fi - if [[ -n $zspec[if] ]] && ! eval "$zspec[if]" &>/dev/null; then +for repo in "${repos[@]}" +do + tags[from]="$( + __zplug::core::core::run_interfaces \ + 'from' \ + "$repo" \ + 2> >(__zplug::io::log::capture) + )" + if [[ -z "$tags[from]" ]]; then + not_installed_repos+=( "$repo" ) continue fi - if __zplug::core::core::is_handler_defined check "$zspec[from]"; then - __zplug::core::core::use_handler check "$zspec[from]" "$line" + if __zplug::core::sources::is_handler_defined "check" "$tags[from]"; then + __zplug::core::sources::use_handler \ + "check" \ + "$tags[from]" \ + "$repo" - if (( $status )); then - fail+=("$zspec[name]") - fi - else - if [[ ! -d $zspec[dir] ]]; then - fail+=("$zspec[name]") + if (( $status != 0 )); then + not_installed_repos+=( "$repo" ) fi fi done -if (( $#fail > 0 )); then +if (( $#not_installed_repos > 0 )); then + # Share not installed repos information + # e.g. for __install__ command + reply=( "${not_installed_repos[@]}" ) + if $is_verbose; then - __zplug::print::print::put "- $fg[red]%s$reset_color: not installed\n" "${(@nO)fail}" + __zplug::io::print::put \ + "- $fg[red]%s$reset_color: not installed\n" \ + "${not_installed_repos[@]}" fi + return 1 -else - return 0 fi + +return 0 diff --git a/autoload/commands/__clean__ b/autoload/commands/__clean__ index 62c35992..43e8bc07 100644 --- a/autoload/commands/__clean__ +++ b/autoload/commands/__clean__ @@ -1,12 +1,11 @@ #!/usr/bin/env zsh +# Description: +# Remove repositories which are no longer managed -__import "core/core" -__import "print/print" - -local arg filter repo -local is_force is_select=false -local -a args repos remove_args -local -A zspec +local repo filter +local is_force="" is_select=false +local -a repos remove_repos +local -A tags local -i ret=0 while (( $# > 0 )) @@ -20,71 +19,107 @@ do is_select=true ;; -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid return 1 ;; + */*) + repos+=( "${arg:gs:@::}" ) + ;; *) - args+=("$arg") + return 1 + ;; esac shift done -filter="$(__zplug::core::core::get_filter "$ZPLUG_FILTER")" if $is_select; then - args=(${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"}) - if (( $#args == 0 )); then + __zplug::utils::shell::search_commands \ + "$ZPLUG_FILTER" \ + | read filter + if [[ -z $filter ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "There is no available filter in ZPLUG_FILTER\n" + return 1 + fi + repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} ) + + # Cace of type Ctrl-C + if (( $#repos == 0 )); then return 0 fi fi -if (( $#args == 0 )); then +if (( $#repos == 0 )); then + # If no argument is given: + # search the repositories that have not been already managed by zplug repos=( "$ZPLUG_REPOS"/*/*(N-/) ) for repo in "${repos[@]}" do - if ! __zplug::core::core::zpluged "${repo:h:t}/${repo:t}"; then - remove_args+=("$repo") + if ! __zplug::base::base::zpluged "${repo:h:t}/${repo:t}"; then + remove_repos+=("$repo") fi done else - for arg in "${args[@]}" + # If the arguments are given or selected by the filter + for repo in "${repos[@]}" do - __parser__ "$arg" - zspec=( "${reply[@]}" ) - if [[ -d $zspec[dir] ]]; then - case "$zspec[from]" in + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" \ + 2> >(__zplug::io::log::capture) + )" + if [[ -d $tags[dir] ]]; then + case "$tags[from]" in "oh-my-zsh") - remove_args+=("$ZPLUG_REPOS/$_ZPLUG_OHMYZSH") + remove_repos+=( "${tags[dir]:F[2]h}" ) ;; *) - remove_args+=("$zspec[dir]") + remove_repos+=( "$tags[dir]" ) ;; esac else - __zplug::print::print::die "[zplug] $arg: no such package\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$repo: no such package\n" ret=1 fi done fi # Remove packages from $ZPLUG_REPOS -for repo in "${remove_args[@]}" +for repo in "${remove_repos[@]}" do - __zplug::print::print::put "${${is_force:+"Removed"}:-"Remove? (y/N)"} ${(qq)repo} " + __zplug::io::print::put \ + "${${is_force:+"Removed"}:-"Remove? (y/N)"} ${(qq)repo} " + if ${(z)is_force:-"read -q"}; then + # Remove directories rm -rf "$repo" rmdir "${repo:h}" - fi &>/dev/null - __zplug::print::print::put "\n" + # Clear cache + __zplug::core::core::run_interfaces 'clear' + fi \ + 2> >(__zplug::io::log::capture) >/dev/null + + __zplug::io::print::put "\n" done # Remove packages from $zplugs -for repo in "${(k)zplugs[@]}" +__zplug::core::core::run_interfaces 'check' +for repo in "${reply[@]}" do - __parser__ "$repo" - zspec=( "${reply[@]}" ) - if [[ ! -d $zspec[dir] ]]; then - unset "zplugs[$repo]" - fi + unset "zplugs[$repo]" done return $ret diff --git a/autoload/commands/__clear__ b/autoload/commands/__clear__ index b686e70e..6f441290 100644 --- a/autoload/commands/__clear__ +++ b/autoload/commands/__clear__ @@ -1,6 +1,6 @@ #!/usr/bin/env zsh - -__import "print/print" +# Description: +# Remove the cache file local arg @@ -9,11 +9,25 @@ do arg="$1" case "$arg" in -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid + return 1 + ;; + */*) + # Unexpect + return 1 + ;; + *) return 1 ;; esac shift done -rm -f "$ZPLUG_CACHE_FILE" "$ZPLUG_HOME/zcompdump" "$ZPLUG_HOME/zcompdump.zwc" +rm -f \ + "$ZPLUG_CACHE_FILE" \ + "$ZPLUG_HOME/zcompdump" \ + "$ZPLUG_HOME/zcompdump.zwc" diff --git a/autoload/commands/__info__ b/autoload/commands/__info__ index 6b2b4e78..e67e692d 100644 --- a/autoload/commands/__info__ +++ b/autoload/commands/__info__ @@ -1,44 +1,66 @@ #!/usr/bin/env zsh +# Description: +# Show the information such as the source URL and tag values for the given package -__import "print/print" -__import "core/core" -__import "core/git" +local arg="$1" repo key +local -a repos +local -A tags -local arg="$1" k -local -A zspec - -if [[ -z $arg ]]; then - __zplug::print::print::die \ - "[zplug] info: too few arguments\n" - return 1 -fi +while (( $# > 0 )) +do + arg="$1" + case "$arg" in + -*|--*) + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid + return 1 + ;; + */*) + repos+=( "${arg:gs:@::}" ) + ;; + *) + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "$arg: invalid argument\n" + return 1 + ;; + esac + shift +done -if ! __zplug::core::core::zpluged "$arg"; then - __zplug::print::print::die \ - "[zplug] info: $arg is not a managed package\n" +# If no argument is given +if (( $#repos == 0 )); then + __zplug::io::print::put \ + "%d plugs, %s\n" \ + $#zplugs \ + "$(du -ch "$ZPLUG_REPOS" | awk '$2 == "total"{print $1}')" return 1 fi -__parser__ "$arg" -zspec=( "${reply[@]}" ) - -if (( $#zspec > 0 )); then - ( - # change directory for remote_url - builtin cd -q "$zspec[dir]" +for repo in "${repos[@]}" +do + if ! __zplug::base::base::zpluged "$repo"; then + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$repo: no such package\n" + return 1 + fi - __zplug::print::print::put \ - "==> $fg[green]$arg$reset_color" - __zplug::print::print::put \ - " <${(%):-"%U"}%s${(%):-"%u"}>\n" \ - "${$(__zplug::core::git::remote_url):-"LOCAL REPO"}" - __zplug::print::print::put \ - " - - - \n" - ) -fi + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) -for k in "${(k)zspec[@]}" -do - __zplug::print::print::put \ - "$fg[red]-$reset_color $fg[blue]$k$reset_color:$fg[yellow]${(qqq)zspec[$k]}$reset_color\n" + for key in "${(k)tags[@]}" + do + __zplug::io::print::put \ + "$fg[red]-$reset_color $fg[blue]$key$reset_color: " + __zplug::io::print::put \ + "$fg[yellow]${(qqq)tags[$key]}$reset_color\n" + done done diff --git a/autoload/commands/__install__ b/autoload/commands/__install__ index a3d24eec..b6b14644 100644 --- a/autoload/commands/__install__ +++ b/autoload/commands/__install__ @@ -1,201 +1,188 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" -__import "job/spinner" - -local arg line filter k -local is_verbose=false is_select=false -local -a args -local -A check -local oh_my_line oh_my_count=0 -local -A zspec -local -i max=0 -local -a failed_packages -local -F SECONDS=0 -local -F start finish -local -a queue -local -i queue_max=$ZPLUG_THREADS - -arg="$1" -case "$arg" in - --verbose) - is_verbose=true; shift - ;; - -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" - return 1 - ;; -esac +# Description: +# Install packages in parallel + +local repo arg +local -aU repos +local -A tags +local -a failed_packages +local -A from +local -i max=0 +local -F SECONDS=0 start_time finish_time + +while (( $# > 0 )) +do + arg="$1" + case "$arg" in + -*|--*) + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid + return 1 + ;; + */*) + repos+=( "${arg:gs:@::}" ) + ;; + *) + return 1 + ;; + esac + shift +done # Initialize { - [[ -d $ZPLUG_REPOS ]] || mkdir -p "$ZPLUG_REPOS" - start=$SECONDS - filter="$(__zplug::core::core::get_filter "$ZPLUG_FILTER")" - if $is_select; then - args=(${(@f)"$(echo "${(F)@}" | eval "$filter")"}) - else - args=(${(u)${@:gs:@::}}) + start_time=$SECONDS + + if (( $#repos == 0 )); then + # Case of existing not installed repos + __zplug::core::core::run_interfaces \ + "check" \ + 2> >(__zplug::io::log::capture) >/dev/null \ + || repos=( "${reply[@]}" ) fi - if (( $#args == 0 )); then - __list__ - return $status - fi - - for line in "${args[@]}" + for repo in "${repos[@]}" do - (( $#line > $max )) && max=$#line + (( $#repo > $max )) && max=$#repo done } -for line in "${args[@]}" +# Main loop +for repo in "${repos[@]}" do - __parser__ "$line" - zspec=( "${reply[@]}" ) - - # Skip installed items - if [[ $zspec[from] == "local" ]]; then - continue + if ! __zplug::base::base::zpluged "$repo"; then + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$repo: no such package\n" + return 1 fi - if [[ -n $zspec[if] ]] && ! eval "$zspec[if]" &>/dev/null; then - if $is_verbose; then - __zplug::print::print::put "$fg[red]-$reset_color $fg[green]$line$reset_color: skipped due to if tag\n" - fi - continue - fi + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) - if __zplug::core::core::is_handler_defined check "$zspec[from]"; then - if __zplug::core::core::use_handler check "$zspec[from]" "$line"; then - if $is_verbose; then - __zplug::print::print::put "$fg[red]-$reset_color $fg[green]$line$reset_color: already installed\n" + # Skip items + { + if [[ -n $tags[if] ]]; then + if ! eval "$tags[if]" 2> >(__zplug::io::log::capture) >/dev/null; then + __zplug::io::print::put \ + "$fg[red]-$reset_color $fg[green]$repo$reset_color: skipped due to if tag\n" + continue fi - continue fi - else - if [[ -d $ZPLUG_REPOS/$line ]]; then - if $is_verbose; then - __zplug::print::print::put "$fg[red]-$reset_color $fg[green]$line$reset_color: already installed\n" + + if __zplug::core::sources::is_handler_defined "check" "$tags[from]"; then + if __zplug::core::sources::use_handler "check" "$tags[from]" "$repo"; then + __zplug::io::print::put \ + "$fg[red]-$reset_color $fg[green]$repo$reset_color: already installed\n" + continue fi - continue fi - fi + } - # For checking - if __zplug::core::core::is_handler_defined check "$zspec[from]"; then - check+=("$zspec[name]" "$zspec[from]") - elif [[ -n $zspec[dir] ]]; then - check+=("$zspec[name]" "$zspec[dir]") - else - check+=("$zspec[name]" "$ZPLUG_REPOS/$line") - fi - - # Case of oh-my-zsh - oh_my_line="" - if [[ $zspec[from] == "oh-my-zsh" ]]; then - if (( oh_my_count++ > 0 )); then - continue - fi - if [[ -d $ZPLUG_REPOS/$_ZPLUG_OHMYZSH ]]; then - continue - fi - oh_my_line="$_ZPLUG_OHMYZSH" - fi + # For checking whether the repo's installation is success + from+=( "$repo" "$tags[from]" ) __zplug::job::spinner::lock - __zplug::job::spinner::spinner & + __zplug::job::spinner::spin & # Run installation in subprocess { trap '__zplug::job::spinner::unlock; trap - SIGINT' SIGINT # All variables are treated as local variable # because of background job (subprocess) - local -i ret + local -i ret=2 local -F SECONDS=0 - __zplug::job::spinner::echo "%-20s %s\n" \ + __zplug::job::spinner::echo \ + "%-20s %s\n" \ "Installing..." \ - "${oh_my_line:-$line}" - - if __zplug::core::core::is_handler_defined install "$zspec[from]"; then - __zplug::core::core::use_handler install "$zspec[from]" "$line" - else - __clone__ \ - --use ${zspec[use]:-""} \ - --from ${zspec[from]:-""} \ - --at ${zspec[at]:-""} \ - --depth ${zspec[depth]:-""} \ - "$line" + "$repo" + + if __zplug::core::sources::is_handler_defined "install" "$tags[from]"; then + __zplug::core::sources::use_handler \ + "install" \ + "$tags[from]" \ + "$repo" + ret=$status fi - ret=$status case "$ret" in 0) - __zplug::job::spinner::echo "$fg[green]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + __zplug::job::spinner::echo \ + "$fg[green]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ "Installed!" \ - "${oh_my_line:-$line}" \ + "$repo" \ $SECONDS # hook after installing - if [[ -n $zspec[hook-build] ]]; then - ( - builtin cd -q "$zspec[dir]" - eval "$zspec[hook-build]" - ) - fi + __zplug::job::hook::build "$repo" ;; 1) - __zplug::job::spinner::echo "$fg[red]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + __zplug::job::spinner::echo \ + --die \ + "$fg[red]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ "Failed to install" \ - "${oh_my_line:-$line}" \ + "$repo" \ $SECONDS ;; + 2) + __zplug::job::spinner::echo \ + --die \ + --zplug \ + --error \ + "sources/$tags[from] is not defined\n" + ;; esac } & - queue+=($!) - if (( $#queue % queue_max == 0 )); then - wait $queue &>/dev/null - queue=() - fi + __zplug::job::queue::enqueue "$!" + __zplug::job::queue::wait done -if (( $#queue > 0 )); then - wait $queue &>/dev/null -fi -queue=() - -__zplug::job::spinner::unlock -failed_packages=() -for name in "${(k)check[@]}" -do - if __zplug::core::core::is_handler_defined check "$check[$name]"; then - if ! __zplug::core::core::use_handler check "$check[$name]" "$name"; then - failed_packages+=( "$name" ) + +# Finalize +{ + __zplug::job::queue::wait_all + __zplug::job::spinner::unlock + + failed_packages=() + for repo in "${(k)from[@]}" + do + if __zplug::core::sources::is_handler_defined "check" "$from[$repo]"; then + if ! __zplug::core::sources::use_handler "check" "$from[$repo]" "$repo"; then + failed_packages+=( "$repo" ) + fi fi - elif [[ ! -e $check[$name] ]]; then - failed_packages+=( "$name" ) - fi -done + done -# Skip footer prints -if (( $#check == 0 )); then - __zplug::print::print::die "[zplug] No package to install\n" - return 1 -else - if (( $#failed_packages == 0 )); then - __zplug::print::print::put "$fg_bold[default] ==> Installation finished successfully!$reset_color\n" + # Skip footer prints + if (( $#from == 0 )); then + __zplug::io::print::f \ + --zplug \ + "No package to install\n" + return 0 else - __zplug::print::print::die "$fg_bold[red] ==> Installation failed for following packages:$reset_color\n" - for package in ${failed_packages[@]} - do - __zplug::print::print::die " $package\n" - done - __zplug::print::print::die "\n" - fi + if (( $#failed_packages == 0 )); then + __zplug::io::print::put \ + "$fg_bold[default] ==> Installation finished successfully!$reset_color\n" + else + __zplug::io::print::die \ + "$fg_bold[red] ==> Installation failed for following packages:$reset_color\n" + __zplug::io::print::die \ + "- $fg_bold[red]%s$reset_color\n" "${failed_packages[@]}" + fi + + finish_time=$SECONDS - finish=$SECONDS - __zplug::print::print::put "zplug: total wall-time %f sec.\n" $(($finish - $start)) + __zplug::io::print::f \ + --zplug \ + --func \ + "total wall-time %f sec.\n" \ + $(( $finish_time - $start_time )) - return $#failed_packages -fi + return $#failed_packages + fi +} diff --git a/autoload/commands/__list__ b/autoload/commands/__list__ index 3f26a1de..b5e06d2c 100644 --- a/autoload/commands/__list__ +++ b/autoload/commands/__list__ @@ -1,18 +1,13 @@ #!/usr/bin/env zsh +# Description: +# List installed packages (more specifically, view the associative array $zplugs) -__import "core/core" -__import "print/print" - -local arg is_select=false filter +local arg filter repo tag +local is_select=false local -i ret=0 -local -a args awk_args +local -a repos similar_repos local -A copy_zplugs -if (( $#zplugs == 0 )); then - __zplug::print::print::die "[zplug] no package managed by zplug\n" - return 1 -fi - while (( $# > 0 )) do arg="$1" @@ -21,42 +16,94 @@ do is_select=true ;; -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid return 1 ;; + */*) + # Do not remove the end of the at sign + # At the end of the treatment, + # get rid of those at displaying to stdout + repos+=( "$arg" ) + ;; *) - args+=("$arg") + return 1 ;; esac shift done -filter="$(__zplug::core::core::get_filter "$ZPLUG_FILTER")" -if $is_select; then - args=(${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"}) - if (( $#args == 0 )); then - return 0 +# Initialize +{ + # If assosiate array "zplugs" is empty, + # it means there are no packages that are managed by zplug + if (( $#zplugs == 0 )); then + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "no package managed by zplug\n" + return 1 fi -fi -if (( $#args > 0 )); then + if $is_select; then + __zplug::utils::shell::search_commands "$ZPLUG_FILTER" \ + | read filter + if [[ -z $filter ]]; then + __zplug::io::print::die \ + --die \ + --zplug \ + --error \ + "There is no available filter in ZPLUG_FILTER\n" + return 1 + fi + repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} ) + + # There is no package selected by the filter + if (( $#repos == 0 )); then + return 0 + fi + fi +} + +if (( $#repos > 0 )); then copy_zplugs=() - for arg in "${args[@]}" + for repo in "${repos[@]}" do - if __zplug::core::core::zpluged "$arg"; then - # This is compelte match - copy_zplugs+=("$arg" "${zplugs[$arg]}") + if __zplug::base::base::zpluged "$repo"; then + # TODO: + # @ (at-sign) + # e.g. zplug list b4b4r07/enhancd + # -> b4b4r07/enhancd + # -> b4b4r07/enhancd (b4b4r07/enhancd@) + + # It's already managed + copy_zplugs+=( + "$repo" + "${zplugs[$repo]}" + ) else - # Fuzzy match with awk - awk_args=(${(@f)"$(awk -v arg=$arg '$1 ~ arg' <<<${(Fk)zplugs[@]})"}) - if (( $#awk_args == 0 )); then - copy_zplugs+=("$arg" "NO SUCH PACKAGE") + # It doesn't managed yet + # Try to search the package with fuzzy match + similar_repos=( ${(@f)"$(awk -v repo=$repo '$1 ~ repo' <<<${(Fk)zplugs[@]})"} ) + # There is even no similar package + if (( $#similar_repos == 0 )); then + copy_zplugs+=( + "$repo" + "NO SUCH PACKAGE" + ) ret=1 fi - for arg in ${awk_args[@]} + for repo in "${similar_repos[@]}" do - if __zplug::core::core::zpluged "$arg"; then - copy_zplugs+=("$arg" "${zplugs[$arg]}") + if __zplug::base::base::zpluged "$repo"; then + copy_zplugs+=( + "$repo" + "${zplugs[$repo]}" + ) fi done fi @@ -65,10 +112,19 @@ else copy_zplugs=( "${(@kv)zplugs[@]}" ) fi -__zplug::print::print::put '%s => %s\n' "${(@kv)copy_zplugs:gs:@::}" \ - | perl -pe 's/=> $/=> '$fg[red]'nil'$reset_color'/g' \ - | perl -pe 's/^(.*)( *=>.*)$/'$fg[green]'$1'$reset_color'$2/g' \ - | perl -pe 's/'"(${(j:|:)_zplug_tag_pattern[@]})"'(:)/'$fg[blue]'$1'$reset_color'$2/g' \ - | perl -pe 's/(NO SUCH PACKAGE)/'$fg[red]'$1'$reset_color'/g' +dq='"' +dq="$(print -nP -- "%F{000}$dq%f")" +for copy in "${(k)copy_zplugs[@]}" +do + tag="nil" + if [[ -n $copy_zplugs[$copy] ]]; then + echo "$copy_zplugs[$copy]" \ + | sed 's/$/'"$dq"'/g; s/:/:'"$dq"'/g; s/, /'"$dq"', /g;' \ + | read tag + fi + printf "%s => %s\n" \ + "$fg[green]${copy:gs:@::}$reset_color" \ + "$tag" +done return $ret diff --git a/autoload/commands/__load__ b/autoload/commands/__load__ index 7f87027c..0bf7ed55 100644 --- a/autoload/commands/__load__ +++ b/autoload/commands/__load__ @@ -1,288 +1,172 @@ #!/usr/bin/env zsh +# Description: +# Source installed plugins and add installed commands to $PATH -__import "print/print" -__import "zplug/cache" -__import "zplug/variables" -__import "support/omz" - -local is_verbose=false is_debug=false -local loaded_omz=false -local arg key k f -local -A zspec -local basename ext -local src dst -local -a sources +local is_verbose=false +local -a repos +local repo +local -A tags + +local arg pkg dep local ignore local -A load_commands -local -a packages unsorted_nice nice_plugins -local -a load_plugins load_fpaths lazy_plugins -local -a ignore_patterns load_patterns -local -a themes_ext plugins_ext +local -a unsorted_repos + +local -aU load_plugins load_fpaths lazy_plugins nice_plugins +local -aU ignore_patterns + local -A reply_hash local -A hook_load local -a failed_packages hook_load_cmds -local -a do_not_checkout -local default_use while (( $# > 0 )) do arg="$1" case "$arg" in --verbose) - shift; is_verbose=true - ;; - --debug) - shift; is_debug=true + is_verbose=true ;; -*|--*) - __zplug::print::print::die "$arg: Unknown option\n" + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid + return 1 + ;; + */*) + repos+=( "${arg:gs:@::}" ) + ;; + *) return 1 ;; esac + shift done # Use cache file -if __zplug::zplug::cache::load; then - if $is_debug; then - __zplug::print::print::put "$ZPLUG_CACHE_FILE\n" - fi +if __zplug::io::cache::load; then return 0 fi -packages=( +repos=( "${(k)zplugs[@]}" ) # Order by nice value -for key in "${packages[@]}" +for repo in "${repos[@]}" do - __parser__ "$key" - zspec=( "${reply[@]}" ) - unsorted_nice+=("$zspec[nice]:$zspec[name]") + if ! __zplug::base::base::zpluged "$repo"; then + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$repo: no such package\n" + return 1 + fi + + tags[nice]="$(__zplug::core::core::run_interfaces 'nice' "$repo")" + unsorted_repos+=( "$tags[nice]:$repo" ) done -unset key -for key in \ - ${${(OnM)unsorted_nice:#-*}#*:} \ - ${${(on)unsorted_nice:#-*}#*:} +# Sorting... +for repo in \ + ${${(OnM)unsorted_repos:#-*}#*:} \ + ${${(on)unsorted_repos:#-*}#*:} do - __parser__ "$key" - zspec=( "${reply[@]}" ) + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + # Packages to skip loading { # FROM tag - if __zplug::core::core::is_handler_defined check "$zspec[from]"; then - if ! __zplug::core::core::use_handler check "$zspec[from]" "$key"; then + if __zplug::core::sources::is_handler_defined check "$tags[from]"; then + if ! __zplug::core::sources::use_handler check "$tags[from]" "$repo"; then continue fi else - if [[ ! -d $zspec[dir] ]]; then + if [[ ! -d $tags[dir] ]]; then continue fi fi # IF tag - if [[ -n $zspec[if] ]]; then - if ! eval "$zspec[if]" &>/dev/null; then - $is_verbose && __zplug::print::print::die "$zspec[name]: (not loaded)\n" + if [[ -n $tags[if] ]]; then + if ! eval "$tags[if]" 2> >(__zplug::io::log::capture) >/dev/null; then + $is_verbose && __zplug::io::print::die "$tags[name]: (not loaded)\n" continue fi fi # ON tag - if [[ -n $zspec[on] ]]; then - if [[ ! -d $ZPLUG_REPOS/${~zspec[on]} ]]; then - $is_verbose && __zplug::print::print::die "$zspec[name]: (not loaded)\n" + if [[ -n $tags[on] ]]; then + __zplug::core::core::run_interfaces \ + 'check' \ + ${~tags[on]} + if (( $status != 0 )); then + $is_verbose && __zplug::io::print::die "$tags[name]: (not loaded)\n" continue fi fi } - do_not_checkout=( "local" "gh-r" ) - if (( ! $do_not_checkout[(I)$zspec[from]] )); then - ( - builtin cd -q "$zspec[dir]" &>/dev/null || \ - builtin cd -q "$zspec[dir]:h" &>/dev/null || \ - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: no such directory '$zspec[dir]' ($zspec[name])\n" - git checkout -q "$zspec[at]" &>/dev/null - if (( $status != 0 )); then - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: pathspec '$zspec[at]' (at tag) did not match ($zspec[name])\n" - fi - ) - fi + # Switch to the revision specified by its tags + __zplug::utils::git::checkout "$repo" - # MAIN - case $zspec[as] in + case $tags[as] in "command") - if [[ ! -d $ZPLUG_HOME/bin ]]; then - mkdir -p "$ZPLUG_HOME/bin" - fi - - if __zplug::core::core::is_handler_defined load_command "$zspec[from]"; then - __zplug::core::core::use_handler load_command "$zspec[from]" "$key" + if __zplug::core::sources::is_handler_defined "load_command" "$tags[from]"; then + __zplug::core::sources::use_handler \ + "load_command" \ + "$tags[from]" \ + "$repo" + reply_hash=( "$reply[@]" ) - reply_hash=( $reply ) load_fpaths+=( ${(@f)reply_hash[load_fpaths]} ) - for pair in ${(@f)reply_hash[load_commands]}; do + for pair in ${(@f)reply_hash[load_commands]} + do # Each line (pair) is null character-separated load_commands+=( ${(@s:\0:)pair} ) done - else - basename="${zspec[name]:t}" - zspec[dir]="${zspec[dir]%/}" - dst=${${zspec[rename-to]:+$ZPLUG_HOME/bin/$zspec[rename-to]}:-"$ZPLUG_HOME/bin"} - - # Add parent directories to fpath if any files starting in _* exist - load_fpaths+=(${zspec[dir]}{_*,/**/_*}(N-.:h)) - - # Mock (example): "b4b4r07/sample" - # sample - # |-- bin - # | |-- sample - # | `-- mycmd1 - # `-- mycmd2 - # - # 1 directory, 2 files - # - if [[ -f $zspec[dir]${zspec[use]:+"/$zspec[use]"} ]]; then - # case: - # zplug "b4b4r07/sample", use:mycmd - load_commands+=( - # expand to "$ZPLUG_REPOS/b4b4r07/sample/mycmd" - "$zspec[dir]${zspec[use]:+"/$zspec[use]"}" - "$dst" - ) - elif [[ -f $zspec[dir]${zspec[use]:+"/$zspec[use]"}/$basename ]]; then - # case: - # zplug "b4b4r07/sample", use:bin - load_commands+=( - # expand to "$ZPLUG_REPOS/b4b4r07/sample/bin/sample" - "$zspec[dir]${zspec[use]:+"/$zspec[use]"}/$basename" - "$dst" - ) - elif [[ -f $zspec[dir]/$basename ]]; then - # case: - # zplug "b4b4r07/sample" - load_commands+=( - # expand to "$ZPLUG_REPOS/b4b4r07/sample/sample" - "$zspec[dir]/$basename" - "$dst" - ) - else - # For brace - # case 1: - # zplug "b4b4r07/sample", use:"bin/{mycmd1,sample}" - # case 2: - # zplug "b4b4r07/sample", use:"bin/*" - sources=( - # expand to "$ZPLUG_REPOS/b4b4r07/sample/mycmd1" - # "$ZPLUG_REPOS/b4b4r07/sample/sample" - $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${zspec[dir]}/${zspec[use]}" 2>/dev/null) - ) - for src in "${sources[@]}" - do - load_commands+=("$src" "$dst") - done - fi fi ;; "plugin") - load_patterns=() - - if __zplug::core::core::is_handler_defined load_plugin "$zspec[from]"; then + if __zplug::core::sources::is_handler_defined "load_plugin" "$tags[from]"; then # Custom handler for loading - __zplug::core::core::use_handler load_plugin "$zspec[from]" "$key" - reply_hash=( $reply ) + __zplug::core::sources::use_handler \ + "load_plugin" \ + "$tags[from]" \ + "$repo" + reply_hash=( "$reply[@]" ) load_fpaths+=( ${(@f)reply_hash[load_fpaths]} ) - load_patterns+=( ${(@f)reply_hash[load_patterns]} ) load_plugins+=( ${(@f)reply_hash[load_plugins]} ) nice_plugins+=( ${(@f)reply_hash[nice_plugins]} ) - themes_ext+=( ${(@f)reply_hash[themes_ext]} ) - plugins_ext+=( ${(@f)reply_hash[plugins_ext]} ) - else - # Default load behavior for plugins - plugins_ext=("plugin.zsh" "zsh-theme" "theme-zsh") - themes_ext=("zsh-theme" "theme-zsh") - - # In order to find main file of the plugin, - # narrow down the candidates in three stages - # 1. use $plugins_ext[@] ==> foo.plugin.zsh - # 2. use $zspec[use] as a file like "*.zsh" ==> bar.zsh - # 3. use in combination - # - zspec[use] as a directory like "bin" - # - and *.zsh files ==> bar.zsh - for ext in "${plugins_ext[@]}" - do - zstyle -a ":zplug:tag" use default_use - default_use=${default_use:-"*.zsh"} - if [[ $zspec[use] == $default_use ]]; then - # NOTE: step 1 - load_patterns+=( "$zspec[dir]"/*.$ext(N-.) ) - fi - - if (( $#load_patterns == 0 )); then - # NOTE: step 2 - # If $zspec[use] is a regular file, - # expect to expand to $zspec[dir]/*.zsh - load_patterns+=( "$zspec[dir]"/${~zspec[use]}(N.) ) - if (( $#load_patterns == 0 )); then - # For brace - load_patterns+=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $zspec[dir]/$zspec[use](N.)" 2>/dev/null) ) - fi - # Add the parent directory to fpath - load_fpaths+=( $zspec[dir]/_*(N.:h) ) - - # NOTE: step 3 - # If $zspec[use] is a directory, - # expect to expand to $zspec[dir]/*.zsh - if (( $#load_patterns == 0 )); then - load_patterns+=( "$zspec[dir]/$zspec[use]"/*.zsh(N.) ) - if (( $#load_patterns == 0 )); then - # For brace - load_patterns+=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $zspec[dir]/$zspec[use]/*.zsh(N.)" 2>/dev/null) ) - fi - # Add the parent directory to fpath - load_fpaths+=( $zspec[dir]/$zspec[use]/_*(N.:h) ) - - # If that is an autoload plugin - if (( $_zplug_boolean_true[(I)$zspec[lazy]] )); then - load_patterns+=( "$zspec[dir]/autoload"/*(N.) ) - load_fpaths+=( "$zspec[dir]/autoload"(N/) ) - fi - fi - fi - done fi + ;; - if [[ $zspec[nice] -gt 9 ]]; then - # the order of loading of plugin files - nice_plugins+=( "${load_patterns[@]}" ) - else - # autoload plugin / regular plugin - if (( $_zplug_boolean_true[(I)$zspec[lazy]] )); then - lazy_plugins+=( "${load_patterns[@]}" ) - else - load_plugins+=( "${load_patterns[@]}" ) - fi - fi + "itself") + __zplug::core::self::load "$repo" + continue ;; *) - __zplug::print::print::die "$zspec[as]: as:value must be either command or plugin\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "as tag is invalid value (%s)\n" \ + "$fg[green]$repo$reset_color" return 1 ;; esac - if [[ -n $zspec[ignore] ]]; then - # Make ignore patterns - if [[ $zspec[from] == "oh-my-zsh" ]]; then - ignore_patterns=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $ZPLUG_REPOS/$_ZPLUG_OHMYZSH/${~zspec[ignore]}" 2>/dev/null)(N) ) - else - ignore_patterns=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${zspec[dir]}/${~zspec[ignore]}" 2>/dev/null)(N) ) - fi - + if [[ -n $tags[ignore] ]]; then + ignore_patterns=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${tags[dir]}/${~tags[ignore]}" \ + 2> >(__zplug::io::log::capture) + )(N) ) for ignore in "${ignore_patterns[@]}" do # Commands @@ -299,113 +183,109 @@ do fi # hook after load - if [[ -n $zspec[hook-load] ]]; then + if [[ -n $tags[hook-load] ]]; then hook_load+=( - "$zspec[name]" - "$zspec[hook-load]" + "$tags[name]" + "$tags[hook-load]" ) fi done # Commands { - for f in "${(k)load_commands[@]}" + for pkg in "${(k)load_commands[@]}" do - if [[ -f $f ]]; then - chmod a=rx "$f" && ln -snf "$f" "$load_commands[$f]" - if (( $status != 0 )); then - failed_packages+=("$f") + if [[ -f $pkg ]]; then + chmod a=rx "$pkg" && ln -snf "$pkg" "$load_commands[$pkg]" + if (( $status == 0 )); then + $is_verbose && \ + __zplug::io::print::put \ + "$fg[green] Linked$reset_color %s to $em[bold]%s$reset_color\n" \ + "${pkg#$ZPLUG_REPOS/}" \ + "$load_commands[$pkg]" + else + failed_packages+=("$pkg") fi fi done + path=( "$ZPLUG_HOME/bin" "${path[@]}" ) - typeset -gx -U path } # Plugins { # Normal plugins - for f in "${(u)load_plugins[@]}" + for pkg in "${(u)load_plugins[@]}" do - if [[ -f $f ]]; then - if $is_debug; then - echo "$f" + if [[ -f $pkg ]]; then + source "$pkg" + if (( $status == 0 )); then + $is_verbose && \ + __zplug::io::print::put \ + "$fg[green] Loaded$reset_color ${pkg#$ZPLUG_REPOS/}\n" else - source "$f" - if (( $status == 0 )); then - $is_verbose && \ - __zplug::print::print::put "$fg[green] Loaded$reset_color ${f#$ZPLUG_REPOS/}\n" - else - failed_packages+=("$f") - fi - fi - if (( $themes_ext[(I)${f:e}] )); then - __zplug::support::omz::theme + failed_packages+=("$pkg") fi else - load_plugins[$load_plugins[(i)$f]]=() + load_plugins[$load_plugins[(i)$pkg]]=() fi done # NOTE: set fpath before compinit - if $is_debug; then - echo ${(F)${(u)load_fpaths[@]}} - else - fpath=( - "${(u)load_fpaths[@]}" - "${fpath[@]}" - ) - compinit -i -d "$ZPLUG_HOME/zcompdump" + fpath=( + "${(u)load_fpaths[@]}" + "${fpath[@]}" + ) + compinit -C -d "$ZPLUG_HOME/zcompdump" - { zcompile "$ZPLUG_HOME/zcompdump" } &! - fi + { + zcompile "$ZPLUG_HOME/zcompdump" + } &! # Nice plugins - for f in "${nice_plugins[@]}" + for pkg in "${(u)nice_plugins[@]}" do - if [[ -f $f ]]; then - if $is_debug; then - echo "$f" - else - source "$f" - if (( $status == 0 )); then - if $is_verbose; then - __zplug::print::print::put "$fg[green] Loaded$reset_color ${f#$ZPLUG_REPOS/}" - __zplug::print::print::put "$fg[yellow] after compinit$reset_color\n" - fi - else - failed_packages+=("$f") + if [[ -f $pkg ]]; then + source "$pkg" + if (( $status == 0 )); then + if $is_verbose; then + __zplug::io::print::put "$fg[green] Loaded$reset_color ${pkg#$ZPLUG_REPOS/}" + __zplug::io::print::put "$fg[yellow] after compinit$reset_color\n" fi - fi - if (( $themes_ext[(I)${f:e}] )); then - __zplug::support::omz::theme + else + failed_packages+=("$pkg") fi else - nice_plugins[$nice_plugins[(i)$f]]=() + nice_plugins[$nice_plugins[(i)$pkg]]=() fi done # Lazy plugins - for f in "${lazy_plugins[@]}" + for pkg in "${(u)lazy_plugins[@]}" do - autoload -Uz "${f:t}" + autoload -Uz "${pkg:t}" done - unset f } - # Hooks after load -for k in "${(k)hook_load[@]}" +for repo in "${(k)hook_load[@]}" do - # execute the hook_load command if the package successfully loads - if (( ! $failed_packages[(I)$k] )); then - eval "$hook_load[$k]" - hook_load_cmds+=("$hook_load[$k]") + # Skip the execution of the hook + # if the loading of the repo is failed + if (( $failed_packages[(I)$repo] )); then + continue fi + + __zplug::job::hook::load "$repo" + + # for cache + hook_load_cmds+=( "$hook_load[$repo]" ) done # Cache in background -{__zplug::zplug::cache::update} &! +{ + __zplug::io::cache::update +} &! diff --git a/autoload/commands/__status__ b/autoload/commands/__status__ index 86762393..ecb00545 100644 --- a/autoload/commands/__status__ +++ b/autoload/commands/__status__ @@ -1,64 +1,100 @@ #!/usr/bin/env zsh - -__import "core/git" -__import "support/gh-r" -__import "job/spinner" -__import "print/print" +# Description: +# Check if the remote repositories are up to date local -a queue local -i queue_max=$ZPLUG_THREADS local -F SECONDS=0 -local -A zspec +local -A tags local -i max=0 dif=0 local is_releases=false is_select=false -local state arg filter -local -a args - -arg="$1" -case "$arg" in - --select) - is_select=true; shift - ;; - -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" - return 1 - ;; -esac +local state arg filter repo +local -a repos + +while (( $# > 0 )) +do + arg="$1" + case "$arg" in + --select) + is_select=true + ;; + -*|--*) + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid + return 1 + ;; + */*) + repos+=( "${arg:gs:@::}" ) + return 1 + ;; + *) + return 1 + ;; + esac + shift +done # Initialize { - filter="$(__zplug::core::core::get_filter "$ZPLUG_FILTER")" if $is_select; then - args=(${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"}) - else - args=(${(u)${@:gs:@::}}) + __zplug::utils::shell::search_commands \ + "$ZPLUG_FILTER" \ + | read filter + if [[ -z $filter ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "There is no available filter in ZPLUG_FILTER\n" + return 1 + fi + repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} ) + + # Cace of type Ctrl-C + if (( $#repos == 0 )); then + return 0 + fi fi - if (( $#args > 0 )); then - for line in "${args[@]}" - do - line="$(__zplug::core::core::packaging "$line")" - (( $#line > $max )) && max=$#line - done - max=$(( $max + 1 )) - - __zplug::print::print::put "Fetching the status of packages ...\n" - __zplug::print::print::put "Packages with from:'local' are skipped.\n" - __zplug::print::print::put "===\n" - __zplug::job::spinner::lock - __zplug::job::spinner::spinner & - else - __zplug::print::print::die "[zplug] No package to get the status" - return 1 + if (( $#repos == 0 )); then + repos=( "${(k)zplugs[@]:gs:@::}" ) fi + + for repo in "${repos[@]}" + do + (( $#repo > $max )) && max=$#repo + done + max=$(( $max + 1 )) } -for line in "${args[@]}" +if (( $#repos > 0 )); then + __zplug::io::print::put "Fetching the status of packages ...\n" + __zplug::io::print::put "Packages with from:'local' are skipped.\n" + __zplug::io::print::put "===\n" + + __zplug::job::spinner::lock + __zplug::job::spinner::spin & +fi + +for repo in "${repos[@]}" do - line="$(__zplug::core::core::packaging "$line")" - __parser__ "$line" - zspec=( "${reply[@]}" ) - case "$zspec[from]" in + if ! __zplug::base::base::zpluged "$repo"; then + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$repo: no such package\n" + return 1 + fi + + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + + case "$tags[from]" in "local") is_releases=false continue @@ -70,8 +106,9 @@ do is_releases=false ;; esac - if [[ ! -d $zspec[dir] ]]; then - shift args + + if [[ ! -d $tags[dir] ]]; then + shift repos continue fi @@ -80,39 +117,37 @@ do trap '__zplug::job::spinner::unlock; trap - SIGINT' SIGINT # Change directory to get the remote status - builtin cd -q \ - "$zspec[dir]" \ - &>/dev/null + __zplug::utils::shell::cd \ + "$tags[dir]" if (( $status == 0 )); then + # Get the status of the repository (whether it is a latest) if $is_releases; then - state="$(__zplug::support::gh-r::get_state "$zspec[name]" "$zspec[dir]")" + __zplug::utils::releases::get_state "$tags[name]" "$tags[dir]" else - state="$(__zplug::core::git::get_state "$zspec[name]" "$zspec[dir]")" - fi - # space size - dif=$(($max - $#line)) - __zplug::job::spinner::echo "${(%):-"%U"}%-${#line}s${(%):-"%u"}%${dif}s %s\n" \ - "$line" \ + __zplug::utils::git::get_state "$tags[name]" "$tags[dir]" + fi \ + | read state + + # Adjust space sizes + dif=$(( $max - $#repo )) + __zplug::job::spinner::echo "%-${#repo}s %${dif}s %s\n" \ + "$em[under]$repo$reset_color" \ "" \ "$state" fi } & - queue+=($!) - - if (( $#queue % queue_max == 0 )); then - wait $queue &>/dev/null - queue=() - fi + __zplug::job::queue::enqueue "$!" + __zplug::job::queue::wait done -if (( $#queue > 0 )); then - wait $queue &>/dev/null -fi -queue=() -__zplug::job::spinner::unlock -if (( $#args > 0 )); then - __zplug::print::print::put "===\n" - __zplug::print::print::put "Finished %.6f\n" $SECONDS +if (( $#repos > 0 )); then + __zplug::job::queue::wait_all + __zplug::job::spinner::unlock + + __zplug::io::print::put "===\n" + __zplug::io::print::put "Finished %.6f\n" $SECONDS + __zplug::io::print::put "\n" fi -__zplug::print::print::put "\n" + +return 0 diff --git a/autoload/commands/__update__ b/autoload/commands/__update__ index da8bd14f..feaf935f 100644 --- a/autoload/commands/__update__ +++ b/autoload/commands/__update__ @@ -1,204 +1,191 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" -__import "print/logger" -__import "job/spinner" -__import "zplug/variables" +# Description: +# Update installed packages in parallel trap '__zplug::job::spinner::unlock; trap - SIGINT' SIGINT -local line filter is_select=false -local -i max=0 ret=0 -local -a args -local -a queue -local -i queue_max=$ZPLUG_THREADS -local -F SECONDS=0 - -arg="$1" -case "$arg" in - --self) - __self__ - return $status - ;; - --select) - is_select=true; shift - ;; - -*|--*) - __zplug::print::print::die "[zplug] $arg: Unknown option\n" - return 1 - ;; -esac +local repo arg f_pkg c_pkg filter +local -aU repos +local -A tags +local -a failed_packages +local -A checked_packages +local -i max=0 +local -F SECONDS=0 start_time finish_time +local is_select=false is_force=false + +while (( $# > 0 )) +do + arg="$1" + case "$arg" in + --self) + __zplug::core::self::update \ + ${2:+"$argv[2,-1]"} + return $status + ;; + --select) + is_select=true + ;; + --force) + is_force=true + ;; + -*|--*) + __zplug::core::options::unknown "$arg" + return $status + ;; + "") + # Invalid + return 1 + ;; + */*) + repos+=( "${arg:gs:@::}" ) + ;; + *) + return 1 + ;; + esac + shift +done # Initialize { - filter="$(__zplug::core::core::get_filter "$ZPLUG_FILTER")" if $is_select; then - args=(${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"}) - else - args=(${(u)${@:gs:@::}}) + __zplug::utils::shell::search_commands \ + "$ZPLUG_FILTER" \ + | read filter + if [[ -z $filter ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "There is no available filter in ZPLUG_FILTER\n" + return 1 + fi + repos=( ${(@f)"$(echo "${(Fk)zplugs[@]}" | eval "$filter")"} ) + + # Cace of type Ctrl-C + if (( $#repos == 0 )); then + return 0 + fi fi - if (( $#args == 0 )); then - __list__ - return $status + if (( $#repos == 0 )); then + repos=( "${(k)zplugs[@]:gs:@::}" ) fi - for line in "${args[@]}" + for repo in "${repos[@]}" do - (( $#line > $max )) && max=$#line + (( $#repo > $max )) && max=$#repo done } __zplug::job::spinner::lock -__zplug::job::spinner::spinner & -for line in "${args[@]}" +__zplug::job::spinner::spin & + +for repo in "${repos[@]}" do - line="$(__zplug::core::core::packaging "$line")" - if ! __zplug::core::core::zpluged "$line"; then - __zplug::print::print::die "[zplug] $line: no such package\n" - ret=1 - continue + if ! __zplug::base::base::zpluged "$repo"; then + __zplug::job::spinner::unlock + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$repo: no such package\n" + return 1 fi # Run installation in subprocess { # All variables are treated as local variable # because of background job (subprocess) - local k ret=1 - local -A zspec - __parser__ "$line" - zspec=( "${reply[@]}" ) - - case "$zspec[from]" in - "local") - continue - ;; - esac - - if [[ $# == 1 && $argv[1] == $zspec[name] ]]; then - if (( $_zplug_boolean_true[(I)$zspec[frozen]] )); then - __zplug::job::spinner::unlock - __zplug::print::print::put "$fg[green]$zspec[name]: $fg[blue]frozen repo$reset_color. Update? [y/N]: " - if read -q; then - __zplug::print::print::put "\n" - __zplug::job::spinner::lock - __zplug::job::spinner::spinner & - SECONDS=0 - else - continue - fi - fi - fi + local key + local -i ret=1 + local -A tags - __zplug::job::spinner::echo "%-20s %s\n" \ - "Updating..." \ - "$line" + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + # Run in anonymous function for using its exit code function () { - if (( $_zplug_boolean_true[(I)$zspec[frozen]] )); then - return 3 - fi + __zplug::job::spinner::echo "%-20s %s\n" \ + "Updating..." \ + "$repo" - # Change directory to fullpath of zspec dir - # or parent directory of zspec dir - # If it fails, return this unnamed function with error code 2 - builtin cd -q $zspec[dir] || \ - builtin cd -q ${zspec[dir]:h} || \ - return 1 - - # If zspec from is gh-r (GitHub Releases), - # send a http request to git.io/releases with os argument - # or, git pull (case of normal plugin) - if [[ $zspec[from] == "gh-r" ]]; then - __releases__ \ - --use "${zspec[use]:-}" \ - --at "${zspec[at]:-}" \ - "$line" + if $is_force; then + # DO update anyway + : else - if [[ -e $zspec[dir]/.git/shallow ]]; then - git fetch --unshallow - else - git fetch - fi - git checkout -q "$zspec[at]" - - local rev_local rev_remote rev_base - rev_local="$(git rev-parse HEAD)" - rev_remote="$(git rev-parse "@{u}")" - rev_base="$(git merge-base HEAD "@{u}")" - - if [[ $rev_local == $rev_remote ]]; then - # up-to-date - return 4 - elif [[ $rev_local = $rev_base ]]; then - # need to pull - git merge --ff-only origin/$zspec[at] && git submodule update --init --recursive - return $status - elif [ $rev_remote = $rev_base ]; then - # need to push - return 1 - else - # Diverged - return 1 + # if frozen:yes is given + if (( $_zplug_boolean_true[(I)$tags[frozen]] )); then + return $_ZPLUG_STATUS_REPO_FROZEN fi fi - } &>/dev/null - # Return code of above unnamed function - # Incidentally, - # nothing is output even if it success or fails + + if __zplug::core::sources::is_handler_defined "update" "$tags[from]"; then + __zplug::core::sources::use_handler \ + "update" \ + "$tags[from]" \ + "$repo" + return $status + fi + } ret=$status case "$ret" in - 0) + $_ZPLUG_STATUS_SUCCESS) __zplug::job::spinner::echo "$fg[green]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ "Updated!" \ - "$line" \ + "$repo" \ $SECONDS # hook after updating - if [[ -n $zspec[hook-build] ]]; then - eval "$zspec[hook-build]" - fi + __zplug::job::hook::build "$repo" ;; - 1) + $_ZPLUG_STATUS_FAILURE) __zplug::job::spinner::echo "$fg[red]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + --die \ "Failed to update" \ - "$line" \ + "$repo" \ $SECONDS ;; - 2) + $_ZPLUG_STATUS_REPO_NOT_FOUND) sleep 1 __zplug::job::spinner::echo "$fg[magenta]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + --die \ "Repo not found" \ - "$line" \ + "$repo" \ $(( SECONDS - 1 )) ;; - 3) + $_ZPLUG_STATUS_REPO_FROZEN) sleep 1 __zplug::job::spinner::echo "$fg[blue]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + --die \ "Frozen repo" \ - "$line" \ + "$repo" \ $(( SECONDS - 1 )) ;; - 4) + $_ZPLUG_STATUS_REPO_UP_TO_DATE) __zplug::job::spinner::echo "$fg[white]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + --die \ "Up-to-date" \ - "$line" \ + "$repo" \ $SECONDS ;; + $_ZPLUG_STATUS_REPO_LOCAL) + sleep 1 + __zplug::job::spinner::echo "$fg[yellow]%-20s$reset_color %-${max}s\t(%.2fs)\n" \ + --die \ + "Skipped due to local repo" \ + "$repo" \ + $(( SECONDS - 1 )) + ;; esac } & - queue+=($!) - if (( $#queue % queue_max == 0 )); then - wait $queue &>/dev/null - queue=() - fi + __zplug::job::queue::enqueue "$!" + __zplug::job::queue::wait done -if (( $#queue > 0 )); then - wait $queue &>/dev/null -fi -queue=() +__zplug::job::queue::wait_all __zplug::job::spinner::unlock + return $ret diff --git a/autoload/init.zsh b/autoload/init.zsh index 79bce2d4..e361b50f 100644 --- a/autoload/init.zsh +++ b/autoload/init.zsh @@ -1,37 +1,15 @@ -#!/usr/bin/env zsh -# init.zsh: -# This file is called only once +# This file just loads some files within autoload directory +# Also, load the body of zplug -if (( $+functions[__import] )); then - return 0 -fi - -source "$ZPLUG_ROOT/base/init.zsh" - -__import "zplug/variables" -__import "zplug/external" -__import "core/core" -__import "job/notify" -__import "print/print" - -if ! __zplug::core::core::zsh_version 4.3.9; then - __zplug::print::print::die "[zplug] zplug does not work this version of zsh $ZSH_VERSION.\n" - __zplug::print::print::die " You must use zsh 4.3.9 or later.\n" - return 1 -fi - -if (( ! $+commands[git] )); then - __zplug::print::print::die "[zplug] git command not found in \$PATH\n" - __zplug::print::print::die " zplug depends on git 1.7 or later.\n" - return 1 -fi +fpath=( +"$ZPLUG_ROOT"/autoload(N-/) +"$ZPLUG_ROOT"/autoload/*(N-/) +"$fpath[@]" +) autoload -Uz add-zsh-hook -autoload -Uz colors; colors +autoload -Uz colors autoload -Uz compinit +autoload -Uz zplug -if ${ZPLUG_CHECK_UPDATE:-false}; then - __zplug::job::notify::check_update -fi - -__zplug::zplug::external::load +colors diff --git a/autoload/options/__help__ b/autoload/options/__help__ index cf765004..0cfcb16a 100644 --- a/autoload/options/__help__ +++ b/autoload/options/__help__ @@ -1,10 +1,14 @@ #!/usr/bin/env zsh - -__import "print/print" +# Description: +# Display the help message local f arg local -a fs args +local -A opts cmds +local obj opt cmd +local -i max=0 + while (( $# > 0 )) do arg="$1" @@ -12,11 +16,16 @@ do -*|--*) break ;; + "") + ;; *) fs=( "$(echo $ZPLUG_HOME/doc/man/man(1|5)/(zplug-|)${arg}.(1|5)(N))" ) # Non-existing man page if [[ $fs[1] == "" ]]; then - __zplug::print::print::die "[zplug] $arg: no such subcommand or tag\n" + __zplug::io::print::f \ + --die \ + --zplug \ + "$arg: no such subcommand or tag\n" return 1 fi # List all hits pages @@ -35,6 +44,45 @@ if (( $#args > 0 )); then man "${args[@]}" return $status fi -__zplug::print::print::die "$_ZPLUG_HELP\n" + +# Measure max length +{ + cmds=( "${(kv)_zplug_commands[@]}" ) + for opt in "${(k)_zplug_options[@]}" + do + opts[--$opt]="$_zplug_options[$opt]" + done + + for obj in "${(k)cmds[@]}" "${(k)opts[@]}" + do + if (( $#obj > $max )); then + max=$#obj + fi + done +} + +# Help message format +{ + printf "usage: zplug [OPTIONS] [COMMANDS [options] [args]]\n" + printf " zplug is a next-generation plugin manager for zsh\n" + + for obj in \ + OPTIONS "${(k)opts[@]}" \ + COMMANDS "${(k)cmds[@]}"; do \ + case "$obj" in + OPTIONS | COMMANDS) + printf "\n$obj:\n" + ;; + *) + [[ -n $opts[$obj] ]] && desc="$opts[$obj]" + [[ -n $cmds[$obj] ]] && desc="$cmds[$obj]" + printf " %-${max}s %s\n" \ + "$obj" \ + "$desc" + ;; + esac + done + printf "\n" +} >&2 return 1 diff --git a/autoload/options/__log__ b/autoload/options/__log__ new file mode 100644 index 00000000..b40cae34 --- /dev/null +++ b/autoload/options/__log__ @@ -0,0 +1,59 @@ +#!/usr/bin/env zsh +# Description: +# Show the report of zplug errors + +if [[ ! -f $ZPLUG_ERROR_LOG ]] || [[ ! -s $ZPLUG_ERROR_LOG ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "ZPLUG_ERROR_LOG: is not found or empty\n" + return 1 +fi + +local arg + +while (( $# > 0 )) +do + arg="$1" + case "$arg" in + edit) + ${=EDITOR:-vim} "$ZPLUG_ERROR_LOG" + return $status + ;; + jq) + if (( ! $+commands[jq] )); then + return 1 + fi + cat "$ZPLUG_ERROR_LOG" \ + | sed -e 's/[[:cntrl:]]//g' \ + | jq '.' + return $status + ;; + less | more) + if [[ $arg == 'pager' ]]; then + arg="less" + fi + cat "$ZPLUG_ERROR_LOG" \ + | ${=PAGER:-$arg} + return $status + ;; + oneline | "") + ;; + clear) + rm -f "$ZPLUG_ERROR_LOG" + return $status + ;; + *) + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "$arg: invalid arguments\n" + return 1 + ;; + esac + shift +done + +cat "$ZPLUG_ERROR_LOG" diff --git a/autoload/options/__version__ b/autoload/options/__version__ index 0c5a470a..0c041849 100644 --- a/autoload/options/__version__ +++ b/autoload/options/__version__ @@ -1,7 +1,7 @@ #!/usr/bin/env zsh +# Description: +# Display the version of zplug -__import "print/print" - -__zplug::print::print::put "$_ZPLUG_VERSION\n" +__zplug::io::print::put "$_ZPLUG_VERSION\n" return 0 diff --git a/autoload/tags/__as__ b/autoload/tags/__as__ index 6b9c4afc..51b44935 100644 --- a/autoload/tags/__as__ +++ b/autoload/tags/__as__ @@ -1,7 +1,6 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# as tag local arg="$1" package local -a parsed_zplugs @@ -9,9 +8,16 @@ local as local default="plugin" local -a candidates +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + candidates=( "$default" "command" +"itself" ) package="${arg}, ${zplugs[$arg]%, }" @@ -26,10 +32,14 @@ if [[ -z $as ]]; then zstyle -s ":zplug:tag" as as ;; 1) - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "as tag must be [${(j:, :)candidates[@]}] ($fg[green]$arg$reset_color)\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "as tag must be [%s] ($fg[green]%s$reset_color)\n" \ + "${(j:, :)candidates[*]}" \ + "$arg" return 1 ;; 2) @@ -38,12 +48,27 @@ if [[ -z $as ]]; then esac fi +if [[ $arg != "zplug/zplug" ]] && [[ $as == "itself" ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --func \ + "%s: cannot set since it's reserved value (%s)\n" \ + "$as" \ + "$arg" + return 1 +fi + : ${as:=$default} if [[ ! $as =~ ^(${(j:|:)candidates[@]})$ ]]; then - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "as tag must be [${(j:, :)candidates[@]}] ($fg[green]$arg$reset_color)\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "as tag must be [%s] ($fg[green]%s$reset_color)\n" \ + "${(j:, :)candidates[*]}" \ + "$arg" return 1 fi diff --git a/autoload/tags/__at__ b/autoload/tags/__at__ index d7555ac0..1f96e849 100644 --- a/autoload/tags/__at__ +++ b/autoload/tags/__at__ @@ -1,14 +1,18 @@ #!/usr/bin/env zsh +# Description: +# at tag -__import "core/core" -__import "print/print" - -local arg package +local arg="$1" package local -a parsed_zplugs local at local default="master" -arg="$1" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -17,4 +21,17 @@ if [[ -z $at ]]; then zstyle -s ":zplug:tag" at at fi +local from +__zplug::core::core::run_interfaces \ + 'from' \ + "$arg" \ + | read from + +if [[ $from == "gh-r" ]]; then + default="latest" + if [[ -n $at ]]; then + at="tag/$at" + fi +fi + echo "${at:-$default}" diff --git a/autoload/tags/__depth__ b/autoload/tags/__depth__ index f38f063a..01bbad4b 100644 --- a/autoload/tags/__depth__ +++ b/autoload/tags/__depth__ @@ -1,14 +1,18 @@ #!/usr/bin/env zsh +# Description: +# depth tag -__import "core/core" -__import "print/print" - -local arg package +local arg="$1" package local -a parsed_zplugs local depth local -i default=0 -arg="$1" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -18,12 +22,44 @@ if [[ -z $depth ]]; then fi : ${depth:=$default} -if [[ $depth != <-> ]]; then - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "depth tag must be an integer ($fg[green]$arg$reset_color)\n" - return 1 -fi + +case $depth in + 0) + case "$ZPLUG_CLONE_DEPTH" in + 0) + #depth_option="" + : + ;; + <->) + #depth_option="--depth=$ZPLUG_CLONE_DEPTH" + depth="$ZPLUG_CLONE_DEPTH" + ;; + *) + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "ZPLUG_CLONE_DEPTH must be a positive number.\n" + return 1 + ;; + esac + ;; + <->) + #depth_option="--depth=$tag_depth" + : + ;; + *) + # not integer + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "depth tag must be a positive number\n" \ + "but, if zero, no shallow clone.\n" + return 1 + ;; +esac echo "$depth" diff --git a/autoload/tags/__dir__ b/autoload/tags/__dir__ index 2b669373..6545f410 100644 --- a/autoload/tags/__dir__ +++ b/autoload/tags/__dir__ @@ -1,13 +1,18 @@ #!/usr/bin/env zsh +# Description: +# dir tag -__import "core/core" -__import "print/print" - -local arg="${1:gs:@:}" package +local arg="${1:gs:@::}" package local -a parsed_zplugs local dir local default="$ZPLUG_REPOS/$arg" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -17,7 +22,11 @@ if [[ -z $dir ]]; then fi local from -from="$(__from__ "$arg")" +__zplug::core::core::run_interfaces \ + 'from' \ + "$arg" \ + | read from + case "$from" in "oh-my-zsh") dir="$ZPLUG_REPOS/$_ZPLUG_OHMYZSH/$arg" diff --git a/autoload/tags/__from__ b/autoload/tags/__from__ index 11965f04..665138cc 100644 --- a/autoload/tags/__from__ +++ b/autoload/tags/__from__ @@ -1,7 +1,6 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# from tag local arg="$1" package local -a parsed_zplugs @@ -9,6 +8,12 @@ local from local default="github" local -a candidates +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + candidates=( "$default" "bitbucket" @@ -30,11 +35,14 @@ if [[ -z $from ]]; then zstyle -s ":zplug:tag" from from ;; 1) - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "from tag must be [${(j:, :)candidates[@]}] ($fg[green]$arg$reset_color)\n" - return 1 + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "from tag must be [%s] ($fg[green]%s$reset_color)\n" \ + "${(j:, :)candidates[*]}" \ + "$arg" ;; 2) # undefined @@ -44,10 +52,14 @@ fi : ${from:=$default} if [[ ! $from =~ ^(${(j:|:)candidates[@]})$ ]]; then - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "from tag must be [${(j:, :)candidates[@]}] ($fg[green]$arg$reset_color)\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "from tag must be [%s] ($fg[green]%s$reset_color)\n" \ + "${(j:, :)candidates[*]}" \ + "$arg" return 1 fi echo "$from" diff --git a/autoload/tags/__frozen__ b/autoload/tags/__frozen__ index 16f8a34e..52a14edd 100644 --- a/autoload/tags/__frozen__ +++ b/autoload/tags/__frozen__ @@ -1,14 +1,18 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" -__import "zplug/variables" +# Description: +# frozen tag local arg package local -a parsed_zplugs local frozen local default="no" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + arg="$1" package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -27,10 +31,13 @@ if [[ -z $frozen ]]; then # ok (false words) : else - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "frozen tag must be a boolean ($fg[green]$arg$reset_color)\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "frozen tag must be a boolean ($fg[green]%s$reset_color)\n" \ + "$arg" return 1 fi ;; @@ -44,10 +51,13 @@ fi if [[ $frozen =~ ^("${(j:|:)_zplug_boolean_true[@]}|${(j:|:)_zplug_boolean_false[@]}")$ ]]; then : else - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ - "frozen tag must be a boolean ($fg[green]$arg$reset_color)\n" + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ + "frozen tag must be a boolean ($fg[green]%s$reset_color)\n" \ + "$arg" return 1 fi diff --git a/autoload/tags/__hook-build__ b/autoload/tags/__hook-build__ index af39ddf9..bea6188f 100644 --- a/autoload/tags/__hook-build__ +++ b/autoload/tags/__hook-build__ @@ -1,14 +1,18 @@ #!/usr/bin/env zsh +# Description: +# hook-build tag -__import "core/core" -__import "print/print" - -local arg package +local arg="$1" package local -a parsed_zplugs local hook_build local default="" -arg="$1" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) diff --git a/autoload/tags/__hook-load__ b/autoload/tags/__hook-load__ index 6b370303..31df7ae1 100644 --- a/autoload/tags/__hook-load__ +++ b/autoload/tags/__hook-load__ @@ -1,14 +1,18 @@ #!/usr/bin/env zsh +# Description: +# hook-load tag -__import "core/core" -__import "print/print" - -local arg package +local arg="$1" package local -a parsed_zplugs local hook_load local default="" -arg="$1" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) diff --git a/autoload/tags/__if__ b/autoload/tags/__if__ index cac89c1b..75029b2c 100644 --- a/autoload/tags/__if__ +++ b/autoload/tags/__if__ @@ -1,14 +1,18 @@ #!/usr/bin/env zsh +# Description: +# if tag -__import "core/core" -__import "print/print" - -local arg package +local arg="$1" package local -a parsed_zplugs local if local default="" -arg="$1" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) diff --git a/autoload/tags/__ignore__ b/autoload/tags/__ignore__ index f2f555da..75d86b0a 100644 --- a/autoload/tags/__ignore__ +++ b/autoload/tags/__ignore__ @@ -1,13 +1,18 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# ignore tag local arg="$1" package local -a parsed_zplugs local ignore local default="" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) diff --git a/autoload/tags/__lazy__ b/autoload/tags/__lazy__ index deec3657..c28a83a0 100644 --- a/autoload/tags/__lazy__ +++ b/autoload/tags/__lazy__ @@ -1,15 +1,18 @@ #!/usr/bin/env zsh +# Description: +# lazy tag -__import "core/core" -__import "print/print" -__import "zplug/variables" - -local arg package +local arg="$1" package local -a parsed_zplugs local lazy local default="no" -arg="$1" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -27,9 +30,11 @@ if [[ -z $lazy ]]; then # ok (false words) : else - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ "lazy tag must be a boolean ($fg[green]$arg$reset_color)\n" return 1 fi @@ -44,9 +49,11 @@ fi if [[ $lazy =~ ^("${(j:|:)_zplug_boolean_true[@]}|${(j:|:)_zplug_boolean_false[@]}")$ ]]; then : else - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ "lazy tag must be a boolean ($fg[green]$arg$reset_color)\n" return 1 fi diff --git a/autoload/tags/__nice__ b/autoload/tags/__nice__ index 4e20f824..d83e5b01 100644 --- a/autoload/tags/__nice__ +++ b/autoload/tags/__nice__ @@ -1,13 +1,18 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# nice tag local arg="$1" package local -a parsed_zplugs local nice local -i default=0 +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -25,9 +30,11 @@ if [[ $nice =~ ^[-+]?[[:digit:]]+$ ]] && \ (( $nice >= -20 )) && (( $nice <= 19 )); then : else - __zplug::print::print::die \ - "[zplug] $fg[red]ERROR$reset_color: " - __zplug::print::print::die \ + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + --func \ "nice tag must be {-20..19} ($fg[green]$arg$reset_color)\n" return 1 fi diff --git a/autoload/tags/__on__ b/autoload/tags/__on__ index 3587c74d..f4c7e82a 100644 --- a/autoload/tags/__on__ +++ b/autoload/tags/__on__ @@ -1,13 +1,18 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# on tag local arg="$1" package local -a parsed_zplugs local on local default="" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) diff --git a/autoload/tags/__rename-to__ b/autoload/tags/__rename-to__ index 34f796bf..c82b7357 100644 --- a/autoload/tags/__rename-to__ +++ b/autoload/tags/__rename-to__ @@ -1,13 +1,18 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# rename-to tag local arg="$1" package local -a parsed_zplugs local rename_to local default="" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) diff --git a/autoload/tags/__use__ b/autoload/tags/__use__ index 9b1784ea..574065b2 100644 --- a/autoload/tags/__use__ +++ b/autoload/tags/__use__ @@ -1,13 +1,18 @@ #!/usr/bin/env zsh - -__import "core/core" -__import "print/print" +# Description: +# use tag local arg="$1" package local -a parsed_zplugs local use local default="*.zsh" +if [[ -n $arg ]] && ! __zplug::base::base::zpluged "$arg"; then + __zplug::io::log::error \ + "$arg: no package managed by zplug" + return 1 +fi + package="${arg}, ${zplugs[$arg]%, }" parsed_zplugs=(${(s/, /)package/, */, }) @@ -16,4 +21,22 @@ if [[ -z $use ]]; then zstyle -s ":zplug:tag" use use fi +local from +__zplug::core::core::run_interfaces \ + 'from' \ + "$arg" \ + | read from + +if [[ $from == "gh-r" ]]; then + default="" + if [[ -n $use ]]; then + use="$(__zplug::utils::shell::glob2regexp "$use")" + else + use="$(__zplug::base::base::get_os)" + if __zplug::base::base::is_osx; then + use="(darwin|osx)" + fi + fi +fi + echo "${use:-$default}" diff --git a/autoload/utils/__add__ b/autoload/utils/__add__ deleted file mode 100644 index f3cccfdb..00000000 --- a/autoload/utils/__add__ +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "print/print" -__import "zplug/external" -__import "zplug/variables" - -local name -local tag key val -local -a tags -local -i max=0 -local -a re_tags - -tags=( ${(s/, /)@:gs/, */, } ) -name="${tags[1]}" -tags[1]=() - -# In the case of "from:local", it accepts multiple slashes -if [[ ! $name =~ [~$/] ]] && [[ ! $name =~ "^[^/]+/[^/]+$" ]]; then - __zplug::print::print::die "[zplug] ERROR: ${(qq)name} is invalid package name\n" - return 1 -fi - -# DEPRECATED: pipe -if [[ -p /dev/stdin ]]; then - __zplug::print::print::die "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: pipe syntax is deprecated!\n" - __zplug::print::print::die "[zplug] Please use '$fg[blue]on$reset_color' tag instead.\n" - return 1 -fi - -if __zplug::core::core::is_cli; then - if __zplug::core::core::zpluged "$name"; then - __zplug::print::print::die "[zplug] $name: already managed\n" - return 1 - else - # Add to the external file - __zplug::zplug::external::generate \ - "zplug ${(qqq)name}${tags[@]:+", ${(j:, :)${(q)tags[@]}}"}" - fi -fi - -# Process the duplication of key -if __zplug::core::core::zpluged; then - for key in "${(k)zplugs[@]}" - do - if [[ $key =~ ^$name@*$ ]] && (( $max < $#key )); then - max=$#key - name="${key}@" - fi - done -fi - -# Reconstruct the tag information -for tag in "${tags[@]}" -do - key=${${(s.:.)tag}[1]} - val=${${(s.:.)tag}[2]} - - if (( $_zplug_tag_pattern[(I)${key}] )); then - case "$key" in - "of") - key="use" - __zplug::print::print::die "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: '$fg[blue]of$reset_color' tag is deprecated. " - __zplug::print::print::die "Please use '$fg[blue]use$reset_color' tag instead ($fg[green]${name:gs:@::}$reset_color).\n" - ;; - "file") - key="rename-to" - __zplug::print::print::die "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: '$fg[blue]file$reset_color' tag is deprecated. " - __zplug::print::print::die "Please use '$fg[blue]rename-to$reset_color' tag instead ($fg[green]${name:gs:@::}$reset_color).\n" - ;; - "commit") - key="at" - __zplug::print::print::die "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: '$fg[blue]commit$reset_color' tag is deprecated. " - __zplug::print::print::die "Please use '$fg[blue]at$reset_color' tag instead ($fg[green]${name:gs:@::}$reset_color).\n" - ;; - "do") - key="hook-build" - __zplug::print::print::die "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: '$fg[blue]do$reset_color' tag is deprecated. " - __zplug::print::print::die "Please use '$fg[blue]hook-build$reset_color' tag instead ($fg[green]${name:gs:@::}$reset_color).\n" - return 1 - ;; - "from") - if __zplug::core::core::is_external "$val"; then - source $ZPLUG_ROOT/base/sources/$val.zsh - fi - ;; - esac - - # Reconstruct - re_tags+=("$key:$val") - else - __zplug::print::print::die "[zplug] $tag: $key is invalid tag name\n" - return 1 - fi -done - -# Add to zplugs -zplugs+=("$name" "${(j:, :)re_tags[@]:-}") diff --git a/autoload/utils/__arguments__ b/autoload/utils/__arguments__ deleted file mode 100644 index 61b2fe25..00000000 --- a/autoload/utils/__arguments__ +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" - -local arg -local -a cmds user_cmds - -user_cmds=( ${^path}/zplug-*(N-.:t:gs:zplug-:) ) - -arg="$1" -case "$arg" in - "") - __zplug::print::print::die \ - "[zplug] too few arguments\n" - return 1 - ;; -esac - -# User-defined command -if [[ -n ${(M)user_cmds:#$arg} ]]; then - eval "$commands[zplug-$arg]" - return $status -fi - -# Auto correct like git(1) -__zplug::core::core::get_autoload_files \ - "$ZPLUG_ROOT/autoload/commands" -reply+=("${user_cmds[@]}") - -cmds=( -${(@f)"$(awk \ - -f "$ZPLUG_ROOT/misc/share/fuzzy.awk" \ - -v search_string="$arg" \ - <<<"${(F)reply:gs:_:}" -)"} -) - -case $#cmds in - 0) - __zplug::print::print::die \ - "[zplug] $arg: no such command\n" - return 1 - ;; - 1) - __zplug::print::print::die \ - "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: " - __zplug::print::print::die \ - "You called a zplug command named '%s', which does not exist.\n" \ - "$arg" - __zplug::print::print::die \ - " Continuing under the assumption that you meant '$fg[green]%s$reset_color'.\n" \ - "$cmds" - shift - zplug "$cmds" ${1:+"$@"} - return $status - ;; - *) - __zplug::print::print::die \ - "[zplug] '%s' is not a zplug command. See 'zplug help'.\n" "$arg" - __zplug::print::print::die \ - " Did you mean one of these?\n" - __zplug::print::print::die \ - " %s\n" ${cmds} - return 1 - ;; -esac diff --git a/autoload/utils/__clone__ b/autoload/utils/__clone__ deleted file mode 100644 index 4d69e672..00000000 --- a/autoload/utils/__clone__ +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env zsh - -__import "print/print" - -local repository -local tag_use tag_from tag_at tag_depth -local depth_option -local url_format -local -i ret - -while (( $# > 0 )) -do - case "$1" in - --use) - tag_use="$2"; shift - ;; - --from) - tag_from="$2"; shift - ;; - --at) - tag_at="$2"; shift - ;; - --depth) - tag_depth="$2"; shift - case $tag_depth in - 0) - case "$ZPLUG_CLONE_DEPTH" in - 0) - depth_option="" - ;; - <->) - depth_option="--depth=$ZPLUG_CLONE_DEPTH" - ;; - *) - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: ZPLUG_CLONE_DEPTH must be a positive number.\n" - return 1 - ;; - esac - ;; - <->) - depth_option="--depth=$tag_depth" - ;; - *) - # not integer - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: depth tag must be a positive number\n" - __zplug::print::print::die " but, if zero, no shallow clone.\n" - return 1 - ;; - esac - ;; - -*|--*) - __zplug::print::print::die "[zplug] $1: Unknown option\n" - return 1 - ;; - *) - repository="$1" - ;; - esac - shift -done - -# If an 'at' tag has been specified, do a deep clone to allow any commit to be -# checked out. -[[ -n "$tag_at" ]] && depth_option="" - -# Initialize -{ - [[ -d $ZPLUG_REPOS ]] || mkdir -p "$ZPLUG_REPOS" - builtin cd -q "$ZPLUG_REPOS" - - case "$tag_from" in - github) - if [[ $ZPLUG_PROTOCOL =~ ^(HTTPS|https)$ ]]; then - # Create the format of URL used to git clone - # When vim-plug clones a repository, it injects git::@ into the URL - # It's a little hack to avoid username/password prompt - # from git when the repository doesn't exist. - # Such thing can happen when there's a typo in the argument, - # or when the repository is removed from GitHub - # For more information, see also vim-plug wiki. - # HTTPS: "https://git::@github.com/%s.git" - url_format="https://git::@github.com/${repository}.git" - - # However, Git 2.3.0 introduced $GIT_TERMINAL_PROMPT - # which can be used to suppress user prompt - if __zplug::core::core::git_version 2.3; then - # HTTPS (git 2.3+): "https://github.com/%s.git" - export GIT_TERMINAL_PROMPT=0 - url_format="https://github.com/${repository}.git" - fi - elif [[ $ZPLUG_PROTOCOL =~ ^(SSH|ssh)$ ]]; then - # SSH: "git@github.com:%s.git" - url_format="git@github.com:${repository}.git" - fi - ;; - - bitbucket) - if [[ $ZPLUG_PROTOCOL =~ ^(HTTPS|https)$ ]]; then - # HTTPS: "https://git::@bitbucket.org/%s.git" - url_format="https://git::@bitbucket.org/${repository}.git" - elif [[ $ZPLUG_PROTOCOL =~ ^(SSH|ssh)$ ]]; then - # SSH: "git@bitbucket.org:%s.git" - url_format="git@bitbucket.org:${repository}.git" - fi - ;; - - gist) - if [[ $ZPLUG_PROTOCOL =~ ^(HTTPS|https)$ ]]; then - # the same as github - # - # HTTPS: "https://git::@github.com/%s.git" - url_format="https://git::@gist.github.com/${repository}.git" - - if __zplug::core::core::git_version 2.3; then - # HTTPS (git 2.3+): "https://gist.github.com/%s.git" - export GIT_TERMINAL_PROMPT=0 - url_format="https://gist.github.com/${repository}.git" - fi - elif [[ $ZPLUG_PROTOCOL =~ ^(SSH|ssh)$ ]]; then - # SSH: "git@github.com:%s.git" - url_format="git@gist.github.com:${repository}.git" - fi - ;; - - gh-r) - __releases__ \ - --use "${tag_use:-}" \ - --at "${tag_at:#master}" \ - "$repository" &>/dev/null - return $status - ;; - - *) - __zplug::print::print::die "[zplug] $tag_from: Unknown tag\n" - return 1 - ;; - esac - - if [[ ! $ZPLUG_PROTOCOL =~ ^(HTTPS|https|SSH|ssh)$ ]]; then - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: $ZPLUG_PROTOCOL is an invalid protocol.\n" - return 1 - fi - - if [[ -z $url_format ]]; then - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: $repository is an invalid 'user/repo' format.\n" - return 1 - fi -} - -# git clone -(( $ret == 0 )) && - git clone \ - $depth_option \ - --recursive \ - --quiet \ - "$url_format" "$repository" &>/dev/null -ret=$status - -if (( $ret == 0 )); then - ( - # revision/branch/tag lock - builtin cd -q "$ZPLUG_REPOS/$repository" - git checkout -q "$tag_at" &>/dev/null - if (( $status != 0 )); then - __zplug::print::print::die "[zplug] $fg[red]ERROR$reset_color: pathspec '$tag_at' (at tag) did not match ($repository)\n" - ret=1 - fi - ) -fi - -return $ret diff --git a/autoload/utils/__options__ b/autoload/utils/__options__ deleted file mode 100644 index 22332911..00000000 --- a/autoload/utils/__options__ +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env zsh - -__import "print/print" - -local arg opt - -arg="${1:?}" -opt="__${arg##*-}__" -shift - -case "$arg" in - "-") - # TODO - ;; - - "--") - # TODO - ;; - - *) - if [[ -f $ZPLUG_ROOT/autoload/options/$opt ]]; then - # call option file if exists - $opt "$@" - - else - __zplug::print::print::die \ - "[zplug] $arg: no such option\n" - return 1 - fi - ;; -esac diff --git a/autoload/utils/__parser__ b/autoload/utils/__parser__ deleted file mode 100644 index 54bcc9ff..00000000 --- a/autoload/utils/__parser__ +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "print/print" - -local arg="$1" tag -local -a tags - -if [[ -z $arg ]]; then - __zplug::print::print::die "[zplug] $funcstack[1]: too few arguments\n" - return 1 -fi - -__zplug::core::core::get_tags -tags=( "${reply[@]}" ) - -reply=("name" "$arg") -for tag in "${tags[@]}" -do - reply+=("$tag" "$(__${tag}__ "$arg")") -done diff --git a/autoload/utils/__releases__ b/autoload/utils/__releases__ deleted file mode 100644 index 3c23d0bf..00000000 --- a/autoload/utils/__releases__ +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "print/print" - -local index -local update=false -local -i ret=0 -local -a candidates_list binaries -local repository -local tag_at tag_use -local bit one_uri artifact -local curl url_format -local curl2 url_format2 -local repo command_name - -while (( $# > 0 )) -do - case "$1" in - --use) - tag_use="$2"; shift - if [[ $tag_use == '*.zsh' ]]; then - tag_use= - fi - ;; - --at) - tag_at="$2"; shift - ;; - -*|--*) - __zplug::print::print::die "$1: Unknown option\n" - return 1 - ;; - *) - repository="$1" - ;; - esac - shift -done - -# Initialize -{ - if [[ ! $repository =~ ^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$ ]]; then - __zplug::print::print::die "$repository: invalid repository type\n" - return 1 - fi - if [[ $tag_at == master ]]; then - tag_at="latest" - fi - if [[ -n $tag_at && $tag_at != "latest" ]]; then - tag_at="tag/$tag_at" - else - tag_at="latest" - fi - - url_format="https://github.com/$repository/releases/$tag_at" - if (( $+commands[curl] )); then - curl="curl -fsSL" - curl2="curl -L -O" - elif (( $+commands[wget] )); then - curl="wget -qO -" - curl2="wget" - fi - - # Get machine information - is_64() { uname -m | grep -q "64$" } - if is_64; then - bit="64" - else - bit="386" - fi - - if [[ -n $tag_use ]]; then - tag_use="$(__zplug::core::core::glob2regexp "$tag_use")" - else - tag_use="$(__zplug::core::core::get_os)" - if __zplug::core::core::is_osx; then - tag_use="(darwin|osx)" - fi - fi -} - -{ - eval "$curl $url_format" 2>/dev/null \ - | grep -o '/'"$repository"'/releases/download/[^"]*' \ - | read -d '\n' -A candidates_list - if (( $#candidates_list == 0 )); then - __zplug::print::print::die "$repository: there are no available releases\n" - return 1 - fi - - echo "${(F)candidates_list}" \ - | grep -E "${tag_use:-}" \ - | grep "$bit" \ - | head -n 1 \ - | read one_uri - if [[ -z $one_uri ]]; then - __zplug::print::print::die "$repository: repository not found\n" - return 1 - fi - - # For updating - repo="$ZPLUG_REPOS/$repository" - command_name="${repo:t}" - if [[ -d $repo ]]; then - # Update - if [[ -f $repo/INDEX ]]; then - index="$(<"$repo/INDEX")" - if [[ $tag_at == "latest" ]]; then - if grep -q "$index" <<<"$one_uri"; then - # up-to-date - return 4 - else - : - fi - else - # up-to-date - return 1 - fi - fi - else - # Not update - mkdir -p "$repo" - fi -} - -# Finalize -( - builtin cd -q "$repo" - url_format2="https://github.com$one_uri" - eval "$curl2 $url_format2" &>/dev/null - artifact="${one_uri:t}" - - case "$artifact" in - *.zip) - unzip "$artifact" &>/dev/null - rm -f "$artifact" - ;; - *.tar.gz|*.tgz) - tar xvf "$artifact" &>/dev/null - rm -f "$artifact" - ;; - *.*) - __zplug::print::print::die "$artifact: Unknown format\n" - return 1 - ;; - *) - # Through - ;; - esac - - file **/*(N-.) \ - | awk -F: '$2 ~ /executable/{print $1}' \ - | read -d '\n' -A binaries - - if (( $#binaries == 0 )); then - __zplug::print::print::die "$command_name: failed to grab binaries from GitHub Releases\n" - return 1 - fi - mv -f "$binaries[1]" "$command_name" - chmod 755 "$command_name" - rm -rf *~"$command_name"(N) - - if [[ -x $command_name ]]; then - __zplug::print::print::put "$command_name: Installed successfully\n" - else - __zplug::print::print::die "$command_name: Failed to install\n" - ret=1 - fi - # builtin cd -q "$OLDPWD" - echo "${one_uri:h:t}" >"$repo/INDEX" -) - -return $ret diff --git a/autoload/utils/__self__ b/autoload/utils/__self__ deleted file mode 100644 index 90e310f6..00000000 --- a/autoload/utils/__self__ +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "print/print" - -local main -main="zplug/zplug" - -__zplug::print::print::put "$fg_bold[default] * zplug self management$reset_color\n" - -if __check__ "$main"; then - __update__ "$main" -else - if ! __zplug::core::core::zpluged "$main"; then - __add__ "$main" - fi - __install__ "$main" -fi - -ln -snf \ - "$ZPLUG_REPOS/$main/init.zsh" \ - "$ZPLUG_HOME/init.zsh" - -if (( $status == 0)) && [[ -d $ZPLUG_REPOS/$main ]]; then - __zplug::print::print::put "$fg[green]Everything is ready. " - __zplug::print::print::put "$fg_bold[default]($ZPLUG_HOME/zplug)$reset_color\n" -else - __zplug::print::print::die "$fg[red]Error occured (see ${(%):-"%U"}$_ZPLUG_URL${(%):-"%u"})$reset_color\n" - return 1 -fi diff --git a/autoload/zplug b/autoload/zplug index dc9e582c..cb158725 100644 --- a/autoload/zplug +++ b/autoload/zplug @@ -1,39 +1,30 @@ #!/usr/bin/env zsh -source "$ZPLUG_ROOT/autoload/init.zsh" -source "$ZPLUG_ROOT/autoload/autoload.zsh" - local arg="$1" case "$arg" in - -* | --* ) - __options__ "$@" - return $status + -* | --*) + __zplug::core::options::parse "$argv[@]" ;; - check | install | status | update) + check | install | update | list | clean | status | clear | load | info) shift - __${arg}__ "${@:-${(k)zplugs[@]}}" - return $status + __zplug::core::core::run_interfaces \ + "$arg" \ + "$argv[@]" ;; - clean | clear | list | load | info) - shift - __${arg}__ "$@" - return $status + */*) + __zplug::core::add::to_zplugs "$argv[@]" ;; "") - # TODO - ;; - - */*) - __add__ "$@" - return $status + __zplug::core::arguments::none ;; *) - __arguments__ "$@" - return $status + __zplug::core::arguments::exec "$argv[@]" ;; esac + +return $status diff --git a/base/base/base.zsh b/base/base/base.zsh new file mode 100644 index 00000000..de2b234a --- /dev/null +++ b/base/base/base.zsh @@ -0,0 +1,125 @@ +__zplug::base::base::is_cli() +{ + # Return true if you run from cli + [[ $- =~ s ]] + return $status +} + +__zplug::base::base::zpluged() +{ + local arg="$1" zplug repo + local -A zspec + + if [[ -z $arg ]]; then + (( $+zplugs )) + return $status + else + if [[ $arg == $_ZPLUG_OHMYZSH ]]; then + for zplug in "${(k)zplugs[@]}" + do + __zplug::core::tags::parse "$zplug" + zspec=( "${reply[@]}" ) + case "$zspec[from]" in + "oh-my-zsh") + return 0 + ;; + esac + done + else + repo="$arg" + fi + (( $+zplugs[$repo] )) + return $status + fi +} + +__zplug::base::base::version_requirement() +{ + local -i idx + local -a min val + + [[ $1 == $2 ]] && return 0 + + val=("${(s:.:)1}") + min=("${(s:.:)2}") + + for (( idx=1; idx <= $#val; idx++ )) + do + if (( val[$idx] > ${min[$idx]:-0} )); then + return 0 + elif (( val[$idx] < ${min[$idx]:-0} )); then + return 1 + fi + done + + return 1 +} + +__zplug::base::base::git_version() +{ + # Return false if git command doesn't exist + if (( ! $+commands[git] )); then + return 1 + fi + + __zplug::base::base::version_requirement \ + ${(M)${(z)"$(git --version)"}:#[0-9]*[0-9]} \ + "${@:?}" + return $status +} + +__zplug::base::base::zsh_version() +{ + __zplug::base::base::version_requirement \ + "$ZSH_VERSION" \ + "${@:?}" + return $status +} + +__zplug::base::base::osx_version() +{ + (( $+commands[sw_vers] )) || return 1 + __zplug::base::base::version_requirement \ + ${${(M)${(@f)"$(sw_vers)"}:#ProductVersion*}[2]} \ + "${@:?}" + return $status +} + +__zplug::base::base::get_os() +{ + typeset -gx PLATFORM + local os + + os="${(L)OSTYPE-"$(uname)"}" + case "$os" in + *'linux'*) PLATFORM='linux' ;; + *'darwin'*) PLATFORM='darwin' ;; + *'bsd'*) PLATFORM='bsd' ;; + *) PLATFORM='unknown' ;; + esac + + echo "$PLATFORM" +} + +__zplug::base::base::is_osx() +{ + [[ ${(L)OSTYPE:-"$(uname)"} == *darwin* ]] +} + +__zplug::base::base::is_linux() +{ + [[ ${(L)OSTYPE:-"$(uname)"} == *linux* ]] +} + +__zplug::base::base::packaging() +{ + local k + + for k in "${(k)zplugs[@]}" + do + echo "$k" + done \ + | awk \ + -f "$_ZPLUG_AWKPATH/packaging.awk" \ + -v pkg="${1:?}" +} diff --git a/base/cli/getopts.zsh b/base/cli/getopts.zsh deleted file mode 100644 index 535a4ee9..00000000 --- a/base/cli/getopts.zsh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env zsh - -__getopts() { - printf -- "%s\n" $argv | sed -E ' - s/^-([A-Za-z]+)/- \1 / - s/^--([A-Za-z0-9_-]+)(!?)=?(.*)/-- \1 \3 \2 /' \ - | awk -f "$ZPLUG_ROOT/misc/share/getopts.awk" -} diff --git a/base/core/add.zsh b/base/core/add.zsh new file mode 100644 index 00000000..664dbc79 --- /dev/null +++ b/base/core/add.zsh @@ -0,0 +1,101 @@ +__zplug::core::add::to_zplugs() +{ + local name + local tag key val + local -a tags + local -a re_tags + + tags=( ${(s/, /)@:gs/, */, } ) + name="$tags[1]" + tags[1]=() + + # DEPRECATED: pipe + if [[ -p /dev/stdin ]]; then + __zplug::core::v1::pipe + return $status + fi + + # In the case of "from:local", it accepts multiple slashes + if [[ ! $name =~ [~$/] ]] && [[ ! $name =~ "^[^/]+/[^/]+$" ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "${(qq)name} is invalid package name\n" + return 1 + fi + + if __zplug::base::base::is_cli; then + if __zplug::base::base::zpluged "$name"; then + __zplug::io::print::f \ + --die \ + --zplug \ + "$name: already managed\n" + return 1 + else + # Add to the external file + __zplug::io::file::append \ + "zplug ${(qqq)name}${tags[@]:+", ${(j:, :)${(q)tags[@]}}"}" + fi + fi + + name="$(__zplug::core::add::proc_at-sign "$name")" + + # Automatically add "as:itself" to tag array + # if $name is zplug repository + if [[ $name == "zplug/zplug" ]]; then + re_tags="as:itself" + fi + + # Reconstruct the tag information + for tag in "${tags[@]}" + do + key=${${(s.:.)tag}[1]} + val=${${(s.:.)tag}[2]} + + if (( $+_zplug_tags[$key] )); then + case $key in + "of" | "file" | "commit" | "do") + # DEPRECATED: old tags + __zplug::core::v1::tags "$key" + ;; + "from") + __zplug::core::sources::call "$val" + ;; + esac + + re_tags+=( "$key:$val" ) + else + __zplug::io::print::f \ + --die \ + --zplug \ + "$tag: '$key' is invalid tag name\n" + return 1 + fi + done + + # In case of that 'from' tag is default value + __zplug::core::sources::use_default + + # Add to zplugs (hash array) + # "$name" "$re_tags[@]" (<-- "key" "value") + # \ `-- '"as:plugin, from:github"' + # `-- e.g. 'enhancd' + zplugs+=("$name" "${(j:, :)re_tags[@]:-}") +} + +__zplug::core::add::proc_at-sign() +{ + local name="${1:?}" key + local -i max=0 + + for key in "${(k)zplugs[@]}" + do + if [[ $key =~ ^$name@*$ ]] && (( $max < $#key )); then + max=$#key + name="${key}@" + fi + done + + echo "$name" +} diff --git a/base/core/arguments.zsh b/base/core/arguments.zsh new file mode 100644 index 00000000..c0656ea1 --- /dev/null +++ b/base/core/arguments.zsh @@ -0,0 +1,91 @@ +__zplug::core::arguments::exec() +{ + local arg="${1:?}" + + reply=() + __zplug::core::commands::user_defined + + # User-defined command + if [[ -n ${(M)reply[@]:#$arg} ]]; then + eval "$commands[zplug-$arg]" + return $status + fi + + # Fuzzy match + if ! __zplug::core::arguments::auto_correct "$arg"; then + return 1 + fi + + zplug "$reply[1]" ${2:+"$argv[2,-1]"} +} + +__zplug::core::arguments::auto_correct() +{ + local arg="${1:?}" + local -i ret=0 + local -a cmds reply_cmds + + reply_cmds=() + + # Add user-defined commands + __zplug::core::commands::user_defined + reply_cmds+=( "${reply[@]}" ) + + # Add zplug subcommands + __zplug::core::commands::get --key + reply_cmds+=( "${reply[@]}" ) + + cmds=( + ${(@f)"$(awk \ + -f "$_ZPLUG_AWKPATH/fuzzy.awk" \ + -v search_string="$arg" \ + <<<"${(F)reply_cmds:gs:_:}" + )":-} + ) + + case $#cmds in + 0) + __zplug::io::print::f \ + --die \ + --zplug \ + "$arg: no such command\n" + ret=1 + ;; + 1) + __zplug::io::print::f \ + --die \ + --zplug \ + --warn \ + "You called a zplug command named '%s', which does not exist.\n" \ + "Continuing under the assumption that you meant '%s'.\n" \ + -- \ + "$arg" \ + "$fg[green]$cmds[1]$reset_color" + + reply=( "$cmds[1]" ) + ;; + *) + __zplug::io::print::f \ + --die \ + --zplug \ + --warn \ + "'%s' is not a zplug command. see 'zplug --help'.\n" \ + "Did you mean one of these?\n" \ + -- \ + "$arg" + __zplug::io::print::die \ + "$fg[yellow]\t- $reset_color%s\n" \ + "${cmds[@]}" + + ret=1 + ;; + esac + + return $ret +} + +__zplug::core::arguments::none() +{ + # TODO + : +} diff --git a/base/core/commands.zsh b/base/core/commands.zsh new file mode 100644 index 00000000..bd1160fa --- /dev/null +++ b/base/core/commands.zsh @@ -0,0 +1,23 @@ +__zplug::core::commands::get() +{ + __zplug::core::core::get_interfaces \ + "commands" \ + "$argv[@]" +} + +__zplug::core::commands::user_defined() +{ + local -a user_cmds + + # reset + reply=() + + user_cmds=( ${^path[@]}/zplug-*(N-.:t:gs:zplug-:) ) + if (( $#user_cmds > 0 )); then + # Be unique + reply+=( "${(u)user_cmds[@]}" ) + return 0 + fi + + return 1 +} diff --git a/base/core/core.zsh b/base/core/core.zsh index f0255320..63e6e701 100644 --- a/base/core/core.zsh +++ b/base/core/core.zsh @@ -1,254 +1,246 @@ -#!/usr/bin/env zsh - -__zplug::core::core::is_cli() { - [[ $- =~ s ]] -} - -__zplug::core::core::is_external() { - local source_name - - source_name="${1:?}" - [[ -f $ZPLUG_ROOT/base/sources/$source_name.zsh ]] -} - -__zplug::core::core::is_handler_defined() { - local subcommand - local source_name - local handler_name - - subcommand="${1:?}" - source_name="${2:?}" - handler_name="__zplug::$source_name::$subcommand" - - if ! __zplug::core::core::is_external "$source_name"; then - return 1 - fi - - (( $+functions[$handler_name] )) -} - -__zplug::core::core::zpluged() { - local arg zplug repo - local -A zspec - - autoload -Uz __parser__ - arg="$1" - - if [[ -z $arg ]]; then - (( $+zplugs )) - return $status - else - if [[ $arg == $_ZPLUG_OHMYZSH ]]; then - for zplug in "${(k)zplugs[@]}" - do - __parser__ "$zplug" - zspec=( "${reply[@]}" ) - case "$zspec[from]" in - "oh-my-zsh") - return 0 - ;; - esac - done - else - repo="$arg" - fi - (( $+zplugs[$repo] )) - return $status - fi -} - -__zplug::core::core::get_autoload_dirs() { - if (( $# > 0 )); then - reply=("$@") - else - reply=( - "$ZPLUG_ROOT/autoload/commands" - "$ZPLUG_ROOT/autoload/options" - "$ZPLUG_ROOT/autoload/tags" - "$ZPLUG_ROOT/autoload/utils" - ) - fi -} - -__zplug::core::core::get_autoload_paths() { - local -a fs - __zplug::core::core::get_autoload_dirs "$@" - fs=( "${^reply[@]}"/__*(N-.) ) - (( $#fs > 0 )) && reply=( "${fs[@]}" ) -} - -__zplug::core::core::get_autoload_files() { - __zplug::core::core::get_autoload_paths "$@" - (( $#reply > 0 )) && reply=( "${reply[@]:t}" ) -} - -__zplug::core::core::get_tags() { - reply=( "$ZPLUG_ROOT/autoload/tags/"__*__(:t:gs:__:) ) -} +__zplug::core::core::get_interfaces() +{ + local arg name desc + local target + local -a targets + local interface + local -A interfaces + local is_key=false is_prefix=false + + while (( $# > 0 )) + do + arg="$1" + case "$arg" in + --key) + is_key=true + ;; + --prefix) + is_prefix=true + ;; + -* | --*) + ;; + "") + ;; + *) + targets+=( "$arg" ) + ;; + esac + shift + done -__zplug::core::core::get_filter() { - local item x + # Initialize + reply=() - for item in "${(s.:.)1}" + for target in "${targets[@]}" do - x="${item%% *}" - # Check if x is available - if (( $+commands[$x] )); then - echo "$x" - return 0 + interfaces=() + for interface in "$ZPLUG_ROOT/autoload/$target"/__*__(N-.) + do + # TODO: /^.*desc(ription)?: ?/ + name="${interface:t:gs:_:}" + if $is_prefix; then + name="__${name}__" + fi + cat "$interface" \ + | awk ' + $0 ~ "# Description:" { + getline + sub(/^# */, "") + print $0 + }' \ + | read desc + interfaces[$name]="$desc" + done + + if $is_key; then + reply+=( "${(k)interfaces[@]}" ) else - continue + reply+=( "${(kv)interfaces[@]}" ) fi done - - return 1 } -__zplug::core::core::version_requirement() { - local -i idx - local -a min val +__zplug::core::core::run_interfaces() +{ + local arg="${1:?}"; shift + local interface + local -i ret=0 - [[ $1 == $2 ]] && return 0 + interface="__${arg:gs:_:}__" - val=("${(s:.:)1}") - min=("${(s:.:)2}") + # Do autoload if not exists in $functions + if (( ! $+functions[$interface] )); then + autoload -Uz "$interface" + fi - for (( idx=1; idx <= $#val; idx++ )) - do - if (( val[$idx] > ${min[$idx]:-0} )); then - return 0 - elif (( val[$idx] < ${min[$idx]:-0} )); then + # Execute + ${=interface} "$argv[@]" + ret=$status + + # TODO: + unfunction "$interface" \ + 2> >(__zplug::io::log::capture) >/dev/null + + return $ret +} + +__zplug::core::core::prepare() +{ + # Unique array + typeset -gx -U path + typeset -gx -U fpath + + # Add to the PATH + path=( + "$ZPLUG_ROOT"/bin + "$ZPLUG_HOME"/bin + "$path[@]" + ) + + # Add to the FPATH + fpath=( + "$ZPLUG_ROOT"/misc/completions(N-/) + "$ZPLUG_ROOT/base/sources" + "$fpath[@]" + ) + + # Check whether you meet the requirements for using zplug + # 1. zsh 4.3.9 or more + # 2. git + # 3. nawk or gawk + { + if ! __zplug::base::base::zsh_version 4.3.9; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "zplug does not work this version of zsh $ZSH_VERSION.\n" \ + "You must use zsh 4.3.9 or later.\n" return 1 fi - done - - return 1 -} -__zplug::core::core::git_version() { - __zplug::core::core::version_requirement \ - ${(M)${(z)"$(git --version)"}:#[0-9]*[0-9]} \ - "${@:?}" - return $status -} - -__zplug::core::core::zsh_version() { - __zplug::core::core::version_requirement \ - "$ZSH_VERSION" \ - "${@:?}" - return $status -} - -__zplug::core::core::osx_version() { - (( $+commands[sw_vers] )) || return 1 - __zplug::core::core::version_requirement \ - ${${(M)${(@f)"$(sw_vers)"}:#ProductVersion*}[2]} \ - "${@:?}" - return $status -} - -__zplug::core::core::get_os() { - typeset -gx PLATFORM - local os - - os="${(L)OSTYPE-"$(uname)"}" - case "$os" in - *'linux'*) PLATFORM='linux' ;; - *'darwin'*) PLATFORM='darwin' ;; - *'bsd'*) PLATFORM='bsd' ;; - *) PLATFORM='unknown' ;; - esac - - echo "$PLATFORM" -} + if ! __zplug::base::base::git_version 1.7; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "git command not found in \$PATH\n" \ + "zplug depends on git 1.7 or later.\n" + return 1 + fi -__zplug::core::core::is_osx() { - [[ ${(L)OSTYPE:-"$(uname)"} == *darwin* ]] -} + if ! __zplug::utils::awk::available; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + 'No available AWK variant in your $PATH\n' + return 1 + fi + } -__zplug::core::core::is_linux() { - [[ ${(L)OSTYPE:-"$(uname)"} == *linux* ]] -} + # Release zplug variables and export + __zplug::core::core::variable || return 1 -__zplug::core::core::glob2regexp() { - local -i i=0 - local glob="${1:?}" char + mkdir -p "$ZPLUG_REPOS" + mkdir -p "$ZPLUG_HOME/bin" - printf "^" - for ((; i < $#glob; i++)) - do - char="${glob:$i:1}" - case "$char" in - \*) - printf '.*' - ;; - .) - printf '\.' - ;; - "{") - printf '(' - ;; - "}") - printf ')' - ;; - ,) - printf '|' - ;; - "?") - printf '.' - ;; - \\) - printf '\\\\' - ;; - *) - printf "$char" - ;; - esac - done - printf "$\n" + # Run compinit if zplug comp file hasn't load + if (( ! $+functions[_zplug] )); then + compinit + fi } -__zplug::core::core::remove_deadlinks() { - local link +__zplug::core::core::variable() +{ + # for 'autoload -Uz zplug' in another subshell + export FPATH="$ZPLUG_ROOT/autoload:$FPATH" + + typeset -gx ZPLUG_HOME=${ZPLUG_HOME:-~/.zplug} + typeset -gx -i ZPLUG_THREADS=${ZPLUG_THREADS:-16} + typeset -gx -i ZPLUG_CLONE_DEPTH=${ZPLUG_CLONE_DEPTH:-0} + typeset -gx ZPLUG_PROTOCOL=${ZPLUG_PROTOCOL:-HTTPS} + typeset -gx ZPLUG_FILTER=${ZPLUG_FILTER:-"fzf-tmux:fzf:peco:percol:fzy:zaw"} + typeset -gx ZPLUG_LOADFILE=${ZPLUG_LOADFILE:-$ZPLUG_HOME/packages.zsh} + typeset -gx ZPLUG_USE_CACHE=${ZPLUG_USE_CACHE:-true} + typeset -gx ZPLUG_CACHE_FILE=${ZPLUG_CACHE_FILE:-$ZPLUG_HOME/.cache} + typeset -gx ZPLUG_REPOS=${ZPLUG_REPOS:-$ZPLUG_HOME/repos} + typeset -gx ZPLUG_SUDO_PASSWORD + typeset -gx ZPLUG_ERROR_LOG=${ZPLUG_ERROR_LOG:-$ZPLUG_HOME/.error_log} + + typeset -gx _ZPLUG_VERSION="2.1.0" + typeset -gx _ZPLUG_URL="https://github.com/zplug/zplug" + typeset -gx _ZPLUG_OHMYZSH="robbyrussell/oh-my-zsh" + typeset -gx _ZPLUG_AWKPATH="$ZPLUG_ROOT/misc/contrib" + + typeset -gx -i _ZPLUG_STATUS_SUCCESS=0 + typeset -gx -i _ZPLUG_STATUS_FAILURE=1 + typeset -gx -i _ZPLUG_STATUS_TRUE=0 + typeset -gx -i _ZPLUG_STATUS_FALSE=1 + typeset -gx -i _ZPLUG_STATUS_REPO_NOT_FOUND=2 + typeset -gx -i _ZPLUG_STATUS_REPO_FROZEN=3 + typeset -gx -i _ZPLUG_STATUS_REPO_UP_TO_DATE=4 + typeset -gx -i _ZPLUG_STATUS_REPO_LOCAL=5 + typeset -gx -i _ZPLUG_STATUS_INVALID_ARGUMENT=6 + typeset -gx -i _ZPLUG_STATUS_INVALID_OPTION=7 + typeset -gx -i _ZPLUG_STATUS_ERROR_PARSE=8 + typeset -gx -i _ZPLUG_STATUS_=255 + + if (( $+ZPLUG_SHALLOW )); then + __zplug::io::print::f \ + --die \ + --zplug \ + --warn \ + "ZPLUG_SHALLOW is deprecated." \ + "Please use 'export ZPLUG_CLONE_DEPTH=1' instead.\n" + fi - for link in "$@" - do - if [[ -L $link ]] && [[ ! -e $link ]]; then - rm -f "$link" + # zplug core variables + { + typeset -gx -A -U \ + _zplug_options \ + _zplug_commands \ + _zplug_tags + + __zplug::core::options::get; _zplug_options=( "${reply[@]}" ) + __zplug::core::commands::get; _zplug_commands=( "${reply[@]}" ) + __zplug::core::tags::get; _zplug_tags=( "${reply[@]}" ) + } + + # boolean + { + typeset -gx -a \ + _zplug_boolean_true \ + _zplug_boolean_false + + _zplug_boolean_true=("true" "yes" "on" 1) + _zplug_boolean_false=("false" "no" "off" 0) + } + + # context ":zplug:config:setopt" + { + local -a only_subshell + typeset -gx _ZPLUG_CONFIG_SUBSHELL=":" + + zstyle -a ":zplug:config:setopt" \ + only_subshell \ + only_subshell + zstyle -t ":zplug:config:setopt" \ + same_curshell + + if (( $_zplug_boolean_true[(I)$same_curshell] )); then + only_subshell=( + "${only_subshell[@]:gs:_:}" + $(setopt) + ) fi - done -} - -__zplug::core::core::packaging() { - local k - for k in "${(k)zplugs[@]}" - do - echo "$k" - done \ - | awk \ - -f "$ZPLUG_ROOT/misc/share/packaging.awk" \ - -v pkg="${1:?}" -} - -# Call the handler of the external source if defined -__zplug::core::core::use_handler() { - local subcommand - local source_name - local handler_name - local line - - subcommand="${1:?}" - source_name="${2:?}" - handler_name="__zplug::$source_name::$subcommand" - line="${3:?}" - - if ! __zplug::core::core::is_handler_defined "$subcommand" "$source_name"; then - # Callback function undefined - return 1 - fi - - eval "$handler_name '$line'" + if (( $#only_subshell > 0 )); then + _ZPLUG_CONFIG_SUBSHELL="setopt ${(u)only_subshell[@]}" + fi + } - return $status + typeset -gx -A em + em[under]="${(%):-"%U"}" + em[bold]="${(%):-"%B"}" } diff --git a/base/core/git.zsh b/base/core/git.zsh deleted file mode 100644 index ef7aa106..00000000 --- a/base/core/git.zsh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "print/print" - -__zplug::core::git::get_head_branch_name() { - local head_branch - - if __zplug::core::core::git_version 1.7.10; then - head_branch="$(git symbolic-ref -q --short HEAD)" - else - head_branch="${$(git symbolic-ref -q HEAD)#refs/heads/}" - fi - - if [[ -z $head_branch ]]; then - git rev-parse --short HEAD - return 1 - fi - __zplug::print::print::put "$head_branch\n" -} - -__zplug::core::git::get_remote_name() { - local branch remote_name - branch="$1" - - if [[ -z $branch ]]; then - __zplug::print::print::die "too few arguments\n" - return 1 - fi - - remote_name="$(git config branch.${branch}.remote)" - if [[ -z $remote_name ]]; then - __zplug::print::print::die "no remote repository\n" - return 1 - fi - - __zplug::print::print::put "$remote_name\n" -} - -__zplug::core::git::get_remote_state() { - local remote_name branch - local merge_branch remote_show - local state url - local -a behind_ahead - local -i behind ahead - - branch="$1" - remote_name="$(__zplug::core::git::get_remote_name "$branch")" - - if (( $status == 0 )); then - merge_branch="${$(git config branch.${branch}.merge)#refs/heads/}" - remote_show="$(git remote show "$remote_name")" - state="$(grep "^ *$branch *pushes" <<<"$remote_show" | sed 's/.*(\(.*\)).*/\1/')" - - if [[ -z $state ]]; then - behind_ahead=( ${(@f)"$(git rev-list \ - --left-right \ - --count \ - "$remote_name/$merge_branch"...$branch)"} ) - behind=$behind_ahead[1] - ahead=$behind_ahead[2] - - if (( $behind > 0 )); then - state="local out of date" - else - origin_head="${$(git ls-remote origin HEAD)[1]}" - if ! git rev-parse -q "$origin_head" &>/dev/null; then - state="local out of date" - elif (( $ahead > 0 )); then - state="fast-forwardable" - else - state="up to date" - fi - fi - fi - - url="$(grep '^ *Push' <<<"$remote_show" | sed 's/^.*URL: \(.*\)$/\1/')" - else - state="$remote_name" - fi - - echo "$state" - echo "$url" -} - -__zplug::core::git::get_state() { - local branch - local -a res - local state url - - if [[ ! -e .git ]]; then - state="not git repo" - fi - - branch="$(__zplug::core::git::get_head_branch_name)" - if (( $status == 0 )); then - res=( ${(@f)"$(__zplug::core::git::get_remote_state "$branch")"} ) - state="$res[1]" - url="$res[2]" - else - state="not on any branch" - fi - - case "$state" in - "local out of date") - state="${fg[red]}${state}${reset_color}" - ;; - "up to date") - state="${fg[green]}${state}${reset_color}" - ;; - esac - __zplug::print::print::put "($state) '${url:-?}'\n" -} - -__zplug::core::git::remote_url() { - if [[ ! -e .git ]]; then - return 1 - fi - - git remote -v | sed -n '1p' | awk '{print $2}' -} diff --git a/base/core/options.zsh b/base/core/options.zsh new file mode 100644 index 00000000..b17cc211 --- /dev/null +++ b/base/core/options.zsh @@ -0,0 +1,96 @@ +__zplug::core::options::get() +{ + __zplug::core::core::get_interfaces \ + "options" \ + "$argv[@]" +} + +__zplug::core::options::parse() +{ + local arg + local -i ret=0 + + while (( $# > 0 )) + do + arg="${1:?}" + case "$arg" in + "--") + # TODO + ;; + + "-") + # TODO + ;; + + --*) + __zplug::core::options::long \ + "$arg" \ + ${2:+"$argv[2,-1]"} + ret=$status + ;; + + -*) + __zplug::core::options::short \ + "$arg" \ + ${2:+"$argv[2,-1]"} + ret=$status + ;; + + *) + # Impossible condition + ;; + esac + shift + done + + return $ret +} + +__zplug::core::options::short() +{ + __zplug::core::options::unknown "$arg" + return $status +} + +__zplug::core::options::long() +{ + local key value + local -a args opts + + __zplug::utils::shell::getopts "$argv[@]" \ + | while read key value; \ + do + case "$key" in + _) + args+=( "$value" ) + ;; + *) + opts+=( "$key" ) + args+=( "$value" ) + ;; + esac + done + + opt="$opts[1]" + + if [[ -f $ZPLUG_ROOT/autoload/options/__${opt}__ ]]; then + __zplug::core::core::run_interfaces \ + "$opt" \ + "$args[@]" + return $status + else + __zplug::core::options::unknown "$argv[1]" + return $status + fi +} + +__zplug::core::options::unknown() +{ + local arg="$1" + + __zplug::io::print::f \ + --die \ + --zplug \ + "$arg: unknown option\n" + return 1 +} diff --git a/base/core/self.zsh b/base/core/self.zsh new file mode 100644 index 00000000..fd25bc1c --- /dev/null +++ b/base/core/self.zsh @@ -0,0 +1,91 @@ +__zplug::core::self::init() +{ + local repo="zplug/zplug" + local src="$ZPLUG_REPOS/$repo/init.zsh" + local dst="$ZPLUG_HOME/init.zsh" + + if [[ ! -f $src ]]; then + __zplug::io::log::error \ + "$src: no such file or directory" + return 1 + fi + + # Link + ln -snf "$src" "$dst" +} + +__zplug::core::self::update() +{ + local HEAD + + if ! __zplug::base::base::zpluged "zplug/zplug"; then + __zplug::io::print::f \ + --die \ + --zplug \ + "zplug/zplug: no package managed by zplug\n" + return 1 + fi + + # If there is a difference in the remote and local + # re-install zplug by itself and initialize + if ! __zplug::core::self::info --up-to-date; then + # TODO: + __zplug::core::core::run_interfaces \ + "update" \ + "zplug/zplug" + return $status + fi + + __zplug::core::self::info --HEAD \ + | read HEAD + __zplug::io::print::f \ + --die \ + --zplug \ + "%s (v%s) %s\n" \ + "$fg[white]up-to-date$reset_color" \ + "$_ZPLUG_VERSION" \ + "$em[under]$HEAD[1,8]$reset_color" + + return 1 +} + +__zplug::core::self::load() +{ + __zplug::core::self::init +} + +__zplug::core::self::info() +{ + local arg + local -A revisions + + __zplug::utils::git::status "zplug/zplug" + revisions=( "$reply[@]" ) + + while (( $# > 0 )) + do + arg="$1" + case "$arg" in + --up-to-date) + # local and origin/master are the same + if [[ $revisions[local] == $revisions[master] ]]; then + return 0 + fi + return 1 + ;; + --local) + echo "$revisions[local]" + ;; + --HEAD) + echo "$revisions[master]" + ;; + --version) + echo "$revisions[$_ZPLUG_VERSION^\{\}]" + ;; + -*|--*) + return 1 + ;; + esac + shift + done +} diff --git a/base/core/sources.zsh b/base/core/sources.zsh new file mode 100644 index 00000000..758dc047 --- /dev/null +++ b/base/core/sources.zsh @@ -0,0 +1,81 @@ +__zplug::core::sources::is_exists() +{ + local source_name="${1:?}" + + [[ -f $ZPLUG_ROOT/base/sources/$source_name.zsh ]] + return $status +} + +__zplug::core::sources::is_handler_defined() +{ + local subcommand source_name handler_name + + subcommand="${1:?}" + source_name="${2:?}" + handler_name="__zplug::sources::$source_name::$subcommand" + + if ! __zplug::core::sources::is_exists "$source_name"; then + return $_ZPLUG_STATUS_FALSE + fi + + (( $+functions[$handler_name] )) + return $status +} + +# Call the handler of the external source if defined +__zplug::core::sources::use_handler() +{ + local \ + subcommand="${1:?}" \ + source_name="${2:?}" \ + repo="${3:?}" + local handler_name="__zplug::sources::$source_name::$subcommand" + + case "$repo" in + "zplug/zplug") + # Search the handler that has a name including 'self' word + handler_name="__zplug::core::self::$subcommand" + (( $+functions[$handler_name] )) || + handler_name="__zplug::sources::github::$subcommand" + # If it isn't found, search another handler + # Nevertheless, callback is undefined + (( $+functions[$handler_name] )) || + return $_ZPLUG_STATUS_FAILURE + ;; + *) + if ! __zplug::core::sources::is_handler_defined "$subcommand" "$source_name"; then + # Callback function is undefined + return $_ZPLUG_STATUS_FAILURE + fi + ;; + esac + + eval "$handler_name '$repo'" + return $status +} + +__zplug::core::sources::call() +{ + local val="${1:?}" + + if __zplug::core::sources::is_exists "$val"; then + { + # Directory '/base/sources' needs to be included in FPATH + autoload -Uz "$val.zsh" + eval "$val.zsh" + unfunction "$val.zsh" + } \ + 2> >(__zplug::io::log::capture) >/dev/null + + fi +} + +__zplug::core::sources::use_default() +{ + local val + + # Get the default value + val="$(__zplug::core::core::run_interfaces 'from')" + + __zplug::core::sources::call "$val" +} diff --git a/base/core/tags.zsh b/base/core/tags.zsh new file mode 100644 index 00000000..456a284b --- /dev/null +++ b/base/core/tags.zsh @@ -0,0 +1,30 @@ +__zplug::core::tags::get() +{ + __zplug::core::core::get_interfaces \ + "tags" \ + "$argv[@]" +} + +__zplug::core::tags::parse() +{ + local arg="${1:?}" tag val + local -A tags + local -a pairs + + __zplug::core::tags::get + tags=( "${reply[@]}" ) + + pairs=("name" "$arg") + + for tag in "${(k)tags[@]}" + do + val="$( + __zplug::core::core::run_interfaces \ + "$tag" \ + "$arg" + )" + pairs+=("$tag" "$val") + done + + reply=( "$pairs[@]" ) +} diff --git a/base/core/v1.zsh b/base/core/v1.zsh new file mode 100644 index 00000000..5c5433b0 --- /dev/null +++ b/base/core/v1.zsh @@ -0,0 +1,48 @@ +__zplug::core::v1::tags() +{ + local key="${1:?}" new_key + + case "$key" in + "of") + new_key="use" + ;; + "file") + new_key="rename-to" + ;; + "commit") + new_key="at" + ;; + "do") + new_key="hook-build" + ;; + *) + # Not old tag + __zplug::io::print::f \ + --die \ + --zplug \ + "$key: this tag is still good\n" + return 1 + esac + + __zplug::io::print::f \ + --die \ + --zplug \ + --warn \ + "'%s' tag is deprecated. Please use '%s' tag instead (%s).\n" \ + "$fg[blue]$key$reset_color" \ + "$fg[blue]$new_key$reset_color" \ + "$fg[green]${name:gs:@::}$reset_color" + + return 1 +} + +__zplug::core::v1::pipe() +{ + __zplug::io::print::f \ + --die \ + --zplug \ + --warn \ + "pipe syntax is deprecated! Please use '%s' tag instead.\n" \ + "$fg[blue]on$reset_color" + return 1 +} diff --git a/base/init.zsh b/base/init.zsh index 8ee165bc..79cd4c96 100644 --- a/base/init.zsh +++ b/base/init.zsh @@ -1,62 +1,49 @@ -#!/usr/bin/env zsh -# init.zsh: -# This file is called only once - -if (( $+functions[__import] )); then - return 0 -fi - -typeset -gx -T \ - _ZPLUG_LIB_CALLED \ - _zplug_lib_called - -_zplug_lib_called=() - -__import() { - local f arg lib is_debug=false +__zplug::base() +{ + local load_file arg + local -aU load_files while (( $# > 0 )) do arg="$1" case "$arg" in - --debug) - shift - is_debug=true - ;; -*|--*) return 1 ;; + */'*') + # e.g. 'base/*' + load_files+=( "$ZPLUG_ROOT/base/${arg:h}"/*.zsh(N-.) ) + ;; */*) - shift - f="$ZPLUG_ROOT/base/${arg}.zsh" - if [[ ! -f $f ]]; then - f="" - continue - fi + # e.g. 'core/add' + load_files+=( "$ZPLUG_ROOT/base/${arg}.zsh"(N-.) ) ;; *) return 1 ;; esac + shift done - # invalid argument - if [[ -z $f ]]; then + # invalid format + if (( $#load_files == 0 )); then return 1 fi - lib="${f:h:t}/${f:t:r}" - if (( ! $_zplug_lib_called[(I)$lib] )); then - if $is_debug; then - printf "$f\n" - else - fpath=( - "${f:h}" - "${fpath[@]}" - ) - autoload -Uz "${f:t}" && eval "${f:t}" - unfunction "${f:t}" + fpath=( + "${load_files[@]:h}" + "${fpath[@]}" + ) + + for load_file in "${load_files[@]}" + do + if (( $+functions[$load_file] )); then + # already defined + continue fi - _zplug_lib_called+=("$lib") - fi + + autoload -Uz "${load_file:t}" && + eval "${load_file:t}" && + unfunction "${load_file:t}" + done } diff --git a/base/io/cache.zsh b/base/io/cache.zsh new file mode 100644 index 00000000..6629b7aa --- /dev/null +++ b/base/io/cache.zsh @@ -0,0 +1,130 @@ +__zplug::io::cache::create() +{ + local name + + for name in "${(ok)zplugs[@]}" + do + # In order to sort $zplugs[$name], + # do not quate this string + echo "${name}${zplugs[$name]:+, ${(os:, :)zplugs[$name]}}" + done +} + +__zplug::io::cache::load() +{ + local key + + $ZPLUG_USE_CACHE || return 2 + + if [[ -f $ZPLUG_CACHE_FILE ]]; then + 2> >(__zplug::io::log::capture) >/dev/null \ + diff -b \ + <( \ + awk \ + -f "$_ZPLUG_AWKPATH/read_cache.awk" \ + "$ZPLUG_CACHE_FILE" \ + ) \ + <( \ + __zplug::io::cache::create \ + ) + + case $status in + 0) + # same + source "$ZPLUG_CACHE_FILE" + return $status + ;; + 1) + # differ + ;; + 2) + # error + ;; + esac + fi + + # if cache file doesn't find, + # returns non-zero exit code + return 1 +} + +__zplug::io::cache::update() +{ + $ZPLUG_USE_CACHE || return 2 + + local load_command + + if [[ ! -d ${ZPLUG_CACHE_FILE:h} ]]; then + mkdir -p "${ZPLUG_CACHE_FILE:h}" + fi + + if [[ -f $ZPLUG_CACHE_FILE ]]; then + chmod a+w "$ZPLUG_CACHE_FILE" + fi + + { + __zplug::io::print::put '#!/usr/bin/env zsh\n\n' + __zplug::io::print::put '# This file was generated by zplug\n' + __zplug::io::print::put '# *** DO NOT EDIT THIS FILE ***\n\n' + __zplug::io::print::put '[[ $- =~ i ]] || exit\n' + if (( ! $path[(I)$ZPLUG_HOME/bin] )); then + __zplug::io::print::put 'export PATH="%s:$PATH"\n' "$ZPLUG_HOME/bin" + fi + __zplug::io::print::put 'export ZSH=${ZSH:-%s}\n' "$ZPLUG_REPOS/$_ZPLUG_OHMYZSH" + __zplug::io::print::put 'export ZSH_CACHE_DIR=${ZSH_CACHE_DIR:-$ZSH/cache}/\n\n' + + __zplug::io::print::put 'if $is_verbose; then\n' + __zplug::io::print::put ' echo "Static loading..." >&2\n' + __zplug::io::print::put 'fi\n' + if [[ -o prompt_subst ]]; then + __zplug::io::print::put '\nsetopt prompt_subst\n' + fi + __zplug::io::print::put '\n' + if (( $#load_commands > 0 )); then + __zplug::io::print::put '# Commands\n' + __zplug::io::print::put 'chmod a=rx "%s"\n' \ + "${(uk)load_commands[@]}" + for load_command in "${(uk)load_commands[@]}" + do + __zplug::io::print::put 'ln -snf "%s" "%s"\n' \ + "$load_command" \ + "$load_commands[$load_command]" + done + __zplug::io::print::put '\n' + fi + if (( $#load_plugins > 0 )); then + __zplug::io::print::put '# Plugins\n' + __zplug::io::print::put 'source %s\n' "${(uqqq)load_plugins[@]}" + __zplug::io::print::put '\n' + fi + if (( $#load_fpaths > 0 )); then + __zplug::io::print::put '# Fpath\n' + __zplug::io::print::put 'fpath=(\n' + __zplug::io::print::put '%s\n' "${(u)load_fpaths[@]}" + __zplug::io::print::put '$fpath\n' + __zplug::io::print::put ')\n' + fi + __zplug::io::print::put '\ncompinit -C -d %s\n\n' "$ZPLUG_HOME/zcompdump" + if (( $#nice_plugins > 0 )); then + __zplug::io::print::put '# Loading after compinit\n' + __zplug::io::print::put 'source %s\n' "${(qqq)nice_plugins[@]}" + __zplug::io::print::put '\n' + fi + if (( $#lazy_plugins > 0 )); then + __zplug::io::print::put '\n# Lazy loading plugins\n' + __zplug::io::print::put 'autoload -Uz %s\n' "${(qqq)lazy_plugins[@]:t}" + __zplug::io::print::put '\n' + fi + if (( $#hook_load_cmds > 0 )); then + __zplug::io::print::put '\n# Hooks after load\n' + __zplug::io::print::put '%s\n' "${hook_load_cmds[@]}" + __zplug::io::print::put '\n' + fi + __zplug::io::print::put '\nreturn 0\n' + __zplug::io::print::put '%s\n' "$(__zplug::io::cache::create)" + } >|"$ZPLUG_CACHE_FILE" + + if [[ -f $ZPLUG_CACHE_FILE ]]; then + chmod a-w "$ZPLUG_CACHE_FILE" + fi +} diff --git a/base/io/file.zsh b/base/io/file.zsh new file mode 100644 index 00000000..92879904 --- /dev/null +++ b/base/io/file.zsh @@ -0,0 +1,46 @@ +__zplug::io::file::load() +{ + if [[ -f $ZPLUG_LOADFILE ]]; then + source "$ZPLUG_LOADFILE" + return $status + else + return 1 + fi +} + +__zplug::io::file::generate() +{ + if [[ -f $ZPLUG_LOADFILE ]]; then + return 0 + fi + + cat <<-TEMPLATE >$ZPLUG_LOADFILE +#!/usr/bin/env zsh +# -*- mode: zsh -*- +# vim:ft=zsh +# +# *** ZPLUG EXTERNAL FILE *** +# You can register plugins or commands to zplug on the +# command-line. If you use zplug on the command-line, +# it is possible to write more easily its settings +# by grace of the command-line completion. +# In this case, zplug spit out its settings to +# $ZPLUG_LOADFILE instead of .zshrc. +# If you launch new zsh process, zplug load command +# automatically search this file and run source command. +# +# +# Example: +# zplug "b4b4r07/enhancd", as:plugin, use:"*.sh" +# zplug "rupa/z", as:plugin, use:"*.sh" +# +TEMPLATE +} + +__zplug::io::file::append() +{ + __zplug::io::file::generate + __zplug::io::print::put \ + "$@\n" \ + >>|"$ZPLUG_LOADFILE" +} diff --git a/base/io/log.zsh b/base/io/log.zsh new file mode 100644 index 00000000..6a4e3fbc --- /dev/null +++ b/base/io/log.zsh @@ -0,0 +1,130 @@ +__zplug::io::log::with_json() +{ + # Variables for error report + # - $funcfiletrace[@] + # - $funcsourcetrace[@] + # - $funcstack[@] + # - $functrace[@] + + local -i i + local -a message + local date level="${1:-"ERROR"}" + + # Assume the stdin that should be discarded to /dev/null + message=( ${(@f)"$(<&0)"} ) + if (( $#message == 0 )); then + return 1 + fi + + # https://tools.ietf.org/html/rfc3339#section-5.6 + date="$(date +%FT%T%z | sed -E 's/(.*)([0-9][0-9])([0-9][0-9])/\1\2:\3/')" + + # Spit out to JSON + printf '{' + printf '"pid": %d,' "$$" + printf '"shlvl": %d,' "$SHLVL" + printf '"level": "%s",' "$level" + printf '"dir": "%s",' "$PWD" + printf '"message": %s,' "${(qqq)message[*]}" + printf '"trace": {' + for ((i = 1; i < $#functrace; i++)) + do + # With comma + printf '"%s": "%s",' \ + "$functrace[$i]" \ + "$funcstack[$i]" + done + # Without comma + printf '"%s": "%s"' \ + "$functrace[$#functrace]" \ + "$funcstack[$#funcstack]" + printf "}," + printf '"date": "%s"' "$date" + printf "}\n" +} + +__zplug::io::log::level() +{ + local level="${(U)1:-"INFO"}" log_level + local -i part="${2:-2}" + local -A syslog_code + + # https://tools.ietf.org/html/rfc5424 + syslog_code=( + '' '0:Emergency:system is unusable' + '' '1:Alert:action must be taken immediately' + '' '2:Critical:critical conditions' + 'ERROR' '3:Error:error conditions' + 'WARN' '4:Warning:warning conditions' + '' '5:Notice:normal but significant condition' + 'INFO' '6:Informational:informational messages' + 'DEBUG' '7:Debug:debug-level messages' + ) + + if (( ! $+syslog_code[$level] )); then + level="INFO" + fi + if (( $part > 3 )); then + part=0 + fi + + echo "$syslog_code[$level]" \ + | awk -F: '{print $'"$part"'}' \ + | read log_level + + echo "${(U)log_level}" +} + +__zplug::io::log::new() +{ + local key value + local level="WARN" + local -a args + + __zplug::utils::shell::getopts "$argv[@]" \ + | while read key value; \ + do + case "$key" in + level) + level="$value" + ;; + _) + args+=( "$value" ) + esac + done + level="$(__zplug::io::log::level "$level")" + + echo "$args[@]" \ + | __zplug::io::log::with_json "$level" \ + | >>|"$ZPLUG_ERROR_LOG" +} + +__zplug::io::log::capture() +{ + __zplug::io::log::with_json "ERROR" \ + | >>|"$ZPLUG_ERROR_LOG" +} + +__zplug::io::log::info() +{ + __zplug::io::log::new \ + --level="INFO" \ + -- \ + "$argv[@]" +} + +__zplug::io::log::warn() +{ + __zplug::io::log::new \ + --level="WARN" \ + -- \ + "$argv[@]" +} + +__zplug::io::log::error() +{ + __zplug::io::log::new \ + --level="ERROR" \ + -- \ + "$argv[@]" +} diff --git a/base/io/print.zsh b/base/io/print.zsh new file mode 100644 index 00000000..ef588201 --- /dev/null +++ b/base/io/print.zsh @@ -0,0 +1,144 @@ +__zplug::io::print::put() +{ + LC_ALL=POSIX command printf -- "$@" +} + +__zplug::io::print::die() +{ + LC_ALL=POSIX command printf -- "$@" >&2 +} + +__zplug::io::print::f() +{ + local -i lines=0 + local w pre_format post_format format func + local -a pre_formats post_formats + local -a formats texts + local arg text + local -i fd=1 + local \ + is_end=false \ + is_multi=false + local \ + is_end_specified=false \ + is_per_specified=false + local \ + is_log=false + + if (( $argv[(I)--] )); then + is_end_specified=true + fi + if (( $argv[(I)*%*] )); then + is_per_specified=true + fi + + while (( $# > 0 )) + do + arg="$1" + case "$arg" in + --put | -1) + fd=1 + ;; + --die | -2) + is_log=true + fd=2 + ;; + --func) + func="$funcstack[2]" + if [[ -n $func ]]; then + # if $func is commands or tags + # trim underscores + if [[ $func =~ __$ ]]; then + func="${func:gs:_:}" + fi + pre_formats+=( "|$em[bold]$func$reset_color|" ) + fi + ;; + --multi) + is_multi=true + ;; + --zplug) + pre_formats+=( "[zplug]" ) + ;; + --warn) + pre_formats+=( "$fg[red]$em[under]WARNING$reset_color:" ) + ;; + --error) + pre_formats+=( "$fg[red]ERROR$reset_color:" ) + ;; + --) + is_end=true + ;; + "") + ;; + *) + # Check if the double hyphens exist in args + if $is_end_specified; then + # Divide + if $is_end; then + texts+=( "$arg" ) + else + post_formats+=( "$arg" ) + fi + else + texts+=( "$arg" ) + fi + ;; + esac + shift + done + + # Change the output destination by the value of $fd + { + echo "${pre_formats[*]}" \ + | __zplug::utils::shell::unansi \ + | read pre_format + repeat $#pre_format; do w="$w "; done + + if $is_end_specified; then + printf "${post_formats[*]}" \ + | grep -c "" \ + | read lines + for (( i = 1; i <= $#post_formats; i++ )) + do + if (( $lines == $#post_formats )); then + if ! $is_multi && (( $i > 1 )); then + pre_formats=( "$w" ) + fi + else + if (( $i > 1 )); then + pre_formats=() + fi + fi + formats[$i]="${pre_formats[*]} $post_formats[$i]" + done + command printf -- "${(j::)formats[@]}" "${texts[@]}" + elif $is_per_specified; then + command printf -- "${pre_formats[*]:+${pre_formats[*]} }${texts[@]}" + else + format="${pre_formats[*]}" + printf "${texts[*]}" \ + | grep -c "" \ + | read lines + for (( i = 1; i <= $#texts; i++ )) + do + if (( $lines == $#texts )); then + if ! $is_multi && (( $i > 1 )); then + format="$w" + fi + else + if (( $i > 1 )); then + format= + fi + fi + formats[$i]="${format:+$format }$post_formats[$i]" + command printf -- "$formats[$i]$texts[$i]" + done + fi + } >&$fd + + if $is_log; then + __zplug::io::log::error \ + "${(q)texts[@]}" + fi +} diff --git a/base/job/hook.zsh b/base/job/hook.zsh new file mode 100644 index 00000000..d9da11f5 --- /dev/null +++ b/base/job/hook.zsh @@ -0,0 +1,54 @@ +__zplug::job::hook::service() +{ + local repo="${1:?}" hook="${2:?}" + local -A tags + + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + + # There is no $hook file in /autoload/tags directory + if (( ! $+tags[$hook] )); then + __zplug::io::print::f \ + --die \ + --zplug \ + "'%s' is not defined as a hook (%s)\n" \ + "$hook" \ + "$fg[green]$repo$reset_color" + return 1 + fi + + if [[ -n $tags[$hook] ]]; then + ( + __zplug::utils::shell::cd "$tags[dir]" + alias sudo=__zplug::utils::shell::sudo + + eval "$tags[$hook]" 2> >(__zplug::io::log::capture) + if (( $status != 0 )); then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "'%s' failed\n" \ + "$tags[$hook]" + fi + ) + fi +} + +__zplug::job::hook::build() +{ + local repo="${1:?}" + + __zplug::job::hook::service \ + "$repo" \ + "hook-build" +} + +__zplug::job::hook::load() +{ + local repo="${1:?}" + + __zplug::job::hook::service \ + "$repo" \ + "hook-load" +} diff --git a/base/job/job.zsh b/base/job/job.zsh deleted file mode 100644 index 8441a36f..00000000 --- a/base/job/job.zsh +++ /dev/null @@ -1 +0,0 @@ -#!/usr/bin/env zsh diff --git a/base/job/notify.zsh b/base/job/notify.zsh deleted file mode 100644 index 5bc91533..00000000 --- a/base/job/notify.zsh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" -__import "print/print" - -__zplug::job::notify::for_linux() { - return 1 -} - -__zplug::job::notify::for_osx() { - local text title sound - - text="${1:?}" - title="${2:-zplug}" - sound="${3:-default}" - - if (( $+commands[osascript] )) && __zplug::core::core::osx_version 10.9; then - osascript -e \ - "display notification "${(qqq)text}" with title "${(qqq)title}" sound name \"$sound\"" - elif (( $+commands[terminal-notifier] )); then - terminal-notifier \ - -title "$title" \ - -message "$text" \ - -sound "$sound" - else - __zplug::print::print::die "[zplug] A notifier is not available on this system.\n" - __zplug::print::print::die " Please install terminal-notifier or upgrade your OS X.\n" - return 1 - fi -} - -__zplug::job::notify::notifier() { - if __zplug::core::core::is_osx; then - __zplug::job::notify::for_osx "$@" - return $status - elif __zplug::core::core::is_linux; then - __zplug::job::notify::for_linux "$@" - return $status - fi -} - -__zplug::job::notify::check_update() ( - local -i cnt - local msg rev state commit - - builtin cd -q "$ZPLUG_REPOS/zplug/zplug" || return 1 - - # Fetch from remote - git fetch &>/dev/null - - # Get the revision hash and commit message - git -c pager.log=false \ - log --oneline -1 \ - origin/HEAD \ - | read rev msg - - git status --branch --short \ - | head -1 \ - | perl -pe 's/^.*?\[(.*?)\].*$/$1/' \ - | read state cnt - - case $cnt in - 1) - commit="commit" - ;& - *) - __zplug::job::notify::notifier \ - "[$rev] \"$msg\" ($state $cnt ${commit:-commits})" \ - 'Update "zplug/zplug"' - ;; - esac -) diff --git a/base/job/polling.zsh b/base/job/polling.zsh index 8b46a6ce..e69de29b 100644 --- a/base/job/polling.zsh +++ b/base/job/polling.zsh @@ -1,12 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/core" - -__zplug::job::polling::finalize() { - __zplug::core::core::get_autoload_files - unfunction "${reply[@]}" &>/dev/null -} - -add-zsh-hook \ - precmd \ - __zplug::job::polling::finalize diff --git a/base/job/queue.zsh b/base/job/queue.zsh new file mode 100644 index 00000000..2141f339 --- /dev/null +++ b/base/job/queue.zsh @@ -0,0 +1,42 @@ +typeset -a _zplug_job_queue + +__zplug::job::queue::enqueue() +{ + local q + + for q in "$@" + do + _zplug_job_queue+=("$q") + done +} + +__zplug::job::queue::dequeue() +{ + : +} + +__zplug::job::queue::clear() +{ + _zplug_job_queue=() +} + +__zplug::job::queue::wait() +{ + local -i queue_max=$ZPLUG_THREADS + + if (( $#_zplug_job_queue % queue_max == 0 )); then + wait "${_zplug_job_queue[@]}" + __zplug::job::queue::clear + fi 2> >(__zplug::io::log::capture) >/dev/null +} + +__zplug::job::queue::wait_all() +{ + local -i queue_max=$ZPLUG_THREADS + + if (( $#_zplug_job_queue > 0 )); then + wait "${_zplug_job_queue[@]}" + fi 2> >(__zplug::io::log::capture) >/dev/null + + __zplug::job::queue::clear +} diff --git a/base/job/spinner.zsh b/base/job/spinner.zsh index 2761b5b0..ee640102 100644 --- a/base/job/spinner.zsh +++ b/base/job/spinner.zsh @@ -1,64 +1,53 @@ -#!/usr/bin/env zsh +typeset -g _zplug_spin_file="/tmp/._zplug_spin_file.$$$RANDOM" -__import "print/print" +__zplug::job::spinner::is_spin() +{ + [[ -f $_zplug_spin_file ]] + return $status +} -typeset -g spin_file=/tmp/.spin.$$$RANDOM +__zplug::job::spinner::lock() +{ + __zplug::job::spinner::is_spin && return 1 -__zplug::job::spinner::is_spin() { - [[ -f $spin_file ]] + set +m + touch "$_zplug_spin_file" } -__zplug::job::spinner::lock() { - if ! __zplug::job::spinner::is_spin; then - set +m - touch $spin_file &>/dev/null - fi -} +__zplug::job::spinner::unlock() +{ + __zplug::job::spinner::is_spin || return 1 -__zplug::job::spinner::unlock() { - if __zplug::job::spinner::is_spin; then - rm -f $spin_file &>/dev/null - fi + rm -f "$_zplug_spin_file" } -__zplug::job::spinner::spinner() { - local spin format - local -F latency +__zplug::job::spinner::spin() +{ + local spinner format="@" + local -F latency=0.05 local -a spinners - # spinners=("⠄" "⠆" "⠇" "⠋" "⠙" "⠸" "⠰" "⠠" "⠰" "⠸" "⠙" "⠋" "⠇" "⠆") spinners=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) - format="@" - latency=0.03 + + tput civis while __zplug::job::spinner::is_spin do - for spin in $spinners + for spinner in "${spinners[@]}" do __zplug::job::spinner::is_spin || break - __zplug::print::print::put "$format" | awk -v t=$latency -v i=$(__zplug::print::print::put "$spin" | sed 's/=/\\\=/') ' - { - system("tput civis") - gsub("@", i) - printf("%s\r", $0) - fflush() - system("sleep "t"") - } - ' >/dev/stderr + + printf " $spinner\r" >/dev/stderr + sleep "$latency" done done tput cnorm - awk 'END { fflush() }' - printf "\r\033[0K" set -m } -__zplug::job::spinner::echo() { - if __zplug::job::spinner::is_spin; then - __zplug::print::print::put "$@" - return 0 - else - return 1 - fi +__zplug::job::spinner::echo() +{ + __zplug::job::spinner::is_spin || return 1 + __zplug::io::print::f "$argv[@]" } diff --git a/base/print/logger.zsh b/base/print/logger.zsh deleted file mode 100644 index 8110039c..00000000 --- a/base/print/logger.zsh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env zsh - -__import "print/print" - -__zplug::print::log::ink() { - local color is_bold=false - local -i tty=1 - local -a text - - while (( $# > 0 )) - do - case "$1" in - --color) - if [[ ! $2 =~ ^(black|blue|cyan|default|green|grey|magenta|red|white|yellow)$ ]]; then - __zplug::print::print::die "$2: must be a color\n" - return 1 - fi - color="$2"; shift - ;; - --bold) - is_bold=true - ;; - --tty) - if [[ $2 != <-> ]]; then - __zplug::print::print::die "$2: must be an interger\n" - return 1 - fi - tty="$2"; shift - ;; - *) - text+=("$1") - ;; - esac - shift - done - - if $is_bold; then - color="$fg_bold[$color]" - else - color="$fg_no_bold[$color]" - fi - - case $tty in - 1) - __zplug::print::print::put "${color}${text}${reset_color}" - ;; - 2) - __zplug::print::print::die "${color}${text}${reset_color}" - ;; - esac -} - -__zplug::print::log::log() { - local state="$1" text="$2" - local bold - local -i tty=1 - - case "$state" in - TITLE) - color="yellow" - ;; - INFO) - color="blue" - ;; - FAIL | WARN) - color="red" - tty=2 - ;; - ERROR) - color="red" - bold="--bold" - tty=2 - ;; - PASS) - color="green" - ;; - SUCCESS) - bold="--bold" - color="green" - ;; - *) - text="$1" - ;; - esac - - __zplug::print::log::ink --color white "[" - __zplug::print::log::ink --color magenta --bold "$(date +%H:%M:%S)" - __zplug::print::log::ink --color white "]" - __zplug::print::log::ink --color "$color" --tty "$tty" $bold " $text" -} diff --git a/base/print/print.zsh b/base/print/print.zsh deleted file mode 100644 index baa095f1..00000000 --- a/base/print/print.zsh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env zsh - -__zplug::print::print::put() { - LC_ALL=POSIX command printf -- "$@" -} - -__zplug::print::print::die() { - LC_ALL=POSIX command printf -- "$@" >&2 -} diff --git a/base/sources/bitbucket.zsh b/base/sources/bitbucket.zsh new file mode 100644 index 00000000..f4219194 --- /dev/null +++ b/base/sources/bitbucket.zsh @@ -0,0 +1,42 @@ +__zplug::sources::bitbucket::check() +{ + __zplug::sources::github::check "$argv[@]" +} + +__zplug::sources::bitbucket::install() +{ + __zplug::sources::github::install "$argv[@]" +} + +__zplug::sources::bitbucket::update() +{ + __zplug::sources::github::update "$argv[@]" +} + +__zplug::sources::bitbucket::get_url() +{ + local repo="$1" url_format + + case "$ZPLUG_PROTOCOL" in + HTTPS | https) + # https://git::@bitbucket.org/%s.git + url_format="https://git::@bitbucket.org/${repo}.git" + ;; + SSH | ssh) + # git@bitbucket.org:%s.git + url_format="git@bitbucket.org:${repo}.git" + ;; + esac + + echo "$url_format" +} + +__zplug::sources::bitbucket::load_plugin() +{ + __zplug::sources::github::load_plugin "$argv[@]" +} + +__zplug::sources::bitbucket::load_command() +{ + __zplug::sources::github::load_command "$argv[@]" +} diff --git a/base/sources/gh-r.zsh b/base/sources/gh-r.zsh new file mode 100644 index 00000000..cd7003ca --- /dev/null +++ b/base/sources/gh-r.zsh @@ -0,0 +1,81 @@ +__zplug::sources::gh-r::check() +{ + local repo="$1" + local -A tags + + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" + )" + + # Repo's directory is not found and + # INDEX file is not found + if [[ ! -d $tags[dir] ]] && [[ ! -f $tags[dir]/INDEX ]]; then + return 1 + fi + + return 0 +} + +__zplug::sources::gh-r::install() +{ + local repo="${1:?}" + local url + + url="$( + __zplug::utils::releases::get_url \ + "$repo" + )" + + __zplug::utils::releases::get "$url" + + return $status +} + +__zplug::sources::gh-r::update() +{ + local repo="${1:?}" + local index url + local -A tags + + tags[dir]="$(__zplug::core::core::run_interfaces 'dir' "$repo")" + tags[use]="$(__zplug::core::core::run_interfaces 'use' "$repo")" + tags[at]="$(__zplug::core::core::run_interfaces 'at' "$repo")" + + __zplug::utils::shell::cd \ + "$tags[dir]" || return $_ZPLUG_STATUS_REPO_NOT_FOUND + + url="$( + __zplug::utils::releases::get_url \ + "$repo" + )" + + if [[ -d $tags[dir] ]]; then + # Update + if [[ -f $tags[dir]/INDEX ]]; then + index="$(<"$tags[dir]/INDEX")" + if [[ $tags[at] == "latest" ]]; then + if grep -q "$index" <<<"$url"; then + # up-to-date + return $_ZPLUG_STATUS_REPO_UP_TO_DATE + else + __zplug::sources::gh-r::clone "$repo" + return $status + fi + else + # up-to-date + return $_ZPLUG_STATUS_REPO_UP_TO_DATE + fi + fi + else + return $_ZPLUG_STATUS_REPO_NOT_FOUND + fi + + return $_ZPLUG_STATUS_SUCCESS +} + +__zplug::sources::gh-r::load_command() +{ + __zplug::sources::github::load_command "$argv[@]" +} diff --git a/base/sources/gist.zsh b/base/sources/gist.zsh new file mode 100644 index 00000000..3c2d9ca1 --- /dev/null +++ b/base/sources/gist.zsh @@ -0,0 +1,48 @@ +__zplug::sources::gist::check() +{ + __zplug::sources::github::check "$argv[@]" +} + +__zplug::sources::gist::install() +{ + __zplug::sources::github::install "$argv[@]" +} + +__zplug::sources::gist::update() +{ + __zplug::sources::github::update "$argv[@]" +} + +__zplug::sources::gist::get_url() +{ + local repo="${1:?}" url_format + + case "$ZPLUG_PROTOCOL" in + HTTPS | https) + # https://git::@github.com/%s.git + url_format="https://git::@gist.github.com/${repo}.git" + + if __zplug::base::base::git_version 2.3; then + # (git 2.3+) https://gist.github.com/%s.git + export GIT_TERMINAL_PROMPT=0 + url_format="https://gist.github.com/${repo}.git" + fi + ;; + SSH | ssh) + # git@github.com:%s.git + url_format="git@gist.github.com:${repo}.git" + ;; + esac + + echo "$url_format" +} + +__zplug::sources::gist::load_plugin() +{ + __zplug::sources::github::load_plugin "$@" +} + +__zplug::sources::gist::load_command() +{ + __zplug::sources::github::load_command "$@" +} diff --git a/base/sources/github.zsh b/base/sources/github.zsh new file mode 100644 index 00000000..fd4f1ddb --- /dev/null +++ b/base/sources/github.zsh @@ -0,0 +1,256 @@ +__zplug::sources::github::check() +{ + local repo="${1:?}" + local -A tags + + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" + )" + + [[ -d $tags[dir] ]] + return $status +} + +__zplug::sources::github::install() +{ + local repo="${1:?}" + + __zplug::utils::git::clone "$repo" + return $status +} + +__zplug::sources::github::update() +{ + local repo="${1:?}" + local rev_local rev_remote rev_base + local -A tags + + tags[dir]="$(__zplug::core::core::run_interfaces 'dir' "$repo")" + tags[at]="$(__zplug::core::core::run_interfaces 'at' "$repo")" + + __zplug::utils::git::merge \ + --dir "$tags[dir]" \ + --branch "$tags[at]" + + return $status +} + +__zplug::sources::github::get_url() +{ + local repo="${1:?}" url_format + + case "$ZPLUG_PROTOCOL" in + HTTPS | https) + # Create the format of URL used to git clone + # When vim-plug clones a repository, it injects git::@ into the URL + # It's a little hack to avoid username/password prompt + # from git when the repository doesn't exist. + # Such thing can happen when there's a typo in the argument, + # or when the repository is removed from GitHub + # For more information, see also vim-plug wiki. + # https://git::@github.com/%s.git + url_format="https://git::@github.com/${repo}.git" + + # However, Git 2.3.0 introduced $GIT_TERMINAL_PROMPT + # which can be used to suppress user prompt + if __zplug::base::base::git_version 2.3; then + # (git 2.3+) https://github.com/%s.git + export GIT_TERMINAL_PROMPT=0 + url_format="https://github.com/${repo}.git" + fi + ;; + SSH | ssh) + # git@github.com:%s.git + url_format="git@github.com:${repo}.git" + ;; + esac + + echo "$url_format" +} + +__zplug::sources::github::load_plugin() +{ + local repo="${1:?}" + local -A tags default_tags + local -a plugins_ext themes_ext + local -a load_patterns + local ext default_use + + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + default_tags[use]="$(__zplug::core::core::run_interfaces 'use' "$repo")" + + # If that is an autoload plugin + if (( $_zplug_boolean_true[(I)$tags[lazy]] )); then + if [[ -n $tags[use] ]]; then + load_patterns+=( "$tags[dir]"/$tags[use](N.) ) + load_fpaths+=( "$tags[dir]"/$tags[use]:h(N/) ) + else + load_patterns+=( "$tags[dir]/autoload"/*(N.) ) + load_fpaths+=( "$tags[dir]/autoload"(N/) ) + fi + else + # Default load behavior for plugins + plugins_ext=("plugin.zsh" "zsh-theme" "theme-zsh") + themes_ext=("zsh-theme" "theme-zsh") + + # In order to find main file of the plugin, + # narrow down the candidates in three stages + # 1. use $plugins_ext[@] ==> foo.plugin.zsh + # 2. use $tags[use] as a file like "*.zsh" ==> bar.zsh + # 3. use in combination + # - tags[use] as a directory like "bin" + # - and *.zsh files ==> bar.zsh + for ext in "${plugins_ext[@]}" + do + if [[ $tags[use] == $default_tags[use] ]]; then + # NOTE: step 1 + load_patterns+=( "$tags[dir]"/*.$ext(N-.) ) + fi + + if (( $#load_patterns == 0 )); then + # NOTE: step 2 + # If $tags[use] is a regular file, + # expect to expand to $tags[dir]/*.zsh + load_patterns+=( "$tags[dir]"/${~tags[use]}(N.) ) + if (( $#load_patterns == 0 )); then + # For brace + load_patterns+=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $tags[dir]/$tags[use](N.)" \ + 2> >(__zplug::io::log::capture) + ) ) + fi + # Add the parent directory to fpath + load_fpaths+=( $tags[dir]/_*(N.:h) ) + + # NOTE: step 3 + # If $tags[use] is a directory, + # expect to expand to $tags[dir]/*.zsh + if (( $#load_patterns == 0 )); then + load_patterns+=( $tags[dir]/$tags[use]/$default_tags[use](N.) ) + if (( $#load_patterns == 0 )); then + # For brace + load_patterns+=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $tags[dir]/$tags[use]/$default_tags[use](N.)" \ + 2> >(__zplug::io::log::capture) + ) ) + fi + # Add the parent directory to fpath + load_fpaths+=( $tags[dir]/$tags[use]/_*(N.:h) ) + fi + fi + done + fi + + if [[ $tags[nice] -gt 9 ]]; then + # the order of loading of plugin files + nice_plugins+=( "${load_patterns[@]}" ) + else + # autoload plugin / regular plugin + if (( $_zplug_boolean_true[(I)$tags[lazy]] )); then + lazy_plugins+=( "${load_patterns[@]}" ) + else + load_plugins+=( "${load_patterns[@]}" ) + fi + fi + + reply=() + [[ -n $load_fpaths ]] && reply+=( load_fpaths "${(F)load_fpaths}" ) + [[ -n $nice_plugins ]] && reply+=( nice_plugins "${(F)nice_plugins}" ) + [[ -n $load_plugins ]] && reply+=( load_plugins "${(F)load_plugins}" ) + [[ -n $lazy_plugins ]] && reply+=( lazy_plugins "${(F)lazy_plugins}" ) +} + +__zplug::sources::github::load_command() +{ + local repo="$1" + local -A tags + local dst basename + local -a sources + local -a load_fpaths load_commands + + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + + basename="${repo:t}" + tags[dir]="${tags[dir]%/}" + dst=${${tags[rename-to]:+$ZPLUG_HOME/bin/$tags[rename-to]}:-"$ZPLUG_HOME/bin"} + + # Add parent directories to fpath if any files starting in _* exist + load_fpaths+=(${tags[dir]}{_*,/**/_*}(N-.:h)) + + # Mock (example): "b4b4r07/sample" + # sample + # |-- bin + # | |-- sample + # | `-- mycmd1 + # `-- mycmd2 + # + # 1 directory, 2 files + # + if [[ -f $tags[dir]${tags[use]:+"/$tags[use]"} ]]; then + # case: + # zplug "b4b4r07/sample", use:mycmd + load_commands+=( + # expand to "$ZPLUG_REPOS/b4b4r07/sample/mycmd" + "$tags[dir]${tags[use]:+"/$tags[use]"}\0$dst" + ) + elif [[ -f $tags[dir]${tags[use]:+"/$tags[use]"}/$basename ]]; then + # case: + # zplug "b4b4r07/sample", use:bin + load_commands+=( + # expand to "$ZPLUG_REPOS/b4b4r07/sample/bin/sample" + "$tags[dir]${tags[use]:+"/$tags[use]"}/$basename\0$dst" + ) + elif [[ -f $tags[dir]/$basename ]]; then + # case: + # zplug "b4b4r07/sample" + load_commands+=( + # expand to "$ZPLUG_REPOS/b4b4r07/sample/sample" + "$tags[dir]/$basename\0$dst" + ) + else + # For brace + # case 1: + # zplug "b4b4r07/sample", use:"bin/{mycmd1,sample}" + # case 2: + # zplug "b4b4r07/sample", use:"bin/*" + sources=( $( + # expand to "$ZPLUG_REPOS/b4b4r07/sample/mycmd1" + # "$ZPLUG_REPOS/b4b4r07/sample/sample" + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${tags[dir]}/${tags[use]}" \ + 2> >(__zplug::io::log::capture) + ) ) + for src in "${sources[@]}" + do + load_commands+=("$src\0$dst") + done + fi + + # Append dst to each element so that load_commands becomes: + # + # load_commands=( + # path/to/cmd1\0dst + # path/to/cmd2\0dst + # ... + # ) + # + # where \0 is a null character used to separate the two strings. + # + # In the caller function (__load__), each line is decomposed into an + # element in an associative array, thus, in the example above, the line: + # + # path/to/cmd1\0dst + # + # becomes an element where the key is "path/to/cmd" and the value is + # "dst". + #load_commands=( ${^load_commands}"\0$dst" ) + + reply=() + [[ -n $load_fpaths ]] && reply+=( load_fpaths "${(F)load_fpaths}" ) + [[ -n $load_commands ]] && reply+=( load_commands "${(F)load_commands}" ) + + return 0 +} diff --git a/base/sources/local.zsh b/base/sources/local.zsh index da526d92..24be478c 100644 --- a/base/sources/local.zsh +++ b/base/sources/local.zsh @@ -1,18 +1,18 @@ -#!/usr/bin/env zsh - -__zplug::local::check() { - local line - local -A zspec - - line="$1" - __parser__ "$line" - zspec=( "${reply[@]}" ) - +__zplug::sources::local::check() +{ + local repo="${1:?}" + local -A tags local expanded_path local -a expanded_paths - # Note: $zspec[dir] can be a dir name or a file name - expanded_paths=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${zspec[dir]}" 2>/dev/null) ) + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + + # Note: $tags[dir] can be a dir name or a file name + expanded_paths=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${tags[dir]}" \ + 2> >(__zplug::io::log::capture) + ) ) # Okay if at least one expanded path exists for expanded_path in ${expanded_paths[@]} @@ -22,87 +22,99 @@ __zplug::local::check() { fi done - __zplug::print::print::die "[zplug] no matching file or directory: ${zspec[dir]}\n" + __zplug::io::log::warn \ + "no matching file or directory in $tags[dir]" return 1 } -__zplug::local::load_plugin() { - local line - local -A zspec - - line="$1" - __parser__ "$line" - zspec=( "${reply[@]}" ) - - local -a load_patterns +__zplug::sources::local::load_plugin() +{ + local repo="${1:?}" + local -A tags + local -a load_plugins local -a load_fpaths local expanded_path local -a expanded_paths - expanded_paths=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${zspec[dir]}" 2>/dev/null) ) + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) - for expanded_path in ${expanded_paths[@]} + expanded_paths=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${tags[dir]}" \ + 2> >(__zplug::io::log::capture) + ) ) + + for expanded_path in "${expanded_paths[@]}" do if [[ -f $expanded_path ]]; then - load_patterns+=( $expanded_path ) + load_plugins+=( "$expanded_path" ) elif [[ -d $expanded_path ]]; then - if [[ -n $zspec[use] ]]; then - load_patterns+=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $expanded_path/$zspec[use]" 2>/dev/null) ) + if [[ -n $tags[use] ]]; then + load_plugins+=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $expanded_path/$tags[use]" \ + 2> >(__zplug::io::log::capture) + ) ) else load_fpaths+=( - $expanded_path/{_*,**/_*}(N-.:h) + "$expanded_path"/{_*,**/_*}(N-.:h) ) fi fi done - if (( $#load_patterns == 0 )); then - __zplug::print::print::die "[zplug] no matching file or directory: ${zspec[dir]}\n" + if (( $#load_plugins == 0 )); then + __zplug::io::log::warn \ + "no matching file or directory in $tags[dir]" return 1 fi reply=() [[ -n $load_fpaths ]] && reply+=( load_fpaths "${(F)load_fpaths}" ) - [[ -n $load_patterns ]] && reply+=( load_patterns "${(F)load_patterns}" ) + [[ -n $load_plugins ]] && reply+=( load_plugins "${(F)load_plugins}" ) return 0 } -__zplug::local::load_command() { - local line - local -A zspec - - line="$1" - __parser__ "$line" - zspec=( "${reply[@]}" ) - +__zplug::sources::local::load_command() +{ + local repo="${1:?}" + local -A tags local -a load_fpaths local -a load_commands local expanded_path local -a expanded_paths - local dst + local dst - expanded_paths=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo ${zspec[dir]}" 2>/dev/null) ) + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) - dst=${${zspec[rename-to]:+$ZPLUG_HOME/bin/$zspec[rename-to]}:-"$ZPLUG_HOME/bin"} + expanded_paths=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $tags[dir]" \ + 2> >(__zplug::io::log::capture) + ) ) + dst=${${tags[rename-to]:+$ZPLUG_HOME/bin/$tags[rename-to]}:-"$ZPLUG_HOME/bin"} - for expanded_path in ${expanded_paths[@]} + for expanded_path in "${expanded_paths[@]}" do if [[ -f $expanded_path ]]; then - load_commands+=( $expanded_path ) + load_commands+=( "$expanded_path" ) elif [[ -d $expanded_path ]]; then - if [[ -n $zspec[use] ]]; then - load_commands+=( $(zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $expanded_path/$zspec[use]" 2>/dev/null) ) + if [[ -n $tags[use] ]]; then + load_commands+=( $( + zsh -c "$_ZPLUG_CONFIG_SUBSHELL; echo $expanded_path/$tags[use]" \ + 2> >(__zplug::io::log::capture) + ) ) else load_fpaths+=( - $expanded_path/{_*,**/_*}(N-.:h) + "$expanded_path"/{_*,**/_*}(N-.:h) ) fi fi done if (( $#load_commands == 0 )); then - __zplug::print::print::die "[zplug] no matching file or directory: ${zspec[dir]}\n" + __zplug::io::log::warn \ + "no matching file or directory in $tags[dir]" return 1 fi @@ -116,8 +128,8 @@ __zplug::local::load_command() { # # where \0 is a null character used to separate the two strings. # - # In the caller function (__load__), each line is decomposed into an - # element in an associative array, thus, in the example above, the line: + # In the caller function (__load__), each repo is decomposed into an + # element in an associative array, thus, in the example above, the repo: # # path/to/cmd1\0dst # diff --git a/base/sources/oh-my-zsh.zsh b/base/sources/oh-my-zsh.zsh index dd43be81..25e5befd 100644 --- a/base/sources/oh-my-zsh.zsh +++ b/base/sources/oh-my-zsh.zsh @@ -1,50 +1,71 @@ -#!/usr/bin/env zsh - -__import "support/omz" - -__zplug::oh-my-zsh::check() { - local line - local -A zspec - - line="$1" - __parser__ "$line" - zspec=( "${reply[@]}" ) - - [[ -d ${zspec[dir]:h} ]] +__zplug::sources::oh-my-zsh::check() +{ + local repo="$1" + local -A tags + + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" + )" + + [[ -d $tags[dir]:h ]] + return $status } -__zplug::oh-my-zsh::install() { - local line - local -A zspec - - line="$1" - __parser__ "$line" - zspec=( "${reply[@]}" ) +__zplug::sources::oh-my-zsh::install() +{ + # Already cloned + if [[ -d $_ZPLUG_OHMYZSH ]]; then + return 0 + fi - __clone__ \ - --use ${zspec[use]:-""} \ - --from "github" \ - --at ${zspec[at]:-""} \ - --depth ${zspec[depth]:-""} \ + __zplug::utils::git::clone \ "$_ZPLUG_OHMYZSH" - return $status } -__zplug::oh-my-zsh::load_plugin() { - local line - local -A zspec +__zplug::sources::oh-my-zsh::update() +{ + local repo="${1:?}" + local -A tags + + tags[dir]="${$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" + ):F[2]h}" + tags[at]="$( + __zplug::core::core::run_interfaces \ + 'at' \ + "$repo" + )" + + __zplug::utils::git::merge \ + --dir "$tags[dir]" \ + --branch "$tags[at]" + + return $status +} - line="$1" - __parser__ "$line" - zspec=( "${reply[@]}" ) +__zplug::sources::oh-my-zsh::get_url() +{ + __zplug::sources::github::get_url "$_ZPLUG_OHMYZSH" +} +__zplug::sources::oh-my-zsh::load_plugin() +{ + local repo="${1:?}" + local -A tags local -a load_fpaths - local -a load_patterns + local -a load_plugins local -a themes_ext + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + load_fpaths=() - load_patterns=() + load_plugins=() # Themes' extensions for Oh-My-Zsh themes_ext=("zsh-theme" "theme-zsh") @@ -57,39 +78,39 @@ __zplug::oh-my-zsh::load_plugin() { # "$ZSH/oh-my-zsh.sh" # "${load_plugins[@]}" # ) - if [[ $zspec[name] =~ ^lib ]]; then - __zplug::support::omz::theme + if [[ $tags[name] =~ ^lib ]]; then + __zplug::utils::omz::theme fi fi - case $zspec[name] in + case $tags[name] in plugins/*) # TODO: use tag - load_patterns=( - ${(@f)"$(__zplug::support::omz::depends "$zspec[name]")"} - "$zspec[dir]"/*.plugin.zsh(N-.) + load_plugins=( + ${(@f)"$(__zplug::utils::omz::depends "$tags[name]")"} + "$tags[dir]"/*.plugin.zsh(N-.) ) ;; themes/*) # TODO: use tag - load_patterns=( - ${(@f)"$(__zplug::support::omz::depends "$zspec[name]")"} - "$zspec[dir]".${^themes_ext}(N-.) + load_plugins=( + ${(@f)"$(__zplug::utils::omz::depends "$tags[name]")"} + "$tags[dir]".${^themes_ext}(N-.) ) ;; lib/*) - load_patterns=( - "$zspec[dir]"${~zspec[use]} + load_plugins=( + "$tags[dir]"${~tags[use]} ) ;; esac load_fpaths+=( - ${zspec[dir]}/{_*,**/_*}(N-.:h) + ${tags[dir]}/{_*,**/_*}(N-.:h) ) reply=() [[ -n $load_fpaths ]] && reply+=( load_fpaths "${(F)load_fpaths}" ) - [[ -n $load_patterns ]] && reply+=( load_patterns "${(F)load_patterns}" ) + [[ -n $load_plugins ]] && reply+=( load_plugins "${(F)load_plugins}" ) return 0 } diff --git a/base/support/gh-r.zsh b/base/support/gh-r.zsh deleted file mode 100644 index e36ac490..00000000 --- a/base/support/gh-r.zsh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env zsh - -__import "core/git" -__import "print/print" - -__zplug::support::gh-r::get_latest() { - local repo curl - local url_format - - repo="${1:?}" - - url_format="https://github.com/$repo/releases/latest" - if (( $+commands[curl] )); then - curl="curl -fsSL" - elif (( $+commands[wget] )); then - curl="wget -qO -" - fi - - eval "$curl $url_format" 2>/dev/null \ - | grep -o '/'"$repo"'/releases/download/[^"]*' \ - | awk -F/ '{print $6}' \ - | sort \ - | uniq -} - -__zplug::support::gh-r::get_state() { - local state - local name="${1:?}" - local dir="${2:?}" - local url="https://github.com/$name/releases" - - if [[ "$(__zplug::support::gh-r::get_latest "$name")" == "$(cat "$dir/INDEX")" ]]; then - state="up to date" - else - state="local out of date" - fi - - case "$state" in - "local out of date") - state="${fg[red]}${state}${reset_color}" - ;; - "up to date") - state="${fg[green]}${state}${reset_color}" - ;; - esac - __zplug::print::print::put "($state) '${url:-?}'\n" -} diff --git a/base/utils/awk.zsh b/base/utils/awk.zsh new file mode 100644 index 00000000..343cfbd7 --- /dev/null +++ b/base/utils/awk.zsh @@ -0,0 +1,66 @@ +__zplug::utils::awk::path() +{ + local awk_path + local -a awk_paths + local awk variant + + # Look up all awk from PATH + for awk_path in ${^path[@]}/{g,n,m,}awk + do + if [[ -x $awk_path ]]; then + awk_paths+=( "$awk_path" ) + fi + done + + # There is no awk execute file in this PATH + if (( $#awk_paths == 0 )); then + __zplug::io::log::warn \ + "gawk or nawk is not found" + return 1 + fi + + # Detect awk variant from available awk list + for awk_path in "${awk_paths[@]}" + do + if ${=awk_path} --version 2>&1 | grep -q "GNU Awk"; then + # GNU Awk + variant="gawk" + awk="$awk_path" + # Use gawk if it's already installed + break + elif ${=awk_path} -Wv 2>&1 | grep -q "mawk"; then + # mawk + variant=${variant:-"mawk"} + echo $awk:$variant + else + # nawk + variant="nawk" + awk="$awk_path" + # Search another variant if awk is nawk + continue + fi + done + + if [[ $awk == "" || $variant == "mawk" ]]; then + __zplug::io::log::warn \ + "gawk or nawk is not found" + return 1 + fi + + echo "$awk" +} + +__zplug::utils::awk::available() +{ + local awk_path + + __zplug::utils::awk::path \ + | read awk_path + + # AWK is available + if [[ -n $awk_path ]]; then + return 0 + else + return 1 + fi +} diff --git a/base/utils/git.zsh b/base/utils/git.zsh new file mode 100644 index 00000000..b7966272 --- /dev/null +++ b/base/utils/git.zsh @@ -0,0 +1,331 @@ +__zplug::utils::git::clone() +{ + local repo="${1:?}" + local depth_option url_format + local -i ret=1 + local -A tags default_tags + + # A validation of ZPLUG_PROTOCOL + # - HTTPS (recommended) + # - SSH + if [[ ! $ZPLUG_PROTOCOL =~ ^(HTTPS|https|SSH|ssh)$ ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "ZPLUG_PROTOCOL is an invalid protocol.\n" + return 1 + fi + + __zplug::core::tags::parse "$repo" + tags=( "${reply[@]}" ) + + if [[ $tags[depth] == 0 ]]; then + depth_option="" + else + depth_option="--depth=$tags[depth]" + fi + + # If an 'at' tag has been specified, do a deep clone to allow any commit to be + # checked out. + default_tags[at]="$( + __zplug::core::core::run_interfaces \ + 'at' + )" + if [[ $tags[at] != $default_tags[at] ]]; then + depth_option="" + fi + + # Assemble a URL for cloning from its handler + if __zplug::core::sources::is_handler_defined "get_url" "$tags[from]"; then + __zplug::core::sources::use_handler \ + "get_url" \ + "$tags[from]" \ + "$repo" \ + | read url_format + + if [[ -z $url_format ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "$repo is an invalid 'user/repo' format.\n" + return 1 + fi + + GIT_TERMINAL_PROMPT=0 \ + git clone \ + --quiet \ + --recursive \ + ${=depth_option} \ + "$url_format" "$tags[dir]" \ + 2> >(__zplug::io::log::capture) >/dev/null + fi + + # The revison (hash/branch/tag) lock + __zplug::utils::git::checkout "$repo" + + return $status +} + +__zplug::utils::git::checkout() +{ + local repo="${1:?}" + local -a do_not_checkout + local -A tags + + do_not_checkout=( "gh-r" ) + tags[at]="$(__zplug::core::core::run_interfaces 'at' "$repo")" + tags[dir]="$(__zplug::core::core::run_interfaces 'dir' "$repo")" + tags[from]="$(__zplug::core::core::run_interfaces 'from' "$repo")" + + if (( $do_not_checkout[(I)$tags[from]] )); then + return 0 + fi + + # Try not to be affected by directory changes + # by running in subshell + ( + __zplug::utils::shell::cd \ + "$tags[dir]" \ + "$tags[dir]:h" + if (( $status != 0 )); then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "no such directory '$tags[dir]' ($repo)\n" + return 1 + fi + + git checkout -q "$tags[at]" \ + 2> >(__zplug::io::log::capture) >/dev/null + if (( $status != 0 )); then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "pathspec '$tags[at]' (at tag) did not match ($repo)\n" + fi + ) +} + +# TODO: +# - __zplug::utils::git::fetch +# - __zplug::utils::git::pull +__zplug::utils::git::merge() +{ + local key value + local opt arg + local -A git + + __zplug::utils::shell::getopts "$argv[@]" \ + | while read key value; \ + do + case "$key" in + dir) + git[dir]="$value" + ;; + branch) + git[branch]="$value" + ;; + esac + done + + __zplug::utils::shell::cd \ + "$git[dir]" || return $_ZPLUG_STATUS_REPO_NOT_FOUND + + { + if [[ -e $git[dir]/.git/shallow ]]; then + git fetch --unshallow + else + git fetch + fi + git checkout -q "$git[branch]" + } 2> >(__zplug::io::log::capture) >/dev/null + + git[local]="$(git rev-parse HEAD)" + git[upstream]="$(git rev-parse "@{upstream}")" + git[base]="$(git merge-base HEAD "@{upstream}")" + + if [[ $git[local] == $git[upstream] ]]; then + # up-to-date + return $_ZPLUG_STATUS_REPO_UP_TO_DATE + + elif [[ $git[local] == $git[base] ]]; then + # need to pull + { + git merge --ff-only "origin/$git[branch]" + git submodule update --init --recursive + } \ + 2> >(__zplug::io::log::capture) >/dev/null + return $status + + elif [[ $git[upstream] == $git[base] ]]; then + # need to push + return $_ZPLUG_STATUS_FAILURE + + else + # Diverged + return $_ZPLUG_STATUS_FAILURE + fi + + return $_ZPLUG_STATUS_SUCCESS +} + +__zplug::utils::git::status() +{ + local repo="${1:?}" + local key val line + local -A tags revisions + + git ls-remote --heads --tags https://github.com/"$repo".git \ + | awk '{print $2,$1}' \ + | sed -E 's@^refs/(heads|tags)/@@g' \ + | while read line; do + key=${${(s: :)line}[1]} + val=${${(s: :)line}[2]} + revisions[$key]="$val" + done + + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" + )" + + # TODO: git rev-parse + git \ + --git-dir="$tags[dir]/.git" \ + --work-tree="$tags[dir]" \ + log \ + --oneline \ + --pretty="format:%H" \ + --max-count=1 \ + | read val + revisions[local]="$val" + + reply=( "${(kv)revisions[@]}" ) +} + +__zplug::utils::git::get_head_branch_name() +{ + local head_branch + + if __zplug::base::base::git_version 1.7.10; then + head_branch="$(git symbolic-ref -q --short HEAD)" + else + head_branch="${$(git symbolic-ref -q HEAD)#refs/heads/}" + fi + + if [[ -z $head_branch ]]; then + git rev-parse --short HEAD + return 1 + fi + printf "$head_branch\n" +} + +__zplug::utils::git::get_remote_name() +{ + local branch="${1:?}" remote_name + + remote_name="$(git config branch.${branch}.remote)" + if [[ -z $remote_name ]]; then + __zplug::io::log::warn \ + "no remote repository" + return 1 + fi + + echo "$remote_name" +} + +__zplug::utils::git::get_remote_state() +{ + local remote_name branch + local merge_branch remote_show + local state url + local -a behind_ahead + local -i behind ahead + + branch="$1" + remote_name="$(__zplug::utils::git::get_remote_name "$branch")" + + if (( $status == 0 )); then + merge_branch="${$(git config branch.${branch}.merge)#refs/heads/}" + remote_show="$(git remote show "$remote_name")" + state="$(grep "^ *$branch *pushes" <<<"$remote_show" | sed 's/.*(\(.*\)).*/\1/')" + + if [[ -z $state ]]; then + behind_ahead=( ${(@f)"$(git rev-list \ + --left-right \ + --count \ + "$remote_name/$merge_branch"...$branch)"} ) + behind=$behind_ahead[1] + ahead=$behind_ahead[2] + + if (( $behind > 0 )); then + state="local out of date" + else + origin_head="${$(git ls-remote origin HEAD)[1]}" + + git rev-parse -q "$origin_head" \ + 2> >(__zplug::io::log::capture) >/dev/null + if (( $status != 0 )); then + state="local out of date" + elif (( $ahead > 0 )); then + state="fast-forwardable" + else + state="up to date" + fi + fi + fi + + url="$(grep '^ *Push' <<<"$remote_show" | sed 's/^.*URL: \(.*\)$/\1/')" + else + state="$remote_name" + fi + + echo "$state" + echo "$url" +} + +__zplug::utils::git::get_state() +{ + local branch + local -a res + local state url + + if [[ ! -e .git ]]; then + state="not git repo" + fi + + state="not on any branch" + + branch="$(__zplug::utils::git::get_head_branch_name)" + if (( $status == 0 )); then + res=( ${(@f)"$(__zplug::utils::git::get_remote_state "$branch")"} ) + state="$res[1]" + url="$res[2]" + fi + + case "$state" in + "local out of date") + state="${fg[red]}${state}${reset_color}" + ;; + "up to date") + state="${fg[green]}${state}${reset_color}" + ;; + esac + + printf "($state) '${url:-?}'\n" +} + +__zplug::utils::git::remote_url() +{ + # Check if it has git directory + [[ -e .git ]] || return 1 + + git remote -v \ + | sed -n '1p' \ + | awk '{print $2}' +} diff --git a/base/support/omz.zsh b/base/utils/omz.zsh similarity index 77% rename from base/support/omz.zsh rename to base/utils/omz.zsh index 32fda13b..731e82b4 100644 --- a/base/support/omz.zsh +++ b/base/utils/omz.zsh @@ -1,12 +1,11 @@ -#!/usr/bin/env zsh - -__zplug::support::omz::depends() { - local lib_f func_name dep - local -a target +__zplug::utils::omz::depends() +{ + local lib_f func_name dep + local -a target local -a -U depends - local -a func_names - local -A omz_libs - local omz_repo="$ZPLUG_REPOS/$_ZPLUG_OHMYZSH" + local -a func_names + local -A omz_libs + local omz_repo="$ZPLUG_REPOS/$_ZPLUG_OHMYZSH" for lib_f in "$omz_repo"/lib/*.zsh(.) do @@ -34,7 +33,7 @@ __zplug::support::omz::depends() { [[ -f $t ]] || continue sed '/^ *#/d' "$t" \ | egrep "(^|\s|['\"(\`])$lib_f($|\s|[\\\\'\")\`])" \ - &>/dev/null && + 2> >(__zplug::io::log::capture) >/dev/null && depends+=( "$omz_libs[$lib_f]" ) done done @@ -46,6 +45,7 @@ __zplug::support::omz::depends() { done } -__zplug::support::omz::theme() { +__zplug::utils::omz::theme() +{ setopt prompt_subst } diff --git a/base/utils/releases.zsh b/base/utils/releases.zsh new file mode 100644 index 00000000..88ce452c --- /dev/null +++ b/base/utils/releases.zsh @@ -0,0 +1,240 @@ +__zplug::utils::releases::get_latest() +{ + local repo="${1:?}" + local cmd url + + repo="${1:?}" + + url="https://github.com/$repo/releases/latest" + if (( $+commands[curl] )); then + cmd="curl -fsSL" + elif (( $+commands[wget] )); then + cmd="wget -qO -" + fi + + eval "$cmd $url" \ + 2> >(__zplug::io::log::capture) \ + | grep -o '/'"$repo"'/releases/download/[^"]*' \ + | awk -F/ '{print $6}' \ + | sort \ + | uniq +} + +__zplug::utils::releases::get_state() +{ + local state + local name="${1:?}" + local dir="${2:?}" + local url="https://github.com/$name/releases" + + if [[ "$(__zplug::utils::releases::get_latest "$name")" == "$(cat "$dir/INDEX")" ]]; then + state="up to date" + else + state="local out of date" + fi + + case "$state" in + "local out of date") + state="${fg[red]}${state}${reset_color}" + ;; + "up to date") + state="${fg[green]}${state}${reset_color}" + ;; + esac + __zplug::io::print::put "($state) '${url:-?}'\n" +} + +__zplug::utils::releases::is_64() +{ + uname -m | grep -q "64$" +} + +__zplug::utils::releases::get_url() +{ + local repo="${1:?}" + local tag_use tag_at + local cmd url + local -i arch=386 + local -a candidates + local result + + { + tag_use="$( + __zplug::core::core::run_interfaces \ + 'use' \ + "$repo" + )" + tag_at="$( + __zplug::core::core::run_interfaces \ + 'at' \ + "$repo" + )" + + #if [[ $tag_use == '*.zsh' ]]; then + # tag_use= + #fi + #if [[ $tag_at == "master" ]]; then + # tag_at="latest" + #fi + + #if [[ -n $tag_at && $tag_at != "latest" ]]; then + # tag_at="tag/$tag_at" + #else + # tag_at="latest" + #fi + + #if [[ -n $tag_use ]]; then + # tag_use="$(__zplug::utils::shell::glob2regexp "$tag_use")" + #else + # tag_use="$(__zplug::base::base::get_os)" + # if __zplug::base::base::is_osx; then + # tag_use="(darwin|osx)" + # fi + #fi + } + + # Get machine information + if __zplug::utils::releases::is_64; then + arch="64" + fi + + url="https://github.com/$repo/releases/$tag_at" + if (( $+commands[curl] )); then + cmd="curl -fsSL" + elif (( $+commands[wget] )); then + cmd="wget -qO -" + fi + + candidates=( + ${(@f)"$( + eval "$cmd $url" \ + 2> >(__zplug::io::log::capture) \ + | grep -o '/'"$repo"'/releases/download/[^"]*' + )"} + ) + if (( $#candidates == 0 )); then + __zplug::io::print::f \ + --die \ + --zplug \ + "$repo: there are no available releases\n" + return 1 + fi + + echo "${(F)candidates[@]}" \ + | grep -E "${tag_use:-}" \ + | grep "$arch" \ + | head -n 1 \ + | read result + + if [[ -z $result ]]; then + __zplug::io::print::f \ + --die \ + --zplug \ + "$repo: repository not found\n" + return 1 + fi + + echo "https://github.com$result" +} + +__zplug::utils::releases::get() +{ + local url="${1:?}" + local repo dir header artifact cmd + local -A tags + + # make 'username/reponame' style + repo="${url:s-https://github.com/--:F[4]h}" + + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + "$repo" + )" + header="${url:h:t}" + artifact="${url:t}" + + if (( $+commands[curl] )); then + cmd="curl -L -O" + elif (( $+commands[wget] )); then + cmd="wget" + fi + + ( + __zplug::utils::shell::cd \ + --force \ + "$tags[dir]" + + # Grab artifact from G-R + eval "$cmd $url" \ + 2> >(__zplug::io::log::capture) >/dev/null + + __zplug::utils::releases::index \ + "$repo" \ + "$artifact" \ + 2> >(__zplug::io::log::capture) >/dev/null && + echo "$header" >"$tags[dir]/INDEX" + ) + + return $status +} + +__zplug::utils::releases::index() +{ + local repo="$1" artifact="$2" + local cmd="${repo:t}" + local -a binaries + + case "$artifact" in + *.zip) + { + unzip "$artifact" + rm -f "$artifact" + } 2> >(__zplug::io::log::capture) >/dev/null + ;; + *.tar.gz|*.tgz) + { + tar xvf "$artifact" + rm -f "$artifact" + } 2> >(__zplug::io::log::capture) >/dev/null + ;; + *.*) + __zplug::io::log::error \ + "$artifact: Unknown extension format" + return 1 + ;; + *) + # Through + ;; + esac + + binaries=( + $( + file **/*(N-.) \ + | awk -F: '$2 ~ /executable/{print $1}' + ) + ) + + if (( $#binaries == 0 )); then + __zplug::io::log::error \ + "$cmd: Failed to grab binaries from GitHub Releases" + return 1 + fi + + { + mv -f "$binaries[1]" "$cmd" + chmod 755 "$cmd" + rm -rf *~"$cmd"(N) + } 2> >(__zplug::io::log::capture) >/dev/null + + if [[ ! -x $cmd ]]; then + __zplug::io::print::die \ + "$repo: Failed to install\n" + return 1 + fi + + __zplug::io::print::put \ + "$repo: Installed successfully\n" + + return 0 +} diff --git a/base/utils/shell.zsh b/base/utils/shell.zsh new file mode 100644 index 00000000..cfcb35e9 --- /dev/null +++ b/base/utils/shell.zsh @@ -0,0 +1,171 @@ +__zplug::utils::shell::remove_deadlinks() +{ + local link + + for link in "$@" + do + if [[ -L $link ]] && [[ ! -e $link ]]; then + rm -f "$link" + fi + done +} + +__zplug::utils::shell::search_commands() +{ + local -a args + local arg element cmd_name + local is_verbose=true + + while (( $# > 0 )) + do + arg="$1" + case $arg in + --verbose) + is_verbose=true + ;; + --silent) + is_verbose=false + ;; + -*|--*) + return 1 + ;; + *) + args=+( "$arg" ) + ;; + esac + shift + done + + for arg in "${args[@]}" + do + for element in "${(s.:.)arg}" + do + # Extract the first argument sparated by a space + cmd_name="${element%% *}" + + # Check if cmd_name is available + if (( $+commands[$cmd_name] )); then + if $is_verbose; then + echo "$cmd_name" + fi + return 0 + else + continue + fi + done + done + + return 1 +} + +__zplug::utils::shell::glob2regexp() +{ + local -i i=0 + local glob="${1:?}" char + + printf "^" + for ((; i < $#glob; i++)) + do + char="${glob:$i:1}" + case "$char" in + \*) + printf '.*' + ;; + .) + printf '\.' + ;; + "{") + printf '(' + ;; + "}") + printf ')' + ;; + ,) + printf '|' + ;; + "?") + printf '.' + ;; + \\) + printf '\\\\' + ;; + *) + printf "$char" + ;; + esac + done + printf "$\n" +} + +__zplug::utils::shell::sudo() +{ + local pw="$ZPLUG_SUDO_PASSWORD" + + if [[ -z $pw ]]; then + __zplug::io::log::error \ + "ZPLUG_SUDO_PASSWORD: is an invalid value\n" + return 1 + fi + + sudo -k + echo "$pw" \ + | sudo -S -p '' "$argv[@]" +} + +__zplug::utils::shell::unansi() +{ + perl -pe 's/\e\[?.*?[\@-~]//g' +} + +__zplug::utils::shell::cd() +{ + local dir arg + local -a dirs + local is_force=false + + while (( $# > 0 )) + do + arg="$1" + case "$arg" in + --force) + is_force=true + ;; + -*|--*) + return 1 + ;; + "") + ;; + *) + dirs+=( "$arg" ) + ;; + esac + shift + done + + for dir in "$dirs[@]" + do + if $is_force; then + [[ -d $dir ]] || mkdir -p "$dir" + fi + + builtin cd "$dir" \ + 2> >(__zplug::io::log::capture) >/dev/null + return $status + done + + return 1 +} + +__zplug::utils::shell::getopts() +{ + printf "%s\n" "$argv[@]" \ + | awk -f "$ZPLUG_ROOT/misc/contrib/getopts.awk" +} + +__zplug::utils::shell::pipestatus() +{ + local _status="${pipestatus[*]-}" + + [[ ${_status//0 /} == 0 ]] + return $status +} diff --git a/base/utils/yaml.zsh b/base/utils/yaml.zsh new file mode 100644 index 00000000..f4ec5dc3 --- /dev/null +++ b/base/utils/yaml.zsh @@ -0,0 +1,54 @@ +typeset -gx -A _zplug_yaml + +__zplug::utils::yaml::tokenizer() +{ + local prefix="$1" + local s='[[:space:]]*' + local w='[a-zA-Z0-9_]*' + local fs="$(echo '@' | tr '@' '\034')" + + sed -ne "s|^\($s\):|\1|" \ + -e "s|^\($s\)\($w\)$s:[[:space:]]*[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \ + -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" \ + | awk -F "$fs" \ + ' + { + indent = length($1) / 2; + vname[indent] = $2; + for (i in vname) { + if (i > indent) { + fidelete vname[i] + } + } + if (length($3) > 0) { + vn = ""; + for (i = 0; i < indent; i++) { + vn=(vn)(vname[i])("_"); + } + #printf("%s%s%s=\"%s\"\n", "'$prefix'", vn, $2, $3); + printf("%s%s%s\n%s\n", "'$prefix'", vn, $2, $3); + } + }' +} + +__zplug::utils::yaml::parser() +{ + local yaml="$1" key + local -A parsed_yaml + + _zplug_yaml=() + + parsed_yaml=( "${(@f)$( + if [[ -f "$yaml" ]]; then + cat "$yaml" + else + cat <&0 + fi \ + | __zplug::utils::yaml::tokenizer + )}" ) + + for key in "${(k)parsed_yaml[@]}" + do + _zplug_yaml[$key]="$parsed_yaml[$key]" + done +} diff --git a/base/zplug/cache.zsh b/base/zplug/cache.zsh deleted file mode 100644 index 197dff45..00000000 --- a/base/zplug/cache.zsh +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env zsh - -__import "print/print" - -__zplug::zplug::cache::tags() { - local key - - for key in "${(k)zplugs[@]}" - do - echo "name:$key, $zplugs[$key]" - done \ - | awk -f "$ZPLUG_ROOT/misc/share/cache.awk" -} - -__zplug::zplug::cache::load() { - local key - - $ZPLUG_USE_CACHE || return 2 - if [[ -f $ZPLUG_CACHE_FILE ]]; then - &>/dev/null diff -b \ - <( \ - awk -f "$ZPLUG_ROOT/misc/share/read_cache.awk" \ - "$ZPLUG_CACHE_FILE" \ - ) \ - <( \ - for key in "${(k)zplugs[@]}" - do \ - echo "name:$key, $zplugs[$key]"; \ - done \ - | awk -f "$ZPLUG_ROOT/misc/share/cache.awk" - ) - - case $status in - 0) - # same - source "$ZPLUG_CACHE_FILE" - return $status - ;; - 1) - # differ - ;; - 2) - # error - __zplug::print::print::die "zplug: cache: something wrong\n" - ;; - esac - fi - - # if cache file doesn't find, - # returns non-zero exit code - return 1 -} - -__zplug::zplug::cache::update() { - $ZPLUG_USE_CACHE || return 2 - if [[ $funcstack[2] != "__load__" ]]; then - printf "[zplug] this function must be called by __load__\n" >&2 - return 2 - fi - - if [[ -f $ZPLUG_CACHE_FILE ]]; then - chmod a+w "$ZPLUG_CACHE_FILE" - fi - - if [[ ! -d ${ZPLUG_CACHE_FILE:h} ]]; then - mkdir -p "${ZPLUG_CACHE_FILE:h}" - fi - - { - __zplug::print::print::put '#!/usr/bin/env zsh\n\n' - __zplug::print::print::put '# This file was generated by zplug\n' - __zplug::print::print::put '# *** DO NOT EDIT THIS FILE ***\n\n' - __zplug::print::print::put '[[ $- =~ i ]] || exit\n' - if (( ! $path[(I)$ZPLUG_HOME/bin] )); then - __zplug::print::print::put 'export PATH="%s:$PATH"\n' "$ZPLUG_HOME/bin" - fi - __zplug::print::print::put 'export ZSH=${ZSH:-%s}\n' "$ZPLUG_REPOS/$_ZPLUG_OHMYZSH" - __zplug::print::print::put 'export ZSH_CACHE_DIR=${ZSH_CACHE_DIR:-$ZSH/cache}/\n\n' - - __zplug::print::print::put 'if $is_verbose; then\n' - __zplug::print::print::put ' echo "Static loading..." >&2\n' - __zplug::print::print::put 'fi\n' - if [[ -o prompt_subst ]]; then - __zplug::print::print::put 'setopt prompt_subst\n' - fi - if (( $#load_plugins > 0 )); then - __zplug::print::print::put 'source %s\n' "${(uqqq)load_plugins[@]}" - fi - if (( $#load_fpaths > 0 )); then - __zplug::print::print::put '\n# fpath\n' - __zplug::print::print::put 'fpath=(\n' - __zplug::print::print::put '%s\n' ${(u)load_fpaths} - __zplug::print::print::put '$fpath\n' - __zplug::print::print::put ')\n' - fi - __zplug::print::print::put 'compinit -i -d %s\n' "$ZPLUG_HOME/zcompdump" - if (( $#nice_plugins > 0 )); then - __zplug::print::print::put '\n# Loading after compinit\n' - __zplug::print::print::put 'source %s\n' "${(qqq)nice_plugins[@]}" - fi - if (( $#lazy_plugins > 0 )); then - __zplug::print::print::put '\n# Lazy loading plugins\n' - __zplug::print::print::put 'autoload -Uz %s\n' "${(qqq)lazy_plugins[@]:t}" - fi - __zplug::print::print::put '\n# Hooks after load\n%s\n' "${hook_load_cmds[@]}" - __zplug::print::print::put '\nreturn 0\n' - __zplug::print::print::put '%s\n' "$(__zplug::zplug::cache::tags)" - } >|"$ZPLUG_CACHE_FILE" - - if [[ -f $ZPLUG_CACHE_FILE ]]; then - chmod a-w "$ZPLUG_CACHE_FILE" - fi -} diff --git a/base/zplug/external.zsh b/base/zplug/external.zsh deleted file mode 100644 index c1e352ff..00000000 --- a/base/zplug/external.zsh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env zsh - -__import "print/print" - -__zplug::zplug::external::load() { - if [[ -f $ZPLUG_LOADFILE ]]; then - source "$ZPLUG_LOADFILE" - fi -} - -__zplug::zplug::external::generate() { - if [[ ! -f $ZPLUG_LOADFILE ]]; then - cat <<-TEMPLATE >$ZPLUG_LOADFILE - #!/usr/bin/env zsh - # -*- mode: zsh -*- - # vim:ft=zsh - # - # *** ZPLUG EXTERNAL FILE *** - # You can register plugins or commands to zplug on the - # command-line. If you use zplug on the command-line, - # it is possible to write more easily its settings - # by grace of the command-line completion. - # In this case, zplug spit out its settings to - # $ZPLUG_LOADFILE instead of .zshrc. - # If you launch new zsh process, zplug load command - # automatically search this file and run source command. - # - # - # Example: - # zplug "b4b4r07/enhancd", as:plugin, of:"*.sh" - # zplug "rupa/z", as:plugin, of:"*.sh" - # -TEMPLATE - fi - - if [[ -n $1 ]]; then - __zplug::print::print::put "$@\n" >>|$ZPLUG_LOADFILE - fi -} diff --git a/base/zplug/variables.zsh b/base/zplug/variables.zsh deleted file mode 100644 index b3c58b37..00000000 --- a/base/zplug/variables.zsh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env zsh - -__import "print/print" -__import "core/core" - -typeset -gx -A zplugs - -typeset -gx ZPLUG_HOME=${ZPLUG_HOME:-~/.zplug} -typeset -gx ZPLUG_THREADS=${ZPLUG_THREADS:-16} -typeset -gx ZPLUG_CLONE_DEPTH=${ZPLUG_CLONE_DEPTH:-0} -typeset -gx ZPLUG_PROTOCOL=${ZPLUG_PROTOCOL:-HTTPS} -typeset -gx ZPLUG_FILTER=${ZPLUG_FILTER:-"fzf-tmux:fzf:peco:percol:zaw"} -typeset -gx ZPLUG_LOADFILE=${ZPLUG_LOADFILE:-$ZPLUG_HOME/packages.zsh} -typeset -gx ZPLUG_USE_CACHE=${ZPLUG_USE_CACHE:-true} -typeset -gx ZPLUG_CACHE_FILE=${ZPLUG_CACHE_FILE:-$ZPLUG_HOME/.cache} -typeset -gx ZPLUG_REPOS=${ZPLUG_REPOS:-$ZPLUG_HOME/repos} - -typeset -gx -r _ZPLUG_VERSION="2.1.0" -typeset -gx -r _ZPLUG_URL="https://github.com/zplug/zplug" -typeset -gx -r _ZPLUG_HELP="usage: zplug [COMMANDS] [OPTIONS] - zplug is a next-generation plugin manager for zsh - -OPTIONS: - --help Display the help message - --version Display the version of zplug - -COMMANDS: - install Install packages in parallel - load Source installed plugins and add installed commands to \$PATH - list List installed packages (more specifically, view the associative array \$zplugs) - update Update installed packages in parallel - check Return true if all packages are installed, false otherwise - status Check if the remote repositories are up to date - clean Remove repositories which are no longer managed - clear Remove the cache file - info Show the information such as the source URL and tag values for the given package - -For more information, see also ${(%):-"%U"}$_ZPLUG_URL${(%):-"%u"}." - -typeset -g -r _ZPLUG_OHMYZSH="robbyrussell/oh-my-zsh" - -__zplug::core::core::get_tags -typeset -ga _zplug_tag_pattern -_zplug_tag_pattern=( "${reply[@]}" ) - -if (( $+ZPLUG_SHALLOW )); then - __zplug::print::print::die "[zplug] $fg[red]${(%):-"%U"}WARNING${(%):-"%u"}$reset_color: ZPLUG_SHALLOW is deprecated. " - __zplug::print::print::die "Please use 'export ZPLUG_CLONE_DEPTH=1' instead.\n" -fi - -typeset -ga _zplug_boolean_true -_zplug_boolean_true=("true" "yes" "on" 1) -typeset -ga _zplug_boolean_false -_zplug_boolean_false=("false" "no" "off" 0) - -# context ":zplug:config:setopt" -local -a only_subshell -typeset -gx _ZPLUG_CONFIG_SUBSHELL=":" -zstyle -a ":zplug:config:setopt" \ - only_subshell \ - only_subshell -zstyle -t ":zplug:config:setopt" \ - same_curshell -if (( $_zplug_boolean_true[(I)$same_curshell] )); then - only_subshell=( - "${only_subshell[@]:gs:_:}" - $(setopt) - ) -fi -if (( $#only_subshell > 0 )); then - _ZPLUG_CONFIG_SUBSHELL="setopt ${(u)only_subshell[@]}" -fi diff --git a/bin/zplug-env b/bin/zplug-env index f942d130..1d498f1f 100755 --- a/bin/zplug-env +++ b/bin/zplug-env @@ -1,8 +1,8 @@ #!/usr/bin/env zsh -# description: The environment variables of zplug +# Description: The environment variables of zplug # ^-- This description is used as complete message -# Sample zplug script +# This is a sample zplug script # For more information, see man page of zplug(1) env \ diff --git a/doc/guide/Badges-and-references.md b/doc/guide/Badges-and-references.md new file mode 100644 index 00000000..6e84da30 --- /dev/null +++ b/doc/guide/Badges-and-references.md @@ -0,0 +1,40 @@ +# Badges + +[![][travis-badge]][travis-link] +[![][latest-badge]][latest-link] +[![][slack-badge]][slack-link] +[![][homebrew-badge]][homebrew-link] +[![][aur-version-badge]][aur-version-link] +[![][aur-votes-badge]][aur-votes-link] +[![][tag-badge]][tag-link] +[![][release-badge]][release-link] +[![][commits-since-badge]][commits-since-link] +[![][website-badge]][website-link] +[![][stable-badge]][stable-link] + +[travis-badge]: https://img.shields.io/travis/zplug/zplug.svg?style=flat-square +[latest-badge]: https://img.shields.io/badge/latest-v2.1.0-ca7f85.svg?style=flat-square +[slack-badge]: https://img.shields.io/badge/slack-join-ca7f85.svg?style=flat-square +[homebrew-badge]: https://img.shields.io/homebrew/v/zplug.svg?style=flat-square +[aur-version-badge]: https://img.shields.io/aur/version/zplug.svg?style=flat-square +[aur-votes-badge]: https://img.shields.io/aur/votes/zplug.svg?style=flat-square +[tag-badge]: https://img.shields.io/github/tag/zplug/zplug.svg?style=flat-square +[release-badge]: https://img.shields.io/github/release/zplug/zplug.svg?style=flat-square +[commits-since-badge]: https://img.shields.io/github/commits-since/zplug/zplug/2.1.0.svg?style=flat-square +[website-badge]: https://img.shields.io/website-up-down-green-red/http/zplug.sh.svg?style=flat-square +[stable-badge]: https://img.shields.io/badge/stable-2.1.0-00CCFF.svg?style=flat-square + +[travis-link]: https://travis-ci.org/zplug/zplug +[latest-link]: https://github.com/zplug/zplug/releases +[slack-link]: https://zplug.herokuapp.com +[homebrew-link]: https://github.com/Homebrew/homebrew-core/blob/master/Formula/zplug.rb +[aur-version-link]: https://aur.archlinux.org/packages/zplug +[aur-votes-link]: https://aur.archlinux.org/packages/zplug +[tag-link]: https://github.com/zplug/zplug/tags +[release-link]: https://github.com/zplug/zplug/releases +[commits-since-link]: https://github.com/zplug/zplug/compare/2.1.0...master +[website-link]: http://zplug.sh +[stable-link]: https://github.com/zplug/zplug/releases/tag/2.1.0 + +[repo]: https://github.com/zplug/zplug +[license]: http://b4b4r07.mit-license.org diff --git a/doc/zplug/External-Commands.md b/doc/guide/External-Commands.md similarity index 100% rename from doc/zplug/External-Commands.md rename to doc/guide/External-Commands.md diff --git a/doc/zplug/External-Sources.md b/doc/guide/External-Sources.md similarity index 100% rename from doc/zplug/External-Sources.md rename to doc/guide/External-Sources.md diff --git a/doc/zplug/How-to-make-zsh-plugins.md b/doc/guide/How-to-make-zsh-plugins.md similarity index 100% rename from doc/zplug/How-to-make-zsh-plugins.md rename to doc/guide/How-to-make-zsh-plugins.md diff --git a/doc/guide/README.ja.md b/doc/guide/README.ja.md new file mode 100644 index 00000000..2d64bdb9 --- /dev/null +++ b/doc/guide/README.ja.md @@ -0,0 +1,372 @@ +[:us:](../../README.md) :jp: + +> Zsh のプラグインマネージャー + +[![Travis][travis-badge]][travis-link] +[![Version][version-badge]][version-link] +[![Slack][slack-badge]][slack-link] + +
+ + + +
+
+ +## メリット + +- 何でも管理できる + - [GitHub](https://github.com) や [Bitbucket](https://bitbucket.org) にあるプラグインや UNIX コマンド + - Gist ファイル ([gist.github.com](https://gist.github.com)) + - 外部フレームワークなどのプラグイン (例: [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) のプラグイン・テーマ) + - [GitHub Releases](https://help.github.com/articles/about-releases/) のバイナリファイル + - ローカルプラグイン + - その他 ([カスタムソース](https://github.com/zplug/zplug/blob/master/doc/zplug/External-Sources.md)によって追加できる) +- 高速インストール・高速アップデート +- 遅延読み込みに対応 +- リビジョンロック(ブランチやタグを固定する機能) +- `post-update` 等のフック機能 +- パッケージ間の依存管理 +- [antigen](https://github.com/zsh-users/antigen) とは違って、`*.plugin.zsh` を必要としない +- 対話的インターフェイス([fzf](https://github.com/junegunn/fzf), [peco](https://github.com/peco/peco), [zaw](https://github.com/zsh-users/zaw) など) +- キャッシュ機能による読み込み高速化 ([起動時間](#vs)) + +***DEMO:*** + +[![](https://raw.githubusercontent.com/b4b4r07/screenshots/master/zplug/install.gif)][repo] + +## インストール + +### 推奨方法 + +```console +$ curl -sL zplug.sh/installer | zsh +``` + +インストーラの実態: + +- [zplug/installer](https://github.com/zplug/installer/blob/master/installer.zsh) + +### [Homebrew](https://github.com/Homebrew/brew) から (OS X) + +```console +$ brew install zplug +``` + +### git から + +GitHub からクローンしてきて `init.zsh` を読み込む: + +```console +$ export ZPLUG_HOME=/path/to/.zplug +$ git clone https://github.com/zplug/zplug $ZPLUG_HOME +``` + +## 必要条件 + +- `zsh`: バージョン 4.3.9 以上 +- `git`: バージョン 1.7 以上 +- `awk`: `mawk` 以外の AWK 処理系 + +## 利用方法 + +`.zshrc` に以下を書き込む: + +1. `zplug` commands でインストールするパッケージについて書く +2. `zplug load` によりプラグインを読み込み、コマンドを `$PATH` に追加するようにする + +### Example + +[![](https://raw.githubusercontent.com/b4b4r07/screenshots/master/zplug/example.png)][repo] + +```zsh +source ~/.zplug/init.zsh + +# ダブルクォーテーションで囲むと良い +zplug "zsh-users/zsh-history-substring-search" + +# コマンドとしてインストールする +# グロブ・パターンを受け付ける(ブレースやワイルドカードなど) +zplug "Jxck/dotfiles", as:command, use:"bin/{histuniq,color}" + +# 何でも管理・読み込みができる(例えば他人の zshrc) +zplug "tcnksm/docker-alias", use:zshrc + +# Disable updates using the "frozen:" tag +zplug "k4rthik/git-cal", as:command, frozen:1 + +# GitHub Releases からバイナリを取得する +# "rename-to:" タグでファイル名を変更できる +zplug "junegunn/fzf-bin", \ + from:gh-r, \ + as:command, \ + rename-to:fzf, \ + use:"*darwin*amd64*" + +# oh-my-zsh のプラグインなど +zplug "plugins/git", from:oh-my-zsh, if:"(( $+commands[git] ))" +zplug "themes/duellj", from:oh-my-zsh +zplug "lib/clipboard", from:oh-my-zsh, if:"[[ $OSTYPE == *darwin* ]]" + +# インストール・アップデート後にコマンドを実行するフック +zplug "tj/n", hook-build:"make install" + +# リビジョン(ブランチ名やハッシュなど)による固定が可能 +zplug "b4b4r07/enhancd", at:v1 +zplug "mollifier/anyframe", at:4c23cb60 + +# "if" タグが真のとき読み込まれる +zplug "hchbaw/opp.zsh", if:"(( ${ZSH_VERSION%%.*} < 5 ))" + +# Gist も同様に管理できる +zplug "b4b4r07/79ee61f7c140c63d2786", \ + from:gist, \ + as:command, \ + use:get_last_pane_path.sh + +# Bitbucket に対応 +zplug "b4b4r07/hello_bitbucket", \ + from:bitbucket, \ + as:command, \ + hook-build:"chmod 755 *.sh", \ + use:"*.sh" + +# 依存管理 +# jq コマンドがインストールされているときのみ emoji-cli を読み込む例 +zplug "stedolan/jq", \ + from:gh-r, \ + as:command, \ + rename-to:jq +zplug "b4b4r07/emoji-cli", \ + on:"stedolan/jq" +# Note: To specify the order in which packages should be loaded, use the nice +# tag described in the next section + +# 読み込む順序を設定する +# 例: zsh-syntax-highlighting は compinit コマンドの実行後に読み込まれる必要がある +# "nice" は 10 以上で compinit 後に実行するようにできる(-20 <= nice <= 19) +zplug "zsh-users/zsh-syntax-highlighting", nice:10 + +# ローカルプラグインを管理する +zplug "~/.zsh", from:local + +# まだインストールされていないプラグインを一括インストールする +if ! zplug check --verbose; then + printf "Install? [y/N]: " + if read -q; then + echo; zplug install + fi +fi + +# その後プラグインを読み込み、コマンドを PATH に追加する +zplug load --verbose +``` + +Finally, use `zplug install` to install your plugins and reload `.zshrc`. + +### 1. オプション + +| オプション | 説明 | +|--------|-------------| +| `--help` | ヘルプを表示する | +| `--version` | バージョン情報を表示する | + +### 2. サブコマンド + +| サブコマンド | 説明 | そのオプション | +|-----------|-------------|---------| +| `install` | 並列インストール | (なし) | +| `load` | インストール済みプラグインを読み込み、インストール済みコマンドを `$PATH` に追加する | `--verbose` | +| `list` | インストール済みパッケージを表示する (端的に連想配列 `$zplugs` を表示する) | `--select` | +| `update` | インストール済みパッケージを並列でアップデートする | `--self`,`--select`,`--force` | +| `check` | 未インストールなパッケージがないなら真を返し、そうでなければ偽を返す | `--verbose` | +| `status` | パッケージが最新かどうか確認する| `--select` | +| `clean` | 管理されていないパッケージを削除する | `--force`,`--select` | +| `clear` | キャッシュを削除する | (なし) | +| `info` | パッケージのタグ情報などを個別に表示する | (なし) | + +#### 実用例 + +```zsh +# zplug check はインストールするものがないときに真を返す +# ゆえにそうでないとき zplug install する +if ! zplug check; then + zplug install +fi + +# プラグインを読み込み、コマンドを実行可能にする +zplug load + +# zplug check は引数に与えられたリポジトリがインストールされているなら真を返す +if zplug check b4b4r07/enhancd; then + # enhancd がインストールされている場合のみ設定する + export ENHANCD_FILTER=fzf-tmux +fi +``` + +#### zplug を zplug で管理する + +zplug 自身を管理するなら以下を実行する (zplug のインストール後に): + +```console +$ zplug update --self +``` + +`--self` オプションを利用すると zplug が `$ZPLUG_HOME/repos` にインストールされて `$ZPLUG_HOME/zplug` にリンクされる。 + +zplug を他のパッケージと同様に管理するには `.zshrc` に以下を書き込む。 + +```zsh +zplug "zplug/zplug" +``` + +あとは `zplug update` を実行するだけ。 + +[![](https://raw.githubusercontent.com/b4b4r07/screenshots/master/zplug/update.gif)][repo] + +### 3. タグ + +`truthy` は `true`, `yes`, `on`, `1` で、 `falsy` は `false`, `no`, `off`, `0` を意味する。 + +| タグ | 説明 | 値 (デフォルト値) | 例 | +|-----|-------------|-----------------|---------| +| `as` | プラグインとして、またはコマンドとして追加するか指定する | `plugin`,`command` (`plugin`) | `as:command` | +| `use` | 読み込むファイルパターンを指定する (`plugin` のとき) か `$PATH` に追加したいコマンドの相対パスを指定する (`command` のとき) / `from:gh-r` の場合は zplug が自動で OS のアーキテクチャを判別するが、意図しない結果の場合 `use:"*darwin*{amd,386}*"` のようにすると良い | *グロブ・パターン* (`use:"*.zsh"`) | `use:bin`,`use:"*.sh"`, `use:*darwin*` | +| `ignore` | `use` タグと似ているが無視したいファイルパターンを指定する ([#56](https://github.com/zplug/zplug/issues/56) 参照) | *グロブ・パターン* (-) | `ignore:"some_*.zsh"` | +| `from` | どこからインストールするか指定する | `github`,`bitbucket`,
`gh-r`,`gist`,
`oh-my-zsh`,`local` (`github`) | `from:gh-r` | +| `at` | branch/tag/commit を指定して固定する | *リビジョン* (`master`) | `at:v1.5.6` | +| `rename-to` | リンクするときに変更したいファイル名を指定する (`as:command` のときのみ有効) | *ファイル名* (-) | `rename-to:fzf` | +| `dir` | パッケージのインストール先 | **READ ONLY** | `dir:/path/to/user/repo` | +| `if` | パッケージをインストールするときの条件を指定する | *真偽値* (-) | `if:"[ -d ~/.zsh ]"` | +| `hook-build` | インストール・アップデート後に実行するコマンド | *コマンド* (-) | `hook-build:"make install"` | +| `hook-load` | ロード後に実行するコマンド | *コマンド* (-) | `hook-load:"echo 'Loaded!'"` | +| `frozen` | 明示的に指定するとアップデート対象から省く | truthy または falsy (false) | `frozen:1` | +| `on` | 指定されたパッケージがインストールされているときのみロードする | *package* | `on:user/repo` | +| `nice` | プラグインの読み込み順序を指定する。 10 以上を指定すると、`compinit` コマンドの実行後に読まれることになる ([#26](https://github.com/zplug/zplug/issues/26) 参照) | -20 から 19 (0) | `nice:19` | +| `lazy` | 遅延読み込みするかどうかを指定する | truthy または falsy (false) | `lazy:true` | +| `depth` | リポジトリをクローンするときのヒストリサイズ。0 はすべてのヒストリをクローンする | 0 と正の整数 (`ZPLUG_CLONE_DEPTH`) | `depth:10` | + +#### デフォルト値を一括変更する + +`zstyle` によってデフォルト値を変更できる。フォーマットは次のように: + +```zsh +zstyle ":zplug:tag" tag_name new_default_value +``` + +例えば、もしプラグインよりコマンドを利用することが多いなら (具体的に言うと`as:command` とするほうが多い場合) こう書くことができる: + +```zsh +zstyle ":zplug:tag" as command +``` + +こうすることでデフォルト値を変更することができる。`as` タグ以外のタグも同様に。 + +#### コマンドライン上から利用する + +コマンドライン上から zplug パッケージを追加できる。もしコマンドライン上から追加することがあるのなら、zsh 補完を利用してより簡単でパワフルに追加できる。 + +[![](https://raw.githubusercontent.com/b4b4r07/screenshots/master/zplug/cli.gif)][repo] + +この場合、`.zshrc` でなく `$ZPLUG_LOADFILE` に設定を記述される。また、新しく zsh を立ち上げるのときは、`zplug load` の際にこのファイルもロードする。 + +[`ZPLUG_LOADFILE`](#zplug_loadfile) の使い方については後述を参照。 + +### 4. 環境変数 + +#### `ZPLUG_HOME` + +デフォルトでは `~/.zplug`。`zplug` はこのディレクトリ以下に配置される。ディレクトリ構成は以下である。 + +``` +$ZPLUG_HOME +|-- bin +| `-- some_command -> ../repos/username_A/reponame1/some_command +`-- repos + |-- username_A + | |-- reponame1 + | | |-- README.md + | | `-- some_command + | `-- reponame2 + | |-- README.md + | `-- some_plugin.zsh + `-- username_B + `-- reponame1 +``` + +`as:command` を指定したとき、zplug はパッケージをコマンドとみなし、同名のシンボリックリンクを `$ZPLUG_HOME/bin` に作成する (違う名前で作成したい場合、`rename-to:` タグを使う)。`$ZPLUG_HOME/bin` は `$PATH` に追加されるので、インストールしたコマンドはいつでもどこからでも実行可能になる。 + +#### `ZPLUG_THREADS` + +インストール・アップデート時に立ち上がるプロセス数の制限値。デフォルトは 16. + +#### `ZPLUG_PROTOCOL` + +デフォルトは HTTPS。取りうる値は `HTTPS` と `SSH`のみ。特別な理由がない限り、 `HTTPS` を推奨する。 + +詳細やその理由については [**Which remote URL should I use?** - GitHub Help](https://help.github.com/articles/which-remote-url-should-i-use/) を参照のこと。 + +#### `ZPLUG_CLONE_DEPTH` + +デフォルトは `0`。When cloning a Git repository, there is an option to limit the amount of history your clone will have. This environment variable how many commits you want to clone. The value `0` means that zplug will clone the whole history of packages. + +#### `ZPLUG_FILTER` + +デフォルトは `fzf-tmux:fzf:peco:percol:zaw`。`--select` オプションを指定すると、`$PATH` にあるコロンで区切られた最初の要素(この例では fzf-tmux)が zplug で使われる対話フィルタとして使用される。`ZPLUG_FILTER` は次のようにスペースや、ダブルクォーテーションを使用することができる: `fzf-tmux -d "10%":/path/to/peco:my peco` + +#### `ZPLUG_LOADFILE` + +デフォルトは `$ZPLUG_HOME/packages.zsh`。このファイルはコマンドライン上からパッケージの追加を行うときに使用される。これを利用することで `.zshrc` から分離してパッケージリストを管理することができる。 + +#### `ZPLUG_USE_CACHE` + +デフォルトは `true`。true の場合、zplug はロードの高速化のためにキャッシュを利用するようになる。キャッシュファイルは `$ZPLUG_CACHE_FILE` も保存されている。キャッシュをクリアする場合は、`zplug clear` を実行するか以下のようにすると良い: + +```console +$ ZPLUG_USE_CACHE=false zplug load +``` + +#### `ZPLUG_CACHE_FILE` + +デフォルトは `$ZPLUG_HOME/.cache`。キャッシュの保存先を変更することができる。例えば `$HOME/.cache/zplug/cache` とか。 + +#### `ZPLUG_REPOS` + +デフォルトは `$ZPLUG_HOME/repos`。パッケージのクローン先かつ保存先の場所を設定することができる。 + +### 外部コマンド + +zplug では `git(1)` のように外部コマンド機能が利用できる。 +`$PATH` のいずれかにある `zplug-cmdname` の規則を持つ実行ファイルは、まるでサブコマンドのように `zplug cmdname` の形で利用することができる。 +これにより自由に自分で zplug のコマンドを追加したり拡張することができる。 +作成方法や利用ガイドラインの詳細については [docs](https://github.com/zplug/zplug/blob/master/doc/zplug/External-Commands.md) ディレクトリ以下にあるので参照とのこと。実際の外部コマンドのサンプルには [`zplug-env`](https://github.com/zplug/zplug/blob/master/bin/zplug-env) を参照すると良い。 + +## V.S. + +zplug は他の有名な zsh プラグインマネージャーよりも速い: + +[![](https://raw.githubusercontent.com/b4b4r07/screenshots/master/zplug/time.png)][repo] + +## メモ + +- antigen :syringe: はもうおしまい。これからは **zplug** :hibiscus: を使おう +- :hibiscus: zplug は [vim-plug](https://github.com/junegunn/vim-plug) や [neobundle.vim](https://github.com/Shougo/neobundle.vim) を参考に設計された + +## その他 + +zplug などから利用できる zsh プラグインは [awesome-zsh-plugins](https://github.com/unixorn/awesome-zsh-plugins) にあるので参考になる。 + +antigen や zgen、もしくは zplug v1 から移行するための情報は [zplug の公式 wiki](https://github.com/zplug/zplug/wiki/Migration) にある。 + +## ライセンス + +[MIT][license] (c) [@b4b4r07](https://github.com/b4b4r07) + +[repo]: https://github.com/zplug/zplug +[license]: http://b4b4r07.mit-license.org +[travis-link]: https://travis-ci.org/zplug/zplug +[travis-badge]: https://img.shields.io/travis/zplug/zplug.svg?style=flat-square +[version-badge]: https://img.shields.io/badge/latest-v2.1.0-ca7f85.svg?style=flat-square +[version-link]: https://github.com/zplug/zplug/releases +[slack-link]: https://zplug.herokuapp.com +[slack-badge]: https://img.shields.io/badge/slack-join-ca7f85.svg?style=flat-square diff --git a/doc/txt/zplug-install.txt b/doc/txt/zplug-install.txt index b8586853..642bacfa 100644 --- a/doc/txt/zplug-install.txt +++ b/doc/txt/zplug-install.txt @@ -11,7 +11,7 @@ zplug-install - Install packages in parallel SYNOPSIS -------- [verse] -'zplug install' [--verbose] [--select] ['"username/reponame"'] +'zplug install' ['"username/reponame"'] The word 'package' refers to the string in the format: "username/reponame". @@ -23,11 +23,8 @@ Install the package that has not yet been installed, even though it is described OPTIONS ------- -*--verbose*:: - Be verbose. - -*--select*:: - Choose the package that is not installed from the list and install it. +*(None)*:: + no options EXAMPLES @@ -43,7 +40,7 @@ $ zplug install Install a paticular package verbosely: ------------ -$ zplug install --verbose 'some_author/some_repo' +$ zplug install 'some_author/some_repo' Installing... some_author/some_repo Installed! some_author/some_repo (2.59s) ==> Installation finished successfully! diff --git a/doc/txt/zplug-update.txt b/doc/txt/zplug-update.txt index d65f8cd0..a448c438 100644 --- a/doc/txt/zplug-update.txt +++ b/doc/txt/zplug-update.txt @@ -11,7 +11,7 @@ zplug-update - Update installed packages in parallel SYNOPSIS -------- [verse] -'zplug update' [--self|--select ['"username/reponame"']] +'zplug update' [--force] [--self|--select ['"username/reponame"']] The word 'package' refers to the string in the format: "username/reponame". @@ -29,6 +29,9 @@ OPTIONS *--select*:: Choose the package that is not updated from the list and update it. +*--force*:: + Forcibly. To update as it is frozen repo without confirmation + EXAMPLES -------- diff --git a/doc/txt/zplug.txt b/doc/txt/zplug.txt deleted file mode 120000 index bffd81d8..00000000 --- a/doc/txt/zplug.txt +++ /dev/null @@ -1 +0,0 @@ -../zplug.txt \ No newline at end of file diff --git a/doc/txt/zplug.txt b/doc/txt/zplug.txt new file mode 100644 index 00000000..616a6901 --- /dev/null +++ b/doc/txt/zplug.txt @@ -0,0 +1,383 @@ +zplug(1) +====== +Masaki Ishiyama (@b4b4r07) b4b4r07@gmail.com +:man manual: ZPLUG Manual + +NAME +---- +zplug - A next-generation plugin manager for zsh + + +SYNOPSIS +-------- +[verse] +'zplug' ['"username/reponame"'[, 'tag:"value"'[,...]]] + [ [] [<'package'>]] + + The word 'package' refers to the string in the format: "username/reponame". + + +DESCRIPTION +----------- +zplug is a super-fast next-generation plugin manager for zsh. +zplug can manage everything including: zsh plugins, UNIX commands, +Gist files, GitHub Releases, local plugins and so on. +Unlike antigen, zplug requires no ZSH plugin file (`*.plugin.zsh`). +It's such a fantabulous piece of software. + +* Can manage everything +** Zsh plugins/UNIX commands on https://github.com[GitHub] + and https://bitbucket.org[Bitbucket] +** Gist file (https://gist.github.com[gist.github.com]) +** Third-party sources e.g., https://github.com/robbyrussell/oh-my-zsh[oh-my-zsh] + plugins/themes +** Birary artifacts on https://help.github.com/articles/about-releases[GitHub Releases] +** Local plugins +** etc. (you can add your own sources!) +* Super-fast parallel installation/update +* Support for lazy-loading +* Branch/tag/commit support +* Post-update, post-load hooks +* Dependencies between packages +* Unlike https://github.com/zsh-users/antigen[antigen], no ZSH plugin file (*.plugin.zsh) required +* Interactive interface (https://github.com/junegunn/fzf[fzf], https://github.com/peco/peco[peco], + https://github.com/zsh-users/zaw[zaw], and so on) +* Cache mechanism for reducing the startup time + + +OPTIONS +------- +*--help*:: + Print the synopsis and a list of all available commands. + +*--version*:: + Print zplug's version. + + +COMMANDS +-------- +*check* [--verbose] ['package']:: + Check whether there is at least one item that's not installed. If 'package' + (username/reponame) is given, check if 'package' is installed. + If the `--verbose` option is given, print extra debugging information. + +*clean* [--force] [--select] ['package']:: + Remove unused packages that are in `$ZPLUG_HOME/repos` after showing a + yes/no prompt. If 'package' is given, uninstall that particular 'package'. + If `--force` option is given, suppress the prompt and uninstall 'package'. + If the `--select` option is given, by using the filter specified in + `$ZPLUG_FILTER`, interactively select the 'package' you want to uninstall. + +*clear*:: + Remove the cache file. + +*install* ['package']:: + Install 'package'. + +*list* [--verbose] [--select] ['package']:: + List installed packages. + `--select` do the same as what's described above. + +*load* [--verbose]:: + Load packages. All packages registered with 'as:plugin' are sourced into + the current zsh process, and its parent directory is added to `$fpath`. In + addition, all packages with 'as:command' are linked to `$ZPLUG_HOME/bin` + and the bin directory is added to `$PATH`. + `--verbose` does the same as what's described above. + +*info* :: + Show the information such as source URL and tag values of the 'package'. + +*status* [--select]:: + Fetch the newest version of the installed packages by zplug. + `--select` does the same as what's described above. + +*update* [--self] [--select] [--force] ['package']:: + Update 'package'. If no package is given, updates all registered packages. + If `--self` is given, update zplug itself. + `--select` does the same as what's described above. + + +TAGS +---- + +Values 'truthy' and 'falsy' mean any of "true, yes, on, 1" and "false, no, off, 0", respectively. + +.zplug list of available tags +[width="80%",cols="4,10,6,4",options="header"] +|========================================================= +|Tag |Description |Value (default) |Example + +|*as* | Whether to register the package as commands or as plugins +| `plugin`,`command` (`plugin`) | `as:command` + +|*use* | Specify the pattern of the files to source (for `plugin`) or the relative path +from the package root of the file to add to `$PATH` (for `command`) / Useful, +for example, with `from:gh-r` you can specify `use:"*darwin*{amd,386}*"` +and so on. If you want to use extended glob, see later section for setting the zstyle. +| *glob* (`use:"*.zsh"`) +| `use:bin`,`use:"*.sh"`, +`use:"*darwin*"` + +|*from* | Specify the service from which you install +| `github`,`bitbucket`,`gh-r`,`gist`, +`oh-my-zsh`,`local` (`github`) | `from:gh-r` + +|*at* | Branch, tag, or commit to use | *revision* (`master`) | `at:v1.5.6` + +|*rename-to* | Specify the filename you want to rename to (only valid with `as:command`) | *filename* (-) | `rename-to:fzf` + +|*dir* | Installation directory which is managed by zplug | **READ ONLY** | `dir:/path/to/user/repo` + +|*if* | The conditions under which to install and/or use the package | *commands* (-) | `if:"[ -d ~/.zsh ]"` + +|*hook-build* | Commands to run after installation/update | *commands* (-) | `hook-build:"make install"` + +|*hook-load* | Commands to run after loading | *commands* (-) | `hook-load:"echo 'Boo!'"` + +|*frozen* | Do not update unless explicitly specified | truthy,falsy (no) | `frozen:true` + +|*on* | Dependencies | *package* (-) | `on:user/repo` + +|*lazy* | Lazy-load | *truthy,falsy* (no) | `lazy:true` + +|*depth* | The number of commits to include in the cloned repository. 0 means the whole history. | Any non-negative integer (`ZPLUG_CLONE_DEPTH`) | `depth:10` | + +|*nice* | Priority of loading the plugins. If the value is 10 or more, +zplug will source the plugin after `compinit` (see also https://github.com/zplug/zplug/issues/26[#26]) +| -20..19 (0) | `nice:19` + +|*ignore* | Similar to `use`, but specify exception pattern of files that you +don't want to load (see also https://github.com/zplug/zplug/issues/56[#56]) +| *glob* (-) | `ignore:"some_*.zsh"` | +|========================================================= + +You can register packages for zplug from the command line. +If you use zplug on the command line, you can take advantage of the command line completions. +When using this method, zplug writes out the package settings to `$ZPLUG_LOADFILE`. +If you launch a new zsh process, `zplug load` command will automatically use +this file. Note that you can also use `$ZPLUG_LOADFILE` to isolate your zplug +package listing from your `.zshrc`. + + +Environment Variables +--------------------- +Various zplug commands use the following environment variables: + +'ZPLUG_HOME':: + Defaults to `~/.zplug`. zplug will store/load plugins in this directory. The directory structure is below. + +------------ +$ZPLUG_HOME +|-- bin +| `-- some_command -> ../repos/username_A/reponame1/some_command +`-- repos + |-- username_A + | |-- reponame1 + | | |-- README.md + | | `-- some_command + | `-- reponame2 + | |-- README.md + | `-- some_plugin.zsh + `-- username_B + `-- reponame1 + +------------ + +If you specify 'as:command' when registering the package, zplug will recognize the plugin +as a command and create a symbolic link of the same name (if you want to rename it, +use `rename-to`) in `$ZPLUG_HOME/bin`. Because zplug adds `$ZPLUG_HOME/bin` to +the `$PATH`, you can run that command from anywhere just like any other commands. + +'ZPLUG_THREADS':: + The maximum number of threads zplug should use when installing/updating. The default value is 16. + +'ZPLUG_PROTOCOL':: + Defaults to HTTPS. Valid options for `$ZPLUG_PROTOCOL` are `HTTPS` or `SSH`. + Unless you have a specific reason, you should use the HTTPS protocol. + For more information, see also https://help.github.com/articles/which-remote-url-should-i-use/[Which remote URL should I use? - GitHub Help] + +'ZPLUG_CLONE_DEPTH':: + Defaults to `0`. + When cloning a Git repository, you can limit the number of commits your + clone has. Setting this to 0 means that it will clone the entire history. + Any non-zero number will clone with that many commits. + +'ZPLUG_FILTER':: + Defaults to `fzf-tmux:fzf:peco:percol:zaw`. + When `--select` option is specified in a subcommand, starting from the + first element of the colon-separated list, whatever filter found will be + used by zplug as the interactive filter. + The `ZPLUG_FILTER` also accepts arguments (e.g. `fzf-tmux -d "10%":/path/to/peco:my peco`). + +'ZPLUG_LOADFILE':: + Defaults to `$ZPLUG_HOME/packages.zsh`. + This file is used to add packages from zplug on the command-line. This is a + useful feature when you want to isolate your zplug configurations from your + `.zshrc`. Note that you don't need to add packages from the command line to + use this feature: you can manually edit this file, and it'll work just + fine! + +'ZPLUG_USE_CACHE':: + Defaults to `true`. + If this variable is true, zplug uses a cache file to speed up the loading process. + The cache file is located at `$ZPLUG_CACHE_FILE` (`$ZPLUG_HOME/.cache` by default). + If you want to clear the cache, please run `zplug clear` or do the following: + +------------ +$ ZPLUG_USE_CACHE=false zplug load +------------ + +'ZPLUG_CACHE_FILE':: + Defaults to `$ZPLUG_HOME/.cache`. + Specifies where to save the cache. For example, you can set this to + `$HOME/.cache/zplug/cache` to follow XDG Base Directory Specification + +'ZPLUG_REPOS':: + Defaults to `$ZPLUG_HOME/repos`. You can change where the repositories are + cloned in case you want to manage them separately. + + +Using zstyle +------------ +You can use zstyle to change the default values for each tag. The format is: +`zstyle ":zplug:tag" tag_name new_default_value`. For example, if you have a +lot of commands and not so many plugins, (i.e. if you find yourself specifying +`as:command` often), you can do: `zstyle ":zplug:tag" as command`. + +You can also specify what options to enable in sub shells. Sub shells are used +when expanding glob expressions. If you want to use the 'extended_glob' for +example, you can do: `zstyle ":zplug:config:setopt" only_subshell +extended_glob`. If you set `:zplug:config:setopt same_curshell` to a truthy +value (i.e. `true`, `1`, `yes`), zplug will enable the options enabled at the +point of sourcing zplug (i.e. at the point of `source $ZPLUG_HOME/init.zsh`). + + +External commands +----------------- +zplug, like 'git(1)', supports external commands. +These are executable scripts that reside somewhere in the PATH, named zplug-cmdname, +which can be invoked with `zplug cmdname`. +This allows you to create your own commands without modifying zplug's internals. +Instructions for creating your own commands can be found in the docs: +https://github.com/zplug/zplug/blob/master/doc/zplug/External-Commands.md +Check out the sample `zplug-env` external command for an example. + + +Configuration +------------- + +Add a zplug section to your .zshrc (or `$ZPLUG_LOADFILE`): + +. Register packages with the zplug command (`zplug "username/reponame"`) +. `zplug load` to source the plugins and add its commands to your `$PATH` + +------------ +source ~/.zplug/zplug + +# Make sure you use double quotes +zplug "zsh-users/zsh-history-substring-search" + +# Can manage a plugin as a command +# And accept glob patterns (e.g., brace, wildcard, ...) +zplug "Jxck/dotfiles", as:command, use:"bin/{histuniq,color}" + +# Can manage everything e.g., other person's zshrc +zplug "tcnksm/docker-alias", use:zshrc + +# Prohibit updates to a plugin by using the "frozen:" tag +zplug "k4rthik/git-cal", as:command, frozen:1 + +# Grab binaries from GitHub Releases +# and rename using the "rename-to:" tag +zplug "junegunn/fzf-bin", \ + as:command, \ + from:gh-r, \ + rename-to:fzf, \ + use:"*darwin*amd64*" + +# Support oh-my-zsh plugins and the like +zplug "plugins/git", from:oh-my-zsh, if:"(( $+commands[git] ))" +zplug "themes/duellj", from:oh-my-zsh +zplug "lib/clipboard", from:oh-my-zsh, if:"[[ $OSTYPE == *darwin* ]]" + +# Run a command after a plugin is installed/updated +zplug "tj/n", hook-build:"make install" + +# Support checking out a specific branch/tag/commit of a plugin +zplug "b4b4r07/enhancd", at:v1 +zplug "mollifier/anyframe", commit:4c23cb60 + +# Install if "if:" tag returns true +zplug "hchbaw/opp.zsh", if:"(( ${ZSH_VERSION%%.*} < 5 ))" + +# Can manage gist file just like other plugins +zplug "b4b4r07/79ee61f7c140c63d2786", \ + as:command, \ + from:gist, \ + use:get_last_pane_path.sh + +# Support bitbucket +zplug "b4b4r07/hello_bitbucket", \ + as:command, \ + from:bitbucket, \ + hook-build:"chmod 755 *.sh", \ + use:"*.sh" + +# Group dependencies, emoji-cli depends on jq in this example +zplug "stedolan/jq", \ + as:command, \ + from:gh-r \ + rename-to:jq, \ + on:"b4b4r07/emoji-cli" + +# Set priority to load command like a nice command +# e.g., zsh-syntax-highlighting must be loaded +# after executing compinit command and sourcing other plugins +zplug "zsh-users/zsh-syntax-highlighting", nice:10 + +# Can manage local plugins +zplug "~/.zsh", from:local + +# Install plugins if there are plugins that have not been installed +if ! zplug check --verbose; then + printf "Install? [y/N]: " + if read -q; then + echo; zplug install + fi +fi + +# Then, source plugins and add commands to $PATH +zplug load --verbose + +------------ + +Finally, use `zplug install` to install your plugins and reload `.zshrc`. + + +Further Documentation +--------------------- + +See the references in https://github.com/zplug/zplug/wiki[official wiki page] to get started using zplug. +The wiki may perhaps be overwhelming for first-time users. + + +Authors +------- +zplug was originally written by Masaki Ishi (a.k.a @b4b4r07). +Many people have contributed to it. + + +Copying +------- +Copyright \(C) 2015-2016 Masaki Ishi + +MIT License + + +Reporting Bugs +-------------- +Report bugs to the https://github.com/zplug/zplug/issues[zplug issues] + + +// vim:ft=asciidoc diff --git a/doc/zplug.txt b/doc/zplug.txt index 4f9fafbf..616a6901 100644 --- a/doc/zplug.txt +++ b/doc/zplug.txt @@ -71,13 +71,12 @@ COMMANDS *clear*:: Remove the cache file. -*install* [--verbose] [--select] ['package']:: +*install* ['package']:: Install 'package'. - `--verbose` / `--select` do the same as what's described above. *list* [--verbose] [--select] ['package']:: List installed packages. - `--verbose` / `--select` do the same as what's described above. + `--select` do the same as what's described above. *load* [--verbose]:: Load packages. All packages registered with 'as:plugin' are sourced into @@ -93,7 +92,7 @@ COMMANDS Fetch the newest version of the installed packages by zplug. `--select` does the same as what's described above. -*update* [--self] [--select] ['package']:: +*update* [--self] [--select] [--force] ['package']:: Update 'package'. If no package is given, updates all registered packages. If `--self` is given, update zplug itself. `--select` does the same as what's described above. @@ -235,8 +234,8 @@ $ ZPLUG_USE_CACHE=false zplug load `$HOME/.cache/zplug/cache` to follow XDG Base Directory Specification 'ZPLUG_REPOS':: -Defaults to `$ZPLUG_HOME/repos`. You can change where the repositories are -cloned in case you want to manage them separately. + Defaults to `$ZPLUG_HOME/repos`. You can change where the repositories are + cloned in case you want to manage them separately. Using zstyle diff --git a/init.zsh b/init.zsh index 1351c9f3..0bd80493 100644 --- a/init.zsh +++ b/init.zsh @@ -1,30 +1,32 @@ #!/usr/bin/env zsh -# init.zsh: -# This file is called only once -# It is desirable that the ZPLUG_ROOT and the ZPLUG_HOME is the same -# because zplug should be installed with git clone URL /path/to/local_dir -# e.g. ~/.zplug -typeset -gx ZPLUG_ROOT="${${(%):-%N}:A:h}" +# A hash array for zplug +typeset -gx -A zplugs +zplugs=() -# Unique array -typeset -gx -U path -typeset -gx -U fpath +# A variable as a starting point of zplug +typeset -gx ZPLUG_ROOT="${${(%):-%N}:A:h}" -# Add to the PATH -path=( -"$ZPLUG_ROOT"/bin -$path -) +# Load basic functions such as an __zplug::base function +source "$ZPLUG_ROOT/base/init.zsh" +# Load autoloader +source "$ZPLUG_ROOT/autoload/init.zsh" -# Add to the FPATH -fpath=( -"$ZPLUG_ROOT"/autoload(N-/) -"$ZPLUG_ROOT"/misc/completions(N-/) -$fpath -) +__zplug::base "base/*" +__zplug::base "core/*" +__zplug::base "io/*" +__zplug::base "job/*" +__zplug::base "sources/*" +__zplug::base "utils/*" -# for 'autoload -Uz zplug' in another subshell -export FPATH="$ZPLUG_ROOT/autoload:$FPATH" +if ! __zplug::core::core::prepare; then + __zplug::io::print::f \ + --die \ + --zplug \ + --error \ + "The loading of zplug was discontinued.\n" + return 1 +fi -autoload -Uz zplug +# Load the external file of zplug +__zplug::io::file::load diff --git a/misc/completions/_zplug b/misc/completions/_zplug index 555d526d..33c8400e 100644 --- a/misc/completions/_zplug +++ b/misc/completions/_zplug @@ -28,7 +28,7 @@ zplug_cmds=( # Completions for user-defined commands for p in ${^path}/zplug-*(N-.) do - desc="$(sed -n '2p' "$p" | sed -E 's/^.*desc(ription)?: ?//')" + desc="$(sed -n '2p' "$p" | sed -E 's/^.*[Dd]esc(ription)?: ?//')" desc="${desc:+"\[User-defined\] $desc"}" zplug_cmds+=("${p:t:gs:zplug-:}:${desc:-"User-defined command"}") done @@ -36,6 +36,7 @@ done _arguments \ '(-)--help[show help message]: :->comp' \ '(-)--version[version information]: :' \ + '(-)--log=[view zplug error log]: :->log' \ '*:: :->comp' && return 0 if (( CURRENT == 1 )); then @@ -61,7 +62,7 @@ case "$words[1]" in _arguments \ '(--verbose)--verbose[show non-installed items in output]' \ '(--select)--select[select items with interactive filters]' \ - '*:: :compadd -x "%F{green}Accept%f %Busername/reponame%b arguments"' + '*:: :compadd -X "%F{green}Accept%f %Busername/reponame%b arguments"' ret=0 ;; load) @@ -111,16 +112,16 @@ case "$words[1]" in "depth[Clone depth]:depth:({0..10})" && ret=0 case $state in on|dir) - compadd -x "%F{green}READ ONLY%f %Bno arguments%b" + compadd -X "%F{green}READ ONLY%f %Bno arguments%b" ;; use) - compadd -J 'command/plugin' -x "%F{yellow}Completing%f %BExample patterns%b" \ + compadd -J 'command/plugin' -X "%F{yellow}Completing%f %BExample patterns%b" \ '*.zsh' \ '*.sh' \ 'zsh/*.zsh' \ '*.plugin.zsh' \ 'init.zsh' - compadd -J 'gh-r' -x "%F{yellow}Completing%f %BGitHub Releases (example)%b" \ + compadd -J 'gh-r' -X "%F{yellow}Completing%f %BGitHub Releases (example)%b" \ 'amd64' \ 'darwin*amd64' \ 'linux*amd64' \ @@ -131,26 +132,37 @@ case "$words[1]" in 'linux' ;; nice) - compadd -V 'default' -x "%F{yellow}Completing%f %Bpriority (default)%b" 0 - compadd -V 'high' -x "%F{yellow}Completing%f %Bpriority (high)%b" -- {-1..-20} - compadd -V 'low' -x "%F{yellow}Completing%f %Bpriority (low)%b" {1..9} - compadd -V 'lowest' -x "%F{yellow}Completing%f %Bpriority (low) after compinit%b" {10..19} + compadd -V 'default' -X "%F{yellow}Completing%f %Bpriority (default)%b" 0 + compadd -V 'high' -X "%F{yellow}Completing%f %Bpriority (high)%b" -- {-1..-20} + compadd -V 'low' -X "%F{yellow}Completing%f %Bpriority (low)%b" {1..9} + compadd -V 'lowest' -X "%F{yellow}Completing%f %Bpriority (low) after compinit%b" {10..19} ;; boolean) - compadd -J 'boolean/true' -x "%F{yellow}Completing%f %Btrue word%b" $_zplug_boolean_true - compadd -J 'boolean/false' -x "%F{yellow}Completing%f %Bfalse word%b" $_zplug_boolean_false + compadd -J 'boolean/true' -X "%F{yellow}Completing%f %Btrue word%b" $_zplug_boolean_true + compadd -J 'boolean/false' -X "%F{yellow}Completing%f %Bfalse word%b" $_zplug_boolean_false ;; esac ;; esac case $state in - comp) + "comp") is_help="yes" _describe -t help_cmds "commands" cmds _describe -t help_tags "tags" tags return 0 ;; + "log") + compadd -J 'log/jq' -X "%F{yellow}Completing%f %Bwith jq%b" \ + 'jq' + compadd -J 'log/pager' -X "%F{yellow}Completing%f %Bwith pager%b" \ + 'less' \ + 'more' + compadd -J 'log/edit' -X "%F{yellow}Completing%f %Bwith editor%b" \ + 'edit' + compadd -J 'log/log' -X "%F{yellow}Completing%f %Bwith log%b" \ + 'oneline' \ + 'clear' esac return ret diff --git a/misc/share/cache.awk b/misc/contrib/cache.awk similarity index 100% rename from misc/share/cache.awk rename to misc/contrib/cache.awk diff --git a/misc/share/fuzzy.awk b/misc/contrib/fuzzy.awk similarity index 100% rename from misc/share/fuzzy.awk rename to misc/contrib/fuzzy.awk diff --git a/misc/contrib/getopts.awk b/misc/contrib/getopts.awk new file mode 100644 index 00000000..cb44550c --- /dev/null +++ b/misc/contrib/getopts.awk @@ -0,0 +1,74 @@ +function out(k,v) { + print(k "" (v == "" ? "" : " "v)) +} + +function pop() { + return len <= 0 ? "_" : opt[len--] +} + +{ + if (done) { + out("_" , $0) + next + } + + if (match($0, "^-[A-Za-z]+")) { + $0 = "- " substr($0, 2, RLENGTH - 1) " " substr($0, RLENGTH + 1) + + } else if (match($0, "^--[A-Za-z0-9_-]+")) { + $0 = "-- " substr($0, 3, RLENGTH - 2) " " substr($0, RLENGTH + 2) + } + + if ($1 == "--" && $2 == "") { + done = 1 + + } else if ($2 == "" || $1 !~ /^-|^--/ ) { + out(pop(), $0) + + } else { + while (len) { + out(pop()) + } + + if ($3 != "") { + if (match($0, $2)) { + $3 = substr($0, RSTART + RLENGTH + 1) + } + } + + if ($1 == "--") { + if ($3 == "") { + opt[++len] = $2 + } else { + out($2, $3) + } + } + + if ($1 == "-") { + if ($2 == "") { + print($1) + next + + } else { + n = split($2, keys, "") + } + + if ($3 == "") { + opt[++len] = keys[n] + + } else { + out(keys[n], $3) + } + + for (i = 1; i < n; i++) { + out(keys[i]) + } + } + } +} + +END { + while (len) { + out(pop()) + } +} diff --git a/misc/share/packaging.awk b/misc/contrib/packaging.awk similarity index 100% rename from misc/share/packaging.awk rename to misc/contrib/packaging.awk diff --git a/misc/share/parser.awk b/misc/contrib/parser.awk similarity index 100% rename from misc/share/parser.awk rename to misc/contrib/parser.awk diff --git a/misc/share/read_cache.awk b/misc/contrib/read_cache.awk similarity index 100% rename from misc/share/read_cache.awk rename to misc/contrib/read_cache.awk diff --git a/misc/dev/make_tests.zsh b/misc/dev/make_tests.zsh new file mode 100644 index 00000000..d2653f4d --- /dev/null +++ b/misc/dev/make_tests.zsh @@ -0,0 +1,42 @@ +#!/usr/bin/env zsh + +local arg="$1" fp ans + +for fp in "${arg:-$ZPLUG_ROOT}/base"/*/*.zsh +do + local parent="${fp:h:t}" + local child="${fp:t:r}" + local test_file="${arg:-$ZPLUG_ROOT}/test/base/$parent/$child.t" + + # Check if already exists + if [[ -f $test_file ]]; then + echo -en "$test_file: is already exists. Overwrite? y/N: " + read -q ans && echo + if [[ ! ${(L)ans} =~ ^y(es)?$ ]]; then + continue + fi + fi + + # Update + rm -f "$test_file" + cat "$fp" \ + | grep "^__zplug::$parent::$child" \ + | awk ' + { + gsub(/\(\)/, "") + gsub(/ {/, "") + print "T_SUB \"" $0 "\" ((" + print " # skip" + print "))" + } + ' >> "$test_file" +done + +for fp in "${arg:-$ZPLUG_ROOT}"/autoload/{commands,options,tags}/__*__ +do + local dir="${fp:h}" + local file="${fp:t}" + local name="${file:gs:_:}" + + touch "${arg:-$ZPLUG_ROOT}/test/$dir/$name.t" +done diff --git a/misc/dev/pre-push b/misc/dev/pre-push new file mode 100644 index 00000000..8f84de1e --- /dev/null +++ b/misc/dev/pre-push @@ -0,0 +1,9 @@ +#!/bin/bash + +if git diff --exit-code --check master..origin/master; then + # the same + exit 0 +fi + +make test +exit $? diff --git a/misc/dev_tools/coverage.zsh b/misc/dev_tools/coverage.zsh deleted file mode 100644 index 8f61e802..00000000 --- a/misc/dev_tools/coverage.zsh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env zsh - -local -F all=0 -local -a pass -local -a fail -local f is_create=false - -while (( $# > 0 )) -do - case "$1" in - -c|--create) - is_create=true - ;; - -*|--*) - printf "$1: unkown option\n" >&2 - exit 1 - ;; - *) - ;; - esac - shift -done - -get_untested_files() { - local f - for f in $ZPLUG_ROOT/(autoload|lib)/**/*(.:gs:$ZPLUG_ROOT/:) - do - let all++ - if [[ -f $ZPLUG_ROOT/test/${f:r}_test.zsh ]]; then - pass+=($f) - else - fail+=($f) - fi - done -} - -show_untested_files() { - get_untested_files - if (( $#fail > 0 )); then - printf "- %s\n" ${fail[@]} - printf "\n" - fi - printf "%d/%d (%3.1f%%)\n" $#pass $all $(($#pass / $all * 100)) -} - -if $is_create; then - get_untested_files - for f in "${fail[@]}" - do - f="test/${f:r}_test.zsh" - mkdir -p "${f:h}" - echo "#!/usr/bin/env zsh" >"$f" - done -else - show_untested_files -fi - diff --git a/misc/dev_tools/make_manpage.sh b/misc/dev_tools/make_manpage.sh deleted file mode 100644 index c5cec6fe..00000000 --- a/misc/dev_tools/make_manpage.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -if [[ -f $ZPLUG_HOME/doc/zplug.txt ]]; then - a2x -f manpage $ZPLUG_HOME/doc/zplug.txt - exit $? -else - echo "zplug.txt: not found" >&2 - exit 1 -fi diff --git a/misc/dev_tools/open_code.zsh b/misc/dev_tools/open_code.zsh deleted file mode 100644 index f457ca96..00000000 --- a/misc/dev_tools/open_code.zsh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env zsh - -if [[ -z $ZPLUG_ROOT ]]; then - exit 1 -fi - -source "$ZPLUG_ROOT/base/core/core.zsh" - -local filter -local dir -local -a wc_files - -filter="$(__zplug::core::core::get_filter "${ZPLUG_FILTER:-"fzf --tac:peco:percol:zaw"}")" -if [[ -z $filter ]]; then - exit -fi - -case "$1" in - "autoload") - dir="autoload" - ;; - "test") - dir="test" - ;; - *) - dir="$(echo -e "autoload\ntest" | eval "$filter")" - if [[ -z $dir ]]; then - exit - fi - ;; -esac - -wc_files=( ${(@f)"$(wc -l $ZPLUG_ROOT/$dir/**/*(N.) | eval "$filter" | awk '{print $2}')"} ) -if (( $#wc_files > 0 )); then - vim -p "${wc_files[@]}" -fi diff --git a/misc/dev_tools/update_manpage.sh b/misc/dev_tools/update_manpage.sh deleted file mode 100644 index db0b0a37..00000000 --- a/misc/dev_tools/update_manpage.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -cnt=0 -if [[ -n $1 ]]; then - files=("$@") -else - files=($ZPLUG_ROOT/doc/txt/*.txt) -fi - -echo "Generates man pages from ascii files!" -echo "It takes time..." - -for file in "${files[@]}" -do - section_number="$(sed -n '1s/^.*(\(.*\))$/\1/p' "$file")" - if [[ ! $section_number =~ [1-7] ]]; then - echo "$file of $section_number: invalid section number" >&2 - continue - fi - - man_dir="$ZPLUG_ROOT/doc/man/man$section_number" - if [[ ! -d $man_dir ]]; then - mkdir -p "$man_dir" - fi - - echo "-- ${file/$ZPLUG_ROOT/} -> ${man_dir/$ZPLUG_ROOT/}" - a2x \ - --doctype=manpage \ - --format=manpage \ - --destination="$man_dir" \ - "$file" &>/dev/null & - (( (cnt += 1) % 16 == 0 )) && wait -done - -wait -echo "==> DONE" -rm -f $ZPLUG_ROOT/doc/txt/*.xml diff --git a/misc/share/getopts.awk b/misc/share/getopts.awk deleted file mode 100644 index 630789f9..00000000 --- a/misc/share/getopts.awk +++ /dev/null @@ -1,68 +0,0 @@ -function add(k, v) { - if (seen[k v]++) return - print k (v == "" ? "" : " "v) -} - -function pop() { - return (size <= 0) ? "_" : stack[size--] -} - -function push(k) { - stack[++size] = k -} - -function flush() { - while (size) { - add(pop()) - } -} - -$0 == "" { next } - -done { - add("_" , $1$2$3) - next -} - -$1 == "--" && !$2 { - done = 1 - next -} - -$1 !~ /^-|^--/ { - add(pop(), $0) - next -} - -size { flush() } - -$3 { - for (i = 4; i <= NF; i++) - $3 = $3" "$i -} - -$1 == "--" { - if ($3 == "") - push($2) - else - add($2, $3) -} - -$1 == "-" { - if ($2 == "") { - print $1 - next - } else { - n = split($2, keys, "") - } - - if ($3 == "") - push(keys[n]) - else - add(keys[n], $3) - - for (i = 1; i < n; i++) - add(keys[i]) -} - -END { flush() } diff --git a/misc/zshrc b/misc/zshrc new file mode 100644 index 00000000..f62a816e --- /dev/null +++ b/misc/zshrc @@ -0,0 +1,244 @@ +#!/usr/bin/env zsh + +# Prepare +tests=() +export ZPLUG_HOME="/tmp/zplug-$RANDOM" +export ZPLUG_REPOS="$ZPLUG_HOME/repos" +mkdir -p "$ZPLUG_HOME" "$ZPLUG_REPOS" + +# Prepare +source "$ZPLUG_ROOT/init.zsh" +zplugs=() +zplug clear + +# as +{ + # plugin + zplug "tcnksm/docker-alias", \ + use:zshrc + # command + zplug "Jxck/dotfiles", \ + as:command, \ + use:"bin/{histuniq,color}" + + tests+=( + '(( $+aliases[dl] ))' + '[[ -x $ZPLUG_HOME/bin/histuniq ]]' + '[[ -x $ZPLUG_HOME/bin/color ]]' + ) +} + +# at +{ + # branch + zplug "b4b4r07/enhancd", \ + at:v1, \ + use:"*.sh" + # commit + zplug "mollifier/anyframe", \ + at:4c23cb60 + + tests+=( + '(( $+functions[enhancd_cd] ))' + '(( $+functions[anyframe-init] ))' + ) +} + +# from +{ + # github + zplug "zsh-users/zsh-history-substring-search", \ + from:github, \ + as:plugin + zplug "mrowa44/emojify", \ + from:github, \ + as:command + # bitbucket + zplug "b4b4r07/hello_bitbucket", \ + from:bitbucket, \ + as:command, \ + hook-build:"chmod 755 *.sh", \ + use:"*.sh" + # oh-my-zsh + zplug "plugins/git", \ + from:oh-my-zsh + zplug "plugins/cp", \ + from:oh-my-zsh + zplug "plugins/emoji", \ + from:oh-my-zsh + # gh-r + zplug "junegunn/fzf-bin", \ + as:command, \ + from:gh-r, \ + rename-to:fzf, \ + use:"*darwin*amd64*" + # gist + zplug "b4b4r07/79ee61f7c140c63d2786", \ + from:gist, \ + as:command, \ + use:get_last_pane_path.sh + # local + ## skip + + tests+=( + '(( $+functions[_zsh_highlight_bind_widgets] ))' + '[[ -x $ZPLUG_HOME/bin/emojify ]]' + '[[ -x $ZPLUG_HOME/bin/hello.sh ]]' + '(( $+aliases[gba] ))' + '(( $+aliases[cpv] ))' + '(( $+functions[random_emoji] ))' + '[[ -x $ZPLUG_HOME/bin/fzf ]]' + '[[ -x $ZPLUG_HOME/bin/get_last_pane_path.sh ]]' + ) +} + +# depth +{ + zplug "willghatch/zsh-cdr", \ + depth:1 +} + +# dir +{ + : 'SKIP' 'TODO' +} + +# frozen +{ + : 'SKIP' +} + +# hook-build +{ + # Duplicates + zplug "b4b4r07/hello_bitbucket", \ + from:bitbucket, \ + as:command, \ + hook-build:"chmod 755 *.sh", \ + use:"*.sh" + + tests+=( + '[[ -x $ZPLUG_HOME/bin/hello.sh ]]' + ) +} + +# hook-load +{ + : +} + +# if +{ + zplug "tj/n", \ + as:command, \ + use:"bin/n", \ + if:'(( $+commands[node] ))' + + tests+=( + '[[ -x $ZPLUG_HOME/bin/n ]]' + ) +} + +# ignore +{ + zplug "zsh-users/zaw", \ + ignore:"zaw-launcher.zsh" + + tests+=( + '(( ! $+functions[zle-line-init] ))' + ) +} + +# lazy +{ + zplug "mollifier/zload", \ + lazy:true, \ + use:"zload" + + tests+=( + '(( $+functions[zload] ))' + ) +} + +# nice +{ + zplug "zsh-users/zsh-syntax-highlighting", \ + nice:19 + + tests+=( + '(( $+functions[_zsh_highlight] ))' + ) +} + +# on +{ + zplug "b4b4r07/zsh-gomi", \ + as:command, \ + use:"bin/gomi", \ + on:"peco/peco" + + tests+=( + '[[ ! -x $ZPLUG_HOME/bin/gomi ]]' + ) +} + +# rename-to +{ + zplug "stedolan/jq", \ + from:gh-r, \ + as:command, \ + rename-to:jq + + tests+=( + '[[ -x $ZPLUG_HOME/bin/jq ]]' + ) +} + +# use +{ + zplug "b4b4r07/http_code", \ + as:command, \ + use:"bin" + zplug "monochromegane/the_platinum_searcher", \ + as:command, \ + from:gh-r, \ + rename-to:pt, \ + use:"*${(L)$(uname -s)}*amd64*" +} + +zplug install || exit 1 +zplug load --verbose || exit 1 + +# on (test case) +{ + local -i line=0 + local -A tags + + tags[dir]="$( + __zplug::core::core::run_interfaces \ + 'dir' \ + 'willghatch/zsh-cdr' + )" + line="$( + git \ + --git-dir="$tags[dir]/.git" \ + --work-tree="$tags[dir]" \ + rev-list --count HEAD + )" + + tests+=( + "[[ $line -eq 1 ]]" + ) +} + +ret=0 +for test in "$tests[@]" +do + eval "$test" + if (( $status != 0 )); then + printf "$fg[red]FAIL: $test$reset_color\n" >&2 + ret=1 + fi +done + +exit $ret diff --git a/test/.helpers/helper.zsh b/test/.helpers/helper.zsh deleted file mode 100644 index f6eb0fff..00000000 --- a/test/.helpers/helper.zsh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env zsh - -unansi() { - cat <&0 \ - | perl -pe 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' -} diff --git a/test/.helpers/mock.zsh b/test/.helpers/mock.zsh deleted file mode 100644 index 0fcb209a..00000000 --- a/test/.helpers/mock.zsh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env zsh - -typeset -g _zplug_mock_repos="${ZPLUG_ROOT:?}/test/.fixtures/repos" - -init_mock_repos() { - local name - for name in "$@" - do - name="$_zplug_mock_repos/$name" - git -C "$name" init --quiet - git -C "$name" config user.email "git@zplug" - git -C "$name" config user.name "zplug" - git -C "$name" add -A >/dev/null - git -C "$name" commit -m "$name" >/dev/null - done -} - -mock_as_plugin() { - local name="${1:?}" - mkdir -p "$_zplug_mock_repos/$name" - printf "${name:t}() { echo ${name:t}; }\n" \ - >"$_zplug_mock_repos/$name/${name:t}".zsh - init_mock_repos "$name" - (( $+functions[zplug] )) && zplug "$name" -} - -mock_as_command() { - local name="${1:?}" - mkdir -p "$_zplug_mock_repos/$name" - printf "#!/usr/bin/env zsh\necho ${name:t}\n" \ - >"$_zplug_mock_repos/$name/${name:t}" - chmod 755 "$_zplug_mock_repos/$name/${name:t}" - init_mock_repos "$name" - (( $+functions[zplug] )) && zplug "$name", as:command -} - -mock_remove() { - local name="${1:?}" - if [[ -d $_zplug_mock_repos/$name ]]; then - rm -rf "$_zplug_mock_repos/$name" - fi -} diff --git a/test/all.t b/test/all.t new file mode 100644 index 00000000..360957e3 --- /dev/null +++ b/test/all.t @@ -0,0 +1,4 @@ +T_SUB "all" (( + source "$ZPLUG_ROOT/misc/zshrc" + t_is $status 0 +)) diff --git a/test/autoload/commands/__check___test.zsh b/test/autoload/commands/__check___test.zsh deleted file mode 100644 index f208dccb..00000000 --- a/test/autoload/commands/__check___test.zsh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - unset ZPLUG_LOADFILE - - local expect actual -} - -describe "__check__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "check command returns true" - mock_as_plugin "foo/foo" - zplug check "foo/foo" - assert.true $status - end - - it "check command returns true (no args)" - zplug check - assert.true $status - end - - # Remove foo - mock_remove "foo/foo" - - it "check command returns false" - zplug check "foo/foo" - assert.false $status - end - - it "check command returns false (no args)" - zplug check - assert.false $status - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/commands/__clean___test.zsh b/test/autoload/commands/__clean___test.zsh deleted file mode 100644 index cdb1ffbf..00000000 --- a/test/autoload/commands/__clean___test.zsh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__clean__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "exist but clean" - mock_as_plugin "foo/foo" - expect="Removed '$ZPLUG_REPOS/foo/foo' " - actual="$(zplug clean --force "foo/foo")" - assert.true $status - assert.equals "$expect" "$actual" - end - - it "non-existing plugin" - mock_as_plugin "bar/bar" - zplugs=() - expect="Removed '$ZPLUG_REPOS/bar/bar' " - actual="$(zplug clean --force)" - assert.true $status - assert.equals "$expect" "$actual" - end - - it "non-registerd plugin" - expect="[zplug] bar/bar: no such package" - actual="$(zplug clean --force "bar/bar" 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/commands/__clear___test.zsh b/test/autoload/commands/__clear___test.zsh deleted file mode 100644 index 8d90519e..00000000 --- a/test/autoload/commands/__clear___test.zsh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__clear__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/commands/__install___test.zsh b/test/autoload/commands/__install___test.zsh deleted file mode 100644 index ce180406..00000000 --- a/test/autoload/commands/__install___test.zsh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__install__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "" - expect="[zplug] no package managed by zplug" - actual="$(zplug install 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "Returns true" - zplug install "b4b4r07/enhancd" &>/dev/null - assert.true $status - end - - it "Returns false" - zplug install "$$/$$" &>/dev/null - assert.false $status - end - - it "Returns true 2" - zplug "b4b4r07/zsh-gomi" - zplug install &>/dev/null - assert.true $status - end -end - -: after -{ - zplugs=() - unset expect actual - rm -rf "$ZPLUG_REPOS" -} diff --git a/test/autoload/commands/__list___test.zsh b/test/autoload/commands/__list___test.zsh deleted file mode 100644 index 9b22d3c3..00000000 --- a/test/autoload/commands/__list___test.zsh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - source "$ZPLUG_ROOT/test/.helpers/helper.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__list__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - zplug "foo/foo" - expect="foo/foo => nil" - actual="$(zplug list | unansi)" - assert.true $status - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - zplug "foo/foo" - expect="foo/foo => nil" - actual="$(zplug list foo | unansi)" - assert.true $status - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - zplug "foo/foo" - expect="foo/foo => nil" - actual="$(zplug list f | unansi)" - assert.true $status - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - zplug "foo/foo" - expect="foo/foo => nil" - actual="$(zplug list f | unansi)" - assert.true $status - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - zplug "foo/foo" - expect="bar => NO SUCH PACKAGE" - actual="$(zplug list bar | unansi)" - assert.true $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/commands/__load___test.zsh b/test/autoload/commands/__load___test.zsh deleted file mode 100644 index fe4ec144..00000000 --- a/test/autoload/commands/__load___test.zsh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - unset ZPLUG_LOADFILE - - local expect actual -} - -describe "__load__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "" - mock_as_command "foo/foo" - zplug load - [[ -x $ZPLUG_HOME/bin/foo ]] - assert.true $status - end - - it "" - mock_as_plugin "bar/bar" - expect=" Loaded bar/bar/bar.zsh" - actual="$(zplug load --verbose | unansi)" - assert.equals "$expect" "$actual" - end - - it "loads from cache at a custom location" - ZPLUG_USE_CACHE=true - ZPLUG_CACHE_FILE=$ZPLUG_HOME/foo/cache - - mock_as_plugin "foo/bar" - zplug load - - sleep 1 - - [[ -f $ZPLUG_CACHE_FILE ]] - assert.true $status - end -end - -: after -{ - zplugs=() - unset expect actual - rm -rf $ZPLUG_HOME -} diff --git a/test/autoload/commands/__status___test.zsh b/test/autoload/commands/__status___test.zsh deleted file mode 100644 index 520e4231..00000000 --- a/test/autoload/commands/__status___test.zsh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__status__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/commands/__update___test.zsh b/test/autoload/commands/__update___test.zsh deleted file mode 100644 index d5d6abf0..00000000 --- a/test/autoload/commands/__update___test.zsh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__update__" - it "Unknown option" - expect="[zplug] --unknown: Unknown option" - actual="$(zplug check --unknown 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/options/__help___test.zsh b/test/autoload/options/__help___test.zsh deleted file mode 100644 index 03c4e476..00000000 --- a/test/autoload/options/__help___test.zsh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__help__" - it "" - expect="$_ZPLUG_HELP" - actual="$(zplug --help 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/options/__version___test.zsh b/test/autoload/options/__version___test.zsh deleted file mode 100644 index c954ec23..00000000 --- a/test/autoload/options/__version___test.zsh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__help__" - it "" - expect="$_ZPLUG_VERSION" - actual="$(zplug --version)" - assert.true $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/utils/__add___test.zsh b/test/autoload/utils/__add___test.zsh deleted file mode 100644 index d0d17dad..00000000 --- a/test/autoload/utils/__add___test.zsh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - source "$ZPLUG_ROOT/test/.helpers/helper.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__add__" - it "Add to zplugs" - zplugs=() - zplug "foo/foo" - (( $+zplugs[foo/foo] )) - assert.true $status - end - - it "Duplicate registration" - zplugs=() - zplug "foo/foo" - zplug "foo/foo" - zplug "foo/foo" - (( $+zplugs[foo/foo] )) - assert.true $status - (( $+zplugs[foo/foo@] )) - assert.true $status - (( $+zplugs[foo/foo@@] )) - assert.true $status - expect="foo/foo => nil -foo/foo => nil -foo/foo => nil" - actual="$(zplug list | unansi)" - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/autoload/utils/__arguments___test.zsh b/test/autoload/utils/__arguments___test.zsh deleted file mode 100644 index 20dc9150..00000000 --- a/test/autoload/utils/__arguments___test.zsh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env zsh - -: before -{ - source "$ZPLUG_ROOT/init.zsh" - source "$ZPLUG_ROOT/test/.helpers/mock.zsh" - source "$ZPLUG_ROOT/test/.helpers/helper.zsh" - - export ZPLUG_HOME="$ZPLUG_ROOT/test/.fixtures" - - local expect actual -} - -describe "__arguments__" - it "" - expect="[zplug] foobarbaz: no such command" - actual="$(zplug foobarbaz 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - expect="[zplug] WARNING: You called a zplug command named 'lisa', which does not exist. - Continuing under the assumption that you meant 'list'. -[zplug] no package managed by zplug" - actual="$(zplug lisa 2>&1 | unansi)" - assert.equals "$expect" "$actual" - end - - it "" - zplugs=() - expect="[zplug] 'lost' is not a zplug command. See 'zplug help'. - Did you mean one of these? - list - load" - actual="$(zplug lost 2>&1)" - assert.false $status - assert.equals "$expect" "$actual" - end -end - -: after -{ - zplugs=() - unset expect actual -} diff --git a/test/base/base/base.t b/test/base/base/base.t new file mode 100644 index 00000000..05b67849 --- /dev/null +++ b/test/base/base/base.t @@ -0,0 +1,30 @@ +T_SUB "__zplug::base::base::is_cli" (( + # skip +)) +T_SUB "__zplug::base::base::zpluged" (( + # skip +)) +T_SUB "__zplug::base::base::version_requirement" (( + # skip +)) +T_SUB "__zplug::base::base::git_version" (( + # skip +)) +T_SUB "__zplug::base::base::zsh_version" (( + # skip +)) +T_SUB "__zplug::base::base::osx_version" (( + # skip +)) +T_SUB "__zplug::base::base::get_os" (( + # skip +)) +T_SUB "__zplug::base::base::is_osx" (( + # skip +)) +T_SUB "__zplug::base::base::is_linux" (( + # skip +)) +T_SUB "__zplug::base::base::packaging" (( + # skip +)) diff --git a/test/base/base/test.t b/test/base/base/test.t new file mode 100644 index 00000000..b394058d --- /dev/null +++ b/test/base/base/test.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::base::test::log_new" (( + # skip +)) +T_SUB "__zplug::base::test::log_captcha" (( + # skip +)) diff --git a/test/base/core/add.t b/test/base/core/add.t new file mode 100644 index 00000000..2840c2e7 --- /dev/null +++ b/test/base/core/add.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::core::add::to_zplugs" (( + # skip +)) +T_SUB "__zplug::core::add::proc_at-sign" (( + # skip +)) diff --git a/test/base/core/arguments.t b/test/base/core/arguments.t new file mode 100644 index 00000000..f296dd03 --- /dev/null +++ b/test/base/core/arguments.t @@ -0,0 +1,9 @@ +T_SUB "__zplug::core::arguments::exec" (( + # skip +)) +T_SUB "__zplug::core::arguments::auto_correct" (( + # skip +)) +T_SUB "__zplug::core::arguments::none" (( + # skip +)) diff --git a/test/base/core/commands.t b/test/base/core/commands.t new file mode 100644 index 00000000..df203657 --- /dev/null +++ b/test/base/core/commands.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::core::commands::get" (( + # skip +)) +T_SUB "__zplug::core::commands::user_defined" (( + # skip +)) diff --git a/test/base/core/core.t b/test/base/core/core.t new file mode 100644 index 00000000..1523fd47 --- /dev/null +++ b/test/base/core/core.t @@ -0,0 +1,12 @@ +T_SUB "__zplug::core::core::get_interfaces" (( + # skip +)) +T_SUB "__zplug::core::core::run_interfaces" (( + # skip +)) +T_SUB "__zplug::core::core::prepare" (( + # skip +)) +T_SUB "__zplug::core::core::variable" (( + # skip +)) diff --git a/test/base/core/options.t b/test/base/core/options.t new file mode 100644 index 00000000..ff3dc9c9 --- /dev/null +++ b/test/base/core/options.t @@ -0,0 +1,15 @@ +T_SUB "__zplug::core::options::get" (( + # skip +)) +T_SUB "__zplug::core::options::parse" (( + # skip +)) +T_SUB "__zplug::core::options::short" (( + # skip +)) +T_SUB "__zplug::core::options::long" (( + # skip +)) +T_SUB "__zplug::core::options::unknown" (( + # skip +)) diff --git a/test/base/core/self.t b/test/base/core/self.t new file mode 100644 index 00000000..5c7a2a6a --- /dev/null +++ b/test/base/core/self.t @@ -0,0 +1,12 @@ +T_SUB "__zplug::core::self::init" (( + # skip +)) +T_SUB "__zplug::core::self::update" (( + # skip +)) +T_SUB "__zplug::core::self::load" (( + # skip +)) +T_SUB "__zplug::core::self::info" (( + # skip +)) diff --git a/test/base/core/sources.t b/test/base/core/sources.t new file mode 100644 index 00000000..174c694b --- /dev/null +++ b/test/base/core/sources.t @@ -0,0 +1,15 @@ +T_SUB "__zplug::core::sources::is_exists" (( + # skip +)) +T_SUB "__zplug::core::sources::is_handler_defined" (( + # skip +)) +T_SUB "__zplug::core::sources::use_handler" (( + # skip +)) +T_SUB "__zplug::core::sources::call" (( + # skip +)) +T_SUB "__zplug::core::sources::use_default" (( + # skip +)) diff --git a/test/base/core/tags.t b/test/base/core/tags.t new file mode 100644 index 00000000..4ffd4a9b --- /dev/null +++ b/test/base/core/tags.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::core::tags::get" (( + # skip +)) +T_SUB "__zplug::core::tags::parse" (( + # skip +)) diff --git a/test/base/core/v1.t b/test/base/core/v1.t new file mode 100644 index 00000000..65f6bf70 --- /dev/null +++ b/test/base/core/v1.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::core::v1::tags" (( + # skip +)) +T_SUB "__zplug::core::v1::pipe" (( + # skip +)) diff --git a/test/base/io/cache.t b/test/base/io/cache.t new file mode 100644 index 00000000..b602f762 --- /dev/null +++ b/test/base/io/cache.t @@ -0,0 +1,9 @@ +T_SUB "__zplug::io::cache::create" (( + # skip +)) +T_SUB "__zplug::io::cache::load" (( + # skip +)) +T_SUB "__zplug::io::cache::update" (( + # skip +)) diff --git a/test/base/io/file.t b/test/base/io/file.t new file mode 100644 index 00000000..9d5413aa --- /dev/null +++ b/test/base/io/file.t @@ -0,0 +1,9 @@ +T_SUB "__zplug::io::file::load" (( + # skip +)) +T_SUB "__zplug::io::file::generate" (( + # skip +)) +T_SUB "__zplug::io::file::append" (( + # skip +)) diff --git a/test/base/io/log.t b/test/base/io/log.t new file mode 100644 index 00000000..4132f88f --- /dev/null +++ b/test/base/io/log.t @@ -0,0 +1,12 @@ +T_SUB "__zplug::io::log::with_json" (( + # skip +)) +T_SUB "__zplug::io::log::level" (( + # skip +)) +T_SUB "__zplug::io::log::new" (( + # skip +)) +T_SUB "__zplug::io::log::capture" (( + # skip +)) diff --git a/test/base/io/print.t b/test/base/io/print.t new file mode 100644 index 00000000..dd0505c3 --- /dev/null +++ b/test/base/io/print.t @@ -0,0 +1,9 @@ +T_SUB "__zplug::io::print::put" (( + # skip +)) +T_SUB "__zplug::io::print::die" (( + # skip +)) +T_SUB "__zplug::io::print::f" (( + # skip +)) diff --git a/test/base/job/hook.t b/test/base/job/hook.t new file mode 100644 index 00000000..f356669e --- /dev/null +++ b/test/base/job/hook.t @@ -0,0 +1,9 @@ +T_SUB "__zplug::job::hook::service" (( + # skip +)) +T_SUB "__zplug::job::hook::build" (( + # skip +)) +T_SUB "__zplug::job::hook::load" (( + # skip +)) diff --git a/test/base/job/queue.t b/test/base/job/queue.t new file mode 100644 index 00000000..d5cfe72a --- /dev/null +++ b/test/base/job/queue.t @@ -0,0 +1,15 @@ +T_SUB "__zplug::job::queue::enqueue" (( + # skip +)) +T_SUB "__zplug::job::queue::dequeue" (( + # skip +)) +T_SUB "__zplug::job::queue::clear" (( + # skip +)) +T_SUB "__zplug::job::queue::wait" (( + # skip +)) +T_SUB "__zplug::job::queue::wait_all" (( + # skip +)) diff --git a/test/base/job/spinner.t b/test/base/job/spinner.t new file mode 100644 index 00000000..c9cb4342 --- /dev/null +++ b/test/base/job/spinner.t @@ -0,0 +1,15 @@ +T_SUB "__zplug::job::spinner::is_spin" (( + # skip +)) +T_SUB "__zplug::job::spinner::lock" (( + # skip +)) +T_SUB "__zplug::job::spinner::unlock" (( + # skip +)) +T_SUB "__zplug::job::spinner::spin" (( + # skip +)) +T_SUB "__zplug::job::spinner::echo" (( + # skip +)) diff --git a/test/base/sources/bitbucket.t b/test/base/sources/bitbucket.t new file mode 100644 index 00000000..c886b4a3 --- /dev/null +++ b/test/base/sources/bitbucket.t @@ -0,0 +1,18 @@ +T_SUB "__zplug::sources::bitbucket::check" (( + # skip +)) +T_SUB "__zplug::sources::bitbucket::install" (( + # skip +)) +T_SUB "__zplug::sources::bitbucket::update" (( + # skip +)) +T_SUB "__zplug::sources::bitbucket::get_url" (( + # skip +)) +T_SUB "__zplug::sources::bitbucket::load_plugin" (( + # skip +)) +T_SUB "__zplug::sources::bitbucket::load_command" (( + # skip +)) diff --git a/test/base/sources/gh-r.t b/test/base/sources/gh-r.t new file mode 100644 index 00000000..6c2eca85 --- /dev/null +++ b/test/base/sources/gh-r.t @@ -0,0 +1,12 @@ +T_SUB "__zplug::sources::gh-r::check" (( + # skip +)) +T_SUB "__zplug::sources::gh-r::install" (( + # skip +)) +T_SUB "__zplug::sources::gh-r::update" (( + # skip +)) +T_SUB "__zplug::sources::gh-r::load_command" (( + # skip +)) diff --git a/test/base/sources/gist.t b/test/base/sources/gist.t new file mode 100644 index 00000000..68d61203 --- /dev/null +++ b/test/base/sources/gist.t @@ -0,0 +1,18 @@ +T_SUB "__zplug::sources::gist::check" (( + # skip +)) +T_SUB "__zplug::sources::gist::install" (( + # skip +)) +T_SUB "__zplug::sources::gist::update" (( + # skip +)) +T_SUB "__zplug::sources::gist::get_url" (( + # skip +)) +T_SUB "__zplug::sources::gist::load_plugin" (( + # skip +)) +T_SUB "__zplug::sources::gist::load_command" (( + # skip +)) diff --git a/test/base/sources/github.t b/test/base/sources/github.t new file mode 100644 index 00000000..d81b8862 --- /dev/null +++ b/test/base/sources/github.t @@ -0,0 +1,18 @@ +T_SUB "__zplug::sources::github::check" (( + # skip +)) +T_SUB "__zplug::sources::github::install" (( + # skip +)) +T_SUB "__zplug::sources::github::update" (( + # skip +)) +T_SUB "__zplug::sources::github::get_url" (( + # skip +)) +T_SUB "__zplug::sources::github::load_plugin" (( + # skip +)) +T_SUB "__zplug::sources::github::load_command" (( + # skip +)) diff --git a/test/base/sources/local.t b/test/base/sources/local.t new file mode 100644 index 00000000..df0a0555 --- /dev/null +++ b/test/base/sources/local.t @@ -0,0 +1,9 @@ +T_SUB "__zplug::sources::local::check" (( + # skip +)) +T_SUB "__zplug::sources::local::load_plugin" (( + # skip +)) +T_SUB "__zplug::sources::local::load_command" (( + # skip +)) diff --git a/test/base/sources/oh-my-zsh.t b/test/base/sources/oh-my-zsh.t new file mode 100644 index 00000000..22d06b83 --- /dev/null +++ b/test/base/sources/oh-my-zsh.t @@ -0,0 +1,15 @@ +T_SUB "__zplug::sources::oh-my-zsh::check" (( + # skip +)) +T_SUB "__zplug::sources::oh-my-zsh::install" (( + # skip +)) +T_SUB "__zplug::sources::oh-my-zsh::update" (( + # skip +)) +T_SUB "__zplug::sources::oh-my-zsh::get_url" (( + # skip +)) +T_SUB "__zplug::sources::oh-my-zsh::load_plugin" (( + # skip +)) diff --git a/test/base/utils/awk.t b/test/base/utils/awk.t new file mode 100644 index 00000000..ee653695 --- /dev/null +++ b/test/base/utils/awk.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::utils::awk::path" (( + # skip +)) +T_SUB "__zplug::utils::awk::available" (( + # skip +)) diff --git a/test/base/utils/git.t b/test/base/utils/git.t new file mode 100644 index 00000000..d5e66698 --- /dev/null +++ b/test/base/utils/git.t @@ -0,0 +1,27 @@ +T_SUB "__zplug::utils::git::clone" (( + # skip +)) +T_SUB "__zplug::utils::git::checkout" (( + # skip +)) +T_SUB "__zplug::utils::git::merge" (( + # skip +)) +T_SUB "__zplug::utils::git::status" (( + # skip +)) +T_SUB "__zplug::utils::git::get_head_branch_name" (( + # skip +)) +T_SUB "__zplug::utils::git::get_remote_name" (( + # skip +)) +T_SUB "__zplug::utils::git::get_remote_state" (( + # skip +)) +T_SUB "__zplug::utils::git::get_state" (( + # skip +)) +T_SUB "__zplug::utils::git::remote_url" (( + # skip +)) diff --git a/test/base/utils/omz.t b/test/base/utils/omz.t new file mode 100644 index 00000000..a7151b81 --- /dev/null +++ b/test/base/utils/omz.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::utils::omz::depends" (( + # skip +)) +T_SUB "__zplug::utils::omz::theme" (( + # skip +)) diff --git a/test/base/utils/releases.t b/test/base/utils/releases.t new file mode 100644 index 00000000..2668901e --- /dev/null +++ b/test/base/utils/releases.t @@ -0,0 +1,18 @@ +T_SUB "__zplug::utils::releases::get_latest" (( + # skip +)) +T_SUB "__zplug::utils::releases::get_state" (( + # skip +)) +T_SUB "__zplug::utils::releases::is_64" (( + # skip +)) +T_SUB "__zplug::utils::releases::get_url" (( + # skip +)) +T_SUB "__zplug::utils::releases::get" (( + # skip +)) +T_SUB "__zplug::utils::releases::index" (( + # skip +)) diff --git a/test/base/utils/shell.t b/test/base/utils/shell.t new file mode 100644 index 00000000..4d615d44 --- /dev/null +++ b/test/base/utils/shell.t @@ -0,0 +1,24 @@ +T_SUB "__zplug::utils::shell::remove_deadlinks" (( + # skip +)) +T_SUB "__zplug::utils::shell::search_commands" (( + # skip +)) +T_SUB "__zplug::utils::shell::glob2regexp" (( + # skip +)) +T_SUB "__zplug::utils::shell::sudo" (( + # skip +)) +T_SUB "__zplug::utils::shell::unansi" (( + # skip +)) +T_SUB "__zplug::utils::shell::cd" (( + # skip +)) +T_SUB "__zplug::utils::shell::getopts" (( + # skip +)) +T_SUB "__zplug::utils::shell::pipestatus" (( + # skip +)) diff --git a/test/base/utils/yaml.t b/test/base/utils/yaml.t new file mode 100644 index 00000000..712c3e4a --- /dev/null +++ b/test/base/utils/yaml.t @@ -0,0 +1,6 @@ +T_SUB "__zplug::utils::yaml::tokenizer" (( + # skip +)) +T_SUB "__zplug::utils::yaml::parser" (( + # skip +)) diff --git a/zplug b/zplug deleted file mode 100644 index d8511da6..00000000 --- a/zplug +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env zsh - -# -# For compatibility zplug v1 -# - -__logo() { - cat <<'EOLOGO' - _ - _____ __ | |_ _ __ _ - |_ / '_ \| | | | |/ _` | - / /| |_) | | |_| | (_| | - /___| .__/|_|\__,_|\__, | - |_| |___/ -EOLOGO -} - -__get_zplug() { - local i - local url="https://github.com/zplug/zplug" - - : ${ZPLUG_HOME:=$1} - if [[ -z $ZPLUG_HOME ]]; then - printf '[zplug] $ZPLUG_HOME is empty\n' >&2 - return 1 - fi - - if [[ -d $ZPLUG_HOME ]]; then - printf "[zplug] zplug is already installed\n" >&2 - return 1 - fi - - if (( ! $+commands[git] )); then - printf "[zplug] zplug requires git command\n" >&2 - return 1 - fi - - git clone \ - "$url" \ - "$ZPLUG_HOME" \ - &>/dev/null & - - while true - do - for i in ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏ - do - print -P -n " $i Downloading %Bzplug%b to $ZPLUG_HOME\r" - sleep 0.02 - done - if [[ -z ${${(v)jobstates##*:*:}%"="*} ]]; then - break - fi - done - - printf "\r\033[0K" - if [[ -d $ZPLUG_HOME ]]; then - printf "[zplug] Welcome to the world of zplug...\U1F33A\n" - else - printf "[zplug] Oops! Failed to install...\n" >&2 - print -P -n "[zplug] For more details, see also %U$url%u\n" >&2 - return 1 - fi -} - -function() { - local init_file="${${(%):-%x}:A:h}/init.zsh" - if [[ -z $ZSH_VERSION ]]; then - printf "[zplug] zplug must be run on ZSH\n" >&2 - return 1 2>&- || exit 1 - fi - - # Check if current zsh is interactive - if [[ $- =~ i ]]; then - # source - if [[ -f $init_file ]]; then - source "$init_file" - return $status - else - __logo >&2 - printf "[zplug] cannot find $init_file\n" >&2 - return 1 - fi - else - __get_zplug "$@" - exit $status - fi -} "$@"