Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ask, choose, confirm: comprehensive support of TTY modes and capabilities #254

Merged
merged 51 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
7f91040
choose, echo-wrap, read-key: support no-TTY
balupton Oct 1, 2024
2c1b508
WIP: choose, confirm, read-key: improve no-TTY support
balupton Oct 5, 2024
c7f31b1
bash.bash: add common helpers for performance
balupton Oct 9, 2024
ba73e79
read-key: rejig some lines for internal clarity
balupton Oct 9, 2024
2582cdf
confirm: rejig color and no-color rendering
balupton Oct 9, 2024
1dbdd43
brew: fix duplication in error messages and improve styling
balupton Oct 9, 2024
2fc7757
echo-wait: rejig some logic for clarity
balupton Oct 10, 2024
47f29cb
dorothy: add `__eval_wrap` helper for debug clarity
balupton Oct 10, 2024
b60ef24
dorothy: rejig clone and update to all support slug/branch/reference/…
balupton Oct 10, 2024
ee11038
fix mistakes in WIP commits
balupton Oct 10, 2024
7b9d99c
read-key: turns out the all key is ctrl+a
balupton Oct 10, 2024
c48e182
command-(missing|working): fix bad commit
balupton Oct 10, 2024
4098286
confirm, read-key: linting
balupton Oct 10, 2024
7a3236c
setup-environment-commands: improve performance
balupton Oct 10, 2024
4193b8e
dorothy: fix bad remote_name automation
balupton Oct 10, 2024
64c9cf6
bash.bash: add `has_needles` helper for performance
balupton Oct 10, 2024
6b7f98a
choose: auto-select solo required item for git-helper use case
balupton Oct 10, 2024
e15cab8
choose: try to fix choose prompt question title not showing on CI
balupton Oct 11, 2024
8a4583b
bash.bash: linting
balupton Oct 11, 2024
c71c557
is-tty: add proc and -p tests
balupton Oct 11, 2024
5def66e
WIP: removed `tty.bash` for `get-terminal-*` commands
balupton Oct 14, 2024
acee8c9
dorothy, symlink-helper: fix alpine symlink failures
balupton Oct 15, 2024
06a2cae
dorothy, fs-realpath: realpath on alpine doesn't support options
balupton Oct 15, 2024
369ff92
dorothy, fs-realpath: readlink on alpine doesn't support needed options
balupton Oct 15, 2024
99ac325
dorothy, fs-realpath: move alpine's implementation to fallback
balupton Oct 15, 2024
a9a57f5
dorothy, fs-realpath: detect when alpine uses busybox or coreutils an…
balupton Oct 15, 2024
41de4c2
dorothy: install coreutils installed on alpine, remove `ps` dependency
balupton Oct 15, 2024
fc24131
echo-file: fix bat usage, all: improve styling
balupton Oct 15, 2024
f62bebd
eval-helper: fix undefined columns
balupton Oct 15, 2024
5405c39
choose and read-key bugfixes
balupton Oct 15, 2024
b4ef3c8
bash.bash: add `__substr` shim, fix for `cpr` and `echo-style`
balupton Oct 16, 2024
383e36a
don't output screen buffer styles if not supported
balupton Oct 16, 2024
648843c
`get-terminal-(alternative|title)-support` fixed
balupton Oct 16, 2024
598918e
style.bash: clear screen if alt buffer not available
balupton Oct 16, 2024
cc483c3
styles: newline and clear if alt screen buffer not supported
balupton Oct 16, 2024
888b090
styles: newline, clear, alt screen buffer adjustments for CI
balupton Oct 16, 2024
d99a9a6
add `dorothy-warnings`, a deprecation system
balupton Oct 23, 2024
a37639d
consistentcy for commands.deprecated
balupton Oct 17, 2024
a3ba02f
debug-network: add comment to avoid https://github.com/bevry/dorothy/…
balupton Oct 17, 2024
e8a0640
readme: list @balupton's github list of Dorothy User Configurations
balupton Oct 17, 2024
713322d
echo-clear-lines: prep for improvements
balupton Oct 17, 2024
8324b75
improvements to clearing, and resolve setup-util(-bash) edge case
balupton Oct 17, 2024
52958a2
shellcheck: ignore SC2016, it is always intentional
balupton Oct 21, 2024
099bb6b
ask/choose/confirm: complete no-TTY support
balupton Oct 23, 2024
0dfebda
ask/choose/confirm: fix broken tests, although `ask` test has a clear…
balupton Oct 23, 2024
613cec8
improvements to TTY and STDIN reporting
balupton Oct 25, 2024
d605711
ask: rewrote for new stdin/tty learnings, properly support no-TTY
balupton Oct 25, 2024
d2b29cb
use the correct quote/escape for the context
balupton Oct 25, 2024
36e8c75
Merge branch 'master' into dev/fix-253
balupton Oct 25, 2024
1c7b588
brew-installed: fix comment typos
balupton Oct 26, 2024
4f66b71
re-add `--needle=` prefix on needle option on `is-needle` calls, to p…
balupton Oct 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ask/choose/confirm: fix broken tests, although ask test has a clear…
…ing issue when testing

get-terminal-position-support: fix crash when stdin not accessible

get-terminal-tty-support: expand debug information to look for ways to ensure ask is only clearing input if it needed to

is-interactive: simplify conditional logic

read-key, is-shapeshifter: add (ctrl|alt)+(left|right) macos keys

dorothy, dorothy-warnings: only output warnings by default if there are new warnings
  • Loading branch information
balupton committed Oct 24, 2024
commit 0dfebda5e6b4ea2e1a9bb74b71fceefb4de36257
4 changes: 4 additions & 0 deletions commands.beta/is-shapeshifter
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ function is_shapeshifter_test() (
$'\e[2~' # insert
$'\e[3~' # delete
$'\e[5~' # page-up
$'\e[1;5D' # page-up
$'\eb' # page-up
$'\e[6~' # page-down
$'\e[1;5C' # page-down
$'\ef' # page-down
$'\177' # backspace
$'\b' # backspace
# $'\n' # enter <-- don't do enter, as that is normal
Expand Down
6 changes: 4 additions & 2 deletions commands/ask
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ function ask_test() (
eval-tester --name='receive default response by timeout and no input' --stdout='a default response' \
-- ask --skip-default --question='What is your response?' --default='a default response'

local down=$'\e[B'

{
sleep 3
__print_line
Expand Down Expand Up @@ -51,7 +53,7 @@ function ask_test() (

# move down and change to custom response
sleep 3
printf $'\eOB'
__print_string "$down"
sleep 3
__print_line

Expand Down Expand Up @@ -289,7 +291,7 @@ function ask_() (
# treat empty string and newline as default
:
elif [[ $__input_result =~ ^[[:cntrl:][:space:]]*$ ]]; then
# if it is only control characters, e.g. escape, and whitespace characters, then treat as empty
# if it is only control characters (e.g. escape) and whitespace characters, then treat as empty
RESULT=''
else
# treat everything else as manual __input_result
Expand Down
45 changes: 25 additions & 20 deletions commands/choose
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ function choose_test() (

local up=$'\e[A' down=$'\e[B' right=$'\e[C' left=$'\e[D' home=$'\e[H' end=$'\e[F' insert=$'\e[2~' delete=$'\e[3~' page_up=$'\e[5~' page_down=$'\e[6~' backspace=$'\177' escape=$'\e' tab=$'\t' backtab=$'\e[Z' all=$'\x01' # enter=$'\x0a' space=' '

local \
timeout_optional='[ timed out: not required ]' \
timeout_required='[ input failure: timed out: required ]' \
timeout_defaults='[ timed out: used default ]'

# TESTS WITHOUT INTERACTION
# as we are checking stderr, do not use color for these tests, as gets too complicated

Expand All @@ -29,66 +34,66 @@ function choose_test() (
-- env COLOR=no choose 'q' 'd' --multi --index --skip-default --default=b --default=c -- a b c

# timeout optional
eval-tester --name='receive no response by timeout with no input and optional' --stderr='q [timed out: not required]' \
eval-tester --name='receive no response by timeout with no input and optional' --stderr="q $timeout_optional" \
-- env COLOR=no choose 'q' 'd' --timeout=5 -- a b c

eval-tester --name='receive no --index response by timeout with no input and optional' --stderr='q [timed out: not required]' \
eval-tester --name='receive no --index response by timeout with no input and optional' --stderr="q $timeout_optional" \
-- env COLOR=no choose 'q' 'd' --index --timeout=5 -- a b c

# timeout required
eval-tester --name='receive timeout response by timeout with no input and reqyured' --status='60' --stderr='q [input failure: timed out: required]' \
eval-tester --name='receive timeout response by timeout with no input and reqyured' --status='60' --stderr="q $timeout_required" \
-- env COLOR=no choose 'q' 'd' --required --timeout=5 -- a b c

eval-tester --name='receive timeout --index response by timeout with no input and reqyured' --status='60' --stderr='q [input failure: timed out: required]' \
eval-tester --name='receive timeout --index response by timeout with no input and reqyured' --status='60' --stderr="q $timeout_required" \
-- env COLOR=no choose 'q' 'd' --index --required --timeout=5 -- a b c

# single mode, single defalut
eval-tester --name='receive default response by timeout with no input and optional' --stdout=b --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default response by timeout with no input and optional' --stdout=b --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --timeout=5 --default=b -- a b c

eval-tester --name='receive default --index response by timeout with no input and optional' --stdout=1 --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default --index response by timeout with no input and optional' --stdout=1 --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --index --timeout=5 --default=b -- a b c

eval-tester --name='receive default response by timeout with no input and required' --stdout=b --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default response by timeout with no input and required' --stdout=b --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --timeout=5 --default=b --required -- a b c

eval-tester --name='receive default --index response by timeout with no input and required' --stdout=1 --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default --index response by timeout with no input and required' --stdout=1 --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --index --timeout=5 --default=b --required -- a b c

# single mode, so only the first match is selected
eval-tester --name='receive default first response by timeout with no input and optional' --stdout=b --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default first response by timeout with no input and optional' --stdout=b --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --timeout=5 --default-fuzzy=b -- a b bb c

eval-tester --name='receive default first --index response by timeout with no input and optional' --stdout=1 --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default first --index response by timeout with no input and optional' --stdout=1 --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --index --timeout=5 --default-fuzzy=b -- a b bb c

eval-tester --name='receive default first response by timeout with no input and required' --stdout=b --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default first response by timeout with no input and required' --stdout=b --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --timeout=5 --default-fuzzy=b --required -- a b bb c

eval-tester --name='receive default first --index response by timeout with no input and required' --stdout=1 --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default first --index response by timeout with no input and required' --stdout=1 --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --index --timeout=5 --default-fuzzy=b --required -- a b bb c

# multi mode
eval-tester --name='receive default responses by timeout with no input and multi and optional' --stdout=$'b\nbb' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default responses by timeout with no input and multi and optional' --stdout=$'b\nbb' --stderr="q $timeout_defaults" \
-- env COLOR=no choose --multi 'q' 'd' --timeout=5 --default-fuzzy=b -- a b bb c

eval-tester --name='receive default --index responses by timeout with no input and multi and optional' --stdout=$'1\n2' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default --index responses by timeout with no input and multi and optional' --stdout=$'1\n2' --stderr="q $timeout_defaults" \
-- env COLOR=no choose --multi 'q' 'd' --index --timeout=5 --default-fuzzy=b -- a b bb c

eval-tester --name='receive default responses by timeout with no input and multi and required' --stdout=$'b\nbb' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default responses by timeout with no input and multi and required' --stdout=$'b\nbb' --stderr="q $timeout_defaults" \
-- env COLOR=no choose --multi 'q' 'd' --timeout=5 --default-fuzzy=b --required -- a b bb c

eval-tester --name='receive default --index responses by timeout with no input and multi and required' --stdout=$'1\n2' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive default --index responses by timeout with no input and multi and required' --stdout=$'1\n2' --stderr="q $timeout_defaults" \
-- env COLOR=no choose --multi 'q' 'd' --index --timeout=5 --default-fuzzy=b --required -- a b bb c

# multiline defaults
eval-tester --name='receive multi-line default first response by timeout with no input' --stdout=$'b\nB' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive multi-line default first response by timeout with no input' --stdout=$'b\nB' --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --timeout=2 --default=$'b\nB' --defaults=$'c\nd' -- a $'b\nB' c d
eval-tester --name='receive multi-line default first --index response by timeout with no input' --stdout=1 --stderr='q [timed out: using defaults]' \
eval-tester --name='receive multi-line default first --index response by timeout with no input' --stdout=1 --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --index --timeout=2 --default=$'b\nB' --defaults=$'c\nd' -- a $'b\nB' c d
eval-tester --name='receive multi-line default responses by timeout with no input' --stdout=$'b\nB\nc\nd' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive multi-line default responses by timeout with no input' --stdout=$'b\nB\nc\nd' --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --multi --timeout=2 --default=$'b\nB' --defaults=$'c\nd' -- a $'b\nB' c d
eval-tester --name='receive multi-line default responses by timeout with no input' --stdout=$'1\n2\n3' --stderr='q [timed out: using defaults]' \
eval-tester --name='receive multi-line default responses by timeout with no input' --stdout=$'1\n2\n3' --stderr="q $timeout_defaults" \
-- env COLOR=no choose 'q' 'd' --multi --index --timeout=2 --default=$'b\nB' --defaults=$'c\nd' -- a $'b\nB' c d

# TESTS WITH INTERACTION
Expand Down
4 changes: 3 additions & 1 deletion commands/confirm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ function confirm_test() (

# --ignore-stderr otherwise only \n^[[68;1R is output

local escape=$'\e'

{
sleep 3
__print_line
Expand Down Expand Up @@ -53,7 +55,7 @@ function confirm_test() (
{
# press escape key
sleep 3
printf $'\x1b'
__print_string "$escape"
} | eval-tester --name='receive abort response by escape key' --status=125 --ignore-stderr \
-- confirm --ppid=-1 --bool --timeout=5 -- 'What is your response?'

Expand Down
4 changes: 2 additions & 2 deletions commands/dorothy
Original file line number Diff line number Diff line change
Expand Up @@ -1987,8 +1987,8 @@ function dorothy_() (
done

# check for warnings
if dorothy-warnings --check; then
dorothy-warnings
if dorothy-warnings check; then
dorothy-warnings list
failures+=('dorothy-warnings')
fi

Expand Down
24 changes: 17 additions & 7 deletions commands/dorothy-warnings
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ function dorothy_warnings() (
Returns [0] always.

--warn | warn
Output the warnings file with appropropriate messaging, only if there are new warnings from last time.
Returns [0] always.
This is the default action.

--list | list
Output the warnings file with appropropriate messaging.
Returns [0] always.
This is the default action.
Expand All @@ -45,6 +50,7 @@ function dorothy_warnings() (
'--check' | 'check' | '--exists' | 'exists') action='check' ;;
'--clear' | 'clear' | '--remove' | 'remove' | '--reset' | 'reset') action='clear' ;;
'--warn' | 'warn') action='warn' ;;
'--list' | 'list') action='warn' ;;
'--add' | 'add')
action='add'
option_args+=("$@")
Expand All @@ -59,19 +65,22 @@ function dorothy_warnings() (
# Act

function dorothy_warnings_check {
test -s "$DOROTHY/state/warnings.txt"
[[ -s "$DOROTHY/state/warnings.txt" ]]
return
}
function dorothy_warnings_clear {
: >"$DOROTHY/state/warnings.txt"
}
function dorothy_warnings_list {
echo-style --stderr \
--notice1='Dorothy has encountered warnings:' --newline \
--="$(echo-file -- "$DOROTHY/state/warnings.txt")" --newline \
--notice1='For help with these warnings, see: ' --code-notice1='https://github.com/bevry/dorothy/issues/185' --newline \
--notice1='To clear these warnings, run: ' --code-notice1='dorothy-warnings clear'
}
function dorothy_warnings_warn {
if test -s "$DOROTHY/state/warnings.txt"; then
echo-style --stderr \
--notice1='Dorothy has encountered warnings:' --newline \
--="$(echo-file -- "$DOROTHY/state/warnings.txt")" --newline \
--notice1='For help with these warnings, see: ' --code-notice1='https://github.com/bevry/dorothy/issues/185' --newline \
--notice1='To clear these warnings, run: ' --code-notice1='dorothy-warnings clear'
if [[ -N "$DOROTHY/state/warnings.txt" ]]; then
dorothy_warnings_list
fi
}
function dorothy_warnings_add {
Expand All @@ -82,6 +91,7 @@ function dorothy_warnings() (
'check') dorothy_warnings_check ;;
'clear') dorothy_warnings_clear ;;
'warn') dorothy_warnings_warn ;;
'list') dorothy_warnings_warn ;;
'add') dorothy_warnings_add ;;
*) help "An unrecognised action was provided: $action" ;;
esac
Expand Down
2 changes: 1 addition & 1 deletion commands/get-terminal-position-support
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function get_terminal_position_support() (
# shorter timeouts aren't suitable as slower machines take a while for the response
# the read will complete immediately upon a response thanks to [-d R] which completes reading when the R is read, which is the final character of the response
local _ line column
IFS='[;' read -t 2 -srd R -p $'\e[6n' _ line column <"$option_device_file"
IFS='[;' read -t 2 -srd R -p $'\e[6n' _ line column 2>/dev/null <"$option_device_file" || :
if test "$option_quiet" = 'yes'; then
if test -n "${line-}" -a -n "${column-}"; then
return 0
Expand Down
Loading
Loading