aboutsummaryrefslogtreecommitdiff
path: root/src/ui/terminal/line.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/terminal/line.cc')
-rw-r--r--src/ui/terminal/line.cc47
1 files changed, 19 insertions, 28 deletions
diff --git a/src/ui/terminal/line.cc b/src/ui/terminal/line.cc
index 8f156cb..0ae2d30 100644
--- a/src/ui/terminal/line.cc
+++ b/src/ui/terminal/line.cc
@@ -22,12 +22,15 @@
#include <algorithm>
#include <iostream>
+#include <memory>
#include <stdexcept>
#include <string>
#include <system_error>
#include <thread>
#include <type_traits>
+#include <utility>
+#include "goldfishterm/simple.h"
#include "third_party/abseil/absl/strings/str_cat.h"
#include "third_party/abseil/absl/strings/string_view.h"
#include "third_party/abseil/absl/synchronization/mutex.h"
@@ -65,12 +68,6 @@ int TerminalColumns() {
return size.ws_col;
}
-absl::string_view ClearToEol() noexcept {
- static const std::string kSequence =
- absl::StrCat("\x1b[K", std::string(3, '\0') /* VT100 padding */);
- return kSequence;
-}
-
} // namespace
TerminalLine::TerminalLine() {
@@ -79,6 +76,7 @@ TerminalLine::TerminalLine() {
}
EnterRawMode();
+ tty_ = std::make_unique<goldfishterm::SimpleTerminalOutput>(current_termios_);
sigwinch_watcher_ = std::thread([this] {
sigset_t sigwinch = SigsetContaining(SIGWINCH);
@@ -109,16 +107,17 @@ void TerminalLine::SetLine(std::string text) {
void TerminalLine::Refresh() {
absl::MutexLock lock(&mu_);
+ tty_->BeginningOfLine();
if (line_.size() < columns_) {
// We can fit the whole line and the cursor on the screen at once.
- WriteRaw(absl::StrCat(kBeginningOfLine, line_, ClearToEol()));
+ tty_->Write(line_);
} else {
auto to_display = std::min<int>(line_.size(), columns_ - 4);
- WriteRaw(
- absl::StrCat(kBeginningOfLine, "...",
- absl::string_view(&*line_.end() - to_display, to_display),
- ClearToEol()));
+ tty_->Write("...");
+ tty_->Write(absl::string_view(&*line_.end() - to_display, to_display));
}
+ tty_->ClearToEndOfLine();
+ tty_->Flush();
}
char TerminalLine::GetChar() {
@@ -139,21 +138,26 @@ char TerminalLine::GetChar() {
void TerminalLine::Beep() {
absl::MutexLock lock(&mu_);
- WriteRaw("\a");
+ tty_->Beep();
+ tty_->Flush();
}
void TerminalLine::PrintLine(absl::string_view message) {
{
absl::MutexLock lock(&mu_);
- WriteRaw(absl::StrCat("\r\n", message, "\r\n"));
+ tty_->BeginningOfLine();
+ tty_->CursorDown();
+ tty_->Write(message);
+ tty_->BeginningOfLine();
+ tty_->CursorDown();
}
- Refresh();
+ Refresh(); // includes a flush
}
void TerminalLine::EnterRawMode() {
CheckedCall("tcgetattr", tcgetattr(STDIN_FILENO, &original_termios_));
- current_termios_ = original_termios_;
+ termios current_termios_ = original_termios_;
current_termios_.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
current_termios_.c_oflag &= ~(OPOST);
current_termios_.c_cflag |= CS8;
@@ -184,19 +188,6 @@ void TerminalLine::ReportSigwinch() {
Refresh();
}
-void TerminalLine::WriteRaw(absl::string_view bytes) {
- while (true) {
- int r = write(STDOUT_FILENO, bytes.data(), bytes.size());
- if (r >= 0) {
- return;
- } else if (errno == EINTR) {
- continue;
- } else {
- throw std::system_error(errno, std::generic_category(), "write");
- }
- }
-}
-
void BlockSigwinch() {
sigset_t sigwinch = SigsetContaining(SIGWINCH);
CheckedCall("pthread_sigmask",