[Lldb-commits] [lldb] [lldb] Improve editline completion formatting (PR #116456)

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Nov 18 00:59:16 PST 2024


================
@@ -927,12 +927,92 @@ unsigned char Editline::BufferEndCommand(int ch) {
 static void
 PrintCompletion(FILE *output_file,
                 llvm::ArrayRef<CompletionResult::Completion> results,
-                size_t max_len) {
+                size_t max_completion_length, size_t max_lenght) {
+
+  constexpr size_t ellipsis_length = 3;
+  constexpr size_t tab_legnth = 8;
+  constexpr size_t separator_length = 4;
+  const size_t description_col =
+      std::min(max_completion_length + tab_legnth, max_lenght);
+
   for (const CompletionResult::Completion &c : results) {
-    fprintf(output_file, "\t%-*s", (int)max_len, c.GetCompletion().c_str());
-    if (!c.GetDescription().empty())
-      fprintf(output_file, " -- %s", c.GetDescription().c_str());
-    fprintf(output_file, "\n");
+    // Print the leading tab-sized padding.
+    fprintf(output_file, "        ");
+    size_t cursor = tab_legnth;
+
+    if (!c.GetCompletion().empty()) {
+      const size_t completion_length = c.GetCompletion().size();
+      if (cursor + completion_length < max_lenght) {
+        fprintf(output_file, "%s", c.GetCompletion().c_str());
+        cursor = cursor + completion_length;
+      } else {
+        // If the completion doesn't fit on the screen, print ellipsis and don't
+        // bother with the description.
+        fprintf(output_file, "%s...\n",
+                c.GetCompletion()
+                    .substr(0, max_lenght - cursor - ellipsis_length)
+                    .c_str());
+        continue;
+      }
+    }
+
+    if (!c.GetDescription().empty()) {
+      // If we have a description, we need at least 4 columns for the separator.
+      if (cursor + separator_length < max_lenght) {
+        // Add padding before the separator.
+        if (cursor < description_col) {
+          std::string padding(description_col - cursor, ' ');
+          fprintf(output_file, "%s", padding.c_str());
+          cursor = description_col;
+        }
+
+        // Print the separator.
+        fprintf(output_file, " -- ");
+        cursor = cursor + separator_length;
+
+        // 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.
+        llvm::StringRef tail = c.GetDescription();
+        while (!tail.empty()) {
+          llvm::StringRef head;
+          std::tie(head, tail) = tail.split('\n');
----------------
labath wrote:

```suggestion
        bool first = true;
        for (llvm::StringRef line = llvm::split(c.GetDescription(), '\n')) {
          if (!first)
            fprintf(output_file, "%*s", description_col + 4, "");
          first = false;
```

(and then delete the padding block below.

https://github.com/llvm/llvm-project/pull/116456


More information about the lldb-commits mailing list