internal/lsp: implement ConvertToStruct code action
With the cursor on `b`, we want to transform:
a: b: whatever
into
a: {
b: whatever
}
Fun complications:
* `whatever` can be multi-line
* field names can be nested. For example:
a: [{x: y: z: _, w: "foo"}.w]: {}
with the cursor on `y`, we want to transform the inner-most field name
(i.e. `y`). So this gets transformed into:
a: [{x: {
y: z: _
}
w: "foo"}.w]: {}
* in some circumstances, we need to remove commas and spaces. E.g.
a: b: _, x: y: _
becomes (with cursor on `b`):
a: {
b: _
}
x: y: _
Note the comma and space before `x` has gone away.
It turns out that parsing CUE into an AST is lossy: i.e. you can't
reconstruct the original []byte from the AST. Consequently, we can't
make this transformation by adjusting the parsed AST because doing so
would lead to canonically formatting the entire AST which is not what
the user expects. so we are forced into byte splicing.
Fixes #4073
Signed-off-by: Matthew Sackman <matthew@cue.works>
Change-Id: I1d56d5154993e7b28fbdc907672b97827e5ec9d4
Reviewed-on: https://cue.gerrithub.io/c/cue-lang/cue/+/1230699
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>