[Lldb-commits] [lldb] [lldb] Implement a statusline in LLDB (PR #121860)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Tue Mar 11 02:46:52 PDT 2025
================
@@ -0,0 +1,200 @@
+//===-- Statusline.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Statusline.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/FormatEntity.h"
+#include "lldb/Host/StreamFile.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Locale.h"
+#include <algorithm>
+#include <cstdint>
+
+#define ESCAPE "\x1b"
+#define ANSI_NORMAL ESCAPE "[0m"
+#define ANSI_SAVE_CURSOR ESCAPE "7"
+#define ANSI_RESTORE_CURSOR ESCAPE "8"
+#define ANSI_CLEAR_BELOW ESCAPE "[J"
+#define ANSI_CLEAR_LINE "\r\x1B[2K"
+#define ANSI_SET_SCROLL_ROWS ESCAPE "[0;%ur"
+#define ANSI_TO_START_OF_ROW ESCAPE "[%u;0f"
+#define ANSI_UP_ROWS ESCAPE "[%dA"
+#define ANSI_DOWN_ROWS ESCAPE "[%dB"
+#define ANSI_FORWARD_COLS ESCAPE "\033[%dC"
+#define ANSI_BACKWARD_COLS ESCAPE "\033[%dD"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static size_t ColumnWidth(llvm::StringRef str) {
+ std::string stripped = ansi::StripAnsiTerminalCodes(str);
+ return llvm::sys::locale::columnWidth(stripped);
+}
+
+Statusline::Statusline(Debugger &debugger) : m_debugger(debugger) { Enable(); }
+
+Statusline::~Statusline() { Disable(); }
+
+void Statusline::TerminalSizeChanged() {
+ m_terminal_size_has_changed = 1;
+
+ // This definitely isn't signal safe, but the best we can do, until we
+ // have proper signal-catching thread.
+ Redraw(/*update=*/false);
+}
+
+void Statusline::Enable() {
+ UpdateTerminalProperties();
+
+ // Reduce the scroll window to make space for the status bar below.
+ SetScrollWindow(m_terminal_height - 1);
+
+ // Draw the statusline.
+ Redraw();
+}
+
+void Statusline::Disable() {
+ UpdateTerminalProperties();
+
+ // Extend the scroll window to cover the status bar.
+ SetScrollWindow(m_terminal_height);
+}
+
+std::string Statusline::TrimAndPad(std::string str, size_t max_width) {
----------------
labath wrote:
There's a joke over here about a guy who wanted to shorten his dog's tail, but he didn't want the dog to suffer too much, so he did it one little piece at a time. :P
I think this will work, but the reason for that is very unobvious: It relies `StripAnsiTerminalCodes` leaving the partial ansi sequences intact (so that a partial escape sequence takes up more space than a complete one). And also on the fact that `columnWidth` returns `-2` for invalid/partial utf8 characters (which, after conversion to `size_t` will be larger than the available width).
I think it'd be better to have function for this which is aware of ansi escape codes and which handles utf8 partial chars explicitly (it might do the same thing as it does now, but with a comment and a test. It shouldn't be that hard to add one to AnsiTerminal (I'm imagining a helper function like `findNextAnsiSequence`, which can be used to implement both `StripAnsiTerminalCodes` and the new "truncate at a specific length" functionality.
Putting it into AnsiTerminal might also be less weird than making TrimAndPad visible only for testing.
https://github.com/llvm/llvm-project/pull/121860
More information about the lldb-commits
mailing list