Community
    • Login

    Increasing 30 Style limit for plugin lexers

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    haml
    6 Posts 2 Posters 3.5k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • William NewberyW
      William Newbery
      last edited by

      I am working on a plugin lexer for some
      Ruby on Rails template languages (ERB, Haml, Slim, etc.) and want to include the embedded languages (like the default HTML ones).

      Notepad has a styles per language limit (fixed size array to load the XML) while Scintilla allows 256 styles. The builtin lexers use the embedded languages for this, but does not look to be exposed.

      Is there any existing way for a plugin while still using the style configurator (sending a bunch of Scintilla messages to apply them is ok)?

      Or would a small API enhancement be required, and what would be the process for getting it accepted?

      1 Reply Last reply Reply Quote 0
      • dailD
        dail
        last edited by

        Is there any existing way for a plugin while still using the style configurator

        The style configurator is not exposed by the API at all.

        (sending a bunch of Scintilla messages to apply them is ok)

        You can completely circumvent the style configurator by sending your own Scintilla messages if you really want to, but then everything would be hard coded, which may be sufficient for what you are doing.

        Or would a small API enhancement be required, and what would be the process for getting it accepted?

        In theory if it is just changing a #define in the code then it shouldn’t be a problem to submit a pull request on github.

        1 Reply Last reply Reply Quote 0
        • William NewberyW
          William Newbery
          last edited by William Newbery

          I spent some time looking through what is there and would be more than just a define. Based on how the builtin lexers do it and having played with a few things I think the options are.

          1. Create an interface (like IDocument) with a couple methods like addLang (npp already has suitable functions to implement it) and pass it to the lexer via the Scintilla API when setting an external lexer. npp does this when opening files, switching tabs, style config changes, etc. and is how built in lexers do this, just without the interface.

          2. As 1. but use NPP messages and notifications rather than an interface/Scintilla API.

          3. As 2., but just the single set message. Plugins need to listen to several events to avoid bugs, due to the different places npp resets the lexer and styles. I think I found all the relevant indirect events, but hard to be sure.

          1 Reply Last reply Reply Quote 0
          • dailD
            dail
            last edited by

            Yeah its possible it is alot more complicated than what I stated since I never looked into it in detail. Keep in mind if any modifications need done within the “scintilla” directory then these would need submitted to the Scintilla project. Notepad++ just uses Scintilla as is.

            1 Reply Last reply Reply Quote 0
            • William NewberyW
              William Newbery
              last edited by William Newbery

              I’m pretty certain there is no issue with Scintilla here for what I want, since its the same as the existing lexers. The issue is just that Notepad++ hardcodes its lexers (a subset of the current Scintilla lexers, plus a custom one for the search results window) in using other Notepad++ API’s that are not part of the plugin interface when it comes to configuring them. The “external lexer” Notepad++ configuration code is separate in many places (presumably because the builtin ones were done first, and never refactored to use common code).

              1 Reply Last reply Reply Quote 0
              • William NewberyW
                William Newbery
                last edited by

                Took a quick shot a 1, would look something like:

                //PluginInterface.h
                static const int NPPLEX_SET = 1;
                // Configure a Scintilla lexer when it is being set as the active lexer
                // This is passed to the ILexer via PrivateCall(NPP_LEX_SET, ISetLexerConfig)
                class ISetLexerConfig
                {
                public:
                	// The Scintilla window this lexer is for
                	virtual HWND getScintilla() = 0;
                	// Adds the styles defined by a language (overwrites any existing style with the same ID)
                	// By default Notepad++ will have added the styles for the lexers own language already
                	virtual void addStyles(const TCHAR *languageName) = 0;
                };
                
                //ScintillaEditView.cpp end of void ScintillaEditView::setExternalLexer(LangType typeDoc)
                class SetLexerConfig : public ISetLexerConfig
                {
                public:
                	explicit SetLexerConfig(ScintillaEditView *self) : _self(self) {}
                	virtual HWND getScintilla()override
                	{
                		return _self->getHSelf();
                	}
                	virtual void addStyles(const TCHAR *languageName)override
                	{
                		LexerStyler *pStyler = (_self->_pParameter->getLStylerArray()).getLexerStylerByName(languageName);
                		if (pStyler)
                		{
                			for (int i = 0; i < pStyler->getNbStyler(); ++i)
                			{
                				_self->setStyle(pStyler->getStyler(i));
                			}
                		}
                	}
                private:
                	ScintillaEditView *_self;
                };
                SetLexerConfig setLexerConfig(this);
                execute(SCI_PRIVATELEXERCALL, NPPLEX_SET, reinterpret_cast<LPARAM>(&setLexerConfig));
                

                Then the lexer can just do something like:

                config->addStyles(L"Scss");
                config->addStyles(L"Javascipt");
                config->addStyles(L"Markdown");
                config->addStyles(L"Ruby");
                

                As well as having a convenient handle to the Scintilla control for more advanced things outside the Notepad++ style GUI.

                Not really looked at the “word lists” yet, but should be same idea (maybe included in addStyles).

                It also occurred to me that maybe some of this could be put in the XML file, which I guess would be approach 4.

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                The Community of users of the Notepad++ text editor.
                Powered by NodeBB | Contributors