Skip to content

Commit

Permalink
Merge pull request #11380 from roberth/eco-friendly-progress-bar
Browse files Browse the repository at this point in the history
progress-bar: Only write when truly updated
  • Loading branch information
edolstra authored Sep 9, 2024
2 parents 5e337ee + c955563 commit 4c7a6ff
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/libmain/progress-bar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class ProgressBar : public Logger
bool haveUpdate = true;
};

/** Helps avoid unnecessary redraws, see `redraw()` */
Sync<std::string> lastOutput_;

Sync<State> state_;

std::thread updateThread;
Expand Down Expand Up @@ -359,6 +362,22 @@ class ProgressBar : public Logger
updateCV.notify_one();
}

/**
* Redraw, if the output has changed.
*
* Excessive redrawing is noticable on slow terminals, and it interferes
* with text selection in some terminals, including libvte-based terminal
* emulators.
*/
void redraw(std::string newOutput)
{
auto lastOutput(lastOutput_.lock());
if (newOutput != *lastOutput) {
writeToStderr(newOutput);
*lastOutput = std::move(newOutput);
}
}

std::chrono::milliseconds draw(State & state)
{
auto nextWakeup = std::chrono::milliseconds::max();
Expand Down Expand Up @@ -412,7 +431,7 @@ class ProgressBar : public Logger
auto width = getWindowSize().second;
if (width <= 0) width = std::numeric_limits<decltype(width)>::max();

writeToStderr("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K");
redraw("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K");

return nextWakeup;
}
Expand Down

0 comments on commit 4c7a6ff

Please sign in to comment.