gleam-lang / gleam-mode

🐙 Gleam support for Emacs
Apache License 2.0
81 stars 23 forks source link

Comment indentation #30

Open rechsteiner opened 3 months ago

rechsteiner commented 3 months ago

Comments are currently indented incorrectly. Here's an example from treesit-check-indent on wisp.gleam:

diff -u /var/folders/4v/snlbfx9x2c56d15shg75hryc0000gn/T/buffer-content-LTLn08 /var/folders/4v/snlbfx9x2c56d15shg75hryc0000gn/T/buffer-content-7ImW9O
--- /var/folders/4v/snlbfx9x2c56d15shg75hryc0000gn/T/buffer-content-LTLn08  2024-08-04 13:54:57.756446481 +0200
+++ /var/folders/4v/snlbfx9x2c56d15shg75hryc0000gn/T/buffer-content-7ImW9O  2024-08-04 13:54:57.758722698 +0200
@@ -33,11 +33,11 @@
 /// The body of a HTTP response, to be sent to the client.
 ///
 pub type Body {
-  /// A body of unicode text.
-  ///
-  /// The body is represented using a `StringBuilder`. If you have a `String`
-  /// you can use the `string_builder.from_string` function to convert it.
-  ///
+/// A body of unicode text.
+///
+/// The body is represented using a `StringBuilder`. If you have a `String`
+/// you can use the `string_builder.from_string` function to convert it.
+///
   Text(StringBuilder)
   /// A body of binary data.
   ///
@@ -341,9 +341,9 @@
   acc: List(BitArray),
 ) -> List(BitArray) {
   case bin {
-    // If we find a char to escape we just advance the `skip` counter so that
-    // it will be ignored in the following slice, then we append the escaped
-    // version to the accumulator.
+  // If we find a char to escape we just advance the `skip` counter so that
+  // it will be ignored in the following slice, then we append the escaped
+  // version to the accumulator.
     <<"<":utf8, rest:bits>> -> {
       let acc = [<<"&lt;":utf8>>, ..acc]
       do_escape_html(rest, skip + 1, original, acc)
...

I took a stab at fixing this, but I'm a bit unsure what the best way forward is here. The comment nodes seem to be quite inconsistent in which parents they have, so it's hard to find a solution that works for all cases (e.g. using parent-bol). For example, statement_comment's inside a type definition are under the data_constructors node, except comments for the first constructor, which are under type_definition itself. Example from wisp.gleam using treesit-explore-mode:

Screenshot 2024-08-04 at 14 00 01

It's possible to work around this by hardcoding the offset based on the parent's type like this:

(defun gleam-ts--statement-comment-indent-offset (node parent bol &rest _)
  (cond
   ((equal (treesit-node-type parent) "type_definition") gleam-ts-indent-offset)
   ((equal (treesit-node-type parent) "data_constructors") 0)
   ((equal (treesit-node-type parent) "binary_expression") 0)
   ((equal (treesit-node-type parent) "case_clauses") 0)
   ((equal (treesit-node-type parent) "function_body") 0)
   ((equal (treesit-node-type parent) "source_file") 0)
   (t gleam-ts-indent-offset)))

But it feels a bit fragile. Maybe it would be better to improve the way comments are parsed inside the tree-sitter-grammar itself?

J3RN commented 1 month ago

Hi @rechsteiner, thanks for bringing this to my attention! You're right, the association of statement_constructor nodes to data_constructor, etc nodes does seem incorrect. Could you please open an issue for this on tree-sitter-gleam?