#pragma once #include #include #include #include #include "app.h" #include "app_manager.h" #include "dialog_model.h" #include "input_history.h" #include "line_editor.h" #include "shell_log.h" namespace roro { // The Shell (issue #67): the console's commands on the device's own screen and keyboard. A third // place to type them, after USB serial and the Debug Console, and trusted like the first: whoever // holds the device can do all of it in Settings anyway (Q205). // // It shows the replies to its own commands, and only those unless asked otherwise (Q206): the // console knows who each line was printed for (Console::Origin) and fills a ring that exists only // while the App is open. Nothing is kept once it is left. class ShellApp : public App { public: using Run = std::function; // What `rm` is pointed at: it decides whether the Shell asks first. enum class Target { Missing, File, EmptyFolder, FullFolder }; using Probe = std::function; // A folder's entries that start with `prefix`, whatever their case, a folder's with a slash at its // end: what Tab completes a path from. `more` when there were too many to give them all. using List = std::function(const std::string& folder, const std::string& prefix, bool& more)>; // How many names a pattern matches (/notes/*.txt), for the question `rm` asks; `more` past the limit. using Count = std::function; ShellApp(Run run, Probe probe, List list, Count count, const char* helpText, AppManager& apps) : run_(std::move(run)), probe_(std::move(probe)), list_(std::move(list)), count_(std::move(count)), helpText_(helpText), apps_(apps) {} void onEnter() override; void onExit() override; bool onKey(const KeyEvent& e) override; bool textEntryActive() const override { return !confirm_; } void update(uint32_t nowMs) override; void draw(Canvas& c) override; void help(std::vector& out) const override; private: void enter(const std::string& line); void runNow(const std::string& line); Run run_; Probe probe_; List list_; Count count_; const char* helpText_; AppManager& apps_; ShellLog log_; std::string ownHelp_; // the Shell's own commands and the keys `key` takes, in the form of `help`'s text LineEditor input_{240}; InputHistory history_{16}; std::unique_ptr confirm_; std::string pending_, question_; // the `rm` being asked about, and what's asked uint32_t ringPos_ = 0, seenRevision_ = 0; int scroll_ = 0; // wrapped lines scrolled back from the bottom bool open_ = false; }; } // namespace roro