📄 lexruby.cxx
字号:
} else if (state == SCE_RB_WORD) { if (ch == '.' || !isSafeWordcharOrHigh(ch)) { // Words include x? in all contexts, // and <letters>= after either 'def' or a dot // Move along until a complete word is on our left // Default accessor treats '.' as word-chars, // but we don't for now. if (ch == '=' && isSafeWordcharOrHigh(chPrev) && (chNext == '(' || strchr(" \t\n\r", chNext) != NULL) && (!strcmp(prevWord, "def") || followsDot(styler.GetStartSegment(), styler))) { // <name>= is a name only when being def'd -- Get it the next time // This means that <name>=<name> is always lexed as // <name>, (op, =), <name> } else if ((ch == '?' || ch == '!') && isSafeWordcharOrHigh(chPrev) && !isSafeWordcharOrHigh(chNext)) { // <name>? is a name -- Get it the next time // But <name>?<name> is always lexed as // <name>, (op, ?), <name> // Same with <name>! to indicate a method that // modifies its target } else if (isEOLChar(ch) && isMatch(styler, lengthDoc, i - 7, "__END__")) { styler.ColourTo(i, SCE_RB_DATASECTION); state = SCE_RB_DATASECTION; // No need to handle this state -- we'll just move to the end preferRE = false; } else { int wordStartPos = styler.GetStartSegment(); int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord); switch (word_style) { case SCE_RB_WORD: preferRE = RE_CanFollowKeyword(prevWord); break; case SCE_RB_WORD_DEMOTED: preferRE = true; break; case SCE_RB_IDENTIFIER: if (isMatch(styler, lengthDoc, wordStartPos, "print")) { preferRE = true; } else if (isEOLChar(ch)) { preferRE = true; } else { preferRE = false; } break; default: preferRE = false; } if (ch == '.') { // We might be redefining an operator-method preferRE = false; } // And if it's the first redo_char(i, ch, chNext, chNext2, state); // pass by ref } } } else if (state == SCE_RB_NUMBER) { if (!is_real_number) { if (ch != '\\') { styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } else if (strchr("\\ntrfvaebs", chNext)) { // Terminal escape sequence -- handle it next time // Nothing more to do this time through the loop } else if (chNext == 'C' || chNext == 'M') { if (chNext2 != '-') { // \C or \M ends the sequence -- handle it next time } else { // Move from abc?\C-x // ^ // to // ^ i += 2; ch = chNext2; chNext = styler.SafeGetCharAt(i + 1); } } else if (chNext == 'c') { // Stay here, \c is a combining sequence advance_char(i, ch, chNext, chNext2); // pass by ref } else { // ?\x, including ?\\ is final. styler.ColourTo(i + 1, state); state = SCE_RB_DEFAULT; preferRE = false; advance_char(i, ch, chNext, chNext2); } } else if (isSafeAlnumOrHigh(ch) || ch == '_') { // Keep going } else if (ch == '.' && ++numDots == 1) { // Keep going } else { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref preferRE = false; } } else if (state == SCE_RB_COMMENTLINE) { if (isEOLChar(ch)) { styler.ColourTo(i - 1, state); state = SCE_RB_DEFAULT; // Use whatever setting we had going into the comment } } else if (state == SCE_RB_HERE_DELIM) { // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx // Slightly different: if we find an immediate '-', // the target can appear indented. if (HereDoc.State == 0) { // '<<' encountered HereDoc.State = 1; HereDoc.DelimiterLength = 0; if (ch == '-') { HereDoc.CanBeIndented = true; advance_char(i, ch, chNext, chNext2); // pass by ref } else { HereDoc.CanBeIndented = false; } if (isEOLChar(ch)) { // Bail out of doing a here doc if there's no target state = SCE_RB_DEFAULT; preferRE = false; } else { HereDoc.Quote = ch; if (ch == '\'' || ch == '"' || ch == '`') { HereDoc.Quoted = true; HereDoc.Delimiter[0] = '\0'; } else { HereDoc.Quoted = false; HereDoc.Delimiter[0] = ch; HereDoc.Delimiter[1] = '\0'; HereDoc.DelimiterLength = 1; } } } else if (HereDoc.State == 1) { // collect the delimiter if (isEOLChar(ch)) { // End the quote now, and go back for more styler.ColourTo(i - 1, state); state = SCE_RB_DEFAULT; i--; chNext = ch; chNext2 = chNext; preferRE = false; } else if (HereDoc.Quoted) { if (ch == HereDoc.Quote) { // closing quote => end of delimiter styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } else { if (ch == '\\' && !isEOLChar(chNext)) { advance_char(i, ch, chNext, chNext2); } HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; } } else { // an unquoted here-doc delimiter if (isSafeAlnumOrHigh(ch) || ch == '_') { HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; } else { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); preferRE = false; } } if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) { styler.ColourTo(i - 1, state); state = SCE_RB_ERROR; preferRE = false; } } } else if (state == SCE_RB_HERE_Q) { // Not needed: HereDoc.State == 2 // Indentable here docs: look backwards // Non-indentable: look forwards, like in Perl // // Why: so we can quickly resolve things like <<-" abc" if (!HereDoc.CanBeIndented) { if (isEOLChar(chPrev) && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) { styler.ColourTo(i - 1, state); i += HereDoc.DelimiterLength - 1; chNext = styler.SafeGetCharAt(i + 1); if (isEOLChar(chNext)) { styler.ColourTo(i, SCE_RB_HERE_DELIM); state = SCE_RB_DEFAULT; HereDoc.State = 0; preferRE = false; } // Otherwise we skipped through the here doc faster. } } else if (isEOLChar(chNext) && lookingAtHereDocDelim(styler, i - HereDoc.DelimiterLength + 1, lengthDoc, HereDoc.Delimiter)) { styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state); styler.ColourTo(i, SCE_RB_HERE_DELIM); state = SCE_RB_DEFAULT; preferRE = false; HereDoc.State = 0; } } else if (state == SCE_RB_CLASS_VAR || state == SCE_RB_INSTANCE_VAR || state == SCE_RB_SYMBOL) { if (!isSafeWordcharOrHigh(ch)) { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref preferRE = false; } } else if (state == SCE_RB_GLOBAL) { if (!isSafeWordcharOrHigh(ch)) { // handle special globals here as well if (chPrev == '$') { if (ch == '-') { // Include the next char, like $-a advance_char(i, ch, chNext, chNext2); } styler.ColourTo(i, state); state = SCE_RB_DEFAULT; } else { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref } preferRE = false; } } else if (state == SCE_RB_POD) { // PODs end with ^=end\s, -- any whitespace can follow =end if (strchr(" \t\n\r", ch) != NULL && i > 5 && isEOLChar(styler[i - 5]) && isMatch(styler, lengthDoc, i - 4, "=end")) { styler.ColourTo(i - 1, state); state = SCE_RB_DEFAULT; preferRE = false; } } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) { if (ch == '\\' && Quote.Up != '\\') { // Skip one advance_char(i, ch, chNext, chNext2); } else if (ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { // Include the options while (isSafeAlpha(chNext)) { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } } else if (ch == Quote.Up) { // Only if close quoter != open quoter Quote.Count++; } else if (ch == '#' ) { if (chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT) { // process #{ ... } styler.ColourTo(i - 1, state); styler.ColourTo(i + 1, SCE_RB_OPERATOR); enterInnerExpression(inner_string_types, inner_expn_brace_counts, inner_quotes, inner_string_count, state, brace_counts, Quote); preferRE = true; // Skip one advance_char(i, ch, chNext, chNext2); } else { //todo: distinguish comments from pound chars // for now, handle as comment styler.ColourTo(i - 1, state); bool inEscape = false; while (++i < lengthDoc) { ch = styler.SafeGetCharAt(i); if (ch == '\\') { inEscape = true; } else if (isEOLChar(ch)) { // Comment inside a regex styler.ColourTo(i - 1, SCE_RB_COMMENTLINE); break; } else if (inEscape) { inEscape = false; // don't look at char } else if (ch == Quote.Down) { // Have the regular handler deal with this // to get trailing modifiers. i--; ch = styler[i]; break; } } chNext = styler.SafeGetCharAt(i + 1); chNext2 = styler.SafeGetCharAt(i + 2); } } // Quotes of all kinds... } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ || state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW || state == SCE_RB_STRING || state == SCE_RB_CHARACTER || state == SCE_RB_BACKTICKS) { if (!Quote.Down && !isspacechar(ch)) { Quote.Open(ch); } else if (ch == '\\' && Quote.Up != '\\') { //Riddle me this: Is it safe to skip *every* escaped char? advance_char(i, ch, chNext, chNext2); } else if (ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } } else if (ch == Quote.Up) { Quote.Count++; } else if (ch == '#' && chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT && state != SCE_RB_CHARACTER && state != SCE_RB_STRING_Q) { // process #{ ... } styler.ColourTo(i - 1, state); styler.ColourTo(i + 1, SCE_RB_OPERATOR); enterInnerExpression(inner_string_types, inner_expn_brace_counts, inner_quotes, inner_string_count, state, brace_counts, Quote); preferRE = true; // Skip one
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -