lexperl.cxx
来自「非常好用的可移植的多平台C/C++源代码编辑器」· CXX 代码 · 共 1,038 行 · 第 1/3 页
CXX
1,038 行
HereDoc.State = 1;
HereDoc.Quote = chNext;
HereDoc.Quoted = false;
HereDoc.DelimiterLength = 0;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
if (chNext == '\'' || chNext == '"' || chNext == '`') { // a quoted here-doc delimiter
i++;
ch = chNext;
chNext = chNext2;
HereDoc.Quoted = true;
} else if (isalpha(chNext) || chNext == '_') {
// an unquoted here-doc delimiter, no special handling
} else if (isspacechar(chNext) || isdigit(chNext) || chNext == '\\'
|| chNext == '=' || chNext == '$' || chNext == '@') {
// left shift << or <<= operator cases
styler.ColourTo(i, SCE_PL_OPERATOR);
state = SCE_PL_DEFAULT;
HereDoc.State = 0;
} else {
// symbols terminates; deprecated zero-length delimiter
}
} else if (HereDoc.State == 1) { // collect the delimiter
if (HereDoc.Quoted) { // a quoted here-doc delimiter
if (ch == HereDoc.Quote) { // closing quote => end of delimiter
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
} else {
if (ch == '\\' && chNext == HereDoc.Quote) { // escaped quote
i++;
ch = chNext;
chNext = chNext2;
}
HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
}
} else { // an unquoted here-doc delimiter
if (isalnum(ch) || ch == '_') {
HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch;
HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
} else {
styler.ColourTo(i - 1, state);
state = SCE_PL_DEFAULT;
goto restartLexer;
}
}
if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
styler.ColourTo(i - 1, state);
state = SCE_PL_ERROR;
goto restartLexer;
}
}
} else if (HereDoc.State == 2) {
// state == SCE_PL_HERE_Q || state == SCE_PL_HERE_QQ || state == SCE_PL_HERE_QX
if (isEOLChar(chPrev) && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) {
i += HereDoc.DelimiterLength;
chPrev = styler.SafeGetCharAt(i - 1);
ch = styler.SafeGetCharAt(i);
if (isEOLChar(ch)) {
styler.ColourTo(i - 1, state);
state = SCE_PL_DEFAULT;
HereDoc.State = 0;
goto restartLexer;
}
chNext = styler.SafeGetCharAt(i + 1);
}
} else if (state == SCE_PL_POD
|| state == SCE_PL_POD_VERB) {
if (isEOLChar(chPrev)) {
if (ch ==' ' || ch == '\t') {
styler.ColourTo(i - 1, state);
state = SCE_PL_POD_VERB;
} else {
styler.ColourTo(i - 1, state);
state = SCE_PL_POD;
if (ch == '=') {
if (isMatch(styler, lengthDoc, i, "=cut")) {
styler.ColourTo(i - 1 + 4, state);
i += 4;
state = SCE_PL_DEFAULT;
ch = styler.SafeGetCharAt(i);
//chNext = styler.SafeGetCharAt(i + 1);
goto restartLexer;
}
}
}
}
} else if (state == SCE_PL_SCALAR // variable names
|| state == SCE_PL_ARRAY
|| state == SCE_PL_HASH
|| state == SCE_PL_SYMBOLTABLE) {
if (ch == ':' && chNext == ':') { // skip ::
i++;
ch = chNext;
chNext = chNext2;
}
else if (isEndVar(ch)) {
if ((state == SCE_PL_SCALAR || state == SCE_PL_ARRAY)
&& i == (styler.GetStartSegment() + 1)) {
// Special variable: $(, $_ etc.
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
} else {
styler.ColourTo(i - 1, state);
state = SCE_PL_DEFAULT;
goto restartLexer;
}
}
} else if (state == SCE_PL_REGEX
|| state == SCE_PL_STRING_QR
) {
if (!Quote.Up && !isspacechar(ch)) {
Quote.Open(ch);
} else if (ch == '\\' && Quote.Up != '\\') {
// SG: Is it save to skip *every* escaped char?
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
} else {
if (ch == Quote.Down /*&& chPrev != '\\'*/) {
Quote.Count--;
if (Quote.Count == 0) {
Quote.Rep--;
if (Quote.Up == Quote.Down) {
Quote.Count++;
}
}
if (!isalpha(chNext)) {
if (Quote.Rep <= 0) {
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
ch = ' ';
}
}
} else if (ch == Quote.Up /*&& chPrev != '\\'*/) {
Quote.Count++;
} else if (!isalpha(chNext)) {
if (Quote.Rep <= 0) {
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
ch = ' ';
}
}
}
} else if (state == SCE_PL_REGSUBST) {
if (!Quote.Up && !isspacechar(ch)) {
Quote.Open(ch);
} else if (ch == '\\' && Quote.Up != '\\') {
// SG: Is it save to skip *every* escaped char?
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
} else {
if (Quote.Count == 0 && Quote.Rep == 1) {
/* We matched something like s(...) or tr{...}
* and are looking for the next matcher characters,
* which could be either bracketed ({...}) or non-bracketed
* (/.../).
*
* Number-signs are problematic. If they occur after
* the close of the first part, treat them like
* a Quote.Up char, even if they actually start comments.
*
* If we find an alnum, we end the regsubst, and punt.
*
* Eric Promislow ericp@activestate.com Aug 9,2000
*/
if (isspacechar(ch)) {
// Keep going
}
else if (isalnum(ch)) {
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
ch = ' ';
} else {
Quote.Open(ch);
}
} else if (ch == Quote.Down /*&& chPrev != '\\'*/) {
Quote.Count--;
if (Quote.Count == 0) {
Quote.Rep--;
}
if (!isalpha(chNext)) {
if (Quote.Rep <= 0) {
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
ch = ' ';
}
}
if (Quote.Up == Quote.Down) {
Quote.Count++;
}
} else if (ch == Quote.Up /*&& chPrev != '\\'*/) {
Quote.Count++;
} else if (!isalpha(chNext)) {
if (Quote.Rep <= 0) {
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
ch = ' ';
}
}
}
} else if (state == SCE_PL_STRING_Q
|| state == SCE_PL_STRING_QQ
|| state == SCE_PL_STRING_QX
|| state == SCE_PL_STRING_QW
|| state == SCE_PL_STRING
|| state == SCE_PL_CHARACTER
|| state == SCE_PL_BACKTICKS
) {
if (!Quote.Down && !isspacechar(ch)) {
Quote.Open(ch);
} else if (ch == '\\' && Quote.Up != '\\') {
i++;
ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
} else if (ch == Quote.Down) {
Quote.Count--;
if (Quote.Count == 0) {
Quote.Rep--;
if (Quote.Rep <= 0) {
styler.ColourTo(i, state);
state = SCE_PL_DEFAULT;
ch = ' ';
}
if (Quote.Up == Quote.Down) {
Quote.Count++;
}
}
} else if (ch == Quote.Up) {
Quote.Count++;
}
}
}
if (state == SCE_PL_ERROR) {
break;
}
chPrev = ch;
}
styler.ColourTo(lengthDoc - 1, state);
}
static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
// Custom folding of POD and packages
bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
char chPrev = styler.SafeGetCharAt(startPos - 1);
int styleNext = styler.StyleAt(startPos);
// Used at end of line to determine if the line was a package definition
bool isPackageLine = false;
bool isPodHeading = false;
for (unsigned int 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');
bool atLineStart = isEOLChar(chPrev) || i == 0;
if (foldComment && (style == SCE_PL_COMMENTLINE)) {
if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
if (chNext2 == '{') {
levelCurrent++;
} else if (chNext2 == '}') {
levelCurrent--;
}
}
}
if (style == SCE_C_OPERATOR) {
if (ch == '{') {
levelCurrent++;
} else if (ch == '}') {
levelCurrent--;
}
}
// Custom POD folding
if (foldPOD && atLineStart) {
int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
if (style == SCE_PL_POD) {
if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
levelCurrent++;
else if (styler.Match(i, "=cut"))
levelCurrent--;
else if (styler.Match(i, "=head"))
isPodHeading = true;
}
}
// Custom package folding
if (foldPackage && atLineStart) {
if (style == SCE_PL_WORD && styler.Match(i, "package")) {
isPackageLine = true;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
if (isPodHeading) {
lev = styler.LevelAt(lineCurrent) - 1;
lev |= SC_FOLDLEVELHEADERFLAG;
styler.SetLevel(lineCurrent, lev);
isPodHeading = false;
}
// Check if line was a package declaration
// because packages need "special" treatment
if (isPackageLine) {
styler.SetLevel(lineCurrent, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG);
levelCurrent = SC_FOLDLEVELBASE + 1;
isPackageLine = false;
}
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;
}
if (!isspacechar(ch))
visibleChars++;
chPrev = ch;
}
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const perlWordListDesc[] = {
"Keywords",
0
};
LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?