1 // Scintilla source code edit control
3 ** Lexer for properties files.
5 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
16 #include "Scintilla.h"
20 #include "LexAccessor.h"
22 #include "StyleContext.h"
23 #include "CharacterSet.h"
24 #include "LexerModule.h"
27 using namespace Scintilla
;
30 static inline bool AtEOL(Accessor
&styler
, Sci_PositionU i
) {
31 return (styler
[i
] == '\n') ||
32 ((styler
[i
] == '\r') && (styler
.SafeGetCharAt(i
+ 1) != '\n'));
35 static inline bool isassignchar(unsigned char ch
) {
36 return (ch
== '=') || (ch
== ':');
39 static void ColourisePropsLine(
41 Sci_PositionU lengthLine
,
42 Sci_PositionU startLine
,
45 bool allowInitialSpaces
) {
48 if (allowInitialSpaces
) {
49 while ((i
< lengthLine
) && isspacechar(lineBuffer
[i
])) // Skip initial spaces
52 if (isspacechar(lineBuffer
[i
])) // don't allow initial spaces
57 if (lineBuffer
[i
] == '#' || lineBuffer
[i
] == '!' || lineBuffer
[i
] == ';') {
58 styler
.ColourTo(endPos
, SCE_PROPS_COMMENT
);
59 } else if (lineBuffer
[i
] == '[') {
60 styler
.ColourTo(endPos
, SCE_PROPS_SECTION
);
61 } else if (lineBuffer
[i
] == '@') {
62 styler
.ColourTo(startLine
+ i
, SCE_PROPS_DEFVAL
);
63 if (isassignchar(lineBuffer
[i
++]))
64 styler
.ColourTo(startLine
+ i
, SCE_PROPS_ASSIGNMENT
);
65 styler
.ColourTo(endPos
, SCE_PROPS_DEFAULT
);
67 // Search for the '=' character
68 while ((i
< lengthLine
) && !isassignchar(lineBuffer
[i
]))
70 if ((i
< lengthLine
) && isassignchar(lineBuffer
[i
])) {
71 styler
.ColourTo(startLine
+ i
- 1, SCE_PROPS_KEY
);
72 styler
.ColourTo(startLine
+ i
, SCE_PROPS_ASSIGNMENT
);
73 styler
.ColourTo(endPos
, SCE_PROPS_DEFAULT
);
75 styler
.ColourTo(endPos
, SCE_PROPS_DEFAULT
);
79 styler
.ColourTo(endPos
, SCE_PROPS_DEFAULT
);
83 static void ColourisePropsDoc(Sci_PositionU startPos
, Sci_Position length
, int, WordList
*[], Accessor
&styler
) {
84 char lineBuffer
[1024];
85 styler
.StartAt(startPos
);
86 styler
.StartSegment(startPos
);
87 Sci_PositionU linePos
= 0;
88 Sci_PositionU startLine
= startPos
;
90 // property lexer.props.allow.initial.spaces
91 // For properties files, set to 0 to style all lines that start with whitespace in the default style.
92 // This is not suitable for SciTE .properties files which use indentation for flow control but
93 // can be used for RFC2822 text where indentation is used for continuation lines.
94 bool allowInitialSpaces
= styler
.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
96 for (Sci_PositionU i
= startPos
; i
< startPos
+ length
; i
++) {
97 lineBuffer
[linePos
++] = styler
[i
];
98 if (AtEOL(styler
, i
) || (linePos
>= sizeof(lineBuffer
) - 1)) {
99 // End of line (or of line buffer) met, colourise it
100 lineBuffer
[linePos
] = '\0';
101 ColourisePropsLine(lineBuffer
, linePos
, startLine
, i
, styler
, allowInitialSpaces
);
106 if (linePos
> 0) { // Last line does not have ending characters
107 ColourisePropsLine(lineBuffer
, linePos
, startLine
, startPos
+ length
- 1, styler
, allowInitialSpaces
);
111 // adaption by ksc, using the "} else {" trick of 1.53
113 static void FoldPropsDoc(Sci_PositionU startPos
, Sci_Position length
, int, WordList
*[], Accessor
&styler
) {
114 bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
116 Sci_PositionU endPos
= startPos
+ length
;
117 int visibleChars
= 0;
118 Sci_Position lineCurrent
= styler
.GetLine(startPos
);
120 char chNext
= styler
[startPos
];
121 int styleNext
= styler
.StyleAt(startPos
);
122 bool headerPoint
= false;
125 for (Sci_PositionU i
= startPos
; i
< endPos
; i
++) {
127 chNext
= styler
[i
+1];
129 int style
= styleNext
;
130 styleNext
= styler
.StyleAt(i
+ 1);
131 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
133 if (style
== SCE_PROPS_SECTION
) {
138 lev
= SC_FOLDLEVELBASE
;
140 if (lineCurrent
> 0) {
141 int levelPrevious
= styler
.LevelAt(lineCurrent
- 1);
143 if (levelPrevious
& SC_FOLDLEVELHEADERFLAG
) {
144 lev
= SC_FOLDLEVELBASE
+ 1;
146 lev
= levelPrevious
& SC_FOLDLEVELNUMBERMASK
;
151 lev
= SC_FOLDLEVELBASE
;
153 if (visibleChars
== 0 && foldCompact
)
154 lev
|= SC_FOLDLEVELWHITEFLAG
;
157 lev
|= SC_FOLDLEVELHEADERFLAG
;
159 if (lev
!= styler
.LevelAt(lineCurrent
)) {
160 styler
.SetLevel(lineCurrent
, lev
);
167 if (!isspacechar(ch
))
171 if (lineCurrent
> 0) {
172 int levelPrevious
= styler
.LevelAt(lineCurrent
- 1);
173 if (levelPrevious
& SC_FOLDLEVELHEADERFLAG
) {
174 lev
= SC_FOLDLEVELBASE
+ 1;
176 lev
= levelPrevious
& SC_FOLDLEVELNUMBERMASK
;
179 lev
= SC_FOLDLEVELBASE
;
181 int flagsNext
= styler
.LevelAt(lineCurrent
);
182 styler
.SetLevel(lineCurrent
, lev
| (flagsNext
& ~SC_FOLDLEVELNUMBERMASK
));
185 static const char *const emptyWordListDesc
[] = {
189 LexerModule
lmProps(SCLEX_PROPERTIES
, ColourisePropsDoc
, "props", FoldPropsDoc
, emptyWordListDesc
);