Custom Lexer

Topics: User Forum
Apr 8, 2014 at 3:09 AM
Edited Apr 8, 2014 at 3:10 AM
I know this subject comes up often and I've referred to the WPF branch as instructed in previous posts. I am using the ScintillaNET.dll from the WPF branch, so it includes the Custom Lexer framework from Blah.

I have referenced the new assembly in my project. I have a custom lexer that implements ScintillaNET.Lexers.CustomLexer. I have added the code required to highlight [sections] similar to the way ini lexer works.

I have created the language.xml file and included it as an embedded resource in my project.

I reviewed the ConfigurationManager code and I think I'm on the right path here but may not be. Since the xml is embedded I get a file stream from the assembly's embedded file (my .xml) and called the following:
 myScintillaInstance.ConfigurationManager.Configure( new Configuration( stream, "languageName", true));
It seems to be crashing due to the control not knowing about my custom Lexer class....how can I feed the control that class?

Am I on the right path with this?
Apr 8, 2014 at 11:53 PM
Edited Apr 9, 2014 at 1:51 AM
Update to this:

I went to just using an actual XML file and setting ConfigurationManager.CustomLocation, still no go....
Apr 9, 2014 at 3:58 AM
Edited Apr 9, 2014 at 4:04 AM
Another update for everyone, I don't give up easily.

I found that when a ScintillaNET instance is loaded the following method gets called from the "Custom Lexer Registration" section.
static CustomLexer()
        {
            foreach (var t in typeof(CustomLexer).Assembly.GetTypes())
            {
                if (BasedOnCustomLexer(t) && (t.Attributes & TypeAttributes.Abstract) != TypeAttributes.Abstract)
                {
                    var l = (CustomLexer)Activator.CreateInstance(t, new object[] { null });
                    KnownCustomLexers.Add(((string)t.GetProperty("LexerName").GetValue(l, null)).ToLower(), new CustomLexerDescription(l));
                }
            }

        }
So it appears I needed to get my custom lexer class into the KnownCustomLexers. So I added the following:
Assembly parentAssembly = Assembly.GetEntryAssembly();
            Type customLexerType = typeof(CustomLexer);

            foreach (var t in parentAssembly.GetTypes().Where(e => e.BaseType == customLexerType))
            {
                if (BasedOnCustomLexer(t) && (t.Attributes & TypeAttributes.Abstract) != TypeAttributes.Abstract)
                {
                    var l = (CustomLexer)Activator.CreateInstance(t, new object[] { null });
                    KnownCustomLexers.Add(((string)t.GetProperty("LexerName").GetValue(l, null)).ToLower(), new CustomLexerDescription(l));
                }
            }
Now for this to work I did have to use the System.Linq namespace which meant using .NET 4.5 (I think I could've gone lower I just maxed it). Now when the control loads it looks for CustomLexers in ScintillaNET and my project and loads them all, this allows the custom lexer in my own code to work.

So I could probably have saved myself a lot of time and just added my lexer straight to ScintillaNET instead of trying to find this out.

Hope it helps! Please let me know if I over complicated it!