📄 lexperl.cxx
字号:
if (isspacechar(chNext) || isdigit(chNext) || chNext == '/') preferRE = false; break; // other styles uses the default, preferRE=false case SCE_PL_POD: case SCE_PL_POD_VERB: case SCE_PL_HERE_Q: case SCE_PL_HERE_QQ: case SCE_PL_HERE_QX: preferRE = true; break; } } backflag = BACK_NONE; if (isHereDoc) { // handle HERE doc // if SCALAR whitespace '<<', *always* a HERE doc if (preferRE || (hereDocSpace && hereDocScalar)) { state = SCE_PL_HERE_DELIM; HereDoc.State = 0; } else { // << operator i++; ch = chNext; chNext = chNext2; goto handleOperator; } } else { // handle regexp if (preferRE) { state = SCE_PL_REGEX; Quote.New(1); Quote.Open(ch); } else { // / and // operators if (chNext == '/') { i++; ch = chNext; chNext = chNext2; } goto handleOperator; } } } else if (ch == '<') { // looks forward for matching > on same line unsigned int fw = i + 1; while (fw < lengthDoc) { char fwch = styler.SafeGetCharAt(fw); if (fwch == ' ') { if (styler.SafeGetCharAt(fw-1) != '\\' || styler.SafeGetCharAt(fw-2) != '\\') goto handleOperator; } else if (isEOLChar(fwch) || isspacechar(fwch)) { goto handleOperator; } else if (fwch == '>') { if ((fw - i) == 2 && // '<=>' case styler.SafeGetCharAt(fw-1) == '=') { goto handleOperator; } styler.ColourTo(fw, SCE_PL_IDENTIFIER); i = fw; ch = fwch; chNext = styler.SafeGetCharAt(i+1); } fw++; } if (fw == lengthDoc) goto handleOperator; } else if (ch == '=' // POD && isalpha(chNext) && (isEOLChar(chPrev))) { state = SCE_PL_POD; backflag = BACK_NONE; //sookedpos = 0; //sooked[sookedpos] = '\0'; } else if (ch == '-' // file test operators && isSingleCharOp(chNext) && !isalnum((chNext2 = styler.SafeGetCharAt(i+2)))) { styler.ColourTo(i + 1, SCE_PL_WORD); state = SCE_PL_DEFAULT; i++; ch = chNext; chNext = chNext2; backflag = BACK_NONE; } else if (ch == '-' // bareword promotion (-FOO cases) && ((isascii(chNext) && isalpha(chNext)) || chNext == '_') && backflag != BACK_NONE) { state = SCE_PL_IDENTIFIER; backflag = BACK_NONE; } else if (ch == '(' && i > 0) { // backtrack to identify if we're starting a sub prototype // for generality, we need to ignore whitespace/comments unsigned int bk = i - 1; // i > 0 tested above styler.Flush(); while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_DEFAULT || styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) { bk--; } if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier goto handleOperator; while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) { bk--; } while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_DEFAULT || styler.StyleAt(bk) == SCE_PL_COMMENTLINE)) { bk--; } if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword || !styler.Match(bk - 2, "sub")) // assume suffix is unique! goto handleOperator; state = SCE_PL_SUB_PROTOTYPE; backflag = BACK_NONE; backPos = i; // needed for restart } else if (isPerlOperator(ch)) { if (ch == '.' && chNext == '.') { // .. and ... i++; if (chNext2 == '.') { i++; } state = SCE_PL_DEFAULT; ch = styler.SafeGetCharAt(i); chNext = styler.SafeGetCharAt(i + 1); } handleOperator: styler.ColourTo(i, SCE_PL_OPERATOR); backflag = BACK_OPERATOR; backPos = i; } else if (ch == 4 || ch == 26) { // ^D and ^Z ends valid perl source styler.ColourTo(i, SCE_PL_DATASECTION); state = SCE_PL_DATASECTION; } else { // keep colouring defaults to make restart easier styler.ColourTo(i, SCE_PL_DEFAULT); } } else if (state == SCE_PL_NUMBER) { if (ch == '.') { if (chNext == '.') { // double dot is always an operator goto numAtEnd; } else if (numState <= PERLNUM_FLOAT) { // non-decimal number or float exponent, consume next dot styler.ColourTo(i - 1, SCE_PL_NUMBER); state = SCE_PL_DEFAULT; goto handleOperator; } else { // decimal or vectors allows dots dotCount++; if (numState == PERLNUM_DECIMAL) { if (dotCount > 1) { if (isdigit(chNext)) { // really a vector numState = PERLNUM_VECTOR; } else // number then dot goto numAtEnd; } } else { // vectors if (!isdigit(chNext)) // vector then dot goto numAtEnd; } } } else if (ch == '_') { // permissive underscoring for number and vector literals } else if (!isascii(ch) || isalnum(ch)) { if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) { if (!isascii(ch) || isalpha(ch)) { if (dotCount == 0) { // change to word state = SCE_PL_IDENTIFIER; } else { // vector then word goto numAtEnd; } } } else if (numState == PERLNUM_DECIMAL) { if (ch == 'E' || ch == 'e') { // exponent numState = PERLNUM_FLOAT; if (chNext == '+' || chNext == '-') { i++; ch = chNext; chNext = chNext2; } } else if (!isascii(ch) || !isdigit(ch)) { // number then word goto numAtEnd; } } else if (numState == PERLNUM_FLOAT) { if (!isdigit(ch)) { // float then word goto numAtEnd; } } else if (numState == PERLNUM_OCTAL) { if (!isdigit(ch)) goto numAtEnd; else if (ch > '7') numState = PERLNUM_BAD; } else if (numState == PERLNUM_BINARY) { if (!isdigit(ch)) goto numAtEnd; else if (ch > '1') numState = PERLNUM_BAD; } else if (numState == PERLNUM_HEX) { int ch2 = toupper(ch); if (!isdigit(ch) && !(ch2 >= 'A' && ch2 <= 'F')) goto numAtEnd; } else {//(numState == PERLNUM_BAD) { if (!isdigit(ch)) goto numAtEnd; } } else { // complete current number or vector numAtEnd: styler.ColourTo(i - 1, actualNumStyle(numState)); state = SCE_PL_DEFAULT; goto restartLexer; } } else if (state == SCE_PL_IDENTIFIER) { if (!isWordStart(chNext) && chNext != '\'') { styler.ColourTo(i, SCE_PL_IDENTIFIER); state = SCE_PL_DEFAULT; ch = ' '; } } else { if (state == SCE_PL_COMMENTLINE) { if (isEOLChar(ch)) { styler.ColourTo(i - 1, state); state = SCE_PL_DEFAULT; goto restartLexer; } else if (isEOLChar(chNext)) { styler.ColourTo(i, state); state = SCE_PL_DEFAULT; } } else if (state == SCE_PL_HERE_DELIM) { // // From perldata.pod: // ------------------ // A line-oriented form of quoting is based on the shell ``here-doc'' // syntax. // Following a << you specify a string to terminate the quoted material, // and all lines following the current line down to the terminating // string are the value of the item. // The terminating string may be either an identifier (a word), // or some quoted text. // If quoted, the type of quotes you use determines the treatment of // the text, just as in regular quoting. // An unquoted identifier works like double quotes. // There must be no space between the << and the identifier. // (If you put a space it will be treated as a null identifier, // which is valid, and matches the first empty line.) // (This is deprecated, -w warns of this syntax) // The terminating string must appear by itself (unquoted and with no // surrounding whitespace) on the terminating line. // // From Bash info: // --------------- // Specifier format is: <<[-]WORD // Optional '-' is for removal of leading tabs from here-doc. // Whitespace acceptable after <<[-] operator. // if (HereDoc.State == 0) { // '<<' encountered bool gotspace = false; unsigned int oldi = i; if (chNext == ' ' || chNext == '\t') { // skip whitespace; legal for quoted delimiters gotspace = true; do { i++; chNext = styler.SafeGetCharAt(i + 1); } while ((i + 1 < lengthDoc) && (chNext == ' ' || chNext == '\t')); chNext2 = styler.SafeGetCharAt(i + 2); } 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 (isspacechar(chNext) || isdigit(chNext) || chNext == '\\' || chNext == '=' || chNext == '$' || chNext == '@' || ((isalpha(chNext) || chNext == '_') && gotspace)) { // left shift << or <<= operator cases // restore position if operator i = oldi; styler.ColourTo(i, SCE_PL_OPERATOR); state = SCE_PL_DEFAULT; backflag = BACK_OPERATOR; backPos = i; HereDoc.State = 0; goto restartLexer; } else { // an unquoted here-doc delimiter, no special handling // (cannot be prefixed by spaces/tabs), or // symbols terminates; deprecated zero-length delimiter } } else if (HereDoc.State == 1) { // collect the delimiter backflag = BACK_NONE; 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; backflag = BACK_NONE; 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -