diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/terminal/line.cc | 47 | ||||
-rw-r--r-- | src/ui/terminal/line.h | 3 |
2 files changed, 22 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", diff --git a/src/ui/terminal/line.h b/src/ui/terminal/line.h index a90e2b7..dfe86cb 100644 --- a/src/ui/terminal/line.h +++ b/src/ui/terminal/line.h @@ -19,8 +19,10 @@ #include <termios.h> +#include <memory> #include <thread> +#include "goldfishterm/simple.h" #include "third_party/abseil/absl/base/thread_annotations.h" #include "third_party/abseil/absl/strings/string_view.h" #include "third_party/abseil/absl/synchronization/mutex.h" @@ -81,6 +83,7 @@ class TerminalLine final { void WriteRaw(absl::string_view bytes) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_); termios original_termios_, current_termios_; + std::unique_ptr<goldfishterm::SimpleTerminalOutput> tty_; std::thread sigwinch_watcher_; |