treesj icon indicating copy to clipboard operation
treesj copied to clipboard

Add support for Terraform

Open vnea opened this issue 11 months ago • 2 comments

Hello,

Is it possible to add support for Terraform (for lists and maps) please?

vnea avatar Jan 17 '25 00:01 vnea

Hi! If tree-sitter supports terraform, it is possible to add support for it. Provide code samples for terraform as here: https://github.com/Wansmer/treesj/tree/main/tests/sample

Wansmer avatar Jan 17 '25 05:01 Wansmer

It is supported yes!

I will do a PR when I will have, thank you.

vnea avatar Jan 17 '25 09:01 vnea

I will do a PR when I will have, thank you.

Hello, did you ever started to add terraform support ? If not I'm going to do it.

bew avatar Apr 23 '25 10:04 bew

Hello, did you ever started to add terraform support ? If not I'm going to do it.

No I didn't, you can do it. Thank you.

vnea avatar Apr 23 '25 10:04 vnea

At the moment I have this:

    mylangs.terraform = {
      tuple = lang_utils.set_preset_for_list({
        join = {
          space_in_brackets = false,
        },
      }),
      -- FIXME: I don't understand why joining an object node does NOT add `,` separators
      --   And when they are there, splitting an object node does NOT remove the `,` separators
      object = lang_utils.set_preset_for_dict({
        split = {
          separator = "",
        },
        join = {
          -- FIXME: When using `force_insert` instead of `separator` it _does_ add the `,`
          --   (but everywhere, even on last item, even if `last_separator=false`)
          separator = ",",
          space_in_brackets = false,
        },
      }),
      function_call = {
        target_nodes = { "function_arguments" },
      },
      function_arguments = lang_utils.set_preset_for_args({
        both = {
          -- note: brackets are text only, in function_call node
          non_bracket_node = true,
        },
        join = {
          recursive = true,
        },
        split = {
          last_separator = true,
        },
      }),
    }

👉 I'm having a hard time understanding how to make object join/split work correctly.

With this example:

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      { # <CURSOR>
        Action   = ["states:SendTaskSuccess"]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
The Treesitter nodes for this example
    (attribute ; [0, 0] - [9, 2]
      (identifier) ; [0, 0] - [0, 6]
      (expression ; [0, 9] - [9, 2]
        (function_call ; [0, 9] - [9, 2]
          (identifier) ; [0, 9] - [0, 19]
          (function_arguments ; [0, 20] - [9, 1]
            (expression ; [0, 20] - [9, 1]
              (collection_value ; [0, 20] - [9, 1]
                (object ; [0, 20] - [9, 1]
                  (object_start) ; [0, 20] - [0, 21]
                  (object_elem ; [1, 2] - [1, 24]
                    key: (expression ; [1, 2] - [1, 9]
                      (variable_expr ; [1, 2] - [1, 9]
                        (identifier))) ; [1, 2] - [1, 9]
                    val: (expression ; [1, 12] - [1, 24]
                      (literal_value ; [1, 12] - [1, 24]
                        (string_lit ; [1, 12] - [1, 24]
                          (quoted_template_start) ; [1, 12] - [1, 13]
                          (template_literal) ; [1, 13] - [1, 23]
                          (quoted_template_end))))) ; [1, 23] - [1, 24]
                  (object_elem ; [2, 2] - [8, 3]
                    key: (expression ; [2, 2] - [2, 11]
                      (variable_expr ; [2, 2] - [2, 11]
                        (identifier))) ; [2, 2] - [2, 11]
                    val: (expression ; [2, 14] - [8, 3]
                      (collection_value ; [2, 14] - [8, 3]
                        (tuple ; [2, 14] - [8, 3]
                          (tuple_start) ; [2, 14] - [2, 15]
                          (expression ; [3, 4] - [7, 5]
                            (collection_value ; [3, 4] - [7, 5]
                              (object ; [3, 4] - [7, 5]
                                (object_start) ; [3, 4] - [3, 5]
                                (object_elem ; [4, 6] - [4, 43]
                                  key: (expression ; [4, 6] - [4, 12]
                                    (variable_expr ; [4, 6] - [4, 12]
                                      (identifier))) ; [4, 6] - [4, 12]
                                  val: (expression ; [4, 17] - [4, 43]
                                    (collection_value ; [4, 17] - [4, 43]
                                      (tuple ; [4, 17] - [4, 43]
                                        (tuple_start) ; [4, 17] - [4, 18]
                                        (expression ; [4, 18] - [4, 42]
                                          (literal_value ; [4, 18] - [4, 42]
                                            (string_lit ; [4, 18] - [4, 42]
                                              (quoted_template_start) ; [4, 18] - [4, 19]
                                              (template_literal) ; [4, 19] - [4, 41]
                                              (quoted_template_end)))) ; [4, 41] - [4, 42]
                                        (tuple_end))))) ; [4, 42] - [4, 43]
                                (object_elem ; [5, 6] - [5, 24]
                                  key: (expression ; [5, 6] - [5, 12]
                                    (variable_expr ; [5, 6] - [5, 12]
                                      (identifier))) ; [5, 6] - [5, 12]
                                  val: (expression ; [5, 17] - [5, 24]
                                    (literal_value ; [5, 17] - [5, 24]
                                      (string_lit ; [5, 17] - [5, 24]
                                        (quoted_template_start) ; [5, 17] - [5, 18]
                                        (template_literal) ; [5, 18] - [5, 23]
                                        (quoted_template_end))))) ; [5, 23] - [5, 24]
                                (object_elem ; [6, 6] - [6, 20]
                                  key: (expression ; [6, 6] - [6, 14]
                                    (variable_expr ; [6, 6] - [6, 14]
                                      (identifier))) ; [6, 6] - [6, 14]
                                  val: (expression ; [6, 17] - [6, 20]
                                    (literal_value ; [6, 17] - [6, 20]
                                      (string_lit ; [6, 17] - [6, 20]
                                        (quoted_template_start) ; [6, 17] - [6, 18]
                                        (template_literal) ; [6, 18] - [6, 19]
                                        (quoted_template_end))))) ; [6, 19] - [6, 20]
                                (object_end)))) ; [7, 4] - [7, 5]
                          (tuple_end))))) ; [8, 2] - [8, 3]
                  (object_end)))))))))) ; [9, 0] - [9, 1]

When I split I don't get the , added between object items, except when I use force_insert, but then they are everywhere and they aren't removed when I split again 🤔

Am I missing something @Wansmer ?

bew avatar Apr 23 '25 11:04 bew

Am I missing something @Wansmer ?

separator and force_insert are conceptually different things. Since there were no commas in join, so they don't appear when formatting. In your case, object can be processed in the following way:

  object = lang_utils.set_preset_for_dict({
    split = {
      format_tree = function(tsj)
        tsj:remove_child(',')
      end,
    },
    join = {
      force_insert = ',',
      no_insert_if = { lang_utils.helpers.if_penultimate },
    },
  }),

Wansmer avatar Apr 24 '25 07:04 Wansmer

Ah yes that works perfectly, thank you, will open a PR after work 👍

bew avatar Apr 24 '25 12:04 bew

Ah yes that works perfectly, thank you, will open a PR after work 👍

Great! Please don't forget about adding the tests: https://github.com/Wansmer/treesj/blob/main/tests/README.md

Wansmer avatar Apr 24 '25 13:04 Wansmer