I just tested with the WPF branch, and it worked just fine for me. The C# code for the lexer is:
And the XML for the configuration (I borrowed VBScript's keyword list to test with) is:
Which branch of ScintillaNET are you using this with?
using System; using System.Drawing; using System.Collections.Generic; namespace ScintillaNET.Lexers { publicsealedclass BBLexer : CustomLexer { privateconstint STYLE_COMMENT = 1; privateconstint STYLE_NUMBER = 2; privateconstint STYLE_KEYWORD = 3; privateconstint STYLE_STRING = 4; privateconstint STYLE_OPERATOR = 6; privateconstint STYLE_IDENTIFIER = 7; privateconstint KEYWORDS_KEYWORDS = 0; privateconstint KEYWORDS_USER1 = 1; privateconstint KEYWORDS_USER2 = 2; privateconstint KEYWORDS_USER3 = 3; publicoverride Dictionary<string, int> StyleNameMapping { get { returnnew Dictionary<string, int>() { { "Comment", STYLE_COMMENT }, { "Number", STYLE_NUMBER }, { "Keyword", STYLE_KEYWORD }, { "Keyword1", STYLE_KEYWORD }, { "String", STYLE_STRING }, { "Operator", STYLE_OPERATOR }, { "Identifier", STYLE_IDENTIFIER }, }; } } publicoverride Dictionary<string, int> KeywordNameMapping { get { returnnew Dictionary<string, int>() { { "Keywords", KEYWORDS_KEYWORDS }, { "User1", KEYWORDS_USER1 }, { "User2", KEYWORDS_USER2 }, { "User3", KEYWORDS_USER3 }, }; } } // Setuppublicoverridestring LexerName { get { return"bb_script"; } } protectedoverridebool EnableCompositeKeywords { get { returntrue; } } protectedoverridebool LowerKeywords { get { returntrue; } } public BBLexer(Scintilla scintilla) : base(scintilla) { } protectedoverridevoid Initialize() { EnsureCompositeKeywords( new KeyValuePair<int, int>(KEYWORDS_KEYWORDS, STYLE_KEYWORD), new KeyValuePair<int, int>(KEYWORDS_USER1, STYLE_KEYWORD), new KeyValuePair<int, int>(KEYWORDS_USER2, STYLE_KEYWORD), new KeyValuePair<int, int>(KEYWORDS_USER3, STYLE_KEYWORD) ); base.Initialize(); Scintilla.Indentation.SmartIndentType = SmartIndent.None; } privateenum State : int { Unknown = STATE_UNKNOWN, Identifier, Number, String, Comment, Operator, } newprivate State CurrentState { get { return (State)base.CurrentState; } set { base.CurrentState = (int)value; } } protectedoverridevoid Style() { StartStyling(); while (!EndOfText) { switch (CurrentState) { case State.Unknown: bool consumed = false; switch (CurrentCharacter) { case';': CurrentState = State.Comment; break; case'"': CurrentState = State.String; break; default: if (IsDigit(CurrentCharacter) || (CurrentCharacter == '.'&& IsDigit(NextCharacter))) { CurrentState = State.Number; } elseif (IsOperator(CurrentCharacter)) { CurrentState = State.Operator; } elseif (IsIdentifierStart(CurrentCharacter)) { CurrentState = State.Identifier; } elseif (IsWhitespace(CurrentCharacter)) { ConsumeWhitespace(); consumed = true; } break; } if (!consumed) Consume(); break; /*////////////////////////////////////////////////////////////////// * Identifier *///////////////////////////////////////////////////////////////// case State.Identifier: if (!IsIdentifier(CurrentCharacter)) { string ident = GetRange(CurrentBasePosition, CurrentPosition).ToLower(); int style; if (CompositeKeywords.TryGetValue(ident, out style)) { Console.WriteLine(ident); SetStyle(style); //SetStyle(STYLE_IDENTIFIER); } else { SetStyle(STYLE_IDENTIFIER); } CurrentState = State.Unknown; } else Consume(); break; /*////////////////////////////////////////////////////////////////// * Numbers *//////////////////////////////////////////////////////////////////case State.Number: if (!IsNumber(CurrentCharacter)) { SetStyle(STYLE_NUMBER); CurrentState = State.Unknown; } else Consume(); break; /*////////////////////////////////////////////////////////////////// * Strings *//////////////////////////////////////////////////////////////////case State.String: if (CurrentCharacter == '"') { if (NextCharacter == '"') { Consume(2); } else { Consume(); SetStyle(STYLE_STRING); CurrentState = State.Unknown; } } elseif (IsEndOfLine(CurrentCharacter)) { MarkSyntaxError(CurrentBasePosition, CurrentPosition - CurrentBasePosition); SetStyle(STYLE_STRING); CurrentState = State.Unknown; } else Consume(); break; /*////////////////////////////////////////////////////////////////// * Operators *//////////////////////////////////////////////////////////////////case State.Operator: if (!IsOperator(CurrentCharacter)) { SetStyle(STYLE_OPERATOR); CurrentState = State.Unknown; } else Consume(); break; /*////////////////////////////////////////////////////////////////// * Commented Lines *//////////////////////////////////////////////////////////////////case State.Comment: if (IsEndOfLine(CurrentCharacter)) { Consume(); SetStyle(STYLE_COMMENT); CurrentState = State.Unknown; } else Consume(); break; default: thrownew Exception("Unknown State!"); } } } } }
<?xmlversion="1.0"encoding="utf-8"?><ScintillaNETxmlns="http://scintillanet.codeplex.com/LanguageConfiguration.xsd"><LanguageName="bb_script"><IndentationTabWidth="4"/><LexerLineCommentPrefix=";"><KeywordsName="Keywords"Inherit="False"> addhandler addressof andalso alias and ansi as assembly attribute auto begin boolean byref byte byval call case catch cbool cbyte cchar cdate cdec cdbl char cint class clng cobj compare const continue cshort csng cstr ctype currency date decimal declare default delegate dim do double each else elseif end enum erase error event exit explicit false finally for friend function get gettype global gosub goto handles if implement implements imports in inherits integer interface is let lib like load long loop lset me mid mod module mustinherit mustoverride mybase myclass namespace new next not nothing notinheritable notoverridable object on option optional or orelse overloads overridable overrides paramarray preserve private property protected public raiseevent readonly redim rem removehandler rset resume return select set shadows shared short single static step stop string structure sub synclock then throw to true try type typeof unload unicode until variant wend when while with withevents writeonly xor </Keywords></Lexer></Language></ScintillaNET>