https://github.com/Teemperor updated 
https://github.com/llvm/llvm-project/pull/206728

>From f1195f00fc1d7cd37542996578a7a2faf3470a2d Mon Sep 17 00:00:00 2001
From: Raphael Isemann <[email protected]>
Date: Tue, 30 Jun 2026 13:32:52 +0100
Subject: [PATCH] [lldb] Add tab-mode to autosuggestion feature

LLDB has an autosuggestion feature that shows previous commands that
start with the current command line invocation. These commands are
shown in a faint color after the command line.

As an alternative to this mode, this patch adds a tab-mode to the
autosuggestions. We no longer show previous commands, but instead just
show what the tab-completion would complete if the user pressed tab.

This makes LLDB's command line a bit less frustrating to explore for
users that don't want to enable the full autosuggestion feature.
---
 lldb/include/lldb/Core/Debugger.h             |  2 +-
 lldb/include/lldb/lldb-private-enumerations.h | 11 +++
 lldb/source/Core/CoreProperties.td            |  7 +-
 lldb/source/Core/Debugger.cpp                 | 26 ++++++-
 lldb/source/Core/IOHandler.cpp                | 16 +++-
 .../autosuggestion/TestAutosuggestion.py      | 75 +++++++++++++++++++
 6 files changed, 129 insertions(+), 8 deletions(-)

diff --git a/lldb/include/lldb/Core/Debugger.h 
b/lldb/include/lldb/Core/Debugger.h
index fff514fed156d..05b1bd83e32fd 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -348,7 +348,7 @@ class Debugger : public 
std::enable_shared_from_this<Debugger>,
 
   llvm::StringRef GetDisabledAnsiSuffix() const;
 
-  bool GetUseAutosuggestion() const;
+  AutosuggestionMode GetAutosuggestionMode() const;
 
   llvm::StringRef GetAutosuggestionAnsiPrefix() const;
 
diff --git a/lldb/include/lldb/lldb-private-enumerations.h 
b/lldb/include/lldb/lldb-private-enumerations.h
index a6965657f5bc9..f6278dbc74325 100644
--- a/lldb/include/lldb/lldb-private-enumerations.h
+++ b/lldb/include/lldb/lldb-private-enumerations.h
@@ -257,6 +257,17 @@ enum class IterationAction {
   Stop,
 };
 
+/// Controls how the `show-autosuggestion` setting drives inline suggestions
+/// in the interactive command line.
+enum AutosuggestionMode {
+  /// Do not show any autosuggestion.
+  eAutosuggestionOff = 0,
+  /// Show a suggestion sourced from previously entered commands.
+  eAutosuggestionOn = 1,
+  /// Show the prefix that tab completion would insert for the current line.
+  eAutosuggestionTabMode = 2,
+};
+
 /// Specifies the type of PCs when creating a `HistoryThread`.
 /// - `Returns` - Usually, when LLDB unwinds the stack or we retrieve a stack
 ///   trace via `backtrace()` we are collecting return addresses (except for 
the
diff --git a/lldb/source/Core/CoreProperties.td 
b/lldb/source/Core/CoreProperties.td
index 8cea0931868aa..97bfd4a361032 100644
--- a/lldb/source/Core/CoreProperties.td
+++ b/lldb/source/Core/CoreProperties.td
@@ -260,10 +260,11 @@ let Definition = "debugger", Path = "" in {
     Global,
     DefaultStringValue<"frame #${frame.index}: 
{${ansi.fg.cyan}${frame.pc}${ansi.normal} 
}{${module.file.basename}{`}}{${function.name-without-args}{${frame.no-debug}${function.pc-offset}}}{
 at 
${ansi.fg.cyan}${line.file.basename}${ansi.normal}:${ansi.fg.yellow}${line.number}${ansi.normal}{:${ansi.fg.yellow}${line.column}${ansi.normal}}}${frame.kind}{${function.is-optimized}
 [opt]}{${function.is-inlined} [inlined]}{${frame.is-artificial} 
[artificial]}\\\\n">,
     Desc<"The default frame format string to use when displaying stack frame 
information for threads from thread backtrace unique.">;
-  def ShowAutosuggestion: Property<"show-autosuggestion", "Boolean">,
+  def ShowAutosuggestion: Property<"show-autosuggestion", "Enum">,
     Global,
-    DefaultFalse,
-    Desc<"If true, LLDB will show suggestions to complete the command the user 
typed. Suggestions may be accepted using Ctrl-F.">;
+    DefaultEnumValue<"eAutosuggestionOff">,
+    EnumValues<"OptionEnumValues(g_show_autosuggestion_enum_values)">,
+    Desc<"Controls whether LLDB shows suggestions to complete the command the 
user typed. Suggestions may be accepted using Ctrl-F. Use 'true' to suggest 
from previously entered commands, 'tab-mode' to suggest the prefix that would 
be inserted by tab completion, or 'false' to disable suggestions.">;
   def ShowAutosuggestionAnsiPrefix: 
Property<"show-autosuggestion-ansi-prefix", "String">,
     Global,
     DefaultStringValue<"${ansi.faint}">,
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index b2e6fe66dc29e..413e74aa37292 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -195,6 +195,25 @@ static constexpr OptionEnumValueElement 
s_stop_show_column_values[] = {
     },
 };
 
+static constexpr OptionEnumValueElement g_show_autosuggestion_enum_values[] = {
+    {
+        eAutosuggestionOff,
+        "false",
+        "Do not show any autosuggestion.",
+    },
+    {
+        eAutosuggestionOn,
+        "true",
+        "Show a suggestion sourced from previously entered commands.",
+    },
+    {
+        eAutosuggestionTabMode,
+        "tab-mode",
+        "Show the prefix that tab completion would insert for the current "
+        "line.",
+    },
+};
+
 #define LLDB_PROPERTIES_debugger
 #include "CoreProperties.inc"
 
@@ -600,10 +619,11 @@ bool Debugger::SetSeparator(llvm::StringRef s) {
   return ret;
 }
 
-bool Debugger::GetUseAutosuggestion() const {
+AutosuggestionMode Debugger::GetAutosuggestionMode() const {
   const uint32_t idx = ePropertyShowAutosuggestion;
-  return GetPropertyAtIndexAs<bool>(
-      idx, g_debugger_properties[idx].default_uint_value != 0);
+  return GetPropertyAtIndexAs<AutosuggestionMode>(
+      idx, static_cast<AutosuggestionMode>(
+               g_debugger_properties[idx].default_uint_value));
 }
 
 llvm::StringRef Debugger::GetAutosuggestionAnsiPrefix() const {
diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp
index 5cc15ad2ed6ff..f19fe3204ddf5 100644
--- a/lldb/source/Core/IOHandler.cpp
+++ b/lldb/source/Core/IOHandler.cpp
@@ -266,7 +266,7 @@ IOHandlerEditline::IOHandlerEditline(
     });
     m_editline_up->SetRedrawCallback([this]() { this->RedrawCallback(); });
 
-    if (debugger.GetUseAutosuggestion()) {
+    if (debugger.GetAutosuggestionMode() != eAutosuggestionOff) {
       m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) {
         return this->SuggestionCallback(line);
       });
@@ -440,6 +440,20 @@ int IOHandlerEditline::FixIndentationCallback(Editline 
*editline,
 
 std::optional<std::string>
 IOHandlerEditline::SuggestionCallback(llvm::StringRef line) {
+  // In tab-mode, we just display what tab would complete if the user
+  // would tab.
+  if (m_debugger.GetAutosuggestionMode() == eAutosuggestionTabMode) {
+    CompletionResult result;
+    CompletionRequest request(line, line.size(), result);
+    m_delegate.IOHandlerComplete(*this, request);
+    StringList matches;
+    result.GetMatches(matches);
+    std::string longest_prefix = matches.LongestCommonPrefix();
+    llvm::StringRef cursor_arg_prefix = request.GetCursorArgumentPrefix();
+    if (longest_prefix.size() > cursor_arg_prefix.size())
+      return longest_prefix.substr(cursor_arg_prefix.size());
+    return std::nullopt;
+  }
   return m_delegate.IOHandlerSuggestion(*this, line);
 }
 
diff --git a/lldb/test/API/iohandler/autosuggestion/TestAutosuggestion.py 
b/lldb/test/API/iohandler/autosuggestion/TestAutosuggestion.py
index 401b06f6c9b49..1a6eef29a7f99 100644
--- a/lldb/test/API/iohandler/autosuggestion/TestAutosuggestion.py
+++ b/lldb/test/API/iohandler/autosuggestion/TestAutosuggestion.py
@@ -154,3 +154,78 @@ def test_autosuggestion_custom_ansi_prefix_suffix(self):
         self.child.expect_exact(self.ANSI_RED + "ame variable" + 
self.ANSI_CYAN)
         self.child.send("\n")
 
+    @skipIfAsan
+    @skipIfEditlineSupportMissing
+    def test_autosuggestion_tab_mode(self):
+        """Test that show-autosuggestion=tab-mode suggests the prefix that
+        tab completion would insert, instead of consulting command history."""
+        self.launch(
+            use_colors=True,
+            extra_args=[
+                "-o",
+                "settings set show-autosuggestion tab-mode",
+                "-o",
+                "settings set use-color true",
+            ],
+        )
+
+        ctrl_f = "\x06"
+
+        # Put 'help frame' into the session history. If tab-mode incorrectly
+        # consulted history (as the 'true' mode does), typing 'hel' would
+        # suggest 'p frame'. In tab-mode the suggestion should be just 'p',
+        # since the only tab completion of 'hel' is 'help'.
+        frame_output_needle = "Syntax: frame <subcommand>"
+        self.expect("help frame", substrs=[frame_output_needle])
+
+        self.child.send("hel")
+        # Note that the ANSI_RESET color prevents us from accepting a longer
+        # suggestion as a valid test outcome.
+        self.child.expect_exact(
+            cursor_horizontal_abs("(lldb) he")
+            + "l"
+            + self.ANSI_FAINT
+            + "p"
+            + self.ANSI_RESET
+        )
+
+        # Applying the suggestion with Ctrl-F should leave the line as 'help'
+        # (not 'help frame'). Running it lists all commands.
+        self.child.send(ctrl_f + "\n")
+        self.child.expect_exact("Debugger commands:")
+
+        # Tab completion must still work in tab-mode. Pressing tab on 'hel'
+        # should complete to 'help'; running it lists all commands.
+        self.child.send("hel\t\n")
+        self.child.expect_exact("Debugger commands:")
+
+    @skipIfAsan
+    @skipIfEditlineSupportMissing
+    def test_autosuggestion_tab_mode_no_common_prefix(self):
+        """Test that show-autosuggestion=tab-mode shows no suggestion when
+        the tab completions don't share a prefix beyond what the user typed."""
+        self.launch(
+            use_colors=True,
+            extra_args=[
+                "-o",
+                "settings set show-autosuggestion tab-mode",
+                "-o",
+                "settings set use-color true",
+            ],
+        )
+
+        ctrl_f = "\x06"
+
+        # 'se' matches several top-level commands (session, settings, ...)
+        # whose longest common prefix is 'se' itself, so tab-mode must not
+        # show any suggestion. Pressing Ctrl-F should therefore do nothing
+        # and running the line should yield the 'ambiguous command' error.
+        self.child.send("se" + ctrl_f + "\n")
+        self.child.expect_exact("ambiguous command 'se'")
+
+        # Tab completion must still work in tab-mode even when there is no
+        # common prefix to suggest: pressing tab on 'se' should list the
+        # available completions.
+        self.child.send("se\t")
+        self.child.expect_exact("session")
+        self.child.expect_exact("settings")

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

Reply via email to