diff options
author | XhmikosR <xhmikosr@gmail.com> | 2016-12-04 18:20:31 +0200 |
---|---|---|
committer | XhmikosR <xhmikosr@gmail.com> | 2016-12-04 18:24:16 +0200 |
commit | 4b604e07bbbf07d3d5ad04e65f0cef56959e3807 (patch) | |
tree | 44a5924e0ef508167b285c8016e6394992153817 /scintilla/lexers | |
parent | a3ee58329361322b321ee2a708e793b1a5e5729a (diff) | |
download | notepad2-mod-master.zip notepad2-mod-master.tar.gz notepad2-mod-master.tar.bz2 |
Update Scintilla to v3.7.1.HEADorigin/masterorigin/HEADmaster
Diffstat (limited to 'scintilla/lexers')
-rw-r--r-- | scintilla/lexers/LexBaan.cxx | 332 | ||||
-rw-r--r-- | scintilla/lexers/LexCPP.cxx | 2 | ||||
-rw-r--r-- | scintilla/lexers/LexEDIFACT.cxx | 319 | ||||
-rw-r--r-- | scintilla/lexers/LexMatlab.cxx | 117 | ||||
-rw-r--r-- | scintilla/lexers/LexPerl.cxx | 2 | ||||
-rw-r--r-- | scintilla/lexers/LexYAML.cxx | 2 |
6 files changed, 649 insertions, 125 deletions
diff --git a/scintilla/lexers/LexBaan.cxx b/scintilla/lexers/LexBaan.cxx index bdc6b32..8439064 100644 --- a/scintilla/lexers/LexBaan.cxx +++ b/scintilla/lexers/LexBaan.cxx @@ -39,7 +39,7 @@ using namespace Scintilla; # endif
namespace {
- // Use an unnamed namespace to protect the functions and classes from name conflicts
+// Use an unnamed namespace to protect the functions and classes from name conflicts
// Options used for LexerBaan
struct OptionsBaan {
@@ -49,6 +49,8 @@ struct OptionsBaan { bool foldCompact;
bool baanFoldSyntaxBased;
bool baanFoldKeywordsBased;
+ bool baanFoldSections;
+ bool baanFoldInnerLevel;
bool baanStylingWithinPreprocessor;
OptionsBaan() {
fold = false;
@@ -57,6 +59,8 @@ struct OptionsBaan { foldCompact = false;
baanFoldSyntaxBased = false;
baanFoldKeywordsBased = false;
+ baanFoldSections = false;
+ baanFoldInnerLevel = false;
baanStylingWithinPreprocessor = false;
}
};
@@ -85,10 +89,18 @@ struct OptionSetBaan : public OptionSet<OptionsBaan> { DefineProperty("fold.baan.syntax.based", &OptionsBaan::baanFoldSyntaxBased,
"Set this property to 0 to disable syntax based folding, which is folding based on '{' & '('.");
-
+
DefineProperty("fold.baan.keywords.based", &OptionsBaan::baanFoldKeywordsBased,
"Set this property to 0 to disable keywords based folding, which is folding based on "
- " for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively.");
+ " for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively."
+ "Also folds declarations which are grouped together.");
+
+ DefineProperty("fold.baan.sections", &OptionsBaan::baanFoldSections,
+ "Set this property to 0 to disable folding of Main Sections as well as Sub Sections.");
+
+ DefineProperty("fold.baan.inner.level", &OptionsBaan::baanFoldInnerLevel,
+ "Set this property to 1 to enable folding of inner levels of select statements."
+ "Disabled by default. case and if statements are also eligible" );
DefineProperty("lexer.baan.styling.within.preprocessor", &OptionsBaan::baanStylingWithinPreprocessor,
"For Baan code, determines whether all preprocessor code is styled in the "
@@ -103,10 +115,6 @@ static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$');
}
-static inline bool IsAWordStart(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
-}
-
static inline bool IsAnOperator(int ch) {
if (IsAlphaNumeric(ch))
return false;
@@ -216,7 +224,16 @@ static bool IsPreProcLine(Sci_Position line, LexAccessor &styler) { Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
for (Sci_Position i = pos; i < eol_pos; i++) {
char ch = styler[i];
- if (ch == '#' || ch == '|' || ch == '^')
+ int style = styler.StyleAt(i);
+ if (ch == '#' && style == SCE_BAAN_PREPROCESSOR) {
+ if (styler.Match(i, "#elif") || styler.Match(i, "#else") || styler.Match(i, "#endif")
+ || styler.Match(i, "#if") || styler.Match(i, "#ifdef") || styler.Match(i, "#ifndef"))
+ // Above PreProcessors has a seperate fold mechanism.
+ return false;
+ else
+ return true;
+ }
+ else if (ch == '^')
return true;
else if (!IsASpaceOrTab(ch))
return false;
@@ -224,24 +241,112 @@ static bool IsPreProcLine(Sci_Position line, LexAccessor &styler) { return false;
}
-static bool IsMainSectionLine(Sci_Position line, LexAccessor &styler) {
+static int mainOrSubSectionLine(Sci_Position line, LexAccessor &styler) {
Sci_Position pos = styler.LineStart(line);
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
for (Sci_Position i = pos; i < eol_pos; i++) {
char ch = styler[i];
int style = styler.StyleAt(i);
- if (style == SCE_BAAN_WORD5)
- return true;
+ if (style == SCE_BAAN_WORD5 || style == SCE_BAAN_WORD4)
+ return style;
+ else if (IsASpaceOrTab(ch))
+ continue;
+ else
+ break;
+ }
+ return 0;
+}
+
+static bool priorSectionIsSubSection(Sci_Position line, LexAccessor &styler){
+ while (line > 0) {
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
+ for (Sci_Position i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ int style = styler.StyleAt(i);
+ if (style == SCE_BAAN_WORD4)
+ return true;
+ else if (style == SCE_BAAN_WORD5)
+ return false;
+ else if (IsASpaceOrTab(ch))
+ continue;
+ else
+ break;
+ }
+ line--;
+ }
+ return false;
+}
+
+static bool nextSectionIsSubSection(Sci_Position line, LexAccessor &styler) {
+ while (line > 0) {
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
+ for (Sci_Position i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ int style = styler.StyleAt(i);
+ if (style == SCE_BAAN_WORD4)
+ return true;
+ else if (style == SCE_BAAN_WORD5)
+ return false;
+ else if (IsASpaceOrTab(ch))
+ continue;
+ else
+ break;
+ }
+ line++;
+ }
+ return false;
+}
+
+static bool IsDeclarationLine(Sci_Position line, LexAccessor &styler) {
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
+ for (Sci_Position i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ int style = styler.StyleAt(i);
+ if (style == SCE_BAAN_WORD) {
+ if (styler.Match(i, "table") || styler.Match(i, "extern") || styler.Match(i, "long")
+ || styler.Match(i, "double") || styler.Match(i, "boolean") || styler.Match(i, "string")
+ || styler.Match(i, "domain")) {
+ for (Sci_Position j = eol_pos; j > pos; j--) {
+ int styleFromEnd = styler.StyleAt(j);
+ if (styleFromEnd == SCE_BAAN_COMMENT)
+ continue;
+ else if (IsASpace(styler[j]))
+ continue;
+ else if (styler[j] != ',')
+ //Above conditions ensures, Declaration is not part of any function parameters.
+ return true;
+ else
+ return false;
+ }
+ }
+ else
+ return false;
+ }
else if (!IsASpaceOrTab(ch))
return false;
}
return false;
}
-static inline int ToLowerCase(int c) {
- if (c >= 'A' && c <= 'Z')
- return 'a' + c - 'A';
- return c;
+static bool IsInnerLevelFold(Sci_Position line, LexAccessor &styler) {
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
+ for (Sci_Position i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ int style = styler.StyleAt(i);
+ if (style == SCE_BAAN_WORD && (styler.Match(i, "else" ) || styler.Match(i, "case")
+ || styler.Match(i, "default") || styler.Match(i, "selectdo") || styler.Match(i, "selecteos")
+ || styler.Match(i, "selectempty") || styler.Match(i, "selecterror")))
+ return true;
+ else if (IsASpaceOrTab(ch))
+ continue;
+ else
+ return false;
+ }
+ return false;
}
static inline bool wordInArray(const std::string& value, std::string *array, int length)
@@ -314,7 +419,7 @@ public: return osBaan.DescribeProperty(name);
}
- int SCI_METHOD PropertySet(const char *key, const char *val);
+ Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
const char * SCI_METHOD DescribeWordListSets() {
return osBaan.DescribeWordListSets();
@@ -399,7 +504,12 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int bool lineHasPreProc = false;
bool lineIgnoreString = false;
bool lineHasDefines = false;
+ char word[1000];
+ int wordlen = 0;
+ std::string preProcessorTags[11] = { "#define", "#elif", "#else", "#endif",
+ "#ident", "#if", "#ifdef", "#ifndef",
+ "#include", "#pragma", "#undef" };
LexAccessor styler(pAccess);
StyleContext sc(startPos, length, initStyle, styler);
@@ -537,7 +647,7 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int sc.Forward();
} while ((!sc.atLineEnd) && sc.More());
}
- else if (IsAWordStart(sc.ch)) {
+ else if (iswordstart(sc.ch)) {
sc.SetState(SCE_BAAN_IDENTIFIER);
}
else if (sc.Match('|')) {
@@ -549,15 +659,26 @@ void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int else if (sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
sc.SetState(SCE_BAAN_PREPROCESSOR);
- // Skip whitespace between # and preprocessor word
- do {
+ word[0] = '\0';
+ wordlen = 0;
+ while (sc.More() && !(IsASpace(sc.chNext) || IsAnOperator(sc.chNext))) {
sc.Forward();
- } while (IsASpace(sc.ch) && sc.More());
- if (sc.MatchIgnoreCase("pragma") || sc.MatchIgnoreCase("include")) {
+ wordlen++;
+ }
+ sc.GetCurrentLowered(word, sizeof(word));
+ if (!sc.atLineEnd) {
+ word[wordlen++] = sc.ch;
+ word[wordlen++] = '\0';
+ }
+ if (!wordInArray(word, preProcessorTags, 11))
+ // Colorise only preprocessor built in Baan.
+ sc.ChangeState(SCE_BAAN_IDENTIFIER);
+ if (strcmp(word, "#pragma") == 0 || strcmp(word, "#include") == 0) {
lineHasPreProc = true;
lineIgnoreString = true;
}
- else if (sc.MatchIgnoreCase("define") || sc.MatchIgnoreCase("undef")) {
+ else if (strcmp(word, "#define") == 0 || strcmp(word, "#undef") == 0 ||
+ strcmp(word, "#ifdef") == 0 || strcmp(word, "#if") == 0 || strcmp(word, "#ifndef") == 0) {
lineHasDefines = true;
lineIgnoreString = false;
}
@@ -594,7 +715,9 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int bool foldNextSelect = true;
bool afterFunctionSection = false;
bool beforeDeclarationSection = false;
-
+ int currLineStyle = 0;
+ int nextLineStyle = 0;
+
std::string startTags[6] = { "for", "if", "on", "repeat", "select", "while" };
std::string endTags[6] = { "endcase", "endfor", "endif", "endselect", "endwhile", "until" };
std::string selectCloseTags[5] = { "selectdo", "selecteos", "selectempty", "selecterror", "endselect" };
@@ -646,13 +769,24 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int levelCurrent--;
}
// PreProcessor Folding
- if (options.foldPreprocessor && atEOL && IsPreProcLine(lineCurrent, styler)) {
- if (!IsPreProcLine(lineCurrent - 1, styler)
- && IsPreProcLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsPreProcLine(lineCurrent - 1, styler)
- && !IsPreProcLine(lineCurrent + 1, styler))
- levelCurrent--;
+ if (options.foldPreprocessor) {
+ if (atEOL && IsPreProcLine(lineCurrent, styler)) {
+ if (!IsPreProcLine(lineCurrent - 1, styler)
+ && IsPreProcLine(lineCurrent + 1, styler))
+ levelCurrent++;
+ else if (IsPreProcLine(lineCurrent - 1, styler)
+ && !IsPreProcLine(lineCurrent + 1, styler))
+ levelCurrent--;
+ }
+ else if (style == SCE_BAAN_PREPROCESSOR) {
+ // folds #ifdef/#if/#ifndef - they are not part of the IsPreProcLine folding.
+ if (ch == '#') {
+ if (styler.Match(i, "#ifdef") || styler.Match(i, "#if") || styler.Match(i, "#ifndef"))
+ levelCurrent++;
+ else if (styler.Match(i, "#endif"))
+ levelCurrent--;
+ }
+ }
}
//Syntax Folding
if (options.baanFoldSyntaxBased && (style == SCE_BAAN_OPERATOR)) {
@@ -664,77 +798,100 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int }
}
//Keywords Folding
- if (options.baanFoldKeywordsBased && style == SCE_BAAN_WORD) {
- word[wordlen++] = static_cast<char>(ToLowerCase(ch));
- if (wordlen == 100) { // prevent overflow
- word[0] = '\0';
- wordlen = 1;
+ if (options.baanFoldKeywordsBased) {
+ if (atEOL && IsDeclarationLine(lineCurrent, styler)) {
+ if (!IsDeclarationLine(lineCurrent - 1, styler)
+ && IsDeclarationLine(lineCurrent + 1, styler))
+ levelCurrent++;
+ else if (IsDeclarationLine(lineCurrent - 1, styler)
+ && !IsDeclarationLine(lineCurrent + 1, styler))
+ levelCurrent--;
}
- if (styleNext != SCE_BAAN_WORD) {
- word[wordlen] = '\0';
- wordlen = 0;
- if (strcmp(word, "for") == 0) {
- Sci_PositionU j = i + 1;
- while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- if (styler.Match(j, "update")) {
- // Means this is a "for update" used by Select which is already folded.
- foldStart = false;
- }
+ else if (style == SCE_BAAN_WORD) {
+ word[wordlen++] = static_cast<char>(MakeLowerCase(ch));
+ if (wordlen == 100) { // prevent overflow
+ word[0] = '\0';
+ wordlen = 1;
}
- else if (strcmp(word, "on") == 0) {
- Sci_PositionU j = i + 1;
- while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
+ if (styleNext != SCE_BAAN_WORD) {
+ word[wordlen] = '\0';
+ wordlen = 0;
+ if (strcmp(word, "for") == 0) {
+ Sci_PositionU j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "update")) {
+ // Means this is a "for update" used by Select which is already folded.
+ foldStart = false;
+ }
}
- if (!styler.Match(j, "case")) {
- // Means this is not a "on Case" statement... could be "on" used by index.
- foldStart = false;
+ else if (strcmp(word, "on") == 0) {
+ Sci_PositionU j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (!styler.Match(j, "case")) {
+ // Means this is not a "on Case" statement... could be "on" used by index.
+ foldStart = false;
+ }
}
- }
- else if (strcmp(word, "select") == 0) {
- if (foldNextSelect) {
- // Next Selects are sub-clause till reach of selectCloseTags[] array.
- foldNextSelect = false;
+ else if (strcmp(word, "select") == 0) {
+ if (foldNextSelect) {
+ // Next Selects are sub-clause till reach of selectCloseTags[] array.
+ foldNextSelect = false;
+ foldStart = true;
+ }
+ else {
+ foldNextSelect = false;
+ foldStart = false;
+ }
+ }
+ else if (wordInArray(word, selectCloseTags, 5)) {
+ // select clause ends, next select clause can be folded.
+ foldNextSelect = true;
foldStart = true;
}
else {
- foldNextSelect = false;
- foldStart = false;
- }
- }
- else if (wordInArray(word, selectCloseTags, 5)) {
- // select clause ends, next select clause can be folded.
- foldNextSelect = true;
- foldStart = true;
- }
- else {
- foldStart = true;
- }
- if (foldStart) {
- if (wordInArray(word, startTags, 6)) {
- levelCurrent++;
+ foldStart = true;
}
- else if (wordInArray(word, endTags, 6)) {
- levelCurrent--;
+ if (foldStart) {
+ if (wordInArray(word, startTags, 6)) {
+ levelCurrent++;
+ }
+ else if (wordInArray(word, endTags, 6)) {
+ levelCurrent--;
+ }
}
}
}
}
- // Main Section Foldings.
+ // Fold inner level of if/select/case statements
+ if (options.baanFoldInnerLevel && atEOL) {
+ bool currLineInnerLevel = IsInnerLevelFold(lineCurrent, styler);
+ bool nextLineInnerLevel = IsInnerLevelFold(lineCurrent + 1, styler);
+ if (currLineInnerLevel && currLineInnerLevel != nextLineInnerLevel) {
+ levelCurrent++;
+ }
+ else if (nextLineInnerLevel && nextLineInnerLevel != currLineInnerLevel) {
+ levelCurrent--;
+ }
+ }
+ // Section Foldings.
// One way of implementing Section Foldings, as there is no END markings of sections.
// first section ends on the previous line of next section.
// Re-written whole folding to accomodate this.
- if (options.baanFoldKeywordsBased && atEOL) {
- if (IsMainSectionLine(lineCurrent, styler)) {
+ if (options.baanFoldSections && atEOL) {
+ currLineStyle = mainOrSubSectionLine(lineCurrent, styler);
+ nextLineStyle = mainOrSubSectionLine(lineCurrent + 1, styler);
+ if (currLineStyle != 0 && currLineStyle != nextLineStyle) {
if (levelCurrent < levelPrev)
--levelPrev;
for (Sci_Position j = styler.LineStart(lineCurrent); j < styler.LineStart(lineCurrent + 1) - 1; j++) {
- if (IsASpaceOrTab(styler[j]))
+ if (IsASpaceOrTab(styler[j]))
continue;
else if (styler.StyleAt(j) == SCE_BAAN_WORD5) {
- if (styler.Match(j, "functions:")) {
+ if (styler.Match(j, "functions:")) {
// Means functions: is the end of MainSections.
// Nothing to fold after this.
afterFunctionSection = true;
@@ -753,12 +910,14 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int if (!afterFunctionSection)
levelCurrent++;
}
- else if (IsMainSectionLine(lineCurrent + 1, styler)) {
+ else if (nextLineStyle != 0 && currLineStyle != nextLineStyle
+ && (priorSectionIsSubSection(lineCurrent -1 ,styler)
+ || !nextSectionIsSubSection(lineCurrent + 1, styler))) {
for (Sci_Position j = styler.LineStart(lineCurrent + 1); j < styler.LineStart(lineCurrent + 1 + 1) - 1; j++) {
if (IsASpaceOrTab(styler[j]))
continue;
else if (styler.StyleAt(j) == SCE_BAAN_WORD5) {
- if (styler.Match(j, "declaration:")) {
+ if (styler.Match(j, "declaration:")) {
// Means declaration: is the start of MainSections.
// Nothing to fold before this.
beforeDeclarationSection = true;
@@ -774,8 +933,13 @@ void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int break;
}
}
- if (!beforeDeclarationSection)
+ if (!beforeDeclarationSection) {
levelCurrent--;
+ if (nextLineStyle == SCE_BAAN_WORD5 && priorSectionIsSubSection(lineCurrent-1, styler))
+ // next levelCurrent--; is to unfold previous subsection fold.
+ // On reaching the next main section, the previous main as well sub section ends.
+ levelCurrent--;
+ }
}
}
if (atEOL) {
diff --git a/scintilla/lexers/LexCPP.cxx b/scintilla/lexers/LexCPP.cxx index 64387a0..ec040fb 100644 --- a/scintilla/lexers/LexCPP.cxx +++ b/scintilla/lexers/LexCPP.cxx @@ -692,7 +692,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i } } - StyleContext sc(startPos, length, initStyle, styler, static_cast<unsigned char>(0xff)); + StyleContext sc(startPos, length, initStyle, styler); LinePPState preproc = vlls.ForLine(lineCurrent); bool definitionsChanged = false; diff --git a/scintilla/lexers/LexEDIFACT.cxx b/scintilla/lexers/LexEDIFACT.cxx new file mode 100644 index 0000000..53e5bb3 --- /dev/null +++ b/scintilla/lexers/LexEDIFACT.cxx @@ -0,0 +1,319 @@ +// Scintilla Lexer for EDIFACT +// Written by Iain Clarke, IMCSoft & Inobiz AB. +// EDIFACT documented here: https://www.unece.org/cefact/edifact/welcome.html +// and more readably here: https://en.wikipedia.org/wiki/EDIFACT +// This code is subject to the same license terms as the rest of the scintilla project: +// The License.txt file describes the conditions under which this software may be distributed. +// + +// Header order must match order in scripts/HeaderOrder.txt +#include <cstdlib> +#include <cassert> +#include <cstring> +#include <cctype> + +#include "ILexer.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#include "LexAccessor.h" +#include "LexerModule.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +class LexerEDIFACT : public ILexer +{ +public: + LexerEDIFACT(); + virtual ~LexerEDIFACT() {} // virtual destructor, as we inherit from ILexer + + static ILexer *Factory() { + return new LexerEDIFACT; + } + + virtual int SCI_METHOD Version() const + { + return lvOriginal; + } + virtual void SCI_METHOD Release() + { + delete this; + } + + const char * SCI_METHOD PropertyNames() + { + return "fold"; + } + int SCI_METHOD PropertyType(const char *) + { + return SC_TYPE_BOOLEAN; // Only one property! + } + const char * SCI_METHOD DescribeProperty(const char *name) + { + if (strcmp(name, "fold")) + return NULL; + return "Whether to apply folding to document or not"; + } + + virtual Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) + { + if (strcmp(key, "fold")) + return -1; + m_bFold = strcmp(val, "0") ? true : false; + return 0; + } + const char * SCI_METHOD DescribeWordListSets() + { + return NULL; + } + virtual Sci_Position SCI_METHOD WordListSet(int, const char *) + { + return -1; + } + virtual void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess); + virtual void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess); + virtual void * SCI_METHOD PrivateCall(int, void *) + { + return NULL; + } + +protected: + Sci_Position InitialiseFromUNA(IDocument *pAccess, Sci_PositionU MaxLength); + Sci_Position FindPreviousEnd(IDocument *pAccess, Sci_Position startPos) const; + Sci_Position ForwardPastWhitespace(IDocument *pAccess, Sci_Position startPos, Sci_Position MaxLength) const; + int DetectSegmentHeader(char SegmentHeader[3]) const; + + bool m_bFold; + char m_chComponent; + char m_chData; + char m_chDecimal; + char m_chRelease; + char m_chSegment; +}; + +LexerModule lmEDIFACT(SCLEX_EDIFACT, LexerEDIFACT::Factory, "edifact"); + +/////////////////////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////////////////////// + +LexerEDIFACT::LexerEDIFACT() +{ + m_bFold = false; + m_chComponent = ':'; + m_chData = '+'; + m_chDecimal = '.'; + m_chRelease = '?'; + m_chSegment = '\''; +} + +void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess) +{ + Sci_PositionU posFinish = startPos + lengthDoc; + InitialiseFromUNA(pAccess, posFinish); + + // Look backwards for a ' or a document beginning + Sci_PositionU posCurrent = FindPreviousEnd(pAccess, startPos); + // And jump past the ' if this was not the beginning of the document + if (posCurrent != 0) + posCurrent++; + + // Style buffer, so we're not issuing loads of notifications + LexAccessor styler (pAccess); + pAccess->StartStyling(posCurrent, '\377'); + styler.StartSegment(posCurrent); + Sci_Position posSegmentStart = -1; + + while ((posCurrent < posFinish) && (posSegmentStart == -1)) + { + posCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish); + // Mark whitespace as default + styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT); + if (posCurrent >= posFinish) + break; + + // Does is start with 3 charaters? ie, UNH + char SegmentHeader[4] = { 0 }; + pAccess->GetCharRange(SegmentHeader, posCurrent, 3); + + int SegmentStyle = DetectSegmentHeader(SegmentHeader); + if (SegmentStyle == SCE_EDI_BADSEGMENT) + break; + if (SegmentStyle == SCE_EDI_UNA) + { + posCurrent += 9; + styler.ColourTo(posCurrent - 1, SCE_EDI_UNA); // UNA + continue; + } + posSegmentStart = posCurrent; + posCurrent += 3; + + styler.ColourTo(posCurrent - 1, SegmentStyle); // UNH etc + + // Colour in the rest of the segment + for (char c; posCurrent < posFinish; posCurrent++) + { + pAccess->GetCharRange(&c, posCurrent, 1); + + if (c == m_chRelease) // ? escape character, check first, in case of ?' + posCurrent++; + else if (c == m_chSegment) // ' + { + // Make sure the whole segment is on one line. styler won't let us go back in time, so we'll settle for marking the ' as bad. + Sci_Position lineSegmentStart = pAccess->LineFromPosition(posSegmentStart); + Sci_Position lineSegmentEnd = pAccess->LineFromPosition(posCurrent); + if (lineSegmentStart == lineSegmentEnd) + styler.ColourTo(posCurrent, SCE_EDI_SEGMENTEND); + else + styler.ColourTo(posCurrent, SCE_EDI_BADSEGMENT); + posSegmentStart = -1; + posCurrent++; + break; + } + else if (c == m_chComponent) // : + styler.ColourTo(posCurrent, SCE_EDI_SEP_COMPOSITE); + else if (c == m_chData) // + + styler.ColourTo(posCurrent, SCE_EDI_SEP_ELEMENT); + else + styler.ColourTo(posCurrent, SCE_EDI_DEFAULT); + } + } + styler.Flush(); + + if (posSegmentStart == -1) + return; + + pAccess->StartStyling(posSegmentStart, -1); + pAccess->SetStyleFor(posFinish - posSegmentStart, SCE_EDI_BADSEGMENT); +} + +void LexerEDIFACT::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument *pAccess) +{ + if (!m_bFold) + return; + + // Fold at UNx lines. ie, UNx segments = 0, other segments = 1. + // There's no sub folding, so we can be quite simple. + Sci_Position endPos = startPos + lengthDoc; + char SegmentHeader[4] = { 0 }; + + int iIndentPrevious = 0; + Sci_Position lineLast = pAccess->LineFromPosition(endPos); + + for (Sci_Position lineCurrent = pAccess->LineFromPosition(startPos); lineCurrent <= lineLast; lineCurrent++) + { + Sci_Position posLineStart = pAccess->LineStart(lineCurrent); + posLineStart = ForwardPastWhitespace(pAccess, posLineStart, endPos); + Sci_Position lineDataStart = pAccess->LineFromPosition(posLineStart); + // Fill in whitespace lines? + for (; lineCurrent < lineDataStart; lineCurrent++) + pAccess->SetLevel(lineCurrent, SC_FOLDLEVELBASE | SC_FOLDLEVELWHITEFLAG | iIndentPrevious); + pAccess->GetCharRange(SegmentHeader, posLineStart, 3); + //if (DetectSegmentHeader(SegmentHeader) == SCE_EDI_BADSEGMENT) // Abort if this is not a proper segment header + + int level = 0; + if (memcmp(SegmentHeader, "UNH", 3) == 0) // UNH starts blocks + level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; + // Check for UNA,B and Z. All others are inside messages + else if (!memcmp(SegmentHeader, "UNA", 3) || !memcmp(SegmentHeader, "UNB", 3) || !memcmp(SegmentHeader, "UNZ", 3)) + level = SC_FOLDLEVELBASE; + else + level = SC_FOLDLEVELBASE | 1; + pAccess->SetLevel(lineCurrent, level); + iIndentPrevious = level & SC_FOLDLEVELNUMBERMASK; + } +} + +Sci_Position LexerEDIFACT::InitialiseFromUNA(IDocument *pAccess, Sci_PositionU MaxLength) +{ + MaxLength -= 9; // drop 9 chars, to give us room for UNA:+.? ' + + Sci_PositionU startPos = 0; + startPos += ForwardPastWhitespace(pAccess, 0, MaxLength); + if (startPos < MaxLength) + { + char bufUNA[9]; + pAccess->GetCharRange(bufUNA, startPos, 9); + + // Check it's UNA segment + if (!memcmp(bufUNA, "UNA", 3)) + { + m_chComponent = bufUNA[3]; + m_chData = bufUNA[4]; + m_chDecimal = bufUNA[5]; + m_chRelease = bufUNA[6]; + // bufUNA [7] should be space - reserved. + m_chSegment = bufUNA[8]; + + return 0; // success! + } + } + + // We failed to find a UNA, so drop to defaults + m_chComponent = ':'; + m_chData = '+'; + m_chDecimal = '.'; + m_chRelease = '?'; + m_chSegment = '\''; + + return -1; +} + +Sci_Position LexerEDIFACT::ForwardPastWhitespace(IDocument *pAccess, Sci_Position startPos, Sci_Position MaxLength) const +{ + char c; + + while (startPos < MaxLength) + { + pAccess->GetCharRange(&c, startPos, 1); + switch (c) + { + case '\t': + case '\r': + case '\n': + case ' ': + break; + default: + return startPos; + } + + startPos++; + } + + return MaxLength; +} + +int LexerEDIFACT::DetectSegmentHeader(char SegmentHeader[3]) const +{ + if ( + SegmentHeader[0] < 'A' || SegmentHeader[0] > 'Z' || + SegmentHeader[1] < 'A' || SegmentHeader[1] > 'Z' || + SegmentHeader[2] < 'A' || SegmentHeader[2] > 'Z') + return SCE_EDI_BADSEGMENT; + + if (memcmp(SegmentHeader, "UNA", 3) == 0) + return SCE_EDI_UNA; + if (memcmp(SegmentHeader, "UNH", 3) == 0) + return SCE_EDI_UNH; + + return SCE_EDI_SEGMENTSTART; +} + +// Look backwards for a ' or a document beginning +Sci_Position LexerEDIFACT::FindPreviousEnd(IDocument *pAccess, Sci_Position startPos) const +{ + for (char c; startPos > 0; startPos--) + { + pAccess->GetCharRange(&c, startPos, 1); + if (c == m_chSegment) + return startPos; + } + // We didn't find a ', so just go with the beginning + return 0; +} + + diff --git a/scintilla/lexers/LexMatlab.cxx b/scintilla/lexers/LexMatlab.cxx index f20f732..e8e2860 100644 --- a/scintilla/lexers/LexMatlab.cxx +++ b/scintilla/lexers/LexMatlab.cxx @@ -15,6 +15,9 @@ **
** Changes by John Donoghue 2014/08/01
** - fix allowed transpose ' after {} operator
+ **
+ ** Changes by John Donoghue 2016/11/15
+ ** - update matlab code folding
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -49,14 +52,28 @@ static bool IsOctaveCommentChar(int c) { return (c == '%' || c == '#') ;
}
-static bool IsMatlabComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
- return len > 0 && IsMatlabCommentChar(styler[pos]) ;
+static inline int LowerCase(int c) {
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
}
-static bool IsOctaveComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
- return len > 0 && IsOctaveCommentChar(styler[pos]) ;
+static int CheckKeywordFoldPoint(char *str) {
+ if (strcmp ("if", str) == 0 ||
+ strcmp ("for", str) == 0 ||
+ strcmp ("switch", str) == 0 ||
+ strcmp ("try", str) == 0 ||
+ strcmp ("do", str) == 0 ||
+ strcmp ("parfor", str) == 0 ||
+ strcmp ("function", str) == 0)
+ return 1;
+ if (strncmp("end", str, 3) == 0 ||
+ strcmp("until", str) == 0)
+ return -1;
+ return 0;
}
+
static void ColouriseMatlabOctaveDoc(
Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler,
@@ -245,58 +262,82 @@ static void ColouriseOctaveDoc(Sci_PositionU startPos, Sci_Position length, int ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
}
-static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int,
+static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *[], Accessor &styler,
- bool (*IsComment)(Accessor&, Sci_Position, Sci_Position)) {
-
- Sci_Position endPos = startPos + length;
+ bool (*IsComment)(int ch)) {
- // Backtrack to previous line in case need to fix its fold status
+ Sci_PositionU endPos = startPos + length;
+ int visibleChars = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
char chNext = styler[startPos];
- for (Sci_Position i = startPos; i < endPos; i++) {
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char word[100];
+ int wordlen = 0;
+ for (Sci_PositionU i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
- int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
- int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
- }
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+
+ // a line that starts with a comment
+ if (style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {
+ // start/end of block comment
+ if (chNext == '{')
+ levelNext ++;
+ if (chNext == '}')
+ levelNext --;
+ }
+ // keyword
+ if(style == SCE_MATLAB_KEYWORD) {
+ word[wordlen++] = static_cast<char>(LowerCase(ch));
+ if (wordlen == 100) { // prevent overflow
+ word[0] = '\0';
+ wordlen = 1;
+ }
+ if (styleNext != SCE_MATLAB_KEYWORD) {
+ word[wordlen] = '\0';
+ wordlen = 0;
+
+ levelNext += CheckKeywordFoldPoint(word);
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
}
- indentCurrent = indentNext;
- styler.SetLevel(lineCurrent, lev);
lineCurrent++;
+ levelCurrent = levelNext;
+ if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {
+ // There is an empty line at end of file so give it same level and empty
+ styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+ }
+ visibleChars = 0;
}
}
}
static void FoldMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
- FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
+ FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
}
static void FoldOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
- FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
+ FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
}
static const char * const matlabWordListDesc[] = {
diff --git a/scintilla/lexers/LexPerl.cxx b/scintilla/lexers/LexPerl.cxx index 4e020cc..b02438b 100644 --- a/scintilla/lexers/LexPerl.cxx +++ b/scintilla/lexers/LexPerl.cxx @@ -755,7 +755,7 @@ void SCI_METHOD LexerPerl::Lex(Sci_PositionU startPos, Sci_Position length, int backPos++;
}
- StyleContext sc(startPos, endPos - startPos, initStyle, styler, static_cast<char>(STYLE_MAX));
+ StyleContext sc(startPos, endPos - startPos, initStyle, styler);
for (; sc.More(); sc.Forward()) {
diff --git a/scintilla/lexers/LexYAML.cxx b/scintilla/lexers/LexYAML.cxx index 7a948f7..a01148c 100644 --- a/scintilla/lexers/LexYAML.cxx +++ b/scintilla/lexers/LexYAML.cxx @@ -55,7 +55,7 @@ static bool KeywordAtChar(char* lineBuffer, char* startComment, const WordList & char* endValue = startComment - 1;
while (endValue >= lineBuffer && *endValue == ' ')
endValue--;
- Sci_PositionU len = endValue - lineBuffer + 1;
+ Sci_PositionU len = static_cast<Sci_PositionU>(endValue - lineBuffer) + 1;
char s[100];
if (len > (sizeof(s) / sizeof(s[0]) - 1))
return false;
|