Repository: casey/just
Pull request #2090 (2024-05-25 10:02:07)

Print mutli-line doc comments before recipe

casey: @kranurag7 re your comment in #2090, this prints out multiline doc comments:

```just
[doc('multiline
comment')]
foo:
```

Like this:

```
Available recipes:
    # multiline
    # comment
    foo
```

How does that strike you?

I was thinking that:

```
Available recipes:
    foo # multiline
          comment
```

Could get awkward to read, and would mean that a long doc comment would be squashed to the right.
kranurag7: Thanks for the fix.

With 1st, one have to re-think that the comment is for the recipe that is listed down and one may get confused if the comment is for the recipe listed down or above.

I think keeping it on the right is more flexible for users because then they'll read from left to right. 

<details><summary>Details</summary>
<p>

```bash
$ ./target/debug/just -f justfile.foo --list
Available recipes:
    # multiline
    # comment
    foo
    hello
    moo
    # this is a comment
    # for test recipe
    # comment
    test
    work
    zoo
```

</p>
</details> 

> Could get awkward to read, and would mean that a long doc comment would be squashed to the right.

we can auto-wrap after few characters, something like git commit messages where auto-wrapping is [recommended](https://github.com/jesseduffield/lazygit/pull/3173) after 72 characters. 
casey: Auto-wrapping would require word-splitting, which is error prone. For example, if word-splitting is done on spaces, the splitter would split commands like `echo foo` in the middle. Whatever we do, I'm inclined to leave the lines as the author wrote them, and they can adjust the line-length how they want.

Patch:
diff --git a/src/subcommand.rs b/src/subcommand.rs
index f7733fc2..5e7b7d21 100644
--- a/src/subcommand.rs
+++ b/src/subcommand.rs
@@ -566,26 +566,41 @@ impl Subcommand {
           .chain(aliases.get(recipe.name()).unwrap_or(&Vec::new()))
           .enumerate()
         {
-          print!(
-            "{}{}",
-            config.list_prefix.repeat(level + 1),
-            RecipeSignature { name, recipe }.color_display(config.color.stdout())
-          );
-
           let doc = if i == 0 {
             recipe.doc().map(Cow::Borrowed)
           } else {
             Some(Cow::Owned(format!("alias for `{}`", recipe.name)))
           };
 
+          if let Some(doc) = &doc {
+            if doc.lines().count() > 1 {
+              for line in doc.lines() {
+                println!(
+                  "{}{} {}",
+                  config.list_prefix.repeat(level + 1),
+                  config.color.stdout().doc().paint("#"),
+                  config.color.stdout().doc().paint(line),
+                );
+              }
+            }
+          }
+
+          print!(
+            "{}{}",
+            config.list_prefix.repeat(level + 1),
+            RecipeSignature { name, recipe }.color_display(config.color.stdout())
+          );
+
           if let Some(doc) = doc {
-            print!(
-              "{:padding$}{} {}",
-              "",
-              config.color.stdout().doc().paint("#"),
-              config.color.stdout().doc().paint(&doc),
-              padding = max_signature_width.saturating_sub(signature_widths[name]) + 1,
-            );
+            if doc.lines().count() <= 1 {
+              print!(
+                "{:padding$}{} {}",
+                "",
+                config.color.stdout().doc().paint("#"),
+                config.color.stdout().doc().paint(&doc),
+                padding = max_signature_width.saturating_sub(signature_widths[name]) + 1,
+              );
+            }
           }
           println!();
         }


Test patch:
diff --git a/tests/attributes.rs b/tests/attributes.rs
index d527b0ef..9c79bb77 100644
--- a/tests/attributes.rs
+++ b/tests/attributes.rs
@@ -156,16 +156,38 @@ fn doc_attribute_suppress() {
   Test::new()
     .justfile(
       "
-    # Non-document comment
-    [doc]
-    foo:
-      echo foo
-  ",
+        # Non-document comment
+        [doc]
+        foo:
+          echo foo
+      ",
+    )
+    .args(["--list"])
+    .stdout(
+      "
+    Available recipes:
+        foo
+        ",
+    )
+    .run();
+}
+
+#[test]
+fn doc_multiline() {
+  Test::new()
+    .justfile(
+      "
+        [doc('multiline
+        comment')]
+        foo:
+      ",
     )
     .args(["--list"])
     .stdout(
       "
     Available recipes:
+        # multiline
+        # comment
         foo
         ",
     )