Skip to content

Commit ee94a3f

Browse files
authored
Return from user prompt without requiring Enter (#354)
* Tests: Add coverage for del / move without -f, but with prompting Supplying the user confirmation via "yes". * Cosmetics: Align inconsistent spacing for before (y/n) prompt * Refactoring: Extract confirm() function The user confirmation query had been duplicated (once) in the code. * Refactoring: confirm(): Leave early if forced * Return from user prompt without requiring Enter By just reading a single character (y for yes, anything else: no). * Tests: Ensure that only a single "y" concludes the confirmation By switching from "yes" (that endlessly prints newline-separated "y"s) to "printf y". * t1800-del: Add coverage for negative confirmation Negative means "anything but y", so "n", "x", and Enter all apply. * Cosmetics: Add trailing space after (y/n) prompt So that the user's typed answer is not recorded directly after it, but with separation: "Foo? (y/n) y" instead of "Foo? (y/n)y". *Compatibility: "read -N 1" is only available in Bash 4.1+ Mac OS still ships with Bash 3.2 :-( Fall back to the original prompting that requires conclusion via Enter then. Note: Even though the tests use "printf y", this still gets accepted, as there'll be EOF after that. In real use (when stdin from the terminal stays open), a concluding Enter is mandatory, though. Closes #152
1 parent 587833b commit ee94a3f

File tree

3 files changed

+91
-14
lines changed

3 files changed

+91
-14
lines changed

tests/t1800-del.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ test_description='basic del functionality
44
'
55
. ./test-lib.sh
66

7+
SPACE=' '
8+
79
test_todo_session 'del usage' <<EOF
810
>>> todo.sh del B
911
usage: todo.sh del ITEM# [TERM]
@@ -44,6 +46,50 @@ TODO: 1 deleted.
4446
TODO: 2 of 2 tasks shown
4547
EOF
4648

49+
cat > todo.txt <<EOF
50+
(B) smell the uppercase Roses +flowers @outside
51+
(A) notice the sunflowers
52+
stop
53+
EOF
54+
test_todo_session 'del with confirmation' <<EOF
55+
>>> todo.sh -p list
56+
2 (A) notice the sunflowers
57+
1 (B) smell the uppercase Roses +flowers @outside
58+
3 stop
59+
--
60+
TODO: 3 of 3 tasks shown
61+
62+
>>> printf n | todo.sh del 1
63+
Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE
64+
TODO: No tasks were deleted.
65+
66+
>>> todo.sh -p list
67+
2 (A) notice the sunflowers
68+
1 (B) smell the uppercase Roses +flowers @outside
69+
3 stop
70+
--
71+
TODO: 3 of 3 tasks shown
72+
73+
>>> printf x | todo.sh del 1
74+
Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE
75+
TODO: No tasks were deleted.
76+
77+
>>> echo | todo.sh del 1
78+
Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE
79+
TODO: No tasks were deleted.
80+
81+
>>> printf y | todo.sh del 1
82+
Delete '(B) smell the uppercase Roses +flowers @outside'? (y/n)$SPACE
83+
1 (B) smell the uppercase Roses +flowers @outside
84+
TODO: 1 deleted.
85+
86+
>>> todo.sh -p list
87+
2 (A) notice the sunflowers
88+
3 stop
89+
--
90+
TODO: 2 of 2 tasks shown
91+
EOF
92+
4793
cat > todo.txt <<EOF
4894
(B) smell the uppercase Roses +flowers @outside
4995
(A) notice the sunflowers

tests/t1850-move.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ test_description='basic move functionality
55
'
66
. ./test-lib.sh
77

8+
SPACE=' '
9+
810
cat > todo.txt <<EOF
911
(B) smell the uppercase Roses +flowers @outside
1012
(A) notice the sunflowers
@@ -31,6 +33,33 @@ TODO: 1 of 1 tasks shown
3133
DONE: 3 of 3 tasks shown
3234
EOF
3335

36+
cat > todo.txt <<EOF
37+
(B) smell the uppercase Roses +flowers @outside
38+
(A) notice the sunflowers
39+
EOF
40+
cat > done.txt <<EOF
41+
x 2009-02-13 make the coffee +wakeup
42+
x 2009-02-13 smell the coffee +wakeup
43+
EOF
44+
test_todo_session 'basic move with confirmation' <<EOF
45+
>>> printf y | todo.sh move 1 done.txt 2>&1 | sed -e "s#'[^']\{1,\}/\([^/']\{1,\}\)'#'\1'#g" -e 's#from .\{1,\}/\([^/]\{1,\}\) to .\{1,\}/\([^/]\{1,\}\)?#from \1 to \2?#g'
46+
Move '(B) smell the uppercase Roses +flowers @outside' from todo.txt to done.txt? (y/n)$SPACE
47+
1 (B) smell the uppercase Roses +flowers @outside
48+
TODO: 1 moved from 'todo.txt' to 'done.txt'.
49+
50+
>>> todo.sh -p ls
51+
2 (A) notice the sunflowers
52+
--
53+
TODO: 1 of 1 tasks shown
54+
55+
>>> todo.sh -p listfile done.txt
56+
3 (B) smell the uppercase Roses +flowers @outside
57+
1 x 2009-02-13 make the coffee +wakeup
58+
2 x 2009-02-13 smell the coffee +wakeup
59+
--
60+
DONE: 3 of 3 tasks shown
61+
EOF
62+
3463
test_todo_session 'basic move with passed source' <<EOF
3564
>>> todo.sh -f move 2 todo.txt done.txt | sed "s#'[^']\{1,\}/\([^/']\{1,\}\)'#'\1'#g"
3665
2 x 2009-02-13 smell the coffee +wakeup

todo.sh

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,20 @@ die()
362362
exit 1
363363
}
364364

365+
confirm()
366+
{
367+
[ $TODOTXT_FORCE = 0 ] || return 0
368+
369+
printf %s "${1:?}? (y/n) "
370+
local readArgs=(-e -r)
371+
[ -n "${BASH_VERSINFO:-}" ] && [ \( ${BASH_VERSINFO[0]} -eq 4 -a ${BASH_VERSINFO[1]} -ge 1 \) -o ${BASH_VERSINFO[0]} -gt 4 ] &&
372+
readArgs+=(-N 1) # Bash 4.1+ supports -N nchars
373+
local answer
374+
read "${readArgs[@]}" answer
375+
echo
376+
[ "$answer" = "y" ]
377+
}
378+
365379
cleaninput()
366380
{
367381
# Parameters: When $1 = "for sed", performs additional escaping for use
@@ -1146,13 +1160,7 @@ case $action in
11461160
getTodo "$item"
11471161

11481162
if [ -z "$3" ]; then
1149-
if [ $TODOTXT_FORCE = 0 ]; then
1150-
echo "Delete '$todo'? (y/n)"
1151-
read -e -r ANSWER
1152-
else
1153-
ANSWER="y"
1154-
fi
1155-
if [ "$ANSWER" = "y" ]; then
1163+
if confirm "Delete '$todo'"; then
11561164
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
11571165
# delete line (changes line numbers)
11581166
sed -i.bak -e "${item}s/^.*//" -e '/./!d' "$TODO_FILE"
@@ -1342,13 +1350,7 @@ case $action in
13421350

13431351
getTodo "$item" "$src"
13441352
[ -z "$todo" ] && die "$item: No such item in $src."
1345-
if [ $TODOTXT_FORCE = 0 ]; then
1346-
echo "Move '$todo' from $src to $dest? (y/n)"
1347-
read -e -r ANSWER
1348-
else
1349-
ANSWER="y"
1350-
fi
1351-
if [ "$ANSWER" = "y" ]; then
1353+
if confirm "Move '$todo' from $src to $dest"; then
13521354
if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
13531355
# delete line (changes line numbers)
13541356
sed -i.bak -e "${item}s/^.*//" -e '/./!d' "$src"

0 commit comments

Comments
 (0)