diff options
Diffstat (limited to 'lexers/LexLua.cxx')
| -rw-r--r-- | lexers/LexLua.cxx | 150 | 
1 files changed, 94 insertions, 56 deletions
| diff --git a/lexers/LexLua.cxx b/lexers/LexLua.cxx index b4a18b3ee..9e6e8a70c 100644 --- a/lexers/LexLua.cxx +++ b/lexers/LexLua.cxx @@ -14,6 +14,8 @@  #include <assert.h>  #include <ctype.h> +#include <string> +  #include "ILexer.h"  #include "Scintilla.h"  #include "SciLexer.h" @@ -82,6 +84,12 @@ static void ColouriseLuaDoc(  		stringWs = lineState & 0x100;  	} +	// results of identifier/keyword matching +	Sci_Position idenPos = 0; +	Sci_Position idenWordPos = 0; +	int idenStyle = SCE_LUA_IDENTIFIER; +	bool foundGoto = false; +  	// Do not leak onto next line  	if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) {  		initStyle = SCE_LUA_DEFAULT; @@ -177,40 +185,32 @@ static void ColouriseLuaDoc(  					sc.SetState(SCE_LUA_DEFAULT);  			}  		} else if (sc.state == SCE_LUA_IDENTIFIER) { -			if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) { -				char s[100]; -				sc.GetCurrent(s, sizeof(s)); -				if (keywords.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD); -					if (strcmp(s, "goto") == 0) {	// goto <label> forward scan -						sc.SetState(SCE_LUA_DEFAULT); -						while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) -							sc.Forward(); -						if (setWordStart.Contains(sc.ch)) { -							sc.SetState(SCE_LUA_LABEL); -							sc.Forward(); -							while (setWord.Contains(sc.ch)) -								sc.Forward(); -							sc.GetCurrent(s, sizeof(s)); -							if (keywords.InList(s)) -								sc.ChangeState(SCE_LUA_WORD); -						} -						sc.SetState(SCE_LUA_DEFAULT); -					} -				} else if (keywords2.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD2); -				} else if (keywords3.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD3); -				} else if (keywords4.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD4); -				} else if (keywords5.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD5); -				} else if (keywords6.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD6); -				} else if (keywords7.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD7); -				} else if (keywords8.InList(s)) { -					sc.ChangeState(SCE_LUA_WORD8); +			idenPos--;			// commit already-scanned identitier/word parts +			if (idenWordPos > 0) { +				idenWordPos--; +				sc.ChangeState(idenStyle); +				sc.ForwardBytes(idenWordPos); +				idenPos -= idenWordPos; +				if (idenPos > 0) { +					sc.SetState(SCE_LUA_IDENTIFIER); +					sc.ForwardBytes(idenPos); +				} +			} else { +				sc.ForwardBytes(idenPos); +			} +			sc.SetState(SCE_LUA_DEFAULT); +			if (foundGoto) {					// goto <label> forward scan +				while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) +					sc.Forward(); +				if (setWordStart.Contains(sc.ch)) { +					sc.SetState(SCE_LUA_LABEL); +					sc.Forward(); +					while (setWord.Contains(sc.ch)) +						sc.Forward(); +					char s[100]; +					sc.GetCurrent(s, sizeof(s)); +					if (keywords.InList(s))		// labels cannot be keywords +						sc.ChangeState(SCE_LUA_WORD);  				}  				sc.SetState(SCE_LUA_DEFAULT);  			} @@ -284,6 +284,66 @@ static void ColouriseLuaDoc(  					sc.Forward();  				}  			} else if (setWordStart.Contains(sc.ch)) { +				// For matching various identifiers with dots and colons, multiple +				// matches are done as identifier segments are added. Longest match is +				// set to a word style. The non-matched part is in identifier style. +				std::string ident; +				idenPos = 0; +				idenWordPos = 0; +				idenStyle = SCE_LUA_IDENTIFIER; +				foundGoto = false; +				int cNext; +				do { +					int c; +					const Sci_Position idenPosOld = idenPos; +					std::string identSeg; +					identSeg += static_cast<char>(sc.GetRelative(idenPos++)); +					while (setWord.Contains(c = sc.GetRelative(idenPos))) { +						identSeg += static_cast<char>(c); +						idenPos++; +					} +					if (keywords.InList(identSeg.c_str()) && (idenPosOld > 0)) { +						idenPos = idenPosOld - 1;	// keywords cannot mix +						ident.pop_back(); +						break; +					} +					ident += identSeg; +					const char* s = ident.c_str(); +					int newStyle = SCE_LUA_IDENTIFIER; +					if (keywords.InList(s)) { +						newStyle = SCE_LUA_WORD; +					} else if (keywords2.InList(s)) { +						newStyle = SCE_LUA_WORD2; +					} else if (keywords3.InList(s)) { +						newStyle = SCE_LUA_WORD3; +					} else if (keywords4.InList(s)) { +						newStyle = SCE_LUA_WORD4; +					} else if (keywords5.InList(s)) { +						newStyle = SCE_LUA_WORD5; +					} else if (keywords6.InList(s)) { +						newStyle = SCE_LUA_WORD6; +					} else if (keywords7.InList(s)) { +						newStyle = SCE_LUA_WORD7; +					} else if (keywords8.InList(s)) { +						newStyle = SCE_LUA_WORD8; +					} +					if (newStyle != SCE_LUA_IDENTIFIER) { +						idenStyle = newStyle; +						idenWordPos = idenPos; +					} +					if (idenStyle == SCE_LUA_WORD)	// keywords cannot mix +						break; +					cNext = sc.GetRelative(idenPos + 1); +					if ((c == '.' || c == ':') && setWordStart.Contains(cNext)) { +						ident += static_cast<char>(c); +						idenPos++; +					} else { +						cNext = 0; +					} +				} while (cNext); +				if ((idenStyle == SCE_LUA_WORD) && (ident.compare("goto") == 0)) { +					foundGoto = true; +				}  				sc.SetState(SCE_LUA_IDENTIFIER);  			} else if (sc.ch == '\"') {  				sc.SetState(SCE_LUA_STRING); @@ -321,28 +381,6 @@ static void ColouriseLuaDoc(  		}  	} -	if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') { -		char s[100]; -		sc.GetCurrent(s, sizeof(s)); -		if (keywords.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD); -		} else if (keywords2.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD2); -		} else if (keywords3.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD3); -		} else if (keywords4.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD4); -		} else if (keywords5.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD5); -		} else if (keywords6.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD6); -		} else if (keywords7.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD7); -		} else if (keywords8.InList(s)) { -			sc.ChangeState(SCE_LUA_WORD8); -		} -	} -  	sc.Complete();  } | 
