Home > database >  Sort a property in HCL Block
Sort a property in HCL Block

Time:02-23

I would like to move name property to the top of the block like this.

There are many resouce block in a file.

Before

resource "datadog_monitor" "A" {
  enable_logs_sample   = "true"
  name                 = "name"
  tags                 = ["env:dev"]
}

resource "datadog_monitor" "B" {
  enable_logs_sample   = "true"
  name                 = "name"
  tags                 = ["env:dev"]
}

After

resource "datadog_monitor" "A" {
  name                 = "name"
  enable_logs_sample   = "true"
  tags                 = ["env:dev"]
}

resource "datadog_monitor" "B" {
  name                 = "name"
  enable_logs_sample   = "true"
  tags                 = ["env:dev"]
}

CodePudding user response:

OK, I think :help :global and the range/address mechanism is one of Vim's best and most underrated feature so it might deserve a detailed run down.

The core editing pattern is the same as in the commands I suggested in my previous answer to a similar question of yours:

  • on each line matching a specific regular expression pattern,
  • do something.

Note that it is a "pattern", not a one-off trick. You are not supposed to "learn" this answer by heart, or commit it to "muscle memory", or bookmark it for the next time you have the exact same problem. Instead, you are supposed to grok the logic behind it in a way that allows you to:

  • recognize a situation where it might come handy,
  • apply it without too much thinking.

So, in order to implement the editing pattern described above, we use the :global command, which works like this:

:[range]global/<pattern>/[range]<command>

where:

  • in range (optional, default is %),
  • mark each line matching <pattern>,
  • then execute <command> on range (optional, default is .).

Like lots of things in Vim, :global is conceptually cool but not necessarily useful on its own. The more familiar you are with ranges/addresses and the more Ex commands you know, the more useful it is.

In this specific case, ranges don't matter much but addresses and Ex commands do… and their sum makes problems like these solvable in, IMO, a pretty intuitive way.

Now, let's go back to our problem:

move every "name" line to the top of the block

and express it in terms that match our editing pattern:

  • mark every line matching name,
  • then move it below the closest line above matching resource.

Which is a simple:

:g/name/m?resource?

Of course, the exact regular expression patterns to use are context-dependent.

The trick is to internalize the patterns so that you already know how to use any new building block you might come upon.

There is really nothing even remotely god-like, here.

  • Related