Files
tai/taicpp/tests/tui_script.cpp
T

88 lines
3.4 KiB
C++

// tui_script: scripted headless session over the demo scene, to diff against python.
// Script lines (stdin):
// feed <hex> stdin bytes -> TuiInput -> app.dispatch
// flush TuiInput.flush() -> dispatch (lone ESC resolution)
// frame print hex of app.frame_bytes()
// text print app.render_text()
// resize R C like SIGWINCH: new size, invalidate, dirty_layout, Resize event
// shell <text> feed text (with \r\n for \n) into the demo shell screen
// ask open the demo question dialog (F1 path)
// sources install the completion sources used by the prompt dialog
#include "TuiComplete.h"
#include "TuiDemo.h"
#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>
using namespace detz::tui;
static std::string unhex(const std::string& h) {
std::string out;
for (size_t i = 0; i + 1 < h.size(); i += 2) out.push_back(static_cast<char>(std::stoi(h.substr(i, 2), nullptr, 16)));
return out;
}
static std::string hex(const std::string& s) {
static const char* d = "0123456789abcdef";
std::string out;
for (unsigned char c : s) { out.push_back(d[c >> 4]); out.push_back(d[c & 15]); }
return out;
}
int main(int argc, char** argv) {
int rows = argc > 1 ? std::atoi(argv[1]) : 30;
int cols = argc > 2 ? std::atoi(argv[2]) : 100;
TuiApp app;
app.rows = rows;
app.cols = cols;
auto built = TuiDemo::build(app, false);
app.mount(built.first);
auto& refs = *built.second;
std::string line;
while (std::getline(std::cin, line)) {
std::istringstream in(line);
std::string cmd;
in >> cmd;
if (cmd == "feed") {
std::string h;
in >> h;
for (auto& ev : app.input.feed(unhex(h))) app.dispatch(*ev);
} else if (cmd == "flush") {
for (auto& ev : app.input.flush()) app.dispatch(*ev);
} else if (cmd == "frame") {
std::printf("%s\n", hex(app.frame_bytes()).c_str());
} else if (cmd == "text") {
std::printf("%s\n--\n", app.render_text().c_str());
} else if (cmd == "resize") {
int r, c;
in >> r >> c;
app.rows = r;
app.cols = c;
app.compositor.invalidate();
app.dirty_layout();
TuiResize ev;
ev.panel = app.root.get();
ev.rows = r;
ev.cols = c;
app.root->emit(ev);
} else if (cmd == "shell") {
std::string h;
in >> h;
refs.shell->screen.feed(unhex(h));
} else if (cmd == "ask") {
refs.ask();
} else if (cmd == "spawn") {
refs.spawn();
} else if (cmd == "sources") {
auto& s = TuiComplete::sources();
s.commands = {"help", "profile", "bots", "quit"};
s.help_text = " /help show help Show this help\n /profile NAME switch Switch profile\n /bots list bots\n";
s.provider_labels = {"Muse", "Grok"};
s.default_models = [] { return std::vector<std::string>{"model-a", "model-b"}; };
s.complete_files = [](const std::string&, const std::string&) { return std::vector<std::string>{"src/a.txt"}; };
s.dir_key = [] { return std::string("/tmp"); };
TuiComplete::reset_command_help();
}
}
return 0;
}