Add an UI to enable/disable specific overlay handlers.
[TortoiseGit.git] / ext / scintilla / src / LexLout.cxx
blob8ec3f39c161328b41dc7acd3cc67123fa66250b7
1 // Scintilla source code edit control
2 /** @file LexLout.cxx
3 ** Lexer for the Basser Lout (>= version 3) typesetting language
4 **/
5 // Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my>
6 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdarg.h>
14 #include "Platform.h"
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "StyleContext.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
23 #ifdef SCI_NAMESPACE
24 using namespace Scintilla;
25 #endif
27 static inline bool IsAWordChar(const int ch) {
28 return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_');
31 static inline bool IsAnOther(const int ch) {
32 return (ch < 0x80) && (ch == '{' || ch == '}' ||
33 ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' ||
34 ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' ||
35 ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' ||
36 ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' ||
37 ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~');
40 static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle,
41 WordList *keywordlists[], Accessor &styler) {
43 WordList &keywords = *keywordlists[0];
44 WordList &keywords2 = *keywordlists[1];
45 WordList &keywords3 = *keywordlists[2];
47 int visibleChars = 0;
48 int firstWordInLine = 0;
49 int leadingAtSign = 0;
51 StyleContext sc(startPos, length, initStyle, styler);
53 for (; sc.More(); sc.Forward()) {
55 if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) {
56 // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line
57 sc.SetState(SCE_LOUT_STRING);
60 // Determine if the current state should terminate.
61 if (sc.state == SCE_LOUT_COMMENT) {
62 if (sc.atLineEnd) {
63 sc.SetState(SCE_LOUT_DEFAULT);
64 visibleChars = 0;
66 } else if (sc.state == SCE_LOUT_NUMBER) {
67 if (!IsADigit(sc.ch) && sc.ch != '.') {
68 sc.SetState(SCE_LOUT_DEFAULT);
70 } else if (sc.state == SCE_LOUT_STRING) {
71 if (sc.ch == '\\') {
72 if (sc.chNext == '\"' || sc.chNext == '\\') {
73 sc.Forward();
75 } else if (sc.ch == '\"') {
76 sc.ForwardSetState(SCE_LOUT_DEFAULT);
77 } else if (sc.atLineEnd) {
78 sc.ChangeState(SCE_LOUT_STRINGEOL);
79 sc.ForwardSetState(SCE_LOUT_DEFAULT);
80 visibleChars = 0;
82 } else if (sc.state == SCE_LOUT_IDENTIFIER) {
83 if (!IsAWordChar(sc.ch)) {
84 char s[100];
85 sc.GetCurrent(s, sizeof(s));
87 if (leadingAtSign) {
88 if (keywords.InList(s)) {
89 sc.ChangeState(SCE_LOUT_WORD);
90 } else {
91 sc.ChangeState(SCE_LOUT_WORD4);
93 } else if (firstWordInLine && keywords3.InList(s)) {
94 sc.ChangeState(SCE_LOUT_WORD3);
96 sc.SetState(SCE_LOUT_DEFAULT);
98 } else if (sc.state == SCE_LOUT_OPERATOR) {
99 if (!IsAnOther(sc.ch)) {
100 char s[100];
101 sc.GetCurrent(s, sizeof(s));
103 if (keywords2.InList(s)) {
104 sc.ChangeState(SCE_LOUT_WORD2);
106 sc.SetState(SCE_LOUT_DEFAULT);
110 // Determine if a new state should be entered.
111 if (sc.state == SCE_LOUT_DEFAULT) {
112 if (sc.ch == '#') {
113 sc.SetState(SCE_LOUT_COMMENT);
114 } else if (sc.ch == '\"') {
115 sc.SetState(SCE_LOUT_STRING);
116 } else if (IsADigit(sc.ch) ||
117 (sc.ch == '.' && IsADigit(sc.chNext))) {
118 sc.SetState(SCE_LOUT_NUMBER);
119 } else if (IsAWordChar(sc.ch)) {
120 firstWordInLine = (visibleChars == 0);
121 leadingAtSign = (sc.ch == '@');
122 sc.SetState(SCE_LOUT_IDENTIFIER);
123 } else if (IsAnOther(sc.ch)) {
124 sc.SetState(SCE_LOUT_OPERATOR);
128 if (sc.atLineEnd) {
129 // Reset states to begining of colourise so no surprises
130 // if different sets of lines lexed.
131 visibleChars = 0;
133 if (!IsASpace(sc.ch)) {
134 visibleChars++;
137 sc.Complete();
140 static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[],
141 Accessor &styler) {
143 unsigned int endPos = startPos + length;
144 int visibleChars = 0;
145 int lineCurrent = styler.GetLine(startPos);
146 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
147 int levelCurrent = levelPrev;
148 char chNext = styler[startPos];
149 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
150 int styleNext = styler.StyleAt(startPos);
151 char s[10];
153 for (unsigned int i = startPos; i < endPos; i++) {
154 char ch = chNext;
155 chNext = styler.SafeGetCharAt(i + 1);
156 int style = styleNext;
157 styleNext = styler.StyleAt(i + 1);
158 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
160 if (style == SCE_LOUT_WORD) {
161 if (ch == '@') {
162 for (unsigned int j = 0; j < 8; j++) {
163 if (!IsAWordChar(styler[i + j])) {
164 break;
166 s[j] = styler[i + j];
167 s[j + 1] = '\0';
169 if (strcmp(s, "@Begin") == 0) {
170 levelCurrent++;
171 } else if (strcmp(s, "@End") == 0) {
172 levelCurrent--;
175 } else if (style == SCE_LOUT_OPERATOR) {
176 if (ch == '{') {
177 levelCurrent++;
178 } else if (ch == '}') {
179 levelCurrent--;
182 if (atEOL) {
183 int lev = levelPrev;
184 if (visibleChars == 0 && foldCompact) {
185 lev |= SC_FOLDLEVELWHITEFLAG;
187 if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
188 lev |= SC_FOLDLEVELHEADERFLAG;
190 if (lev != styler.LevelAt(lineCurrent)) {
191 styler.SetLevel(lineCurrent, lev);
193 lineCurrent++;
194 levelPrev = levelCurrent;
195 visibleChars = 0;
197 if (!isspacechar(ch))
198 visibleChars++;
200 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
201 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
202 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
205 static const char * const loutWordLists[] = {
206 "Predefined identifiers",
207 "Predefined delimiters",
208 "Predefined keywords",
212 LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists);