Reputation: 351
I would like to sort an HCL block with env
Before
resource "datadog_monitor" "A" {
tags = ["env:stg"]
}
resource "datadog_monitor" "B" {
tags = ["env:dev"]
}
After
resource "datadog_monitor" "B" {
tags = ["env:dev"]
}
resource "datadog_monitor" "A" {
tags = ["env:stg"]
}
Upvotes: 0
Views: 97
Reputation: 196751
The usual way is to squeeze the blocks into single lines, sort those lines, and then expand the blocks back to their original form. Assumption: the buffer only contains those blocks.
Squeeze
:[range]g/^res/.,/^}/s/\n/§
Explanation:
res
in [range]
(%
by default),\n
with a fancy character §
.Result:
resource "datadog_monitor" "A" {§ tags = ["env:stg"]§}§
resource "datadog_monitor" "B" {§ tags = ["env:dev"]§}§
Sort
:[range]sort /env/
Explanation:
[range]
(%
by default),env
.Result:
resource "datadog_monitor" "B" {§ tags = ["env:dev"]§}§
resource "datadog_monitor" "A" {§ tags = ["env:stg"]§}§
Unsqueeze
:[range]g/^res/s/§/\r/g
Explanation:
res
in [range]
(%
by default),§
with the appropriate EOL character.Result:
resource "datadog_monitor" "B" {
tags = ["env:dev"]
}
resource "datadog_monitor" "A" {
tags = ["env:stg"]
}
See :help :range
, :help :global
, :help :substitute
, :help :sort
.
Upvotes: 1
Reputation: 6026
Well this is not trivial. Vim sort has a regex for sorting patterns.
:'<,'>sort /tags = \["env:/
Does tell vim to ignore everyting up to "env:
and just sort afterwards.
But this applies to lines of codes not blocks. so your code will be split up.
To work around this in vim, one could join the relevant lines together before sorting:
:g/tags/norm JkJ
This allows the sort before to work. Splitting it again then is trivial:
:%s/{/{\r/g
:%s/}/}\r/g
But in the end, I guess there must be better tools than vim for that. Maybe someone knowing awk
really well could create an more elegant solution. (And there are possibly also other vim solutions).
Upvotes: 0