1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-21 09:49:36 +01:00

Fix prompting

This commit is contained in:
Eelco Dolstra 2020-11-26 20:48:18 +01:00
parent 07ba1eb67e
commit 846c028609

View file

@ -9,6 +9,7 @@
#include <thread> #include <thread>
#include <iostream> #include <iostream>
#include <chrono> #include <chrono>
#include <future>
#include <termios.h> #include <termios.h>
#include <poll.h> #include <poll.h>
@ -124,7 +125,8 @@ private:
idBuilds, idBuilds,
idVerifyPaths, idVerifyPaths,
idStatus, idStatus,
idQuit idQuit,
idPrompt,
}; };
typedef std::pair<StatusLineGroup, uint16_t> LineId; typedef std::pair<StatusLineGroup, uint16_t> LineId;
@ -149,6 +151,8 @@ private:
size_t prevStatusLines = 0; size_t prevStatusLines = 0;
bool helpShown = false; bool helpShown = false;
std::optional<std::promise<std::optional<char>>> prompt;
}; };
const bool isTTY; const bool isTTY;
@ -228,12 +232,22 @@ public:
} }
c = std::tolower(c); c = std::tolower(c);
if (c == 3 || c == 'q') { if (c == 3 || c == 4 || c == 'q') {
auto state(state_.lock()); auto state(state_.lock());
state->statusLines.insert_or_assign({idQuit, 0}, ANSI_RED "Exiting..."); state->statusLines.insert_or_assign({idQuit, 0}, ANSI_RED "Exiting...");
draw(*state); draw(*state);
triggerInterrupt(); triggerInterrupt();
} }
{
auto state(state_.lock());
if (state->prompt) {
state->prompt->set_value(c != '\n' ? c : std::optional<char>());
state->prompt.reset();
continue;
}
}
if (c == 'l') { if (c == 'l') {
auto state(state_.lock()); auto state(state_.lock());
progressBarSettings.printBuildLogs = !progressBarSettings.printBuildLogs; progressBarSettings.printBuildLogs = !progressBarSettings.printBuildLogs;
@ -821,13 +835,28 @@ public:
std::optional<char> ask(std::string_view msg) override std::optional<char> ask(std::string_view msg) override
{ {
auto state(state_.lock()); checkInterrupt();
if (!state->active || !isatty(STDIN_FILENO)) return {};
std::cerr << fmt("\r\e[K%s ", msg); std::future<std::optional<char>> fut;
auto s = trim(readLine(STDIN_FILENO));
if (s.size() != 1) return {}; {
draw(*state); auto state(state_.lock());
return s[0]; if (!inputThread.joinable()) return {};
state->statusLines.insert_or_assign({idPrompt, 0}, fmt(ANSI_BOLD "%s " ANSI_NORMAL, msg));
draw(*state);
state->prompt = std::promise<std::optional<char>>();
fut = state->prompt->get_future();
}
auto res = fut.get();
{
auto state(state_.lock());
removeStatusLines(*state, idPrompt);
draw(*state);
}
return res;
} }
}; };