LuaScript icon indicating copy to clipboard operation
LuaScript copied to clipboard

OnStyle callback is never called (confirmed also in the example file)

Open meisterluk opened this issue 1 year ago • 2 comments

CustomStyle.lua example file

--[[ An example file

proc clip(int a)
« Clip into the positive zone »
if (a > 0) a
0
end 
]]

-- Define style numbers
S_DEFAULT = 0
S_IDENTIFIER = 1
S_KEYWORD = 2
S_UNICODECOMMENT = 3

-- Anytime a file is switched, check to see if it needs styled
npp.AddEventHandler("OnSwitchFile", function(filename, bufferid)
    if npp:GetExtPart() == ".abc" then
        -- Add the event handler for our custom style function
        npp.AddEventHandler("OnStyle", CustomStyle)
        
        -- Make sure to set the lexer as a custom container
        editor.Lexer = SCLEX_CONTAINER
        
        -- Set up the styles as appropriate
        editor.StyleFore[S_DEFAULT] = 0x7f007f
        editor.StyleBold[S_DEFAULT] = true
        editor.StyleFore[S_IDENTIFIER] = 0x000000
        editor.StyleFore[S_KEYWORD] = 0x800000
        editor.StyleBold[S_KEYWORD] = true
        editor.StyleFore[S_UNICODECOMMENT] = 0x008000
        editor.StyleFont[S_UNICODECOMMENT] = "Georgia"
        editor.StyleItalic[S_UNICODECOMMENT] = true
        editor.StyleSize[S_UNICODECOMMENT] = 9 
        
        -- Clear any style and re-lex the entire document
        editor:ClearDocumentStyle()
        editor:Colourise(0, -1)
    else
        -- Can remove the handler if it's not needed
        npp.RemoveEventHandler("OnStyle", CustomStyle)
    end

    return false
end)

-- Style the document. Handles UTF-8 characters
function CustomStyle(styler)
    identifierCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

    styler:StartStyling(styler.startPos, styler.lengthDoc, styler.initStyle)
    while styler:More() do
        -- Exit state if needed
        if styler:State() == S_IDENTIFIER then
            if not identifierCharacters:find(styler:Current(), 1, true) then
                identifier = styler:Token()
                if identifier == "if" or identifier == "end" then
                    styler:ChangeState(S_KEYWORD)
                end
                styler:SetState(S_DEFAULT)
            end
        elseif styler:State() == S_UNICODECOMMENT then
            if styler:Match("»") then
                styler:ForwardSetState(S_DEFAULT)
            end
        end

        -- Enter state if needed
        if styler:State() == S_DEFAULT then
            if styler:Match("«") then
                styler:SetState(S_UNICODECOMMENT)
            elseif identifierCharacters:find(styler:Current(), 1, true) then
                styler:SetState(S_IDENTIFIER)
            end
        end

        styler:Forward()
    end
    styler:EndStyling()
end
  1. This source defines a function for callback OnSwitchFile. It declares to call CustomStyle for the event OnStyle if the file extension is abc.
  2. My understanding is that editor:Colourise(0, -1) should lead to invocation of callback OnStyle.
  3. Handling the callback OnStyle and thus calling CustomStyle should colorize the document as a consequence.
  4. By adding print() statements and opening the Lua Console, one can observe which functions are actually run.

Expected behavior:

  1. Callback OnSwitchFile is handled.
  2. Callback OnStyle is handled.

Actual behavior:

  1. Callback OnSwitchFile is handled.
  2. Callback OnStyle is never handled, thus the function CustomStyle is never called.

This can be confirmed by the resulting styling. The given example document (stored with a filepath ending with .abc) leads to the following coloring:

clip

This coloring (every foreground text color is purple) can be explained by the editor.StyleFore[S_DEFAULT] = 0x7f007f which is run and sets the default color to purple. But the actual styling function CustomStyle is not run.

Environment:

  • Windows 10
  • LuaScript v0.12 (64 bit). Lua 5.3.5
  • Seems like the OnStyle handling should be triggered here but SCN_STYLENEEDED does not seem to be a received Scintilla notification.

meisterluk avatar Aug 27 '24 10:08 meisterluk

Thanks for opening this and looking into it. It looks like Scintilla has been updated quite a bit for Notepad++ and this is causing the issue.

Scintilla (i.e. the editor) now sets lexers differently and using editor.Lexer = SCLEX_CONTAINER is no longer supported by Scintilla. It use to be you could use the lexer ID (e.g. SCLEX_CONTAINER) in this case, but now you have to instantiate the lexer and then pass that newly created lexer to Scintilla.

According to their documentation the lexer would need to be set to null using the SetILexer() call...but since this is new to Scintilla LuaScript does not support this function call. I'd be willing to accept a PR but probably won't be fixing this myself as I haven't done Notepad++ plugin development in quite a while.

dail8859 avatar Aug 27 '24 12:08 dail8859

I see, thank you for your analysis. I am afraid I have no experience with Scintilla / Npp plugin development and don't have the time available to study it right now. Let us keep the issue open then.

meisterluk avatar Aug 28 '24 21:08 meisterluk