aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/LexYAML.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/LexYAML.cxx')
-rw-r--r--src/LexYAML.cxx181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/LexYAML.cxx b/src/LexYAML.cxx
new file mode 100644
index 000000000..da9816408
--- /dev/null
+++ b/src/LexYAML.cxx
@@ -0,0 +1,181 @@
+// Scintilla source code edit control
+/** @file LexYAML.cxx
+ ** Lexer for YAML.
+ **/
+// Copyright 2003- by Sean O'Dell <sean@celsoft.com>
+// Release under the same license as Scintilla/SciTE.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "PropSet.h"
+#include "Accessor.h"
+#include "KeyWords.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+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 void ColouriseYAMLLine(
+ char *lineBuffer,
+ unsigned int lengthLine,
+ unsigned int startLine,
+ unsigned int endPos,
+ WordList &keywords,
+ Accessor &styler) {
+
+ unsigned int i = 0;
+ bool bInQuotes = false;
+ unsigned int startValue, endValue, valueLen;
+ char scalar[256];
+ if (lineBuffer[0] == '#') { // Comment
+ styler.ColourTo(endPos, SCE_YAML_COMMENT);
+ return;
+ }
+ if (strncmp(lineBuffer, "---", 3) == 0) { // Document marker
+ styler.ColourTo(endPos, SCE_YAML_DOCUMENT);
+ return;
+ }
+ // Skip initial spaces
+ while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
+ i++;
+ }
+ while (i < lengthLine) {
+ if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') {
+ bInQuotes = !bInQuotes;
+ } else if (lineBuffer[i] == ':' && !bInQuotes) {
+ styler.ColourTo(startLine + i, SCE_YAML_IDENTIFIER);
+ // Non-folding scalar
+ startValue = i + 1;
+ while ((startValue < lengthLine) && isspacechar(lineBuffer[startValue])) {
+ startValue++;
+ }
+ endValue = lengthLine - 1;
+ while ((endValue >= startValue) && isspacechar(lineBuffer[endValue])) {
+ endValue--;
+ }
+ valueLen = endValue - startValue + 1;
+ if (endValue < startValue || valueLen > sizeof(scalar)) {
+ break;
+ }
+ strncpy(scalar, &lineBuffer[startValue], valueLen);
+ scalar[valueLen] = '\0';
+ if (scalar[0] == '&' || scalar[0] == '*') {
+ styler.ColourTo(startLine + endValue, SCE_YAML_REFERENCE);
+ }
+ else if (keywords.InList(scalar)) { // Convertible value (true/false, etc.)
+ styler.ColourTo(startLine + endValue, SCE_YAML_KEYWORD);
+ } else {
+ startValue = 0;
+ while (startValue < valueLen) {
+ if (!isdigit(scalar[startValue]) && scalar[startValue] != '-' && scalar[startValue] != '.' && scalar[startValue] != ',') {
+ break;
+ }
+ startValue++;
+ }
+ if (startValue >= valueLen) {
+ styler.ColourTo(startLine + endValue, SCE_YAML_NUMBER);
+ }
+ }
+ break; // 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;
+ for (unsigned int i = startPos; i < startPos + length; 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, linePos, startLine, i, *keywordLists[0], styler);
+ linePos = 0;
+ startLine = i + 1;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ ColouriseYAMLLine(lineBuffer, linePos, startLine, startPos + length - 1, *keywordLists[0], styler);
+ }
+}
+
+static int IdentifierLevelYAMLLine(
+ char *lineBuffer,
+ unsigned int lengthLine) {
+
+ unsigned int i = 0;
+ bool bInQuotes = false;
+ int level;
+ if (lineBuffer[0] == '#') { // Comment
+ return 0xFFFFFFFF;
+ }
+ if (strncmp(lineBuffer, "---", 3) == 0) { // Document marker
+ return 0;
+ }
+ // Count initial spaces and '-' character
+ while ((i < lengthLine) && (isspacechar(lineBuffer[i]) || lineBuffer[i] == '-')) {
+ i++;
+ }
+ level = i;
+ while (i < lengthLine) {
+ if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') {
+ bInQuotes = !bInQuotes;
+ } else if (lineBuffer[i] == ':' && !bInQuotes) {
+ return level;
+ }
+ i++;
+ }
+ return -level; // Scalar
+}
+
+static void FoldYAMLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ char lineBuffer[1024];
+ styler.StartAt(startPos);
+ styler.StartSegment(startPos);
+ unsigned int linePos = 0;
+ int currentLevel;
+ int lastLevel = 0xFFFFFFFF;
+ unsigned int lineCurrent = 0;
+ for (unsigned int i = startPos; i < startPos + length; 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';
+ currentLevel = IdentifierLevelYAMLLine(lineBuffer, linePos);
+ if (currentLevel != static_cast<int>(0xFFFFFFFF)) {
+ if (abs(currentLevel) > abs(lastLevel) && lastLevel >= 0) { // indented higher than last, and last was an identifier line
+ styler.SetLevel(lineCurrent - 1, SC_FOLDLEVELHEADERFLAG);
+ }
+ lastLevel = currentLevel;
+ }
+ linePos = 0;
+ lineCurrent++;
+ }
+ }
+ if (linePos > 0) { // Last line does not have ending characters
+ currentLevel = IdentifierLevelYAMLLine(lineBuffer, linePos);
+ if (currentLevel != static_cast<int>(0xFFFFFFFF)) {
+ if (abs(currentLevel) > abs(lastLevel) && lastLevel >= 0) {
+ styler.SetLevel(lineCurrent - 1, SC_FOLDLEVELHEADERFLAG);
+ }
+ }
+ }
+}
+
+LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, "yaml", FoldYAMLDoc, yamlWordListDesc);