phplaravelsublimetextphpdocsublimetext4

How can I add custom/dynamic/magic PHP function definitions to Sublime Text?


I know Sublime Text isn't an IDE, but that's what I like about it. Still, it's nice to have certain IDE-esque functionality from time to time.

Mostly for use with Laravel, I'd like the ability for Sublime to find definitions of symbols that aren't defined in a standard PHP way, eg.

public function truncate()

I have a Str macro defined called truncate, but Sublime (and various packages I've tried) don't recognize this as a symbol obviously.

It would be amazing to write a doc block above the macro definition that Sublime Text would recognize as a symbol when its goto_definition is called. Maybe something like:

    /**
     * @method Str::truncate()
     * ...or...
     * @function truncate()
     */
    Str::macro('truncate', fn() => '...');

The same concept could be applied to magic methods that use __call(). I've seen other developers list magic or inherited properties in doc blocks on classes possibly for their editor/IDE of choice, but it could just be considerate coders conscious of human readability.

I assume that PHP Storm and similar are smart enough or tailored toward these Laravel concepts to achieve this, but I'm not sure how I can configure or extend Sublime for this use case. I have seen some reference to custom symbol recognition in Sublime but I recall it being pretty complicated without much documentation or examples.

I'm sure there are various ways to accomplish this, but I've yet to see anything promising. Any ideas?


Solution

  • Sublime Text relies on the scopes assigned to the text by the syntax definition. Sublime automatically adds text matching certain scopes to the symbol index. (Which can be configured to include additional scopes.)

    Currently, the PHP syntax definition doesn't scope the text after @method or @function in a docblock as anything special. So, we'll need to rectify that.

    Firstly, install https://packagecontrol.io/packages/OverrideAudit if you haven't already, it makes tracking changes made to package files much easier.

    Then, open the Command Palette, and type OA: Open and select OverrideAudit: Open Resource. Navigate to PHP. Navigate to PHP Source.sublime-syntax.

    Search for # Annotations from PHPUnit i.e. https://github.com/sublimehq/Packages/blob/3de7248f8a27fc329f930dd5cb28e6f16b2c751e/PHP/PHP%20Source.sublime-syntax#L1685

    Under that line, paste in the following:

        - match: \@(function)\b
          scope: keyword.other.phpunit.php
          push:
            - match: \w+
              scope: entity.name.function.php
            - match: (?=\S)
              pop: true
    

    indentation is important, so make sure the - is directly under the #.

    Save the file.

    Then, go back to your PHP file, and press F12 when your caret is next to the word truncate and it will go to the @function truncate() line. (You'll see truncate colored as a function definition even though it is inside the comment.)

    @function