Skip to content

Commit

Permalink
Allow tasksh to process cmdline args
Browse files Browse the repository at this point in the history
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 GothenburgBitFactory#15
  • Loading branch information
ThomasAdam committed Jul 13, 2018
1 parent 908d2cc commit f865530
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 26 deletions.
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -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

Expand Down
5 changes: 4 additions & 1 deletion doc/man/tasksh.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
tasksh \- Interactive taskwarrior shell

.SH SYNOPSIS
.B tasksh
.B tasksh [task commands]...
.br
.B tasksh --version

Expand All @@ -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
Expand Down
83 changes: 59 additions & 24 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,20 @@ 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 ();

// 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";
Expand Down Expand Up @@ -138,52 +143,82 @@ static int commandLoop (bool autoClear)
return status;
}

static bool should_auto_clear()
{
bool autoClear = false;
std::string input;
std::string output;
execute ("task", {"_get", "rc.tasksh.autoclear"}, input, output);
output = lowerCase (output);
autoClear = (output == "true\n" ||
output == "1\n" ||
output == "y\n" ||
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;
}
else

if (isatty (fileno (stdin)))
welcome ();

// Process anything given as command-line arguments.
if (argc > 1)
{
try
{
// Get the Taskwarrior rc.tasksh.autoclear Boolean setting.
bool autoClear = false;
std::string input;
std::string output;
execute ("task", {"_get", "rc.tasksh.autoclear"}, input, output);
output = lowerCase (output);
autoClear = (output == "true\n" ||
output == "1\n" ||
output == "y\n" ||
output == "yes\n" ||
output == "on\n");

if (isatty (fileno (stdin)))
welcome ();

while ((status = commandLoop (autoClear)) == 0)
;
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;
}
}

catch (...)
try
{
while (status == 0)
{
std::cerr << "Unknown error." << "\n";
status = -2;
command = get_response ();
status = commandLoop (command, should_auto_clear ());
}
}

catch (const std::string& error)
{
std::cerr << error << "\n";
status = -1;
}

catch (...)
{
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.
return status == -1 ? 0 : status;
Expand Down

0 comments on commit f865530

Please sign in to comment.