diff options
Diffstat (limited to 'scintilla/lexers/LexProps.cxx')
-rw-r--r-- | scintilla/lexers/LexProps.cxx | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/scintilla/lexers/LexProps.cxx b/scintilla/lexers/LexProps.cxx new file mode 100644 index 0000000..45af729 --- /dev/null +++ b/scintilla/lexers/LexProps.cxx @@ -0,0 +1,189 @@ +// Scintilla source code edit control +/** @file LexProps.cxx + ** Lexer for properties files. + **/ +// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <ctype.h> + +#include "ILexer.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#include "WordList.h" +#include "LexAccessor.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "CharacterSet.h" +#include "LexerModule.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { + return (styler[i] == '\n') || + ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); +} + +static inline bool isassignchar(unsigned char ch) { + return (ch == '=') || (ch == ':'); +} + +static void ColourisePropsLine( + char *lineBuffer, + Sci_PositionU lengthLine, + Sci_PositionU startLine, + Sci_PositionU endPos, + Accessor &styler, + bool allowInitialSpaces) { + + Sci_PositionU i = 0; + if (allowInitialSpaces) { + while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces + i++; + } else { + if (isspacechar(lineBuffer[i])) // don't allow initial spaces + i = lengthLine; + } + + if (i < lengthLine) { + if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { + styler.ColourTo(endPos, SCE_PROPS_COMMENT); + } else if (lineBuffer[i] == '[') { + styler.ColourTo(endPos, SCE_PROPS_SECTION); + } else if (lineBuffer[i] == '@') { + styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL); + if (isassignchar(lineBuffer[i++])) + styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT); + styler.ColourTo(endPos, SCE_PROPS_DEFAULT); + } else { + // Search for the '=' character + while ((i < lengthLine) && !isassignchar(lineBuffer[i])) + i++; + if ((i < lengthLine) && isassignchar(lineBuffer[i])) { + styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY); + styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT); + styler.ColourTo(endPos, SCE_PROPS_DEFAULT); + } else { + styler.ColourTo(endPos, SCE_PROPS_DEFAULT); + } + } + } else { + styler.ColourTo(endPos, SCE_PROPS_DEFAULT); + } +} + +static void ColourisePropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { + char lineBuffer[1024]; + styler.StartAt(startPos); + styler.StartSegment(startPos); + Sci_PositionU linePos = 0; + Sci_PositionU startLine = startPos; + + // property lexer.props.allow.initial.spaces + // For properties files, set to 0 to style all lines that start with whitespace in the default style. + // This is not suitable for SciTE .properties files which use indentation for flow control but + // can be used for RFC2822 text where indentation is used for continuation lines. + bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0; + + for (Sci_PositionU 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'; + ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces); + linePos = 0; + startLine = i + 1; + } + } + if (linePos > 0) { // Last line does not have ending characters + ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces); + } +} + +// adaption by ksc, using the "} else {" trick of 1.53 +// 030721 +static void FoldPropsDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + + Sci_PositionU endPos = startPos + length; + int visibleChars = 0; + Sci_Position lineCurrent = styler.GetLine(startPos); + + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + bool headerPoint = false; + int lev; + + for (Sci_PositionU i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler[i+1]; + + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + + if (style == SCE_PROPS_SECTION) { + headerPoint = true; + } + + if (atEOL) { + lev = SC_FOLDLEVELBASE; + + if (lineCurrent > 0) { + int levelPrevious = styler.LevelAt(lineCurrent - 1); + + if (levelPrevious & SC_FOLDLEVELHEADERFLAG) { + lev = SC_FOLDLEVELBASE + 1; + } else { + lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; + } + } + + if (headerPoint) { + lev = SC_FOLDLEVELBASE; + } + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + + if (headerPoint) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + + lineCurrent++; + visibleChars = 0; + headerPoint = false; + } + if (!isspacechar(ch)) + visibleChars++; + } + + if (lineCurrent > 0) { + int levelPrevious = styler.LevelAt(lineCurrent - 1); + if (levelPrevious & SC_FOLDLEVELHEADERFLAG) { + lev = SC_FOLDLEVELBASE + 1; + } else { + lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; + } + } else { + lev = SC_FOLDLEVELBASE; + } + int flagsNext = styler.LevelAt(lineCurrent); + styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK)); +} + +static const char *const emptyWordListDesc[] = { + 0 +}; + +LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc); |