mirror of https://github.com/mattmc3/antidote
Add new Zsh parser to replace Awk parser
This commit is contained in:
parent
839e7621b6
commit
112f982589
|
|
@ -3,39 +3,53 @@
|
|||
### Parse antidote's bundle DSL.
|
||||
#function __antidote_parse_bundles {
|
||||
emulate -L zsh; setopt local_options $_adote_funcopts
|
||||
$__adote_awkcmd '
|
||||
BEGIN { RS="[\r\n]" }
|
||||
|
||||
# skip comments and empty lines
|
||||
/^ *$/ || /^ *#/ {next}
|
||||
# Declare vars
|
||||
local bundle_str bundle_repr collected_input err lineno=0
|
||||
local key val
|
||||
local -a bundles
|
||||
local -A bundle
|
||||
|
||||
# strip trailing comments
|
||||
{ sub(/[ \t]#.*$/,"",$0) }
|
||||
# Get piped/passed bundles
|
||||
collected_input="$(__antidote_collect_input "$@")"
|
||||
if [[ -n "$collected_input" ]]; then
|
||||
bundles=( "${(@f)collected_input}" )
|
||||
else
|
||||
bundles=()
|
||||
fi
|
||||
if ! (( $#bundles )) ; then
|
||||
print -ru2 -- "antidote: error: bundle argument expected"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# escape leading $ variables
|
||||
{ sub(/^\$/,"\\$",$0) }
|
||||
for bundle_str in $bundles; do
|
||||
(( lineno += 1 ))
|
||||
|
||||
# handle extension functionality (eg :use ohmyzsh)
|
||||
$1~/^:/ {
|
||||
sub(/^:/,"",$1)
|
||||
printf "antidote-script-" $1
|
||||
for (i=2; i<=NF; i++) {
|
||||
printf " %s",$i
|
||||
}
|
||||
printf "\n"
|
||||
next
|
||||
}
|
||||
# Parse the bundle.
|
||||
bundle_repr=$(__antidote_parser "$bundle_str"); err=$?
|
||||
if [[ -z "$bundle_repr" ]]; then
|
||||
continue
|
||||
elif [[ "$err" -ne 0 ]]; then
|
||||
print -ru2 -- "antidote: Bundle parser error on line ${lineno}: '$bundle_str'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Turn the typeset repr into the bundle assoc_arr
|
||||
eval "$bundle_repr"
|
||||
|
||||
# move flags to front and call antidote-script
|
||||
{
|
||||
sub(/ #.*$/,"",$0)
|
||||
printf "antidote-script"
|
||||
for (i=2; i<=NF; i++) {
|
||||
sub(/^/,"--",$i)
|
||||
sub(/:/," ",$i)
|
||||
printf " %s",$i
|
||||
}
|
||||
printf " %s\n",$1
|
||||
}
|
||||
' "$@"
|
||||
print -rn -- "antidote-script"
|
||||
for key in ${(ok)bundle}; do
|
||||
[[ "$key" != name ]] && [[ "$key" != '_'* ]] || continue
|
||||
val="${bundle[$key]}"
|
||||
printf ' --%s %s' $key $val
|
||||
done
|
||||
|
||||
# Escape leading $ variables
|
||||
if [[ "${bundle[name]}" == '$'* ]]; then
|
||||
printf ' \$%s\n' "${bundle[name]#\$}"
|
||||
else
|
||||
printf ' %s\n' "${bundle[name]}"
|
||||
fi
|
||||
done
|
||||
#}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
#!/bin/zsh
|
||||
|
||||
### Parse antidote's bundle DSL to an associative array.
|
||||
# Example:
|
||||
# __antidote_parser 'foo/bar path:plugins/baz kind:fpath pre:myprecmd # comment'
|
||||
# typeset -A bundle=( [kind]=fpath [path]=plugins/baz [pre]=myprecmd [name]=foo/bar )
|
||||
#
|
||||
# Notes:
|
||||
# bundle_str : antidote DSL syntax
|
||||
# bundle : assoc array representation
|
||||
# bundle_repr : Zsh serialization of the bundle assoc arrary
|
||||
#
|
||||
# Metadata:
|
||||
# _repodir : The clone destination dir
|
||||
# _type : The type of bundle (url, repo, path, ?)
|
||||
# _repo : The user/repo short form of the URL
|
||||
# _url : The git repo URL
|
||||
#
|
||||
#function __antidote_parser {
|
||||
emulate -L zsh; setopt local_options $_adote_funcopts
|
||||
local MATCH MBEGIN MEND; local -a match mbegin mend # appease 'warn_create_global'
|
||||
local bundle_str bundle_var bundle_repr gitsite str pair key value
|
||||
local -a kvpairs parts
|
||||
local -A bundle
|
||||
|
||||
bundle_str="$1"
|
||||
bundle_var="${2:-bundle}"
|
||||
|
||||
# Allow the user to override the default git site if they really want to
|
||||
zstyle -s ':antidote:gitremote' url 'gitsite' \
|
||||
|| gitsite='https://github.com'
|
||||
gitsite="${gitsite%/}"
|
||||
|
||||
# Remove anything after the first '#'
|
||||
bundle_str=${bundle_str%%\#*}
|
||||
# Trim spaces
|
||||
bundle_str=${${bundle_str/#[[:space:]]#}/%[[:space:]]#}
|
||||
# Skip empty bundle strings
|
||||
[[ -z "$bundle_str" ]] && return 0
|
||||
# 1st field gets a 'name:' prefix so we can treat everything as key:val pairs
|
||||
bundle_str="name:${bundle_str}"
|
||||
|
||||
# Split line into key-value pairs with quoting
|
||||
kvpairs=(${(Q)${(z)bundle_str}})
|
||||
for pair in "${kvpairs[@]}"; do
|
||||
key=${pair%%:*} # Extract key (before first ':')
|
||||
if [[ "$pair" == *:* ]]; then
|
||||
value=${pair#*:} # Extract value (after first ':')
|
||||
else
|
||||
value=
|
||||
fi
|
||||
bundle[$key]=$value
|
||||
done
|
||||
|
||||
# Enhance the bundle with metadata fields. Metadata fields begin with an underscore
|
||||
# since those will never be part of the DSL. Let's start with _type, which tells us
|
||||
# whether the bundle is a URL, a user/repo, or a path
|
||||
if [[ "$bundle[name]" == *://*/*/* || "$bundle[name]" == (ssh|git)@*:*/* ]]; then
|
||||
if [[ "$bundle[name]" == *://*/*/*/* || "$bundle[name]" == *@*:*/*/* ]]; then
|
||||
bundle[_type]="?"
|
||||
else
|
||||
bundle[_type]="url"
|
||||
fi
|
||||
elif [[ "$bundle[name]" == *('@'|':')* ]] ; then
|
||||
bundle[_type]="?" # bad URLs
|
||||
elif [[ "$bundle[name]" == ('~'|'$'|'.')* ]]; then
|
||||
bundle[_type]="path"
|
||||
elif [[ "$bundle[name]" == */* && "$bundle[name]" != */*/* ]]; then
|
||||
bundle[_type]="repo"
|
||||
elif [[ "$bundle[name]" == */* ]]; then
|
||||
bundle[_type]="path"
|
||||
else
|
||||
bundle[_type]="?"
|
||||
fi
|
||||
|
||||
# For git repos, we add a metadata field for the URL
|
||||
if [[ "$bundle[_type]" == url ]]; then
|
||||
str="$bundle[name]"
|
||||
str=${str%.git}
|
||||
str=${str:gs/\:/\/}
|
||||
parts=( ${(ps./.)str} )
|
||||
if [[ $#parts -gt 1 ]]; then
|
||||
bundle[_repo]="${parts[-2]}/${parts[-1]}"
|
||||
else
|
||||
bundle[_repo]="$str"
|
||||
fi
|
||||
bundle[_url]="$bundle[name]"
|
||||
elif [[ "$bundle[_type]" == repo ]]; then
|
||||
bundle[_repo]="${bundle[name]}"
|
||||
bundle[_url]="${gitsite}/${bundle[name]}"
|
||||
fi
|
||||
|
||||
# If there's a git URL, we also need to set the _repodir
|
||||
if [[ -v bundle[_url] ]]; then
|
||||
# TODO: Remove for antidote 2.0
|
||||
if zstyle -t ':antidote:compatibility-mode' 'antibody' || ! zstyle -t ':antidote:bundle' use-friendly-names; then
|
||||
# sanitize URL for safe use as a dir name
|
||||
# ex: $ANTIDOTE_HOME/https-COLON--SLASH--SLASH-github.com-SLASH-zsh-users-SLASH-zsh-autosuggestions
|
||||
str="$bundle[_url]"
|
||||
str=${str%.git}
|
||||
str=${str:gs/\@/-AT-}
|
||||
str=${str:gs/\:/-COLON-}
|
||||
str=${str:gs/\//-SLASH-}
|
||||
bundle[_repodir]="$str"
|
||||
else
|
||||
bundle[_repodir]="$bundle[_repo]"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Print the parsed bundle assoc arr using whatever bundle_var the user wants
|
||||
bundle_repr="$(declare -p bundle)"
|
||||
bundle_repr="typeset -A ${bundle_var}=${bundle_repr#*=}"
|
||||
|
||||
# Sanity check that I probably don't need.
|
||||
if [[ ! "$bundle_repr" =~ "^typeset\ -A\ ${bundle_var}=" ]]; then
|
||||
print -ru2 -- "antidote: Unable to parse bundle string: '$bundle_str'."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Return/print the result.
|
||||
typeset -g REPLY="$bundle_repr"
|
||||
print -r -- "$REPLY"
|
||||
#}
|
||||
|
|
@ -89,13 +89,13 @@ antidote-script foo/bar
|
|||
|
||||
```zsh
|
||||
% echo 'https://github.com/foo/bar path:lib branch:dev' | __antidote_parse_bundles
|
||||
antidote-script --path lib --branch dev https://github.com/foo/bar
|
||||
antidote-script --branch dev --path lib https://github.com/foo/bar
|
||||
% echo 'git@github.com:foo/bar.git kind:clone branch:main' | __antidote_parse_bundles
|
||||
antidote-script --kind clone --branch main git@github.com:foo/bar.git
|
||||
antidote-script --branch main --kind clone git@github.com:foo/bar.git
|
||||
% echo 'foo/bar kind:fpath abc:xyz' | __antidote_parse_bundles
|
||||
antidote-script --kind fpath --abc xyz foo/bar
|
||||
antidote-script --abc xyz --kind fpath foo/bar
|
||||
% echo 'foo/bar path:plugins/myplugin kind:path # trailing comment' | __antidote_parse_bundles
|
||||
antidote-script --path plugins/myplugin --kind path foo/bar
|
||||
antidote-script --kind path --path plugins/myplugin foo/bar
|
||||
%
|
||||
```
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ antidote-script --kind path foo/bar
|
|||
The bundle parser is an awk script that turns the bundle DSL into antidote-script statements.
|
||||
|
||||
```zsh
|
||||
% __antidote_parse_bundles $ZDOTDIR/.zsh_plugins.txt
|
||||
% __antidote_parse_bundles < $ZDOTDIR/.zsh_plugins.txt
|
||||
antidote-script ~/foo/bar
|
||||
antidote-script --path plugins/myplugin \$ZSH_CUSTOM
|
||||
antidote-script foo/bar
|
||||
|
|
@ -122,7 +122,7 @@ antidote-script --kind fpath foo/bar
|
|||
antidote-script --kind path foo/bar
|
||||
antidote-script --path lib ohmy/ohmy
|
||||
antidote-script --path plugins/extract ohmy/ohmy
|
||||
antidote-script --path plugins/magic-enter --kind defer ohmy/ohmy
|
||||
antidote-script --kind defer --path plugins/magic-enter ohmy/ohmy
|
||||
antidote-script --path custom/themes/pretty.zsh-theme ohmy/ohmy
|
||||
%
|
||||
```
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
```zsh
|
||||
% antidote-script #=> --exit 1
|
||||
% antidote-script
|
||||
antidote: error: bundle argument expected
|
||||
%
|
||||
```
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
# antidote bundle parser tests
|
||||
|
||||
## Setup
|
||||
|
||||
```zsh
|
||||
% source ./tests/__init__.zsh
|
||||
% t_setup
|
||||
% zstyle ':antidote:gitremote' url 'https://fakegitsite.com/'
|
||||
%
|
||||
```
|
||||
|
||||
## Test bundle parser associative arrays
|
||||
|
||||
The bundle parser takes the antidote bundle format and returns an associative array
|
||||
from the results of `declare -p parsed_bundle`
|
||||
|
||||
Test empty:
|
||||
|
||||
```zsh
|
||||
% __antidote_parser
|
||||
% __antidote_parser '# This is a full line comment'
|
||||
%
|
||||
```
|
||||
|
||||
Test assoc array for repo
|
||||
|
||||
```zsh
|
||||
% __antidote_parser 'foo/bar' | print_aarr
|
||||
$assoc_arr : bundle
|
||||
_repo : foo/bar
|
||||
_repodir : foo/bar
|
||||
_type : repo
|
||||
_url : https://fakegitsite.com/foo/bar
|
||||
name : foo/bar
|
||||
%
|
||||
```
|
||||
|
||||
Test assoc array for repo in compatibility mode
|
||||
|
||||
```zsh
|
||||
% zstyle ':antidote:bundle' use-friendly-names off
|
||||
% __antidote_parser 'foo/bar' | print_aarr
|
||||
$assoc_arr : bundle
|
||||
_repo : foo/bar
|
||||
_repodir : https-COLON--SLASH--SLASH-fakegitsite.com-SLASH-foo-SLASH-bar
|
||||
_type : repo
|
||||
_url : https://fakegitsite.com/foo/bar
|
||||
name : foo/bar
|
||||
% zstyle ':antidote:bundle' use-friendly-names on
|
||||
%
|
||||
```
|
||||
|
||||
Test assoc array for path
|
||||
|
||||
```zsh
|
||||
% __antidote_parser '$ZSH_CUSTOM/foo' 'mybundle' | print_aarr
|
||||
$assoc_arr : mybundle
|
||||
_type : path
|
||||
name : $ZSH_CUSTOM/foo
|
||||
%
|
||||
```
|
||||
|
||||
Test assoc array for jibberish
|
||||
|
||||
```zsh
|
||||
% __antidote_parser 'a b c d:e:f' | print_aarr
|
||||
$assoc_arr : bundle
|
||||
_type : ?
|
||||
b :
|
||||
c :
|
||||
d : e:f
|
||||
name : a
|
||||
% __antidote_parser 'foo bar:baz' | print_aarr
|
||||
$assoc_arr : bundle
|
||||
_type : ?
|
||||
bar : baz
|
||||
name : foo
|
||||
%
|
||||
```
|
||||
|
||||
Test assoc array for everything
|
||||
|
||||
```zsh
|
||||
% __antidote_parser 'foo/bar branch:baz kind:zsh path:plugins/baz pre:precmd post:"post cmd"' | print_aarr
|
||||
$assoc_arr : bundle
|
||||
_repo : foo/bar
|
||||
_repodir : foo/bar
|
||||
_type : repo
|
||||
_url : https://fakegitsite.com/foo/bar
|
||||
branch : baz
|
||||
kind : zsh
|
||||
name : foo/bar
|
||||
path : plugins/baz
|
||||
post : post cmd
|
||||
pre : precmd
|
||||
%
|
||||
```
|
||||
|
||||
## Test specific keys have known values
|
||||
|
||||
Test name:
|
||||
|
||||
```zsh
|
||||
% __antidote_parser 'foo/bar' | aarr_val name
|
||||
foo/bar
|
||||
%
|
||||
```
|
||||
|
||||
Test \_type:
|
||||
|
||||
```zsh
|
||||
% __antidote_parser 'foo/bar' | aarr_val _type
|
||||
repo
|
||||
% __antidote_parser 'https://github.com/foo/bar' | aarr_val _type
|
||||
url
|
||||
% __antidote_parser 'git@bitbucket.org:foo/bar' | aarr_val _type
|
||||
url
|
||||
% __antidote_parser '$foo/bar' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser '$foo/bar/baz.zsh' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser '~foo/bar' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser '~/foo' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser './foo.zsh' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser '../foo.zsh' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser 'foo/bar/' | aarr_val _type
|
||||
path
|
||||
% __antidote_parser 'foo:bar' | aarr_val _type
|
||||
?
|
||||
% __antidote_parser 'bad@gitsite.com/foo/bar' | aarr_val _type
|
||||
?
|
||||
% __antidote_parser 'http:/badsite.com/foo/bar' | aarr_val _type
|
||||
?
|
||||
% __antidote_parser 'https://badsite.com/foo/bar/baz' | aarr_val _type
|
||||
?
|
||||
% __antidote_parser 'https://badsite.com/foo' | aarr_val _type
|
||||
?
|
||||
%
|
||||
```
|
||||
|
||||
## Teardown
|
||||
|
||||
```zsh
|
||||
% t_teardown
|
||||
%
|
||||
```
|
||||
Loading…
Reference in New Issue