Multiline class properties break indentation #47

Closed
Ilyes512 opened this Issue May 6, 2016 · 6 comments

Projects

None yet

4 participants

@Ilyes512
Ilyes512 commented May 6, 2016

So, today I found out that a multiline class property breaks the indentation for the file. I will try and describe it by giving example's:

I start of with the below, where //[] equals my current cursor position with insert-mode:

<?php

class testing
{
    protected $testing = 'This is a multiline
        property value
        that continues over multiple
        lines';//[]
}

When I hit return the cursor goes to the next line, but the indent is wrong:

<?php

class testing
{
    protected $testing = 'This is a multiline
        property value
        that continues over multiple
        lines';
//[]
}

Note the cursor position. So if I start inserting the next property without hitting tab again I get this:

<?php

class testing
{
    protected $testing = 'This is a multiline
        property value
        that continues over multiple
        lines';

protected $foobar;

}

Even when I manually override the spacing and insert the tabs after the fact like this:

<?php

class testing
{
    protected $testing = 'This is a multiline
        property value
        that continues over multiple
        lines';

    protected $foobar;

    public function __construct() {
        echo 'hello world';
    }
}

Once I hit gg=G to reformat the current file's spacing. It changes it to:

<?php

class testing
{
    protected $testing = 'This is a multiline
        property value
        that continues over multiple
        lines';

protected $foobar;

public function __construct() {
    echo 'hello world';
}
}

I am not really sure if it's my configuration or the plugin it self. My dotfiles can be found in my repository on github right here. More specifically my .vimrc can be found here and my plugin file here.

I can also tell you that vim does recognize the file as php (:set filetype? returns filetype=php). If you need some more info just ask. I can usually answer very quickly (if I can).

@h3xx
h3xx commented May 6, 2016

Something I noticed was that the semicolon placement matters:

class testing {
    protected $testing = 'This is a multiline
        property'
;
    protected $foobar;
}

The $foobar property indents correctly.

@2072
Owner
2072 commented May 8, 2016

I'll check this out but you should use heredoc/nowdoc notation which is properly supported and reliable. Multi-line strings are very difficult to identify correctly (without a real parser) and insert an uncontrollable number of spaces in your strings...

@Ilyes512
Ilyes512 commented May 8, 2016

@2072 I understand there is heredoc/nowdoc, but ideally I would still like to use multiline properties anyways.

I understand that this might be hard or even not feasible. I still would like to thank you for you time in any case :)

(BTW I don't know how this plugin works, still a noob with Vim. I will try and understand how it's implemented to get a feeling.)

@andrey-utkin
andrey-utkin commented Jun 2, 2016 edited

Experiencing similar difficulty. In a codebase of a project I'm participating in, we have SQL queries formatted as quoted.

<?php

class A
{
    public function a()
    {
        $query =
            "UPDATE mytable
                SET a = 'a'
          RETURNING *";

        $a = f("a", "b",
               "c");
    }
}

And when you go to edit $a = f("a", "b", to move "b" to next line, you get:

<?php

class A
{
    public function a()
    {
        $query =
            "UPDATE mytable
                SET a = 'a'
          RETURNING *";

$a = f("a",
    "b",
               "c");
    }
}

What is most annoying is that alignment of the beginning of the line, $a = f("a",, gets messed up.

Is there any flag i could tweak?

@2072
Owner
2072 commented Jun 2, 2016

I have no time to look into this right now or any time soon (not before the end of July).

Besides using here/nowdoc (which also adds the benefit of enabling syntax highlighting if you use the SQL keyword) one could also write this kind of code in the following way:

class A
{
    public function a()
    {
        $query =
            "UPDATE mytable"
            ." SET a = 'a'"
            ." RETURNING *";

        $a = f("a", "b",
            "c");
    }
}

This is quite cleaner and avoids passing random spaces/tabs/line breaks to your query parser...

And with nowdoc style:

class A
{
    public function a()
    {
        $query = <<<'SQL'
            UPDATE mytable
                SET a = 'a'
          RETURNING *
SQL;

        $a = f("a",
            "b",
            "c");
    }
}
@2072 2072 added a commit that closed this issue Oct 2, 2016
@2072 Fix #47: Prevent multi-line strings declaration from breaking indenta…
…tion.

This seems to be working in most cases but I'm sure this will break again as there is no way to handle multi-line strings declaration properly without a real parser...
facba65
@2072 2072 closed this in facba65 Oct 2, 2016
@2072
Owner
2072 commented Oct 2, 2016

OK this is fixed for now but as expected it was quite annoying to do. It may break again depending on what text you write in your multi-line strings... I've added a fail-safe to prevent breaking indentation if the start of the multi-line string declaration cannot be found.

As stated in #22 (comment), the safest way to write these is:

class testing
{
    protected $testing = '
        This is an ugly multiline
        property value
        that continues over multiple
        lines';
}

so that, just like with herdoc, there is a way to look for the start of the declaration while safely skipping the string's content...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment