[Lldb-commits] [lldb] [lldb] Don't show multi-line descriptions when tab completing (PR #207379)
Raphael Isemann via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 3 04:45:21 PDT 2026
https://github.com/Teemperor created https://github.com/llvm/llvm-project/pull/207379
Some commands have multi-line decriptions which are currently shown in the tab-completion menu. While these descriptions contain useful information in their multi-line description, they do bloat the tab completion list when rendered in full.
This patch changes the completion logic to only show the first line of a command description as the completion description.
>From ca0905f4172b4a0da55f3a5844772c231c617115 Mon Sep 17 00:00:00 2001
From: Raphael Isemann <rise at apple.com>
Date: Fri, 3 Jul 2026 12:39:44 +0100
Subject: [PATCH] [lldb] Don't show multi-line descriptions when tab completing
Some commands have multi-line decriptions which are currently shown
in the tab-completion menu. While these descriptions contain useful
information in their multi-line description, they do bloat the
tab completion list when rendered in full.
This patch changes the completion logic to only show the first line
of a command description as the completion description.
---
lldb/source/Host/common/Editline.cpp | 56 ++++++-------------
.../API/terminal/TestEditlineCompletions.py | 34 ++---------
2 files changed, 22 insertions(+), 68 deletions(-)
diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp
index 5be0450cb17e9..cb323101b91d4 100644
--- a/lldb/source/Host/common/Editline.cpp
+++ b/lldb/source/Host/common/Editline.cpp
@@ -1004,46 +1004,22 @@ PrintCompletion(FILE *output_file,
// Print the separator.
fprintf(output_file, " -- ");
- // Descriptions can contain newlines. We want to print them below each
- // other, aligned after the separator. For example, foo has a
- // two-line description:
- //
- // foo -- Something that fits on the line.
- // More information below.
- //
- // However, as soon as a line exceed the available screen width and
- // print ellipsis, we don't print the next line. For example, foo has a
- // three-line description:
- //
- // foo -- Something that fits on the line.
- // Something much longer that doesn't fit...
- //
- // Because we had to print ellipsis on line two, we don't print the
- // third line.
- bool first = true;
- for (llvm::StringRef line : llvm::split(c.GetDescription(), '\n')) {
- if (line.empty())
- break;
- if (max_height && lines_printed >= *max_height)
- break;
- if (!first)
- fprintf(output_file, "%*s",
- static_cast<int>(description_col + separator_length), "");
-
- first = false;
- const size_t position = description_col + separator_length;
- const size_t description_length = line.size();
- if (position + description_length < max_length) {
- fprintf(output_file, "%.*s\n", static_cast<int>(description_length),
- line.data());
- lines_printed++;
- } else {
- fprintf(output_file, "%.*s...\n",
- static_cast<int>(max_length - position - ellipsis_length),
- line.data());
- lines_printed++;
- continue;
- }
+ // Descriptions can contain newlines. We only show the first line and
+ // cut off the rest, so that multi-line descriptions don't clutter the
+ // completion list.
+ llvm::StringRef description =
+ llvm::StringRef(c.GetDescription()).split('\n').first;
+ const size_t position = description_col + separator_length;
+ const size_t description_length = description.size();
+ if (position + description_length < max_length) {
+ fprintf(output_file, "%.*s\n", static_cast<int>(description_length),
+ description.data());
+ lines_printed++;
+ } else {
+ fprintf(output_file, "%.*s...\n",
+ static_cast<int>(max_length - position - ellipsis_length),
+ description.data());
+ lines_printed++;
}
}
return results_printed;
diff --git a/lldb/test/API/terminal/TestEditlineCompletions.py b/lldb/test/API/terminal/TestEditlineCompletions.py
index ac1d3f90e2970..b149086a26708 100644
--- a/lldb/test/API/terminal/TestEditlineCompletions.py
+++ b/lldb/test/API/terminal/TestEditlineCompletions.py
@@ -48,20 +48,16 @@ def test_separator(self):
@skipIfAsan
@skipIfEditlineSupportMissing
- def test_multiline_description(self):
- """Test that multi-line descriptions are correctly padded and truncated."""
+ def test_cut_off_multiline_description(self):
+ """Test that only the first line of a multi-line description is shown."""
self.launch(dimensions=(10, 72))
self.child.send("k\t")
+ # We check that these two lines are next to each other to make sure the
+ # multiline description of kdb-remote is not shown in full.
self.child.expect(
- " kdp-remote -- Connect to a process via remote KDP server."
+ " kdp-remote -- Connect to a process via remote KDP server.\r\n"
+ " kill -- Terminate the current target process."
)
- self.child.expect(
- " If no UDP port is specified, port 41139 is assu..."
- )
- self.child.expect(
- " kdp-remote is an abbreviation for 'process conn..."
- )
- self.child.expect(" kill -- Terminate the current target process.")
@skipIfAsan
@skipIfEditlineSupportMissing
@@ -78,21 +74,3 @@ def test_completion_pagination(self):
self.child.expect(" _regexp-down")
self.child.expect(" _regexp-env")
self.child.expect("More")
-
- @skipIfAsan
- @skipIfEditlineSupportMissing
- def test_completion_multiline_pagination(self):
- """Test that we use the terminal height for pagination and account for multi-line descriptions."""
- self.launch(dimensions=(6, 72))
- self.child.send("k\t")
- self.child.expect("Available completions:")
- self.child.expect(
- " kdp-remote -- Connect to a process via remote KDP server."
- )
- self.child.expect(
- " If no UDP port is specified, port 41139 is assu..."
- )
- self.child.expect(
- " kdp-remote is an abbreviation for 'process conn..."
- )
- self.child.expect("More")
More information about the lldb-commits
mailing list