On server, channel dprint through the readline-device. Also some refactors and quality improvements.

This commit is contained in:
2026-01-09 14:28:58 -05:00
parent 1087d18a2e
commit 7fa3f39d72
15 changed files with 258 additions and 253 deletions

View File

@@ -24,11 +24,8 @@ static int common_prefix_length(const std::u32string &a, const std::u32string &b
return minlen;
}
void ReadlineDevice::set_print_callback(print_callback cb) {
print_cb_ = cb;
}
void ReadlineDevice::set_prompt(std::string_view prompt) {
std::scoped_lock lock(mutex_);
desired_prompt_ = drvutil::utf8_to_utf32(prompt, nullptr);
echo_command();
}
@@ -36,7 +33,7 @@ void ReadlineDevice::set_prompt(std::string_view prompt) {
void ReadlineDevice::erase_command() {
int ccsize = current_prompt_.size() + current_command_.size();
if (ccsize > 0) {
print_cb_(n_backspaces(ccsize));
drvutil::console_write(n_backspaces(ccsize));
current_prompt_.clear();
current_command_.clear();
}
@@ -46,8 +43,8 @@ void ReadlineDevice::echo_command() {
// If the prompt has changed, erase everything and start over.
if (desired_prompt_ != current_prompt_) {
int ccsize = current_prompt_.size() + current_command_.size();
print_cb_(n_backspaces(ccsize));
print_cb_(desired_prompt_);
drvutil::console_write(n_backspaces(ccsize));
drvutil::console_write(desired_prompt_);
current_command_.clear();
current_prompt_ = desired_prompt_;
}
@@ -58,31 +55,31 @@ void ReadlineDevice::echo_command() {
// Echo backspaces to remove the non-matching part.
int remove = current_command_.size() - match;
if (remove > 0) {
print_cb_(n_backspaces(remove));
drvutil::console_write(n_backspaces(remove));
current_command_ = current_command_.substr(0, match);
}
// Echo the new part.
std::u32string newpart = desired_command_.substr(current_command_.size());
if (!newpart.empty()) {
print_cb_(newpart);
drvutil::console_write(newpart);
current_command_ = desired_command_;
}
}
std::string ReadlineDevice::putcode(char32_t c) {
std::scoped_lock lock(mutex_);
if ((c == '\n') && (readline_lastc_ == '\r')) {
// Ignore newline immediately after carriage return.
// Otherwise, crlf produces two newlines.
return "";
} else if ((c == '\r') || (c == '\n')) {
echo_command();
print_cb_(white_ + newline_);
drvutil::console_write(white_ + newline_);
std::u32string result = desired_command_ + newline_;
desired_command_.clear();
current_prompt_.clear();
current_command_.clear();
echo_command();
return drvutil::utf32_to_utf8(result);
} else if ((c == '\b') || (c == 127)) {
int len = desired_command_.size();
@@ -105,11 +102,12 @@ std::string ReadlineDevice::putcode(char32_t c) {
void ReadlineDevice::printline(std::string_view s) {
std::scoped_lock lock(mutex_);
bool missing_newline = ((s.size() == 0) || (s[s.size() - 1] != '\n'));
std::u32string utf32 = drvutil::utf8_to_utf32(s, nullptr);
erase_command();
print_cb_(utf32);
if (missing_newline) print_cb_(newline_);
drvutil::console_write(utf32);
if (missing_newline) drvutil::console_write(newline_);
echo_command();
}