summaryrefslogtreecommitdiffstats
path: root/scintilla/lexers
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@gmail.com>2016-12-04 18:20:31 +0200
committerXhmikosR <xhmikosr@gmail.com>2016-12-04 18:24:16 +0200
commit4b604e07bbbf07d3d5ad04e65f0cef56959e3807 (patch)
tree44a5924e0ef508167b285c8016e6394992153817 /scintilla/lexers
parenta3ee58329361322b321ee2a708e793b1a5e5729a (diff)
downloadnotepad2-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.cxx332
-rw-r--r--scintilla/lexers/LexCPP.cxx2
-rw-r--r--scintilla/lexers/LexEDIFACT.cxx319
-rw-r--r--scintilla/lexers/LexMatlab.cxx117
-rw-r--r--scintilla/lexers/LexPerl.cxx2
-rw-r--r--scintilla/lexers/LexYAML.cxx2
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;