jacobslusser / ScintillaNET

A Windows Forms control, wrapper, and bindings for the Scintilla text editor.
MIT License
967 stars 245 forks source link

ScintillaNet Keywords #461

Open App-Index opened 5 years ago

App-Index commented 5 years ago

Any help would be much appreciated:

I'm using the SQL Lexer with custom keywords. I've found that keywords are to be separated by TAB or Space when assigned using the .SetKeywords() method.

I'm trying to use syntax colouring for keywords that consists of multiple words e.g. "red sky" but instead this will result in "red" and "sky" being identified as separate keywords.

The .SetKeywords() consists of the following code:

public unsafe void SetKeywords(int set, string keywords)
        {
            set = Helpers.Clamp(set, 0, NativeMethods.KEYWORDSET_MAX);
            var bytes = Helpers.GetBytes(keywords ?? string.Empty, Encoding.ASCII, zeroTerminated: true);

            fixed (byte* bp = bytes)
                DirectMessage(NativeMethods.SCI_SETKEYWORDS, new IntPtr(set), new IntPtr(bp));
        }

Does anyone know how to amend this correctly? I'd really love and much appreciate any help

Alternatively: Is it possible to manually change the ForeColor of a range of characters within the Scintilla control similar to the feature in a RichTextBox, without ever altering any of the properties of Keywords?

tobeypeters commented 5 years ago

If you're asking how to have "red sky" treated as one single keyword ... Not possible. Not without writing your own Lexer. I wrote my own CSharp Lexer, if you want to write your own SQL Lexer.

https://github.com/tobeypeters/CSharpLexer

I might not be the greatest coder in the world. But, it's a starting point. OR if you know c/c++ you can modify Scintillas SQL lexer.

App-Index commented 5 years ago

Hey Tobey, Thanks for your response. Even writing your own Lexer won't solve the issue as keywords are still separated word per word. I

tobeypeters commented 5 years ago

No a custom Lexer would fix it. I mean, you would have to add multiple word checks. If you find a string is it the start of à multiple string keyword? If so, is there a string following it? If so, are the two strings combined a "keyword"? If so, Style it accordingly. If it not, Style both words as a string

That's all you're after ... Isn't it? I'd sit down and write a cheap version to demo it. But, unless I was getting paid upfront to make time to do it... Probably don't have time. Otherwise, I'd just make it and upload it for you.

Edit: I do see your confusion. If you wrote your own Lexer. You would need to create your own SetKeywords(). Like mine, I use a List to store keywords.

public static List KEYWORDS, //Primary keywords CONTEXTUAL_KEYWORDS, //Secondary keywords USER_KEYWORDS; //User-defined keywords

So, obviously, I have to parse the incoming list of keywords. If I wanted to support a list of multi-string keywords, I would use something other than a space character to delimit them. Maybe a comma?

So, yes you couldn't just alter the existing SQL lexer in Scintilla. Because SetKeywords() used space for its delimiter.

Edit 2: Been thinking about this. Thought I had a solution. It'd mostly work. But ... multi-word would suck. Basically, easiest way seems to be completely tokenizing the whole text/section of text up front. Then you could easily check to see what TYPE and what VALUE the next and previous tokens contain. What if you wanted keywords to be 3, 4, 5, etc ... words long? You'd need a flexible system. I'm thinking ... how'd I do it? Got to consider things like different commenting methods and such.

Edit 3: Looking at something similar to what I said in Edit 2. But, using regular expressions to look for the desired multi-string Keywords ... Actually, might be able to do something with this.

tobeypeters commented 5 years ago

If you want to look at my code, I added Multi-String Keyword support to my Scintilla CSharpLexer. It may be a start, for you?

https://github.com/tobeypeters/CSharpLexer

App-Index commented 5 years ago

@tobeypeters you are a first class legend my friend you don't understand how useful this is. <3 for you my G

tobeypeters commented 5 years ago

@Sheikz13 Glad I can help. You will have to alter it to make sure it works as you want with SQL syntax. Kinda, should already? Remember, I'm not the greatest programmer ... but alright. Should be pretty solid?