AndrewRadev / sideways.vim

A Vim plugin to move function arguments (and other delimited-by-something items) left and right.
http://www.vim.org/scripts/script.php?script_id=4171
MIT License
481 stars 9 forks source link

Moving last argument when there others with omitted type in Go #21

Open vladimiroff opened 7 years ago

vladimiroff commented 7 years ago

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) { ... }
AndrewRadev commented 7 years ago

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).

vladimiroff commented 7 years ago

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:

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.