Allow tasksh to process cmdline args

When invoking tasksh with command line arguments, it's useful to try and
process these via taskwarrior so that:

   tasksh pro:home list

would output the appropriate tasks before displaying the prompt.

To achieve this, refactor some of the setup calls to generate the
prompt, as well as refactoring the commandLoop.

Fixes GH issue #15
This commit is contained in:
Thomas Adam 2018-06-21 23:10:35 +01:00
parent 908d2cc38c
commit f8655302ef
3 changed files with 64 additions and 26 deletions

2
NEWS
View file

@ -1,7 +1,7 @@
New Features in tasksh 1.3.0
-
- tasksh passes command-line arguments through to taskwarrior.
New commands in tasksh 1.3.0

View file

@ -4,7 +4,7 @@
tasksh \- Interactive taskwarrior shell
.SH SYNOPSIS
.B tasksh
.B tasksh [task commands]...
.br
.B tasksh --version
@ -18,6 +18,9 @@ When built with libreadline, tasksh provides command editing and history.
Tasksh has an integrated 'review' command that leads you through an interactive
review session.
If Tasksh is invoked with command line arguments, those are passed straight
through to taskwarrior.
Tasksh supports all recent versions of Taskwarrior.
.SH COMMANDS

View file

@ -93,8 +93,7 @@ const std::string getResponse (const std::string& prompt)
return response;
}
////////////////////////////////////////////////////////////////////////////////
static int commandLoop (bool autoClear)
static const std::string get_response ()
{
// Compose the prompt.
auto prompt = promptCompose ();
@ -102,6 +101,12 @@ static int commandLoop (bool autoClear)
// Display prompt, get input.
auto command = getResponse (prompt);
return command;
}
////////////////////////////////////////////////////////////////////////////////
static int commandLoop (std::string command, bool autoClear)
{
// Obey Taskwarrior's rc.tasksh.autoclear.
if (autoClear)
std::cout << "\033[2J\033[0;0H";
@ -138,21 +143,8 @@ static int commandLoop (bool autoClear)
return status;
}
////////////////////////////////////////////////////////////////////////////////
int main (int argc, const char** argv)
static bool should_auto_clear()
{
int status = 0;
// Lightweight version checking that doesn't require initialization or any I/O.
if (argc == 2 && !strcmp (argv[1], "--version"))
{
std::cout << VERSION << "\n";
}
else
{
try
{
// Get the Taskwarrior rc.tasksh.autoclear Boolean setting.
bool autoClear = false;
std::string input;
std::string output;
@ -164,11 +156,55 @@ int main (int argc, const char** argv)
output == "yes\n" ||
output == "on\n");
return autoClear;
}
////////////////////////////////////////////////////////////////////////////////
int main (int argc, const char** argv)
{
std::string command = "";
int status = 0;
// Lightweight version checking that doesn't require initialization or any I/O.
if (argc == 2 && !strcmp (argv[1], "--version"))
{
std::cout << VERSION << "\n";
// Returning -1 drops out of the command loop, but gets translated to 0 here,
// so that there is a clean way to exit.
return status == -1 ? 0 : status;
}
if (isatty (fileno (stdin)))
welcome ();
while ((status = commandLoop (autoClear)) == 0)
;
// Process anything given as command-line arguments.
if (argc > 1)
{
try
{
std::string cmd;
for (int i = 1; i < argc; i++)
{
std::string cmd_str (argv[i]);
command += " " + cmd_str;
}
status = commandLoop (command, should_auto_clear ());
}
catch (const std::string& error)
{
std::cerr << error << "\n";
status = -1;
}
}
try
{
while (status == 0)
{
command = get_response ();
status = commandLoop (command, should_auto_clear ());
}
}
catch (const std::string& error)
@ -182,7 +218,6 @@ int main (int argc, const char** argv)
std::cerr << "Unknown error." << "\n";
status = -2;
}
}
// Returning -1 drops out of the command loop, but gets translated to 0 here,
// so that there is a clean way to exit.