AndrewRadev/splitjoin.vim

Ignoring trailing whitespaces on join

arashm opened this issue · 10 comments

Having this in a ruby file:

User.select(:first_name, :last_name)
    .distinct
    .joins(:posts)
    .where(
      signed_up: true,
      'posts.subject': 'test'
    )

and trying to join them, gives me this:

User.select(:first_name, :last_name)    .distinct    .joins(:posts)    .where(      signed_up: true,      'posts.subject': 'test'    )

I have added let g:splitjoin_normalize_whitespace = 1 in my vim.rc file, but still no luck. Is there anyway to ignore the initial whitespaces by default whenever doing join?

Unfortunately, the problem is not the whitespace -- this style of joining is not supported yet. What you're seeing is the default J behaviour, I think. The plugin falls back to it if it doesn't find anything it can operate on.

There's a somewhat related issue here: #146. I haven't gotten around to working on it yet, but I'll see what I can do to also add join support for something like this.

I actually have set nojoinspaces enabled, so the J command works fine and removes the initial spaces. I didn't know the plugin fallback to J, seems like J itself works fine, but for some reason not when SplitJoin calls it.

P.S. J still adds one space when joining the lines :/

P.S. J still adds one space when joining the lines :/

Yeah, this is one reason I made splitjoin in the first place :). The normal J almost works for html tags, but not quite.

Anyway, I was slightly wrong. It's not that it falls back to J, it falls back to the normal usage of gJ. You see, gJ is already a built-in, and it simply leaves whitespace as-is, including indentation. You can try it out with the command :normal! gJ. (the full discussion is here, if you're curious: #14).

By the way, just to confirm, when I put the cursor on the first line of your example, and input gJ, I get this:

User.select(:first_name, :last_name)    .distinct
    .joins(:posts)
    .where(
      signed_up: true,
      'posts.subject': 'test'
    )

Is this your experience as well? Or do you get the entire block joined up for some reason? Because that might invalidate my hypothesis.

Is this your experience as well?

I get the same result. Also using :normal! gJ (when selecting the whole block) gives me this:

User.select(:first_name, :last_name)    .distinct
    .joins(:posts)    .where(
      signed_up: true,      'posts.subject': 'test'
    )

which is not better...

Yeah, not very useful :).

Anyway, I'll see what I can do to support this, but no promises on when I can get around to it, I'm afraid.

Thanks Andrew. It's appreciated 👍

Sorry I took a while to get around to this.

I stand slightly corrected on this one:

Unfortunately, the problem is not the whitespace -- this style of joining is not supported yet.

It sort of was, for method calls with trailing dots, I just hadn't documented it :). I extended the functionality to work with leading dots as well, so this should, I think, fix your issue:

Method continuations ~
For the moment, this only works in the direction of joining, since splitting
is too ambiguous (how to decide whether to split the method dot or the
function's arguments?).
>
one.
two.three(foo, bar)
one
.two.three(foo, bar)
one.two.three(foo, bar)

Could you try it out and let me know how it feels to you?

Hey, sorry for late response I thought I use it in real life coding for a while and then comment. It looks really nice and works for method joins. However for method parameters like this, it still doesn't work:

    create(:comb_bet_with_groups,
           group_type: :teased,
           client_id: client.id,
           event: event,
           associated_runner: runner,
           event_type: event.event_type)

Although it works fine if I keep everything in a separate like this:

create(
      :comb_bet_with_groups,
      group_type: :teased,
      client_id: client.id,
      event: event,
      associated_runner: runner,
      event_type: event.event_type
    )

Generally I don't find it as a big issue though. Thank you very much for the effort. It's fantastic!

I think I've fixed your problem with the method parameters, though it depends on the example. Your particular case should immediately join into a single line, but that's because it's one argument and multiple "options". This should also join the same way:

    create(:comb_bet_with_groups, :foo, :bar
           group_type: :teased,
           client_id: client.id)

On the other hand, if the :foo and :bar are on separate lines, it'll join them one by one and only then join the options. The plugin considers "arguments" and "options" (keyword args at the end of the method call) separately. There's a flag that changes the behaviour in some cases, but it wouldn't work this time, I think.

This area is generally a bit messy. Ruby function calls are complicated, both in terms of possible syntaxes, and possible styles. But I think it should work in a useful way now, at least?

Yeah certainly at this point I call this done. Thank you very much for the effort. I close the issue :)