sideways.vim
sideways.vim copied to clipboard
Moving last argument when there others with omitted type in Go
Suppose we have the function foo defined as follows:
func foo(a string, b string) { ... }
Given that both arguments are of the same type we could omit the type declaration of a:
func foo(a, b string) { ... }
In that case when moving any of the arguments, a becomes the last argument without declared type, which is invalid Go code:
func foo(b string, a) { ... }
Unfortunately, I can't think of any way to implement this properly in the plugin. The way it works is with simple patterns for the start/end pair of brackets, and for the delimiter: https://github.com/AndrewRadev/sideways.vim/blob/2d5cd2b3cb853067f192cd0e445c35e6007d6fe3/plugin/sideways.vim#L11-L16. I can't really imagine a set of patterns that would do the trick. I tried a few hacks, but they end up too ambiguous. If you can come up with a valid description that'll do the trick, feel free to post one, and I could try it out, see if I can get it to work.
The only working idea I can think of is to transform the a, b string into a string, b string beforehand, swap or edit as needed, and then compact arguments and types again. The transformation might be implementable via https://github.com/AndrewRadev/switch.vim (though I'm not 100% sure about that, either, would have to try it out).
I can't really imagine a set of patterns that would do the trick. I tried a few hacks, but they end up too ambiguous.
Yeah, me neither. Especially when decided to dig more into generalizing the issue. It's more complicated than what I first thought. Can think of at least two more problematic cases:
-
If only the left argument has a type and there are more argument before: For example in
foo(a, b int, c, d string)swappingbandcshould result tofoo(a int, c string, b int, d string). -
There's a case when both arguments about to be swapped have a type and things are still complicated: Suppose we have
foo(a, b int, c string)and we decide to swapbandc. Then if the plugin simply swaps them will actually change the type ofafrominttostring.
The only working idea I can think of is to transform the a, b string into a string, b string beforehand, swap or edit as needed, and then compact arguments and types again. The transformation might be implementable via https://github.com/AndrewRadev/switch.vim (though I'm not 100% sure about that, either, would have to try it out).
Yeah, that will fix it but gofmt (even when called with -s simplify code) doesn't compact function arguments (nor any other tool I can think of) and calling sideways on a function will effectively mean compact argument's types at the end.
On the other hand, based on my experience and looking around in the standard library compacting argument's types when possible seems like widely accepted implicit convention. So it might not be the worst idea ever.
In any case, I would love if you get the transform -> move -> compact approach working, but at the same time completely understand if you decide to close this and decide to not fix it at all.