diff options
author | Kein-Hong Man <unknown> | 2018-03-08 07:54:20 +1100 |
---|---|---|
committer | Kein-Hong Man <unknown> | 2018-03-08 07:54:20 +1100 |
commit | fede631dfa75dd8518bbde5b845a9da7d133ce24 (patch) | |
tree | 42bfef8081830b6baeac987ef75fae375ad51bd8 | |
parent | bb59ac2319ce5229d021c4a0496b1931ad4684c3 (diff) | |
download | scintilla-mirror-fede631dfa75dd8518bbde5b845a9da7d133ce24.tar.gz |
Backport: Bug [#1952]. Match identifier chains with dots and colons.
Backport of changeset 6475:8fb85a29591f.
-rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
-rw-r--r-- | lexers/LexLua.cxx | 150 |
2 files changed, 98 insertions, 56 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 61f6680d9..8557f5895 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -601,6 +601,10 @@ <a href="http://sourceforge.net/p/scintilla/bugs/1999/">Bug #1999</a>. </li> <li> + Lua lexer matches identifier chains with dots and colons. + <a href="http://sourceforge.net/p/scintilla/bugs/1952/">Bug #1952</a>. + </li> + <li> Fix HTML lexer handling of Django so that nesting a {{ }} or {% %} Django tag inside of a {# #} Django comment does not break highlighting of rest of file </li> 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(); } |