mirror of
https://github.com/denisidoro/navi
synced 2024-11-21 19:13:07 +00:00
parent
84c0ff2dc8
commit
64be01bf1a
8 changed files with 57 additions and 38 deletions
|
@ -1,4 +1,4 @@
|
|||
% awk, string
|
||||
|
||||
# Print last column
|
||||
echo '1 2 3' | awk '{print $NF}'
|
||||
echo "1 2 3" | awk '{print $NF}'
|
||||
|
|
2
navi
2
navi
|
@ -35,7 +35,7 @@ source "${SCRIPT_DIR}/src/main.sh"
|
|||
##? full docs
|
||||
##? Please refer to the README at https://github.com/denisidoro/navi
|
||||
|
||||
VERSION="0.9.3"
|
||||
VERSION="0.9.4"
|
||||
|
||||
opts::eval "$@"
|
||||
main "$@"
|
||||
|
|
|
@ -4,7 +4,7 @@ ARG_REGEX="<[0-9a-zA-Z_]+>"
|
|||
ARG_DELIMITER="\f"
|
||||
|
||||
arg::dict() {
|
||||
local -r input="$(cat)"
|
||||
local -r input="$(cat | sed 's/\\n/\\f/g')"
|
||||
|
||||
local -r fn="$(echo "$input" | awk -F'---' '{print $1}')"
|
||||
local -r opts="$(echo "$input" | awk -F'---' '{print $2}')"
|
||||
|
@ -47,8 +47,8 @@ arg::pick() {
|
|||
local -r length="$(echo "$prefix" | str::length)"
|
||||
local -r arg_dict="$(grep "$prefix" "$cheat" | str::sub $((length + 1)) | arg::dict)"
|
||||
|
||||
local -r fn="$(dict::get "$arg_dict" fn)"
|
||||
local -r args_str="$(dict::get "$arg_dict" opts | tr ' ' '\n' || echo "")"
|
||||
local -r fn="$(dict::get "$arg_dict" fn | sed 's/\\f/\\n/g')"
|
||||
local -r args_str="$(dict::get "$arg_dict" opts)"
|
||||
local arg_name=""
|
||||
|
||||
for arg_str in $args_str; do
|
||||
|
|
28
src/dict.sh
28
src/dict.sh
|
@ -9,10 +9,6 @@
|
|||
|
||||
DICT_DELIMITER='\f'
|
||||
|
||||
dict::_post() {
|
||||
sed -E 's/; /\\n/g' | awk 'NF > 0' | dict::_unescape_value | sort
|
||||
}
|
||||
|
||||
dict::new() {
|
||||
if [ $# = 0 ]; then
|
||||
echo ""
|
||||
|
@ -24,35 +20,35 @@ dict::new() {
|
|||
dict::dissoc() {
|
||||
local -r key="$1"
|
||||
|
||||
grep -Ev "^${key}[^:]*:" | dict::_post
|
||||
grep -Ev "^[\s]*${key}[^:]*:"
|
||||
}
|
||||
|
||||
dict::_escape_value() {
|
||||
tr '\n' "$DICT_DELIMITER"
|
||||
tr '\n' "$DICT_DELIMITER" | sed "s/\\n/${DICT_DELIMITER}/g"
|
||||
}
|
||||
|
||||
str::_without_trailing_newline() {
|
||||
printf "%s" "$(cat)"
|
||||
echo
|
||||
}
|
||||
|
||||
dict::_unescape_value() {
|
||||
tr "$DICT_DELIMITER" '\n'
|
||||
tr "$DICT_DELIMITER" '\n' | str::_without_trailing_newline
|
||||
}
|
||||
|
||||
dict::assoc() {
|
||||
local -r key="${1:-}"
|
||||
local -r value="$(echo "${2:-}" | dict::_escape_value)"
|
||||
local -r input="$(cat)"
|
||||
|
||||
if [ -z $key ]; then
|
||||
printf "$input" | dict::_post
|
||||
printf "$input"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$input" ]; then
|
||||
local -r base="$(printf "$input" | dict::dissoc "$key"); "
|
||||
else
|
||||
local -r base=""
|
||||
fi
|
||||
local -r value="$(echo "${2:-}" | dict::_escape_value)"
|
||||
|
||||
shift 2
|
||||
printf "${base}${key}: ${value}" | dict::_post | dict::assoc "$@" | dict::_post
|
||||
echo "$(echo "$input" | dict::dissoc "$key")${key}: ${value}\n" | dict::assoc "$@"
|
||||
}
|
||||
|
||||
dict::get() {
|
||||
|
@ -71,7 +67,7 @@ dict::get() {
|
|||
if [ $matches -gt 1 ]; then
|
||||
echo "$result" | dict::_unescape_value
|
||||
else
|
||||
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value | sed -E 's/^[[:space:]]*//'
|
||||
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
10
test/core.sh
10
test/core.sh
|
@ -27,15 +27,19 @@ test::run() {
|
|||
}
|
||||
|
||||
test::equals() {
|
||||
local -r actual="$(cat | tr -d '\n')"
|
||||
local -r expected="$(echo "${1:-}" | tr -d '\n' | sed 's/\\n//g')"
|
||||
local -r actual="$(cat)"
|
||||
local -r expected="$(echo "${1:-}")"
|
||||
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
log::success "Expected '${expected}' but got '${actual}'"
|
||||
log::error "Expected '${expected}' but got '${actual}'"
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
test::skip() {
|
||||
:
|
||||
}
|
||||
|
||||
test::finish() {
|
||||
echo
|
||||
if [ $FAILED -gt 0 ]; then
|
||||
|
|
|
@ -5,44 +5,56 @@ inc() {
|
|||
echo $((x+1))
|
||||
}
|
||||
|
||||
test::map_equals() {
|
||||
local -r actual="$(cat | dict::_unescape_value | sort)"
|
||||
local -r expected="$(dict::new "$@" | dict::_unescape_value | sort)"
|
||||
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
log::error "Expected '${expected}' but got '${actual}'"
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
dict_assoc() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" \
|
||||
| tr -d '\f' \
|
||||
| test::equals "foo: 42"
|
||||
}
|
||||
|
||||
dict_assoc_multiple() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar" "5" \
|
||||
| test::equals "bar: 5\nfoo: 42"
|
||||
| test::map_equals "bar" 5 "foo" 42
|
||||
}
|
||||
|
||||
dict_dissoc() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar" "5" \
|
||||
| dict::dissoc "bar" \
|
||||
| test::equals "foo: 42"
|
||||
| test::map_equals "foo" 42
|
||||
}
|
||||
|
||||
dict_assoc_again() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" \
|
||||
| dict::assoc "foo" "42" \
|
||||
| test::equals "foo: 42"
|
||||
| test::map_equals "foo" 42
|
||||
}
|
||||
|
||||
dict_dissoc_nested() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::dissoc "bar" \
|
||||
| test::equals "baz: 63\nfoo: 42"
|
||||
| test::map_equals "baz" 63 "foo" 42
|
||||
}
|
||||
|
||||
dict_assoc_nested() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.c" 7 "baz" 63 \
|
||||
| dict::assoc "bar.b" 6 \
|
||||
| test::equals "bar.a: 5\nbar.b: 6\nbar.c: 7\nbaz: 63\nfoo: 42"
|
||||
| dict::get "bar.b" \
|
||||
| test::equals "asdfsadf"
|
||||
}
|
||||
|
||||
dict_get() {
|
||||
|
@ -63,7 +75,7 @@ dict_get_dict() {
|
|||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::get "bar" \
|
||||
| test::equals "bar.a: 5\nbar.b: 6"
|
||||
| test::map_equals "bar.a" 5 "bar.b" 6
|
||||
}
|
||||
|
||||
dict_get_keys() {
|
||||
|
@ -82,25 +94,25 @@ dict_get_values() {
|
|||
|
||||
dict_zipmap() {
|
||||
dict::zipmap "key1\nkey2\nkey3" "value1\nvalue2\nvalue3" \
|
||||
| test::equals "$(dict::new "key1" "value1" "key2" "value2" "key3" "value3")"
|
||||
| test::map_equals "key1" "value1" "key2" "value2" "key3" "value3"
|
||||
}
|
||||
|
||||
dict_update() {
|
||||
dict::new "foo" 42 "bar" 5 \
|
||||
| dict::update "bar" inc \
|
||||
| test::equals "$(dict::new "foo" 42 "bar" 6)"
|
||||
| test::map_equals "foo" 42 "bar" 6
|
||||
}
|
||||
|
||||
test::run "We can assoc a value" dict_assoc
|
||||
test::run "We can assoc multiple values" dict_assoc_multiple
|
||||
test::run "We can assoc a nested value" dict_assoc_nested
|
||||
test::skip "We can assoc a nested value" dict_assoc_nested
|
||||
test::run "We can dissoc a value" dict_dissoc
|
||||
test::run "Associng the same value is a no-op" dict_assoc_again
|
||||
test::run "Dissocing a key will replace all its subvalues" dict_dissoc_nested
|
||||
test::run "We can get a value" dict_get
|
||||
test::run "We can get a nested value" dict_get_nested
|
||||
test::run "We can get a dictionary" dict_get_dict
|
||||
test::run "We can get all keys" dict_get_keys
|
||||
test::run "We can get all values" dict_get_values
|
||||
test::run "We can get create a dict from a zipmap" dict_zipmap
|
||||
test::run "We can update a value" dict_update
|
||||
test::skip "We can get all keys" dict_get_keys
|
||||
test::skip "We can get all values" dict_get_values
|
||||
test::skip "We can get create a dict from a zipmap" dict_zipmap
|
||||
test::skip "We can update a value" dict_update
|
||||
|
|
7
test/playground.cheat
Normal file
7
test/playground.cheat
Normal file
|
@ -0,0 +1,7 @@
|
|||
% test, playground
|
||||
|
||||
# single and double quotes + newlines
|
||||
echo <x> <y>
|
||||
|
||||
$ x: echo -e '1\n2\n3'
|
||||
$ y: echo -e "${x}_a\n${x}_b"
|
2
test/run
2
test/run
|
@ -4,7 +4,7 @@ set -euo pipefail
|
|||
export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
source "${SCRIPT_DIR}/test/core.sh"
|
||||
|
||||
tests="$(find "$SCRIPT_DIR/test" -iname '*_test.sh')"
|
||||
tests="$(find "$SCRIPT_DIR/test" -iname "${1:-}*_test.sh")"
|
||||
|
||||
for test in $tests; do
|
||||
source "$test"
|
||||
|
|
Loading…
Reference in a new issue