1
1
Fork 0
mirror of https://github.com/tonydamage/nux-env.git synced 2025-12-12 13:34:29 +01:00

Nuweb drop

Signed-off-by: root <root@tdm-cloud.(none)>
This commit is contained in:
root 2019-03-09 12:32:11 +01:00
parent ee9a720f67
commit a7b55553ad
62 changed files with 1772 additions and 608 deletions

13
inc/nux/array.nuxsh.sh Executable file
View file

@ -0,0 +1,13 @@
@namespace nux.array {
function :contains array value {
local array_ref="$array[@]";
for c in "${!array_ref}"; do
if [ "$c" == "$value" ]; then
return 0;
fi
done
return 1
}
}

0
inc/nux/check.inc.sh Normal file → Executable file
View file

0
inc/nux/color.nuxsh.sh Normal file → Executable file
View file

10
inc/nux/dsl.inc.sh Normal file → Executable file
View file

@ -98,11 +98,11 @@ nux.dsl.plan() {
local file="$2";
local cached="${3:-$file${NUDSL_CACHE_SUFFIX}}";
if [ "$file" -ot "$cached" ]; then
nux.log debug No need to recompile.
nux.log trace No need to recompile '$file'.
return;
fi
nux.log debug Needs regeneration, creating new version.
nux.log trace File '$file' Needs regeneration, creating new version.
local dirname=$(dirname "$cached")
mkdir -p "$dirname";
@ -110,9 +110,9 @@ nux.dsl.plan() {
if (nux.dsl.process plan "$language" "$file" > "$execution_plan") ; then
mv -f "$execution_plan" "$cached";
else
echo "Plan could not be generated. See errors."
echo "Plan for $file could not be generated. See errors." >&2
rm "$execution_plan"
return -1;
return 1;
fi
}
@ -136,7 +136,7 @@ nux.dsl.process0() {
fi
done
if [ -n "$process_failed" ]; then
return -1;
return 1;
fi
done;
}

0
inc/nux/help.nuxsh.sh Normal file → Executable file
View file

113
inc/nux/json.inc.sh Executable file
View file

@ -0,0 +1,113 @@
## #nux.json NUX Script JSON Helper library
##
## #Public functions
## nux.json.start
## Starts operation on new JSON. Resets write operations stack and JSON
## source file to empty (useful for creating JSON from scratch.)
function nux.json.start {
nux_json_opstack=".";
nux_json_source="-n";
}
## nux.json.open <file>
## Opens JSON File for reading and writing using *nux.json.open* and
## *nux.json.write* commands.
##
## In order to work with empty JSON use *-n* as *file*. This allows
## for creating new JSON from scratch.
##
## NOTE: Open does not reset operation stack. To reset operation stack
## and opened file use *nux.json.start*
function nux.json.open {
local file="$1"
if [ -f "$file" ]; then
nux_json_source="$file"
fi
}
## nux.json.read <path>
## Reads *path* from currently opened JSON file.
## NOTE: Read does not see changes performed by *nux.json.write* unless
## these changes were flushed using *nux.json.flush*.
function nux.json.read {
local path=".$1";
jq -r "$path" "$nux_json_source";
}
## nux.json.write <path> <value>
## Adds write operation to action stack. Writes are not performed
## immediately, but rather when *nux.json.flush* is invoked.
## This allows for batching of operations or opting out of actually
## modifying file.
function nux.json.write {
local path=".$1";
local value="$2";
nux_json_opstack="${nux_json_opstack} | $path |= \"$value\""
}
function nux.json.write.raw {
local path=".$1";
local value="$2";
nux_json_opstack="${nux_json_opstack} | $path |= $value"
}
## nux.json.flush [<target>]
## Flushes any write operations to specified *target* file.
## If *target* is not specified JSON is outputted to *STDIN*.
##
## NOTE: Flush does not reset operation stack. To reset
## operation stack and opened file use *nux.json.start*
##
function nux.json.flush {
local target="$1"
if [ -n "$target" ]; then
local write_target="$target";
if [ "$nux_json_source" == "$target" ]; then
write_target=$(mktemp "$(dirname "$target")/tempXXXXXX.json")
fi
jq -r "$nux_json_opstack" "$nux_json_source" > "$write_target"
if [ "$nux_json_source" == "$target" ]; then
mv -f "$write_target" "$target"
fi
else
jq -r "$nux_json_opstack" "$nux_json_source"
fi
}
## nux.json.shorthands
## Exposes shorthands for writing and reading from JSON file.
## *njw* - nux.json.write
## *njr* - nux.json.read
##
function nux.json.shorthands {
function njw {
nux.json.write "$@"
}
function njr {
nux.json.read "$@"
}
}
## # Usage Notes
##
## ## Operation stack and flush
##
## As mentioned in documentation for *nux.json.flush* write stack
## is not removed, but rather kept alone, separatly from reference
## to open file. This allows for having modification template
## which could be executed on multiple files.
##
## The following example adds meta.author and meta.email
## to every JSON in directory.
##
## *nux.json.start*
## *nux.json.write* meta.author "Tony Tkacik"
## *nux.json.write* meta.email "example@example.com"
## *for* f *in* "*.json";
## *do*
## *nux.json.open* "$f"
## *nux.json.flush* "$f"
## *done*;
##
##

0
inc/nux/log.inc.sh Normal file → Executable file
View file

50
inc/nux/meta.nuxsh.sh Executable file
View file

@ -0,0 +1,50 @@
nux_meta_backends="func file"
@namespace nux.meta {
function :add-impl impl {
nux_meta_backends="$impl $nux_meta_backends"
}
function :get filename name default {
for backend in $nux_meta_backends; do
#nux.log debug "Invoking $backend nux.meta.impl.$backend.get $(declare -f nux.meta.impl.$backend.get)";
local value=$(nux.meta.impl.$backend.get "$filename" "$name");
if [ -n "$value" ] {
echo "$value"
return 0;
}
done
if [ -z "$default" ] {
return 1;
}
echo "$default"
}
}
@namespace nux.meta.impl.file {
function :get filename name {
if [ -e "$filename/.nux.meta" ] {
grep "^$name " "$filename/.nux.meta" | cut -d " " -f2-
}
}
function :add filename name value {
local meta="$filename/.nux.meta";
local metaline="$name $value";
if ! ( [ -e "$meta" ] && grep "^$metaline\$" "$meta" > /dev/null ) {
nux.log debug "Writing pin to $meta"
echo "$metaline" >> "$meta"
}
}
}
@namespace nux.meta.impl.func {
function :get filename name {
local funcspec="${name//:/.}"
nux.exec.optional "nux.meta.impl.func.$funcspec" "$filename"
}
}

0
inc/nux/meta/impl/.gitkeep Executable file
View file

37
inc/nux/mime.nuxsh.sh Executable file
View file

@ -0,0 +1,37 @@
function nux.mime {
nux.mime.naive.suffix "$@"
}
@namespace nux.mime {
function :naive.suffix filename {
local type=binary/octet
local suffix="${filename##*.}"
suffix="${suffix,,}"
if [ -d "$filename" ]; then
type=directory
else
case "${suffix,,}" in
txt) type=text/plain;;
css) type=text/css;;
jpeg) ;&
jpg) type=image/jpeg;;
png) type=image/png;;
zip) type=application/zip;;
cbr) type=application/x-cbz;;
cbz) type=application/x-cbr;;
pdf) type=application/pdf;;
epub) type=application/epub+zip;;
mp4) type=video/mp4;;
esac
fi
echo $type;
}
}

0
inc/nux/mime/impl/.gitkeep Executable file
View file

106
inc/nux/nuxsh.inc.sh Normal file → Executable file
View file

@ -1,16 +1,17 @@
nux.use nux/dsl
nux.nuxsh.language.def() {
local identifier='[^ ;{}=()$]+'
local identifier_char='[^ ;{}=()$:]'
local identifier='[^ ;{}=()$:]+'
local comment='(( *)(#.*))?'
local whitespace="([ ]*)"
local uarg="([^ #\{\}\"'\"'\"';]+)";
local uarg="([^ #{}\"'\"'\"';]+)";
local sarg="('\"'\"'[^'\"'\"']+'\"'\"')";
local darg='("[^"]*")';
local args="((($uarg|$darg|$sarg) *)*)";
local prefixed_id="([^ :]*:)?($identifier)"
local prefixed_id="($identifier_char*:)?($identifier)"
.match.line() {
local type="$1";
@ -34,11 +35,11 @@ nux.nuxsh.language.def() {
.match.line if_start "(if)( +)$prefixed_id( +)$args?( *)(\{)" \
keyword indent2 prefix identifier indent3 args - - - - - indent4 syntax3
.match.line function_start "((function)( +))($identifier)((\()|( *))(($identifier,? *)*)(\))?( *)(\{)" \
.match.line function_start "((function)( +))(:?$identifier)((\()|( *))(($identifier,? *)*)(\))?( *)(\{)" \
- keyword indent2 identifier - syntax indent3 args - syntax2 indent4 syntax3
.match.line block_start "($identifier)(( +)$args)?( *)(\{)" \
identifier - indent2 args - - - - - indent3 syntax3
.match.line block_start "$prefixed_id(( +)$args)?( *)(\{)" \
prefix identifier - indent2 args - - - - - indent3 syntax3
.match.line statement "$prefixed_id(( +)$args)?( *)(;?)"\
prefix identifier - indent2 args - - - - - indent3 syntax2
@ -69,16 +70,26 @@ nux.nuxsh.language.def() {
echo ${_block_type[${#_block_type[@]}-1]}
}
function .block.args.get {
echo ${_block_args[${#_block_args[@]}-1]}
}
function .block.pop {
unset _block_type[${#_block_type[@]}-1]
unset _block_args[${#_block_args[@]}-1]
}
function .block.push {
_block_type[${#_block_type[@]}]="$1"
local block="$1";shift;
_block_type[${#_block_type[@]}]="$block"
_block_args[${#_block_args[@]}]="$@"
}
.match.block_start.plan() {
.block.push $identifier;
nux.log debug "P '$identifier' '$prefix' "
local identifier=$(.identifier)
nux.log debug "Block '$identifier' '$prefix' "
.block.push "$identifier" "$args";
nux.exec.or .block.$identifier.start.plan .block.start.plan
}
@ -86,7 +97,7 @@ nux.nuxsh.language.def() {
local identifier=$(.block.get)
if [ "$identifier" == "$blocktrac_root" ]; then
nux.dsl.process.fail "unnecessary block end '$line' "
return -1;
return 1;
fi
nux.exec.or .block.$identifier.end.plan .block.end.plan
.block.pop;
@ -99,8 +110,8 @@ nux.nuxsh.language.def() {
}
.action.prefix() {
echo "# prefix: $1 $2"
eval "_import_prefix_$1='$2'";
echo "# prefix: $1 ${2%.}"
eval "_import_prefix_$1='${2%.}'";
}
@ -109,20 +120,27 @@ nux.nuxsh.language.def() {
local var=_import_prefix_${prefix%:}
local prepend=${!var};
if [ -z "$prepend" ] ; then
nudsl.process.fail "undefined prefix: $prefix";
nux.dsl.process.fail "undefined prefix: $prefix";
return;
fi
echo "$prepend$identifier"
echo "$prepend.$identifier"
else
echo "$identifier"
cat <<< "$identifier"
fi
}
.match.statement.plan() {
echo "${indent}$(.identifier) ${args}"
identifier=$(.identifier);
nux.exec.or .statement.$identifier.plan .statement.plan
}
.statement.plan() {
echo "${indent}$identifier ${args}"
}
.match.rule.plan() {
echo "rule " >&2;
eval ".action.${rule//:/.} $args";
}
@ -156,8 +174,8 @@ nux.nuxsh.language.def() {
.match.function_start.plan() {
.block.push function
case $identifier in
.*) ;;
:*) identifier="$_namespace${identifier#:}"
:) identifier="$_namespace";;
:*) identifier="$_namespace.${identifier#:}";;
esac;
echo "${indent}$identifier() {";
for arg in ${args//,/ }; do
@ -169,7 +187,7 @@ nux.nuxsh.language.def() {
case $identifier in
function) echo "$line";;
*"()") echo "$line";;
*) nudsl.process.fail Invalid block syntax: "'$identifier' '$line'";
*) nux.dsl.process.fail Invalid block syntax: "'$identifier' '$line'";
esac;
}
@ -189,6 +207,10 @@ nux.nuxsh.language.def() {
"""
}
.action.syntax() {
nux.use "$1.syntax"
}
.action.block.rewrite.call() {
echo "# block:rewrite:block:call $@"
eval """.block.$1.start.plan() {
@ -200,8 +222,56 @@ nux.nuxsh.language.def() {
}
"""
}
.action.block.rewrite.call2() {
echo "# block:rewrite:block:call2 $@"
nux.nuxsh.block.rewrite.call "$1" "$2" "$3"
}
}
nux.nuxsh.block.rewrite.call() {
eval """.block.$1.start.plan() {
echo \"\${indent}\"'${2}'\" \$args\"
}
.block.$1.end.plan() {
local args=\"\$(.block.args.get)\";
echo \"\${indent}\"'${3}' \"\$args\"
}
"""
}
nux.nuxsh.block.rewrite.func() {
eval """
.block.$1.start.plan() {
${2} \"\${indent}\" \"\$args\"
}
.block.$1.end.plan() {
${3} \"\${indent}\" \"\$args\"
}
"""
}
nux.nuxsh.statement.rewrite.func() {
eval """
.statement.$1.plan() {
${2} \"\${indent}\" \"\$args\"
}
"""
}
nux.nuxsh.statement.rewrite.call() {
eval """.statement.$1.plan() {
nux.nuxsh.statement.rewrite.call0 '$2' '$3'
}
"""
}
nux.nuxsh.statement.rewrite.call0() {
echo "${indent}${1} $args ${2}"
}
function nux.nuxsh.use {
local file="$1";
local cached="$2";

120
inc/nux/repl.inc.sh Executable file
View file

@ -0,0 +1,120 @@
## nux.repl.start <processor> [<prompt>] [<complete>]
## Starts NUX REPL
##
## FIXME: Add autocompletion
function nux.repl.start {
function .null() {
:
}
local processor=$1;
local prompt=${2:-.null};
local complete=$3;
local command=""
if nux.check.function $complete; then
bind -x '"\C-i": "nux.repl.completion $prompt $complete"' &> /dev/null
fi
while IFS=" " read -e -p "$($prompt)" options
do
history -s "$options" > /dev/null 2>&1
nux.log debug Readed line is: $nc_white$options$nc_end
command=$(echo $options | cut -d" " -f1)
arguments=${options#"$command"}
nux.log debug Command: $command, arguments: $arguments
case "$command" in
exit)
break;;
*)
$processor $command $arguments
;;
esac
done
}
## nux.repl.completion <prompt> <completion>
##
##
## This function is modified version of
## https://github.com/mchav/with/blob/master/with
function nux.repl.completion() {
local prompt=$1;
local compgen_command=$2;
shift;shift;
# print readline's prompt for visual separation
if [ "$#" -eq 0 ]; then
echo "$($prompt)$READLINE_LINE"
fi
pmpt=$($prompt)
# remove part after readline cursor from completion line
local completion_line completion_word
completion_line="${READLINE_LINE:0:READLINE_POINT}"
completion_word="${completion_line##* }"
# set completion cursor according to pmpt length
COMP_POINT=$((${#pmpt}+${#completion_line}+1))
COMP_WORDBREAKS="\n\"'><=;|&(:"
COMP_LINE="$pmpt $completion_line"
# TODO: the purpose of these variables is still unclear
# COMP_TYPE=63
# COMP_KEY=9
# get index of word to be completed
local whitespaces_count escaped_whitespaces_count
whitespaces_count=$(echo "$COMP_LINE" | grep -o ' ' | wc -l)
escaped_whitespaces_count=$(echo "$COMP_LINE" | grep -o '\\ ' | wc -l)
COMP_CWORD=$((whitespaces_count-escaped_whitespaces_count))
# get sourced completion command
local program_name complete_command
program_name=${COMP_WORDS[0]}
program_name=$(basename "$program_name")
complete_command=$(complete -p | grep " ${program_name}$")
COMPREPLY=()
COMPREPLY=($($compgen_command "$completion_line"))
# get commmon prefix of available completions
local completions_prefix readline_prefix readline_suffix
completions_prefix=$(printf "%s\n" "${COMPREPLY[@]}" | \
sed -e '$!{N;s/^\(.*\).*\n\1.*$/\1\n\1/;D;}' | xargs)
readline_prefix="${READLINE_LINE:0:READLINE_POINT}"
readline_suffix="${READLINE_LINE:READLINE_POINT}"
# remove the word to be completed
readline_prefix=$(sed s/'\w*$'// <(echo "$readline_prefix") | xargs)
READLINE_LINE=""
if [[ "$readline_prefix" != "" ]]; then
READLINE_LINE="$readline_prefix "
fi
READLINE_LINE="$READLINE_LINE$completions_prefix"
# adjust readline cursor position
READLINE_POINT=$((${#READLINE_LINE}+1))
if [[ "$readline_suffix" != "" ]]; then
READLINE_LINE="$READLINE_LINE $readline_suffix"
fi
local completions_count display_all
completions_count=${#COMPREPLY[@]}
display_all="y"
if [[ $completions_count -eq 1 ]]; then
READLINE_LINE=$(echo "$READLINE_LINE" | xargs)
READLINE_LINE="$READLINE_LINE "
return
elif [[ $completions_count -gt 80 ]]; then
echo -en "Display all $completions_count possibilities? (y or n) "
read -N 1 display_all
echo "$display_all"
fi
if [[ "$display_all" = "y" ]]; then
for completion in "${COMPREPLY[@]}"; do echo "$completion"; done | column
fi
}