diff --git a/luprex/core/cpp/lpxclient.cpp b/luprex/core/cpp/lpxclient.cpp index 7a3f25e8..7a981b6d 100644 --- a/luprex/core/cpp/lpxclient.cpp +++ b/luprex/core/cpp/lpxclient.cpp @@ -32,9 +32,13 @@ public: // Establish a connection to the server. channel_ = new_outgoing_channel("localhost:8085"); + + // Set the console prompt + get_stdio_channel()->set_prompt(console_.get_prompt()); } void do_command(const util::StringVec &words) { + if (words.empty()) return; stdostream() << "Command: "; for (const std::string &word : words) { stdostream() << word << " "; @@ -48,12 +52,8 @@ public: std::string line = get_stdio_channel()->in()->readline(); if (line == "") break; console_.add(line); - const util::StringVec &words = console_.words(); - if (!words.empty()) { - do_command(words); - console_.clear(); - } - get_stdio_channel()->out()->write_bytes(console_.get_prompt()); + get_stdio_channel()->set_prompt(console_.get_prompt()); + do_command(console_.get_command()); } // Check for communication from server.. diff --git a/luprex/core/cpp/luaconsole.cpp b/luprex/core/cpp/luaconsole.cpp index 6214887e..0c672a51 100644 --- a/luprex/core/cpp/luaconsole.cpp +++ b/luprex/core/cpp/luaconsole.cpp @@ -10,28 +10,20 @@ static bool is_single_letter(const std::string &s) { LuaConsole::LuaConsole() { lua_state_ = luaL_newstate(); - clear(); + clear_raw_input(); } LuaConsole::~LuaConsole() { lua_close(lua_state_); } -void LuaConsole::clear() { - raw_input_ = ""; - lines_ = 0; - words_.clear(); - prompt_ = "> "; -} - - -void LuaConsole::split_words() { - words_.clear(); +static LuaConsole::StringVec split_words(const std::string &raw) { + LuaConsole::StringVec result; std::string acc; - for (char c : raw_input_) { + for (char c : raw) { if ((c == ' ')||(c == '\n')||(c == '\r')) { if (!acc.empty()) { - words_.push_back(acc); + result.push_back(acc); acc = ""; } } else { @@ -39,16 +31,23 @@ void LuaConsole::split_words() { } } if (!acc.empty()) { - words_.push_back(acc); + result.push_back(acc); } + return result; } -std::string LuaConsole::get_prompt() { - std::string result = prompt_; - prompt_ = ""; +LuaConsole::StringVec LuaConsole::get_command() { + StringVec result = words_; + words_.clear(); return result; } +void LuaConsole::clear_raw_input() { + raw_input_ = ""; + lines_ = 0; + prompt_ = "> "; +} + void LuaConsole::add(std::string line) { for (int i = 0; i < int(line.size()); i++) { if (line[i] == '\n') line[i] = ' '; @@ -56,18 +55,19 @@ void LuaConsole::add(std::string line) { raw_input_ += line; raw_input_ += '\n'; lines_ += 1; + prompt_ = ">> "; // Try to interpret it as a special command. if (lines_ == 1) { - split_words(); - if (words_.size() >= 1) { - if (is_single_letter(words_[0]) || (util::validinteger(words_[0]))) { - // We have a valid parsed command. Return it. + StringVec words = split_words(raw_input_); + if (words.size() >= 1) { + if (is_single_letter(words[0]) || (util::validinteger(words[0]))) { + words_ = words; + clear_raw_input(); return; } } } - words_.clear(); // Translate lua expression with leading '=' to 'return' std::string partial; @@ -90,14 +90,13 @@ void LuaConsole::add(std::string line) { if (strstr(msg, eof) != tp) { words_.push_back("syntax"); words_.push_back(msg); + clear_raw_input(); } } else { words_.push_back("lua"); words_.push_back(partial); + clear_raw_input(); } lua_settop(lua_state_, top); - if (words_.empty()) { - prompt_ = ">> "; - } } diff --git a/luprex/core/cpp/luaconsole.hpp b/luprex/core/cpp/luaconsole.hpp index b2fef0b6..f8a12f35 100644 --- a/luprex/core/cpp/luaconsole.hpp +++ b/luprex/core/cpp/luaconsole.hpp @@ -8,9 +8,9 @@ // 1. Print the prompt suggested by 'get_prompt'. // 2. Read a line of text from stdin. // 3. Add the line to the LuaConsole using 'add'. -// 4. Get the command words using 'words'. -// 5. If the words are empty, do nothing. -// 6. If the words contain something, execute and call 'clear'. +// 4. Get the command words using 'get_command'. +// 5. If the command is empty, do nothing. +// 6. If the command is nonempty, execute it and call 'clear'. // // The 'words' returned by the luaconsole can be empty, meaning // that there's no command to execute. If the words are nonempty, @@ -43,32 +43,31 @@ private: StringVec words_; std::string prompt_; - void split_words(); - void clear_command(); + void clear_raw_input(); public: LuaConsole(); ~LuaConsole(); - // Fetch the stored prompt. Also clears the stored prompt. You should fetch - // and print the prompt after 'add' or 'clear'. - std::string get_prompt(); - - // Get the command words. + // Fetch the recommended prompt. // + // You should update the prompt immediately after 'add'. + // + const std::string &get_prompt() { return prompt_; } + + // Fetch the command to execute. + // + // You should fetch the command after calling 'add'. // Returns the empty vector if there is no command. // If there is a command, the first word is the command word. // See the file comment for certain built-in command words. // - const StringVec &words() const { return words_; } + StringVec get_command(); // Add a line of text that was just read from the console. - // If more input is needed, stores the ">> " prompt. + // void add(std::string line); - // Call 'clear' after executing an action. - // Stores the "> " prompt. - void clear(); }; #endif // LUACONSOLE_HPP diff --git a/luprex/core/cpp/textgame.cpp b/luprex/core/cpp/textgame.cpp index e12ffa24..c8841d86 100644 --- a/luprex/core/cpp/textgame.cpp +++ b/luprex/core/cpp/textgame.cpp @@ -158,7 +158,8 @@ void TextGame::do_quit_command(const StringVec &cmd) { } void TextGame::do_command(const StringVec &words) { - if (words[0] == "lua") do_lua_command(words); + if (words.empty()) return; + else if (words[0] == "lua") do_lua_command(words); else if (words[0] == "syntax") do_syntax_command(words); else if (words[0] == "v") do_view_command(words); else if (words[0] == "m") do_menu_command(words); @@ -219,18 +220,14 @@ void TextGame::event_update() std::string line = get_stdio_channel()->in()->readline(); if (line == "") break; console_.add(line); - const StringVec &words = console_.words(); - if (!words.empty()) { - do_command(words); - console_.clear(); - channel_printbuffer(); - } + get_stdio_channel()->set_prompt(console_.get_prompt()); + do_command(console_.get_command()); + channel_printbuffer(); check_redirects(); if (actor_id_ == 0) { stop_driver(); - return; + break; } - get_stdio_channel()->set_prompt(console_.get_prompt()); } }