================ @@ -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) { + size_t column_width = ColumnWidth(str); + + // Trim the string. + if (column_width > max_width) { + size_t min_width_idx = max_width; + size_t min_width = column_width; + + // Use a StringRef for more efficient slicing in the loop below. + llvm::StringRef str_ref = str; + + // Keep extending the string to find the minimum column width to make sure + // we include as many ANSI escape characters or Unicode code units as + // possible. This is far from the most efficient way to do this, but it's + // means our stripping code doesn't need to be ANSI and Unicode aware and + // should be relatively cold code path. + for (size_t i = column_width; i < str.length(); ++i) { + size_t stripped_width = ColumnWidth(str_ref.take_front(i)); + if (stripped_width <= column_width) { + min_width = stripped_width; + min_width_idx = i; + } + } + + str = str.substr(0, min_width_idx); + column_width = min_width; + } + + // Pad the string. + if (column_width < max_width) + str.append(max_width - column_width, ' '); ---------------- labath wrote:
Is padding necessary given that you do a ANSI_CLEAR_LINE below? https://github.com/llvm/llvm-project/pull/121860 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits