jcberquist / sublimetext-cfml

CFML (ColdFusion and Lucee) package for Sublime Text
MIT License
115 stars 24 forks source link

<cffunction> Autocomplete Not Reading Local Artifacts #115

Closed Moonsword22 closed 6 years ago

Moonsword22 commented 6 years ago

Autocomplete inside a <cffunction> tag is not reading from the artifacts within the page, either directly within the function body or within an embedded <cfscript> tag. It looks like this is a scope issue because inside a <cfquery> tag, either within or outside a <cffunction> tag, everything works normally.

The behavior has been encountered on Sublime Text v3.1 and the most recent CFML package on Windows 10. Two separate installs of Sublime Text on two unconnected machines (one is my home PC, the other my desktop at work) have the same behavior. The home PC never had the CFML package installed until tonight so it does not appear to be a package upgrade problem.

If need be, I can force one of the machines back to an older version of Sublime to see if this is a regression from Sublime Text v3.1.

The below code demonstrates the scoping weirdness as best I've been able to determine it with code comments on what happens in each situation.

<cfcomponent>
    <cfset variables.nComponentId = 1>

    <cfscript>
        // Autocomplete works
        variables.nComponentId = 2;

        // Autocomplete works
        nFunctionId = 0;
    </cfscript>

    <cfquery name="variables.qFoo">
        DECLARE @componentId INT = <cfqueryparam cfsqltype="cf_sql_integer" value="#variables.nComponentId#">

        SELECT *
        FROM component
        WHERE
            nComponentId = @nComponentId
    </cfquery>

    <!--- Autocomplete works --->
    <cfset variables.qFoo.nComponentId>

    <cffunction name="functionGoesHere">
        <!--- Autocomplete does not work --->
        <cfset local.nFunctionId = 1>

        <cfscript>
            // Autocomplete does not work from the rest of the page on a scoped variable
            local.nFunctionId = 2;

            // Autocomplete works from the rest of the page on an unscoped reference
            nComponentId = 3;
        </cfscript>

        <cfquery name="local.qBar">
            -- Autocomplete works
            DECLARE @nFunctionId INT  = <cfqueryparam cfsqltype="cf_sql_integer" value="#local.nFunctionId#">

            SELECT *
            FROM function
            WHERE
                nFunctionId = @nFunctionId
        </cfquery>

        <!--- Autocomplete does not work --->
        <cfset local.qBar.nFunctionId>
    </cffunction>
</cfcomponent>
jcberquist commented 6 years ago

Thank you for the detailed report. I think that the reason this is happening is a bit complex. The completions that are missing are completions that are normally supplied by Sublime Text itself. It seems that inside of a text.html scope from the syntax highlighter those completions are filtered out. The body of <cffunction> tags include such a scope (text.html.cfml) because it is possible to include arbitrary HTML inside them (really any text, if output=true for the function; all such text gets included in the output). A quick workaround is to use the All Autocomplete package, which will restore those completions.

I think I might need to be more restrictive highlighting HTML inside of the CFML functions, but I will need to consider that some more.

Moonsword22 commented 6 years ago

Thanks for the workaround recommendation - I'd seen it in the settings when I was trying to figure out if something about the update broke this. It does indeed function as a workaround so I may wind up forwarding that out to the rest of my team.

Is it possible to block the text.html scope from inside <cfscript> blocks? You should only see HTML in CF Script within an output() function or a string, the latter of which probably isn't formatted anyway.

jcberquist commented 6 years ago

I have traced this back to the default HTML package and specifically to this completion provider: https://github.com/sublimehq/Packages/blob/master/HTML/html_completions.py - when it runs, it explicitly inhibits the Sublime Text provided completions (using the flags sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS). This does run inside <cffunction> tags since I am highlighting HTML inside of them, and that is why the buffer completions are missing.

I do think your suggestion might be the solution to this. Newer ST builds allow one to remove parent scopes from specific contexts, so I think it is possible to remove the text.html.cfml scope from inside <cfscript> blocks and from the script in <cfset> tags and the like. I don't think it will have any undesired side effects to remove that scope, but I want to look around a little more before making the change.

Moonsword22 commented 6 years ago

We write enough business logic in tags at the office I'd prefer to fix the problem entirely. All Autocomplete is functional, though.

But fixing the script tags would be an improvement.

jcberquist commented 6 years ago

I have pushed an update that removes the text.html.cfml scope when writing cfscript inside tags. Testing with your example code above, this seems to work. Let me know if this update fixes this issue for you.

Moonsword22 commented 6 years ago

Yep, it worked for the <cfscript> tags.

Is there any chance of getting the <cffunction> tags working as well? Like I said, the way we write code, there's a fair bit of logic inside tags in our utility CFCs so I'd like to squash that if possible as well. I fully understand if that's not practical at the moment. Your prompt assistance with this has been greatly appreciated.

As noted, All Autocomplete is working well as a stand-in. (I ran the test at home, which doesn't have that package installed.)

jcberquist commented 6 years ago

Could you say more about where it is still not working? Like I said, I tested with your example code above, and I thought that in every place where you indicated you were not getting buffer suggestions before it now works.

Moonsword22 commented 6 years ago

Finally noticing this, sorry for the delay over the weekend. I just double-checked. Everything is working.

Thanks for your help!

jcberquist commented 6 years ago

Glad to hear it.