Skip to content

Commit

Permalink
Refactor code (denisidoro#49)
Browse files Browse the repository at this point in the history
Use dictionaries + more
  • Loading branch information
denisidoro authored Sep 23, 2019
1 parent 2753e84 commit c4e9c7a
Show file tree
Hide file tree
Showing 16 changed files with 338 additions and 75 deletions.
3 changes: 3 additions & 0 deletions cheats/git.cheat
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,7 @@ git clean -dxf
# Sign all commits in a branch based on master
git rebase master -S -f

# See all open pull requests of a user on Github
url::open 'https://github.com/pulls?&q=author:<user>+is:open+is:pr'

$ branch: git branch | awk '{print $NF}'
3 changes: 2 additions & 1 deletion navi
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ source "${SCRIPT_DIR}/src/main.sh"
##? Please refer to the README at https://github.com/denisidoro/navi

VERSION="0.8.1"
opts::eval "$@"

OPTIONS="$(opts::eval "$@")"
export NAVI_PATH="$(dict::get "$OPTIONS" path)"
main "$@"
4 changes: 2 additions & 2 deletions scripts/install
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ set -euo pipefail
export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"

script() {
echo "#!/usr/bin/env bash"
echo "${SCRIPT_DIR}/navi" '"$@"'
echo "#!/usr/bin/env bash"
echo "${SCRIPT_DIR}/navi" '"$@"'
}

BIN="/usr/local/bin/navi"
Expand Down
4 changes: 4 additions & 0 deletions scripts/lint
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ set -euo pipefail

export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"

# please refer to https://github.com/denisidoro/dotfiles/blob/master/scripts/code/beautify

cd "${SCRIPT_DIR}"
find . -iname '*.sh' | xargs -I% dot code beautify %
find scripts/* | xargs -I% dot code beautify %
dot code beautify "${SCRIPT_DIR}/test/run"
dot code beautify "${SCRIPT_DIR}/navi"
24 changes: 12 additions & 12 deletions scripts/release
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "${SCRIPT_DIR}/src/main.sh"

sha256() {
if command_exists sha256sum; then
sha256sum
elif command_exists shasum; then
shasum -a 256
elif command_exists openssl; then
openssl dgst -sha256
else
echoerr "Unable to calculate sha256!"
exit 43
fi
if command_exists sha256sum; then
sha256sum
elif command_exists shasum; then
shasum -a 256
elif command_exists openssl; then
openssl dgst -sha256
else
echoerr "Unable to calculate sha256!"
exit 43
fi
}

header() {
echo "$*"
echo
echo "$*"
echo
}

cd "$SCRIPT_DIR"
Expand Down
30 changes: 22 additions & 8 deletions src/arg.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/usr/bin/env bash

ARG_REGEX="<[0-9a-zA-Z_]+>"
ARG_DELIMITER="£"

arg::fn() {
awk -F'---' '{print $1}'
}
arg::dict() {
local -r fn="$(awk -F'---' '{print $1}')"
local -r opts="$(awk -F'---' '{print $2}')"

arg::opts() {
awk -F'---' '{print $2}'
dict::new fn "$fn" opts "$opts"
}

arg::interpolate() {
Expand All @@ -19,21 +19,35 @@ arg::interpolate() {

arg::next() {
grep -Eo "$ARG_REGEX" \
| xargs \
| head -n1 \
| tr -d '<' \
| tr -d '>'
}

arg::deserialize() {
local -r arg="$1"

if [ ${arg:0:1} = "'" ]; then
local -r out="$(echo "${arg:1:${#arg}-2}")"
else
local -r out="$arg"
fi

echo "$out" | sed "s/${ARG_DELIMITER}/ /g"
}

# TODO: separation of concerns
arg::pick() {
local -r arg="$1"
local -r cheat="$2"

local -r prefix="$ ${arg}:"
local -r length="$(echo "$prefix" | str::length)"
local -r arg_description="$(grep "$prefix" "$cheat" | str::sub $((length + 1)))"
local -r arg_dict="$(grep "$prefix" "$cheat" | str::sub $((length + 1)) | arg::dict)"

local -r fn="$(echo "$arg_description" | arg::fn)"
local -r args_str="$(echo "$arg_description" | arg::opts | tr ' ' '\n' || echo "")"
local -r fn="$(dict::get "$arg_dict" fn)"
local -r args_str="$(dict::get "$arg_dict" opts | tr ' ' '\n' || echo "")"
local arg_name=""

for arg_str in $args_str; do
Expand Down
2 changes: 1 addition & 1 deletion src/cheat.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ cheat::from_selection() {
local -r cheats="$1"
local -r selection="$2"

local -r tags="$(echo "$selection" | selection::tags)"
local -r tags="$(dict::get "$selection" tags)"

for cheat in $cheats; do
if grep -q "% $tags" "$cheat"; then
Expand Down
110 changes: 110 additions & 0 deletions src/dict.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/env bash

DICT_DELIMITER='\f'

dict::_post() {
sed -E 's/; /\\n/g' | awk 'NF > 0' | dict::_unescape_value | sort
}

dict::new() {
if [ $# = 0 ]; then
echo ""
else
echo "" | dict::assoc "$@"
fi
}

dict::dissoc() {
local -r key="$1"

grep -Ev "^${key}[^:]*:" | dict::_post
}

dict::_escape_value() {
tr '\n' "$DICT_DELIMITER"
}

dict::_unescape_value() {
tr "$DICT_DELIMITER" '\n'
}

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
return
fi

if [ -n "$input" ]; then
local -r base="$(printf "$input" | dict::dissoc "$key"); "
else
local -r base=""
fi

shift 2
printf "${base}${key}: ${value}" | dict::_post | dict::assoc "$@" | dict::_post
}

dict::get() {
if [ $# = 1 ]; then
local -r input="$(cat)"
local -r key="$1"
else
local -r input="$1"
local -r key="$2"
fi

local -r prefix="${key}[^:]*: "
local -r result="$(echo "$input" | grep -E "^${prefix}")"
local -r matches="$(echo "$result" | wc -l || echo 0)"

if [ $matches -gt 1 ]; then
echo "$result" | dict::_unescape_value
else
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value
fi
}

dict::keys() {
grep -Eo '^[^:]+: ' | sed 's/: //g'
}

dict::values() {
awk -F':' '{$1=""; print $0}' | cut -c3-
}

dict::zipmap() {
IFS='\n'

local -r keys_str="$1"
local -r values_str="$2"

keys=()
values=()
for key in $keys_str; do
keys+=("$key")
done
for value in $values_str; do
values+=("$value")
done

for ((i=0; i<${#keys[@]}; ++i)); do
if [ -n "${keys[i]}" ]; then
echo "${keys[i]}: ${values[i]}"
fi
done
}

dict::update() {
local -r key="$1"
local -r fn="$2"
local -r input="$(cat)"

local -r value="$(echo "$input" | dict::get "$key")"
local -r updated_value="$(eval "$fn" "$value")"

echo "$input" | dict::assoc "$key" "$updated_value"
}
32 changes: 24 additions & 8 deletions src/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

source "${SCRIPT_DIR}/src/arg.sh"
source "${SCRIPT_DIR}/src/cheat.sh"
source "${SCRIPT_DIR}/src/dict.sh"
source "${SCRIPT_DIR}/src/health.sh"
source "${SCRIPT_DIR}/src/misc.sh"
source "${SCRIPT_DIR}/src/opts.sh"
Expand All @@ -14,8 +15,11 @@ handler::main() {
local -r cheats="$(cheat::find)"
local -r selection="$(ui::select "$cheats")"
local -r cheat="$(cheat::from_selection "$cheats" "$selection")"

[ -z "$cheat" ] && exit 67
local cmd="$(selection::command "$selection" "$cheat")"

local -r interpolation="$(dict::get "$OPTIONS" interpolation)"
local cmd="$(selection::cmd "$selection" "$cheat")"
local arg value

while $interpolation; do
Expand All @@ -36,6 +40,7 @@ handler::main() {

local -r unresolved_arg="$(echo "$cmd" | arg::next || echo "")"

local -r print="$(dict::get "$OPTIONS" print)"
if $print || [ -n "$unresolved_arg" ]; then
echo "$cmd"
else
Expand All @@ -44,26 +49,37 @@ handler::main() {
}

handler::preview() {
local -r selection="$(echo "$query" | selection::standardize)"
local -r query="$1"
local -r selection="$(echo "$query" | selection::dict)"
local -r cheats="$(cheat::find)"
local -r cheat="$(cheat::from_selection "$cheats" "$selection")"
[ -n "$cheat" ] && selection::command "$selection" "$cheat"
[ -n "$cheat" ] && selection::cmd "$selection" "$cheat"
}

handler::text() {
dict::get "$OPTIONS" text
ui::clear_previous_line
}

main() {
case ${entry_point:-} in
case "$(dict::get "$OPTIONS" entry_point)" in
preview)
handler::preview "$@" \
|| echo "Unable to find command for '${query:-}'"
local -r query="$(dict::get "$OPTIONS" query)"
handler::preview "$query" \
|| echo "Unable to find command for '$query'"
;;
search)
health::fzf
local -r query="$(dict::get "$OPTIONS" query)"
search::save "$query" || true
handler::main "$@"
handler::main
;;
text)
handler::text
;;
*)
health::fzf
handler::main "$@"
handler::main
;;
esac
}
12 changes: 12 additions & 0 deletions src/misc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,15 @@ command_exists() {
echoerr() {
echo "$@" 1>&2
}

url::open() {
if command_exists xdg-open; then
xdg-open "$@"
elif command_exists open; then
open "$@"
elif command_exists google-chrome; then
google-chrome "$@"
elif command_exists firefox; then
firefox "$@"
fi
}
Loading

0 comments on commit c4e9c7a

Please sign in to comment.