diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 42efd70..b3bdf07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,8 @@ include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src ${TASKSH_INCLUDE_DIRS}) -set (tasksh_SRCS diag.cpp +set (tasksh_SRCS context.cpp + diag.cpp help.cpp prompt.cpp Color.cpp Color.h diff --git a/src/context.cpp b/src/context.cpp new file mode 100644 index 0000000..98d6ce5 --- /dev/null +++ b/src/context.cpp @@ -0,0 +1,89 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// http://www.opensource.org/licenses/mit-license.php +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include // TODO Remove. +#include +#include +#include + +static const char* contextColors[] = +{ + "bold white on red", + "bold white on blue", + "bold white on green", + "bold white on magenta", + "black on cyan", + "black on yellow", + "black on white", +}; + +#define NUM_COLORS (sizeof contextColors) + +//////////////////////////////////////////////////////////////////////////////// +int cmdClear (std::vector & contexts) +{ + contexts.clear (); + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +int cmdLeave (std::vector & contexts) +{ + if (contexts.size ()) + contexts.pop_back (); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +int cmdContext ( + const std::vector & args, + std::vector & contexts) +{ + // TODO Verify context not already in use. + if (args.size () > 1) + contexts.push_back (args[1]); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string composeContexts ( + std::vector & contexts, + bool pretty /* = false */) +{ + std::string combined; + for (int i = 0; i < contexts.size (); ++i) + combined += (i ? " " : "") + + (pretty + ? Color::colorize (" " + contexts[i] + " ", contextColors[i % NUM_COLORS]) + : contexts[i]); + + return combined; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/diag.cpp b/src/diag.cpp index 4c5d234..ede0a77 100644 --- a/src/diag.cpp +++ b/src/diag.cpp @@ -40,7 +40,7 @@ #endif //////////////////////////////////////////////////////////////////////////////// -int cmdDiagnostics () +int cmdDiagnostics (const std::vector & args) { // TODO Version // TODO Platform diff --git a/src/help.cpp b/src/help.cpp index 4e4bb42..c7a3024 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -31,11 +31,9 @@ #include //////////////////////////////////////////////////////////////////////////////// -int cmdHelp () +int cmdHelp (const std::vector & args) { - // TODO This needs some work. - std::cout << "tasksh help\n"; - + std::cout << "Run 'man tasksh' for help.\n"; return 0; } diff --git a/src/main.cpp b/src/main.cpp index 17e2325..15610f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -42,18 +43,20 @@ // a 'task' prefix could disambiguate. // tasksh commands. -int cmdHelp (); -int cmdDiagnostics (); -std::string composePrompt (); +int cmdHelp (const std::vector &); +int cmdDiagnostics (const std::vector &); +int cmdContext (const std::vector &, std::vector &); +int cmdClear (std::vector &); +int cmdLeave (std::vector &); +std::string composePrompt (std::vector &); +std::string composeContexts (std::vector &, bool pretty = false); std::string findTaskwarrior (); //////////////////////////////////////////////////////////////////////////////// -static int commandLoop () +static int commandLoop (std::vector & contexts) { - // TODO Local data: timer, context stack. No globals. - // Compose the prompt. - std::string prompt = composePrompt (); + std::string prompt = composePrompt (contexts); // Display prompt, get input. #ifdef HAVE_READLINE @@ -81,16 +84,22 @@ static int commandLoop () } #endif + std::vector args; + split (args, command, ' '); + // Dispatch command int status = 0; - if (closeEnough ("exit", command, 3)) status = -1; - else if (closeEnough ("quit", command, 3)) status = -1; - else if (closeEnough ("help", command, 3)) status = cmdHelp (); - else if (closeEnough ("diagnostics", command, 3)) status = cmdDiagnostics (); + if (closeEnough ("exit", args[0], 3)) status = -1; + else if (closeEnough ("quit", args[0], 3)) status = -1; + else if (closeEnough ("help", args[0], 3)) status = cmdHelp (args ); + else if (closeEnough ("diagnostics", args[0], 3)) status = cmdDiagnostics (args ); + else if (closeEnough ("context", args[0], 3)) status = cmdContext (args, contexts); + else if (closeEnough ("clear", args[0], 3)) status = cmdClear ( contexts); + else if (closeEnough ("leave", args[0], 3)) status = cmdLeave ( contexts); else if (command != "") { + command = "task " + composeContexts (contexts) + " " + command; std::cout << "[task " << command << "]\n"; - command = "task " + command; system (command.c_str ()); // Deliberately ignoreѕ taskwarrior exit status, otherwise empty filters @@ -114,7 +123,8 @@ int main (int argc, const char** argv) { try { - while ((status = commandLoop ()) == 0) + std::vector contexts; + while ((status = commandLoop (contexts)) == 0) ; } diff --git a/src/prompt.cpp b/src/prompt.cpp index 326c059..ae9830f 100644 --- a/src/prompt.cpp +++ b/src/prompt.cpp @@ -25,16 +25,23 @@ //////////////////////////////////////////////////////////////////////////////// #include +#include #include +std::string composeContexts (std::vector &, bool plain = true); + //////////////////////////////////////////////////////////////////////////////// -std::string composePrompt () +std::string composePrompt (std::vector & contexts) { // TODO The prompt may be composed of different elements: // TODO - The configurable text // TODO - The accumulated context, as colored tokens. // TODO - sync status // TODO - time + std::string decoration = composeContexts (contexts, true); + if (decoration.length ()) + return "task " + composeContexts (contexts, true) + " > "; + return "task> "; }