https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/177295

>From 7b5adeb2e31c5ef10eaf31fff75a73caf9c20671 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Wed, 21 Jan 2026 17:31:45 -0800
Subject: [PATCH 1/4] [lldb] Align command and settings in apropos output

Align the output of commands and settings in the apropos output. Right
now, padding is added between the command and its description to match
the longest setting, while settings are not padded at all. With this
patch, both are padded by the same amount.

Fixes #177284
---
 lldb/source/Commands/CommandObjectApropos.cpp | 61 ++++++++++++-------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectApropos.cpp 
b/lldb/source/Commands/CommandObjectApropos.cpp
index d663f2bd923fe..360e48c461070 100644
--- a/lldb/source/Commands/CommandObjectApropos.cpp
+++ b/lldb/source/Commands/CommandObjectApropos.cpp
@@ -11,6 +11,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/Property.h"
 #include "lldb/Utility/Args.h"
+#include "lldb/Utility/StreamString.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -32,46 +33,64 @@ void CommandObjectApropos::DoExecute(Args &args, 
CommandReturnObject &result) {
   if (argc == 1) {
     auto search_word = args[0].ref();
     if (!search_word.empty()) {
-      // The bulk of the work must be done inside the Command Interpreter,
-      // since the command dictionary is private.
+      // Find all commands matching the search word and compute the max length.
       StringList commands_found;
       StringList commands_help;
 
       m_interpreter.FindCommandsForApropos(
           search_word, commands_found, commands_help, true, true, true, true);
 
+      size_t max_len = commands_found.GetMaxStringLength();
+
+      // Find all the properties matching the search word and compute the max
+      // length.
+      std::vector<const Property *> properties;
+      const size_t num_properties =
+          GetDebugger().Apropos(search_word, properties);
+      for (const Property *prop : properties) {
+        StreamString qualified_name;
+        prop->DumpQualifiedName(qualified_name);
+        max_len = std::max(max_len, qualified_name.GetString().size());
+      }
+
+      ReturnStatus return_status = eReturnStatusSuccessFinishNoResult;
+
       if (commands_found.GetSize() == 0) {
         result.AppendMessageWithFormat("No commands found pertaining to '%s'. "
                                        "Try 'help' to see a complete list of "
                                        "debugger commands.\n",
                                        args[0].c_str());
       } else {
-        if (commands_found.GetSize() > 0) {
-          result.AppendMessageWithFormat(
-              "The following commands may relate to '%s':\n", args[0].c_str());
-          const size_t max_len = commands_found.GetMaxStringLength();
-
-          for (size_t i = 0; i < commands_found.GetSize(); ++i)
-            m_interpreter.OutputFormattedHelpText(
-                result.GetOutputStream(), commands_found.GetStringAtIndex(i),
-                "--", commands_help.GetStringAtIndex(i), max_len);
-        }
+        result.AppendMessageWithFormat(
+            "The following commands may relate to '%s':\n", args[0].c_str());
+        for (size_t i = 0; i < commands_found.GetSize(); ++i)
+          m_interpreter.OutputFormattedHelpText(
+              result.GetOutputStream(), commands_found.GetStringAtIndex(i),
+              "--", commands_help.GetStringAtIndex(i), max_len);
+        return_status = eReturnStatusSuccessFinishResult;
       }
 
-      std::vector<const Property *> properties;
-      const size_t num_properties =
-          GetDebugger().Apropos(search_word, properties);
-      if (num_properties) {
-        const bool dump_qualified_name = true;
+      if (num_properties == 0) {
+        result.AppendMessageWithFormat(
+            "No settings found pertaining to '%s'. "
+            "Try 'settings show' to see a complete list of "
+            "debugger settings.\n",
+            args[0].c_str());
+
+      } else {
         result.AppendMessageWithFormatv(
             "\nThe following settings variables may relate to '{0}': \n\n",
-            args[0].ref());
+            search_word);
+
+        const bool dump_qualified_name = true;
         for (size_t i = 0; i < num_properties; ++i)
-          properties[i]->DumpDescription(
-              m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
+          properties[i]->DumpDescription(m_interpreter,
+                                         result.GetOutputStream(), max_len,
+                                         dump_qualified_name);
+        return_status = eReturnStatusSuccessFinishResult;
       }
 
-      result.SetStatus(eReturnStatusSuccessFinishNoResult);
+      result.SetStatus(return_status);
     } else {
       result.AppendError("'' is not a valid search word.\n");
     }

>From 3f151c7cdce2b34169f7b659d0cc5211e3198ee2 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Wed, 21 Jan 2026 19:32:11 -0800
Subject: [PATCH 2/4] Update TestSettings.py

---
 lldb/test/API/commands/settings/TestSettings.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/test/API/commands/settings/TestSettings.py 
b/lldb/test/API/commands/settings/TestSettings.py
index 95b07f8326f2c..8410befe399a3 100644
--- a/lldb/test/API/commands/settings/TestSettings.py
+++ b/lldb/test/API/commands/settings/TestSettings.py
@@ -22,8 +22,7 @@ def 
test_apropos_should_also_search_settings_description(self):
             "apropos 'environment variable'",
             substrs=[
                 "target.env-vars",
-                "environment variables",
-                "executable's environment",
+                "A list of user",
             ],
         )
 

>From 8c4935bde1b926ceb072e4454ae0528b4f510671 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Thu, 22 Jan 2026 15:35:14 -0800
Subject: [PATCH 3/4] Add PExpect test

---
 .../formatting/TestAproposFormatting.py       | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 
lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py

diff --git a/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py 
b/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py
new file mode 100644
index 0000000000000..a10791937c243
--- /dev/null
+++ b/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py
@@ -0,0 +1,35 @@
+"""
+Test the formatting and alignment of the apropos command output.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbpexpect import PExpectTest
+
+
+class AproposFormattingTest(PExpectTest):
+    # PExpect uses many timeouts internally and doesn't play well
+    # under ASAN on a loaded machine.
+    @skipIfAsan
+    @skipIfEditlineSupportMissing
+    def test_apropos_with_settings_alignment(self):
+        """Test that apropos aligns both commands and settings to the same 
column."""
+        self.launch()
+        self.child.setwinsize(24, 120)
+
+        self.child.sendline("apropos disass")
+
+        self.child.expect_exact("The following commands may relate to 
'disass':")
+        self.child.expect_exact(
+            "  disassemble                   -- Disassemble specified 
instructions in the current target."
+        )
+
+        self.child.expect_exact(
+            "The following settings variables may relate to 'disass':"
+        )
+        self.child.expect_exact(
+            "  disassembly-format            -- The default disassembly format 
string to use"
+        )
+
+        self.expect_prompt()
+        self.quit()

>From b6515590361720e1e3dfd7cdce37c6b23633c1fe Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Thu, 22 Jan 2026 22:27:42 -0800
Subject: [PATCH 4/4] Use separate padding

---
 lldb/source/Commands/CommandObjectApropos.cpp | 41 +++++++++----------
 .../formatting/TestAproposFormatting.py       |  2 +-
 2 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectApropos.cpp 
b/lldb/source/Commands/CommandObjectApropos.cpp
index 360e48c461070..acd19eecec8dd 100644
--- a/lldb/source/Commands/CommandObjectApropos.cpp
+++ b/lldb/source/Commands/CommandObjectApropos.cpp
@@ -33,28 +33,14 @@ void CommandObjectApropos::DoExecute(Args &args, 
CommandReturnObject &result) {
   if (argc == 1) {
     auto search_word = args[0].ref();
     if (!search_word.empty()) {
-      // Find all commands matching the search word and compute the max length.
+      ReturnStatus return_status = eReturnStatusSuccessFinishNoResult;
+
+      // Find all commands matching the search word.
       StringList commands_found;
       StringList commands_help;
-
       m_interpreter.FindCommandsForApropos(
           search_word, commands_found, commands_help, true, true, true, true);
 
-      size_t max_len = commands_found.GetMaxStringLength();
-
-      // Find all the properties matching the search word and compute the max
-      // length.
-      std::vector<const Property *> properties;
-      const size_t num_properties =
-          GetDebugger().Apropos(search_word, properties);
-      for (const Property *prop : properties) {
-        StreamString qualified_name;
-        prop->DumpQualifiedName(qualified_name);
-        max_len = std::max(max_len, qualified_name.GetString().size());
-      }
-
-      ReturnStatus return_status = eReturnStatusSuccessFinishNoResult;
-
       if (commands_found.GetSize() == 0) {
         result.AppendMessageWithFormat("No commands found pertaining to '%s'. "
                                        "Try 'help' to see a complete list of "
@@ -63,13 +49,26 @@ void CommandObjectApropos::DoExecute(Args &args, 
CommandReturnObject &result) {
       } else {
         result.AppendMessageWithFormat(
             "The following commands may relate to '%s':\n", args[0].c_str());
+        const size_t commands_max_len = commands_found.GetMaxStringLength();
         for (size_t i = 0; i < commands_found.GetSize(); ++i)
           m_interpreter.OutputFormattedHelpText(
               result.GetOutputStream(), commands_found.GetStringAtIndex(i),
-              "--", commands_help.GetStringAtIndex(i), max_len);
+              "--", commands_help.GetStringAtIndex(i), commands_max_len);
         return_status = eReturnStatusSuccessFinishResult;
       }
 
+      // Find all the properties matching the search word.
+      size_t properties_max_len = 0;
+      std::vector<const Property *> properties;
+      const size_t num_properties =
+          GetDebugger().Apropos(search_word, properties);
+      for (const Property *prop : properties) {
+        StreamString qualified_name;
+        prop->DumpQualifiedName(qualified_name);
+        properties_max_len =
+            std::max(properties_max_len, qualified_name.GetString().size());
+      }
+
       if (num_properties == 0) {
         result.AppendMessageWithFormat(
             "No settings found pertaining to '%s'. "
@@ -84,9 +83,9 @@ void CommandObjectApropos::DoExecute(Args &args, 
CommandReturnObject &result) {
 
         const bool dump_qualified_name = true;
         for (size_t i = 0; i < num_properties; ++i)
-          properties[i]->DumpDescription(m_interpreter,
-                                         result.GetOutputStream(), max_len,
-                                         dump_qualified_name);
+          properties[i]->DumpDescription(
+              m_interpreter, result.GetOutputStream(), properties_max_len,
+              dump_qualified_name);
         return_status = eReturnStatusSuccessFinishResult;
       }
 
diff --git a/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py 
b/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py
index a10791937c243..b9073348f7583 100644
--- a/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py
+++ b/lldb/test/API/commands/apropos/formatting/TestAproposFormatting.py
@@ -21,7 +21,7 @@ def test_apropos_with_settings_alignment(self):
 
         self.child.expect_exact("The following commands may relate to 
'disass':")
         self.child.expect_exact(
-            "  disassemble                   -- Disassemble specified 
instructions in the current target."
+            "  disassemble -- Disassemble specified instructions in the 
current target."
         )
 
         self.child.expect_exact(

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to