-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[lldb] Support OSC escape codes for native progress #162162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This PR adds support for emitting the ConEmu OSC 9;4 sequences to show a GUI native progress bar. There's a limited number of terminal emulators that support this, so for now this requires explicit opt-in through a setting. I'm reusing the existing `show-progress` setting, which became a NOOP with the introduction of the statusline. The option now defaults to off. Implements llvm#160369
@llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) ChangesThis PR adds support for emitting the OSC There's a limited number of terminal emulators that support this, so for now this requires explicit opt-in through a setting. I'm reusing the existing Implements #160369 Full diff: https://github.com/llvm/llvm-project/pull/162162.diff 4 Files Affected:
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index 06136ed40471d..78f1fa6757f9d 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -682,6 +682,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
lldb::LockableStreamFileSP GetErrorStreamSP() { return m_error_stream_sp; }
/// @}
+ bool IsInteractiveColorTTY();
bool StatuslineSupported();
void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
diff --git a/lldb/include/lldb/Utility/AnsiTerminal.h b/lldb/include/lldb/Utility/AnsiTerminal.h
index 7db184ad67225..350c1fb145300 100644
--- a/lldb/include/lldb/Utility/AnsiTerminal.h
+++ b/lldb/include/lldb/Utility/AnsiTerminal.h
@@ -72,6 +72,15 @@
#define ANSI_ESC_START_LEN 2
+// OSC (Operating System Commands)
+#define OSC_ESCAPE_START "\033"
+#define OSC_ESCAPE_END "\x07"
+
+#define OSC_PROGRESS_REMOVE OSC_ESCAPE_START "]9;4;0;0" OSC_ESCAPE_END
+#define OSC_PROGRESS_SHOW OSC_ESCAPE_START "]9;4;1;%u" OSC_ESCAPE_END
+#define OSC_PROGRESS_ERROR OSC_ESCAPE_START "]9;4;2;%u" OSC_ESCAPE_END
+#define OSC_PROGRESS_INDETERMINATE OSC_ESCAPE_START "]9;4;3;%u" OSC_ESCAPE_END
+
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td
index fda34a8ad2630..1be911c291703 100644
--- a/lldb/source/Core/CoreProperties.td
+++ b/lldb/source/Core/CoreProperties.td
@@ -162,10 +162,12 @@ let Definition = "debugger" in {
Global,
DefaultTrue,
Desc<"Whether to use Ansi color codes or not.">;
- def ShowProgress: Property<"show-progress", "Boolean">,
- Global,
- DefaultTrue,
- Desc<"Whether to show progress or not if the debugger's output is an interactive color-enabled terminal.">;
+ def ShowProgress
+ : Property<"show-progress", "Boolean">,
+ Global,
+ DefaultFalse,
+ Desc<"Whether to show progress using Operating System Command (OSC) "
+ "Sequences in supporting terminal emulators.">;
def ShowProgressAnsiPrefix: Property<"show-progress-ansi-prefix", "String">,
Global,
DefaultStringValue<"${ansi.faint}">,
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 568cd9d3d03b6..13fd3a705128e 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -2066,19 +2066,23 @@ void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
m_forward_listener_sp.reset();
}
+bool Debugger::IsInteractiveColorTTY() {
+ if (lldb::LockableStreamFileSP stream_sp = GetOutputStreamSP()) {
+ File &file = stream_sp->GetUnlockedFile();
+ return file.GetIsInteractive() && file.GetIsRealTerminal() &&
+ file.GetIsTerminalWithColors();
+ }
+ return false;
+}
+
bool Debugger::StatuslineSupported() {
// We have trouble with the contol codes on Windows, see
// https://github.com/llvm/llvm-project/issues/134846.
#ifndef _WIN32
- if (GetShowStatusline()) {
- if (lldb::LockableStreamFileSP stream_sp = GetOutputStreamSP()) {
- File &file = stream_sp->GetUnlockedFile();
- return file.GetIsInteractive() && file.GetIsRealTerminal() &&
- file.GetIsTerminalWithColors();
- }
- }
-#endif
+ return GetShowStatusline() && IsInteractiveColorTTY();
+#else
return false;
+#endif
}
static bool RequiresFollowChildWorkaround(const Process &process) {
@@ -2271,10 +2275,11 @@ void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) {
ProgressReport progress_report{data->GetID(), data->GetCompleted(),
data->GetTotal(), data->GetMessage()};
- // Do some bookkeeping regardless of whether we're going to display
- // progress reports.
{
std::lock_guard<std::mutex> guard(m_progress_reports_mutex);
+
+ // Do some bookkeeping regardless of whether we're going to display
+ // progress reports.
auto it = llvm::find_if(m_progress_reports, [&](const auto &report) {
return report.id == progress_report.id;
});
@@ -2287,6 +2292,30 @@ void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) {
} else {
m_progress_reports.push_back(progress_report);
}
+
+ // Show progress using Operating System Command (OSC) sequences.
+ if (GetShowProgress() && IsInteractiveColorTTY()) {
+ if (lldb::LockableStreamFileSP stream_sp = GetOutputStreamSP()) {
+
+ // Clear progress if this was the last progress event.
+ if (m_progress_reports.empty()) {
+ stream_sp->Lock() << OSC_PROGRESS_REMOVE;
+ return;
+ }
+
+ const ProgressReport &report = m_progress_reports.back();
+
+ // Show indeterminate progress.
+ if (report.total == UINT64_MAX) {
+ stream_sp->Lock() << OSC_PROGRESS_INDETERMINATE;
+ return;
+ }
+
+ // Compute and show the progress value (0-100).
+ const unsigned value = (report.completed / report.total) * 100;
+ stream_sp->Lock().Printf(OSC_PROGRESS_SHOW, value);
+ }
+ }
}
}
|
This PR adds support for emitting the OSC
9;4
sequences to show a GUI native progress bar.There's a limited number of terminal emulators that support this, so for now this requires explicit opt-in through a setting. I'm reusing the existing
show-progress
setting, which became a NOOP with the introduction of the statusline. The option now defaults to off.Implements #160369