// Scintilla source code edit control /** @file LexYAML.cxx ** Lexer for YAML. **/ // Copyright 2003- by Sean O'Dell // The License.txt file describes the conditions under which this software may be distributed. #include #include #include #include #include #include "Platform.h" #include "PropSet.h" #include "Accessor.h" #include "StyleContext.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static const char * const yamlWordListDesc[] = { "Keywords", 0 }; static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); } static unsigned int SpaceCount(char* lineBuffer) { if (lineBuffer == NULL) return 0; char* headBuffer = lineBuffer; while (*headBuffer == ' ') headBuffer++; return headBuffer - lineBuffer; } #define YAML_STATE_BITSIZE 16 #define YAML_STATE_MASK (0xFFFF0000) #define YAML_STATE_DOCUMENT (1 << YAML_STATE_BITSIZE) #define YAML_STATE_VALUE (2 << YAML_STATE_BITSIZE) #define YAML_STATE_COMMENT (3 << YAML_STATE_BITSIZE) #define YAML_STATE_TEXT_PARENT (4 << YAML_STATE_BITSIZE) #define YAML_STATE_TEXT (5 << YAML_STATE_BITSIZE) static void ColouriseYAMLLine( char *lineBuffer, unsigned int currentLine, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList &keywords, Accessor &styler) { unsigned int i = 0; bool bInQuotes = false; unsigned int indentAmount = SpaceCount(lineBuffer); if (currentLine > 0) { int parentLineState = styler.GetLineState(currentLine - 1); if ((parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT || (parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT_PARENT) { unsigned int parentIndentAmount = parentLineState&(~YAML_STATE_MASK); if (indentAmount > parentIndentAmount) { styler.SetLineState(currentLine, YAML_STATE_TEXT | parentIndentAmount); styler.ColourTo(endPos, SCE_YAML_TEXT); return; } } } styler.SetLineState(currentLine, 0); if (strncmp(lineBuffer, "---", 3) == 0) { // Document marker styler.SetLineState(currentLine, YAML_STATE_DOCUMENT); styler.ColourTo(endPos, SCE_YAML_DOCUMENT); return; } // Skip initial spaces while ((i < lengthLine) && lineBuffer[i] == ' ') { // YAML always uses space, never TABS or anything else i++; } if (lineBuffer[i] == '\t') { // if we skipped all spaces, and we are NOT inside a text block, this is wrong styler.ColourTo(endPos, SCE_YAML_ERROR); return; } if (lineBuffer[i] == '#') { // Comment styler.SetLineState(currentLine, YAML_STATE_COMMENT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } while (i < lengthLine) { if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') { bInQuotes = !bInQuotes; } else if (lineBuffer[i] == ':' && !bInQuotes) { styler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER); styler.ColourTo(startLine + i, SCE_YAML_OPERATOR); // Non-folding scalar i++; while ((i < lengthLine) && isspacechar(lineBuffer[i])) i++; unsigned int endValue = lengthLine - 1; while ((endValue >= i) && isspacechar(lineBuffer[endValue])) endValue--; lineBuffer[endValue + 1] = '\0'; if (lineBuffer[i] == '|' || lineBuffer[i] == '>') { i++; if (lineBuffer[i] == '+' || lineBuffer[i] == '-') i++; while ((i < lengthLine) && isspacechar(lineBuffer[i])) i++; if (lineBuffer[i] == '\0') { styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount); styler.ColourTo(endPos, SCE_YAML_DEFAULT); return; } else if (lineBuffer[i] == '#') { styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount); styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } else { styler.ColourTo(endPos, SCE_YAML_ERROR); return; } } else if (lineBuffer[i] == '#') { styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } styler.SetLineState(currentLine, YAML_STATE_VALUE); if (lineBuffer[i] == '&' || lineBuffer[i] == '*') { styler.ColourTo(endPos, SCE_YAML_REFERENCE); return; } if (keywords.InList(&lineBuffer[i])) { // Convertible value (true/false, etc.) styler.ColourTo(endPos, SCE_YAML_KEYWORD); return; } else { unsigned int i2 = i; while ((i < lengthLine) && lineBuffer[i]) { if (!(isascii(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') { styler.ColourTo(endPos, SCE_YAML_DEFAULT); return; } i++; } if (i > i2) { styler.ColourTo(endPos, SCE_YAML_NUMBER); return; } } break; // shouldn't get here, but just in case, the rest of the line is coloured the default } i++; } styler.ColourTo(endPos, SCE_YAML_DEFAULT); } static void ColouriseYAMLDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { char lineBuffer[1024]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; unsigned int endPos = startPos + length; unsigned int maxPos = styler.Length(); unsigned int lineCurrent = styler.GetLine(startPos); for (unsigned int i = startPos; i < maxPos && i < endPos; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, i, *keywordLists[0], styler); linePos = 0; startLine = i + 1; lineCurrent++; } } if (linePos > 0) { // Last line does not have ending characters ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, startPos + length - 1, *keywordLists[0], styler); } } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); if (styler[pos] == '#') return true; return false; } static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unused*/, WordList *[], Accessor &styler) { const int maxPos = startPos + length; const int maxLines = styler.GetLine(maxPos - 1); // Requested last line const int docLines = styler.GetLine(styler.Length() - 1); // Available last line const bool foldComment = styler.GetPropertyInt("fold.comment.yaml") != 0; // Backtrack to previous non-blank line so we can determine indent level // for any white space lines // and so we can fix any preceding fold level (which is why we go back // at least one line in all cases) int spaceFlags = 0; int lineCurrent = styler.GetLine(startPos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); while (lineCurrent > 0) { lineCurrent--; indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && (!IsCommentLine(lineCurrent, styler))) break; } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; // Set up initial loop state int prevComment = 0; if (lineCurrent >= 1) prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler); // Process all characters to end of requested range // or comment that hangs over the end of the range. Cap processing in all cases // to end of document (in case of unclosed comment at end). while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; int indentNext = indentCurrent; if (lineNext <= docLines) { // Information about next line is only available if not at end of document indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int comment = foldComment && IsCommentLine(lineCurrent, styler); const int comment_start = (comment && !prevComment && (lineNext <= docLines) && IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));HTTP/1.1 200 OK Connection: keep-alive Connection: keep-alive Connection: keep-alive Content-Disposition: inline; filename="LexYAML.cxx" Content-Disposition: inline; filename="LexYAML.cxx" Content-Disposition: inline; filename="LexYAML.cxx" Content-Length: 10718 Content-Length: 10718 Content-Length: 10718 Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Security-Policy: default-src 'none' Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8 Date: Tue, 21 Oct 2025 15:22:29 UTC ETag: "99f34da8895a527d8e11d46396814023a6071e94" ETag: "99f34da8895a527d8e11d46396814023a6071e94" ETag: "99f34da8895a527d8e11d46396814023a6071e94" Expires: Fri, 19 Oct 2035 15:22:29 GMT Expires: Fri, 19 Oct 2035 15:22:30 GMT Expires: Fri, 19 Oct 2035 15:22:30 GMT Last-Modified: Tue, 21 Oct 2025 15:22:29 GMT Last-Modified: Tue, 21 Oct 2025 15:22:30 GMT Last-Modified: Tue, 21 Oct 2025 15:22:30 GMT Server: OpenBSD httpd Server: OpenBSD httpd Server: OpenBSD httpd X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff // Scintilla source code edit control /** @file LexYAML.cxx ** Lexer for YAML. **/ // Copyright 2003- by Sean O'Dell // The License.txt file describes the conditions under which this software may be distributed. #include #include #include #include #include #include "Platform.h" #include "PropSet.h" #include "Accessor.h" #include "StyleContext.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static const char * const yamlWordListDesc[] = { "Keywords", 0 }; static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); } static unsigned int SpaceCount(char* lineBuffer) { if (lineBuffer == NULL) return 0; char* headBuffer = lineBuffer; while (*headBuffer == ' ') headBuffer++; return headBuffer - lineBuffer; } #define YAML_STATE_BITSIZE 16 #define YAML_STATE_MASK (0xFFFF0000) #define YAML_STATE_DOCUMENT (1 << YAML_STATE_BITSIZE) #define YAML_STATE_VALUE (2 << YAML_STATE_BITSIZE) #define YAML_STATE_COMMENT (3 << YAML_STATE_BITSIZE) #define YAML_STATE_TEXT_PARENT (4 << YAML_STATE_BITSIZE) #define YAML_STATE_TEXT (5 << YAML_STATE_BITSIZE) static void C