[Lldb-commits] [lldb] [lldb] Support OSC escape codes for native progress (PR #162162)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Oct 6 14:27:28 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Jonas Devlieghere (JDevlieghere)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/162162.diff
4 Files Affected:
- (modified) lldb/include/lldb/Core/Debugger.h (+1)
- (modified) lldb/include/lldb/Utility/AnsiTerminal.h (+9)
- (modified) lldb/source/Core/CoreProperties.td (+6-4)
- (modified) lldb/source/Core/Debugger.cpp (+39-10)
``````````diff
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);
+ }
+ }
}
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/162162
More information about the lldb-commits
mailing list