mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Enhancement - better confirmation
- Added feature to allow the user to quit when asked to confirm multiple changes. Now task asks "Proceed with change? (Yes/no/all/quit)".
This commit is contained in:
parent
549e700bc8
commit
d44e9363f0
8 changed files with 72 additions and 23 deletions
|
@ -3,6 +3,8 @@
|
|||
|
||||
1.8.5 ()
|
||||
+ Fixed bug that was causing the 'completed' report to sort incorrectly.
|
||||
+ Added feature to allow the user to quit when asked to confirm multiple
|
||||
changes. Now task asks "Proceed with change? (Yes/no/all/quit)".
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ extern Context context;
|
|||
Permission::Permission ()
|
||||
: needConfirmation (false)
|
||||
, allConfirmed (false)
|
||||
, quit (false)
|
||||
{
|
||||
// Turning confirmations off is the same as entering "all".
|
||||
if (context.config.get ("confirmation", true) == false)
|
||||
|
@ -46,6 +47,9 @@ Permission::Permission ()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Permission::confirmed (const Task& task, const std::string& question)
|
||||
{
|
||||
if (quit)
|
||||
return false;
|
||||
|
||||
if (!needConfirmation)
|
||||
return true;
|
||||
|
||||
|
@ -67,13 +71,15 @@ bool Permission::confirmed (const Task& task, const std::string& question)
|
|||
|
||||
std::cout << std::endl;
|
||||
|
||||
int answer = confirm3 (question);
|
||||
int answer = confirm4 (question);
|
||||
if (answer == 2)
|
||||
allConfirmed = true;
|
||||
|
||||
if (answer > 0)
|
||||
if (answer == 1 || answer == 2)
|
||||
return true;
|
||||
|
||||
if (answer == 3)
|
||||
quit = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
private:
|
||||
bool needConfirmation;
|
||||
bool allConfirmed;
|
||||
bool quit;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -829,7 +829,7 @@ int handleDone (std::string &outs)
|
|||
|
||||
if (taskDiff (before, *task))
|
||||
{
|
||||
if (permission.confirmed (before, taskDifferences (before, *task) + "Are you sure?"))
|
||||
if (permission.confirmed (before, taskDifferences (before, *task) + "Proceed with change?"))
|
||||
{
|
||||
context.tdb.update (*task);
|
||||
|
||||
|
@ -983,7 +983,7 @@ int handleModify (std::string &outs)
|
|||
|
||||
if (taskDiff (before, *other))
|
||||
{
|
||||
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Are you sure?"))
|
||||
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?"))
|
||||
{
|
||||
context.tdb.update (*other);
|
||||
++count;
|
||||
|
@ -1043,7 +1043,7 @@ int handleAppend (std::string &outs)
|
|||
|
||||
if (taskDiff (before, *other))
|
||||
{
|
||||
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Are you sure?"))
|
||||
if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?"))
|
||||
{
|
||||
context.tdb.update (*other);
|
||||
|
||||
|
@ -1335,7 +1335,7 @@ int handleAnnotate (std::string &outs)
|
|||
|
||||
if (taskDiff (before, *task))
|
||||
{
|
||||
if (permission.confirmed (before, taskDifferences (before, *task) + "Are you sure?"))
|
||||
if (permission.confirmed (before, taskDifferences (before, *task) + "Proceed with change?"))
|
||||
{
|
||||
context.tdb.update (*task);
|
||||
|
||||
|
|
|
@ -49,10 +49,10 @@ if (open my $fh, '>', 'response.txt')
|
|||
|
||||
qx{../task rc:confirm.rc add foo} for 1 .. 10;
|
||||
|
||||
# Test the various forms of "yes".
|
||||
my $output = qx{echo "yes" | ../task rc:confirm.rc del 1};
|
||||
like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - yes works');
|
||||
unlike ($output, qr/Task not deleted\./, 'confirmation - yes works');
|
||||
# Test the various forms of "Yes".
|
||||
my $output = qx{echo "Yes" | ../task rc:confirm.rc del 1};
|
||||
like ($output, qr/Permanently delete task 1 'foo'\? \(y\/n\)/, 'confirmation - Yes works');
|
||||
unlike ($output, qr/Task not deleted\./, 'confirmation - Yes works');
|
||||
|
||||
$output = qx{echo "ye" | ../task rc:confirm.rc del 2};
|
||||
like ($output, qr/Permanently delete task 2 'foo'\? \(y\/n\)/, 'confirmation - ye works');
|
||||
|
|
|
@ -38,6 +38,7 @@ int main (int argc, char** argv)
|
|||
|
||||
// TODO bool confirm (const std::string&);
|
||||
// TODO int confirm3 (const std::string&);
|
||||
// TODO int confirm4 (const std::string&);
|
||||
// TODO void delay (float);
|
||||
// TODO std::string formatSeconds (time_t);
|
||||
// TODO std::string formatSecondsCompact (time_t);
|
||||
|
@ -84,14 +85,14 @@ int main (int argc, char** argv)
|
|||
|
||||
std::string output = taskDifferences (left, right);
|
||||
t.ok (taskDiff (left, right), "Detected changes");
|
||||
t.ok (output.find ("zero was changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00");
|
||||
t.ok (output.find ("one was deleted") != std::string::npos, "Detected deletion one:1 ->");
|
||||
t.ok (output.find ("zero will be changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00");
|
||||
t.ok (output.find ("one will be deleted") != std::string::npos, "Detected deletion one:1 ->");
|
||||
t.ok (output.find ("two") == std::string::npos, "Detected no change two:2 -> two:2");
|
||||
t.ok (output.find ("three was set to '3'") != std::string::npos, "Detected addition -> three:3");
|
||||
t.ok (output.find ("three will be set to '3'") != std::string::npos, "Detected addition -> three:3");
|
||||
|
||||
t.notok (taskDiff (right, rightAgain), "No changes detected");
|
||||
output = taskDifferences (right, rightAgain);
|
||||
t.ok (output.find ("No changes were made") != std::string::npos, "No changes detected");
|
||||
t.ok (output.find ("No changes will be made") != std::string::npos, "No changes detected");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
50
src/util.cpp
50
src/util.cpp
|
@ -82,7 +82,7 @@ bool confirm (const std::string& question)
|
|||
int confirm3 (const std::string& question)
|
||||
{
|
||||
std::vector <std::string> options;
|
||||
options.push_back ("yes");
|
||||
options.push_back ("Yes");
|
||||
options.push_back ("no");
|
||||
options.push_back ("all");
|
||||
|
||||
|
@ -104,11 +104,49 @@ int confirm3 (const std::string& question)
|
|||
}
|
||||
while (matches.size () != 1);
|
||||
|
||||
if (matches[0] == "yes") return 1;
|
||||
if (matches[0] == "Yes") return 1;
|
||||
else if (matches[0] == "all") return 2;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 0 = no
|
||||
// 1 = yes
|
||||
// 2 = all
|
||||
// 3 = quit
|
||||
int confirm4 (const std::string& question)
|
||||
{
|
||||
std::vector <std::string> options;
|
||||
options.push_back ("Yes");
|
||||
options.push_back ("no");
|
||||
options.push_back ("all");
|
||||
options.push_back ("quit");
|
||||
|
||||
std::string answer;
|
||||
std::vector <std::string> matches;
|
||||
|
||||
do
|
||||
{
|
||||
std::cout << question
|
||||
<< " ("
|
||||
<< options[0] << "/"
|
||||
<< options[1] << "/"
|
||||
<< options[2] << "/"
|
||||
<< options[3]
|
||||
<< ") ";
|
||||
|
||||
std::getline (std::cin, answer);
|
||||
answer = trim (answer);
|
||||
autoComplete (answer, options, matches);
|
||||
}
|
||||
while (matches.size () != 1);
|
||||
|
||||
if (matches[0] == "Yes") return 1;
|
||||
else if (matches[0] == "all") return 2;
|
||||
else if (matches[0] == "quit") return 3;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void delay (float f)
|
||||
{
|
||||
|
@ -500,12 +538,12 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||
foreach (name, beforeOnly)
|
||||
out << " - "
|
||||
<< *name
|
||||
<< " was deleted\n";
|
||||
<< " will be deleted\n";
|
||||
|
||||
foreach (name, afterOnly)
|
||||
out << " - "
|
||||
<< *name
|
||||
<< " was set to '"
|
||||
<< " will be set to '"
|
||||
<< renderAttribute (*name, after.get (*name))
|
||||
<< "'\n";
|
||||
|
||||
|
@ -515,7 +553,7 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||
before.get (*name) != after.get (*name))
|
||||
out << " - "
|
||||
<< *name
|
||||
<< " was changed from '"
|
||||
<< " will be changed from '"
|
||||
<< renderAttribute (*name, before.get (*name))
|
||||
<< "' to '"
|
||||
<< renderAttribute (*name, after.get (*name))
|
||||
|
@ -523,7 +561,7 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||
|
||||
// Shouldn't just say nothing.
|
||||
if (out.str ().length () == 0)
|
||||
out << " - No changes were made\n";
|
||||
out << " - No changes will be made\n";
|
||||
|
||||
return out.str ();
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ for (typeof (c) *foreach_p = & (c); \
|
|||
// util.cpp
|
||||
bool confirm (const std::string&);
|
||||
int confirm3 (const std::string&);
|
||||
int confirm4 (const std::string&);
|
||||
void delay (float);
|
||||
std::string formatSeconds (time_t);
|
||||
std::string formatSecondsCompact (time_t);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue