Public Access
Shell: the console's commands on the device's own screen and keyboard (#67)
An App in the Launcher that runs the same commands as USB serial and the Debug Console, trusted like the first. It shows what the console prints while it is open, through a second ring of the console's that exists only meanwhile; Ctrl+b keeps only what follows your own commands. Tab completes a command's name from the firmware's help text, Fn with up and down recalls earlier lines, Alt with up and down scrolls back. `rm` asks first in the Shell, `rm -f` doesn't. Nothing is kept once the App is left. `screenshot [seconds]` saves the screen as a PNG in /screenshots on the card, now or after a pause: written a row at a time, indexed colour with RGB332 as the palette, in one stored deflate block. 487 host tests (11 new: the PNG writer, the Shell's log filter, Tab). Checked on the device over the Debug Console: commands, Tab, history, a screenshot fetched and decoded on the PC, rm with and without the question, a delayed screenshot of another screen. 12 KB of flash; 7 KB of heap while open. Decisions Q204 to Q212 in docs/milestones/S1.md. Safe Mode: #77. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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 what the console prints while it is open, read from a ring of the console's that exists
|
||||
// only meanwhile; nothing is kept once the App is left.
|
||||
class ShellApp : public App {
|
||||
public:
|
||||
using Run = std::function<void(const std::string& line)>;
|
||||
|
||||
ShellApp(Run run, const char* helpText, AppManager& apps) : run_(std::move(run)), 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<KeyHelp>& out) const override;
|
||||
|
||||
private:
|
||||
void enter(const std::string& line);
|
||||
void runNow(const std::string& line);
|
||||
|
||||
Run run_;
|
||||
const char* helpText_;
|
||||
AppManager& apps_;
|
||||
ShellLog log_;
|
||||
std::vector<std::string> words_; // the commands Tab completes: built on entering, from `help`
|
||||
LineEditor input_{240};
|
||||
InputHistory history_{16};
|
||||
std::unique_ptr<DialogModel> confirm_;
|
||||
std::string pending_; // the `rm` being asked about
|
||||
uint32_t ringPos_ = 0, seenRevision_ = 0;
|
||||
int scroll_ = 0; // wrapped lines scrolled back from the bottom
|
||||
bool open_ = false;
|
||||
};
|
||||
|
||||
} // namespace roro
|
||||
Reference in New Issue
Block a user