diff options
-rw-r--r-- | cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | doc/ScintillaHistory.html | 13 | ||||
-rw-r--r-- | include/SciLexer.h | 30 | ||||
-rw-r--r-- | include/Scintilla.iface | 34 | ||||
-rw-r--r-- | lexers/LexSAS.cxx | 220 | ||||
-rw-r--r-- | lexers/LexStata.cxx | 203 | ||||
-rw-r--r-- | src/Catalogue.cxx | 2 | ||||
-rw-r--r-- | win32/scintilla.mak | 6 |
8 files changed, 516 insertions, 0 deletions
diff --git a/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj b/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj index 4658ed67b..e2df2d63d 100644 --- a/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj +++ b/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj @@ -227,6 +227,8 @@ 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; F437405F9F32C7DEFCA38C11 /* LexIndent.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 282E41F3B9E2BFEDD6A05BE7 /* LexIndent.cxx */; }; + FDC7442CAD70B9A67EF1639D /* LexSAS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = A95147A1AB7CADB00DAFE724 /* LexSAS.cxx */; }; + 5F804AA6B60FE695863A39FE /* LexStata.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 7623427695416AB1270EE023 /* LexStata.cxx */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -457,6 +459,8 @@ 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8DC2EF5B0486A6940098B216 /* Scintilla.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Scintilla.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; + A95147A1AB7CADB00DAFE724 /* LexSAS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSAS.cxx; path = ../../lexers/LexSAS.cxx; sourceTree = SOURCE_ROOT; }; + 7623427695416AB1270EE023 /* LexStata.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexStata.cxx; path = ../../lexers/LexStata.cxx; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -640,6 +644,7 @@ 28A7D6041995E47D0062D204 /* LexRegistry.cxx */, 114B6EFB11FA7526004FB6AB /* LexRuby.cxx */, 1160E0371803651C00BCEBCB /* LexRust.cxx */, + A95147A1AB7CADB00DAFE724 /* LexSAS.cxx */, 114B6EFC11FA7526004FB6AB /* LexScriptol.cxx */, 114B6EFD11FA7526004FB6AB /* LexSmalltalk.cxx */, 114B6EFE11FA7526004FB6AB /* LexSML.cxx */, @@ -647,6 +652,7 @@ 114B6F0011FA7526004FB6AB /* LexSpecman.cxx */, 114B6F0111FA7526004FB6AB /* LexSpice.cxx */, 114B6F0211FA7526004FB6AB /* LexSQL.cxx */, + 7623427695416AB1270EE023 /* LexStata.cxx */, 11FDAEB6174E1A9700FA161B /* LexSTTXT.cxx */, 114B6F0311FA7526004FB6AB /* LexTACL.cxx */, 114B6F0411FA7526004FB6AB /* LexTADS3.cxx */, @@ -1112,6 +1118,8 @@ 11FF3FE21810EB3900E13F13 /* LexDMAP.cxx in Sources */, F437405F9F32C7DEFCA38C11 /* LexIndent.cxx in Sources */, 3D994BD7A5EAC4FA5B3CFBDF /* LexMaxima.cxx in Sources */, + FDC7442CAD70B9A67EF1639D /* LexSAS.cxx in Sources */, + 5F804AA6B60FE695863A39FE /* LexStata.cxx in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index ec670d803..8d000f0d8 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -530,6 +530,7 @@ <td>Giuseppe Corbelli</td> <td>Andreas Rönnquist</td> <td>Henrik Hank</td> + <td>Luke Rasmussen</td> </tr> </table> <p> @@ -542,6 +543,18 @@ </li> </ul> <h3> + <a href="https://www.scintilla.org/scite411.zip">Release 4.1.1</a> + </h3> + <ul> + <li> + Released 19 June 2018. + </li> + <li> + Lexers added for SAS and Stata. + <a href="https://sourceforge.net/p/scintilla/feature-requests/1185/">Feature #1185.</a> + </li> + </ul> + <h3> <a href="https://www.scintilla.org/scite410.zip">Release 4.1.0</a> </h3> <ul> diff --git a/include/SciLexer.h b/include/SciLexer.h index f4ef9954b..b6f864c6d 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -136,6 +136,8 @@ #define SCLEX_EDIFACT 121 #define SCLEX_INDENT 122 #define SCLEX_MAXIMA 123 +#define SCLEX_STATA 124 +#define SCLEX_SAS 125 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 @@ -1825,6 +1827,34 @@ #define SCE_EDI_UNA 6 #define SCE_EDI_UNH 7 #define SCE_EDI_BADSEGMENT 8 +#define SCE_STATA_DEFAULT 0 +#define SCE_STATA_COMMENT 1 +#define SCE_STATA_COMMENTLINE 2 +#define SCE_STATA_COMMENTBLOCK 3 +#define SCE_STATA_NUMBER 4 +#define SCE_STATA_OPERATOR 5 +#define SCE_STATA_IDENTIFIER 6 +#define SCE_STATA_STRING 7 +#define SCE_STATA_TYPE 8 +#define SCE_STATA_WORD 9 +#define SCE_STATA_GLOBAL_MACRO 10 +#define SCE_STATA_MACRO 11 +#define SCE_SAS_DEFAULT 0 +#define SCE_SAS_COMMENT 1 +#define SCE_SAS_COMMENTLINE 2 +#define SCE_SAS_COMMENTBLOCK 3 +#define SCE_SAS_NUMBER 4 +#define SCE_SAS_OPERATOR 5 +#define SCE_SAS_IDENTIFIER 6 +#define SCE_SAS_STRING 7 +#define SCE_SAS_TYPE 8 +#define SCE_SAS_WORD 9 +#define SCE_SAS_GLOBAL_MACRO 10 +#define SCE_SAS_MACRO 11 +#define SCE_SAS_MACRO_KEYWORD 12 +#define SCE_SAS_BLOCK_KEYWORD 13 +#define SCE_SAS_MACRO_FUNCTION 14 +#define SCE_SAS_STATEMENT 15 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ #endif diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 8b08f4d2f..420a529a0 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2932,6 +2932,8 @@ val SCLEX_JSON=120 val SCLEX_EDIFACT=121 val SCLEX_INDENT=122 val SCLEX_MAXIMA=123 +val SCLEX_STATA=124 +val SCLEX_SAS=125 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -4853,6 +4855,38 @@ val SCE_EDI_SEP_RELEASE=5 val SCE_EDI_UNA=6 val SCE_EDI_UNH=7 val SCE_EDI_BADSEGMENT=8 +# Lexical states for SCLEX_STATA +lex STATA=SCLEX_STATA SCE_STATA_ +val SCE_STATA_DEFAULT=0 +val SCE_STATA_COMMENT=1 +val SCE_STATA_COMMENTLINE=2 +val SCE_STATA_COMMENTBLOCK=3 +val SCE_STATA_NUMBER=4 +val SCE_STATA_OPERATOR=5 +val SCE_STATA_IDENTIFIER=6 +val SCE_STATA_STRING=7 +val SCE_STATA_TYPE=8 +val SCE_STATA_WORD=9 +val SCE_STATA_GLOBAL_MACRO=10 +val SCE_STATA_MACRO=11 +# Lexical states for SCLEX_SAS +lex SAS=SCLEX_SAS SCE_SAS_ +val SCE_SAS_DEFAULT=0 +val SCE_SAS_COMMENT=1 +val SCE_SAS_COMMENTLINE=2 +val SCE_SAS_COMMENTBLOCK=3 +val SCE_SAS_NUMBER=4 +val SCE_SAS_OPERATOR=5 +val SCE_SAS_IDENTIFIER=6 +val SCE_SAS_STRING=7 +val SCE_SAS_TYPE=8 +val SCE_SAS_WORD=9 +val SCE_SAS_GLOBAL_MACRO=10 +val SCE_SAS_MACRO=11 +val SCE_SAS_MACRO_KEYWORD=12 +val SCE_SAS_BLOCK_KEYWORD=13 +val SCE_SAS_MACRO_FUNCTION=14 +val SCE_SAS_STATEMENT=15 # Events diff --git a/lexers/LexSAS.cxx b/lexers/LexSAS.cxx new file mode 100644 index 000000000..29feba82d --- /dev/null +++ b/lexers/LexSAS.cxx @@ -0,0 +1,220 @@ +// Scintilla source code edit control +/** @file LexSAS.cxx + ** Lexer for SAS + **/ +// Author: Luke Rasmussen (luke.rasmussen@gmail.com) +// +// The License.txt file describes the conditions under which this software may +// be distributed. +// +// Developed as part of the StatTag project at Northwestern University Feinberg +// School of Medicine with funding from Northwestern University Clinical and +// Translational Sciences Institute through CTSA grant UL1TR001422. This work +// has not been reviewed or endorsed by NCATS or the NIH. + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <ctype.h> + +#include "ILexer.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#include "WordList.h" +#include "LexAccessor.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "CharacterSet.h" +#include "LexerModule.h" + +using namespace Scintilla; + +static void ColouriseSASDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &blockKeywords = *keywordlists[1]; + WordList &functionKeywords = *keywordlists[2]; + WordList &statements = *keywordlists[3]; + + CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-"); + CharacterSet setMacroStart(CharacterSet::setNone, "%"); + CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); + CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); + + StyleContext sc(startPos, length, initStyle, styler); + bool lineHasNonCommentChar = false; + for (; sc.More(); sc.Forward()) { + if (sc.atLineStart) { + lineHasNonCommentChar = false; + } + + // Determine if the current state should terminate. + switch (sc.state) { + case SCE_SAS_OPERATOR: + sc.SetState(SCE_SAS_DEFAULT); + break; + case SCE_SAS_NUMBER: + // We accept almost anything because of hex. and number suffixes + if (!setWord.Contains(sc.ch)) { + sc.SetState(SCE_SAS_DEFAULT); + } + break; + case SCE_SAS_MACRO: + if (!setWord.Contains(sc.ch) || (sc.ch == '.')) { + char s[1000]; + sc.GetCurrentLowered(s, sizeof(s)); + if (keywords.InList(s)) { + sc.ChangeState(SCE_SAS_MACRO_KEYWORD); + } + else if (blockKeywords.InList(s)) { + sc.ChangeState(SCE_SAS_BLOCK_KEYWORD); + } + else if (functionKeywords.InList(s)) { + sc.ChangeState(SCE_SAS_MACRO_FUNCTION); + } + sc.SetState(SCE_SAS_DEFAULT); + } + break; + case SCE_SAS_IDENTIFIER: + if (!setWord.Contains(sc.ch) || (sc.ch == '.')) { + char s[1000]; + sc.GetCurrentLowered(s, sizeof(s)); + if (statements.InList(s)) { + sc.ChangeState(SCE_SAS_STATEMENT); + } + else if(blockKeywords.InList(s)) { + sc.ChangeState(SCE_SAS_BLOCK_KEYWORD); + } + sc.SetState(SCE_SAS_DEFAULT); + } + break; + case SCE_SAS_COMMENTBLOCK: + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_SAS_DEFAULT); + } + break; + case SCE_SAS_COMMENT: + case SCE_SAS_COMMENTLINE: + if (sc.Match(';')) { + sc.Forward(); + sc.SetState(SCE_SAS_DEFAULT); + } + break; + case SCE_SAS_STRING: + if (sc.ch == '\"') { + sc.ForwardSetState(SCE_SAS_DEFAULT); + } + break; + } + + // Determine if a new state should be entered. + if (sc.state == SCE_SAS_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + lineHasNonCommentChar = true; + sc.SetState(SCE_SAS_NUMBER); + } + else if (setWordStart.Contains(sc.ch)) { + lineHasNonCommentChar = true; + sc.SetState(SCE_SAS_IDENTIFIER); + } + else if (sc.Match('*') && !lineHasNonCommentChar) { + sc.SetState(SCE_SAS_COMMENT); + } + else if (sc.Match('/', '*')) { + sc.SetState(SCE_SAS_COMMENTBLOCK); + sc.Forward(); // Eat the * so it isn't used for the end of the comment + } + else if (sc.Match('/', '/')) { + sc.SetState(SCE_SAS_COMMENTLINE); + } + else if (sc.ch == '\"') { + lineHasNonCommentChar = true; + sc.SetState(SCE_SAS_STRING); + } + else if (setMacroStart.Contains(sc.ch)) { + lineHasNonCommentChar = true; + sc.SetState(SCE_SAS_MACRO); + } + else if (isoperator(static_cast<char>(sc.ch))) { + lineHasNonCommentChar = true; + sc.SetState(SCE_SAS_OPERATOR); + } + } + } + + sc.Complete(); +} + +// Store both the current line's fold level and the next lines in the +// level store to make it easy to pick up with each increment +// and to make it possible to fiddle the current level for "} else {". +static void FoldSASDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], + Accessor &styler) { + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; + Sci_PositionU endPos = startPos + length; + int visibleChars = 0; + Sci_Position lineCurrent = styler.GetLine(startPos); + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) + levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; + int levelMinCurrent = levelCurrent; + int levelNext = levelCurrent; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + for (Sci_PositionU i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (style == SCE_R_OPERATOR) { + if (ch == '{') { + // Measure the minimum before a '{' to allow + // folding on "} else {" + if (levelMinCurrent > levelNext) { + levelMinCurrent = levelNext; + } + levelNext++; + } + else if (ch == '}') { + levelNext--; + } + } + if (atEOL) { + int levelUse = levelCurrent; + if (foldAtElse) { + levelUse = levelMinCurrent; + } + int lev = levelUse | levelNext << 16; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if (levelUse < levelNext) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelCurrent = levelNext; + levelMinCurrent = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) + visibleChars++; + } +} + + +static const char * const SASWordLists[] = { + "Language Keywords", + "Macro Keywords", + "Types", + 0, +}; + +LexerModule lmSAS(SCLEX_SAS, ColouriseSASDoc, "sas", FoldSASDoc, SASWordLists); diff --git a/lexers/LexStata.cxx b/lexers/LexStata.cxx new file mode 100644 index 000000000..78410c627 --- /dev/null +++ b/lexers/LexStata.cxx @@ -0,0 +1,203 @@ +// Scintilla source code edit control +/** @file LexStata.cxx + ** Lexer for Stata + **/ +// Author: Luke Rasmussen (luke.rasmussen@gmail.com) +// +// The License.txt file describes the conditions under which this software may +// be distributed. +// +// Developed as part of the StatTag project at Northwestern University Feinberg +// School of Medicine with funding from Northwestern University Clinical and +// Translational Sciences Institute through CTSA grant UL1TR001422. This work +// has not been reviewed or endorsed by NCATS or the NIH. + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <ctype.h> + +#include "ILexer.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#include "WordList.h" +#include "LexAccessor.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "CharacterSet.h" +#include "LexerModule.h" + +using namespace Scintilla; + +static void ColouriseStataDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &types = *keywordlists[1]; + + CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-"); + CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); + CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); + + StyleContext sc(startPos, length, initStyle, styler); + bool lineHasNonCommentChar = false; + for (; sc.More(); sc.Forward()) { + if (sc.atLineStart) { + lineHasNonCommentChar = false; + } + + // Determine if the current state should terminate. + switch (sc.state) { + case SCE_STATA_OPERATOR: + sc.SetState(SCE_STATA_DEFAULT); + break; + case SCE_STATA_NUMBER: + // We accept almost anything because of hex. and number suffixes + if (!setWord.Contains(sc.ch)) { + sc.SetState(SCE_STATA_DEFAULT); + } + break; + case SCE_STATA_IDENTIFIER: + if (!setWord.Contains(sc.ch) || (sc.ch == '.')) { + char s[1000]; + sc.GetCurrent(s, sizeof(s)); + if (keywords.InList(s)) { + sc.ChangeState(SCE_STATA_WORD); + } + else if (types.InList(s)) { + sc.ChangeState(SCE_STATA_TYPE); + } + sc.SetState(SCE_STATA_DEFAULT); + } + break; + case SCE_STATA_COMMENTBLOCK: + if (sc.Match('*', '/')) { + sc.Forward(); + sc.ForwardSetState(SCE_STATA_DEFAULT); + } + break; + case SCE_STATA_COMMENT: + case SCE_STATA_COMMENTLINE: + if (sc.atLineStart) { + sc.SetState(SCE_STATA_DEFAULT); + } + break; + case SCE_STATA_STRING: + if (sc.ch == '\\') { + // Per Stata documentation, the following characters are the only ones that can + // be escaped (not our typical set of quotes, etc.): + // https://www.stata.com/support/faqs/programming/backslashes-and-macros/ + if (sc.chNext == '$' || sc.chNext == '`' || sc.chNext == '\\') { + sc.Forward(); + } + } + else if (sc.ch == '\"') { + sc.ForwardSetState(SCE_STATA_DEFAULT); + } + break; + } + + // Determine if a new state should be entered. + if (sc.state == SCE_STATA_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + lineHasNonCommentChar = true; + sc.SetState(SCE_STATA_NUMBER); + } + else if (setWordStart.Contains(sc.ch)) { + lineHasNonCommentChar = true; + sc.SetState(SCE_STATA_IDENTIFIER); + } + else if (sc.Match('*') && !lineHasNonCommentChar) { + sc.SetState(SCE_STATA_COMMENT); + } + else if (sc.Match('/', '*')) { + sc.SetState(SCE_STATA_COMMENTBLOCK); + sc.Forward(); // Eat the * so it isn't used for the end of the comment + } + else if (sc.Match('/', '/')) { + sc.SetState(SCE_STATA_COMMENTLINE); + } + else if (sc.ch == '\"') { + lineHasNonCommentChar = true; + sc.SetState(SCE_STATA_STRING); + } + else if (isoperator(sc.ch)) { + lineHasNonCommentChar = true; + sc.SetState(SCE_STATA_OPERATOR); + } + } + } + + sc.Complete(); +} + +// Store both the current line's fold level and the next lines in the +// level store to make it easy to pick up with each increment +// and to make it possible to fiddle the current level for "} else {". +static void FoldStataDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], + Accessor &styler) { + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; + Sci_PositionU endPos = startPos + length; + int visibleChars = 0; + Sci_Position lineCurrent = styler.GetLine(startPos); + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) + levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; + int levelMinCurrent = levelCurrent; + int levelNext = levelCurrent; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + for (Sci_PositionU i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (style == SCE_R_OPERATOR) { + if (ch == '{') { + // Measure the minimum before a '{' to allow + // folding on "} else {" + if (levelMinCurrent > levelNext) { + levelMinCurrent = levelNext; + } + levelNext++; + } + else if (ch == '}') { + levelNext--; + } + } + if (atEOL) { + int levelUse = levelCurrent; + if (foldAtElse) { + levelUse = levelMinCurrent; + } + int lev = levelUse | levelNext << 16; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if (levelUse < levelNext) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelCurrent = levelNext; + levelMinCurrent = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) + visibleChars++; + } +} + + +static const char * const StataWordLists[] = { + "Language Keywords", + "Types", + 0, +}; + +LexerModule lmStata(SCLEX_STATA, ColouriseStataDoc, "stata", FoldStataDoc, StataWordLists); diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx index 438fd2ba1..979aaa1d7 100644 --- a/src/Catalogue.cxx +++ b/src/Catalogue.cxx @@ -168,6 +168,7 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmRegistry); LINK_LEXER(lmRuby); LINK_LEXER(lmRust); + LINK_LEXER(lmSAS); LINK_LEXER(lmScriptol); LINK_LEXER(lmSmalltalk); LINK_LEXER(lmSML); @@ -176,6 +177,7 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmSpice); LINK_LEXER(lmSQL); LINK_LEXER(lmSrec); + LINK_LEXER(lmStata); LINK_LEXER(lmSTTXT); LINK_LEXER(lmTACL); LINK_LEXER(lmTADS3); diff --git a/win32/scintilla.mak b/win32/scintilla.mak index 8a760fa39..cdda0d0ec 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -189,6 +189,7 @@ LEXOBJS=\ $(DIR_O)\LexRegistry.obj \ $(DIR_O)\LexRuby.obj \ $(DIR_O)\LexRust.obj \ + $(DIR_O)\LexSAS.obj \ $(DIR_O)\LexScriptol.obj \ $(DIR_O)\LexSmalltalk.obj \ $(DIR_O)\LexSML.obj \ @@ -196,6 +197,7 @@ LEXOBJS=\ $(DIR_O)\LexSpecman.obj \ $(DIR_O)\LexSpice.obj \ $(DIR_O)\LexSQL.obj \ + $(DIR_O)\LexStata.obj \ $(DIR_O)\LexSTTXT.obj \ $(DIR_O)\LexTACL.obj \ $(DIR_O)\LexTADS3.obj \ @@ -698,6 +700,8 @@ $(DIR_O)\LexRuby.obj: ..\lexers\LexRuby.cxx $(LEX_HEADERS) $(DIR_O)\LexRust.obj: ..\lexers\LexRust.cxx $(LEX_HEADERS) +$(DIR_O)\LexSAS.obj: ..\lexers\LexSAS.cxx $(LEX_HEADERS) + $(DIR_O)\LexScriptol.obj: ..\lexers\LexScriptol.cxx $(LEX_HEADERS) $(DIR_O)\LexSmalltalk.obj: ..\lexers\LexSmalltalk.cxx $(LEX_HEADERS) @@ -712,6 +716,8 @@ $(DIR_O)\LexSpice.obj: ..\lexers\LexSpice.cxx $(LEX_HEADERS) $(DIR_O)\LexSQL.obj: ..\lexers\LexSQL.cxx $(LEX_HEADERS) +$(DIR_O)\LexStata.obj: ..\lexers\LexStata.cxx $(LEX_HEADERS) + $(DIR_O)\LexSTTXT.obj: ..\lexers\LexSTTXT.cxx $(LEX_HEADERS) $(DIR_O)\LexTACL.obj: ..\lexers\LexTACL.cxx $(LEX_HEADERS) |